Zulip Chat Archive

Stream: general

Topic: Turning a datatype expression into a Prop


l1mey (Sep 07 2025 at 08:14):

Is there a way to turn an expression AST into a proposition, for example over the naturals? Here is some code below that it would look as:

inductive Inst : Type where
  | const : (v : Nat)  Inst
  | add : Inst  Inst  Inst
  | sub : Inst  Inst  Inst
  | hole : String  Inst

def lhs : Inst := .add (.hole "x") (.hole "y")
def rhs : Inst := .add (.hole "y") (.hole "x")

theorem equal : lhs.func = rhs.func :=
  funext x y
  ...

Niels Voss (Sep 07 2025 at 09:21):

Sorry, I'm not quite sure what you're asking. Did you want help proving equal? Also, what is the definition of Inst.func?

l1mey (Sep 07 2025 at 20:13):

I'm wondering how I would write Inst.func, it would take in an Inst and create a function with an argument for every different hole and return that. Proving equal is just an example. Am I forced to use metaprogramming here?

Aaron Liu (Sep 07 2025 at 20:18):

can you give an example

Aaron Liu (Sep 07 2025 at 20:18):

what function will lhs.func be

l1mey (Sep 07 2025 at 20:20):

def lhs_func (x y : Nat) : Nat := x + y

Aaron Liu (Sep 07 2025 at 20:28):

how do you determine which strings correspond to which arguments

l1mey (Sep 07 2025 at 20:30):

Probably the first argument from the "left" which is x goes first. But that's an implementation detail. My question is if I am forced to use metaprogramming to construct such an expression and how would I do so.

Aaron Liu (Sep 07 2025 at 20:43):

it is possible to construct the function without metaprogramming

Aaron Liu (Sep 07 2025 at 20:44):

basically, define it recursively by pattern matching

Aaron Liu (Sep 07 2025 at 20:44):

you will probably have to use some sort of monad to keep track of which holes are which variables

Ilmārs Cīrulis (Sep 07 2025 at 20:48):

This doesn't work for you, right?

import Mathlib

inductive Inst : Type where
  | const : (v : Nat)  Inst
  | add : Inst  Inst  Inst
  | sub : Inst  Inst  Inst
  | hole : String  Inst

def meaning := String  Nat

def eval (M : meaning) (A : Inst) : Nat :=
  match A with
  | Inst.const v => v
  | Inst.add X Y => eval M X + eval M Y
  | Inst.sub X Y => eval M X - eval M Y
  | Inst.hole s => M s

def equivalent (A B : Inst): Prop :=
  forall (M : meaning), eval M A = eval M B

def lhs : Inst := .add (.hole "x") (.hole "y")
def rhs : Inst := .add (.hole "y") (.hole "x")

theorem identity : equivalent lhs rhs := by
  unfold lhs rhs
  intros M
  simp [eval]
  rw [add_comm]

I agree with Aaron Liu that it should be possible to construct what you want, of course.

Ilmārs Cīrulis (Sep 07 2025 at 20:50):

But I'm probably too slow to do it fast enough. :sweat_smile:

l1mey (Sep 07 2025 at 20:58):

After the simp [eval] it does give

M : meaning
 M "x" + M "y" = M "y" + M "x"

This is okay for me, but it would be nicer to have a normal Lean expression.

Aaron Liu (Sep 07 2025 at 20:58):

this is a normal Lean expression???

Aaron Liu (Sep 07 2025 at 20:59):

what exactly are you looking for?

l1mey (Sep 07 2025 at 21:00):

def lhs.func (x y : Nat) : Nat := x + y
def rhs.func (x y : Nat) : Nat := y + x

which I'm guessing is only possible with metaprogramming.

Aaron Liu (Sep 07 2025 at 21:01):

it's possible without metaprogramming (but you won't be able to control the variable names)

Aaron Liu (Sep 07 2025 at 21:02):

it's just really, a weird thing to do?

Aaron Liu (Sep 07 2025 at 21:03):

by the way, I mean up to defeq of course

Aaron Liu (Sep 07 2025 at 21:03):

so you'll be able to do def lhs.func := Inst.func lhs and you'll be able to do theorem lhs.func_def : lhs.func = fun x y => x + y := rfl


Last updated: Dec 20 2025 at 21:32 UTC