This PR implements several modifications for the cutsat procedure in `grind`. - The maximal variable is now at the beginning of linear polynomials. - The old `LinearArith.Solver` was deleted, and the normalizer was moved to `Simp`. - cutsat first files were created, and basic infrastructure for representing divisibility constraints was added.
85 lines
2.7 KiB
Text
85 lines
2.7 KiB
Text
import Lean
|
|
|
|
open Int.Linear
|
|
|
|
-- Convenient RArray literals
|
|
elab tk:"#R[" ts:term,* "]" : term => do
|
|
let ts : Array Lean.Syntax := ts
|
|
let es ← ts.mapM fun stx => Lean.Elab.Term.elabTerm stx none
|
|
if h : 0 < es.size then
|
|
return (Lean.RArray.toExpr (← Lean.Meta.inferType es[0]!) id (Lean.RArray.ofArray es h))
|
|
else
|
|
throwErrorAt tk "RArray cannot be empty"
|
|
|
|
example (x₁ x₂ : Int) :
|
|
Expr.denote #R[x₁, x₂] (.add (.add (.var 0) (.var 1)) (.num 3))
|
|
=
|
|
x₁ + x₂ + 3 :=
|
|
rfl
|
|
|
|
example (x₁ x₂ : Int) :
|
|
Poly.denote #R[x₁, x₂] (.add 1 0 (.add 3 1 (.num 4)))
|
|
=
|
|
1 * x₁ + ((3 * x₂) + 4) :=
|
|
rfl
|
|
|
|
example (x₁ x₂ : Int) :
|
|
Expr.denote #R[x₁, x₂] (.sub (.add (.mulR (.var 0) 4) (.mulL 2 (.var 1))) (.num 3))
|
|
=
|
|
(x₁*4) + 2*x₂ - 3 :=
|
|
rfl
|
|
|
|
example :
|
|
Expr.toPoly (.add (.add (.var 1) (.var 1)) (.num 3))
|
|
=
|
|
Expr.toPoly (.add (.num 3) (.mulL 2 (.var 1))) :=
|
|
rfl
|
|
|
|
example :
|
|
Expr.toPoly (.add (.add (.add (.var 1) (.var 1)) (.num 3)) (.var 2))
|
|
=
|
|
Expr.toPoly (.add (.add (.num 3) (.var 2)) (.mulL 2 (.var 1))) :=
|
|
rfl
|
|
|
|
example (x₁ x₂ x₃ : Int) :
|
|
RawRelCnstr.denote #R[x₁, x₂, x₃] (.eq (.sub (.add (.mulR (.var 0) 4) (.mulL 2 (.var 1))) (.num 3)) (.sub (.var 1) (.var 2)))
|
|
=
|
|
((x₁*4) + 2*x₂ - 3 = x₂ - x₃) :=
|
|
rfl
|
|
|
|
example :
|
|
RawRelCnstr.norm (.eq (.sub (.add (.mulR (.var 0) 4) (.mulL 2 (.var 1))) (.num 3)) (.sub (.var 1) (.var 2)))
|
|
=
|
|
RawRelCnstr.norm (.eq (.add (.var 2) (.add (.var 1) (.add (.mulL 4 (.var 0)) (.num (-3))))) (.num 0)) :=
|
|
rfl
|
|
|
|
example (x₁ x₂ x₃ : Int) : (x₁ + x₂) + (x₂ + x₃) = x₃ + 2*x₂ + x₁ :=
|
|
Expr.eq_of_toPoly_eq #R[x₁, x₂, x₃]
|
|
(Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
|
|
(Expr.add (Expr.add (Expr.var 2) (Expr.mulL 2 (Expr.var 1))) (Expr.var 0))
|
|
rfl
|
|
|
|
example :
|
|
RawRelCnstr.norm
|
|
(.eq (Expr.add (Expr.add (Expr.var 0) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 2)))
|
|
(Expr.add (Expr.var 2) (Expr.var 1)))
|
|
=
|
|
RawRelCnstr.norm
|
|
(.eq (Expr.add (Expr.var 0) (Expr.var 1))
|
|
(Expr.num 0))
|
|
:=
|
|
rfl
|
|
|
|
example (x₁ x₂ x₃ : Int) : ((x₁ + x₂) + (x₂ + x₃) = x₃ + x₂) = (x₁ + x₂ = 0) :=
|
|
RawRelCnstr.eq_of_norm_eq #R[x₃, x₂, x₁]
|
|
(.eq (Expr.add (Expr.add (Expr.var 2) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 0)))
|
|
(Expr.add (Expr.var 0) (Expr.var 1)))
|
|
(.eq (.add 1 2 (.add 1 1 (.num 0))))
|
|
rfl
|
|
|
|
example (x₁ x₂ x₃ : Int) : ((x₁ + x₂) + (x₂ + x₃) ≤ x₃ + x₂) = (x₁ + x₂ ≤ 0) :=
|
|
RawRelCnstr.eq_of_norm_eq #R[x₃, x₂, x₁]
|
|
(.le (Expr.add (Expr.add (Expr.var 2) (Expr.var 1)) (Expr.add (Expr.var 1) (Expr.var 0)))
|
|
(Expr.add (Expr.var 0) (Expr.var 1)))
|
|
(.le (Poly.add 1 2 (.add 1 1 (.num 0))))
|
|
rfl
|