[Agda] Associativity for free!

James Chapman james at cs.ioc.ee
Fri Nov 4 14:22:07 CET 2011


I should have said this follows the structure of Altenkirch and Reus' proof for untyped terms.

Also, this agda proof is described in the accepted draft paper "Relative Monads formalized" (http://www.cs.ioc.ee/~james/Publications.html)  which I should really finish, well, today.

James

On Nov 4, 2011, at 1:29 PM, James Chapman wrote:

> Dear Alan + all,
> 
> On Wed, Nov 2, 2011 at 6:26 PM, Alan Jeffrey <ajeffrey at bell-labs.com> wrote:
>> My original motivation for "associativity for free" was properties about
>> lambda-calculi. I've now worked through some of the details, and here is the
>> syntax of the simply-typed lambda-calculus.
> 
> For contrast, here's renaming and substitution for well typed lambda
> terms. Renamings are just functions from variables to variables,
> substitutions are just functions form variables to terms. No clever
> representations here, no clever getting them both as a instance of a
> more general operation, I just wanted to use the interface to
> substitution suggested by the (relative) monadic nature of well-typed
> terms. The proof is a simplification of the paper proof in Altenkirch
> and Reus' paper "Monadic presentations of lambda terms using
> generalized inductive types" and follows the approximately the same
> structure. The development goes up to proving that the substitution
> operation commutes with composition of substitutions (just composition
> of functions) -- the third monad law. It's about 170 lines in all
> including the utilities prelude.
> 
> module WellTypedTerms where
> 
> -- Utilities
> data _≅_ {A : Set} : {A' : Set} → A → A' → Set where
>  refl : {a : A} → a ≅ a
> 
> trans : ∀{A A' A''}{a : A}{a' : A'}{a'' : A''} → a ≅ a' → a' ≅ a'' → a ≅ a''
> trans refl p = p
> 
> sym : ∀{A A'}{a : A}{a' : A'} → a ≅ a' → a' ≅ a
> sym refl = refl
> 
> resp : ∀{A}{B : A → Set}(f : ∀ a → B a){a a' : A} → a ≅ a' → f a ≅ f a'
> resp f refl = refl
> 
> resp2 : ∀{A}{B : A → Set}{C : (x : A) → B x → Set}(f : (x : A)(y : B
> x) → C x y){a a' : A} → a ≅ a' → {b : B a}{b' : B a'} → b ≅ b' → f a b
> ≅ f a' b'
> resp2 f refl refl = refl
> 
> _•_ : {A : Set}{B : A → Set}{C : (a : A) → B a → Set} →
>      (∀{a} b → C a b) → (g : (∀ a → B a)) → ∀ a → C a (g a)
> f • g = λ a → f (g a)
> 
> id : {A : Set} → A → A
> id a = a
> 
> postulate iext : {A : Set}{B B' : A → Set}{f : ∀ {a} → B a}{g : ∀{a} → B' a} →
>                 (∀ a → f {a} ≅ g {a}) →
>                 _≅_ { {a : A} → B a} { {a : A} → B' a} f g
> 
> postulate ext : {A : Set}{B B' : A → Set}{f : ∀ a → B a}{g : ∀ a → B' a} →
>                (∀ a → f a ≅ g a) → f ≅ g
> 
> --Well type lambda terms
> 
> data Ty : Set where
>  ι   : Ty
>  _⇒_ : Ty → Ty → Ty
> 
> data Con : Set where
>  ε   : Con
>  _<_ : Con → Ty → Con
> 
> data Var : Con → Ty → Set where
>  vz : ∀{Γ σ} → Var (Γ < σ) σ
>  vs : ∀{Γ σ τ} → Var Γ σ → Var (Γ < τ) σ
> 
> data Tm : Con → Ty → Set where
>  var : ∀{Γ σ} → Var Γ σ → Tm Γ σ
>  app : ∀{Γ σ τ} → Tm Γ (σ ⇒ τ) → Tm Γ σ → Tm Γ τ
>  lam : ∀{Γ σ τ} → Tm (Γ < σ) τ → Tm Γ (σ ⇒ τ)
> 
> -- Renaming
> 
> Ren : Con → Con → Set
> Ren Γ Δ = ∀ {σ} → Var Γ σ → Var Δ σ
> 
> renId : ∀{Γ} → Ren Γ Γ
> renId = id
> 
> renComp : ∀{B Γ Δ} → Ren Γ Δ → Ren B Γ → Ren B Δ
> renComp f g = f • g
> 
> wk : ∀{Γ Δ σ} → Ren Γ Δ → Ren (Γ < σ) (Δ < σ)
> wk f vz     = vz
> wk f (vs i) = vs (f i)
> 
> ren : ∀{Γ Δ} → Ren Γ Δ → ∀ {σ} → Tm Γ σ → Tm Δ σ
> ren f (var x)   = var (f x)
> ren f (app t u) = app (ren f t) (ren f u)
> ren f (lam t)   = lam (ren (wk f) t)
> 
> wkid : ∀{Γ σ τ}(x : Var (Γ < τ) σ) → wk renId x ≅ renId x
> wkid vz     = refl
> wkid (vs x) = refl
> 
> renid : ∀{Γ σ}(t : Tm Γ σ) → ren renId t ≅ id t
> renid (var x)   = refl
> renid (app t u) = resp2 app (renid t) (renid u)
> renid (lam t) = resp lam (trans (resp (λ (f : Ren _ _) → ren f t)
>                                      (iext (λ _ → ext wkid)))
>                                (renid t))
> 
> wkcomp : ∀ {B Γ Δ}(f : Ren Γ Δ)(g : Ren B Γ){σ τ}(x : Var (B < σ) τ) →
>            wk (renComp f g) x ≅ renComp (wk f) (wk g) x
> wkcomp f g vz     = refl
> wkcomp f g (vs i) = refl
> 
> rencomp : ∀ {B Γ Δ}(f : Ren Γ Δ)(g : Ren B Γ){σ}(t : Tm B σ) →
>            ren (renComp f g) t ≅ (ren f • ren g) t
> rencomp f g (var x)   = refl
> rencomp f g (app t u) = resp2 app (rencomp f g t) (rencomp f g u)
> rencomp f g (lam t)   = resp lam (trans (resp (λ (f : Ren _ _) → ren f t)
>                                              (iext λ _ → ext (wkcomp f g)))
>                                        (rencomp (wk f) (wk g) t))
> 
> -- Substitutions
> 
> Sub : Con → Con → Set
> Sub Γ Δ = ∀{σ} → Var Γ σ → Tm Δ σ
> 
> lift : ∀{Γ Δ σ} → Sub Γ Δ → Sub (Γ < σ) (Δ < σ)
> lift f vz     = var vz
> lift f (vs x) = ren vs (f x)
> 
> sub : ∀{Γ Δ} → Sub Γ Δ → ∀{σ} → Tm Γ σ → Tm Δ σ
> sub f (var x)   = f x
> sub f (app t u) = app (sub f t) (sub f u)
> sub f (lam t)   = lam (sub (lift f) t)
> 
> subId : ∀{Γ} → Sub Γ Γ
> subId = var
> 
> subComp : ∀{B Γ Δ} → Sub Γ Δ → Sub B Γ → Sub B Δ
> subComp f g = sub f • g
> 
> liftid : ∀{Γ σ τ}(x : Var (Γ < σ) τ) → lift subId x ≅ subId x
> liftid vz     = refl
> liftid (vs x) = refl
> 
> -- first monad law, the second holds definitionally
> subid : ∀{Γ σ}(t : Tm Γ σ) → sub subId t ≅ id t
> subid (var x)   = refl
> subid (app t u) = resp2 app (subid t) (subid u)
> subid (lam t)   = resp lam (trans (resp (λ (f : Sub _ _) → sub f t)
>                                        (iext λ _ → ext liftid))
>                                  (subid t))
> 
> liftwk : ∀{B Γ Δ}(f : Sub Γ Δ)(g : Ren B Γ){σ τ}(x : Var (B < σ) τ) →
>            (lift f • wk g) x ≅ lift (f • g) x
> liftwk f g vz     = refl
> liftwk f g (vs x) = refl
> 
> subren : ∀{B Γ Δ}(f : Sub Γ Δ)(g : Ren B Γ){σ}(t : Tm B σ) →
>         (sub f • ren g) t ≅ sub (f • g) t
> subren f g (var x)   = refl
> subren f g (app t u) = resp2 app (subren f g t) (subren f g u)
> subren f g (lam t)   = resp lam (trans (subren (lift f) (wk g) t)
>                                       (resp (λ (f : Sub _ _) → sub f t)
>                                             (iext λ _ → ext (liftwk f g))))
> 
> renwklift : ∀{B Γ Δ}(f : Ren Γ Δ)(g : Sub B Γ){σ τ}(x : Var (B < σ) τ) →
>               (ren (wk f) • lift g) x ≅ lift (ren f • g) x
> renwklift f g vz     = refl
> renwklift f g (vs x) = trans (sym (rencomp (wk f) vs (g x)))
>                                (rencomp vs f (g x))
> 
> rensub : ∀{B Γ Δ}(f : Ren Γ Δ)(g : Sub B Γ){σ}(t : Tm B σ) →
>         (ren f •  sub g) t ≅ sub (ren f • g) t
> rensub f g (var x)   = refl
> rensub f g (app t u) = resp2 app (rensub f g t) (rensub f g u)
> rensub f g (lam t)   = resp lam (trans (rensub (wk f) (lift g) t)
>                                       (resp (λ (f : Sub _ _) → sub f t)
>                                             (iext λ _ →
>                                               ext (renwklift f g))))
> 
> liftcomp : ∀{B Γ Δ}(f : Sub Γ Δ)(g : Sub B Γ){σ τ}(x : Var (B < σ) τ) →
>           lift (subComp f g) x ≅ subComp (lift f) (lift g) x
> liftcomp f g vz     = refl
> liftcomp f g (vs x) = trans (rensub vs f (g x))
>                            (sym (subren (lift f) vs (g x)))
> 
> 
> -- third monad law
> subcomp : ∀{B Γ Δ}(f : Sub Γ Δ)(g : Sub B Γ){σ}(t : Tm B σ) →
>          sub (subComp f g) t ≅ (sub f • sub g) t
> subcomp f g (var x)   = refl
> subcomp f g (app t u) = resp2 app (subcomp f g t) (subcomp f g u)
> subcomp f g (lam t)   = resp lam (trans (resp (λ (f : Sub _ _) → sub f t)
>                                              (iext λ _ → ext (liftcomp f g)))
>                                        (subcomp (lift f) (lift g) t))
> 
> Regards,
> 
> James



More information about the Agda mailing list