{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Misc.Tuple where
import Data.SBV
import Data.SBV.Tuple
import Data.SBV.Control
import Prelude hiding ((!!))
import Data.SBV.List ((!!))
import Data.SBV.RegExp
import qualified Data.SBV.String as S
import qualified Data.SBV.List as L
type Dict a b = SBV [(a, b)]
example :: IO [(String, Integer)]
example :: IO [(String, Integer)]
example = forall a. Symbolic a -> IO a
runSMT forall a b. (a -> b) -> a -> b
$ do Dict String Integer
dict :: Dict String Integer <- forall a. SymVal a => String -> Symbolic (SBV a)
free String
"dict"
let len :: Int
len = Int
5 :: Int
range :: [Int]
range = [Int
0 .. Int
len forall a. Num a => a -> a -> a
- Int
1]
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ forall a. SymVal a => SList a -> SInteger
L.length Dict String Integer
dict forall a. EqSymbolic a => a -> a -> SBool
.== forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
let goodKey :: a -> SBV String -> SBool
goodKey a
i SBV String
s = let l :: SInteger
l = SBV String -> SInteger
S.length SBV String
s
r :: RegExp
r = RegExp
asciiLower forall a. Num a => a -> a -> a
* RegExp -> RegExp
KStar (RegExp
asciiLetter forall a. Num a => a -> a -> a
+ RegExp
digit forall a. Num a => a -> a -> a
+ RegExp
"_" forall a. Num a => a -> a -> a
+ RegExp
"'")
in SInteger
l forall a. EqSymbolic a => a -> a -> SBool
.== forall a b. (Integral a, Num b) => a -> b
fromIntegral a
iforall a. Num a => a -> a -> a
+SInteger
3 SBool -> SBool -> SBool
.&& SBV String
s forall a. RegExpMatchable a => a -> RegExp -> SBool
`match` RegExp
r
restrict :: a -> m ()
restrict a
i = case forall tup a. Tuple tup a => SBV tup -> a
untuple (Dict String Integer
dict forall a. SymVal a => SList a -> SInteger -> SBV a
!! forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) of
(SBV String
k, SInteger
v) -> forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ forall {a}. Integral a => a -> SBV String -> SBool
goodKey a
i SBV String
k SBool -> SBool -> SBool
.&& SInteger
v forall a. EqSymbolic a => a -> a -> SBool
.== SBV String -> SInteger
S.length SBV String
k
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {a} {m :: * -> *}.
(Integral a, SolverContext m) =>
a -> m ()
restrict [Int]
range
let keys :: [SBV String]
keys = [(Dict String Integer
dict forall a. SymVal a => SList a -> SInteger -> SBV a
!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)forall a b. a -> (a -> b) -> b
^.forall b a. HasField "_1" b a => SBV a -> SBV b
_1 | Int
i <- [Int]
range]
forall (m :: * -> *). SolverContext m => SBool -> m ()
constrain forall a b. (a -> b) -> a -> b
$ forall a. EqSymbolic a => [a] -> SBool
distinct [SBV String]
keys
forall a. Query a -> Symbolic a
query forall a b. (a -> b) -> a -> b
$ do Query ()
ensureSat
forall a. SymVal a => SBV a -> Query a
getValue Dict String Integer
dict