module UniqueLogic.ST.TF.System.Label ( -- * Preparation Variable, globalVariable, -- * Posing statements T, Sys.localVariable, Sys.constant, Sys.assignment2, Sys.assignment3, Sys.Apply, Sys.arg, Sys.runApply, -- * Solution Sys.solve, Sys.query, ) where import qualified UniqueLogic.ST.TF.System as Sys import qualified UniqueLogic.ST.TF.MonadTrans as UMT import qualified Control.Monad.Trans.Writer as MW import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT, ) import Control.Monad (liftM, ) import qualified Data.Ref as Ref import Data.Monoid (Monoid, ) import Data.Traversable (traverse, ) import Prelude hiding (log, ) type T w = Sys.T (MW.WriterT w) type Variable w = Sys.Variable (MW.WriterT w) globalVariable :: (Monoid w, Ref.C s) => (a -> MW.Writer w a) -> s (Variable w s a) globalVariable log = Sys.globalVariable (\al av -> Sys.updateIfNew al av . wrap log) wrap :: (Monoid w, Ref.C s) => (a -> MW.Writer w b) -> MaybeT s a -> MaybeT (UMT.Wrap (MW.WriterT w) s) b wrap log = mapMaybeT $ UMT.wrap . MW.WriterT . liftM (MW.runWriter . traverse log) -- UMT.wrap . MW.writer . MW.runWriter . traverse log <=< UMT.lift