Skip to content

Commit e006dfc

Browse files
committed
Add support for CVC5
This adds basic support for the CVC5 SMT solver by adding `cvc5` and related proof scripts. I hae added a `test_cvc5` integration test to kick the tires. This addresses one part of #1706.
1 parent c120306 commit e006dfc

File tree

12 files changed

+106
-6
lines changed

12 files changed

+106
-6
lines changed

.github/ci.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ install_system_deps() {
8080
cp $BIN/yices_smt2$EXT $BIN/yices-smt2$EXT
8181
export PATH="$BIN:$PATH"
8282
echo "$BIN" >> "$GITHUB_PATH"
83-
is_exe "$BIN" z3 && is_exe "$BIN" cvc4 && is_exe "$BIN" yices
83+
is_exe "$BIN" z3 && is_exe "$BIN" cvc4 && is_exe "$BIN" cvc5 && is_exe "$BIN" yices
8484
}
8585

8686
build_cryptol() {
@@ -127,6 +127,7 @@ zip_dist_with_solvers() {
127127
# dependencies) as the SAW binaries.
128128
cp "$BIN/abc" dist/bin/
129129
cp "$BIN/cvc4" dist/bin/
130+
cp "$BIN/cvc5" dist/bin/
130131
cp "$BIN/yices" dist/bin/
131132
cp "$BIN/yices-smt2" dist/bin/
132133
# Z3 4.8.14 has been known to nondeterministically time out with the AWSLC

CHANGES.md

+5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@
9090
allows verification certain kinds of simple loops by using a
9191
user-provided loop invariant.
9292

93+
* Add a `cvc5` family of proof scripts that use the CVC5 SMT solver.
94+
(Note that the `sbv_cvc5` and `sbv_unint_cvc5` are non-functional
95+
on Windows at this time due to a downstream issue with CVC5 1.0.4 and
96+
earlier.)
97+
9398
# Version 0.9
9499

95100
## New Features

doc/manual/manual.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ sawscript> sat_print abc {{ \(x:[8]) -> x+x == x*2 }}
11311131
Sat: [x = 0]
11321132
~~~~
11331133

1134-
In addition to these, the `boolector`, `cvc4`, `mathsat`, and `yices`
1134+
In addition to these, the `boolector`, `cvc4`, `cvc5`, `mathsat`, and `yices`
11351135
provers are available. The internal decision procedure `rme`, short for
11361136
Reed-Muller Expansion, is an automated prover that works particularly
11371137
well on the Galois field operations that show up, for example, in AES.
@@ -1199,6 +1199,8 @@ named subterms should be represented as uninterpreted functions.
11991199

12001200
* `unint_cvc4 : [String] -> ProofScript ()`
12011201

1202+
* `unint_cvc5 : [String] -> ProofScript ()`
1203+
12021204
* `unint_yices : [String] -> ProofScript ()`
12031205

12041206
* `unint_z3 : [String] -> ProofScript ()`
@@ -1218,6 +1220,8 @@ library to represent and solve SMT queries:
12181220

12191221
* `sbv_unint_cvc4 : [String] -> ProofScript ()`
12201222

1223+
* `sbv_unint_cvc5 : [String] -> ProofScript ()`
1224+
12211225
* `sbv_unint_yices : [String] -> ProofScript ()`
12221226

12231227
* `sbv_unint_z3 : [String] -> ProofScript ()`
@@ -1226,6 +1230,8 @@ The `w4_`-prefixed tactics make use of the What4 library instead of SBV:
12261230

12271231
* `w4_unint_cvc4 : [String] -> ProofScript ()`
12281232

1233+
* `w4_unint_cvc5 : [String] -> ProofScript ()`
1234+
12291235
* `w4_unint_yices : [String] -> ProofScript ()`
12301236

12311237
* `w4_unint_z3 : [String] -> ProofScript ()`

doc/tutorial/tutorial.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ passes the given term through unchanged, because it might be used for
296296
either satisfiability or validity checking.
297297

298298
The SMT-Lib export capabilities in SAWScript make use of the Haskell
299-
SBV package, and support ABC, Boolector, CVC4, MathSAT, Yices, and Z3.
299+
SBV package, and support ABC, Boolector, CVC4, CVC5, MathSAT, Yices, and Z3.
300300

301301
\newpage
302302

intTests/test_cvc5/test.saw

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let
2+
{{
3+
add_mul_lemma : Integer -> Integer -> Integer -> Integer -> Bit
4+
add_mul_lemma m n p q =
5+
(0 <= m /\ 0 <= n /\ 0 <= p /\ 0 <= q /\ n < q /\ p < m) ==>
6+
(m * n + p < m * q)
7+
}};
8+
9+
prove cvc5 {{ add_mul_lemma }};

intTests/test_cvc5/test.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set -e
2+
3+
$SAW test.saw

saw-remote-api/python/saw_client/proofscript.py

+11
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class CVC4(UnintProver):
4545
def __init__(self, unints : List[str]) -> None:
4646
super().__init__("w4-cvc4", unints)
4747

48+
class CVC5(UnintProver):
49+
def __init__(self, unints : List[str]) -> None:
50+
super().__init__("w4-cvc5", unints)
51+
4852
class Yices(UnintProver):
4953
def __init__(self, unints : List[str]) -> None:
5054
super().__init__("w4-yices", unints)
@@ -57,6 +61,10 @@ class CVC4_SBV(UnintProver):
5761
def __init__(self, unints : List[str]) -> None:
5862
super().__init__("sbv-cvc4", unints)
5963

64+
class CVC5_SBV(UnintProver):
65+
def __init__(self, unints : List[str]) -> None:
66+
super().__init__("sbv-cvc5", unints)
67+
6068
class Yices_SBV(UnintProver):
6169
def __init__(self, unints : List[str]) -> None:
6270
super().__init__("sbv-yices", unints)
@@ -121,6 +129,9 @@ def to_json(self) -> Any:
121129
def cvc4(unints : List[str]) -> ProofTactic:
122130
return UseProver(CVC4(unints))
123131

132+
def cvc5(unints : List[str]) -> ProofTactic:
133+
return UseProver(CVC5(unints))
134+
124135
def yices(unints : List[str]) -> ProofTactic:
125136
return UseProver(Yices(unints))
126137

saw-remote-api/src/SAWServer/ProofScript.hs

+7
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ data Prover
5757
| SBV_ABC_SMTLib
5858
| SBV_Boolector [String]
5959
| SBV_CVC4 [String]
60+
| SBV_CVC5 [String]
6061
| SBV_MathSAT [String]
6162
| SBV_Yices [String]
6263
| SBV_Z3 [String]
6364
| W4_ABC_SMTLib
6465
| W4_ABC_Verilog
6566
| W4_Boolector [String]
6667
| W4_CVC4 [String]
68+
| W4_CVC5 [String]
6769
| W4_Yices [String]
6870
| W4_Z3 [String]
6971

@@ -87,18 +89,21 @@ instance FromJSON Prover where
8789
"abc" -> pure W4_ABC_SMTLib
8890
"boolector" -> SBV_Boolector <$> unints
8991
"cvc4" -> SBV_CVC4 <$> unints
92+
"cvc5" -> SBV_CVC5 <$> unints
9093
"mathsat" -> SBV_MathSAT <$> unints
9194
"rme" -> pure RME
9295
"sbv-abc" -> pure SBV_ABC_SMTLib
9396
"sbv-boolector" -> SBV_Boolector <$> unints
9497
"sbv-cvc4" -> SBV_CVC4 <$> unints
98+
"sbv-cvc5" -> SBV_CVC5 <$> unints
9599
"sbv-mathsat" -> SBV_MathSAT <$> unints
96100
"sbv-yices" -> SBV_Yices <$> unints
97101
"sbv-z3" -> SBV_Z3 <$> unints
98102
"w4-abc-smtlib" -> pure W4_ABC_SMTLib
99103
"w4-abc-verilog" -> pure W4_ABC_Verilog
100104
"w4-boolector" -> W4_Boolector <$> unints
101105
"w4-cvc4" -> W4_CVC4 <$> unints
106+
"w4-cvc5" -> W4_CVC5 <$> unints
102107
"w4-yices" -> W4_Yices <$> unints
103108
"w4-z3" -> W4_Z3 <$> unints
104109
"yices" -> SBV_Yices <$> unints
@@ -273,13 +278,15 @@ interpretProofScript (ProofScript ts) = go ts
273278
SBV_ABC_SMTLib -> return $ SB.proveABC_SBV
274279
SBV_Boolector unints -> return $ SB.proveUnintBoolector unints
275280
SBV_CVC4 unints -> return $ SB.proveUnintCVC4 unints
281+
SBV_CVC5 unints -> return $ SB.proveUnintCVC5 unints
276282
SBV_MathSAT unints -> return $ SB.proveUnintMathSAT unints
277283
SBV_Yices unints -> return $ SB.proveUnintYices unints
278284
SBV_Z3 unints -> return $ SB.proveUnintZ3 unints
279285
W4_ABC_SMTLib -> return $ SB.w4_abc_smtlib2
280286
W4_ABC_Verilog -> return $ SB.w4_abc_verilog
281287
W4_Boolector unints -> return $ SB.w4_unint_boolector unints
282288
W4_CVC4 unints -> return $ SB.w4_unint_cvc4 unints
289+
W4_CVC5 unints -> return $ SB.w4_unint_cvc5 unints
283290
W4_Yices unints -> return $ SB.w4_unint_yices unints
284291
W4_Z3 unints -> return $ SB.w4_unint_z3 unints
285292
go [Trivial] = return $ SB.trivial

src/SAWScript/Builtins.hs

+16
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,9 @@ proveZ3 = proveSBV SBV.z3
10051005
proveCVC4 :: ProofScript ()
10061006
proveCVC4 = proveSBV SBV.cvc4
10071007

1008+
proveCVC5 :: ProofScript ()
1009+
proveCVC5 = proveSBV SBV.cvc5
1010+
10081011
proveMathSAT :: ProofScript ()
10091012
proveMathSAT = proveSBV SBV.mathSAT
10101013

@@ -1020,6 +1023,9 @@ proveUnintZ3 = proveUnintSBV SBV.z3
10201023
proveUnintCVC4 :: [String] -> ProofScript ()
10211024
proveUnintCVC4 = proveUnintSBV SBV.cvc4
10221025

1026+
proveUnintCVC5 :: [String] -> ProofScript ()
1027+
proveUnintCVC5 = proveUnintSBV SBV.cvc5
1028+
10231029
proveUnintMathSAT :: [String] -> ProofScript ()
10241030
proveUnintMathSAT = proveUnintSBV SBV.mathSAT
10251031

@@ -1040,6 +1046,9 @@ w4_z3 = wrapW4Prover Prover.proveWhat4_z3 []
10401046
w4_cvc4 :: ProofScript ()
10411047
w4_cvc4 = wrapW4Prover Prover.proveWhat4_cvc4 []
10421048

1049+
w4_cvc5 :: ProofScript ()
1050+
w4_cvc5 = wrapW4Prover Prover.proveWhat4_cvc5 []
1051+
10431052
w4_yices :: ProofScript ()
10441053
w4_yices = wrapW4Prover Prover.proveWhat4_yices []
10451054

@@ -1055,6 +1064,9 @@ w4_unint_z3_using tactic = wrapW4Prover (Prover.proveWhat4_z3_using tactic)
10551064
w4_unint_cvc4 :: [String] -> ProofScript ()
10561065
w4_unint_cvc4 = wrapW4Prover Prover.proveWhat4_cvc4
10571066

1067+
w4_unint_cvc5 :: [String] -> ProofScript ()
1068+
w4_unint_cvc5 = wrapW4Prover Prover.proveWhat4_cvc5
1069+
10581070
w4_unint_yices :: [String] -> ProofScript ()
10591071
w4_unint_yices = wrapW4Prover Prover.proveWhat4_yices
10601072

@@ -1066,6 +1078,10 @@ offline_w4_unint_cvc4 :: [String] -> String -> ProofScript ()
10661078
offline_w4_unint_cvc4 unints path =
10671079
wrapW4ProveExporter Prover.proveExportWhat4_cvc4 unints path ".smt2"
10681080

1081+
offline_w4_unint_cvc5 :: [String] -> String -> ProofScript ()
1082+
offline_w4_unint_cvc5 unints path =
1083+
wrapW4ProveExporter Prover.proveExportWhat4_cvc5 unints path ".smt2"
1084+
10691085
offline_w4_unint_yices :: [String] -> String -> ProofScript ()
10701086
offline_w4_unint_yices unints path =
10711087
wrapW4ProveExporter Prover.proveExportWhat4_yices unints path ".smt2"

src/SAWScript/Interpreter.hs

+38
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,11 @@ primitives = Map.fromList
19181918
Current
19191919
[ "Use the CVC4 theorem prover to prove the current goal." ]
19201920

1921+
, prim "cvc5" "ProofScript ()"
1922+
(pureVal proveCVC5)
1923+
Current
1924+
[ "Use the CVC5 theorem prover to prove the current goal." ]
1925+
19211926
, prim "z3" "ProofScript ()"
19221927
(pureVal proveZ3)
19231928
Current
@@ -1947,6 +1952,13 @@ primitives = Map.fromList
19471952
, "given list of names as uninterpreted."
19481953
]
19491954

1955+
, prim "unint_cvc5" "[String] -> ProofScript ()"
1956+
(pureVal proveUnintCVC5)
1957+
Current
1958+
[ "Use the CVC5 theorem prover to prove the current goal. Leave the"
1959+
, "given list of names as uninterpreted."
1960+
]
1961+
19501962
, prim "unint_yices" "[String] -> ProofScript ()"
19511963
(pureVal proveUnintYices)
19521964
Current
@@ -1964,6 +1976,11 @@ primitives = Map.fromList
19641976
Current
19651977
[ "Use the CVC4 theorem prover to prove the current goal." ]
19661978

1979+
, prim "sbv_cvc5" "ProofScript ()"
1980+
(pureVal proveCVC5)
1981+
Current
1982+
[ "Use the CVC5 theorem prover to prove the current goal." ]
1983+
19671984
, prim "sbv_z3" "ProofScript ()"
19681985
(pureVal proveZ3)
19691986
Current
@@ -1993,6 +2010,13 @@ primitives = Map.fromList
19932010
, "given list of names as uninterpreted."
19942011
]
19952012

2013+
, prim "sbv_unint_cvc5" "[String] -> ProofScript ()"
2014+
(pureVal proveUnintCVC5)
2015+
Current
2016+
[ "Use the CVC5 theorem prover to prove the current goal. Leave the"
2017+
, "given list of names as uninterpreted."
2018+
]
2019+
19962020
, prim "sbv_unint_yices" "[String] -> ProofScript ()"
19972021
(pureVal proveUnintYices)
19982022
Current
@@ -2116,6 +2140,13 @@ primitives = Map.fromList
21162140
, "given list of names as uninterpreted."
21172141
]
21182142

2143+
, prim "w4_unint_cvc5" "[String] -> ProofScript ()"
2144+
(pureVal w4_unint_cvc5)
2145+
Current
2146+
[ "Prove the current goal using What4 (CVC5 backend). Leave the"
2147+
, "given list of names as uninterpreted."
2148+
]
2149+
21192150
, prim "w4_abc_aiger" "ProofScript ()"
21202151
(pureVal w4_abc_aiger)
21212152
Current
@@ -2161,6 +2192,13 @@ primitives = Map.fromList
21612192
," SMT-Lib2 format. Leave the given list of names as uninterpreted."
21622193
]
21632194

2195+
, prim "offline_w4_unint_cvc5" "[String] -> String -> ProofScript ()"
2196+
(pureVal offline_w4_unint_cvc5)
2197+
Current
2198+
[ "Write the current goal to the given file using What4 (CVC5 backend) in"
2199+
," SMT-Lib2 format. Leave the given list of names as uninterpreted."
2200+
]
2201+
21642202
, prim "split_goal" "ProofScript ()"
21652203
(pureVal split_goal)
21662204
Experimental

src/SAWScript/Prover/SBV.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module SAWScript.Prover.SBV
22
( proveUnintSBV
33
, proveUnintSBVIO
44
, SBV.SMTConfig
5-
, SBV.z3, SBV.cvc4, SBV.yices, SBV.mathSAT, SBV.boolector
5+
, SBV.z3, SBV.cvc4, SBV.cvc5, SBV.yices, SBV.mathSAT, SBV.boolector
66
, prepNegatedSBV
77
) where
88

src/SAWScript/Prover/What4.hs

+6-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ proveExportWhat4_sym solver un hashConsing outFilePath t =
111111
-- Assume unsat
112112
return (Nothing, stats)
113113

114-
proveWhat4_z3, proveWhat4_boolector, proveWhat4_cvc4,
114+
proveWhat4_z3, proveWhat4_boolector,
115+
proveWhat4_cvc4, proveWhat4_cvc5,
115116
proveWhat4_dreal, proveWhat4_stp, proveWhat4_yices,
116117
proveWhat4_abc ::
117118
Set VarIndex {- ^ Uninterpreted functions -} ->
@@ -122,6 +123,7 @@ proveWhat4_z3, proveWhat4_boolector, proveWhat4_cvc4,
122123
proveWhat4_z3 = proveWhat4_sym z3Adapter
123124
proveWhat4_boolector = proveWhat4_sym boolectorAdapter
124125
proveWhat4_cvc4 = proveWhat4_sym cvc4Adapter
126+
proveWhat4_cvc5 = proveWhat4_sym cvc5Adapter
125127
proveWhat4_dreal = proveWhat4_sym drealAdapter
126128
proveWhat4_stp = proveWhat4_sym stpAdapter
127129
proveWhat4_yices = proveWhat4_sym yicesAdapter
@@ -141,7 +143,8 @@ proveWhat4_z3_using tactic un hashConsing t =
141143
_ <- setOpt z3TacticSetting $ Text.pack tactic
142144
return ()
143145

144-
proveExportWhat4_z3, proveExportWhat4_boolector, proveExportWhat4_cvc4,
146+
proveExportWhat4_z3, proveExportWhat4_boolector,
147+
proveExportWhat4_cvc4, proveExportWhat4_cvc5,
145148
proveExportWhat4_dreal, proveExportWhat4_stp, proveExportWhat4_yices ::
146149
Set VarIndex {- ^ Uninterpreted functions -} ->
147150
Bool {- ^ Hash-consing of ExportWhat4 terms -}->
@@ -152,6 +155,7 @@ proveExportWhat4_z3, proveExportWhat4_boolector, proveExportWhat4_cvc4,
152155
proveExportWhat4_z3 = proveExportWhat4_sym z3Adapter
153156
proveExportWhat4_boolector = proveExportWhat4_sym boolectorAdapter
154157
proveExportWhat4_cvc4 = proveExportWhat4_sym cvc4Adapter
158+
proveExportWhat4_cvc5 = proveExportWhat4_sym cvc5Adapter
155159
proveExportWhat4_dreal = proveExportWhat4_sym drealAdapter
156160
proveExportWhat4_stp = proveExportWhat4_sym stpAdapter
157161
proveExportWhat4_yices = proveExportWhat4_sym yicesAdapter

0 commit comments

Comments
 (0)