1
- Scala SMT-LIB [ ![ Build Status ] ( http ://laraquad4.epfl.ch:9000 /epfl-lara/scala-smtlib/status/master )] ( http ://laraquad4.epfl.ch:9000 /epfl-lara/scala-smtlib)
1
+ Scala SMT-LIB [ ![ scala-smtlib CI ] ( https ://github.com /epfl-lara/scala-smtlib/actions/workflows/scala-smtlib-CI.yml/badge.svg )] ( https ://github.com /epfl-lara/scala-smtlib/actions/workflows/scala-smtlib-CI.yml )
2
2
=============
3
3
4
4
Scala SMT-LIB is a lightweight, no dependency, abstraction over the
@@ -47,8 +47,28 @@ You may want to use Scala SMT-LIB if:
47
47
Setup
48
48
-----
49
49
50
- The latest stable release for Scala 2.11 is available on Sonatype, simply add
51
- the following to your ` build.sbt ` :
50
+ To include Scala SMT-LIB in your project, you can add it as a dependency
51
+ referring to a commit hash. You can add the following to your ` build.sbt ` :
52
+
53
+ ``` scala
54
+ def remoteProject (repo : String , version : String ) = RootProject (uri(s " ${repo}# ${version}" ))
55
+
56
+ // Choose a commit hash to pin the Scala SMT-LIB version (replace with the latest or chosen commit):
57
+ val smtlibRepository = " https://github.com/epfl-lara/scala-smtlib.git"
58
+ val smtlibCommitHash = " a8fc084fa48a59f0f58b6f3fba5433b8fe5eb280" // example commit
59
+
60
+ lazy val scalaSmtlib = remoteProject(smtlibRepository, smtlibCommitHash)
61
+
62
+ // And depend on it in your project
63
+ lazy val yourProject = (project in file(" ." ))
64
+ .settings(
65
+ // ...
66
+ )
67
+ .dependsOn(scalaSmtlib) // <<<
68
+ ```
69
+
70
+ The last stable release for Scala 2.11 is available on Sonatype, add the
71
+ following to your project settings in ` build.sbt ` :
52
72
53
73
``` scala
54
74
libraryDependencies += " com.regblanc" %% " scala-smtlib" % " 0.2.2"
@@ -57,7 +77,7 @@ libraryDependencies += "com.regblanc" %% "scala-smtlib" % "0.2.2"
57
77
Getting Started with Examples
58
78
-----------------------------
59
79
60
- To construct a parser, you will need a java.io.Reader and a lexer:
80
+ To construct a parser, you will need a ` java.io.Reader ` and a lexer:
61
81
62
82
``` scala
63
83
val is = new java.io.FileReader (" INPUT" )
@@ -103,10 +123,10 @@ val formula = Assert(LessThan(NumeralLit(0), Plus(x, y)))
103
123
smtlib.printer.RecursivePrinter .toString(formula) // (assert (< 0 (+ x y)))
104
124
```
105
125
106
- The above is a little bit verbose due to the objective of supporting all of
107
- SMT-LIB. We are hoping to provide a nicer API in the future to build SMT-LIB
108
- scripts, at least in the common cases, but the AST will probably remain at the
109
- core of the library.
126
+ The above is a bit verbose due to the objective of supporting all of SMT-LIB. We
127
+ are hoping to provide a nicer API in the future to build SMT-LIB scripts, at
128
+ least in the common cases, but the AST will probably remain at the core of the
129
+ library.
110
130
111
131
Low Level API
112
132
-------------
@@ -147,14 +167,14 @@ such as `stdin`). The following two exceptions can be thrown by the lexer:
147
167
throw the exception on the first ` f ` . The exception indicates the position
148
168
in the input.
149
169
* ` UnexpectedEOFException ` occurs when the EOF is reached in the middle of an
150
- un-completed token. For example, a string literal which is not closed before
151
- the EOF.
170
+ incomplete token. For example, a string literal which is not closed before the
171
+ EOF.
152
172
153
173
154
174
### Parsing
155
175
156
176
Usually one does not need to work on a token by token basis, and is only
157
- interested in fully formated SMT-LIB expressions. The
177
+ interested in fully formatted SMT-LIB expressions. The
158
178
[ ` parser ` ] ( /src/main/scala/smtlib/parser ) provides the extraction of SMT-LIB
159
179
expressions. The [ ` Parser ` ] ( /src/main/scala/smtlib/parser/Parser.scala ) consumes
160
180
tokens generated by the above lexer:
@@ -184,68 +204,82 @@ parameter a `Term`. Their ASTs are defined
184
204
### Printing
185
205
186
206
The [ ` printer ` ] ( /src/main/scala/smtlib/printer ) helps with printing out SMT-LIB
187
- complient commands. This means that the output of a printer can be send
207
+ compliant commands. This means that the output of a printer can be sent
188
208
directly to an SMT solver.
189
209
190
210
### Standard Theories
191
211
192
- Finally the [ ` theories ` ] ( /src/main/scala/smtlib/theories ) module provides tree
193
- builders to create theory-specific formulas. Each theory module provides
194
- ` apply ` and ` unapply ` methods on various object to manipulate the ` Term `
195
- representing the actual theory expression.
212
+ Finally, the [ ` theories ` ] ( /src/main/scala/smtlib/theories ) module provides tree
213
+ builders to create theory-specific formulas. Each theory module provides ` apply `
214
+ and ` unapply ` methods on various object to manipulate the ` Term ` representing
215
+ the actual theory expression.
196
216
197
217
Development
198
218
-----------
199
219
200
- The library is still under development and the API will likely go through quite a few
201
- changes. It was originally part of [ CafeSat] ( https://github.com/regb/scabolic )
202
- and has been made standalone in order for the
203
- [ Leon] ( https://github.com/epfl-lara/leon ) project to rely on it.
220
+ The library is still under development and the API will likely go through quite
221
+ a few changes. It was originally part of
222
+ [ CafeSat] ( https://github.com/regb/cafesat ) and has been made standalone in order
223
+ for the [ Inox] ( https://github.com/epfl-lara/inox ) and
224
+ [ Stainless] ( https://github.com/epfl-lara/stainless ) projects to rely on it.
204
225
Hopefully, it can be useful to other people as well.
205
226
206
227
### Testing
207
228
208
- In order to attain a decent level of quality, there is a relatively strict policy for testing.
209
- Testing is separated in two levels of testing: unit tests and integration tests. Unit test
210
- are dependency free and run entirely in memory. While integration tests will rely on things
211
- like file system and external solvers. Unit test are very fast and should be easy to run as part
212
- of a regular build cycle (you can run them after each compile), while integration tests are a bit
213
- slower and are meant to pass on each commit.
229
+ In order to attain a decent level of quality, there is a relatively strict
230
+ policy for testing. Testing is separated in two levels of testing: unit tests
231
+ and integration tests. Unit test are dependency free and run entirely in memory.
232
+ While integration tests will rely on things like file system and external
233
+ solvers. Unit test are very fast and should be easy to run as part of a regular
234
+ build cycle (you can run them after each compile), while integration tests are a
235
+ bit slower and are meant to pass on each commit.
214
236
215
237
In SBT, the command ` sbt test ` will run the unit test suite, while the command
216
- ` sbt it: test ` will run the integration test suite. During developement, it
217
- should be fine to run in mode ` ~testQuick ` .
238
+ ` sbt IntegrationTest/ test ` will run the integration test suite. During
239
+ development, it should be fine to run in ` ~testQuick ` mode .
218
240
219
241
### Building the Sources
220
242
221
243
The project is built with [ sbt] ( http://www.scala-sbt.org/ ) . To build the
222
244
library, just type:
223
245
224
- sbt package
246
+ ``` console
247
+ $ sbt package
248
+ ```
225
249
226
250
It will produce a jar that you can add to the classpath of your own project.
227
251
228
- If you are building your project using sbt, it is possible to setup a reference
229
- to this github repository in the build system to automatically get the most
230
- recent build. [ Here] ( https://github.com/regb/cafesat/blob/master/build.sbt ) is
231
- an example of how to do it, you can pick any commit. If you are interested in
232
- this route, you should check the sbt official documentation.
233
-
234
252
Optionally, you can test Scala SMT-LIB in your environment by running the test
235
253
suite. The tests are organized in unit and functional tests. Tu run the unit
236
254
tests (very fast) you can type:
237
255
238
- sbt test
256
+ ``` console
257
+ $ sbt test
258
+ ```
259
+
260
+ The functional tests are testing end-to-end flows of Scala SMT-LIB. They do take
261
+ a bit more time and require some setup in your environment. In particular, they
262
+ will try to use the SMT solvers ` z3 ` , ` cvc4 ` , ` cvc5 ` , and ` bitwuzla ` if they are
263
+ available in your PATH (the commands tried are exactly the solver names as
264
+ listed). If present in the PATH, Scala SMT-LIB will test its interpreter module
265
+ directly against these SMT solvers.
239
266
240
- All tests should pass. Please open an issue if any test is failing. The
241
- functional tests are testing end-to-end flows of Scala SMT-LIB. They do take a
242
- bit more time and require some setup in your environment. In particular, they
243
- will try to use the SMT solvers ` z3 ` and/or ` cvc4 ` if they are available in
244
- your PATH (the commands tried are exactly ` z3 ` and ` cvc4 ` ). If present in the
245
- PATH, Scala SMT-LIB will test its interpreter module directly against these SMT
246
- solvers. You can run those tests with:
267
+ The solvers binaries can also be obtained through the
268
+ [ ` scripts/install_solvers.sh ` ] ( scripts/install_solvers.sh ) script. You can run
269
+ it with:
247
270
248
- sbt it:test
271
+ ``` console
272
+ $ INSTALL_SOLVERS=1 scripts/install_solvers.sh
273
+ ```
274
+
275
+ Default known versions of the solvers are used in the script unless given on the
276
+ command line.
277
+
278
+ You can run those tests with:
279
+
280
+ ``` console
281
+ $ sbt IntegrationTest/test
282
+ ```
249
283
250
284
Changelog
251
285
---------
0 commit comments