{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} module Control.Search.Combinator.Misc (dbs, lds, bbmin) where import Control.Search.Language import Control.Search.GeneratorInfo import Control.Search.Generator import Control.Search.Stat import Data.Int import Control.Monatron.IdT ldsLoop :: Monad m => Stat -> MkEval m ldsLoop limit super' = return $ commentEval $ super { treeState_ = entry ("lds",Int,assign 0) : treeState_ super , initH = \i -> readStat limit >>= \f -> initH super i @>>>@ return (assign (f i) (tstate i @-> "lds")) , evalState_ = ("lds_complete", Bool, const $ return true) : evalState_ super , pushLeftH = \i -> pushLeft super (i `onCommit` mkCopy i "lds") , pushRightH = \i -> pushRight super (i `onCommit` mkUpdate i "lds" (\x -> x - 1)) >>= \stmt -> return $ IfThenElse (tstate (old i) @-> "lds" @>= 0) stmt (abort i >>> (estate i @=> "lds_complete" <== false)) , toString = "lds(" ++ show limit ++ "," ++ toString super ++ ")" , complete = \i -> return $ estate i @=> "lds_complete" } where super = evalStat limit super' -------------------------------------------------------------------------------- dbsLoop :: Monad m => Int32 -> MkEval m dbsLoop limit super = return $ commentEval $ super { treeState_ = entry ("depth_limit",Int,assign $ IVal limit) : treeState_ super , evalState_ = ("dbs_complete", Bool, const $ return true) : evalState_ super , pushLeftH = push pushLeft , pushRightH = push pushRight , toString = "dbs(" ++ show limit ++ "," ++ toString super ++ ")" , complete = \i -> return $ estate i @=> "dbs_complete" } where push dir = \i -> dir super (i `onCommit` mkUpdate i "depth_limit" (\x -> x - 1)) >>= \stmt -> return $ IfThenElse (tstate (old i) @-> "depth_limit" @>= 0) stmt ((estate i @=> "dbs_complete" <== false) >>> abort i) -------------------------------------------------------------------------------- bbLoop :: Monad m => String -> MkEval m bbLoop var super = return $ commentEval $ super { treeState_ = entry ("tree_bound_version",Int,assign 0) : treeState_ super , evalState_ = ("bound_version",Int,const $ return 0) : ("bound",Int,const $ return $ IVal maxBound) : evalState_ super , returnH = \i -> returnE super (i `onCommit` let get = VHook (rp 0 (space i) ++ "->iv[VAR_" ++ var ++ "].min()") in (Assign (estate i @=> "bound") get >>> inc (estate i @=> "bound_version"))) , bodyH = \i -> let set = Post (space i) (VHook (rp 0 (space i) ++ "->iv[VAR_" ++ var ++ "]") $< (estate i @=> "bound")) in do r <- bodyE super i return $ (ifthen (tstate i @-> "tree_bound_version" @< (estate i @=>"bound_version")) (set >>> (Assign (tstate i @-> "tree_bound_version") ((tstate i @-> "tree_bound_version") + 1))) >>> r) , pushLeftH = push pushLeft , pushRightH = push pushRight , intVarsE = var : intVarsE super , complete = const $ return true , toString = "bb(" ++ show var ++ "," ++ toString super ++ ")" } where push dir = \i -> dir super (i `onCommit` mkCopy i "tree_bound_version") bbmin :: String -> Search bbmin var = Search { mkeval = bbLoop var , runsearch = runIdT } lds :: Stat -> Search lds n = Search { mkeval = ldsLoop n , runsearch = runIdT } dbs :: Int32 -> Search dbs n = Search { mkeval = dbsLoop n , runsearch = runIdT }