Zulip Chat Archive

Stream: lean4

Topic: MVarId.assign vs IsDefEq


Floris van Doorn (Feb 26 2025 at 16:51):

The docstring for docs#Lean.MVarId.assign suggest to use docs#Lean.Meta.isDefEq instead. However, this doesn't have the same behavior for me:

import Lean.Elab.Tactic.Simp

open Lean Meta Elab Tactic Term

elab "abstract" tacs:ppDedent(tacticSeq) : tactic => do
  let target  getMainTarget
  let goal  getMainGoal
  let newGoal  mkFreshExprMVar target
  setGoals [newGoal.mvarId!]
  evalTactic tacs
  let newGoal  instantiateMVars newGoal
  let newMVars  getMVars newGoal
  -- _ ← goal.assign newGoal -- uncomment this line and the kernel error disappears
  _  isDefEq (mkMVar goal) newGoal
  setGoals newMVars.toList

/--
error: unsolved goals
case left
f : True ∧ True → Nat
n : Nat
⊢ True

case right
f : True ∧ True → Nat
n : Nat
⊢ True
---
error: (kernel) declaration has metavariables '_example'
-/
#guard_msgs in
example (f : True  True  Nat) (n : Nat) :
  n = f (by abstract constructor) := sorry

The isDefEq generates a kernel error, while the assign doesn't. What causes the difference? Am I doing something wrong? (This is a bare-bones version of #22296, and I think I can safely use assign in this case.)

Eric Wieser (Feb 26 2025 at 16:56):

(deleted)

Aaron Liu (Feb 26 2025 at 16:59):

isDefEq does not assign synthetic opaque metavariables, so it is resolved with proof irrelevance.

Eric Wieser (Feb 26 2025 at 17:00):

withAssignableSyntheticOpaque <| isDefEq indeed makes it work

Kyle Miller (Feb 26 2025 at 17:57):

What I usually see is doing isDefEq on the types, and then using MVarId.assign if that succeeds. The batteries function docs#Lean.MVarId.assignIfDefeq does this for you.

MVarId.assign does no checking of anything (not even occurs checks), and I think it probably shouldn't be used by metaprogrammers.

Floris van Doorn (Feb 27 2025 at 00:29):

Aaron Liu said:

isDefEq does not assign synthetic opaque metavariables, so it is resolved with proof irrelevance.

Thanks!

Is there already a place where I can learn what the different kinds metavariables are, so that I can learn what this means? (The reference manual currently doesn't, but I just opened leanprover/reference-manual#329 asking for it.)

Kyle Miller (Feb 27 2025 at 00:48):

There's at least the docstring to docs#Lean.MetavarKind

Synthetic mvars have a docs#Lean.Elab.Term.SyntheticMVarKind entry

Synthetic opaque metavariables are generally used for goals. They exist because unification/elaboration might otherwise solve for a goal metavariable using an unassigned non-goal metavariable, causing the goal to disappear from the goal list.


Last updated: May 02 2025 at 03:31 UTC