packages feed

twee-lib 2.6.1 → 2.7.1

raw patch · 28 files changed

+1060/−247 lines, 28 filesdep +binarydep +deepseqdep −cerealdep ~randomPVP ok

version bump matches the API change (PVP)

Dependencies added: binary, deepseq

Dependencies removed: cereal

Dependency ranges changed: random

API changes (from Hackage documentation)

- Twee: [cfg_score_cp] :: Config f -> Depth -> Index f (Hint f) -> Equation f -> Float
- Twee: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Goal f)
- Twee.Base: instance Data.Serialize.Serialize Twee.Base.Id
- Twee.CP: Hint :: {-# UNPACK #-} !Term f -> {-# UNPACK #-} !Float -> Hint f
- Twee.CP: [cfg_funweight] :: Config -> !Float
- Twee.CP: [cfg_resonance] :: Config -> !Bool
- Twee.CP: [hint_cost] :: Hint f -> {-# UNPACK #-} !Float
- Twee.CP: [hint_term] :: Hint f -> {-# UNPACK #-} !Term f
- Twee.CP: data Hint f
- Twee.CP: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show a, GHC.Show.Show f) => GHC.Show.Show (Twee.CP.Overlap a f)
- Twee.CP: instance Data.Serialize.Serialize Twee.CP.How
- Twee.CP: instance GHC.Enum.Enum Twee.CP.Depth
- Twee.CP: instance GHC.Num.Num Twee.CP.Depth
- Twee.CP: instance GHC.Real.Integral Twee.CP.Depth
- Twee.CP: instance GHC.Real.Real Twee.CP.Depth
- Twee.CP: instance Twee.Base.Symbolic (Twee.CP.Hint f)
- Twee.Equation: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Equation.Equation f)
- Twee.Index: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f, GHC.Show.Show a) => GHC.Show.Show (Twee.Index.Index f a)
- Twee.KBO: class Weighted f
- Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.Weighted f) => Twee.KBO.Sized (Twee.Equation.Equation f)
- Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.Weighted f) => Twee.KBO.Sized (Twee.Term.Core.Term f)
- Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.Weighted f) => Twee.KBO.Sized (Twee.Term.Core.TermList f)
- Twee.KBO: instance (Twee.KBO.Weighted f, Data.Intern.Intern f) => Twee.KBO.Weighted (Data.Intern.Sym f)
- Twee.Proof: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Axiom f)
- Twee.Proof: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Derivation f)
- Twee.Proof: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Presentation f)
- Twee.Proof: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Proof f)
- Twee.Proof: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.ProvedGoal f)
- Twee.Rule: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Rule.Rule f)
- Twee.Rule: instance (GHC.Show.Show f, Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f) => GHC.Show.Show (Twee.Rule.Orientation f)
- Twee.Rule.Index: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f, GHC.Show.Show a) => GHC.Show.Show (Twee.Rule.Index.RuleIndex f a)
- Twee.Term: instance (Data.Typeable.Internal.Typeable f, GHC.Classes.Ord f, GHC.Show.Show f) => GHC.Show.Show (Twee.Term.TriangleSubst f)
- Twee.Utils: U16 :: Int -> U16
- Twee.Utils: U8 :: Int -> U8
- Twee.Utils: instance Data.Serialize.Serialize Twee.Utils.U16
- Twee.Utils: instance Data.Serialize.Serialize Twee.Utils.U8
- Twee.Utils: instance GHC.Classes.Eq Twee.Utils.U16
- Twee.Utils: instance GHC.Classes.Eq Twee.Utils.U8
- Twee.Utils: instance GHC.Classes.Ord Twee.Utils.U16
- Twee.Utils: instance GHC.Classes.Ord Twee.Utils.U8
- Twee.Utils: instance GHC.Enum.Enum Twee.Utils.U16
- Twee.Utils: instance GHC.Enum.Enum Twee.Utils.U8
- Twee.Utils: instance GHC.Num.Num Twee.Utils.U16
- Twee.Utils: instance GHC.Num.Num Twee.Utils.U8
- Twee.Utils: instance GHC.Real.Integral Twee.Utils.U16
- Twee.Utils: instance GHC.Real.Integral Twee.Utils.U8
- Twee.Utils: instance GHC.Real.Real Twee.Utils.U16
- Twee.Utils: instance GHC.Real.Real Twee.Utils.U8
- Twee.Utils: newtype U16
- Twee.Utils: newtype U8
+ Data.BatchedQueue: -- calling <a>insert</a>. A label represents a piece of information which
+ Data.BatchedQueue: -- default <tt>Label a = ()</tt>.
+ Data.BatchedQueue: -- is shared in common between all entries in a batch, and which might be
+ Data.BatchedQueue: -- used to store that batch more efficiently. Labels are optional, and by
+ Data.BatchedQueue: -- | Individual entries in the batch.
+ Data.BatchedQueue: batchLabel :: Batch a => a -> Label a
+ Data.BatchedQueue: batchSize :: Batch a => a -> Int
+ Data.BatchedQueue: class Ord Entry a => Batch a where {
+ Data.BatchedQueue: data Queue a
+ Data.BatchedQueue: data StandardBatch a
+ Data.BatchedQueue: empty :: Queue a
+ Data.BatchedQueue: insert :: Batch a => Label a -> [Entry a] -> Queue a -> Queue a
+ Data.BatchedQueue: instance (GHC.Classes.Ord a, Data.Binary.Class.Binary a) => Data.BatchedQueue.Batch (Data.BatchedQueue.StandardBatch a)
+ Data.BatchedQueue: instance Data.BatchedQueue.Batch a => GHC.Classes.Eq (Data.BatchedQueue.Best a)
+ Data.BatchedQueue: instance Data.BatchedQueue.Batch a => GHC.Classes.Ord (Data.BatchedQueue.Best a)
+ Data.BatchedQueue: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.BatchedQueue.Best a)
+ Data.BatchedQueue: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.BatchedQueue.Queue a)
+ Data.BatchedQueue: instance GHC.Classes.Ord a => GHC.Classes.Eq (Data.BatchedQueue.StandardBatch a)
+ Data.BatchedQueue: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.BatchedQueue.StandardBatch a)
+ Data.BatchedQueue: makeBatch :: Batch a => Label a -> [Entry a] -> [a]
+ Data.BatchedQueue: mapMaybe :: Batch a => (Entry a -> Maybe (Entry a)) -> Queue a -> Queue a
+ Data.BatchedQueue: removeMin :: Batch a => Queue a -> Maybe (Entry a, Queue a)
+ Data.BatchedQueue: removeMinFilter :: Batch a => (Label a -> Bool) -> Queue a -> Maybe (Entry a, Queue a)
+ Data.BatchedQueue: size :: Batch a => Queue a -> Int
+ Data.BatchedQueue: toBatches :: Queue a -> [a]
+ Data.BatchedQueue: toList :: Batch a => Queue a -> [Entry a]
+ Data.BatchedQueue: type Entry a;
+ Data.BatchedQueue: type Label a = ();
+ Data.BatchedQueue: unbatch :: Batch a => a -> [Entry a]
+ Data.BatchedQueue: unconsBatch :: Batch a => a -> (Entry a, Maybe a)
+ Data.BatchedQueue: }
+ Data.Binary.Sharing: ($dmget) :: (Binary a, Generic a, GBinary (Rep a)) => Get a
+ Data.Binary.Sharing: ($dmput) :: (Binary a, Generic a, GBinary (Rep a)) => a -> Put
+ Data.Binary.Sharing: ReadShowBinary :: a -> ReadShowBinary a
+ Data.Binary.Sharing: Shared :: a -> Shared a
+ Data.Binary.Sharing: [getReadShowBinary] :: ReadShowBinary a -> a
+ Data.Binary.Sharing: [getShared] :: Shared a -> a
+ Data.Binary.Sharing: class Binary a
+ Data.Binary.Sharing: data Get a
+ Data.Binary.Sharing: data PutM a
+ Data.Binary.Sharing: decode :: Binary a => ByteString -> a
+ Data.Binary.Sharing: decodeFile :: Binary a => FilePath -> IO a
+ Data.Binary.Sharing: encode :: Binary a => a -> ByteString
+ Data.Binary.Sharing: encodeFile :: Binary a => FilePath -> a -> IO ()
+ Data.Binary.Sharing: get :: Binary a => Get a
+ Data.Binary.Sharing: getInt8 :: Get Int8
+ Data.Binary.Sharing: getIntegral :: (Integral a, Bits a) => Get a
+ Data.Binary.Sharing: getList :: Get a -> Get [a]
+ Data.Binary.Sharing: getWord8 :: Get Word8
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary b) => Data.Binary.Sharing.Binary (Data.Either.Either a b)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary b) => Data.Binary.Sharing.Binary (a, b)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary b, Data.Binary.Sharing.Binary c) => Data.Binary.Sharing.Binary (a, b, c)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary b, Data.Binary.Sharing.Binary c, Data.Binary.Sharing.Binary d) => Data.Binary.Sharing.Binary (a, b, c, d)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary b, Data.Binary.Sharing.Binary c, Data.Binary.Sharing.Binary d, Data.Binary.Sharing.Binary e) => Data.Binary.Sharing.Binary (a, b, c, d, e)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary k, Data.Binary.Sharing.Binary v, Data.Hashable.Class.Hashable k) => Data.Binary.Sharing.Binary (Data.HashMap.Internal.HashMap k v)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary k, Data.Binary.Sharing.Binary v, GHC.Classes.Ord k) => Data.Binary.Sharing.Binary (Data.Map.Internal.Map k v)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary k, Data.Hashable.Class.Hashable k) => Data.Binary.Sharing.Binary (Data.HashSet.Internal.HashSet k)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.Binary k, GHC.Classes.Ord k) => Data.Binary.Sharing.Binary (Data.Set.Internal.Set k)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.GBinary f, Data.Binary.Sharing.GBinary g) => Data.Binary.Sharing.GBinary (f GHC.Generics.:*: g)
+ Data.Binary.Sharing: instance (Data.Binary.Sharing.GBinary f, Data.Binary.Sharing.GBinary g) => Data.Binary.Sharing.GBinary (f GHC.Generics.:+: g)
+ Data.Binary.Sharing: instance (Data.Typeable.Internal.Typeable a, GHC.Classes.Eq a, Data.Hashable.Class.Hashable a, Data.Binary.Sharing.Binary a) => Data.Binary.Sharing.Binary (Data.Binary.Sharing.Shared a)
+ Data.Binary.Sharing: instance (GHC.Show.Show a, GHC.Read.Read a) => Data.Binary.Sharing.Binary (Data.Binary.Sharing.ReadShowBinary a)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary ()
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary Data.ByteString.Internal.Type.ByteString
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary Data.ByteString.Lazy.Internal.ByteString
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary Data.IntSet.Internal.IntSet
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Int.Int16
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Int.Int32
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Int.Int64
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Int.Int8
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Num.Integer.Integer
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Bool
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Char
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Double
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Float
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Int
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Types.Word
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Word.Word16
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Word.Word32
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Word.Word64
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary GHC.Word.Word8
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.Binary.Sharing.SharedEncoding a)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.Primitive.SmallArray.SmallArray a)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (GHC.Maybe.Maybe a)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary [a]
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.GBinary (GHC.Generics.K1 i a)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.Binary v => Data.Binary.Sharing.Binary (Data.IntMap.Internal.IntMap v)
+ Data.Binary.Sharing: instance Data.Binary.Sharing.GBinary GHC.Generics.U1
+ Data.Binary.Sharing: instance Data.Binary.Sharing.GBinary GHC.Generics.V1
+ Data.Binary.Sharing: instance Data.Binary.Sharing.GBinary f => Data.Binary.Sharing.GBinary (GHC.Generics.M1 i c f)
+ Data.Binary.Sharing: instance Data.Hashable.Class.Hashable Data.Binary.Sharing.Value
+ Data.Binary.Sharing: instance GHC.Base.Applicative Data.Binary.Sharing.Get
+ Data.Binary.Sharing: instance GHC.Base.Applicative Data.Binary.Sharing.PutM
+ Data.Binary.Sharing: instance GHC.Base.Functor Data.Binary.Sharing.Get
+ Data.Binary.Sharing: instance GHC.Base.Functor Data.Binary.Sharing.PutM
+ Data.Binary.Sharing: instance GHC.Base.Monad Data.Binary.Sharing.Get
+ Data.Binary.Sharing: instance GHC.Base.Monad Data.Binary.Sharing.PutM
+ Data.Binary.Sharing: instance GHC.Base.Monoid Data.Binary.Sharing.Put
+ Data.Binary.Sharing: instance GHC.Base.Semigroup Data.Binary.Sharing.Put
+ Data.Binary.Sharing: instance GHC.Classes.Eq Data.Binary.Sharing.Value
+ Data.Binary.Sharing: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Binary.Sharing.Shared a)
+ Data.Binary.Sharing: instance GHC.Show.Show a => GHC.Show.Show (Data.Binary.Sharing.Shared a)
+ Data.Binary.Sharing: liftGet :: Get a -> Get a
+ Data.Binary.Sharing: liftPut :: PutM a -> PutM a
+ Data.Binary.Sharing: newtype ReadShowBinary a
+ Data.Binary.Sharing: newtype Shared a
+ Data.Binary.Sharing: put :: Binary a => a -> Put
+ Data.Binary.Sharing: putInt8 :: Int8 -> PutM ()
+ Data.Binary.Sharing: putIntegral :: (Integral a, Bits a) => a -> Put
+ Data.Binary.Sharing: putList :: (a -> Put) -> [a] -> Put
+ Data.Binary.Sharing: putWord8 :: Word8 -> PutM ()
+ Data.Binary.Sharing: runGet :: Get a -> ByteString -> a
+ Data.Binary.Sharing: runPut :: Put -> ByteString
+ Data.Binary.Sharing: type Put = PutM ()
+ Data.Binary.Sharing: unliftGet :: Get a -> Get a
+ Data.Binary.Sharing: unliftPut :: PutM a -> PutM a
+ Data.ChurchList: ChurchList :: (forall b. () => (a -> b -> b) -> b -> b) -> ChurchList a
+ Data.ChurchList: append :: ChurchList a -> ChurchList a -> ChurchList a
+ Data.ChurchList: cons :: a -> ChurchList a -> ChurchList a
+ Data.ChurchList: eta :: a -> a
+ Data.ChurchList: filter :: (a -> Bool) -> ChurchList a -> ChurchList a
+ Data.ChurchList: foldl' :: (b -> a -> b) -> b -> ChurchList a -> b
+ Data.ChurchList: foldr :: (a -> b -> b) -> b -> ChurchList a -> b
+ Data.ChurchList: fromList :: [a] -> ChurchList a
+ Data.ChurchList: fromMaybe :: Maybe a -> ChurchList a
+ Data.ChurchList: instance GHC.Base.Alternative Data.ChurchList.ChurchList
+ Data.ChurchList: instance GHC.Base.Applicative Data.ChurchList.ChurchList
+ Data.ChurchList: instance GHC.Base.Functor Data.ChurchList.ChurchList
+ Data.ChurchList: instance GHC.Base.Monad Data.ChurchList.ChurchList
+ Data.ChurchList: instance GHC.Base.MonadPlus Data.ChurchList.ChurchList
+ Data.ChurchList: join :: ChurchList (ChurchList a) -> ChurchList a
+ Data.ChurchList: newtype ChurchList a
+ Data.ChurchList: nil :: ChurchList a
+ Data.ChurchList: null :: ChurchList a -> Bool
+ Data.ChurchList: toList :: ChurchList a -> [a]
+ Data.ChurchList: unit :: a -> ChurchList a
+ Data.DynamicArray: (!) :: Default a => Array a -> Int -> a
+ Data.DynamicArray: Array :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !SmallArray a -> Array a
+ Data.DynamicArray: [arrayContents] :: Array a -> {-# UNPACK #-} !SmallArray a
+ Data.DynamicArray: [arrayStart] :: Array a -> {-# UNPACK #-} !Int
+ Data.DynamicArray: arraySize :: Array a -> Int
+ Data.DynamicArray: class Default a
+ Data.DynamicArray: data Array a
+ Data.DynamicArray: def :: Default a => a
+ Data.DynamicArray: getWithDefault :: a -> Int -> Array a -> a
+ Data.DynamicArray: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.DynamicArray.Array a)
+ Data.DynamicArray: instance GHC.Generics.Generic (Data.DynamicArray.Array a)
+ Data.DynamicArray: instance GHC.Show.Show a => GHC.Show.Show (Data.DynamicArray.Array a)
+ Data.DynamicArray: newArray :: Array a
+ Data.DynamicArray: singleton :: Default a => Int -> a -> Array a
+ Data.DynamicArray: toList :: Array a -> [(Int, a)]
+ Data.DynamicArray: update :: Default a => Int -> a -> Array a -> Array a
+ Data.DynamicArray: updateWithDefault :: a -> Int -> a -> Array a -> Array a
+ Data.Heap: data Heap a
+ Data.Heap: empty :: Heap a
+ Data.Heap: insert :: Ord a => a -> Heap a -> Heap a
+ Data.Heap: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.Heap.Heap a)
+ Data.Heap: instance GHC.Generics.Generic (Data.Heap.Heap a)
+ Data.Heap: instance GHC.Show.Show a => GHC.Show.Show (Data.Heap.Heap a)
+ Data.Heap: mapMaybe :: forall a b. Ord b => (a -> Maybe b) -> Heap a -> Heap b
+ Data.Heap: removeMin :: Ord a => Heap a -> Maybe (a, Heap a)
+ Data.Heap: singleton :: a -> Heap a
+ Data.Heap: size :: Heap a -> Int
+ Data.Heap: toList :: Heap a -> [a]
+ Data.Heap: union :: Ord a => Heap a -> Heap a -> Heap a
+ Data.Intern: instance (Data.Intern.Intern a, Data.Binary.Sharing.Binary a) => Data.Binary.Sharing.Binary (Data.Intern.Sym a)
+ Data.Intern: instance Data.Hashable.Class.Hashable (Data.Intern.Sym a)
+ Data.Numbered: (!) :: Numbered a -> Int -> (Int, a)
+ Data.Numbered: data Numbered a
+ Data.Numbered: delete :: Int -> Numbered a -> Numbered a
+ Data.Numbered: empty :: Numbered a
+ Data.Numbered: filter :: (a -> Bool) -> Numbered a -> Numbered a
+ Data.Numbered: fromList :: [(Int, a)] -> Numbered a
+ Data.Numbered: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Data.Numbered.Numbered a)
+ Data.Numbered: instance GHC.Show.Show a => GHC.Show.Show (Data.Numbered.Numbered a)
+ Data.Numbered: lookup :: Int -> Numbered a -> Maybe a
+ Data.Numbered: modify :: Int -> a -> (a -> a) -> Numbered a -> Numbered a
+ Data.Numbered: put :: Int -> a -> Numbered a -> Numbered a
+ Data.Numbered: singleton :: Int -> a -> Numbered a
+ Data.Numbered: size :: Numbered a -> Int
+ Data.Numbered: toList :: Numbered a -> [(Int, a)]
+ Data.PackedSequence: data PackedSequence a
+ Data.PackedSequence: empty :: PackedSequence a
+ Data.PackedSequence: fromList :: Binary a => [a] -> PackedSequence a
+ Data.PackedSequence: instance Data.Binary.Sharing.Binary (Data.PackedSequence.PackedSequence a)
+ Data.PackedSequence: instance GHC.Classes.Eq (Data.PackedSequence.PackedSequence a)
+ Data.PackedSequence: instance GHC.Generics.Generic (Data.PackedSequence.PackedSequence a)
+ Data.PackedSequence: null :: PackedSequence a -> Bool
+ Data.PackedSequence: size :: PackedSequence a -> Int
+ Data.PackedSequence: toList :: Binary a => PackedSequence a -> [a]
+ Data.PackedSequence: uncons :: Binary a => PackedSequence a -> Maybe (a, PackedSequence a)
+ Twee: DerivedHint :: HintKind
+ Twee: Hints :: ![Rule f] -> !Index f (Rule f) -> !Int -> Hints f
+ Twee: NewHint :: !Rule f -> !HintKind -> Message f
+ Twee: UserHint :: HintKind
+ Twee: [cfg_cp_config] :: Config f -> !Config
+ Twee: [cfg_hint_func] :: Config f -> Int -> Float -> Sym f
+ Twee: [hints_index] :: Hints f -> !Index f (Rule f)
+ Twee: [hints_list] :: Hints f -> ![Rule f]
+ Twee: [hints_next] :: Hints f -> !Int
+ Twee: addHint' :: Function f => Config f -> State f -> Term f -> HintKind -> Float -> State f
+ Twee: addHintHintsPairs :: Function f => Config f -> Rule f -> State f -> State f
+ Twee: addHintRulePairs :: Function f => Config f -> Rule f -> Active f -> State f -> State f
+ Twee: addHintRulesPairs :: Function f => Config f -> Rule f -> State f -> State f
+ Twee: addHintsRulePairs :: Function f => Config f -> Active f -> State f -> State f
+ Twee: applyHints :: Function f => Hints f -> Term f -> Term f
+ Twee: data HintKind
+ Twee: data Hints f
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Active f)
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Goal f)
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Hints f)
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Message f)
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.State f)
+ Twee: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Goal f)
+ Twee: instance Data.Binary.Sharing.Binary Twee.Batch
+ Twee: instance Data.Binary.Sharing.Binary Twee.BatchKind
+ Twee: instance Data.Binary.Sharing.Binary Twee.HintKind
+ Twee: instance Data.Binary.Sharing.Binary Twee.Info
+ Twee: instance Data.Binary.Sharing.Binary Twee.Passive
+ Twee: instance GHC.Classes.Eq Twee.Batch
+ Twee: instance GHC.Classes.Eq Twee.HintKind
+ Twee: instance GHC.Generics.Generic (Twee.Active f)
+ Twee: instance GHC.Generics.Generic (Twee.Goal f)
+ Twee: instance GHC.Generics.Generic (Twee.Hints f)
+ Twee: instance GHC.Generics.Generic (Twee.Message f)
+ Twee: instance GHC.Generics.Generic (Twee.State f)
+ Twee: instance GHC.Generics.Generic Twee.Batch
+ Twee: instance GHC.Generics.Generic Twee.BatchKind
+ Twee: instance GHC.Generics.Generic Twee.HintKind
+ Twee: instance GHC.Generics.Generic Twee.Info
+ Twee: instance GHC.Generics.Generic Twee.Passive
+ Twee: instance GHC.Show.Show Twee.HintKind
+ Twee: instance Text.PrettyPrint.HughesPJClass.Pretty Twee.HintKind
+ Twee: scoreCP :: Function f => Config f -> Depth -> Hints f -> Equation f -> Float
+ Twee: scoreTerm :: Function f => Config f -> Hints f -> Term f -> Float
+ Twee.Base: class Weighted f
+ Twee.Base: instance Data.Binary.Class.Binary Twee.Base.Id
+ Twee.Base: instance Data.Binary.Sharing.Binary Twee.Base.Id
+ Twee.Base: instance Twee.Base.Weighted f => Twee.Base.Weighted (Data.Intern.Sym f)
+ Twee.Base: weight :: Weighted f => f -> Float
+ Twee.CP: [getDepth] :: Depth -> Int
+ Twee.CP: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary a, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.CP.Overlap a f)
+ Twee.CP: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show a, GHC.Show.Show f) => GHC.Show.Show (Twee.CP.Overlap a f)
+ Twee.CP: instance Data.Binary.Class.Binary Twee.CP.How
+ Twee.CP: instance Data.Binary.Sharing.Binary (Twee.CP.Positions f)
+ Twee.CP: instance Data.Binary.Sharing.Binary (Twee.CP.Positions2 f)
+ Twee.CP: instance Data.Binary.Sharing.Binary Twee.CP.Depth
+ Twee.CP: instance Data.Binary.Sharing.Binary Twee.CP.Direction
+ Twee.CP: instance Data.Binary.Sharing.Binary Twee.CP.How
+ Twee.CP: instance GHC.Generics.Generic (Twee.CP.Overlap a f)
+ Twee.CP: instance GHC.Generics.Generic (Twee.CP.Positions2 f)
+ Twee.CP: instance GHC.Generics.Generic Twee.CP.Depth
+ Twee.CP: instance GHC.Generics.Generic Twee.CP.Direction
+ Twee.CP: termScore :: Function f => Config -> Term f -> Float
+ Twee.Constraints: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Constraints.Atom f)
+ Twee.Constraints: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Constraints.Model f)
+ Twee.Constraints: instance GHC.Classes.Ord (Twee.Constraints.Model f)
+ Twee.Constraints: instance GHC.Generics.Generic (Twee.Constraints.Atom f)
+ Twee.Constraints: instance GHC.Generics.Generic (Twee.Constraints.Model f)
+ Twee.Constraints: modelFromOrder' :: (Minimal f, Ord f) => [[Atom f]] -> Model f
+ Twee.Equation: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Equation.Equation f)
+ Twee.Equation: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Equation.Equation f)
+ Twee.Equation: instance Data.Hashable.Class.Hashable (Twee.Equation.Equation f)
+ Twee.Equation: instance GHC.Generics.Generic (Twee.Equation.Equation f)
+ Twee.Index: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f, Data.Binary.Sharing.Binary a) => Data.Binary.Sharing.Binary (Twee.Index.Index f a)
+ Twee.Index: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f, Data.Binary.Sharing.Binary a) => Data.Binary.Sharing.Binary (Twee.Index.SIndex f a)
+ Twee.Index: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f, GHC.Show.Show a) => GHC.Show.Show (Twee.Index.Index f a)
+ Twee.Index: instance GHC.Generics.Generic (Twee.Index.SIndex f a)
+ Twee.KBO: class ArgWeighted f
+ Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.ArgWeighted f) => Twee.KBO.Sized (Twee.Equation.Equation f)
+ Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.ArgWeighted f) => Twee.KBO.Sized (Twee.Term.Core.Term f)
+ Twee.KBO: instance (Data.Intern.Intern f, Twee.KBO.Sized f, Twee.KBO.ArgWeighted f) => Twee.KBO.Sized (Twee.Term.Core.TermList f)
+ Twee.KBO: instance (Twee.KBO.ArgWeighted f, Data.Intern.Intern f) => Twee.KBO.ArgWeighted (Data.Intern.Sym f)
+ Twee.LPO: lessEq :: Function f => Term f -> Term f -> Bool
+ Twee.LPO: lessEqBasic :: Function f => Term f -> Term f -> Bool
+ Twee.LPO: lessEqSkolem :: Function f => Term f -> Term f -> Bool
+ Twee.LPO: lessIn :: Function f => Model f -> Term f -> Term f -> Maybe Strictness
+ Twee.Proof: [axiom_vars] :: Axiom f -> !Maybe (Map Var String)
+ Twee.Proof: [pg_vars] :: ProvedGoal f -> Maybe (Map Var String)
+ Twee.Proof: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Proof.Axiom f)
+ Twee.Proof: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Proof.Proof f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Proof.Derivation f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Proof.Presentation f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Proof.ProvedGoal f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Axiom f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Derivation f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Presentation f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.Proof f)
+ Twee.Proof: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Proof.ProvedGoal f)
+ Twee.Proof: instance Data.Hashable.Class.Hashable (Twee.Proof.Axiom f)
+ Twee.Proof: instance Data.Hashable.Class.Hashable (Twee.Proof.Derivation f)
+ Twee.Proof: instance Data.Hashable.Class.Hashable (Twee.Proof.Proof f)
+ Twee.Proof: instance Data.Hashable.Class.Hashable f => Data.Hashable.Class.Hashable (Twee.Proof.PrettyVars f)
+ Twee.Proof: instance GHC.Classes.Eq f => GHC.Classes.Eq (Twee.Proof.PrettyVars f)
+ Twee.Proof: instance GHC.Generics.Generic (Twee.Proof.Axiom f)
+ Twee.Proof: instance GHC.Generics.Generic (Twee.Proof.Derivation f)
+ Twee.Proof: instance GHC.Generics.Generic (Twee.Proof.Presentation f)
+ Twee.Proof: instance GHC.Generics.Generic (Twee.Proof.PrettyVars f)
+ Twee.Proof: instance GHC.Generics.Generic (Twee.Proof.ProvedGoal f)
+ Twee.Proof: instance Text.PrettyPrint.HughesPJClass.Pretty f => Text.PrettyPrint.HughesPJClass.Pretty (Twee.Proof.PrettyVars f)
+ Twee.Proof: instance Twee.Pretty.PrettyTerm f => Twee.Pretty.PrettyTerm (Twee.Proof.PrettyVars f)
+ Twee.Rule: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Rule.ConfluenceFailure f)
+ Twee.Rule: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Rule.Orientation f)
+ Twee.Rule: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Rule.Rule f)
+ Twee.Rule: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Rule.Rule f)
+ Twee.Rule: instance (GHC.Show.Show f, Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f) => GHC.Show.Show (Twee.Rule.Orientation f)
+ Twee.Rule: instance GHC.Generics.Generic (Twee.Rule.ConfluenceFailure f)
+ Twee.Rule: instance GHC.Generics.Generic (Twee.Rule.Orientation f)
+ Twee.Rule: instance GHC.Generics.Generic (Twee.Rule.Rule f)
+ Twee.Rule.Index: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, Data.Binary.Sharing.Binary f, Data.Binary.Sharing.Binary a) => Data.Binary.Sharing.Binary (Twee.Rule.Index.RuleIndex f a)
+ Twee.Rule.Index: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f, GHC.Show.Show a) => GHC.Show.Show (Twee.Rule.Index.RuleIndex f a)
+ Twee.Rule.Index: instance GHC.Generics.Generic (Twee.Rule.Index.RuleIndex f a)
+ Twee.Term: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Term.Core.Term f)
+ Twee.Term: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Term.Core.TermList f)
+ Twee.Term: instance (Data.Intern.Intern f, Data.Binary.Sharing.Binary f) => Data.Binary.Sharing.Binary (Twee.Term.Subst f)
+ Twee.Term: instance (Data.Typeable.Internal.Typeable f, Data.Hashable.Class.Hashable f, GHC.Show.Show f) => GHC.Show.Show (Twee.Term.TriangleSubst f)
+ Twee.Term: instance Data.Binary.Sharing.Binary Twee.Term.Core.Var
+ Twee.Term: instance Data.Hashable.Class.Hashable (Twee.Term.Core.Term f)
+ Twee.Term: instance Data.Hashable.Class.Hashable (Twee.Term.Core.TermList f)
+ Twee.Term: instance Data.Hashable.Class.Hashable (Twee.Term.Subst f)
+ Twee.Term: instance Data.Hashable.Class.Hashable Twee.Term.Core.Var
+ Twee.Utils: fastNub :: Ord a => [a] -> [a]
+ Twee.Utils: instance Data.Binary.Sharing.Binary a => Data.Binary.Sharing.Binary (Twee.Utils.Sample a)
- Data.Intern: type Intern a = (Typeable a, Ord a)
+ Data.Intern: type Intern a = (Typeable a, Eq a, Hashable a)
- Twee: Config :: Maybe (Term f -> Bool) -> Int64 -> Int -> Int -> Maybe Double -> Bool -> Int -> Int -> Int -> Bool -> Bool -> Bool -> (Depth -> Index f (Hint f) -> Equation f -> Float) -> Config -> Config f -> [Axiom f] -> Bool -> Bool -> Bool -> Int -> Bool -> Float -> Float -> Bool -> Config f
+ Twee: Config :: Maybe (Term f -> Bool) -> Int64 -> Int -> Int -> Maybe Double -> Bool -> Int -> Int -> Int -> Bool -> Bool -> Bool -> (Int -> Float -> Sym f) -> !Config -> Config -> Config f -> [Axiom f] -> Bool -> Bool -> Bool -> Int -> Bool -> Float -> Float -> Bool -> Config f
- Twee: State :: ![Axiom f] -> !RuleIndex f (Rule f) -> !IntMap (Active f) -> !Index f (Equation f) -> ![Goal f] -> !Queue Batch -> !Index f (Hint f) -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Int64 -> {-# UNPACK #-} !Id -> !Sample (Maybe (Overlap (Active f) f)) -> !IntSet -> !Index f (Rule f) -> ![Message f] -> Maybe QCGen -> Maybe (ConfluenceFailure f) -> State f
+ Twee: State :: ![Axiom f] -> !RuleIndex f (Rule f) -> !IntMap (Active f) -> !Index f (Equation f) -> ![Goal f] -> !Queue Batch -> {-# UNPACK #-} !Hints f -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Int64 -> {-# UNPACK #-} !Id -> !Sample (Maybe (Overlap (Active f) f)) -> !IntSet -> !Index f (Rule f) -> ![Message f] -> Maybe (ReadShowBinary QCGen) -> Maybe (ConfluenceFailure f) -> State f
- Twee: [st_hints] :: State f -> !Index f (Hint f)
+ Twee: [st_hints] :: State f -> {-# UNPACK #-} !Hints f
- Twee: [st_random_seed] :: State f -> Maybe QCGen
+ Twee: [st_random_seed] :: State f -> Maybe (ReadShowBinary QCGen)
- Twee: activeScore :: Config f -> State f -> Active f -> Float
+ Twee: activeScore :: Function f => Config f -> State f -> Active f -> Float
- Twee: addActiveOnly :: Function f => State f -> Active f -> State f
+ Twee: addActiveOnly :: Function f => Config f -> State f -> Active f -> State f
- Twee: addActiveSimp :: Function f => State f -> Active f -> State f
+ Twee: addActiveSimp :: Function f => Config f -> State f -> Active f -> State f
- Twee.Base: type Function f = (Ordered f, Minimal f, PrettyTerm f, EqualsBonus f, Intern f)
+ Twee.Base: type Function f = (Ordered f, Minimal f, PrettyTerm f, EqualsBonus f, Intern f, Weighted f)
- Twee.Base: type Intern a = (Typeable a, Ord a)
+ Twee.Base: type Intern a = (Typeable a, Eq a, Hashable a)
- Twee.CP: Config :: !Float -> !Float -> !Float -> !Float -> !Float -> !Float -> !Float -> !Bool -> Config
+ Twee.CP: Config :: !Float -> !Float -> !Float -> !Float -> !Float -> !Float -> Config
- Twee.CP: score :: Function f => Config -> Depth -> Index f (Hint f) -> Equation f -> Float
+ Twee.CP: score :: Function f => Config -> Depth -> (Term f -> Float) -> Equation f -> Float
- Twee.KBO: argWeight :: Weighted f => f -> Integer
+ Twee.KBO: argWeight :: ArgWeighted f => f -> Integer
- Twee.KBO: lessEq :: (Function f, Sized f, Weighted f) => Term f -> Term f -> Bool
+ Twee.KBO: lessEq :: (Function f, Sized f, ArgWeighted f) => Term f -> Term f -> Bool
- Twee.KBO: lessEqSkolem :: (Function f, Sized f, Weighted f) => Term f -> Term f -> Bool
+ Twee.KBO: lessEqSkolem :: (Function f, Sized f, ArgWeighted f) => Term f -> Term f -> Bool
- Twee.KBO: lessIn :: (Function f, Sized f, Weighted f) => Model f -> Term f -> Term f -> Maybe Strictness
+ Twee.KBO: lessIn :: (Function f, Sized f, ArgWeighted f) => Model f -> Term f -> Term f -> Maybe Strictness
- Twee.Proof: Axiom :: {-# UNPACK #-} !Int -> !String -> !Equation f -> Axiom f
+ Twee.Proof: Axiom :: {-# UNPACK #-} !Int -> !String -> !Maybe (Map Var String) -> !Equation f -> Axiom f
- Twee.Proof: ProvedGoal :: Int -> String -> Proof f -> Equation f -> Subst f -> ProvedGoal f
+ Twee.Proof: ProvedGoal :: Int -> String -> Proof f -> Maybe (Map Var String) -> Equation f -> Subst f -> ProvedGoal f
- Twee.Proof: certify :: Function f => Derivation f -> Proof f
+ Twee.Proof: certify :: Derivation f -> Proof f
- Twee.Proof: describeEquation :: Function f => String -> String -> Maybe String -> Equation f -> Doc
+ Twee.Proof: describeEquation :: Function f => String -> String -> Maybe String -> Maybe (Map Var String) -> Equation f -> Doc

Files

Data/BatchedQueue.hs view
@@ -1,5 +1,5 @@ -- | A queue where entries can be added in batches and stored compactly.-{-# LANGUAGE TypeFamilies, RecordWildCards, FlexibleContexts, ScopedTypeVariables #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.BatchedQueue(   Queue, Batch(..), StandardBatch, unbatch, empty, insert, removeMin, removeMinFilter, mapMaybe, toBatches, toList, size) where @@ -8,11 +8,12 @@ import qualified Data.Maybe import Data.PackedSequence(PackedSequence) import qualified Data.PackedSequence as PackedSequence-import Data.Serialize+import qualified Data.Binary as Cereal+import Data.Binary.Sharing import Data.Ord  -- | A queue of batches.-newtype Queue a = Queue (Heap.Heap (Best a))+newtype Queue a = Queue (Heap.Heap (Best a)) deriving Binary  -- | The type of batches must be a member of this class. class Ord (Entry a) => Batch a where@@ -47,7 +48,7 @@   type Label a = ()  -- A newtype wrapper for batches which compares the smallest entry.-newtype Best a = Best { unBest :: a }+newtype Best a = Best { unBest :: a } deriving Binary instance Batch a => Eq (Best a) where x == y = compare x y == EQ instance Batch a => Ord (Best a) where   {-# INLINEABLE compare #-}@@ -130,7 +131,7 @@ instance Ord a => Ord (StandardBatch a) where   compare = comparing batch_best -instance (Ord a, Serialize a) => Batch (StandardBatch a) where+instance (Ord a, Cereal.Binary a) => Batch (StandardBatch a) where   type Label (StandardBatch a) = ()   type Entry (StandardBatch a) = a 
+ Data/Binary/Sharing.hs view
@@ -0,0 +1,424 @@+-- | A serialisation library with support for sharing. Built on top of binary.++{-# LANGUAGE ConstraintKinds, GADTs, DerivingVia, TypeSynonymInstances, FlexibleInstances, DefaultSignatures, DeriveAnyClass, DeriveFunctor, TupleSections #-}+module Data.Binary.Sharing(Binary(..), Shared(..), Put, PutM, encode, encodeFile, runPut, liftPut, unliftPut, Get, decode, decodeFile, runGet, liftGet, unliftGet, putList, getList, putWord8, getWord8, putInt8, getInt8, putIntegral, getIntegral, ReadShowBinary(..)) where+import qualified Data.Binary as S+import qualified Data.Binary.Get as S+import qualified Data.Binary.Put as S+import Data.Typeable+import qualified Data.HashMap.Strict as HashMap+import Data.HashMap.Strict(HashMap)+import Data.Maybe+import GHC.Generics+import Data.Hashable+import Control.Monad+import Data.Bits+import Data.Word+import Data.Int+import Data.Char+import qualified Data.ByteString.Lazy as BS+import qualified Data.ByteString as BSS+import Control.Monad.Trans.State.Strict hiding (get, put)+import qualified Control.Monad.Trans.State.Strict as State+import qualified Data.Primitive.SmallArray as SmallArray+import qualified Data.Foldable as Foldable+import qualified Data.Map as Map+import qualified Data.IntMap as IntMap+import qualified Data.Set as Set+import qualified Data.IntSet as IntSet+import qualified Data.HashSet as HashSet++----------------------------------------------------------------------+-- The basic serialiser/deserialiser types.+--+-- The idea is that both serialisation and deserialisation maintain a+-- store of shared values we have already seen (each associated with an+-- ID). When we emit a value we have already seen, we instead just emit+-- its ID. This is handled in the "Binary (Shared a)" instance.+----------------------------------------------------------------------++-- | A serialiser.+newtype PutM a = PutM { unPutM :: Store -> S.PutM (a, Store) } deriving Functor+-- Note we can't use StateT because then generalised newtype deriving doesn't work+instance Applicative PutM where+  pure x = PutM $ \store -> pure (x, store)+  mf <*> mx = mf >>= \f -> mx >>= \x -> pure (f x)+instance Monad PutM where+  mx >>= f =+    PutM $ \store -> do+      (x, store) <- unPutM mx store+      unPutM (f x) store+type Put = PutM ()++instance Semigroup Put where+  mx <> my = do { mx; my }++instance Monoid Put where+  mempty = pure mempty++-- Lift a state-monadic computation into Put.+liftStatePut :: State Store a -> PutM a+liftStatePut act = PutM $ \store -> return (runState act store)++-- | Lift a binary serialiser into Put.+liftPut :: S.PutM a -> PutM a+liftPut putter = PutM $ \store -> (, store) <$> putter++-- | Convert a 'Put' back into a binary serialiser.+unliftPut :: PutM a -> S.PutM a+unliftPut (PutM putter) = fst <$> putter emptyStore++-- | Serialise a value.+runPut :: Put -> BS.ByteString+runPut = S.runPut . unliftPut++-- | Serialise a value.+encode :: Binary a => a -> BS.ByteString+encode = runPut . put++-- | Serialise a value to a file.+encodeFile :: Binary a => FilePath -> a -> IO ()+encodeFile path = BS.writeFile path . encode++-- | A deserialiser.+newtype Get a = Get { unGet :: Store -> S.Get (a, Store) } deriving Functor+instance Applicative Get where+  pure x = Get $ \store -> pure (x, store)+  mf <*> mx = mf >>= \f -> mx >>= \x -> pure (f x)+instance Monad Get where+  mx >>= f =+    Get $ \store -> do+      (x, store) <- unGet mx store+      unGet (f x) store++-- Lift a state-monadic computation into Get.+liftStateGet :: State Store a -> Get a+liftStateGet act = Get $ \store -> return (runState act store)++-- | Lift a binary serialiser into Get.+liftGet :: S.Get a -> Get a+liftGet getter = Get $ \store -> (, store) <$> getter++-- | Convert a 'Get' back into a binary serialiser.+unliftGet :: Get a -> S.Get a+unliftGet (Get getter) = fst <$> getter emptyStore++-- | Deserialise a value.+runGet :: Get a -> BS.ByteString -> a+runGet = S.runGet . unliftGet++-- | Deserialise a value.+decode :: Binary a => BS.ByteString -> a+decode = runGet get++-- | Deserialise a value from a file.+decodeFile :: Binary a => FilePath -> IO a+decodeFile path = decode <$> BS.readFile path++----------------------------------------------------------------------+-- The sharing primitive.+----------------------------------------------------------------------++-- | A newtype wrapper which uses sharing on serialisation.+-- If the same 'Shared' value is 'put' multiple times, only the first+-- occurrence will be serialised in full and the later ones will+-- instead serialise as a "pointer" to the first one. The test for+-- whether a value is the same as a previous one uses '(==)'.+newtype Shared a = Shared { getShared :: a } deriving (Eq, Show)++-- The binary format for a "Shared a".+-- The first time a given Shared value appears, we allocate a key (ID) for+-- it and emit it as a 'Let'; if it reoccurs, we emit a 'Ref' to the existing ID.+data SharedEncoding a = Let Key a | Ref Key++instance Binary a => Binary (SharedEncoding a) where+  put (Let key x) = do+    put (key `unsafeShiftL` 1)+    put x+  put (Ref key) = do+    put (key `unsafeShiftL` 1 + 1)++  get = do+    keyTag <- get+    let key = keyTag `unsafeShiftR` 1+    case testBit keyTag 0 of+      False -> do -- Let+        x <- get+        return (Let key x)+      True -> -- Ref+        return (Ref key)++instance (Typeable a, Eq a, Hashable a, Binary a) => Binary (Shared a) where+  put (Shared x) = do+    mkey <- liftStatePut (lookupValue x)+    case mkey of+      Just key ->+        put (Ref key :: SharedEncoding a)+      Nothing -> do+        key <- liftStatePut reserveKey+        put (Let key x)+        liftStatePut (addValue key x)++  get = Shared <$> do+    value <- get+    case value of+      Let key x -> do+        liftStateGet (addValue key x)+        return x+      Ref key ->+        liftStateGet (lookupKey key)++----------------------------------------------------------------------+-- The store of previously-seen values.+----------------------------------------------------------------------++data Store =+  Store {+    -- Maps between values and ID numbers.+    store_keys :: HashMap Key Value,+    store_values :: HashMap Value Key,+    -- The next available ID number.+    store_next_key :: Key }+type Key = Integer++-- Useful for making heterogeneous maps.+data Value where+  Value :: (Eq a, Hashable a, Typeable a) => a -> Value++instance Eq Value where+  Value x == Value y =+    case cast x of+      Just x' -> x' == y+      Nothing -> error "type error"++instance Hashable Value where+  hashWithSalt s (Value x) = hashWithSalt s (typeOf x, x)++emptyStore :: Store+emptyStore = Store HashMap.empty HashMap.empty 0++-- Check if an existing value exists in the store.+lookupValue :: (Eq a, Hashable a, Typeable a) => a -> State Store (Maybe Key)+lookupValue x = do+  let value = Value x+  Store{..} <- State.get+  return (fromIntegral <$> HashMap.lookup value store_values)++-- Allocate a new key.+reserveKey :: Monad m => StateT Store m Key+reserveKey = do+  store@Store{..} <- State.get+  State.put store{store_next_key = store_next_key+1}+  return (fromIntegral store_next_key)++-- Add a new value to the store.+addValue :: (Eq a, Hashable a, Typeable a) => Key -> a -> State Store ()+addValue key x = do+  let value = Value x+  store@Store{..} <- State.get+  when (HashMap.member key store_keys) $ error "key already found"+  when (HashMap.member value store_values) $ error "value already found"+  State.put store{+    store_keys = HashMap.insert key value store_keys,+    store_values = HashMap.insert value key store_values }++-- Find a value by ID number.+lookupKey :: Typeable a => Key -> State Store a+lookupKey key = do+  Store{..} <- State.get+  case HashMap.lookup key store_keys of+    Just (Value x) -> return (fromJust (cast x))+    Nothing -> error ("invalid value " ++ show key ++ " " ++ show store_next_key)++----------------------------------------------------------------------+-- Primitive serialisers.+----------------------------------------------------------------------++putWord8 = liftPut . S.putWord8+getWord8 = liftGet S.getWord8+putInt8 = liftPut . S.putInt8+getInt8 = liftGet S.getInt8++putIntegral :: (Integral a, Bits a) => a -> Put+putIntegral n+  | toInteger n >= -1 && toInteger n < 126 =+    putWord8 (clearBit (fromIntegral n) 7)+  | otherwise = do+    putWord8 (setBit (fromIntegral n) 7)+    putIntegral (n `shiftR` 7)++getIntegral :: (Integral a, Bits a) => Get a+getIntegral = getIntegral' 0 0++getIntegral' :: (Integral a, Bits a) => Int -> a -> Get a+getIntegral' !k !n = do+  x <- getWord8+  let !n' = n + fromIntegral (clearBit x 7) `shiftL` k+  if testBit x 7 then getIntegral' (k+7) n'+    else if x == 127 then return (n' - (1 `shiftL` (k+7)))+    else return n'++-- QuickCheck property:+-- quickCheck (withNumTests 1000000 (withMaxSize 100000 (\x -> runGet getIntegral (runPut (putIntegral (x :: Int))) === Right x)))+-- TODO: add to test suite++putList :: (a -> Put) -> [a] -> Put+putList putter xs = do+  put (length xs)+  mapM_ putter xs++getList :: Get a -> Get [a]+getList getter = do+  len <- get+  replicateM len getter++----------------------------------------------------------------------+-- A class for serialisation/deserialisation.+----------------------------------------------------------------------++class Binary a where+  put :: a -> Put+  get :: Get a++  default put :: (Generic a, GBinary (Rep a)) => a -> Put+  put x = gput (from x)++  default get :: (Generic a, GBinary (Rep a)) => Get a+  get = to <$> gget++instance Binary Int where { put = putIntegral; get = getIntegral }+instance Binary Int8 where { put = putInt8; get = getInt8 }+instance Binary Int16 where { put = putIntegral; get = getIntegral }+instance Binary Int32 where { put = putIntegral; get = getIntegral }+instance Binary Int64 where { put = putIntegral; get = getIntegral }+instance Binary Word where { put = putIntegral; get = getIntegral }+instance Binary Word8 where { put = putWord8; get = getWord8 }+instance Binary Word16 where { put = putIntegral; get = getIntegral }+instance Binary Word32 where { put = putIntegral; get = getIntegral }+instance Binary Word64 where { put = putIntegral; get = getIntegral }+instance Binary Integer where { put = putIntegral; get = getIntegral }+instance Binary Char where { put = putIntegral . ord; get = chr <$> getIntegral }+instance Binary BS.ByteString where { put = liftPut . S.put; get = liftGet S.get }+instance Binary BSS.ByteString where { put = liftPut . S.put; get = liftGet S.get }+instance Binary Float where { put = liftPut. S.put; get = liftGet S.get }+instance Binary Double where { put = liftPut . S.put; get = liftGet S.get }+deriving instance Binary Bool+deriving instance Binary ()+deriving instance (Binary a, Binary b) => Binary (a, b)+deriving instance (Binary a, Binary b, Binary c) => Binary (a, b, c)+deriving instance (Binary a, Binary b, Binary c, Binary d) => Binary (a, b, c, d)+deriving instance (Binary a, Binary b, Binary c, Binary d, Binary e) => Binary (a, b, c, d, e)+deriving instance Binary a => Binary (Maybe a)+deriving instance (Binary a, Binary b) => Binary (Either a b)+instance Binary a => Binary (SmallArray.SmallArray a) where+  put = put . Foldable.toList+  get = SmallArray.smallArrayFromList <$> get++-- | Serialise a value via read/show.+newtype ReadShowBinary a = ReadShowBinary { getReadShowBinary :: a }+instance (Show a, Read a) => Binary (ReadShowBinary a) where+  put = put . show . getReadShowBinary+  get = ReadShowBinary . read <$> get++instance Binary a => Binary [a] where+  put = putList put+  get = getList get++instance (Binary k, Binary v, Ord k) => Binary (Map.Map k v) where+  put = put . Map.toList+  get = Map.fromList <$> get++instance (Binary k, Binary v, Hashable k) => Binary (HashMap k v) where+  put = put . HashMap.toList+  get = HashMap.fromList <$> get++instance Binary v => Binary (IntMap.IntMap v) where+  put = put . IntMap.toList+  get = IntMap.fromList <$> get++instance (Binary k, Ord k) => Binary (Set.Set k) where+  put = put . Set.toList+  get = Set.fromList <$> get++instance (Binary k, Hashable k) => Binary (HashSet.HashSet k) where+  put = put . HashSet.toList+  get = HashSet.fromList <$> get++instance Binary IntSet.IntSet where+  put = put . IntSet.toList+  get = IntSet.fromList <$> get++----------------------------------------------------------------------+-- Generic instances.+----------------------------------------------------------------------++class GBinary f where+  gput :: f a -> Put+  gget :: Get (f a)++  gconstructors :: proxy (f a) -> Int+  gconstructors _ = 1++  gconstructor :: f a -> Int+  gconstructor _ = 0++  gputConstructor :: f a -> Put+  gputConstructor = gput++  ggetConstructor :: Int -> Get (f a)+  ggetConstructor 0 = gget+  ggetConstructor _ = error "ggetConstructor: out of bounds"++instance (GBinary f, GBinary g) => GBinary (f :*: g) where+  gput (x :*: y) = do+    gput x+    gput y+  gget = liftM2 (:*:) gget gget++instance (GBinary f, GBinary g) => GBinary (f :+: g) where+  gput x = do+    put (gconstructor x)+    gputConstructor x++  gget = do+    tag <- get+    ggetConstructor tag++  gconstructors _ =+    gconstructors (Proxy :: Proxy (f a)) + gconstructors (Proxy :: Proxy (g a))++  gconstructor (L1 x) = gconstructor x+  gconstructor (R1 x) = gconstructor x + gconstructors (Proxy :: Proxy (f a))++  gputConstructor (L1 x) = gputConstructor x+  gputConstructor (R1 x) = gputConstructor x++  ggetConstructor n+    | n < m = L1 <$> ggetConstructor n+    | otherwise = R1 <$> ggetConstructor (n-m)+    where+      m = gconstructors (Proxy :: Proxy (f a))++instance GBinary f => GBinary (M1 i c f) where+  gput (M1 x) = gput x+  gget = M1 <$> gget+  gconstructors _ = gconstructors (Proxy :: Proxy (f a))+  gconstructor (M1 x) = gconstructor x+  gputConstructor (M1 x) = gputConstructor x+  ggetConstructor n = M1 <$> ggetConstructor n++instance Binary a => GBinary (K1 i a) where+  gput (K1 x) = put x+  gget = K1 <$> get++instance GBinary U1 where+  gput U1 = return ()+  gget = return U1++instance GBinary V1 where+  gput _ = error "gput: void"+  gget = error "gget: void"+  gconstructors _ = 0+  gconstructor _ = error "gconstructor: void"+  gputConstructor = error "gputConstructor: void"+  ggetConstructor _ = error "ggetConstructor: void"
Data/ChurchList.hs view
@@ -1,5 +1,5 @@ -- | Church-encoded lists. Used in Twee.CP to make sure that fusion happens.-{-# LANGUAGE Rank2Types, BangPatterns #-}+{-# LANGUAGE Rank2Types #-} module Data.ChurchList where  import Prelude(Functor(..), Applicative(..), Monad(..), Bool(..), Maybe(..), (.), ($), id)
Data/DynamicArray.hs view
@@ -1,6 +1,6 @@ -- | Zero-indexed dynamic arrays, optimised for lookup. -- Modification is slow. Uninitialised indices have a default value.-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP, DeriveAnyClass #-} module Data.DynamicArray where  #ifdef BOUNDS_CHECKS@@ -10,6 +10,8 @@ #endif import Control.Monad.ST import Data.List+import Data.Binary.Sharing+import GHC.Generics  -- | A type which has a default value. class Default a where@@ -22,6 +24,7 @@     arrayStart    :: {-# UNPACK #-} !Int,     -- | The contents of the array.     arrayContents :: {-# UNPACK #-} !(P.SmallArray a) }+  deriving (Generic, Binary)  arraySize :: Array a -> Int arraySize = P.sizeofSmallArray . arrayContents
Data/Heap.hs view
@@ -1,15 +1,18 @@ -- | Skew heaps. -{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}+{-# LANGUAGE DeriveAnyClass #-} module Data.Heap(   Heap, empty, singleton, insert, removeMin, union, mapMaybe, size, toList) where +import Data.Binary.Sharing+import GHC.Generics+ -- | A heap.  -- N.B.: arguments are not strict so code has to take care -- to force stuff appropriately. -- The Int field is the size of the heap.-data Heap a = Nil | Node {-# UNPACK #-} !Int a (Heap a) (Heap a) deriving Show+data Heap a = Nil | Node {-# UNPACK #-} !Int a (Heap a) (Heap a) deriving (Show, Generic, Binary)  -- | Take the union of two heaps. {-# INLINEABLE union #-}
Data/Intern.hs view
@@ -1,28 +1,30 @@ -- | Interning, annotating values with unique IDs. -{-# LANGUAGE RecordWildCards, ScopedTypeVariables, BangPatterns, MagicHash, RoleAnnotations, CPP, PatternSynonyms, ViewPatterns, ConstraintKinds #-}+{-# LANGUAGE MagicHash, RoleAnnotations, CPP, PatternSynonyms, ViewPatterns, ConstraintKinds, GeneralizedNewtypeDeriving #-} module Data.Intern(Intern, Sym, pattern Sym, intern, unintern, unsafeMkSym, symId) where  import Data.IORef import System.IO.Unsafe-import qualified Data.Map.Strict as Map-import Data.Map.Strict(Map)+import qualified Data.HashMap.Strict as HashMap+import Data.HashMap.Strict(HashMap) import qualified Data.DynamicArray as DynamicArray import Data.DynamicArray(Array) import Data.Typeable import GHC.Exts import GHC.Int import Unsafe.Coerce+import Data.Hashable+import Data.Binary.Sharing  -- | Type class constraints for a value to be internable.-type Intern a = (Typeable a, Ord a)+type Intern a = (Typeable a, Eq a, Hashable a)  -- | An interned value of type @a@. newtype Sym a = MkSym Int32-  deriving (Eq, Ord)+  deriving (Eq, Ord, Hashable)  instance Show a => Show (Sym a) where-  show = show . unintern+  showsPrec n = showsPrec n . unintern  -- | The unique ID of a symbol. symId :: Sym a -> Int@@ -38,19 +40,17 @@ -- The global cache of interned values. {-# NOINLINE cachesRef #-} cachesRef :: IORef Caches-cachesRef = unsafePerformIO (newIORef (Caches 0 Map.empty DynamicArray.newArray))+cachesRef = unsafePerformIO (newIORef (Caches 0 HashMap.empty DynamicArray.newArray))  data Caches =   Caches {     -- The next id number to assign.     caches_nextId :: {-# UNPACK #-} !Int32,     -- A map from values to IDs.-    caches_from   :: !(Map TypeRep (Cache Any)),+    caches_from   :: !(HashMap TypeRep (HashMap Any Int32)),     -- The reverse map from IDs to values.     caches_to     :: !(Array Any) } -type Cache a = Map a Int32- atomicModifyCaches :: (Caches -> (Caches, a)) -> IO a atomicModifyCaches f = do   -- N.B. atomicModifyIORef' ref f evaluates f ref *after* doing the@@ -70,10 +70,10 @@   if ok then return x else atomicModifyCaches f  -- Versions of unsafeCoerce with slightly more type checking-toAnyCache :: Cache a -> Cache Any+toAnyCache :: HashMap a Int32 -> HashMap Any Int32 toAnyCache = unsafeCoerce -fromAnyCache :: Cache Any -> Cache a+fromAnyCache :: HashMap Any Int32 -> HashMap a Int32 fromAnyCache = unsafeCoerce  toAny :: a -> Any@@ -86,6 +86,7 @@ {-# NOINLINE intern #-} intern :: forall a. Intern a => a -> Sym a intern x =+  hash x `seq`   unsafeDupablePerformIO $ do     -- Common case: symbol is already interned.     caches <- readIORef cachesRef@@ -105,21 +106,21 @@      tryFind :: Caches -> Maybe (Sym a)     tryFind Caches{..} =-      MkSym <$> (Map.lookup ty caches_from >>= Map.lookup x . fromAnyCache)+      MkSym <$> (HashMap.lookup ty caches_from >>= HashMap.lookup x . fromAnyCache)      insert :: Caches -> (Caches, Sym a)     insert caches@Caches{..} =       if n < 0 then error "label overflow" else       (caches {          caches_nextId = n+1,-         caches_from = Map.insert ty (toAnyCache (Map.insert x n cache)) caches_from,+         caches_from = HashMap.insert ty (toAnyCache (HashMap.insert x n cache)) caches_from,          caches_to = DynamicArray.updateWithDefault undefined (fromIntegral n) (toAny x) caches_to },        MkSym n)       where         n = caches_nextId         cache =           fromAnyCache $-          Map.findWithDefault Map.empty ty caches_from+          HashMap.findWithDefault HashMap.empty ty caches_from  -- | Recover the underlying value from a 'Sym'. unintern :: Sym a -> a@@ -145,3 +146,8 @@ pattern Sym :: Intern a => a -> Sym a pattern Sym x <- (unintern -> x) where   Sym x = intern x++-- Serialise a Sym as the underlying value, because it needs to be interned on deserialisation.+instance (Intern a, Binary a) => Binary (Sym a) where+  put = put . Shared . unintern+  get = intern . getShared <$> get
Data/Numbered.hs view
@@ -13,6 +13,8 @@ import Data.Primitive.SmallArray import Data.Int import Data.Maybe+import qualified Data.Binary.Sharing as Binary+import Data.Binary.Sharing(Binary)  -- | An array of key-value pairs. data Numbered a =@@ -21,6 +23,10 @@     {-# UNPACK #-} !(SmallArray a)  instance Show a => Show (Numbered a) where show = show . toList++instance Binary a => Binary (Numbered a) where+  put = Binary.put . toList+  get = fromList <$> Binary.get  -- | An empty array. empty :: Numbered a
Data/PackedSequence.hs view
@@ -1,17 +1,22 @@ -- | Sequences which are stored compactly in memory -- by serialising their contents as a @ByteString@.+{-# LANGUAGE DeriveAnyClass #-} module Data.PackedSequence(PackedSequence, empty, null, size, fromList, toList, uncons) where  import Prelude hiding (null)-import Data.Serialize+import Data.Binary+import Data.Binary.Get+import Data.Binary.Put+import qualified Data.Binary.Sharing as Sharing import Data.ByteString(ByteString) import qualified Data.ByteString as BS import Data.List(unfoldr)+import GHC.Generics  -- | A sequence, stored in a serialised form data PackedSequence a =   Seq {-# UNPACK #-} !Int {-# UNPACK #-} !ByteString-  deriving Eq+  deriving (Eq, Generic, Sharing.Binary)  -- | An empty sequence. empty :: PackedSequence a@@ -27,19 +32,19 @@  -- | Convert a list into a sequence. {-# INLINEABLE fromList #-}-fromList :: Serialize a => [a] -> PackedSequence a-fromList xs = Seq (length xs) (runPut (mapM_ put xs))+fromList :: Binary a => [a] -> PackedSequence a+fromList xs = Seq (length xs) (BS.toStrict (runPut (mapM_ put xs)))  -- | Convert a sequence into a list. {-# INLINEABLE toList #-}-toList :: Serialize a => PackedSequence a -> [a]+toList :: Binary a => PackedSequence a -> [a] toList = unfoldr uncons  -- | Find and remove the first value from a sequence. {-# INLINEABLE uncons #-}-uncons :: Serialize a => PackedSequence a -> Maybe (a, PackedSequence a)+uncons :: Binary a => PackedSequence a -> Maybe (a, PackedSequence a) uncons (Seq 0 _) = Nothing uncons (Seq n bs) =-  Just $ case runGetState get bs 0 of-    Left err -> error err-    Right (x, bs) -> (x, Seq (n-1) bs)+  Just $ case runGetOrFail get (BS.fromStrict bs) of+    Left (_, _, err) -> error err+    Right (bs, _, x) -> (x, Seq (n-1) (BS.toStrict bs))
Data/Primitive/ByteArray/Checked.hs view
@@ -1,7 +1,6 @@ -- | A bounds-checked version of 'Data.Primitive.ByteArray'. -- See that module for documentation. -{-# LANGUAGE ScopedTypeVariables #-} module Data.Primitive.ByteArray.Checked(   module Data.Primitive.ByteArray,   module Data.Primitive.ByteArray.Checked) where
Twee.hs view
@@ -1,5 +1,5 @@ -- | The main prover loop.-{-# LANGUAGE RecordWildCards, MultiParamTypeClasses, GADTs, BangPatterns, OverloadedStrings, ScopedTypeVariables, GeneralizedNewtypeDeriving, PatternGuards, TypeFamilies, FlexibleInstances, RankNTypes, TupleSections #-}+{-# LANGUAGE MultiParamTypeClasses, GADTs, OverloadedStrings, GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes, TupleSections, DeriveAnyClass, CPP #-} module Twee where  import Twee.Base@@ -41,9 +41,11 @@ import qualified Data.PackedSequence as PackedSequence import Test.QuickCheck.Gen hiding (sample) import Test.QuickCheck.Random-import Debug.Trace+--import Debug.Trace import Twee.Generate import qualified System.Random as Random+import GHC.Generics+import Data.Binary.Sharing  ---------------------------------------------------------------------- -- * Configuration and prover state.@@ -64,7 +66,8 @@     cfg_set_join_goals            :: Bool,     cfg_always_simplify           :: Bool,     cfg_complete_subsets          :: Bool,-    cfg_score_cp                  :: Depth -> Index f (Hint f) -> Equation f -> Float,+    cfg_hint_func                 :: Int -> Float -> Sym f,+    cfg_cp_config                 :: !CP.Config,     cfg_join                      :: Join.Config,     cfg_proof_presentation        :: Proof.Config f,     cfg_eliminate_axioms          :: [Axiom f],@@ -86,7 +89,7 @@     st_joinable       :: !(Index f (Equation f)),     st_goals          :: ![Goal f],     st_queue          :: !(Queue Batch),-    st_hints          :: !(Index f (Hint f)),+    st_hints          :: {-# UNPACK #-} !(Hints f),     st_next_active    :: {-# UNPACK #-} !Id,     st_considered     :: {-# UNPACK #-} !Int64,     st_simplified_at  :: {-# UNPACK #-} !Id,@@ -94,8 +97,9 @@     st_not_complete   :: !IntSet,     st_complete       :: !(Index f (Rule f)),     st_messages_rev   :: ![Message f],-    st_random_seed    :: Maybe QCGen,+    st_random_seed    :: Maybe (ReadShowBinary QCGen),     st_problem_term   :: Maybe (ConfluenceFailure f) }+  deriving (Generic, Binary)  -- | The default prover configuration. defaultConfig :: Function f => Config f@@ -113,7 +117,8 @@     cfg_set_join_goals = True,     cfg_always_simplify = False,     cfg_complete_subsets = False,-    cfg_score_cp = \d hints eqn -> score CP.defaultConfig d hints eqn,+    cfg_hint_func = \_ _ -> error "cfg_hint_func not configured",+    cfg_cp_config = CP.defaultConfig,     cfg_join = Join.defaultConfig,     cfg_proof_presentation = Proof.defaultConfig,     cfg_eliminate_axioms = [],@@ -126,6 +131,21 @@     cfg_hint_skel_factor = 0,     cfg_print_score = False } +-- | Compute cfg_score_cp from the CP configuration.+{-# INLINE scoreCP #-}+scoreCP :: Function f => Config f -> Depth -> Hints f -> Equation f -> Float+scoreCP config@Config{..} d hints eqn =+  let s1 = score cfg_cp_config d (scoreTerm config hints) eqn+      -- s2 = score cfg_cp_config d (scoreTerm config (Hints [] Index.empty 0)) eqn+  {-+  in if s1 /= s2 then trace ("used hint for " ++ prettyShow eqn) (trace (prettyShow eqn ++ " => " ++ prettyShow (bothSides (applyHints hints) eqn)) s1) else s1+  -}+  in s1++{-# INLINE scoreTerm #-}+scoreTerm :: Function f => Config f -> Hints f -> Term f -> Float+scoreTerm Config{..} hints t = termScore cfg_cp_config (applyHints hints t)+ -- | Does this configuration run the prover in a complete mode? configIsComplete :: Config f -> Bool configIsComplete Config{..} =@@ -145,7 +165,11 @@     st_joinable = Index.empty,     st_goals = [],     st_queue = Queue.empty,-    st_hints = Index.empty,+    st_hints =+      Hints {+        hints_list = [],+        hints_index = Index.empty,+        hints_next = 0 },     st_next_active = 1,     st_considered = 0,     st_simplified_at = 1,@@ -156,7 +180,7 @@     st_random_seed =       case cfg_random_mode of         False -> Nothing-        True -> Just (mkQCGen 12345),+        True -> Just (ReadShowBinary (mkQCGen 12345)),     st_problem_term = Nothing }  ----------------------------------------------------------------------@@ -169,6 +193,8 @@     NewActive !(Maybe Float) !(Active f)     -- | A new joinable equation.   | NewEquation !(Equation f)+    -- | A new hint was added.+  | NewHint !(Rule f) !HintKind     -- | A rule was deleted.   | DeleteActive !(Active f)     -- | The CP queue was simplified.@@ -181,6 +207,7 @@   | Status !Int     -- | New problem term discovered.   | NewProblemTerm !(ConfluenceFailure f)+  deriving (Generic, Binary)  instance Function f => Pretty (Message f) where   pPrint (NewActive mscore rule) =@@ -190,6 +217,8 @@  --   $$ case cp_top (active_cp rule) of { Just t -> text "  (normal forms of term" <+> pPrint t <#> text ")"; Nothing -> pPrintEmpty }   pPrint (NewEquation eqn) =     text "  (hard)" <+> pPrint eqn+  pPrint (NewHint rule kind) =+    text "  (" <#> pPrint kind <+> text "hint)" <+> pPrint rule   pPrint (DeleteActive rule) =     text "  (delete rule " <#> pPrint (active_id rule) <#> text ")"   pPrint SimplifyQueue =@@ -255,7 +284,7 @@     passive_rule1 :: {-# UNPACK #-} !Id,     passive_rule2 :: {-# UNPACK #-} !Id,     passive_how   :: !How }-  deriving Eq+  deriving (Eq, Generic, Binary)  instance Ord Passive where   compare = comparing f@@ -272,8 +301,9 @@     batch_rule      :: {-# UNPACK #-} !Id,     batch_best      :: {-# UNPACK #-} !Passive,     batch_rest      :: {-# UNPACK #-} !(PackedSequence (Float, Id, How)) }+  deriving (Eq, Generic, Binary) -data BatchKind = Rule1 | Rule2 deriving Eq+data BatchKind = Rule1 | Rule2 deriving (Eq, Generic, Binary)  instance Queue.Batch Batch where   type Label Batch = Id@@ -311,14 +341,14 @@  {-# INLINEABLE makePassive #-} makePassive :: Function f => Config f -> State f -> Overlap (Active f) f -> Passive-makePassive Config{..} State{..} Overlap{..} =+makePassive config@Config{..} State{..} Overlap{..} =   Passive {-    passive_score = cfg_score_cp depth st_hints overlap_eqn,+    passive_score = scoreCP config depth st_hints overlap_eqn,     passive_rule1 = active_id overlap_rule1,     passive_rule2 = active_id overlap_rule2,     passive_how   = overlap_how }   where-    depth = succ (the overlap_rule1 `max` the overlap_rule2)+    depth = Depth (succ (getDepth (the overlap_rule1) `max` getDepth (the overlap_rule2)))  -- | Turn a Passive back into an overlap. -- Doesn't try to simplify it.@@ -333,16 +363,18 @@ -- | Renormalise a queued Passive. {-# INLINEABLE simplifyPassive #-} simplifyPassive :: Function f => Config f -> State f -> Passive -> Maybe (Passive)-simplifyPassive Config{..} state@State{..} passive = do+simplifyPassive config@Config{..} state@State{..} passive = do   overlap <- findPassive state passive   overlap <- simplifyOverlap (index_oriented st_rules) overlap   let r1 = overlap_rule1 overlap       r2 = overlap_rule2 overlap   return passive {     passive_score =+#ifndef USE_LPO       passive_score passive `min`+#endif       -- XXX factor out depth calculation-      cfg_score_cp (succ (the r1 `max` the r2)) st_hints (overlap_eqn overlap) }+      scoreCP config (Depth (succ (getDepth (the r1) `max` getDepth (the r2)))) st_hints (overlap_eqn overlap) }  -- | Check if we should renormalise the queue. {-# INLINEABLE shouldSimplifyQueue #-}@@ -371,9 +403,10 @@ -- --   * removing any orphans from the head of the queue --   * ignoring CPs that are too big+--   * putting back any CPs whose score got bigger since they were enqueued {-# INLINEABLE dequeue #-} dequeue :: Function f => Config f -> State f -> (Maybe (Info, CriticalPair f, Active f, Active f), State f)-dequeue Config{..} state@State{..} =+dequeue config@Config{..} state@State{..} =   case deq 0 st_queue of     -- Explicitly make the queue empty, in case it e.g. contained a     -- lot of orphans@@ -389,14 +422,19 @@         Just (overlap@Overlap{overlap_eqn = t :=: u, overlap_rule1 = rule1, overlap_rule2 = rule2})           | fromMaybe True (cfg_accept_term <*> pure t),             fromMaybe True (cfg_accept_term <*> pure u),-            cp <- makeCriticalPair overlap ->-              return ((combineInfo (active_info rule1) (active_info rule2), cp, rule1, rule2), n+1, queue)+            cp <- makeCriticalPair overlap,+            Just newPassive <- simplifyPassive config state passive ->+              if passive_score newPassive <= passive_score passive then+                return ((combineInfo (active_info rule1) (active_info rule2), cp, rule1, rule2), n+1, queue)+              else+                deq (n+1) (Queue.insert (passive_rule1 newPassive) [newPassive] queue)+         _ -> deq (n+1) queue      combineInfo i1 i2 =       Info {         -- XXX factor out depth calculation-        info_depth = succ (max (info_depth i1) (info_depth i2)),+        info_depth = Depth (succ (max (getDepth (info_depth i1)) (getDepth (info_depth i2)))),         info_max = IntSet.union (info_max i1) (info_max i2) }  ----------------------------------------------------------------------@@ -413,6 +451,7 @@     -- A model in which the rule is false (used when reorienting)     active_model :: !(Model f),     active_positions :: !(Positions2 f) }+  deriving (Generic, Binary)  active_cp :: Active f -> CriticalPair f active_cp Active{..} =@@ -421,9 +460,9 @@     cp_top = active_top,     cp_proof = derivation active_proof } -activeScore :: Config f -> State f -> Active f -> Float-activeScore Config{..} State{..} Active{..} =-  cfg_score_cp (info_depth active_info) st_hints (equation active_proof)+activeScore :: Function f => Config f -> State f -> Active f -> Float+activeScore config@Config{..} State{..} Active{..} =+  scoreCP config (info_depth active_info) st_hints (equation active_proof)  activeRules :: Active f -> [Rule f] activeRules Active{..} =@@ -435,6 +474,7 @@   Info {     info_depth :: {-# UNPACK #-} !Depth,     info_max   :: !IntSet }+  deriving (Generic, Binary)  instance Eq (Active f) where   (==) = (==) `on` active_id@@ -459,7 +499,7 @@       | otherwise = Nothing     state' =       message (NewActive mscore active) $-      addActiveOnly state{st_next_active = st_next_active+1} active+      addActiveOnly config state{st_next_active = st_next_active+1} active   in if subsumed (st_joinable, st_complete) st_rules (unorient active_rule) then     state   else@@ -509,8 +549,9 @@  -- Add an active without generating critical pairs. Used in interreduction. {-# INLINEABLE addActiveOnly #-}-addActiveOnly :: Function f => State f -> Active f -> State f-addActiveOnly state@State{..} active@Active{..} =+addActiveOnly :: Function f => Config f -> State f -> Active f -> State f+addActiveOnly config state@State{..} active@Active{..} =+  addHintsRulePairs config active $   state {     st_rules = foldl' insertRule st_rules (activeRules active),     st_active_set = IntMap.insert (fromIntegral active_id) active st_active_set }@@ -520,8 +561,9 @@  -- Add an active without generating critical pairs. Used in interreduction. {-# INLINEABLE addActiveSimp #-}-addActiveSimp :: Function f => State f -> Active f -> State f-addActiveSimp state@State{..} active@Active{..} =+addActiveSimp :: Function f => Config f -> State f -> Active f -> State f+addActiveSimp config state@State{..} active@Active{..} =+  addHintsRulePairs config active $   state {     st_rules = foldl' insertRule st_rules (activeRules active) }   where@@ -603,22 +645,12 @@ addAxiom :: Function f => Config f -> State f -> Axiom f -> State f addAxiom config state axiom =   consider config state{st_axioms = axiom:st_axioms state}-    Info { info_depth = 0, info_max = IntSet.fromList [axiom_number axiom | cfg_complete_subsets config] }+    Info { info_depth = Depth 0, info_max = IntSet.fromList [axiom_number axiom | cfg_complete_subsets config] }     CriticalPair {       cp_eqn = axiom_eqn axiom,       cp_top = Nothing,       cp_proof = Proof.axiom axiom } --- Add a new hint.-{-# INLINEABLE addHint #-}-addHint :: Function f => Config f -> State f -> Term f -> State f-addHint Config{..} state@State{..} hint =-  state { st_hints = Index.insert hint (Hint hint cost) st_hints }-  where-    cost = fromIntegral (len hint - length (vars hint)) * cfg_hint_skel_factor + cfg_hint_skel_cost +-      -- Add a cost for duplicated variables (since they only get counted once otherwise)-      fromIntegral (length (vars hint) - length (usort (vars hint)))- -- Record an equation as being joinable. {-# INLINEABLE addJoinable #-} addJoinable :: Function f => State f -> Equation f -> State f@@ -675,7 +707,7 @@     goal_expanded_rhs :: Map (Term f) (Derivation f),     goal_lhs          :: Map (Term f) (Term f, Reduction f),     goal_rhs          :: Map (Term f) (Term f, Reduction f) }-  deriving Show+  deriving (Show, Generic, Binary)  -- Add a new goal. {-# INLINEABLE addGoal #-}@@ -766,6 +798,113 @@     goal_rhs = Map.singleton u (u, []) }  ----------------------------------------------------------------------+-- Hints.+----------------------------------------------------------------------++data Hints f =+  Hints {+    -- contains only user-provided hints+    hints_list  :: ![Rule f],+    -- also contains hints formed through CPs+    hints_index :: !(Index f (Rule f)),+    hints_next   :: !Int }+  deriving (Generic, Binary)++data HintKind = UserHint | DerivedHint deriving (Eq, Show, Generic, Binary)++instance Pretty HintKind where+  pPrint UserHint = text "show"+  pPrint DerivedHint = text "auto"++-- Add a new hint.+{-# INLINEABLE addHint #-}+addHint :: Function f => Config f -> State f -> Term f -> State f+addHint config@Config{..} state@State{..} hint =+  addHint' config state hint UserHint cost+  where+    cost = fromIntegral (len hint - length (vars hint)) * cfg_hint_skel_factor + cfg_hint_skel_cost++-- Add a new hint, with a specified kind and cost.+{-# INLINEABLE addHint' #-}+addHint' :: Function f => Config f -> State f -> Term f -> HintKind -> Float -> State f+addHint' config@Config{..} state@State{st_hints = Hints{..}, ..} hint kind cost =+  (if kind == UserHint then addHintRulesPairs config rule . addHintHintsPairs config rule else id) $+  {-+  trace ("hint: " ++ prettyShow hint) $+  trace ("kind: " ++ show kind) $+  trace ("cost: " ++ show cost) $+  trace ("hint term: " ++ prettyShow hintTerm) $+  trace "" $+  -}+  message (NewHint rule kind) $+  state {+    st_hints = Hints {+      hints_list = if kind == UserHint then rule:hints_list else hints_list,+      hints_index = Index.insert hint rule hints_index,+      hints_next = hints_next + 1 } }+  where+    args = usort (vars hint)++    hintTerm = build (app (cfg_hint_func hints_next cost) (map var args))++    -- A rule expressing applying the hint. Uses a dummy value for the proof+    -- field since this rule should never be used in a proof anyway. +    rule = Rule Oriented (certify (Proof.Refl hintTerm)) hint hintTerm++-- Add various kiknds of derived hints.+{-# INLINEABLE addHintsRulePairs #-}+addHintsRulePairs :: Function f => Config f -> Active f -> State f -> State f+addHintsRulePairs config active state =+  foldl' (\state rule -> addHintRulePairs config rule active state) state (hints_list (st_hints state))++{-# INLINEABLE addHintRulesPairs #-}+addHintRulesPairs :: Function f => Config f -> Rule f -> State f -> State f+addHintRulesPairs config rule state =+  foldl' (\state active -> addHintRulePairs config rule active state) state (IntMap.elems (st_active_set state))++{-# INLINEABLE addHintRulePairs #-}+addHintRulePairs :: Function f => Config f -> Rule f -> Active f -> State f -> State f+addHintRulePairs config rule active state =+  foldl' considerOverlap state (overlaps (Index.empty :: Index f (Rule f)) [makeActive rule] active)+    where+      -- hack: need to turn the turn into an Active to invoke 'overlaps'+      makeActive rule = Active 0 (Info (Depth 0) IntSet.empty) rule Nothing (rule_proof rule) (modelFromOrder []) (positionsRule rule)+      considerOverlap state Overlap{..} = considerNorm (simplifyTerm state) t u state+        where+          t = eqn_lhs overlap_eqn+          u = eqn_rhs overlap_eqn++      -- t: term we are considering adding a hint for+      -- u: version of the term where perhaps a hint has already been added+      considerNorm norm t u state+        | st > su =+        {-+          trace ("rule: " ++ prettyShow rule) $+          trace ("active: " ++ prettyShow (active_id active)) $+          trace ("term: " ++ prettyShow t) $+          trace ("norm first: " ++ prettyShow t' ++ " (cost " ++ show st ++ ")") $+          trace ("hint first: " ++ prettyShow u' ++ " (cost " ++ show su ++ ")") $+        -}+          addHint' config state t' DerivedHint su+        | otherwise = state+        where+          t' = norm t+          u' = norm u+          st = scoreTerm config (st_hints state) t'+          su = scoreTerm config (st_hints state) u'++{-# INLINEABLE addHintHintsPairs #-}+addHintHintsPairs :: Function f => Config f -> Rule f -> State f -> State f+addHintHintsPairs _ _ state = state++-- Apply hints to a term.+applyHints :: Function f => Hints f -> Term f -> Term f+applyHints Hints{..} t =+  {-let u = simplify idx t in+  if t == u then u else traceShow ("hint: " ++ prettyShow t ++ " => " ++ prettyShow u) u-}+  simplify hints_index t++---------------------------------------------------------------------- -- Interreduction. ---------------------------------------------------------------------- @@ -795,18 +934,18 @@       (Just active_model) (active_cp active)   of     Right (_, cps) ->-      flip addActiveSimp active $+      flip (addActiveSimp config) active $       flip (foldl' (\state cp -> consider config state active_info cp)) cps $       message (DeleteActive active) $       deleteActive state active     Left (cp, model)       | cp_eqn cp `simplerThan` cp_eqn (active_cp active) ->-        flip addActiveSimp active $+        flip (addActiveSimp config) active $         flip (foldl' (\state cp -> consider config state active_info cp)) (split cp) $         message (DeleteActive active) $         deleteActive state active       | model /= active_model ->-        flip addActiveOnly active { active_model = model } $+        flip (addActiveOnly config) active { active_model = model } $         deleteActive state active       | otherwise ->         state@@ -886,9 +1025,9 @@           (Nothing, state) -> (False, state)           (Just (info, overlap, _, _), state) ->             (True, consider config state info overlap)-      Just g -> -- random mode+      Just (ReadShowBinary g) -> -- random mode         let (g1, g2) = Random.split g in-        let state' = state { st_random_seed = Just g2 } in+        let state' = state { st_random_seed = Just (ReadShowBinary g2) } in         case findCriticalPair config state' g1 of           Nothing -> (True, state'{st_problem_term = Nothing})           Just (info, overlap, changed, cf) ->@@ -949,7 +1088,7 @@         Nothing ->           trace ("Overlap " ++ prettyShow (overlap_eqn o) ++ " was spurious") Nothing -- should be rare         Just o' ->-          Just (cfg_score_cp config 0 (st_hints state) (overlap_eqn o'), (Info 0 IntSet.empty, makeCriticalPair o, changed, cf))+          Just (scoreCP config (Depth 0) (st_hints state) (overlap_eqn o'), (Info (Depth 0) IntSet.empty, makeCriticalPair o, changed, cf))  -- Return all goal terms. Handles the $equals coding. goalTerms :: Function f => State f -> [Term f]
Twee/Base.hs view
@@ -1,7 +1,7 @@ -- | Useful operations on terms and similar. Also re-exports some generally -- useful modules such as 'Twee.Term' and 'Twee.Pretty'. -{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances, DeriveFunctor, DefaultSignatures, FlexibleContexts, TypeOperators, MultiParamTypeClasses, GeneralizedNewtypeDeriving, ConstraintKinds, RecordWildCards, BangPatterns, PatternSynonyms #-}+{-# LANGUAGE FlexibleInstances, UndecidableInstances, DeriveFunctor, DefaultSignatures, TypeOperators, MultiParamTypeClasses, GeneralizedNewtypeDeriving, ConstraintKinds, PatternSynonyms, RankNTypes #-} module Twee.Base(   -- * Re-exported functionality   module Twee.Term, module Twee.Pretty,@@ -14,7 +14,7 @@   -- * Typeclasses   Minimal(..), minimalTerm, isMinimal, erase, eraseExcept, ground, skolemise,   Ordered(..), lessThan, orientTerms,-  EqualsBonus(..), isTrueTerm, isFalseTerm, decodeEquality,+  EqualsBonus(..), Weighted(..), isTrueTerm, isFalseTerm, decodeEquality,   Strictness(..), Function) where  import Prelude hiding (lookup)@@ -30,12 +30,13 @@ import Data.List hiding (singleton) import Data.Maybe import qualified Data.IntMap.Strict as IntMap-import Data.Serialize+import Data.Binary.Sharing+import qualified Data.Binary as Cereal import Data.Intern  -- | Represents a unique identifier (e.g., for a rule). newtype Id = Id { unId :: Int32 }-  deriving (Eq, Ord, Show, Enum, Bounded, Num, Real, Integral, Serialize)+  deriving (Eq, Ord, Show, Enum, Bounded, Num, Real, Integral, Binary, Cereal.Binary)  instance Pretty Id where   pPrint = text . show . unId@@ -244,10 +245,18 @@ skolemise :: (Symbolic a, ConstantOf a ~ f, Minimal f) => a -> a skolemise t = subst (\(V x) -> con (skolem x)) t --- | For types which have a notion of size. -- | The collection of constraints which the type of function symbols must -- satisfy in order to be used by twee.-type Function f = (Ordered f, Minimal f, PrettyTerm f, EqualsBonus f, Intern f)+type Function f = (Ordered f, Minimal f, PrettyTerm f, EqualsBonus f, Intern f, Weighted f)++-- | For functions which have a notion of weight.+-- Used for weighing terms in CP selection.+class Weighted f where+  weight :: f -> Float+  weight _ = 1++instance Weighted f => Weighted (Sym f) where+  weight = weight . unintern  -- | A hack for encoding Horn clauses. See 'Twee.CP.Score'. -- The default implementation of 'hasEqualsBonus' should work OK.
Twee/CP.hs view
@@ -1,12 +1,12 @@ -- | Critical pair generation.-{-# LANGUAGE BangPatterns, FlexibleContexts, ScopedTypeVariables, MultiParamTypeClasses, RecordWildCards, OverloadedStrings, TypeFamilies, GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses, OverloadedStrings, DeriveAnyClass #-}+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-} module Twee.CP where  import qualified Twee.Term as Term import Twee.Base import Twee.Rule import Twee.Index(Index)-import qualified Twee.Index as Index import qualified Data.Set as Set import Control.Monad import Data.List hiding (singleton)@@ -17,15 +17,24 @@ import qualified Twee.Proof as Proof import Twee.Proof(Derivation, congPath) import Data.Bits-import Data.Serialize+import Data.Binary.Sharing+import qualified Data.Binary as Cereal import Data.Int --import Debug.Trace+import GHC.Generics  -- | The set of positions at which a term can have critical overlaps. data Positions f = NilP | ConsP {-# UNPACK #-} !Int !(Positions f)+instance Binary (Positions f) where+  put = put . unfoldr op+    where+      op NilP = Nothing+      op (ConsP x xs) = Just (x, xs)+  get = foldr ConsP NilP <$> (get :: Get [Int])+ type PositionsOf a = Positions (ConstantOf a) -- | Like Positions but for an equation (one set of positions per term).-data Positions2 f = ForwardsPos !(Positions f) | BothPos !(Positions f) !(Positions f)+data Positions2 f = ForwardsPos !(Positions f) | BothPos !(Positions f) !(Positions f) deriving (Generic, Binary)  instance Show (Positions f) where   show = show . ChurchList.toList . positionsChurch@@ -73,7 +82,7 @@     overlap_top   :: {-# UNPACK #-} !(Term f),     -- | The critical pair itself.     overlap_eqn   :: {-# UNPACK #-} !(Equation f) }-  deriving Show+  deriving (Show, Generic, Binary)  data How =   How {@@ -82,14 +91,14 @@     how_dir2 :: !Direction }   deriving (Eq, Ord, Show) -data Direction = Forwards | Backwards deriving (Eq, Ord, Enum, Show)+data Direction = Forwards | Backwards deriving (Eq, Ord, Enum, Show, Generic, Binary)  direct :: Rule f -> Direction -> Rule f direct rule Forwards = rule direct rule Backwards = backwards rule -instance Serialize How where-  put = put . packHow+instance Cereal.Binary How where+  put = Cereal.put . packHow     where       packHow :: How -> Int32       packHow How{..} =@@ -98,7 +107,7 @@         fromEnum how_dir2 `shiftL` 1 +         how_pos `shiftL` 2 -  get = fmap unpackHow get+  get = fmap unpackHow Cereal.get     where       unpackHow :: Int32 -> How       unpackHow n0 =@@ -108,8 +117,12 @@           how_dir2 = toEnum ((n `shiftR` 1) .&. 1),           how_pos  = n `shiftR` 2 } +instance Binary How where+  put = liftPut . Cereal.put+  get = liftGet Cereal.get+ -- | Represents the depth of a critical pair.-newtype Depth = Depth Int deriving (Eq, Ord, Num, Real, Enum, Integral, Show)+newtype Depth = Depth { getDepth :: Int } deriving (Eq, Ord, Show, Generic, Binary)  -- | Compute all overlaps of a rule with a set of rules. {-# INLINEABLE overlaps #-}@@ -200,22 +213,10 @@   Config {     cfg_lhsweight :: !Float,     cfg_rhsweight :: !Float,-    cfg_funweight :: !Float,     cfg_varweight :: !Float,     cfg_depthweight :: !Float,     cfg_dupcost :: !Float,-    cfg_dupfactor :: !Float,-    cfg_resonance :: !Bool }--data Hint f =-  Hint {-    hint_term :: {-# UNPACK #-} !(Term f),-    hint_cost :: {-# UNPACK #-} !Float }--instance Symbolic (Hint f) where-  type ConstantOf (Hint f) = f-  termsDL Hint{..} = termsDL hint_term-  subst_ sub (Hint t c) = Hint (subst_ sub t) c+    cfg_dupfactor :: !Float }  -- | The default heuristic configuration. defaultConfig :: Config@@ -223,29 +224,33 @@   Config {     cfg_lhsweight = 4,     cfg_rhsweight = 1,-    cfg_funweight = 1,     cfg_varweight = 6/7,     cfg_depthweight = 2,     cfg_dupcost = 1,-    cfg_dupfactor = 0,-    cfg_resonance = False }+    cfg_dupfactor = 0 }  -- | Compute a score for a critical pair.  -- We compute: --   cfg_lhsweight * size l + cfg_rhsweight * size r -- where l is the biggest term and r is the smallest,--- and variables have weight 1 and functions have weight cfg_funweight.-{-# INLINEABLE score #-}-score :: Function f => Config -> Depth -> Index f (Hint f) -> Equation f -> Float-score Config{..} depth hints (l :=: r) =-  fromIntegral depth * cfg_depthweight ++-- and variables have weight cfg_varweight.+{-# INLINE score #-}+score :: Function f => Config -> Depth -> (Term f -> Float) -> Equation f -> Float+score Config{..} depth termScore (l :=: r) =+  fromIntegral (getDepth depth) * cfg_depthweight +   (m + n) * cfg_rhsweight +   max m n * (cfg_lhsweight - cfg_rhsweight)   where-    m = size' 0 (singleton l) []-    n = size' 0 (singleton r) []+    m = termScore l+    n = termScore r +-- | Compute a score for a single term.+{-# INLINEABLE termScore #-}+termScore :: Function f => Config -> Term f -> Float+termScore Config{..} t =+  size' 0 (singleton t) []+  where     size' !_ !_ !_ | False = undefined     size' n Nil ts =       case ts of@@ -254,23 +259,18 @@     size' n (Cons t ts) us       | len t > 1, t `isSubtermOfList` ts || any (t `isSubtermOfList`) us =         size' (n+cfg_dupcost+cfg_dupfactor*fromIntegral (len t)) ts us-    size' n (Cons t ts) us-      | len t > 1, (sub, Hint{..}):_ <- Index.matches t hints,-        not cfg_resonance || allSubst (\_ t -> case t of { UnsafeCons (Var _) _ -> True; _ -> False }) sub =-        size' (n + hint_cost) ts (map snd (Term.substToList' sub) ++ us)-        --trace ("hint: len " ++ show (len t) ++ ", new cost " ++ show new_cost ++ ": " ++ prettyShow t) $     size' n ts xs       | Cons (App f ws@(Cons a (Cons b us))) vs <- ts,         not (isVar a),         not (isVar b),         hasEqualsBonus f,         Just sub <- unify a b =-        size' (n+cfg_funweight) ws xs `min`+        size' (n+weight f) ws xs `min`         size' (n+1) (subst sub us) (subst sub (vs:xs))     size' n (Cons (Var _) ts) us =       size' (n+cfg_varweight) ts us-    size' n ConsSym{hd = App{}, rest = ts} us =-      size' (n+cfg_funweight) ts us+    size' n ConsSym{hd = App f _, rest = ts} us =+      size' (n+weight f) ts us  ---------------------------------------------------------------------- -- * Higher-level handling of critical pairs.
Twee/Constraints.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleContexts, UndecidableInstances, RecordWildCards #-}+{-# LANGUAGE DeriveAnyClass #-} -- | Solving constraints on variable ordering. module Twee.Constraints where @@ -18,8 +18,10 @@ import Test.QuickCheck.Gen(unGen) import Test.QuickCheck.Random(mkQCGen) import Data.Intern+import GHC.Generics+import Data.Binary.Sharing -data Atom f = Constant (Sym f) | Variable Var deriving (Show, Eq, Ord)+data Atom f = Constant (Sym f) | Variable Var deriving (Show, Eq, Ord, Generic, Binary)  {-# INLINE atoms #-} atoms :: Term f -> [Atom f]@@ -188,7 +190,7 @@ addTerm _ b = b  newtype Model f = Model (Map (Atom f) (Int, Int))-  deriving (Eq, Show)+  deriving (Eq, Ord, Show, Generic, Binary) -- Representation: map from atom to (major, minor) -- x <  y if major x < major y -- x <= y if major x = major y and minor x < minor y@@ -215,8 +217,11 @@         rel = if i == j then LessEq else Less  modelFromOrder :: (Minimal f, Ord f) => [Atom f] -> Model f-modelFromOrder xs =-  Model (Map.fromList [(x, (i, i)) | (x, i) <- zip xs [0..]])+modelFromOrder xs = modelFromOrder' [[x] | x <- xs]++modelFromOrder' :: (Minimal f, Ord f) => [[Atom f]] -> Model f+modelFromOrder' xss =+  Model (Map.fromList [(x, (i, j)) | (xs, i) <- zip xss [0..], (x, j) <- zip xs [0..]])  weakenModel :: Model f -> [Model f] weakenModel (Model m) =
Twee/Equation.hs view
@@ -1,9 +1,12 @@ -- | Equations.-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DeriveAnyClass #-} module Twee.Equation where  import Twee.Base import Control.Monad+import GHC.Generics+import Data.Binary.Sharing+import Data.Hashable  -------------------------------------------------------------------------------- -- * Equations.@@ -13,7 +16,8 @@   (:=:) {     eqn_lhs :: {-# UNPACK #-} !(Term f),     eqn_rhs :: {-# UNPACK #-} !(Term f) }-  deriving (Eq, Ord, Show)+  deriving (Eq, Ord, Show, Generic, Hashable, Binary)+ type EquationOf a = Equation (ConstantOf a)  instance Symbolic (Equation f) where
Twee/Generate.hs view
@@ -7,7 +7,7 @@ import Data.Maybe import Twee.Profile import Twee.Utils-import Debug.Trace+--import Debug.Trace  type Pat f = Term f type LHS f = Term f@@ -31,7 +31,7 @@   [ (1, return sub) ] ++   -- commit to top-level function...   [ (n, genList (reduce n (length ps)) lhss ps sub)-  | App f psl <- [p]+  | App _f psl <- [p]   , let ps = unpack psl   ] ++   -- ...or use a LHS for inspiration
Twee/Index.hs view
@@ -5,7 +5,7 @@ -- the search term is an instance of the key, and return the corresponding -- values. -{-# LANGUAGE BangPatterns, RecordWildCards, OverloadedStrings, FlexibleContexts, CPP, TupleSections, TypeFamilies #-}+{-# LANGUAGE OverloadedStrings, CPP, TupleSections, DeriveAnyClass #-} -- We get some bogus warnings because of pattern synonyms. {-# OPTIONS_GHC -fno-warn-overlapping-patterns #-} {-# OPTIONS_GHC -O2 -fmax-worker-args=100 #-}@@ -40,6 +40,8 @@ import qualified Data.IntMap.Strict as IntMap import Twee.Profile import Data.Intern+import Data.Binary.Sharing+import GHC.Generics  -- The term index in this module is a _perfect discrimination tree_. -- This is a trie whose keys are terms, represented as flat lists of symbols@@ -489,3 +491,26 @@       Nothing ->         searchVars t ts binds var (start+1) rest +----------------------------------------------------------------------+-- Serialisation.+----------------------------------------------------------------------++-- When serialising, we must change the 'fun' array to index by function and not function number.+data  SIndex f a = SIndex Int (TermList f) [a] [(Sym f, Index f a)] (Numbered (Index f a)) | SEmpty+  deriving (Generic, Binary)++toSerialised :: Index f a -> SIndex f a+toSerialised Empty = SEmpty+toSerialised (Index minSize prefix here funs vars) = SIndex minSize prefix here funs' vars+  where+    funs' = [(unsafeMkSym f, idx) | (f, idx) <- Array.toList funs, not (null idx)]++fromSerialised :: SIndex f a -> Index f a+fromSerialised SEmpty = Empty+fromSerialised (SIndex minSize prefix here funs vars) = Index minSize prefix here funs' vars+  where+    funs' = foldr (uncurry Array.update) newArray [(symId f, idx) | (f, idx) <- funs]++instance (Intern f, Binary f, Binary a) => Binary (Index f a) where+  put = put . toSerialised+  get = fromSerialised <$> get
Twee/Join.hs view
@@ -1,5 +1,4 @@ -- | Tactics for joining critical pairs.-{-# LANGUAGE FlexibleContexts, BangPatterns, RecordWildCards, TypeFamilies, ScopedTypeVariables #-} module Twee.Join where  import Twee.Base@@ -220,7 +219,7 @@         _ -> normaliseWith (const True) (rewrite (ok t u m) (index_all idx)) t     ok t u m rule sub =       case cp_top of-        Just top | cfg_use_connectedness_in_ground_joining ->+        Just _top | cfg_use_connectedness_in_ground_joining ->           reducesWith lessEqSkolemModel rule sub &&           unorient rule `simplerThan` (t :=: u)         _ ->
Twee/KBO.hs view
@@ -1,7 +1,6 @@ -- | An implementation of Knuth-Bendix ordering. -{-# LANGUAGE PatternGuards, BangPatterns #-}-module Twee.KBO(lessEq, lessIn, lessEqSkolem, Sized(..), Weighted(..)) where+module Twee.KBO(lessEq, lessIn, lessEqSkolem, Sized(..), ArgWeighted(..)) where  import Twee.Base hiding (lessEq, lessIn, lessEqSkolem) import Twee.Equation@@ -13,7 +12,7 @@ import Twee.Utils import Data.Intern -lessEqSkolem :: (Function f, Sized f, Weighted f) => Term f -> Term f -> Bool+lessEqSkolem :: (Function f, Sized f, ArgWeighted f) => Term f -> Term f -> Bool lessEqSkolem !t !u   | m < n = True   | m > n = False@@ -39,7 +38,7 @@       in loop ts us  -- | Check if one term is less than another in KBO.-lessEq :: (Function f, Sized f, Weighted f) => Term f -> Term f -> Bool+lessEq :: (Function f, Sized f, ArgWeighted f) => Term f -> Term f -> Bool lessEq (App f Nil) _ | f == minimal = True lessEq (Var x) (Var y) | x == y = True lessEq _ (Var _) = False@@ -76,14 +75,14 @@  -- See "notes/kbo under assumptions" for how this works. -lessIn :: (Function f, Sized f, Weighted f) => Model f -> Term f -> Term f -> Maybe Strictness+lessIn :: (Function f, Sized f, ArgWeighted f) => Model f -> Term f -> Term f -> Maybe Strictness lessIn model t u =   case sizeLessIn model t u of     Nothing -> Nothing     Just Strict -> Just Strict     Just Nonstrict -> lexLessIn model t u -sizeLessIn :: (Function f, Sized f, Weighted f) => Model f -> Term f -> Term f -> Maybe Strictness+sizeLessIn :: (Function f, Sized f, ArgWeighted f) => Model f -> Term f -> Term f -> Maybe Strictness sizeLessIn model t u =   case minimumIn model m of     Just l@@ -123,7 +122,7 @@       | k < 0 = Nothing       | otherwise = Just k -lexLessIn :: (Function f, Sized f, Weighted f) => Model f -> Term f -> Term f -> Maybe Strictness+lexLessIn :: (Function f, Sized f, ArgWeighted f) => Model f -> Term f -> Term f -> Maybe Strictness lexLessIn _ t u | t == u = Just Nonstrict lexLessIn cond t u   | Just a <- fromTerm t,@@ -157,13 +156,13 @@   -- | Compute the size.   size  :: a -> Integer -class Weighted f where+class ArgWeighted f where   argWeight :: f -> Integer -instance (Weighted f, Intern f) => Weighted (Sym f) where+instance (ArgWeighted f, Intern f) => ArgWeighted (Sym f) where   argWeight = argWeight . unintern -weightedVars :: (Weighted f, Intern f) => Term f -> [(Var, Integer)]+weightedVars :: (ArgWeighted f, Intern f) => Term f -> [(Var, Integer)] weightedVars t = collate sum (loop 1 t)   where     loop k (Var x) = [(x, k)]@@ -173,7 +172,7 @@ instance (Intern f, Sized f) => Sized (Sym f) where   size = size . unintern -instance (Intern f, Sized f, Weighted f) => Sized (TermList f) where+instance (Intern f, Sized f, ArgWeighted f) => Sized (TermList f) where   size = aux 0     where       aux n Nil = n@@ -181,9 +180,9 @@         aux (n + size f + argWeight f * size t) u       aux n (Cons (Var _) t) = aux (n+1) t -instance (Intern f, Sized f, Weighted f) => Sized (Term f) where+instance (Intern f, Sized f, ArgWeighted f) => Sized (Term f) where   size = size . singleton -instance (Intern f, Sized f, Weighted f) => Sized (Equation f) where+instance (Intern f, Sized f, ArgWeighted f) => Sized (Equation f) where   size (x :=: y) = size x + size y 
+ Twee/LPO.hs view
@@ -0,0 +1,107 @@+-- | An implementation of lexicographic path ordering.++module Twee.LPO(lessEqBasic, lessEq, lessIn, lessEqSkolem) where++import Twee.Base hiding (lessEq, lessIn, lessEqSkolem)+import Twee.Constraints hiding (lessEq, lessIn, lessEqSkolem)+import Data.Maybe+import Control.Monad++lessEqSkolem :: Function f => Term f -> Term f -> Bool+lessEqSkolem (App f Nil) _ | f == minimal = True+lessEqSkolem _ (App f Nil) | f == minimal = False+lessEqSkolem (Var x) (Var y) = x <= y+lessEqSkolem _ (Var _) = False+lessEqSkolem (Var _) _ = True+lessEqSkolem t@(App f ts) u@(App g us)+  | f == g = lexMA ts us+  | f << g = majo ts u+  | otherwise = alpha t us+  where+    lexMA Nil Nil = True+    lexMA (Cons t' ts) (Cons u' us)+      | t' == u' = lexMA ts us+      | lessEqSkolem t' u' = majo ts u+      | otherwise = alpha t us++    majo ts u = and [t /= u && lessEqSkolem t u | t <- unpack ts]+    alpha t us = or [lessEqSkolem t u | u <- unpack us]++-- For testing+lessEqBasic :: Function f => Term f -> Term f -> Bool+lessEqBasic t u = eqModErasure t u || lessBasic t u+  where+    eqModErasure (App f _) _ | f == minimal = True+    eqModErasure (Var x) (Var y) = x == y+    eqModErasure (App f ts) (App g us) =+      f == g && and (zipWith eqModErasure (unpack ts) (unpack us))+    eqModErasure _ _ = False++lessBasic :: Function f => Term f -> Term f -> Bool+lessBasic (App f Nil) (App g _) | f == minimal && g /= minimal = True+lessBasic (Var _) (Var _) = False+lessBasic (Var x) (App _ ts) = x `elem` vars ts+lessBasic t@(App f ts) u@(App g us)+  | or [lessEqBasic t u' | u' <- unpack us] = True+  | f << g && and [lessBasic t' u | t' <- unpack ts] = True+  | f == g = and [lessBasic t' u | t' <- unpack ts] && loop ts us+  where+    loop Nil Nil = False+    loop (Cons t ts) (Cons u us) =+      if t == u then loop ts us else lessBasic t u+lessBasic _ _ = False++-- | Check if one term is less than another in LPO.+lessEq :: Function f => Term f -> Term f -> Bool+lessEq (App f Nil) _ | f == minimal = True+lessEq (Var x) (Var y) = x == y+lessEq _ (Var _) = False+lessEq (Var x) t = x `elem` vars t+lessEq t@(App f ts) u@(App g us)+  | f == g = lexMA ts us+  | f << g = majo ts u+  | otherwise = alpha t us+  where+    lexMA Nil Nil = True+    lexMA (Cons t' ts) (Cons u' us)+      | t' == u' = lexMA ts us+      | lessEq t' u' =+        case unify t' u' of+          Just sub -> majo ts u && lexMA (subst sub ts) (subst sub us)+          Nothing -> majo ts u+      | otherwise = alpha t us++    majo ts u = and [isNothing (unify t u) && lessEq t u | t <- unpack ts]+    alpha t us = or [lessEq t u | u <- unpack us]++lessIn :: Function f => Model f -> Term f -> Term f -> Maybe Strictness+lessIn model t u+  | Just a <- fromTerm t,+    Just b <- fromTerm u,+    Just s <- lessEqInModel model a b = Just s+lessIn _ _ (Var _) = Nothing+lessIn model (Var x) t+  | any isJust [lessEqInModel model (Variable x) a | a <- catMaybes (map fromTerm (subterms t))] = Just Strict+  | otherwise = Nothing+lessIn model t@(App f ts) u@(App g us)+  | f == g = lexMA ts us+  | f << g = majo ts u+  | otherwise = alpha t us+  where+    lexMA Nil Nil = Just Nonstrict+    lexMA (Cons t' ts) (Cons u' us) =+      case lessIn model t' u' of+        Just Nonstrict ->+          case (let Just sub = unify t' u' in lexMA (subst sub ts) (subst sub us), majo ts u) of+            (Just Strict, Just Strict) -> Just Strict+            (Just _, Just _) -> Just Nonstrict+            _ -> Nothing+        Just Strict -> majo ts u+        Nothing -> alpha t us++    majo ts u = do+      guard (and [lessIn model t u == Just Strict | t <- unpack ts])+      return Strict+    alpha t us = do+      guard (or [isJust (lessIn model t u) | u <- unpack us])+      return Strict
Twee/Profile.hs view
@@ -1,5 +1,5 @@ -- Basic support for profiling.-{-# LANGUAGE BangPatterns, RecordWildCards, CPP, OverloadedStrings #-}+{-# LANGUAGE CPP, OverloadedStrings #-} module Twee.Profile(stamp, stampWith, stampM, stampGen, stampGen', profile) where  #ifdef PROFILE
Twee/Proof.hs view
@@ -1,5 +1,5 @@--- | Equational proofs which are checked for correctedness.-{-# LANGUAGE TypeFamilies, PatternGuards, RecordWildCards, ScopedTypeVariables, OverloadedStrings #-}+-- | Equational proofs which are checked for correctness.+{-# LANGUAGE OverloadedStrings, DeriveAnyClass #-} module Twee.Proof(   -- * Constructing proofs   Proof, Derivation(..), Axiom(..),@@ -33,6 +33,10 @@ import Control.Monad.Trans.State.Strict import Data.Graph import Twee.Profile+import qualified Data.Binary.Sharing as Binary+import Data.Binary.Sharing(Binary, Shared(..))+import GHC.Generics+import Data.Hashable  ---------------------------------------------------------------------- -- Equational proofs. Only valid proofs can be constructed.@@ -65,7 +69,7 @@     -- Parallel, i.e., takes a function symbol and one derivation for each     -- argument of that function.   | Cong {-# UNPACK #-} !(Sym f) ![Derivation f]-  deriving (Eq, Show)+  deriving (Eq, Show, Generic, Hashable, Binary)  --  | An axiom, which comes without proof. data Axiom f =@@ -76,9 +80,12 @@     -- | A description of the axiom.     -- Has no semantic meaning; for convenience only.     axiom_name :: !String,+    -- | Human-readable names for the variables of the axiom.+    -- Has no semantic meaning; for convenience only.+    axiom_vars :: !(Maybe (Map Var String)),     -- | The equation which the axiom asserts.     axiom_eqn :: !(Equation f) }-  deriving (Eq, Ord, Show)+  deriving (Eq, Ord, Show, Generic, Hashable)  -- | Checks a 'Derivation' and, if it is correct, returns a -- certified 'Proof'.@@ -87,11 +94,11 @@  -- This is the trusted core of the module. {-# INLINEABLE certify #-}-certify :: Function f => Derivation f -> Proof f+certify :: Derivation f -> Proof f certify p =   stamp "certify proof" $   case check p of-    Nothing -> error ("Invalid proof created!\n" ++ prettyShow p)+    Nothing -> error "Invalid proof created!"     Just eqn -> Proof eqn p   where     check (UseLemma proof sub) =@@ -129,6 +136,8 @@   -- Don't look at the proof itself, to prevent exponential blowup   -- when a proof contains UseLemma   compare = comparing equation+instance Hashable (Proof f) where+  hashWithSalt s = hashWithSalt s . equation  instance Symbolic (Derivation f) where   type ConstantOf (Derivation f) = f@@ -167,6 +176,16 @@     text "axiom" <#>     pPrintTuple [pPrint axiom_number, text axiom_name, pPrint axiom_eqn] +instance (Intern f, Binary f) => Binary (Axiom f) where+  put Axiom{..} = Binary.put (Shared (axiom_number, axiom_name, axiom_vars, axiom_eqn))+  get = do+    Shared (num, name, vars, eqn) <- Binary.get+    return (Axiom num name vars eqn)++instance (Intern f, Binary f) => Binary (Proof f) where+  put = Binary.put . Shared . derivation+  get = certify . getShared <$> Binary.get+ foldLemmas :: (Intern f, PrettyTerm f) => (Map (Proof f) a -> Derivation f -> a) -> [Derivation f] -> Map (Proof f) a foldLemmas op ds =   execState (mapM_ foldGoal ds) Map.empty@@ -498,7 +517,7 @@     pres_lemmas :: [Proof f],     -- | The goals proved.     pres_goals  :: [ProvedGoal f] }-  deriving Show+  deriving (Show, Generic, Binary)  -- Note: only the pg_proof field should be trusted! -- The remaining fields are for information only.@@ -515,9 +534,10 @@     -- In general, subst pg_witness_hint pg_goal_hint == equation pg_proof.     -- For non-existential goals, pg_goal_hint == equation pg_proof     -- and pg_witness_hint is the empty substitution.+    pg_vars         :: Maybe (Map Var String),     pg_goal_hint    :: Equation f,     pg_witness_hint :: Subst f }-  deriving Show+  deriving (Show, Generic, Binary)  -- | Construct a @ProvedGoal@. provedGoal :: Int -> String -> Proof f -> ProvedGoal f@@ -526,6 +546,7 @@     pg_number = number,     pg_name = name,     pg_proof = proof,+    pg_vars = Nothing,     pg_goal_hint = equation proof,     pg_witness_hint = emptySubst } @@ -731,8 +752,11 @@       Symm <$> generaliseStep p     generaliseStep (Trans p q) =       liftM2 Trans (generaliseStep p) (generaliseStep q)-    generaliseStep (Cong f ps) =-      Cong f <$> mapM generaliseStep ps+    generaliseStep (Cong f ps) = do+      q <- cong f <$> mapM generaliseStep ps+      case q of+        Refl{} -> generaliseStep q+        _ -> return q      freshen xs f = do       n <- get@@ -842,19 +866,19 @@ pPrintPresentation :: forall f. Function f => Config f -> Presentation f -> Doc pPrintPresentation config (Presentation axioms lemmas goals) =   vcat $ intersperse (text "") $-    vcat [ describeEquation "Axiom" (axiomNum axiom) (Just name) eqn $$+    vcat [ describeEquation "Axiom" (axiomNum axiom) (Just name) vars eqn $$            ppAxiomUses axiom-         | axiom@(Axiom _ name eqn) <- axioms,+         | axiom@(Axiom _ name vars eqn) <- axioms,            not (invisible eqn) ]:-    [ pp "Lemma" (lemmaNum p) Nothing (equation p) emptySubst p+    [ pp "Lemma" (lemmaNum p) Nothing (equation p) Nothing emptySubst p     | p <- lemmas,       not (invisible (equation p)) ] ++-    [ pp "Goal" (show num) (Just pg_name) pg_goal_hint pg_witness_hint pg_proof+    [ pp "Goal" (show num) (Just pg_name) pg_goal_hint pg_vars pg_witness_hint pg_proof     | (num, ProvedGoal{..}) <- zip [1..] goals ]   where-    pp kind n mname eqn witness p =-      describeEquation kind n mname eqn $$-      ppWitness witness $$+    pp kind n mname eqn names witness p =+      describeEquation kind n mname names eqn $$+      ppWitness names witness $$       text "Proof:" $$       pPrintLemma config axiomNum lemmaNum p @@ -863,14 +887,18 @@     axiomNum x = show (fromJust (Map.lookup x axiomNums))     lemmaNum x = show (fromJust (Map.lookup x lemmaNums)) -    ppWitness sub+    ppWitness names sub       | sub == emptySubst = pPrintEmpty       | otherwise =           vcat [             text "The goal is true when:",             nest 2 $ vcat-              [ pPrint x <+> text "=" <+> pPrint t-              | (x, t) <- substToList sub ],+              [ text name <+> text "=" <+> pPrint t+              | (x, t) <- substToList sub,+                let name =+                      case names of+                        Nothing -> prettyShow x+                        Just names -> fromJust (Map.lookup x names) ],             if minimal `elem` funs sub then               text "where" <+> doubleQuotes (pPrint (minimal :: Sym f)) <+>               text "stands for an arbitrary term of your choice."@@ -900,14 +928,31 @@ -- Used both here and in the main file. describeEquation ::   Function f =>-  String -> String -> Maybe String -> Equation f -> Doc-describeEquation kind num mname eqn =+  String -> String -> Maybe String -> Maybe (Map Var String) -> Equation f -> Doc+describeEquation kind num mname mvars eqn =   text kind <+> text num <#>   (case mname of      Nothing -> text ""      Just name -> text (" (" ++ name ++ ")")) <#>-  text ":" <+> pPrint eqn <#> text "."+  text ":" <+> pPrint (prettyVars eqn) <#> text "."+  where+    var x =+      case mvars of+        Nothing -> prettyShow x+        Just vars -> fromJust (Map.lookup x vars)+    prettyVars (t :=: u) = build (pv t) :=: build (pv u)+    pv (Var x) = con (Sym (PrettyVar (var x)))+    pv (App (Sym f) ts) = app (Sym (PrettyFunc f)) (map pv (unpack ts)) +data PrettyVars f = PrettyVar String | PrettyFunc f+  deriving (Eq, Generic, Hashable)+instance Pretty f => Pretty (PrettyVars f) where+  pPrint (PrettyVar x) = text x+  pPrint (PrettyFunc f) = pPrint f+instance PrettyTerm f => PrettyTerm (PrettyVars f) where+  termStyle (PrettyVar _) = uncurried+  termStyle (PrettyFunc f) = termStyle f+ ---------------------------------------------------------------------- -- Making proofs of existential goals more readable. ----------------------------------------------------------------------@@ -945,16 +990,17 @@ decodeGoal config pg =   case maybeDecodeGoal config pg of     Nothing -> pg-    Just (name, witness, goal, deriv) ->+    Just (name, vars, witness, goal, deriv) ->       checkProvedGoal $       pg {         pg_name = name,         pg_proof = certify deriv,+        pg_vars = vars,         pg_goal_hint = goal,         pg_witness_hint = witness }  maybeDecodeGoal :: forall f. Function f =>-  Config f -> ProvedGoal f -> Maybe (String, Subst f, Equation f, Derivation f)+  Config f -> ProvedGoal f -> Maybe (String, Maybe (Map Var String), Subst f, Equation f, Derivation f) maybeDecodeGoal Config{..} ProvedGoal{..}   | not cfg_eliminate_existentials_coding = Nothing   --  N.B. presentWithGoals takes care of expanding any lemma which mentions@@ -977,11 +1023,11 @@     decodeReflexivity _ = Nothing      -- Detect $equals(t, u) = $false.-    decodeConjecture :: Derivation f -> Maybe (String, Equation f, Subst f)+    decodeConjecture :: Derivation f -> Maybe (String, Maybe (Map Var String), Equation f, Subst f)     decodeConjecture (UseAxiom Axiom{..} sub) = do       guard (isFalseTerm (eqn_rhs axiom_eqn))       (t, u) <- decodeEquality (eqn_lhs axiom_eqn)-      return (axiom_name, t :=: u, sub)+      return (axiom_name, axiom_vars, t :=: u, sub)     decodeConjecture _ = Nothing      extract (p:ps) = do@@ -993,10 +1039,10 @@     cont p1 p2 (p:ps)       | Just t <- decodeReflexivity p =         cont (Refl t) (Refl t) ps-      | Just (name, eqn, sub) <- decodeConjecture p =+      | Just (name, vars, eqn, sub) <- decodeConjecture p =         -- If p1: s=t and p2: s=u         -- then symm p1 `trans` p2: t=u.-        return (name, sub, eqn, symm p1 `trans` p2)+        return (name, vars, sub, eqn, symm p1 `trans` p2)       | Cong eq [p1', p2'] <- p, isEquals eq =         cont (p1 `trans` p1') (p2 `trans` p2') ps     cont _ _ _ = Nothing
Twee/Rule.hs view
@@ -1,5 +1,5 @@ -- | Term rewriting.-{-# LANGUAGE TypeFamilies, FlexibleContexts, RecordWildCards, BangPatterns, OverloadedStrings, MultiParamTypeClasses, ScopedTypeVariables, GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings, MultiParamTypeClasses, DeriveAnyClass #-} module Twee.Rule where  import Twee.Base@@ -22,17 +22,16 @@ import Data.Tuple import Twee.Profile import Data.MemoUgly-import Debug.Trace-import Twee.Pretty-import Data.Function+--import Debug.Trace import Control.Arrow((***)) import GHC.Stack import Test.QuickCheck hiding (Function, subterms, Fun)-import Twee.Profile import Test.QuickCheck.Gen import Data.Semigroup import qualified Data.List.NonEmpty as NonEmpty import Test.QuickCheck.Random+import GHC.Generics+import Data.Binary.Sharing  -------------------------------------------------------------------------------- -- * Rewrite rules.@@ -48,13 +47,15 @@     -- For unoriented rules: vars lhs == vars rhs          -- | A proof that the rule holds.+    -- For efficiency, is not updated on substitution or on using 'backwards'.+    -- Use 'ruleDerivation' to extract a proof which accounts for this.     rule_proof :: !(Proof f),      -- | The left-hand side of the rule.     lhs :: {-# UNPACK #-} !(Term f),     -- | The right-hand side of the rule.     rhs :: {-# UNPACK #-} !(Term f) }-  deriving Show+  deriving (Show, Generic, Binary) instance Eq (Rule f) where   x == y = compare x y == EQ instance Ord (Rule f) where@@ -92,7 +93,7 @@   | Permutative [(Term f, Term f)]     -- | An unoriented rule.   | Unoriented-  deriving Show+  deriving (Show, Generic, Binary)  instance Eq (Orientation f) where _ == _ = True instance Ord (Orientation f) where compare _ _ = EQ@@ -542,6 +543,7 @@     cf_right :: Reduction1 f,     cf_orig_term :: Term f,     cf_orig_left :: Reduction1 f }+  deriving (Generic, Binary)  cf_left_term, cf_right_term :: ConfluenceFailure f -> Term f cf_left_term ConfluenceFailure{..} = result1 cf_term cf_left@@ -628,7 +630,7 @@     trace _ x = x     --normFirstStep t = trace (prettyShow (t, take 1 $ anywhere1 strat t)) $ head (head (anywhere1 strat t))     normSteps t = normaliseWith1 (const True) strat t-    normStepsVia r t = r `trans1` normSteps (result1 t r)+    --normStepsVia r t = r `trans1` normSteps (result1 t r)     norm =       memo $ \t ->         stamp "hasUNF.norm" $@@ -660,7 +662,7 @@     -- precondition: normR t r1 /= normR t r2     --conflict, conflict' :: Term f -> Reduction1 f -> Term f -> Reduction1 f -> Term f -> UNF f     conflict t rs1 u rs2 v = stamp "conflict" (conflict' t rs1 u rs2 v)-    conflict' t (r1:rs1) u (r2:rs2) v+    conflict' t (r1:_rs1) _u (r2:_rs2) _v       | trace "" $         trace ("Conflicting term: " ++ prettyShow t) $         trace ("Rule 1: " ++ prettyShow r1) $
Twee/Rule/Index.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE RecordWildCards, ScopedTypeVariables, FlexibleContexts, TypeFamilies #-}+{-# LANGUAGE DeriveAnyClass #-} module Twee.Rule.Index(   RuleIndex(..),   empty, insert, delete,@@ -9,12 +9,14 @@ import Twee.Rule import Twee.Index hiding (insert, delete, empty) import qualified Twee.Index as Index+import GHC.Generics+import Data.Binary.Sharing(Binary)  data RuleIndex f a =   RuleIndex {     index_oriented :: !(Index f a),     index_all      :: !(Index f a) }-  deriving Show+  deriving (Show, Generic, Binary)  empty :: RuleIndex f a empty = RuleIndex Index.empty Index.empty
Twee/Task.hs view
@@ -1,5 +1,4 @@ -- | A module which can run housekeeping tasks every so often.-{-# LANGUAGE RecordWildCards #-} module Twee.Task(Task, newTask, checkTask) where  import System.CPUTime
Twee/Term.hs view
@@ -1,4 +1,4 @@--- | Terms and substitutions.+-- | Terms and substitutions -- -- Terms in twee are represented as arrays rather than as an algebraic data -- type. This module defines pattern synonyms ('App', 'Var', 'Cons', 'Nil')@@ -13,7 +13,7 @@ --   * substitutions ('Substitution', 'Subst', 'subst'); --   * unification ('unify') and matching ('match'); --   * miscellaneous useful functions on terms.-{-# LANGUAGE BangPatterns, PatternSynonyms, ViewPatterns, TypeFamilies, OverloadedStrings, ScopedTypeVariables, CPP, DefaultSignatures #-}+{-# LANGUAGE PatternSynonyms, ViewPatterns, OverloadedStrings, CPP, DefaultSignatures, TypeApplications, GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -O2 -fmax-worker-args=100 #-} #ifdef USE_LLVM {-# OPTIONS_GHC -fllvm #-}@@ -65,7 +65,6 @@  import Prelude hiding (lookup) import Twee.Term.Core hiding (F)-import qualified Twee.Term.Core as Core import Data.List hiding (lookup, find, singleton) import Data.Maybe #if __GLASGOW_HASKELL__ < 804@@ -73,10 +72,11 @@ #endif import Data.IntMap.Strict(IntMap) import qualified Data.IntMap.Strict as IntMap-import Control.Arrow((&&&)) import Twee.Utils import Data.Intern import GHC.Stack+import Data.Binary.Sharing+import Data.Hashable  -------------------------------------------------------------------------------- -- * A type class for builders@@ -211,6 +211,8 @@   Subst {     unSubst :: IntMap (TermList f) }   deriving (Eq, Ord)+instance Hashable (Subst f) where+  hashWithSalt s = hashWithSalt s . substToList  -- | Return the highest-number variable in a substitution plus 1. {-# INLINE substSize #-}@@ -351,7 +353,7 @@ matchListIn !sub !pat !t   | lenList t < lenList pat = Nothing   | otherwise =-    let +    let         loop !sub ConsSym{hd = pat, tl = pats, rest = pats1} !ts = do           ConsSym{hd = t, tl = ts, rest = ts1} <- Just ts           case (pat, t) of@@ -510,6 +512,34 @@     occurs _ _ _ = Just ()  --------------------------------------------------------------------------------+-- Serialisation.+--------------------------------------------------------------------------------++instance (Intern f, Binary f) => Binary (TermList f) where+  put t = put (unpack t)+  get = buildList <$> getList getTerm++type BinarydTerm f = Either Var (Sym f, TermList f)++instance (Intern f, Binary f) => Binary (Term f) where+  put (Var x) = put (Left x :: BinarydTerm f)+  put (App f ts) = put (Right (f, ts) :: BinarydTerm f)+  get = build <$> getTerm++getTerm :: forall f. (Intern f, Binary f) => Get (Builder f)+getTerm = do+  val <- get :: Get (BinarydTerm f)+  case val of+    Left x -> return (var x)+    Right (f, ts) -> return (app f ts)++instance (Intern f, Binary f) => Binary (Subst f) where+  put = put . substToList+  get = fromJust . listToSubst <$> get++deriving instance Binary Var++-------------------------------------------------------------------------------- -- Miscellaneous stuff. -------------------------------------------------------------------------------- @@ -731,3 +761,9 @@ -- | Compare the values of two 'Sym's. (<<) :: (Intern f, Ord f) => Sym f -> Sym f -> Bool f << g = unintern f < unintern g++instance Hashable (Term f) where+  hashWithSalt s = hashWithSalt s . singleton+instance Hashable (TermList f) where+  hashWithSalt s = hashWithSalt s . map root . subtermsList+deriving instance Hashable Var
Twee/Term/Core.hs view
@@ -2,8 +2,8 @@ -- This module contains all the low-level icky bits -- and provides primitives for building higher-level stuff. {-# LANGUAGE CPP, PatternSynonyms, ViewPatterns,-    MagicHash, UnboxedTuples, BangPatterns,-    RankNTypes, RecordWildCards, GeneralizedNewtypeDeriving,+    MagicHash, UnboxedTuples,+    RankNTypes, GeneralizedNewtypeDeriving,     OverloadedStrings, RoleAnnotations #-} {-# OPTIONS_GHC -O2 -fmax-worker-args=100 #-} #ifdef USE_LLVM
Twee/Utils.hs view
@@ -1,6 +1,6 @@ -- | Miscellaneous utility functions. -{-# LANGUAGE CPP, MagicHash, GeneralizedNewtypeDeriving #-}+{-# LANGUAGE CPP, MagicHash #-} module Twee.Utils where  import Control.Arrow((&&&))@@ -12,8 +12,9 @@ import GHC.Types import Data.Bits import System.Random-import Data.Serialize+import qualified Data.Set as Set --import Test.QuickCheck hiding ((.&.))+import Data.Binary.Sharing  repeatM :: Monad m => m a -> m [a] repeatM = sequence . repeat@@ -48,6 +49,15 @@ usortBy' :: Ord b => (a -> b) -> [a] -> [a] usortBy' f = map snd . usortBy (comparing fst) . map (\x -> (f x, x)) +-- Like usort but preserves order+fastNub :: Ord a => [a] -> [a]+fastNub xs = collect Set.empty xs+  where+    collect _ [] = []+    collect seen (x:xs)+      | x `Set.member` seen = collect seen xs+      | otherwise = x:collect (Set.insert x seen) xs+ orElse :: Ordering -> Ordering -> Ordering EQ `orElse` x = x x  `orElse` _ = x@@ -143,6 +153,12 @@     prefix = [0..k-1]  data Sample a = Sample Integer [(Integer, Int)] [a]+-- TODO serialise properly+instance Binary a => Binary (Sample a) where+  put _ = put ()+  get = do+    () <- get+    return (emptySample 10)  emptySample :: Int -> Sample a emptySample k = Sample 0 (reservoir k) []@@ -178,41 +194,6 @@ foldn :: (a -> a) -> a -> Int -> a foldn _ e 0 = e foldn op e n | n > 0 = op (foldn op e (n-1))--newtype U8 = U8 Int deriving (Eq, Ord, Num, Real, Enum, Integral)---- Untested!-instance Serialize U8 where-  put (U8 n)-    | n < 0x80 = putWord8 (fromIntegral n)-    | n < 0x4000 = do-      putWord16be (fromIntegral n + 0x8000)-    | otherwise = do-      putWord32be (fromIntegral n + 0xc0000000)-  get = do-    x <- lookAhead getWord8-    if x < 0x80 then fromIntegral <$> getWord8-    else if x < 0xc0 then do-      n <- getWord16be-      return (fromIntegral (n - 0x8000))-    else do-      n <- getWord32be-      return (fromIntegral (n - 0xc0000000))---- Untested!-newtype U16 = U16 Int deriving (Eq, Ord, Num, Real, Enum, Integral)-instance Serialize U16 where-  put (U16 n)-    | n < 0x8000 = do-      putWord16be (fromIntegral n)-    | otherwise = do-      putWord32be (fromIntegral n + 0x80000000)-  get = do-    x <- lookAhead getWord8-    if x < 0x80 then fromIntegral <$> getWord16be-    else do-      n <- getWord32be-      return (fromIntegral (n - 0x80000000))  -- Can be used to write strictness annotations e.g. -- f !_ !_ | never = undefined
twee-lib.cabal view
@@ -1,7 +1,7 @@ name:                twee-lib-version:             2.6.1+version:             2.7.1 synopsis:            An equational theorem prover-homepage:            http://github.com/nick8325/twee+homepage:            http://smallbone.se license:             BSD3 license-file:        LICENSE author:              Nick Smallbone@@ -26,8 +26,8 @@  source-repository head   type:     git-  location: https://github.com/nick8325/twee.git-  branch:   master+  location: https://codeberg.org/nick8325/twee+  branch:   main  flag llvm   description: Build using LLVM backend for faster code.@@ -55,6 +55,7 @@     Twee.Index     Twee.Join     Twee.KBO+    Twee.LPO     Twee.Pretty     Twee.Profile     Twee.Proof@@ -65,7 +66,7 @@     Twee.Utils     Twee.Term.Core     Data.Intern-  other-modules:+    Data.Binary.Sharing     Data.BatchedQueue     Data.ChurchList     Data.DynamicArray@@ -83,14 +84,26 @@     ghc-prim,     primitive >= 0.7.1.0,     uglymemo,-    random,+    random >= 1.2,     bytestring,-    cereal,-    QuickCheck+    binary,+    QuickCheck,+    deepseq >= 1.4.0.0,+    unordered-containers,+    hashable   hs-source-dirs:      .-  ghc-options:         -W -fno-warn-incomplete-patterns -fno-warn-dodgy-imports -fno-warn-x-partial+  ghc-options:         -W -fno-warn-incomplete-patterns -fno-warn-dodgy-imports -fno-warn-deprecations   default-language:    Haskell2010-  default-extensions:  TypeOperators+  default-extensions:+    BangPatterns+    DeriveGeneric+    FlexibleContexts+    PatternGuards+    RecordWildCards+    ScopedTypeVariables+    StandaloneDeriving+    TypeFamilies+    TypeOperators    if flag(llvm)     cpp-options: -DUSE_LLVM