Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Calling aesop from a tactic to obtain an `Expr`
Anne Baanen (Feb 15 2024 at 10:55):
I'm running into the limits of my understanding of tactics here. I'm in the following situation: in #10538 we have proveFinsetNonempty
which attempts to generate a proof. I would like to see if we can do this instead via calling into aesop to do this. However, aesop works on the level of MVarId
s (i.e. goals) and here the expected output is an Expr
. So do I understand correctly that I have to do something like:
1.Create a new goal, obtain a MVarId
- Make an
Expr
with theProp
we want to show - Set the goal type to be equal to the
Expr
we made - Call docs#Aesop.search with my parameters
- Check that aesop doesn't return any unsolved subgoals
- Get the term that solved the goal with docs#Lean.getExprMVarAssignment?
If this is correct, how do I do steps 1-3?
Jannis Limperg (Feb 15 2024 at 11:04):
I think this is correct and you should be able to use docs#Lean.Meta.mkFreshExprMVar to create the mvar. Note that this mvar inherits the current local context (as reported by getLCtx
); if you want a particular local context, use docs#Lean.Meta.mkFreshExprMVarAt. The local context contains the hypotheses that are allowed to appear in your final Expr
.
Anne Baanen (Feb 15 2024 at 11:07):
I see, thanks! We do want to use the current context for assumption
purposes so mkFreshExprMVar
sounds good. It returns an Expr
, do I then use docs#Lean.Expr.mvarId! on it or is there something I should take into account?
Anne Baanen (Feb 15 2024 at 11:14):
It seems to work, thanks! One final question: what's the best way to pass rulesets into docs#Aesop.search, for example to do the equivalent of by aesop (rule_sets [-default, Finset.Nonempty])
? Should I try to replicate what the frontend code does?
Jannis Limperg (Feb 15 2024 at 11:24):
Anne Baanen said:
I see, thanks! We do want to use the current context for
assumption
purposes somkFreshExprMVar
sounds good. It returns anExpr
, do I then use docs#Lean.Expr.mvarId! on it or is there something I should take into account?
Yes, the returned Expr
is always .mvar mvarId
. The return type should really be changed imo, but it would be a big refactor.
Anne Baanen (Feb 15 2024 at 11:29):
I think I answered my question about rulesets, it would be something like:
let rulesets ← Aesop.getDefaultRuleSetNames
let ((mvar, rules), _) ← (Aesop.Frontend.TacticConfig.getRuleSet mvar
{ additionalRules := #[],
erasedRules := #[],
enabledRuleSets := (rulesets.erase `default).insert `Finset.Nonempty,
options := {},
simpConfig := {},
simpConfigSyntax? := .none }).run
let (remainingGoals, _) ← Aesop.search mvar (.some rules)
Jannis Limperg (Feb 15 2024 at 11:30):
Anne Baanen said:
It seems to work, thanks! One final question: what's the best way to pass rulesets into docs#Aesop.search, for example to do the equivalent of
by aesop (rule_sets [-default, Finset.Nonempty])
? Should I try to replicate what the frontend code does?
Oh, the handling of rule sets has changed quite a bit on master. Now it's docs#Aesop.Frontend.getGlobalRuleSets into docs#Aesop.mkLocalRuleSet. (There should be a function combining the two.)
Anne Baanen (Feb 15 2024 at 11:46):
Got it, so it should be:
let rulesets ← Aesop.Frontend.getGlobalRuleSets #[`builtin, `Finset.Nonempty]
let rules ← Aesop.mkLocalRuleSet rulesets { terminal := true, generateScript := false }
Jannis Limperg (Feb 15 2024 at 12:31):
I think so, yes.
Anne Baanen (Feb 15 2024 at 13:35):
Thanks so much for your quick answers! :D
Last updated: May 02 2025 at 03:31 UTC