@@ -7,159 +7,44 @@ prelude
7
7
import Init.Core
8
8
import Init.Omega
9
9
10
- namespace Lean.Grind.Offset
11
-
12
- abbrev Var := Nat
13
- abbrev Context := Lean.RArray Nat
14
-
15
- def fixedVar := 100000000 -- Any big number should work here
16
-
17
- def Var.denote (ctx : Context) (v : Var) : Nat :=
18
- bif v == fixedVar then 1 else ctx.get v
19
-
20
- structure Cnstr where
21
- x : Var
22
- y : Var
23
- k : Nat := 0
24
- l : Bool := true
25
- deriving Repr, DecidableEq, Inhabited
26
-
27
- def Cnstr.denote (c : Cnstr) (ctx : Context) : Prop :=
28
- if c.l then
29
- c.x.denote ctx + c.k ≤ c.y.denote ctx
30
- else
31
- c.x.denote ctx ≤ c.y.denote ctx + c.k
32
-
33
- def trivialCnstr : Cnstr := { x := 0 , y := 0 , k := 0 , l := true }
34
-
35
- @[simp] theorem denote_trivial (ctx : Context) : trivialCnstr.denote ctx := by
36
- simp [Cnstr.denote, trivialCnstr]
37
-
38
- def Cnstr.trans (c₁ c₂ : Cnstr) : Cnstr :=
39
- if c₁.y = c₂.x then
40
- let { x, k := k₁, l := l₁, .. } := c₁
41
- let { y, k := k₂, l := l₂, .. } := c₂
42
- match l₁, l₂ with
43
- | false , false =>
44
- { x, y, k := k₁ + k₂, l := false }
45
- | false , true =>
46
- if k₁ < k₂ then
47
- { x, y, k := k₂ - k₁, l := true }
48
- else
49
- { x, y, k := k₁ - k₂, l := false }
50
- | true , false =>
51
- if k₁ < k₂ then
52
- { x, y, k := k₂ - k₁, l := false }
53
- else
54
- { x, y, k := k₁ - k₂, l := true }
55
- | true , true =>
56
- { x, y, k := k₁ + k₂, l := true }
57
- else
58
- trivialCnstr
59
-
60
- @[simp] theorem Cnstr.denote_trans_easy (ctx : Context) (c₁ c₂ : Cnstr) (h : c₁.y ≠ c₂.x) : (c₁.trans c₂).denote ctx := by
61
- simp [*, Cnstr.trans]
62
-
63
- @[simp] theorem Cnstr.denote_trans (ctx : Context) (c₁ c₂ : Cnstr) : c₁.denote ctx → c₂.denote ctx → (c₁.trans c₂).denote ctx := by
64
- by_cases c₁.y = c₂.x
65
- case neg => simp [*]
66
- simp [trans, *]
67
- let { x, k := k₁, l := l₁, .. } := c₁
68
- let { y, k := k₂, l := l₂, .. } := c₂
69
- simp_all; split
70
- · simp [denote]; omega
71
- · split <;> simp [denote] <;> omega
72
- · split <;> simp [denote] <;> omega
73
- · simp [denote]; omega
74
-
75
- def Cnstr.isTrivial (c : Cnstr) : Bool := c.x == c.y && c.k == 0
76
-
77
- theorem Cnstr.of_isTrivial (ctx : Context) (c : Cnstr) : c.isTrivial = true → c.denote ctx := by
78
- cases c; simp [isTrivial]; intros; simp [*, denote]
79
-
80
- def Cnstr.isFalse (c : Cnstr) : Bool := c.x == c.y && c.k != 0 && c.l == true
81
-
82
- theorem Cnstr.of_isFalse (ctx : Context) {c : Cnstr} : c.isFalse = true → ¬c.denote ctx := by
83
- cases c; simp [isFalse]; intros; simp [*, denote]; omega
84
-
85
- def Cnstrs := List Cnstr
86
-
87
- def Cnstrs.denoteAnd' (ctx : Context) (c₁ : Cnstr) (c₂ : Cnstrs) : Prop :=
88
- match c₂ with
89
- | [] => c₁.denote ctx
90
- | c::cs => c₁.denote ctx ∧ Cnstrs.denoteAnd' ctx c cs
91
-
92
- theorem Cnstrs.denote'_trans (ctx : Context) (c₁ c : Cnstr) (cs : Cnstrs) : c₁.denote ctx → denoteAnd' ctx c cs → denoteAnd' ctx (c₁.trans c) cs := by
93
- induction cs
94
- next => simp [denoteAnd', *]; apply Cnstr.denote_trans
95
- next c cs ih => simp [denoteAnd']; intros; simp [*]
96
-
97
- def Cnstrs.trans' (c₁ : Cnstr) (c₂ : Cnstrs) : Cnstr :=
98
- match c₂ with
99
- | [] => c₁
100
- | c::c₂ => trans' (c₁.trans c) c₂
101
-
102
- @[simp] theorem Cnstrs.denote'_trans' (ctx : Context) (c₁ : Cnstr) (c₂ : Cnstrs) : denoteAnd' ctx c₁ c₂ → (trans' c₁ c₂).denote ctx := by
103
- induction c₂ generalizing c₁
104
- next => intros; simp_all [trans', denoteAnd']
105
- next c cs ih => simp [denoteAnd']; intros; simp [trans']; apply ih; apply denote'_trans <;> assumption
106
-
107
- def Cnstrs.denoteAnd (ctx : Context) (c : Cnstrs) : Prop :=
108
- match c with
109
- | [] => True
110
- | c::cs => denoteAnd' ctx c cs
111
-
112
- def Cnstrs.trans (c : Cnstrs) : Cnstr :=
113
- match c with
114
- | [] => trivialCnstr
115
- | c::cs => trans' c cs
116
-
117
- theorem Cnstrs.of_denoteAnd_trans {ctx : Context} {c : Cnstrs} : c.denoteAnd ctx → c.trans.denote ctx := by
118
- cases c <;> simp [*, trans, denoteAnd] <;> intros <;> simp [*]
119
-
120
- def Cnstrs.isFalse (c : Cnstrs) : Bool :=
121
- c.trans.isFalse
122
-
123
- theorem Cnstrs.unsat' (ctx : Context) (c : Cnstrs) : c.isFalse = true → ¬ c.denoteAnd ctx := by
124
- simp [isFalse]; intro h₁ h₂
125
- have := of_denoteAnd_trans h₂
126
- have := Cnstr.of_isFalse ctx h₁
127
- contradiction
128
-
129
- /-- `denote ctx [c_1, ..., c_n] C` is `c_1.denote ctx → ... → c_n.denote ctx → C` -/
130
- def Cnstrs.denote (ctx : Context) (cs : Cnstrs) (C : Prop ) : Prop :=
131
- match cs with
132
- | [] => C
133
- | c::cs => c.denote ctx → denote ctx cs C
134
-
135
- theorem Cnstrs.not_denoteAnd'_eq (ctx : Context) (c : Cnstr) (cs : Cnstrs) (C : Prop ) : (denoteAnd' ctx c cs → C) = denote ctx (c::cs) C := by
136
- simp [denote]
137
- induction cs generalizing c
138
- next => simp [denoteAnd', denote]
139
- next c' cs ih =>
140
- simp [denoteAnd', denote, *]
141
-
142
- theorem Cnstrs.not_denoteAnd_eq (ctx : Context) (cs : Cnstrs) (C : Prop ) : (denoteAnd ctx cs → C) = denote ctx cs C := by
143
- cases cs
144
- next => simp [denoteAnd, denote]
145
- next c cs => apply not_denoteAnd'_eq
146
-
147
- def Cnstr.isImpliedBy (cs : Cnstrs) (c : Cnstr) : Bool :=
148
- cs.trans == c
149
-
150
- /-! Main theorems used by `grind`. -/
151
-
152
- /-- Auxiliary theorem used by `grind` to prove that a system of offset inequalities is unsatisfiable. -/
153
- theorem Cnstrs.unsat (ctx : Context) (cs : Cnstrs) : cs.isFalse = true → cs.denote ctx False := by
154
- intro h
155
- rw [← not_denoteAnd_eq]
156
- apply unsat'
157
- assumption
158
-
159
- /-- Auxiliary theorem used by `grind` to prove an implied offset inequality. -/
160
- theorem Cnstrs.imp (ctx : Context) (cs : Cnstrs) (c : Cnstr) (h : c.isImpliedBy cs = true ) : cs.denote ctx (c.denote ctx) := by
161
- rw [← eq_of_beq h]
162
- rw [← not_denoteAnd_eq]
163
- apply of_denoteAnd_trans
164
-
165
- end Lean.Grind.Offset
10
+ namespace Lean.Grind
11
+ def isLt (x y : Nat) : Bool := x < y
12
+
13
+ theorem Nat.le_ro (u w v k : Nat) : u ≤ w → w ≤ v + k → u ≤ v + k := by
14
+ omega
15
+ theorem Nat.le_lo (u w v k : Nat) : u ≤ w → w + k ≤ v → u + k ≤ v := by
16
+ omega
17
+ theorem Nat.lo_le (u w v k : Nat) : u + k ≤ w → w ≤ v → u + k ≤ v := by
18
+ omega
19
+ theorem Nat.lo_lo (u w v k₁ k₂ : Nat) : u + k₁ ≤ w → w + k₂ ≤ v → u + (k₁ + k₂) ≤ v := by
20
+ omega
21
+ theorem Nat.lo_ro_1 (u w v k₁ k₂ : Nat) : isLt k₂ k₁ = true → u + k₁ ≤ w → w ≤ v + k₂ → u + (k₁ - k₂) ≤ v := by
22
+ simp [isLt]; omega
23
+ theorem Nat.lo_ro_2 (u w v k₁ k₂ : Nat) : u + k₁ ≤ w → w ≤ v + k₂ → u ≤ v + (k₂ - k₁) := by
24
+ omega
25
+ theorem Nat.ro_le (u w v k : Nat) : u ≤ w + k → w ≤ v → u ≤ v + k := by
26
+ omega
27
+ theorem Nat.ro_lo_1 (u w v k₁ k₂ : Nat) : u ≤ w + k₁ → w + k₂ ≤ v → u ≤ v + (k₁ - k₂) := by
28
+ omega
29
+ theorem Nat.ro_lo_2 (u w v k₁ k₂ : Nat) : isLt k₁ k₂ = true → u ≤ w + k₁ → w + k₂ ≤ v → u + (k₂ - k₁) ≤ v := by
30
+ simp [isLt]; omega
31
+ theorem Nat.ro_ro (u w v k₁ k₂ : Nat) : u ≤ w + k₁ → w ≤ v + k₂ → u ≤ v + (k₁ + k₂) := by
32
+ omega
33
+
34
+ theorem Nat.of_le_eq_false (u v : Nat) : ((u ≤ v) = False) → v + 1 ≤ u := by
35
+ simp; omega
36
+ theorem Nat.of_lo_eq_false_1 (u v : Nat) : ((u + 1 ≤ v) = False) → v ≤ u := by
37
+ simp; omega
38
+ theorem Nat.of_lo_eq_false (u v k : Nat) : ((u + k ≤ v) = False) → v ≤ u + (k-1 ) := by
39
+ simp; omega
40
+ theorem Nat.of_ro_eq_false (u v k : Nat) : ((u ≤ v + k) = False) → v + (k+1 ) ≤ u := by
41
+ simp; omega
42
+
43
+ theorem Nat.unsat_le_lo (u v k : Nat) : isLt 0 k = true → u ≤ v → v + k ≤ u → False := by
44
+ simp [isLt]; omega
45
+ theorem Nat.unsat_lo_lo (u v k₁ k₂ : Nat) : isLt 0 (k₁+k₂) = true → u + k₁ ≤ v → v + k₂ ≤ u → False := by
46
+ simp [isLt]; omega
47
+ theorem Nat.unsat_lo_ro (u v k₁ k₂ : Nat) : isLt k₂ k₁ = true → u + k₁ ≤ v → v ≤ u + k₂ → False := by
48
+ simp [isLt]; omega
49
+
50
+ end Lean.Grind
0 commit comments