{-# OPTIONS --without-K --exact-split --safe #-}
open import Fragment.Algebra.Signature
module Fragment.Algebra.Free.Properties (Σ : Signature) where
open import Level using (Level)
open import Function using (_∘_)
open import Fragment.Algebra.Algebra Σ
open import Fragment.Algebra.Free.Base Σ
open import Fragment.Algebra.Free.Evaluation Σ
open import Fragment.Algebra.Free.Monad Σ
open import Fragment.Algebra.Homomorphism Σ
open import Fragment.Algebra.Quotient Σ
open import Fragment.Setoid.Morphism as M
hiding (∣_∣; ∣_∣-cong; id; _≗_)
open import Data.Fin using (Fin)
open import Data.Vec using (Vec; []; _∷_; map)
open import Data.Vec.Properties using (map-∘)
open import Data.Vec.Relation.Binary.Pointwise.Inductive as PW
using (Pointwise; Pointwise-≡⇒≡; []; _∷_)
import Relation.Binary.Reasoning.Setoid as Reasoning
open import Relation.Binary using (Setoid; Rel; IsEquivalence)
open import Relation.Binary.PropositionalEquality as PE using (_≡_)
private
variable
a b c ℓ₁ ℓ₂ ℓ₃ : Level
module _
{A : Algebra {a} {ℓ₁}}
(h : Free ∥ A ∥/≈ ⟿ A)
(inj : ∣ h ∣⃗ · unit M.≗ M.id)
where
open Setoid ∥ A ∥/≈
open Reasoning ∥ A ∥/≈
mutual
map-∣eval∣-universal : ∀ {n} {xs : Vec (Term ∥ A ∥) n}
→ Pointwise (≈[ A ]) (map ∣ h ∣ xs)
(map ∣ eval A ∣ xs)
map-∣eval∣-universal {_} {[]} = []
map-∣eval∣-universal {_} {x ∷ xs} =
eval-universal {x} ∷ map-∣eval∣-universal {_} {xs}
eval-universal : h ≗ eval A
eval-universal {atom x} = inj
eval-universal {term f xs} = begin
∣ h ∣ (term f xs)
≈⟨ sym (∣ h ∣-hom f xs) ⟩
A ⟦ f ⟧ (map ∣ h ∣ xs)
≈⟨ (A ⟦ f ⟧-cong) map-∣eval∣-universal ⟩
A ⟦ f ⟧ (map ∣ eval A ∣ xs)
≈⟨ ∣ eval A ∣-hom f xs ⟩
∣ eval A ∣ (term f xs)
∎
module _
{A : Setoid a ℓ₁}
{B : Setoid b ℓ₂}
(f : A ↝ Herbrand B)
where
bind-unitₗ : ∣ bind f ∣⃗ · unit M.≗ f
bind-unitₗ = Setoid.refl (Herbrand B)
module _ {A : Setoid a ℓ₁} where
open Setoid ∥ Free A ∥/≈
open Reasoning ∥ Free A ∥/≈
mutual
map-∣bind∣-unitʳ : ∀ {n} → {xs : Vec ∥ Free A ∥ n}
→ Pointwise ≈[ Free A ] (map ∣ bind {B = A} unit ∣ xs) xs
map-∣bind∣-unitʳ {xs = []} = []
map-∣bind∣-unitʳ {xs = x ∷ xs} = bind-unitʳ ∷ map-∣bind∣-unitʳ
bind-unitʳ : bind {B = A} unit ≗ id
bind-unitʳ {atom _} = Setoid.refl (Herbrand A)
bind-unitʳ {term f xs} = begin
∣ bind {B = A} unit ∣ (term f xs)
≈⟨ sym (∣ bind unit ∣-hom f xs) ⟩
term f (map ∣ bind {B = A} unit ∣ xs)
≈⟨ term map-∣bind∣-unitʳ ⟩
term f xs
∎
module _
{A : Setoid a ℓ₁}
{B : Setoid b ℓ₂}
{C : Setoid c ℓ₃}
(g : B ↝ Herbrand C)
(f : A ↝ Herbrand B)
where
open Setoid ∥ Free C ∥/≈
open Reasoning ∥ Free C ∥/≈
mutual
map-∣bind∣-assoc : ∀ {n} → {xs : Vec ∥ Free A ∥ n}
→ Pointwise (≈[ Free C ])
(map (∣ bind g ∣ ∘ ∣ bind f ∣) xs)
(map ∣ bind (∣ bind g ∣⃗ · f) ∣ xs)
map-∣bind∣-assoc {xs = []} = []
map-∣bind∣-assoc {xs = x ∷ xs} = bind-assoc {x} ∷ map-∣bind∣-assoc
bind-assoc : bind g ⊙ bind f ≗ bind (∣ bind g ∣⃗ · f)
bind-assoc {atom _} = refl
bind-assoc {term op xs} = begin
∣ bind g ∣ (∣ bind f ∣ (term op xs))
≈⟨ sym (∣ bind g ∣-cong (∣ bind f ∣-hom op xs)) ⟩
∣ bind g ∣ (term op (map ∣ bind f ∣ xs))
≈⟨ sym (∣ bind g ∣-hom op (map ∣ bind f ∣ xs)) ⟩
term op (map ∣ bind g ∣ (map ∣ bind f ∣ xs))
≈⟨ sym (term (PW.map reflexive (PW.≡⇒Pointwise-≡ (map-∘ ∣ bind g ∣ ∣ bind f ∣ xs)))) ⟩
term op (map (∣ bind g ∣ ∘ ∣ bind f ∣) xs)
≈⟨ term map-∣bind∣-assoc ⟩
term op (map ∣ bind (∣ bind g ∣⃗ · f) ∣ xs)
≈⟨ ∣ bind (∣ bind g ∣⃗ · f) ∣-hom op xs ⟩
∣ bind (∣ bind g ∣⃗ · f) ∣ (term op xs)
∎
fmap-id : ∀ {A : Setoid a ℓ₁} → fmap M.id ≗ id
fmap-id {A = A} = bind-unitʳ {A = A}
module _ {n}
(A : Algebra {a} {ℓ₁})
(θ : Env A n)
where
IsInstantiation : F n ⟿ A → Set _
IsInstantiation f = ∀ x → ∣ f ∣ (atom (dyn x)) ≡ θ x
inst-isInstantiation : IsInstantiation (inst A θ)
inst-isInstantiation x = PE.refl
mutual
map-∣inst∣-universal : ∀ {h m} → IsInstantiation h
→ {xs : Vec ∥ F n ∥ m}
→ Pointwise ≈[ A ] (map ∣ h ∣ xs)
(map ∣ inst A θ ∣ xs)
map-∣inst∣-universal p {xs = []} = []
map-∣inst∣-universal {h = h} p {xs = x ∷ xs} =
inst-universal {h = h} p ∷ map-∣inst∣-universal {h = h} p
inst-universal : ∀ {h} → IsInstantiation h → h ≗ (inst A θ)
inst-universal {h} p {x = atom (dyn x)} = Setoid.reflexive ∥ A ∥/≈ (p x)
inst-universal {h} p {x = term f xs} = begin
∣ h ∣ (term f xs)
≈⟨ Setoid.sym ∥ A ∥/≈ (∣ h ∣-hom f xs) ⟩
A ⟦ f ⟧ (map ∣ h ∣ xs)
≈⟨ (A ⟦ f ⟧-cong) (map-∣inst∣-universal {h = h} p {xs = xs}) ⟩
A ⟦ f ⟧ (map ∣ inst A θ ∣ xs)
≈⟨ ∣ inst A θ ∣-hom f xs ⟩
∣ inst A θ ∣ (term f xs)
∎
where open Reasoning ∥ A ∥/≈
module _
{B : Algebra {b} {ℓ₂}}
(h : A ⟿ B)
where
mutual
map-∣inst∣-assoc : ∀ {m} {xs : Vec ∥ F n ∥ m}
→ Pointwise ≈[ B ]
(map ∣ h ⊙ inst A θ ∣ xs)
(map ∣ inst B (∣ h ∣ ∘ θ) ∣ xs)
map-∣inst∣-assoc {xs = []} = []
map-∣inst∣-assoc {xs = x ∷ xs} = inst-assoc {x = x} ∷ map-∣inst∣-assoc
inst-assoc : h ⊙ inst A θ ≗ inst B (∣ h ∣ ∘ θ)
inst-assoc {atom (dyn _)} = Setoid.refl ∥ B ∥/≈
inst-assoc {term f xs} = begin
∣ h ⊙ inst A θ ∣ (term f xs)
≈⟨ sym (∣ h ⊙ inst A θ ∣-hom f xs) ⟩
B ⟦ f ⟧ (map ∣ h ⊙ inst A θ ∣ xs)
≈⟨ (B ⟦ f ⟧-cong) map-∣inst∣-assoc ⟩
B ⟦ f ⟧ (map ∣ inst B (∣ h ∣ ∘ θ) ∣ xs)
≈⟨ ∣ inst B (∣ h ∣ ∘ θ) ∣-hom f xs ⟩
∣ inst B (∣ h ∣ ∘ θ) ∣ (term f xs)
∎
where open Setoid ∥ B ∥/≈
open Reasoning ∥ B ∥/≈