@@ -26,9 +26,12 @@ module SMT (
2626 ackCommand ,
2727 loadFile ,
2828 reinit ,
29+ askRetryLimit ,
30+ localTimeOut ,
2931 Config (.. ),
3032 defaultConfig ,
3133 TimeOut (.. ),
34+ RetryLimit (.. ),
3235 RLimit (.. ),
3336 ResetInterval (.. ),
3437 Prelude (.. ),
@@ -216,6 +219,11 @@ reinit :: MonadSMT m => m ()
216219reinit = liftSMT reinitSMT
217220{-# INLINE reinit #-}
218221
222+ -- | Get the retry limit from the SMT
223+ askRetryLimit :: MonadSMT m => m RetryLimit
224+ askRetryLimit = liftSMT askRetryLimitSMT
225+ {-# INLINE askRetryLimit #-}
226+
219227-- * Implementation
220228
221229data SolverSetup = SolverSetup
@@ -376,6 +384,10 @@ instance MonadSMT m => MonadSMT (RWST r () s m)
376384newtype TimeOut = TimeOut { getTimeOut :: Limit Integer }
377385 deriving stock (Eq , Ord , Read , Show )
378386
387+ -- | Retry-limit for SMT queries.
388+ newtype RetryLimit = RetryLimit { getRetryLimit :: Limit Integer }
389+ deriving stock (Eq , Ord , Read , Show )
390+
379391-- | Resource-limit for SMT queries.
380392newtype RLimit = RLimit { getRLimit :: Limit Integer }
381393 deriving stock (Eq , Ord , Read , Show )
@@ -399,6 +411,8 @@ data Config = Config
399411 logFile :: ! (Maybe FilePath )
400412 , -- | query time limit
401413 timeOut :: ! TimeOut
414+ , -- | query retry limit
415+ retryLimit :: ! RetryLimit
402416 , -- | query resource limit
403417 rLimit :: ! RLimit
404418 , -- | reset solver after this number of queries
@@ -417,6 +431,7 @@ defaultConfig =
417431 , prelude = Prelude Nothing
418432 , logFile = Nothing
419433 , timeOut = TimeOut (Limit 40 )
434+ , retryLimit = RetryLimit (Limit 1 )
420435 , rLimit = RLimit Unlimited
421436 , resetInterval = ResetInterval 100
422437 }
@@ -605,6 +620,29 @@ reinitSMT =
605620 Nothing -> return ()
606621 Just solverSetup -> reinitSMT' solverSetup
607622
623+ {- | Run a solver action with an adjusted timeout,
624+ and reset the timeout when it's done.
625+ -}
626+ localTimeOut :: MonadSMT m => (TimeOut -> TimeOut ) -> m a -> m a
627+ localTimeOut adjust isolated = do
628+ originalTimeOut <- liftSMT extractTimeOut
629+ setTimeOut $ adjust originalTimeOut
630+ isolated <* setTimeOut originalTimeOut
631+ where
632+ extractTimeOut =
633+ SMT $
634+ pure . \ case
635+ Nothing -> TimeOut Unlimited
636+ Just setup -> timeOut $ config setup
637+
638+ -- | Get the retry limit for SMT queries.
639+ askRetryLimitSMT :: SMT RetryLimit
640+ askRetryLimitSMT =
641+ SMT $
642+ pure . \ case
643+ Nothing -> RetryLimit (Limit 0 )
644+ Just setup -> retryLimit $ config setup
645+
608646-- --------------------------------
609647-- Internal
610648
0 commit comments