solve_by_elim
, apply_rules
, and apply_assumption
. #
solve_by_elim
takes a collection of facts from the local context or
supplied as arguments by the user, and performs a backtracking
depth-first search by attempting to apply
these facts to the goal.
It is a highly configurable tactic, with options to control the backtracking, to solve multiple goals simultaneously (with backtracking between goals), or to supply a discharging tactic for unprovable goals.
apply_rules
and apply_assumption
are much simpler tactics which do
not perform backtracking, but are currently implemented in terms of
solve_by_elim
with backtracking disabled, in order to be able to share
the front-end customisation and parsing of user options. It would be
reasonable to further separate these in future.
applyTactics lemmas goal
will return an iterator that applies the
lemmas to the goal goal
and returns ones that succeed.
Providing this to the backtracking
tactic,
we can perform backtracking search based on applying a list of lemmas.
applyTactics (trace := `name)
will construct trace nodes for ``nameindicating which calls to
apply` succeeded or failed.
Instances For
applyFirst lemmas goal
applies the first of the lemmas
which can be successfully applied to goal
, and fails if none apply.
We use this in apply_rules
and apply_assumption
where backtracking is not needed.
Instances For
The default maxDepth
for apply_rules
is higher.
- proc : List Lean.MVarId → List Lean.MVarId → Lean.MetaM (Option (List Lean.MVarId))
- discharge : Lean.MVarId → Lean.MetaM (Option (List Lean.MVarId))
- transparency : Lean.Meta.TransparencyMode
Transparency mode for calls to
apply
. - symm : Bool
Also use symmetric versions (via
@[symm]
) of local hypotheses. - exfalso : Bool
Try proving the goal via
exfalso
ifsolve_by_elim
otherwise fails. This is only used when operating on a single goal.
Instances For
Configuration structure to control the behaviour of solve_by_elim
:
- transparency mode for calls to
apply
- whether to use
symm
on hypotheses andexfalso
on the goal as needed, - see also
BacktrackConfig
for hooks allowing flow control.
- proc : List Lean.MVarId → List Lean.MVarId → Lean.MetaM (Option (List Lean.MVarId))
- discharge : Lean.MVarId → Lean.MetaM (Option (List Lean.MVarId))
- backtracking : Bool
Enable backtracking search.
- intro : Bool
Trying calling
intro
if no lemmas apply. - constructor : Bool
Try calling
constructor
if no lemmas apply.
Instances For
Equations
- Lean.Meta.SolveByElim.SolveByElimConfig.instCoeBacktrackConfig = { coe := fun (x : Lean.Meta.SolveByElim.SolveByElimConfig) => x.toBacktrackConfig }
Create or modify a Config
which allows a class of goals to be returned as subgoals.
Instances For
Create or modify a Config
which runs a tactic on the main goal.
If that tactic fails, fall back to the proc
behaviour of cfg
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Create or modify a Config
which calls intro
on each goal before applying lemmas.
Instances For
Attempt typeclass inference on each goal, before applying lemmas.
Equations
- cfg.synthInstance = cfg.mainGoalProc fun (g : Lean.MVarId) => do let __do_lift ← g.getType let __do_lift ← Lean.Meta.synthInstance __do_lift g.assign __do_lift pure []
Instances For
Add a discharging tactic, falling back to the original discharging tactic if it fails.
Return none
to return the goal as a new subgoal, or some goals
to replace it.
Instances For
Create or modify a SolveByElimConfig
which calls intro
on any goal for which no lemma applies.
Equations
- cfg.introsAfter = cfg.withDischarge fun (g : Lean.MVarId) => do let __do_lift ← g.intro1P pure (some [__do_lift.snd])
Instances For
Call constructor
when no lemmas apply.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Create or modify a Config
which
calls synthInstance
on any goal for which no lemma applies.
Equations
- cfg.synthInstanceAfter = cfg.withDischarge fun (g : Lean.MVarId) => do let __do_lift ← g.getType let __do_lift ← Lean.Meta.synthInstance __do_lift g.assign __do_lift pure (some [])
Instances For
Create or modify a Config
which rejects branches for which test
,
applied to the instantiations of the original goals, fails or returns false
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Create or modify a SolveByElimConfig
which rejects complete solutions for which test
,
applied to the instantiations of the original goals, fails or returns false
.
Equations
Instances For
Create or modify a Config
which only accept solutions
for which every expression in use
appears as a subexpression.
Instances For
Process the intro
and constructor
options by implementing the discharger
tactic.
Instances For
Elaborate a list of lemmas and local context.
See mkAssumptionSet
for an explanation of why this is needed.
Instances For
Returns the list of tactics corresponding to applying the available lemmas to the goal.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Applies the first possible lemma to the goal.
Instances For
Solve a collection of goals by repeatedly applying lemmas, backtracking as necessary.
Arguments:
cfg : SolveByElimConfig
additional configuration options (options forapply
, maximum depth, and custom flow control)lemmas : List (TermElabM Expr)
lemmas to apply. These are thunks inTermElabM
to avoid stuck metavariables.ctx : TermElabM (List Expr)
monadic function returning the local hypotheses to use.goals : List MVarId
the initial list of goals forsolveByElim
Returns a list of suspended goals, if it succeeded on all other subgoals.
By default cfg.suspend
is false,
cfg.discharge
fails, and cfg.failAtMaxDepth
is true
,
and so the returned list is always empty.
Custom wrappers (e.g. apply_assumption
and apply_rules
) may modify this behaviour.
Instances For
Run either backtracking search, or repeated application, on the list of goals.
Equations
- One or more equations did not get rendered due to their size.
Instances For
If symm
is true
, then adds in symmetric versions of each hypothesis.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A MetaM
analogue of the apply_rules
user tactic.
We pass the lemmas as TermElabM Expr
rather than just Expr
,
so they can be generated fresh for each application, to avoid stuck metavariables.
By default it uses all local hypotheses, but you can disable this with only := true
.
If you need to remove particular local hypotheses, call solveByElim
directly.
Equations
- One or more equations did not get rendered due to their size.
Instances For
mkAssumptionSet
builds a collection of lemmas for use in
the backtracking search in solve_by_elim
.
- By default, it includes all local hypotheses, along with
rfl
,trivial
,congrFun
andcongrArg
. - The flag
noDefaults
removes these. - The flag
star
includes all local hypotheses, but notrfl
,trivial
,congrFun
, orcongrArg
. (It doesn't make sense to usestar
withoutnoDefaults
.) - The argument
add
is the list of terms inside the square brackets that did not have-
and can be used to add expressions or local hypotheses - The argument
remove
is the list of terms inside the square brackets that had a-
, and can be used to remove local hypotheses. (It doesn't make sense to remove expressions which are not local hypotheses, to remove local hypotheses unless!noDefaults || star
, and it does not make sense to usestar
unless you remove at least one local hypothesis.)
mkAssumptionSet
returns not a List expr
, but a List (TermElabM Expr) × TermElabM (List Expr)
.
There are two separate problems that need to be solved.
Stuck metavariables #
Lemmas with implicit arguments would be filled in with metavariables if we created the
Expr
objects immediately, so instead we return thunks that generate the expressions
on demand. This is the first component, with type List (TermElabM Expr)
.
As an example, we have def rfl : ∀ {α : Sort u} {a : α}, a = a
, which on elaboration will become
@rfl ?m_1 ?m_2
.
Because solve_by_elim
works by repeated application of lemmas against subgoals,
the first time such a lemma is successfully applied,
those metavariables will be unified, and thereafter have fixed values.
This would make it impossible to apply the lemma
a second time with different values of the metavariables.
See https://github.com/leanprover-community/mathlib/issues/2269
Relevant local hypotheses #
solve_by_elim*
works with multiple goals,
and we need to use separate sets of local hypotheses for each goal.
The second component of the returned value provides these local hypotheses.
(Essentially using getLocalHyps
, along with some filtering to remove hypotheses
that have been explicitly removed via only
or [-h]
.)
Instances For
Run elabTerm
.