@@ -67,12 +67,9 @@ a second time with different values of the metavariables.
67
67
See https://github.com/leanprover-community/mathlib/issues/2269
68
68
-/
69
69
def mkAssumptionSet (noDflt : Bool) (hs : List (TSyntax `term)) :
70
- MetaM (List (TermElabM Expr) × TermElabM (List Expr)) :=
71
- do
70
+ MetaM (List (TermElabM Expr) × TermElabM (List Expr)) := do
71
+ let hs := if noDflt then hs else [← `(rfl), ← `(trivial), ← `(congrFun), ← `(congrArg)] ++ hs
72
72
let hs := hs.map (λ s => Elab.Term.elabTerm s.raw none)
73
- let hs := if noDflt then hs else
74
- ([← `(rfl), ← `(trivial), ← `(congrFun), ← `(congrArg)].map
75
- (λ s => Elab.Term.elabTerm s.raw none)) ++ hs
76
73
let locals : TermElabM (List Expr) := if noDflt then pure [] else pure (← getLocalHyps).toList
77
74
return (hs, locals)
78
75
@@ -81,6 +78,11 @@ def exceptEmoji : Except ε α → String
81
78
| .error _ => crossEmoji
82
79
| .ok _ => checkEmoji
83
80
81
+ /-- Elaborate the context and the list of lemmas -/
82
+ def elabContextLemmas (lemmas : List (TermElabM Expr)) (ctx : TermElabM (List Expr)) :
83
+ MetaM (List Expr) := Elab.Term.TermElabM.run' do
84
+ pure ((← lemmas.mapM id) ++ (← ctx))
85
+
84
86
/-- Attempt to solve the given metavariable by repeating applying a list of facts. -/
85
87
def solveByElimAux (lemmas : List (TermElabM Expr)) (ctx : TermElabM (List Expr)) (n : Nat) :
86
88
TacticM Unit := Tactic.done <|> match n with
@@ -92,10 +94,7 @@ def solveByElimAux (lemmas : List (TermElabM Expr)) (ctx : TermElabM (List Expr)
92
94
-- the `do` block below runs, potentially unifying mvars in the goal.
93
95
(return m!"{exceptEmoji ·} working on: {← addMessageContextFull goal}" )
94
96
do
95
- let es ← Elab.Term.TermElabM.run' do
96
- let ctx' ← ctx
97
- let lemmas' ← lemmas.mapM id
98
- pure (lemmas' ++ ctx')
97
+ let es ← elabContextLemmas lemmas ctx
99
98
100
99
-- We attempt to find an expression which can be applied,
101
100
-- and for which all resulting sub-goals can be discharged using `solveByElim n`.
@@ -158,3 +157,29 @@ syntax (name := solveByElim) "solve_by_elim" "*"? (config)? (&" only")? (simpArg
158
157
elab_rules : tactic | `(tactic| solve_by_elim $[only%$o]? $[[$[$t:term],*]]?) => do
159
158
let es := (t.getD #[]).toList
160
159
solveByElimImpl o.isSome es 6 (← getMainGoal)
160
+
161
+ /--
162
+ `apply_assumption` looks for an assumption of the form `... → ∀ _, ... → head`
163
+ where `head` matches the current goal.
164
+
165
+ [ todo ] not yet implemented:
166
+ If this fails, `apply_assumption` will call `symmetry` and try again.
167
+
168
+ [ todo ] not yet implemented:
169
+ If this also fails, `apply_assumption` will call `exfalso` and try again,
170
+ so that if there is an assumption of the form `P → ¬ Q`, the new tactic state
171
+ will have two goals, `P` and `Q`.
172
+
173
+ [ todo ] not yet implemented:
174
+ Optional arguments:
175
+ - `lemmas`: a list of expressions to apply, instead of the local constants
176
+ - `tac`: a tactic to run on each subgoal after applying an assumption; if
177
+ this tactic fails, the corresponding assumption will be rejected and
178
+ the next one will be attempted.
179
+ -/
180
+ syntax (name := applyAssumption) "apply_assumption" : tactic
181
+
182
+ elab_rules : tactic | `(tactic| apply_assumption) => withMainContext do
183
+ let ctx := (← getLocalHyps).toList
184
+ let lemmas := [← `(rfl), ← `(trivial), ← `(congrArg)].map (λ s => Elab.Term.elabTerm s.raw none)
185
+ (← elabContextLemmas lemmas (pure ctx)).firstM fun e => (liftMetaTactic (Lean.MVarId.apply · e))
0 commit comments