Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
) Adds a term elaborator for `congr(...)` "congruence quotations". For example, if `hf : f = f'` and `hx : x = x'`, then we have `congr($hf $x) : f x = f' x'`. This supports the functions having implicit arguments, and it has support for subsingleton instance arguments. So for example, if `s t : Set X` are sets with `Fintype` instances and `h : s = t` then `congr(Fintype.card $h) : Fintype.card s = Fintype.card t` works. Ports the `congrm` tactic as a convenient frontend for applying a congruence quotation to the goal. Holes are turned into congruence holes. For example, `congrm 1 + ?_` uses `congr(1 + $(?_))`. Placeholders (`_`) do not turn into congruence holes; that's not to say they have to be identical on the LHS and RHS, but `congrm` itself is responsible for finding a congruence lemma for such arguments. Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Moritz Doll <moritz.doll@googlemail.com>
- Loading branch information
1 parent
dd64a90
commit 9a9e31c
Showing
18 changed files
with
1,130 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/- | ||
Copyright (c) 2023 Moritz Doll, Damiano Testa. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Moritz Doll, Gabriel Ebner, Damiano Testa, Kyle Miller | ||
-/ | ||
import Mathlib.Tactic.TermCongr | ||
|
||
/-! | ||
# The `congrm` tactic | ||
The `congrm` tactic ("`congr` with matching") | ||
is a convenient frontend for `congr(...)` congruence quotations. | ||
Roughly, `congrm e` is `refine congr(e')`, where `e'` is `e` with every `?m` placeholder | ||
replaced by `$(?m)`. | ||
-/ | ||
|
||
namespace Mathlib.Tactic | ||
open Lean Parser Tactic Elab Tactic Meta | ||
|
||
initialize registerTraceClass `Tactic.congrm | ||
|
||
/-- | ||
`congrm e` is a tactic for proving goals of the form `lhs = rhs`, `lhs ↔ rhs`, `HEq lhs rhs`, | ||
or `R lhs rhs` when `R` is a reflexive relation. | ||
The expression `e` is a pattern containing placeholders `?_`, | ||
and this pattern is matched against `lhs` and `rhs` simultaneously. | ||
These placeholders generate new goals that state that corresponding subexpressions | ||
in `lhs` and `rhs` are equal. | ||
If the placeholders have names, such as `?m`, then the new goals are given tags with those names. | ||
Examples: | ||
```lean | ||
example {a b c d : ℕ} : | ||
Nat.pred a.succ * (d + (c + a.pred)) = Nat.pred b.succ * (b + (c + d.pred)) := by | ||
congrm Nat.pred (Nat.succ ?h1) * (?h2 + ?h3) | ||
/- Goals left: | ||
case h1 ⊢ a = b | ||
case h2 ⊢ d = b | ||
case h3 ⊢ c + a.pred = c + d.pred | ||
-/ | ||
sorry | ||
sorry | ||
sorry | ||
example {a b : ℕ} (h : a = b) : (fun y : ℕ => ∀ z, a + a = z) = (fun x => ∀ z, b + a = z) := by | ||
congrm fun x => ∀ w, ?_ + a = w | ||
-- ⊢ a = b | ||
exact h | ||
``` | ||
The `congrm` command is a convenient frontend to `congr(...)` congruence quotations. | ||
If the goal is an equality, `congrm e` is equivalent to `refine congr(e')` where `e'` is | ||
built from `e` by replacing each placeholder `?m` by `$(?m)`. | ||
The pattern `e` is allowed to contain `$(...)` expressions to immediately substitute | ||
equality proofs into the congruence, just like for congruence quotations. | ||
-/ | ||
syntax (name := congrM) "congrm " term : tactic | ||
|
||
elab_rules : tactic | ||
| `(tactic| congrm $expr:term) => do | ||
-- Wrap all synthetic holes `?m` as `c(?m)` to form `congr(...)` pattern | ||
let pattern ← expr.raw.replaceM fun stx => | ||
if stx.isOfKind ``Parser.Term.syntheticHole then | ||
pure <| stx.mkAntiquotNode `term | ||
else if stx.isAntiquots then | ||
-- Don't look into `$(..)` expressions | ||
pure stx | ||
else | ||
pure none | ||
trace[Tactic.congrm] "pattern: {pattern}" | ||
-- Chain together transformations as needed to convert the goal to an Eq if possible. | ||
liftMetaTactic fun g => do | ||
return [← (← g.iffOfEq).liftReflToEq] | ||
-- Apply `congr(...)` | ||
withMainContext do | ||
let gStx ← Term.exprToSyntax (← getMainTarget) | ||
-- Gives the expected type to `refine` as a workaround for its elaboration order. | ||
evalTactic <| ← `(tactic| refine (congr($(⟨pattern⟩)) : $gStx)) |
Oops, something went wrong.