|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Leonardo de Moura |
| 5 | +-/ |
| 6 | +module |
| 7 | +prelude |
| 8 | +public import Init.Grind.Ordered.Ring |
| 9 | +import Init.Grind.Ring |
| 10 | +public section |
| 11 | +namespace Lean.Grind.Order |
| 12 | + |
| 13 | +/-! |
| 14 | +Helper theorems to assert constraints |
| 15 | +-/ |
| 16 | + |
| 17 | +theorem le_of_eq {α} [LE α] [Std.IsPreorder α] |
| 18 | + (a b : α) : a = b → a ≤ b := by |
| 19 | + intro h; subst a; apply Std.IsPreorder.le_refl |
| 20 | + |
| 21 | +theorem le_of_not_le {α} [LE α] [Std.IsLinearPreorder α] |
| 22 | + (a b : α) : ¬ a ≤ b → b ≤ a := by |
| 23 | + intro h |
| 24 | + have := Std.IsLinearPreorder.le_total a b |
| 25 | + cases this; contradiction; assumption |
| 26 | + |
| 27 | +theorem lt_of_not_le {α} [LE α] [LT α] [Std.IsLinearPreorder α] [Std.LawfulOrderLT α] |
| 28 | + (a b : α) : ¬ a ≤ b → b < a := by |
| 29 | + intro h |
| 30 | + rw [Std.LawfulOrderLT.lt_iff] |
| 31 | + have := Std.IsLinearPreorder.le_total a b |
| 32 | + cases this; contradiction; simp [*] |
| 33 | + |
| 34 | +theorem le_of_not_lt {α} [LE α] [LT α] [Std.IsLinearPreorder α] [Std.LawfulOrderLT α] |
| 35 | + (a b : α) : ¬ a < b → b ≤ a := by |
| 36 | + rw [Std.LawfulOrderLT.lt_iff] |
| 37 | + open Classical in |
| 38 | + rw [Classical.not_and_iff_not_or_not, Classical.not_not] |
| 39 | + intro h; cases h |
| 40 | + next => |
| 41 | + have := Std.IsLinearPreorder.le_total a b |
| 42 | + cases this; contradiction; assumption |
| 43 | + next => assumption |
| 44 | + |
| 45 | +theorem int_lt (x y k : Int) : x < y + k → x ≤ y + (k-1) := by |
| 46 | + omega |
| 47 | + |
| 48 | +/-! |
| 49 | +Helper theorem for equality propagation |
| 50 | +-/ |
| 51 | + |
| 52 | +theorem eq_of_le_of_le {α} [LE α] [Std.IsPartialOrder α] {a b : α} : a ≤ b → b ≤ a → a = b := |
| 53 | + Std.IsPartialOrder.le_antisymm _ _ |
| 54 | + |
| 55 | +/-! |
| 56 | +Transitivity |
| 57 | +-/ |
| 58 | + |
| 59 | +theorem le_trans {α} [LE α] [Std.IsPreorder α] {a b c : α} (h₁ : a ≤ b) (h₂ : b ≤ c) : a ≤ c := |
| 60 | + Std.IsPreorder.le_trans _ _ _ h₁ h₂ |
| 61 | + |
| 62 | +theorem lt_trans {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] {a b c : α} (h₁ : a < b) (h₂ : b < c) : a < c := |
| 63 | + Preorder.lt_trans h₁ h₂ |
| 64 | + |
| 65 | +theorem le_lt_trans {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] {a b c : α} (h₁ : a ≤ b) (h₂ : b < c) : a < c := |
| 66 | + Preorder.lt_of_le_of_lt h₁ h₂ |
| 67 | + |
| 68 | +theorem lt_le_trans {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] {a b c : α} (h₁ : a < b) (h₂ : b ≤ c) : a < c := |
| 69 | + Preorder.lt_of_lt_of_le h₁ h₂ |
| 70 | + |
| 71 | +theorem lt_unsat {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] (a : α) : a < a → False := |
| 72 | + Preorder.lt_irrefl a |
| 73 | + |
| 74 | +/-! |
| 75 | +Transitivity with offsets |
| 76 | +-/ |
| 77 | + |
| 78 | +attribute [local instance] Ring.intCast |
| 79 | + |
| 80 | +theorem le_trans_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 81 | + (a b c : α) (k₁ k₂ k : Int) (h₁ : a ≤ b + k₁) (h₂ : b ≤ c + k₂) : k == k₂ + k₁ → a ≤ c + k := by |
| 82 | + intro h; simp at h; subst k |
| 83 | + replace h₂ := OrderedAdd.add_le_left_iff (M := α) k₁ |>.mp h₂ |
| 84 | + have := le_trans h₁ h₂ |
| 85 | + simp [Ring.intCast_add, ← Semiring.add_assoc, this] |
| 86 | + |
| 87 | +theorem lt_trans_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 88 | + (a b c : α) (k₁ k₂ k : Int) (h₁ : a < b + k₁) (h₂ : b < c + k₂) : k == k₂ + k₁ → a < c + k := by |
| 89 | + intro h; simp at h; subst k |
| 90 | + replace h₂ := OrderedAdd.add_lt_left_iff (M := α) k₁ |>.mp h₂ |
| 91 | + have := lt_trans h₁ h₂ |
| 92 | + simp [Ring.intCast_add, ← Semiring.add_assoc, this] |
| 93 | + |
| 94 | +theorem le_lt_trans_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 95 | + (a b c : α) (k₁ k₂ k : Int) (h₁ : a ≤ b + k₁) (h₂ : b < c + k₂) : k == k₂ + k₁ → a < c + k := by |
| 96 | + intro h; simp at h; subst k |
| 97 | + replace h₂ := OrderedAdd.add_lt_left_iff (M := α) k₁ |>.mp h₂ |
| 98 | + have := le_lt_trans h₁ h₂ |
| 99 | + simp [Ring.intCast_add, ← Semiring.add_assoc, this] |
| 100 | + |
| 101 | +theorem lt_le_trans_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 102 | + (a b c : α) (k₁ k₂ k : Int) (h₁ : a < b + k₁) (h₂ : b ≤ c + k₂) : k == k₂ + k₁ → a < c + k := by |
| 103 | + intro h; simp at h; subst k |
| 104 | + replace h₂ := OrderedAdd.add_le_left_iff (M := α) k₁ |>.mp h₂ |
| 105 | + have := lt_le_trans h₁ h₂ |
| 106 | + simp [Ring.intCast_add, ← Semiring.add_assoc, this] |
| 107 | + |
| 108 | +/-! |
| 109 | +Unsat detection |
| 110 | +-/ |
| 111 | + |
| 112 | +theorem le_unsat_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 113 | + (a : α) (k : Int) : k.blt' 0 → a ≤ a + k → False := by |
| 114 | + simp; intro h₁ h₂ |
| 115 | + replace h₂ := OrderedAdd.add_le_left_iff (-a) |>.mp h₂ |
| 116 | + rw [AddCommGroup.add_neg_cancel, Semiring.add_assoc, Semiring.add_comm _ (-a)] at h₂ |
| 117 | + rw [← Semiring.add_assoc, AddCommGroup.add_neg_cancel, Semiring.add_comm, Semiring.add_zero] at h₂ |
| 118 | + rw [← Ring.intCast_zero] at h₂ |
| 119 | + replace h₂ := OrderedRing.le_of_intCast_le_intCast _ _ h₂ |
| 120 | + omega |
| 121 | + |
| 122 | +theorem lt_unsat_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 123 | + (a : α) (k : Int) : k.ble' 0 → a < a + k → False := by |
| 124 | + simp; intro h₁ h₂ |
| 125 | + replace h₂ := OrderedAdd.add_lt_left_iff (-a) |>.mp h₂ |
| 126 | + rw [AddCommGroup.add_neg_cancel, Semiring.add_assoc, Semiring.add_comm _ (-a)] at h₂ |
| 127 | + rw [← Semiring.add_assoc, AddCommGroup.add_neg_cancel, Semiring.add_comm, Semiring.add_zero] at h₂ |
| 128 | + rw [← Ring.intCast_zero] at h₂ |
| 129 | + replace h₂ := OrderedRing.lt_of_intCast_lt_intCast _ _ h₂ |
| 130 | + omega |
| 131 | + |
| 132 | +/-! |
| 133 | +Helper theorems |
| 134 | +-/ |
| 135 | + |
| 136 | +private theorem add_lt_add_of_le_of_lt {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 137 | + {a b c d : α} (hab : a ≤ b) (hcd : c < d) : a + c < b + d := |
| 138 | + lt_le_trans (OrderedAdd.add_lt_right a hcd) (OrderedAdd.add_le_left hab d) |
| 139 | + |
| 140 | +private theorem add_lt_add_of_lt_of_le {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 141 | + {a b c d : α} (hab : a < b) (hcd : c ≤ d) : a + c < b + d := |
| 142 | + le_lt_trans (OrderedAdd.add_le_right a hcd) (OrderedAdd.add_lt_left hab d) |
| 143 | + |
| 144 | +/-! Theorems for propagating constraints to `True` -/ |
| 145 | + |
| 146 | +theorem le_eq_true_of_le_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 147 | + (a b : α) (k₁ k₂ : Int) : k₁.ble' k₂ → a ≤ b + k₁ → (a ≤ b + k₂) = True := by |
| 148 | + simp; intro h₁ h₂ |
| 149 | + replace h₁ : 0 ≤ k₂ - k₁ := by omega |
| 150 | + replace h₁ := OrderedRing.nonneg_intCast_of_nonneg (R := α) _ h₁ |
| 151 | + replace h₁ := OrderedAdd.add_le_add h₂ h₁ |
| 152 | + rw [Semiring.add_zero, Semiring.add_assoc, Int.sub_eq_add_neg, Int.add_comm] at h₁ |
| 153 | + rw [Ring.intCast_add, Ring.intCast_neg, ← Semiring.add_assoc (k₁ : α)] at h₁ |
| 154 | + rw [AddCommGroup.add_neg_cancel, Semiring.add_comm 0, Semiring.add_zero] at h₁ |
| 155 | + assumption |
| 156 | + |
| 157 | +theorem le_eq_true_of_lt_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 158 | + (a b : α) (k₁ k₂ : Int) : k₁.ble' k₂ → a < b + k₁ → (a ≤ b + k₂) = True := by |
| 159 | + intro h₁ h₂ |
| 160 | + replace h₂ := Std.le_of_lt h₂ |
| 161 | + apply le_eq_true_of_le_k <;> assumption |
| 162 | + |
| 163 | +theorem lt_eq_true_of_lt_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 164 | + (a b : α) (k₁ k₂ : Int) : k₁.ble' k₂ → a < b + k₁ → (a < b + k₂) = True := by |
| 165 | + simp; intro h₁ h₂ |
| 166 | + replace h₁ : 0 ≤ k₂ - k₁ := by omega |
| 167 | + replace h₁ := OrderedRing.nonneg_intCast_of_nonneg (R := α) _ h₁ |
| 168 | + replace h₁ := add_lt_add_of_le_of_lt h₁ h₂ |
| 169 | + rw [Semiring.add_comm, Semiring.add_zero, Semiring.add_comm, Semiring.add_assoc, Int.sub_eq_add_neg, Int.add_comm] at h₁ |
| 170 | + rw [Ring.intCast_add, Ring.intCast_neg, ← Semiring.add_assoc (k₁ : α)] at h₁ |
| 171 | + rw [AddCommGroup.add_neg_cancel, Semiring.add_comm 0, Semiring.add_zero] at h₁ |
| 172 | + assumption |
| 173 | + |
| 174 | +theorem lt_eq_true_of_le_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 175 | + (a b : α) (k₁ k₂ : Int) : k₁.blt' k₂ → a ≤ b + k₁ → (a < b + k₂) = True := by |
| 176 | + simp; intro h₁ h₂ |
| 177 | + replace h₁ : 0 < k₂ - k₁ := by omega |
| 178 | + replace h₁ := OrderedRing.pos_intCast_of_pos (R := α) _ h₁ |
| 179 | + replace h₁ := add_lt_add_of_le_of_lt h₂ h₁ |
| 180 | + rw [Semiring.add_zero, Semiring.add_assoc, Int.sub_eq_add_neg, Int.add_comm] at h₁ |
| 181 | + rw [Ring.intCast_add, Ring.intCast_neg, ← Semiring.add_assoc (k₁ : α)] at h₁ |
| 182 | + rw [AddCommGroup.add_neg_cancel, Semiring.add_comm 0, Semiring.add_zero] at h₁ |
| 183 | + assumption |
| 184 | + |
| 185 | +/-! Theorems for propagating constraints to `False` -/ |
| 186 | + |
| 187 | +theorem le_eq_false_of_le_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 188 | + (a b : α) (k₁ k₂ : Int) : (k₂ + k₁).blt' 0 → a ≤ b + k₁ → (b ≤ a + k₂) = False := by |
| 189 | + intro h₁; simp; intro h₂ h₃ |
| 190 | + have h := le_trans_k _ _ _ _ _ (k₂ + k₁) h₂ h₃ |
| 191 | + simp at h |
| 192 | + apply le_unsat_k _ _ h₁ h |
| 193 | + |
| 194 | +theorem lt_eq_false_of_le_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 195 | + (a b : α) (k₁ k₂ : Int) : (k₂ + k₁).ble' 0 → a ≤ b + k₁ → (b < a + k₂) = False := by |
| 196 | + intro h₁; simp; intro h₂ h₃ |
| 197 | + have h := le_lt_trans_k _ _ _ _ _ (k₂ + k₁) h₂ h₃ |
| 198 | + simp at h |
| 199 | + apply lt_unsat_k _ _ h₁ h |
| 200 | + |
| 201 | +theorem lt_eq_false_of_lt_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 202 | + (a b : α) (k₁ k₂ : Int) : (k₂ + k₁).ble' 0 → a < b + k₁ → (b < a + k₂) = False := by |
| 203 | + intro h₁; simp; intro h₂ h₃ |
| 204 | + have h := lt_trans_k _ _ _ _ _ (k₂ + k₁) h₂ h₃ |
| 205 | + simp at h |
| 206 | + apply lt_unsat_k _ _ h₁ h |
| 207 | + |
| 208 | +theorem le_eq_false_of_lt_k {α} [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α] |
| 209 | + (a b : α) (k₁ k₂ : Int) : (k₂ + k₁).ble' 0 → a < b + k₁ → (b ≤ a + k₂) = False := by |
| 210 | + intro h₁; simp; intro h₂ h₃ |
| 211 | + have h := lt_le_trans_k _ _ _ _ _ (k₂ + k₁) h₂ h₃ |
| 212 | + simp at h |
| 213 | + apply lt_unsat_k _ _ h₁ h |
| 214 | + |
| 215 | +end Lean.Grind.Order |
0 commit comments