{-# LANGUAGE CPP #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} #ifndef HLINT {-# LANGUAGE DefaultSignatures #-} #endif {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_HADDOCK not-home #-} -------------------------------------------------------------------- -- | -- Copyright : © Edward Kmett 2010-2014, Johan Kiviniemi 2013 -- License : BSD3 -- Maintainer: Edward Kmett -- Stability : experimental -- Portability: non-portable -- -------------------------------------------------------------------- module Ersatz.Orderable ( Orderable(..) , GOrderable(..) ) where import Prelude hiding ((&&),(||),not,and,or,all,any) import Data.Foldable (toList) import Data.Int import Data.Void import Data.Word import Ersatz.Bit import Ersatz.Equatable import GHC.Generics import Numeric.Natural import qualified Data.IntMap as IntMap import qualified Data.Map as Map import qualified Data.Sequence as Seq import qualified Data.Tree as Tree infix 4 =?, >? -- | Instances for this class for arbitrary types can be automatically derived from 'Generic'. class Equatable t => Orderable t where -- | Compare for less-than within the SAT problem. ( t -> Bit -- | Compare for less-than or equal-to within the SAT problem. (<=?) :: t -> t -> Bit x <=? y = x === y || x t -> t -> Bit a =?) :: t -> t -> Bit x >=? y = y <=? x -- | Compare for greater-than within the SAT problem. (>?) :: t -> t -> Bit x >? y = y Orderable (Map.Map k v) where x Orderable (IntMap.IntMap v) where x [(k,v)] -> [(k,v)] -> Bit assocsLt _ [] = false assocsLt [] _ = true assocsLt ((k1,v1):xs) ((k2,v2):ys) = case compare k1 k2 of LT -> true GT -> false EQ -> v1 [(k,v)] -> [(k,v)] -> Bit assocsLe [] _ = true assocsLe _ [] = false assocsLe ((k1,v1):xs) ((k2,v2):ys) = case compare k1 k2 of LT -> true GT -> false EQ -> v1 Orderable (Seq.Seq v) where x Orderable (Tree.Tree a) where Tree.Node x xs Orderable (a,b) instance (Orderable a, Orderable b, Orderable c) => Orderable (a,b,c) instance (Orderable a, Orderable b, Orderable c, Orderable d) => Orderable (a,b,c,d) instance (Orderable a, Orderable b, Orderable c, Orderable d, Orderable e) => Orderable (a,b,c,d,e) instance (Orderable a, Orderable b, Orderable c, Orderable d, Orderable e, Orderable f) => Orderable (a,b,c,d,e,f) instance (Orderable a, Orderable b, Orderable c, Orderable d, Orderable e, Orderable f, Orderable g) => Orderable (a,b,c,d,e,f,g) instance Orderable a => Orderable (Maybe a) instance (Orderable a, Orderable b) => Orderable (Either a b) -- | Lexicographic order instance Orderable a => Orderable [a] where #ifndef HLINT [] GOrderable f where ( f a -> Bit (<=?#) :: f a -> f a -> Bit instance GOrderable U1 where U1 GOrderable (f :*: g) where (a :*: b) GOrderable (f :+: g) where L1 _ GOrderable (M1 i c f) where M1 x GOrderable (K1 i a) where K1 a