Zulip Chat Archive

Stream: lean4

Topic: Lean.Meta.isDefEq doesn't know (3 = 3) = true?


Tanner Swett (Jun 30 2023 at 21:23):

I'm trying to write an #assert_eq command that throws an error if its two arguments are not definitionally equal expressions. It uses Lean.meta.isDefEq to try to determine if the arguments are definitionally equal or not. However, isDefEq seems to be telling me that the expression (3 = 3 : Bool) isn't definitionally equal to the expression true. Why not?

Part of me thinks I need to reduce the input expressions, but isn't isDefEq supposed to usually be able to determine whether or not two expressions are definitionally equal without actually reducing them first?

Here's my code:

elab "#assert_eq " l:term:arg r:term:arg : command => do
  let l_equals_r  liftTermElabM <| do
    let l_value  elabTerm (expectedType? := none) l
    let r_value  elabTerm (expectedType? := none) r
    Lean.Meta.isDefEq l_value r_value

  if not l_equals_r then
    throwErrorAt r "The value{Lean.indentD l}\nis not definitionally equal to the value{Lean.indentD r}"

#assert_eq (3 = 3 : Bool) true

Kyle Miller (Jun 30 2023 at 21:54):

It's probably because you're not synthesizing metavariables before doing the defeq check (like with synthesizeSyntheticMVarsNoPostponing). You need this to get Lean to commit to 3 being a Nat, which requires it to use a default OfNat instance.

Kyle Miller (Jun 30 2023 at 21:55):

There's already such a command in Std4 by the way: https://github.com/leanprover/std4/blob/main/Std/Tactic/GuardExpr.lean#L197

Tanner Swett (Jun 30 2023 at 21:57):

Sticking a synthesizeSyntheticMVarsNoPostponing in there seems to do the trick! Thank you!

Tanner Swett (Jun 30 2023 at 22:32):

(also, since I plan to do quite a lot of metaprogramming, I figure it's a good idea to try implementing the simple stuff myself)


Last updated: Dec 20 2023 at 11:08 UTC