Skip to content

Commit d9077f3

Browse files
Update lean-toolchain for leanprover/lean4#11416
2 parents 2c0779d + 0d1f1ab commit d9077f3

File tree

9 files changed

+180
-27
lines changed

9 files changed

+180
-27
lines changed

Batteries/Data/Char/Basic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Jannis Limperg, François G. Dorais
66
module
77

88
public import Batteries.Classes.Order
9+
public import Batteries.Data.List.Lemmas
910

1011
@[expose] public section
1112

Batteries/Data/Fin/Basic.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ This is the dependent version of `Fin.foldl`. -/
8888
(f : ∀ (i : Fin n), α i.castSucc → α i.succ) (init : α 0) : α (last n) :=
8989
dfoldlM (m := Id) n α f init
9090

91+
/-- Sum of a tuple indexed by `Fin n`. -/
92+
@[inline] protected def sum [Zero α] [Add α] (x : Fin n → α) : α :=
93+
foldr n (x · + ·) 0
94+
95+
/-- Product of a tuple indexed by `Fin n`. -/
96+
@[inline] protected def prod [One α] [Mul α] (x : Fin n → α) : α :=
97+
foldr n (x · * ·) 1
98+
99+
/-- Count the number of true values of a decidable predicate on `Fin n`. -/
100+
@[inline] protected def countP (p : Fin n → Bool) : Nat :=
101+
Fin.sum (p · |>.toNat)
102+
91103
/--
92104
`findSome? f` returns `f i` for the first `i` for which `f i` is `some _`, or `none` if no such
93105
element is found. The function `f` is not evaluated on further inputs after the first `i` is found.

Batteries/Data/Fin/Lemmas.lean

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module
77

88
public import Batteries.Data.Fin.Basic
99
public import Batteries.Data.Nat.Lemmas
10+
public import Batteries.Data.List.Basic
1011
public import Batteries.Util.ProofWanted
1112
public import Batteries.Tactic.Alias
1213

@@ -39,6 +40,67 @@ theorem foldr_assoc {op : α → α → α} [ha : Std.Associative op] {f : Fin n
3940

4041
@[simp] theorem coe_clamp (n m : Nat) : (clamp n m : Nat) = min n m := rfl
4142

43+
/-! ### sum -/
44+
45+
@[simp, grind =]
46+
theorem sum_zero [Zero α] [Add α] (x : Fin 0 → α) :
47+
Fin.sum x = 0 := by
48+
simp [Fin.sum]
49+
50+
theorem sum_succ [Zero α] [Add α] (x : Fin (n + 1) → α) :
51+
Fin.sum x = x 0 + Fin.sum (x ·.succ) := by
52+
simp [Fin.sum, foldr_succ]
53+
54+
@[simp, grind =]
55+
theorem sum_eq_sum_map_finRange [Zero α] [Add α] (x : Fin n → α) :
56+
Fin.sum x = (List.finRange n |>.map x).sum := by
57+
simp only [Fin.sum, foldr_eq_finRange_foldr, List.sum, List.foldr_map]
58+
59+
/-! ### prod -/
60+
61+
@[simp, grind =]
62+
theorem prod_zero [One α] [Mul α] (x : Fin 0 → α) :
63+
Fin.prod x = 1 := by
64+
simp [Fin.prod]
65+
66+
theorem prod_succ [One α] [Mul α] (x : Fin (n + 1) → α) :
67+
Fin.prod x = x 0 * Fin.prod (x ·.succ) := by
68+
simp [Fin.prod, foldr_succ]
69+
70+
@[simp, grind =]
71+
theorem prod_eq_prod_map_finRange [One α] [Mul α] (x : Fin n → α) :
72+
Fin.prod x = (List.finRange n |>.map x).prod := by
73+
simp only [Fin.prod, foldr_eq_finRange_foldr, List.prod, List.foldr_map]
74+
75+
/-! ### countP -/
76+
77+
@[simp, grind =] theorem countP_zero (p : Fin 0 → Bool) : Fin.countP p = 0 := by
78+
simp [Fin.countP]
79+
80+
@[simp, grind =] theorem countP_one (p : Fin 1 → Bool) : Fin.countP p = (p 0).toNat := by
81+
simp [Fin.countP, List.finRange_succ]
82+
83+
theorem countP_succ (p : Fin (n + 1) → Bool) :
84+
Fin.countP p = (p 0).toNat + Fin.countP (p ·.succ) := by
85+
simp [Fin.countP, List.finRange_succ]; rfl
86+
87+
@[simp, grind =]
88+
theorem countP_eq_countP_map_finRange (x : Fin n → Bool) :
89+
Fin.countP x = (List.finRange n).countP x := by
90+
induction n with
91+
| zero => rfl
92+
| succ n ih => simp +arith [countP_succ, List.finRange_succ, List.countP_cons, List.countP_map,
93+
Bool.cond_eq_ite, Bool.toNat, ih]; rfl
94+
95+
@[grind .]
96+
theorem countP_le (p : Fin n → Bool) : Fin.countP p ≤ n := by
97+
induction n with simp only [countP_zero, countP_succ, Nat.le_refl]
98+
| succ _ ih =>
99+
rw [Nat.add_comm]
100+
apply Nat.add_le_add
101+
· exact ih ..
102+
· exact Bool.toNat_le ..
103+
42104
/-! ### findSome? -/
43105

44106
@[simp] theorem findSome?_zero {f : Fin 0 → Option α} : findSome? f = none := by simp [findSome?]

Batteries/Data/List/Lemmas.lean

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,41 @@ theorem append_eq_of_isPrefixOf?_eq_some [BEq α] [LawfulBEq α] {xs ys zs : Lis
926926
theorem append_eq_of_isSuffixOf?_eq_some [BEq α] [LawfulBEq α] {xs ys zs : List α}
927927
(h : xs.isSuffixOf? ys = some zs) : zs ++ xs = ys := by simp_all
928928

929+
/-! ### finRange -/
930+
931+
theorem get_finRange (i : Fin (finRange n).length) :
932+
(finRange n).get i = Fin.cast length_finRange i := by simp
933+
934+
@[simp, grind =]
935+
theorem finRange_eq_nil_iff : finRange n = [] ↔ n = 0 := by
936+
simp [eq_nil_iff_length_eq_zero]
937+
938+
theorem finRange_eq_pmap_range : finRange n = (range n).pmap Fin.mk (by simp) := by
939+
apply List.ext_getElem <;> simp [finRange]
940+
941+
theorem nodup_finRange (n) : (finRange n).Nodup := by
942+
rw [finRange_eq_pmap_range]
943+
exact (Pairwise.pmap nodup_range _) fun _ _ _ _ => @Fin.ne_of_val_ne _ ⟨_, _⟩ ⟨_, _⟩
944+
945+
theorem pairwise_lt_finRange (n) : Pairwise (· < ·) (finRange n) := by
946+
rw [finRange_eq_pmap_range]
947+
exact List.pairwise_lt_range.pmap (by simp) (by simp)
948+
949+
theorem pairwise_le_finRange (n) : Pairwise (· ≤ ·) (finRange n) := by
950+
rw [finRange_eq_pmap_range]
951+
exact List.pairwise_le_range.pmap (by simp) (by simp)
952+
953+
@[simp]
954+
theorem map_get_finRange (l : List α) : (finRange l.length).map l.get = l := by
955+
apply ext_getElem <;> simp
956+
957+
@[simp]
958+
theorem map_getElem_finRange (l : List α) : (finRange l.length).map (l[·.1]) = l := by
959+
apply ext_getElem <;> simp
960+
961+
@[simp]
962+
theorem map_coe_finRange_eq_range : (finRange n).map (↑·) = List.range n := by
963+
apply List.ext_getElem <;> simp
929964
/-! ### sum/prod -/
930965

931966
private theorem foldr_eq_foldl_aux (f : α → α → α) (init : α) [Std.Associative f]

Batteries/Tactic/Init.lean

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,31 @@ elab (name := exacts) "exacts " "[" hs:term,* "]" : tactic => do
3131
evalTactic (← `(tactic| exact $stx))
3232
evalTactic (← `(tactic| done))
3333

34+
/--
35+
`by_contra_core` is the component of `by_contra` that turns the goal into the form `p → False`.
36+
`by_contra h` is defined as `by_contra_core` followed by `rintro h`.
37+
* If the goal is a negation `¬q`, the goal becomes `q → False`.
38+
* If the goal has a `Decidable` instance, it uses `Decidable.byContradiction` instead of
39+
`Classical.byContradiction`.
40+
-/
41+
scoped macro "by_contra_core" : tactic => `(tactic| first
42+
| guard_target = Not _; change _ → False
43+
| refine @Decidable.byContradiction _ _ ?_
44+
| refine @Classical.byContradiction _ ?_)
45+
3446
/--
3547
`by_contra h` proves `⊢ p` by contradiction,
3648
introducing a hypothesis `h : ¬p` and proving `False`.
3749
* If `p` is a negation `¬q`, `h : q` will be introduced instead of `¬¬q`.
3850
* If `p` is decidable, it uses `Decidable.byContradiction` instead of `Classical.byContradiction`.
39-
* If `h` is omitted, the introduced variable `_: ¬p` will be anonymous.
51+
* If `h` is omitted, the introduced variable will be called `this`.
4052
-/
41-
macro (name := byContra) tk:"by_contra" e?:(ppSpace colGt binderIdent)? : tactic => do
42-
let e := match e? with
43-
| some e => match e with
44-
| `(binderIdent| $e:ident) => e
45-
| e => Unhygienic.run `(_%$e) -- HACK: hover fails without Unhygienic here
46-
| none => Unhygienic.run `(_%$tk)
47-
`(tactic| first
48-
| guard_target = Not _; intro $e:term
49-
| refine @Decidable.byContradiction _ _ fun $e => ?_
50-
| refine @Classical.byContradiction _ fun $e => ?_)
53+
syntax (name := byContra) "by_contra" (ppSpace colGt rcasesPatMed)? (" : " term)? : tactic
54+
55+
macro_rules
56+
| `(tactic| by_contra $[$pat?]? $[: $ty?]?) => do
57+
let pat ← pat?.getDM `(rcasesPatMed| $(mkIdent `this):ident)
58+
`(tactic| (by_contra_core; rintro ($pat:rcasesPatMed) $[: $ty?]?))
5159

5260
/--
5361
Given a proof `h` of `p`, `absurd h` changes the goal to `⊢ ¬ p`.

Batteries/Tactic/Lint/Simp.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ def formatLemmas (usedSimps : Simp.UsedSimps) (simpName : String) (higherOrder :
102102
@[env_linter] def simpNF : Linter where
103103
noErrorsFound := "All left-hand sides of simp lemmas are in simp-normal form."
104104
errorsFound := "SOME SIMP LEMMAS ARE NOT IN SIMP-NORMAL FORM.
105-
see note [simp-normal form] for tips how to debug this.
106-
https://leanprover-community.github.io/mathlib_docs/notes.html#simp-normal%20form"
105+
Please change the lemma to make sure their left-hand sides are in simp normal form.
106+
To learn about simp normal forms, see
107+
https://leanprover-community.github.io/extras/simp.html#simp-normal-form
108+
and https://lean-lang.org/doc/reference/latest/The-Simplifier/Simp-Normal-Forms/."
107109
test := fun declName => do
108110
unless ← isSimpTheorem declName do return none
109111
withConfig Elab.Term.setElabConfig do

BatteriesTest/by_contra.lean

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ example (P : Prop) [Decidable P] : nonDecid P = decid P := by
2121

2222
example (P : Prop) : P → P := by
2323
by_contra
24-
guard_hyp ‹_› : ¬(P → P)
24+
guard_hyp this : ¬(P → P)
2525
exact ‹¬(P → P)› id
2626

2727
example (P : Prop) : {_ : P} → P := by
2828
by_contra
29-
guard_hyp ‹_› : ¬(P → P)
29+
guard_hyp this : ¬(P → P)
3030
exact ‹¬(P → P)› id
3131

3232
/-!
@@ -42,11 +42,44 @@ case left
4242
---
4343
error: unsolved goals
4444
case right
45-
x✝ : ¬True
45+
this : ¬True
4646
⊢ False
4747
-/
4848
#guard_msgs in
4949
example : True ∧ True := by
5050
constructor
5151
· skip
5252
· by_contra
53+
54+
example (n : Nat) (h : n ≠ 0) : n ≠ 0 := by
55+
by_contra rfl
56+
simp only [Ne, not_true_eq_false] at h
57+
58+
example (p q : Prop) (hnp : ¬ p) : ¬ (p ∧ q) := by
59+
by_contra ⟨hp, _⟩
60+
exact hnp hp
61+
62+
example (p q : Prop) (hnp : ¬ p) (hnq : ¬ q) : ¬ (p ∨ q) := by
63+
by_contra hp | hq
64+
· exact hnp hp
65+
· exact hnq hq
66+
67+
/--
68+
error: unsolved goals
69+
n : Nat
70+
this : n ≠ 0
71+
⊢ False
72+
-/
73+
#guard_msgs in
74+
example (n : Nat) : n = 0 := by
75+
by_contra : n ≠ 0
76+
77+
/--
78+
error: unsolved goals
79+
n : Nat
80+
h_ne : n ≠ 0
81+
⊢ False
82+
-/
83+
#guard_msgs in
84+
example (n : Nat) : n = 0 := by
85+
by_contra h_ne : n ≠ 0

BatteriesTest/print_prefix.lean

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ inductive TEmpty : Type
55
info: TEmpty : Type
66
TEmpty.casesOn.{u} (motive : TEmpty → Sort u) (t : TEmpty) : motive t
77
TEmpty.ctorIdx : TEmpty → Nat
8-
TEmpty.noConfusion.{u} {P : Sort u} {x1 x2 : TEmpty} (h12 : x1 = x2) : TEmpty.noConfusionType P x1 x2
9-
TEmpty.noConfusionType.{u} (P : Sort u) (x1 x2 : TEmpty) : Sort u
8+
TEmpty.noConfusion.{u} {P : Sort u} {t t' : TEmpty} (eq : t = t') : TEmpty.noConfusionType P t t'
9+
TEmpty.noConfusionType.{u} (P : Sort u) (t t' : TEmpty) : Sort u
1010
TEmpty.rec.{u} (motive : TEmpty → Sort u) (t : TEmpty) : motive t
1111
TEmpty.recOn.{u} (motive : TEmpty → Sort u) (t : TEmpty) : motive t
1212
-/
@@ -58,11 +58,11 @@ TestStruct.mk.inj {foo bar foo✝ bar✝ : Int} :
5858
{ foo := foo, bar := bar } = { foo := foo✝, bar := bar✝ } → foo = foo✝ ∧ bar = bar✝
5959
TestStruct.mk.injEq (foo bar foo✝ bar✝ : Int) :
6060
({ foo := foo, bar := bar } = { foo := foo✝, bar := bar✝ }) = (foo = foo✝ ∧ bar = bar✝)
61-
TestStruct.mk.noConfusion.{u} (P : Sort u) (foo bar foo' bar' : Int)
62-
(h : { foo := foo, bar := bar } = { foo := foo', bar := bar' }) (k : foo = foo' → bar = bar' → P) : P
61+
TestStruct.mk.noConfusion.{u} {P : Sort u} {foo bar foo' bar' : Int}
62+
(eq : { foo := foo, bar := bar } = { foo := foo', bar := bar' }) (k : foo = foo' → bar = bar' → P) : P
6363
TestStruct.mk.sizeOf_spec (foo bar : Int) : sizeOf { foo := foo, bar := bar } = 1 + sizeOf foo + sizeOf bar
64-
TestStruct.noConfusion.{u} {P : Sort u} {x1 x2 : TestStruct} (h12 : x1 = x2) : TestStruct.noConfusionType P x1 x2
65-
TestStruct.noConfusionType.{u} (P : Sort u) (x1 x2 : TestStruct) : Sort u
64+
TestStruct.noConfusion.{u} {P : Sort u} {t t' : TestStruct} (eq : t = t') : TestStruct.noConfusionType P t t'
65+
TestStruct.noConfusionType.{u} (P : Sort u) (t t' : TestStruct) : Sort u
6666
TestStruct.rec.{u} {motive : TestStruct → Sort u} (mk : (foo bar : Int) → motive { foo := foo, bar := bar })
6767
(t : TestStruct) : motive t
6868
TestStruct.recOn.{u} {motive : TestStruct → Sort u} (t : TestStruct)
@@ -79,10 +79,10 @@ TestStruct.casesOn.{u} {motive : TestStruct → Sort u} (t : TestStruct)
7979
TestStruct.ctorIdx : TestStruct → Nat
8080
TestStruct.foo (self : TestStruct) : Int
8181
TestStruct.mk (foo bar : Int) : TestStruct
82-
TestStruct.mk.noConfusion.{u} (P : Sort u) (foo bar foo' bar' : Int)
83-
(h : { foo := foo, bar := bar } = { foo := foo', bar := bar' }) (k : foo = foo' → bar = bar' → P) : P
84-
TestStruct.noConfusion.{u} {P : Sort u} {x1 x2 : TestStruct} (h12 : x1 = x2) : TestStruct.noConfusionType P x1 x2
85-
TestStruct.noConfusionType.{u} (P : Sort u) (x1 x2 : TestStruct) : Sort u
82+
TestStruct.mk.noConfusion.{u} {P : Sort u} {foo bar foo' bar' : Int}
83+
(eq : { foo := foo, bar := bar } = { foo := foo', bar := bar' }) (k : foo = foo' → bar = bar' → P) : P
84+
TestStruct.noConfusion.{u} {P : Sort u} {t t' : TestStruct} (eq : t = t') : TestStruct.noConfusionType P t t'
85+
TestStruct.noConfusionType.{u} (P : Sort u) (t t' : TestStruct) : Sort u
8686
TestStruct.rec.{u} {motive : TestStruct → Sort u} (mk : (foo bar : Int) → motive { foo := foo, bar := bar })
8787
(t : TestStruct) : motive t
8888
TestStruct.recOn.{u} {motive : TestStruct → Sort u} (t : TestStruct)

lean-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
leanprover/lean4-pr-releases:pr-release-11416-8580d0e
1+
leanprover/lean4-pr-releases:pr-release-11416-22e91fa

0 commit comments

Comments
 (0)