module Datafix.ProblemBuilder
( ProblemBuilder
, buildProblem
) where
import Data.Primitive.Array
import Datafix.Description
import Datafix.NodeAllocator
import Datafix.Utils.TypeLevel
newtype ProblemBuilder m a
= ProblemBuilder { unwrapProblemBuilder :: NodeAllocator (ChangeDetector (Domain m), LiftedFunc (Domain m) m) a }
deriving (Functor, Applicative, Monad)
instance MonadDependency m => MonadDatafix m (ProblemBuilder m) where
datafix cd func = ProblemBuilder $ allocateNode $ \node -> do
let deref = dependOn @m node
(ret, transfer) <- unwrapProblemBuilder (func deref)
return (ret, (cd, transfer))
buildProblem
:: forall m
. MonadDependency m
=> Currying (ParamTypes (Domain m)) (ReturnType (Domain m) -> ReturnType (Domain m) -> Bool)
=> ProblemBuilder m (LiftedFunc (Domain m) m)
-> (Node, Node, DataFlowProblem m)
buildProblem buildDenotation = (root, Node (sizeofArray arr 1), prob)
where
prob = DFP (snd . indexArray arr . unwrapNode) (fst . indexArray arr . unwrapNode)
(root, arr) = runAllocator $ allocateNode $ \root_ -> do
denotation <- unwrapProblemBuilder buildDenotation
return (root_, (alwaysChangeDetector @(Domain m), denotation))