This PR implements support for positive constraints in `grind order`.
The new module can already solve problems such as:
```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
(a b c : α) : a ≤ b → b ≤ c → c < a → False := by
grind
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
(a b c d : α) : a ≤ b → b ≤ c → c < d → d ≤ a → False := by
grind
example [LE α] [Std.IsPreorder α]
(a b c : α) : a ≤ b → b ≤ c → a ≤ c := by
grind
example [LE α] [Std.IsPreorder α]
(a b c d : α) : a ≤ b → b ≤ c → c ≤ d → a ≤ d := by
grind
```
It also generalizes support for offset constraints in `grind` to rings.
The new module implements theory propagation and reduces the number of
case splits required to solve problems:
```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α]
(a b : α) : a ≤ 5 → b ≤ 8 → a > 6 ∨ b > 10 → False := by
grind -linarith (splits := 0)
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [CommRing α] [OrderedRing α]
(a b c : α) : a + b*c + 2*c ≤ 5 → a + c > 5 - c - c*b → False := by
grind -linarith (splits := 0)
example (a b : Int) (h : a + b > 5) : (if a + b ≤ 0 then b else a) = a := by
grind -linarith -cutsat (splits := 0)
```
We still need to implement support for negated constraints.
33 lines
1.9 KiB
Text
33 lines
1.9 KiB
Text
module
|
||
/--
|
||
trace: [grind.debug.proof] fun h h_1 h_2 h_3 h_4 h_5 h_6 h_7 h_8 =>
|
||
let ctx := RArray.branch 1 (RArray.leaf One.one) (RArray.leaf (f 2));
|
||
let p_1 := Poly.nil;
|
||
let p_2 := Poly.add 1 1 Poly.nil;
|
||
let p_3 := Poly.add 1 0 Poly.nil;
|
||
let p_4 := Poly.add (-1) 1 (Poly.add 1 0 Poly.nil);
|
||
let p_5 := Poly.add (-1) 0 Poly.nil;
|
||
let e_1 := (Expr.intMul 1 (Expr.var 1)).add (Expr.intMul 0 (Expr.var 0));
|
||
let e_2 := Expr.zero;
|
||
let e_3 := (Expr.intMul (-1) (Expr.var 1)).add (Expr.intMul 1 (Expr.var 0));
|
||
let rctx := RArray.leaf (f 2);
|
||
let rp_1 := CommRing.Poly.add 1 (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 0);
|
||
let rp_2 := CommRing.Poly.add (-1) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 1);
|
||
let re_1 := CommRing.Expr.var 0;
|
||
let re_2 := CommRing.Expr.num 0;
|
||
let re_3 := ((CommRing.Expr.num 1).neg.mul (CommRing.Expr.var 0)).add (CommRing.Expr.num 1);
|
||
lt_unsat ctx
|
||
(le_lt_combine ctx p_3 p_5 p_1 (eagerReduce (Eq.refl true))
|
||
(le_le_combine ctx p_4 p_2 p_3 (eagerReduce (Eq.refl true))
|
||
(le_norm ctx e_3 e_2 p_4 (eagerReduce (Eq.refl true))
|
||
(CommRing.le_norm rctx re_3 re_2 rp_2 (eagerReduce (Eq.refl true)) h_8))
|
||
(le_norm ctx e_1 e_2 p_2 (eagerReduce (Eq.refl true))
|
||
(CommRing.le_norm rctx re_1 re_2 rp_1 (eagerReduce (Eq.refl true)) h_1)))
|
||
(zero_lt_one ctx p_5 (eagerReduce (Eq.refl true)) (Eq.refl One.one)))
|
||
-/
|
||
#guard_msgs in
|
||
open Std Lean Grind Linarith in
|
||
set_option trace.grind.debug.proof true in -- Context should contain only `f 2` and `One`
|
||
example [CommRing α] [LE α] [LT α] [LawfulOrderLT α] [IsLinearOrder α] [OrderedRing α] (f : Nat → α) :
|
||
f 1 <= 0 → f 2 <= 0 → f 3 <= 0 → f 4 <= 0 → f 5 <= 0 → f 6 <= 0 → f 7 <= 0 → f 8 <= 0 → -1 * f 2 + 1 <= 0 → False := by
|
||
grind -order
|