This PR ensures users can select the "minimal indexable subexpression" condition in `grind` parameters. Example, they can now write `grind [! -> thmName]`. `grind?` will include the `!` modifier whenever users had used `@[grind!]`. This PR also fixes a missing case in the new pattern inference procedure. It also adjusts some `grind` annotations and tests in preparation for setting the new pattern inference heuristic as the new default.
23 lines
782 B
Text
23 lines
782 B
Text
module
|
||
variable {α : Type u} {l : List α} {P Q : α → Bool}
|
||
|
||
attribute [grind =] List.countP_nil List.countP_cons
|
||
|
||
theorem List.countP_le_countP (hpq : ∀ x ∈ l, P x → Q x) :
|
||
l.countP P ≤ l.countP Q := by
|
||
induction l <;> grind
|
||
|
||
-- TODO: how to explain to the user that `l.countP P ≤ l.countP Q` is a bad pattern
|
||
grind_pattern List.countP_le_countP => l.countP P, l.countP Q
|
||
|
||
theorem List.countP_lt_countP (hpq : ∀ x ∈ l, P x → Q x) (y:α) (hx: y ∈ l) (hxP : P y = false) (hxQ : Q y) :
|
||
l.countP P < l.countP Q := by
|
||
induction l <;> grind
|
||
|
||
/--
|
||
info: List.countP_nil: [@List.countP #1 #0 (@List.nil _)]
|
||
---
|
||
info: List.countP_cons: [@List.countP #3 #2 (@List.cons _ #1 #0)]
|
||
-/
|
||
#guard_msgs (info) in
|
||
attribute [grind? =] List.countP_nil List.countP_cons
|