z3py-compatible solver interface. ``check()`` builds the conjunction of all assertions, negates it, and tries to prove the negation via grind. If proved, returns ``unsat`` (the constraints are contradictory). Otherwise ``unknown``.
| 542 | |
| 543 | |
| 544 | class Solver: |
| 545 | """z3py-compatible solver interface. |
| 546 | |
| 547 | ``check()`` builds the conjunction of all assertions, negates it, |
| 548 | and tries to prove the negation via grind. If proved, returns |
| 549 | ``unsat`` (the constraints are contradictory). Otherwise ``unknown``. |
| 550 | """ |
| 551 | |
| 552 | def __init__(self) -> None: |
| 553 | self._assertions: list[BoolRef] = [] |
| 554 | self._stack: list[int] = [] |
| 555 | |
| 556 | def add(self, *args: BoolRef) -> None: |
| 557 | for a in args: |
| 558 | self._assertions.append(a) |
| 559 | |
| 560 | # Aliases for add |
| 561 | append = add |
| 562 | insert = add |
| 563 | |
| 564 | def set(self, *args: Any, **keys: Any) -> None: |
| 565 | """Set solver options (no-op — Lean solver has no tunable parameters).""" |
| 566 | pass |
| 567 | |
| 568 | def push(self) -> None: |
| 569 | self._stack.append(len(self._assertions)) |
| 570 | |
| 571 | def pop(self, n: int = 1) -> None: |
| 572 | for _ in range(n): |
| 573 | if not self._stack: |
| 574 | raise IndexError("pop from empty solver stack") |
| 575 | self._assertions = self._assertions[: self._stack.pop()] |
| 576 | |
| 577 | def num_scopes(self) -> int: |
| 578 | """Return number of push scopes.""" |
| 579 | return len(self._stack) |
| 580 | |
| 581 | def check(self, *assumptions: BoolRef) -> CheckSatResult: |
| 582 | asserts = list(self._assertions) |
| 583 | asserts.extend(assumptions) |
| 584 | if not asserts: |
| 585 | return sat |
| 586 | conj = And(*asserts) |
| 587 | # Try proving negation → unsat |
| 588 | negated = Not(conj) |
| 589 | if _try_prove(negated): |
| 590 | return unsat |
| 591 | # Try proving conjunction directly → sat (tautologically true) |
| 592 | if _try_prove(conj): |
| 593 | return sat |
| 594 | return unknown |
| 595 | |
| 596 | def model(self) -> ModelRef: |
| 597 | raise NotImplementedError( |
| 598 | "Model extraction not supported: Lean is a proof checker, not an SMT solver" |
| 599 | ) |
| 600 | |
| 601 | def assertions(self) -> list[BoolRef]: |
no outgoing calls