Zulip Chat Archive
Stream: iris-lean
Topic: iRevert implementation and Qq
Oliver Soeser (Jul 04 2025 at 13:16):
I have submitted PR #74 implementing the irevert tactic. However, I ran into some issues using Qq in this part of my code:
let f ← getFVarId hyp
let (some ldecl) := ((← getLCtx).find? f) | throwError "unknown identifier"
let bibase := mkAppN (mkConst ``BI.toBIBase [u]) #[prop, bi]
let φ := ldecl.type
let (_, mvarId) ← mvar.revert #[f]
mvarId.withContext do
if ← Meta.isProp φ then
let p := mkAppN (mkConst ``BI.pure [u]) #[prop, bibase, φ]
let m ← mkFreshExprSyntheticOpaqueMVar <|
IrisGoal.toExpr { u, prop, bi, hyps, goal := mkAppN (mkConst ``wand [u]) #[prop, bibase, p, goal], .. }
let pf := mkAppN (mkConst ``pure_revert [u]) #[prop, bi, e, goal, φ, m]
mvarId.assign pf
replaceMainGoal [m.mvarId!]
else
let v ← Meta.getLevel φ
let Φ ← mapForallTelescope' (λ t _ => do
let (some ig) := parseIrisGoal? t | throwError "not in proof mode"
return ig.goal
) (Expr.mvar mvarId)
let m ← mkFreshExprSyntheticOpaqueMVar <|
IrisGoal.toExpr { u, prop, bi, hyps, goal := mkAppN (mkConst ``BI.forall [u, v]) #[prop, bibase, φ, Φ], ..}
let pf := mkAppN (mkConst ``forall_revert [u, v]) #[prop, φ, bi, e, Φ, m]
mvarId.assign pf
replaceMainGoal [m.mvarId!]
Whenever I tried using Qq instead of the cumbersome notation used above, I got cryptic errors like
unquoteExpr: match ldecl with
| LocalDecl.cdecl index fvarId userName t bi kind => t
| LocalDecl.ldecl index fvarId userName t value nonDep kind => t : Expr
so I had to build expressions in the less convenient manner. I realise that this is not ideal since Qq is used across iris-lean for tasks like these. If anyone has an idea how this could be remedied or is able to submit a PR to my fork with a Qq based implementation it would be greatly appreciated.
Mario Carneiro (Jul 04 2025 at 23:33):
do you have a MWE of a bad Qq version?
Mario Carneiro (Jul 04 2025 at 23:34):
the problem is most likely using let where you should use have to construct a Qq value using non-Qq functions
Oliver Soeser (Jul 05 2025 at 10:59):
Thanks! That was indeed the issue
Oliver Soeser (Jul 05 2025 at 11:00):
What is the difference between have and let with regards to Qq?
Mario Carneiro (Jul 05 2025 at 11:12):
Qq tries to introspect lets when constructing the embedded proof context, and it gets confused when it finds something defined using unapproved functions
Mario Carneiro (Jul 05 2025 at 11:12):
this is probably a Qq bug
Last updated: Dec 20 2025 at 21:32 UTC