module Control.Search.Combinator.Once (once, onceOld) where

import Control.Search.Language
import Control.Search.GeneratorInfo
import Control.Search.Generator
import Control.Search.Memo
import Control.Search.Stat
import Control.Search.Combinator.Until

import Control.Monatron.IdT

onceLoop :: MkEval m
onceLoop super = return $ commentEval $ super
                 { evalState_  = ("onceMore", Bool, const $ return true) : evalState_ super
		 , bodyH     = \i -> do goOn <- bodyE super i
                                        ca <- cachedAbort i
                                        return $ IfThenElse (estate i @=> "onceMore")
                                                   goOn
                                                   ca
		 , returnH   = \i -> returnE super $ i `onCommit` assign false (estate i @=> "onceMore")
                 , toString  = "once(" ++ toString super ++ ")"
                 }

once :: Search
once = 
  Search { mkeval     = onceLoop
         , runsearch  = runIdT
         } 

onceOld = limit 1 solutionsStat