module Generic.Fusion where
open import Size
open import Data.Sum
open import Data.List hiding ([_] ; zip ; lookup)
open import Function
open import Relation.Binary.PropositionalEquality hiding ([_])
open import indexed
open import rel
open import var hiding (_<$>_)
open import varlike
open import environment
open import Generic.Syntax
open import Generic.Semantics
open import Generic.Zip
open import Generic.Simulation using (reify^R ; vl^VarTm)
open import Generic.Identity
module _ {I : Set} {π₯β π₯β π₯β πβ πβ πβ : I β List I β Set}
(π‘^E : {Ξ Ξ Ξ : List I} β (Ξ βEnv) π₯β Ξ β (Ξ βEnv) π₯β Ξ β (Ξ βEnv) π₯β Ξ β Set)
(π‘^π₯ : Rel π₯β π₯β)
(π‘^π : Rel πβ πβ)
where
record Fus (d : Desc I) (π’β : Sem d π₯β πβ) (π’β : Sem d π₯β πβ) (π’β : Sem d π₯β πβ) : Set where
field
quoteβ : (i : I) β [ πβ i βΆ Tm d β i ]
vl^π₯β : VarLike π₯β
th^R : {Ξ Ξ Ξ Ξ : List I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} β (Ο : Thinning Ξ Ξ) β π‘^E Οβ Οβ Οβ β
π‘^E Οβ (th^Env (Sem.th^π₯ π’β) Οβ Ο) (th^Env (Sem.th^π₯ π’β) Οβ Ο)
>>^R : {Ξ Ξ Ξ Ξ : List I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ
: (Ξ βEnv) π₯β Ξ} β π‘^E Οβ Οβ Οβ β β[ π‘^π₯ ] Οβ Οβ
β
π‘^E (freshΛ‘ vl^π₯β Ξ {Ξ} >> th^Env (Sem.th^π₯ π’β) Οβ (freshΚ³ vl^Var Ξ)) (Οβ >> Οβ) (Οβ
>> Οβ)
var^R : {Ξ Ξ Ξ : List I} {i : I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} β π‘^E Οβ Οβ Οβ β (v : Var i Ξ) β
rel π‘^π (Sem.sem π’β Οβ (quoteβ i (Sem.var π’β (lookup Οβ v))))
(Sem.var π’β (lookup Οβ v))
alg^R : {Ξ Ξ Ξ : List I} {s : Size} {i : I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} β (b : β¦ d β§ (Scope (Tm d s)) i Ξ) β π‘^E Οβ Οβ Οβ β
let vβ = fmap d (Sem.body π’β Οβ) b
vβ = fmap d (Sem.body π’β Οβ) b
in Zip d (Kripke^R π‘^π₯ π‘^π)
(fmap d (Ξ» Ξ i β Sem.body π’β Οβ Ξ i β quoteβ i β reify vl^π₯β Ξ i) vβ)
vβ β
rel π‘^π (Sem.sem π’β Οβ (quoteβ i (Sem.alg π’β vβ))) (Sem.alg π’β vβ)
fus : {s : Size} {i : I} {Ξ Ξ Ξ : List I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} β π‘^E Οβ Οβ Οβ β (t : Tm d s i Ξ) β rel π‘^π (Sem.sem π’β Οβ (quoteβ i (Sem.sem π’β Οβ t)))
(Sem.sem π’β Οβ t)
body : {s : Size} {Ξ Ξ Ξ : List I} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} {Οβ : (Ξ βEnv) π₯β Ξ} β π‘^E Οβ Οβ Οβ β (Ξ : List I) (i : I) (b : Scope (Tm d s) Ξ i Ξ) β
Kripke^R π‘^π₯ π‘^π Ξ i (Sem.body π’β Οβ Ξ i (quoteβ i (reify vl^π₯β Ξ i (Sem.body π’β Οβ Ξ i b))))
(Sem.body π’β Οβ Ξ i b)
fus Ο^R (`var v) = var^R Ο^R v
fus Ο^R (`con t) = alg^R t Ο^R (rew (zip d (body Ο^R) t)) where
eq = fmapΒ² d (Sem.body π’β _) (Ξ» Ξ i t β Sem.body π’β _ Ξ i (quoteβ i (reify vl^π₯β Ξ i t))) t
rew = subst (Ξ» v β Zip d (Kripke^R π‘^π₯ π‘^π) v _) (sym eq)
body Ο^R [] i b = fus Ο^R b
body Ο^R (Ο β· Ξ) i b = Ξ» ren vs^R β fus (>>^R (th^R ren Ο^R) vs^R) b
module _ {I : Set} (d : Desc I) where
open β‘-Reasoning
RenΒ² : Fus (Ξ» Οβ β β[ Eq^R ] β (select Οβ)) Eq^R Eq^R d Renaming Renaming Renaming
Fus.quoteβ RenΒ² = Ξ» _ t β t
Fus.vl^π₯β RenΒ² = vl^Var
Fus.th^R RenΒ² = Ξ» Ο Ο^R β pack^R (Ξ» k β cong (lookup Ο) (lookup^R Ο^R k))
Fus.>>^R RenΒ² {Ξ} {Ξ} {Ξ} {Ξ} {Οβ} {Οβ} {Οβ} {Οβ} {Οβ
} = Ξ» Ο^R vs^R β pack^R (aux Ο^R vs^R) where
aux : β[ Eq^R ] (select Οβ Οβ) Οβ β β[ Eq^R ] Οβ Οβ
β {i : I} (k : Var i (Ξ ++ Ξ)) β
[ lookup Οβ , lookup Οβ ]β² (split Ξ ([ lookup (freshΛ‘ vl^Var Ξ) , (lookup (freshΚ³ vl^Var Ξ) ββ² (lookup Οβ)) ]β² (split Ξ k)))
β‘ [ lookup Οβ
, lookup Οβ ]β² (split Ξ k)
aux Ο^R vs^R k with split Ξ k
... | injβ kΛ‘ =
begin
[ lookup Οβ , lookup Οβ ] (split Ξ (injectΛ‘ Ξ (lookup (base vl^Var) kΛ‘)))
β‘β¨ cong [ lookup Οβ , lookup Οβ ]β² (split-injectΛ‘ Ξ (lookup (base vl^Var) kΛ‘)) β©
lookup Οβ (lookup (base vl^Var) kΛ‘)
β‘β¨ cong (lookup Οβ) (lookup-base^Var kΛ‘) β©
lookup Οβ kΛ‘
β‘β¨ lookup^R vs^R kΛ‘ β©
lookup Οβ
kΛ‘
β
... | injβ kΚ³ =
begin
[ lookup Οβ , lookup Οβ ] (split Ξ (injectΚ³ Ξ (lookup (base vl^Var) (lookup Οβ kΚ³))))
β‘β¨ cong [ lookup Οβ , lookup Οβ ]β² (split-injectΚ³ Ξ (lookup (base vl^Var) (lookup Οβ kΚ³))) β©
lookup Οβ (lookup (base vl^Var) (lookup Οβ kΚ³))
β‘β¨ cong (lookup Οβ) (lookup-base^Var (lookup Οβ kΚ³)) β©
lookup Οβ (lookup Οβ kΚ³)
β‘β¨ lookup^R Ο^R kΚ³ β©
lookup Οβ kΚ³
β
Fus.var^R RenΒ² = Ξ» Ο^R v β cong `var (lookup^R Ο^R v)
Fus.alg^R RenΒ² {Οβ = Οβ} {Οβ} {Οβ} b Ο^R = Ξ» zipped β cong `con $
let vβ = fmap d (Sem.body Renaming Οβ) b
vβ = fmap d (Sem.body Renaming Οβ) b in
begin
fmap d (reify vl^Var) (fmap d (Sem.body Renaming Οβ) (fmap d (reify vl^Var) vβ))
β‘β¨ cong (fmap d (reify vl^Var)) (fmapΒ² d (reify vl^Var) (Sem.body Renaming Οβ) vβ) β©
fmap d (reify vl^Var) (fmap d (Ξ» Ξ¦ i β (Sem.body Renaming Οβ Ξ¦ i) β (reify vl^Var Ξ¦ i)) vβ)
β‘β¨ zip^reify Eq^R (reify^R Eq^R Eq^R (vl^Refl vl^Var)) d zipped β©
fmap d (reify vl^Var) vβ
β
renΒ² : {Ξ Ξ Ξ : List I} {i : I} β β t (Οβ : Thinning Ξ Ξ) (Οβ : Thinning Ξ Ξ) β
ren Οβ {i = i} (ren Οβ t) β‘ ren (select Οβ Οβ) t
renΒ² t Οβ Οβ = Fus.fus RenΒ² (pack^R (Ξ» _ β refl)) t
RenSub : Fus (Ξ» Οβ β β[ Eq^R ] β (select Οβ)) Eq^R Eq^R d Renaming Substitution Substitution
Fus.quoteβ RenSub = Ξ» _ t β t
Fus.vl^π₯β RenSub = vl^Var
Fus.th^R RenSub = Ξ» Ο Ο^R β pack^R (Ξ» k β cong (ren Ο) (lookup^R Ο^R k))
Fus.>>^R RenSub {Ξ} {Ξ} {Ξ} {Ξ} {Οβ} {Οβ} {Οβ} {Οβ} {Οβ
} = Ξ» Ο^R vs^R β pack^R (aux Ο^R vs^R) where
aux : β[ Eq^R ] (select Οβ Οβ) Οβ β β[ Eq^R ] Οβ Οβ
β {i : I} (k : Var i (Ξ ++ Ξ)) β
[ lookup Οβ , lookup Οβ ]β² (split Ξ ([ lookup (freshΛ‘ vl^Var Ξ) , (lookup (freshΚ³ vl^Var Ξ) ββ² (lookup Οβ)) ]β² (split Ξ k)))
β‘ [ lookup Οβ
, lookup Οβ ]β² (split Ξ k)
aux Ο^R vs^R k with split Ξ k
... | injβ kΛ‘ =
begin
[ lookup Οβ , lookup Οβ ] (split Ξ (injectΛ‘ Ξ (lookup (base vl^Var) kΛ‘)))
β‘β¨ cong [ lookup Οβ , lookup Οβ ]β² (split-injectΛ‘ Ξ (lookup (base vl^Var) kΛ‘)) β©
lookup Οβ (lookup (base vl^Var) kΛ‘)
β‘β¨ cong (lookup Οβ) (lookup-base^Var kΛ‘) β©
lookup Οβ kΛ‘
β‘β¨ lookup^R vs^R kΛ‘ β©
lookup Οβ
kΛ‘
β
... | injβ kΚ³ =
begin
[ lookup Οβ , lookup Οβ ] (split Ξ (injectΚ³ Ξ (lookup (base vl^Var) (lookup Οβ kΚ³))))
β‘β¨ cong [ lookup Οβ , lookup Οβ ]β² (split-injectΚ³ Ξ (lookup (base vl^Var) (lookup Οβ kΚ³))) β©
lookup Οβ (lookup (base vl^Var) (lookup Οβ kΚ³))
β‘β¨ cong (lookup Οβ) (lookup-base^Var (lookup Οβ kΚ³)) β©
lookup Οβ (lookup Οβ kΚ³)
β‘β¨ lookup^R Ο^R kΚ³ β©
lookup Οβ kΚ³
β
Fus.var^R RenSub = Ξ» Ο^R v β lookup^R Ο^R v
Fus.alg^R RenSub {Οβ = Οβ} {Οβ} {Οβ} b Ο^R = Ξ» zipped β cong `con $
let vβ = fmap d (Sem.body Renaming Οβ) b
vβ = fmap d (Sem.body Substitution Οβ) b in
begin
fmap d (reify vl^Tm) (fmap d (Sem.body Substitution Οβ) (fmap d (reify vl^Var) vβ))
β‘β¨ cong (fmap d (reify vl^Tm)) (fmapΒ² d (reify vl^Var) (Sem.body Substitution Οβ) vβ) β©
fmap d (reify vl^Tm) (fmap d (Ξ» Ξ¦ i β (Sem.body Substitution Οβ Ξ¦ i) β (reify vl^Var Ξ¦ i)) vβ)
β‘β¨ zip^reify Eq^R (reify^R Eq^R Eq^R (vl^Refl vl^Tm)) d zipped β©
fmap d (reify vl^Tm) vβ
β
rensub : {Ξ Ξ Ξ : List I} {i : I} β β t (Οβ : Thinning Ξ Ξ) (Οβ : (Ξ βEnv) (Tm d β) Ξ) β
sub Οβ {i = i} (ren Οβ t) β‘ sub (select Οβ Οβ) t
rensub t Οβ Οβ = Fus.fus RenSub (pack^R (Ξ» _ β refl)) t
SubRen : Fus (Ξ» Οβ Οβ β β[ Eq^R ] (ren Οβ <$> Οβ)) VarTm^R Eq^R d Substitution Renaming Substitution
Fus.quoteβ SubRen = Ξ» _ β id
Fus.vl^π₯β SubRen = vl^Tm
Fus.th^R SubRen {Οβ = Οβ} {Οβ} {Οβ} = Ξ» Ο Ο^R β pack^R $ Ξ» k β
begin
ren (select Οβ Ο) (lookup Οβ k) β‘β¨ sym $ renΒ² (lookup Οβ k) Οβ Ο β©
ren Ο (ren Οβ (lookup Οβ k)) β‘β¨ cong (ren Ο) (lookup^R Ο^R k) β©
ren Ο (lookup Οβ k)
β
Fus.>>^R SubRen {Ξ} {Ξ} {Ξ} {Ξ} {Οβ} {Οβ} {Οβ} {Οβ} {Οβ
} = Ξ» Ο^R vs^R β pack^R (aux Ο^R vs^R) where
aux : β[ Eq^R ] (ren Οβ <$> Οβ) Οβ β β[ VarTm^R ] Οβ Οβ
β {i : I} (k : Var i (Ξ ++ Ξ)) β
ren (Οβ >> Οβ) ([ (ren (pack (injectΛ‘ Ξ)) β (lookup (base vl^Tm)))
, (ren (freshΚ³ vl^Var Ξ) β (lookup Οβ))
] (split Ξ k))
β‘ [ lookup Οβ
, lookup Οβ ]β² (split Ξ k)
aux Ο^R vs^R k with split Ξ k
... | injβ kΛ‘ =
begin
ren (Οβ >> Οβ) (ren (pack (injectΛ‘ Ξ)) (lookup (base vl^Tm) kΛ‘))
β‘β¨ Fus.fus RenΒ² (pack^R (injectΛ‘->> Οβ Οβ)) (lookup (base vl^Tm) kΛ‘) β©
ren Οβ (lookup (base vl^Tm) kΛ‘)
β‘β¨ cong (ren Οβ) (lookup-base^Tm kΛ‘) β©
ren Οβ (`var kΛ‘)
β‘β¨ lookup^R vs^R kΛ‘ β©
lookup Οβ
kΛ‘
β
... | injβ kΚ³ =
begin
ren (Οβ >> Οβ) (ren (freshΚ³ vl^Var Ξ) (lookup Οβ kΚ³))
β‘β¨ Fus.fus RenΒ² (pack^R (freshΚ³->> Ξ Οβ Οβ)) (lookup Οβ kΚ³) β©
ren Οβ (lookup Οβ kΚ³)
β‘β¨ lookup^R Ο^R kΚ³ β©
lookup Οβ kΚ³
β
Fus.var^R SubRen = Ξ» Ο^R v β lookup^R Ο^R v
Fus.alg^R SubRen {Οβ = Οβ} {Οβ} {Οβ} b Ο^R = Ξ» zipped β cong `con $
let vβ = fmap d (Sem.body Substitution Οβ) b
vβ = fmap d (Sem.body Substitution Οβ) b in
begin
fmap d (reify vl^Var) (fmap d (Sem.body Renaming Οβ) (fmap d (reify vl^Tm) vβ))
β‘β¨ cong (fmap d (reify vl^Var)) (fmapΒ² d (reify vl^Tm) (Sem.body Renaming Οβ) vβ) β©
fmap d (reify vl^Var) (fmap d (Ξ» Ξ¦ i β (Sem.body Renaming Οβ Ξ¦ i) β (reify vl^Tm Ξ¦ i)) vβ)
β‘β¨ zip^reify VarTm^R (reify^R VarTm^R Eq^R vl^VarTm) d zipped β©
fmap d (reify vl^Tm) vβ
β
subren : {Ξ Ξ Ξ : List I} {i : I} β β t (Οβ : (Ξ βEnv) (Tm d β) Ξ) (Οβ : Thinning Ξ Ξ) β
ren Οβ {i = i} (sub Οβ t) β‘ sub (ren Οβ <$> Οβ) t
subren t Οβ Οβ = Fus.fus SubRen (pack^R (Ξ» k β refl)) t
SubΒ² : Fus (Ξ» Οβ Οβ β β[ Eq^R ] (sub Οβ <$> Οβ)) Eq^R Eq^R d Substitution Substitution Substitution
Fus.quoteβ SubΒ² = Ξ» _ t β t
Fus.vl^π₯β SubΒ² = vl^Tm
Fus.th^R SubΒ² {Οβ = Οβ} {Οβ} {Οβ} = Ξ» Ο Ο^R β pack^R $ Ξ» k β
begin
sub (ren Ο <$> Οβ) (lookup Οβ k) β‘β¨ sym $ subren (lookup Οβ k) Οβ Ο β©
ren Ο (sub Οβ (lookup Οβ k)) β‘β¨ cong (ren Ο) (lookup^R Ο^R k) β©
ren Ο (lookup Οβ k)
β
Fus.>>^R SubΒ² {Ξ} {Ξ} {Ξ} {Ξ} {Οβ} {Οβ} {Οβ} {Οβ} {Οβ
} = Ξ» Ο^R vs^R β pack^R (aux Ο^R vs^R) where
aux : β[ Eq^R ] (sub Οβ <$> Οβ) Οβ β β[ Eq^R ] Οβ Οβ
β {i : I} (k : Var i (Ξ ++ Ξ)) β
sub (Οβ >> Οβ) ([ lookup (freshΛ‘ vl^Tm Ξ) , ren (freshΚ³ vl^Var Ξ) β lookup Οβ ]β² (split Ξ k))
β‘ [ lookup Οβ
, lookup Οβ ]β² (split Ξ k)
aux Ο^R vs^R k with split Ξ k
... | injβ kΛ‘ =
begin
sub (Οβ >> Οβ) (ren (pack (injectΛ‘ Ξ)) (lookup (base vl^Tm) kΛ‘))
β‘β¨ Fus.fus RenSub (pack^R (injectΛ‘->> Οβ Οβ)) (lookup (base vl^Tm) kΛ‘) β©
sub Οβ (lookup (base vl^Tm) kΛ‘)
β‘β¨ cong (sub Οβ) (lookup-base^Tm kΛ‘) β©
sub Οβ (`var kΛ‘)
β‘β¨ lookup^R vs^R kΛ‘ β©
lookup Οβ
kΛ‘
β
... | injβ kΚ³ =
begin
sub (Οβ >> Οβ) (ren (freshΚ³ vl^Var Ξ) (lookup Οβ kΚ³))
β‘β¨ Fus.fus RenSub (pack^R (freshΚ³->> Ξ Οβ Οβ)) (lookup Οβ kΚ³) β©
sub Οβ (lookup Οβ kΚ³)
β‘β¨ lookup^R Ο^R kΚ³ β©
lookup Οβ kΚ³
β
Fus.var^R SubΒ² = Ξ» Ο^R v β lookup^R Ο^R v
Fus.alg^R SubΒ² {Οβ = Οβ} {Οβ} {Οβ} b Ο^R = Ξ» zipped β cong `con $
let vβ = fmap d (Sem.body Substitution Οβ) b
vβ = fmap d (Sem.body Substitution Οβ) b in
begin
fmap d (reify vl^Tm) (fmap d (Sem.body Substitution Οβ) (fmap d (reify vl^Tm) vβ))
β‘β¨ cong (fmap d (reify vl^Tm)) (fmapΒ² d (reify vl^Tm) (Sem.body Substitution Οβ) vβ) β©
fmap d (reify vl^Tm) (fmap d (Ξ» Ξ¦ i β (Sem.body Substitution Οβ Ξ¦ i) β (reify vl^Tm Ξ¦ i)) vβ)
β‘β¨ zip^reify Eq^R (reify^R Eq^R Eq^R (vl^Refl vl^Tm)) d zipped β©
fmap d (reify vl^Tm) vβ
β
subΒ² : {Ξ Ξ Ξ : List I} {i : I} β β t (Οβ : (Ξ βEnv) (Tm d β) Ξ) (Οβ : (Ξ βEnv) (Tm d β) Ξ) β
sub Οβ {i = i} (sub Οβ t) β‘ sub (sub Οβ <$> Οβ) t
subΒ² t Οβ Οβ = Fus.fus SubΒ² (pack^R (Ξ» k β refl)) t
renΞ² : β {Ξ Ξ i j} (b : Tm d β j (i β· Ξ)) (u : Tm d β i Ξ) (Ο : Thinning Ξ Ξ) β
ren Ο (b [ u /0]) β‘ ren (lift vl^Var (i β· []) Ο) b [ ren Ο u /0]
renΞ² {i = i} b u Ο = begin
ren Ο (b [ u /0]) β‘β¨ subren b (u /0]) Ο β©
sub (ren Ο <$> (u /0])) b β‘β¨ sym (Fus.fus RenSub eq^R b) β©
ren Οβ² b [ ren Ο u /0] β where
Οβ² = lift vl^Var (i β· []) Ο
eq^R : β[ Eq^R ] (select Οβ² (ren Ο u /0])) (ren Ο <$> (u /0]))
lookup^R eq^R z = refl
lookup^R eq^R (s k) = begin
lookup (base vl^Tm) (lookup (base vl^Var) (lookup Ο k)) β‘β¨ lookup-base^Tm _ β©
`var (lookup (base vl^Var) (lookup Ο k)) β‘β¨ cong `var (lookup-base^Var _) β©
`var (lookup Ο k) β‘β¨ sym (cong (ren Ο) (lookup-base^Tm k)) β©
ren Ο (lookup (base vl^Tm) k) β
subΞ² : β {Ξ Ξ i j} (b : Tm d β j (i β· Ξ)) (u : Tm d β i Ξ) (Ο : (Ξ βEnv) (Tm d β) Ξ) β
sub Ο (b [ u /0]) β‘ sub (lift vl^Tm (i β· []) Ο) b [ sub Ο u /0]
subΞ² {i = i} b u Ο = begin
sub Ο (b [ u /0]) β‘β¨ subΒ² b (u /0]) Ο β©
sub (sub Ο <$> (base vl^Tm β u)) b β‘β¨ sym (Fus.fus SubΒ² eq^Rβ² b) β©
sub Οβ² b [ sub Ο u /0] β where
Οβ² = lift vl^Tm (i β· []) Ο
Ο = freshΚ³ vl^Var (i β· [])
eq^R : β[ Eq^R ] (select Ο (sub Ο u /0])) (base vl^Tm)
lookup^R eq^R z = refl
lookup^R eq^R (s k) = cong (ren extend β lookup (base vl^Tm)) (lookup-base^Var k)
eq^Rβ² : β[ Eq^R ] (sub (sub Ο u /0]) <$> Οβ²) (sub Ο <$> (base vl^Tm β u))
lookup^R eq^Rβ² z = refl
lookup^R eq^Rβ² (s k) = begin
sub (sub Ο u /0]) (ren Ο (lookup Ο k)) β‘β¨ Fus.fus RenSub eq^R (lookup Ο k) β©
sub (base vl^Tm) (lookup Ο k) β‘β¨ sub-id (lookup Ο k) β©
lookup Ο k β‘β¨ cong (sub Ο) (sym $ lookup-base^Tm k) β©
sub Ο (lookup (base vl^Tm) k) β