@@ -5,9 +5,11 @@ Authors: Robert Y. Lewis, Keeley Hoek
5
5
-/
6
6
import Mathlib.Algebra.NeZero
7
7
import Mathlib.Data.Nat.Defs
8
+ import Mathlib.Data.Int.DivMod
8
9
import Mathlib.Logic.Embedding.Basic
9
10
import Mathlib.Logic.Equiv.Set
10
11
import Mathlib.Tactic.Common
12
+ import Mathlib.Tactic.Attr.Register
11
13
12
14
/-!
13
15
# The finite type with `n` elements
@@ -190,6 +192,7 @@ protected theorem heq_ext_iff {k l : ℕ} (h : k = l) {i : Fin k} {j : Fin l} :
190
192
191
193
end coe
192
194
195
+
193
196
section Order
194
197
195
198
/-!
@@ -332,6 +335,58 @@ theorem one_lt_last [NeZero n] : 1 < last (n + 1) := by
332
335
333
336
end Order
334
337
338
+ /-! ### Coercions to `ℤ` and the `fin_omega` tactic. -/
339
+
340
+ open Int
341
+
342
+ theorem coe_int_sub_eq_ite {n : Nat} (u v : Fin n) :
343
+ ((u - v : Fin n) : Int) = if v ≤ u then (u - v : Int) else (u - v : Int) + n := by
344
+ rw [Fin.sub_def]
345
+ split
346
+ · rw [ofNat_emod, Int.emod_eq_sub_self_emod, Int.emod_eq_of_lt] <;> omega
347
+ · rw [ofNat_emod, Int.emod_eq_of_lt] <;> omega
348
+
349
+ theorem coe_int_sub_eq_mod {n : Nat} (u v : Fin n) :
350
+ ((u - v : Fin n) : Int) = ((u : Int) - (v : Int)) % n := by
351
+ rw [coe_int_sub_eq_ite]
352
+ split
353
+ · rw [Int.emod_eq_of_lt] <;> omega
354
+ · rw [Int.emod_eq_add_self_emod, Int.emod_eq_of_lt] <;> omega
355
+
356
+ theorem coe_int_add_eq_ite {n : Nat} (u v : Fin n) :
357
+ ((u + v : Fin n) : Int) = if (u + v : ℕ) < n then (u + v : Int) else (u + v : Int) - n := by
358
+ rw [Fin.add_def]
359
+ split
360
+ · rw [ofNat_emod, Int.emod_eq_of_lt] <;> omega
361
+ · rw [ofNat_emod, Int.emod_eq_sub_self_emod, Int.emod_eq_of_lt] <;> omega
362
+
363
+ theorem coe_int_add_eq_mod {n : Nat} (u v : Fin n) :
364
+ ((u + v : Fin n) : Int) = ((u : Int) + (v : Int)) % n := by
365
+ rw [coe_int_add_eq_ite]
366
+ split
367
+ · rw [Int.emod_eq_of_lt] <;> omega
368
+ · rw [Int.emod_eq_sub_self_emod, Int.emod_eq_of_lt] <;> omega
369
+
370
+ -- Write `a + b` as `if (a + b : ℕ) < n then (a + b : ℤ) else (a + b : ℤ) - n` and
371
+ -- similarly `a - b` as `if (b : ℕ) ≤ a then (a - b : ℤ) else (a - b : ℤ) + n`.
372
+ attribute [fin_omega] coe_int_sub_eq_ite coe_int_add_eq_ite
373
+
374
+ -- Rewrite inequalities in `Fin` to inequalities in `ℕ`
375
+ attribute [fin_omega] Fin.lt_iff_val_lt_val Fin.le_iff_val_le_val
376
+
377
+ -- Rewrite `1 : Fin (n + 2)` to `1 : ℤ`
378
+ attribute [fin_omega] val_one
379
+
380
+ /--
381
+ Preprocessor for `omega` to handle inequalities in `Fin`.
382
+ Note that this involves a lot of case splitting, so may be slow.
383
+ -/
384
+ -- Further adjustment to the simp set can probably make this more powerful.
385
+ -- Please experiment and PR updates!
386
+ macro "fin_omega" : tactic => `(tactic|
387
+ { try simp only [fin_omega, ← Int.ofNat_lt, ← Int.ofNat_le] at *
388
+ omega })
389
+
335
390
section Add
336
391
337
392
/-!
@@ -1439,9 +1494,8 @@ instance uniqueFinOne : Unique (Fin 1) where
1439
1494
@[simp]
1440
1495
theorem coe_fin_one (a : Fin 1 ) : (a : ℕ) = 0 := by simp [Subsingleton.elim a 0 ]
1441
1496
1442
- lemma eq_one_of_neq_zero (i : Fin 2 ) (hi : i ≠ 0 ) : i = 1 :=
1443
- fin_two_eq_of_eq_zero_iff
1444
- (by simpa only [one_eq_zero_iff, succ.injEq, iff_false, reduceCtorEq] using hi)
1497
+ lemma eq_one_of_neq_zero (i : Fin 2 ) (hi : i ≠ 0 ) : i = 1 := by
1498
+ fin_omega
1445
1499
1446
1500
@[simp]
1447
1501
theorem coe_neg_one : ↑(-1 : Fin (n + 1 )) = n := by
@@ -1454,15 +1508,7 @@ theorem last_sub (i : Fin (n + 1)) : last n - i = Fin.rev i :=
1454
1508
Fin.ext <| by rw [coe_sub_iff_le.2 i.le_last, val_last, val_rev, Nat.succ_sub_succ_eq_sub]
1455
1509
1456
1510
theorem add_one_le_of_lt {n : ℕ} {a b : Fin (n + 1 )} (h : a < b) : a + 1 ≤ b := by
1457
- cases' a with a ha
1458
- cases' b with b hb
1459
- cases n
1460
- · simp only [Nat.zero_add, Nat.lt_one_iff] at ha hb
1461
- simp [ha, hb]
1462
- simp only [le_iff_val_le_val, val_add, lt_iff_val_lt_val, val_mk, val_one] at h ⊢
1463
- rwa [Nat.mod_eq_of_lt, Nat.succ_le_iff]
1464
- rw [Nat.succ_lt_succ_iff]
1465
- exact h.trans_le (Nat.le_of_lt_succ hb)
1511
+ cases n <;> fin_omega
1466
1512
1467
1513
theorem exists_eq_add_of_le {n : ℕ} {a b : Fin n} (h : a ≤ b) : ∃ k ≤ b, b = a + k := by
1468
1514
obtain ⟨k, hk⟩ : ∃ k : ℕ, (b : ℕ) = a + k := Nat.exists_eq_add_of_le h
@@ -1473,27 +1519,18 @@ theorem exists_eq_add_of_le {n : ℕ} {a b : Fin n} (h : a ≤ b) : ∃ k ≤ b,
1473
1519
theorem exists_eq_add_of_lt {n : ℕ} {a b : Fin (n + 1 )} (h : a < b) :
1474
1520
∃ k < b, k + 1 ≤ b ∧ b = a + k + 1 := by
1475
1521
cases n
1476
- · cases' a with a ha
1477
- cases' b with b hb
1478
- simp only [Nat.zero_add, Nat.lt_one_iff] at ha hb
1479
- simp [ha, hb] at h
1522
+ · omega
1480
1523
obtain ⟨k, hk⟩ : ∃ k : ℕ, (b : ℕ) = a + k + 1 := Nat.exists_eq_add_of_lt h
1481
1524
have hkb : k < b := by omega
1482
- refine ⟨⟨k, hkb.trans b.is_lt⟩, hkb, ?_, ?_⟩
1483
- · rw [Fin.le_iff_val_le_val, Fin.val_add_one]
1484
- split_ifs <;> simp [Nat.succ_le_iff, hkb]
1525
+ refine ⟨⟨k, hkb.trans b.is_lt⟩, hkb, by fin_omega, ?_⟩
1485
1526
simp [Fin.ext_iff, Fin.val_add, ← hk, Nat.mod_eq_of_lt b.is_lt]
1486
1527
1487
1528
lemma pos_of_ne_zero {n : ℕ} {a : Fin (n + 1 )} (h : a ≠ 0 ) :
1488
1529
0 < a :=
1489
1530
Nat.pos_of_ne_zero (val_ne_of_ne h)
1490
1531
1491
1532
lemma sub_succ_le_sub_of_le {n : ℕ} {u v : Fin (n + 2 )} (h : u < v) : v - (u + 1 ) < v - u := by
1492
- have h' : u + 1 ≤ v := add_one_le_of_lt h
1493
- apply lt_def.mpr
1494
- simp only [sub_val_of_le h', sub_val_of_le (Fin.le_of_lt h)]
1495
- refine Nat.sub_lt_sub_left h (lt_def.mp ?_)
1496
- exact lt_add_one_iff.mpr (Fin.lt_of_lt_of_le h v.le_last)
1533
+ fin_omega
1497
1534
1498
1535
end AddGroup
1499
1536
0 commit comments