Zulip Chat Archive

Stream: lean4

Topic: Unfolding into ite?


Ryan Lahfa (Apr 29 2021 at 14:29):

I'm trying to do some simple program verification using Lean 4 and I have this little de Bruijn indexes formalization:

import Lean
open Classical

inductive LambdaTerm where
| var (val : Nat)
| app (fn: LambdaTerm) (arg: LambdaTerm)
| lambda (body: LambdaTerm)

def allFreeVariablesBoundBy (n: Nat) (t: LambdaTerm): Prop :=
  aux n t 0
where
  aux n t depth : Prop := match t with
| LambdaTerm.var (val := m) => m < n + depth
| LambdaTerm.app (fn := fn) (arg := arg) => aux n fn depth  aux n arg depth
| LambdaTerm.lambda (body := fn) => aux n fn (depth + 1)

macro "C[" n:term "](" t:term ")" : term => `(allFreeVariablesBoundBy $n $t)
def isClosedTerm (t: LambdaTerm): Prop := C[0](t)

def substitute (t: LambdaTerm) (index: Nat) (expr: LambdaTerm): LambdaTerm :=
  aux index t 0
where
  aux i t depth : LambdaTerm := match t with
  | LambdaTerm.var (val := m) => if i + depth = m then expr else t
  | LambdaTerm.app fn arg => LambdaTerm.app (aux i fn depth) (aux i arg depth)
  | LambdaTerm.lambda body => LambdaTerm.lambda (aux i body (depth + 1))

theorem substitute.idOnClosed (depth: Nat) (t: LambdaTerm) (ht: C[depth](t)) (index: Nat) (expr: LambdaTerm) (hexpr: isClosedTerm expr): substitute.aux t index expr depth = t :=
by induction t with
| var m => have p: index + depth  m := sorry; admit
| app fn arg h_fn h_arg => admit
| lambda body h_body => admit

In substitute.idOnClosed, I'm trying to reduce the goal to its (if i + depth = m then expr else LambdaTerm.var m) = LambdaTerm.var m form so I can apply ifNeg and rfl, but I'm unable to see how to do it. I also searched here but without any luck.

I tried change which is not implemented, simp, dsimp and other similar things, and re-read the tests/examples provided in the repository.

Mario Carneiro (Apr 29 2021 at 14:52):

Although change is not implemented, show exists and does the same thing

Mario Carneiro (Apr 29 2021 at 14:58):

You've done induction on the wrong variable, t and expr are flipped

Mario Carneiro (Apr 29 2021 at 14:59):

theorem substitute.idOnClosed (depth: Nat) (t: LambdaTerm) (ht: C[depth](t))
  (index: Nat) (expr: LambdaTerm) (hexpr: isClosedTerm expr):
  substitute.aux expr index t depth = t :=
by induction t with
| var m => have p: index + depth  m := sorry; simp [aux, p]
| app fn arg h_fn h_arg => admit
| lambda body h_body => admit

Ryan Lahfa (Apr 29 2021 at 15:06):

Mario Carneiro said:

theorem substitute.idOnClosed (depth: Nat) (t: LambdaTerm) (ht: C[depth](t))
  (index: Nat) (expr: LambdaTerm) (hexpr: isClosedTerm expr):
  substitute.aux expr index t depth = t :=
by induction t with
| var m => have p: index + depth  m := sorry; simp [aux, p]
| app fn arg h_fn h_arg => admit
| lambda body h_body => admit

Uh! Many thanks!


Last updated: Dec 20 2023 at 11:08 UTC