@@ -91,17 +91,26 @@ def elabCasesM (pats : Array Term) (recursive allowSplit : Bool) : TacticM Unit
9191 liftMetaTactic (casesMatching (matchPatterns pats) recursive allowSplit)
9292
9393/--
94- * `casesm p` applies the `cases` tactic to a hypothesis `h : type`
95- if `type` matches the pattern `p`.
96- * `casesm p_1, ..., p_n` applies the `cases` tactic to a hypothesis `h : type`
97- if `type` matches one of the given patterns.
98- * `casesm* p` is a more efficient and compact version of `· repeat casesm p`.
94+ `casesm p` searches for the first hypothesis `h : type` where `type` matches the term `p`,
95+ and splits the main goal by cases on `h`. Use holes in `p` to indicate arbitrary subexpressions,
96+ for example `casesm _ ∧ _` will match any conjunction. `casesm p` fails if no hypothesis type
97+ matches `p`.
98+
99+ * `casesm p_1, ..., p_n` searches for a hypothesis `h : type` where `type` matches one or more of
100+ the given patterns `p_1`, ... `p_n`, and splits the main goal by cases on `h`.
101+ * `casesm* p` repeatedly performs case splits until no more hypothesis type matches `p`.
102+ This is a more efficient and compact version of `· repeat casesm p`.
99103 It is more efficient because the pattern is compiled once.
100- * `casesm! p` only applies `cases` if the number of resulting subgoals is <= 1.
104+ * `casesm! p` and `casesm!* p` skip a hypothesis if the main goal would be replaced with two or more
105+ subgoals.
101106
102- Example: The following tactic destructs all conjunctions and disjunctions in the current context.
107+ Example:
103108```
104- casesm* _ ∨ _, _ ∧ _
109+ example (h : a ∧ b ∨ c ∧ d) (h2 : e ∧ f) : True := by
110+ -- The following tactic destructs all conjunctions and disjunctions in the current context.
111+ casesm* _∨_, _∧_
112+ · clear ‹a› ‹b› ‹e› ‹f›; (fail_if_success clear ‹c›); trivial
113+ · clear ‹c› ‹d› ‹e› ‹f›; trivial
105114```
106115-/
107116elab (name := casesM) "casesm" recursive:"*" ? ppSpace pats:term,+ : tactic => do
@@ -118,15 +127,24 @@ def elabCasesType (heads : Array Ident)
118127 liftMetaTactic (casesType heads recursive allowSplit)
119128
120129/--
121- * `cases_type I` applies the `cases` tactic to a hypothesis `h : (I ...)`
122- * `cases_type I_1 ... I_n` applies the `cases` tactic to a hypothesis
123- `h : (I_1 ...)` or ... or `h : (I_n ...)`
124- * `cases_type* I` is shorthand for `· repeat cases_type I`
125- * `cases_type! I` only applies `cases` if the number of resulting subgoals is <= 1.
126-
127- Example: The following tactic destructs all conjunctions and disjunctions in the current goal.
130+ `cases_type I` searches for a hypothesis `h : type` where `I` has the form `(I ...)`, and splits the
131+ main goal by cases on `h`. `cases_type p` fails if no hypothesis type has the identifier `I` as its
132+ head symbol.
133+
134+ * `cases_type I_1 ... I_n` searches for a hypothesis `h : type` where `type` has one or more of
135+ `I_1`, ..., `I_n` as its head symbol, and splits the main goal by cases on `h`.
136+ * `cases_type* I` repeatedly performs case splits until no more hypothesis type has `I` as its head
137+ symbol. This shorthand for `· repeat cases_type I`.
138+ * `cases_type! p` and `cases_type!* p` skip a hypothesis if the main goal would be replaced with two
139+ or more subgoals.
140+
141+ Example:
128142```
129- cases_type* Or And
143+ example (h : a ∧ b ∨ c ∧ d) (h2 : e ∧ f) : True := by
144+ -- The following tactic destructs all conjunctions and disjunctions in the current context.
145+ cases_type* Or And
146+ · clear ‹a› ‹b› ‹e› ‹f›; (fail_if_success clear ‹c›); trivial
147+ · clear ‹c› ‹d› ‹e› ‹f›; trivial
130148```
131149-/
132150elab (name := casesType) "cases_type" recursive:"*" ? heads:(ppSpace colGt ident)+ : tactic =>
@@ -167,15 +185,18 @@ where
167185 return (acc.push g)
168186
169187/--
170- * `constructorm p_1, ..., p_n` applies the `constructor` tactic to the main goal
171- if `type` matches one of the given patterns.
172- * `constructorm* p` is a more efficient and compact version of `· repeat constructorm p`.
173- It is more efficient because the pattern is compiled once.
188+ `constructorm p_1, ..., p_n`, where the main goal has type `type`, applies the first matching
189+ constructor for `type`, if `type` matches one of the given patterns. If `type` does not match any
190+ of the patterns, `constructorm` fails.
191+
192+ * `constructorm* p_1, ..., p_n` repeatedly applies a constructor until the goal no longer matches
193+ `p_1`, ..., `p_n`. This is a more efficient and compact version of
194+ `· repeat constructorm p_1, ..., p_n`. It is more efficient because the pattern is compiled once.
174195
175- Example: The following tactic proves any theorem like `True ∧ (True ∨ True)` consisting of
176- and/or/true:
196+ Examples:
177197```
178- constructorm* _ ∨ _, _ ∧ _, True
198+ example : True ∧ (True ∨ True) := by
199+ constructorm* _ ∨ _, _ ∧ _, True
179200```
180201-/
181202elab (name := constructorM) "constructorm" recursive:"*" ? ppSpace pats:term,+ : tactic => do
0 commit comments