{-# OPTIONS --without-K #-}
open import Core.Functor
open import Core.Functor.Monad
open import Core.Ternary
open import Core.Logic
open import Core.Signature
open import Core.Extensionality
open import Core.MonotonePredicate
open import Effect.Base
open import Effect.Theory.FirstOrder
open import Effect.Elaborate
open import Effect.Syntax.Free
open import Effect.Syntax.Hefty
open import Effect.Relation.Binary.FirstOrderInclusion
open import Effect.Relation.Binary.HigherOrderInclusion
open import Effect.Relation.Ternary.FirstOrderSeparation
open import Effect.Relation.Ternary.HigherOrderSeparation
open import Data.List hiding ([_])
open import Data.List.Membership.Propositional
open import Data.List.Relation.Unary.Any hiding (map)
open import Data.Vec hiding (map ; _++_ ; [_])
open import Data.Sum hiding (map)
open import Data.Product hiding (map)
open import Data.Nat
open import Data.List using (map)
open import Relation.Unary hiding (_∈_ ; _⊆_)
open import Relation.Binary.PropositionalEquality using (_≡_ ; refl ; sym ; trans ; cong ; cong₂)
open import Function
module Effect.Theory.HigherOrder where
record Equationᴴ (η : Effectᴴ) : Set₁ where
constructor _≗ᴴ_
field
{Δ′} : ℕ
{Γ′ R′} : Effect → TypeContext Δ′ → Set
lhsᴴ rhsᴴ : {ε : Effect} → Π[ Γ′ ε ⇒ R′ ε ⊢ Hefty (η ε) ]
open Equationᴴ public
embed-equation : Equation ε → Equationᴴ (const $ ↑ ε)
embed-equation eq = (embed-free ∘₂ eq .lhs) ≗ᴴ (embed-free ∘₂ eq .lhs)
wk-equationᴴ : ⦃ η₁ ≲ η₂ ⦄ → Equationᴴ η₁ → Equationᴴ η₂
wk-equationᴴ eq = (♯ᴴ ∘₂ eq .lhsᴴ) ≗ᴴ (♯ᴴ ∘₂ eq .rhsᴴ)
Respectsᴴ : (_~_ : ∀ {A} → Free ε A → Free ε A → Set₁) → Algebra (η ε) (Free ε) → Equationᴴ η → Set₁
Respectsᴴ _~_ alg (lhs ≗ᴴ rhs) =
∀ {δ γ} → fold-hefty pure alg (lhs δ γ) ~ fold-hefty pure alg (rhs δ γ)
record Theoryᴴ (η : Effectᴴ) : Set₁ where
field
arity : Set
eqs : arity → □ Equationᴴ η
open Theoryᴴ public
variable Th Th₁ Th₂ Th₃ Th′ : Theoryᴴ η
_◂ᴴ_ : □ Equationᴴ η → Theoryᴴ η → Set₁
eq ◂ᴴ Th = ∃ λ a → eq ≡ Th .eqs a
wk-theoryᴴ : η₁ ≲ η₂ → Theoryᴴ η₁ → Theoryᴴ η₂
arity (wk-theoryᴴ i Th) = Th .arity
eqs (wk-theoryᴴ i Th) = λ a → necessary λ i′ → □⟨ Th .eqs a ⟩ ≲ᴴ-trans i i′
_⟨⊎⟩ᴴ_ : ∀[ Theoryᴴ ⇒ Theoryᴴ ⇒ Theoryᴴ ]
arity (Th₁ ⟨⊎⟩ᴴ Th₂) = Th₁ .arity ⊎ Th₂ .arity
eqs (Th₁ ⟨⊎⟩ᴴ Th₂) = [ Th₁ .eqs , Th₂ .eqs ]
_[⊎]ᴴ_ : Theoryᴴ η₁ → Theoryᴴ η₂ → Theoryᴴ (η₁ ·⊕ η₂)
Th₁ [⊎]ᴴ Th₂ = wk-theoryᴴ ·⊑-⊕-left Th₁ ⟨⊎⟩ᴴ wk-theoryᴴ ·⊑-⊕-right Th₂
infix 2 _≅⟨_⟩_
data _≅⟨_⟩_ {η η′ : Effectᴴ} ⦃ i : η ≲ η′ ⦄
: (m₁ : Hefty (η′ ε) A) → Theoryᴴ η → (m₂ : Hefty (η′ ε) A) → Set₁ where
≅-refl :
m ≅⟨ Th ⟩ m
≅-sym : {m₁ : Hefty (η′ ε) A}
→ m₁ ≅⟨ Th ⟩ m₂
→ m₂ ≅⟨ Th ⟩ m₁
≅-trans : {m₁ : Hefty (η′ ε) A}
→ m₁ ≅⟨ Th ⟩ m₂
→ m₂ ≅⟨ Th ⟩ m₃
→ m₁ ≅⟨ Th ⟩ m₃
≅-cong : (c : η′ ε .command)
→ (r₁ r₂ : η′ ε .response c → Hefty (η′ ε) A)
→ (s₁ s₂ : (ψ : η′ ε .fork c) → Hefty (η′ ε) (η′ ε .returns ψ))
→ (∀ {x} → r₁ x ≅⟨ Th ⟩ r₂ x)
→ (∀ {ψ} → s₁ ψ ≅⟨ Th ⟩ s₂ ψ)
→ impure ⟪ c , r₁ , s₁ ⟫ ≅⟨ Th ⟩ impure ⟪ c , r₂ , s₂ ⟫
≅-eq : (eq : □ Equationᴴ η)
→ eq ◂ᴴ Th
→ (δ : TypeContext ((□⟨ eq ⟩ i) .Δ′))
→ (γ : (□⟨ eq ⟩ i) .Γ′ ε δ)
→ (k : (□⟨ eq ⟩ i) .R′ ε δ → Hefty (η′ ε) B)
→ ((□⟨ eq ⟩ i) .rhsᴴ δ γ) >>= k ≅⟨ Th ⟩ ((□⟨ eq ⟩ i) .rhsᴴ δ γ) >>= k
open Elaboration
Correctᴴ : Theoryᴴ η → Theory ε → Elaboration η ε → Set₁
Correctᴴ {η = η} {ε} Th T e =
∀ {ε′ η′}
→ (e′ : Elaboration η′ ε′)
→ ⦃ ζ : e ⊑ e′ ⦄
→ {eq : □ Equationᴴ η}
→ eq ◂ᴴ Th
→ Respectsᴴ (_≈⟨ T ⟩_) (□⟨ e′ .elab ⟩ ≲-refl) (□⟨ eq ⟩ ζ .≲-effᴴ)
map-id : (m : Hefty σ A) → map-hefty id m ≡ m
map-id (pure x) = refl
map-id (impure ⟪ c , r , s ⟫) =
cong₂
(λ □₁ □₂ → impure ⟪ c , □₁ , □₂ ⟫)
(extensionality (map-id ∘ r))
refl
⟨⊕⟩-fold-left : ∀ (m : Hefty σ A)
{f : Algebra σ F} {g : Algebra σ′ F}
{k : ∀[ id ⇒ F ]}
→ fold-hefty k f m
≡ fold-hefty k (f ⟨⊕⟩ g) (♯ᴴ ⦃ ⊑-⊕-left ⦄ m)
⟨⊕⟩-fold-left (pure _) = refl
⟨⊕⟩-fold-left (impure ⟪ c , r , s ⟫) {f} {g} {k} =
cong₂
(λ □₁ □₂ → f .α ⟪ c , □₁ , □₂ ⟫)
( extensionality λ x → ⟨⊕⟩-fold-left $ r x )
( extensionality λ x → ⟨⊕⟩-fold-left $ s x )
⟨⊕⟩-fold-right : ∀ (m : Hefty σ A)
{f : Algebra σ′ F} {g : Algebra σ F}
{k : ∀[ id ⇒ F ]}
→ fold-hefty k g m
≡ fold-hefty k (f ⟨⊕⟩ g) (♯ᴴ ⦃ ⊑-⊕-right ⦄ m)
⟨⊕⟩-fold-right (pure _) = refl
⟨⊕⟩-fold-right (impure ⟪ c , r , s ⟫) {f} {g} {k} =
cong₂
(λ □₁ □₂ → g .α ⟪ c , □₁ , □₂ ⟫)
( extensionality λ x → ⟨⊕⟩-fold-right $ r x )
( extensionality λ x → ⟨⊕⟩-fold-right $ s x )
[⊎]ᴴ-correct :
∀ {e₁ e₂}
→ {Th₁ : Theoryᴴ η₁}
→ {Th₂ : Theoryᴴ η₂}
→ (T : Theory ε)
→ Correctᴴ Th₁ T e₁
→ Correctᴴ Th₂ T e₂
→ Correctᴴ (Th₁ [⊎]ᴴ Th₂) T (e₁ ⟪⊕⟫ e₂)
[⊎]ᴴ-correct {e₁ = e₁} {e₂ = e₂} {Th₁ = Th₁} {Th₂ = Th₂} T C₁ C₂ e′ ⦃ ζ ⦄ {eq} (inj₁ a , refl)
= C₁ e′ ⦃ ζ′ ⦄ (a , refl)
where
ζ′ : e₁ ⊑ e′
≲-eff ζ′ = ζ .≲-eff
≲-effᴴ ζ′ = ≲ᴴ-trans ·⊑-⊕-left $ ζ .≲-effᴴ
preserves-cases ζ′ m e′′ = ζ .preserves-cases (injᴴ ⦃ ⊑-⊕-left ⦄ m) e′′
[⊎]ᴴ-correct {e₁ = e₁} {e₂ = e₂} {Th₁ = Th₁} {Th₂ = Th₂} T C₁ C₂ e′ ⦃ ζ ⦄ {eq} (inj₂ a , refl)
= C₂ e′ ⦃ ζ′ ⦄ (a , refl)
where
ζ′ : e₂ ⊑ e′
≲-eff ζ′ = ζ .≲-eff
≲-effᴴ ζ′ = ≲ᴴ-trans ·⊑-⊕-right $ ζ .≲-effᴴ
preserves-cases ζ′ m e′′ = ζ .preserves-cases (injᴴ ⦃ ⊑-⊕-right ⦄ m) e′′
weaken-correct :
∀ {T : Theory ε} e (Th : Theoryᴴ η) (T′ : Theory ε′)
→ (sub : T ≪ T′)
→ Correctᴴ Th T e
→ Correctᴴ Th T′ (weaken (sub .≲-eff) e)
weaken-correct e Th T′ sub C e′ ⦃ ζ ⦄ px = ≈-weaken sub _ _ (C e′ ⦃ ζ′ ⦄ px)
where ζ′ : e ⊑ e′
≲-eff ζ′ = ≲-trans (sub .≲-eff) (ζ .≲-eff)
≲-effᴴ ζ′ = ζ .≲-effᴴ
preserves-cases ζ′ m e′′ = (ζ .preserves-cases m e′′)
compose-elab-correct :
∀ (e₁ : Elaboration η₁ ε₁)
→ (e₂ : Elaboration η₂ ε₂)
→ (T₁ : Theory ε₁)
→ (T₂ : Theory ε₂)
→ (Th₁ : Theoryᴴ η₁)
→ (Th₂ : Theoryᴴ η₂)
→ Correctᴴ Th₁ T₁ e₁
→ Correctᴴ Th₂ T₂ e₂
→ (σ : ε₁ ∙ ε₂ ≈ ε)
→ Correctᴴ (Th₁ [⊎]ᴴ Th₂) (compose-theory (T₁ ✴⟨ σ ⟩ T₂)) (compose-elab (e₁ ✴⟨ σ ⟩ e₂))
compose-elab-correct e₁ e₂ T₁ T₂ Th₁ Th₂ C₁ C₂ σ =
[⊎]ᴴ-correct (compose-theory (T₁ ✴⟨ σ ⟩ T₂))
(weaken-correct e₁ Th₁ (compose-theory (T₁ ✴⟨ σ ⟩ T₂)) (≪-compose-left T₁ T₂ σ) C₁)
(weaken-correct e₂ Th₂ (compose-theory (T₁ ✴⟨ σ ⟩ T₂)) (≪-compose-right T₁ T₂ σ) C₂)