1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
module XFD.Solver where
import Unsafe
import XFD.FD (FDConstr, FDExpr (FDVar))
import qualified XFD.SMTLib.Types as SMT (Option(..))
type SolverArgs a = [Option] -> [FDExpr] -> FDConstr -> a
type SolverImpl = SolverConfig -> SolverArgs (IO [[Int]])
data SolverConfig = Config
{ executable :: String
, flags :: [String]
, solveWith :: SolverImpl
, smtOptions :: Maybe [SMT.Option]
, smtLogic :: String
}
data Option = Debug Int
| All
| First
| FirstN Int
| Persist String
| Minimize FDExpr
| Maximize FDExpr
type ExtractedOptions = (Int, Int , (Bool, String), (Bool, FDExpr), (Bool, FDExpr))
defaultConfig :: SolverConfig
defaultConfig = Config
{ flags = []
, smtOptions = Just [SMT.ProduceModels True]
, smtLogic = "QF_LIA"
}
defaultOptions :: ExtractedOptions
defaultOptions = ( 0
, (-1)
, (False, _)
, (False, _)
, (False, _)
)
getSolverOptions :: [Option] -> ExtractedOptions
getSolverOptions options = getOpts options defaultOptions
where
getOpts [] opts = opts
getOpts (o:os) (d, n, (p, f), mi, ma) = case o of
Debug i -> getOpts os (i, n , (p, f), mi, ma)
All -> getOpts os (d, (-1), (p, f), mi, ma)
First -> getOpts os (d, 1 , (p, f), mi, ma)
FirstN i -> getOpts os (d, i , (p, f), mi, ma)
Persist s -> getOpts os (d, n , (True, s), mi, ma)
Minimize v -> getOpts os (d, n, (p, f), (True, assertVar v), ma)
Maximize v -> getOpts os (d, n, (p, f), mi, (True, assertVar v))
assertVar v = case v of
FDVar _ _ _ _ -> v
solveFDwith :: SolverConfig -> SolverArgs [Int]
solveFDwith cfg opt vars constr =
let solveF = solveWith cfg
solutions = unsafePerformIO $ solveF cfg opt vars constr
in foldr1 (?) solutions
solveFDOnewith :: SolverConfig -> SolverArgs [Int]
solveFDOnewith cfg opt vars constr =
let solveF = solveWith cfg
options = opt ++ [First]
solutions = unsafePerformIO $ solveF cfg options vars constr
in head solutions
solveFDAllwith :: SolverConfig -> SolverArgs [[Int]]
solveFDAllwith cfg opt vars constr =
let solveF = solveWith cfg
options = opt ++ [All]
solutions = unsafePerformIO $ solveF cfg options vars constr
in solutions
|