Sloth is a decision procedure for several relevant fragments of string constraints, including the straight-line fragment and acyclic formulas. In contrast to most other string solvers, Sloth is able to decide satisfiability of constraints combining concatenation, regular expressions, and transduction, all of which are essential in applications. Sloth uses succinct alternating finite-state automata (AFAs) as concise symbolic representations of string constraints, and uses model checking algorithms like IC3 for solving emptiness of the AFA. More details on the algorithm can be found in our POPL'18 paper; a technical report is available here.
It is easiest to work with one of the binary releases of sloth. The following packages are needed in order to run Sloth on your system:
In order to compile a binary release of Sloth, you have to do following steps:
aigtoaig
(aiger), abc
and nuXmv
into /usr/bin/
./sloth
java -jar target/scala-2.11/sloth-assembly-1.0.jar
In order to compile Sloth from the sources, in addition to one of the model checkers (nuXvm or abc) you need the Scala build system, which is included in common Linux distributions:
$ git clone https://github.com/uuverifiers/sloth.git
sbt assembly
./sloth
to invoke the tool+model | print models/satisfying assignments |
+splitOpt | enable split optimization. This optimization sometimes reduces the number of considered cases significantly |
-modelChecker=abc|nuxmv|simple | choose the model checker, default is nuxmv. Option "simple" enable our model checker that is used on formulae without splitting (recommended uses with +splitOpt). |
+minimalSuccessors | enable an optimisation that reduces the set of considered AFA states (use for abc, nuxmv) |
+assert | enable runtime assertions in Sloth |
Sloth processes constraints in the SMT-LIB 2.6 format, extended with a theory of strings. Sloth is mostly compatible with input language from CVC4 (http://cvc4.cs.stanford.edu/wiki/Strings) and supports a large subset of the CVC4 string operations; a summary of supported operations is given below. For examples, we recommend to have a look at the tests directory.
SMTLIB language | |
---|---|
String Sort | String |
String literals | "abcdef" |
String equality | (= s1 s2) |
Concatenation | (str.++ s1 ... sn) |
Single replacement | (str.replace s t1 t2) |
Replacement | (str.replaceall s t1 t2) |
Membership in regular expression | (str.in.re s r) |
String to regular expression | (str.to.re s) |
Regular expression concatenation | (re.++ r1 ... rn) |
Regular expression union | (re.union r1 ... rn) |
Regular expression intersection | (re.inter r1 ... rn) |
Regular expression Kleene star | (re.* r) |
Regular expression plus | (re.+ r) |
Regular expression character range | (re.range s t) |
At the moment Sloth only supports 256 character (8-bit) Extended ASCII alphabets. String literals are composed from printable characters (value between 0x20 and 0x7e) in double quotes. Escape sequences are supported too. They are interpreted in the usual way, as shown in the following table.
\0 ... \9 | represents ASCII character 0 … 9, respectively |
\a, \b, \e, \f, \n,\r, \t, \v | represents its corresponding ASCII character |
\ooo | encodes a single ASCII character where ooo consists of exactly three digits in the octal encoding of the character (from 0 to 377) |
\xNN | encodes a single ASCII character, where NN is two-digit hexadecimal constant |
(declare-fun x () String)
(declare-const x String)
(str.++ s1 ... sn)
(str.replace s t1 t2)
(str.replaceall s t1 t2)
(str.in.re s r)
(str.to.re s)
(re.++ r_1 ... r_n)
(re.union r_1 ... r_n)
(re.inter r_1 ... r_n)
(re.* r)
(re.+ r)
(re.opt r)
(re.range s t)
re.nostr
re.allchar
Sloth can also handle string transformations expressed as transducers. We represent transducers as mutually recursive functions with multiple arguments in SMT-LIB. In general, the characteristic function of the language accepted by an transducer can be written as a set of mutually (primitive) recursive functions over strings; the equations defining the functions directly correspond to the transitions of the transducer.
For instance, considering strings over 8-bit bit-vectors, the following recursive function describes the to-uppercase transducer. The transducer definition makes use of the additional operations seq-head to extract the first character of a (non-empty) string, and seq-tail to compute the tail:
This function can then be used to formulate string constraints, for instance:
It is also possible to work with non-length-preserving transducers, i.e., transducers that map a string to a new string of potentially different length. For instance, the following transducer extracts the string in between the 0th and 1st occurrence of '=':
If you have any questions, do not hesitate to contact the tool/method authors:
This work is supported by the AQUAS: Aggregated Quality Assurance for Systems (737475), the Czech Science Foundation (projects 14-11384S, 16-24707Y, 17-12465S), the internal BUT FIT project FIT-S-17-4014, and the IT4IXS: IT4Innovations Excellence in Science (LQ1602).
Copyright (c) 2018 Petr Janku <ijanku@fit.vutbr.cz>