diff --git a/src/Init/Data/Array/Bootstrap.lean b/src/Init/Data/Array/Bootstrap.lean index e0ba68d36b..dcd2b10939 100644 --- a/src/Init/Data/Array/Bootstrap.lean +++ b/src/Init/Data/Array/Bootstrap.lean @@ -100,9 +100,15 @@ abbrev push_toList := @toList_push @[simp, grind =] theorem empty_append {xs : Array α} : #[] ++ xs = xs := by apply ext'; simp only [toList_append, List.nil_append] -@[simp, grind _=_] theorem append_assoc {xs ys zs : Array α} : xs ++ ys ++ zs = xs ++ (ys ++ zs) := by +@[simp] theorem append_assoc {xs ys zs : Array α} : xs ++ ys ++ zs = xs ++ (ys ++ zs) := by apply ext'; simp only [toList_append, List.append_assoc] +grind_pattern append_assoc => (xs ++ ys) ++ zs where + xs =/= #[]; ys =/= #[]; zs =/= #[] + +grind_pattern append_assoc => xs ++ (ys ++ zs) where + xs =/= #[]; ys =/= #[]; zs =/= #[] + @[simp] theorem appendList_eq_append {xs : Array α} {l : List α} : xs.appendList l = xs ++ l := rfl @[simp, grind =] theorem toList_appendList {xs : Array α} {l : List α} : @@ -110,6 +116,4 @@ abbrev push_toList := @toList_push rw [← appendList_eq_append]; unfold Array.appendList induction l generalizing xs <;> simp [*] - - end Array diff --git a/src/Init/Data/Array/Extract.lean b/src/Init/Data/Array/Extract.lean index 89a1747803..e9191a3905 100644 --- a/src/Init/Data/Array/Extract.lean +++ b/src/Init/Data/Array/Extract.lean @@ -200,7 +200,7 @@ theorem getElem?_extract_of_succ {as : Array α} {j : Nat} : simp [getElem?_extract] omega -@[simp, grind =] theorem extract_extract {as : Array α} {i j k l : Nat} : +@[simp] theorem extract_extract {as : Array α} {i j k l : Nat} : (as.extract i j).extract k l = as.extract (i + k) (min (i + l) j) := by ext m h₁ h₂ · simp @@ -208,6 +208,9 @@ theorem getElem?_extract_of_succ {as : Array α} {j : Nat} : · simp only [size_extract] at h₁ h₂ simp [Nat.add_assoc] +grind_pattern extract_extract => (as.extract i j).extract k l where + as =/= #[] + theorem extract_eq_empty_of_eq_empty {as : Array α} {i j : Nat} (h : as = #[]) : as.extract i j = #[] := by simp [h] diff --git a/src/Init/Data/Array/Lemmas.lean b/src/Init/Data/Array/Lemmas.lean index 9d1dd1d61a..71f56156e6 100644 --- a/src/Init/Data/Array/Lemmas.lean +++ b/src/Init/Data/Array/Lemmas.lean @@ -1628,12 +1628,15 @@ theorem filterMap_eq_filter {p : α → Bool} (w : stop = as.size) : cases as simp -@[grind =] theorem filterMap_filterMap {f : α → Option β} {g : β → Option γ} {xs : Array α} : filterMap g (filterMap f xs) = filterMap (fun x => (f x).bind g) xs := by cases xs simp [List.filterMap_filterMap] +grind_pattern filterMap_filterMap => filterMap g (filterMap f xs) where + f =/= some + g =/= some + @[grind =] theorem map_filterMap {f : α → Option β} {g : β → γ} {xs : Array α} : map g (filterMap f xs) = filterMap (fun x => (f x).map g) xs := by diff --git a/src/Init/Data/Int/Bitwise/Lemmas.lean b/src/Init/Data/Int/Bitwise/Lemmas.lean index f745117166..530458e1c8 100644 --- a/src/Init/Data/Int/Bitwise/Lemmas.lean +++ b/src/Init/Data/Int/Bitwise/Lemmas.lean @@ -24,12 +24,17 @@ theorem natCast_shiftRight (n s : Nat) : n >>> s = (n : Int) >>> s := rfl theorem negSucc_shiftRight (m n : Nat) : -[m+1] >>> n = -[m >>>n +1] := rfl -@[grind _=_] theorem shiftRight_add (i : Int) (m n : Nat) : i >>> (m + n) = i >>> m >>> n := by simp only [shiftRight_eq, Int.shiftRight] cases i <;> simp [Nat.shiftRight_add] +grind_pattern shiftRight_add => i >>> (m + n) where + i =/= 0 + +grind_pattern shiftRight_add => i >>> m >>> n where + i =/= 0 + theorem shiftRight_eq_div_pow (m : Int) (n : Nat) : m >>> n = m / ((2 ^ n) : Nat) := by simp only [shiftRight_eq, Int.shiftRight, Nat.shiftRight_eq_div_pow] diff --git a/src/Init/Data/List/Basic.lean b/src/Init/Data/List/Basic.lean index cf2502db9f..51ea705406 100644 --- a/src/Init/Data/List/Basic.lean +++ b/src/Init/Data/List/Basic.lean @@ -622,11 +622,17 @@ instance : Std.LawfulIdentity (α := List α) (· ++ ·) [] where | nil => simp | cons _ as ih => simp [ih, Nat.succ_add] -@[simp, grind _=_] theorem append_assoc (as bs cs : List α) : (as ++ bs) ++ cs = as ++ (bs ++ cs) := by +@[simp] theorem append_assoc (as bs cs : List α) : (as ++ bs) ++ cs = as ++ (bs ++ cs) := by induction as with | nil => rfl | cons a as ih => simp [ih] +grind_pattern append_assoc => (as ++ bs) ++ cs where + as =/= []; bs =/= []; cs =/= [] + +grind_pattern append_assoc => as ++ (bs ++ cs) where + as =/= []; bs =/= []; cs =/= [] + instance : Std.Associative (α := List α) (· ++ ·) := ⟨append_assoc⟩ -- Arguments are explicit as there is often ambiguity inferring the arguments. diff --git a/src/Init/Data/List/Lemmas.lean b/src/Init/Data/List/Lemmas.lean index e4d0a29d2d..cf09e57787 100644 --- a/src/Init/Data/List/Lemmas.lean +++ b/src/Init/Data/List/Lemmas.lean @@ -1217,9 +1217,13 @@ theorem tailD_map {f : α → β} {l l' : List α} : theorem getLastD_map {f : α → β} {l : List α} {a : α} : (map f l).getLastD (f a) = f (l.getLastD a) := by simp -@[simp, grind _=_] theorem map_map {g : β → γ} {f : α → β} {l : List α} : +@[simp] theorem map_map {g : β → γ} {f : α → β} {l : List α} : map g (map f l) = map (g ∘ f) l := by induction l <;> simp_all +grind_pattern map_map => map g (map f l) where + g =/= List.reverse + f =/= List.reverse + /-! ### filter -/ @[simp] theorem filter_cons_of_pos {p : α → Bool} {a : α} {l} (pa : p a) : @@ -1428,13 +1432,16 @@ theorem filterMap_eq_filter {p : α → Bool} : | nil => rfl | cons a l IH => by_cases pa : p a <;> simp [Option.guard, pa, ← IH] -@[grind =] theorem filterMap_filterMap {f : α → Option β} {g : β → Option γ} {l : List α} : filterMap g (filterMap f l) = filterMap (fun x => (f x).bind g) l := by induction l with | nil => rfl | cons a l IH => cases h : f a <;> simp [filterMap_cons, *] +grind_pattern filterMap_filterMap => filterMap g (filterMap f l) where + f =/= some + g =/= some + @[grind =] theorem map_filterMap {f : α → Option β} {g : β → γ} {l : List α} : map g (filterMap f l) = filterMap (fun x => (f x).map g) l := by diff --git a/src/Init/Data/List/Nat/Modify.lean b/src/Init/Data/List/Nat/Modify.lean index 031e7ee23f..4587bbe678 100644 --- a/src/Init/Data/List/Nat/Modify.lean +++ b/src/Init/Data/List/Nat/Modify.lean @@ -68,10 +68,13 @@ theorem getElem?_modifyHead {l : List α} {f : α → α} {i} : @[simp, grind =] theorem tail_modifyHead {f : α → α} {l : List α} : (l.modifyHead f).tail = l.tail := by cases l <;> simp -@[simp, grind =] theorem take_modifyHead {f : α → α} {l : List α} {i} : +@[simp] theorem take_modifyHead {f : α → α} {l : List α} {i} : (l.modifyHead f).take i = (l.take i).modifyHead f := by cases l <;> cases i <;> simp +grind_pattern take_modifyHead => (l.modifyHead f).take i where + i =/= 0 + @[simp] theorem drop_modifyHead_of_pos {f : α → α} {l : List α} {i} (h : 0 < i) : (l.modifyHead f).drop i = l.drop i := by cases l <;> cases i <;> simp_all @@ -213,7 +216,6 @@ theorem modify_eq_self {f : α → α} {i} {l : List α} (h : l.length ≤ i) : intro h omega -@[grind =] theorem modify_modify_eq (f g : α → α) (i) (l : List α) : (l.modify i f).modify i g = l.modify i (g ∘ f) := by apply ext_getElem @@ -222,6 +224,9 @@ theorem modify_modify_eq (f g : α → α) (i) (l : List α) : simp only [getElem_modify, Function.comp_apply] split <;> simp +grind_pattern modify_modify_eq => (l.modify i f).modify i g where + l =/= [] + theorem modify_modify_ne (f g : α → α) {i j} (l : List α) (h : i ≠ j) : (l.modify i f).modify j g = (l.modify j g).modify i f := by apply ext_getElem diff --git a/src/Init/Data/Nat/Bitwise/Lemmas.lean b/src/Init/Data/Nat/Bitwise/Lemmas.lean index a3350451d3..e45c65c6a3 100644 --- a/src/Init/Data/Nat/Bitwise/Lemmas.lean +++ b/src/Init/Data/Nat/Bitwise/Lemmas.lean @@ -485,11 +485,16 @@ protected theorem and_comm (x y : Nat) : x &&& y = y &&& x := by apply Nat.eq_of_testBit_eq simp [Bool.and_comm] -@[grind _=_] protected theorem and_assoc (x y z : Nat) : (x &&& y) &&& z = x &&& (y &&& z) := by apply Nat.eq_of_testBit_eq simp [Bool.and_assoc] +grind_pattern Nat.and_assoc => (x &&& y) &&& z where + x =/= 0; y =/= 0; z =/= 0 + +grind_pattern Nat.and_assoc => x &&& (y &&& z) where + x =/= 0; y =/= 0; z =/= 0 + instance : Std.Associative (α := Nat) (· &&& ·) where assoc := Nat.and_assoc diff --git a/src/Init/Data/Nat/Lemmas.lean b/src/Init/Data/Nat/Lemmas.lean index 66c35053d1..ee56687551 100644 --- a/src/Init/Data/Nat/Lemmas.lean +++ b/src/Init/Data/Nat/Lemmas.lean @@ -1719,11 +1719,16 @@ theorem shiftRight_succ_inside : ∀m n, m >>> (n+1) = (m/2) >>> n | 0 => by simp | n + 1 => by simp [zero_shiftRight n, shiftRight_succ] -@[grind _=_] theorem shiftLeft_add (m n : Nat) : ∀ k, m <<< (n + k) = (m <<< n) <<< k | 0 => rfl | k + 1 => by simp [← Nat.add_assoc, shiftLeft_add _ _ k, shiftLeft_succ] +grind_pattern shiftLeft_add => m <<< (n + k) where + m =/= 0 + +grind_pattern shiftLeft_add => (m <<< n) <<< k where + m =/= 0 + @[simp] theorem shiftLeft_shiftRight (x n : Nat) : x <<< n >>> n = x := by rw [Nat.shiftLeft_eq, Nat.shiftRight_eq_div_pow, Nat.mul_div_cancel _ (Nat.two_pow_pos _)] diff --git a/tests/lean/run/grind_lint_1.lean b/tests/lean/run/grind_lint_1.lean index 7ac2bbfba2..b2d97b05ca 100644 --- a/tests/lean/run/grind_lint_1.lean +++ b/tests/lean/run/grind_lint_1.lean @@ -23,7 +23,7 @@ error: `Array.swap_swap` is not marked with the `@[grind]` attribute for theorem #grind_lint skip Array.getElem_swap /-- -info: instantiating `Array.range_succ` triggers 47 additional `grind` theorem instantiations +info: instantiating `Array.range_succ` triggers 19 additional `grind` theorem instantiations --- info: Try this to display the actual theorem instances: [apply] set_option trace.grind.ematch.instance true in @@ -37,7 +37,7 @@ info: Try this to display the actual theorem instances: #grind_lint mute Array.append_assoc -- It is not used during E-matching by `#grind_lint check` and `#grind_lint inspect` /-- -info: instantiating `Array.range_succ` triggers 22 additional `grind` theorem instantiations +info: instantiating `Array.range_succ` triggers 19 additional `grind` theorem instantiations --- info: Try this to display the actual theorem instances: [apply] set_option trace.grind.ematch.instance true in @@ -47,9 +47,9 @@ info: Try this to display the actual theorem instances: #grind_lint inspect Array.range_succ /-- -info: instantiating `Array.range_succ` triggers 22 additional `grind` theorem instantiations +info: instantiating `Array.range_succ` triggers 19 additional `grind` theorem instantiations --- -info: instantiating `Array.range'_succ` triggers 17 additional `grind` theorem instantiations +info: instantiating `Array.range'_succ` triggers 14 additional `grind` theorem instantiations --- info: Try this to display the actual theorem instances: [apply] set_option trace.grind.ematch.instance true in @@ -58,52 +58,16 @@ info: Try this to display the actual theorem instances: #guard_msgs in #grind_lint inspect Array.range_succ Array.range'_succ -/-- -info: instantiating `Array.extract_empty` triggers more than 100 additional `grind` theorem instantiations ---- -info: instantiating `Array.filterMap_some` triggers more than 100 additional `grind` theorem instantiations ---- -info: instantiating `Array.range_succ` triggers 22 additional `grind` theorem instantiations --/ #guard_msgs in -#grind_lint check (min := 20) (detailed := 200) in Array +#grind_lint check (min := 20) in Array #grind_lint skip Array.extract_empty -- `#grind_lint check` skips it from now on -/-- -info: instantiating `Array.filterMap_some` triggers more than 100 additional `grind` theorem instantiations ---- -info: instantiating `Array.range_succ` triggers 22 additional `grind` theorem instantiations --/ #guard_msgs in -#grind_lint check (min := 20) (detailed := 200) in Array +#grind_lint check (min := 20) in Array -/-- -info: instantiating `Array.filterMap_some` triggers more than 100 additional `grind` theorem instantiations ---- -info: Array.filterMap_some -[thm] instances - [thm] Array.filterMap_filterMap ↦ 94 - [thm] Array.size_filterMap_le ↦ 5 - [thm] Array.filterMap_some ↦ 1 ---- -info: Try this to display the actual theorem instances: - [apply] set_option trace.grind.ematch.instance true in - #grind_lint inspect Array.filterMap_some --/ #guard_msgs in #grind_lint inspect Array.filterMap_some -/-- -info: instantiating `Array.filterMap_some` triggers more than 100 additional `grind` theorem instantiations ---- -info: Array.filterMap_some -[thm] instances - [thm] Array.filterMap_filterMap ↦ 94 - [thm] Array.size_filterMap_le ↦ 5 - [thm] Array.filterMap_some ↦ 1 ---- -info: instantiating `Array.range_succ` triggers 22 additional `grind` theorem instantiations --/ #guard_msgs in #grind_lint check (min := 20) in module Init.Data.Array