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

-- | 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
  , 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 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

-- | 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)
           => Handle prog -> m [a]

  -- | Searches for a fact in a program.
  --   Returns 'Nothing' if no matching fact was found;
  --   otherwise 'Just' the fact.
  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. (Fact a, ContainsFact prog a)
           => Handle prog -> SouffleM [a]
  getFacts :: Handle prog -> SouffleM [a]
getFacts (Handle prog :: ForeignPtr Souffle
prog) = IO [a] -> SouffleM [a]
forall a. IO a -> SouffleM a
SouffleM (IO [a] -> SouffleM [a]) -> IO [a] -> SouffleM [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
    Ptr Relation -> IO (ForeignPtr RelationIterator)
Internal.getRelationIterator Ptr Relation
relation IO (ForeignPtr RelationIterator)
-> (ForeignPtr RelationIterator -> IO [a]) -> IO [a]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [a] -> ForeignPtr RelationIterator -> IO [a]
forall a. Marshal a => [a] -> ForeignPtr RelationIterator -> IO [a]
go []
    where
      go :: [a] -> ForeignPtr RelationIterator -> IO [a]
go acc :: [a]
acc it :: ForeignPtr RelationIterator
it = do
        Bool
hasNext <- ForeignPtr RelationIterator -> IO Bool
Internal.relationIteratorHasNext ForeignPtr RelationIterator
it
        if Bool
hasNext
          then 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
            [a] -> ForeignPtr RelationIterator -> IO [a]
go (a
result a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc) ForeignPtr RelationIterator
it
          else [a] -> IO [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
acc
  {-# 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 [a]
getFacts = m [a] -> ReaderT r m [a]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [a] -> ReaderT r m [a])
-> (Handle prog -> m [a]) -> Handle prog -> ReaderT r m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m [a]
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> m [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 [a]
getFacts = m [a] -> WriterT w m [a]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [a] -> WriterT w m [a])
-> (Handle prog -> m [a]) -> Handle prog -> WriterT w m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m [a]
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> m [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 [a]
getFacts = m [a] -> StateT s m [a]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [a] -> StateT s m [a])
-> (Handle prog -> m [a]) -> Handle prog -> StateT s m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m [a]
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> m [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 [a]
getFacts = m [a] -> RWST r w s m [a]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [a] -> RWST r w s m [a])
-> (Handle prog -> m [a]) -> Handle prog -> RWST r w s m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m [a]
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> m [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 [a]
getFacts = m [a] -> ExceptT s m [a]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [a] -> ExceptT s m [a])
-> (Handle prog -> m [a]) -> Handle prog -> ExceptT s m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle prog -> m [a]
forall (m :: * -> *) a prog.
(MonadSouffle m, Fact a, ContainsFact prog a) =>
Handle prog -> m [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 #-}