diff options
Diffstat (limited to 'src/Relation/Binary/Vec/Pointwise.agda')
-rw-r--r-- | src/Relation/Binary/Vec/Pointwise.agda | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/Relation/Binary/Vec/Pointwise.agda b/src/Relation/Binary/Vec/Pointwise.agda new file mode 100644 index 0000000..9613aa4 --- /dev/null +++ b/src/Relation/Binary/Vec/Pointwise.agda @@ -0,0 +1,204 @@ +------------------------------------------------------------------------ +-- Pointwise lifting of relations to vectors +------------------------------------------------------------------------ + +{-# OPTIONS --universe-polymorphism #-} + +module Relation.Binary.Vec.Pointwise where + +open import Category.Applicative.Indexed +open import Data.Fin +open import Data.Plus as Plus hiding (equivalent; map) +open import Data.Vec as Vec hiding ([_]; map) +import Data.Vec.Properties as VecProp +open import Function +open import Function.Equality using (_⟨$⟩_) +open import Function.Equivalence as Equiv + using (_⇔_; module Equivalent) +open import Level +open import Relation.Binary +open import Relation.Binary.PropositionalEquality as P using (_≡_) +open import Relation.Nullary + +private + module Dummy {a} {A : Set a} where + + -- Functional definition. + + record Pointwise (_∼_ : Rel A a) {n} (xs ys : Vec A n) : Set a where + constructor ext + field app : ∀ i → lookup i xs ∼ lookup i ys + + -- Inductive definition. + + infixr 5 _∷_ + + data Pointwise′ (_∼_ : Rel A a) : + ∀ {n} (xs ys : Vec A n) → Set a where + [] : Pointwise′ _∼_ [] [] + _∷_ : ∀ {n x y} {xs ys : Vec A n} + (x∼y : x ∼ y) (xs∼ys : Pointwise′ _∼_ xs ys) → + Pointwise′ _∼_ (x ∷ xs) (y ∷ ys) + + -- The two definitions are equivalent. + + equivalent : ∀ {_∼_ : Rel A a} {n} {xs ys : Vec A n} → + Pointwise _∼_ xs ys ⇔ Pointwise′ _∼_ xs ys + equivalent {_∼_} = Equiv.equivalent (to _ _) from + where + to : ∀ {n} (xs ys : Vec A n) → + Pointwise _∼_ xs ys → Pointwise′ _∼_ xs ys + to [] [] xs∼ys = [] + to (x ∷ xs) (y ∷ ys) xs∼ys = + Pointwise.app xs∼ys zero ∷ + to xs ys (ext (Pointwise.app xs∼ys ∘ suc)) + + nil : Pointwise _∼_ [] [] + nil = ext λ() + + cons : ∀ {n x y} {xs ys : Vec A n} → + x ∼ y → Pointwise _∼_ xs ys → Pointwise _∼_ (x ∷ xs) (y ∷ ys) + cons {x = x} {y} {xs} {ys} x∼y xs∼ys = ext helper + where + helper : ∀ i → lookup i (x ∷ xs) ∼ lookup i (y ∷ ys) + helper zero = x∼y + helper (suc i) = Pointwise.app xs∼ys i + + from : ∀ {n} {xs ys : Vec A n} → + Pointwise′ _∼_ xs ys → Pointwise _∼_ xs ys + from [] = nil + from (x∼y ∷ xs∼ys) = cons x∼y (from xs∼ys) + + -- Pointwise preserves reflexivity. + + refl : ∀ {_∼_ : Rel A a} {n} → + Reflexive _∼_ → Reflexive (Pointwise _∼_ {n = n}) + refl rfl = ext (λ _ → rfl) + + -- Pointwise preserves symmetry. + + sym : ∀ {_∼_ : Rel A a} {n} → + Symmetric _∼_ → Symmetric (Pointwise _∼_ {n = n}) + sym sm xs∼ys = ext λ i → sm (Pointwise.app xs∼ys i) + + -- Pointwise preserves transitivity. + + trans : ∀ {_∼_ : Rel A a} {n} → + Transitive _∼_ → Transitive (Pointwise _∼_ {n = n}) + trans trns xs∼ys ys∼zs = ext λ i → + trns (Pointwise.app xs∼ys i) (Pointwise.app ys∼zs i) + + -- Pointwise preserves equivalences. + + isEquivalence : + ∀ {_∼_ : Rel A a} {n} → + IsEquivalence _∼_ → IsEquivalence (Pointwise _∼_ {n = n}) + isEquivalence equiv = record + { refl = refl (IsEquivalence.refl equiv) + ; sym = sym (IsEquivalence.sym equiv) + ; trans = trans (IsEquivalence.trans equiv) + } + + -- Pointwise _≡_ is equivalent to _≡_. + + Pointwise-≡ : ∀ {n} {xs ys : Vec A n} → + Pointwise _≡_ xs ys ⇔ xs ≡ ys + Pointwise-≡ = + Equiv.equivalent + (to ∘ _⟨$⟩_ (Equivalent.to equivalent)) + (λ xs≡ys → P.subst (Pointwise _≡_ _) xs≡ys (refl P.refl)) + where + to : ∀ {n} {xs ys : Vec A n} → Pointwise′ _≡_ xs ys → xs ≡ ys + to [] = P.refl + to (P.refl ∷ xs∼ys) = P.cong (_∷_ _) $ to xs∼ys + + -- Pointwise and Plus commute when the underlying relation is + -- reflexive. + + ⁺∙⇒∙⁺ : ∀ {_∼_ : Rel A a} {n} {xs ys : Vec A n} → + Plus (Pointwise _∼_) xs ys → Pointwise (Plus _∼_) xs ys + ⁺∙⇒∙⁺ [ ρ≈ρ′ ] = ext (λ x → [ Pointwise.app ρ≈ρ′ x ]) + ⁺∙⇒∙⁺ (ρ ∼⁺⟨ ρ≈ρ′ ⟩ ρ′≈ρ″) = + ext (λ x → _ ∼⁺⟨ Pointwise.app (⁺∙⇒∙⁺ ρ≈ρ′ ) x ⟩ + Pointwise.app (⁺∙⇒∙⁺ ρ′≈ρ″) x) + + ∙⁺⇒⁺∙ : ∀ {_∼_ : Rel A a} {n} {xs ys : Vec A n} → + Reflexive _∼_ → + Pointwise (Plus _∼_) xs ys → Plus (Pointwise _∼_) xs ys + ∙⁺⇒⁺∙ {_∼_} x∼x = + Plus.map (_⟨$⟩_ (Equivalent.from equivalent)) ∘ + helper ∘ + _⟨$⟩_ (Equivalent.to equivalent) + where + helper : ∀ {n} {xs ys : Vec A n} → + Pointwise′ (Plus _∼_) xs ys → Plus (Pointwise′ _∼_) xs ys + helper [] = [ [] ] + helper (_∷_ {x = x} {y = y} {xs = xs} {ys = ys} x∼y xs∼ys) = + x ∷ xs ∼⁺⟨ Plus.map (λ x∼y → x∼y ∷ xs∼xs) x∼y ⟩ + y ∷ xs ∼⁺⟨ Plus.map (λ xs∼ys → x∼x ∷ xs∼ys) (helper xs∼ys) ⟩∎ + y ∷ ys ∎ + where + xs∼xs : Pointwise′ _∼_ xs xs + xs∼xs = Equivalent.to equivalent ⟨$⟩ refl x∼x + +open Dummy public + +-- Note that ∙⁺⇒⁺∙ cannot be defined if the requirement of reflexivity +-- is dropped. + +private + + module Counterexample where + + data D : Set where + i j x y z : D + + data _R_ : Rel D zero where + iRj : i R j + xRy : x R y + yRz : y R z + + xR⁺z : x [ _R_ ]⁺ z + xR⁺z = + x ∼⁺⟨ [ xRy ] ⟩ + y ∼⁺⟨ [ yRz ] ⟩∎ + z ∎ + + ix = i ∷ x ∷ [] + jz = j ∷ z ∷ [] + + ix∙⁺jz : Pointwise′ (Plus _R_) ix jz + ix∙⁺jz = [ iRj ] ∷ xR⁺z ∷ [] + + ¬ix⁺∙jz : ¬ Plus′ (Pointwise′ _R_) ix jz + ¬ix⁺∙jz [ iRj ∷ () ∷ [] ] + ¬ix⁺∙jz ((iRj ∷ xRy ∷ []) ∷ [ () ∷ yRz ∷ [] ]) + ¬ix⁺∙jz ((iRj ∷ xRy ∷ []) ∷ (() ∷ yRz ∷ []) ∷ _) + + counterexample : + ¬ (∀ {n} {xs ys : Vec D n} → + Pointwise (Plus _R_) xs ys → + Plus (Pointwise _R_) xs ys) + counterexample ∙⁺⇒⁺∙ = + ¬ix⁺∙jz (Equivalent.to Plus.equivalent ⟨$⟩ + Plus.map (_⟨$⟩_ (Equivalent.to equivalent)) + (∙⁺⇒⁺∙ (Equivalent.from equivalent ⟨$⟩ ix∙⁺jz))) + +-- Map. + +map : ∀ {a} {A : Set a} {_R_ _R′_ : Rel A a} {n} → + _R_ ⇒ _R′_ → Pointwise _R_ ⇒ Pointwise _R′_ {n} +map R⇒R′ xsRys = ext λ i → + R⇒R′ (Pointwise.app xsRys i) + +-- A variant. + +gmap : ∀ {a} {A A′ : Set a} + {_R_ : Rel A a} {_R′_ : Rel A′ a} {f : A → A′} {n} → + _R_ =[ f ]⇒ _R′_ → + Pointwise _R_ =[ Vec.map {n = n} f ]⇒ Pointwise _R′_ +gmap {_R′_ = _R′_} {f} R⇒R′ {i = xs} {j = ys} xsRys = ext λ i → + let module M = Morphism (VecProp.lookup-morphism i) in + P.subst₂ _R′_ (P.sym $ M.op-<$> f xs) + (P.sym $ M.op-<$> f ys) + (R⇒R′ (Pointwise.app xsRys i)) |