module UniqueLogic.ST.System.Simple (
   -- * Preparation
   Variable,
   globalVariable,
   -- * Posing statements
   T,
   localVariable,
   constant,
   Sys.assignment2,
   Sys.assignment3,
   Sys.Apply, Sys.arg, Sys.runApply,
   -- * Solution
   solve,
   query,
   ) where

import qualified UniqueLogic.ST.System as Sys
import qualified UniqueLogic.ST.Duplicate as Duplicate

import Control.Monad.Trans.Identity (IdentityT, runIdentityT, )
import Control.Monad.ST (ST, )


type T = Sys.T IdentityT

type Variable s a = Sys.Variable IdentityT s (Duplicate.Ignore a)


globalVariable :: ST s (Variable s a)
globalVariable :: forall s a. ST s (Variable s a)
globalVariable =
   forall (w :: (* -> *) -> * -> *) a s.
(C w, C a) =>
SimpleUpdater w s a -> ST s (Variable w s a)
Sys.globalVariable forall (w :: (* -> *) -> * -> *) a s.
(C w, C a) =>
SimpleUpdater w s a
Sys.simpleUpdate

localVariable :: T s (Variable s a)
localVariable :: forall s a. T s (Variable s a)
localVariable = forall (w :: (* -> *) -> * -> *) a s.
(C w, C a) =>
T w s (Variable w s a)
Sys.localVariable

constant :: a -> T s (Variable s a)
constant :: forall a s. a -> T s (Variable s a)
constant = forall (w :: (* -> *) -> * -> *) a s.
(C w, C a) =>
a -> T w s (Variable w s a)
Sys.constant forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Ignore a
Duplicate.Ignore

solve :: T s a -> ST s a
solve :: forall s a. T s a -> ST s a
solve = forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: (* -> *) -> * -> *) s a. C w => T w s a -> w (ST s) a
Sys.solve

query :: Variable s a -> ST s (Maybe a)
query :: forall s a. Variable s a -> ST s (Maybe a)
query = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Duplicate.Ignore a
a) -> a
a)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (w :: (* -> *) -> * -> *) s a.
Variable w s a -> ST s (Maybe a)
Sys.query