Source code on Github
------------------------------------------------------------------------
-- The Agda standard library
--
-- Properties of ternary relations
------------------------------------------------------------------------

-- The contents of this module should be accessed via `Relation.Ternary`.

{-# OPTIONS --without-K --safe #-}

module Relation.Ternary.Core where

open import Data.Product using (_×_)
open import Function.Base using (_on_)
open import Level using (Level; _⊔_; suc)

private
  variable
    a b c  ℓ₁ ℓ₂ ℓ₃ : Level
    A : Set a
    B : Set b
    C : Set c

------------------------------------------------------------------------
-- Definitions
------------------------------------------------------------------------

-- Heterogeneous ternary relations

3REL : Set a  Set b  Set c  ( : Level)  Set (a  b  c  suc )
3REL A B C  = A  B  C  Set 

-- Homogeneous ternary relations

3Rel : Set a  ( : Level)  Set (a  suc )
3Rel A  = 3REL A A A 

------------------------------------------------------------------------
-- Relationships between relations
------------------------------------------------------------------------

infix 4 _⇒_ _⇔_ _=[_]⇒_

-- Implication/containment - could also be written _⊆_.
-- and corresponding notion of equivalence

_⇒_ : 3REL A B C ℓ₁  3REL A B C ℓ₂  Set _
P  Q =  {x y z}  P x y z  Q x y z

_⇔_ : 3REL A B C ℓ₁  3REL A B C ℓ₂  Set _
P  Q = P  Q × Q  P

-- Generalised implication - if P ≡ Q it can be read as "f preserves P".

-- _on_ : (B → B → C) → (A → B) → (A → A → C)
-- _*_ on f = f -⟨ _*_ ⟩- f

_on³_ : (B  B  B  C)  (A  B)  (A  A  A  C)
(_~_~_ on³ f) x y z = f x ~ f y ~ f z

_=[_]⇒_ : 3Rel A ℓ₁  (A  B)  3Rel B ℓ₂  Set _
P =[ f ]⇒ Q = P  (Q on³ f)

-- A synonym for _=[_]⇒_.

_Preserves_⟶_ : (A  B)  3Rel A ℓ₁  3Rel B ℓ₂  Set _
f Preserves P  Q = P =[ f ]⇒ Q

-- A ternary variant of _Preserves_⟶_.

_Preserves_⟶_⟶_ : (A  B  C)  3Rel A ℓ₁  3Rel B ℓ₂  3Rel C ℓ₃  Set _
_∙_ Preserves P  Q  R =  {x y z u v w}  P x y z  Q u v w  R (x  u) (y  v) (z  w)