DeBruijnExSubstSized.agda 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. {-# OPTIONS --sized-types #-}
  2. module Termination.Sized.DeBruijnExSubstSized where
  3. open import Data.Nat
  4. open import Data.Maybe
  5. open import Function -- using (_∘_) -- composition, identity
  6. open import Relation.Binary.PropositionalEquality hiding ( subst )
  7. open ≡-Reasoning
  8. open import Size
  9. open import Termination.Sized.DeBruijnBase
  10. -- untyped de Bruijn terms
  11. data LamE (A : Set) : Size -> Set where
  12. varE : {ι : _} -> A -> LamE A (↑ ι)
  13. appE : {ι : _} -> LamE A ι -> LamE A ι -> LamE A (↑ ι)
  14. absE : {ι : _} -> LamE (Maybe A) ι -> LamE A (↑ ι)
  15. flatE : {ι : _} -> LamE (LamE A ι) ι -> LamE A (↑ ι)
  16. -- functoriality of LamE
  17. lamE : {A B : Set} -> (A -> B) -> {ι : _} -> LamE A ι -> LamE B ι
  18. lamE f (varE a) = varE (f a)
  19. lamE f (appE t1 t2) = appE (lamE f t1) (lamE f t2)
  20. lamE f (absE r) = absE (lamE (fmap f) r)
  21. lamE f (flatE r) = flatE (lamE (lamE f) r)
  22. eval : {ι : _} -> {A : Set} -> LamE A ι -> Lam A
  23. eval (varE a) = var a
  24. eval (appE t1 t2) = app (eval t1) (eval t2)
  25. eval (absE r) = abs (eval r)
  26. eval (flatE r) = subst (eval) (eval r)
  27. -- Theorem (naturality of eval): eval ∘ lamE f ≡ lam f ∘ eval
  28. evalNAT : {A B : Set}(f : A -> B) -> {ι : _} -> (t : LamE A ι) ->
  29. eval (lamE f t) ≡ lam f (eval t)
  30. evalNAT f (varE a) = refl
  31. evalNAT f (appE t1 t2) = begin
  32. eval (lamE f (appE t1 t2))
  33. ≡⟨ refl ⟩
  34. eval (appE (lamE f t1) (lamE f t2))
  35. ≡⟨ refl ⟩
  36. app (eval (lamE f t1)) (eval (lamE f t2))
  37. ≡⟨ cong (\ x -> app x (eval (lamE f t2))) (evalNAT f t1) ⟩
  38. app (lam f (eval t1)) (eval (lamE f t2))
  39. ≡⟨ cong (\ x -> app (lam f (eval t1)) x) (evalNAT f t2) ⟩
  40. app (lam f (eval t1)) (lam f (eval t2))
  41. ≡⟨ refl ⟩
  42. lam f (app (eval t1) (eval t2))
  43. ≡⟨ refl ⟩
  44. lam f (eval (appE t1 t2))
  45. evalNAT f (absE r) = begin
  46. eval (lamE f (absE r))
  47. ≡⟨ refl ⟩
  48. eval (absE (lamE (fmap f) r))
  49. ≡⟨ refl ⟩
  50. abs (eval (lamE (fmap f) r))
  51. ≡⟨ cong abs (evalNAT (fmap f) r) ⟩
  52. abs (lam (fmap f) (eval r))
  53. ≡⟨ refl ⟩
  54. lam f (abs (eval r))
  55. ≡⟨ refl ⟩
  56. lam f (eval (absE r))
  57. -- in the following case, one manual size annotation is needed on the RHS
  58. -- it is for the first application of the I.H.
  59. evalNAT f (flatE {ι} r) = begin
  60. eval (lamE f (flatE r))
  61. ≡⟨ refl ⟩
  62. eval (flatE (lamE (lamE f) r))
  63. ≡⟨ refl ⟩
  64. subst eval (eval (lamE (lamE f) r))
  65. ≡⟨ cong (subst (eval {ι})) (evalNAT (lamE f) r) ⟩
  66. subst eval (lam (lamE f) (eval r))
  67. ≡⟨ substLaw1 (lamE f) eval (eval r) ⟩
  68. subst (eval ∘ lamE f) (eval r)
  69. ≡⟨ substExt (evalNAT f) (eval r) ⟩
  70. subst (lam f ∘ eval) (eval r)
  71. ≡⟨ substLaw2 f eval (eval r) ⟩
  72. lam f (subst eval (eval r))
  73. ≡⟨ refl ⟩
  74. lam f (eval (flatE r))
  75. evalNATcor : {A : Set}{ι : _}(ee : LamE (LamE A ι) ι) ->
  76. subst id (eval (lamE eval ee)) ≡ eval (flatE ee)
  77. evalNATcor ee = begin
  78. subst id (eval (lamE eval ee))
  79. ≡⟨ cong (subst id) (evalNAT eval ee) ⟩
  80. subst id (lam eval (eval ee))
  81. ≡⟨ substLaw1 eval id (eval ee) ⟩
  82. subst eval (eval ee)
  83. ≡⟨ refl ⟩
  84. eval (flatE ee)