Copyright | (c) Chris Penner 2019 |
---|---|
License | BSD3 |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- type Prop a = PropT Identity a
- data PropT m a
- data PVar f
- newPVar :: (Monad m, MonoFoldable f, Typeable f, Typeable (Element f)) => f -> PropT m (PVar f)
- solve :: (Functor f, Typeable (Element g)) => Prop (f (PVar g)) -> Maybe (f (Element g))
- solveAll :: (Functor f, Typeable (Element g)) => Prop (f (PVar g)) -> [f (Element g)]
- constrain :: (Monad m, Typeable g, Typeable (Element f)) => PVar f -> PVar g -> (Element f -> g -> g) -> PropT m ()
- disjoint :: forall a m. (Monad m, Typeable a, Ord a) => PVar (Set a) -> PVar (Set a) -> PropT m ()
- equal :: forall a m. (Monad m, Typeable a, Ord a) => PVar (Set a) -> PVar (Set a) -> PropT m ()
- require :: (Monad m, Typeable a, Ord a, Typeable b) => (a -> b -> Bool) -> PVar (Set a) -> PVar (Set b) -> PropT m ()
Initializing problems
A monad transformer for setting up constraint problems.
A propagator variable where the possible values are contained in the MonoFoldable type f
.
newPVar :: (Monad m, MonoFoldable f, Typeable f, Typeable (Element f)) => f -> PropT m (PVar f) Source #
Used to create a new propagator variable within the setup for your problem.
f
is any MonoFoldable container which contains each of the possible states which the variable could take. In practice this most standard containers make a good candidate, it's easy to define a your own instance if needed.
E.g. For a sudoku solver you would use newPVar
to create a variable for each cell, passing a Set Int
or IntSet
containing the numbers [1..9]
.
Finding Solutions
solve :: (Functor f, Typeable (Element g)) => Prop (f (PVar g)) -> Maybe (f (Element g)) Source #
Pure version of solveT
solveAll :: (Functor f, Typeable (Element g)) => Prop (f (PVar g)) -> [f (Element g)] Source #
Pure version of solveAllT
Constraining variables
constrain :: (Monad m, Typeable g, Typeable (Element f)) => PVar f -> PVar g -> (Element f -> g -> g) -> PropT m () Source #
constrain
the relationship between two PVar
s. Note that this is a ONE WAY relationship; e.g. constrain a b f
will propagate constraints from a
to b
but not vice versa.
Given PVar f
and PVar g
as arguments, provide a function which will filter/alter the options in g
according to the choice.
For a sudoku puzzle f
and g
each represent cells on the board. If f ~ Set Int
and g ~ Set Int
, then you might pass a constraint filter:
constrain a b $ \elementA setB -> S.delete elementA setB)
Take a look at some linking functions which are already provided: disjoint
, equal
, require
disjoint :: forall a m. (Monad m, Typeable a, Ord a) => PVar (Set a) -> PVar (Set a) -> PropT m () Source #
Apply the constraint that two variables may NOT be set to the same value. This constraint is bidirectional.
E.g. you might apply this constraint to two cells in the same row of sudoku grid to assert they don't contain the same value.