{-# 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
(Int -> Solution -> ShowS)
-> (Solution -> String) -> ([Solution] -> ShowS) -> Show Solution
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 (([Integer] -> [SInteger]) -> [[Integer]] -> [[SInteger]]
forall a b. (a -> b) -> [a] -> [b]
map ((Integer -> SInteger) -> [Integer] -> [SInteger]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> SInteger
forall a. SymVal a => a -> SBV a
literal) [[Integer]]
m)
if Bool
homogeneous
then Solution -> IO Solution
forall (m :: * -> *) a. Monad m => a -> m a
return (Solution -> IO Solution) -> Solution -> IO Solution
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]
Solution -> IO Solution
forall (m :: * -> *) a. Monad m => a -> m a
return (Solution -> IO Solution) -> Solution -> IO Solution
forall a b. (a -> b) -> a -> b
$ [[Integer]] -> [[Integer]] -> Solution
NonHomogeneous [[Integer]]
ones [[Integer]]
zeros
where rhs :: [Integer]
rhs = (([Integer], Integer) -> Integer)
-> [([Integer], Integer)] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map ([Integer], Integer) -> Integer
forall a b. (a, b) -> b
snd [([Integer], Integer)]
problem
lhs :: [[Integer]]
lhs = (([Integer], Integer) -> [Integer])
-> [([Integer], Integer)] -> [[Integer]]
forall a b. (a -> b) -> [a] -> [b]
map ([Integer], Integer) -> [Integer]
forall a b. (a, b) -> a
fst [([Integer], Integer)]
problem
homogeneous :: Bool
homogeneous = (Integer -> Bool) -> [Integer] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0) [Integer]
rhs
m :: [[Integer]]
m | Bool
homogeneous = [[Integer]]
lhs
| Bool
True = (Integer -> [Integer] -> [Integer])
-> [Integer] -> [[Integer]] -> [[Integer]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Integer
x [Integer]
y -> -Integer
x Integer -> [Integer] -> [Integer]
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 = AllSatResult -> [[Integer]]
forall a. SatModel a => AllSatResult -> [a]
extractModels (AllSatResult -> [[Integer]]) -> IO AllSatResult -> IO [[Integer]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` SMTConfig -> SymbolicT IO SBool -> IO AllSatResult
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 <- Int -> Symbolic [SInteger]
forall a. SymVal a => Int -> Symbolic [SBV a]
mkExistVars Int
n
[SInteger]
bs <- Int -> Symbolic [SInteger]
forall a. SymVal a => Int -> Symbolic [SBV a]
mkForallVars Int
n
SBool -> SymbolicT IO SBool
forall (m :: * -> *) a. Monad m => a -> m a
return (SBool -> SymbolicT IO SBool) -> SBool -> SymbolicT IO SBool
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 [SInteger] -> [SInteger] -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== [SInteger]
bs SBool -> SBool -> SBool
.|| SBool -> SBool
sNot ([SInteger]
bs [SInteger] -> [SInteger] -> SBool
forall a. OrdSymbolic a => [a] -> [a] -> SBool
`less` [SInteger]
as))
n :: Int
n = if [[SInteger]] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[SInteger]]
m then Int
0 else [SInteger] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[SInteger]] -> [SInteger]
forall a. [a] -> a
head [[SInteger]]
m)
ok :: [SInteger] -> SBool
ok [SInteger]
xs = (SInteger -> SBool) -> [SInteger] -> SBool
forall a. (a -> SBool) -> [a] -> SBool
sAny (SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.> SInteger
0) [SInteger]
xs SBool -> SBool -> SBool
.&& (SInteger -> SBool) -> [SInteger] -> SBool
forall a. (a -> SBool) -> [a] -> SBool
sAll (SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
0) [SInteger]
xs SBool -> SBool -> SBool
.&& [SBool] -> SBool
sAnd [[SInteger] -> SInteger
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((SInteger -> SInteger -> SInteger)
-> [SInteger] -> [SInteger] -> [SInteger]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
(*) [SInteger]
r [SInteger]
xs) SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
0 | [SInteger]
r <- [[SInteger]]
m]
[a]
as less :: [a] -> [a] -> SBool
`less` [a]
bs = [SBool] -> SBool
sAnd ((a -> a -> SBool) -> [a] -> [a] -> [SBool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
(.<=) [a]
as [a]
bs) SBool -> SBool -> SBool
.&& [SBool] -> SBool
sOr ((a -> a -> SBool) -> [a] -> [a] -> [SBool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
(.<) [a]
as [a]
bs)
test :: IO Solution
test :: IO Solution
test = Maybe Int -> [([Integer], Integer)] -> IO Solution
ldn Maybe Int
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 (Int -> Maybe Int
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]]
_ -> [Integer] -> IO [Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return [Integer]
xs
Solution
_ -> Int -> IO [Integer]
search (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)