% 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, CS, UpdateT, ChoiceStore, Computation, eval, evalPartial, evalPrint, > > Strategy, depthFirst, > > module Data.LazyNondet > > ) where > > import Data.LazyNondet > > import Control.Monad.State > import Control.Monad.Update > import Control.Monad.Trans.Update > > import Control.Constraint.Choice > > class (MonadUpdate s m, Update s m m, ChoiceStore s) => CFLP s m The type class `CFLP` is a shortcut for the type-class constraints on constraint functional-logic 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 ChoiceStoreIM (UpdateT ChoiceStoreIM []) We declare instances for every combination of monad and constraint store that we intend to use. > type CS = ChoiceStoreIM > > noConstraints :: Context CS > noConstraints = Context noChoices > > type Computation m a = Context CS -> ID -> Nondet CS (UpdateT CS m) a 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. > evaluate :: (CFLP CS m, Update CS m m') > => (Nondet CS m a -> Context CS -> m' b) > -> Strategy m' -> (Context CS -> ID -> Nondet CS m a) > -> IO [b] > evaluate evalNondet enumerate op = do > i <- initID > return $ enumerate $ evalNondet (op noConstraints i) noConstraints The `evaluate` function enumerates the non-deterministic solutions of a constraint functional-logic computation according to a given strategy. > eval, evalPartial :: (CFLP CS m, Update CS m m', Generic a) > => Strategy m' -> (Context CS -> ID -> Nondet CS m a) > -> IO [a] > eval s = liftM (map primitive) . evaluate groundNormalForm s > evalPartial s = liftM (map primitive) . evaluate partialNormalForm s > > evalPrint :: (CFLP CS m, Update CS m m', Generic a) > => Strategy m' -> (Context CS -> ID -> Nondet CS m a) > -> IO () > evalPrint s op = evaluate partialNormalForm 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 We provide * an `eval` operation to compute Haskell terms from non-deterministic data, * an operation `evalPartial` to compute partial Haskell terms where logic variables are replaced with an error, and * an `evalPrint` operation that interactively shows (partial) solutions of a constraint functional-logic computation.