module Subst_list where open import Ty using (Var; Con; _β‡’_; 𝕋; 𝕋𝕋; 𝕋𝕋s; 𝕍ar; _β‰Ÿt_) open import Relation.Nullary.Decidable using (⌊_βŒ‹) open import Data.List using (List; []; _∷_; filter; map) open import Data.Product using (_Γ—_; _,_; proj₁; projβ‚‚; βˆƒ; Ξ£) open import Data.Maybe.Core using (Maybe; nothing; just) open import Data.Bool using (false) open import Data.Nat using (_β‰Ÿ_) open import Relation.Nullary.Core using (yes; no) open import Function using (_∘_) open import Relation.Binary using (Decidable) open import Relation.Binary.PropositionalEquality using (cong; _≑_; refl; sym) open Relation.Binary.PropositionalEquality.≑-Reasoning using (begin_; _β‰‘βŸ¨_⟩_; _∎) Mapping : Set Mapping = 𝕍ar Γ— 𝕋 Subs : Set Subs = List Mapping emptySubs : Subs emptySubs = [] insert : 𝕍ar β†’ 𝕋 β†’ Subs β†’ Subs insert v Ο„ s = (v , Ο„) ∷ s sub : 𝕋 β†’ 𝕍ar β†’ 𝕋 β†’ 𝕋 -- substitute Ο„ for v in t' sub Ο„ v (Var v') with v β‰Ÿ v' ... | yes _ = Ο„ ... | no _ = Var v' sub Ο„ v (Con c) = Con c sub Ο„ v (τ₁ β‡’ Ο„β‚‚) = (sub Ο„ v τ₁) β‡’ (sub Ο„ v Ο„β‚‚) apply : Subs β†’ 𝕋 β†’ 𝕋 apply [] Ο„ = Ο„ apply ((v , Ο„β‚€) ∷ s) Ο„ = apply s (sub Ο„β‚€ v Ο„) applyP : Subs β†’ 𝕋𝕋 β†’ 𝕋𝕋 applyP [] p = p -- needed because otherwise agda does not take into account the -- fact that applyP [] (τ₁ , Ο„β‚‚) ≑ (τ₁ , Ο„β‚‚) applyP s (τ₁ , Ο„β‚‚) = (apply s τ₁ , apply s Ο„β‚‚) applyL : Subs β†’ 𝕋𝕋s β†’ 𝕋𝕋s applyL [] l = l -- this is needed because otherwise agda does not take into account the -- fact that applyL [] l ≑ l applyL s l = map (applyP s) l _∘s_ : Subs β†’ Subs β†’ Subs s₁ ∘s [] = s₁ s₁ ∘s ((v , Ο„) ∷ sβ‚‚) = (v , apply s₁ Ο„) ∷ (s₁ ∘s sβ‚‚) _β‰Ί_ : Subs β†’ Subs β†’ Set s₁ β‰Ί sβ‚‚ = βˆƒ (\s β†’ (s ∘s s₁) ≑ sβ‚‚) _∘ms_ : Maybe Subs β†’ Maybe Subs β†’ Maybe Subs nothing ∘ms nothing = nothing just s₁ ∘ms just [] = just s₁ just s₁ ∘ms just ((v , Ο„)∷ sβ‚‚) = just ((v , apply s₁ Ο„) ∷ (s₁ ∘s sβ‚‚)) nothing ∘ms just _ = nothing just _ ∘ms nothing = nothing invL : βˆ€ {A B : Set} {a : A} {b : B} {c : A} {d : B} β†’ ((a , b) ≑ (c , d)) β†’ (a ≑ c) invL {A} {B} {a} {b} {.a} {.b} refl = refl invR : βˆ€ {A B : Set} {a : A} {b : B} {c : A} {d : B} β†’ (((a , b) ≑ (c , d)) β†’ (b ≑ d)) invR {A} {B} {a} {b} {.a} {.b} refl = refl invHd : βˆ€ {A : Set} {a : A} {x : List A} {b : A} {y : List A} β†’ ((a ∷ x) ≑ (b ∷ y)) β†’ (a ≑ b) invHd {A} {a} {x} {.a} {.x} refl = refl invTl : βˆ€ {A : Set} {a : A} {x : List A} {b : A} {y : List A} β†’ (((a ∷ x) ≑ (b ∷ y)) β†’ (x ≑ y)) invTl {A} {a} {x} {.a} {.x} refl = refl invJust : βˆ€ {A : Set} {n : A} {m : A} β†’ (just n ≑ just m) β†’ n ≑ m invJust {A} {n} {.n} refl = refl invLβ‡’ : βˆ€ {a b c d : 𝕋} β†’ ((a β‡’ b) ≑ (c β‡’ d)) β†’ (a ≑ c) invLβ‡’ {a} {b} { .a} {.b} refl = refl invRβ‡’ : βˆ€ {a b c d : 𝕋} β†’ ((a β‡’ b) ≑ (c β‡’ d)) β†’ (b ≑ d) invRβ‡’ {a} {b} {.a} {.b} refl = refl _β‰Ÿm_ : Decidable {A = Mapping} _≑_ -- Equality on pairs (v,t). (v , Ο„) β‰Ÿm (v' , Ο„') with v β‰Ÿ v' (v , Ο„) β‰Ÿm (.v , Ο„') | yes refl with Ο„ β‰Ÿt Ο„' (v , Ο„) β‰Ÿm (.v , .Ο„) | yes refl | yes refl = yes refl (v , Ο„) β‰Ÿm (.v , Ο„') | yes refl | no prf = no (prf ∘ invR) (v , Ο„) β‰Ÿm (v' , Ο„') | no prf = no (prf ∘ invL) _β‰Ÿs_ : Decidable {A = Subs} _≑_ -- Equality on values of type Subs (lists of pairs (v,t)). [] β‰Ÿs [] = yes refl (m1 ∷ s1) β‰Ÿs (m2 ∷ s2) with m1 β‰Ÿm m2 (m1 ∷ s1) β‰Ÿs (.m1 ∷ s2) | yes refl with s1 β‰Ÿs s2 (m1 ∷ s1) β‰Ÿs (.m1 ∷ .s1) | yes refl | yes refl = yes refl (m1 ∷ s1) β‰Ÿs (.m1 ∷ s2) | yes refl | no prf = no (prf ∘ invTl) (m1 ∷ s1) β‰Ÿs (m2 ∷ s2) | no prf = no (prf ∘ invHd) [] β‰Ÿs (_ ∷ _) = no (Ξ» ()) (_ ∷ _) β‰Ÿs [] = no (Ξ» ()) _β‰Ÿms_ : Decidable {A = Maybe Subs} _≑_ nothing β‰Ÿms nothing = yes refl just s1 β‰Ÿms just s2 with s1 β‰Ÿs s2 just s1 β‰Ÿms just .s1 | yes refl = yes refl just s1 β‰Ÿms just s2 | no prf = no (prf ∘ invJust) nothing β‰Ÿms just _ = no Ξ»() just _ β‰Ÿms nothing = no Ξ»() lemmaApply0 : βˆ€ t β†’ apply emptySubs t ≑ t lemmaApply0 (Var v) = refl lemmaApply0 (Con c) = refl lemmaApply0 (ta β‡’ tb) = begin apply emptySubs (ta β‡’ tb) β‰‘βŸ¨ refl ⟩ apply emptySubs ta β‡’ apply emptySubs tb β‰‘βŸ¨ cong (Ξ» ta β†’ (ta β‡’ apply emptySubs tb)) (lemmaApply0 ta) ⟩ ta β‡’ apply emptySubs tb β‰‘βŸ¨ cong (_β‡’_ ta) (lemmaApply0 tb) ⟩ ta β‡’ tb ∎ lemmaS0 : βˆ€ (s : Subs) β†’ (emptySubs ∘s s) ≑ s lemmaS0 [] = refl lemmaS0 ((v , t) ∷ s1) = begin emptySubs ∘s ((v , t) ∷ s1) β‰‘βŸ¨ refl ⟩ (v , apply emptySubs t) ∷ (emptySubs ∘s s1) β‰‘βŸ¨ cong (Ξ» t β†’ ((v , t) ∷ (emptySubs ∘s s1))) (lemmaApply0 t) ⟩ (v , t ) ∷ (emptySubs ∘s s1) β‰‘βŸ¨ cong (Ξ» s β†’ (v , t) ∷ s) (lemmaS0 s1) ⟩ ((v , t ) ∷ s1) ∎ comm_apply : βˆ€ s τ₁ Ο„β‚‚ β†’ (apply s τ₁ ≑ apply s Ο„β‚‚) β†’ (apply s Ο„β‚‚ ≑ apply s τ₁) comm_apply s τ₁ Ο„β‚‚ = sym