Skip to content

Commit 8145118

Browse files
committed
chore(Tactic/GRewrite): rewrite grw family tactic docstrings (#36283)
This PR rewrites the docstrings for tactics in the `grw` family: `grw`, `grewrite`, `apply_rw`, `apply_rewrite`, `nth_rw` and `nth_rewrite`, to consistently match the official style guide, to make sure they are complete while not getting too long. The `grw` tactic docstring was nice and complete, but the others were very brief and needed expansion (especially since it took me quite some time to understand the motivation behind `apply_rw`). Co-authored-by: Anne C.A. Baanen <vierkantor@vierkantor.com>
1 parent 02ac6c3 commit 8145118

File tree

1 file changed

+150
-23
lines changed

1 file changed

+150
-23
lines changed

Mathlib/Tactic/GRewrite/Elab.lean

Lines changed: 150 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,37 @@ def grewriteLocalDecl (stx : Syntax) (symm : Bool) (fvarId : FVarId) (config : G
6161
declare_config_elab elabGRewriteConfig GRewrite.Config
6262

6363
/--
64-
`grewrite [e]` is like `grw [e]`, but it doesn't try to close the goal with `rfl`.
65-
This is analogous to `rw` and `rewrite`, where `rewrite` doesn't try to close the goal with `rfl`.
64+
`grewrite [e₁, ..., eₙ]` uses each expression `eᵢ : Rᵢ aᵢ bᵢ` (where `Rᵢ` is any two-argument
65+
relation) as a generalized rewrite rule on the main goal, replacing occurrences of `aᵢ` with `bᵢ`.
66+
Occurrences of `bᵢ` are not rewritten, even if logically possible. Use `grewrite [← eᵢ]` to rewrite
67+
in the other direction, replacing occurrences of `bᵢ` with `aᵢ`.
68+
69+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
70+
used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to
71+
fill these in by unification with the matching part of the target. Parameters are only filled in
72+
once per rule, restricting which later rewrites can be found. Parameters that are not filled in
73+
after unification will create side goals.
74+
75+
To be able to use `grewrite`, the relevant lemmas need to be tagged with `@[gcongr]`.
76+
To rewrite inside a transitive relation, you can also give it an `IsTrans` instance.
77+
The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it.
78+
A future version of `grewrite` may get special support for making better use of strict inequalities.
79+
80+
`grw` is like `grewrite` but tries to close the goal afterwards by "cheap" (reducible) `rfl`.
81+
To rewrite only in the `n`-th position, use `nth_grewrite n`.
82+
This is useful when `grewrite` tries to rewrite in a position that is not valid for the given
83+
relation.
84+
`apply_rewrite [e₁, ..., eₙ]` is a shorthand for `grewrite +implicationHyp [e₁, ..., eₙ]`: it
85+
interprets `· → ·` as a relation instead of adding the hypothesis as a side condition.
86+
87+
* `grewrite [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing
88+
occurrences of `b` with `a`.
89+
* `grewrite (config := cfg) [e₁, ..., eₙ]` uses `cfg` as configuration. See `GRewrite.Config` for
90+
details.
91+
* To let `grewrite` unfold more aggressively, as in `erw`, use
92+
`grewrite (transparency := default) [e₁, ..., eₙ]`.
93+
* `grewrite +implicationHyp [e₁, ..., eₙ]` interprets `· → ·` as a relation (see `apply_rewrite`).
94+
* `grewrite [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
6695
-/
6796
syntax (name := grewriteSeq) "grewrite" optConfig rwRuleSeq (location)? : tactic
6897

@@ -76,9 +105,39 @@ syntax (name := grewriteSeq) "grewrite" optConfig rwRuleSeq (location)? : tactic
76105
(throwTacticEx `grewrite · "did not find instance of the pattern in the current goal")
77106

78107
/--
79-
`grw [e]` works just like `rw [e]`, but `e` can be a relation other than `=` or `↔`.
108+
`grw [e₁, ..., eₙ]` uses each expression `eᵢ : Rᵢ aᵢ bᵢ` (where `Rᵢ` is any two-argument
109+
relation) as a generalized rewrite rule on the main goal, replacing occurrences of `aᵢ` with `bᵢ`,
110+
then tries to close the main goal by "cheap" (reducible) `rfl`.
111+
Occurrences of `bᵢ` are not rewritten, even if logically possible. Use `grw [← eᵢ]` to rewrite
112+
in the other direction, replacing occurrences of `bᵢ` with `aᵢ`.
80113
81-
For example:
114+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
115+
used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to
116+
fill these in by unification with the matching part of the target. Parameters are only filled in
117+
once per rule, restricting which later rewrites can be found. Parameters that are not filled in
118+
after unification will create side goals.
119+
120+
To be able to use `grw`, the relevant lemmas need to be tagged with `@[gcongr]`.
121+
To rewrite inside a transitive relation, you can also give it an `IsTrans` instance.
122+
The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it.
123+
A future version of `grw` may get special support for making better use of strict inequalities.
124+
125+
`grewrite` is like `grw` but does not try to apply `rfl` afterwards.
126+
To rewrite only in the `n`-th position, use `nth_grw n`.
127+
This is useful when `grw` tries to rewrite in a position that is not valid for the given relation.
128+
`apply_rw [rules]` is a shorthand for `grw +implicationHyp [rules]`: it interprets `· → ·` as a
129+
relation instead of adding the hypothesis as a side condition.
130+
131+
* `grw [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing occurrences
132+
of `b` with `a`.
133+
* `grw (config := cfg) [e₁, ..., eₙ]` uses `cfg` as configuration. See `GRewrite.Config` for
134+
details.
135+
* To let `grw` unfold more aggressively, as in `erw`, use
136+
`grw (transparency := default) [e₁, ..., eₙ]`.
137+
* `grw +implicationHyp [e₁, ..., e\_n]` interprets `· → ·` as a relation (see `apply_rw`).
138+
* `grw [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
139+
140+
Examples:
82141
83142
```lean
84143
variable {a b c d n : ℤ}
@@ -92,25 +151,11 @@ example (h : a ≡ b [ZMOD n]) : a ^ 2 ≡ b ^ 2 [ZMOD n] := by
92151
example (h₁ : a ∣ b) (h₂ : b ∣ a ^ 2 * c) : a ∣ b ^ 2 * c := by
93152
grw [h₁] at *
94153
exact h₂
95-
```
96-
97-
To replace the RHS with the LHS of the given relation, use the `←` notation (just like in `rw`):
98154
99-
```
155+
-- To replace the RHS with the LHS of the given relation, use the `←` notation (just like in `rw`):
100156
example (h₁ : a < b) (h₂ : b ≤ c) : a + d ≤ c + d := by
101157
grw [← h₂, ← h₁]
102158
```
103-
104-
The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it.
105-
A future version of `grw` may get special support for making better use of strict inequalities.
106-
107-
To rewrite only in the `n`-th position, use `nth_grw n`.
108-
This is useful when `grw` tries to rewrite in a position that is not valid for the given relation.
109-
110-
To be able to use `grw`, the relevant lemmas need to be tagged with `@[gcongr]`.
111-
To rewrite inside a transitive relation, you can also give it an `IsTrans` instance.
112-
113-
To let `grw` unfold more aggressively, as in `erw`, use `grw (transparency := default)`.
114159
-/
115160
macro (name := grwSeq) "grw " c:optConfig s:rwRuleSeq l:(location)? : tactic =>
116161
match s with
@@ -119,20 +164,102 @@ macro (name := grwSeq) "grw " c:optConfig s:rwRuleSeq l:(location)? : tactic =>
119164
`(tactic| (grewrite $c [$rs,*] $(l)?; with_annotate_state $rbrak (try (with_reducible rfl))))
120165
| _ => Macro.throwUnsupported
121166

167+
/--
168+
`apply_rewrite [e₁, ..., eₙ]` uses the expressions `e₁`, ..., `eₙ` as generalized rewrite rules, of
169+
type `pᵢ → qᵢ`, on the main goal, replacing occurrences of `pᵢ` with `qᵢ`. The difference with
170+
`grewrite` is that `grewrite` would turn `pᵢ` into a side goal and expect `qᵢ` to be a relation.
171+
172+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
173+
used. This provides a convenient way to unfold `e`.
122174
123-
/-- `apply_rewrite [rules]` is a shorthand for `grewrite +implicationHyp [rules]`. -/
175+
* `apply_rewrite [← e]` applies the rewrite rule `e : p → q` in the reverse direction, replacing
176+
occurrences of `q` with `p`.
177+
* `apply_rewrite (config := cfg) [e₁, ..., eₙ]` uses `cfg` as configuration. See `GRewrite.Config`
178+
for details.
179+
To let `apply_rewrite` unfold more aggressively, as in `erw`, use
180+
`apply_rewrite (transparency := default) [e₁, ..., eₙ]`.
181+
* `apply_rewrite [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
182+
-/
124183
macro "apply_rewrite" c:optConfig s:rwRuleSeq loc:(location)? : tactic => do
125184
`(tactic| grewrite $[$(getConfigItems c)]* +implicationHyp $s:rwRuleSeq $(loc)?)
126185

127-
/-- `apply_rw [rules]` is a shorthand for `grw +implicationHyp [rules]`. -/
186+
/--
187+
`apply_rw [e₁, ..., eₙ]` uses the expressions `e₁`, ..., `eₙ` as generalized rewrite rules, of type
188+
`pᵢ → qᵢ`, on the main goal, replacing occurrences of `pᵢ` with `qᵢ`. The difference with `grw` is
189+
that `grw` would turn `pᵢ` into a side goal and expect `qᵢ` to be a relation.
190+
191+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
192+
used. This provides a convenient way to unfold `e`.
193+
194+
* `apply_rw [← e]` applies the rewrite rule `e : p → q` in the reverse direction, replacing
195+
occurrences of `q` with `p`.
196+
* `apply_rw (config := cfg) [e₁, ..., eₙ]` uses `cfg` as configuration. See `GRewrite.Config`
197+
for details.
198+
To let `apply_rw` unfold more aggressively, as in `erw`, use
199+
`apply_rw (transparency := default) [e₁, ..., eₙ]`.
200+
* `apply_rw [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
201+
-/
128202
macro (name := applyRwSeq) "apply_rw " c:optConfig s:rwRuleSeq loc:(location)? : tactic => do
129203
`(tactic| grw $[$(getConfigItems c)]* +implicationHyp $s:rwRuleSeq $(loc)?)
130204

131-
/-- `nth_grewrite` is just like `nth_rewrite`, but for `grewrite`. -/
205+
/--
206+
`nth_grewrite n₁ ... nₖ [e₁, ..., eₙ]` is a variant of `grewrite` that for each expression
207+
`eᵢ : R aᵢ bᵢ` only replaces the `n₁, ..., nₖ`th occurrence of `aᵢ` with `bᵢ`.
208+
Occurrences of `bᵢ` are not rewritten, even if logically possible. Use
209+
`nth_grewrite n₁ ... nₖ [← eᵢ]` to rewrite in the other direction, replacing occurrences of `bᵢ`
210+
with `aᵢ`.
211+
212+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
213+
used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to
214+
fill these in by unification with the matching part of the target. Parameters are only filled in
215+
once per rule, restricting which later rewrites can be found. Parameters that are not filled in
216+
after unification will create side goals.
217+
218+
To be able to use `nth_grewrite`, the relevant lemmas need to be tagged with `@[gcongr]`.
219+
To rewrite inside a transitive relation, you can also give it an `IsTrans` instance.
220+
The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it.
221+
A future version of `nth_grewrite` may get special support for making better use of strict
222+
inequalities.
223+
224+
* `nth_grewrite n₁ ... nₖ [← e]` applies the rewrite rule `e : R a b` in the reverse direction,
225+
replacing the `n₁, ..., nₖ`th occurrences of `b` with `a`.
226+
* `nth_grewrite (config := cfg) n₁ ... nₖ [e₁, ..., eₙ]` uses `cfg` as configuration. See
227+
`GRewrite.Config` for details.
228+
* To let `nth_grewrite` unfold more aggressively, as in `erw`, use
229+
`nth_grewrite (transparency := default) n₁ ... nₖ [e₁, ..., eₙ]`.
230+
* `nth_grewrite +implicationHyp n₁ ... nₖ [e₁, ..., eₙ]` interprets `· → ·` as a relation.
231+
* `nth_grewrite n₁ ... nₖ [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
232+
-/
132233
macro "nth_grewrite" c:optConfig ppSpace nums:(num)+ s:rwRuleSeq loc:(location)? : tactic => do
133234
`(tactic| grewrite $[$(getConfigItems c)]* (occs := .pos [$[$nums],*]) $s:rwRuleSeq $(loc)?)
134235

135-
/-- `nth_grw` is just like `nth_rw`, but for `grw`. -/
236+
/--
237+
`nth_grw n₁ ... nₖ [e₁, ..., eₙ]` is a variant of `grw` that for each expression `eᵢ : R aᵢ bᵢ` only
238+
replaces the `n₁, ..., nₖ`th occurrence of `aᵢ` with `bᵢ`. Occurrences of `bᵢ` are not rewritten,
239+
even if logically possible. Use `nth_grw n₁ ... nₖ [← eᵢ]` to rewrite in the other direction,
240+
replacing occurrences of `bᵢ` with `aᵢ`.
241+
242+
If an expression `e` is a defined constant, then the equational theorems associated with `e` are
243+
used. This provides a convenient way to unfold `e`. If `e` has parameters, the tactic will try to
244+
fill these in by unification with the matching part of the target. Parameters are only filled in
245+
once per rule, restricting which later rewrites can be found. Parameters that are not filled in
246+
after unification will create side goals.
247+
248+
To be able to use `nth_grw`, the relevant lemmas need to be tagged with `@[gcongr]`.
249+
To rewrite inside a transitive relation, you can also give it an `IsTrans` instance.
250+
The strict inequality `a < b` is turned into the non-strict inequality `a ≤ b` to rewrite with it.
251+
A future version of `nth_grw` may get special support for making better use of strict
252+
inequalities.
253+
254+
* `nth_grw n₁ ... nₖ [← e]` applies the rewrite rule `e : R a b` in the reverse direction, replacing
255+
the `n₁, ..., nₖ`th occurrences of `b` with `a`.
256+
* `nth_grw (config := cfg) n₁ ... nₖ [e₁, ..., eₙ]` uses `cfg` as configuration. See
257+
`GRewrite.Config` for details.
258+
* To let `nth_grw` unfold more aggressively, as in `erw`, use
259+
`nth_grw (transparency := default) n₁ ... nₖ [e₁, ..., eₙ]`.
260+
* `nth_grw +implicationHyp n₁ ... nₖ [e₁, ..., eₙ]` interprets `· → ·` as a relation.
261+
* `nth_grw n₁ ... nₖ [e₁, ..., eₙ] at l` rewrites at the location(s) `l`.
262+
-/
136263
macro "nth_grw" c:optConfig ppSpace nums:(num)+ s:rwRuleSeq loc:(location)? : tactic => do
137264
`(tactic| grw $[$(getConfigItems c)]* (occs := .pos [$[$nums],*]) $s:rwRuleSeq $(loc)?)
138265

0 commit comments

Comments
 (0)