|
| 1 | +import LeanSubst |
| 2 | + |
| 3 | +namespace LeanSubst.Examples.LambdaCalc |
| 4 | + |
| 5 | + inductive Term where |
| 6 | + | var : Nat -> Term |
| 7 | + | app : Term -> Term -> Term |
| 8 | + | lam : Term -> Term |
| 9 | + |
| 10 | + prefix:100 ":λ " => Term.lam |
| 11 | + infixl:65 " :@ " => Term.app |
| 12 | + |
| 13 | + @[coe] |
| 14 | + def Term.from_action : Subst.Action Term -> Term |
| 15 | + | re y => var y |
| 16 | + | su t => t |
| 17 | + |
| 18 | + @[simp, grind =] |
| 19 | + theorem Term.from_action_id {n} : from_action (+0 n) = var n := by |
| 20 | + simp [from_action, Subst.id] |
| 21 | + |
| 22 | + @[simp, grind =] |
| 23 | + theorem Term.from_action_succ {n} : from_action (+1 n) = var (n + 1) := by |
| 24 | + simp [from_action, Subst.succ] |
| 25 | + |
| 26 | + @[simp, grind =] |
| 27 | + theorem Term.from_acton_re {n} : from_action (re n) = var n := by simp [from_action] |
| 28 | + |
| 29 | + @[simp, grind =] |
| 30 | + theorem Term.from_action_su {t} : from_action (su t) = t := by simp [from_action] |
| 31 | + |
| 32 | + instance instCoe_SubstActionTerm_Term : Coe (Subst.Action Term) Term where |
| 33 | + coe := Term.from_action |
| 34 | + |
| 35 | + class Kit (A : Type) where |
| 36 | + coe : A -> Term |
| 37 | + lift : (Nat -> A) -> Nat -> A |
| 38 | + |
| 39 | + instance : Kit Nat where |
| 40 | + coe := Term.var |
| 41 | + lift := Ren.lift |
| 42 | + |
| 43 | + instance [RenMap Term] : Kit (Subst.Action Term) where |
| 44 | + coe := Term.from_action |
| 45 | + lift := Subst.lift |
| 46 | + |
| 47 | + @[simp] |
| 48 | + def kitmap {A} (σ : Nat -> A) [kit : Kit A] : Term -> Term |
| 49 | + | .var x => kit.coe (σ x) |
| 50 | + | t1 :@ t2 => kitmap σ t1 :@ kitmap σ t2 |
| 51 | + | :λ t => :λ kitmap (kit.lift σ) t |
| 52 | + |
| 53 | + @[simp] |
| 54 | + def rmap (r : Ren) : Term -> Term := kitmap r |
| 55 | + |
| 56 | + instance : RenMap Term where |
| 57 | + rmap := rmap |
| 58 | + |
| 59 | + @[simp] |
| 60 | + def smap (σ : Subst Term) : Term -> Term := kitmap σ |
| 61 | + |
| 62 | + instance SubstMap_Term : SubstMap Term Term where |
| 63 | + smap := smap |
| 64 | + |
| 65 | + @[simp, grind =] |
| 66 | + theorem subst_var {x} {σ : Subst Term} : (Term.var x)[σ] = σ x := by |
| 67 | + simp [SubstMap.smap] |
| 68 | + |
| 69 | + @[simp, grind =] |
| 70 | + theorem subst_app {t1 t2} {σ : Subst Term} : (t1 :@ t2)[σ] = t1[σ] :@ t2[σ] := by |
| 71 | + simp [SubstMap.smap] |
| 72 | + |
| 73 | + @[simp, grind =] |
| 74 | + theorem subst_lam {t} {σ : Subst Term} : (:λ t)[σ] = :λ t[σ.lift] := by |
| 75 | + simp [SubstMap.smap] |
| 76 | + |
| 77 | + @[simp] |
| 78 | + theorem Term.from_action_compose {x} {σ τ : Subst Term} |
| 79 | + : (from_action (σ x))[τ] = from_action ((σ ∘ τ) x) |
| 80 | + := by |
| 81 | + simp [Term.from_action, Subst.compose] |
| 82 | + generalize zdef : σ x = z |
| 83 | + cases z <;> simp [Term.from_action] |
| 84 | + |
| 85 | + theorem apply_id {t : Term} : t[+0] = t := by |
| 86 | + induction t |
| 87 | + all_goals (simp at * <;> try simp [*]) |
| 88 | + |
| 89 | + instance : SubstMapId Term Term where |
| 90 | + apply_id := apply_id |
| 91 | + |
| 92 | + theorem apply_stable (r : Ren) (σ : Subst Term) |
| 93 | + : r = σ -> rmap r = smap σ |
| 94 | + := by subst_solve_stable r, σ |
| 95 | + |
| 96 | + instance : SubstMapStable Term where |
| 97 | + apply_stable := apply_stable |
| 98 | + |
| 99 | + theorem apply_compose {s : Term} {σ τ : Subst Term} : s[σ][τ] = s[σ ∘ τ] := by |
| 100 | + subst_solve_compose Term, s, σ, τ |
| 101 | + |
| 102 | + instance : SubstMapCompose Term Term where |
| 103 | + apply_compose := apply_compose |
| 104 | + |
| 105 | +end LeanSubst.Examples.LambdaCalc |
0 commit comments