Documentation

Lean.Meta.Tactic.Grind.Arith.Cutsat.Types

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:

Constraint Types: We handle four categories of linear polynomial constraints (where p is a linear polynomial):

  1. Equality: p = 0
  2. Divisibility: d ∣ p
  3. Inequality: p ≤ 0
  4. Disequality: p ≠ 0

Implementation Details:

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:

Variable Assignment: When assigning a variable y, we consider:

Contradiction Handling:

Optimization: We employ rational approximation for model construction:

A equality constraint and its justification/proof.

Instances For
    Instances For

      A divisibility constraint and its justification/proof.

      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 (if left is true and c₃? is none)
        • cooper_right_split (if left is false and c₃? is none)
        • cooper_dvd_left_split (if left is true and c₃? is some)
        • cooper_dvd_right_split (if left is false and c₃? is some)

        See CooperSplit

        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).

          Instances For
            Instances For

              An inequality constraint and its justification/proof.

              Instances For
                Instances For

                  A disequality constraint and its justification/proof.

                  Instances For
                    Instances For

                      A proof of False. Remark: We will later add support for a backtracking search inside of cutsat.

                      Instances For
                        @[reducible, inline]
                        Instances For

                          State of the cutsat procedure.

                          • vars : PArray Expr

                            Mapping from variables to their denotations.

                          • Mapping from Expr to a variable representing it.

                          • Variable orders superseded by reorderVars, oldest first: entry i is the pair (vars, varMap) of epoch i, and the current order is epoch varsHistory.size. Justification objects created before a reordering contain polynomials in the order of their epoch, so proof generation needs every superseded order.

                          • natToIntMap : PHashMap ExprPtr (Expr × Expr)

                            The field natToIntMap contains a mapping from a Nat-term e to the pair (e', he), where he : NatCast.natCast e = e'

                          • Some Nat variables encode nested terms such as b+1. This is a mapping from this kind of variable to the integer variable representing natCast (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.

                          • lowers : PArray (PArray LeCnstr)

                            Mapping from variables to their "lower" bounds. We say a relational constraint c is a lower bound for a variable x if x is the maximal variable in c, and x coefficient in c is negative.

                          • uppers : PArray (PArray LeCnstr)

                            Mapping from variables to their "upper" bounds. We say a relational constraint c is a upper bound for a variable x if x is the maximal variable in c, and x coefficient in c is positive.

                          • Mapping from variables to their disequalities. We say a disequality constraint c is a disequality for a variable x if x is the maximal variable in c.

                          • elimEqs : PArray (Option EqCnstr)

                            Mapping from variable to equation constraint used to eliminate it. solved variables should not occur in dvdCnstrs, lowers, or uppers.

                          • elimStack : List Var

                            Elimination stack. For every variable in elimStack. If x in elimStack, then elimEqs[x] is not none.

                          • occurs : PArray VarSet

                            Mapping from variable to occurrences. For example, an entry x ↦ {y, z} means that x may occur in dvdCnstrs, lowers, or uppers of variables y and z. If x occurs in dvdCnstrs[y], lowers[y], or uppers[y], then y is in occurs[x], but the reverse is not true. If x is in elimStack, then occurs[x] is the empty set.

                          • assignment : PArray Rat

                            Partial assignment being constructed by cutsat.

                          • nextCnstrId : Nat

                            Next unique id for a constraint.

                          • caseSplits : Bool

                            caseSplits is true if cutsat is searching for model and already performed case splits. This information is used to decide whether a conflict should immediately close the current grind goal or not.

                          • steps : Nat

                            Cumulative number of steps performed by the model search. The model search is interrupted when this counter reaches the liaSteps configuration threshold, and the solver becomes incomplete.

                          • conflict? : Option UnsatProof

                            conflict? is some .. if a contradictory constraint was derived. This field is only set when caseSplits is true. Otherwise, we can convert UnsatProof into a Lean term and close the current grind goal.

                          • diseqSplits : PHashMap Poly FVarId

                            Cache decision variables used when splitting on disequalities. This is necessary because the same disequality may be in different conflicts.

                          • divMod : PHashSet (Expr × Int)
                          • usedCommRing : Bool

                            usedCommRing is true if the CommRing has been used to normalize expressions.

                          • nonlinearOccs : PHashMap Var (List Var)

                            Mapping from terms to variables representing nonlinear terms. For example, suppose the denotation of variable x is the nonlinear term a*b*c, and y is the nonlinear term a / d. Then the mapping contains the entries

                            • a ↦ [x, y]
                            • b ↦ [x]
                            • c ↦ [x]
                            • d ↦ [y]
                          Instances For