% Constraint Functional-Logic Programming % Sebastian Fischer (sebf@informatik.uni-kiel.de) This module provides an interface that can be used for constraint functional-logic programming in Haskell. > {-# LANGUAGE > MultiParamTypeClasses, > FlexibleInstances, > FlexibleContexts, > RankNTypes > #-} > > module Control.CFLP ( > > CFLP, EvalStore, 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 type-class constraints on constraint functional-logic operations. > 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 Currently, the constraint store used to evaluate constraint functional-logic 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 non-deterministic results in a list. > depthFirst :: Strategy [] > depthFirst = id The strategy of the list monad is depth-first 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 non-deterministic solutions of a constraint functional-logic 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|n]: " > s <- getLine > if s `elem` ["n","no"] then return () else printSols xs For convenience, we provide an `evalPrint` operation that interactively shows solutions of a constraint functional-logic computation.