|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Damiano Testa. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Damiano Testa |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module canonically_ordered_comm_semiring_two_mul |
| 7 | +! leanprover-community/mathlib commit 328375597f2c0dd00522d9c2e5a33b6a6128feeb |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Data.ZMod.Basic |
| 12 | +import Mathlib.RingTheory.Subsemiring.Basic |
| 13 | +import Mathlib.Algebra.Order.Monoid.Basic |
| 14 | + |
| 15 | +/-! |
| 16 | +
|
| 17 | +A `CanonicallyOrderedCommSemiring` with two different elements `a` and `b` such that |
| 18 | +`a ≠ b` and `2 * a = 2 * b`. Thus, multiplication by a fixed non-zero element of a canonically |
| 19 | +ordered semiring need not be injective. In particular, multiplying by a strictly positive element |
| 20 | +need not be strictly monotone. |
| 21 | +
|
| 22 | +Recall that a `CanonicallyOrderedCommSemiring` is a commutative semiring with a partial ordering |
| 23 | +that is "canonical" in the sense that the inequality `a ≤ b` holds if and only if there is a `c` |
| 24 | +such that `a + c = b`. There are several compatibility conditions among addition/multiplication |
| 25 | +and the order relation. The point of the counterexample is to show that monotonicity of |
| 26 | +multiplication cannot be strengthened to **strict** monotonicity. |
| 27 | +
|
| 28 | +Reference: |
| 29 | +https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/canonically_ordered.20pathology |
| 30 | +-/ |
| 31 | + |
| 32 | + |
| 33 | +set_option linter.uppercaseLean3 false |
| 34 | + |
| 35 | +namespace Counterexample |
| 36 | + |
| 37 | +namespace FromBhavik |
| 38 | + |
| 39 | +/-- Bhavik Mehta's example. There are only the initial definitions, but no proofs. The Type |
| 40 | +`K` is a canonically ordered commutative semiring with the property that `2 * (1/2) ≤ 2 * 1`, even |
| 41 | +though it is not true that `1/2 ≤ 1`, since `1/2` and `1` are not comparable. -/ |
| 42 | +def K : Type := |
| 43 | + Subsemiring.closure ({1.5} : Set ℚ) |
| 44 | +deriving CommSemiring |
| 45 | +#align counterexample.from_Bhavik.K Counterexample.FromBhavik.K |
| 46 | + |
| 47 | +instance : Coe K ℚ := |
| 48 | + ⟨fun x => x.1⟩ |
| 49 | + |
| 50 | +instance inhabitedK : Inhabited K := |
| 51 | + ⟨0⟩ |
| 52 | +#align counterexample.from_Bhavik.inhabited_K Counterexample.FromBhavik.inhabitedK |
| 53 | + |
| 54 | +instance : Preorder K where |
| 55 | + le x y := x = y ∨ (x : ℚ) + 1 ≤ (y : ℚ) |
| 56 | + le_refl x := Or.inl rfl |
| 57 | + le_trans x y z xy yz := by |
| 58 | + rcases xy with (rfl | xy); · apply yz |
| 59 | + rcases yz with (rfl | yz); · right; apply xy |
| 60 | + right |
| 61 | + exact xy.trans (le_trans ((le_add_iff_nonneg_right _).mpr zero_le_one) yz) |
| 62 | + |
| 63 | +end FromBhavik |
| 64 | + |
| 65 | +theorem mem_zmod_2 (a : ZMod 2) : a = 0 ∨ a = 1 := by |
| 66 | + rcases a with ⟨_ | _, _ | _ | _ | _⟩ |
| 67 | + · exact Or.inl rfl |
| 68 | + · exact Or.inr rfl |
| 69 | +#align counterexample.mem_zmod_2 Counterexample.mem_zmod_2 |
| 70 | + |
| 71 | +theorem add_self_zmod_2 (a : ZMod 2) : a + a = 0 := by rcases mem_zmod_2 a with (rfl | rfl) <;> rfl |
| 72 | +#align counterexample.add_self_zmod_2 Counterexample.add_self_zmod_2 |
| 73 | + |
| 74 | +namespace Nxzmod2 |
| 75 | + |
| 76 | +variable {a b : ℕ × ZMod 2} |
| 77 | + |
| 78 | +/-- The preorder relation on `ℕ × ℤ/2ℤ` where we only compare the first coordinate, |
| 79 | +except that we leave incomparable each pair of elements with the same first component. |
| 80 | +For instance, `∀ α, β ∈ ℤ/2ℤ`, the inequality `(1,α) ≤ (2,β)` holds, |
| 81 | +whereas, `∀ n ∈ ℤ`, the elements `(n,0)` and `(n,1)` are incomparable. -/ |
| 82 | +instance preN2 : PartialOrder (ℕ × ZMod 2) where |
| 83 | + le x y := x = y ∨ x.1 < y.1 |
| 84 | + le_refl a := Or.inl rfl |
| 85 | + le_trans x y z xy yz := by |
| 86 | + rcases xy with (rfl | xy) |
| 87 | + · exact yz |
| 88 | + · rcases yz with (rfl | yz) |
| 89 | + · exact Or.inr xy |
| 90 | + · exact Or.inr (xy.trans yz) |
| 91 | + le_antisymm := by |
| 92 | + intro a b ab ba |
| 93 | + cases' ab with ab ab |
| 94 | + · exact ab |
| 95 | + · cases' ba with ba ba |
| 96 | + · exact ba.symm |
| 97 | + · exact (Nat.lt_asymm ab ba).elim |
| 98 | +#align counterexample.Nxzmod_2.preN2 Counterexample.Nxzmod2.preN2 |
| 99 | + |
| 100 | +instance csrN2 : CommSemiring (ℕ × ZMod 2) := by infer_instance |
| 101 | +#align counterexample.Nxzmod_2.csrN2 Counterexample.Nxzmod2.csrN2 |
| 102 | + |
| 103 | +instance csrN21 : AddCancelCommMonoid (ℕ × ZMod 2) := |
| 104 | + { Nxzmod2.csrN2 with add_left_cancel := fun a _ _ h => (add_right_inj a).mp h } |
| 105 | +#align counterexample.Nxzmod_2.csrN2_1 Counterexample.Nxzmod2.csrN21 |
| 106 | + |
| 107 | +/-- A strict inequality forces the first components to be different. -/ |
| 108 | +@[simp] |
| 109 | +theorem lt_def : a < b ↔ a.1 < b.1 := by |
| 110 | + refine' ⟨fun h => _, fun h => _⟩ |
| 111 | + · rcases h with ⟨rfl | a1, h1⟩ |
| 112 | + · exact (not_or.mp h1).1.elim rfl |
| 113 | + · exact a1 |
| 114 | + refine' ⟨Or.inr h, not_or.mpr ⟨fun k => _, not_lt.mpr h.le⟩⟩ |
| 115 | + rw [k] at h |
| 116 | + exact Nat.lt_asymm h h |
| 117 | +#align counterexample.Nxzmod_2.lt_def Counterexample.Nxzmod2.lt_def |
| 118 | + |
| 119 | +theorem add_left_cancel : ∀ a b c : ℕ × ZMod 2, a + b = a + c → b = c := fun a _ _ h => |
| 120 | + (add_right_inj a).mp h |
| 121 | +#align counterexample.Nxzmod_2.add_left_cancel Counterexample.Nxzmod2.add_left_cancel |
| 122 | + |
| 123 | +theorem add_le_add_left : ∀ a b : ℕ × ZMod 2, a ≤ b → ∀ c : ℕ × ZMod 2, c + a ≤ c + b := by |
| 124 | + rintro a b (rfl | ab) c |
| 125 | + · rfl |
| 126 | + · exact Or.inr (by simpa) |
| 127 | +#align counterexample.Nxzmod_2.add_le_add_left Counterexample.Nxzmod2.add_le_add_left |
| 128 | + |
| 129 | +theorem le_of_add_le_add_left : ∀ a b c : ℕ × ZMod 2, a + b ≤ a + c → b ≤ c := by |
| 130 | + rintro a b c (bc | bc) |
| 131 | + · exact le_of_eq ((add_right_inj a).mp bc) |
| 132 | + · exact Or.inr (by simpa using bc) |
| 133 | +#align counterexample.Nxzmod_2.le_of_add_le_add_left Counterexample.Nxzmod2.le_of_add_le_add_left |
| 134 | + |
| 135 | +instance : ZeroLEOneClass (ℕ × ZMod 2) := |
| 136 | + ⟨by dsimp only [LE.le]; decide⟩ |
| 137 | + |
| 138 | +theorem mul_lt_mul_of_pos_left : ∀ a b c : ℕ × ZMod 2, a < b → 0 < c → c * a < c * b := |
| 139 | + fun _ _ _ ab c0 => lt_def.mpr ((mul_lt_mul_left (lt_def.mp c0)).mpr (lt_def.mp ab)) |
| 140 | +#align counterexample.Nxzmod_2.mul_lt_mul_of_pos_left Counterexample.Nxzmod2.mul_lt_mul_of_pos_left |
| 141 | + |
| 142 | +theorem mul_lt_mul_of_pos_right : ∀ a b c : ℕ × ZMod 2, a < b → 0 < c → a * c < b * c := |
| 143 | + fun _ _ _ ab c0 => lt_def.mpr ((mul_lt_mul_right (lt_def.mp c0)).mpr (lt_def.mp ab)) |
| 144 | +#align counterexample.Nxzmod_2.mul_lt_mul_of_pos_right Counterexample.Nxzmod2.mul_lt_mul_of_pos_right |
| 145 | + |
| 146 | +instance socsN2 : StrictOrderedCommSemiring (ℕ × ZMod 2) := |
| 147 | + { Nxzmod2.csrN21, (inferInstance : PartialOrder (ℕ × ZMod 2)), |
| 148 | + (inferInstance : CommSemiring (ℕ × ZMod 2)), |
| 149 | + pullback_nonzero Prod.fst Prod.fst_zero |
| 150 | + Prod.fst_one with |
| 151 | + add_le_add_left := add_le_add_left |
| 152 | + le_of_add_le_add_left := le_of_add_le_add_left |
| 153 | + zero_le_one := zero_le_one |
| 154 | + mul_lt_mul_of_pos_left := mul_lt_mul_of_pos_left |
| 155 | + mul_lt_mul_of_pos_right := mul_lt_mul_of_pos_right } |
| 156 | +#align counterexample.Nxzmod_2.socsN2 Counterexample.Nxzmod2.socsN2 |
| 157 | + |
| 158 | +end Nxzmod2 |
| 159 | + |
| 160 | +namespace ExL |
| 161 | + |
| 162 | +open Nxzmod2 Subtype |
| 163 | + |
| 164 | +/-- Initially, `L` was defined as the subsemiring closure of `(1,0)`. -/ |
| 165 | +def L : Type := |
| 166 | + { l : ℕ × ZMod 2 // l ≠ (0, 1) } |
| 167 | +#align counterexample.ex_L.L Counterexample.ExL.L |
| 168 | + |
| 169 | +theorem add_L {a b : ℕ × ZMod 2} (ha : a ≠ (0, 1)) (hb : b ≠ (0, 1)) : a + b ≠ (0, 1) := by |
| 170 | + rcases a with ⟨a, a2⟩ |
| 171 | + rcases b with ⟨b, b2⟩ |
| 172 | + match b with |
| 173 | + | 0 => |
| 174 | + rcases mem_zmod_2 b2 with (rfl | rfl) |
| 175 | + · simp [ha, -Prod.mk.injEq] |
| 176 | + · cases hb rfl |
| 177 | + | b + 1 => |
| 178 | + simp [(a + b).succ_ne_zero] |
| 179 | +#align counterexample.ex_L.add_L Counterexample.ExL.add_L |
| 180 | + |
| 181 | +theorem mul_L {a b : ℕ × ZMod 2} (ha : a ≠ (0, 1)) (hb : b ≠ (0, 1)) : a * b ≠ (0, 1) := by |
| 182 | + rcases a with ⟨a, a2⟩ |
| 183 | + rcases b with ⟨b, b2⟩ |
| 184 | + cases b |
| 185 | + · rcases mem_zmod_2 b2 with (rfl | rfl) <;> rcases mem_zmod_2 a2 with (rfl | rfl) <;> simp |
| 186 | + -- while this looks like a non-terminal `simp`, it (almost) isn't: there is only one goal where |
| 187 | + -- it does not finish the proof and on that goal it asks to prove `false` |
| 188 | + exact hb rfl |
| 189 | + cases a |
| 190 | + · rcases mem_zmod_2 b2 with (rfl | rfl) <;> rcases mem_zmod_2 a2 with (rfl | rfl) <;> simp |
| 191 | + -- while this looks like a non-terminal `simp`, it (almost) isn't: there is only one goal where |
| 192 | + -- it does not finish the proof and on that goal it asks to prove `false` |
| 193 | + exact ha rfl |
| 194 | + · simp [mul_ne_zero _ _, Nat.succ_ne_zero _] |
| 195 | +#align counterexample.ex_L.mul_L Counterexample.ExL.mul_L |
| 196 | + |
| 197 | +/-- The subsemiring corresponding to the elements of `L`, used to transfer instances. -/ |
| 198 | +def lSubsemiring : Subsemiring (ℕ × ZMod 2) where |
| 199 | + carrier := {l | l ≠ (0, 1)} |
| 200 | + zero_mem' := by decide |
| 201 | + one_mem' := by decide |
| 202 | + add_mem' := add_L |
| 203 | + mul_mem' := mul_L |
| 204 | +#align counterexample.ex_L.L_subsemiring Counterexample.ExL.lSubsemiring |
| 205 | + |
| 206 | +instance : OrderedCommSemiring L := |
| 207 | + lSubsemiring.toOrderedCommSemiring |
| 208 | + |
| 209 | +instance inhabited : Inhabited L := |
| 210 | + ⟨1⟩ |
| 211 | +#align counterexample.ex_L.inhabited Counterexample.ExL.inhabited |
| 212 | + |
| 213 | +theorem bot_le : ∀ a : L, 0 ≤ a := by |
| 214 | + rintro ⟨⟨an, a2⟩, ha⟩ |
| 215 | + cases an |
| 216 | + · rcases mem_zmod_2 a2 with (rfl | rfl) |
| 217 | + · rfl |
| 218 | + · exact (ha rfl).elim |
| 219 | + · refine' Or.inr _ |
| 220 | + exact Nat.succ_pos _ |
| 221 | +#align counterexample.ex_L.bot_le Counterexample.ExL.bot_le |
| 222 | + |
| 223 | +instance orderBot : OrderBot L where |
| 224 | + bot := 0 |
| 225 | + bot_le := bot_le |
| 226 | +#align counterexample.ex_L.order_bot Counterexample.ExL.orderBot |
| 227 | + |
| 228 | +theorem exists_add_of_le : ∀ a b : L, a ≤ b → ∃ c, b = a + c := by |
| 229 | + rintro a ⟨b, _⟩ (⟨rfl, rfl⟩ | h) |
| 230 | + · exact ⟨0, (add_zero _).symm⟩ |
| 231 | + · exact |
| 232 | + ⟨⟨b - a.1, fun H => (tsub_pos_of_lt h).ne' (Prod.mk.inj_iff.1 H).1⟩, |
| 233 | + Subtype.ext <| Prod.ext (add_tsub_cancel_of_le h.le).symm (add_sub_cancel'_right _ _).symm⟩ |
| 234 | +#align counterexample.ex_L.exists_add_of_le Counterexample.ExL.exists_add_of_le |
| 235 | + |
| 236 | +theorem le_self_add : ∀ a b : L, a ≤ a + b := by |
| 237 | + rintro a ⟨⟨bn, b2⟩, hb⟩ |
| 238 | + obtain rfl | h := Nat.eq_zero_or_pos bn |
| 239 | + · obtain rfl | rfl := mem_zmod_2 b2 |
| 240 | + · exact Or.inl (Prod.ext (add_zero _).symm (add_zero _).symm) |
| 241 | + · exact (hb rfl).elim |
| 242 | + · exact Or.inr ((lt_add_iff_pos_right _).mpr h) |
| 243 | +#align counterexample.ex_L.le_self_add Counterexample.ExL.le_self_add |
| 244 | + |
| 245 | +theorem eq_zero_or_eq_zero_of_mul_eq_zero : ∀ a b : L, a * b = 0 → a = 0 ∨ b = 0 := by |
| 246 | + rintro ⟨⟨a, a2⟩, ha⟩ ⟨⟨b, b2⟩, hb⟩ ab1 |
| 247 | + injection ab1 with ab |
| 248 | + injection ab with abn ab2 |
| 249 | + rw [mul_eq_zero] at abn |
| 250 | + rcases abn with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩) |
| 251 | + · refine' Or.inl _ |
| 252 | + rcases mem_zmod_2 a2 with (rfl | rfl) |
| 253 | + · rfl |
| 254 | + · exact (ha rfl).elim |
| 255 | + · refine' Or.inr _ |
| 256 | + rcases mem_zmod_2 b2 with (rfl | rfl) |
| 257 | + · rfl |
| 258 | + · exact (hb rfl).elim |
| 259 | +#align counterexample.ex_L.eq_zero_or_eq_zero_of_mul_eq_zero Counterexample.ExL.eq_zero_or_eq_zero_of_mul_eq_zero |
| 260 | + |
| 261 | +instance can : CanonicallyOrderedCommSemiring L := |
| 262 | + { (inferInstance : OrderBot L), |
| 263 | + (inferInstance : |
| 264 | + OrderedCommSemiring L) with |
| 265 | + exists_add_of_le := @(exists_add_of_le) |
| 266 | + le_self_add := le_self_add |
| 267 | + eq_zero_or_eq_zero_of_mul_eq_zero := @(eq_zero_or_eq_zero_of_mul_eq_zero) } |
| 268 | +#align counterexample.ex_L.can Counterexample.ExL.can |
| 269 | + |
| 270 | +/-- The elements `(1,0)` and `(1,1)` of `L` are different, but their doubles coincide. |
| 271 | +-/ |
| 272 | +example : ∃ a b : L, a ≠ b ∧ 2 * a = 2 * b := by |
| 273 | + refine' ⟨⟨(1, 0), by simp⟩, 1, fun h : (⟨(1, 0), _⟩ : L) = ⟨⟨1, 1⟩, _⟩ => _, rfl⟩ |
| 274 | + obtain F : (0 : ZMod 2) = 1 := congr_arg (fun j : L => j.1.2) h |
| 275 | + cases F |
| 276 | + |
| 277 | +end ExL |
| 278 | + |
| 279 | +end Counterexample |
0 commit comments