% Constraint FunctionalLogic Programming
% Sebastian Fischer (sebf@informatik.unikiel.de)
This module provides an interface that can be used for constraint
functionallogic programming in Haskell.
>
>
> module Control.CFLP (
>
> CFLP, Computation, eval, evalPrint,
>
> Strategy, depthFirst,
>
> module Data.LazyNondet,
> module Data.LazyNondet.Bool,
> module Data.LazyNondet.List
>
> ) where
>
> import Data.LazyNondet
> import Data.LazyNondet.Bool
> import Data.LazyNondet.List
>
> import Control.Monad.State
> import Control.Monad.Constraint
> import Control.Monad.Constraint.Choice
>
> class (MonadConstr Choice m,
> ConstraintStore Choice cs,
> MonadSolve cs m m)
> => CFLP cs m
The type class `CFLP` is a shortcut for the typeclass constraints on
constraint functionallogic computations that are parameterized over a
constraint store and a constraint monad. Hence, such computations can
be executed with different constraint stores and search strategies.
> instance CFLP ChoiceStore (ConstrT ChoiceStore [])
We declare instances for every combination of monad and constraint
store that we intend to use.
> type EvalStore = ChoiceStore
>
> noConstraints :: EvalStore
> noConstraints = noChoices
>
> type Computation m a = EvalStore -> ID -> Nondet (ConstrT EvalStore m) a
Currently, the constraint store used to evaluate constraint
functionallogic programs is simply a `ChoiceStore`. It will be a
combination of different constraint stores, when more constraint
solvers have been implemented.
> type Strategy m = forall a . m a -> [a]
A `Strategy` specifies how to enumerate nondeterministic results in a
list.
> depthFirst :: Strategy []
> depthFirst = id
The strategy of the list monad is depthfirst search.
> eval :: (CFLP EvalStore m, MonadSolve EvalStore m m', Data a)
> => Strategy m' -> (EvalStore -> ID -> Nondet m a)
> -> IO [a]
> eval enumerate op = do
> i <- initID
> return (enumerate (normalForm (op noConstraints i) noConstraints))
The `eval` function enumerates the nondeterministic solutions of a
constraint functionallogic computation according to a given strategy.
> evalPrint :: (CFLP EvalStore m, MonadSolve EvalStore m m', Data a, Show a)
> => Strategy m' -> (EvalStore -> ID -> Nondet m a)
> -> IO ()
> evalPrint s op = eval s op >>= printSols
>
> printSols :: Show a => [a] -> IO ()
> printSols [] = putStrLn "No more solutions."
> printSols (x:xs) = do
> print x
> putStr "more? [Y(es)|n(o)|a(ll)]: "
> s <- getLine
> if s `elem` ["n","no"] then
> return ()
> else if s `elem` ["a","all"]
> then mapM_ print xs
> else printSols xs
For convenience, we provide an `evalPrint` operation that
interactively shows solutions of a constraint functionallogic
computation.