123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- {-# OPTIONS --sized-types #-}
- module Termination.Sized.DeBruijnExSubstSized where
- open import Data.Nat
- open import Data.Maybe
- open import Function -- using (_∘_) -- composition, identity
- open import Relation.Binary.PropositionalEquality hiding ( subst )
- open ≡-Reasoning
- open import Size
- open import Termination.Sized.DeBruijnBase
- -- untyped de Bruijn terms
- data LamE (A : Set) : Size -> Set where
- varE : {ι : _} -> A -> LamE A (↑ ι)
- appE : {ι : _} -> LamE A ι -> LamE A ι -> LamE A (↑ ι)
- absE : {ι : _} -> LamE (Maybe A) ι -> LamE A (↑ ι)
- flatE : {ι : _} -> LamE (LamE A ι) ι -> LamE A (↑ ι)
- -- functoriality of LamE
- lamE : {A B : Set} -> (A -> B) -> {ι : _} -> LamE A ι -> LamE B ι
- lamE f (varE a) = varE (f a)
- lamE f (appE t1 t2) = appE (lamE f t1) (lamE f t2)
- lamE f (absE r) = absE (lamE (fmap f) r)
- lamE f (flatE r) = flatE (lamE (lamE f) r)
- eval : {ι : _} -> {A : Set} -> LamE A ι -> Lam A
- eval (varE a) = var a
- eval (appE t1 t2) = app (eval t1) (eval t2)
- eval (absE r) = abs (eval r)
- eval (flatE r) = subst (eval) (eval r)
- -- Theorem (naturality of eval): eval ∘ lamE f ≡ lam f ∘ eval
- evalNAT : {A B : Set}(f : A -> B) -> {ι : _} -> (t : LamE A ι) ->
- eval (lamE f t) ≡ lam f (eval t)
- evalNAT f (varE a) = refl
- evalNAT f (appE t1 t2) = begin
- eval (lamE f (appE t1 t2))
- ≡⟨ refl ⟩
- eval (appE (lamE f t1) (lamE f t2))
- ≡⟨ refl ⟩
- app (eval (lamE f t1)) (eval (lamE f t2))
- ≡⟨ cong (\ x -> app x (eval (lamE f t2))) (evalNAT f t1) ⟩
- app (lam f (eval t1)) (eval (lamE f t2))
- ≡⟨ cong (\ x -> app (lam f (eval t1)) x) (evalNAT f t2) ⟩
- app (lam f (eval t1)) (lam f (eval t2))
- ≡⟨ refl ⟩
- lam f (app (eval t1) (eval t2))
- ≡⟨ refl ⟩
- lam f (eval (appE t1 t2))
- ∎
- evalNAT f (absE r) = begin
- eval (lamE f (absE r))
- ≡⟨ refl ⟩
- eval (absE (lamE (fmap f) r))
- ≡⟨ refl ⟩
- abs (eval (lamE (fmap f) r))
- ≡⟨ cong abs (evalNAT (fmap f) r) ⟩
- abs (lam (fmap f) (eval r))
- ≡⟨ refl ⟩
- lam f (abs (eval r))
- ≡⟨ refl ⟩
- lam f (eval (absE r))
- ∎
- -- in the following case, one manual size annotation is needed on the RHS
- -- it is for the first application of the I.H.
- evalNAT f (flatE {ι} r) = begin
- eval (lamE f (flatE r))
- ≡⟨ refl ⟩
- eval (flatE (lamE (lamE f) r))
- ≡⟨ refl ⟩
- subst eval (eval (lamE (lamE f) r))
- ≡⟨ cong (subst (eval {ι})) (evalNAT (lamE f) r) ⟩
- subst eval (lam (lamE f) (eval r))
- ≡⟨ substLaw1 (lamE f) eval (eval r) ⟩
- subst (eval ∘ lamE f) (eval r)
- ≡⟨ substExt (evalNAT f) (eval r) ⟩
- subst (lam f ∘ eval) (eval r)
- ≡⟨ substLaw2 f eval (eval r) ⟩
- lam f (subst eval (eval r))
- ≡⟨ refl ⟩
- lam f (eval (flatE r))
- ∎
- evalNATcor : {A : Set}{ι : _}(ee : LamE (LamE A ι) ι) ->
- subst id (eval (lamE eval ee)) ≡ eval (flatE ee)
- evalNATcor ee = begin
- subst id (eval (lamE eval ee))
- ≡⟨ cong (subst id) (evalNAT eval ee) ⟩
- subst id (lam eval (eval ee))
- ≡⟨ substLaw1 eval id (eval ee) ⟩
- subst eval (eval ee)
- ≡⟨ refl ⟩
- eval (flatE ee)
- ∎
|