-- | Queries into how long until properties hold or fail. We use Int16 to -- return the value, so your queries must not require looking more than 32,767 -- periods :) . Thus, in the following, the parameter @n@ must be @0 <= n <= -- 32,767@. -1 indicates the test failed. module Language.Copilot.Libs.Indexes(soonest, soonestFail, latest, latestFail) where import Prelude (id, Int, String, fromIntegral, ($)) import qualified Prelude as P import Data.Int (Int16) import Language.Copilot.Libs.ErrorChks import Language.Copilot.Core import Language.Copilot.Language soonestHlp :: String -> (Spec Bool -> Spec Bool) -> Int -> Spec Bool -> Spec Int16 soonestHlp name f n s = int16Chk name n $ nPosChk name n (buildStr 0) where buildStr m = if m P.> n then (-1) else mux (f $ drop m s) (fI m) (buildStr (m P.+ 1)) fI = fromIntegral latestHlp :: String -> (Spec Bool -> Spec Bool) -> Int -> Spec Bool -> Spec Int16 latestHlp name f n s = int16Chk name n $ nPosChk name n (buildStr n) where buildStr m = if m P.< 0 then (-1) else mux (f $ drop m s) (fI m) (buildStr (m P.- 1)) fI = fromIntegral -- | Returns the smallest @m <= n@ such that @drop m s@ is true, and @-1@ if no -- such @m@ exists. soonest :: Int -> Spec Bool -> Spec Int16 soonest = soonestHlp "soonest" id -- | Returns the smallest @m <= n@ such that @drop m s@ is false, and @-1@ if no -- such @m@ exists. soonestFail :: Int -> Spec Bool -> Spec Int16 soonestFail = soonestHlp "soonestFail" not -- | Returns the largest @m <= n@ such that @drop m s@ is true, and @-1@ if no -- such @m@ exists. latest :: Int -> Spec Bool -> Spec Int16 latest = latestHlp "latest" id -- | Returns the largest @m <= n@ such that @drop m s@ is false, and @-1@ if no -- such @m@ exists. latestFail :: Int -> Spec Bool -> Spec Int16 latestFail = latestHlp "latest" not