{-# OPTIONS --without-K --exact-split --safe #-} open import Fragment.Algebra.Signature module Fragment.Algebra.Free.Base (Σ : Signature) where open import Fragment.Algebra.Algebra Σ open import Fragment.Algebra.Free.Atoms public open import Level using (Level; _⊔_) open import Function using (_∘_) open import Data.Empty using (⊥) open import Data.Nat using (ℕ) open import Data.Fin using (Fin) open import Data.Vec using (Vec; []; _∷_) open import Data.Vec.Relation.Binary.Pointwise.Inductive using (Pointwise; []; _∷_) open import Relation.Binary using (Setoid; IsEquivalence) open import Relation.Binary.PropositionalEquality as PE using (_≡_) private variable a ℓ : Level module _ (A : Set a) where data Term : Set a where atom : A → Term term : ∀ {arity} → (f : ops Σ arity) → Vec Term arity → Term module _ (S : Setoid a ℓ) where open Setoid S renaming (Carrier to A) data _~_ : Term A → Term A → Set (a ⊔ ℓ) where atom : ∀ {x y} → x ≈ y → atom x ~ atom y term : ∀ {arity xs ys} {f : ops Σ arity} → Pointwise _~_ xs ys → term f xs ~ term f ys private mutual map-~-refl : ∀ {n} {xs : Vec _ n} → Pointwise _~_ xs xs map-~-refl {xs = []} = [] map-~-refl {xs = x ∷ xs} = ~-refl ∷ map-~-refl ~-refl : ∀ {x} → x ~ x ~-refl {atom _} = atom refl ~-refl {term _ _} = term map-~-refl mutual map-~-sym : ∀ {n} {xs ys : Vec _ n} → Pointwise _~_ xs ys → Pointwise _~_ ys xs map-~-sym [] = [] map-~-sym (x≈y ∷ xs≈ys) = ~-sym x≈y ∷ map-~-sym xs≈ys ~-sym : ∀ {x y} → x ~ y → y ~ x ~-sym (atom x≈y) = atom (sym x≈y) ~-sym (term xs≈ys) = term (map-~-sym xs≈ys) mutual map-~-trans : ∀ {n} {xs ys zs : Vec _ n} → Pointwise _~_ xs ys → Pointwise _~_ ys zs → Pointwise _~_ xs zs map-~-trans [] [] = [] map-~-trans (x≈y ∷ xs≈ys) (y≈z ∷ ys≈zs) = ~-trans x≈y y≈z ∷ map-~-trans xs≈ys ys≈zs ~-trans : ∀ {x y z} → x ~ y → y ~ z → x ~ z ~-trans (atom x≈y) (atom y≈z) = atom (trans x≈y y≈z) ~-trans (term xs≈ys) (term ys≈zs) = term (map-~-trans xs≈ys ys≈zs) ~-isEquivalence : IsEquivalence _~_ ~-isEquivalence = record { refl = ~-refl ; sym = ~-sym ; trans = ~-trans } Herbrand : Setoid _ _ Herbrand = record { Carrier = Term A ; _≈_ = _~_ ; isEquivalence = ~-isEquivalence } Free : Algebra Free = record { ∥_∥/≈ = Herbrand ; ∥_∥/≈-isAlgebra = Free-isAlgebra } where term-cong : Congruence Herbrand term term-cong f p = term p Free-isAlgebra : IsAlgebra Herbrand Free-isAlgebra = record { ⟦_⟧ = term ; ⟦⟧-cong = term-cong } F : ℕ → Algebra F = Free ∘ Atoms (PE.setoid ⊥)