Equations
- One or more equations did not get rendered due to their size.
- Lean.Meta.Grind.Arith.Cutsat.instHashablePoly_lean.hash (Int.Linear.Poly.num a) = mixHash 0 (hash a)
Instances For
This module implements a model-based decision procedure for linear integer arithmetic, inspired by Section 4 of "Cutting to the Chase: Solving Linear Integer Arithmetic". Our implementation includes several enhancements and modifications: Key Features:
- Extended constraint support (equality and disequality)
- Optimized encoding of
Cooper-Leftrule using "big"-disjunction instead of fresh variables - Decision variable tracking for case splits (disequalities,
Cooper-Left,Cooper-Right)
Constraint Types: We handle four categories of linear polynomial constraints (where p is a linear polynomial):
Implementation Details:
- Polynomials use
Int.Linear.Polywith sorted linear monomials (leading monomial contains max variable) - Equalities are eliminated eagerly
- Divisibility constraints are maintained in solved form (one constraint per variable) using
Div-Solve
Model Construction:
The procedure builds a model incrementally, resolving conflicts through constraint generation.
For example:
Given a partial model {x := 1} and constraint 3 ∣ 3*y + x + 1:
- Cannot extend to
ybecause3 ∣ 3*y + 2is unsatisfiable - Generate implied constraint
3 ∣ x + 1 - Force model update for
x
Variable Assignment:
When assigning a variable y, we consider:
- Best upper and lower bounds (inequalities)
- Divisibility constraint
- Disequality constraints
Cooper-LeftandCooper-Rightrules handle the combination of inequalities and divisibility. For unsatisfiable disequalities p ≠ 0, we generate case split:p + 1 ≤ 0 ∨ -p + 1 ≤ 0
Contradiction Handling:
- Check dependency on decision variables
- If independent, use contradiction to close current grind goal
- Otherwise, trigger backtracking
Optimization: We employ rational approximation for model construction:
- Continue with rational solutions when integer solutions aren't immediately found
- Helps identify simpler unsatisfiability proofs before full integer model construction
- core0
(a zero : Expr)
: EqCnstrProof
An equality
a = 0coming from the core. - core
(a b : Expr)
(p₁ p₂ : Poly)
: EqCnstrProof
An equality
a = bcoming from the core.p₁andp₂are the polynomials corresponding toaandb. - coreToInt (a b toIntThm : Expr) (lhs rhs : Int.Linear.Expr) : EqCnstrProof
- defn
(e : Expr)
(p : Poly)
: EqCnstrProof
eisp - defnNat (h : Expr) (x : Var) (e' : Int.Linear.Expr) : EqCnstrProof
- norm (c : EqCnstr) : EqCnstrProof
- divCoeffs (c : EqCnstr) : EqCnstrProof
- subst (x : Var) (c₁ c₂ : EqCnstr) : EqCnstrProof
- ofLeGe (c₁ c₂ : LeCnstr) : EqCnstrProof
- reorder (c : EqCnstr) : EqCnstrProof
- commRingNorm (c : EqCnstr) (e : CommRing.RingExpr) (p : CommRing.Poly) : EqCnstrProof
- defnCommRing (e : Expr) (p : Poly) (re : CommRing.RingExpr) (rp : CommRing.Poly) (p' : Poly) : EqCnstrProof
- defnNatCommRing (h : Expr) (x : Var) (e' : Int.Linear.Expr) (p : Poly) (re : CommRing.RingExpr) (rp : CommRing.Poly) (p' : Poly) : EqCnstrProof
- mul (a? : Option Expr) (cs : Array (Expr × Int × EqCnstr)) : EqCnstrProof
- div (k : Int) (y? : Option Var) (c : EqCnstr) : EqCnstrProof
- mod (k : Int) (y? : Option Var) (c : EqCnstr) : EqCnstrProof
- pow (ka : Int) (ca? : Option EqCnstr) (kb : Nat) (cb? : Option EqCnstr) : EqCnstrProof
Instances For
The predicate of type Nat → Prop, which serves as the conclusion of the
cooper_left, cooper_right, cooper_dvd_left, and cooper_dvd_right theorems.
The specific predicate used is determined as follows:
cooper_left_split(ifleftistrueandc₃?isnone)cooper_right_split(ifleftisfalseandc₃?isnone)cooper_dvd_left_split(ifleftistrueandc₃?issome)cooper_dvd_right_split(ifleftisfalseandc₃?issome)
See CooperSplit
Instances For
An instance of the CooperSplitPred at k.
- pred : CooperSplitPred
- k : Nat
- h : CooperSplitProof
Instances For
The cooper_left, cooper_right, cooper_dvd_left, and cooper_dvd_right theorems have a resulting type
that is a big-or of the form OrOver n (cooper_*_split ...). The predicate (cooper_*_split ...) has type Nat → Prop.
The cutsat procedure performs case splitting on (cooper_*_split ... (n-1)) down to (cooper_*_split ... 1).
If it derives False from each case, it uses orOver_resolve and orOver_one to deduce the final case,
which has type (cooper_*_split ... 0).
- dec
(h : FVarId)
: CooperSplitProof
The first
n-1cases are decisions (aka case-splits). - last
(hs : Array (FVarId × UnsatProof))
(decVars : Array FVarId)
: CooperSplitProof
The last case which has type
(cooper_*_split ... 0)
Instances For
- core (e : Expr) : DvdCnstrProof
- coreOfNat (e thm : Expr) (d : Nat) (a : Int.Linear.Expr) : DvdCnstrProof
- norm (c : DvdCnstr) : DvdCnstrProof
- divCoeffs (c : DvdCnstr) : DvdCnstrProof
- solveCombine (c₁ c₂ : DvdCnstr) : DvdCnstrProof
- solveElim (c₁ c₂ : DvdCnstr) : DvdCnstrProof
- elim (c : DvdCnstr) : DvdCnstrProof
- ofEq (x : Var) (c : EqCnstr) : DvdCnstrProof
- subst (x : Var) (c₁ : EqCnstr) (c₂ : DvdCnstr) : DvdCnstrProof
- cooper₁ (c : CooperSplit) : DvdCnstrProof
- cooper₂
(c : CooperSplit)
: DvdCnstrProof
c.c₃?must besome - reorder (c : DvdCnstr) : DvdCnstrProof
- commRingNorm (c : DvdCnstr) (e : CommRing.RingExpr) (p : CommRing.Poly) : DvdCnstrProof
Instances For
- core (e : Expr) : LeCnstrProof
- coreNeg (e : Expr) (p : Poly) : LeCnstrProof
- coreToInt (e : Expr) (pos : Bool) (toIntThm : Expr) (lhs rhs : Int.Linear.Expr) : LeCnstrProof
- ofNatNonneg (a : Expr) : LeCnstrProof
- bound (h : Expr) : LeCnstrProof
- dec (h : FVarId) : LeCnstrProof
- norm (c : LeCnstr) : LeCnstrProof
- divCoeffs (c : LeCnstr) : LeCnstrProof
- combine (c₁ c₂ : LeCnstr) : LeCnstrProof
- combineDivCoeffs (c₁ c₂ : LeCnstr) (k : Int) : LeCnstrProof
- subst (x : Var) (c₁ : EqCnstr) (c₂ : LeCnstr) : LeCnstrProof
- ofLeDiseq (c₁ : LeCnstr) (c₂ : DiseqCnstr) : LeCnstrProof
- ofDiseqSplit (c₁ : DiseqCnstr) (decVar : FVarId) (h : UnsatProof) (decVars : Array FVarId) : LeCnstrProof
- cooper (c : CooperSplit) : LeCnstrProof
- dvdTight (c₁ : DvdCnstr) (c₂ : LeCnstr) : LeCnstrProof
- negDvdTight (c₁ : DvdCnstr) (c₂ : LeCnstr) : LeCnstrProof
- reorder (c : LeCnstr) : LeCnstrProof
- commRingNorm (c : LeCnstr) (e : CommRing.RingExpr) (p : CommRing.Poly) : LeCnstrProof
Instances For
- core0
(a zero : Expr)
: DiseqCnstrProof
An disequality
a != 0coming from the core. That is,(a = 0) = Falsein the core. - core
(a b : Expr)
(p₁ p₂ : Poly)
: DiseqCnstrProof
An disequality
a ≠ bcoming from the core. That is,(a = b) = Falsein the core.p₁andp₂are the polynomials corresponding toaandb. - coreToInt (a b toIntThm : Expr) (lhs rhs : Int.Linear.Expr) : DiseqCnstrProof
- norm (c : DiseqCnstr) : DiseqCnstrProof
- divCoeffs (c : DiseqCnstr) : DiseqCnstrProof
- neg (c : DiseqCnstr) : DiseqCnstrProof
- subst (x : Var) (c₁ : EqCnstr) (c₂ : DiseqCnstr) : DiseqCnstrProof
- reorder (c : DiseqCnstr) : DiseqCnstrProof
- commRingNorm (c : DiseqCnstr) (e : CommRing.RingExpr) (p : CommRing.Poly) : DiseqCnstrProof
Instances For
A proof of False.
Remark: We will later add support for a backtracking search inside of cutsat.
- dvd (c : DvdCnstr) : UnsatProof
- le (c : LeCnstr) : UnsatProof
- eq (c : EqCnstr) : UnsatProof
- diseq (c : DiseqCnstr) : UnsatProof
- cooper (c₁ c₂ : LeCnstr) (c₃ : DvdCnstr) : UnsatProof
Instances For
Equations
- Lean.Meta.Grind.Arith.Cutsat.instInhabitedLeCnstr = { default := { p := Int.Linear.Poly.num 0, h := Lean.Meta.Grind.Arith.Cutsat.LeCnstrProof.core default } }
Equations
- Lean.Meta.Grind.Arith.Cutsat.instInhabitedDvdCnstr = { default := { d := 0, p := Int.Linear.Poly.num 0, h := Lean.Meta.Grind.Arith.Cutsat.DvdCnstrProof.core default } }
Equations
- Lean.Meta.Grind.Arith.Cutsat.instInhabitedCooperSplit = { default := { pred := default, k := 0, h := Lean.Meta.Grind.Arith.Cutsat.CooperSplitProof.dec default } }
Instances For
State of the cutsat procedure.
Mapping from variables to their denotations.
Mapping from
Exprto a variable representing it.varsbefore they were reordered. This array is empty if the variables were not reordered. We need them to generate the proof term because some justification objects contain terms using variables before the reordering.varMapbefore variables were reordered.The field
natToIntMapcontains a mapping from aNat-termeto the pair(e', he), wherehe : NatCast.natCast e = e'Some
Natvariables encode nested terms such asb+1. This is a mapping from this kind of variable to the integer variable representingnatCast (b+1).Mapping from variables to divisibility constraints. Recall that we keep the divisibility constraint in solved form. Thus, we have at most one divisibility per variable.
Mapping from variables to their "lower" bounds. We say a relational constraint
cis a lower bound for a variablexifxis the maximal variable inc, andxcoefficient incis negative.Mapping from variables to their "upper" bounds. We say a relational constraint
cis a upper bound for a variablexifxis the maximal variable inc, andxcoefficient incis positive.- diseqs : PArray (PArray DiseqCnstr)
Mapping from variables to their disequalities. We say a disequality constraint
cis a disequality for a variablexifxis the maximal variable inc. Mapping from variable to occurrences. For example, an entry
x ↦ {y, z}means thatxmay occur indvdCnstrs,lowers, oruppersof variablesyandz. Ifxoccurs indvdCnstrs[y],lowers[y], oruppers[y], thenyis inoccurs[x], but the reverse is not true. Ifxis inelimStack, thenoccurs[x]is the empty set.Partial assignment being constructed by cutsat.
- nextCnstrId : Nat
Next unique id for a constraint.
- caseSplits : Bool
caseSplitsistrueif cutsat is searching for model and already performed case splits. This information is used to decide whether a conflict should immediately close the currentgrindgoal or not. - conflict? : Option UnsatProof
conflict?issome ..if a contradictory constraint was derived. This field is only set whencaseSplitsistrue. Otherwise, we can convertUnsatProofinto a Lean term and close the currentgrindgoal. Cache decision variables used when splitting on disequalities. This is necessary because the same disequality may be in different conflicts.
Pairs
(x, n)s.t. we have expanded the theoremsMapping from a type
αto its correspondingToIntInfoobject idx intoInfos, which contains the information needed to embedαterms intoIntterms.- toIntTermMap : PHashMap ExprPtr ToIntTermInfo
For each type
αintoIntInfos, the mappingtoIntVarMapcontains a mapping from a α-termeto the pair(toInt e, α). Mapping from
a : α(whereToInt α) totoInt athat has been internalized. We use this information during model construction.- usedCommRing : Bool
usedCommRingistrueif theCommRinghas been used to normalize expressions.
Instances For
Equations
- One or more equations did not get rendered due to their size.