Zulip Chat Archive

Stream: Is there code for X?

Topic: Types up to variable renaming


Anthony Bordg (Apr 01 2025 at 16:20):

Is there code for determining whether two types are the same (say, up to definitional equality, or maybe even literally) up to renaming of the variables that appear in these types?

Ruben Van de Velde (Apr 01 2025 at 16:22):

Equality of types is not likely to be a concept you want to work with

Anthony Bordg (Apr 01 2025 at 16:28):

(This is not for a formalization project).

Yaël Dillies (Apr 01 2025 at 16:31):

Maybe this question belongs in #metaprogramming / tactics ?

Anthony Bordg (Apr 01 2025 at 16:34):

Yes, possibly; since there may already exist some code for that (e.g. in Lean.Meta?) I thought I should try here first.

Kyle Miller (Apr 01 2025 at 16:36):

Could you give some examples of interesting pairs with answers of 'yes' and 'no'? There are a few things you could be meaning here, and that would pin it down (and give people some test cases to work toward)

Jireh Loreaux (Apr 01 2025 at 16:38):

The implementation of docs#Lean.Parser.Tactic.guardTarget is probably relevant. isn't renaming just α-equivalence?

Kyle Miller (Apr 01 2025 at 17:08):

@Jireh Loreaux If I remember correctly, all that means is that it uses ==, which ignores binder names; if you check just the de Bruijn indices you get alpha equivalence checking for free.

Kyle Miller (Apr 01 2025 at 17:09):

If there were a way to reliably abstract the variables to create lambdas that close them, in some fixed order, that would be a way to check for this kind of alpha equivalence.

Kyle Miller (Apr 01 2025 at 17:10):

A reason I'm asking for some positive and negative pairs is that I'd like to see what's special about types vs general expressions.

Yaël Dillies (Apr 01 2025 at 19:00):

Yaël Dillies said:

Maybe this question belongs in #metaprogramming / tactics ?

I'm just suggesting this because which stream you post in influences the default reply that ruben-bot posts :robot:

Ruben Van de Velde (Apr 01 2025 at 19:09):

:robot:

Anthony Bordg (Apr 03 2025 at 09:12):

Jireh Loreaux said:

The implementation of docs#Lean.Parser.Tactic.guardTarget is probably relevant. isn't renaming just α-equivalence?

Yes, this is simply α\alpha-equivalence. I will try to refine what I really want to achieve, but α\alpha-equiv is certainly part of it.

Anthony Bordg (Apr 25 2025 at 17:25):

One limitation of #guard_expr e =ₐ e' is that it expects two pure expressions e and e'. Can one use #guard_expr with the outputs of some function (that would take as input the name of a def/theorem and returns its associated expression as output)?

Aaron Liu (Apr 25 2025 at 17:27):

Maybe by_elab?

Anthony Bordg (Apr 25 2025 at 17:29):

Kyle Miller said:

A reason I'm asking for some positive and negative pairs is that I'd like to see what's special about types vs general expressions.

If you imply that I should consider the lambda expression associated with an identifier instead of its type, I think you're right.

Eric Wieser (Apr 26 2025 at 12:52):

Or possibly delta%?

Anthony Bordg (Apr 28 2025 at 10:09):

by_elab seems to work fine. For instance:

def name1 :   (  )   := λ n f  f n
def name2 :   (  )   := λ m g  g m

def getDeclExpr (n : Name) : MetaM Expr := do
  let env  getEnv
  match env.find? n with
  | some decl =>
    match decl.value? with
    | some val => return val
    | none     => throwError "Declaration {n} has no value (might be opaque or a constant)"
  | none => throwError "Declaration {n} not found"

#guard_expr (by_elab getDeclExpr `name1) =ₐ (by_elab getDeclExpr `name2)

Last updated: May 02 2025 at 03:31 UTC