{-# Language AllowAmbiguousTypes #-} module Data.Semilattice.Property ( -- * Properties of join lattices monotone_join , idempotent_join , idempotent_join_on , associative_join , associative_join_on , commutative_join , commutative_join_on , neutral_join , neutral_join_on , distributive_join -- * Properties of meet semilattices , monotone_meet , idempotent_meet , idempotent_meet_on , associative_meet , associative_meet_on , commutative_meet , commutative_meet_on , neutral_meet , neutral_meet_on , distributive_meet -- * Properties of lattices , absorbative , absorbative' , annihilative_join , annihilative_meet , distributive , codistributive , majority_glb , commutative_glb , commutative_glb' , associative_glb --, distributive_finite_on --, distributive_finite1_on --, distributive_cross_on --, distributive_cross1_on -- * Properties of semilattice & lattice morphisms , morphism_join , morphism_join_on , morphism_join' , morphism_join_on' , morphism_meet , morphism_meet_on , morphism_meet' , morphism_meet_on' , morphism_distributive ) where --import Data.Semigroup.Property as Prop import Data.Prd hiding ((~~)) import Data.Semigroup import Data.Semigroup.Join import Data.Semigroup.Meet import Data.Semilattice import Test.Function as Prop import Test.Logic (Rel, (==>)) import qualified Test.Operation as Prop import Prelude hiding (Ord(..), Num(..), sum) ------------------------------------------------------------------------------------ -- Properties of join semilattices -- | \( \forall a, b, c: b \leq c \Rightarrow b ∨ a \leq c ∨ a \) -- -- This is a required property. -- monotone_join :: JoinSemilattice r => r -> r -> r -> Bool monotone_join x = Prop.monotone_on (<=) (<=) (∨ x) -- | \( \forall a \in R: a ∨ a = a \) -- -- @ 'idempotent_join' = 'absorbative' 'top' @ -- -- See < https://en.wikipedia.org/wiki/Band_(mathematics) >. -- -- This is a required property. -- idempotent_join :: JoinSemilattice r => r -> Bool idempotent_join = idempotent_join_on (=~) idempotent_join_on :: (Join-Semigroup) r => Rel r b -> r -> b idempotent_join_on (~~) r = (∨) r r ~~ r -- | \( \forall a, b, c \in R: (a ∨ b) ∨ c = a ∨ (b ∨ c) \) -- -- This is a required property. -- associative_join :: JoinSemilattice r => r -> r -> r -> Bool associative_join = Prop.associative_on (=~) (∨) associative_join_on :: (Join-Semigroup) r => Rel r b -> r -> r -> r -> b associative_join_on (~~) = Prop.associative_on (~~) (∨) -- | \( \forall a, b \in R: a ∨ b = b ∨ a \) -- -- This is a required property. -- commutative_join :: JoinSemilattice r => r -> r -> Bool commutative_join = commutative_join_on (=~) commutative_join_on :: (Join-Semigroup) r => Rel r b -> r -> r -> b commutative_join_on (~~) = Prop.commutative_on (~~) (∨) -- | \( \forall a \in R: (bottom ∨ a) = a \) -- -- This is a required property for bounded join semilattices. -- neutral_join :: BoundedJoinSemilattice r => r -> Bool neutral_join = neutral_join_on (=~) neutral_join_on :: (Join-Monoid) r => Rel r b -> r -> b neutral_join_on (~~) = Prop.neutral_on (~~) (∨) bottom -- | \( \forall a, b, c: c \leq a ∨ b \Rightarrow \exists a',b': c = a' ∨ b' \) -- -- See < https://en.wikipedia.org/wiki/Distributivity_(order_theory)#Distributivity_for_semilattices > -- -- This is a required property for distributive join semilattices. -- distributive_join :: JoinSemilattice r => r -> r -> r -> r -> r -> Bool distributive_join c a b a' b' = c <= a ∨ b ==> a' <= a && b' <= b && c <= a' ∨ b' ------------------------------------------------------------------------------------ -- Properties of meet semilattices -- | \( \forall a, b, c: b \leq c \Rightarrow b ∧ a \leq c ∧ a \) -- -- This is a required property. -- monotone_meet :: MeetSemilattice r => r -> r -> r -> Bool monotone_meet x = Prop.monotone_on (<=) (<=) (∧ x) -- | \( \forall a, b, c \in R: (a * b) * c = a * (b * c) \) -- -- This is a required property. -- associative_meet :: MeetSemilattice r => r -> r -> r -> Bool associative_meet = associative_meet_on (=~) associative_meet_on :: (Meet-Semigroup) r => Rel r b -> r -> r -> r -> b associative_meet_on (~~) = Prop.associative_on (~~) (∧) -- | \( \forall a, b \in R: a ∧ b = b ∧ a \) -- -- This is a required property. -- commutative_meet :: MeetSemilattice r => r -> r -> Bool commutative_meet = commutative_meet_on (=~) commutative_meet_on :: (Meet-Semigroup) r => Rel r b -> r -> r -> b commutative_meet_on (~~) = Prop.commutative_on (~~) (∧) -- | \( \forall a \in R: a ∧ a = a \) -- -- @ 'idempotent_meet' = 'absorbative' 'bottom' @ -- -- See < https://en.wikipedia.org/wiki/Band_(mathematics) >. -- -- This is a required property. -- idempotent_meet :: MeetSemilattice r => r -> Bool idempotent_meet = idempotent_meet_on (=~) idempotent_meet_on :: (Meet-Semigroup) r => Rel r b -> r -> b idempotent_meet_on (~~) r = (∧) r r ~~ r -- | \( \forall a \in R: (bottom ∧ a) = a \) -- -- This is a required property for bounded meet semilattices. -- neutral_meet :: BoundedMeetSemilattice r => r -> Bool neutral_meet = neutral_meet_on (=~) neutral_meet_on :: (Meet-Monoid) r => Rel r b -> r -> b neutral_meet_on (~~) = Prop.neutral_on (~~) (∧) top -- | \( \forall a, b, c: c \leq a ∨ b \Rightarrow \exists a',b': c = a' ∧ b' \) -- -- See < https://en.wikipedia.org/wiki/Distributivity_(order_theory)#Distributivity_for_semilattices > -- -- This is a required property for distributive meet semilattices. -- distributive_meet :: MeetSemilattice r => r -> r -> r -> r -> r -> Bool distributive_meet c a b a' b' = c >= a ∧ b ==> a' >= a && b' >= b && c >= a' ∧ b' ------------------------------------------------------------------------------------ -- Properties of lattices -- | \( \forall a, b \in R: a ∧ b ∨ b = b \) -- -- Absorbativity is a generalized form of idempotency: -- -- @ -- 'absorbative' 'top' a = a ∨ a = a -- @ -- -- This is a required property. -- absorbative :: Lattice r => r -> r -> Bool absorbative x y = (x ∧ y ∨ y) =~ y -- | \( \forall a, b \in R: a ∨ b ∧ b = b \) -- -- Absorbativity is a generalized form of idempotency: -- -- @ -- 'absorbative'' 'bottom' a = a ∨ a = a -- @ -- -- This is a required property. -- absorbative' :: Lattice r => r -> r -> Bool absorbative' x y = (x ∨ y ∧ y) =~ y -- | \( \forall a \in R: (top ∨ a) = top \) -- -- If /R/ is a lattice then its top element must be annihilative. -- -- This is a required property. -- annihilative_join :: UpperBoundedLattice r => r -> Bool annihilative_join r = Prop.annihilative_on (=~) (∨) top r -- | \( \forall a \in R: (bottom ∧ a) = bottom \) -- -- If /R/ is a lattice then its bottom element must be annihilative. -- -- For 'Semiring' instances this property translates to: -- -- @ -- 'zero' '*' a = 'zero' -- @ -- -- For 'Alternative' instances this property translates to: -- -- @ -- 'empty' '*>' a = 'empty' -- @ -- -- This is a required property. -- annihilative_meet :: LowerBoundedLattice r => r -> Bool annihilative_meet r = Prop.annihilative_on (=~) (∧) bottom r ------------------------------------------------------------------------------------ -- Properties of distributive lattices distributive :: Lattice r => r -> r -> r -> Bool distributive = Prop.distributive_on (=~) (∧) (∨) -- | \( \forall a, b, c \in R: c ∨ (a ∧ b) \equiv (c ∨ a) ∧ (c ∨ b) \) -- -- A right-codistributive semiring has a right-annihilative meet: -- -- @ 'codistributive' 'top' a 'bottom' = 'top' '=~' 'top' '∨' a @ -- -- idempotent mulitiplication: -- -- @ 'codistributive' 'bottom' 'bottom' a = a '=~' a '∧' a @ -- -- and idempotent addition: -- -- @ 'codistributive' a 'bottom' a = a '=~' a '∨' a @ -- -- Furthermore if /R/ is commutative then it is a right-distributive lattice. -- codistributive :: Lattice r => r -> r -> r -> Bool codistributive = Prop.distributive_on' (=~) (∧) (∨) -- | @ 'glb' x x y = x @ -- majority_glb :: Lattice r => r -> r -> Bool majority_glb x y = glb x y y =~ y -- | @ 'glb' x y z = 'glb' z x y @ -- commutative_glb :: Lattice r => r -> r -> r -> Bool commutative_glb x y z = glb x y z =~ glb z x y -- | @ 'glb' x y z = 'glb' x z y @ -- commutative_glb' :: Lattice r => r -> r -> r -> Bool commutative_glb' x y z = glb x y z =~ glb x z y -- | @ 'glb' ('glb' x w y) w z = 'glb' x w ('glb' y w z) @ -- associative_glb :: Lattice r => r -> r -> r -> r -> Bool associative_glb x y z w = glb (glb x w y) w z =~ glb x w (glb y w z) ------------------------------------------------------------------------------------ -- Properties of semilattice & lattice morphisms -- | \( \forall a, b: f(a ∨ b) = f(a) ∨ f(b) \) -- -- Given two join-semilattices (S, ∨) and (T, ∨), a homomorphism is a monotone function /f: S → T/ such that -- -- @ f (x '∨' y) '=~' f x '∨' f y @ -- -- This is a required property for join semilattice morphisms. -- morphism_join :: JoinSemilattice r => JoinSemilattice s => (r -> s) -> r -> r -> Bool morphism_join = morphism_join_on (=~) morphism_join_on :: (Join-Semigroup) r => (Join-Semigroup) s => Rel s b -> (r -> s) -> r -> r -> b morphism_join_on (~~) f x y = (f $ x ∨ y) ~~ (f x ∨ f y) -- | \( \forall a, b: f(bottom) = bottom \) -- -- This is a required property for bounded join semilattice morphisms. -- morphism_join' :: BoundedJoinSemilattice r => BoundedJoinSemilattice s => (r -> s) -> Bool morphism_join' = morphism_join_on' (=~) morphism_join_on' :: (Join-Monoid) r => (Join-Monoid) s => Rel s b -> (r -> s) -> b morphism_join_on' (~~) f = (f bottom) ~~ bottom -- | \( \forall a, b: f(a ∧ b) = f(a) ∧ f(b) \) -- -- The obvious dual replacing '∧' with '∨' and 'bottom' with 'top' transforms this -- definition of a join-semilattice homomorphism into its meet-semilattice equivalent. -- -- This is a required property for meet semilattice morphisms. -- morphism_meet :: MeetSemilattice r => MeetSemilattice s => (r -> s) -> r -> r -> Bool morphism_meet = morphism_meet_on (=~) morphism_meet_on :: (Meet-Semigroup) r => (Meet-Semigroup) s => Rel s b -> (r -> s) -> r -> r -> b morphism_meet_on (~~) f x y = (f $ x ∧ y) ~~ (f x ∧ f y) -- | \( \forall a, b: f(top) = top \) -- -- This is a required property for bounded meet semilattice morphisms. -- morphism_meet' :: BoundedMeetSemilattice r => BoundedMeetSemilattice s => (r -> s) -> Bool morphism_meet' = morphism_meet_on' (=~) morphism_meet_on' :: (Meet-Monoid) r => (Meet-Monoid) s => Rel s b -> (r -> s) -> b morphism_meet_on' (~~) f = (f top) ~~ top -- | Distributive lattice morphisms are compatible with 'glb'. -- morphism_distributive :: Prd r => Prd s => Lattice r => Lattice s => (r -> s) -> r -> r -> r -> Bool morphism_distributive f x y z = f (glb x y z) =~ glb (f x) (f y) (f z)