Skip to content

Commit b83e865

Browse files
committed
Branch more during container size realization
1 parent 4c85ce4 commit b83e865

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

crosshair/libimpl/builtinslib.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,13 @@ def __gt__(self, other):
14111411
)
14121412
return ret
14131413

1414+
def __ch_realize__(self) -> object:
1415+
# TODO: Bisect-search with small bounded ranges?
1416+
choice_conformity = (
1417+
1.0 if self._ch_minimum is None and self._ch_maximum is None else 0.9
1418+
)
1419+
return context_statespace().find_model_value(self.var, choice_conformity)
1420+
14141421
def _ch_intersect_bounds(
14151422
self, new_min: Optional[int], new_max: Optional[int]
14161423
) -> None:

crosshair/libimpl/builtinslib_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import sys
1111
from abc import ABC, abstractmethod
1212
from array import array
13+
from bisect import bisect_left
1314
from numbers import Integral
1415
from typing import (
1516
Callable,
@@ -1778,6 +1779,22 @@ def f(ls: List[int], i: int) -> List[int]:
17781779
check_states(f, CONFIRMED)
17791780

17801781

1782+
def test_list_can_realize_nonzero_length_without_exhausting_other_paths() -> None:
1783+
def f(x: int, ls: List[int]) -> list[int]:
1784+
"""
1785+
post: len(_) < 5
1786+
"""
1787+
lslen = len(ls)
1788+
with NoTracing():
1789+
realize(lslen)
1790+
1791+
haystack = list(range(1000))
1792+
y = bisect_left(haystack, x)
1793+
return ls
1794+
1795+
check_states(f, POST_FAIL)
1796+
1797+
17811798
def test_list_range_fail() -> None:
17821799
def f(ls: List[int]) -> List[int]:
17831800
"""

crosshair/libimpl/datetimelib_ch_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ def check_date_ctime(dt: date) -> ResultComparison:
181181

182182
def check_date_strftime(dt: date, fmt: str) -> ResultComparison:
183183
"""post: _"""
184+
# not using skipIf because this is invoked via `test_builtin`:
185+
if sys.version_info < (3, 13):
186+
# strftime null character handling aligned between python and C
187+
# implementations in https://github.com/python/cpython/pull/125657
188+
return True
184189
return compare_results(_invoker("strftime"), dt, fmt)
185190

186191

@@ -303,6 +308,11 @@ def check_time_isoformat(tm: time) -> ResultComparison:
303308

304309
def check_time_strftime(tm: time, fmt: str) -> ResultComparison:
305310
"""post: _"""
311+
# not using skipIf because this is invoked via `test_builtin`:
312+
if sys.version_info < (3, 13):
313+
# strftime null character handling aligned between python and C
314+
# implementations in https://github.com/python/cpython/pull/125657
315+
return True
306316
return compare_results(_invoker("strftime"), tm, fmt)
307317

308318

crosshair/statespace.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ def raise_not_deterministic(
962962
else:
963963
raise exc
964964

965-
def find_model_value(self, expr: z3.ExprRef) -> Any:
965+
def find_model_value(self, expr: z3.ExprRef, choice_conformity=1.0) -> Any:
966966
with NoTracing():
967967
while True:
968968
if isinstance(self._search_position, NodeStem):
@@ -980,7 +980,9 @@ def find_model_value(self, expr: z3.ExprRef) -> Any:
980980
debug(" Traceback: ", ch_stack())
981981
debug(" *** End Not Deterministic Debug *** ")
982982
raise NotDeterministic
983-
(chosen, _, next_node) = node.choose(self, probability_true=1.0)
983+
(chosen, _, next_node) = node.choose(
984+
self, probability_true=choice_conformity
985+
)
984986
self.choices_made.append(node)
985987
self._search_position = next_node
986988
if chosen:

0 commit comments

Comments
 (0)