@@ -61,8 +61,37 @@ def grewriteLocalDecl (stx : Syntax) (symm : Bool) (fvarId : FVarId) (config : G
6161declare_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 -/
6796syntax (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
84143variable {a b c d n : ℤ}
@@ -92,25 +151,11 @@ example (h : a ≡ b [ZMOD n]) : a ^ 2 ≡ b ^ 2 [ZMOD n] := by
92151example (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`):
100156example (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-/
115160macro (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+ -/
124183macro "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+ -/
128202macro (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+ -/
132233macro "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+ -/
136263macro "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