{-# OPTIONS --allow-unsolved-metas #-}
open import Relation.Binary using (Decidable)
open import Relation.Binary.PropositionalEquality using (_≡_)
module SyntaxRew
{{ Α : Set }}
{{ C : Set }}
{{ Var : Set }}
{{ decEqVar : Decidable (_≡_ {A = Var}) }}
{{ Κ : Set }}
where
open import Syntax
{{ Α }}
{{ C }}
{{ Var }}
{{ decEqVar }}
{{ Κ }}
public
data MT : Set where
symbM : Κ → MT
go : Go → MT
_apM_ : MT → MT → MT
<_,_>M : t → MT → MT
lamM : Κ → MT → MT
open import Data.Product using (_×_ ; _,_)
open import Relation.Binary.PropositionalEquality using (refl)
inspect-apM : {e₁ e₂ : MT} {ê₁ ê₂ : MT} →
e₁ apM ê₁ ≡ e₂ apM ê₂ →
e₁ ≡ e₂ × ê₁ ≡ ê₂
inspect-apM refl = refl , refl
inspect-<>M : {M₁ M₂ : t} {ê₁ ê₂ : MT} →
< M₁ , ê₁ >M ≡ < M₂ , ê₂ >M →
M₁ ≡ M₂ × ê₁ ≡ ê₂
inspect-<>M refl = refl , refl
inspect-lamM : {κ₁ κ₂ : Κ} {ê₁ ê₂ : MT} →
lamM κ₁ ê₁ ≡ lamM κ₂ ê₂ →
κ₁ ≡ κ₂ × ê₁ ≡ ê₂
inspect-lamM refl = refl , refl
inMT : PT → MT
inMT (symbP κ) = symbM κ
inMT (e apP e₁) = (inMT e) apM (inMT e₁)
inMT < M , e >P = < M , (inMT e) >M
inMT (lamP κ e) = lamM κ (inMT e)
open import Relation.Binary.PropositionalEquality using (cong ; cong₂)
injective-inMT : {e₁ e₂ : PT} → inMT e₁ ≡ inMT e₂ → e₁ ≡ e₂
injective-inMT {symbP x₁} {symbP .x₁} refl = cong symbP refl
injective-inMT {symbP x₁} {e₂ apP e₃} ()
injective-inMT {symbP x₁} {< x₂ , e₂ >P} ()
injective-inMT {symbP x₁} {lamP x₂ e₂} ()
injective-inMT {e₁ apP e₂} {symbP x₁} ()
injective-inMT {e₁ apP e₂} {e₃ apP e₄} x
with inspect-apM x
... | eql , eqr = cong₂ (λ e e' → e apP e') (injective-inMT eql) (injective-inMT eqr)
injective-inMT {e₁ apP e₂} {< x₁ , e₃ >P} ()
injective-inMT {e₁ apP e₂} {lamP x₁ e₃} ()
injective-inMT {< x₁ , e₁ >P} {symbP x₂} ()
injective-inMT {< x₁ , e₁ >P} {e₂ apP e₃} ()
injective-inMT {< x₁ , e₁ >P} {< x₂ , e₂ >P} x
with inspect-<>M x
... | refl , eq = cong (<_,_>P x₁) (injective-inMT eq)
injective-inMT {< x₁ , e₁ >P} {lamP x₂ e₂} ()
injective-inMT {lamP x₁ e₁} {symbP x₂} ()
injective-inMT {lamP x₁ e₁} {e₂ apP e₃} ()
injective-inMT {lamP x₁ e₁} {< x₂ , e₂ >P} ()
injective-inMT {lamP x₁ e₁} {lamP x₂ e₂} x
with inspect-lamM x
... | refl , eq = cong (lamP x₁) (injective-inMT eq)
_[_/_]MT : MT → t → Var → MT
symbM κ [ M / x ]MT = symbM κ
(e apM e') [ M / x ]MT = (e [ M / x ]MT) apM (e' [ M / x ]MT)
< M , e >M [ N / x ]MT = < M [ N / x ]t , e [ N / x ]MT >M
lamM κ e [ M / x ]MT = lamM κ (e [ M / x ]MT)
go G [ M / x ]MT = go (G [ M / x ]Go )
open import Relation.Binary.PropositionalEquality using ( refl ; cong₂ ; cong )
inMT-[/]-dist : {e : PT } {N : t} {x : Var} →
inMT (e [ N / x ]PT) ≡ (inMT e) [ N / x ]MT
inMT-[/]-dist {symbP κ} = refl
inMT-[/]-dist {e apP e₁} = cong₂ (λ e' e'' → e' apM e'') inMT-[/]-dist inMT-[/]-dist
inMT-[/]-dist {< M , e >P} {N} {x} = cong (λ e' → < ( M [ N / x ]t ) , e' >M) inMT-[/]-dist
inMT-[/]-dist {lamP κ e} = cong (λ e' → lamM κ e') inMT-[/]-dist
inMT-PT : {e₁ e₂ : PT} → inMT e₁ ≡ inMT e₂ → e₁ ≡ e₂
inMT-PT {symbP x} {symbP x₁} refl = cong symbP refl
inMT-PT {symbP x} {e₂ apP e₃} ()
inMT-PT {symbP x} {< x₁ , e₂ >P} ()
inMT-PT {symbP x} {lamP x₁ e₂} ()
inMT-PT {e₁ apP e₂} {symbP x} ()
inMT-PT {e₁ apP e₂} {e₃ apP e₄} eq
with inspect-apM eq
... | eql , eqr = cong₂ (λ x x₁ → x apP x₁) (injective-inMT eql) (injective-inMT eqr)
inMT-PT {e₁ apP e₂} {< x , e₃ >P} ()
inMT-PT {e₁ apP e₂} {lamP x e₃} ()
inMT-PT {< x , e₁ >P} {symbP x₁} ()
inMT-PT {< x , e₁ >P} {e₂ apP e₃} ()
inMT-PT {< x , e₁ >P} {< x₁ , e₂ >P} eq
with inspect-<>M eq
... | eq₁ , eq₂ = cong₂ (λ x₂ y → < x₂ , y >P) eq₁ (inMT-PT eq₂)
inMT-PT {< x , e₁ >P} {lamP x₁ e₂} ()
inMT-PT {lamP x e₁} {symbP x₁} ()
inMT-PT {lamP x e₁} {e₂ apP e₃} ()
inMT-PT {lamP x e₁} {< x₁ , e₂ >P} ()
inMT-PT {lamP x e₁} {lamP x₁ e₂} eq
with inspect-lamM eq
... | eq₁ , eq₂ = cong₂ (λ x₂ y → lamP x₂ y) eq₁ (inMT-PT eq₂)
open import Data.Product using (∃)
inMT-PT' : {e₁ : MT} {e₂ : PT} → e₁ ≡ inMT e₂ → (∃ λ e₁' → inMT e₁' ≡ e₁)
inMT-PT' {symbM x} {symbP .x} refl = (symbP x) , refl
inMT-PT' {symbM x} {e₂ apP e₃} ()
inMT-PT' {symbM x} {< x₁ , e₂ >P} ()
inMT-PT' {symbM x} {lamP x₁ e₂} ()
inMT-PT' {go x} {symbP x₁} ()
inMT-PT' {go x} {e₂ apP e₃} ()
inMT-PT' {go x} {< x₁ , e₂ >P} ()
inMT-PT' {go x} {lamP x₁ e₂} ()
inMT-PT' {e₁ apM e₂} {symbP x} ()
inMT-PT' {.(inMT e₂) apM .(inMT e₃)} {e₂ apP e₃} refl = (e₂ apP e₃) , refl
inMT-PT' {e₁ apM e₂} {< x , e₃ >P} ()
inMT-PT' {e₁ apM e₂} {lamP x e₃} ()
inMT-PT' {< x , e₁ >M} {symbP x₁} ()
inMT-PT' {< x , e₁ >M} {e₂ apP e₃} ()
inMT-PT' {< x , .(inMT e₂) >M} {< .x , e₂ >P} refl = < x , e₂ >P , refl
inMT-PT' {< x , e₁ >M} {lamP x₁ e₂} ()
inMT-PT' {lamM x e₁} {symbP x₁} ()
inMT-PT' {lamM x e₁} {e₂ apP e₃} ()
inMT-PT' {lamM x e₁} {< x₁ , e₂ >P} ()
inMT-PT' {lamM x .(inMT e₂)} {lamP .x e₂} refl = (lamP x e₂) , refl
data RewC : Set where
● : RewC
_ap_ : MT → RewC → RewC
<_,_> : t → RewC → RewC
lam : Κ → RewC → RewC
_[_]RewC : RewC → RewC → RewC
● [ C' ]RewC = C'
(e ap C ) [ C' ]RewC = _ap_ e (C [ C' ]RewC)
< M , C > [ C' ]RewC = < M , C [ C' ]RewC >
lam κ C [ C' ]RewC = lam κ (C [ C' ]RewC)
_[_] : RewC → MT → MT
● [ ê ] = ê
(e ap C ) [ ê ] = e apM (C [ ê ])
< M , C > [ ê ] = < M , C [ ê ] >M
lam κ C [ ê ] = lamM κ (C [ ê ])
RewC-MT-[]-comm : {C₁ C₂ : RewC} {ê : MT} →
((C₁ [ C₂ ]RewC) [ ê ] ) ≡ C₁ [ (C₂ [ ê ] ) ]
RewC-MT-[]-comm {●} = refl
RewC-MT-[]-comm {e ap C₁} = cong (_apM_ e) (RewC-MT-[]-comm {C₁ = C₁})
RewC-MT-[]-comm {< M , C₁ >} = cong (<_,_>M M) (RewC-MT-[]-comm {C₁ = C₁})
RewC-MT-[]-comm {lam κ C₁} = cong (lamM κ) (RewC-MT-[]-comm {C₁ = C₁})
open import Relation.Nullary using (yes ; no )
open import Data.Product using ( ∃ )
unique-RewC-Go : {C₁ C₂ : RewC} {ê : MT} {G : Go} →
C₁ [ go G ] ≡ C₂ [ ê ] →
∃ λ C' → C' [ go G ] ≡ ê × ∀ { ê' } → C₁ [ ê' ] ≡ C₂ [ C' [ ê' ] ]
unique-RewC-Go {●} {●} refl = ● , (refl , (λ {x} → refl))
unique-RewC-Go {●} {e ap C₂} ()
unique-RewC-Go {●} {< M , C₂ >} ()
unique-RewC-Go {●} {lam κ C₂} ()
unique-RewC-Go {e ap C₁} {●} refl = (e ap C₁) , refl , (λ {x} → refl)
unique-RewC-Go {e ap C₁} {e' ap C₂} eq
with inspect-apM eq
... | refl , eq'
with unique-RewC-Go eq'
... | C' , eq'' , res = C' , eq'' , cong (_apM_ e) res
unique-RewC-Go {e ap C₁} {< M , C₂ >} ()
unique-RewC-Go {e ap C₁} {lam κ C₂} ()
unique-RewC-Go {< M , C₁ >} {●} refl = < M , C₁ > , refl , (λ {x} → refl)
unique-RewC-Go {< M , C₁ >} {e ap C₂} ()
unique-RewC-Go {< M , C₁ >} {< M' , C₂ >} eq
with inspect-<>M eq
... | refl , eq'
with unique-RewC-Go eq'
... | C' , eq'' , res = C' , eq'' , cong (<_,_>M M) res
unique-RewC-Go {< M , C₁ >} {lam κ C₂} ()
unique-RewC-Go {lam κ C₁} {●} refl = lam κ C₁ , refl , (λ {x} → refl)
unique-RewC-Go {lam κ C₁} {e ap C₂} ()
unique-RewC-Go {lam κ C₁} {< M , C₂ >} ()
unique-RewC-Go {lam κ C₁} {lam κ' C₂} eq
with inspect-lamM eq
... | refl , eq'
with unique-RewC-Go eq'
... | C' , eq'' , res = C' , eq'' , cong (lamM κ) res
unique-RewC-Go' : {C₁ C₂ : RewC} {ê ê' : MT} {G : Go} →
C₁ [ go G ] ≡ C₂ [ ê ] →
∃ λ C' → C' [ go G ] ≡ ê × C₁ [ ê' ] ≡ C₂ [ C' [ ê' ] ]
unique-RewC-Go' {●} {●} refl = ● , (refl , (refl))
unique-RewC-Go' {●} {e ap C₂} ()
unique-RewC-Go' {●} {< M , C₂ >} ()
unique-RewC-Go' {●} {lam κ C₂} ()
unique-RewC-Go' {e ap C₁} {●} refl = (e ap C₁) , refl , (refl)
unique-RewC-Go' {e ap C₁} {e' ap C₂} eq
with inspect-apM eq
... | refl , eq'
with unique-RewC-Go' eq'
... | C' , eq'' , res = C' , eq'' , cong (_apM_ e) res
unique-RewC-Go' {e ap C₁} {< M , C₂ >} ()
unique-RewC-Go' {e ap C₁} {lam κ C₂} ()
unique-RewC-Go' {< M , C₁ >} {●} refl = < M , C₁ > , refl , (refl)
unique-RewC-Go' {< M , C₁ >} {e ap C₂} ()
unique-RewC-Go' {< M , C₁ >} {< M' , C₂ >} eq
with inspect-<>M eq
... | refl , eq'
with unique-RewC-Go' eq'
... | C' , eq'' , res = C' , eq'' , cong (<_,_>M M) res
unique-RewC-Go' {< M , C₁ >} {lam κ C₂} ()
unique-RewC-Go' {lam κ C₁} {●} refl = lam κ C₁ , refl , (refl)
unique-RewC-Go' {lam κ C₁} {e ap C₂} ()
unique-RewC-Go' {lam κ C₁} {< M , C₂ >} ()
unique-RewC-Go' {lam κ C₁} {lam κ' C₂} eq
with inspect-lamM eq
... | refl , eq'
with unique-RewC-Go' eq'
... | C' , eq'' , res = C' , eq'' , cong (lamM κ) res
_ΘMT_ : ∀ {S Γ Γ'} → Θ S Γ Γ' → MT → MT
θ ΘMT symbM κ = symbM κ
θ ΘMT go G = go (θ ΘGo G)
θ ΘMT (ê apM ê₁) = (θ ΘMT ê) apM (θ ΘMT ê₁ )
θ ΘMT < M , ê >M = < θ Θt M , θ ΘMT ê >M
θ ΘMT lamM κ ê = lamM κ (θ ΘMT ê)
_ΘC_ : ∀ { S Γ Γ'} → Θ S Γ Γ' → RewC → RewC
θ ΘC ● = ●
θ ΘC (e ap C₁) = (θ ΘMT e) ap (θ ΘC C₁)
θ ΘC < M , C₁ > = < θ Θt M , θ ΘC C₁ >
θ ΘC lam κ C₁ = lam κ (θ ΘC C₁)