This module offers three different SAT tactics for proving goals involving BitVec and Bool:
bv_decidetakes the goal, hands it over to a SAT solver and verifies the generated LRAT UNSAT proof to prove the goal.bv_check file.lratcan prove the same things asbv_decide. However instead of dynamically handing the goal to a SAT solver to obtain an LRAT proof, the LRAT proof is read fromfile.lrat. This allows users that do not have a SAT solver installed to verify proofs.bv_decide?offers a code action to turn abv_decideinvocation automatically into abv_checkone.
Additionally it offers bv_normalize, which only runs the preprocessing of the tactics above.
There are also some options to influence the behavior of bv_decide and friends:
sat.solver: the name of the SAT solver used bybv_decide. It goes through 3 steps to determine which solver to use:- If sat.solver is set to something != "" it will use that.
- If sat.solver is set to "" it will check if there is a cadical binary next to the executing
program. Usually that program is going to be
leanitself and we do ship acadicalnext to it. - If that does not succeed try to call
cadicalfrom PATH.
sat.timeout: The timeout for waiting for the SAT solver in seconds, default 10.sat.trimProofs: Whether to run the trimming algorithm on LRAT proofs, default true.sat.binaryProofs: Whether to use the binary LRAT proof format, default true.trace.Meta.Tactic.bvandtrace.Meta.Tactic.satfor inspecting the inner workings ofbv_decide.debug.skipKernelTC: may be set to true to disable actually checking the LRAT proof.bv_decidewill still run bitblasting + SAT solving so this option essentially trusts the SAT solver.
Architecture #
bv_decide roughly runs through the following steps:
- Apply
false_or_by_contrato start a proof by contradiction. - Apply the
bv_normalizeandsevalsimp set to all hypotheses. This has two effects: - Use proof by reflection to reduce the proof to showing that an SMT-LIB-syntax-like value that represents the conjunction of all relevant assumptions is UNSAT.
- Use a verified bitblasting algorithm to turn that expression into an AIG.
The bitblasting algorithms are collected from various other bitblasters, including Bitwuzla and
Z3 and verified using Lean's
BitVectheory. - Turn the AIG into a CNF.
- Run CaDiCal on the CNF to obtain an LRAT proof that the CNF is UNSAT. If CaDiCal returns SAT instead the tactic aborts here and presents a counterexample.
- Use an LRAT checker with a soundness proof in Lean to show that the LRAT proof is correct.
- Chain all the proofs so far to demonstrate that the original goal holds.
Axioms #
bv_decide makes use of proof by reflection and adds the result of the compiled check as an axoim,
thus adding the Lean compiler to the trusted code base.
Adding a new primitive #
bv_decide knows two kinds of primitives:
- The ones that can be reduced to already existing ones.
- The ones that cannot.
For the first kind the steps to adding them are very simple, go to Std.Tactic.BVDecide.Normalize
and add the reduction lemma into the bv_normalize simp set. Don't forget to add a test!
For the second kind more steps are involved:
- Add a new constructor to
BVExpr/BVPred - Add a bitblasting algorithm for the new constructor to
Std.Tactic.BVDecide.Bitblast.BVExpr.Circuit.Impl. - Verify that algorithm in
Std.Tactic.BVDecide.Bitblast.BVExpr.Circuit.Lemmas. - Integrate it with either the expression or predicate bitblaster and use the proof above to verify it.
- Add simplification lemmas for the primitive to
bv_normalizeinStd.Tactic.BVDecide.Normalize. If there are multiple ways to write the primitive (e.g. with TC based notation and without) you should normalize for one notation here. - Add the reflection code to
Lean.Meta.Tactic.BVDecide.Reflect - Add a test!
Equations
- One or more equations did not get rendered due to their size.
Instances For
Get the directory that contains the Lean file which is currently being elaborated.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
This tactic works just like bv_decide but skips calling a SAT solver by using a proof that is
already stored on disk. It is called with the name of an LRAT file in the same directory as the
current Lean file:
bv_check "proof.lrat"
Equations
- Lean.Elab.Tactic.BVDecide.BVCheck.bvCheck g hypotheses ctx = (discard (Lean.Meta.Tactic.BVDecide.closeWithBVReflection g (Lean.Meta.Tactic.BVDecide.lratChecker ctx))).run hypotheses
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Produce a file with the pattern: LeanFileName-DeclName-Line-Col.lrat
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Lean.Elab.Tactic.BVDecide.BVTrace.mkContext cfg types = do let lratPath ← Lean.Elab.Tactic.BVDecide.BVTrace.getLratFileName Lean.Elab.Tactic.BVDecide.BVCheck.mkContext lratPath cfg types
Instances For
- normalize : TraceResult
- check (path : System.FilePath) : TraceResult
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.