Documentation

Cslib.Languages.LambdaCalculus.Named.Untyped.Properties

λ-calculus #

The untyped λ-calculus, with a named representation of variables. This file contains properties of α-equivalence and capture-avoiding substitution.

Main results #

A variable in a term is either free or bound.

@[simp]
theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_unused {Var : Type u} [DecidableEq Var] {m : Term Var} {x y : Var} :
xm.varsm.rename x y = m

Renaming an unused variable has no effect.

@[simp]
theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_same {Var : Type u} [DecidableEq Var] {m : Term Var} {x : Var} :
m.rename x x = m

Renaming a variable to itself has no effect.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_vars_used {Var : Type u} [DecidableEq Var] {m : Term Var} {x y : Var} :
x m.vars(m.rename x y).vars = m.vars.erase x {y}

Renaming a used variable changes the set of variables.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_remove {Var : Type u} [DecidableEq Var] {m : Term Var} {x y : Var} :
x yx(m.rename x y).vars

Renaming removes the variable.

@[simp]
theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_vars {Var : Type u} [DecidableEq Var] {m : Term Var} {x y : Var} :
(m.rename x y).vars = m.vars \ {x} if x m.vars then {y} else

The set of variables after renaming.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_fv {Var : Type u} [DecidableEq Var] {m : Term Var} {x y : Var} :
ym.vars(m.rename x y).fv = m.fv \ {x} if x m.fv then {y} else

The set of free variables after renaming.

@[simp]
theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_concat {Var : Type u} [DecidableEq Var] {m : Term Var} {x y z : Var} :
ym.vars(m.rename x y).rename y z = m.rename x z

Concatenation of renaming.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_comm_fresh {Var : Type u} [DecidableEq Var] {m : Term Var} {x y z w : Var} :
x zym.vars {x, z}wm.vars {x, z}(m.rename x y).rename z w = (m.rename z w).rename x y

Commutativity of renaming distinct variables.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.rename_comm {Var : Type u} [DecidableEq Var] {m : Term Var} {x y z w : Var} :
ym.vars {x, z}wm.vars {x, y, z}(m.rename x y).rename (if z = x then y else z) w = (m.rename z w).rename x y

Commutativity of renaming.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.induction_by_sizeOf {Var : Type u} {C : Term VarProp} (step : ∀ (m : Term Var), (∀ (m1 : Term Var), sizeOf m1 < sizeOf mC m1)C m) (m : Term Var) :
C m

α-equivalent terms have the same size.

α-equivalent terms have the same free variables.

Reflexivity of α-equivalence.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.symm {Var : Type u} [DecidableEq Var] {m n : Term Var} :
m nn m

Symmetry of α-equivalence.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.rename_preserve {Var : Type u} [DecidableEq Var] [HasFresh Var] (m n : Term Var) (x y : Var) :
ym.vars n.varsm n(m.rename x y) (n.rename x y)

Renaming α-equivalent terms produces α-equivalent terms.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.abs_elim {Var : Type u} [DecidableEq Var] [HasFresh Var] {m1 m2 : Term Var} {x1 x2 y : Var} :
ym1.vars m2.vars {x1, x2}(Term.abs x1 m1) (Term.abs x2 m2)(m1.rename x1 y) (m2.rename x2 y)

Elimination rule for α-equivalence of abstractions. It states that if two abstractions are α-equivalent, then their bodies can be renamed to any'' fresh variable y and remain α-equivalent. This is sometimes easier to use than using by_cases on the equivalence, which can only produce the claim for some'' fresh y.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.trans {Var : Type u} [DecidableEq Var] [HasFresh Var] {m n p : Term Var} :
m nn pm p

Transitivity of α-equivalence.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.rename_non_fv {Var : Type u} [DecidableEq Var] [HasFresh Var] {m : Term Var} {x y : Var} :
xm.fvym.varsm (m.rename x y)

Renaming a non-free variable results in an α-equivalent term

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.abs_non_fv {Var : Type u} [DecidableEq Var] [HasFresh Var] {m1 m2 : Term Var} {x1 x2 : Var} :
m1 m2x1m1.fvx2m2.fv(Term.abs x1 m1) (Term.abs x2 m2)

Abstracting over an arbitrary non-free variable results in the same term, modulo α-equivalence.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.abs_rename {Var : Type u} [DecidableEq Var] [HasFresh Var] {m : Term Var} {x y : Var} :
ym.vars {x}(Term.abs x m) (Term.abs y (m.rename x y))

Renaming an abstraction leads to an α-equivalent term.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.Context.complete {Var : Type u} (m : Term Var) :
∃ (c : Context Var) (x : Var), m = c.fill (var x)

Any Term can be obtained by filling a Context with a variable. This proves that Context completely captures the syntax of terms.

The set of variables after filling a context.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.AlphaEquiv.context {Var : Type u} [DecidableEq Var] [HasFresh Var] {m n : Term Var} {c : Context Var} :
m n(c.fill m) (c.fill n)

α-equivalence is preserved under context filling.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.Subst.function_to_relation {Var : Type u} [DecidableEq Var] [HasFresh Var] {m r : Term Var} {x : Var} :
m.Subst x r m[x := r]

The functional definition of substitution satisfies the relational definition of substitution.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.subst.non_free {Var : Type u} [DecidableEq Var] [HasFresh Var] {m r : Term Var} {x : Var} :
xm.fvm[x := r] m

Substituting a non-free variable has no effect.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.subst.abs_fresh {Var : Type u} [DecidableEq Var] [HasFresh Var] {m r : Term Var} {x y z : Var} :
zm.vars r.vars {x, y}(abs y m)[x := r] (abs z (m.rename y z)[x := r])

Modulo α-equivalence, substituting an abstraction falls back to the fresh variable case only. With this lemma, the three cases in the definition of subst can be reduced to one.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.subst.preserve_AlphaEquiv {Var : Type u} [DecidableEq Var] [HasFresh Var] {m m' r r' : Term Var} {x : Var} :
m m'r r'm[x := r] m'[x := r']

Substituting α-equivalent terms produces α-equivalent terms.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.Subst.relation_iff_function {Var : Type u} [DecidableEq Var] [HasFresh Var] {m n r : Term Var} {x : Var} :
m.Subst x r n n m[x := r]

The relational definition of substitution coincides with the functional definition of substitution, modulo α-equivalence.

theorem Cslib.LambdaCalculus.Named.Untyped.Term.subst.commutativity {Var : Type u} [DecidableEq Var] [HasFresh Var] {m r1 r2 : Term Var} {x y : Var} :
xr2.fv {y}m[x := r1][y := r2] m[y := r2][x := r1[y := r2]]

Commutativity of substitution (a.k.a. the substitution lemma)