{-# OPTIONS_GHC -Wno-redundant-constraints #-}
{-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts, DataKinds #-}
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, TypeOperators #-}
{-# LANGUAGE DerivingVia, InstanceSigs, UndecidableInstances, BangPatterns #-}

-- | This module provides the top level API of this library.
--   It makes use of Haskell's powerful typesystem to make certain invalid states
--   impossible to represent. It does this with a small type level DSL for
--   describing properties of the Datalog program (see the 'Program' and 'Fact'
--   typeclasses for more information).
--   This module also provides a MTL-style interface to Souffle related operations
--   so it can be integrated with existing monad transformer stacks.
module Language.Souffle
  ( Program(..)
  , Fact(..)
  , Marshal.Marshal(..)
  , Handle
  , CollectFacts
  , MonadSouffle(..)
  , SouffleM
  , runSouffle
  ) where

import Prelude hiding ( init )
import Data.Foldable ( traverse_ )
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
import Control.Monad.RWS
import Control.Monad.Except
import Foreign.ForeignPtr
import Foreign.Ptr
import Type.Errors.Pretty
import Data.Proxy
import Data.Kind
import Data.Word
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
import qualified Language.Souffle.Internal as Internal
import qualified Language.Souffle.Marshal as Marshal


-- | A datatype representing a handle to a datalog program.
--   The type parameter is used for keeping track of which program
--   type the handle belongs to for additional type safety.
newtype Handle prog = Handle (ForeignPtr Internal.Souffle)

-- | A typeclass for describing a datalog program.
--
-- Example usage (assuming the program was generated from path.dl
-- and contains 2 facts: Edge and Reachable):
--
-- @
-- data Path = Path  -- Handle for the datalog program
--
-- instance Program Path where
--   type ProgramFacts Path = '[Edge, Reachable]
--   factName = const "path"
-- @
class Program a where
  -- | A type level list of facts that belong to this program.
  --   This list is used to check that only known facts are added to a program.
  type ProgramFacts a :: [Type]

  -- | Function for obtaining the name of a Datalog program.
  --   This has to be the same as the name of the .dl file (minus the extension).
  --
  -- It uses a 'Proxy' to select the correct instance.
  programName :: Proxy a -> String

-- | A typeclass for data types representing a fact in datalog.
class Marshal.Marshal a => Fact a where
  -- | Function for obtaining the name of a fact
  --   (has to be the same as described in the Datalog program).
  --
  -- It uses a 'Proxy' to select the correct instance.
  --
  -- Example usage:
  --
  -- @
  -- instance Fact Edge where
  --   factName = const "edge"
  -- @
  factName :: Proxy a -> String

type family ContainsFact prog fact :: Constraint where
  ContainsFact prog fact =
    CheckContains prog (ProgramFacts prog) fact

type family CheckContains prog facts fact :: Constraint where
  CheckContains prog '[] fact =
    TypeError ("You tried to perform an action with a fact of type '" <> fact
    <> "' for program '" <> prog <> "'."
    % "The program contains the following facts: " <> ProgramFacts prog <> "."
    % "It does not contain fact: " <> fact <> "."
    % "You can fix this error by adding the type '" <> fact
    <> "' to the ProgramFacts type in the Program instance for " <> prog <> ".")
  CheckContains _ (a ': _) a = ()
  CheckContains prog (_ ': as) b = CheckContains prog as b


-- | A monad for executing Souffle-related actions in.
newtype SouffleM a
  = SouffleM
  { SouffleM a -> IO a
runSouffle :: IO a  -- ^ Returns the underlying IO action.
  } deriving ( a -> SouffleM b -> SouffleM a
(a -> b) -> SouffleM a -> SouffleM b
(forall a b. (a -> b) -> SouffleM a -> SouffleM b)
-> (forall a b. a -> SouffleM b -> SouffleM a) -> Functor SouffleM
forall a b. a -> SouffleM b -> SouffleM a
forall a b. (a -> b) -> SouffleM a -> SouffleM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SouffleM b -> SouffleM a
$c<$ :: forall a b. a -> SouffleM b -> SouffleM a
fmap :: (a -> b) -> SouffleM a -> SouffleM b
$cfmap :: forall a b. (a -> b) -> SouffleM a -> SouffleM b
Functor, Functor SouffleM
a -> SouffleM a
Functor SouffleM =>
(forall a. a -> SouffleM a)
-> (forall a b. SouffleM (a -> b) -> SouffleM a -> SouffleM b)
-> (forall a b c.
    (a -> b -> c) -> SouffleM a -> SouffleM b -> SouffleM c)
-> (forall a b. SouffleM a -> SouffleM b -> SouffleM b)
-> (forall a b. SouffleM a -> SouffleM b -> SouffleM a)
-> Applicative SouffleM
SouffleM a -> SouffleM b -> SouffleM b
SouffleM a -> SouffleM b -> SouffleM a
SouffleM (a -> b) -> SouffleM a -> SouffleM b
(a -> b -> c) -> SouffleM a -> SouffleM b -> SouffleM c
forall a. a -> SouffleM a
forall a b. SouffleM a -> SouffleM b -> SouffleM a
forall a b. SouffleM a -> SouffleM b -> SouffleM b
forall a b. SouffleM (a -> b) -> SouffleM a -> SouffleM b
forall a b c.
(a -> b -> c) -> SouffleM a -> SouffleM b -> SouffleM c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: SouffleM a -> SouffleM b -> SouffleM a
$c<* :: forall a b. SouffleM a -> SouffleM b -> SouffleM a
*> :: SouffleM a -> SouffleM b -> SouffleM b
$c*> :: forall a b. SouffleM a -> SouffleM b -> SouffleM b
liftA2 :: (a -> b -> c) -> SouffleM a -> SouffleM b -> SouffleM c
$cliftA2 :: forall a b c.
(a -> b -> c) -> SouffleM a -> SouffleM b -> SouffleM c
<*> :: SouffleM (a -> b) -> SouffleM a -> SouffleM b
$c<*> :: forall a b. SouffleM (a -> b) -> SouffleM a -> SouffleM b
pure :: a -> SouffleM a
$cpure :: forall a. a -> SouffleM a
$cp1Applicative :: Functor SouffleM
Applicative, Applicative SouffleM
a -> SouffleM a
Applicative SouffleM =>
(forall a b. SouffleM a -> (a -> SouffleM b) -> SouffleM b)
-> (forall a b. SouffleM a -> SouffleM b -> SouffleM b)
-> (forall a. a -> SouffleM a)
-> Monad SouffleM
SouffleM a -> (a -> SouffleM b) -> SouffleM b
SouffleM a -> SouffleM b -> SouffleM b
forall a. a -> SouffleM a
forall a b. SouffleM a -> SouffleM b -> SouffleM b
forall a b. SouffleM a -> (a -> SouffleM b) -> SouffleM b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> SouffleM a
$creturn :: forall a. a -> SouffleM a
>> :: SouffleM a -> SouffleM b -> SouffleM b
$c>> :: forall a b. SouffleM a -> SouffleM b -> SouffleM b
>>= :: SouffleM a -> (a -> SouffleM b) -> SouffleM b
$c>>= :: forall a b. SouffleM a -> (a -> SouffleM b) -> SouffleM b
$cp1Monad :: Applicative SouffleM
Monad, Monad SouffleM
Monad SouffleM =>
(forall a. IO a -> SouffleM a) -> MonadIO SouffleM
IO a -> SouffleM a
forall a. IO a -> SouffleM a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> SouffleM a
$cliftIO :: forall a. IO a -> SouffleM a
$cp1MonadIO :: Monad SouffleM
MonadIO ) via IO

-- | Helper typeclass for collecting facts into a container-like structure.
--   The order of returned facts is unspecified for performance reasons.
--   Only used internally.
class CollectFacts c where
  collectFacts :: Marshal.Marshal a
               => Int
               -> ForeignPtr Internal.RelationIterator
               -> IO (c a)

instance CollectFacts V.Vector where
  collectFacts :: Int -> ForeignPtr RelationIterator -> IO (Vector a)
collectFacts factCount :: Int
factCount iterator :: ForeignPtr RelationIterator
iterator = do
    MVector RealWorld a
vec <- Int -> IO (MVector (PrimState IO) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> m (MVector (PrimState m) a)
MV.unsafeNew Int
factCount
    MVector RealWorld a
-> Int -> Int -> ForeignPtr RelationIterator -> IO (Vector a)
forall a.
Marshal a =>
MVector RealWorld a
-> Int -> Int -> ForeignPtr RelationIterator -> IO (Vector a)
go MVector RealWorld a
vec 0 Int
factCount ForeignPtr RelationIterator
iterator
    where
      go :: MVector RealWorld a
-> Int -> Int -> ForeignPtr RelationIterator -> IO (Vector a)
go vec :: MVector RealWorld a
vec idx :: Int
idx count :: Int
count _ | Int
idx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
count = MVector (PrimState IO) a -> IO (Vector a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze MVector RealWorld a
MVector (PrimState IO) a
vec
      go vec :: MVector RealWorld a
vec idx :: Int
idx count :: Int
count it :: ForeignPtr RelationIterator
it = do
        Ptr Tuple
tuple <- ForeignPtr RelationIterator -> IO (Ptr Tuple)
Internal.relationIteratorNext ForeignPtr RelationIterator
it
        a
result <- MarshalT IO a -> Ptr Tuple -> IO a
forall (m :: * -> *) a. MarshalT m a -> Ptr Tuple -> m a
Marshal.runMarshalT MarshalT IO a
forall a (m :: * -> *). (Marshal a, MonadIO m) => MarshalT m a
Marshal.pop Ptr Tuple
tuple
        MVector (PrimState IO) a -> Int -> a -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.unsafeWrite MVector RealWorld a
MVector (PrimState IO) a
vec Int
idx a
result
        MVector RealWorld a
-> Int -> Int -> ForeignPtr RelationIterator -> IO (Vector a)
go MVector RealWorld a
vec (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Int
count ForeignPtr RelationIterator
it
  {-# INLINABLE collectFacts #-}

instance CollectFacts [] where
  collectFacts :: Int -> ForeignPtr RelationIterator -> IO [a]
collectFacts factCount :: Int
factCount = Int -> Int -> [a] -> ForeignPtr RelationIterator -> IO [a]
forall t a.
(Eq t, Marshal a, Num t) =>
t -> t -> [a] -> ForeignPtr RelationIterator -> IO [a]
go 0 Int
factCount []
    where
      go :: t -> t -> [a] -> ForeignPtr RelationIterator -> IO [a]
go idx :: t
idx count :: t
count acc :: [a]
acc _ | t
idx t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
count = [a] -> IO [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
acc
      go idx :: t
idx count :: t
count ![a]
acc !ForeignPtr RelationIterator
it = do
        Ptr Tuple
tuple <- ForeignPtr RelationIterator -> IO (Ptr Tuple)
Internal.relationIteratorNext ForeignPtr RelationIterator
it
        a
result <- MarshalT IO a -> Ptr Tuple -> IO a
forall (m :: * -> *) a. MarshalT m a -> Ptr Tuple -> m a
Marshal.runMarshalT MarshalT IO a
forall a (m :: * -> *). (Marshal a, MonadIO m) => MarshalT m a
Marshal.pop Ptr Tuple
tuple
        t -> t -> [a] -> ForeignPtr RelationIterator -> IO [a]
go (t
idx t -> t -> t
forall a. Num a => a -> a -> a
+ 1) t
count (a
result a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc) ForeignPtr RelationIterator
it
  {-# INLINABLE collectFacts #-}

-- | A mtl-style typeclass for Souffle-related actions.
class Monad m => MonadSouffle m where
  {- | Initializes a Souffle program.

     The action will return 'Nothing' if it failed to load the Souffle program.
     Otherwise it will return a 'Handle' that can be used in other functions
     in this module.
  -}
  init :: Program prog => prog -> m (Maybe (Handle prog))

  -- | Runs the Souffle program.
  run :: Handle prog -> m ()

  -- | Sets the number of CPU cores this Souffle program should use.
  setNumThreads :: Handle prog -> Word64 -> m ()

  -- | Gets the number of CPU cores this Souffle program should use.
  getNumThreads :: Handle prog -> m Word64

  -- | Load all facts from files in a certain directory.
  loadFiles :: Handle prog -> FilePath -> m ()

  -- | Write out all facts of the program to CSV files
  --   (as defined in the Souffle program).
  writeFiles :: Handle prog -> m ()

  -- | Returns all facts of a program. This function makes use of type inference
  --   to select the type of fact to return.
  getFacts :: (Fact a, ContainsFact prog a, CollectFacts c)
           => Handle prog -> m (c a)

  -- | Searches for a fact in a program.
  --   Returns 'Nothing' if no matching fact was found; otherwise 'Just' the fact.
  --
  --   Conceptually equivalent to @List.find (== fact) \<$\> getFacts prog@, but this operation
  --   can be implemented much faster.
  findFact :: (Fact a, ContainsFact prog a)
           => Handle prog -> a -> m (Maybe a)

  -- | Adds a fact to the program.
  addFact :: (Fact a, ContainsFact prog a)
          => Handle prog -> a -> m ()

  -- | Adds multiple facts to the program. This function could be implemented
  --   in terms of 'addFact', but this is done as a minor optimization.
  addFacts :: (Foldable t, Fact a, ContainsFact prog a)
           => Handle prog -> t a -> m ()

instance MonadSouffle SouffleM where
  init :: forall prog. Program prog
       => prog -> SouffleM (Maybe (Handle prog))
  init :: prog -> SouffleM (Maybe (Handle prog))
init _ =
    let progName :: FilePath
progName = Proxy prog -> FilePath
forall a. Program a => Proxy a -> FilePath
programName (Proxy prog
forall k (t :: k). Proxy t
Proxy :: Proxy prog)
    in IO (Maybe (Handle prog)) -> SouffleM (Maybe (Handle prog))
forall a. IO a -> SouffleM a
SouffleM (IO (Maybe (Handle prog)) -> SouffleM (Maybe (Handle prog)))
-> IO (Maybe (Handle prog)) -> SouffleM (Maybe (Handle prog))
forall a b. (a -> b) -> a -> b
$ (ForeignPtr Souffle -> Handle prog)
-> Maybe (ForeignPtr Souffle) -> Maybe (Handle prog)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr Souffle -> Handle prog
forall prog. ForeignPtr Souffle -> Handle prog
Handle (Maybe (ForeignPtr Souffle) -> Maybe (Handle prog))
-> IO (Maybe (ForeignPtr Souffle)) -> IO (Maybe (Handle prog))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO (Maybe (ForeignPtr Souffle))
Internal.init FilePath
progName
  {-# INLINABLE init #-}

  run :: Handle prog -> SouffleM ()
run (Handle prog :: ForeignPtr Souffle
prog) = IO () -> SouffleM ()
forall a. IO a -> SouffleM a
SouffleM (IO () -> SouffleM ()) -> IO () -> SouffleM ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr Souffle -> IO ()
Internal.run ForeignPtr Souffle
prog
  {-# INLINABLE run #-}

  setNumThreads :: Handle prog -> Word64 -> SouffleM ()
setNumThreads (Handle prog :: ForeignPtr Souffle
prog) numCores :: Word64
numCores =
    IO () -> SouffleM ()
forall a. IO a -> SouffleM a
SouffleM (IO () -> SouffleM ()) -> IO () -> SouffleM ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr Souffle -> Word64 -> IO ()
Internal.setNumThreads ForeignPtr Souffle
prog Word64
numCores
  {-# INLINABLE setNumThreads #-}

  getNumThreads :: Handle prog -> SouffleM Word64
getNumThreads (Handle prog :: ForeignPtr Souffle
prog) =
    IO Word64 -> SouffleM Word64
forall a. IO a -> SouffleM a
SouffleM (IO Word64 -> SouffleM Word64) -> IO Word64 -> SouffleM Word64
forall a b. (a -> b) -> a -> b
$ ForeignPtr Souffle -> IO Word64
Internal.getNumThreads ForeignPtr Souffle
prog
  {-# INLINABLE getNumThreads #-}

  loadFiles :: Handle prog -> FilePath -> SouffleM ()
loadFiles (Handle prog :: ForeignPtr Souffle
prog) = IO () -> SouffleM ()
forall a. IO a -> SouffleM a
SouffleM (IO () -> SouffleM ())
-> (FilePath -> IO ()) -> FilePath -> SouffleM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Souffle -> FilePath -> IO ()
Internal.loadAll ForeignPtr Souffle
prog
  {-# INLINABLE loadFiles #-}

  writeFiles :: Handle prog -> SouffleM ()
writeFiles (Handle prog :: ForeignPtr Souffle
prog) = IO () -> SouffleM ()
forall a. IO a -> SouffleM a
SouffleM (IO () -> SouffleM ()) -> IO () -> SouffleM ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr Souffle -> IO ()
Internal.printAll ForeignPtr Souffle
prog
  {-# INLINABLE writeFiles #-}

  addFact :: forall a prog. (Fact a, ContainsFact prog a)
          => Handle prog -> a -> SouffleM ()
  addFact :: Handle prog -> a -> SouffleM ()
addFact (Handle prog :: ForeignPtr Souffle
prog) fact :: a
fact = IO () -> SouffleM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SouffleM ()) -> IO () -> SouffleM ()
forall a b. (a -> b) -> a -> b
$ do
    let relationName :: FilePath
relationName = Proxy a -> FilePath
forall a. Fact a => Proxy a -> FilePath
factName (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
    Ptr Relation
relation <- ForeignPtr Souffle -> FilePath -> IO (Ptr Relation)
Internal.getRelation ForeignPtr Souffle
prog FilePath
relationName
    Ptr Relation -> a -> IO ()
forall a. Fact a => Ptr Relation -> a -> IO ()
addFact' Ptr Relation
relation a
fact
  {-# INLINABLE addFact #-}

  addFacts :: forall t a prog. (Foldable t, Fact a, ContainsFact prog a)
           => Handle prog -> t a -> SouffleM ()
  addFacts :: Handle prog -> t a -> SouffleM ()
addFacts (Handle prog :: ForeignPtr Souffle
prog) facts :: t a
facts = IO () -> SouffleM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SouffleM ()) -> IO () -> SouffleM ()
forall a b. (a -> b) -> a -> b
$ do
    let relationName :: FilePath
relationName = Proxy a -> FilePath
forall a. Fact a => Proxy a -> FilePath
factName (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
    Ptr Relation
relation <- ForeignPtr Souffle -> FilePath -> IO (Ptr Relation)
Internal.getRelation ForeignPtr Souffle
prog FilePath
relationName
    (a -> IO ()) -> t a -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Ptr Relation -> a -> IO ()
forall a. Fact a => Ptr Relation -> a -> IO ()
addFact' Ptr Relation
relation) t a
facts
  {-# INLINABLE addFacts #-}

  getFacts :: forall a prog c. (Fact a, ContainsFact prog a, CollectFacts c)
           => Handle prog -> SouffleM (c a)
  getFacts :: Handle prog -> SouffleM (c a)
getFacts (Handle prog :: ForeignPtr Souffle
prog) = IO (c a) -> SouffleM (c a)
forall a. IO a -> SouffleM a
SouffleM (IO (c a) -> SouffleM (c a)) -> IO (c a) -> SouffleM (c a)
forall a b. (a -> b) -> a -> b
$ do
    let relationName :: FilePath
relationName = Proxy a -> FilePath
forall a. Fact a => Proxy a -> FilePath
factName (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
    Ptr Relation
relation <- ForeignPtr Souffle -> FilePath -> IO (Ptr Relation)
Internal.getRelation ForeignPtr Souffle
prog FilePath
relationName
    Int
factCount <- Ptr Relation -> IO Int
Internal.countFacts Ptr Relation
relation
    Ptr Relation -> IO (ForeignPtr RelationIterator)
Internal.getRelationIterator Ptr Relation
relation IO (ForeignPtr RelationIterator)
-> (ForeignPtr RelationIterator -> IO (c a)) -> IO (c a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> ForeignPtr RelationIterator -> IO (c a)
forall (c :: * -> *) a.
(CollectFacts c, Marshal a) =>
Int -> ForeignPtr RelationIterator -> IO (c a)
collectFacts Int
factCount
  {-# INLINABLE getFacts #-}

  findFact :: forall a prog. (Fact a, ContainsFact prog a)
           => Handle prog -> a -> SouffleM (Maybe a)
  findFact :: Handle prog -> a -> SouffleM (Maybe a)
findFact (Handle prog :: ForeignPtr Souffle
prog) a :: a
a = IO (Maybe a) -> SouffleM (Maybe a)
forall a. IO a -> SouffleM a
SouffleM (IO (Maybe a) -> SouffleM (Maybe a))
-> IO (Maybe a) -> SouffleM (Maybe a)
forall a b. (a -> b) -> a -> b
$ do
    let relationName :: FilePath
relationName = Proxy a -> FilePath
forall a. Fact a => Proxy a -> FilePath
factName (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
    Ptr Relation
relation <- ForeignPtr Souffle -> FilePath -> IO (Ptr Relation)
Internal.getRelation ForeignPtr Souffle
prog FilePath
relationName
    ForeignPtr Tuple
tuple <- Ptr Relation -> IO (ForeignPtr Tuple)
Internal.allocTuple Ptr Relation
relation
    ForeignPtr Tuple -> (Ptr Tuple -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tuple
tuple ((Ptr Tuple -> IO ()) -> IO ()) -> (Ptr Tuple -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ MarshalT IO () -> Ptr Tuple -> IO ()
forall (m :: * -> *) a. MarshalT m a -> Ptr Tuple -> m a
Marshal.runMarshalT (a -> MarshalT IO ()
forall a (m :: * -> *).
(Marshal a, MonadIO m) =>
a -> MarshalT m ()
Marshal.push a
a)
    Bool
found <- Ptr Relation -> ForeignPtr Tuple -> IO Bool
Internal.containsTuple Ptr Relation
relation ForeignPtr Tuple
tuple
    Maybe a -> IO (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe a -> IO (Maybe a)) -> Maybe a -> IO (Maybe a)
forall a b. (a -> b) -> a -> b
$ if Bool
found then a -> Maybe a
forall a. a -> Maybe a
Just a
a else Maybe a
forall a. Maybe a
Nothing
  {-# INLINABLE findFact #-}

addFact' :: Fact a => Ptr Internal.Relation -> a -> IO ()
addFact' :: Ptr Relation -> a -> IO ()
addFact' relation :: Ptr Relation
relation fact :: a
fact = do
  ForeignPtr Tuple
tuple <- Ptr Relation -> IO (ForeignPtr Tuple)
Internal.allocTuple Ptr Relation
relation
  ForeignPtr Tuple -> (Ptr Tuple -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tuple
tuple ((Ptr Tuple -> IO ()) -> IO ()) -> (Ptr Tuple -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ MarshalT IO () -> Ptr Tuple -> IO ()
forall (m :: * -> *) a. MarshalT m a -> Ptr Tuple -> m a
Marshal.runMarshalT (a -> MarshalT IO ()
forall a (m :: * -> *).
(Marshal a, MonadIO m) =>
a -> MarshalT m ()
Marshal.push a
fact)
  Ptr Relation -> ForeignPtr Tuple -> IO ()
Internal.addTuple Ptr Relation
relation ForeignPtr Tuple
tuple
{-# INLINABLE addFact' #-}


instance MonadSouffle m => MonadSouffle (ReaderT r m) where
  init :: prog -> ReaderT r m (Maybe (Handle prog))
init = m (Maybe (Handle prog)) -> ReaderT r m (Maybe (Handle prog))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Handle prog)) -> ReaderT r m (Maybe (Handle prog)))
-> (prog -> m (Maybe (Handle prog)))
-> prog
-> ReaderT r m (Maybe (Handle prog))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. prog -> m (Maybe (Handle prog))
forall (m :: * -> *) prog.
(MonadSouffle m, Program prog) =>
prog -> m (Maybe (Handle prog))
init
  {-# INLINABLE init #-}
  run :: Handle prog -> ReaderT r m ()
run = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (Handle prog -> m ()) -> Handle prog -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
run
  {-# INLINABLE run #-}
  setNumThreads :: Handle prog -> Word64 -> ReaderT r m ()
setNumThreads prog :: Handle prog
prog = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (Word64 -> m ()) -> Word64 -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> Word64 -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> Word64 -> m ()
setNumThreads Handle prog
prog
  {-# INLINABLE setNumThreads #-}
  getNumThreads :: Handle prog -> ReaderT r m Word64
getNumThreads = m Word64 -> ReaderT r m Word64
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Word64 -> ReaderT r m Word64)
-> (Handle prog -> m Word64) -> Handle prog -> ReaderT r m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m Word64
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> m Word64
getNumThreads
  {-# INLINABLE getNumThreads #-}
  loadFiles :: Handle prog -> FilePath -> ReaderT r m ()
loadFiles prog :: Handle prog
prog = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (FilePath -> m ()) -> FilePath -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> FilePath -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> FilePath -> m ()
loadFiles Handle prog
prog
  {-# INLINABLE loadFiles #-}
  writeFiles :: Handle prog -> ReaderT r m ()
writeFiles = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (Handle prog -> m ()) -> Handle prog -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
writeFiles
  {-# INLINABLE writeFiles #-}
  getFacts :: Handle prog -> ReaderT r m (c a)
getFacts = m (c a) -> ReaderT r m (c a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (c a) -> ReaderT r m (c a))
-> (Handle prog -> m (c a)) -> Handle prog -> ReaderT r m (c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m (c a)
forall (m :: * -> *) a prog (c :: * -> *).
(MonadSouffle m, Fact a, ContainsFact prog a, CollectFacts c) =>
Handle prog -> m (c a)
getFacts
  {-# INLINABLE getFacts #-}
  findFact :: Handle prog -> a -> ReaderT r m (Maybe a)
findFact prog :: Handle prog
prog = m (Maybe a) -> ReaderT r m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ReaderT r m (Maybe a))
-> (a -> m (Maybe a)) -> a -> ReaderT r m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m (Maybe a)
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m (Maybe a)
findFact Handle prog
prog
  {-# INLINABLE findFact #-}
  addFact :: Handle prog -> a -> ReaderT r m ()
addFact fact :: Handle prog
fact = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ()) -> (a -> m ()) -> a -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m ()
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m ()
addFact Handle prog
fact
  {-# INLINABLE addFact #-}
  addFacts :: Handle prog -> t a -> ReaderT r m ()
addFacts facts :: Handle prog
facts = m () -> ReaderT r m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ()) -> (t a -> m ()) -> t a -> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> t a -> m ()
forall (m :: * -> *) (t :: * -> *) a prog.
(MonadSouffle m, Foldable t, Fact a, ContainsFact prog a) =>
Handle prog -> t a -> m ()
addFacts Handle prog
facts
  {-# INLINABLE addFacts #-}

instance (Monoid w, MonadSouffle m) => MonadSouffle (WriterT w m) where
  init :: prog -> WriterT w m (Maybe (Handle prog))
init = m (Maybe (Handle prog)) -> WriterT w m (Maybe (Handle prog))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Handle prog)) -> WriterT w m (Maybe (Handle prog)))
-> (prog -> m (Maybe (Handle prog)))
-> prog
-> WriterT w m (Maybe (Handle prog))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. prog -> m (Maybe (Handle prog))
forall (m :: * -> *) prog.
(MonadSouffle m, Program prog) =>
prog -> m (Maybe (Handle prog))
init
  {-# INLINABLE init #-}
  run :: Handle prog -> WriterT w m ()
run = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (Handle prog -> m ()) -> Handle prog -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
run
  {-# INLINABLE run #-}
  setNumThreads :: Handle prog -> Word64 -> WriterT w m ()
setNumThreads prog :: Handle prog
prog = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (Word64 -> m ()) -> Word64 -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> Word64 -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> Word64 -> m ()
setNumThreads Handle prog
prog
  {-# INLINABLE setNumThreads #-}
  getNumThreads :: Handle prog -> WriterT w m Word64
getNumThreads = m Word64 -> WriterT w m Word64
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Word64 -> WriterT w m Word64)
-> (Handle prog -> m Word64) -> Handle prog -> WriterT w m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m Word64
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> m Word64
getNumThreads
  {-# INLINABLE getNumThreads #-}
  loadFiles :: Handle prog -> FilePath -> WriterT w m ()
loadFiles prog :: Handle prog
prog = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (FilePath -> m ()) -> FilePath -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> FilePath -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> FilePath -> m ()
loadFiles Handle prog
prog
  {-# INLINABLE loadFiles #-}
  writeFiles :: Handle prog -> WriterT w m ()
writeFiles = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (Handle prog -> m ()) -> Handle prog -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
writeFiles
  {-# INLINABLE writeFiles #-}
  getFacts :: Handle prog -> WriterT w m (c a)
getFacts = m (c a) -> WriterT w m (c a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (c a) -> WriterT w m (c a))
-> (Handle prog -> m (c a)) -> Handle prog -> WriterT w m (c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m (c a)
forall (m :: * -> *) a prog (c :: * -> *).
(MonadSouffle m, Fact a, ContainsFact prog a, CollectFacts c) =>
Handle prog -> m (c a)
getFacts
  {-# INLINABLE getFacts #-}
  findFact :: Handle prog -> a -> WriterT w m (Maybe a)
findFact prog :: Handle prog
prog = m (Maybe a) -> WriterT w m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> WriterT w m (Maybe a))
-> (a -> m (Maybe a)) -> a -> WriterT w m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m (Maybe a)
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m (Maybe a)
findFact Handle prog
prog
  {-# INLINABLE findFact #-}
  addFact :: Handle prog -> a -> WriterT w m ()
addFact fact :: Handle prog
fact = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ()) -> (a -> m ()) -> a -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m ()
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m ()
addFact Handle prog
fact
  {-# INLINABLE addFact #-}
  addFacts :: Handle prog -> t a -> WriterT w m ()
addFacts facts :: Handle prog
facts = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ()) -> (t a -> m ()) -> t a -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> t a -> m ()
forall (m :: * -> *) (t :: * -> *) a prog.
(MonadSouffle m, Foldable t, Fact a, ContainsFact prog a) =>
Handle prog -> t a -> m ()
addFacts Handle prog
facts
  {-# INLINABLE addFacts #-}

instance MonadSouffle m => MonadSouffle (StateT s m) where
  init :: prog -> StateT s m (Maybe (Handle prog))
init = m (Maybe (Handle prog)) -> StateT s m (Maybe (Handle prog))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Handle prog)) -> StateT s m (Maybe (Handle prog)))
-> (prog -> m (Maybe (Handle prog)))
-> prog
-> StateT s m (Maybe (Handle prog))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. prog -> m (Maybe (Handle prog))
forall (m :: * -> *) prog.
(MonadSouffle m, Program prog) =>
prog -> m (Maybe (Handle prog))
init
  {-# INLINABLE init #-}
  run :: Handle prog -> StateT s m ()
run = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (Handle prog -> m ()) -> Handle prog -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
run
  {-# INLINABLE run #-}
  setNumThreads :: Handle prog -> Word64 -> StateT s m ()
setNumThreads prog :: Handle prog
prog = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (Word64 -> m ()) -> Word64 -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> Word64 -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> Word64 -> m ()
setNumThreads Handle prog
prog
  {-# INLINABLE setNumThreads #-}
  getNumThreads :: Handle prog -> StateT s m Word64
getNumThreads = m Word64 -> StateT s m Word64
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Word64 -> StateT s m Word64)
-> (Handle prog -> m Word64) -> Handle prog -> StateT s m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m Word64
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> m Word64
getNumThreads
  {-# INLINABLE getNumThreads #-}
  loadFiles :: Handle prog -> FilePath -> StateT s m ()
loadFiles prog :: Handle prog
prog = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (FilePath -> m ()) -> FilePath -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> FilePath -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> FilePath -> m ()
loadFiles Handle prog
prog
  {-# INLINABLE loadFiles #-}
  writeFiles :: Handle prog -> StateT s m ()
writeFiles = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (Handle prog -> m ()) -> Handle prog -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
writeFiles
  {-# INLINABLE writeFiles #-}
  getFacts :: Handle prog -> StateT s m (c a)
getFacts = m (c a) -> StateT s m (c a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (c a) -> StateT s m (c a))
-> (Handle prog -> m (c a)) -> Handle prog -> StateT s m (c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m (c a)
forall (m :: * -> *) a prog (c :: * -> *).
(MonadSouffle m, Fact a, ContainsFact prog a, CollectFacts c) =>
Handle prog -> m (c a)
getFacts
  {-# INLINABLE getFacts #-}
  findFact :: Handle prog -> a -> StateT s m (Maybe a)
findFact prog :: Handle prog
prog = m (Maybe a) -> StateT s m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> StateT s m (Maybe a))
-> (a -> m (Maybe a)) -> a -> StateT s m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m (Maybe a)
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m (Maybe a)
findFact Handle prog
prog
  {-# INLINABLE findFact #-}
  addFact :: Handle prog -> a -> StateT s m ()
addFact fact :: Handle prog
fact = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ()) -> (a -> m ()) -> a -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m ()
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m ()
addFact Handle prog
fact
  {-# INLINABLE addFact #-}
  addFacts :: Handle prog -> t a -> StateT s m ()
addFacts facts :: Handle prog
facts = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ()) -> (t a -> m ()) -> t a -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> t a -> m ()
forall (m :: * -> *) (t :: * -> *) a prog.
(MonadSouffle m, Foldable t, Fact a, ContainsFact prog a) =>
Handle prog -> t a -> m ()
addFacts Handle prog
facts
  {-# INLINABLE addFacts #-}

instance (MonadSouffle m, Monoid w) => MonadSouffle (RWST r w s m) where
  init :: prog -> RWST r w s m (Maybe (Handle prog))
init = m (Maybe (Handle prog)) -> RWST r w s m (Maybe (Handle prog))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Handle prog)) -> RWST r w s m (Maybe (Handle prog)))
-> (prog -> m (Maybe (Handle prog)))
-> prog
-> RWST r w s m (Maybe (Handle prog))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. prog -> m (Maybe (Handle prog))
forall (m :: * -> *) prog.
(MonadSouffle m, Program prog) =>
prog -> m (Maybe (Handle prog))
init
  {-# INLINABLE init #-}
  run :: Handle prog -> RWST r w s m ()
run = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (Handle prog -> m ()) -> Handle prog -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
run
  {-# INLINABLE run #-}
  setNumThreads :: Handle prog -> Word64 -> RWST r w s m ()
setNumThreads prog :: Handle prog
prog = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (Word64 -> m ()) -> Word64 -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> Word64 -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> Word64 -> m ()
setNumThreads Handle prog
prog
  {-# INLINABLE setNumThreads #-}
  getNumThreads :: Handle prog -> RWST r w s m Word64
getNumThreads = m Word64 -> RWST r w s m Word64
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Word64 -> RWST r w s m Word64)
-> (Handle prog -> m Word64) -> Handle prog -> RWST r w s m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m Word64
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> m Word64
getNumThreads
  {-# INLINABLE getNumThreads #-}
  loadFiles :: Handle prog -> FilePath -> RWST r w s m ()
loadFiles prog :: Handle prog
prog = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (FilePath -> m ()) -> FilePath -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> FilePath -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> FilePath -> m ()
loadFiles Handle prog
prog
  {-# INLINABLE loadFiles #-}
  writeFiles :: Handle prog -> RWST r w s m ()
writeFiles = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (Handle prog -> m ()) -> Handle prog -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
writeFiles
  {-# INLINABLE writeFiles #-}
  getFacts :: Handle prog -> RWST r w s m (c a)
getFacts = m (c a) -> RWST r w s m (c a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (c a) -> RWST r w s m (c a))
-> (Handle prog -> m (c a)) -> Handle prog -> RWST r w s m (c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m (c a)
forall (m :: * -> *) a prog (c :: * -> *).
(MonadSouffle m, Fact a, ContainsFact prog a, CollectFacts c) =>
Handle prog -> m (c a)
getFacts
  {-# INLINABLE getFacts #-}
  findFact :: Handle prog -> a -> RWST r w s m (Maybe a)
findFact prog :: Handle prog
prog = m (Maybe a) -> RWST r w s m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> RWST r w s m (Maybe a))
-> (a -> m (Maybe a)) -> a -> RWST r w s m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m (Maybe a)
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m (Maybe a)
findFact Handle prog
prog
  {-# INLINABLE findFact #-}
  addFact :: Handle prog -> a -> RWST r w s m ()
addFact fact :: Handle prog
fact = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ()) -> (a -> m ()) -> a -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m ()
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m ()
addFact Handle prog
fact
  {-# INLINABLE addFact #-}
  addFacts :: Handle prog -> t a -> RWST r w s m ()
addFacts facts :: Handle prog
facts = m () -> RWST r w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST r w s m ())
-> (t a -> m ()) -> t a -> RWST r w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> t a -> m ()
forall (m :: * -> *) (t :: * -> *) a prog.
(MonadSouffle m, Foldable t, Fact a, ContainsFact prog a) =>
Handle prog -> t a -> m ()
addFacts Handle prog
facts
  {-# INLINABLE addFacts #-}

instance MonadSouffle m => MonadSouffle (ExceptT s m) where
  init :: prog -> ExceptT s m (Maybe (Handle prog))
init = m (Maybe (Handle prog)) -> ExceptT s m (Maybe (Handle prog))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Handle prog)) -> ExceptT s m (Maybe (Handle prog)))
-> (prog -> m (Maybe (Handle prog)))
-> prog
-> ExceptT s m (Maybe (Handle prog))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. prog -> m (Maybe (Handle prog))
forall (m :: * -> *) prog.
(MonadSouffle m, Program prog) =>
prog -> m (Maybe (Handle prog))
init
  {-# INLINABLE init #-}
  run :: Handle prog -> ExceptT s m ()
run = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ())
-> (Handle prog -> m ()) -> Handle prog -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
run
  {-# INLINABLE run #-}
  setNumThreads :: Handle prog -> Word64 -> ExceptT s m ()
setNumThreads prog :: Handle prog
prog = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ())
-> (Word64 -> m ()) -> Word64 -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> Word64 -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> Word64 -> m ()
setNumThreads Handle prog
prog
  {-# INLINABLE setNumThreads #-}
  getNumThreads :: Handle prog -> ExceptT s m Word64
getNumThreads = m Word64 -> ExceptT s m Word64
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Word64 -> ExceptT s m Word64)
-> (Handle prog -> m Word64) -> Handle prog -> ExceptT s m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m Word64
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> m Word64
getNumThreads
  {-# INLINABLE getNumThreads #-}
  loadFiles :: Handle prog -> FilePath -> ExceptT s m ()
loadFiles prog :: Handle prog
prog = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ())
-> (FilePath -> m ()) -> FilePath -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> FilePath -> m ()
forall (m :: * -> *) prog.
MonadSouffle m =>
Handle prog -> FilePath -> m ()
loadFiles Handle prog
prog
  {-# INLINABLE loadFiles #-}
  writeFiles :: Handle prog -> ExceptT s m ()
writeFiles = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ())
-> (Handle prog -> m ()) -> Handle prog -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m ()
forall (m :: * -> *) prog. MonadSouffle m => Handle prog -> m ()
writeFiles
  {-# INLINABLE writeFiles #-}
  getFacts :: Handle prog -> ExceptT s m (c a)
getFacts = m (c a) -> ExceptT s m (c a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (c a) -> ExceptT s m (c a))
-> (Handle prog -> m (c a)) -> Handle prog -> ExceptT s m (c a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m (c a)
forall (m :: * -> *) a prog (c :: * -> *).
(MonadSouffle m, Fact a, ContainsFact prog a, CollectFacts c) =>
Handle prog -> m (c a)
getFacts
  {-# INLINABLE getFacts #-}
  findFact :: Handle prog -> a -> ExceptT s m (Maybe a)
findFact prog :: Handle prog
prog = m (Maybe a) -> ExceptT s m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ExceptT s m (Maybe a))
-> (a -> m (Maybe a)) -> a -> ExceptT s m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m (Maybe a)
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m (Maybe a)
findFact Handle prog
prog
  {-# INLINABLE findFact #-}
  addFact :: Handle prog -> a -> ExceptT s m ()
addFact fact :: Handle prog
fact = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ()) -> (a -> m ()) -> a -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> a -> m ()
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> a -> m ()
addFact Handle prog
fact
  {-# INLINABLE addFact #-}
  addFacts :: Handle prog -> t a -> ExceptT s m ()
addFacts facts :: Handle prog
facts = m () -> ExceptT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT s m ()) -> (t a -> m ()) -> t a -> ExceptT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> t a -> m ()
forall (m :: * -> *) (t :: * -> *) a prog.
(MonadSouffle m, Foldable t, Fact a, ContainsFact prog a) =>
Handle prog -> t a -> m ()
addFacts Handle prog
facts
  {-# INLINABLE addFacts #-}