{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Existentials.Diophantine where
import Data.SBV
data Solution = Homogeneous [[Integer]]
| NonHomogeneous [[Integer]] [[Integer]]
deriving Int -> Solution -> ShowS
[Solution] -> ShowS
Solution -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Solution] -> ShowS
$cshowList :: [Solution] -> ShowS
show :: Solution -> String
$cshow :: Solution -> String
showsPrec :: Int -> Solution -> ShowS
$cshowsPrec :: Int -> Solution -> ShowS
Show
ldn :: Maybe Int -> [([Integer], Integer)] -> IO Solution
ldn :: Maybe Int -> [([Integer], Integer)] -> IO Solution
ldn Maybe Int
mbLim [([Integer], Integer)]
problem = do [[Integer]]
solution <- Maybe Int -> [[SInteger]] -> IO [[Integer]]
basis Maybe Int
mbLim (forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map forall a. SymVal a => a -> SBV a
literal) [[Integer]]
m)
if Bool
homogeneous
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [[Integer]] -> Solution
Homogeneous [[Integer]]
solution
else do let ones :: [[Integer]]
ones = [[Integer]
xs | (Integer
1:[Integer]
xs) <- [[Integer]]
solution]
zeros :: [[Integer]]
zeros = [[Integer]
xs | (Integer
0:[Integer]
xs) <- [[Integer]]
solution]
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [[Integer]] -> [[Integer]] -> Solution
NonHomogeneous [[Integer]]
ones [[Integer]]
zeros
where rhs :: [Integer]
rhs = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [([Integer], Integer)]
problem
lhs :: [[Integer]]
lhs = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [([Integer], Integer)]
problem
homogeneous :: Bool
homogeneous = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== Integer
0) [Integer]
rhs
m :: [[Integer]]
m | Bool
homogeneous = [[Integer]]
lhs
| Bool
True = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Integer
x [Integer]
y -> -Integer
x forall a. a -> [a] -> [a]
: [Integer]
y) [Integer]
rhs [[Integer]]
lhs
basis :: Maybe Int -> [[SInteger]] -> IO [[Integer]]
basis :: Maybe Int -> [[SInteger]] -> IO [[Integer]]
basis Maybe Int
mbLim [[SInteger]]
m = forall a. SatModel a => AllSatResult -> [a]
extractModels forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a. Provable a => SMTConfig -> a -> IO AllSatResult
allSatWith SMTConfig
z3{allSatMaxModelCount :: Maybe Int
allSatMaxModelCount = Maybe Int
mbLim} SymbolicT IO SBool
cond
where cond :: SymbolicT IO SBool
cond = do [SInteger]
as <- forall a. SymVal a => Int -> Symbolic [SBV a]
mkExistVars Int
n
[SInteger]
bs <- forall a. SymVal a => Int -> Symbolic [SBV a]
mkForallVars Int
n
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [SInteger] -> SBool
ok [SInteger]
as SBool -> SBool -> SBool
.&& ([SInteger] -> SBool
ok [SInteger]
bs SBool -> SBool -> SBool
.=> [SInteger]
as forall a. EqSymbolic a => a -> a -> SBool
.== [SInteger]
bs SBool -> SBool -> SBool
.|| SBool -> SBool
sNot ([SInteger]
bs forall {b}. OrdSymbolic b => [b] -> [b] -> SBool
`less` [SInteger]
as))
n :: Int
n = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[SInteger]]
m then Int
0 else forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. [a] -> a
head [[SInteger]]
m)
ok :: [SInteger] -> SBool
ok [SInteger]
xs = forall a. (a -> SBool) -> [a] -> SBool
sAny (forall a. OrdSymbolic a => a -> a -> SBool
.> SInteger
0) [SInteger]
xs SBool -> SBool -> SBool
.&& forall a. (a -> SBool) -> [a] -> SBool
sAll (forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
0) [SInteger]
xs SBool -> SBool -> SBool
.&& [SBool] -> SBool
sAnd [forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(*) [SInteger]
r [SInteger]
xs) forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
0 | [SInteger]
r <- [[SInteger]]
m]
[b]
as less :: [b] -> [b] -> SBool
`less` [b]
bs = [SBool] -> SBool
sAnd (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. OrdSymbolic a => a -> a -> SBool
(.<=) [b]
as [b]
bs) SBool -> SBool -> SBool
.&& [SBool] -> SBool
sOr (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. OrdSymbolic a => a -> a -> SBool
(.<) [b]
as [b]
bs)
test :: IO Solution
test :: IO Solution
test = Maybe Int -> [([Integer], Integer)] -> IO Solution
ldn forall a. Maybe a
Nothing [([Integer
2,Integer
1,-Integer
1], Integer
2)]
sailors :: IO [Integer]
sailors :: IO [Integer]
sailors = Int -> IO [Integer]
search Int
1
where search :: Int -> IO [Integer]
search Int
i = do Solution
soln <- Maybe Int -> [([Integer], Integer)] -> IO Solution
ldn (forall a. a -> Maybe a
Just Int
i) [ ([Integer
1, -Integer
5, Integer
0, Integer
0, Integer
0, Integer
0, Integer
0], Integer
1)
, ([Integer
0, Integer
4, -Integer
5 , Integer
0, Integer
0, Integer
0, Integer
0], Integer
1)
, ([Integer
0, Integer
0, Integer
4, -Integer
5 , Integer
0, Integer
0, Integer
0], Integer
1)
, ([Integer
0, Integer
0, Integer
0, Integer
4, -Integer
5, Integer
0, Integer
0], Integer
1)
, ([Integer
0, Integer
0, Integer
0, Integer
0, Integer
4, -Integer
5, Integer
0], Integer
1)
, ([Integer
0, Integer
0, Integer
0, Integer
0, Integer
0, Integer
4, -Integer
5], Integer
1)
]
case Solution
soln of
NonHomogeneous ([Integer]
xs:[[Integer]]
_) [[Integer]]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return [Integer]
xs
Solution
_ -> Int -> IO [Integer]
search (Int
iforall a. Num a => a -> a -> a
+Int
1)