module Duration.Lattice (POrd (..), Lattice (..), Complete (..)) where
import Duration.POrd
class POrd d => Lattice d where
meet :: [d] -> d
join :: [d] -> d
join = compl . meet . (map compl)
compl :: d -> d
top :: d
top = meet []
bot :: d
bot = join []
instance Lattice Integer where
meet = minimum
compl = negate
instance Lattice Rational where
meet = minimum
compl = negate
data Complete a = Top | Bot | Value a deriving (Eq, Show)
instance (Ord a, Num a) => Num (Complete a) where
Bot + Top = error "Complete : undefined sum (Bot + Top)"
Top + Bot = error "Complete : undefined sum (Top + Bot)"
Bot + _ = Bot
_ + Bot = Bot
Top + _ = Top
_ + Top = Top
Value x + Value y = Value $ x+y
negate Bot = Top
negate Top = Bot
negate (Value x) = Value $ negate x
signum = const $ Value 1
abs = id
fromInteger = Value . fromInteger
(Value x) * (Value y) = Value $ x*y
Top * Top = Top
Top * Bot = Bot
Bot * Top = Bot
Bot * Bot = Top
Top * (Value y)
= case y of
0 -> error "Complete : undefined sum product (Top * 0)"
_ -> Top
Bot * (Value y) = Top * (Value (y))
(Value y) * Top = Top * (Value y)
(Value y) * Bot = Top * (Value (y))
instance (Ord a, Fractional a) => Fractional (Complete a) where
recip Bot = Value 0
recip Top = Value 0
recip (Value f) = Value (recip f)
fromRational f = Value (fromRational f)
instance Ord a => Ord (Complete a) where
(<=) Bot _ = True
(<=) _ Top = True
(<=) _ Bot = False
(<=) Top _ = False
(<=) (Value x) (Value y) = x <= y
instance POrd a => POrd (Complete a) where
pLeq _ Top = True
pLeq Top _ = False
pLeq Bot _ = True
pLeq _ Bot = False
pLeq (Value a) (Value b) = pLeq a b
instance (Num a, Ord a, POrd a) => Lattice (Complete a) where
meet [] = Top
meet (x:xs)
= let rs = meet xs
in case compare x rs of
LT -> x
_ -> rs
compl = negate
instance (Lattice a,Lattice b) => Lattice (a,b) where
meet l = (meet . fst . unzip $ l,meet . snd . unzip $ l)
compl (a,b) = (compl a, compl b)
instance (Lattice a,Lattice b) => Lattice (Complete (Either a b)) where
meet = meetCE
where
meetCE [] = Top
meetCE (x:l)
= case (x,meetCE l) of
(Top,r) -> r
(r,Top) -> r
(Value (Left a1),Value (Left a2))
-> Value (Left (meet [a1,a2]))
(Value (Right b1),Value (Right b2))
-> Value (Right (meet [b1,b2]))
_ -> Bot
compl Top = Bot
compl Bot = Top
compl (Value (Left a)) = Value (Left $ compl a)
compl (Value (Right b)) = Value (Right $ compl b)