connections 0.1.0 → 0.2.0
raw patch · 25 files changed
+3608/−3735 lines, 25 filesdep +doctestdep −finite-typelitsdep −transformersdep −universe-basedep ~basenew-component:exe:doctestPVP ok
version bump matches the API change (PVP)
Dependencies added: doctest
Dependencies removed: finite-typelits, transformers, universe-base
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.Connection: (/\) :: Semilattice 'R a => a -> a -> a
- Data.Connection: (\/) :: Semilattice 'L a => a -> a -> a
- Data.Connection: L :: Kan
- Data.Connection: R :: Kan
- Data.Connection: ceiling :: Connection 'L a b => a -> b
- Data.Connection: ceiling1 :: Connection 'L a b => (a -> a) -> b -> b
- Data.Connection: ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b
- Data.Connection: choice :: Conn k a b -> Conn k c d -> Conn k (Either a c) (Either b d)
- Data.Connection: class (Preorder a, Preorder b) => Connection k a b
- Data.Connection: conn :: Connection k a b => Conn k a b
- Data.Connection: connL :: Connection 'L a b => ConnL a b
- Data.Connection: connR :: Connection 'R a b => ConnR a b
- Data.Connection: data Conn (k :: Kan) a b
- Data.Connection: data Kan
- Data.Connection: embedL :: Connection 'L a b => b -> a
- Data.Connection: embedR :: Connection 'R a b => b -> a
- Data.Connection: filterL :: Connection 'L a b => a -> b -> Bool
- Data.Connection: filterR :: Connection 'R a b => a -> b -> Bool
- Data.Connection: floor :: Connection 'R a b => a -> b
- Data.Connection: floor1 :: Connection 'R a b => (a -> a) -> b -> b
- Data.Connection: floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b
- Data.Connection: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection: glb :: Triple (a, a) a => a -> a -> a -> a
- Data.Connection: half :: (Num a, Preorder a) => Trip a b -> a -> Maybe Ordering
- Data.Connection: infixr 5 \/
- Data.Connection: infixr 6 /\
- Data.Connection: lub :: Triple (a, a) a => a -> a -> a -> a
- Data.Connection: maximal :: Extremal 'R a => a
- Data.Connection: maybeL :: Triple () b => Trip (Maybe a) (Either a b)
- Data.Connection: maybeR :: Triple () a => Trip (Maybe b) (Either a b)
- Data.Connection: midpoint :: Fractional a => Trip a b -> a -> a
- Data.Connection: minimal :: Extremal 'L a => a
- Data.Connection: pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b
- Data.Connection: pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b
- Data.Connection: pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b
- Data.Connection: round :: forall a b. (Num a, Triple a b) => a -> b
- Data.Connection: round1 :: forall a b. (Num a, Triple a b) => (a -> a) -> b -> b
- Data.Connection: round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
- Data.Connection: strong :: Conn k a b -> Conn k c d -> Conn k (a, c) (b, d)
- Data.Connection: swapL :: ConnR a b -> ConnL b a
- Data.Connection: swapR :: ConnL a b -> ConnR b a
- Data.Connection: truncate :: (Num a, Triple a b) => a -> b
- Data.Connection: truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b
- Data.Connection: truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
- Data.Connection: type ConnDouble k = Connection k Double
- Data.Connection: type ConnExtended k a b = Connection k a (Extended b)
- Data.Connection: type ConnFloat k = Connection k Float
- Data.Connection: type ConnInteger k = Connection k (Maybe Integer)
- Data.Connection: type ConnL = Conn 'L
- Data.Connection: type ConnR = Conn 'R
- Data.Connection: type ConnRational k = Connection k Rational
- Data.Connection: type Extremal k = Connection k ()
- Data.Connection: type Semilattice k a = Connection k (a, a) a
- Data.Connection: type Trip a b = forall k. Conn k a b
- Data.Connection: type Triple a b = (Connection 'L a b, Connection 'R a b)
- Data.Connection.Class: (/\) :: Semilattice 'R a => a -> a -> a
- Data.Connection.Class: (\/) :: Semilattice 'L a => a -> a -> a
- Data.Connection.Class: filterL :: Connection 'L a b => a -> b -> Bool
- Data.Connection.Class: filterR :: Connection 'R a b => a -> b -> Bool
- Data.Connection.Class: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.L () a, Data.Order.Preorder b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L () (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a, Data.Connection.Class.Connection 'Data.Connection.Conn.L (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Either.Either a b, Data.Either.Either a b) (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a, Data.Connection.Class.Connection 'Data.Connection.Conn.R (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Either.Either a b, Data.Either.Either a b) (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Connection.Class.Triple (a, a) a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k ((a, b), (a, b)) (a, b)
- Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Connection 'Data.Connection.Conn.R () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Either.Either a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Connection 'Data.Connection.Conn.L (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Connection 'Data.Connection.Conn.R (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Set.Internal.Set a)
- Data.Connection.Class: instance (Data.Order.Total a, Data.Universe.Class.Finite a, Data.Connection.Class.Connection 'Data.Connection.Conn.R () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Map.Internal.Map a b)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () a) => Data.Connection.Class.Connection k () (Data.Semigroup.Internal.Endo a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k () (Data.Functor.Contravariant.Op b a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k () (a -> b)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (a, a) a) => Data.Connection.Class.Connection k (Data.Semigroup.Internal.Endo a, Data.Semigroup.Internal.Endo a) (Data.Semigroup.Internal.Endo a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k (Data.Functor.Contravariant.Op b a, Data.Functor.Contravariant.Op b a) (Data.Functor.Contravariant.Op b a)
- Data.Connection.Class: instance (Data.Universe.Class.Finite a, Data.Connection.Class.Triple (b, b) b) => Data.Connection.Class.Connection k (a -> b, a -> b) (a -> b)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Order.Extended.Extended a, Data.Order.Extended.Extended a) (Data.Order.Extended.Extended a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (GHC.Maybe.Maybe a, GHC.Maybe.Maybe a) (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Int.Int64)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Double (Data.Order.Extended.Extended GHC.Types.Int)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Int.Int32)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Int.Int64)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Float (Data.Order.Extended.Extended GHC.Types.Int)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Integer.Type.Integer
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Natural.Natural
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Types.Int
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe GHC.Integer.Type.Integer) GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Order.Extended.Extended a, Data.Order.Extended.Extended a) (Data.Order.Extended.Extended a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (GHC.Maybe.Maybe a, GHC.Maybe.Maybe a) (GHC.Maybe.Maybe a)
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int32 GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int32 GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Int.Int64 GHC.Int.Int8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Integer.Type.Integer
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Natural.Natural GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word16 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word32 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word32 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.R GHC.Word.Word64 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection k () Data.IntSet.Internal.IntSet
- Data.Connection.Class: instance Data.Connection.Class.Connection k (Data.Finite.Internal.Finite n, Data.Finite.Internal.Finite n) (Data.Finite.Internal.Finite n)
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int16 GHC.Word.Word16
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int32 GHC.Word.Word32
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Word.Word64
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int8 GHC.Word.Word8
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Int.Int64
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Types.Word
- Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Word GHC.Word.Word64
- Data.Connection.Class: instance Data.Universe.Class.Finite a => Data.Connection.Class.Connection k () (Data.Functor.Contravariant.Predicate a)
- Data.Connection.Class: instance Data.Universe.Class.Finite a => Data.Connection.Class.Connection k (Data.Functor.Contravariant.Predicate a, Data.Functor.Contravariant.Predicate a) (Data.Functor.Contravariant.Predicate a)
- Data.Connection.Class: instance GHC.TypeNats.KnownNat n => Data.Connection.Class.Connection k () (Data.Finite.Internal.Finite n)
- Data.Connection.Class: maybeL :: Triple () b => Trip (Maybe a) (Either a b)
- Data.Connection.Class: maybeR :: Triple () a => Trip (Maybe b) (Either a b)
- Data.Connection.Class: swapL :: ConnR a b -> ConnL b a
- Data.Connection.Class: swapR :: ConnL a b -> ConnR b a
- Data.Connection.Class: type ConnDouble k = Connection k Double
- Data.Connection.Class: type ConnFloat k = Connection k Float
- Data.Connection.Class: type Extremal k = Connection k ()
- Data.Connection.Class: type Semilattice k a = Connection k (a, a) a
- Data.Connection.Class: type Trip a b = forall k. Conn k a b
- Data.Connection.Conn: counitL :: ConnL a b -> b -> b
- Data.Connection.Conn: counitR :: ConnR a b -> a -> a
- Data.Connection.Conn: fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)
- Data.Connection.Conn: lowerL :: ConnL a b -> a -> b
- Data.Connection.Conn: lowerL1 :: ConnL a b -> (a -> a) -> b -> b
- Data.Connection.Conn: lowerL2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b
- Data.Connection.Conn: lowerR1 :: ConnR a b -> (b -> b) -> a -> a
- Data.Connection.Conn: lowerR2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a
- Data.Connection.Conn: trip :: (a -> b) -> (b -> a) -> (a -> b) -> Trip a b
- Data.Connection.Conn: type Trip a b = forall k. Conn k a b
- Data.Connection.Conn: unitL :: ConnL a b -> a -> a
- Data.Connection.Conn: unitR :: ConnR a b -> b -> b
- Data.Connection.Conn: upperL1 :: ConnL a b -> (b -> b) -> a -> a
- Data.Connection.Conn: upperL2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a
- Data.Connection.Conn: upperR :: ConnR a b -> a -> b
- Data.Connection.Conn: upperR1 :: ConnR a b -> (a -> a) -> b -> b
- Data.Connection.Conn: upperR2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b
- Data.Connection.Double: covers :: Double -> Double -> Bool
- Data.Connection.Double: epsilon :: Double
- Data.Connection.Double: f64f32 :: Conn k Double Float
- Data.Connection.Double: f64i08 :: Conn k Double (Extended Int8)
- Data.Connection.Double: f64i16 :: Conn k Double (Extended Int16)
- Data.Connection.Double: f64i32 :: Conn k Double (Extended Int32)
- Data.Connection.Double: max64 :: Double -> Double -> Double
- Data.Connection.Double: min64 :: Double -> Double -> Double
- Data.Connection.Double: shift :: Int64 -> Double -> Double
- Data.Connection.Double: ulp :: Double -> Double -> Maybe (Ordering, Word64)
- Data.Connection.Double: until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a
- Data.Connection.Double: within :: Word64 -> Double -> Double -> Bool
- Data.Connection.Float: covers :: Float -> Float -> Bool
- Data.Connection.Float: epsilon :: Float
- Data.Connection.Float: shift :: Int32 -> Float -> Float
- Data.Connection.Float: ulp :: Float -> Float -> Maybe (Ordering, Word32)
- Data.Connection.Float: within :: Word32 -> Float -> Float -> Bool
- Data.Connection.Int: i08c08 :: ConnL Int8 CChar
- Data.Connection.Int: i08w08 :: Conn k Int8 Word8
- Data.Connection.Int: i16c16 :: ConnL Int16 CShort
- Data.Connection.Int: i16w16 :: Conn k Int16 Word16
- Data.Connection.Int: i32c32 :: ConnL Int32 CInt
- Data.Connection.Int: i32w32 :: Conn k Int32 Word32
- Data.Connection.Int: i64c64 :: ConnL Int64 CLong
- Data.Connection.Int: i64w64 :: Conn k Int64 Word64
- Data.Connection.Int: intnat :: ConnL Integer Natural
- Data.Connection.Int: ixxi64 :: Conn k Int Int64
- Data.Connection.Int: ixxwxx :: Conn k Int Word
- Data.Connection.Property: ordering :: Trip () Ordering
- Data.Connection.Property: range' :: Triple () a => (a, a)
- Data.Connection.Word: binc08 :: ConnL Bool CBool
- Data.Connection.Word: c08bin :: ConnL CBool Bool
- Data.Connection.Word: w08c08 :: ConnL Word8 CUChar
- Data.Connection.Word: w08i08 :: ConnL Word8 Int8
- Data.Connection.Word: w16c16 :: ConnL Word16 CUShort
- Data.Connection.Word: w16i16 :: ConnL Word16 Int16
- Data.Connection.Word: w32c32 :: ConnL Word32 CUInt
- Data.Connection.Word: w32i32 :: ConnL Word32 Int32
- Data.Connection.Word: w64c64 :: ConnL Word64 CULong
- Data.Connection.Word: w64i64 :: ConnL Word64 Int64
- Data.Connection.Word: wxxw64 :: Conn k Word Word64
- Data.Lattice: class Lattice a => Heyting k a
- Data.Lattice: false :: Lattice a => a
- Data.Lattice: glb :: Triple (a, a) a => a -> a -> a -> a
- Data.Lattice: heytingL :: Lattice a => (a -> a -> a) -> a -> Conn 'L a a
- Data.Lattice: heytingR :: Lattice a => (a -> a -> a) -> a -> Conn 'R a a
- Data.Lattice: instance (Data.Lattice.Heyting k a, Data.Lattice.Heyting k b) => Data.Lattice.Heyting k (a, b)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Boolean (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Order.Total a, Data.Universe.Class.Finite a) => Data.Lattice.Symmetric (Data.Set.Internal.Set a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting a) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting a) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.L (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Biheyting b) => Data.Lattice.Heyting 'Data.Connection.Conn.R (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean a) => Data.Lattice.Boolean (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean b) => Data.Lattice.Boolean (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Boolean b) => Data.Lattice.Boolean (a -> b)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric a) => Data.Lattice.Symmetric (Data.Semigroup.Internal.Endo a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric b) => Data.Lattice.Symmetric (Data.Functor.Contravariant.Op b a)
- Data.Lattice: instance (Data.Universe.Class.Finite a, Data.Lattice.Symmetric b) => Data.Lattice.Symmetric (a -> b)
- Data.Lattice: instance Data.Lattice.Boolean Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L ()
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Int.Int8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Bool
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Int
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Ordering
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Types.Word
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.L GHC.Word.Word8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R ()
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Int.Int8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Bool
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Int
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Ordering
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Types.Word
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word16
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word32
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word64
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R GHC.Word.Word8
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Lifted a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Order.Extended.Lowered a)
- Data.Lattice: instance Data.Lattice.Heyting 'Data.Connection.Conn.R a => Data.Lattice.Heyting 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
- Data.Lattice: instance Data.Lattice.Symmetric Data.IntSet.Internal.IntSet
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Boolean (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance Data.Universe.Class.Finite a => Data.Lattice.Symmetric (Data.Functor.Contravariant.Predicate a)
- Data.Lattice: instance GHC.TypeNats.KnownNat n => Data.Lattice.Heyting 'Data.Connection.Conn.L (Data.Finite.Internal.Finite n)
- Data.Lattice: instance GHC.TypeNats.KnownNat n => Data.Lattice.Heyting 'Data.Connection.Conn.R (Data.Finite.Internal.Finite n)
- Data.Lattice: lub :: Triple (a, a) a => a -> a -> a -> a
- Data.Lattice: true :: Lattice a => a
- Data.Lattice: type HeytingL = Heyting 'L
- Data.Lattice: type HeytingR = Heyting 'R
- Data.Lattice: type Semilattice k a = Connection k (a, a) a
- Data.Lattice.Property: heytingL0 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL1 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL10 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL11 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL12 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL13 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL14 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL15 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL16 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL17 :: Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL18 :: Heyting 'L c => c -> Bool
- Data.Lattice.Property: heytingL19 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL2 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL20 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL3 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL4 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL5 :: Heyting 'L a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingL6 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL7 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingL8 :: forall a. Heyting 'L a => a -> Bool
- Data.Lattice.Property: heytingL9 :: Heyting 'L a => a -> a -> Bool
- Data.Lattice.Property: heytingR0 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR1 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR10 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR11 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR12 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR13 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR14 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR15 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR16 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR17 :: Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR2 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR3 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR4 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR5 :: Heyting 'R a => a -> a -> a -> Bool
- Data.Lattice.Property: heytingR6 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR7 :: Heyting 'R a => a -> a -> Bool
- Data.Lattice.Property: heytingR8 :: forall a. Heyting 'R a => a -> Bool
- Data.Lattice.Property: heytingR9 :: Heyting 'R a => a -> a -> Bool
- Data.Order: (<) :: Preorder a => a -> a -> Bool
- Data.Order: (>) :: Preorder a => a -> a -> Bool
- Data.Order: instance (Data.Order.Total a, Data.Order.Preorder r, Data.Universe.Class.Finite r) => Data.Order.Preorder (Control.Monad.Trans.Cont.Cont r a)
- Data.Order: instance (Data.Order.Total a, Data.Order.Preorder r, Data.Universe.Class.Finite r) => Data.Order.Preorder (Control.Monad.Trans.Select.Select r a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder a) => Data.Order.Preorder (Data.Semigroup.Internal.Endo a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder b) => Data.Order.Preorder (Data.Functor.Contravariant.Op b a)
- Data.Order: instance (Data.Universe.Class.Finite a, Data.Order.Preorder b) => Data.Order.Preorder (a -> b)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Semigroup.Internal.Endo a)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Contravariant.Op b a)
- Data.Order: instance (Data.Universe.Class.Finite a, GHC.Classes.Eq b) => GHC.Classes.Eq (a -> b)
- Data.Order: instance Data.Order.Preorder (Data.Finite.Internal.Finite n)
- Data.Order: instance Data.Universe.Class.Finite a => Data.Order.Preorder (Data.Functor.Contravariant.Predicate a)
- Data.Order: instance Data.Universe.Class.Finite a => GHC.Classes.Eq (Data.Functor.Contravariant.Predicate a)
- Data.Order.Interval: open32 :: Float -> Float -> Interval Float
- Data.Order.Interval: open32L :: Float -> Float -> Interval Float
- Data.Order.Interval: open32R :: Float -> Float -> Interval Float
- Data.Order.Interval: open64 :: Double -> Double -> Interval Double
- Data.Order.Interval: open64L :: Double -> Double -> Interval Double
- Data.Order.Interval: open64R :: Double -> Double -> Interval Double
+ Data.Connection.Class: (/|\) :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c
+ Data.Connection.Class: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Data.Connection.Class: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Data.Connection.Class: (\|/) :: Conn k c a -> Conn k c b -> Conn k c (Either a b)
+ Data.Connection.Class: embed :: Conn k a b -> b -> a
+ Data.Connection.Class: extremal :: Triple () a => Conn k a Bool
+ Data.Connection.Class: half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering
+ Data.Connection.Class: identity :: Conn k a a
+ Data.Connection.Class: infixr 1 <<<
+ Data.Connection.Class: infixr 3 \|/
+ Data.Connection.Class: infixr 4 /|\
+ Data.Connection.Class: instance (Data.Connection.Class.Left () a, Data.Order.Preorder b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L () (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Connection.Class.Triple () a, Data.Order.Preorder b) => Data.Connection.Class.Connection k (GHC.Maybe.Maybe b) (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Right () b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Preorder a, Data.Connection.Class.Triple () b) => Data.Connection.Class.Connection k (GHC.Maybe.Maybe a) (Data.Either.Either a b)
+ Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Left (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
+ Data.Connection.Class: instance (Data.Order.Total a, Data.Connection.Class.Right (b, b) b) => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.Map.Internal.Map a b, Data.Map.Internal.Map a b) (Data.Map.Internal.Map a b)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L () Data.IntSet.Internal.IntSet
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L () GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int16 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int32 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int64 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Int.Int8 GHC.Word.Word8
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Integer.Type.Integer GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Natural.Natural (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Int GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Word (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Types.Word GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word16 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word32 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word64 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word64 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int16)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int32)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Int.Int64)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Integer.Type.Integer)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 (GHC.Maybe.Maybe GHC.Types.Int)
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Natural.Natural
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word16
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word32
+ Data.Connection.Class: instance Data.Connection.Class.Connection 'Data.Connection.Conn.L GHC.Word.Word8 GHC.Word.Word64
+ Data.Connection.Class: instance Data.Connection.Class.Connection k Data.Order.Positive GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int16 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int32 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int64 GHC.Types.Int
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Int.Int8 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Real.Rational GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Double GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Float GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Int GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Ordering GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Types.Word GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word16 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word32 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word64 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word64 GHC.Types.Word
+ Data.Connection.Class: instance Data.Connection.Class.Connection k GHC.Word.Word8 GHC.Types.Bool
+ Data.Connection.Class: instance Data.Connection.Class.Left (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
+ Data.Connection.Class: instance Data.Connection.Class.Right () a => Data.Connection.Class.Connection 'Data.Connection.Conn.R () (GHC.Maybe.Maybe a)
+ Data.Connection.Class: instance Data.Connection.Class.Right (a, a) a => Data.Connection.Class.Connection 'Data.Connection.Conn.R (Data.IntMap.Internal.IntMap a, Data.IntMap.Internal.IntMap a) (Data.IntMap.Internal.IntMap a)
+ Data.Connection.Class: join :: Left (a, a) a => a -> a -> a
+ Data.Connection.Class: meet :: Right (a, a) a => a -> a -> a
+ Data.Connection.Class: midpoint :: Fractional a => ConnK a b -> a -> a
+ Data.Connection.Class: range :: Conn k a b -> a -> (b, b)
+ Data.Connection.Class: round :: forall a b. (Num a, Triple a b) => a -> b
+ Data.Connection.Class: round1 :: (Num a, Triple a b) => (a -> a) -> b -> b
+ Data.Connection.Class: round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: truncate :: (Num a, Triple a b) => a -> b
+ Data.Connection.Class: truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b
+ Data.Connection.Class: truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: type ConnK a b = forall k. Conn k a b
+ Data.Connection.Class: type Left = Connection 'L
+ Data.Connection.Class: type Right = Connection 'R
+ Data.Connection.Conn: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Data.Connection.Conn: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Data.Connection.Conn: ceilingWith :: ConnL a b -> a -> b
+ Data.Connection.Conn: ceilingWith1 :: ConnL a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: ceilingWith2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: counit :: ConnL a b -> b -> b
+ Data.Connection.Conn: filterWith :: Preorder b => ConnL a b -> a -> b -> Bool
+ Data.Connection.Conn: floorWith :: ConnR a b -> a -> b
+ Data.Connection.Conn: floorWith1 :: ConnR a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: floorWith2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering
+ Data.Connection.Conn: idealWith :: Preorder b => ConnR a b -> a -> b -> Bool
+ Data.Connection.Conn: identity :: Conn k a a
+ Data.Connection.Conn: infixr 1 <<<
+ Data.Connection.Conn: lower :: ConnR a b -> a -> a
+ Data.Connection.Conn: lower1 :: ConnR a b -> (b -> b) -> a -> a
+ Data.Connection.Conn: lower2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a
+ Data.Connection.Conn: midpoint :: Fractional a => ConnK a b -> a -> a
+ Data.Connection.Conn: roundWith :: forall a b. (Num a, Preorder a) => ConnK a b -> a -> b
+ Data.Connection.Conn: roundWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: roundWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: truncateWith :: (Num a, Preorder a) => ConnK a b -> a -> b
+ Data.Connection.Conn: truncateWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b
+ Data.Connection.Conn: truncateWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b
+ Data.Connection.Conn: type ConnK a b = forall k. Conn k a b
+ Data.Connection.Conn: unit :: ConnR a b -> b -> b
+ Data.Connection.Conn: upL :: ConnL (Down a) (Down b) -> ConnL b a
+ Data.Connection.Conn: upR :: ConnR (Down a) (Down b) -> ConnR b a
+ Data.Connection.Conn: upper :: ConnL a b -> a -> a
+ Data.Connection.Conn: upper1 :: ConnL a b -> (b -> b) -> a -> a
+ Data.Connection.Conn: upper2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a
+ Data.Connection.Float: f64f32 :: Conn k Double Float
+ Data.Connection.Float: f64i08 :: Conn k Double (Extended Int8)
+ Data.Connection.Float: f64i16 :: Conn k Double (Extended Int16)
+ Data.Connection.Float: f64i32 :: Conn k Double (Extended Int32)
+ Data.Connection.Float: max64 :: Double -> Double -> Double
+ Data.Connection.Float: min64 :: Double -> Double -> Double
+ Data.Connection.Float: near32 :: Word32 -> Float -> Float -> Bool
+ Data.Connection.Float: near64 :: Word64 -> Double -> Double -> Bool
+ Data.Connection.Float: shift32 :: Int32 -> Float -> Float
+ Data.Connection.Float: shift64 :: Int64 -> Double -> Double
+ Data.Connection.Float: ulp32 :: Float -> Float -> Maybe (Ordering, Word32)
+ Data.Connection.Float: ulp64 :: Double -> Double -> Maybe (Ordering, Word64)
+ Data.Connection.Float: until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a
+ Data.Connection.Int: i08ixx :: ConnL Int8 (Maybe Int)
+ Data.Connection.Int: i16ixx :: ConnL Int16 (Maybe Int)
+ Data.Connection.Int: i32ixx :: ConnL Int32 (Maybe Int)
+ Data.Connection.Int: i64ixx :: Conn k Int64 Int
+ Data.Connection.Int: w08i16 :: ConnL Word8 (Maybe Int16)
+ Data.Connection.Int: w08i32 :: ConnL Word8 (Maybe Int32)
+ Data.Connection.Int: w08i64 :: ConnL Word8 (Maybe Int64)
+ Data.Connection.Int: w08int :: ConnL Word8 (Maybe Integer)
+ Data.Connection.Int: w08ixx :: ConnL Word8 (Maybe Int)
+ Data.Connection.Int: w16i32 :: ConnL Word16 (Maybe Int32)
+ Data.Connection.Int: w16i64 :: ConnL Word16 (Maybe Int64)
+ Data.Connection.Int: w16int :: ConnL Word16 (Maybe Integer)
+ Data.Connection.Int: w16ixx :: ConnL Word16 (Maybe Int)
+ Data.Connection.Int: w32i64 :: ConnL Word32 (Maybe Int64)
+ Data.Connection.Int: w32int :: ConnL Word32 (Maybe Integer)
+ Data.Connection.Int: w32ixx :: ConnL Word32 (Maybe Int)
+ Data.Connection.Int: w64int :: ConnL Word64 (Maybe Integer)
+ Data.Connection.Int: wxxint :: ConnL Word (Maybe Integer)
+ Data.Connection.Word: i08nat :: ConnL Int8 Natural
+ Data.Connection.Word: i08w08 :: ConnL Int8 Word8
+ Data.Connection.Word: i08w16 :: ConnL Int8 Word16
+ Data.Connection.Word: i08w32 :: ConnL Int8 Word32
+ Data.Connection.Word: i08w64 :: ConnL Int8 Word64
+ Data.Connection.Word: i08wxx :: ConnL Int8 Word
+ Data.Connection.Word: i16nat :: ConnL Int16 Natural
+ Data.Connection.Word: i16w16 :: ConnL Int16 Word16
+ Data.Connection.Word: i16w32 :: ConnL Int16 Word32
+ Data.Connection.Word: i16w64 :: ConnL Int16 Word64
+ Data.Connection.Word: i16wxx :: ConnL Int16 Word
+ Data.Connection.Word: i32nat :: ConnL Int32 Natural
+ Data.Connection.Word: i32w32 :: ConnL Int32 Word32
+ Data.Connection.Word: i32w64 :: ConnL Int32 Word64
+ Data.Connection.Word: i32wxx :: ConnL Int32 Word
+ Data.Connection.Word: i64nat :: ConnL Int64 Natural
+ Data.Connection.Word: i64w64 :: ConnL Int64 Word64
+ Data.Connection.Word: i64wxx :: ConnL Int64 Word
+ Data.Connection.Word: intnat :: ConnL Integer Natural
+ Data.Connection.Word: ixxnat :: ConnL Int Natural
+ Data.Connection.Word: ixxw64 :: ConnL Int Word64
+ Data.Connection.Word: ixxwxx :: ConnL Int Word
+ Data.Connection.Word: w64wxx :: Conn k Word64 Word
+ Data.Lattice: algebra :: Algebra k a => a -> Conn k a a
+ Data.Lattice: bottom :: Join a => a
+ Data.Lattice: bounded :: (Semilattice k a, Connection k () a) => Conn k () a
+ Data.Lattice: class Semilattice k a => Algebra k a
+ Data.Lattice: class Order a => Semilattice (k :: Kan) a
+ Data.Lattice: coheyting :: Join a => (a -> a -> a) -> a -> ConnL a a
+ Data.Lattice: instance (Data.Lattice.Coheyting a, Data.Lattice.Coheyting b) => Data.Lattice.Algebra 'Data.Connection.Conn.L (a, b)
+ Data.Lattice: instance (Data.Lattice.Heyting a, Data.Lattice.Heyting b) => Data.Lattice.Algebra 'Data.Connection.Conn.R (a, b)
+ Data.Lattice: instance (Data.Lattice.Join a, Data.Lattice.Join b) => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Either.Either a b)
+ Data.Lattice: instance (Data.Lattice.Lattice a, Data.Lattice.Lattice b) => Data.Lattice.Semilattice k (a, b)
+ Data.Lattice: instance (Data.Lattice.Meet a, Data.Lattice.Meet b) => Data.Lattice.Semilattice 'Data.Connection.Conn.R (Data.Either.Either a b)
+ Data.Lattice: instance (Data.Order.Total k, Data.Lattice.Join a) => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.Map.Internal.Map k a)
+ Data.Lattice: instance (Data.Order.Total k, Data.Lattice.Join a) => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Map.Internal.Map k a)
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L ()
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.L GHC.Word.Word8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R ()
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Algebra 'Data.Connection.Conn.R GHC.Word.Word8
+ Data.Lattice: instance Data.Lattice.Boolean GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Lifted a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (Data.Order.Extended.Lowered a)
+ Data.Lattice: instance Data.Lattice.Heyting a => Data.Lattice.Algebra 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.IntMap.Internal.IntMap a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Join a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Meet a => Data.Lattice.Semilattice 'Data.Connection.Conn.R (Data.Order.Extended.Extended a)
+ Data.Lattice: instance Data.Lattice.Meet a => Data.Lattice.Semilattice 'Data.Connection.Conn.R (GHC.Maybe.Maybe a)
+ Data.Lattice: instance Data.Lattice.Semilattice 'Data.Connection.Conn.L Data.IntSet.Internal.IntSet
+ Data.Lattice: instance Data.Lattice.Semilattice k ()
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int16
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int32
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int64
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Int.Int8
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Bool
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Int
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Ordering
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Types.Word
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word16
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word32
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word64
+ Data.Lattice: instance Data.Lattice.Semilattice k GHC.Word.Word8
+ Data.Lattice: instance Data.Order.Total a => Data.Lattice.Algebra 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
+ Data.Lattice: instance Data.Order.Total a => Data.Lattice.Semilattice 'Data.Connection.Conn.L (Data.Set.Internal.Set a)
+ Data.Lattice: semilattice :: (Semilattice k a, Connection k (a, a) a) => Conn k (a, a) a
+ Data.Lattice: top :: Meet a => a
+ Data.Lattice: type Coheyting a = (Lattice a, Algebra 'L a)
+ Data.Lattice: type Heyting a = (Lattice a, Algebra 'R a)
+ Data.Lattice: type Join = Semilattice 'L
+ Data.Lattice: type Meet = Semilattice 'R
+ Data.Lattice.Property: coheyting0 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting1 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting10 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting11 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting12 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting13 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting14 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting15 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting16 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting17 :: Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting18 :: Coheyting c => c -> Bool
+ Data.Lattice.Property: coheyting19 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting2 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting20 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting3 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting4 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting5 :: Coheyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: coheyting6 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting7 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: coheyting8 :: forall a. Coheyting a => a -> Bool
+ Data.Lattice.Property: coheyting9 :: Coheyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting0 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting1 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting10 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting11 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting12 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting13 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting14 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting15 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting16 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting17 :: Heyting a => a -> Bool
+ Data.Lattice.Property: heyting2 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting3 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting4 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting5 :: Heyting a => a -> a -> a -> Bool
+ Data.Lattice.Property: heyting6 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting7 :: Heyting a => a -> a -> Bool
+ Data.Lattice.Property: heyting8 :: forall a. Heyting a => a -> Bool
+ Data.Lattice.Property: heyting9 :: Heyting a => a -> a -> Bool
+ Data.Order: [getDown] :: Down a -> a
+ Data.Order: pgt :: Preorder a => a -> a -> Bool
+ Data.Order: plt :: Preorder a => a -> a -> Bool
+ Data.Order.Syntax: (<) :: Preorder a => a -> a -> Bool
+ Data.Order.Syntax: (>) :: Preorder a => a -> a -> Bool
- Data.Connection.Class: ceiling :: Connection 'L a b => a -> b
+ Data.Connection.Class: ceiling :: Left a b => a -> b
- Data.Connection.Class: ceiling1 :: Connection 'L a b => (a -> a) -> b -> b
+ Data.Connection.Class: ceiling1 :: Left a b => (a -> a) -> b -> b
- Data.Connection.Class: ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b
- Data.Connection.Class: connL :: Connection 'L a b => ConnL a b
+ Data.Connection.Class: connL :: Left a b => ConnL a b
- Data.Connection.Class: connR :: Connection 'R a b => ConnR a b
+ Data.Connection.Class: connR :: Right a b => ConnR a b
- Data.Connection.Class: embedL :: Connection 'L a b => b -> a
+ Data.Connection.Class: embedL :: Left a b => b -> a
- Data.Connection.Class: embedR :: Connection 'R a b => b -> a
+ Data.Connection.Class: embedR :: Right a b => b -> a
- Data.Connection.Class: floor :: Connection 'R a b => a -> b
+ Data.Connection.Class: floor :: Right a b => a -> b
- Data.Connection.Class: floor1 :: Connection 'R a b => (a -> a) -> b -> b
+ Data.Connection.Class: floor1 :: Right a b => (a -> a) -> b -> b
- Data.Connection.Class: floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b
+ Data.Connection.Class: floor2 :: Right a b => (a -> a -> a) -> b -> b -> b
- Data.Connection.Class: infixr 5 \/
+ Data.Connection.Class: infixr 5 `join`
- Data.Connection.Class: infixr 6 /\
+ Data.Connection.Class: infixr 6 `meet`
- Data.Connection.Class: maximal :: Extremal 'R a => a
+ Data.Connection.Class: maximal :: Right () a => a
- Data.Connection.Class: minimal :: Extremal 'L a => a
+ Data.Connection.Class: minimal :: Left () a => a
- Data.Connection.Class: type ConnExtended k a b = Connection k a (Extended b)
+ Data.Connection.Class: type ConnExtended a b = Triple a (Extended b)
- Data.Connection.Class: type ConnInteger k = Connection k (Maybe Integer)
+ Data.Connection.Class: type ConnInteger a = Left a (Maybe Integer)
- Data.Connection.Class: type ConnL = Conn 'L
+ Data.Connection.Class: type ConnL = Conn 'L
- Data.Connection.Class: type ConnR = Conn 'R
+ Data.Connection.Class: type ConnR = Conn 'R
- Data.Connection.Class: type ConnRational k = Connection k Rational
+ Data.Connection.Class: type ConnRational a = Triple Rational a
- Data.Connection.Class: type Triple a b = (Connection 'L a b, Connection 'R a b)
+ Data.Connection.Class: type Triple a b = (Left a b, Right a b)
- Data.Connection.Conn: range :: Trip a b -> a -> (b, b)
+ Data.Connection.Conn: range :: Conn k a b -> a -> (b, b)
- Data.Connection.Conn: type ConnL = Conn 'L
+ Data.Connection.Conn: type ConnL = Conn 'L
- Data.Connection.Conn: type ConnR = Conn 'R
+ Data.Connection.Conn: type ConnR = Conn 'R
- Data.Connection.Int: i08i16 :: ConnL Int8 Int16
+ Data.Connection.Int: i08i16 :: ConnL Int8 (Maybe Int16)
- Data.Connection.Int: i08i32 :: ConnL Int8 Int32
+ Data.Connection.Int: i08i32 :: ConnL Int8 (Maybe Int32)
- Data.Connection.Int: i08i64 :: ConnL Int8 Int64
+ Data.Connection.Int: i08i64 :: ConnL Int8 (Maybe Int64)
- Data.Connection.Int: i16i32 :: ConnL Int16 Int32
+ Data.Connection.Int: i16i32 :: ConnL Int16 (Maybe Int32)
- Data.Connection.Int: i16i64 :: ConnL Int16 Int64
+ Data.Connection.Int: i16i64 :: ConnL Int16 (Maybe Int64)
- Data.Connection.Int: i32i64 :: ConnL Int32 Int64
+ Data.Connection.Int: i32i64 :: ConnL Int32 (Maybe Int64)
- Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool
+ Data.Connection.Property: adjoint :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
- Data.Connection.Property: closed :: (Preorder a, Preorder b) => Trip a b -> a -> Bool
+ Data.Connection.Property: closed :: (Preorder a, Preorder b) => ConnK a b -> a -> Bool
- Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool
+ Data.Connection.Property: idempotent :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool
- Data.Connection.Property: kernel :: (Preorder a, Preorder b) => Trip a b -> b -> Bool
+ Data.Connection.Property: kernel :: (Preorder a, Preorder b) => ConnK a b -> b -> Bool
- Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => Trip a b -> a -> a -> b -> b -> Bool
+ Data.Connection.Property: monotonic :: (Preorder a, Preorder b) => ConnK a b -> a -> a -> b -> b -> Bool
- Data.Lattice: (//) :: Heyting 'R a => a -> a -> a
+ Data.Lattice: (//) :: Algebra 'R a => a -> a -> a
- Data.Lattice: (/\) :: Semilattice 'R a => a -> a -> a
+ Data.Lattice: (/\) :: Meet a => a -> a -> a
- Data.Lattice: (\/) :: Semilattice 'L a => a -> a -> a
+ Data.Lattice: (\/) :: Join a => a -> a -> a
- Data.Lattice: (\\) :: Heyting 'L a => a -> a -> a
+ Data.Lattice: (\\) :: Algebra 'L a => a -> a -> a
- Data.Lattice: boolean :: Boolean a => Trip a a
+ Data.Lattice: boolean :: Boolean a => Conn k a a
- Data.Lattice: booleanL :: Heyting 'L a => Conn 'L a a
+ Data.Lattice: booleanL :: Coheyting a => ConnL a a
- Data.Lattice: booleanR :: Heyting 'R a => Conn 'R a a
+ Data.Lattice: booleanR :: Heyting a => ConnR a a
- Data.Lattice: boundary :: Heyting 'L a => a -> a
+ Data.Lattice: boundary :: Coheyting a => a -> a
- Data.Lattice: equiv :: Heyting 'L a => a -> a -> a
+ Data.Lattice: equiv :: Algebra 'L a => a -> a -> a
- Data.Lattice: heyting :: Heyting k a => a -> Conn k a a
+ Data.Lattice: heyting :: Meet a => (a -> a -> a) -> a -> ConnR a a
- Data.Lattice: iff :: Heyting 'R a => a -> a -> a
+ Data.Lattice: iff :: Algebra 'R a => a -> a -> a
- Data.Lattice: middle :: Heyting 'R a => a -> a
+ Data.Lattice: middle :: Heyting a => a -> a
- Data.Lattice: neg :: Heyting 'R a => a -> a
+ Data.Lattice: neg :: Heyting a => a -> a
- Data.Lattice: non :: Heyting 'L a => a -> a
+ Data.Lattice: non :: Coheyting a => a -> a
- Data.Lattice: type Biheyting a = (HeytingL a, HeytingR a)
+ Data.Lattice: type Biheyting a = (Coheyting a, Heyting a)
- Data.Lattice: type Lattice a = (Eq a, Semilattice 'L a, Extremal 'L a, Semilattice 'R a, Extremal 'R a)
+ Data.Lattice: type Lattice a = (Join a, Meet a)
- Data.Lattice.Property: boolean0 :: (Heyting R a, Heyting L a) => a -> Bool
+ Data.Lattice.Property: boolean0 :: Biheyting a => a -> Bool
- Data.Lattice.Property: boolean1 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: boolean1 :: Heyting a => a -> Bool
- Data.Lattice.Property: boolean2 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: boolean2 :: Heyting a => a -> Bool
- Data.Lattice.Property: boolean3 :: Heyting L a => a -> Bool
+ Data.Lattice.Property: boolean3 :: Coheyting a => a -> Bool
- Data.Lattice.Property: boolean4 :: Heyting R a => a -> a -> Bool
+ Data.Lattice.Property: boolean4 :: Heyting a => a -> a -> Bool
- Data.Lattice.Property: boolean5 :: (Heyting L a, Heyting R a) => a -> a -> Bool
+ Data.Lattice.Property: boolean5 :: Biheyting a => a -> a -> Bool
- Data.Lattice.Property: boolean6 :: (Heyting R a, Heyting L a) => a -> a -> Bool
+ Data.Lattice.Property: boolean6 :: Biheyting a => a -> a -> Bool
- Data.Lattice.Property: symmetric1 :: (Heyting R a, Heyting L a) => a -> Bool
+ Data.Lattice.Property: symmetric1 :: Biheyting a => a -> Bool
- Data.Lattice.Property: symmetric12 :: Symmetric c => c -> c -> Bool
+ Data.Lattice.Property: symmetric12 :: Symmetric a => a -> a -> Bool
- Data.Lattice.Property: symmetric13 :: Symmetric c => c -> c -> Bool
+ Data.Lattice.Property: symmetric13 :: Symmetric a => a -> a -> Bool
- Data.Lattice.Property: symmetric2 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric2 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric3 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric3 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric4 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric4 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric5 :: Symmetric c => c -> Bool
+ Data.Lattice.Property: symmetric5 :: Symmetric a => a -> Bool
- Data.Lattice.Property: symmetric6 :: Heyting R a => a -> Bool
+ Data.Lattice.Property: symmetric6 :: Heyting a => a -> Bool
Files
- ChangeLog.md +17/−2
- connections.cabal +21/−14
- src/Data/Connection.hs +4/−182
- src/Data/Connection/Class.hs +705/−814
- src/Data/Connection/Conn.hs +363/−208
- src/Data/Connection/Double.hs +0/−322
- src/Data/Connection/Float.hs +249/−136
- src/Data/Connection/Int.hs +122/−123
- src/Data/Connection/Property.hs +19/−38
- src/Data/Connection/Ratio.hs +140/−133
- src/Data/Connection/Word.hs +141/−101
- src/Data/Lattice.hs +517/−388
- src/Data/Lattice/Property.hs +168/−136
- src/Data/Order.hs +184/−311
- src/Data/Order/Extended.hs +46/−39
- src/Data/Order/Interval.hs +24/−157
- src/Data/Order/Property.hs +87/−112
- src/Data/Order/Syntax.hs +69/−28
- test/Test/Data/Connection.hs +4/−9
- test/Test/Data/Connection/Float.hs +7/−146
- test/Test/Data/Connection/Int.hs +232/−96
- test/Test/Data/Connection/Word.hs +308/−69
- test/Test/Data/Lattice.hs +148/−153
- test/doctest.hs +14/−0
- test/test.hs +19/−18
ChangeLog.md view
@@ -2,6 +2,21 @@ ## 0.0.3 -- 2020-02-17 -* `Data.Float` : add cmath utils+* `Data.Connection.Float` : float utils * `Data.Connection.Ratio` : add rational connections-* `Numeric.Prelude` : add numeric prelude++## 0.1.0 -- 2020-07-07++* Unify `Connection` and `Triple` into a single class+* Add `Heyting`, `Symmetric`, and `Boolean` algebras+* Add misc new instances++## 0.2.0 -- 2021-02-21++* Change integral connection instances to non-shifting behavior.+* Move all one-sided `Connection` instances to `Connection 'L`.+* Consolidate floating point utilities into one module.+* Rename some functions in `Class.hs` and `Conn.hs` for clarity.+* Move `<` and `>` to `Syntax.hs`.+* Remove niche instances w/ upstream dependencies.+* Add misc new instances.
connections.cabal view
@@ -1,5 +1,5 @@ name: connections-version: 0.1.0+version: 0.2.0 synopsis: Orders, Galois connections, and lattices. description: A library for order manipulation using Galois connections. homepage: https://github.com/cmk/connections@@ -26,7 +26,6 @@ , Data.Connection.Word , Data.Connection.Ratio , Data.Connection.Float- , Data.Connection.Double , Data.Connection.Property , Data.Lattice@@ -41,19 +40,7 @@ build-depends: base >= 4.10 && < 5.0 , containers >= 0.4.0 && < 1.0- , transformers >= 0.5.5 && < 0.6- , universe-base >= 1.1.1 && < 2.0- , finite-typelits >= 0.1.4.2 && < 0.1.5 - default-extensions:- ScopedTypeVariables- , TypeApplications- , MultiParamTypeClasses- , UndecidableInstances- , FlexibleInstances- , FlexibleContexts- , TypeOperators- test-suite test type: exitcode-stdio-1.0 other-modules:@@ -76,3 +63,23 @@ hs-source-dirs: test default-language: Haskell2010 ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall++executable doctest+ main-is: doctest.hs+ ghc-options: -Wall -threaded+ hs-source-dirs: test+ default-language: Haskell2010+ x-doctest-options: --fast++ build-depends:+ base+ , doctest >= 0.8+ , connections -any++ default-extensions: + ScopedTypeVariables+ , TypeApplications+ , MultiParamTypeClasses+ , UndecidableInstances+ , FlexibleInstances+ , FlexibleContexts
src/Data/Connection.hs view
@@ -1,187 +1,9 @@-{-# Language TypeApplications #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds #-}-{-# Language DataKinds #-}-{-# Language Safe #-}-{-# Language ViewPatterns #-}-{-# Language PatternSynonyms #-}-{-# Language RankNTypes #-}-{-# Language QuantifiedConstraints #-}+{-# LANGUAGE Safe #-} module Data.Connection (- -- * Types- Kan(..)- , Semilattice- , Extremal- , ConnFloat- , ConnDouble- , ConnInteger- , ConnRational- , ConnExtended- -- * Connection L- , type ConnL- , pattern ConnL- , connL- , swapL- , embedL- , ceiling- , ceiling1- , ceiling2- , filterL- , minimal- , (\/)- , glb- -- * Connection R- , type ConnR- , pattern ConnR- , connR- , swapR- , floor- , floor1- , floor2- , embedR- , filterR- , maximal- , (/\)- , lub- -- * Connection- , type Trip- , pattern Conn- , half- , midpoint- , round- , round1- , round2- , truncate- , truncate1- , truncate2- , maybeL- , maybeR- , choice- , strong- , fmapped- -- * Connection- , Conn()- , Triple- , Connection(..)+ module Data.Connection.Conn,+ module Data.Connection.Class, ) where -import safe Data.Connection.Conn import safe Data.Connection.Class-import safe Data.Order-import safe Prelude hiding- (Bounded,fromInteger, fromRational, floor, ceiling, round, truncate)---- $setup--- >>> :set -XTypeApplications--- >>> import Data.Int--- >>> import Prelude hiding (Ord(..), Bounded, fromInteger, fromRational, RealFrac(..))--- >>> import qualified Prelude as P--- >>> :load Data.Connection---- | Determine which half of the interval between 2 representations of /a/ a particular value lies.--- --- @ 'half' t x = 'pcompare' (x - 'counitR' t x) ('unitL' t x - x) @----half :: (Num a, Preorder a) => Trip a b -> a -> Maybe Ordering-half t x = pcompare (x - counitR t x) (unitL t x - x) ---- | Return the midpoint of the interval containing x.------ >>> midpoint f32i08 4.3--- 4.5--- >>> midpoint f64i08 4.3--- 4.5--- >>> pi - midpoint f64f32 pi--- 3.1786509424591713e-8------ >>> maybe False (~~ EQ) $ half f64f32 (midpoint f64f32 pi)--- True----midpoint :: Fractional a => Trip a b -> a -> a-midpoint t x = counitR t x / 2 + unitL t x / 2-------------------------------------------------------------------------- Rounding-------------------------------------------------------------------------- | Return the nearest value to x.------ > round @a @a = id--- --- If x lies halfway between two finite values, then return the value--- with the larger absolute value (i.e. round away from zero).------ See <https://en.wikipedia.org/wiki/Rounding>.------ Usable in conjunction with /RebindableSyntax/:------ >>> fromRational = round--- >>> fromRational @Float 1.3--- 1.3--- >>> fromRational @Float (1 :% 0)--- Infinity--- >>> fromRational @Float (0 :% 0)--- NaN----round :: forall a b. (Num a, Triple a b) => a -> b-round x = case pcompare halfR halfL of- Just GT -> ceiling x- Just LT -> floor x- _ -> truncate x-- where- halfR = x - counitR (connR @a @b) x -- dist from lower bound-- halfL = unitL (connL @a @b) x - x -- dist from upper bound---- | Lift a unary function over a 'Trip'.------ Results are rounded to the nearest value with ties away from 0.----round1 :: forall a b. (Num a, Triple a b) => (a -> a) -> b -> b-round1 f x = round $ f (g x) where Conn _ g _ = connL-{-# INLINE round1 #-}---- | Lift a binary function over a 'Trip'.------ Results are rounded to the nearest value with ties away from 0.------ >>> f x y = (x + y) - x --- >>> maxOdd32 = 1.6777215e7--- >>> maxOdd64 = 9.007199254740991e15--- >>> f maxOdd32 2.0 :: Float--- 1.0--- >>> round2 @Rational @Float f maxOdd32 2.0--- 2.0--- >>> f maxOdd64 2.0 :: Double--- 1.0--- >>> round2 @Rational @Double f maxOdd64 2.0--- 2.0----round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b-round2 f x y = round $ f (g x) (g y) where Conn _ g _ = connL-{-# INLINE round2 #-}---- | Truncate towards zero.------ > truncate @a @a = id----truncate :: (Num a, Triple a b) => a -> b-truncate x = if x >~ 0 then floor x else ceiling x---- | Lift a unary function over a 'Trip'.------ Results are truncated towards 0.----truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b-truncate1 f x = truncate $ f (g x) where Conn _ g _ = connL-{-# INLINE truncate1 #-}---- | Lift a binary function over a 'Trip'.------ Results are truncated towards 0.----truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b-truncate2 f x y = truncate $ f (g x) (g y) where Conn _ g _ = connL-{-# INLINE truncate2 #-}+import safe Data.Connection.Conn
src/Data/Connection/Class.hs view
@@ -1,815 +1,706 @@-{-# Language TypeApplications #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds #-}-{-# Language DataKinds #-}-{-# Language Safe #-}-{-# Language ViewPatterns #-}-{-# Language PatternSynonyms #-}-{-# Language RankNTypes #-}-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE StandaloneDeriving #-}--module Data.Connection.Class (- -- * Types- Kan(..)- , Conn()- , Semilattice- , Extremal- , ConnFloat- , ConnDouble- , ConnInteger- , ConnRational- , ConnExtended- -- * Connection L- , ConnL- , pattern ConnL- , connL- , swapL- , embedL- , ceiling- , ceiling1- , ceiling2- , filterL- , minimal- , (\/)- , glb- -- * Connection R- , ConnR- , pattern ConnR- , connR- , swapR- , floor- , floor1- , floor2- , embedR- , filterR- , maximal- , (/\)- , lub- -- * Connection k- , Trip- , pattern Conn- , maybeL- , maybeR- , choice- , strong- , fmapped- -- * Connection- , Connection(..)- , Triple-) where--import safe Control.Applicative (liftA2)-import safe Control.Category ((>>>))-import safe Data.Bool (bool)-import safe Data.Connection.Conn-import safe Data.Connection.Int-import safe Data.Connection.Word-import safe Data.Connection.Float-import safe Data.Connection.Double-import safe Data.Connection.Ratio-import safe Data.Functor.Contravariant-import safe Data.Functor.Identity-import safe Data.Monoid-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Interval-import safe Data.Word-import safe Data.Int-import safe GHC.TypeNats-import safe Numeric.Natural-import safe Prelude hiding (Bounded, floor, ceiling, fromInteger, fromRational)-import safe qualified Control.Category as C-import safe qualified Data.IntMap as IntMap-import safe qualified Data.IntSet as IntSet-import safe qualified Data.Map as Map-import safe qualified Data.Set as Set-import safe qualified Data.Finite as F-import safe qualified Data.Universe.Class as U-import safe qualified Prelude as P---- $setup--- >>> :set -XTypeApplications--- >>> import Data.Int--- >>> import Prelude hiding (Ord(..), Bounded, fromInteger, fromRational, RealFrac(..))--- >>> import qualified Prelude as P--- >>> :load Data.Connection----- | Semilattices.------ A complete is a partially ordered set in which every two elements have a unique join --- (least upper bound or supremum) and a unique meet (greatest lower bound or infimum). ------ These operations may in turn be defined by the lower and upper adjoints to the unique--- function /a -> (a, a)/.------ /Associativity/------ @--- x '\/' (y '\/' z) = (x '\/' y) '\/' z--- x '/\' (y '/\' z) = (x '/\' y) '/\' z--- @------ /Commutativity/------ @--- x '\/' y = y '\/' x--- x '/\' y = y '/\' x--- @------ /Idempotency/------ @--- x '\/' x = x--- x '/\' x = x--- @------ /Absorption/------ @--- (x '\/' y) '/\' y = y--- (x '/\' y) '\/' y = y--- @------ See < https://en.wikipedia.org/wiki/Absorption_law Absorption >.------ Note that distributivity is _not_ a requirement for a complete.--- However when /a/ is distributive we have;--- --- @--- 'glb' x y z = 'lub' x y z--- @------ See < https://en.wikipedia.org/wiki/Lattice_(order) >.----type Semilattice k a = Connection k (a, a) a--type Extremal k = Connection k ()--type ConnInteger k = Connection k (Maybe Integer)--type ConnFloat k = Connection k Float--type ConnDouble k = Connection k Double--type ConnRational k = Connection k Rational--type ConnExtended k a b = Connection k a (Extended b)---- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3.----class (Preorder a, Preorder b) => Connection k a b where-- -- |- --- -- >>> range (conn @_ @Double @Float) pi- -- (3.1415925,3.1415927)- -- >>> range (conn @_ @Rational @Float) (1 :% 7)- -- (0.14285713,0.14285715)- -- >>> range (conn @_ @Rational @Float) (1 :% 8)- -- (0.125,0.125)- --- conn :: Conn k a b---- | A constraint kind representing an <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections.----type Triple a b = (Connection 'L a b, Connection 'R a b)---------------------------------------------------------------------------- Connection L-------------------------------------------------------------------------- | A specialization of /conn/ to left-side connections.------ This is a convenience function provided primarily to avoid needing--- to enable /DataKinds/.----connL :: Connection 'L a b => ConnL a b-connL = conn @'L---- | Extract the center of a 'Trip' or upper half of a 'ConnL'.----embedL :: Connection 'L a b => b -> a-embedL = embed connL---- | Extract the ceiling of a 'Trip' or lower half of a 'ConnL'.------ > ceiling @a @a = id------ >>> ceiling @Rational @Float (0 :% 0)--- NaN--- >>> ceiling @Rational @Float (1 :% 0)--- Infinity--- >>> ceiling @Rational @Float (13 :% 10)--- 1.3000001----ceiling :: Connection 'L a b => a -> b-ceiling = lowerL connL---- | Lift a unary function over a 'ConnL'.----ceiling1 :: Connection 'L a b => (a -> a) -> b -> b-ceiling1 = lowerL1 connL---- | Lift a binary function over a 'ConnL'.----ceiling2 :: Connection 'L a b => (a -> a -> a) -> b -> b -> b-ceiling2 = lowerL2 connL---- | Obtain the principal filter in /B/ generated by an element of /A/.------ A subset /B/ of a lattice is an filter if and only if it is an upper set --- that is closed under finite meets, i.e., it is nonempty and for all --- /x/, /y/ in /B/, the element @x /\ y@ is also in /b/.------ /filterL/ and /filterR/ commute with /Down/:------ > filterL a b <=> filterR (Down a) (Down b)------ > filterL (Down a) (Down b) <=> filterR a b------ /filterL a/ is upward-closed for all /a/:------ > a <= b1 && b1 <= b2 => a <= b2------ > a1 <= b && inf a2 <= b => ceiling a1 /\ ceiling a2 <= b------ See <https://en.wikipedia.org/wiki/Filter_(mathematics)>----filterL :: Connection 'L a b => a -> b -> Bool-filterL a b = ceiling a <~ b---- | A minimal element of a preorder defined by a connection with '()'.------ 'minimal' needn't be unique, but we must have:------ > x <~ minimal => x ~~ minimal----minimal :: Extremal 'L a => a-minimal = lowerL connL ()--infixr 5 \/---- | Semigroup operation on a join-semilattice.------ > (\/) = curry $ lowerL forked----(\/) :: Semilattice 'L a => a -> a -> a-(\/) = curry $ lowerL connL---- | Greatest lower bound operator.------ > glb x x y = x--- > glb x y z = glb z x y--- > glb x x y = x--- > glb x y z = glb x z y--- > glb (glb x w y) w z = glb x w (glb y w z)------ >>> glb 1.0 9.0 7.0--- 7.0--- >>> glb 1.0 9.0 (0.0 / 0.0)--- 9.0--- >>> glb (fromList [1..3]) (fromList [3..5]) (fromList [5..7]) :: Set Int--- fromList [3,5]----glb :: Triple (a, a) a => a -> a -> a -> a-glb x y z = (x \/ y) /\ (y \/ z) /\ (z \/ x)-------------------------------------------------------------------------- Connection R-------------------------------------------------------------------------- | A specialization of /conn/ to right-side connections.------ This is a convenience function provided primarily to avoid needing--- to enable /DataKinds/.----connR :: Connection 'R a b => ConnR a b-connR = conn @'R---- | Extract the floor of a 'Trip' or upper half of a 'ConnL'.------ > floor @a @a = id------ >>> floor @Rational @Float (0 :% 0)--- NaN--- >>> floor @Rational @Float (1 :% 0)--- Infinity--- >>> floor @Rational @Float (13 :% 10)--- 1.3----floor :: Connection 'R a b => a -> b-floor = upperR connR---- | Lift a unary function over a 'ConnR'.----floor1 :: Connection 'R a b => (a -> a) -> b -> b-floor1 = upperR1 connR---- | Lift a binary function over a 'ConnR'.----floor2 :: Connection 'R a b => (a -> a -> a) -> b -> b -> b-floor2 = upperR2 connR---- | Extract the center of a 'Trip' or lower half of a 'ConnR'.----embedR :: Connection 'R a b => b -> a-embedR = embed connR---- | Obtain the principal ideal in /B/ generated by an element of /A/.------ A subset /B/ of a lattice is an ideal if and only if it is a lower set --- that is closed under finite joins, i.e., it is nonempty and for all --- /x/, /y/ in /B/, the element /x \/ y/ is also in /B/.------ /filterR a/ is downward-closed for all /a/:------ > a >= b1 && b1 >= b2 => a >= b2------ > a1 >= b && a2 >= b => floor a1 \/ floor a2 >= b------ See <https://en.wikipedia.org/wiki/Ideal_(order_theory)>----filterR :: Connection 'R a b => a -> b -> Bool-filterR a b = b <~ floor a---- | A maximal element of a preorder defined by a connection with '()'.------ 'maximal' needn't be unique, but we must have:------ > x >~ maximal => x ~~ maximal----maximal :: Extremal 'R a => a-maximal = upperR connR ()--infixr 6 /\ -- comment for the parser---- | Semigroup operation on a meet-semilattice.------ > (/\) = curry $ upperR forked----(/\) :: Semilattice 'R a => a -> a -> a-(/\) = curry $ upperR connR---- | Least upper bound operator.------ The order dual of 'glb'.------ >>> lub 1.0 9.0 7.0--- 7.0--- >>> lub 1.0 9.0 (0.0 / 0.0)--- 1.0----lub :: Triple (a, a) a => a -> a -> a -> a-lub x y z = (x /\ y) \/ (y /\ z) \/ (z /\ x)-------------------------------------------------------------------------- Connection------------------------------------------------------------------------maybeL :: Triple () b => Trip (Maybe a) (Either a b)-maybeL = trip f g h where- f = maybe (Right minimal) Left- g = either Just (const Nothing)- h = maybe (Right maximal) Left--maybeR :: Triple () a => Trip (Maybe b) (Either a b)-maybeR = trip f g h where- f = maybe (Left minimal) Right- g = either (const Nothing) Just- h = maybe (Left maximal) Right-------------------------------------------------------------------------- Instances------------------------------------------------------------------------instance Preorder a => Connection k a a where- conn = C.id--instance Connection 'R Word16 Word8 where- conn = swapR w08w16--instance Connection 'R Word32 Word8 where- conn = swapR w08w32--instance Connection 'R Word32 Word16 where- conn = swapR w16w32--instance Connection 'R Word64 Word8 where- conn = swapR w08w64--instance Connection 'R Word64 Word16 where- conn = swapR w16w64--instance Connection 'R Word64 Word32 where- conn = swapR w32w64--instance Connection k Word Word64 where- conn = wxxw64--instance Connection 'R Natural Word8 where- conn = swapR w08nat--instance Connection 'R Natural Word16 where- conn = swapR w16nat--instance Connection 'R Natural Word32 where- conn = swapR w32nat--instance Connection 'R Natural Word64 where- conn = swapR w64nat--instance Connection 'R Natural Word where- conn = swapR wxxnat--instance Connection 'R Natural Integer where- conn = swapR intnat--instance Connection 'R Int32 Int8 where- conn = swapR i08i32--instance Connection 'R Int32 Int16 where- conn = swapR i16i32--instance Connection 'R Int64 Int8 where- conn = swapR i08i64--instance Connection 'R Int64 Int16 where- conn = swapR i16i64--instance Connection 'R Int64 Int32 where- conn = swapR i32i64--instance Connection k Int Int64 where- conn = ixxi64--instance Connection 'R (Maybe Integer) Word8 where- conn = swapR $ w08nat >>> natint--instance Connection 'R (Maybe Integer) Word16 where- conn = swapR $ w16nat >>> natint--instance Connection 'R (Maybe Integer) Word32 where- conn = swapR $ w32nat >>> natint--instance Connection 'R (Maybe Integer) Word64 where- conn = swapR $ w64nat >>> natint--instance Connection 'R (Maybe Integer) Word where- conn = swapR $ wxxnat >>> natint--instance Connection 'R (Maybe Integer) Natural where- conn = swapR natint--instance Connection 'R (Maybe Integer) Int8 where- conn = swapR i08int--instance Connection 'R (Maybe Integer) Int16 where- conn = swapR i16int--instance Connection 'R (Maybe Integer) Int32 where- conn = swapR i32int--instance Connection 'R (Maybe Integer) Int64 where- conn = swapR i64int--instance Connection 'R (Maybe Integer) Int where- conn = swapR ixxint--instance Connection 'R (Maybe Integer) Integer where- -- | Provided as a shim for /RebindableSyntax/.- -- Note that this instance will clip negative numbers to zero.- conn = swapR $ intnat >>> natint--instance Connection k Int8 Word8 where- conn = i08w08--instance Connection k Int16 Word16 where- conn = i16w16--instance Connection k Int32 Word32 where- conn = i32w32--instance Connection k Int64 Word64 where- conn = i64w64--instance Connection k Int Word where- conn = ixxwxx--instance Connection k Double Float where- conn = f64f32--instance Connection k Rational Float where- conn = ratf32--instance Connection k Rational Double where- conn = ratf64--instance Connection k Rational (Extended Int8) where- conn = rati08--instance Connection k Rational (Extended Int16) where- conn = rati16--instance Connection k Rational (Extended Int32) where- conn = rati32--instance Connection k Rational (Extended Int64) where- conn = rati64--instance Connection k Rational (Extended Int) where- conn = ratixx--instance Connection k Rational (Extended Integer) where- conn = ratint--instance Connection k Float (Extended Int8) where- conn = f32i08--instance Connection k Float (Extended Int16) where- conn = f32i16--instance Connection 'L Float (Extended Int32) where- conn = conn >>> fmapped (i16w16 >>> w16w32 >>> w32i32)--instance Connection 'L Float (Extended Int64) where- conn = conn >>> fmapped (i16w16 >>> w16w64 >>> w64i64)--instance Connection 'L Float (Extended Int) where- conn = conn >>> fmapped (i16w16 >>> w16wxx >>> swapL ixxwxx)--instance Connection k Double (Extended Int8) where- conn = f64i08--instance Connection k Double (Extended Int16) where- conn = f64i16--instance Connection k Double (Extended Int32) where- conn = f64i32--instance Connection 'L Double (Extended Int64) where- conn = conn >>> fmapped (i32w32 >>> w32w64 >>> w64i64)--instance Connection 'L Double (Extended Int) where- conn = conn >>> fmapped (i32w32 >>> w32wxx >>> swapL ixxwxx)--instance Connection k a b => Connection k (Identity a) b where- conn = Conn runIdentity Identity runIdentity >>> conn--instance Connection k a b => Connection k a (Identity b) where- conn = conn >>> Conn Identity runIdentity Identity-------------------------------------------------------------------------- ------------------------------------------------------------------------fork :: a -> (a, a)-fork x = (x, x)--semilatticeN5 :: (Total a, Fractional a) => Conn k (a, a) a-semilatticeN5 = Conn (uncurry joinN5) fork (uncurry meetN5) where- joinN5 x y = maybe (1 / 0) (bool y x . (>= EQ)) (pcompare x y)-- meetN5 x y = maybe (-1 / 0) (bool y x . (<= EQ)) (pcompare x y)--extremalN5 :: (Total a, Fractional a) => Conn k () a-extremalN5 = Conn (const $ -1/0) (const ()) (const $ 1/0)--semilatticeOrd :: (Total a) => Conn k (a, a) a-semilatticeOrd = Conn (uncurry max) fork (uncurry min)--extremalOrd :: (Total a, P.Bounded a) => Conn k () a-extremalOrd = Conn (const minBound) (const ()) (const maxBound)--instance Connection k ((),()) () where conn = semilatticeOrd-instance Connection k (Bool, Bool) Bool where conn = semilatticeOrd-instance Connection k () Bool where conn = extremalOrd-instance Connection k (Ordering, Ordering) Ordering where conn = semilatticeOrd-instance Connection k () Ordering where conn = extremalOrd--instance Connection k (Word8, Word8) Word8 where conn = semilatticeOrd-instance Connection k () Word8 where conn = extremalOrd-instance Connection k (Word16, Word16) Word16 where conn = semilatticeOrd-instance Connection k () Word16 where conn = extremalOrd-instance Connection k (Word32, Word32) Word32 where conn = semilatticeOrd-instance Connection k () Word32 where conn = extremalOrd-instance Connection k (Word64, Word64) Word64 where conn = semilatticeOrd-instance Connection k () Word64 where conn = extremalOrd-instance Connection k (Word, Word) Word where conn = semilatticeOrd-instance Connection k () Word where conn = extremalOrd-instance Connection k (Natural, Natural) Natural where conn = semilatticeOrd--instance Connection k (Positive, Positive) Positive where conn = semilatticeN5-instance Connection k () Positive where- conn = Conn (const $ 0 :% 1) (const ()) (const $ 1 :% 0)--instance Connection k (Int8, Int8) Int8 where conn = semilatticeOrd-instance Connection k () Int8 where conn = extremalOrd-instance Connection k (Int16, Int16) Int16 where conn = semilatticeOrd-instance Connection k () Int16 where conn = extremalOrd-instance Connection k (Int32, Int32) Int32 where conn = semilatticeOrd-instance Connection k () Int32 where conn = extremalOrd-instance Connection k (Int64, Int64) Int64 where conn = semilatticeOrd-instance Connection k () Int64 where conn = extremalOrd-instance Connection k (Int, Int) Int where conn = semilatticeOrd-instance Connection k () Int where conn = extremalOrd-instance Connection k (Integer, Integer) Integer where conn = semilatticeOrd--instance Connection k (Rational, Rational) Rational where conn = semilatticeN5-instance Connection k () Rational where- conn = Conn (const $ -1 :% 0) (const ()) (const $ 1 :% 0)--instance Connection k (F.Finite n, F.Finite n) (F.Finite n) where conn = semilatticeOrd-instance KnownNat n => Connection k () (F.Finite n) where conn = extremalOrd--instance Connection k (Float, Float) Float where conn = semilatticeN5-instance Connection k () Float where conn = extremalN5--instance Connection k (Double, Double) Double where conn = semilatticeN5-instance Connection k () Double where conn = extremalN5--instance Total a => Connection k (Set.Set a, Set.Set a) (Set.Set a) where- conn = Conn (uncurry Set.union) fork (uncurry Set.intersection)----instance (Total a, U.Finite a) => Connection k () (Set.Set a) where--- conn = Conn (const Set.empty) (const ()) (const $ Set.fromList U.universeF)-instance (Total a) => Connection 'L () (Set.Set a) where- conn = ConnL (const Set.empty) (const ())--instance (Total a, U.Finite a) => Connection 'R () (Set.Set a) where- conn = ConnR (const ()) (const $ Set.fromList U.universeF)--instance Connection k (IntSet.IntSet, IntSet.IntSet) IntSet.IntSet where- conn = Conn (uncurry IntSet.union) fork (uncurry IntSet.intersection)--instance Connection k () IntSet.IntSet where- conn = Conn (const IntSet.empty) (const ()) (const $ IntSet.fromList U.universeF)--instance (Total a, Connection 'L (b,b) b) => Connection 'L (Map.Map a b, Map.Map a b) (Map.Map a b) where- conn = ConnL (uncurry $ Map.unionWith (\/)) fork--instance (Total a, Connection 'R (b,b) b) => Connection 'R (Map.Map a b, Map.Map a b) (Map.Map a b) where- conn = ConnR fork (uncurry $ Map.intersectionWith (/\))--instance (Total a, Preorder b) => Connection 'L () (Map.Map a b) where- conn = ConnL (const Map.empty) (const ()) --instance (Total a, U.Finite a, Connection 'R () b) => Connection 'R () (Map.Map a b) where- conn = ConnR (const ()) (const . Map.fromList $ U.universeF `zip` repeat maximal)--instance Connection 'L (a,a) a => Connection 'L (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where- conn = ConnL (uncurry $ IntMap.unionWith (\/)) fork--instance Connection 'R (a,a) a => Connection 'R (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where- conn = ConnR fork (uncurry $ IntMap.intersectionWith (/\))--instance Preorder a => Connection 'L () (IntMap.IntMap a) where- conn = ConnL (const IntMap.empty) (const ())--instance Connection 'R () a => Connection 'R () (IntMap.IntMap a) where- conn = ConnR (const ()) (const . IntMap.fromList $ U.universeF `zip` repeat maximal)--joinMaybe :: Connection 'L (a, a) a => Maybe a -> Maybe a -> Maybe a-joinMaybe (Just x) (Just y) = Just (x \/ y)-joinMaybe u@(Just _) _ = u-joinMaybe _ u@(Just _) = u-joinMaybe Nothing Nothing = Nothing--meetMaybe :: Connection 'R (a, a) a => Maybe a -> Maybe a -> Maybe a-meetMaybe Nothing Nothing = Nothing-meetMaybe Nothing _ = Nothing-meetMaybe _ Nothing = Nothing-meetMaybe (Just x) (Just y) = Just (x /\ y)--instance Connection 'L (a, a) a => Connection 'L (Maybe a, Maybe a) (Maybe a) where- conn = ConnL (uncurry joinMaybe) fork--instance Connection 'R (a, a) a => Connection 'R (Maybe a, Maybe a) (Maybe a) where- conn = ConnR fork (uncurry meetMaybe)--instance Preorder a => Connection 'L () (Maybe a) where- conn = ConnL (const Nothing) (const ())--instance Connection 'R () a => Connection 'R () (Maybe a) where- conn = ConnR (const ()) (const $ Just maximal)--joinExtended :: Connection 'L (a, a) a => Extended a -> Extended a -> Extended a-joinExtended Top _ = Top-joinExtended _ Top = Top-joinExtended (Extended x) (Extended y) = Extended (x \/ y)-joinExtended Bottom y = y-joinExtended x Bottom = x--meetExtended :: Connection 'R (a, a) a => Extended a -> Extended a -> Extended a-meetExtended Top y = y-meetExtended x Top = x-meetExtended (Extended x) (Extended y) = Extended (x /\ y)-meetExtended Bottom _ = Bottom-meetExtended _ Bottom = Bottom--instance Connection 'L (a, a) a => Connection 'L (Extended a, Extended a) (Extended a) where- conn = ConnL (uncurry joinExtended) fork--instance Connection 'R (a, a) a => Connection 'R (Extended a, Extended a) (Extended a) where- conn = ConnR fork (uncurry meetExtended)--instance Preorder a => Connection k () (Extended a) where- conn = Conn (const Bottom) (const ()) (const Top)--joinEither :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => Either a b -> Either a b -> Either a b-joinEither (Right x) (Right y) = Right (x \/ y)-joinEither u@(Right _) _ = u-joinEither _ u@(Right _) = u-joinEither (Left x) (Left y) = Left (x \/ y)--meetEither :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => Either a b -> Either a b -> Either a b-meetEither (Left x) (Left y) = Left (x /\ y)-meetEither l@(Left _) _ = l-meetEither _ l@(Left _) = l-meetEither (Right x) (Right y) = Right (x /\ y)---- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.-instance (Connection 'L (a,a) a, Connection 'L (b,b) b) => Connection 'L (Either a b, Either a b) (Either a b) where- conn = ConnL (uncurry joinEither) fork--instance (Connection 'R (a,a) a, Connection 'R (b,b) b) => Connection 'R (Either a b, Either a b) (Either a b) where- conn = ConnR fork (uncurry meetEither)--instance (Connection 'L () a, Preorder b) => Connection 'L () (Either a b) where- conn = ConnL (const $ Left minimal) (const ())--instance (Preorder a, Connection 'R () b) => Connection 'R () (Either a b) where- conn = ConnR (const ()) (const $ Right maximal)--joinTuple :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => (a, b) -> (a, b) -> (a, b)-joinTuple (x1, y1) (x2, y2) = (x1 \/ x2, y1 \/ y2)--meetTuple :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => (a, b) -> (a, b) -> (a, b)-meetTuple (x1, y1) (x2, y2) = (x1 /\ x2, y1 /\ y2)--instance (Triple (a, a) a, Triple (b, b) b) => Connection k ((a, b), (a, b)) (a, b) where- conn = Conn (uncurry joinTuple) fork (uncurry meetTuple)--instance (Triple () a, Triple () b) => Connection k () (a, b) where- conn = Conn (const (minimal, minimal)) (const ()) (const (maximal, maximal))--instance (U.Finite a, Triple (b, b) b) => Connection k (a -> b, a -> b) (a -> b) where- conn = Conn (uncurry $ liftA2 (\/)) fork (uncurry $ liftA2 (/\))--instance (U.Finite a, Triple () b) => Connection k () (a -> b) where- conn = Conn (const $ pure minimal) (const ()) (const $ pure maximal)--instance (U.Finite a, Triple (a, a) a) => Connection k (Endo a, Endo a) (Endo a) where- conn = Conn (\(Endo x, Endo y) -> Endo $ x\/y) fork (\(Endo x, Endo y) -> Endo $ x/\y)--instance (U.Finite a, Triple () a) => Connection k () (Endo a) where- conn = Conn (const $ Endo minimal) (const ()) (const $ Endo maximal)--instance (U.Finite a, Triple (b, b) b) => Connection k (Op b a, Op b a) (Op b a) where- conn = Conn (\(Op x, Op y) -> Op $ x\/y) fork (\(Op x, Op y) -> Op $ x/\y)--instance (U.Finite a, Triple () b) => Connection k () (Op b a) where- conn = Conn (const $ Op minimal) (const ()) (const $ Op maximal)--instance U.Finite a => Connection k (Predicate a, Predicate a) (Predicate a) where- conn = Conn (\(Predicate x, Predicate y) -> Predicate $ x\/y) fork (\(Predicate x, Predicate y) -> Predicate $ x/\y)--instance U.Finite a => Connection k () (Predicate a) where- conn = Conn (const $ Predicate minimal) (const ()) (const $ Predicate maximal)--{--instance (Applicative m, Connection k r) => Connection k (ContT r m a) where- (<>) = liftA2 joinCont--instance (Applicative m, Connection k () r) => Connection k () (ContT r m a) where- mempty = pure . ContT . const $ pure bottom--instance Monad m => Connection k (SelectT r m a) where- (<>) = liftA2 joinSelect--instance MonadPlus m => Connection k () (SelectT r m a)) where- bottom = pure empty-instance (Ord.Ord a, Preorder a, Preorder r, Finite r) => Preorder (Cont r a) where- (ContT x) <~ (ContT y) = x `contLe` y--instance (Ord.Ord a, Preorder a, Preorder r, Finite r) => Preorder (Select r a) where- (SelectT x) <~ (SelectT y) = x `contLe` y-instance (Applicative m, Total a, Preorder r, Finite r, Connection 'L r) => Connection 'L (ContT r m a, ContT r m a) (ContT r m a) where- conn = ConnL (uncurry joinCont) fork--joinCont :: (Applicative m, Connection 'L (r,r) r) => ContT r m a -> ContT r m a -> ContT r m a-joinCont (ContT f) (ContT g) = ContT $ \p -> liftA2 join (f p) (g p) --instance (Monad m, Total a, Preorder r, Finite r, Extremal 'L r) => Connection 'L (SelectT r m a, SelectT r m a) (SelectT r m a) where- conn = ConnL (uncurry joinSelect) fork--joinSelect :: (Monad m, Extremal 'L r) => SelectT r m b -> SelectT r m b -> SelectT r m b-joinSelect x y = branch x y >>= id- where- ifM c x y = c >>= \b -> if b then x else y- branch x y = SelectT $ \p -> ifM ((~~ maximal) <$> p x) (pure x) (pure y)- +{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}++module Data.Connection.Class (+ -- * Conn+ Conn (),+ identity,++ -- * Connection k+ Triple,+ pattern Conn,+ ConnK,+ embed,+ extremal,+ lub,+ glb,+ half,+ midpoint,+ range,+ round,+ round1,+ round2,+ truncate,+ truncate1,+ truncate2,++ -- * Connection L+ Left,+ pattern ConnL,+ ConnL,+ connL,+ embedL,+ minimal,+ join,+ ceiling,+ ceiling1,+ ceiling2,++ -- * Connection R+ Right,+ pattern ConnR,+ ConnR,+ connR,+ embedR,+ maximal,+ meet,+ floor,+ floor1,+ floor2,++ -- * Combinators+ (>>>),+ (<<<),+ (/|\),+ (\|/),+ choice,+ strong,++ -- * Connection+ Kan (..),+ ConnInteger,+ ConnRational,+ ConnExtended,+ Connection (..),+) where++import safe Control.Category ((>>>))+import safe Data.Bool (bool)+import safe Data.Connection.Conn+import safe Data.Connection.Float+import safe Data.Connection.Int+import safe Data.Connection.Ratio+import safe Data.Connection.Word+import safe Data.Functor.Identity+import safe Data.Int+import safe qualified Data.IntMap as IntMap+import safe qualified Data.IntSet as IntSet+import safe qualified Data.Map as Map+import safe Data.Order+import safe Data.Order.Extended+import safe qualified Data.Set as Set+import safe Data.Word+import safe Numeric.Natural+import safe Prelude hiding (ceiling, floor, round, truncate)++-- $setup+-- >>> :set -XTypeApplications+-- >>> :set -XFlexibleContexts+-- >>> import GHC.Real (Ratio(..))+-- >>> import Data.Set (Set,fromList)+-- >>> :load Data.Connection+-- >>> import Prelude hiding (round, floor, ceiling, truncate)++type Left = Connection 'L++type Right = Connection 'R++-- | A constraint kind representing an <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections.+type Triple a b = (Left a b, Right a b)++-- | A constraint kind for 'Integer' conversions.+--+-- Usable in conjunction with /RebindableSyntax/:+--+-- > fromInteger = embedL . Just :: ConnInteger a => Integer -> a+type ConnInteger a = Left a (Maybe Integer)++-- | A constraint kind for 'Rational' conversions.+--+-- Usable in conjunction with /RebindableSyntax/:+--+-- > fromRational = round :: ConnRational a => Rational -> a+type ConnRational a = Triple Rational a++type ConnExtended a b = Triple a (Extended b)++-- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3.+class (Preorder a, Preorder b) => Connection k a b where+ -- |+ --+ -- >>> range (conn @_ @Rational @Float) (22 :% 7)+ -- (3.142857,3.1428573)+ -- >>> range (conn @_ @Double @Float) pi+ -- (3.1415925,3.1415927)+ conn :: Conn k a b++infixr 3 \|/++-- | A preorder variant of 'Control.Arrow.|||'.+(\|/) :: Conn k c a -> Conn k c b -> Conn k c (Either a b)+f \|/ g = Conn Left (either id id) Right >>> f `choice` g++infixr 4 /|\++-- | A preorder variant of 'Control.Arrow.&&&'.+(/|\) :: Connection k (c, c) c => Conn k a c -> Conn k b c -> Conn k (a, b) c+f /|\ g = f `strong` g >>> conn++---------------------------------------------------------------------+-- Connection k+---------------------------------------------------------------------++-- | The canonical connections against a 'Bool'.+extremal :: Triple () a => Conn k a Bool+extremal = Conn f g h+ where+ g False = minimal+ g True = maximal++ f i+ | i ~~ minimal = False+ | otherwise = True++ h i+ | i ~~ maximal = True+ | otherwise = False++-- | Least upper bound operator.+--+-- The order dual of 'glb'.+--+-- >>> lub 1.0 9.0 7.0+-- 7.0+-- >>> lub 1.0 9.0 (0.0 / 0.0)+-- 1.0+lub :: Triple (a, a) a => a -> a -> a -> a+lub x y z = (x `meet` y) `join` (y `meet` z) `join` (z `meet` x)++-- | Greatest lower bound operator.+--+-- > glb x x y = x+-- > glb x y z = glb z x y+-- > glb x y z = glb x z y+-- > glb (glb x w y) w z = glb x w (glb y w z)+--+-- >>> glb 1.0 9.0 7.0+-- 7.0+-- >>> glb 1.0 9.0 (0.0 / 0.0)+-- 9.0+-- >>> glb (fromList [1..3]) (fromList [3..5]) (fromList [5..7]) :: Set Int+-- fromList [3,5]+glb :: Triple (a, a) a => a -> a -> a -> a+glb x y z = (x `join` y) `meet` (y `join` z) `meet` (z `join` x)++-- | Return the nearest value to x.+--+-- > round @a @a = id+--+-- If x lies halfway between two finite values, then return the value+-- with the larger absolute value (i.e. round away from zero).+--+-- See <https://en.wikipedia.org/wiki/Rounding>.+round :: forall a b. (Num a, Triple a b) => a -> b+round x = case pcompare halfR halfL of+ Just GT -> ceiling x+ Just LT -> floor x+ _ -> truncate x+ where+ halfR = x - lower (connR @a @b) x -- dist from lower bound+ halfL = upper (connL @a @b) x - x -- dist from upper bound++-- | Lift a unary function over a 'Conn'.+--+-- Results are rounded to the nearest value with ties away from 0.+round1 :: (Num a, Triple a b) => (a -> a) -> b -> b+round1 f x = round $ f (g x) where Conn _ g _ = connL+{-# INLINE round1 #-}++-- | Lift a binary function over a 'Conn'.+--+-- Results are rounded to the nearest value with ties away from 0.+--+-- Example avoiding loss-of-precision:+--+-- >>> f x y = (x + y) - x+-- >>> maxOdd32 = 1.6777215e7+-- >>> f maxOdd32 2.0 :: Float+-- 1.0+-- >>> round2 @Rational @Float f maxOdd32 2.0+-- 2.0+-- >>> maxOdd64 = 9.007199254740991e15+-- >>> f maxOdd64 2.0 :: Double+-- 1.0+-- >>> round2 @Rational @Double f maxOdd64 2.0+-- 2.0+round2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b+round2 f x y = round $ f (g x) (g y) where Conn _ g _ = connL+{-# INLINE round2 #-}++-- | Truncate towards zero.+--+-- > truncate @a @a = id+truncate :: (Num a, Triple a b) => a -> b+truncate x = if x >~ 0 then floor x else ceiling x++-- | Lift a unary function over a 'Conn'.+--+-- Results are truncated towards 0.+truncate1 :: (Num a, Triple a b) => (a -> a) -> b -> b+truncate1 f x = truncate $ f (g x) where Conn _ g _ = connL+{-# INLINE truncate1 #-}++-- | Lift a binary function over a 'Conn'.+--+-- Results are truncated towards 0.+truncate2 :: (Num a, Triple a b) => (a -> a -> a) -> b -> b -> b+truncate2 f x y = truncate $ f (g x) (g y) where Conn _ g _ = connL+{-# INLINE truncate2 #-}++---------------------------------------------------------------------+-- Connection L+---------------------------------------------------------------------++-- | A specialization of /conn/ to left-side connections.+--+-- This is a convenience function provided primarily to avoid needing+-- to enable /DataKinds/.+connL :: Left a b => ConnL a b+connL = conn @ 'L++-- | Extract the center of a 'Conn' or upper half of a 'ConnL'.+embedL :: Left a b => b -> a+embedL = embed connL++-- | A minimal element of a preorder.+--+-- 'minimal' needn't be unique, but it must obey:+--+-- > x <~ minimal => x ~~ minimal+minimal :: Left () a => a+minimal = ceiling ()++infixr 5 `join`++-- | Semigroup operation on a join-lattice.+join :: Left (a, a) a => a -> a -> a+join = curry ceiling++-- | Extract the ceiling of a 'Conn' or lower half of a 'ConnL'.+--+-- > ceiling @a @a = id+-- > ceiling (x1 `join` a2) = ceiling x1 `join` ceiling x2+--+-- The latter law is the adjoint functor theorem for preorders.+--+-- >>> Data.Connection.ceiling @Rational @Float (0 :% 0)+-- NaN+-- >>> Data.Connection.ceiling @Rational @Float (1 :% 0)+-- Infinity+-- >>> Data.Connection.ceiling @Rational @Float (13 :% 10)+-- 1.3000001+ceiling :: Left a b => a -> b+ceiling = ceilingWith conn++-- | Lift a unary function over a 'ConnL'.+ceiling1 :: Left a b => (a -> a) -> b -> b+ceiling1 = ceilingWith1 conn++-- | Lift a binary function over a 'ConnL'.+ceiling2 :: Left a b => (a -> a -> a) -> b -> b -> b+ceiling2 = ceilingWith2 conn++---------------------------------------------------------------------+-- Connection R+---------------------------------------------------------------------++-- | A specialization of /conn/ to right-side connections.+--+-- This is a convenience function provided primarily to avoid needing+-- to enable /DataKinds/.+connR :: Right a b => ConnR a b+connR = conn @ 'R++-- | Extract the center of a 'ConnK' or lower half of a 'ConnR'.+embedR :: Right a b => b -> a+embedR = embed connR++-- | A maximal element of a preorder.+--+-- 'maximal' needn't be unique, but it must obey:+--+-- > x >~ maximal => x ~~ maximal+maximal :: Right () a => a+maximal = floor ()++infixr 6 `meet`++-- | Semigroup operation on a meet-lattice.+meet :: Right (a, a) a => a -> a -> a+meet = curry floor++-- | Extract the floor of a 'ConnK' or upper half of a 'ConnL'.+--+-- > floor @a @a = id+-- > floor (x1 `meet` x2) = floor x1 `meet` floor x2+--+-- The latter law is the adjoint functor theorem for preorders.+--+-- >>> Data.Connection.floor @Rational @Float (0 :% 0)+-- NaN+-- >>> Data.Connection.floor @Rational @Float (1 :% 0)+-- Infinity+-- >>> Data.Connection.floor @Rational @Float (13 :% 10)+-- 1.3+floor :: Right a b => a -> b+floor = floorWith conn++-- | Lift a unary function over a 'ConnR'.+floor1 :: Right a b => (a -> a) -> b -> b+floor1 = floorWith1 conn++-- | Lift a binary function over a 'ConnR'.+floor2 :: Right a b => (a -> a -> a) -> b -> b -> b+floor2 = floorWith2 conn++---------------------------------------------------------------------+-- Instances+---------------------------------------------------------------------++instance Preorder a => Connection k a a where conn = identity++instance Connection k ((), ()) () where conn = latticeOrd++instance Connection k () Bool where conn = bounded+instance Connection k Ordering Bool where conn = extremal+instance Connection k Word8 Bool where conn = extremal+instance Connection k Word16 Bool where conn = extremal+instance Connection k Word32 Bool where conn = extremal+instance Connection k Word64 Bool where conn = extremal+instance Connection k Word Bool where conn = extremal+instance Connection k Positive Bool where conn = extremal+instance Connection k Int8 Bool where conn = extremal+instance Connection k Int16 Bool where conn = extremal+instance Connection k Int32 Bool where conn = extremal+instance Connection k Int64 Bool where conn = extremal+instance Connection k Int Bool where conn = extremal+instance Connection k Rational Bool where conn = extremal+instance Connection k Float Bool where conn = extremal+instance Connection k Double Bool where conn = extremal+instance Connection k (Bool, Bool) Bool where conn = latticeOrd++instance Connection k () Ordering where conn = bounded+instance Connection k (Ordering, Ordering) Ordering where conn = latticeOrd++instance Connection k () Word8 where conn = bounded+instance Connection 'L Int8 Word8 where conn = i08w08+instance Connection k (Word8, Word8) Word8 where conn = latticeOrd++instance Connection k () Word16 where conn = bounded+instance Connection 'L Word8 Word16 where conn = w08w16+instance Connection 'L Int8 Word16 where conn = i08w16+instance Connection 'L Int16 Word16 where conn = i16w16+instance Connection k (Word16, Word16) Word16 where conn = latticeOrd++instance Connection k () Word32 where conn = bounded+instance Connection 'L Word8 Word32 where conn = w08w32+instance Connection 'L Word16 Word32 where conn = w16w32+instance Connection 'L Int8 Word32 where conn = i08w32+instance Connection 'L Int16 Word32 where conn = i16w32+instance Connection 'L Int32 Word32 where conn = i32w32+instance Connection k (Word32, Word32) Word32 where conn = latticeOrd++instance Connection k () Word64 where conn = bounded+instance Connection 'L Word8 Word64 where conn = w08w64+instance Connection 'L Word16 Word64 where conn = w16w64+instance Connection 'L Word32 Word64 where conn = w32w64+instance Connection 'L Int8 Word64 where conn = i08w64+instance Connection 'L Int16 Word64 where conn = i16w64+instance Connection 'L Int32 Word64 where conn = i32w64+instance Connection 'L Int64 Word64 where conn = i64w64+instance Connection 'L Int Word64 where conn = ixxw64+instance Connection k (Word64, Word64) Word64 where conn = latticeOrd++instance Connection k () Word where conn = bounded+instance Connection 'L Word8 Word where conn = w08wxx+instance Connection 'L Word16 Word where conn = w16wxx+instance Connection 'L Word32 Word where conn = w32wxx+instance Connection k Word64 Word where conn = w64wxx+instance Connection 'L Int8 Word where conn = i08wxx+instance Connection 'L Int16 Word where conn = i16wxx+instance Connection 'L Int32 Word where conn = i32wxx+instance Connection 'L Int64 Word where conn = i64wxx+instance Connection 'L Int Word where conn = ixxwxx+instance Connection k (Word, Word) Word where conn = latticeOrd++instance Connection 'L () Natural where conn = ConnL (const 0) (const ())+instance Connection 'L Word8 Natural where conn = w08nat+instance Connection 'L Word16 Natural where conn = w16nat+instance Connection 'L Word32 Natural where conn = w32nat+instance Connection 'L Word64 Natural where conn = w64nat+instance Connection 'L Word Natural where conn = wxxnat+instance Connection 'L Int8 Natural where conn = i08nat+instance Connection 'L Int16 Natural where conn = i16nat+instance Connection 'L Int32 Natural where conn = i32nat+instance Connection 'L Int64 Natural where conn = i64nat+instance Connection 'L Int Natural where conn = ixxnat+instance Connection 'L Integer Natural where conn = intnat+instance Connection k (Natural, Natural) Natural where conn = latticeOrd++instance Connection k () Positive where+ conn = Conn (const $ 0 :% 1) (const ()) (const $ 1 :% 0)+instance Connection k (Positive, Positive) Positive where conn = latticeN5++instance Connection k () Int8 where conn = bounded+instance Connection k (Int8, Int8) Int8 where conn = latticeOrd+instance Connection k () Int16 where conn = bounded+instance Connection k (Int16, Int16) Int16 where conn = latticeOrd+instance Connection k () Int32 where conn = bounded+instance Connection k (Int32, Int32) Int32 where conn = latticeOrd+instance Connection k () Int64 where conn = bounded+instance Connection k (Int64, Int64) Int64 where conn = latticeOrd+instance Connection k () Int where conn = bounded+instance Connection k (Int, Int) Int where conn = latticeOrd+instance Connection k (Integer, Integer) Integer where conn = latticeOrd++instance Connection k () Rational where+ conn = Conn (const $ -1 :% 0) (const ()) (const $ 1 :% 0)+instance Connection k (Rational, Rational) Rational where conn = latticeN5++instance Connection k () Float where conn = extremalN5+instance Connection k Double Float where conn = f64f32+instance Connection k Rational Float where conn = ratf32+instance Connection k (Float, Float) Float where conn = latticeN5++instance Connection k () Double where conn = extremalN5+instance Connection k Rational Double where conn = ratf64+instance Connection k (Double, Double) Double where conn = latticeN5++instance Connection 'L Word8 (Maybe Int16) where conn = w08i16+instance Connection 'L Int8 (Maybe Int16) where conn = i08i16++instance Connection 'L Word8 (Maybe Int32) where conn = w08i32+instance Connection 'L Word16 (Maybe Int32) where conn = w16i32+instance Connection 'L Int8 (Maybe Int32) where conn = i08i32+instance Connection 'L Int16 (Maybe Int32) where conn = i16i32++instance Connection 'L Word8 (Maybe Int64) where conn = w08i64+instance Connection 'L Word16 (Maybe Int64) where conn = w16i64+instance Connection 'L Word32 (Maybe Int64) where conn = w32i64+instance Connection 'L Int8 (Maybe Int64) where conn = i08i64+instance Connection 'L Int16 (Maybe Int64) where conn = i16i64+instance Connection 'L Int32 (Maybe Int64) where conn = i32i64++instance Connection 'L Word8 (Maybe Int) where conn = w08ixx+instance Connection 'L Word16 (Maybe Int) where conn = w16ixx+instance Connection 'L Word32 (Maybe Int) where conn = w32ixx+instance Connection 'L Int8 (Maybe Int) where conn = i08ixx+instance Connection 'L Int16 (Maybe Int) where conn = i16ixx+instance Connection 'L Int32 (Maybe Int) where conn = i32ixx+instance Connection k Int64 Int where conn = i64ixx++instance Connection 'L Word8 (Maybe Integer) where conn = w08int+instance Connection 'L Word16 (Maybe Integer) where conn = w16int+instance Connection 'L Word32 (Maybe Integer) where conn = w32int+instance Connection 'L Word64 (Maybe Integer) where conn = w64int+instance Connection 'L Word (Maybe Integer) where conn = wxxint+instance Connection 'L Natural (Maybe Integer) where conn = natint++instance Connection 'L Int8 (Maybe Integer) where conn = i08int+instance Connection 'L Int16 (Maybe Integer) where conn = i16int+instance Connection 'L Int32 (Maybe Integer) where conn = i32int+instance Connection 'L Int64 (Maybe Integer) where conn = i64int+instance Connection 'L Int (Maybe Integer) where conn = ixxint++{-+instance Connection 'L Integer (Maybe Integer) where+ -- | Provided as a shim for /RebindableSyntax/.+ -- Note that this instance will clip negative numbers to zero.+conn = swapR $ intnat >>> natint+-}++instance Connection k Rational (Extended Int8) where conn = rati08+instance Connection k Rational (Extended Int16) where conn = rati16+instance Connection k Rational (Extended Int32) where conn = rati32+instance Connection k Rational (Extended Int64) where conn = rati64+instance Connection k Rational (Extended Int) where conn = ratixx+instance Connection k Rational (Extended Integer) where conn = ratint++-- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+instance Connection k Float (Extended Int8) where conn = f32i08++-- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.+instance Connection k Float (Extended Int16) where conn = f32i16++-- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int8) where conn = f64i08++-- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int16) where conn = f64i16++-- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.+instance Connection k Double (Extended Int32) where conn = f64i32++instance Connection k a b => Connection k (Identity a) b where+ conn = Conn runIdentity Identity runIdentity >>> conn++instance Connection k a b => Connection k a (Identity b) where+ conn = conn >>> Conn Identity runIdentity Identity++instance (Triple () a, Triple () b) => Connection k () (a, b) where+ conn = Conn (const (minimal, minimal)) (const ()) (const (maximal, maximal))++instance Preorder a => Connection 'L () (Maybe a) where+ conn = ConnL (const Nothing) (const ())++instance Right () a => Connection 'R () (Maybe a) where+ conn = ConnR (const ()) (const $ Just maximal)++instance Preorder a => Connection k () (Extended a) where+ conn = Conn (const Bottom) (const ()) (const Top)++instance (Left () a, Preorder b) => Connection 'L () (Either a b) where+ conn = ConnL (const $ Left minimal) (const ())++instance (Preorder a, Right () b) => Connection 'R () (Either a b) where+ conn = ConnR (const ()) (const $ Right maximal)++instance (Preorder a, Triple () b) => Connection k (Maybe a) (Either a b) where+ conn = maybeL++instance (Triple () a, Preorder b) => Connection k (Maybe b) (Either a b) where+ conn = maybeR++instance (Total a) => Connection 'L () (Set.Set a) where+ conn = ConnL (const Set.empty) (const ())++instance Total a => Connection k (Set.Set a, Set.Set a) (Set.Set a) where+ conn = Conn (uncurry Set.union) fork (uncurry Set.intersection)++instance Connection 'L () IntSet.IntSet where+ conn = ConnL (const IntSet.empty) (const ())++instance Connection k (IntSet.IntSet, IntSet.IntSet) IntSet.IntSet where+ conn = Conn (uncurry IntSet.union) fork (uncurry IntSet.intersection)++instance (Total a, Preorder b) => Connection 'L () (Map.Map a b) where+ conn = ConnL (const Map.empty) (const ())++instance (Total a, Left (b, b) b) => Connection 'L (Map.Map a b, Map.Map a b) (Map.Map a b) where+ conn = ConnL (uncurry $ Map.unionWith join) fork++instance (Total a, Right (b, b) b) => Connection 'R (Map.Map a b, Map.Map a b) (Map.Map a b) where+ conn = ConnR fork (uncurry $ Map.intersectionWith meet)++instance Preorder a => Connection 'L () (IntMap.IntMap a) where+ conn = ConnL (const IntMap.empty) (const ())++instance Left (a, a) a => Connection 'L (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where+ conn = ConnL (uncurry $ IntMap.unionWith join) fork++instance Right (a, a) a => Connection 'R (IntMap.IntMap a, IntMap.IntMap a) (IntMap.IntMap a) where+ conn = ConnR fork (uncurry $ IntMap.intersectionWith meet)++-- Internal++-------------------------++fork :: a -> (a, a)+fork x = (x, x)++bounded :: Bounded a => Conn k () a+bounded = Conn (const minBound) (const ()) (const maxBound)++latticeN5 :: (Total a, Fractional a) => Conn k (a, a) a+latticeN5 = Conn (uncurry joinN5) fork (uncurry meetN5)+ where+ joinN5 x y = maybe (1 / 0) (bool y x . (>= EQ)) (pcompare x y)++ meetN5 x y = maybe (-1 / 0) (bool y x . (<= EQ)) (pcompare x y)++extremalN5 :: (Total a, Fractional a) => Conn k () a+extremalN5 = Conn (const $ -1 / 0) (const ()) (const $ 1 / 0)++latticeOrd :: (Total a) => Conn k (a, a) a+latticeOrd = Conn (uncurry max) fork (uncurry min)++maybeL :: Triple () b => Conn k (Maybe a) (Either a b)+maybeL = Conn f g h+ where+ f = maybe (Right minimal) Left+ g = either Just (const Nothing)+ h = maybe (Right maximal) Left++maybeR :: Triple () a => Conn k (Maybe b) (Either a b)+maybeR = Conn f g h+ where+ f = maybe (Left minimal) Right+ g = either (const Nothing) Just+ h = maybe (Left maximal) Right++{-+instance (Triple (a, a) a, Triple (b, b) b) => Connection k ((a, b), (a, b)) (a, b) where+ conn = Conn (uncurry joinTuple) fork (uncurry meetTuple)++instance Left (a, a) a => Connection 'L (Maybe a, Maybe a) (Maybe a) where+ conn = ConnL (uncurry joinMaybe) fork++instance Right (a, a) a => Connection 'R (Maybe a, Maybe a) (Maybe a) where+ conn = ConnR fork (uncurry meetMaybe)++instance Left (a, a) a => Connection 'L (Extended a, Extended a) (Extended a) where+ conn = ConnL (uncurry joinExtended) fork++instance Right (a, a) a => Connection 'R (Extended a, Extended a) (Extended a) where+ conn = ConnR fork (uncurry meetExtended)++-- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.+instance (Left (a, a) a, Left (b, b) b) => Connection 'L (Either a b, Either a b) (Either a b) where+ conn = ConnL (uncurry joinEither) fork++instance (Right (a, a) a, Right (b, b) b) => Connection 'R (Either a b, Either a b) (Either a b) where+ conn = ConnR fork (uncurry meetEither)++joinMaybe :: Connection 'L (a, a) a => Maybe a -> Maybe a -> Maybe a+joinMaybe (Just x) (Just y) = Just (x `join` y)+joinMaybe u@(Just _) _ = u+joinMaybe _ u@(Just _) = u+joinMaybe Nothing Nothing = Nothing++meetMaybe :: Connection 'R (a, a) a => Maybe a -> Maybe a -> Maybe a+meetMaybe Nothing Nothing = Nothing+meetMaybe Nothing _ = Nothing+meetMaybe _ Nothing = Nothing+meetMaybe (Just x) (Just y) = Just (x `meet` y)++joinExtended :: Connection 'L (a, a) a => Extended a -> Extended a -> Extended a+joinExtended Top _ = Top+joinExtended _ Top = Top+joinExtended (Extended x) (Extended y) = Extended (x `join` y)+joinExtended Bottom y = y+joinExtended x Bottom = x++meetExtended :: Connection 'R (a, a) a => Extended a -> Extended a -> Extended a+meetExtended Top y = y+meetExtended x Top = x+meetExtended (Extended x) (Extended y) = Extended (x `meet` y)+meetExtended Bottom _ = Bottom+meetExtended _ Bottom = Bottom++joinEither :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => Either a b -> Either a b -> Either a b+joinEither (Right x) (Right y) = Right (x `join` y)+joinEither u@(Right _) _ = u+joinEither _ u@(Right _) = u+joinEither (Left x) (Left y) = Left (x `join` y)++meetEither :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => Either a b -> Either a b -> Either a b+meetEither (Left x) (Left y) = Left (x `meet` y)+meetEither l@(Left _) _ = l+meetEither _ l@(Left _) = l+meetEither (Right x) (Right y) = Right (x `meet` y)++joinTuple :: (Connection 'L (a, a) a, Connection 'L (b, b) b) => (a, b) -> (a, b) -> (a, b)+joinTuple (x1, y1) (x2, y2) = (x1 `join` x2, y1 `join` y2)++meetTuple :: (Connection 'R (a, a) a, Connection 'R (b, b) b) => (a, b) -> (a, b) -> (a, b)+meetTuple (x1, y1) (x2, y2) = (x1 `meet` x2, y1 `meet` y2) -}
src/Data/Connection/Conn.hs view
@@ -1,137 +1,246 @@-{-# Language TypeFamilies #-}-{-# Language TypeApplications #-}-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds #-}-{-# Language Safe #-}-{-# Language DeriveFunctor #-}-{-# Language DeriveGeneric #-}-{-# Language DataKinds #-}-{-# Language ViewPatterns #-}-{-# Language PatternSynonyms #-}-{-# Language RankNTypes #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}+ module Data.Connection.Conn (- -- * Conn- Kan(..)- , Conn()- , embed- -- ** Trip- , type Trip- , pattern Conn- , trip- , range- -- ** ConnL- , type ConnL- , pattern ConnL- , swapL- , downL- , unitL- , counitL- , lowerL- , lowerL1- , lowerL2- , upperL1- , upperL2- -- ** ConnR- , type ConnR- , pattern ConnR- , swapR- , downR- , unitR- , counitR- , upperR- , upperR1- , upperR2- , lowerR1- , lowerR2- -- * Connections- , choice- , strong- , fmapped+ -- * Conn+ Kan (..),+ Conn (),+ pattern Conn,+ embed,+ range,+ identity,++ -- * Connection k+ ConnK,+ half,+ midpoint,+ roundWith,+ roundWith1,+ roundWith2,+ truncateWith,+ truncateWith1,+ truncateWith2,++ -- * Connection L+ ConnL,+ pattern ConnL,+ upL,+ downL,+ swapL,+ counit,+ upper,+ upper1,+ upper2,+ filterWith,+ ceilingWith,+ ceilingWith1,+ ceilingWith2,++ -- * Connection R+ ConnR,+ pattern ConnR,+ upR,+ downR,+ swapR,+ unit,+ lower,+ lower1,+ lower2,+ idealWith,+ floorWith,+ floorWith1,+ floorWith2,++ -- * Combinators+ (>>>),+ (<<<),+ choice,+ strong, ) where import safe Control.Arrow-import safe Control.Category (Category)+import safe Control.Category (Category, (<<<), (>>>))+import safe qualified Control.Category as C import safe Data.Bifunctor (bimap) import safe Data.Order-import safe Prelude hiding (Ord(..), Bounded)-import safe qualified Control.Category as C+import safe Prelude hiding (Ord (..)) --- | A data kind distinguishing the chirality of a Kan extension.------ Here it serves to distinguish the directionality of a preorder:------ * /L/-tagged types are 'upwards-directed'+-- $setup+-- >>> :set -XTypeApplications+-- >>> import Data.Int+-- >>> import Data.Ord (Down(..))+-- >>> import GHC.Real (Ratio(..))+-- >>> :load Data.Connection+-- >>> ratf32 = conn @_ @Rational @Float+-- >>> f64f32 = conn @_ @Double @Float++-- | A data kind distinguishing the directionality of a Galois connection: ----- * /R/-tagged types are 'downwards-directed'+-- * /L/-tagged types are low / increasing (e.g. 'Data.Connection.Class.minimal', 'Data.Connection.Class.upper', 'Data.Connection.Class.ceiling', 'Data.Connection.Class.join') --+-- * /R/-tagged types are high / decreasing (e.g. 'Data.Connection.Class.maximal', 'Data.Connection.Class.lower', 'Data.Connection.Class.floor', 'Data.Connection.Class.meet') data Kan = L | R -- | An < https://ncatlab.org/nlab/show/adjoint+string adjoint string > of Galois connections of length 2 or 3. ---data Conn (k :: Kan) a b = Conn_ (a -> (b , b)) (b -> a)+-- Connections have many nice properties wrt numerical conversion:+--+-- >>> range (conn @_ @Rational @Float) (1 :% 8) -- eighths are exactly representable in a float+-- (0.125,0.125)+-- >>> range (conn @_ @Rational @Float) (1 :% 7) -- sevenths are not+-- (0.14285713,0.14285715)+data Conn (k :: Kan) a b = Galois (a -> (b, b)) (b -> a) instance Category (Conn k) where- id = Conn_ (id &&& id) id+ id = identity+ {-# INLINE id #-} - Conn_ f1 g1 . Conn_ f2 g2 = Conn_ ((fst.f1).(fst.f2) &&& (snd.f1).(snd.f2)) (g2 . g1)+ Galois f1 g1 . Galois f2 g2 = Galois ((fst . f1) . (fst . f2) &&& (snd . f1) . (snd . f2)) (g2 . g1)+ {-# INLINE (.) #-} --- | Obtain the center of a /Trip/, upper half of a /ConnL/, or the lower half of a /ConnR/.+-- | Obtain a /Conn/ from an adjoint triple of monotone functions. ---embed :: Conn k a b -> b -> a-embed (Conn_ _ g) = g+-- This is a view pattern for an arbitrary 'Conn'. When applied to a 'ConnL'+-- or 'ConnR', the two functions of type @a -> b@ returned will be identical.+--+-- /Caution/: /Conn f g h/ must obey \(f \dashv g \dashv h\). This condition is not checked.+--+-- For detailed properties see 'Data.Connection.Property'.+pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b+pattern Conn f g h <- (embed &&& _1 &&& _2 -> (g, (h, f))) where Conn f g h = Galois (h &&& f) g +{-# COMPLETE Conn #-}+ -- Internal floor function. When \(f \dashv g \dashv h \) this is h. _1 :: Conn k a b -> a -> b-_1 (Conn_ f _) = fst . f+_1 (Galois f _) = fst . f+{-# INLINE _1 #-} -- Internal ceiling function. When \(f \dashv g \dashv h \) this is f. _2 :: Conn k a b -> a -> b-_2 (Conn_ f _) = snd . f+_2 (Galois f _) = snd . f+{-# INLINE _2 #-} +-- | The identity 'Conn'.+identity :: Conn k a a+identity = Galois (id &&& id) id+{-# INLINE identity #-}++-- | Obtain the center of a 'ConnK', upper adjoint of a 'ConnL', or lower adjoint of a 'ConnR'.+embed :: Conn k a b -> b -> a+embed (Galois _ g) = g+{-# INLINE embed #-}++-- | Obtain the upper and/or lower adjoints of a connection.+--+-- > range c = floorWith c &&& ceilingWith c+--+-- >>> range f64f32 pi+-- (3.1415925,3.1415927)+-- >>> range f64f32 (0/0)+-- (NaN,NaN)+range :: Conn k a b -> a -> (b, b)+range (Galois f _) = f+{-# INLINE range #-}+ ------------------------------------------------------------------------ Trip+-- ConnK --------------------------------------------------------------------- -- | An <https://ncatlab.org/nlab/show/adjoint+triple adjoint triple> of Galois connections. -- -- An adjoint triple is a chain of connections of length 3: ----- \(f \dashv g \dashv h \) +-- \(f \dashv g \dashv h \) -- -- For detailed properties see 'Data.Connection.Property'.+type ConnK a b = forall k. Conn k a b++-- | Determine which half of the interval between 2 representations of /a/ a particular value lies. ---type Trip a b = forall k. Conn k a b+-- @ 'half' t x = 'pcompare' (x - 'lower' t x) ('upper' t x - x) @+--+-- >>> maybe False (== EQ) $ half f64f32 (midpoint f64f32 pi)+-- True+half :: (Num a, Preorder a) => ConnK a b -> a -> Maybe Ordering+half c x = pcompare (x - lower c x) (upper c x - x)+{-# INLINE half #-} --- | A view pattern for an arbitrary (left or right) 'Conn'.+-- | Return the midpoint of the interval containing x. ----- /Caution/: /Conn f g h/ must obey \(f \dashv g \dashv h\). This condition is not checked.+-- >>> pi - midpoint f64f32 pi+-- 3.1786509424591713e-8+midpoint :: Fractional a => ConnK a b -> a -> a+midpoint c x = lower c x / 2 + upper c x / 2+{-# INLINE midpoint #-}++-- | Return the nearest value to x. ----- For detailed properties see 'Data.Connection.Property'.+-- > roundWith identity = id ---pattern Conn :: (a -> b) -> (b -> a) -> (a -> b) -> Conn k a b-pattern Conn f g h <- (embed &&& _1 &&& _2 -> (g, (h, f)))- where Conn f g h = Conn_ (h &&& f) g-{-# COMPLETE Conn #-}+-- If x lies halfway between two finite values, then return the value+-- with the larger absolute value (i.e. round away from zero).+--+-- See <https://en.wikipedia.org/wiki/Rounding>.+roundWith :: forall a b. (Num a, Preorder a) => ConnK a b -> a -> b+roundWith c x = case half c x of+ Just GT -> ceilingWith c x+ Just LT -> floorWith c x+ _ -> truncateWith c x+{-# INLINE roundWith #-} --- | Obtain a /forall k. Conn k/ from an adjoint triple of monotone functions.+-- | Lift a unary function over a 'ConnK'. ----- /Caution/: @Conn f g h@ must obey \(f \dashv g \dashv h\). This condition is not checked.+-- Results are rounded to the nearest value with ties away from 0.+roundWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b+roundWith1 c f x = roundWith c $ f (g x) where Conn _ g _ = c+{-# INLINE roundWith1 #-}++-- | Lift a binary function over a 'ConnK'. ---trip :: (a -> b) -> (b -> a) -> (a -> b) -> Trip a b-trip f g h = Conn_ (h &&& f) g+-- Results are rounded to the nearest value with ties away from 0.+--+-- Example avoiding loss-of-precision:+--+-- >>> f x y = (x + y) - x+-- >>> maxOdd32 = 1.6777215e7+-- >>> f maxOdd32 2.0 :: Float+-- 1.0+-- >>> roundWith2 ratf32 f maxOdd32 2.0+-- 2.0+roundWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b+roundWith2 c f x y = roundWith c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE roundWith2 #-} --- | Obtain the lower and upper functions from a 'Trip'.+-- | Truncate towards zero. ----- > range c = upperR c &&& lowerL c+-- > truncateWith identity = id+truncateWith :: (Num a, Preorder a) => ConnK a b -> a -> b+truncateWith c x = if x >~ 0 then floorWith c x else ceilingWith c x+{-# INLINE truncateWith #-}++-- | Lift a unary function over a 'ConnK'. ----- >>> range f64f32 pi--- (3.1415925,3.1415927)--- >>> range f64f32 (0/0)--- (NaN,NaN)+-- Results are truncated towards zero. ---range :: Trip a b -> a -> (b, b)-range c = upperR c &&& lowerL c +-- > truncateWith1 identity = id+truncateWith1 :: (Num a, Preorder a) => ConnK a b -> (a -> a) -> b -> b+truncateWith1 c f x = truncateWith c $ f (g x) where Conn _ g _ = c+{-# INLINE truncateWith1 #-} +truncateWith2 :: (Num a, Preorder a) => ConnK a b -> (a -> a -> a) -> b -> b -> b+truncateWith2 c f x y = truncateWith c $ f (g x) (g y) where Conn _ g _ = c+{-# INLINE truncateWith2 #-}+ --------------------------------------------------------------------- -- ConnL ---------------------------------------------------------------------@@ -142,7 +251,7 @@ -- is an adjunction in the category of preorders. -- -- Each side of the connection may be defined in terms of the other:--- +-- -- \( g(x) = \sup \{y \in E \mid f(y) \leq x \} \) -- -- \( f(x) = \inf \{y \in E \mid g(y) \geq x \} \)@@ -150,94 +259,122 @@ -- For further information see 'Data.Connection.Property'. -- -- /Caution/: Monotonicity is not checked.--- type ConnL = Conn 'L -- | A view pattern for a 'ConnL'. -- -- /Caution/: /ConnL f g/ must obey \(f \dashv g \). This condition is not checked.--- pattern ConnL :: (a -> b) -> (b -> a) -> ConnL a b-pattern ConnL f g <- (_2 &&& embed -> (f, g)) where ConnL f g = Conn_ (f &&& f) g+pattern ConnL f g <- (_2 &&& embed -> (f, g)) where ConnL f g = Galois (f &&& f) g+ {-# COMPLETE ConnL #-} --- | Witness to the symmetry between 'ConnL' and 'ConnR'.------ > swapL . swapR = id--- > swapR . swapL = id+-- | Convert an inverted 'ConnL' to a 'ConnL'. ---swapL :: ConnR a b -> ConnL b a-swapL (ConnR f g) = ConnL f g+-- > upL . downL = downL . upL = id+upL :: ConnL (Down a) (Down b) -> ConnL b a+upL (ConnL f g) = ConnL g' f'+ where+ f' x = let (Down y) = f (Down x) in y+ g' x = let (Down y) = g (Down x) in y+{-# INLINE upL #-} --- | Convert an arbitrary 'Conn' to an inverted 'ConnL'.+-- | Convert a 'ConnL' to an inverted 'ConnL'. ----- >>> unitL (downL $ conn @_ @() @Ordering) (Down LT)+-- >>> upper (downL $ conn @_ @() @Ordering) (Down LT) -- Down LT--- >>> unitL (downL $ conn @_ @() @Ordering) (Down GT)+-- >>> upper (downL $ conn @_ @() @Ordering) (Down GT) -- Down LT--- downL :: ConnL a b -> ConnL (Down b) (Down a) downL (ConnL f g) = ConnL (\(Down x) -> Down $ g x) (\(Down x) -> Down $ f x)+{-# INLINE downL #-} --- | Round trip through a connection.------ > unitL c = upperL1 c id = embed c . lowerL c--- > x <= unitL c x--- --- >>> compare pi $ unitL f64f32 pi--- LT+-- | Witness to the symmetry between 'ConnL' and 'ConnR'. ---unitL :: ConnL a b -> a -> a-unitL c = upperL1 c id+-- > swapL . swapR = id+-- > swapR . swapL = id+swapL :: ConnR a b -> ConnL b a+swapL (ConnR f g) = ConnL f g+{-# INLINE swapL #-} --- | Reverse round trip through a connection.+-- | Reverse round trip through a 'ConnK' or 'ConnL'. ----- > x >= counitL c x+-- This is the counit of the resulting comonad: ----- >>> counitL (conn @_ @() @Ordering) LT+-- > x >~ counit c x+--+-- >>> counit (conn @_ @() @Ordering) LT -- LT--- >>> counitL (conn @_ @() @Ordering) GT+-- >>> counit (conn @_ @() @Ordering) GT -- LT+counit :: ConnL a b -> b -> b+counit c = ceilingWith1 c id+{-# INLINE counit #-}++-- | Round trip through a 'ConnK' or 'ConnL'. ---counitL :: ConnL a b -> b -> b-counitL c = lowerL1 c id+-- > upper c = upper1 c id = embed c . ceilingWith c+-- > x <= upper c x+--+-- >>> compare pi $ upper f64f32 pi+-- LT+upper :: ConnL a b -> a -> a+upper c = upper1 c id+{-# INLINE upper #-} --- | Extract the lower half of a 'Trip' or 'ConnL'.+-- | Map over a 'ConnK' or 'ConnL' from the right.+upper1 :: ConnL a b -> (b -> b) -> a -> a+upper1 (ConnL f g) h a = g $ h (f a)+{-# INLINE upper1 #-}++-- | Zip over a 'ConnK' or 'ConnL' from the right.+upper2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a+upper2 (ConnL f g) h a1 a2 = g $ h (f a1) (f a2)+{-# INLINE upper2 #-}++-- | Obtain the principal filter in /B/ generated by an element of /A/. ----- When /a/ and /b/ are lattices we have:+-- A subset /B/ of a lattice is an filter if and only if it is an upper set+-- that is closed under finite meets, i.e., it is nonempty and for all+-- /x/, /y/ in /B/, the element @x `meet` y@ is also in /b/. ----- > lowerL c (x1 \/ a2) = lowerL c x1 \/ lowerL c x2+-- /filterWith/ and /idealWith/ commute with /Down/: ----- This is the adjoint functor theorem for preorders.+-- > filterWith c a b <=> idealWith c (Down a) (Down b) ----- >>> upperR f64f32 pi--- 3.1415925--- >>> lowerL f64f32 pi--- 3.1415927+-- > filterWith c (Down a) (Down b) <=> idealWith c a b ---lowerL :: ConnL a b -> a -> b-lowerL (ConnL f _) = f---- | Map over a connection from the left.+-- /filterWith c a/ is upward-closed for all /a/: ---lowerL1 :: ConnL a b -> (a -> a) -> b -> b-lowerL1 (ConnL f g) h b = f $ h (g b)---- | Zip over a connection from the left.+-- > a <= b1 && b1 <= b2 => a <= b2 ---lowerL2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b-lowerL2 (ConnL f g) h b1 b2 = f $ h (g b1) (g b2)---- | Map over a connection from the left.+-- > a1 <= b && inf a2 <= b => ceiling a1 `meet` ceiling a2 <= b ---upperL1 :: ConnL a b -> (b -> b) -> a -> a-upperL1 (ConnL f g) h a = g $ h (f a)+-- See <https://en.wikipedia.org/wiki/Filter_(mathematics)>+filterWith :: Preorder b => ConnL a b -> a -> b -> Bool+filterWith c a b = ceilingWith c a <~ b+{-# INLINE filterWith #-} --- | Zip over a connection from the left.+-- | Extract the left half of a 'ConnK' or 'ConnL'. ---upperL2 :: ConnL a b -> (b -> b -> b) -> a -> a -> a-upperL2 (ConnL f g) h a1 a2 = g $ h (f a1) (f a2)+-- >>> floorWith f64f32 pi+-- 3.1415925+-- >>> ceilingWith f64f32 pi+-- 3.1415927+ceilingWith :: ConnL a b -> a -> b+ceilingWith (ConnL f _) = f+{-# INLINE ceilingWith #-} +-- | Map over a 'ConnK' or 'ConnL' from the left.+ceilingWith1 :: ConnL a b -> (a -> a) -> b -> b+ceilingWith1 (ConnL f g) h b = f $ h (g b)+{-# INLINE ceilingWith1 #-}++-- | Zip over a 'ConnK' or 'ConnL' from the left.+ceilingWith2 :: ConnL a b -> (a -> a -> a) -> b -> b -> b+ceilingWith2 (ConnL f g) h b1 b2 = f $ h (g b1) (g b2)+{-# INLINE ceilingWith2 #-}+ --------------------------------------------------------------------- -- ConnR ---------------------------------------------------------------------@@ -252,126 +389,144 @@ -- use one version over the other. -- -- However some use cases (e.g. rounding) require an adjoint triple--- of connections (i.e. a 'Trip') that can lower into a standard+-- of connections (i.e. a 'ConnK') that can lower into a standard -- connection in either of two ways.--- type ConnR = Conn 'R -- | A view pattern for a 'ConnR'. -- -- /Caution/: /ConnR f g/ must obey \(f \dashv g \). This condition is not checked.--- pattern ConnR :: (b -> a) -> (a -> b) -> ConnR a b-pattern ConnR f g <- (embed &&& _1 -> (f, g)) where ConnR f g = Conn_ (g &&& g) f+pattern ConnR f g <- (embed &&& _1 -> (f, g)) where ConnR f g = Galois (g &&& g) f+ {-# COMPLETE ConnR #-} --- | Convert an arbitrary 'Conn' to an inverted 'ConnR'.+-- | Convert an inverted 'ConnR' to a 'ConnR'. ----- >>> counitR (downR $ conn @_ @() @Ordering) (Down LT)+-- > upR . downR = downR . upR = id+upR :: ConnR (Down a) (Down b) -> ConnR b a+upR (ConnR f g) = ConnR g' f'+ where+ f' x = let (Down y) = f (Down x) in y+ g' x = let (Down y) = g (Down x) in y+{-# INLINE upR #-}++-- | Convert a 'ConnR' to an inverted 'ConnR'.+--+-- >>> lower (downR $ conn @_ @() @Ordering) (Down LT) -- Down GT--- >>> counitR (downR $ conn @_ @() @Ordering) (Down GT)+-- >>> lower (downR $ conn @_ @() @Ordering) (Down GT) -- Down GT--- downR :: ConnR a b -> ConnR (Down b) (Down a) downR (ConnR f g) = ConnR (\(Down x) -> Down $ g x) (\(Down x) -> Down $ f x)+{-# INLINE downR #-} -- | Witness to the symmetry between 'ConnL' and 'ConnR'. -- -- > swapL . swapR = id -- > swapR . swapL = id--- swapR :: ConnL a b -> ConnR b a swapR (ConnL f g) = ConnR f g+{-# INLINE swapR #-} --- | Round trip through a connection.+-- | Round trip through a 'ConnK' or 'ConnR'. ----- > unitR c = upperR1 c id = upperR c . embed c--- > x <= unitR c x+-- This is the unit of the resulting monad: ----- >>> unitR (conn @_ @() @Ordering) LT+-- > x <~ unit c x+-- > unit c = floorWith1 c id = floorWith c . embed c+--+-- >>> unit (conn @_ @() @Ordering) LT -- GT--- >>> unitR (conn @_ @() @Ordering) GT+-- >>> unit (conn @_ @() @Ordering) GT -- GT----unitR :: ConnR a b -> b -> b-unitR c = upperR1 c id+unit :: ConnR a b -> b -> b+unit c = floorWith1 c id+{-# INLINE unit #-} --- | Reverse round trip through a connection.+-- | Reverse round trip through a 'ConnK' or 'ConnR'. ----- > x >= counitR c x+-- > x >~ lower c x ----- >>> compare pi $ counitR f64f32 pi+-- >>> compare pi $ lower f64f32 pi -- GT----counitR :: ConnR a b -> a -> a-counitR c = lowerR1 c id+lower :: ConnR a b -> a -> a+lower c = lower1 c id+{-# INLINE lower #-} --- | Extract the upper half of a connection.+-- | Map over a 'ConnK' or 'ConnR' from the left.+lower1 :: ConnR a b -> (b -> b) -> a -> a+lower1 (ConnR f g) h a = f $ h (g a)+{-# INLINE lower1 #-}++-- | Zip over a 'ConnK' or 'ConnR' from the left.+lower2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a+lower2 (ConnR f g) h a1 a2 = f $ h (g a1) (g a2)+{-# INLINE lower2 #-}++-- | Obtain the principal ideal in /B/ generated by an element of /A/. ----- When /a/ and /b/ are lattices we have:+-- A subset /B/ of a lattice is an ideal if and only if it is a lower set+-- that is closed under finite joins, i.e., it is nonempty and for all+-- /x/, /y/ in /B/, the element /x `join` y/ is also in /B/. ----- > upperR c (x1 /\ x2) = upperR c x1 /\ upperR c x2+-- /idealWith c a/ is downward-closed for all /a/: ----- This is the adjoint functor theorem for preorders.+-- > a >= b1 && b1 >= b2 => a >= b2 ----- >>> upperR f64f32 pi--- 3.1415925--- >>> lowerL f64f32 pi--- 3.1415927+-- > a1 >= b && a2 >= b => floor a1 `join` floor a2 >= b ---upperR :: ConnR a b -> a -> b-upperR (ConnR _ g) = g+-- See <https://en.wikipedia.org/wiki/Ideal_(order_theory)>+idealWith :: Preorder b => ConnR a b -> a -> b -> Bool+idealWith c a b = b <~ floorWith c a+{-# INLINE idealWith #-} --- | Map over a connection from the left.+-- | Extract the right half of a 'ConnK' or 'ConnR' ---upperR1 :: ConnR a b -> (a -> a) -> b -> b-upperR1 (ConnR f g) h b = g $ h (f b)---- | Zip over a connection from the left.+-- This is the adjoint functor theorem for preorders. ---upperR2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b-upperR2 (ConnR f g) h b1 b2 = g $ h (f b1) (f b2)+-- >>> floorWith f64f32 pi+-- 3.1415925+-- >>> ceilingWith f64f32 pi+-- 3.1415927+floorWith :: ConnR a b -> a -> b+floorWith (ConnR _ g) = g+{-# INLINE floorWith #-} --- | Map over a connection from the right.----lowerR1 :: ConnR a b -> (b -> b) -> a -> a-lowerR1 (ConnR f g) h a = f $ h (g a)+-- | Map over a 'ConnK' or 'ConnR' from the right.+floorWith1 :: ConnR a b -> (a -> a) -> b -> b+floorWith1 (ConnR f g) h b = g $ h (f b)+{-# INLINE floorWith1 #-} --- | Zip over a connection from the right.----lowerR2 :: ConnR a b -> (b -> b -> b) -> a -> a -> a-lowerR2 (ConnR f g) h a1 a2 = f $ h (g a1) (g a2)+-- | Zip over a 'ConnK' or 'ConnR' from the right.+floorWith2 :: ConnR a b -> (a -> a -> a) -> b -> b -> b+floorWith2 (ConnR f g) h b1 b2 = g $ h (f b1) (f b2)+{-# INLINE floorWith2 #-} ------------------------------------------------------------------------ Connections+-- Combinators --------------------------------------------------------------------- -- | Lift two 'Conn's into a 'Conn' on the <https://en.wikibooks.org/wiki/Category_Theory/Categories_of_ordered_sets coproduct order> -- -- > (choice id) (ab >>> cd) = (choice id) ab >>> (choice id) cd -- > (flip choice id) (ab >>> cd) = (flip choice id) ab >>> (flip choice id) cd--- choice :: Conn k a b -> Conn k c d -> Conn k (Either a c) (Either b d)-choice (Conn ab ba ab') (Conn cd dc cd') = Conn f g h where- f = either (Left . ab) (Right . cd)- g = either (Left . ba) (Right . dc)- h = either (Left . ab') (Right . cd')+choice (Conn ab ba ab') (Conn cd dc cd') = Conn f g h+ where+ f = either (Left . ab) (Right . cd)+ g = either (Left . ba) (Right . dc)+ h = either (Left . ab') (Right . cd')+{-# INLINE choice #-} -- | Lift two 'Conn's into a 'Conn' on the <https://en.wikibooks.org/wiki/Order_Theory/Preordered_classes_and_poclasses#product_order product order> -- -- > (strong id) (ab >>> cd) = (strong id) ab >>> (strong id) cd -- > (flip strong id) (ab >>> cd) = (flip strong id) ab >>> (flip strong id) cd--- strong :: Conn k a b -> Conn k c d -> Conn k (a, c) (b, d)-strong (Conn ab ba ab') (Conn cd dc cd') = Conn f g h where- f = bimap ab cd - g = bimap ba dc- h = bimap ab' cd'---- | Lift a 'Conn' into a functor.------ /Caution/: This function will result in an invalid connection--- if the functor alters the internal preorder (i.e. 'Data.Ord.Down').----fmapped :: Functor f => Conn k a b -> Conn k (f a) (f b)-fmapped (Conn f g h) = Conn (fmap f) (fmap g) (fmap h)+strong (Conn ab ba ab') (Conn cd dc cd') = Conn f g h+ where+ f = bimap ab cd+ g = bimap ba dc+ h = bimap ab' cd'+{-# INLINE strong #-}
− src/Data/Connection/Double.hs
@@ -1,322 +0,0 @@-{-# Language ConstraintKinds #-}-{-# Language Safe #-}-{-# Language RankNTypes #-}-module Data.Connection.Double (- f64f32- , f64i08- , f64i16- , f64i32- , min64- , max64- , ulp- , covers- , shift- , within- , epsilon- , until-) where-----import safe Data.Universe.Class-import safe Data.Bool-import safe Data.Connection.Conn-import safe Data.Int-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Syntax hiding (min, max)-import safe Data.Word-import safe GHC.Float as F-import safe Prelude hiding (Eq(..), Ord(..), until)-import safe qualified Data.Connection.Float as F32-import safe qualified Prelude as P-------------------------------------------------------------------------- Connections------------------------------------------------------------------------f64f32 :: Conn k Double Float-f64f32 = Conn f1 g f2 where- f1 x = let est = F.double2Float x in- if g est >~ x- then est- else ascend32 est g x-- f2 x = let est = F.double2Float x in- if g est <~ x- then est- else descend32 est g x-- g = F.float2Double-- ascend32 z g1 y = until (\x -> g1 x >~ y) (<~) (F32.shift 1) z-- descend32 z h1 x = until (\y -> h1 y <~ x) (>~) (F32.shift (-1)) z---- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.-f64i08 :: Conn k Double (Extended Int8)-f64i08 = triple 127---- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.-f64i16 :: Conn k Double (Extended Int16)-f64i16 = triple 32767---- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.-f64i32 :: Conn k Double (Extended Int32)-f64i32 = triple 2147483647--------------------------------------------------------------------------- Double-------------------------------------------------------------------------- | A /NaN/-handling min function.------ > min64 x NaN = x--- > min64 NaN y = y----min64 :: Double -> Double -> Double-min64 x y = case (isNaN x, isNaN y) of- (False, False) -> if x <= y then x else y- (False, True) -> x- (True, False) -> y- (True, True) -> x---- | A /NaN/-handling max function.------ > max64 x NaN = x--- > max64 NaN y = y----max64 :: Double -> Double -> Double-max64 x y = case (isNaN x, isNaN y) of- (False, False) -> if x >= y then x else y- (False, True) -> x- (True, False) -> y- (True, True) -> x---- | Covering relation on the /N5/ lattice of doubles.------ < https://en.wikipedia.org/wiki/Covering_relation >------ >>> covers 1 (shift 1 1)--- True--- >>> covers 1 (shift 2 1)--- False----covers :: Double -> Double -> Bool-covers x y = x ~~ shift (-1) y---- | Compute the signed distance between two doubles in units of least precision.------ >>> ulp 1.0 (shift 1 1.0)--- Just (LT,1)--- >>> ulp (0.0/0.0) 1.0--- Nothing----ulp :: Double -> Double -> Maybe (Ordering, Word64)-ulp x y = fmap f $ pcompare x y- where x' = doubleInt64 x- y' = doubleInt64 y- f LT = (LT, fromIntegral . abs $ y' - x')- f EQ = (EQ, 0)- f GT = (GT, fromIntegral . abs $ x' - y')---- | Shift by /n/ units of least precision.------ >>> shift 1 0--- 1.0e-45--- >>> shift 1 $ 0/0--- NaN--- >>> shift (-1) $ 0/0--- NaN--- >>> shift 1 $ 1/0--- Infinity----shift :: Int64 -> Double -> Double-shift n x | x ~~ 0/0 = x- | otherwise = int64Double . clamp64 . (+ n) . doubleInt64 $ x---- | Compare two double-precision floats for approximate equality.------ Required accuracy is specified in units of least precision.------ See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.--- -within :: Word64 -> Double -> Double -> Bool-within tol x y = maybe False ((<= tol) . snd) $ ulp x y---- | Difference between 1 and the smallest representable value greater than 1.------ > epsilon = shift 1 1 - 1------ >>> epsilon--- 2.220446049250313e-16----epsilon :: Double-epsilon = shift 1 1.0 - 1.0--{----- | Minimal positive value.------ >>> minimal64--- 5.0e-324--- >>> shift (-1) minimal64--- 0----minimal64 :: Double-minimal64 = shift 1 0.0---- | Maximum finite value.------ >>> maximal64--- 1.7976931348623157e308--- >>> shift 1 maximal64--- Infinity--- >>> shift (-1) $ negate maximal64--- -Infinity--- -maximal64 :: Double-maximal64 = shift (-1) maxBound --}------------------------------------------------------------------------------------ Orphans-----------------------------------------------------------------------{--instance Universe Double where- universe = 0/0 : indexFromTo (minBound ... maxBound)--instance Finite Double--}------------------------------------------------------------------------- Internal------------------------------------------------------------------------{-# INLINE until #-}-until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a-until pre rel f seed = go seed- where go x | x' `rel` x = x- | pre x = x- | otherwise = go x'- where x' = f x------- Non-monotonic function -signed64 :: Word64 -> Int64-signed64 x | x < 0x8000000000000000 = fromIntegral x- | otherwise = fromIntegral (maxBound P.- (x P.- 0x8000000000000000))---- Non-monotonic function converting from 2s-complement format.-unsigned64 :: Int64 -> Word64-unsigned64 x | x >~ 0 = fromIntegral x- | otherwise = 0x8000000000000000 + (maxBound P.- (fromIntegral x))---- Clamp between the int representations of -1/0 and 1/0 -clamp64 :: Int64 -> Int64-clamp64 = P.max (-9218868437227405313) . P.min 9218868437227405312 --int64Double :: Int64 -> Double-int64Double = word64Double . unsigned64--doubleInt64 :: Double -> Int64-doubleInt64 = signed64 . doubleWord64 ---- Bit-for-bit conversion.-word64Double :: Word64 -> Double-word64Double = F.castWord64ToDouble---- TODO force to pos representation?--- Bit-for-bit conversion.-doubleWord64 :: Double -> Word64-doubleWord64 = (+0) . F.castDoubleToWord64--{----- | Exact embedding up to the largest representable 'Int64'.-f64i64 :: Conn Double (Maybe Int64)-f64i64 = Conn (nanf f) (nan g) where- f x | abs x <~ 2**53-1 = P.ceiling x- | otherwise = if x >~ 0 then 2^53 else minBound-- g i | abs' i <~ 2^53-1 = fromIntegral i- | otherwise = if i >~ 0 then 1/0 else -2**53- --- | Exact embedding up to the largest representable 'Int64'.-i64f64 :: Conn (Maybe Int64) Double-i64f64 = Conn (nan g) (nanf f) where- f x | abs x <~ 2**53-1 = P.floor x- | otherwise = if x >~ 0 then maxBound else -2^53-- g i | abs i <~ 2^53-1 = fromIntegral i- | otherwise = if i >~ 0 then 2**53 else -1/0---- | Exact embedding up to the largest representable 'Int64'.-f64ixx :: Conn Double (Maybe Int)-f64ixx = Conn (nanf f) (nan g) where- f x | abs x <~ 2**53-1 = P.ceiling x- | otherwise = if x >~ 0 then 2^53 else minBound-- g i | abs' i <~ 2^53-1 = fromIntegral i- | otherwise = if i >~ 0 then 1/0 else -2**53- --- | Exact embedding up to the largest representable 'Int64'.-ixxf64 :: Conn (Maybe Int) Double-ixxf64 = Conn (nan g) (nanf f) where- f x | abs x <~ 2**53-1 = P.floor x- | otherwise = if x >~ 0 then maxBound else -2^53-- g i | abs i <~ 2^53-1 = fromIntegral i- | otherwise = if i >~ 0 then 2**53 else -1/0---}---{---- |------ @'lower64' x@ is the least element /y/ in the descending--- chain such that @not $ f y '<~' x@.----lower :: Preorder a => Double -> (Double -> a) -> a -> Double-lower z f x = until (\y -> f y <~ x) (>~) (shift $ -1) z---- |------ @'upper64' y@ is the greatest element /x/ in the ascending--- chain such that @g x '<~' y@.----upper :: Preorder a => Double -> (Double -> a) -> a -> Double-upper z g y = until (\x -> g x >~ y) (<~) (shift 1) z---- |------ @'lower' x@ is the least element /y/ in the descending--- chain such that @not $ f y '<~' x@.----lower :: Preorder a => Float -> (Float -> a) -> a -> Float-lower z f x = until (\y -> f y <~ x) (>~) (F32.shift $ -1) z---- |------ @'upper' y@ is the greatest element /x/ in the ascending--- chain such that @not $ g x '>~' y@.----upper :: Preorder a => Float -> (Float -> a) -> a -> Float-upper z g y = until (\x -> g x >~ y) (<~) (F32.shift 1) z--}--------------------------------------------------------------------------- Internal------------------------------------------------------------------------triple :: (Bounded a, Integral a) => Double -> Conn k Double (Extended a)-triple high = Conn f1 g f2 where- f1 = liftExtended (~~ -1/0) (\x -> x ~~ 0/0 || x > high) $ \x -> if x < low then minBound else P.ceiling x-- f2 = liftExtended (\x -> x ~~ 0/0 || x < low) (~~ 1/0) $ \x -> if x > high then maxBound else P.floor x-- g = extended (-1/0) (1/0) P.fromIntegral- - low = -1 - high
src/Data/Connection/Float.hs view
@@ -1,17 +1,30 @@-{-# Language ConstraintKinds #-}-{-# Language Safe #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Safe #-}+ module Data.Connection.Float (- -- * Connections- f32i08- , f32i16- --, f32i32- , min32- , max32- , covers- , ulp- , shift- , within- , epsilon+ -- * Connections+ f32i08,+ f32i16,+ f64i08,+ f64i16,+ f64i32,+ f64f32,++ -- * Float+ min32,+ max32,+ ulp32,+ near32,+ shift32,++ -- * Double+ min64,+ max64,+ ulp64,+ near64,+ shift64,+ until, ) where import safe Data.Bool@@ -19,13 +32,63 @@ import safe Data.Int import safe Data.Order import safe Data.Order.Extended-import safe Data.Order.Syntax+import safe Data.Order.Syntax hiding (max, min) import safe Data.Word import safe GHC.Float as F-import safe Prelude hiding (Eq(..), Ord(..), until)-import safe qualified Prelude as P +import safe Prelude hiding (Eq (..), Ord (..), until)+import safe qualified Prelude as P ---------------------------------------------------------------------+-- Connections+---------------------------------------------------------------------++-- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.+f32i08 :: Conn k Float (Extended Int8)+f32i08 = triple 127++-- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.+--+-- > ceilingWith f32i16 32767.0+-- Extended 32767+-- > ceilingWith f32i16 32767.1+-- Top+f32i16 :: Conn k Float (Extended Int16)+f32i16 = triple 32767++-- | All 'Data.Int.Int08' values are exactly representable in a 'Double'.+f64i08 :: Conn k Double (Extended Int8)+f64i08 = triple 127++-- | All 'Data.Int.Int16' values are exactly representable in a 'Double'.+f64i16 :: Conn k Double (Extended Int16)+f64i16 = triple 32767++-- | All 'Data.Int.Int32' values are exactly representable in a 'Double'.+f64i32 :: Conn k Double (Extended Int32)+f64i32 = triple 2147483647++f64f32 :: Conn k Double Float+f64f32 = Conn f1 g f2+ where+ f1 x =+ let est = F.double2Float x+ in if g est >~ x+ then est+ else ascend32 est g x++ f2 x =+ let est = F.double2Float x+ in if g est <~ x+ then est+ else descend32 est g x++ g = F.float2Double++ ascend32 z g1 y = until (\x -> g1 x >~ y) (<~) (shift32 1) z++ descend32 z h1 x = until (\y -> h1 y <~ x) (>~) (shift32 (-1)) z++--------------------------------------------------------------------- -- Float --------------------------------------------------------------------- @@ -33,124 +96,200 @@ -- -- > min32 x NaN = x -- > min32 NaN y = y--- min32 :: Float -> Float -> Float min32 x y = case (isNaN x, isNaN y) of- (False, False) -> if x <= y then x else y- (False, True) -> x- (True, False) -> y- (True, True) -> x+ (False, False) -> if x <= y then x else y+ (False, True) -> x+ (True, False) -> y+ (True, True) -> x -- | A /NaN/-handling max32 function. -- -- > max32 x NaN = x -- > max32 NaN y = y--- max32 :: Float -> Float -> Float max32 x y = case (isNaN x, isNaN y) of- (False, False) -> if x >= y then x else y- (False, True) -> x- (True, False) -> y- (True, True) -> x---- | Covering relation on the /N5/ lattice of floats.------ < https://en.wikipedia.org/wiki/Covering_relation >------ >>> covers 1 (shift 1 1)--- True--- >>> covers 1 (shift 2 1)--- False----covers :: Float -> Float -> Bool-covers x y = x ~~ shift (-1) y+ (False, False) -> if x >= y then x else y+ (False, True) -> x+ (True, False) -> y+ (True, True) -> x -- | Compute the signed distance between two floats in units of least precision. ----- >>> ulp 1.0 (shift 1 1.0)+-- >>> ulp32 1.0 (shift32 1 1.0) -- Just (LT,1)--- >>> ulp (0.0/0.0) 1.0+-- >>> ulp32 (0.0/0.0) 1.0 -- Nothing+ulp32 :: Float -> Float -> Maybe (Ordering, Word32)+ulp32 x y = fmap f $ pcompare x y+ where+ x' = floatInt32 x+ y' = floatInt32 y+ f LT = (LT, fromIntegral . abs $ y' - x')+ f EQ = (EQ, 0)+ f GT = (GT, fromIntegral . abs $ x' - y')++-- | Compare two floats for approximate equality. ---ulp :: Float -> Float -> Maybe (Ordering, Word32)-ulp x y = fmap f $ pcompare x y- where x' = floatInt32 x- y' = floatInt32 y- f LT = (LT, fromIntegral . abs $ y' - x')- f EQ = (EQ, 0)- f GT = (GT, fromIntegral . abs $ x' - y')+-- Required accuracy is specified in units of least precision.+--+-- See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.+near32 :: Word32 -> Float -> Float -> Bool+near32 tol x y = maybe False ((<= tol) . snd) $ ulp32 x y -- | Shift a float by /n/ units of least precision. ----- >>> shift 1 0+-- >>> shift32 1 0 -- 1.0e-45--- >>> shift 1 $ 0/0+-- >>> shift32 1 1 - 1+-- 1.1920929e-7+-- >>> shift32 1 $ 0/0 -- NaN--- >>> shift (-1) $ 0/0+-- >>> shift32 (-1) $ 0/0 -- NaN--- >>> shift 1 $ 1/0+-- >>> shift32 1 $ 1/0 -- Infinity----shift :: Int32 -> Float -> Float-shift n x | x ~~ 0/0 = x- | otherwise = int32Float . clamp32 . (+ n) . floatInt32 $ x+shift32 :: Int32 -> Float -> Float+shift32 n x+ | x ~~ 0 / 0 = x+ | otherwise = int32Float . clamp32 . (+ n) . floatInt32 $ x --- | Compare two floats for approximate equality.------ Required accuracy is specified in units of least precision.------ See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.--- -within :: Word32 -> Float -> Float -> Bool-within tol x y = maybe False ((<= tol) . snd) $ ulp x y+---------------------------------------------------------------------+-- Double+--------------------------------------------------------------------- --- | Difference between 1 and the smallest representable value greater than 1.+-- | A /NaN/-handling min function. ----- > epsilon = shift 1 1 - 1+-- > min64 x NaN = x+-- > min64 NaN y = y+min64 :: Double -> Double -> Double+min64 x y = case (isNaN x, isNaN y) of+ (False, False) -> if x <= y then x else y+ (False, True) -> x+ (True, False) -> y+ (True, True) -> x++-- | A /NaN/-handling max function. ----- >>> epsilon--- 1.1920929e-7+-- > max64 x NaN = x+-- > max64 NaN y = y+max64 :: Double -> Double -> Double+max64 x y = case (isNaN x, isNaN y) of+ (False, False) -> if x >= y then x else y+ (False, True) -> x+ (True, False) -> y+ (True, True) -> x++-- | Compute the signed distance between two doubles in units of least precision. ---epsilon :: Float-epsilon = shift 1 1.0 - 1.0+-- >>> ulp64 1.0 (shift64 1 1.0)+-- Just (LT,1)+-- >>> ulp64 (0.0/0.0) 1.0+-- Nothing+ulp64 :: Double -> Double -> Maybe (Ordering, Word64)+ulp64 x y = fmap f $ pcompare x y+ where+ x' = doubleInt64 x+ y' = doubleInt64 y+ f LT = (LT, fromIntegral . abs $ y' - x')+ f EQ = (EQ, 0)+ f GT = (GT, fromIntegral . abs $ x' - y') -{---- | Minimal32 positive value.+-- | Compare two double-precision floats for approximate equality. ----- >>> minimal32--- 1.0e-45--- >>> shift (-1) minimal32--- 0+-- Required accuracy is specified in units of least precision. ---minimal32 :: Float-minimal32 = shift 1 0.0+-- See also <https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/>.+near64 :: Word64 -> Double -> Double -> Bool+near64 tol x y = maybe False ((<= tol) . snd) $ ulp64 x y --- | Maximum finite value.+-- | Shift by /n/ units of least precision. ----- >>> maximal32--- 3.4028235e38--- >>> shift 1 maximal32+-- >>> shift64 1 0+-- 5.0e-324+-- >>> shift64 1 1 - 1+-- 2.220446049250313e-16+-- >>> shift64 1 $ 0/0+-- NaN+-- >>> shift64 (-1) $ 0/0+-- NaN+-- >>> shift64 1 $ 1/0 -- Infinity--- >>> shift (-1) $ negate maximal32--- -Infinity----maximal32 :: Float-maximal32 = shift (-1) (1/0) ---}+shift64 :: Int64 -> Double -> Double+shift64 n x+ | x ~~ 0 / 0 = x+ | otherwise = int64Double . clamp64 . (+ n) . doubleInt64 $ x ------------------------------------------------------------------------ Float+-- Internal --------------------------------------------------------------------- --- | All 'Data.Int.Int08' values are exactly representable in a 'Float'.-f32i08 :: Conn k Float (Extended Int8)-f32i08 = signedTriple 127+{-# INLINE until #-}+until :: (a -> Bool) -> (a -> a -> Bool) -> (a -> a) -> a -> a+until pre rel f seed = go seed+ where+ go x+ | x' `rel` x = x+ | pre x = x+ | otherwise = go x'+ where+ x' = f x --- | All 'Data.Int.Int16' values are exactly representable in a 'Float'.-f32i16 :: Conn k Float (Extended Int16)-f32i16 = signedTriple 32767+-- Non-monotonic function+signed32 :: Word32 -> Int32+signed32 x+ | x < 0x80000000 = fromIntegral x+ | otherwise = fromIntegral (maxBound - (x - 0x80000000)) +-- Non-monotonic function+signed64 :: Word64 -> Int64+signed64 x+ | x < 0x8000000000000000 = fromIntegral x+ | otherwise = fromIntegral (maxBound P.- (x P.- 0x8000000000000000))++-- Non-monotonic function converting from 2s-complement format.+unsigned32 :: Int32 -> Word32+unsigned32 x+ | x >= 0 = fromIntegral x+ | otherwise = 0x80000000 + (maxBound - (fromIntegral x))++-- Non-monotonic function converting from 2s-complement format.+unsigned64 :: Int64 -> Word64+unsigned64 x+ | x >~ 0 = fromIntegral x+ | otherwise = 0x8000000000000000 + (maxBound P.- (fromIntegral x))++int32Float :: Int32 -> Float+int32Float = F.castWord32ToFloat . unsigned32++floatInt32 :: Float -> Int32+floatInt32 = signed32 . (+ 0) . F.castFloatToWord32++int64Double :: Int64 -> Double+int64Double = F.castWord64ToDouble . unsigned64++doubleInt64 :: Double -> Int64+doubleInt64 = signed64 . (+ 0) . F.castDoubleToWord64++-- Clamp between the int representations of -1/0 and 1/0+clamp32 :: Int32 -> Int32+clamp32 = P.max (-2139095041) . P.min 2139095040++-- Clamp between the int representations of -1/0 and 1/0+clamp64 :: Int64 -> Int64+clamp64 = P.max (-9218868437227405313) . P.min 9218868437227405312++triple :: (RealFrac a, Preorder a, Bounded b, Integral b) => a -> Conn k a (Extended b)+triple high = Conn f g h+ where+ f = liftExtended (~~ -1 / 0) (\x -> x ~~ 0 / 0 || x > high) $ \x -> if x < low then minBound else P.ceiling x++ g = extended (-1 / 0) (1 / 0) P.fromIntegral++ h = liftExtended (\x -> x ~~ 0 / 0 || x < low) (~~ 1 / 0) $ \x -> if x > high then maxBound else P.floor x++ low = -1 - high+ {- -- | Exact embedding up to the largest representable 'Int32'. f32i32 :: ConnL Float (Maybe Int32)@@ -161,7 +300,6 @@ g i | abs' i <~ 2^24-1 = fromIntegral i | otherwise = if i >~ 0 then 1/0 else -2**24 - -- | Exact embedding up to the largest representable 'Int32'. i32f32 :: ConnL (Maybe Int32) Float i32f32 = Conn (nan g) (nanf f) where@@ -170,47 +308,22 @@ g i | abs i <~ 2^24-1 = fromIntegral i | otherwise = if i >~ 0 then 2**24 else -1/0--} ------------------------------------------------------------------------- Internal------------------------------------------------------------------------signedTriple :: (Bounded a, Integral a) => Float -> Conn k Float (Extended a)-signedTriple high = Conn f g h where-- f = liftExtended (~~ -1/0) (\x -> x ~~ 0/0 || x > high) $ \x -> if x < low then minBound else P.ceiling x-- g = extended (-1/0) (1/0) P.fromIntegral- - h = liftExtended (\x -> x ~~ 0/0 || x < low) (~~ 1/0) $ \x -> if x > high then maxBound else P.floor x-- low = -1 - high---- Non-monotonic function -signed32 :: Word32 -> Int32-signed32 x | x < 0x80000000 = fromIntegral x- | otherwise = fromIntegral (maxBound - (x - 0x80000000))---- Non-monotonic function converting from 2s-complement format.-unsigned32 :: Int32 -> Word32-unsigned32 x | x >= 0 = fromIntegral x- | otherwise = 0x80000000 + (maxBound - (fromIntegral x))---- Clamp between the int representations of -1/0 and 1/0 -clamp32 :: Int32 -> Int32-clamp32 = P.max (-2139095041) . P.min 2139095040--int32Float :: Int32 -> Float-int32Float = word32Float . unsigned32+-- | Exact embedding up to the largest representable 'Int64'.+f64i64 :: Conn Double (Maybe Int64)+f64i64 = Conn (nanf f) (nan g) where+ f x | abs x <~ 2**53-1 = P.ceiling x+ | otherwise = if x >~ 0 then 2^53 else minBound -floatInt32 :: Float -> Int32-floatInt32 = signed32 . floatWord32 + g i | abs' i <~ 2^53-1 = fromIntegral i+ | otherwise = if i >~ 0 then 1/0 else -2**53 --- Bit-for-bit conversion.-word32Float :: Word32 -> Float-word32Float = F.castWord32ToFloat+-- | Exact embedding up to the largest representable 'Int64'.+f64ixx :: Conn Double (Maybe Int)+f64ixx = Conn (nanf f) (nan g) where+ f x | abs x <~ 2**53-1 = P.ceiling x+ | otherwise = if x >~ 0 then 2^53 else minBound --- Bit-for-bit conversion.-floatWord32 :: Float -> Word32-floatWord32 = (+0) . F.castFloatToWord32+ g i | abs' i <~ 2^53-1 = fromIntegral i+ | otherwise = if i >~ 0 then 1/0 else -2**53+-}
src/Data/Connection/Int.hs view
@@ -1,164 +1,163 @@-{-# Language ConstraintKinds #-}-{-# Language Safe #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Connection.Int (- -- * Int8- i08c08- , i08w08- , i08i16- , i08i32- , i08i64- , i08int- -- * Int16- , i16c16- , i16w16- , i16i32- , i16i64- , i16int- -- * Int32- , i32c32- , i32w32- , i32i64- , i32int- -- * Int64- , i64c64- , i64w64- , i64int- -- * Int- , ixxwxx- , ixxi64- , ixxint- -- * Integer- , intnat- , natint- ) where+ -- * Int16+ w08i16,+ i08i16, -import safe Control.Category ((>>>))+ -- * Int32+ w08i32,+ w16i32,+ i08i32,+ i16i32,++ -- * Int64+ w08i64,+ w16i64,+ w32i64,+ i08i64,+ i16i64,+ i32i64,++ -- * Int+ w08ixx,+ w16ixx,+ w32ixx,+ i08ixx,+ i16ixx,+ i32ixx,+ i64ixx,++ -- * Integer+ w08int,+ w16int,+ w32int,+ w64int,+ wxxint,+ natint,+ i08int,+ i16int,+ i32int,+ i64int,+ ixxint,+) where+ import safe Control.Applicative import safe Control.Monad import safe Data.Connection.Conn-import safe Data.Connection.Word import safe Data.Int-import safe Data.Order.Syntax import safe Data.Word-import safe Foreign.C.Types import safe Numeric.Natural-import safe Prelude hiding (Eq(..), Ord(..), Bounded)-import safe qualified Prelude as P--i08c08 :: ConnL Int8 CChar-i08c08 = ConnL CChar $ \(CChar x) -> x--i08w08 :: Conn k Int8 Word8-i08w08 = unsigned--i08int :: ConnL Int8 (Maybe Integer)-i08int = signed--i16c16 :: ConnL Int16 CShort-i16c16 = ConnL CShort $ \(CShort x) -> x--i16w16 :: Conn k Int16 Word16-i16w16 = unsigned+import safe Prelude -i16int :: ConnL Int16 (Maybe Integer)-i16int = signed+-- Int16+w08i16 :: ConnL Word8 (Maybe Int16)+w08i16 = signed -i32c32 :: ConnL Int32 CInt-i32c32 = ConnL CInt $ \(CInt x) -> x+i08i16 :: ConnL Int8 (Maybe Int16)+i08i16 = signed -i32w32 :: Conn k Int32 Word32-i32w32 = unsigned+-- Int32+w08i32 :: ConnL Word8 (Maybe Int32)+w08i32 = signed -i32int :: ConnL Int32 (Maybe Integer)-i32int = signed+w16i32 :: ConnL Word16 (Maybe Int32)+w16i32 = signed -i64c64 :: ConnL Int64 CLong-i64c64 = ConnL CLong $ \(CLong x) -> x+i08i32 :: ConnL Int8 (Maybe Int32)+i08i32 = signed -i64w64 :: Conn k Int64 Word64-i64w64 = unsigned+i16i32 :: ConnL Int16 (Maybe Int32)+i16i32 = signed --- | /Caution/: This assumes that 'Int' on your system is 64 bits.-ixxi64 :: Conn k Int Int64-ixxi64 = Conn fromIntegral fromIntegral fromIntegral+-- Int64+w08i64 :: ConnL Word8 (Maybe Int64)+w08i64 = signed -i64int :: ConnL Int64 (Maybe Integer)-i64int = signed+w16i64 :: ConnL Word16 (Maybe Int64)+w16i64 = signed -ixxwxx :: Conn k Int Word-ixxwxx = unsigned+w32i64 :: ConnL Word32 (Maybe Int64)+w32i64 = signed --- | /Caution/: This assumes that 'Int' on your system is 64 bits.-ixxint :: ConnL Int (Maybe Integer)-ixxint = signed+i08i64 :: ConnL Int8 (Maybe Int64)+i08i64 = signed -intnat :: ConnL Integer Natural-intnat = ConnL (fromIntegral . max 0) fromIntegral+i16i64 :: ConnL Int16 (Maybe Int64)+i16i64 = signed -natint :: ConnL Natural (Maybe Integer)-natint = ConnL (fmap fromIntegral . fromPred (==0)) (maybe 0 $ P.fromInteger . max 0)+i32i64 :: ConnL Int32 (Maybe Int64)+i32i64 = signed -i08i16 :: ConnL Int8 Int16-i08i16 = i08w08 >>> w08w16 >>> w16i16+-- Int+w08ixx :: ConnL Word8 (Maybe Int)+w08ixx = signed -i08i32 :: ConnL Int8 Int32-i08i32 = i08w08 >>> w08w32 >>> w32i32+w16ixx :: ConnL Word16 (Maybe Int)+w16ixx = signed -i08i64 :: ConnL Int8 Int64-i08i64 = i08w08 >>> w08w64 >>> w64i64+w32ixx :: ConnL Word32 (Maybe Int)+w32ixx = signed -i16i32 :: ConnL Int16 Int32-i16i32 = i16w16 >>> w16w32 >>> w32i32+i08ixx :: ConnL Int8 (Maybe Int)+i08ixx = signed -i16i64 :: ConnL Int16 Int64-i16i64 = i16w16 >>> w16w64 >>> w64i64+i16ixx :: ConnL Int16 (Maybe Int)+i16ixx = signed -i32i64 :: ConnL Int32 Int64-i32i64 = i32w32 >>> w32w64 >>> w64i64+i32ixx :: ConnL Int32 (Maybe Int)+i32ixx = signed ------------------------------------------------------------------------- Internal----------------------------------------------------------------------+-- | /Caution/: This assumes that 'Int' on your system is 64 bits.+i64ixx :: Conn k Int64 Int+i64ixx = Conn fromIntegral fromIntegral fromIntegral +-- Integer+w08int :: ConnL Word8 (Maybe Integer)+w08int = signed -fromPred :: Alternative f => (t -> Bool) -> t -> f t-fromPred p a = a <$ guard (p a)+w16int :: ConnL Word16 (Maybe Integer)+w16int = signed -unsigned :: (P.Bounded a, Integral a, Integral b) => Conn k a b-unsigned = Conn f g f where- f y = fromIntegral (y + P.maxBound + 1)- g x = fromIntegral x - P.minBound+w32int :: ConnL Word32 (Maybe Integer)+w32int = signed -signed :: forall a. (P.Bounded a, Integral a) => ConnL a (Maybe Integer)-signed = ConnL f g where- f = fmap fromIntegral . fromPred (==P.minBound)- g = maybe P.minBound $ P.fromInteger . min (fromIntegral @a P.maxBound) . max (fromIntegral @a P.minBound)+w64int :: ConnL Word64 (Maybe Integer)+w64int = signed -{-+wxxint :: ConnL Word (Maybe Integer)+wxxint = signed +natint :: ConnL Natural (Maybe Integer)+natint = ConnL (fmap fromIntegral . fromPred (/= 0)) (maybe 0 $ fromInteger . max 0) -clip08 :: Integer -> Integer-clip08 = min 127 . max (-128)+i08int :: ConnL Int8 (Maybe Integer)+i08int = signed -clip16 :: Integer -> Integer-clip16 = min 32767 . max (-32768)+i16int :: ConnL Int16 (Maybe Integer)+i16int = signed -clip32 :: Integer -> Integer-clip32 = min 2147483647 . max (-2147483648)+i32int :: ConnL Int32 (Maybe Integer)+i32int = signed -clip64 :: Integer -> Integer-clip64 = min 9223372036854775807 . max (-9223372036854775808)+i64int :: ConnL Int64 (Maybe Integer)+i64int = signed -unsigned :: (Bounded a, Preorder b, Integral a, Integral b) => ConnL a b-unsigned = ConnL f g where- f = fromIntegral . max 0- g = fromIntegral . min (f P.maxBound)+ixxint :: ConnL Int (Maybe Integer)+ixxint = signed -signed' :: forall a k. (Bounded a, Integral a) => Conn k a (Extended Integer)-signed' = Conn f g h where- f = liftExtended (~~ P.minBound) (const False) fromIntegral- g = extended P.minBound P.maxBound $ P.fromInteger . min (fromIntegral @a P.maxBound) . max (fromIntegral @a P.minBound)- h = liftExtended (const False) (~~ P.maxBound) fromIntegral--}+---------------------------------------------------------------------+-- Internal+--------------------------------------------------------------------- +fromPred :: (a -> Bool) -> a -> Maybe a+fromPred p a = a <$ guard (p a) +signed :: forall a b. (Bounded a, Integral a, Integral b) => ConnL a (Maybe b)+signed = ConnL f g+ where+ f = fmap fromIntegral . fromPred (/= minBound)+ g = maybe minBound $ fromIntegral @b . min (fromIntegral @a maxBound) . max (fromIntegral @a minBound)
src/Data/Connection/Property.hs view
@@ -1,8 +1,8 @@-{-# Language DataKinds #-}-{-# Language TypeFamilies #-}-{-# Language TypeApplications #-}-{-# Language ConstraintKinds #-}-{-# Language RankNTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} -- | Galois connections have the same properties as adjunctions defined over other categories: --@@ -23,24 +23,22 @@ -- \( \forall x : counit \circ f (x) \sim f (x) \) -- -- \( \forall x : unit \circ g (x) \sim g (x) \)--- module Data.Connection.Property where +import Data.Connection import Data.Order import Data.Order.Property-import Data.Connection-import Data.Connection.Conn-import Prelude hiding (Num(..),Ord(..), floor, ceiling)+import Prelude hiding (Num (..), Ord (..), ceiling, floor) -- | \( \forall x, y : f \dashv g \Rightarrow f (x) \leq y \Leftrightarrow x \leq g (y) \) -- -- A Galois connection is an adjunction of preorders. This is a required property.----adjoint :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool-adjoint t a b = adjointL t a b &&- adjointR t a b &&- adjointL (swapL t) b a &&- adjointR (swapR t) b a+adjoint :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool+adjoint t a b =+ adjointL t a b+ && adjointR t a b+ && adjointL (swapL t) b a+ && adjointR (swapR t) b a adjointL :: (Preorder a, Preorder b) => ConnL a b -> a -> b -> Bool adjointL (ConnL f g) = adjunction (<~) (<~) f g@@ -51,8 +49,7 @@ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.----closed :: (Preorder a, Preorder b) => Trip a b -> a -> Bool+closed :: (Preorder a, Preorder b) => ConnK a b -> a -> Bool closed t a = closedL t a && closedR t a closedL :: (Preorder a, Preorder b) => ConnL a b -> a -> Bool@@ -64,8 +61,7 @@ -- | \( \forall x : f \dashv g \Rightarrow x \leq g \circ f (x) \) -- -- This is a required property.----kernel :: (Preorder a, Preorder b) => Trip a b -> b -> Bool+kernel :: (Preorder a, Preorder b) => ConnK a b -> b -> Bool kernel t b = kernelL t b && kernelR t b kernelL :: (Preorder a, Preorder b) => ConnL a b -> b -> Bool@@ -77,8 +73,7 @@ -- | \( \forall x, y : x \leq y \Rightarrow f (x) \leq f (y) \) -- -- This is a required property.----monotonic :: (Preorder a, Preorder b) => Trip a b -> a -> a -> b -> b -> Bool+monotonic :: (Preorder a, Preorder b) => ConnK a b -> a -> a -> b -> b -> Bool monotonic t a1 a2 b1 b2 = monotonicL t a1 a2 b1 b2 && monotonicR t a1 a2 b1 b2 monotonicR :: (Preorder a, Preorder b) => ConnR a b -> a -> a -> b -> b -> Bool@@ -90,27 +85,24 @@ -- | \( \forall x: f \dashv g \Rightarrow counit \circ f (x) \sim f (x) \wedge unit \circ g (x) \sim g (x) \) -- -- See <https://ncatlab.org/nlab/show/idempotent+adjunction>----idempotent :: (Preorder a, Preorder b) => Trip a b -> a -> b -> Bool+idempotent :: (Preorder a, Preorder b) => ConnK a b -> a -> b -> Bool idempotent t a b = idempotentL t a b && idempotentR t a b idempotentL :: (Preorder a, Preorder b) => ConnL a b -> a -> b -> Bool-idempotentL c@(ConnL f g) a b = projective (~~) g (unitL c) b && projective (~~) f (counitL c) a+idempotentL c@(ConnL f g) a b = projective (~~) g (upper c) b && projective (~~) f (counit c) a idempotentR :: (Preorder a, Preorder b) => ConnR a b -> a -> b -> Bool-idempotentR c@(ConnR f g) a b = projective (~~) g (unitR c) a && projective (~~) f (counitR c) b+idempotentR c@(ConnR f g) a b = projective (~~) g (unit c) a && projective (~~) f (lower c) b --------------------------------------------------------------------- -- Properties of general relations --------------------------------------------------------------------- -- | \( \forall a, b: a \leq b \Rightarrow f(a) \leq f(b) \)--- monotone :: Rel r Bool -> Rel s Bool -> (r -> s) -> r -> r -> Bool monotone (#) (%) f a b = a # b ==> f a % f b -- | \( \forall a, b: a \leq b \Rightarrow f(b) \leq f(a) \)--- antitone :: Rel r Bool -> Rel s Bool -> (r -> s) -> r -> r -> Bool antitone (#) (%) f a b = a # b ==> f b % f a @@ -118,26 +110,15 @@ -- -- For example, a monotone Galois connection is defined by @adjunction (<~) (<~)@, -- and an antitone Galois connection is defined by @adjunction (>~) (<~)@.--- adjunction :: Rel r Bool -> Rel s Bool -> (s -> r) -> (r -> s) -> s -> r -> Bool adjunction (#) (%) f g a b = f a # b <=> a % g b -range' :: Triple () a => (a, a)-range' = (floor (), ceiling ())--ordering :: Trip () Ordering-ordering = trip (const GT) (const ()) (const LT)---extremalOrd :: (Total a, P.Bounded a) => Conn k () a---extremalOrd = Conn (const minBound) (const ()) (const maxBound)- -- | \( \forall a: f (g a) \sim a \)--- invertible :: Rel s b -> (s -> r) -> (r -> s) -> s -> b invertible (#) f g a = g (f a) # a -- | \( \forall a: g \circ f (a) \sim f (a) \) -- -- > idempotent (#) f = projective (#) f f--- projective :: Rel s b -> (r -> s) -> (s -> s) -> r -> b projective (#) f g r = g (f r) # f r
src/Data/Connection/Ratio.hs view
@@ -1,163 +1,158 @@-{-# Language AllowAmbiguousTypes #-}-{-# Language ConstraintKinds #-}-{-# Language Safe #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Connection.Ratio (- Ratio(..) - , reduce- , shiftd- -- * Rational- , ratf32- , ratf64- , rati08- , rati16- , rati32- , rati64- , ratixx- , ratint- -- * Positive- , posw08- , posw16- , posw32- , posw64- , poswxx- , posnat+ Ratio (..),+ reduce,+ shiftd,++ -- * Rational+ ratf32,+ ratf64,+ rati08,+ rati16,+ rati32,+ rati64,+ ratixx,+ ratint,++ -- * Positive+ posw08,+ posw16,+ posw32,+ posw64,+ poswxx,+ posnat, ) where import safe Data.Connection.Conn+import safe qualified Data.Connection.Float as Float import safe Data.Int import safe Data.Order import safe Data.Order.Extended+import safe Data.Order.Syntax import safe Data.Ratio import safe Data.Word-import safe GHC.Real (Ratio(..), Rational)+import safe GHC.Real (Ratio (..), Rational) import safe Numeric.Natural-import safe Prelude hiding (Ord(..), until)+import safe Prelude hiding (Ord (..), until) import safe qualified Prelude as P-import safe qualified Data.Connection.Float as F32-import safe qualified Data.Connection.Double as F64 -- | A total version of 'GHC.Real.reduce'.--- reduce :: Integral a => Ratio a -> Ratio a reduce (x :% 0) = x :% 0 reduce (x :% y) = (x `quot` d) :% (y `quot` d) where d = gcd x y -- | Shift by n 'units of least precision' where the ULP is determined by the denominator--- --- This is an analog of 'Data.Connection.Float.shift' for rationals. --+-- This is an analog of 'Data.Connection.Float.shift32' for rationals. shiftd :: Num a => a -> Ratio a -> Ratio a shiftd n (x :% y) = (n + x) :% y ------------------------------------------------------------------------ Rational+-- Ratio Integer --------------------------------------------------------------------- rati08 :: Conn k Rational (Extended Int8)-rati08 = signedTriple 127+rati08 = signedTriple rati16 :: Conn k Rational (Extended Int16)-rati16 = signedTriple 32767+rati16 = signedTriple rati32 :: Conn k Rational (Extended Int32)-rati32 = signedTriple 2147483647+rati32 = signedTriple rati64 :: Conn k Rational (Extended Int64)-rati64 = signedTriple 9223372036854775807+rati64 = signedTriple ratixx :: Conn k Rational (Extended Int)-ratixx = signedTriple 9223372036854775807+ratixx = signedTriple ratint :: Conn k Rational (Extended Integer)-ratint = Conn f g h where- - f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+ratint = Conn f g h+ where+ f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling - g = extended ninf pinf P.fromIntegral+ g = extended ninf pinf P.fromIntegral - h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+ h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor ratf32 :: Conn k Rational Float-ratf32 = Conn (toFloating f) (fromFloating g) (toFloating h) where- f x = let est = P.fromRational x in --F.fromRat'- if fromFloating g est >~ x- then est- else ascendf est (fromFloating g) x- - g = flip approxRational 0 +ratf32 = Conn (toFloating f) (fromFloating g) (toFloating h)+ where+ f x =+ let est = P.fromRational x+ in if fromFloating g est >~ x+ then est+ else ascendf est (fromFloating g) x - h x = let est = P.fromRational x in- if fromFloating g est <~ x- then est- else descendf est (fromFloating g) x+ g = flip approxRational 0 - ascendf z g1 y = F64.until (\x -> g1 x >~ y) (<~) (F32.shift 1) z+ h x =+ let est = P.fromRational x+ in if fromFloating g est <~ x+ then est+ else descendf est (fromFloating g) x - descendf z f1 x = F64.until (\y -> f1 y <~ x) (>~) (F32.shift (-1)) z+ ascendf z g1 y = Float.until (\x -> g1 x >~ y) (<~) (Float.shift32 1) z + descendf z f1 x = Float.until (\y -> f1 y <~ x) (>~) (Float.shift32 (-1)) z+ ratf64 :: Conn k Rational Double-ratf64 = Conn (toFloating f) (fromFloating g) (toFloating h) where- f x = let est = P.fromRational x in- if fromFloating g est >~ x- then est- else ascendf est (fromFloating g) x- - g = flip approxRational 0 +ratf64 = Conn (toFloating f) (fromFloating g) (toFloating h)+ where+ f x =+ let est = P.fromRational x+ in if fromFloating g est >~ x+ then est+ else ascendf est (fromFloating g) x - h x = let est = P.fromRational x in- if fromFloating g est <~ x- then est- else descendf est (fromFloating g) x+ g = flip approxRational 0 - ascendf z g1 y = F64.until (\x -> g1 x >~ y) (<~) (F64.shift 1) z+ h x =+ let est = P.fromRational x+ in if fromFloating g est <~ x+ then est+ else descendf est (fromFloating g) x - descendf z f1 x = F64.until (\y -> f1 y <~ x) (>~) (F64.shift (-1)) z+ ascendf z g1 y = Float.until (\x -> g1 x >~ y) (<~) (Float.shift64 1) z + descendf z f1 x = Float.until (\y -> f1 y <~ x) (>~) (Float.shift64 (-1)) z+ --------------------------------------------------------------------- -- Ratio Natural --------------------------------------------------------------------- -posw08 :: Conn k Positive (Lowered Word8) -posw08 = unsignedTriple 255+posw08 :: Conn k Positive (Lowered Word8)+posw08 = unsignedTriple -posw16 :: Conn k Positive (Lowered Word16) -posw16 = unsignedTriple 65535+posw16 :: Conn k Positive (Lowered Word16)+posw16 = unsignedTriple -posw32 :: Conn k Positive (Lowered Word32) -posw32 = unsignedTriple 4294967295+posw32 :: Conn k Positive (Lowered Word32)+posw32 = unsignedTriple -posw64 :: Conn k Positive (Lowered Word64) -posw64 = unsignedTriple 18446744073709551615+posw64 :: Conn k Positive (Lowered Word64)+posw64 = unsignedTriple -poswxx :: Conn k Positive (Lowered Word) -poswxx = unsignedTriple 18446744073709551615+poswxx :: Conn k Positive (Lowered Word)+poswxx = unsignedTriple posnat :: Conn k Positive (Lowered Natural)-posnat = Conn f g h where- - f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) P.ceiling+posnat = Conn f g h+ where+ f = liftEitherR (\x -> x ~~ nan || x ~~ pinf) P.ceiling - g = either P.fromIntegral (const pinf)+ g = either P.fromIntegral (const pinf) - h = liftEitherR (~~ pinf) $ \x -> if x ~~ nan then 0 else P.floor x+ h = liftEitherR (~~ pinf) $ \x -> if x ~~ nan then 0 else P.floor x --------------------------------------------------------------------- -- Internal --------------------------------------------------------------------- -{--pabs :: (Lattice a, Eq a, Num a) => a -> a-pabs x = if 0 <~ x then x else negate x--cancel :: (Lattice a, Eq a, Num a) => Ratio a -> Ratio a-cancel (x :% y) = if x < 0 && y < 0 then (pabs x) :% (pabs y) else x :% y---- | An exception-safe version of 'nanf' for rationals.----nanr :: Integral b => (a -> Ratio b) -> Maybe a -> Ratio b-nanr f = maybe (0 :% 0) f--}- pinf :: Num a => Ratio a pinf = 1 :% 0 @@ -167,56 +162,68 @@ nan :: Num a => Ratio a nan = 0 :% 0 -{--intnat :: Conn Integer Natural-intnat = Conn (fromIntegral . max 0) fromIntegral+unsignedTriple :: forall a k. (Bounded a, Integral a) => Conn k Positive (Lowered a)+unsignedTriple = Conn f g h+ where+ f x+ | x ~~ nan = Right maxBound+ | x > high = Right maxBound+ | otherwise = Left $ P.ceiling x -natint :: Conn Natural (Lifted Integer)-natint = Conn (lifts P.fromIntegral) (lifted $ P.fromInteger . max 0)+ g = either P.fromIntegral (const pinf) -ratpos :: Conn k Rational Positive-ratpos = Conn k f g h where- - f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling+ h x+ | x ~~ nan = Left minBound+ | x ~~ pinf = Right maxBound+ | x > high = Left maxBound+ | otherwise = Left $ P.floor x - g = extended minBound maxBound P.fromIntegral+ high = P.fromIntegral @a maxBound - h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor--}+signedTriple :: forall a k. (Bounded a, Integral a) => Conn k Rational (Extended a)+signedTriple = Conn f g h+ where+ f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else P.ceiling x -unsignedTriple :: (Bounded a, Integral a) => Ratio Natural -> Conn k Positive (Lowered a) -unsignedTriple high = Conn f g h where- f x | x ~~ nan = Right maxBound- | x > high = Right maxBound- | otherwise = Left $ P.ceiling x+ g = extended ninf pinf P.fromIntegral - g = either P.fromIntegral (const pinf)+ h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else P.floor x - h x | x ~~ nan = Left minBound- | x ~~ pinf = Right maxBound- | x > high = Left maxBound- | otherwise = Left $ P.floor x+ high = P.fromIntegral @a maxBound+ low = -1 - high -signedTriple :: (Bounded a, Integral a) => Rational -> Conn k Rational (Extended a)-signedTriple high = Conn f g h where+toFloating :: Fractional a => (Rational -> a) -> Rational -> a+toFloating f x+ | x ~~ nan = 0 / 0+ | x ~~ ninf = (-1) / 0+ | x ~~ pinf = 1 / 0+ | otherwise = f x - f = liftExtended (~~ ninf) (\x -> x ~~ nan || x > high) $ \x -> if x < low then minBound else P.ceiling x+fromFloating :: (Order a, Fractional a) => (a -> Rational) -> a -> Rational+fromFloating f x+ | x ~~ 0 / 0 = nan+ | x ~~ (-1) / 0 = ninf+ | x ~~ 1 / 0 = pinf+ | otherwise = f x - g = extended ninf pinf P.fromIntegral- - h = liftExtended (\x -> x ~~ nan || x < low) (~~ pinf) $ \x -> if x > high then maxBound else P.floor x+{-+pabs :: (Lattice a, Eq a, Num a) => a -> a+pabs x = if 0 <~ x then x else negate x - low = -1 - high+cancel :: (Lattice a, Eq a, Num a) => Ratio a -> Ratio a+cancel (x :% y) = if x < 0 && y < 0 then (pabs x) :% (pabs y) else x :% y +-- | An exception-safe version of 'nanf' for rationals.+--+nanr :: Integral b => (a -> Ratio b) -> Maybe a -> Ratio b+nanr f = maybe (0 :% 0) f -toFloating :: (Order (Ratio a), Fractional b, Num a) => (Ratio a -> b) -> Ratio a -> b-toFloating f x | x ~~ nan = 0/0- | x ~~ ninf = (-1)/0- | x ~~ pinf = 1/0- | otherwise = f x+ratpos :: Conn k Rational Positive+ratpos = Conn k f g h where -fromFloating :: (Order a, Eq a, Fractional a, Num b) => (a -> Ratio b) -> a -> Ratio b-fromFloating f x | x ~~ 0/0 = nan- | x ~~ (-1)/0 = ninf- | x ~~ 1/0 = pinf- | otherwise = f x+ f = liftExtended (~~ ninf) (\x -> x ~~ nan || x ~~ pinf) P.ceiling++ g = extended minBound maxBound P.fromIntegral++ h = liftExtended (\x -> x ~~ nan || x ~~ ninf) (~~ pinf) P.floor+-}
src/Data/Connection/Word.hs view
@@ -1,145 +1,185 @@-{-# Language Safe #-}+{-# LANGUAGE Safe #-}+ module Data.Connection.Word (- -- * Bool- c08bin- , binc08- -- * Word8- , w08c08- , w08i08- , w08w16- , w08w32- , w08w64- , w08wxx- , w08nat- -- * Word16- , w16c16- , w16i16- , w16w32- , w16w64- , w16wxx- , w16nat- -- * Word32- , w32c32- , w32i32- , w32w64- , w32wxx- , w32nat- -- * Word64- , w64c64- , w64i64- , w64nat- -- * Word- , wxxw64- , wxxnat+ -- * Word8+ i08w08,++ -- * Word16+ w08w16,+ i08w16,+ i16w16,++ -- * Word32+ w08w32,+ w16w32,+ i08w32,+ i16w32,+ i32w32,++ -- * Word64+ w08w64,+ w16w64,+ w32w64,+ i08w64,+ i16w64,+ i32w64,+ i64w64,+ ixxw64,++ -- * Word+ w08wxx,+ w16wxx,+ w32wxx,+ w64wxx,+ i08wxx,+ i16wxx,+ i32wxx,+ i64wxx,+ ixxwxx,++ -- * Natural+ w08nat,+ w16nat,+ w32nat,+ w64nat,+ wxxnat,+ i08nat,+ i16nat,+ i32nat,+ i64nat,+ ixxnat,+ intnat, ) where import safe Data.Connection.Conn import safe Data.Int-import safe Data.Order-import safe Data.Order.Syntax import safe Data.Word-import safe Foreign.C.Types import safe Numeric.Natural-import safe Prelude hiding (Ord(..), Eq(..)) -c08bin :: ConnL CBool Bool-c08bin = ConnL f g where- f (CBool i) | i == 255 = True- | otherwise = False- - g True = CBool 255- g _ = CBool 254+-- Word8+i08w08 :: ConnL Int8 Word8+i08w08 = unsigned -binc08 :: ConnL Bool CBool-binc08 = ConnL f g where- f False = CBool 0- f _ = CBool 1+-- Word16+w08w16 :: ConnL Word8 Word16+w08w16 = unsigned - g (CBool i) | i == 0 = False- | otherwise = True+i08w16 :: ConnL Int8 Word16+i08w16 = unsigned -w08c08 :: ConnL Word8 CUChar-w08c08 = ConnL CUChar $ \(CUChar x) -> x+i16w16 :: ConnL Int16 Word16+i16w16 = unsigned -w08i08 :: ConnL Word8 Int8-w08i08 = signed+-- Word32+w08w32 :: ConnL Word8 Word32+w08w32 = unsigned -w08nat :: ConnL Word8 Natural-w08nat = unsigned+w16w32 :: ConnL Word16 Word32+w16w32 = unsigned -w08w16 :: ConnL Word8 Word16-w08w16 = unsigned+i08w32 :: ConnL Int8 Word32+i08w32 = unsigned --- w08w32 = w08w16 >>> w16w32-w08w32 :: ConnL Word8 Word32-w08w32 = unsigned+i16w32 :: ConnL Int16 Word32+i16w32 = unsigned --- w08w64 = w08w32 >>> w32w64 = w08w16 >>> w16w64+i32w32 :: ConnL Int32 Word32+i32w32 = unsigned++-- Word64 w08w64 :: ConnL Word8 Word64 w08w64 = unsigned -w08wxx :: ConnL Word8 Word-w08wxx = unsigned+w16w64 :: ConnL Word16 Word64+w16w64 = unsigned -w16c16 :: ConnL Word16 CUShort-w16c16 = ConnL CUShort $ \(CUShort x) -> x+w32w64 :: ConnL Word32 Word64+w32w64 = unsigned -w16i16 :: ConnL Word16 Int16-w16i16 = signed+i08w64 :: ConnL Int8 Word64+i08w64 = unsigned -w16w32 :: ConnL Word16 Word32-w16w32 = unsigned+i16w64 :: ConnL Int16 Word64+i16w64 = unsigned --- w16w64 = w16w32 >>> w32w64-w16w64 :: ConnL Word16 Word64-w16w64 = unsigned+i32w64 :: ConnL Int32 Word64+i32w64 = unsigned +i64w64 :: ConnL Int64 Word64+i64w64 = unsigned++ixxw64 :: ConnL Int Word64+ixxw64 = unsigned++-- Word+w08wxx :: ConnL Word8 Word+w08wxx = unsigned+ w16wxx :: ConnL Word16 Word w16wxx = unsigned -w16nat :: ConnL Word16 Natural-w16nat = unsigned+w32wxx :: ConnL Word32 Word+w32wxx = unsigned -w32c32 :: ConnL Word32 CUInt-w32c32 = ConnL CUInt $ \(CUInt x) -> x+-- | /Caution/: This assumes that 'Word' on your system is 64 bits.+w64wxx :: Conn k Word64 Word+w64wxx = Conn fromIntegral fromIntegral fromIntegral -w32i32 :: ConnL Word32 Int32-w32i32 = signed+i08wxx :: ConnL Int8 Word+i08wxx = unsigned -w32w64 :: ConnL Word32 Word64-w32w64 = unsigned+i16wxx :: ConnL Int16 Word+i16wxx = unsigned -w32wxx :: ConnL Word32 Word-w32wxx = unsigned+i32wxx :: ConnL Int32 Word+i32wxx = unsigned -w32nat :: ConnL Word32 Natural-w32nat = unsigned+i64wxx :: ConnL Int64 Word+i64wxx = unsigned -w64c64 :: ConnL Word64 CULong-w64c64 = ConnL CULong $ \(CULong x) -> x+ixxwxx :: ConnL Int Word+ixxwxx = unsigned -w64i64 :: ConnL Word64 Int64-w64i64 = signed+-- Natural+w08nat :: ConnL Word8 Natural+w08nat = unsigned +w16nat :: ConnL Word16 Natural+w16nat = unsigned++w32nat :: ConnL Word32 Natural+w32nat = unsigned+ w64nat :: ConnL Word64 Natural w64nat = unsigned --- | /Caution/: This assumes that 'Word' on your system is 64 bits.-wxxw64 :: Conn k Word Word64-wxxw64 = Conn fromIntegral fromIntegral fromIntegral---- | /Caution/: This assumes that 'Word' on your system is 64 bits. wxxnat :: ConnL Word Natural-wxxnat = ConnL fromIntegral (fromIntegral . min 18446744073709551615)+wxxnat = unsigned +i08nat :: ConnL Int8 Natural+i08nat = unsigned++i16nat :: ConnL Int16 Natural+i16nat = unsigned++i32nat :: ConnL Int32 Natural+i32nat = unsigned++i64nat :: ConnL Int64 Natural+i64nat = unsigned++ixxnat :: ConnL Int Natural+ixxnat = unsigned++intnat :: ConnL Integer Natural+intnat = ConnL (fromIntegral . max 0) fromIntegral+ --------------------------------------------------------------------- -- Internal ----------------------------------------------------------------------signed :: (Bounded b, Integral a, Integral b) => ConnL a b-signed = ConnL (\x -> fromIntegral x - minBound)- (\y -> fromIntegral (y + maxBound + 1)) -unsigned :: (Bounded a, Preorder b, Integral a, Integral b) => ConnL a b-unsigned = ConnL f g where- f = fromIntegral- g = fromIntegral . min (f maxBound)+unsigned :: (Bounded a, Integral a, Integral b) => ConnL a b+unsigned = ConnL f g+ where+ f = fromIntegral . max 0+ g = fromIntegral . min (f maxBound)
src/Data/Lattice.hs view
@@ -1,121 +1,202 @@-{-# LANGUAGE Safe #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ -- | Lattices & algebras module Data.Lattice (- -- * Types- Lattice- , Semilattice- -- * HeytingL- , type HeytingL- , (\\)- , non- , equiv- , boundary- , booleanL- , heytingL- -- * HeytingR- , type HeytingR- , (//)- , neg- , iff- , middle- , booleanR- , heytingR- -- * Heyting- , (\/)- , (/\)- , glb- , lub- , true- , false- , Heyting(..)- -- * Symmetric- , Biheyting- , Symmetric(..)- , symmetricL- , symmetricR- -- * Boolean- , Boolean(..)+ -- * Semilattice+ Lattice,+ Semilattice (..),++ -- ** Meet+ Meet,+ (/\),+ top,++ -- ** Join+ Join,+ (\/),+ bottom,++ -- * Algebra+ Biheyting,+ Algebra (..),++ -- ** Heyting+ Heyting,+ (//),+ iff,+ neg,+ middle,+ heyting,+ booleanR,++ -- ** Coheyting+ Coheyting,+ (\\),+ equiv,+ non,+ boundary,+ coheyting,+ booleanL,++ -- ** Symmetric+ Symmetric (..),+ converseL,+ converseR,+ symmetricL,+ symmetricR,++ -- ** Boolean+ Boolean (..), ) where -import safe Control.Applicative import safe Data.Bifunctor (bimap) import safe Data.Bool hiding (not)-import safe Data.Connection.Conn import safe Data.Connection.Class+import safe Data.Connection.Conn import safe Data.Either-import safe Data.Functor.Contravariant-import safe Data.Foldable-import safe Data.Order-import safe Data.Order.Extended-import safe Data.Order.Interval-import safe Data.Order.Syntax import safe Data.Int-import safe Data.Maybe-import safe Data.Monoid-import safe Data.Word-import safe GHC.TypeNats---import safe Numeric.Natural-import safe Prelude hiding (Eq(..),Ord(..),Bounded, not) import safe qualified Data.IntMap as IntMap import safe qualified Data.IntSet as IntSet import safe qualified Data.Map as Map-import safe qualified Data.Map.Merge.Lazy as Map+import safe Data.Order+import safe Data.Order.Extended+import safe Data.Order.Syntax import safe qualified Data.Set as Set-import safe qualified Data.Finite as F-import safe qualified Data.Universe.Class as U+import safe Data.Word+import safe Prelude hiding (Eq (..), Ord (..), not) import safe qualified Prelude as P ------------------------------------------------------------------------------- -- Lattices ------------------------------------------------------------------------------- +type Lattice a = (Join a, Meet a)++-- | A convenience alias for a join semilattice+type Join = Semilattice 'L++-- | A convenience alias for a meet semilattice+type Meet = Semilattice 'R+ -- | Bounded < https://ncatlab.org/nlab/show/lattice lattices >. --+-- A lattice is a partially ordered set in which every two elements have a unique join+-- (least upper bound or supremum) and a unique meet (greatest lower bound or infimum).+--+-- A bounded lattice adds unique elements 'top' and 'bottom', which serve as+-- identities to '\/' and '/\', respectively.+-- -- /Neutrality/: ----- The least and greatest elements of a complete /a/ are given by the unique--- upper and lower adjoints to the function /a -> ()/.+-- @+-- x '\/' 'bottom' = x+-- x '/\' 'top' = x+-- 'glb' 'bottom' x 'top' = x+-- 'lub' 'bottom' x 'top' = x+-- @ --+-- /Associativity/+-- -- @--- x '\/' 'false' = x--- x '/\' 'true' = x--- 'glb' 'false' x 'true' = x--- 'lub' 'false' x 'true' = x+-- x '\/' (y '\/' z) = (x '\/' y) '\/' z+-- x '/\' (y '/\' z) = (x '/\' y) '/\' z -- @ ---type Lattice a = (Eq a, Semilattice 'L a, Extremal 'L a, Semilattice 'R a, Extremal 'R a)+-- /Commutativity/+--+-- @+-- x '\/' y = y '\/' x+-- x '/\' y = y '/\' x+-- @+--+-- /Idempotency/+--+-- @+-- x '\/' x = x+-- x '/\' x = x+-- @+--+-- /Absorption/+--+-- @+-- (x '\/' y) '/\' y = y+-- (x '/\' y) '\/' y = y+-- @+--+-- See < https://en.wikipedia.org/wiki/Absorption_law Absorption >.+--+-- Note that distributivity is _not_ a requirement for a complete.+-- However when /a/ is distributive we have:+--+-- @+-- 'glb' x y z = 'lub' x y z+-- @+--+-- See < https://en.wikipedia.org/wiki/Lattice_(order) >.+class Order a => Semilattice (k :: Kan) a where+ -- | The defining connection of a bounded semilattice.+ --+ -- 'bottom' and 'top' are defined by the left and right adjoints to /a -> ()/.+ bounded :: Conn k () a+ default bounded :: Connection k () a => Conn k () a+ bounded = conn + -- | The defining connection of a semilattice.+ --+ -- '\/' and '/\' are defined by the left and right adjoints to /a -> (a, a)/.+ semilattice :: Conn k (a, a) a+ default semilattice :: Connection k (a, a) a => Conn k (a, a) a+ semilattice = conn++infixr 6 /\ -- comment for the parser++-- | Lattice meet.+--+-- > (/\) = curry $ floorWith semilattice+(/\) :: Meet a => a -> a -> a+(/\) = curry $ floorWith semilattice+ -- | The unique top element of a bounded lattice ----- > x /\ true = x--- > x \/ true = true+-- > x /\ top = x+-- > x \/ top = top+top :: Meet a => a+top = floorWith bounded ()++infixr 5 \/++-- | Lattice join. ---true :: Lattice a => a-true = maximal+-- > (\/) = curry $ ceilingWith semilattice+(\/) :: Join a => a -> a -> a+(\/) = curry $ ceilingWith semilattice -- | The unique bottom element of a bounded lattice ----- > x /\ false = false--- > x \/ false = x----false :: Lattice a => a-false = minimal+-- > x /\ bottom = bottom+-- > x \/ bottom = x+bottom :: Join a => a+bottom = ceilingWith bounded () ------------------------------------------------------------------------------- -- Heyting algebras ------------------------------------------------------------------------------- +-- | A convenience alias for a Heyting algebra.+type Heyting a = (Lattice a, Algebra 'R a)++-- | A convenience alias for a < https://ncatlab.org/nlab/show/co-Heyting+algebra co-Heyting algebra >.+type Coheyting a = (Lattice a, Algebra 'L a)+ -- | A < https://ncatlab.org/nlab/show/co-Heyting+algebra bi-Heyting algebra >. -- -- /Laws/:@@ -123,30 +204,21 @@ -- > neg x <= non x -- -- with equality occurring iff /a/ is a 'Boolean' algebra.----type Biheyting a = (HeytingL a, HeytingR a)---- | A convenience alias for a < https://ncatlab.org/nlab/show/co-Heyting+algebra co-Heyting algebra >.----type HeytingL = Heyting 'L---- | A convenience alias for a Heyting algebra.----type HeytingR = Heyting 'R+type Biheyting a = (Coheyting a, Heyting a) --- | Heyting algebras+-- | Heyting and co-Heyting algebras ----- A Heyting algebra is a bounded, distributive complete equipped with an+-- A Heyting algebra is a bounded, distributive lattice equipped with an -- implication operation. ----- * The complete of closed subsets of a trueological space is the primordial--- example of a /HeytingL/ (co-Heyting) algebra.+-- * The complete of closed subsets of a topological space is the primordial+-- example of a /Coheyting/ (co-Algebra) algebra. ----- * The dual complete of open subsets of a trueological space is likewise--- the primordial example of a /HeytingR/ algebra.+-- * The dual complete of open subsets of a topological space is likewise+-- the primordial example of a /Heyting/ algebra. ----- /Heyting 'L/:--- +-- /Coheyting/:+-- -- Co-implication to /a/ is the lower adjoint of disjunction with /a/: -- -- > x \\ a <= y <=> x <= y \/ a@@ -155,12 +227,12 @@ -- -- > EQ /\ non EQ = EQ /\ GT \\ EQ = EQ /\ GT = EQ /= LT ----- See < https://ncatlab.org/nlab/show/co-Heyting+algebra >+-- See < https://ncatlab.org/nlab/show/co-Algebra+algebra > ----- /Heyting 'R/:+-- /Heyting/: -- -- Implication from /a/ is the upper adjoint of conjunction with /a/:--- +-- -- > x <= a // y <=> a /\ x <= y -- -- Similarly, Heyting algebras needn't obey the law of the excluded middle:@@ -168,20 +240,94 @@ -- > EQ \/ neg EQ = EQ \/ EQ // LT = EQ \/ LT = EQ /= GT -- -- See < https://ncatlab.org/nlab/show/Heyting+algebra >----class Lattice a => Heyting k a where- +class Semilattice k a => Algebra k a where -- | The defining connection of a (co-)Heyting algebra. --- -- > heyting @'L x = ConnL (\\ x) (\/ x) - -- > heyting @'R x = ConnR (x /\) (x //)- --- heyting :: a -> Conn k a a+ -- > algebra @'L x = ConnL (\\ x) (\/ x)+ -- > algebra @'R x = ConnR (x /\) (x //)+ algebra :: a -> Conn k a a ---------------------------------------------------------------------------------- HeytingL+-- Heyting ------------------------------------------------------------------------------- +infixr 8 // -- same as ^++-- | Logical implication:+--+-- \( a \Rightarrow b = \vee \{x \mid x \wedge a \leq b \} \)+--+-- /Laws/:+--+-- > x /\ y <= z <=> x <= y // z+-- > x // y <= x // (y \/ z)+-- > x <= y => z // x <= z // y+-- > y <= x // (x /\ y)+-- > x <= y <=> x // y = top+-- > (x \/ z) // y <= x // y+-- > (x /\ y) // z = x // y // z+-- > x // (y /\ z) = x // y /\ x // z+-- > x /\ x // y = x /\ y+--+-- >>> False // False+-- True+-- >>> False // True+-- True+-- >>> True // False+-- False+-- >>> True // True+-- True+(//) :: Algebra 'R a => a -> a -> a+(//) = floorWith . algebra++-- | Intuitionistic equivalence.+--+-- When @a@ is /Bool/ this is 'if-and-only-if'.+iff :: Algebra 'R a => a -> a -> a+iff x y = (x // y) /\ (y // x)++-- | Logical negation.+--+-- @ 'neg' x = x '//' 'bottom' @+--+-- /Laws/:+--+-- > neg bottom = top+-- > neg top = bottom+-- > x <= neg (neg x)+-- > neg (x \/ y) <= neg x+-- > neg (x // y) = neg (neg x) /\ neg y+-- > neg (x \/ y) = neg x /\ neg y+-- > x /\ neg x = bottom+-- > neg (neg (neg x)) = neg x+-- > neg (neg (x \/ neg x)) = top+--+-- Some logics may in addition obey < https://ncatlab.org/nlab/show/De+Morgan+Algebra+algebra De Morgan conditions >.+neg :: Heyting a => a -> a+neg x = x // bottom++-- | The Algebra (< https://ncatlab.org/nlab/show/excluded+middle not necessarily excluded>) middle operator.+middle :: Heyting a => a -> a+middle x = x \/ neg x++-- | Default constructor for a Algebra algebra.+heyting :: Meet a => (a -> a -> a) -> a -> ConnR a a+heyting f a = ConnR (a /\) (a `f`)++-- | An adjunction between a Algebra algebra and its Boolean sub-algebra.+--+-- Double negation is a meet-preserving monad.+booleanR :: Heyting a => ConnR a a+booleanR =+ let -- Check that /x/ is a regular element+ -- See https://ncatlab.org/nlab/show/regular+element+ inj x = if x ~~ (neg . neg) x then x else bottom+ in ConnR (neg . neg) inj++-------------------------------------------------------------------------------+-- Coheyting+-------------------------------------------------------------------------------+ infixl 8 \\ -- | Logical co-implication:@@ -189,12 +335,12 @@ -- \( a \Rightarrow b = \wedge \{x \mid a \leq b \vee x \} \) -- -- /Laws/:--- +-- -- > x \\ y <= z <=> x <= y \/ z -- > x \\ y >= (x /\ z) \\ y -- > x >= y => x \\ z >= y \\ z -- > x >= x \\ y--- > x >= y <=> y \\ x = false+-- > x >= y <=> y \\ x = bottom -- > x \\ (y /\ z) >= x \\ y -- > z \\ (x \/ y) = z \\ x \\ y -- > (y \/ z) \\ x = y \\ x \/ z \\ x@@ -216,147 +362,52 @@ -- fromList [EQ,GT] -- >>> [GT,EQ] \\ [LT] -- fromList [EQ,GT]--- -(\\) :: Heyting 'L a => a -> a -> a-(\\) = flip $ lowerL . heyting+(\\) :: Algebra 'L a => a -> a -> a+(\\) = flip $ ceilingWith . algebra +-- | Intuitionistic co-equivalence.+equiv :: Algebra 'L a => a -> a -> a+equiv x y = (x \\ y) \/ (y \\ x)+ -- | Logical < https://ncatlab.org/nlab/show/co-Heyting+negation co-negation >. ----- @ 'non' x = 'true' '\\' x @+-- @ 'non' x = 'top' '\\' x @ -- -- /Laws/:--- --- > non false = true--- > non true = false+--+-- > non bottom = top+-- > non top = bottom -- > x >= non (non x) -- > non (x /\ y) >= non x -- > non (y \\ x) = non (non x) \/ non y -- > non (x /\ y) = non x \/ non y--- > x \/ non x = true+-- > x \/ non x = top -- > non (non (non x)) = non x--- > non (non (x /\ non x)) = false----non :: Heyting 'L a => a -> a-non x = true \\ x---- | Intuitionistic co-equivalence.----equiv :: Heyting 'L a => a -> a -> a-equiv x y = (x \\ y) \/ (y \\ x)+-- > non (non (x /\ non x)) = bottom+non :: Coheyting a => a -> a+non x = top \\ x --- | The co-Heyting < https://ncatlab.org/nlab/show/co-Heyting+boundary boundary > operator. +-- | The co-Heyting < https://ncatlab.org/nlab/show/co-Heyting+boundary boundary > operator. -- -- > x = boundary x \/ (non . non) x -- > boundary (x /\ y) = (boundary x /\ y) \/ (x /\ boundary y) -- (Leibniz rule) -- > boundary (x \/ y) \/ boundary (x /\ y) = boundary x \/ boundary y----boundary :: Heyting 'L a => a -> a+boundary :: Coheyting a => a -> a boundary x = x /\ non x +-- | Default constructor for a co-Heyting algebra.+coheyting :: Join a => (a -> a -> a) -> a -> ConnL a a+coheyting f a = ConnL (`f` a) (\/ a)+ -- | An adjunction between a co-Heyting algebra and its Boolean sub-algebra. -- -- Double negation is a join-preserving comonad.----booleanL :: Heyting 'L a => Conn 'L a a+booleanL :: Coheyting a => ConnL a a booleanL =- let - -- Check that /x/ is a regular element- -- See https://ncatlab.org/nlab/show/regular+element- inj x = if x == (non . non) x then x else true-- in- ConnL inj (non . non)---- | Default constructor for a co-Heyting algebra.----heytingL :: Lattice a => (a -> a -> a) -> a -> Conn 'L a a-heytingL f a = ConnL (`f` a) (\/ a)------------------------------------------------------------------------------------ HeytingR----------------------------------------------------------------------------------infixr 8 // -- same as ^---- | Logical implication:------ \( a \Rightarrow b = \vee \{x \mid x \wedge a \leq b \} \)------ /Laws/:------ > x /\ y <= z <=> x <= y // z--- > x // y <= x // (y \/ z)--- > x <= y => z // x <= z // y--- > y <= x // (x /\ y)--- > x <= y <=> x // y = true--- > (x \/ z) // y <= x // y--- > (x /\ y) // z = x // y // z--- > x // (y /\ z) = x // y /\ x // z--- > x /\ x // y = x /\ y------ >>> False // False--- True--- >>> False // True--- True--- >>> True // False--- False--- >>> True // True--- True----(//) :: Heyting 'R a => a -> a -> a-(//) x = upperR $ heyting x---- | Logical negation.------ @ 'neg' x = x '//' 'false' @------ /Laws/:------ > neg false = true--- > neg true = false--- > x <= neg (neg x)--- > neg (x \/ y) <= neg x--- > neg (x // y) = neg (neg x) /\ neg y--- > neg (x \/ y) = neg x /\ neg y--- > x /\ neg x = false--- > neg (neg (neg x)) = neg x--- > neg (neg (x \/ neg x)) = true------ Some logics may in addition obey < https://ncatlab.org/nlab/show/De+Morgan+Heyting+algebra De Morgan conditions >.----neg :: Heyting 'R a => a -> a-neg x = x // false---- | Intuitionistic equivalence.------ When /a=Bool/ this is 'if-and-only-if'.----iff :: Heyting 'R a => a -> a -> a-iff x y = (x // y) /\ (y // x)---- | The Heyting (< https://ncatlab.org/nlab/show/excluded+middle not necessarily excluded>) middle operator.----middle :: Heyting 'R a => a -> a-middle x = x \/ neg x---- | An adjunction between a Heyting algebra and its Boolean sub-algebra.------ Double negation is a meet-preserving monad.----booleanR :: Heyting 'R a => Conn 'R a a-booleanR = - let- -- Check that /x/ is a regular element- -- See https://ncatlab.org/nlab/show/regular+element- inj x = if x == (neg . neg) x then x else false-- in - ConnR (neg . neg) inj---- | Default constructor for a Heyting algebra.----heytingR :: Lattice a => (a -> a -> a) -> a -> Conn 'R a a-heytingR f a = ConnR (a /\) (a `f`)+ let -- Check that /x/ is a regular element+ -- See https://ncatlab.org/nlab/show/regular+element+ inj x = if x ~~ (non . non) x then x else top+ in ConnL inj (non . non) ------------------------------------------------------------------------------- -- Symmetric@@ -364,8 +415,8 @@ -- | Symmetric Heyting algebras ----- A symmetric Heyting algebra is a <https://ncatlab.org/nlab/show/De+Morgan+Heyting+algebra De Morgan >--- bi-Heyting algebra with an idempotent, antitone negation operator.+-- A symmetric Heyting algebra is a <https://ncatlab.org/nlab/show/De+Morgan+Algebra+algebra De Morgan >+-- bi-Algebra algebra with an idempotent, antitone negation operator. -- -- /Laws/: --@@ -379,9 +430,7 @@ -- > converseR x <= converseL x -- -- with equality occurring iff /a/ is a 'Boolean' algebra.--- class Biheyting a => Symmetric a where- -- | Symmetric negation. -- -- > not . not = id@@ -394,7 +443,6 @@ -- > non = not . converseR = converseL . not -- > x \\ y = not (not y // not x) -- > x // y = not (not y \\ not x)- -- not :: a -> a infixl 4 `xor`@@ -402,226 +450,254 @@ -- | Exclusive or. -- -- > xor x y = (x \/ y) /\ (not x \/ not y)- -- xor :: a -> a -> a xor x y = (x \/ y) /\ not (x /\ y) - -- | Left converse operator.- -- - converseL :: a -> a- converseL x = true \\ not x-- -- | Right converse operator.- -- - converseR :: a -> a- converseR x = not x // false+-- | Left converse operator.+converseL :: Symmetric a => a -> a+converseL x = top \\ not x --- | Default constructor for a co-Heyting algebra.----symmetricL :: Symmetric a => a -> ConnL a a-symmetricL = heytingL $ \x y -> not (not y // not x)+-- | Right converse operator.+converseR :: Symmetric a => a -> a+converseR x = not x // bottom -- | Default constructor for a Heyting algebra.--- symmetricR :: Symmetric a => a -> ConnR a a-symmetricR = heytingR $ \x y -> not (not y \\ not x)+symmetricR = heyting $ \x y -> not (not y \\ not x) +-- | Default constructor for a co-Heyting algebra.+symmetricL :: Symmetric a => a -> ConnL a a+symmetricL = coheyting $ \x y -> not (not y // not x)+ ------------------------------------------------------------------------------- -- Boolean ------------------------------------------------------------------------------- -- | Boolean algebras. ----- < https://ncatlab.org/nlab/show/Boolean+algebra Boolean algebras > are --- symmetric Heyting algebras that satisfy both the law of excluded middle+-- < https://ncatlab.org/nlab/show/Boolean+algebra Boolean algebras > are+-- symmetric Algebra algebras that satisfy both the law of excluded middle -- and the law of law of non-contradiction: ----- > x \/ neg x = true--- > x /\ non x = false+-- > x \/ neg x = top+-- > x /\ non x = bottom -- -- If /a/ is Boolean we also have: -- -- > non = not = neg--- class Symmetric a => Boolean a where- -- | A witness to the lawfulness of a boolean algebra.- --- boolean :: Trip a a+ boolean :: Conn k a a boolean = Conn (converseR . converseL) id (converseL . converseR) ------------------------------------------------------------------------------- -- Instances ------------------------------------------------------------------------------- --impliesL :: (Total a, P.Bounded a) => a -> a -> a-impliesL x y = if y < x then x else P.minBound--impliesR :: (Total a, P.Bounded a) => a -> a -> a-impliesR x y = if x > y then y else P.maxBound--instance Heyting 'L () where heyting = heytingL impliesL-instance Heyting 'L Bool where heyting = heytingL impliesL-instance Heyting 'L Ordering where heyting = heytingL impliesL-instance Heyting 'L Word8 where heyting = heytingL impliesL-instance Heyting 'L Word16 where heyting = heytingL impliesL-instance Heyting 'L Word32 where heyting = heytingL impliesL-instance Heyting 'L Word64 where heyting = heytingL impliesL-instance Heyting 'L Word where heyting = heytingL impliesL-instance KnownNat n => Heyting 'L (F.Finite n) where heyting = heytingL impliesL--instance Heyting 'R () where heyting = heytingR impliesR-instance Heyting 'R Bool where heyting = heytingR impliesR---instance Heyting 'R Ordering where heyting = heytingR impliesR-instance Heyting 'R Word8 where heyting = heytingR impliesR-instance Heyting 'R Word16 where heyting = heytingR impliesR-instance Heyting 'R Word32 where heyting = heytingR impliesR-instance Heyting 'R Word64 where heyting = heytingR impliesR-instance Heyting 'R Word where heyting = heytingR impliesR-instance KnownNat n => Heyting 'R (F.Finite n) where heyting = heytingR impliesR--instance Heyting 'L Int8 where heyting = heytingL impliesL-instance Heyting 'L Int16 where heyting = heytingL impliesL-instance Heyting 'L Int32 where heyting = heytingL impliesL-instance Heyting 'L Int64 where heyting = heytingL impliesL-instance Heyting 'L Int where heyting = heytingL impliesL-instance Heyting 'R Int8 where heyting = heytingR impliesR-instance Heyting 'R Int16 where heyting = heytingR impliesR-instance Heyting 'R Int32 where heyting = heytingR impliesR-instance Heyting 'R Int64 where heyting = heytingR impliesR-instance Heyting 'R Int where heyting = heytingR impliesR+instance Semilattice k ()+instance Algebra 'L () where algebra = coheyting impliesL+instance Algebra 'R () where algebra = heyting impliesR+instance Symmetric () where not = id+instance Boolean () -instance Symmetric () where not _ = ()+instance Semilattice k Bool+instance Algebra 'L Bool where algebra = coheyting impliesL+instance Algebra 'R Bool where algebra = heyting impliesR instance Symmetric Bool where not = P.not-instance Symmetric Ordering where- not LT = GT- not EQ = EQ- not GT = LT- -instance Heyting 'R Ordering where heyting = symmetricR--instance Boolean () instance Boolean Bool ----------------------------------------------------------------------------------- Instances: sum types--------------------------------------------------------------------------------+instance Semilattice k Ordering+instance Algebra 'L Ordering where algebra = coheyting impliesL+instance Algebra 'R Ordering where algebra = heyting impliesR+instance Symmetric Ordering where+ not LT = GT+ not EQ = EQ+ not GT = LT+instance Boolean Ordering +instance Semilattice k Word8+instance Algebra 'L Word8 where algebra = coheyting impliesL+instance Algebra 'R Word8 where algebra = heyting impliesR +instance Semilattice k Word16+instance Algebra 'L Word16 where algebra = coheyting impliesL+instance Algebra 'R Word16 where algebra = heyting impliesR --- |--- Subdirectly irreducible Heyting algebra.-instance Heyting 'R a => Heyting 'R (Lowered a) where- heyting = heytingR f where+instance Semilattice k Word32+instance Algebra 'L Word32 where algebra = coheyting impliesL+instance Algebra 'R Word32 where algebra = heyting impliesR - (Left a) `f` (Left b) | a <= b = true- | otherwise = Left (a // b)- (Right _) `f` a = a- _ `f` (Right _) = true+instance Semilattice k Word64+instance Algebra 'L Word64 where algebra = coheyting impliesL+instance Algebra 'R Word64 where algebra = heyting impliesR -instance Heyting 'R a => Heyting 'R (Lifted a) where- heyting = heytingR f where- f (Right a) (Right b) = Right (a // b)- f (Left _) _ = Right true- f _ (Left _) = false+instance Semilattice k Word+instance Algebra 'L Word where algebra = coheyting impliesL+instance Algebra 'R Word where algebra = heyting impliesR -instance Heyting 'R a => Heyting 'R (Maybe a) where- heyting = heytingR f where- f (Just a) (Just b) = Just (a // b)- f Nothing _ = Just true- f _ Nothing = Nothing+instance Semilattice k Int8+instance Algebra 'L Int8 where algebra = coheyting impliesL+instance Algebra 'R Int8 where algebra = heyting impliesR ---instance Complete k a => Complete k (Extended a)-instance Heyting 'R a => Heyting 'R (Extended a) where- heyting = heytingR f where+instance Semilattice k Int16+instance Algebra 'L Int16 where algebra = coheyting impliesL+instance Algebra 'R Int16 where algebra = heyting impliesR - Extended a `f` Extended b | a <= b = Top- | otherwise = Extended (a // b)- Top `f` a = a- _ `f` Top = Top- Bottom `f` _ = Top- _ `f` Bottom = Bottom+instance Semilattice k Int32+instance Algebra 'L Int32 where algebra = coheyting impliesL+instance Algebra 'R Int32 where algebra = heyting impliesR ---instance Symmetric a => Symmetric (Extended a) where+instance Semilattice k Int64+instance Algebra 'L Int64 where algebra = coheyting impliesL+instance Algebra 'R Int64 where algebra = heyting impliesR +instance Semilattice k Int+instance Algebra 'L Int where algebra = coheyting impliesL+instance Algebra 'R Int where algebra = heyting impliesR+ ------------------------------------------------------------------------------- -- Instances: product types ------------------------------------------------------------------------------- -instance (Heyting k a, Heyting k b) => Heyting k (a, b) where- heyting (a,b) = heyting a `strong` heyting b+instance (Lattice a, Lattice b) => Semilattice k (a, b) where+ bounded = Conn (const (bottom, bottom)) (const ()) (const (top, top))+ semilattice = Conn (uncurry joinTuple) fork (uncurry meetTuple) +instance (Heyting a, Heyting b) => Algebra 'R (a, b) where+ algebra (a, b) = algebra a `strong` algebra b++instance (Coheyting a, Coheyting b) => Algebra 'L (a, b) where+ algebra (a, b) = algebra a `strong` algebra b+ instance (Symmetric a, Symmetric b) => Symmetric (a, b) where- not = bimap not not+ not = bimap not not -instance (Boolean a, Boolean b) => Boolean (a, b) where+instance (Boolean a, Boolean b) => Boolean (a, b) ---------------------------------------------------------------------------------- Instances: function types+-- Instances: sum types ------------------------------------------------------------------------------- +instance Join a => Semilattice 'L (Maybe a) where+ bounded = ConnL (const Nothing) (const ())+ semilattice = ConnL (uncurry joinMaybe) fork -instance (U.Finite a, Biheyting b) => Heyting 'L (a -> b) where- heyting = heytingL $ liftA2 (\\)+instance Meet a => Semilattice 'R (Maybe a) where+ bounded = ConnR (const ()) (const $ Just top)+ semilattice = ConnR fork (uncurry meetMaybe) -instance (U.Finite a, Biheyting b) => Heyting 'R (a -> b) where- heyting = heytingR $ liftA2 (//)+instance Heyting a => Algebra 'R (Maybe a) where+ algebra = heyting f+ where+ f (Just a) (Just b) = Just (a // b)+ f Nothing _ = Just top+ f _ Nothing = Nothing -instance (U.Finite a, Symmetric b) => Symmetric (a -> b) where not = fmap not+instance Join a => Semilattice 'L (Extended a) where+ bounded = Conn (const Bottom) (const ()) (const Top)+ semilattice = ConnL (uncurry joinExtended) fork -instance (U.Finite a, Boolean b) => Boolean (a -> b)+instance Meet a => Semilattice 'R (Extended a) where+ bounded = Conn (const Bottom) (const ()) (const Top)+ semilattice = ConnR fork (uncurry meetExtended) -deriving via (a -> a) instance (U.Finite a, Biheyting a) => Heyting 'L (Endo a)-deriving via (a -> a) instance (U.Finite a, Biheyting a) => Heyting 'R (Endo a)-instance (U.Finite a, Symmetric a) => Symmetric (Endo a)-instance (U.Finite a, Boolean a) => Boolean (Endo a)+instance Heyting a => Algebra 'R (Extended a) where+ algebra = heyting f+ where+ Extended a `f` Extended b+ | a <~ b = Top+ | otherwise = Extended (a // b)+ Top `f` a = a+ _ `f` Top = Top+ Bottom `f` _ = Top+ _ `f` Bottom = Bottom -deriving via (a -> b) instance (U.Finite a, Biheyting b) => Heyting 'L (Op b a)-deriving via (a -> b) instance (U.Finite a, Biheyting b) => Heyting 'R (Op b a)-instance (U.Finite a, Symmetric b) => Symmetric (Op b a)-instance (U.Finite a, Boolean b) => Boolean (Op b a)+-- | All minimal elements of the upper lattice cover all maximal elements of the lower lattice.+instance (Join a, Join b) => Semilattice 'L (Either a b) where+ bounded = ConnL (const $ Left bottom) (const ())+ semilattice = ConnL (uncurry joinEither) fork -deriving via (Op Bool a) instance (U.Finite a) => Heyting 'L (Predicate a)-deriving via (Op Bool a) instance (U.Finite a) => Heyting 'R (Predicate a)-instance (U.Finite a) => Symmetric (Predicate a)-instance (U.Finite a) => Boolean (Predicate a)+instance (Meet a, Meet b) => Semilattice 'R (Either a b) where+ bounded = ConnR (const ()) (const $ Right top)+ semilattice = ConnR fork (uncurry meetEither) +-- |+-- Subdirectly irreducible Algebra algebra.+instance Heyting a => Algebra 'R (Lowered a) where+ algebra = heyting f+ where+ (Left a) `f` (Left b)+ | a <~ b = top+ | otherwise = Left (a // b)+ (Right _) `f` a = a+ _ `f` (Right _) = top++instance Heyting a => Algebra 'R (Lifted a) where+ algebra = heyting f+ where+ f (Right a) (Right b) = Right (a // b)+ f (Left _) _ = Right top+ f _ (Left _) = bottom+ ------------------------------------------------------------------------------- -- Instances: collections ------------------------------------------------------------------------------- +instance Total a => Semilattice 'L (Set.Set a) -instance (Total a, U.Finite a) => Heyting 'L (Set.Set a) where- heyting = heytingL (Set.\\)+instance Total a => Algebra 'L (Set.Set a) where+ algebra = coheyting (Set.\\) -instance (Total a, U.Finite a) => Heyting 'R (Set.Set a) where- heyting = symmetricR+--instance (Total a, U.Finite a) => Algebra 'R (Set.Set a) where+-- algebra = symmetricR -instance (Total a, U.Finite a) => Symmetric (Set.Set a) where- not = non --(U.universe Set.\\)+--instance (Total a, U.Finite a) => Symmetric (Set.Set a) where+-- not = non --(U.universe Set.\\) -instance (Total a, U.Finite a) => Boolean (Set.Set a) where+--instance (Total a, U.Finite a) => Boolean (Set.Set a) where -instance Heyting 'L IntSet.IntSet where- heyting = heytingL (IntSet.\\)+instance Semilattice 'L IntSet.IntSet -instance Heyting 'R IntSet.IntSet where- --heyting = heytingR $ \x y -> non x \/ y- heyting = symmetricR+instance Algebra 'L IntSet.IntSet where+ algebra = coheyting (IntSet.\\) +{-+instance Algebra 'R IntSet.IntSet where+ --heyting = heyting $ \x y -> non x \/ y+ algebra = symmetricR+ instance Symmetric IntSet.IntSet where not = non --(U.universe IntSet.\\) instance Boolean IntSet.IntSet where +-}++instance (Total k, Join a) => Semilattice 'L (Map.Map k a) where+ bounded = ConnL (const Map.empty) (const ())++ semilattice = ConnL f fork+ where+ f = uncurry $ Map.unionWith (curry $ ceilingWith semilattice)++instance (Total k, Join a) => Algebra 'L (Map.Map k a) where+ algebra = coheyting (Map.\\)++instance (Join a) => Semilattice 'L (IntMap.IntMap a) where+ bounded = ConnL (const IntMap.empty) (const ())++ semilattice = ConnL f fork+ where+ f = uncurry $ IntMap.unionWith (curry $ ceilingWith semilattice)++instance (Join a) => Algebra 'L (IntMap.IntMap a) where+ algebra = coheyting (IntMap.\\)+ {- TODO pick an instance either key-aware or no-instance (Total a, U.Finite a, Lattice b) => Heyting 'L (Map.Map a b) where- heyting = heytingL (Map.\\) -instance (Total a, U.Finite a, Heyting 'R b) => Heyting 'R (Map.Map a b) where+instance (Total a, U.Finite a, Heyting b) => Algebra 'R (Map.Map a b) where - heyting = heytingR $ \a b ->+ algebra = heyting $ \a b -> let x = Map.merge Map.dropMissing -- drop if an element is missing in @b@@@ -634,30 +710,29 @@ -- a @true@ key in Map.union x y-{-+ -- TODO: compare performance impliesMap a b = Map.intersection (`implies`) a b `Map.union` Map.map (const true) (Map.difference b a) `Map.union` Map.fromList [(k, true) | k <- universeF, not (Map.member k a), not (Map.member k b)]--}--} +-} {- -- A symmetric Heyting algebra--- +-- -- λ> implies (False ... True) (False ... True) -- Interval True True -- λ> implies (False ... True) (singleton False) -- Interval False False -- λ> implies (singleton True) (False ... True) -- Interval False True--- +-- -- λ> implies ([EQ,GT] ... [EQ,GT]) ([LT] ... [LT,EQ]) :: Interval (Set.Set Ordering) -- Interval (fromList [LT]) (fromList [LT,EQ])--- +-- -- TODO: may need /a/ to be boolean here. implies :: Symmetric a => Interval a -> Interval a -> Interval a implies i1 i2 = maybe iempty (uncurry (...)) $ liftA2 f (endpts i1) (endpts i2) where@@ -669,11 +744,11 @@ coimplies i1 i2 = not (not i1 `implies` not i2) -- The symmetry--- neg x = true \\ not x--- non x = not x // false+-- neg x = top \\ not x+-- non x = not x // bottom -- λ> not ([LT] ... [LT,GT]) :: Interval (Set.Set Ordering) -- Interval (fromList [EQ]) (fromList [EQ,GT])--- +-- not :: Symmetric a => Interval a -> Interval a not = maybe iempty (\(x1, x2) -> neg x2 ... neg x1) . endpts @@ -681,16 +756,70 @@ -- Interval False False -- λ> (False ... True) `implies` (singleton False) -- Interval False False--- -neg' x = (false ... true) `coimplies` (not x)+--+neg' x = (bottom ... top) `coimplies` (not x) -- λ> non' (False ... True) -- Interval False False -- λ> (singleton True) `coimplies` (False ... True) -- Interval False False--- -non' x = not x `implies` (singleton false)+--+non' x = not x `implies` (singleton bottom) -} +-- Internal +-------------------------+fork :: a -> (a, a)+fork x = (x, x)++impliesL :: (Total a, P.Bounded a) => a -> a -> a+impliesL x y = if y < x then x else P.minBound++impliesR :: (Total a, P.Bounded a) => a -> a -> a+impliesR x y = if x > y then y else P.maxBound++joinTuple :: (Semilattice 'L a, Semilattice 'L b) => (a, b) -> (a, b) -> (a, b)+joinTuple (x1, y1) (x2, y2) = (x1 \/ x2, y1 \/ y2)++meetTuple :: (Semilattice 'R a, Semilattice 'R b) => (a, b) -> (a, b) -> (a, b)+meetTuple (x1, y1) (x2, y2) = (x1 /\ x2, y1 /\ y2)++joinMaybe :: Join a => Maybe a -> Maybe a -> Maybe a+joinMaybe (Just x) (Just y) = Just (x \/ y)+joinMaybe u@(Just _) _ = u+joinMaybe _ u@(Just _) = u+joinMaybe Nothing Nothing = Nothing++meetMaybe :: Meet a => Maybe a -> Maybe a -> Maybe a+meetMaybe Nothing Nothing = Nothing+meetMaybe Nothing _ = Nothing+meetMaybe _ Nothing = Nothing+meetMaybe (Just x) (Just y) = Just (x /\ y)++joinExtended :: Join a => Extended a -> Extended a -> Extended a+joinExtended Top _ = Top+joinExtended _ Top = Top+joinExtended (Extended x) (Extended y) = Extended (x \/ y)+joinExtended Bottom y = y+joinExtended x Bottom = x++meetExtended :: Meet a => Extended a -> Extended a -> Extended a+meetExtended Top y = y+meetExtended x Top = x+meetExtended (Extended x) (Extended y) = Extended (x /\ y)+meetExtended Bottom _ = Bottom+meetExtended _ Bottom = Bottom++joinEither :: (Join a, Join b) => Either a b -> Either a b -> Either a b+joinEither (Right x) (Right y) = Right (x \/ y)+joinEither u@(Right _) _ = u+joinEither _ u@(Right _) = u+joinEither (Left x) (Left y) = Left (x \/ y)++meetEither :: (Meet a, Meet b) => Either a b -> Either a b -> Either a b+meetEither (Left x) (Left y) = Left (x /\ y)+meetEither l@(Left _) _ = l+meetEither _ l@(Left _) = l+meetEither (Right x) (Right y) = Right (x /\ y)
src/Data/Lattice/Property.hs view
@@ -1,178 +1,212 @@-{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+ module Data.Lattice.Property where -import Data.Connection.Conn-import Data.Connection.Property-import Data.Order+import Data.Lattice import Data.Order.Property import Data.Order.Syntax-import Data.Lattice-import Prelude hiding (Eq(..), Ord(..), Bounded, not)+import Prelude hiding (Bounded, Eq (..), Ord (..), not) ---foo x y z = x // y <= x // y /\ z---foo x z y = x /\ z // y <= x // y--- --- x '\\' x = 'true'--- x '/\' (x '\\' y) = x '/\' y--- y '/\' (x '\\' y) = y--- x '\\' (y '\\' z) = (x '/\' y) '\\' z--- x '\\' (y '/\' z) = (x '\\' y) '/\' (x '\\' z)--- 'neg' (x '/\' y) = 'neg' (x '\/' y)--- 'neg' (x '\/' y) = 'neg' x '/\' 'neg' y--- (x '\\' y) '\/' x '<=' y--- y '<=' (x '\\' x '/\' y)--- x '<=' y => (z '\\' x) '<=' (z '\\' y)--- x '<=' y => (x '\\' z) '<=' (y '\\' z)--- x '<=' y <=> x '\\' y '==' 'true'--- x '/\' y '<=' z <=> x '<=' (y '\\' z) <=> y '<=' (x '\\' z)--- ---+coheyting0 :: Coheyting a => a -> a -> a -> Bool+coheyting0 x y z = x \\ y <= z <=> x <= y \/ z +coheyting1 :: Coheyting a => a -> a -> a -> Bool+coheyting1 x y z = x \\ y >= (x /\ z) \\ y --- adjointL $ ConnL (\x -> y \\ not x) (\z -> not z // not y)-symmetric1 x = neg x <= non x-symmetric2 x = (neg . neg) x == (converseR . converseL) x-symmetric3 x = (non . non) x == (converseL . converseR) x-symmetric4 x = non x == (converseL . not) x && neg x == (not . converseL) x-symmetric5 x = non x == (not . converseR) x && neg x == (converseR . not) x-symmetric6 x = neg x \/ neg (neg x) == true-symmetric7 x y = not (x /\ y) == not x \/ not y-symmetric8 x y = (not . not) (x \/ y) == not (not x) \/ not (not y)-symmetric9 x y = not (x \/ y) == not x /\ not y-symmetric10 x y = converseL (x \/ y) == converseL x \/ converseL y-symmetric11 x y = converseR (x /\ y) == converseR x /\ converseR y-symmetric12 x y = converseL (x /\ y) == (non . non) (converseL x /\ converseL y)-symmetric13 x y = converseR (x \/ y) == (neg . neg) (converseR x \/ converseR y)- -boolean0 x = neg x == non x-boolean1 x = neg (neg x) == x-boolean2 x = x \/ neg x == true-boolean3 x = x /\ non x == false -boolean4 x y = (x <= y) // (neg y <= neg x)-boolean5 x y = x \\ y == neg (neg y // neg x)-boolean6 x y = x // y == non (non y \\ non x)+coheyting2 :: Coheyting a => a -> a -> a -> Bool+coheyting2 x y z = x \\ (y /\ z) >= x \\ y +coheyting3 :: Coheyting a => a -> a -> a -> Bool+coheyting3 x y z = x >= y ==> x \\ z >= y \\ z -heytingL0 :: Heyting 'L a => a -> a -> a -> Bool-heytingL0 x y z = x \\ y <= z <=> x <= y \/ z+coheyting4 :: Coheyting a => a -> a -> a -> Bool+coheyting4 x y z = z \\ (x \/ y) == z \\ x \\ y -heytingL1 :: Heyting 'L a => a -> a -> a -> Bool-heytingL1 x y z = x \\ y >= (x /\ z) \\ y+coheyting5 :: Coheyting a => a -> a -> a -> Bool+coheyting5 x y z = (y \/ z) \\ x == y \\ x \/ z \\ x -heytingL2 :: Heyting 'L a => a -> a -> a -> Bool-heytingL2 x y z = x \\ (y /\ z) >= x \\ y+coheyting6 :: Coheyting a => a -> a -> Bool+coheyting6 x y = x >= x \\ y -heytingL3 :: Heyting 'L a => a -> a -> a -> Bool-heytingL3 x y z = x >= y ==> x \\ z >= y \\ z+coheyting7 :: Coheyting a => a -> a -> Bool+coheyting7 x y = x \/ y \\ x == x \/ y -heytingL4 :: Heyting 'L a => a -> a -> a -> Bool-heytingL4 x y z = z \\ (x \/ y) == z \\ x \\ y+coheyting8 :: forall a. Coheyting a => a -> Bool+coheyting8 _ = non bottom == top @a && non top == bottom @a -heytingL5 :: Heyting 'L a => a -> a -> a -> Bool-heytingL5 x y z = (y \/ z) \\ x == y \\ x \/ z \\ x+-- Double co-negation is a co-monad.+coheyting9 :: Coheyting a => a -> a -> Bool+coheyting9 x y = x /\ non y >= x \\ y -heytingL6 :: Heyting 'L a => a -> a -> Bool-heytingL6 x y = x >= x \\ y+coheyting10 :: Coheyting a => a -> a -> Bool+coheyting10 x y = x >= y <=> y \\ x == bottom -heytingL7 :: Heyting 'L a => a -> a -> Bool-heytingL7 x y = x \/ y \\ x == x \/ y+coheyting11 :: Coheyting a => a -> a -> Bool+coheyting11 x y = non (x /\ y) >= non x -heytingL8 :: forall a. Heyting 'L a => a -> Bool-heytingL8 _ = non false == true @a && non true == false @a+coheyting12 :: Coheyting a => a -> a -> Bool+coheyting12 x y = non (y \\ x) == non (non x) \/ non y --- Double co-negation is a co-monad.-heytingL9 :: Heyting 'L a => a -> a -> Bool-heytingL9 x y = x /\ non y >= x \\ y+coheyting13 :: Coheyting a => a -> a -> Bool+coheyting13 x y = non (x /\ y) == non x \/ non y -heytingL10 :: Heyting 'L a => a -> a -> Bool-heytingL10 x y = x >= y <=> y \\ x == false+coheyting14 :: Coheyting a => a -> Bool+coheyting14 x = x \/ non x == top -heytingL11 :: Heyting 'L a => a -> a -> Bool-heytingL11 x y = non (x /\ y) >= non x+coheyting15 :: Coheyting a => a -> Bool+coheyting15 x = non (non (non x)) == non x -heytingL12 :: Heyting 'L a => a -> a -> Bool-heytingL12 x y = non (y \\ x) == non (non x) \/ non y+coheyting16 :: Coheyting a => a -> Bool+coheyting16 x = non (non (x /\ non x)) == bottom -heytingL13 :: Heyting 'L a => a -> a -> Bool-heytingL13 x y = non (x /\ y) == non x \/ non y+coheyting17 :: Coheyting a => a -> Bool+coheyting17 x = x >= non (non x) -heytingL14 :: Heyting 'L a => a -> Bool-heytingL14 x = x \/ non x == true+coheyting18 :: Coheyting c => c -> Bool+coheyting18 x = x == boundary x \/ (non . non) x -heytingL15 :: Heyting 'L a => a -> Bool-heytingL15 x = non (non (non x)) == non x+coheyting19 :: Coheyting a => a -> a -> Bool+coheyting19 x y = boundary (x /\ y) == (boundary x /\ y) \/ (x /\ boundary y) -- (Leibniz rule) -heytingL16 :: Heyting 'L a => a -> Bool-heytingL16 x = non (non (x /\ non x)) == false+coheyting20 :: Coheyting a => a -> a -> Bool+coheyting20 x y = boundary (x \/ y) \/ boundary (x /\ y) == boundary x \/ boundary y -heytingL17 :: Heyting 'L a => a -> Bool-heytingL17 x = x >= non (non x)+heyting0 :: Heyting a => a -> a -> a -> Bool+heyting0 x y z = x /\ y <= z <=> x <= y // z -heytingL18 :: Heyting 'L c => c -> Bool-heytingL18 x = x == boundary x \/ (non . non) x+heyting1 :: Heyting a => a -> a -> a -> Bool+heyting1 x y z = x // y <= x // (y \/ z) -heytingL19 :: Heyting 'L a => a -> a -> Bool-heytingL19 x y = boundary (x /\ y) == (boundary x /\ y) \/ (x /\ boundary y) -- (Leibniz rule)+heyting2 :: Heyting a => a -> a -> a -> Bool+heyting2 x y z = (x \/ z) // y <= x // y -heytingL20 :: Heyting 'L a => a -> a -> Bool-heytingL20 x y = boundary (x \/ y) \/ boundary (x /\ y) == boundary x \/ boundary y+heyting3 :: Heyting a => a -> a -> a -> Bool+heyting3 x y z = x <= y ==> z // x <= z // y +heyting4 :: Heyting a => a -> a -> a -> Bool+heyting4 x y z = (x /\ y) // z == x // y // z -heytingR0 :: Heyting 'R a => a -> a -> a -> Bool-heytingR0 x y z = x /\ y <= z <=> x <= y // z+heyting5 :: Heyting a => a -> a -> a -> Bool+heyting5 x y z = x // (y /\ z) == x // y /\ x // z -heytingR1 :: Heyting 'R a => a -> a -> a -> Bool-heytingR1 x y z = x // y <= x // (y \/ z)+heyting6 :: Heyting a => a -> a -> Bool+heyting6 x y = y <= x // (x /\ y) -heytingR2 :: Heyting 'R a => a -> a -> a -> Bool-heytingR2 x y z = (x \/ z) // y <= x // y+heyting7 :: Heyting a => a -> a -> Bool+heyting7 x y = x /\ x // y == x /\ y -heytingR3 :: Heyting 'R a => a -> a -> a -> Bool-heytingR3 x y z = x <= y ==> z // x <= z // y+heyting8 :: forall a. Heyting a => a -> Bool+heyting8 _ = neg bottom == top @a && neg top == bottom @a -heytingR4 :: Heyting 'R a => a -> a -> a -> Bool-heytingR4 x y z = (x /\ y) // z == x // y // z+-- Double negation is a monad.+heyting9 :: Heyting a => a -> a -> Bool+heyting9 x y = neg x \/ y <= x // y -heytingR5 :: Heyting 'R a => a -> a -> a -> Bool-heytingR5 x y z = x // (y /\ z) == x // y /\ x // z+heyting10 :: Heyting a => a -> a -> Bool+heyting10 x y = x <= y <=> x // y == top -heytingR6 :: Heyting 'R a => a -> a -> Bool-heytingR6 x y = y <= x // (x /\ y)+heyting11 :: Heyting a => a -> a -> Bool+heyting11 x y = neg (x \/ y) <= neg x -heytingR7 :: Heyting 'R a => a -> a -> Bool-heytingR7 x y = x /\ x // y == x /\ y+heyting12 :: Heyting a => a -> a -> Bool+heyting12 x y = neg (x // y) == neg (neg x) /\ neg y -heytingR8 :: forall a. Heyting 'R a => a -> Bool-heytingR8 _ = neg false == true @a && neg true == false @a+heyting13 :: Heyting a => a -> a -> Bool+heyting13 x y = neg (x \/ y) == neg x /\ neg y --- Double negation is a monad.-heytingR9 :: Heyting 'R a => a -> a -> Bool-heytingR9 x y = neg x \/ y <= x // y+heyting14 :: Heyting a => a -> Bool+heyting14 x = x /\ neg x == bottom -heytingR10 :: Heyting 'R a => a -> a -> Bool-heytingR10 x y = x <= y <=> x // y == true+heyting15 :: Heyting a => a -> Bool+heyting15 x = neg (neg (neg x)) == neg x -heytingR11 :: Heyting 'R a => a -> a -> Bool-heytingR11 x y = neg (x \/ y) <= neg x+heyting16 :: Heyting a => a -> Bool+heyting16 x = neg (neg (x \/ neg x)) == top -heytingR12 :: Heyting 'R a => a -> a -> Bool-heytingR12 x y = neg (x // y) == neg (neg x) /\ neg y+heyting17 :: Heyting a => a -> Bool+heyting17 x = x <= neg (neg x) -heytingR13 :: Heyting 'R a => a -> a -> Bool-heytingR13 x y = neg (x \/ y) == neg x /\ neg y+--+-- x '\\' x = 'top'+-- x '/\' (x '\\' y) = x '/\' y+-- y '/\' (x '\\' y) = y+-- x '\\' (y '\\' z) = (x '/\' y) '\\' z+-- x '\\' (y '/\' z) = (x '\\' y) '/\' (x '\\' z)+-- 'neg' (x '/\' y) = 'neg' (x '\/' y)+-- 'neg' (x '\/' y) = 'neg' x '/\' 'neg' y+-- (x '\\' y) '\/' x '<=' y+-- y '<=' (x '\\' x '/\' y)+-- x '<=' y => (z '\\' x) '<=' (z '\\' y)+-- x '<=' y => (x '\\' z) '<=' (y '\\' z)+-- x '<=' y <=> x '\\' y '==' 'top'+-- x '/\' y '<=' z <=> x '<=' (y '\\' z) <=> y '<=' (x '\\' z)+--+-- -heytingR14 :: Heyting 'R a => a -> Bool-heytingR14 x = x /\ neg x == false+-- adjointL $ ConnL (\x -> y \\ not x) (\z -> not z // not y)+symmetric1 :: Biheyting a => a -> Bool+symmetric1 x = neg x <= non x -heytingR15 :: Heyting 'R a => a -> Bool-heytingR15 x = neg (neg (neg x)) == neg x+symmetric2 :: Symmetric a => a -> Bool+symmetric2 x = (neg . neg) x == (converseR . converseL) x -heytingR16 :: Heyting 'R a => a -> Bool-heytingR16 x = neg (neg (x \/ neg x)) == true+symmetric3 :: Symmetric a => a -> Bool+symmetric3 x = (non . non) x == (converseL . converseR) x -heytingR17 :: Heyting 'R a => a -> Bool-heytingR17 x = x <= neg (neg x)+symmetric4 :: Symmetric a => a -> Bool+symmetric4 x = non x == (converseL . not) x && neg x == (not . converseL) x +symmetric5 :: Symmetric a => a -> Bool+symmetric5 x = non x == (not . converseR) x && neg x == (converseR . not) x++symmetric6 :: Heyting a => a -> Bool+symmetric6 x = neg x \/ neg (neg x) == top++symmetric7 :: Symmetric a => a -> a -> Bool+symmetric7 x y = not (x /\ y) == not x \/ not y++symmetric8 :: Symmetric a => a -> a -> Bool+symmetric8 x y = (not . not) (x \/ y) == not (not x) \/ not (not y)++symmetric9 :: Symmetric a => a -> a -> Bool+symmetric9 x y = not (x \/ y) == not x /\ not y++symmetric10 :: Symmetric a => a -> a -> Bool+symmetric10 x y = converseL (x \/ y) == converseL x \/ converseL y++symmetric11 :: Symmetric a => a -> a -> Bool+symmetric11 x y = converseR (x /\ y) == converseR x /\ converseR y++symmetric12 :: Symmetric a => a -> a -> Bool+symmetric12 x y = converseL (x /\ y) == (non . non) (converseL x /\ converseL y)++symmetric13 :: Symmetric a => a -> a -> Bool+symmetric13 x y = converseR (x \/ y) == (neg . neg) (converseR x \/ converseR y)++boolean0 :: Biheyting a => a -> Bool+boolean0 x = neg x == non x++boolean1 :: Heyting a => a -> Bool+boolean1 x = neg (neg x) == x++boolean2 :: Heyting a => a -> Bool+boolean2 x = x \/ neg x == top++boolean3 :: Coheyting a => a -> Bool+boolean3 x = x /\ non x == bottom++boolean4 :: Heyting a => a -> a -> Bool+boolean4 x y = (x <= y) // (neg y <= neg x)++boolean5 :: Biheyting a => a -> a -> Bool+boolean5 x y = x \\ y == neg (neg y // neg x)++boolean6 :: Biheyting a => a -> a -> Bool+boolean6 x y = x // y == non (non y \\ non x)+ {- infix 4 `joinLe` -- | The partial ordering induced by the join-semilattice structure.@@ -237,8 +271,8 @@ -- | \( \forall a \in R: a \/ a = a \) ----- @ 'idempotent_join' = 'absorbative' 'true' @--- +-- @ 'idempotent_join' = 'absorbative' 'top' @+-- -- See < https:\\en.wikipedia.org/wiki/Band_(mathematics) >. -- -- This is a required property.@@ -254,10 +288,10 @@ -- This is a required property. -- associative_join :: Lattice r => r -> r -> r -> Bool-associative_join = associative_on (~~) (\/) +associative_join = associative_on (~~) (\/) associative_join_on :: Semilattice 'L r => Rel r b -> r -> r -> r -> b-associative_join_on (=~) = associative_on (=~) (\/) +associative_join_on (=~) = associative_on (=~) (\/) -- | \( \forall a, b, c: (a \# b) \# c \doteq a \# (b \# c) \) --@@ -272,8 +306,7 @@ commutative_join = commutative_join_on (~~) commutative_join_on :: Semilattice 'L r => Rel r b -> r -> r -> b-commutative_join_on (=~) = commutative_on (=~) (\/) -+commutative_join_on (=~) = commutative_on (=~) (\/) -- | \( \forall a, b: a \# b \doteq b \# a \) --@@ -285,7 +318,7 @@ -- Absorbativity is a generalized form of idempotency: -- -- @--- 'absorbative' 'true' a = a \/ a = a+-- 'absorbative' 'top' a = a \/ a = a -- @ -- -- This is a required property.@@ -298,7 +331,7 @@ -- Absorbativity is a generalized form of idempotency: -- -- @--- 'absorbative'' 'false' a = a \/ a = a+-- 'absorbative'' 'bottom' a = a \/ a = a -- @ -- -- This is a required property.@@ -350,7 +383,6 @@ -- See < https:\\en.wikipedia.org/wiki/Distributivity_(order_theory)#Distributivity_for_semilattices > -- modular :: Lattice r => r -> r -> r -> Bool-modular a b c = a \/ (c /\ b) ~~ (a \/ c) /\ b -+modular a b c = a \/ (c /\ b) ~~ (a \/ c) /\ b -}
src/Data/Order.hs view
@@ -1,60 +1,57 @@-{-# LANGUAGE Safe #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE ConstraintKinds #-}-{-# Language DataKinds #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Data.Order (- -- * Constraint kinds- Order- , Total- -- * Preorders- , Preorder(..)- , pcomparing- -- * DerivingVia- , Base(..), N5(..) - -- * Re-exports- , Ordering(..)- , Down(..)- , Positive+ -- * Constraint kinds+ Order,+ Total,++ -- * Preorders+ Preorder (..),+ pcomparing,++ -- * DerivingVia+ Base (..),+ N5 (..),++ -- * Re-exports+ Ordering (..),+ Down (..),+ Positive, ) where import safe Control.Applicative-import safe Control.Monad.Trans.Select-import safe Control.Monad.Trans.Cont import safe Data.Bool import safe Data.Complex import safe Data.Either-import safe Data.Foldable (foldl')+import safe qualified Data.Eq as Eq import safe Data.Functor.Identity-import safe Data.Functor.Contravariant import safe Data.Int+import safe qualified Data.IntMap as IntMap+import safe qualified Data.IntSet as IntSet import safe Data.List.NonEmpty+import safe qualified Data.Map as Map import safe Data.Maybe-import safe Data.Ord (Down(..))+import safe Data.Ord (Down (..))+import safe qualified Data.Ord as Ord import safe Data.Semigroup-import safe Data.Universe.Class (Finite(..))-import safe Data.Word+import safe qualified Data.Set as Set import safe Data.Void+import safe Data.Word import safe GHC.Real import safe Numeric.Natural-import safe Prelude hiding (Ord(..), Bounded, until)-import safe qualified Data.IntMap as IntMap-import safe qualified Data.IntSet as IntSet-import safe qualified Data.Map as Map-import safe qualified Data.Set as Set-import safe qualified Data.Ord as Ord-import safe qualified Data.Eq as Eq-import safe qualified Data.Finite as F-+import safe Prelude hiding (Bounded, Ord (..), until) -- | An < https://en.wikipedia.org/wiki/Order_theory#Partially_ordered_sets order > on /a/. --@@ -62,17 +59,15 @@ -- -- We instead use a constraint kind in order to retain compatibility with the -- downstream users of /Eq/.--- type Order a = (Eq.Eq a, Preorder a) -- | A < https://en.wikipedia.org/wiki/Total_order total order > on /a/.--- --- Note: ideally this would be a subclass of /PartialOrder/, without instances+--+-- Note: ideally this would be a subclass of /Order/, without instances -- for /Float/, /Double/, /Rational/, etc. -- -- We instead use a constraint kind in order to retain compatibility with the -- downstream users of /Ord/.--- type Total a = (Ord.Ord a, Preorder a) -------------------------------------------------------------------------------@@ -84,7 +79,7 @@ -- A preorder relation '<~' must satisfy the following two axioms: -- -- \( \forall x: x \leq x \) (reflexivity)--- +-- -- \( \forall a, b, c: ((a \leq b) \wedge (b \leq c)) \Rightarrow (a \leq c) \) (transitivity) -- -- Given a preorder on /a/ one may define an equivalence relation '~~' such that@@ -101,25 +96,21 @@ -- -- Minimal complete definition: either 'pcompare' or '<~'. Using 'pcompare' can -- be more efficient for complex types.--- class Preorder a where- {-# MINIMAL (<~) | pcompare #-} + {-# MINIMAL (<~) | pcompare #-} - infix 4 <~, >~, <, >, ?~, ~~, /~, `pcompare`, `pmax`, `pmin`+ infix 4 <~, >~, ?~, ~~, /~, `plt`, `pgt`, `pmax`, `pmin`, `pcompare` -- | A non-strict preorder order relation on /a/. -- -- Is /x/ less than or equal to /y/? --- -- Is /x/ less than or equal to /y/?- -- -- '<~' is reflexive, anti-symmetric, and transitive. -- -- > x <~ y = x < y || x ~~ y -- > x <~ y = maybe False (<~ EQ) (pcompare x y) -- -- for all /x/, /y/ in /a/.- -- (<~) :: a -> a -> Bool x <~ y = maybe False (Ord.<= EQ) (pcompare x y) @@ -127,79 +118,29 @@ -- -- Is /x/ greater than or equal to /y/? --- -- Is /x/ greater than or equal to /y/?- -- -- '>~' is reflexive, anti-symmetric, and transitive. -- -- > x >~ y = x > y || x ~~ y -- > x >~ y = maybe False (>~ EQ) (pcompare x y) -- -- for all /x/, /y/ in /a/.- -- (>~) :: a -> a -> Bool (>~) = flip (<~) - -- | A strict preorder relation on /a/.- --- -- Is /x/ less than /y/?- --- -- Is /x/ less than /y/?- --- -- '<' is irreflexive, asymmetric, and transitive.- --- -- > x < y = x <~ y && not (y <~ x)- -- > x < y = maybe False (< EQ) (pcompare x y)- --- -- When '<~' is antisymmetric then /a/ is a partial - -- order and we have:- -- - -- > x < y = x <~ y && x /~ y- --- -- for all /x/, /y/ in /a/.- --- (<) :: a -> a -> Bool- x < y = maybe False (Ord.< EQ) (pcompare x y)-- -- | A converse strict preorder relation on /a/.- --- -- Is /x/ greater than /y/?- --- -- Is /x/ greater than /y/?- --- -- '>' is irreflexive, asymmetric, and transitive.- --- -- > x > y = x >~ y && not (y >~ x)- -- > x > y = maybe False (> EQ) (pcompare x y)- -- - -- When '<~' is antisymmetric then /a/ is a partial - -- order and we have:- -- - -- > x > y = x >~ y && x /~ y- --- -- for all /x/, /y/ in /a/.- --- (>) :: a -> a -> Bool- (>) = flip (<)-- -- | An equivalence relation on /a/. - --- -- Are /x/ and /y/ comparable?+ -- | An equivalence relation on /a/. -- -- Are /x/ and /y/ comparable? -- -- '?~' is reflexive, symmetric, and transitive. -- -- If /a/ implements 'Ord' then we should have @x ?~ y = True@.- -- (?~) :: a -> a -> Bool x ?~ y = maybe False (const True) (pcompare x y)- + -- | An equivalence relation on /a/. -- -- Are /x/ and /y/ equivalent? --- -- Are /x/ and /y/ equivalent?- -- -- '~~' is reflexive, symmetric, and transitive. -- -- > x ~~ y = x <~ y && y <~ x@@ -207,19 +148,53 @@ -- -- Use this as a lawful substitute for '==' when comparing -- floats, doubles, or rationals.- -- (~~) :: a -> a -> Bool x ~~ y = maybe False (Eq.== EQ) (pcompare x y) -- | Negation of '~~'. -- -- Are /x/ and /y/ not equivalent?- -- (/~) :: a -> a -> Bool x /~ y = not $ x ~~ y- - -- | A similarity relation on /a/. ++ -- | A strict preorder relation on /a/. --+ -- Is /x/ less than /y/?+ --+ -- 'plt' is irreflexive, asymmetric, and transitive.+ --+ -- > x `plt` y = x <~ y && not (y <~ x)+ -- > x `plt` y = maybe False (< EQ) (pcompare x y)+ --+ -- When '<~' is antisymmetric then /a/ is a partial+ -- order and we have:+ --+ -- > x `plt` y = x <~ y && x /~ y+ --+ -- for all /x/, /y/ in /a/.+ plt :: a -> a -> Bool+ plt x y = maybe False (Ord.< EQ) (pcompare x y)++ -- | A converse strict preorder relation on /a/.+ --+ -- Is /x/ greater than /y/?+ --+ -- 'pgt' is irreflexive, asymmetric, and transitive.+ --+ -- > x `pgt` y = x >~ y && not (y >~ x)+ -- > x `pgt` y = maybe False (> EQ) (pcompare x y)+ --+ -- When '<~' is antisymmetric then /a/ is a partial+ -- order and we have:+ --+ -- > x `pgt` y = x >~ y && x /~ y+ --+ -- for all /x/, /y/ in /a/.+ pgt :: a -> a -> Bool+ pgt = flip plt++ -- | A similarity relation on /a/.+ -- -- Are /x/ and /y/ either equivalent or incomparable? -- -- 'similar' is reflexive and symmetric, but not necessarily transitive.@@ -229,10 +204,31 @@ -- > similar (0/0 :: Float) 5 = True -- -- If /a/ implements 'Ord' then we should have @('~~') = 'similar' = ('==')@.- -- similar :: a -> a -> Bool similar x y = maybe True (Eq.== EQ) (pcompare x y) + -- | A partial version of 'Data.Ord.max'.+ --+ -- Returns the left-hand argument in the case of equality.+ pmax :: a -> a -> Maybe a+ pmax x y = do+ o <- pcompare x y+ case o of+ GT -> Just x+ EQ -> Just x+ LT -> Just y++ -- | A partial version of 'Data.Ord.min'.+ --+ -- Returns the left-hand argument in the case of equality.+ pmin :: a -> a -> Maybe a+ pmin x y = do+ o <- pcompare x y+ case o of+ GT -> Just y+ EQ -> Just x+ LT -> Just x+ -- | A partial version of 'Data.Ord.compare'. -- -- > x < y = maybe False (< EQ) $ pcompare x y@@ -242,46 +238,20 @@ -- > x ~~ y = maybe False (~~ EQ) $ pcompare x y -- > x ?~ y = maybe False (const True) $ pcompare x y -- > similar x y = maybe True (~~ EQ) $ pcompare x y- -- - -- If /a/ implements 'Ord' then we should have @'pcompare' x y = 'Just' '$' 'compare' x y@. --+ -- If /a/ implements 'Ord' then we should have @'pcompare' x y = 'Just' '$' 'compare' x y@. pcompare :: a -> a -> Maybe Ordering- pcompare x y - | x <~ y = Just $ if y <~ x then EQ else LT- | y <~ x = Just GT- | otherwise = Nothing-- -- | A partial version of 'Data.Ord.max'. - --- -- Returns the left-hand argument in the case of equality.- --- pmax :: a -> a -> Maybe a- pmax x y = do- o <- pcompare x y- case o of- GT -> Just x- EQ -> Just x- LT -> Just y-- -- | A partial version of 'Data.Ord.min'. - --- -- Returns the left-hand argument in the case of equality.- --- pmin :: a -> a -> Maybe a- pmin x y = do- o <- pcompare x y- case o of- GT -> Just y- EQ -> Just x- LT -> Just x+ pcompare x y+ | x <~ y = Just $ if y <~ x then EQ else LT+ | y <~ x = Just GT+ | otherwise = Nothing -- | A partial version of 'Data.Order.Total.comparing'. -- -- > pcomparing p x y = pcompare (p x) (p y) ----- The partial application /pcomparing f/ induces a lawful preorder for +-- The partial application /pcomparing f/ induces a lawful preorder for -- any total function /f/.--- pcomparing :: Preorder a => (b -> a) -> b -> b -> Maybe Ordering pcomparing p x y = pcompare (p x) (p y) @@ -289,14 +259,14 @@ -- DerivingVia --------------------------------------------------------------------- -newtype Base a = Base { getBase :: a } deriving stock (Eq.Eq, Ord.Ord, Show, Functor)- deriving Applicative via Identity-+newtype Base a = Base {getBase :: a}+ deriving stock (Eq.Eq, Ord.Ord, Show, Functor)+ deriving (Applicative) via Identity instance Ord.Ord a => Preorder (Base a) where- x <~ y = getBase $ liftA2 (Ord.<=) x y- x >~ y = getBase $ liftA2 (Ord.>=) x y- pcompare x y = Just . getBase $ liftA2 Ord.compare x y+ x <~ y = getBase $ liftA2 (Ord.<=) x y+ x >~ y = getBase $ liftA2 (Ord.>=) x y+ pcompare x y = Just . getBase $ liftA2 Ord.compare x y --instance Preorder Void where _ <~ _ = True deriving via (Base Void) instance Preorder Void@@ -316,32 +286,30 @@ deriving via (Base Int32) instance Preorder Int32 deriving via (Base Int64) instance Preorder Int64 deriving via (Base Integer) instance Preorder Integer-deriving via (Base (F.Finite n)) instance Preorder (F.Finite n) --TODO move to Order and derive Preorder as well-newtype N5 a = N5 { getN5 :: a } deriving stock (Eq, Show, Functor)- deriving Applicative via Identity+newtype N5 a = N5 {getN5 :: a}+ deriving stock (Eq, Show, Functor)+ deriving (Applicative) via Identity instance (Ord.Ord a, Fractional a) => Preorder (N5 a) where- x <~ y = getN5 $ liftA2 n5Le x y+ x <~ y = getN5 $ liftA2 n5Le x y -- N5 lattice ordering: NInf <= NaN <= PInf n5Le :: (Ord.Ord a, Fractional a) => a -> a -> Bool-n5Le x y | x Eq./= x && y Eq./= y = True- | x Eq./= x = y == 1/0- | y Eq./= y = x == -1/0- | otherwise = x Ord.<= y+n5Le x y+ | x Eq./= x && y Eq./= y = True+ | x Eq./= x = y == 1 / 0+ | y Eq./= y = x == -1 / 0+ | otherwise = x Ord.<= y deriving via (N5 Float) instance Preorder Float deriving via (N5 Double) instance Preorder Double - --------------------------------------------------------------------- -- Instances --------------------------------------------------------------------- -- -- N5 lattice ordering: NInf <= NaN <= PInf {- pinf = 1 :% 0@@ -358,206 +326,111 @@ Nothing -} pcompareRat :: Rational -> Rational -> Maybe Ordering-pcompareRat (0:%0) (x:%0) = Just $ Ord.compare 0 x-pcompareRat (x:%0) (0:%0) = Just $ Ord.compare x 0-pcompareRat (x:%0) (y:%0) = Just $ Ord.compare (signum x) (signum y)-pcompareRat (0:%0) _ = Nothing-pcompareRat _ (0:%0) = Nothing-pcompareRat _ (x:%0) = Just $ Ord.compare 0 x -- guard against div-by-zero exceptions-pcompareRat (x:%0) _ = Just $ Ord.compare x 0+pcompareRat (0 :% 0) (x :% 0) = Just $ Ord.compare 0 x+pcompareRat (x :% 0) (0 :% 0) = Just $ Ord.compare x 0+pcompareRat (x :% 0) (y :% 0) = Just $ Ord.compare (signum x) (signum y)+pcompareRat (0 :% 0) _ = Nothing+pcompareRat _ (0 :% 0) = Nothing+pcompareRat _ (x :% 0) = Just $ Ord.compare 0 x -- guard against div-by-zero exceptions+pcompareRat (x :% 0) _ = Just $ Ord.compare x 0 pcompareRat x y = Just $ Ord.compare x y -- | Positive rationals, extended with an absorbing zero. -- -- 'Positive' is the canonical < https://en.wikipedia.org/wiki/Semifield#Examples semifield >.--- type Positive = Ratio Natural -- N5 lattice comparison pcomparePos :: Positive -> Positive -> Maybe Ordering-pcomparePos (0:%0) (x:%0) = Just $ Ord.compare 0 x-pcomparePos (x:%0) (0:%0) = Just $ Ord.compare x 0-pcomparePos (_:%0) (_:%0) = Just EQ -- all non-nan infs are equal-pcomparePos (0:%0) (0:%_) = Just $ GT-pcomparePos (0:%_) (0:%0) = Just $ LT-pcomparePos (0:%0) _ = Nothing-pcomparePos _ (0:%0) = Nothing-pcomparePos (x:%y) (x':%y') = Just $ Ord.compare (x*y') (x'*y)+pcomparePos (0 :% 0) (x :% 0) = Just $ Ord.compare 0 x+pcomparePos (x :% 0) (0 :% 0) = Just $ Ord.compare x 0+pcomparePos (_ :% 0) (_ :% 0) = Just EQ -- all non-nan infs are equal+pcomparePos (0 :% 0) (0 :% _) = Just $ GT+pcomparePos (0 :% _) (0 :% 0) = Just $ LT+pcomparePos (0 :% 0) _ = Nothing+pcomparePos _ (0 :% 0) = Nothing+pcomparePos (x :% y) (x' :% y') = Just $ Ord.compare (x * y') (x' * y) instance Preorder Rational where- pcompare = pcompareRat+ pcompare = pcompareRat instance Preorder Positive where- pcompare = pcomparePos+ pcompare = pcomparePos instance (Preorder a, Num a) => Preorder (Complex a) where- pcompare = pcomparing $ \(x :+ y) -> x^2 + y^2+ pcompare = pcomparing $ \(x :+ y) -> x * x + y * y instance Preorder a => Preorder (Down a) where- (Down x) <~ (Down y) = y <~ x- pcompare (Down x) (Down y) = pcompare y x+ (Down x) <~ (Down y) = y <~ x+ pcompare (Down x) (Down y) = pcompare y x instance Preorder a => Preorder (Dual a) where- (Dual x) <~ (Dual y) = y <~ x- pcompare (Dual x) (Dual y) = pcompare y x+ (Dual x) <~ (Dual y) = y <~ x+ pcompare (Dual x) (Dual y) = pcompare y x instance Preorder a => Preorder (Max a) where- Max a <~ Max b = a <~ b+ Max a <~ Max b = a <~ b instance Preorder a => Preorder (Min a) where- Min a <~ Min b = a <~ b+ Min a <~ Min b = a <~ b instance Preorder Any where- Any x <~ Any y = x <~ y+ Any x <~ Any y = x <~ y instance Preorder All where- All x <~ All y = y <~ x+ All x <~ All y = y <~ x instance Preorder a => Preorder (Identity a) where- pcompare (Identity x) (Identity y) = pcompare x y+ pcompare (Identity x) (Identity y) = pcompare x y instance Preorder a => Preorder (Maybe a) where- Nothing <~ _ = True- Just{} <~ Nothing = False- Just a <~ Just b = a <~ b+ Nothing <~ _ = True+ Just{} <~ Nothing = False+ Just a <~ Just b = a <~ b instance Preorder a => Preorder [a] where- {-# SPECIALISE instance Preorder [Char] #-}- --[] <~ _ = True- --(_:_) <~ [] = False- --(x:xs) <~ (y:ys) = x <~ y && xs <~ ys+ {-# SPECIALIZE instance Preorder [Char] #-} - pcompare [] [] = Just EQ- pcompare [] (_:_) = Just LT- pcompare (_:_) [] = Just GT- pcompare (x:xs) (y:ys) = case pcompare x y of- Just EQ -> pcompare xs ys- other -> other+ --[] <~ _ = True+ --(_:_) <~ [] = False+ --(x:xs) <~ (y:ys) = x <~ y && xs <~ ys + pcompare [] [] = Just EQ+ pcompare [] (_ : _) = Just LT+ pcompare (_ : _) [] = Just GT+ pcompare (x : xs) (y : ys) = case pcompare x y of+ Just EQ -> pcompare xs ys+ other -> other+ instance Preorder a => Preorder (NonEmpty a) where- (x :| xs) <~ (y :| ys) = x <~ y && xs <~ ys+ (x :| xs) <~ (y :| ys) = x <~ y && xs <~ ys instance (Preorder a, Preorder b) => Preorder (Either a b) where- Right a <~ Right b = a <~ b- Right _ <~ _ = False-- Left a <~ Left b = a <~ b- Left _ <~ _ = True- -instance (Preorder a, Preorder b) => Preorder (a, b) where - (a,b) <~ (i,j) = a <~ i && b <~ j+ Right a <~ Right b = a <~ b+ Right _ <~ _ = False+ Left a <~ Left b = a <~ b+ Left _ <~ _ = True -instance (Preorder a, Preorder b, Preorder c) => Preorder (a, b, c) where - (a,b,c) <~ (i,j,k) = a <~ i && b <~ j && c <~ k+instance (Preorder a, Preorder b) => Preorder (a, b) where+ (a, b) <~ (i, j) = a <~ i && b <~ j -instance (Preorder a, Preorder b, Preorder c, Preorder d) => Preorder (a, b, c, d) where - (a,b,c,d) <~ (i,j,k,l) = a <~ i && b <~ j && c <~ k && d <~ l+instance (Preorder a, Preorder b, Preorder c) => Preorder (a, b, c) where+ (a, b, c) <~ (i, j, k) = a <~ i && b <~ j && c <~ k -instance (Preorder a, Preorder b, Preorder c, Preorder d, Preorder e) => Preorder (a, b, c, d, e) where - (a,b,c,d,e) <~ (i,j,k,l,m) = a <~ i && b <~ j && c <~ k && d <~ l && e <~ m+instance (Preorder a, Preorder b, Preorder c, Preorder d) => Preorder (a, b, c, d) where+ (a, b, c, d) <~ (i, j, k, l) = a <~ i && b <~ j && c <~ k && d <~ l ---instance (Foldable1 f, Representable f, Preorder a) => Preorder (Co f a) where--- Co f <~ Co g = and $ liftR2 (<~) f g+instance (Preorder a, Preorder b, Preorder c, Preorder d, Preorder e) => Preorder (a, b, c, d, e) where+ (a, b, c, d, e) <~ (i, j, k, l, m) = a <~ i && b <~ j && c <~ k && d <~ l && e <~ m instance (Ord.Ord k, Preorder a) => Preorder (Map.Map k a) where- (<~) = Map.isSubmapOfBy (<~)+ (<~) = Map.isSubmapOfBy (<~) instance Ord.Ord a => Preorder (Set.Set a) where- (<~) = Set.isSubsetOf+ (<~) = Set.isSubsetOf instance Preorder a => Preorder (IntMap.IntMap a) where- (<~) = IntMap.isSubmapOfBy (<~)+ (<~) = IntMap.isSubmapOfBy (<~) instance Preorder IntSet.IntSet where- (<~) = IntSet.isSubsetOf---- | TODO: short-circuiting version.------ >>> const 3 <~ (const 4 :: Int8 -> Int8)--- True--- >>> const 3 <~ (id :: Int8 -> Int8)--- False-instance (Finite a, Preorder b) => Preorder (a -> b) where- pcompare f g = foldl' acc (Just EQ) [f x `pcompare` g x | x <- universeF]- where acc old new = do- m' <- new- n' <- old- case (m', n') of- (x , EQ) -> Just x- (EQ, y ) -> Just y- (x , y ) -> if x == y then Just x else Nothing--instance (Finite a, Preorder a) => Preorder (Endo a) where- pcompare (Endo f) (Endo g) = pcompare f g--instance (Finite a, Preorder b) => Preorder (Op b a) where- --universe = coerce (universe :: [b -> a])- --universe = map Op universe- pcompare (Op f) (Op g) = pcompare f g--instance (Finite a) => Preorder (Predicate a) where- --universe = map (Predicate . flip S.member) universe- --universe = map Op universe- pcompare (Predicate f) (Predicate g) = pcompare f g---- |--- >>> cont ($ 1) == (cont ($ 2) :: Cont Bool Int8)--- False--- >>> cont ($ 1) == (cont ($ 2) :: Cont () Int8)--- True-instance (Total a, Preorder r, Finite r) => Preorder (Cont r a) where- (ContT x) <~ (ContT y) = x `contLe` y--instance (Total a, Preorder r, Finite r) => Preorder (Select r a) where- (SelectT x) <~ (SelectT y) = x `contLe` y--contLe :: forall a b c. (Finite b, Ord.Ord a, Preorder a, Preorder b, Preorder c) => ((a -> b) -> c) -> ((a -> b) -> c) -> Bool-contLe x y = if (universeF :: [b]) ~~ [] then True else point $ counter Map.empty- where- --point :: Preorder b => a -> Bool- point ar = x ar <~ y ar-- --counter :: (Finite b, Ord.Ord a, Preorder c) => Map.Map a b -> a -> b- counter acc a = case Map.lookup a acc of- Just b -> b-- Nothing -> case [b | b <- universeF - , let acc' = Map.insert a b acc- func a' | a' < a = counter acc a'- | otherwise = counter acc' a'- , not . point $ func- ] of- (b:_) -> b- [] -> Prelude.head universeF -- Return a failed counter-example to be pruned by 'point'---{--exm1, exm2, exm3 :: Cont Bool Integer-exm1 = cont $ \ib -> (ib 7 && ib 4) || ib 8-exm2 = cont $ \ib -> (ib 7 || ib 8) && (ib 4 || ib 8)-exm3 = cont $ \ib -> (ib 7 || ib 8) && ib 4---- exm1 ~~ exm2 >~ exm3-ex1 = (exm1 ~~ exm2, exm1 ~~ exm3, exm2 ~~ exm3) --(True, False, False)-ex2 = (exm1 ~~ exm2, exm1 >~ exm3, exm2 >~ exm3) --(True, True, True)-ex3 = (exm1 ~~ exm2 \/ exm3) -- True---- exm2 >~ exm3--- λ> runCont exm2 diff--- True--- λ> runCont exm3 diff--- False-diff :: Integer -> Bool-diff i = if i ~~ 7 || i ~~ 8 then True else False--}-------------------------------------------------------------------------- Orphan Instances------------------------------------------------------------------------instance (Finite a, Eq b) => Eq (a -> b) where- f == g = and [f x == g x | x <- universeF]--deriving via (a -> a) instance (Finite a, Eq a) => Eq (Endo a)-deriving via (a -> b) instance (Finite a, Eq b) => Eq (Op b a)-deriving via (Op Bool a) instance (Finite a) => Eq (Predicate a)+ (<~) = IntSet.isSubsetOf
src/Data/Order/Extended.hs view
@@ -1,25 +1,26 @@-{-# Language Safe #-}-{-# Language DeriveFunctor #-}-{-# Language DeriveGeneric #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE Safe #-} module Data.Order.Extended (- -- * Lattice extensions- type Lifted- , type Lowered- , Extended(..)- , extended- --, retract- -- * Lattice Extensions- , liftMaybe- , liftEitherL- , liftEitherR- , liftExtended+ -- * Lattice extensions+ Lifted,+ Lowered,+ Extended (..),+ extended,+ --, retract++ -- * Lattice Extensions+ liftMaybe,+ liftEitherL,+ liftEitherR,+ liftExtended, ) where import safe Data.Order import safe Data.Order.Syntax import safe GHC.Generics-import safe Prelude hiding (Eq(..), Ord(..),Bounded)+import safe Prelude hiding (Bounded, Eq (..), Ord (..)) type Lifted = Either () @@ -29,21 +30,19 @@ -- -- The top is the absorbing element for the join, and the bottom is the absorbing -- element for the meet.--- data Extended a = Bottom | Extended a | Top- deriving ( Eq, Ord, Show, Generic, Functor, Generic1 )+ deriving (Eq, Ord, Show, Generic, Functor, Generic1) -- | Eliminate an 'Extended'. extended :: b -> b -> (a -> b) -> Extended a -> b-extended b _ _ Bottom = b-extended _ t _ Top = t+extended b _ _ Bottom = b+extended _ t _ Top = t extended _ _ f (Extended x) = f x ------------------------------------------------------------------------------- -- Lattice extensions ------------------------------------------------------------------------------- - {- lifts :: Minimal a => Eq a => (a -> b) -> a -> Lifted b lifts = liftEitherL (== minimal)@@ -55,40 +54,48 @@ lowered f = either f (const maximal) lowers :: Maximal a => Eq a => (a -> b) -> a -> Lowered b-lowers = liftEitherR (== maximal) +lowers = liftEitherR (== maximal) -} liftMaybe :: (a -> Bool) -> (a -> b) -> a -> Maybe b-liftMaybe p f = g where- g i | p i = Nothing- | otherwise = Just $ f i+liftMaybe p f = g+ where+ g i+ | p i = Nothing+ | otherwise = Just $ f i liftEitherL :: (a -> Bool) -> (a -> b) -> a -> Lifted b-liftEitherL p f = g where- g i | p i = Left ()- | otherwise = Right $ f i+liftEitherL p f = g+ where+ g i+ | p i = Left ()+ | otherwise = Right $ f i liftEitherR :: (a -> Bool) -> (a -> b) -> a -> Lowered b-liftEitherR p f = g where- g i | p i = Right ()- | otherwise = Left $ f i+liftEitherR p f = g+ where+ g i+ | p i = Right ()+ | otherwise = Left $ f i liftExtended :: (a -> Bool) -> (a -> Bool) -> (a -> b) -> a -> Extended b-liftExtended p q f = g where- g i | p i = Bottom- | q i = Top- | otherwise = Extended $ f i+liftExtended p q f = g+ where+ g i+ | p i = Bottom+ | q i = Top+ | otherwise = Extended $ f i --------------------------------------------------------------------- -- Instances --------------------------------------------------------------------- instance Preorder a => Preorder (Extended a) where- _ <~ Top = True- Top <~ _ = False- Bottom <~ _ = True- _ <~ Bottom = False- Extended x <~ Extended y = x <~ y+ _ <~ Top = True+ Top <~ _ = False+ Bottom <~ _ = True+ _ <~ Bottom = False+ Extended x <~ Extended y = x <~ y {- instance Universe a => Universe (Extended a) where
src/Data/Order/Interval.hs view
@@ -1,33 +1,21 @@-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE Safe #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE Safe #-} module Data.Order.Interval (- Interval()- , imap- , (...)- , iempty- , singleton- , contains- , endpts- --, above- --, below- --, interval- -- * Floating point intervals- , open32- , open32L- , open32R- , open64- , open64L- , open64R+ Interval (),+ imap,+ (...),+ iempty,+ singleton,+ contains,+ endpts, ) where import safe Data.Bifunctor (bimap)+import safe qualified Data.Eq as Eq import safe Data.Order import safe Data.Order.Syntax-import safe Prelude hiding (Ord(..), Eq(..), Bounded, until)-import safe qualified Data.Eq as Eq-import safe qualified Data.Connection.Float as F32-import safe qualified Data.Connection.Double as F64+import safe Prelude hiding (Bounded, Eq (..), Ord (..), until) --------------------------------------------------------------------- -- Intervals@@ -38,14 +26,12 @@ -- An interval in a poset /P/ is a subset /I/ of /P/ with the following property: -- -- \( \forall x, y \in I, z \in P: x \leq z \leq y \Rightarrow z \in I \)----data Interval a = Empty | Interval !a !a deriving Show+data Interval a = Empty | Interval !a !a deriving (Show) -- | Map over an interval. -- -- /Note/ this is not a functor, as a non-monotonic map -- may cause the interval to collapse to the iempty interval.--- imap :: Preorder b => (a -> b) -> Interval a -> Interval b imap f = maybe iempty (uncurry (...)) . fmap (bimap f f) . endpts @@ -55,19 +41,17 @@ -- -- /Note/: Endpoints are preorder-sorted. If /pcompare x y = Nothing/ -- then the resulting interval will be empty.--- (...) :: Preorder a => a -> a -> Interval a x ... y = case pcompare x y of- Just LT -> Interval x y- Just EQ -> Interval x y- _ -> Empty+ Just LT -> Interval x y+ Just EQ -> Interval x y+ _ -> Empty {-# INLINE (...) #-} -- | The iempty interval. -- -- >>> iempty -- Empty--- iempty :: Interval a iempty = Empty {-# INLINE iempty #-}@@ -76,13 +60,11 @@ -- -- >>> singleton 1 -- 1 ... 1--- singleton :: a -> Interval a singleton a = Interval a a {-# INLINE singleton #-} -- | Obtain the endpoints of an interval.--- endpts :: Interval a -> Maybe (a, a) endpts Empty = Nothing endpts (Interval x y) = Just (x, y)@@ -92,132 +74,21 @@ contains Empty _ = False contains (Interval x y) p = x <~ p && p <~ y -{------ | \( X_\geq(x) = \{ y \in X | y \geq x \} \)------ Construct the upper set of an element /x/.------ This function is monotone:------ > x <~ y <=> above x <~ above y------ by the Yoneda lemma for preorders.----above :: Maximal a => a -> Interval a-above x = x ... maximal-{-# INLINE above #-}---- | \( X_\leq(x) = \{ y \in X | y \leq x \} \)------ Construct the lower set of an element /x/.------ This function is antitone:------ > x <~ y <=> below x >~ below y----below :: Minimal a => a -> Interval a-below x = minimal ... x-{-# INLINE below #-}----}- ------------------------------------------------------------------------ Floating point intervals--------------------------------------------------------------------------- | Construnct an open interval.------ >>> contains 1 $ open32 1 2--- False--- >>> contains 2 $ open32 1 2--- False----open32 :: Float -> Float -> Interval Float-open32 x y = F32.shift 1 x ... F32.shift (-1) y---- | Construnct a half-open interval.------ >>> contains 1 $ open32L 1 2--- False--- >>> contains 2 $ open32L 1 2--- True----open32L :: Float -> Float -> Interval Float-open32L x y = F32.shift 1 x ... y---- | Construnct a half-open interval.------ >>> contains 1 $ open32R 1 2--- True--- >>> contains 2 $ open32R 1 2--- False----open32R :: Float -> Float -> Interval Float-open32R x y = x ... F32.shift (-1) y---- | Construnct an open interval.------ >>> contains 1 $ open64 1 2--- False--- >>> contains 2 $ open64 1 2--- False----open64 :: Double -> Double -> Interval Double-open64 x y = F64.shift 1 x ... F64.shift (-1) y---- | Construnct a half-open interval.------ >>> contains 1 $ open64L 1 2--- False--- >>> contains 2 $ open64L 1 2--- True----open64L :: Double -> Double -> Interval Double-open64L x y = F64.shift 1 x ... y---- | Construnct a half-open interval.------ >>> contains 1 $ open64R 1 2--- True--- >>> contains 2 $ open64R 1 2--- False----open64R :: Double -> Double -> Interval Double-open64R x y = x ... F64.shift (-1) y--{---- | Generate a list of the contents on an interval.------ Returns the list of values in the interval defined by a bounding pair.------ Lawful variant of 'enumFromTo'.----indexFromTo :: Interval Float -> [Float]-indexFromTo i = case endpts i of- Nothing -> []- Just (x, y) -> flip unfoldr x $ \i -> if i ~~ y then Nothing else Just (i, shift 1 i)--}----------------------------------------------------------------------- -- Instances --------------------------------------------------------------------- instance Eq a => Eq (Interval a) where- Empty == Empty = True- Empty == _ = False- _ == Empty = False- Interval x y == Interval x' y' = x == x' && y == y'+ Empty == Empty = True+ Empty == _ = False+ _ == Empty = False+ Interval x y == Interval x' y' = x == x' && y == y' -- | A < https://en.wikipedia.org/wiki/Containment_order containment order >--- instance Preorder a => Preorder (Interval a) where- Empty <~ _ = True- _ <~ Empty = False- Interval x y <~ Interval x' y' = x' <~ x && y <~ y'+ Empty <~ _ = True+ _ <~ Empty = False+ Interval x y <~ Interval x' y' = x' <~ x && y <~ y' {- instance Bounded 'L a => Connection k (Maybe a) (Interval a) where@@ -231,19 +102,15 @@ f = maybe Nothing (Just . uncurry (\/)) . endpts g = maybe iempty singleton h = maybe Nothing (Just . uncurry (/\)) . endpts--} --{- instance Lattice a => Lattice (Interval a) where (\/) = joinInterval (/\) = meetInterval +bottom = Empty+top = bottom ... top joinInterval Empty i = i joinInterval i Empty = i joinInterval (I x y) (I x' y') = I (x /\ x') (y \/ y') -instance Bounded a => Bounded (Interval a) where- bottom = Empty- top = bottom ... top -}
src/Data/Order/Property.hs view
@@ -1,57 +1,65 @@-{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DataKinds #-}+ -- | See <https://en.wikipedia.org/wiki/Binary_relation#Properties>. module Data.Order.Property (- type Rel- , (==>), (<=>)- , xor, xor3- -- * Orders- , preorder- , order- -- ** Non-strict preorders- , antisymmetric_le- , reflexive_le- , transitive_le- , connex_le- -- ** Strict preorders- , asymmetric_lt- , transitive_lt- , irreflexive_lt- , semiconnex_lt- , trichotomous_lt- -- ** Semiorders- , chain_22- , chain_31- -- * Equivalence relations- , symmetric_eq- , reflexive_eq- , transitive_eq- -- * Properties of generic relations- , reflexive- , irreflexive- , coreflexive- , quasireflexive- , transitive- , euclideanL- , euclideanR- , connex- , semiconnex- , trichotomous- , symmetric- , asymmetric- , antisymmetric+ Rel,+ (==>),+ (<=>),+ xor,+ xor3,++ -- * Orders+ preorder,+ order,++ -- ** Non-strict preorders+ antisymmetric_le,+ reflexive_le,+ transitive_le,+ connex_le,++ -- ** Strict preorders+ asymmetric_lt,+ transitive_lt,+ irreflexive_lt,+ semiconnex_lt,+ trichotomous_lt,++ -- ** Semiorders+ chain_22,+ chain_31,++ -- * Equivalence relations+ symmetric_eq,+ reflexive_eq,+ transitive_eq,++ -- * Properties of generic relations+ reflexive,+ irreflexive,+ coreflexive,+ quasireflexive,+ transitive,+ euclideanL,+ euclideanR,+ connex,+ semiconnex,+ trichotomous,+ symmetric,+ asymmetric,+ antisymmetric, ) where -import Data.Connection.Conn+import Data.Lattice hiding (not) import Data.Order import Data.Order.Syntax-import Data.Lattice hiding (not)-import Prelude hiding (Ord(..), Eq(..))+import Prelude hiding (Eq (..), Ord (..)) -- | See <https://en.wikipedia.org/wiki/Binary_relation#Properties>. -- -- Note that these properties do not exhaust all of the possibilities. ----- As an example over the natural numbers, the relation \(a \# b \) defined by +-- As an example over the natural numbers, the relation \(a \# b \) defined by -- \( a > 2 \) is neither symmetric nor antisymmetric, let alone asymmetric. type Rel r b = r -> r -> b @@ -65,38 +73,34 @@ (<=>) :: Bool -> Bool -> Bool (<=>) x y = (x ==> y) && (y ==> x) -- xor3 :: Bool -> Bool -> Bool -> Bool xor3 a b c = (a `xor` (b `xor` c)) && not (a && b && c) -- | Check a 'Preorder' is internally consistent. -- -- This is a required property.--- preorder :: Preorder r => r -> r -> Bool-preorder x y = - ((x <~ y) == le x y) &&- ((x >~ y) == ge x y) &&- ((x ?~ y) == cp x y) &&- ((x ~~ y) == eq x y) &&- ((x /~ y) == ne x y) &&- ((x < y) == lt x y) &&- ((x > y) == gt x y) &&- (similar x y == sm x y) &&- (pcompare x y == pcmp x y)-+preorder x y =+ ((x <~ y) == le x y)+ && ((x >~ y) == ge x y)+ && ((x ?~ y) == cp x y)+ && ((x ~~ y) == eq x y)+ && ((x /~ y) == ne x y)+ && ((x < y) == lt x y)+ && ((x > y) == gt x y)+ && (similar x y == sm x y)+ && (pcompare x y == pcmp x y) where le x1 y1 = x1 < y1 || x1 ~~ y1 ge = flip le- + cp x1 y1 = x1 <~ y1 || x1 >~ y1 eq x1 y1 = x1 <~ y1 && x1 >~ y1 ne x1 y1 = not $ eq x1 y1- + lt x1 y1 = x1 <~ y1 && x1 /~ y1 gt = flip lt@@ -104,22 +108,19 @@ sm x1 y1 = not (x1 < y1) && not (x1 > y1) pcmp x1 y1- | x1 <~ y1 = Just $ if y1 <~ x1 then EQ else LT- | y1 <~ x1 = Just GT- | otherwise = Nothing-+ | x1 <~ y1 = Just $ if y1 <~ x1 then EQ else LT+ | y1 <~ x1 = Just GT+ | otherwise = Nothing -- | Check that an 'Order' is internally consistent. -- -- This is a required property.--- order :: Order r => r -> r -> Bool-order x y = - ((x <= y) == le x y) &&- ((x >= y) == ge x y) &&- ((x == y) == eq x y) &&- ((x /= y) == ne x y)-+order x y =+ ((x <= y) == le x y)+ && ((x >= y) == ge x y)+ && ((x == y) == eq x y)+ && ((x /= y) == ne x y) where le x1 y1 = maybe False (<~ EQ) $ pcompare x1 y1 @@ -138,7 +139,6 @@ -- '<~' is an antisymmetric relation. -- -- This is a required property.--- antisymmetric_le :: Preorder r => r -> r -> Bool antisymmetric_le = antisymmetric (~~) (<~) @@ -147,23 +147,20 @@ -- '<~' is a reflexive relation. -- -- This is a required property.----reflexive_le :: Preorder r => r -> Bool-reflexive_le = reflexive (<~) +reflexive_le :: Preorder r => r -> Bool+reflexive_le = reflexive (<~) -- | \( \forall a, b, c: ((a \leq b) \wedge (b \leq c)) \Rightarrow (a \leq c) \) -- -- '<~' is an transitive relation. -- -- This is a required property.--- transitive_le :: Preorder r => r -> r -> r -> Bool transitive_le = transitive (<~) -- | \( \forall a, b: ((a \leq b) \vee (b \leq a)) \) -- -- '<~' is a connex relation.--- connex_le :: Preorder r => r -> r -> Bool connex_le = connex (<~) @@ -176,7 +173,6 @@ -- 'lt' is an asymmetric relation. -- -- This is a required property.--- asymmetric_lt :: Preorder r => r -> r -> Bool asymmetric_lt = asymmetric (<) @@ -185,23 +181,20 @@ -- 'lt' is an irreflexive relation. -- -- This is a required property.----irreflexive_lt :: Preorder r => r -> Bool-irreflexive_lt = irreflexive (<) +irreflexive_lt :: Preorder r => r -> Bool+irreflexive_lt = irreflexive (<) -- | \( \forall a, b, c: ((a \lt b) \wedge (b \lt c)) \Rightarrow (a \lt c) \) -- -- 'lt' is a transitive relation. -- -- This is a required property.--- transitive_lt :: Preorder r => r -> r -> r -> Bool transitive_lt = transitive (<) -- | \( \forall a, b: \neg (a = b) \Rightarrow ((a \lt b) \vee (b \lt a)) \) -- -- 'lt' is a semiconnex relation.--- semiconnex_lt :: Preorder r => r -> r -> Bool semiconnex_lt = semiconnex (~~) (<) @@ -210,7 +203,6 @@ -- In other words, exactly one of \(a \lt b\), \(a = b\), or \(b \lt a\) holds. -- -- If 'lt' is a trichotomous relation then the set is totally ordered.--- trichotomous_lt :: Preorder r => r -> r -> Bool trichotomous_lt = trichotomous (~~) (<) @@ -218,10 +210,9 @@ -- Semiorders --------------------------------------------------------------------- --- | \( \forall x, y, z, w: x \lt y \wedge y \sim z \wedge z \lt w \Rightarrow x \lt w \) +-- | \( \forall x, y, z, w: x \lt y \wedge y \sim z \wedge z \lt w \Rightarrow x \lt w \) -- -- A < https://en.wikipedia.org/wiki/Semiorder semiorder > does not allow 2-2 chains.--- chain_22 :: Preorder r => r -> r -> r -> r -> Bool chain_22 x y z w = x < y && similar y z && z < w ==> x < w @@ -229,7 +220,7 @@ -- -- A < https://en.wikipedia.org/wiki/Semiorder semiorder > does not allow 3-1 chains. ----- /Note/: This library models floats, doubles, rationals etc +-- /Note/: This library models floats, doubles, rationals etc -- as < https://en.wikipedia.org/wiki/Modular_lattice#Examples N5 > lattices, -- which do not possess the 3-1 chain property and are not semiorders. --@@ -245,7 +236,6 @@ -- '~~' is a symmetric relation. -- -- This is a required property.--- symmetric_eq :: Preorder r => r -> r -> Bool symmetric_eq = symmetric (~~) @@ -254,16 +244,14 @@ -- '~~' is a reflexive relation. -- -- This is a required property----reflexive_eq :: Preorder r => r -> Bool-reflexive_eq = reflexive (~~) +reflexive_eq :: Preorder r => r -> Bool+reflexive_eq = reflexive (~~) -- | \( \forall a, b, c: ((a = b) \wedge (b = c)) \Rightarrow (a = c) \) -- -- '~~' is a transitive relation. -- -- This is a required property.--- transitive_eq :: Preorder r => r -> r -> r -> Bool transitive_eq = transitive (~~) @@ -274,59 +262,51 @@ -- | \( \forall a: (a \# a) \) -- -- For example, ≥ is a reflexive relation but > is not.--- reflexive :: Rel r b -> r -> b-reflexive (#) a = a # a +reflexive (#) a = a # a -- | \( \forall a: \neg (a \# a) \) -- -- For example, > is an irreflexive relation, but ≥ is not.--- irreflexive :: Rel r Bool -> r -> Bool irreflexive (#) a = not $ a # a -- | \( \forall a, b: ((a \# b) \wedge (b \# a)) \Rightarrow (a \equiv b) \) ----- For example, the relation over the integers in which each odd number is --- related to itself is a coreflexive relation. The equality relation is the --- only example of a relation that is both reflexive and coreflexive, and any +-- For example, the relation over the integers in which each odd number is+-- related to itself is a coreflexive relation. The equality relation is the+-- only example of a relation that is both reflexive and coreflexive, and any -- coreflexive relation is a subset of the equality relation.--- coreflexive :: Rel r Bool -> Rel r Bool -> r -> r -> Bool coreflexive (%) (#) a b = (a # b) && (b # a) ==> (a % b) -- | \( \forall a, b: (a \# b) \Rightarrow ((a \# a) \wedge (b \# b)) \)--- quasireflexive :: Rel r Bool -> r -> r -> Bool quasireflexive (#) a b = (a # b) ==> (a # a) && (b # b) -- | \( \forall a, b, c: ((a \# b) \wedge (a \# c)) \Rightarrow (b \# c) \) -- -- For example, /=/ is a right Euclidean relation because if /x = y/ and /x = z/ then /y = z/.--- euclideanR :: Rel r Bool -> r -> r -> r -> Bool euclideanR (#) a b c = (a # b) && (a # c) ==> b # c -- | \( \forall a, b, c: ((b \# a) \wedge (c \# a)) \Rightarrow (b \# c) \) -- -- For example, /=/ is a left Euclidean relation because if /x = y/ and /x = z/ then /y = z/.--- euclideanL :: Rel r Bool -> r -> Rel r Bool euclideanL (#) a b c = (b # a) && (c # a) ==> b # c -- | \( \forall a, b, c: ((a \# b) \wedge (b \# c)) \Rightarrow (a \# c) \) -- -- For example, "is ancestor of" is a transitive relation, while "is parent of" is not.--- transitive :: Rel r Bool -> r -> r -> r -> Bool transitive (#) a b c = (a # b) && (b # c) ==> a # c -- | \( \forall a, b: ((a \# b) \vee (b \# a)) \) -- -- For example, ≥ is a connex relation, while 'divides evenly' is not.--- --- A connex relation cannot be symmetric, except for the universal relation. --+-- A connex relation cannot be symmetric, except for the universal relation. connex :: Rel r Bool -> r -> r -> Bool connex (#) a b = (a # b) || (b # a) @@ -335,26 +315,23 @@ -- A binary relation is semiconnex if it relates all pairs of _distinct_ elements in some way. -- -- A relation is connex if and only if it is semiconnex and reflexive.--- semiconnex :: Rel r Bool -> Rel r Bool -> r -> r -> Bool semiconnex (%) (#) a b = not (a % b) ==> connex (#) a b -- | \( \forall a, b, c: ((a \# b) \vee (a \doteq b) \vee (b \# a)) \wedge \neg ((a \# b) \wedge (a \doteq b) \wedge (b \# a)) \) -- -- In other words, exactly one of \(a \# b\), \(a \doteq b\), or \(b \# a\) holds.--- +-- -- For example, > is a trichotomous relation, while ≥ is not. -- -- Note that @ trichotomous (>) @ should hold for any 'Ord' instance.--- trichotomous :: Rel r Bool -> Rel r Bool -> r -> r -> Bool trichotomous (%) (#) a b = xor3 (a # b) (a % b) (b # a) -- | \( \forall a, b: (a \# b) \Leftrightarrow (b \# a) \) ----- For example, "is a blood relative of" is a symmetric relation, because +-- For example, "is a blood relative of" is a symmetric relation, because -- A is a blood relative of B if and only if B is a blood relative of A.--- symmetric :: Rel r Bool -> r -> r -> Bool symmetric (#) a b = (a # b) <=> (b # a) @@ -363,14 +340,12 @@ -- For example, > is an asymmetric relation, but ≥ is not. -- -- A relation is asymmetric if and only if it is both antisymmetric and irreflexive.--- asymmetric :: Rel r Bool -> r -> r -> Bool asymmetric (#) a b = (a # b) ==> not (b # a) -- | \( \forall a, b: (a \# b) \wedge (b \# a) \Rightarrow a \equiv b \) ----- For example, ≥ is an antisymmetric relation; so is >, but vacuously +-- For example, ≥ is an antisymmetric relation; so is >, but vacuously -- (the condition in the definition is always false).--- antisymmetric :: Rel r Bool -> Rel r Bool -> r -> r -> Bool antisymmetric (%) (#) a b = (a # b) && (b # a) ==> (a % b)
src/Data/Order/Syntax.hs view
@@ -1,37 +1,83 @@-{-# LANGUAGE Safe #-} {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE Safe #-}+ -- | Utilities for custom preludes and RebindableSyntax. module Data.Order.Syntax (- -- * Partial orders- Order- , (==),(/=)- , (<=),(>=)- -- * Total orders- , Total- , min ,max- , compare- , comparing- -- * Re-exports- , Eq.Eq()- , Ord.Ord()+ -- * Preorders+ (<),+ (>),++ -- * Partial orders+ Order,+ (==),+ (/=),+ (<=),+ (>=),++ -- * Total orders+ Total,+ min,+ max,+ compare,+ comparing,++ -- * Re-exports+ Eq.Eq (),+ Ord.Ord (), ) where import safe Control.Exception-import safe Data.Order import safe qualified Data.Eq as Eq import safe qualified Data.Ord as Ord+import safe Data.Order -import Prelude hiding (Eq(..),Ord(..))+import Prelude hiding (Eq (..), Ord (..)) +infix 4 <, >++-- | A strict preorder relation on /a/.+--+-- Is /x/ less than /y/?+--+-- '<' is irreflexive, asymmetric, and transitive.+--+-- > x < y = x <~ y && not (y <~ x)+-- > x < y = maybe False (< EQ) (pcompare x y)+--+-- When '<~' is antisymmetric then /a/ is a partial+-- order and we have:+--+-- > x < y = x <~ y && x /~ y+--+-- for all /x/, /y/ in /a/.+(<) :: Preorder a => a -> a -> Bool+(<) = plt++-- | A converse strict preorder relation on /a/.+--+-- Is /x/ greater than /y/?+--+-- '>' is irreflexive, asymmetric, and transitive.+--+-- > x > y = x >~ y && not (y >~ x)+-- > x > y = maybe False (> EQ) (pcompare x y)+--+-- When '<~' is antisymmetric then /a/ is a partial+-- order and we have:+--+-- > x > y = x >~ y && x /~ y+--+-- for all /x/, /y/ in /a/.+(>) :: Preorder a => a -> a -> Bool+(>) = flip (<)+ ------------------------------------------------------------------------------- -- Partial orders ------------------------------------------------------------------------------- - infix 4 ==, /=, <=, >= -- | A wrapper around /==/ that forces /NaN == NaN/.--- (==) :: Eq.Eq a => a -> a -> Bool (==) x y = if x Eq./= x && y Eq./= y then True else x Eq.== y @@ -48,7 +94,6 @@ -- Total orders ------------------------------------------------------------------------------- - infix 4 `min`, `max`, `compare`, `comparing` -- | Find the minimum of two values.@@ -57,11 +102,10 @@ -- -- /Note/: this function will throw a /ArithException/ on floats and rationals -- if one of the arguments is finite and the other is /NaN/.--- min :: Total a => a -> a -> a min x y = case compare x y of- GT -> y- _ -> x+ GT -> y+ _ -> x -- | Find the minimum of two values. --@@ -69,11 +113,10 @@ -- -- /Note/: this function will throw a /ArithException/ on floats and rationals -- if one of the arguments is finite and the other is /NaN/.--- max :: Total a => a -> a -> a max x y = case compare x y of- LT -> y- _ -> x+ LT -> y+ _ -> x -- | Compare two values in a total order. --@@ -95,15 +138,13 @@ -- -- >>> compare (0/0 :: Double) 0 -- *** Exception: divide by zero--- compare :: Total a => a -> a -> Ordering compare x y = case pcompare x y of- Just o -> o- Nothing -> throw DivideByZero+ Just o -> o+ Nothing -> throw DivideByZero -- | Compare on the range of a function. -- -- > comparing p x y = compare (p x) (p y)--- comparing :: Total a => (b -> a) -> b -> b -> Ordering comparing p x y = compare (p x) (p y)
test/Test/Data/Connection.hs view
@@ -9,6 +9,7 @@ import Data.Connection.Ratio import Data.Foldable import Data.Lattice+import Data.Int import Data.Word import Data.Order import Data.Order.Extended@@ -16,7 +17,7 @@ import GHC.Real hiding (Fractional(..), (^^), (^), div) import Hedgehog import Numeric.Natural-import Prelude hiding (Eq(..),Ord(..),Bounded)+import Prelude hiding (Eq(..),Ord(..)) import qualified Hedgehog.Gen as G import qualified Hedgehog.Range as R import Data.Connection.Property as Prop@@ -24,8 +25,8 @@ import Data.Order.Property import Data.Order.Syntax -ri :: (Integral a, Lattice a) => Range a-ri = R.linearFrom 0 false true+ri :: (Integral a, Bounded a) => Range a+ri = R.linearFrom 0 minBound maxBound ri' :: Range Integer ri' = R.linearFrom 0 (- 2^127) (2^127)@@ -62,12 +63,6 @@ -- potentially ineffiecient gen_ivl :: Preorder a => Gen a -> Gen a -> Gen (Interval a) gen_ivl g1 g2 = liftA2 (...) g1 g2 ----gen_inf :: Bounded a => Gen a -> Gen (Inf a)---gen_inf g = liftA2 (foldl' $ flip filterL) (fmap inf g) $ G.list (R.constant 0 20) g----gen_sup :: Bounded a => Gen a -> Gen (Sup a)---gen_sup g = liftA2 (foldl' $ flip filterR) (fmap sup g) $ G.list (R.constant 0 20) g gen_maybe :: Gen a -> Gen (Maybe a) gen_maybe gen = G.frequency [(9, Just <$> gen), (1, pure Nothing)]
test/Test/Data/Connection/Float.hs view
@@ -3,7 +3,6 @@ import Data.Connection.Conn import Data.Connection.Float-import Data.Connection.Double import Data.Int import Hedgehog import Prelude hiding (Ord(..),Bounded, until)@@ -77,156 +76,18 @@ assert $ Prop.monotonic (f64i32) x x' y y' assert $ Prop.idempotent (f64i32) x y -{---prop_connections_f32 :: Property-prop_connections_f32 = withTests 1000 . property $ do- x <- forAll f32- y <- forAll (gen_maybe $ G.integral ri)- x' <- forAll f32- y' <- forAll (gen_maybe $ G.integral ri)- - assert $ Prop.adjoint f32i32 x y- assert $ Prop.adjoint i32f32 y x- assert $ Prop.closed f32i32 x- assert $ Prop.closed i32f32 y- assert $ Prop.kernel i32f32 x- assert $ Prop.kernel f32i32 y- assert $ Prop.monotonicL f32i32 x x'- assert $ Prop.monotonicL i32f32 y y'- assert $ Prop.monotonicR f32i32 y y'- assert $ Prop.monotonicR i32f32 x x'- assert $ Prop.idempotentL f32i32 x- assert $ Prop.idempotentL i32f32 y- assert $ Prop.idempotentR i32f32 x- assert $ Prop.idempotentR f32i32 y--prop_connections_f64 :: Property-prop_connections_f64 = withTests 1000 . property $ do+prop_connection_f64f32 :: Property+prop_connection_f64f32 = withTests 1000 . property $ do x <- forAll f64- y <- forAll (gen_maybe $ G.integral ri) x' <- forAll f64- y' <- forAll (gen_maybe $ G.integral ri)- - assert $ Prop.adjoint f64i64 x y- assert $ Prop.adjoint i64f64 y x- assert $ Prop.closed f64i64 x- assert $ Prop.closed i64f64 y- assert $ Prop.kernel i64f64 x- assert $ Prop.kernel f64i64 y- assert $ Prop.monotonicL f64i64 x x'- assert $ Prop.monotonicL i64f64 y y'- assert $ Prop.monotonicR f64i64 y y'- assert $ Prop.monotonicR i64f64 x x'- assert $ Prop.idempotentL f64i64 x- assert $ Prop.idempotentL i64f64 y- assert $ Prop.idempotentR i64f64 x- assert $ Prop.idempotentR f64i64 y--prop_prd_u32 :: Property-prop_prd_u32 = withTests 1000 . property $ do- x <- connl f32u32 <$> forAll f32- y <- connl f32u32 <$> forAll f32- z <- connl f32u32 <$> forAll f32- assert $ Prop.reflexive_eq x- assert $ Prop.reflexive_le x- assert $ Prop.irreflexive_lt x- assert $ Prop.symmetric x y- assert $ Prop.asymmetric x y- assert $ Prop.antisymmetric x y- assert $ Prop.transitive_lt x y z- assert $ Prop.transitive_le x y z- assert $ Prop.transitive_eq x y z--gen_sgn :: Gen Signed-gen_sgn = Signed <$> f32--gen_ugn :: Gen Unsigned-gen_ugn = (Unsigned . abs) <$> f32--prop_connections_f32u32 :: Property-prop_connections_f32u32 = withTests 1000 . property $ do- x <- forAll f32- y <- Ulp32 <$> forAll (G.integral ri)- x' <- forAll f32- y' <- Ulp32 <$> forAll (G.integral ri)-- assert $ Prop.adjoint f32u32 x y- assert $ Prop.adjoint u32f32 y x- assert $ Prop.monotonicL f32u32 x x'- assert $ Prop.monotonicL u32f32 y y'- assert $ Prop.monotonicR f32u32 y y'- assert $ Prop.monotonicR u32f32 x x'- assert $ Prop.closed f32u32 x- assert $ Prop.closed u32f32 y- assert $ Prop.kernel u32f32 x- assert $ Prop.kernel f32u32 y--prop_connections_f32sgn :: Property-prop_connections_f32sgn = withTests 10000 . property $ do- x <- forAll f32- x' <- forAll f32- y <- forAll $ gen_sgn- y' <- forAll $ gen_sgn-- assert $ Prop.adjoint f32sgn x y- assert $ Prop.monotonicL f32sgn x x'- assert $ Prop.monotonicR f32sgn y y'- assert $ Prop.closed f32sgn x- assert $ Prop.kernel f32sgn y--prop_connections_f32w08 :: Property-prop_connections_f32w08 = withTests 10000 . property $ do- x <- forAll f32- x' <- forAll f32- y <- forAll $ gen_n5 $ G.integral (ri @Word8)- y' <- forAll $ gen_n5 $ G.integral (ri @Word8)-- assert $ Prop.adjoint (tripl f32w08) x y- assert $ Prop.adjoint (tripr f32w08) y x- assert $ Prop.monotonicL (tripl f32w08) x x'- assert $ Prop.monotonicL (tripr f32w08) y y'- assert $ Prop.monotonicR (tripl f32w08) y y'- assert $ Prop.monotonicR (tripr f32w08) x x'- assert $ Prop.closed (tripl f32w08) x- assert $ Prop.closed (tripr f32w08) y- assert $ Prop.kernel (tripl f32w08) y- assert $ Prop.kernel (tripr f32w08) x--prop_connections_f32w64 :: Property-prop_connections_f32w64 = withTests 1000 . property $ do- x <- forAll f32 y <- forAll f32- x' <- forAll f32 y' <- forAll f32- z <- forAll (gen_n5 $ G.integral @_ @Word64 ri)- w <- forAll (gen_n5 $ G.integral @_ @Word64 ri)- z' <- forAll (gen_n5 $ G.integral @_ @Word64 ri)- w' <- forAll (gen_n5 $ G.integral @_ @Word64 ri)- exy <- forAll $ G.element [Left x, Right y]- exy' <- forAll $ G.element [Left x', Right y']- ezw <- forAll $ G.element [Left z, Right w]- ezw' <- forAll $ G.element [Left z', Right w'] - assert $ Prop.closed (idx @Float) x --TODO in Index.hs- assert $ Prop.kernel (idx @Float) z- assert $ Prop.monotonicL (idx @Float) x x'- assert $ Prop.monotonicR (idx @Float) z z'- assert $ Prop.adjoint (idx @Float) x z-- assert $ Prop.closed (idx @(Float,Float)) (x,y)- assert $ Prop.kernel (idx @(Float,Float)) (z,w)- assert $ Prop.monotonicL (idx @(Float,Float)) (x,y) (x',y')- assert $ Prop.monotonicR (idx @(Float,Float)) (z,w) (z',w')- assert $ Prop.adjoint (idx @(Float,Float)) (x,y)(z,w)-- assert $ Prop.closed (idx @(EitheR Float Float)) exy- assert $ Prop.kernel (idx @(EitheR Float Float)) ezw- assert $ Prop.monotonicL (idx @(EitheR Float Float)) exy exy'- assert $ Prop.monotonicR (idx @(EitheR Float Float)) ezw ezw'- assert $ Prop.adjoint (idx @(EitheR Float Float)) exy ezw--}-+ assert $ Prop.adjoint (f64f32) x y+ assert $ Prop.closed (f64f32) x+ assert $ Prop.kernel (f64f32) y+ assert $ Prop.monotonic (f64f32) x x' y y'+ assert $ Prop.idempotent (f64f32) x y tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Connection/Int.hs view
@@ -2,31 +2,85 @@ module Test.Data.Connection.Int where import Data.Connection.Int-import Data.Connection.Conn import Data.Int import Data.Word import Hedgehog-import Prelude hiding (Bounded) import Test.Data.Connection import qualified Data.Connection.Property as Prop import qualified Hedgehog.Gen as G -prop_connectionsL :: Property-prop_connectionsL = withTests 1000 . property $ do+prop_connections_int16 :: Property+prop_connections_int16 = withTests 1000 . property $ do i08 <- forAll $ G.integral (ri @Int8) w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ gen_maybe $ G.integral (ri @Int16)++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ gen_maybe $ G.integral (ri @Int16)++ assert $ Prop.adjointL w08i16 w08 i16+ assert $ Prop.closedL w08i16 w08+ assert $ Prop.kernelL w08i16 i16+ assert $ Prop.monotonicL w08i16 w08 w08' i16 i16'+ assert $ Prop.idempotentL w08i16 w08 i16++ assert $ Prop.adjointL i08i16 i08 i16+ assert $ Prop.closedL i08i16 i08+ assert $ Prop.kernelL i08i16 i16+ assert $ Prop.monotonicL i08i16 i08 i08' i16 i16'+ assert $ Prop.idempotentL i08i16 i08 i16++prop_connections_int32 :: Property+prop_connections_int32 = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8) i16 <- forAll $ G.integral (ri @Int16) w16 <- forAll $ G.integral (ri @Word16)+ i32 <- forAll $ gen_maybe $ G.integral (ri @Int32)++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ i32' <- forAll $ gen_maybe $ G.integral (ri @Int32)++ assert $ Prop.adjointL w08i32 w08 i32+ assert $ Prop.closedL w08i32 w08+ assert $ Prop.kernelL w08i32 i32+ assert $ Prop.monotonicL w08i32 w08 w08' i32 i32'+ assert $ Prop.idempotentL w08i32 w08 i32+ + assert $ Prop.adjointL w16i32 w16 i32+ assert $ Prop.closedL w16i32 w16+ assert $ Prop.kernelL w16i32 i32+ assert $ Prop.monotonicL w16i32 w16 w16' i32 i32'+ assert $ Prop.idempotentL w16i32 w16 i32++ assert $ Prop.adjointL i08i32 i08 i32+ assert $ Prop.closedL i08i32 i08+ assert $ Prop.kernelL i08i32 i32+ assert $ Prop.monotonicL i08i32 i08 i08' i32 i32'+ assert $ Prop.idempotentL i08i32 i08 i32+ + assert $ Prop.adjointL i16i32 i16 i32+ assert $ Prop.closedL i16i32 i16+ assert $ Prop.kernelL i16i32 i32+ assert $ Prop.monotonicL i16i32 i16 i16' i32 i32'+ assert $ Prop.idempotentL i16i32 i16 i32++prop_connections_int64 :: Property+prop_connections_int64 = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16) i32 <- forAll $ G.integral (ri @Int32) w32 <- forAll $ G.integral (ri @Word32)- i64 <- forAll $ G.integral (ri @Int64)- w64 <- forAll $ G.integral (ri @Word64)- ixx <- forAll $ G.integral (ri @Int)- wxx <- forAll $ G.integral (ri @Word)- int <- forAll $ G.integral ri'- nat <- forAll $ G.integral rn- mnt <- forAll $ gen_maybe (G.integral ri')+ i64 <- forAll $ gen_maybe $ G.integral (ri @Int64) i08' <- forAll $ G.integral (ri @Int8) w08' <- forAll $ G.integral (ri @Word8)@@ -34,57 +88,112 @@ w16' <- forAll $ G.integral (ri @Word16) i32' <- forAll $ G.integral (ri @Int32) w32' <- forAll $ G.integral (ri @Word32)- i64' <- forAll $ G.integral (ri @Int64)- w64' <- forAll $ G.integral (ri @Word64)- ixx' <- forAll $ G.integral (ri @Int)- wxx' <- forAll $ G.integral (ri @Word)- int' <- forAll $ G.integral ri'- nat' <- forAll $ G.integral rn- mnt' <- forAll $ gen_maybe (G.integral ri')+ i64' <- forAll $ gen_maybe $ G.integral (ri @Int64) - assert $ Prop.adjointL intnat int nat- --assert $ Prop.adjointL natint nat mnt- assert $ Prop.adjointL ixxwxx ixx wxx- assert $ Prop.adjointL i64w64 i64 w64- assert $ Prop.adjointL i32w32 i32 w32- assert $ Prop.adjointL i16w16 i16 w16- assert $ Prop.adjointL i08w08 i08 w08+ assert $ Prop.adjointL w08i64 w08 i64+ assert $ Prop.closedL w08i64 w08+ assert $ Prop.kernelL w08i64 i64+ assert $ Prop.monotonicL w08i64 w08 w08' i64 i64'+ assert $ Prop.idempotentL w08i64 w08 i64+ + assert $ Prop.adjointL w16i64 w16 i64+ assert $ Prop.closedL w16i64 w16+ assert $ Prop.kernelL w16i64 i64+ assert $ Prop.monotonicL w16i64 w16 w16' i64 i64'+ assert $ Prop.idempotentL w16i64 w16 i64+ + assert $ Prop.adjointL w32i64 w32 i64+ assert $ Prop.closedL w32i64 w32+ assert $ Prop.kernelL w32i64 i64+ assert $ Prop.monotonicL w32i64 w32 w32' i64 i64'+ assert $ Prop.idempotentL w32i64 w32 i64 - assert $ Prop.closedL intnat int- --assert $ Prop.closedL natint nat- assert $ Prop.closedL ixxwxx ixx- assert $ Prop.closedL i64w64 i64- assert $ Prop.closedL i32w32 i32- assert $ Prop.closedL i16w16 i16- assert $ Prop.closedL i08w08 i08+ assert $ Prop.adjointL i08i64 i08 i64+ assert $ Prop.closedL i08i64 i08+ assert $ Prop.kernelL i08i64 i64+ assert $ Prop.monotonicL i08i64 i08 i08' i64 i64'+ assert $ Prop.idempotentL i08i64 i08 i64+ + assert $ Prop.adjointL i16i64 i16 i64+ assert $ Prop.closedL i16i64 i16+ assert $ Prop.kernelL i16i64 i64+ assert $ Prop.monotonicL i16i64 i16 i16' i64 i64'+ assert $ Prop.idempotentL i16i64 i16 i64+ + assert $ Prop.adjointL i32i64 i32 i64+ assert $ Prop.closedL i32i64 i32+ assert $ Prop.kernelL i32i64 i64+ assert $ Prop.monotonicL i32i64 i32 i32' i64 i64'+ assert $ Prop.idempotentL i32i64 i32 i64 - assert $ Prop.kernelL intnat nat- --assert $ Prop.kernelL natint mnt- assert $ Prop.kernelL ixxwxx wxx- assert $ Prop.kernelL i64w64 w64- assert $ Prop.kernelL i32w32 w32- assert $ Prop.kernelL i16w16 w16- assert $ Prop.kernelL i08w08 w08+prop_connections_int :: Property+prop_connections_int = withTests 1000 . property $ do - assert $ Prop.monotonicL intnat int int' nat nat'- --assert $ Prop.monotonicL natint nat nat' mnt mnt'- assert $ Prop.monotonicL ixxwxx ixx ixx' wxx wxx'- assert $ Prop.monotonicL i64w64 i64 i64' w64 w64'- assert $ Prop.monotonicL i32w32 i32 i32' w32 w32'- assert $ Prop.monotonicL i16w16 i16 i16' w16 w16'- assert $ Prop.monotonicL i08w08 i08 i08' w08 w08'+ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16)+ i32 <- forAll $ G.integral (ri @Int32)+ w32 <- forAll $ G.integral (ri @Word32)+ i64 <- forAll $ G.integral (ri @Int64)+ ixx <- forAll $ gen_maybe $ G.integral (ri @Int)+ int <- forAll $ G.integral (ri @Int) - assert $ Prop.idempotentL intnat int nat- -- assert $ Prop.idempotentL natint nat mnt- assert $ Prop.idempotentL ixxwxx ixx wxx- assert $ Prop.idempotentL i64w64 i64 w64- assert $ Prop.idempotentL i32w32 i32 w32- assert $ Prop.idempotentL i16w16 i16 w16- assert $ Prop.idempotentL i08w08 i08 w08+ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ i32' <- forAll $ G.integral (ri @Int32)+ w32' <- forAll $ G.integral (ri @Word32)+ i64' <- forAll $ G.integral (ri @Int64)+ ixx' <- forAll $ gen_maybe $ G.integral (ri @Int)+ int' <- forAll $ G.integral (ri @Int) -prop_connectionsR :: Property-prop_connectionsR = withTests 1000 . property $ do+ assert $ Prop.adjointL w08ixx w08 ixx+ assert $ Prop.closedL w08ixx w08+ assert $ Prop.kernelL w08ixx ixx+ assert $ Prop.monotonicL w08ixx w08 w08' ixx ixx'+ assert $ Prop.idempotentL w08ixx w08 ixx+ + assert $ Prop.adjointL w16ixx w16 ixx+ assert $ Prop.closedL w16ixx w16+ assert $ Prop.kernelL w16ixx ixx+ assert $ Prop.monotonicL w16ixx w16 w16' ixx ixx'+ assert $ Prop.idempotentL w16ixx w16 ixx+ + assert $ Prop.adjointL w32ixx w32 ixx+ assert $ Prop.closedL w32ixx w32+ assert $ Prop.kernelL w32ixx ixx+ assert $ Prop.monotonicL w32ixx w32 w32' ixx ixx'+ assert $ Prop.idempotentL w32ixx w32 ixx + assert $ Prop.adjointL i08ixx i08 ixx+ assert $ Prop.closedL i08ixx i08+ assert $ Prop.kernelL i08ixx ixx+ assert $ Prop.monotonicL i08ixx i08 i08' ixx ixx'+ assert $ Prop.idempotentL i08ixx i08 ixx+ + assert $ Prop.adjointL i16ixx i16 ixx+ assert $ Prop.closedL i16ixx i16+ assert $ Prop.kernelL i16ixx ixx+ assert $ Prop.monotonicL i16ixx i16 i16' ixx ixx'+ assert $ Prop.idempotentL i16ixx i16 ixx+ + assert $ Prop.adjointL i32ixx i32 ixx+ assert $ Prop.closedL i32ixx i32+ assert $ Prop.kernelL i32ixx ixx+ assert $ Prop.monotonicL i32ixx i32 i32' ixx ixx'+ assert $ Prop.idempotentL i32ixx i32 ixx+ + assert $ Prop.adjoint i64ixx i64 int+ assert $ Prop.closed i64ixx i64+ assert $ Prop.kernel i64ixx int+ assert $ Prop.monotonic i64ixx i64 i64' int int'+ assert $ Prop.idempotent i64ixx i64 int++prop_connections_integer :: Property+prop_connections_integer = withTests 1000 . property $ do+ i08 <- forAll $ G.integral (ri @Int8) w08 <- forAll $ G.integral (ri @Word8) i16 <- forAll $ G.integral (ri @Int16)@@ -95,9 +204,8 @@ w64 <- forAll $ G.integral (ri @Word64) ixx <- forAll $ G.integral (ri @Int) wxx <- forAll $ G.integral (ri @Word)- int <- forAll $ G.integral ri'+ int <- forAll $ gen_maybe $ G.integral ri' nat <- forAll $ G.integral rn- mnt <- forAll $ gen_maybe (G.integral ri') i08' <- forAll $ G.integral (ri @Int8) w08' <- forAll $ G.integral (ri @Word8)@@ -109,49 +217,77 @@ w64' <- forAll $ G.integral (ri @Word64) ixx' <- forAll $ G.integral (ri @Int) wxx' <- forAll $ G.integral (ri @Word)- int' <- forAll $ G.integral ri'+ int' <- forAll $ gen_maybe (G.integral ri') nat' <- forAll $ G.integral rn- mnt' <- forAll $ gen_maybe (G.integral ri')+ + assert $ Prop.adjointL w08int w08 int+ assert $ Prop.closedL w08int w08+ assert $ Prop.kernelL w08int int+ assert $ Prop.monotonicL w08int w08 w08' int int'+ assert $ Prop.idempotentL w08int w08 int+ + assert $ Prop.adjointL w16int w16 int+ assert $ Prop.closedL w16int w16+ assert $ Prop.kernelL w16int int+ assert $ Prop.monotonicL w16int w16 w16' int int'+ assert $ Prop.idempotentL w16int w16 int+ + assert $ Prop.adjointL w32int w32 int+ assert $ Prop.closedL w32int w32+ assert $ Prop.kernelL w32int int+ assert $ Prop.monotonicL w32int w32 w32' int int'+ assert $ Prop.idempotentL w32int w32 int+ + assert $ Prop.adjointL w64int w64 int+ assert $ Prop.closedL w64int w64+ assert $ Prop.kernelL w64int int+ assert $ Prop.monotonicL w64int w64 w64' int int'+ assert $ Prop.idempotentL w64int w64 int+ + assert $ Prop.adjointL wxxint wxx int+ assert $ Prop.closedL wxxint wxx+ assert $ Prop.kernelL wxxint int+ assert $ Prop.monotonicL wxxint wxx wxx' int int'+ assert $ Prop.idempotentL wxxint wxx int - assert $ Prop.adjointR (swapR intnat) nat int- -- assert $ Prop.adjointR (swapR natint) mnt nat- assert $ Prop.adjointR (swapR ixxwxx) wxx ixx- assert $ Prop.adjointR (swapR i64w64) w64 i64- assert $ Prop.adjointR (swapR i32w32) w32 i32- assert $ Prop.adjointR (swapR i16w16) w16 i16- assert $ Prop.adjointR (swapR i08w08) w08 i08+ assert $ Prop.adjointL natint nat int+ assert $ Prop.closedL natint nat+ assert $ Prop.kernelL natint int+ assert $ Prop.monotonicL natint nat nat' int int'+ assert $ Prop.idempotentL natint nat int+ + + assert $ Prop.adjointL i08int i08 int+ assert $ Prop.closedL i08int i08+ assert $ Prop.kernelL i08int int+ assert $ Prop.monotonicL i08int i08 i08' int int'+ assert $ Prop.idempotentL i08int i08 int+ + assert $ Prop.adjointL i16int i16 int+ assert $ Prop.closedL i16int i16+ assert $ Prop.kernelL i16int int+ assert $ Prop.monotonicL i16int i16 i16' int int'+ assert $ Prop.idempotentL i16int i16 int+ + assert $ Prop.adjointL i32int i32 int+ assert $ Prop.closedL i32int i32+ assert $ Prop.kernelL i32int int+ assert $ Prop.monotonicL i32int i32 i32' int int'+ assert $ Prop.idempotentL i32int i32 int+ + assert $ Prop.adjointL i64int i64 int+ assert $ Prop.closedL i64int i64+ assert $ Prop.kernelL i64int int+ assert $ Prop.monotonicL i64int i64 i64' int int'+ assert $ Prop.idempotentL i64int i64 int+ + assert $ Prop.adjointL ixxint ixx int+ assert $ Prop.closedL ixxint ixx+ assert $ Prop.kernelL ixxint int+ assert $ Prop.monotonicL ixxint ixx ixx' int int'+ assert $ Prop.idempotentL ixxint ixx int - assert $ Prop.closedR (swapR intnat) nat- --assert $ Prop.closedR (swapR natint) mnt- assert $ Prop.closedR (swapR ixxwxx) wxx- assert $ Prop.closedR (swapR i64w64) w64- assert $ Prop.closedR (swapR i32w32) w32- assert $ Prop.closedR (swapR i16w16) w16- assert $ Prop.closedR (swapR i08w08) w08 - assert $ Prop.kernelR (swapR intnat) int- --assert $ Prop.kernelR (swapR natint) nat- assert $ Prop.kernelR (swapR ixxwxx) ixx- assert $ Prop.kernelR (swapR i64w64) i64- assert $ Prop.kernelR (swapR i32w32) i32- assert $ Prop.kernelR (swapR i16w16) i16- assert $ Prop.kernelR (swapR i08w08) i08-- assert $ Prop.monotonicR (swapR intnat) nat nat' int int'- -- assert $ Prop.monotonicR (swapR natint) mnt mnt' nat nat'- assert $ Prop.monotonicR (swapR ixxwxx) wxx wxx' ixx ixx'- assert $ Prop.monotonicR (swapR i64w64) w64 w64' i64 i64'- assert $ Prop.monotonicR (swapR i32w32) w32 w32' i32 i32'- assert $ Prop.monotonicR (swapR i16w16) w16 w16' i16 i16'- assert $ Prop.monotonicR (swapR i08w08) w08 w08' i08 i08'-- assert $ Prop.idempotentR (swapR intnat) nat int- -- assert $ Prop.idempotentR (swapR natint) mnt nat- assert $ Prop.idempotentR (swapR ixxwxx) wxx ixx- assert $ Prop.idempotentR (swapR i64w64) w64 i64- assert $ Prop.idempotentR (swapR i32w32) w32 i32- assert $ Prop.idempotentR (swapR i16w16) w16 i16- assert $ Prop.idempotentR (swapR i08w08) w08 i08 tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Connection/Word.hs view
@@ -3,25 +3,116 @@ import Data.Int import Data.Word-import Data.Connection.Conn import Data.Connection.Word import Hedgehog import Test.Data.Connection import qualified Data.Connection.Property as Prop import qualified Hedgehog.Gen as G -prop_connections :: Property-prop_connections = withTests 1000 . property $ do+prop_connections_word8 :: Property+prop_connections_word8 = withTests 1000 . property $ do+ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8) + i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)++ assert $ Prop.adjointL i08w08 i08 w08+ assert $ Prop.closedL i08w08 i08+ assert $ Prop.kernelL i08w08 w08+ assert $ Prop.monotonicL i08w08 i08 i08' w08 w08'+ assert $ Prop.idempotentL i08w08 i08 w08++prop_connections_word16 :: Property+prop_connections_word16 = withTests 1000 . property $ do+ i08 <- forAll $ G.integral (ri @Int8) w08 <- forAll $ G.integral (ri @Word8) i16 <- forAll $ G.integral (ri @Int16) w16 <- forAll $ G.integral (ri @Word16)++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ + assert $ Prop.adjointL w08w16 w08 w16+ assert $ Prop.closedL w08w16 w08+ assert $ Prop.kernelL w08w16 w16+ assert $ Prop.monotonicL w08w16 w08 w08' w16 w16'+ assert $ Prop.idempotentL w08w16 w08 w16+ + assert $ Prop.adjointL i08w16 i08 w16+ assert $ Prop.closedL i08w16 i08+ assert $ Prop.kernelL i08w16 w16+ assert $ Prop.monotonicL i08w16 i08 i08' w16 w16'+ assert $ Prop.idempotentL i08w16 i08 w16+ + assert $ Prop.adjointL i16w16 i16 w16+ assert $ Prop.closedL i16w16 i16+ assert $ Prop.kernelL i16w16 w16+ assert $ Prop.monotonicL i16w16 i16 i16' w16 w16'+ assert $ Prop.idempotentL i16w16 i16 w16++prop_connections_word32 :: Property+prop_connections_word32 = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16) i32 <- forAll $ G.integral (ri @Int32) w32 <- forAll $ G.integral (ri @Word32)++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ i32' <- forAll $ G.integral (ri @Int32)+ w32' <- forAll $ G.integral (ri @Word32)+ + assert $ Prop.adjointL w08w32 w08 w32+ assert $ Prop.closedL w08w32 w08+ assert $ Prop.kernelL w08w32 w32+ assert $ Prop.monotonicL w08w32 w08 w08' w32 w32'+ assert $ Prop.idempotentL w08w32 w08 w32++ assert $ Prop.adjointL w16w32 w16 w32+ assert $ Prop.closedL w16w32 w16+ assert $ Prop.kernelL w16w32 w32+ assert $ Prop.monotonicL w16w32 w16 w16' w32 w32'+ assert $ Prop.idempotentL w16w32 w16 w32+ + assert $ Prop.adjointL i08w32 i08 w32+ assert $ Prop.closedL i08w32 i08+ assert $ Prop.kernelL i08w32 w32+ assert $ Prop.monotonicL i08w32 i08 i08' w32 w32'+ assert $ Prop.idempotentL i08w32 i08 w32++ assert $ Prop.adjointL i16w32 i16 w32+ assert $ Prop.closedL i16w32 i16+ assert $ Prop.kernelL i16w32 w32+ assert $ Prop.monotonicL i16w32 i16 i16' w32 w32'+ assert $ Prop.idempotentL i16w32 i16 w32++ assert $ Prop.adjointL i32w32 i32 w32+ assert $ Prop.closedL i32w32 i32+ assert $ Prop.kernelL i32w32 w32+ assert $ Prop.idempotentL i32w32 i32 w32+ assert $ Prop.monotonicL i32w32 i32 i32' w32 w32'++prop_connections_word64 :: Property+prop_connections_word64 = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16)+ i32 <- forAll $ G.integral (ri @Int32)+ w32 <- forAll $ G.integral (ri @Word32) i64 <- forAll $ G.integral (ri @Int64) w64 <- forAll $ G.integral (ri @Word64)- nat <- forAll $ G.integral rn+ ixx <- forAll $ G.integral (ri @Int) i08' <- forAll $ G.integral (ri @Int8) w08' <- forAll $ G.integral (ri @Word8)@@ -31,82 +122,230 @@ w32' <- forAll $ G.integral (ri @Word32) i64' <- forAll $ G.integral (ri @Int64) w64' <- forAll $ G.integral (ri @Word64)- nat' <- forAll $ G.integral rn+ ixx' <- forAll $ G.integral (ri @Int) - assert $ Prop.adjointL w64nat w64 nat- assert $ Prop.adjointL w64i64 w64 i64- assert $ Prop.adjointL w32nat w32 nat- assert $ Prop.adjointL w32w64 w32 w64- assert $ Prop.adjointL w32i32 w32 i32- assert $ Prop.adjointL w16nat w16 nat- assert $ Prop.adjointL w16w64 w16 w64- assert $ Prop.adjointL w16w32 w16 w32- assert $ Prop.adjointL w16i16 w16 i16- assert $ Prop.adjointL w08nat w08 nat assert $ Prop.adjointL w08w64 w08 w64- assert $ Prop.adjointL w08w32 w08 w32- assert $ Prop.adjointL w08w16 w08 w16- assert $ Prop.adjointL w08i08 w08 i08+ assert $ Prop.closedL w08w64 w08+ assert $ Prop.kernelL w08w64 w64+ assert $ Prop.monotonicL w08w64 w08 w08' w64 w64'+ assert $ Prop.idempotentL w08w64 w08 w64 - assert $ Prop.closedL w64nat w64- assert $ Prop.closedL w64i64 w64- assert $ Prop.closedL w32nat w32- assert $ Prop.closedL w32w64 w32- assert $ Prop.closedL w32i32 w32- assert $ Prop.closedL w16nat w16+ assert $ Prop.adjointL w16w64 w16 w64 assert $ Prop.closedL w16w64 w16- assert $ Prop.closedL w16w32 w16- assert $ Prop.closedL w16i16 w16- assert $ Prop.closedL w08nat w08- assert $ Prop.closedL w08w64 w08- assert $ Prop.closedL w08w32 w08- assert $ Prop.closedL w08w16 w08- assert $ Prop.closedL w08i08 w08+ assert $ Prop.kernelL w16w64 w64+ assert $ Prop.monotonicL w16w64 w16 w16' w64 w64'+ assert $ Prop.idempotentL w16w64 w16 w64 - assert $ Prop.kernelL w64nat nat- assert $ Prop.kernelL w64i64 i64- assert $ Prop.kernelL w32nat nat+ assert $ Prop.adjointL w32w64 w32 w64+ assert $ Prop.closedL w32w64 w32 assert $ Prop.kernelL w32w64 w64- assert $ Prop.kernelL w32i32 i32- assert $ Prop.kernelL w16nat nat- assert $ Prop.kernelL w16w64 w64- assert $ Prop.kernelL w16w32 w32- assert $ Prop.kernelL w16i16 i16+ assert $ Prop.monotonicL w32w64 w32 w32' w64 w64'+ assert $ Prop.idempotentL w32w64 w32 w64+ + assert $ Prop.adjointL i08w64 i08 w64+ assert $ Prop.closedL i08w64 i08+ assert $ Prop.kernelL i08w64 w64+ assert $ Prop.monotonicL i08w64 i08 i08' w64 w64'+ assert $ Prop.idempotentL i08w64 i08 w64++ assert $ Prop.adjointL i16w64 i16 w64+ assert $ Prop.closedL i16w64 i16+ assert $ Prop.kernelL i16w64 w64+ assert $ Prop.monotonicL i16w64 i16 i16' w64 w64'+ assert $ Prop.idempotentL i16w64 i16 w64++ assert $ Prop.adjointL i32w64 i32 w64+ assert $ Prop.closedL i32w64 i32+ assert $ Prop.kernelL i32w64 w64+ assert $ Prop.idempotentL i32w64 i32 w64+ assert $ Prop.monotonicL i32w64 i32 i32' w64 w64'++ assert $ Prop.adjointL i64w64 i64 w64+ assert $ Prop.closedL i64w64 i64+ assert $ Prop.kernelL i64w64 w64+ assert $ Prop.idempotentL i64w64 i64 w64+ assert $ Prop.monotonicL i64w64 i64 i64' w64 w64'++ assert $ Prop.adjointL ixxw64 ixx w64+ assert $ Prop.closedL ixxw64 ixx+ assert $ Prop.kernelL ixxw64 w64+ assert $ Prop.idempotentL ixxw64 ixx w64+ assert $ Prop.monotonicL ixxw64 ixx ixx' w64 w64'++prop_connections_word :: Property+prop_connections_word = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16)+ i32 <- forAll $ G.integral (ri @Int32)+ w32 <- forAll $ G.integral (ri @Word32)+ i64 <- forAll $ G.integral (ri @Int64)+ w64 <- forAll $ G.integral (ri @Word64)+ ixx <- forAll $ G.integral (ri @Int)+ wxx <- forAll $ G.integral (ri @Word)++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ i32' <- forAll $ G.integral (ri @Int32)+ w32' <- forAll $ G.integral (ri @Word32)+ i64' <- forAll $ G.integral (ri @Int64)+ w64' <- forAll $ G.integral (ri @Word64)+ ixx' <- forAll $ G.integral (ri @Int)+ wxx' <- forAll $ G.integral (ri @Word)++ assert $ Prop.adjointL w08wxx w08 wxx+ assert $ Prop.closedL w08wxx w08+ assert $ Prop.kernelL w08wxx wxx+ assert $ Prop.monotonicL w08wxx w08 w08' wxx wxx'+ assert $ Prop.idempotentL w08wxx w08 wxx++ assert $ Prop.adjointL w16wxx w16 wxx+ assert $ Prop.closedL w16wxx w16+ assert $ Prop.kernelL w16wxx wxx+ assert $ Prop.monotonicL w16wxx w16 w16' wxx wxx'+ assert $ Prop.idempotentL w16wxx w16 wxx++ assert $ Prop.adjointL w32wxx w32 wxx+ assert $ Prop.closedL w32wxx w32+ assert $ Prop.kernelL w32wxx wxx+ assert $ Prop.monotonicL w32wxx w32 w32' wxx wxx'+ assert $ Prop.idempotentL w32wxx w32 wxx++ assert $ Prop.adjoint w64wxx w64 wxx+ assert $ Prop.closed w64wxx w64+ assert $ Prop.kernel w64wxx wxx+ assert $ Prop.monotonic w64wxx w64 w64' wxx wxx'+ assert $ Prop.idempotent w64wxx w64 wxx+ + assert $ Prop.adjointL i08wxx i08 wxx+ assert $ Prop.closedL i08wxx i08+ assert $ Prop.kernelL i08wxx wxx+ assert $ Prop.monotonicL i08wxx i08 i08' wxx wxx'+ assert $ Prop.idempotentL i08wxx i08 wxx++ assert $ Prop.adjointL i16wxx i16 wxx+ assert $ Prop.closedL i16wxx i16+ assert $ Prop.kernelL i16wxx wxx+ assert $ Prop.monotonicL i16wxx i16 i16' wxx wxx'+ assert $ Prop.idempotentL i16wxx i16 wxx++ assert $ Prop.adjointL i32wxx i32 wxx+ assert $ Prop.closedL i32wxx i32+ assert $ Prop.kernelL i32wxx wxx+ assert $ Prop.idempotentL i32wxx i32 wxx+ assert $ Prop.monotonicL i32wxx i32 i32' wxx wxx'++ assert $ Prop.adjointL i64wxx i64 wxx+ assert $ Prop.closedL i64wxx i64+ assert $ Prop.kernelL i64wxx wxx+ assert $ Prop.idempotentL i64wxx i64 wxx+ assert $ Prop.monotonicL i64wxx i64 i64' wxx wxx'++ assert $ Prop.adjointL ixxwxx ixx wxx+ assert $ Prop.closedL ixxwxx ixx+ assert $ Prop.kernelL ixxwxx wxx+ assert $ Prop.idempotentL ixxwxx ixx wxx+ assert $ Prop.monotonicL ixxwxx ixx ixx' wxx wxx'++prop_connections_natural :: Property+prop_connections_natural = withTests 1000 . property $ do++ i08 <- forAll $ G.integral (ri @Int8)+ w08 <- forAll $ G.integral (ri @Word8)+ i16 <- forAll $ G.integral (ri @Int16)+ w16 <- forAll $ G.integral (ri @Word16)+ i32 <- forAll $ G.integral (ri @Int32)+ w32 <- forAll $ G.integral (ri @Word32)+ i64 <- forAll $ G.integral (ri @Int64)+ w64 <- forAll $ G.integral (ri @Word64)+ ixx <- forAll $ G.integral (ri @Int)+ wxx <- forAll $ G.integral (ri @Word)+ int <- forAll $ G.integral ri''+ nat <- forAll $ G.integral rn++ i08' <- forAll $ G.integral (ri @Int8)+ w08' <- forAll $ G.integral (ri @Word8)+ i16' <- forAll $ G.integral (ri @Int16)+ w16' <- forAll $ G.integral (ri @Word16)+ i32' <- forAll $ G.integral (ri @Int32)+ w32' <- forAll $ G.integral (ri @Word32)+ i64' <- forAll $ G.integral (ri @Int64)+ w64' <- forAll $ G.integral (ri @Word64)+ ixx' <- forAll $ G.integral (ri @Int)+ wxx' <- forAll $ G.integral (ri @Word)+ int' <- forAll $ G.integral ri''+ nat' <- forAll $ G.integral rn++ assert $ Prop.adjointL w08nat w08 nat+ assert $ Prop.closedL w08nat w08 assert $ Prop.kernelL w08nat nat- assert $ Prop.kernelL w08w64 w64- assert $ Prop.kernelL w08w32 w32- assert $ Prop.kernelL w08w16 w16- assert $ Prop.kernelL w08i08 i08+ assert $ Prop.monotonicL w08nat w08 w08' nat nat'+ assert $ Prop.idempotentL w08nat w08 nat - assert $ Prop.monotonicL w64nat w64 w64' nat nat'- assert $ Prop.monotonicL w64i64 w64 w64' i64 i64'- assert $ Prop.monotonicL w32nat w32 w32' nat nat'- assert $ Prop.monotonicL w32w64 w32 w32' w64 w64'- assert $ Prop.monotonicL w32i32 w32 w32' i32 i32'+ assert $ Prop.adjointL w16nat w16 nat+ assert $ Prop.closedL w16nat w16+ assert $ Prop.kernelL w16nat nat assert $ Prop.monotonicL w16nat w16 w16' nat nat'- assert $ Prop.monotonicL w16w64 w16 w16' w64 w64'- assert $ Prop.monotonicL w16w32 w16 w16' w32 w32'- assert $ Prop.monotonicL w16i16 w16 w16' i16 i16'- assert $ Prop.monotonicL w08nat w08 w08' nat nat'- assert $ Prop.monotonicL w08w64 w08 w08' w64 w64'- assert $ Prop.monotonicL w08w32 w08 w08' w32 w32'- assert $ Prop.monotonicL w08w16 w08 w08' w16 w16'- assert $ Prop.monotonicL w08i08 w08 w08' i08 i08'+ assert $ Prop.idempotentL w16nat w16 nat - assert $ Prop.idempotentL w64nat w64 nat- assert $ Prop.idempotentL w64i64 w64 i64+ assert $ Prop.adjointL w32nat w32 nat+ assert $ Prop.closedL w32nat w32+ assert $ Prop.kernelL w32nat nat+ assert $ Prop.monotonicL w32nat w32 w32' nat nat' assert $ Prop.idempotentL w32nat w32 nat- assert $ Prop.idempotentL w32w64 w32 w64- assert $ Prop.idempotentL w32i32 w32 i32- assert $ Prop.idempotentL w16nat w16 nat- assert $ Prop.idempotentL w16w64 w16 w64- assert $ Prop.idempotentL w16w32 w16 w32- assert $ Prop.idempotentL w16i16 w16 i16- assert $ Prop.idempotentL w08nat w08 nat- assert $ Prop.idempotentL w08w64 w08 w64- assert $ Prop.idempotentL w08w32 w08 w32- assert $ Prop.idempotentL w08w16 w08 w16- assert $ Prop.idempotentL w08i08 w08 i08++ assert $ Prop.adjointL w64nat w64 nat+ assert $ Prop.closedL w64nat w64+ assert $ Prop.kernelL w64nat nat+ assert $ Prop.monotonicL w64nat w64 w64' nat nat'+ assert $ Prop.idempotentL w64nat w64 nat++ assert $ Prop.adjointL wxxnat wxx nat+ assert $ Prop.closedL wxxnat wxx+ assert $ Prop.kernelL wxxnat nat+ assert $ Prop.monotonicL wxxnat wxx wxx' nat nat'+ assert $ Prop.idempotentL wxxnat wxx nat+ + assert $ Prop.adjointL i08nat i08 nat+ assert $ Prop.closedL i08nat i08+ assert $ Prop.kernelL i08nat nat+ assert $ Prop.monotonicL i08nat i08 i08' nat nat'+ assert $ Prop.idempotentL i08nat i08 nat++ assert $ Prop.adjointL i16nat i16 nat+ assert $ Prop.closedL i16nat i16+ assert $ Prop.kernelL i16nat nat+ assert $ Prop.monotonicL i16nat i16 i16' nat nat'+ assert $ Prop.idempotentL i16nat i16 nat++ assert $ Prop.adjointL i32nat i32 nat+ assert $ Prop.closedL i32nat i32+ assert $ Prop.kernelL i32nat nat+ assert $ Prop.idempotentL i32nat i32 nat+ assert $ Prop.monotonicL i32nat i32 i32' nat nat'++ assert $ Prop.adjointL i64nat i64 nat+ assert $ Prop.closedL i64nat i64+ assert $ Prop.kernelL i64nat nat+ assert $ Prop.idempotentL i64nat i64 nat+ assert $ Prop.monotonicL i64nat i64 i64' nat nat'++ assert $ Prop.adjointL ixxnat ixx nat+ assert $ Prop.closedL ixxnat ixx+ assert $ Prop.kernelL ixxnat nat+ assert $ Prop.idempotentL ixxnat ixx nat+ assert $ Prop.monotonicL ixxnat ixx ixx' nat nat'++ assert $ Prop.adjointL intnat int nat+ assert $ Prop.closedL intnat int+ assert $ Prop.kernelL intnat nat+ assert $ Prop.idempotentL intnat int nat+ assert $ Prop.monotonicL intnat int int' nat nat'+ tests :: IO Bool tests = checkParallel $$(discover)
test/Test/Data/Lattice.hs view
@@ -2,18 +2,16 @@ {-# LANGUAGE DataKinds #-} module Test.Data.Lattice where -import Data.Connection import Data.Lattice import Data.Connection.Property import Data.Lattice.Property-import Data.Order import Test.Data.Connection import Hedgehog import qualified Hedgehog.Gen as G -prop_heytingL :: Property-prop_heytingL = withTests 1000 . property $ do+prop_coheyting :: Property+prop_coheyting = withTests 1000 . property $ do b1 <- forAll G.bool b2 <- forAll G.bool b3 <- forAll G.bool@@ -23,15 +21,12 @@ w1 <- forAll $ G.integral (ri @Word) w2 <- forAll $ G.integral (ri @Word) w3 <- forAll $ G.integral (ri @Word)- f1 <- forAll f32- f2 <- forAll f32- f3 <- forAll f32 - assert $ adjointL (heyting b3) b1 b2- assert $ closedL (heyting b3) b1- assert $ kernelL (heyting b3) b2- assert $ monotonicL (heyting b3) b1 b2 b3 b2- assert $ idempotentL (heyting b3) b1 b2+ assert $ adjointL (algebra b3) b1 b2+ assert $ closedL (algebra b3) b1+ assert $ kernelL (algebra b3) b2+ assert $ monotonicL (algebra b3) b1 b2 b3 b2+ assert $ idempotentL (algebra b3) b1 b2 assert $ adjointL booleanL b1 b2 assert $ closedL booleanL b1@@ -39,32 +34,32 @@ assert $ monotonicL booleanL b1 b2 b3 b2 assert $ idempotentL booleanL b1 b3 - assert $ heytingL1 b1 b2 b3- assert $ heytingL2 b1 b2 b3- assert $ heytingL3 b1 b2 b3- assert $ heytingL4 b1 b2 b3- assert $ heytingL5 b1 b2 b3- assert $ heytingL6 b1 b2- assert $ heytingL7 b1 b2- assert $ heytingL8 b1- assert $ heytingL9 b1 b2- assert $ heytingL10 b1 b2- assert $ heytingL11 b1 b2- assert $ heytingL12 b1 b2- assert $ heytingL13 b1 b2- assert $ heytingL14 b1- assert $ heytingL15 b1- assert $ heytingL16 b1- assert $ heytingL17 b1- assert $ heytingL18 b1- assert $ heytingL19 b1 b2- assert $ heytingL20 b1 b2+ assert $ coheyting1 b1 b2 b3+ assert $ coheyting2 b1 b2 b3+ assert $ coheyting3 b1 b2 b3+ assert $ coheyting4 b1 b2 b3+ assert $ coheyting5 b1 b2 b3+ assert $ coheyting6 b1 b2+ assert $ coheyting7 b1 b2+ assert $ coheyting8 b1+ assert $ coheyting9 b1 b2+ assert $ coheyting10 b1 b2+ assert $ coheyting11 b1 b2+ assert $ coheyting12 b1 b2+ assert $ coheyting13 b1 b2+ assert $ coheyting14 b1+ assert $ coheyting15 b1+ assert $ coheyting16 b1+ assert $ coheyting17 b1+ assert $ coheyting18 b1+ assert $ coheyting19 b1 b2+ assert $ coheyting20 b1 b2 - assert $ adjointL (heyting o3) o1 o2- assert $ closedL (heyting o3) o1- assert $ kernelL (heyting o3) o2- assert $ monotonicL (heyting o3) o1 o2 o3 o2- assert $ idempotentL (heyting o3) o1 o2+ assert $ adjointL (algebra o3) o1 o2+ assert $ closedL (algebra o3) o1+ assert $ kernelL (algebra o3) o2+ assert $ monotonicL (algebra o3) o1 o2 o3 o2+ assert $ idempotentL (algebra o3) o1 o2 assert $ adjointL booleanL o1 o2 assert $ closedL booleanL o1@@ -72,32 +67,32 @@ assert $ monotonicL booleanL o1 o2 o3 o2 assert $ idempotentL booleanL o1 o3 - assert $ heytingL1 o1 o2 o3- assert $ heytingL2 o1 o2 o3- assert $ heytingL3 o1 o2 o3- assert $ heytingL4 o1 o2 o3- assert $ heytingL5 o1 o2 o3- assert $ heytingL6 o1 o2- assert $ heytingL7 o1 o2- assert $ heytingL8 o1- assert $ heytingL9 o1 o2- assert $ heytingL10 o1 o2- assert $ heytingL11 o1 o2- assert $ heytingL12 o1 o2- assert $ heytingL13 o1 o2- assert $ heytingL14 o1- assert $ heytingL15 o1- assert $ heytingL16 o1- assert $ heytingL17 o1- assert $ heytingL18 o1- assert $ heytingL19 o1 o2- assert $ heytingL20 o1 o2+ assert $ coheyting1 o1 o2 o3+ assert $ coheyting2 o1 o2 o3+ assert $ coheyting3 o1 o2 o3+ assert $ coheyting4 o1 o2 o3+ assert $ coheyting5 o1 o2 o3+ assert $ coheyting6 o1 o2+ assert $ coheyting7 o1 o2+ assert $ coheyting8 o1+ assert $ coheyting9 o1 o2+ assert $ coheyting10 o1 o2+ assert $ coheyting11 o1 o2+ assert $ coheyting12 o1 o2+ assert $ coheyting13 o1 o2+ assert $ coheyting14 o1+ assert $ coheyting15 o1+ assert $ coheyting16 o1+ assert $ coheyting17 o1+ assert $ coheyting18 o1+ assert $ coheyting19 o1 o2+ assert $ coheyting20 o1 o2 - assert $ adjointL (heyting w3) w1 w2- assert $ closedL (heyting w3) w1- assert $ kernelL (heyting w3) w2- assert $ monotonicL (heyting w3) w1 w2 w3 w2- assert $ idempotentL (heyting w3) w1 w2+ assert $ adjointL (algebra w3) w1 w2+ assert $ closedL (algebra w3) w1+ assert $ kernelL (algebra w3) w2+ assert $ monotonicL (algebra w3) w1 w2 w3 w2+ assert $ idempotentL (algebra w3) w1 w2 assert $ adjointL booleanL w1 w2 assert $ closedL booleanL w1@@ -105,29 +100,29 @@ assert $ monotonicL booleanL w1 w2 w3 w2 assert $ idempotentL booleanL w1 w3 - assert $ heytingL1 w1 w2 w3- assert $ heytingL2 w1 w2 w3- assert $ heytingL3 w1 w2 w3- assert $ heytingL4 w1 w2 w3- assert $ heytingL5 w1 w2 w3- assert $ heytingL6 w1 w2- assert $ heytingL7 w1 w2- assert $ heytingL8 w1- assert $ heytingL9 w1 w2- assert $ heytingL10 w1 w2- assert $ heytingL11 w1 w2- assert $ heytingL12 w1 w2- assert $ heytingL13 w1 w2- assert $ heytingL14 w1- assert $ heytingL15 w1- assert $ heytingL16 w1- assert $ heytingL17 w1- assert $ heytingL18 w1- assert $ heytingL19 w1 w2- assert $ heytingL20 w1 w2+ assert $ coheyting1 w1 w2 w3+ assert $ coheyting2 w1 w2 w3+ assert $ coheyting3 w1 w2 w3+ assert $ coheyting4 w1 w2 w3+ assert $ coheyting5 w1 w2 w3+ assert $ coheyting6 w1 w2+ assert $ coheyting7 w1 w2+ assert $ coheyting8 w1+ assert $ coheyting9 w1 w2+ assert $ coheyting10 w1 w2+ assert $ coheyting11 w1 w2+ assert $ coheyting12 w1 w2+ assert $ coheyting13 w1 w2+ assert $ coheyting14 w1+ assert $ coheyting15 w1+ assert $ coheyting16 w1+ assert $ coheyting17 w1+ assert $ coheyting18 w1+ assert $ coheyting19 w1 w2+ assert $ coheyting20 w1 w2 -prop_heytingR :: Property-prop_heytingR = withTests 1000 . property $ do+prop_heyting :: Property+prop_heyting = withTests 1000 . property $ do b1 <- forAll G.bool b2 <- forAll G.bool b3 <- forAll G.bool@@ -138,11 +133,11 @@ w2 <- forAll $ G.integral (ri @Word) w3 <- forAll $ G.integral (ri @Word) - assert $ adjointR (heyting b3) b1 b2- assert $ closedR (heyting b3) b1- assert $ kernelR (heyting b3) b2- assert $ monotonicR (heyting b3) b1 b2 b3 b2- assert $ idempotentR (heyting b3) b1 b2+ assert $ adjointR (algebra b3) b1 b2+ assert $ closedR (algebra b3) b1+ assert $ kernelR (algebra b3) b2+ assert $ monotonicR (algebra b3) b1 b2 b3 b2+ assert $ idempotentR (algebra b3) b1 b2 assert $ adjointR booleanR b1 b2 assert $ closedR booleanR b1@@ -150,30 +145,30 @@ assert $ monotonicR booleanR b1 b2 b3 b2 assert $ idempotentR booleanR b1 b3 - assert $ heytingR0 b1 b2 b3- assert $ heytingR1 b1 b2 b3- assert $ heytingR2 b1 b2 b3- assert $ heytingR3 b1 b2 b3- assert $ heytingR4 b1 b2 b3- assert $ heytingR5 b1 b2 b3- assert $ heytingR6 b1 b2- assert $ heytingR7 b1 b2- assert $ heytingR8 b1- assert $ heytingR9 b1 b2- assert $ heytingR10 b1 b2- assert $ heytingR11 b1 b2- assert $ heytingR12 b1 b2- assert $ heytingR13 b1 b2- assert $ heytingR14 b1- assert $ heytingR15 b1- assert $ heytingR16 b1- assert $ heytingR17 b1+ assert $ heyting0 b1 b2 b3+ assert $ heyting1 b1 b2 b3+ assert $ heyting2 b1 b2 b3+ assert $ heyting3 b1 b2 b3+ assert $ heyting4 b1 b2 b3+ assert $ heyting5 b1 b2 b3+ assert $ heyting6 b1 b2+ assert $ heyting7 b1 b2+ assert $ heyting8 b1+ assert $ heyting9 b1 b2+ assert $ heyting10 b1 b2+ assert $ heyting11 b1 b2+ assert $ heyting12 b1 b2+ assert $ heyting13 b1 b2+ assert $ heyting14 b1+ assert $ heyting15 b1+ assert $ heyting16 b1+ assert $ heyting17 b1 - assert $ adjointR (heyting o3) o1 o2- assert $ closedR (heyting o3) o1- assert $ kernelR (heyting o3) o2- assert $ monotonicR (heyting o3) o1 o2 o3 o2- assert $ idempotentR (heyting o3) o1 o2+ assert $ adjointR (algebra o3) o1 o2+ assert $ closedR (algebra o3) o1+ assert $ kernelR (algebra o3) o2+ assert $ monotonicR (algebra o3) o1 o2 o3 o2+ assert $ idempotentR (algebra o3) o1 o2 assert $ adjointR booleanR o1 o2 assert $ closedR booleanR o1@@ -181,30 +176,30 @@ assert $ monotonicR booleanR o1 o2 o3 o2 assert $ idempotentR booleanR o1 o3 - assert $ heytingR0 o1 o2 o3- assert $ heytingR1 o1 o2 o3- assert $ heytingR2 o1 o2 o3- assert $ heytingR3 o1 o2 o3- assert $ heytingR4 o1 o2 o3- assert $ heytingR5 o1 o2 o3- assert $ heytingR6 o1 o2- assert $ heytingR7 o1 o2- assert $ heytingR8 o1- assert $ heytingR9 o1 o2- assert $ heytingR10 o1 o2- assert $ heytingR11 o1 o2- assert $ heytingR12 o1 o2- assert $ heytingR13 o1 o2- assert $ heytingR14 o1- assert $ heytingR15 o1- assert $ heytingR16 o1- assert $ heytingR17 o1+ assert $ heyting0 o1 o2 o3+ assert $ heyting1 o1 o2 o3+ assert $ heyting2 o1 o2 o3+ assert $ heyting3 o1 o2 o3+ assert $ heyting4 o1 o2 o3+ assert $ heyting5 o1 o2 o3+ assert $ heyting6 o1 o2+ assert $ heyting7 o1 o2+ assert $ heyting8 o1+ assert $ heyting9 o1 o2+ assert $ heyting10 o1 o2+ assert $ heyting11 o1 o2+ assert $ heyting12 o1 o2+ assert $ heyting13 o1 o2+ assert $ heyting14 o1+ assert $ heyting15 o1+ assert $ heyting16 o1+ assert $ heyting17 o1 - assert $ adjointR (heyting w3) w1 w2- assert $ closedR (heyting w3) w1- assert $ kernelR (heyting w3) w2- assert $ monotonicR (heyting w3) w1 w2 w3 w2- assert $ idempotentR (heyting w3) w1 w2+ assert $ adjointR (algebra w3) w1 w2+ assert $ closedR (algebra w3) w1+ assert $ kernelR (algebra w3) w2+ assert $ monotonicR (algebra w3) w1 w2 w3 w2+ assert $ idempotentR (algebra w3) w1 w2 assert $ adjointR booleanR w1 w2 assert $ closedR booleanR w1@@ -212,24 +207,24 @@ assert $ monotonicR booleanR w1 w2 w3 w2 assert $ idempotentR booleanR w1 w3 - assert $ heytingR0 w1 w2 w3- assert $ heytingR1 w1 w2 w3- assert $ heytingR2 w1 w2 w3- assert $ heytingR3 w1 w2 w3- assert $ heytingR4 w1 w2 w3- assert $ heytingR5 w1 w2 w3- assert $ heytingR6 w1 w2- assert $ heytingR7 w1 w2- assert $ heytingR8 w1- assert $ heytingR9 w1 w2- assert $ heytingR10 w1 w2- assert $ heytingR11 w1 w2- assert $ heytingR12 w1 w2- assert $ heytingR13 w1 w2- assert $ heytingR14 w1- assert $ heytingR15 w1- assert $ heytingR16 w1- assert $ heytingR17 w1+ assert $ heyting0 w1 w2 w3+ assert $ heyting1 w1 w2 w3+ assert $ heyting2 w1 w2 w3+ assert $ heyting3 w1 w2 w3+ assert $ heyting4 w1 w2 w3+ assert $ heyting5 w1 w2 w3+ assert $ heyting6 w1 w2+ assert $ heyting7 w1 w2+ assert $ heyting8 w1+ assert $ heyting9 w1 w2+ assert $ heyting10 w1 w2+ assert $ heyting11 w1 w2+ assert $ heyting12 w1 w2+ assert $ heyting13 w1 w2+ assert $ heyting14 w1+ assert $ heyting15 w1+ assert $ heyting16 w1+ assert $ heyting17 w1 prop_symmetric :: Property prop_symmetric = withTests 1000 . property $ do
+ test/doctest.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}++import Test.DocTest+import Prelude (IO)++main :: IO ()+main =+ doctest+ [ "-isrc"+ , "src/Data/Connection.hs"+ , "src/Data/Connection/Conn.hs"+ , "src/Data/Connection/Class.hs"+ , "src/Data/Connection/Float.hs"+ ]
test/test.hs view
@@ -1,31 +1,32 @@ import Control.Monad import System.Exit (exitFailure)-import System.IO (BufferMode(..), hSetBuffering, stdout, stderr)+import System.IO (BufferMode (..), hSetBuffering, stderr, stdout) -import qualified Test.Data.Order as P-import qualified Test.Data.Lattice as L import qualified Test.Data.Connection as C-import qualified Test.Data.Connection.Int as CI-import qualified Test.Data.Connection.Word as CW import qualified Test.Data.Connection.Float as CF+import qualified Test.Data.Connection.Int as CI import qualified Test.Data.Connection.Ratio as CR+import qualified Test.Data.Connection.Word as CW+import qualified Test.Data.Lattice as L+import qualified Test.Data.Order as P tests :: IO [Bool]-tests = sequence - [ P.tests- , L.tests- , C.tests- , CI.tests- , CW.tests- , CF.tests- , CR.tests- ]+tests =+ sequence+ [ P.tests+ , L.tests+ , C.tests+ , CI.tests+ , CW.tests+ , CF.tests+ , CR.tests+ ] main :: IO () main = do- hSetBuffering stdout LineBuffering- hSetBuffering stderr LineBuffering+ hSetBuffering stdout LineBuffering+ hSetBuffering stderr LineBuffering - results <- tests+ results <- tests - unless (and results) exitFailure+ unless (and results) exitFailure