RInGen is a SMTLIB2 converter. It takes arbitrary SMTLIB2 files as input and generates Horn clauses over pure algebraic datatypes in SMTLIB2 and Prolog. It can optionally run a number of CHC and other solvers over output clauses, currently: Z3, Eldarica, CVC4 in finite model find mode, CVC4 in inductive mode, VeriMAP (for inductively defined data types), Vampire.
- Supports extra
(lemma P *args* *lemma-expr*)
syntax (see, e.g.,samples/lemmas_with_new_syntax.smt2
). - Supports
define-fun
,define-fun-rec
anddefine-funs-rec
translation to predicates- Functions are translated to predicates with a supplementary return-argument
-
let
andmatch
expressions are eliminated
- Supports instantiation of the free sorts (declared with
declare-sort
) to PeanoNat
algebraic datatype - Supports
Int
sort substitution with PeanoNat
algebraic datatype- Supports
Int
operations translation to predicates overNat
:-
,+
,*
,mod
,div
,<
,<=
,>
,>=
- Supports
- Supports ADT selectors and testers translation to clauses
.NET core >= 6.0
- (optionally, to run solvers)
z3
,eldarica
,cvc4
,VeriMAP-iddt
,vampire
executables accessible in the environment
git clone --recursive https://github.com/Columpio/RInGen.git
dotnet build -c Release RInGen.sln
Build standalone version (for specific platform from the list)
dotnet publish -c Release -r <RID> -p:PublishReadyToRun=true RInGen.sln
For example, to build for CHC-COMP (running on StarExec, which has RHEL 7) call
dotnet publish -c Release -r rhel.7-x64 -p:PublishReadyToRun=true RInGen.sln
Executable then can be found in the ~/RInGen/bin/Release/net6.0/<RID>/publish
folder.
~$ unzip /path/to/standalone-<RID>.zip -d RInGen
~$ cd RInGen
~/RInGen$ ./RInGen ..arguments..
~$ unzip /path/to/dotnet-build.zip -d RInGen
~$ cd RInGen
~/RInGen$ dotnet RInGen.dll ..arguments..
~/RInGen$ dotnet bin/Release/net5.0/RInGen.dll ..arguments..
Quiet mode. Only outputs are sat
, unsat
, unknown
when in solve
mode or nothing when in transform
mode.
Time limit for transformation and/or solving, in seconds (default 300
).
A full path PATH
to an output path where to put auxiliary files (default: same as input).
Treated as a directory if ends with a directory separator (e.g., /).
Otherwise, treated as a file.
Specifies full path to either a single SMTLIB2 file or a directory.
If /FULL/PATH.smt2
leads to a file and the --output-directory
flag is not specified,
the tool will generate Horn clauses in SMTLIB2 format and save them at /FULL/PATH.*.0.smt2
.
Otherwise if /FULL/PATH.smt2
leads to a directory,
the tool will recursively traverse the directory and process all .smt2
files.
Only transform input files, do not run any solvers.
If original
is specified, saves as smt2
with ADTs.
If freesorts
is specified, saves as smt2
with all algebraic datatypes transformed into sorts.
Specifically, each ADT sort declaration with declare-datatypes
is substituted with
declare-sort
for ADT sort and a number of declare-fun
declarations for constructors.
If prolog
is specified, saves as pl
Prolog problem.
Default: original
.
solve (--table) --solver SOLVER_NAME (--in) (--path /FULL/PATH) (--transform-options <transform-options>)
Process input files and run one (or many) solvers.
Generate a solver run statistics table. Useful after running several solvers.
Run a specific solver after processing. Available options:
- Z3 (
z3
) - Eldarica (
eldarica
) - CVC4 in finite model find mode (
cvc_fmf
) - CVC4 in inductive mode (
cvc_ind
) - VeriMAP (for inductively defined data types) (
verimap
) - CHC-COMP-optimized fork of Vampire (
vampire
)
Note that in order to run
Z3
,Eldarica
,CVC4
,Vampire
andVeriMAP
one should havez3
,eld
,cvc4
,vampire
andVeriMAP-iddt
executables accessible in the environment. The easiest way to do that is to prefix tool running with:
env 'VeriMAP-iddt=/FULL/PATH/TO/VeriMAP-iddt-linux_x86_64/VeriMAP-iddt'
Interactive mode: reads smt2
commands from stdin.
Runs solver on (check-sat)
SMTLIB2 command.
Noninteractive mode: read smt2
commands from specified path (file or directory)
Transformation options to be performed before solving
Convert TIP-like systems to Horn clauses.
This flag makes the tool treat all assert
ions as queries, meaning that
they are transformed to the following form:
(assert (forall ... (=> .. false)))
Synchronize ADT terms of a CHC system by making all user predicates unary and introducing new predicates and combined ADT declarations.
User predicate with signature S1 * ... * Sn
will become a unary predicate over fresh ADT sort S1...Sn
.
Term synchronization is hardcoded (like in TATA): left subterm is synchronized with left subterm, right with right, etc.
$ ringen transform /FULL/PATH/TO/DIRECTORY
Obtained clauses are in the /FULL/PATH/TO/DIRECTORY.Original
folder.
$ ringen --timelimit 5 solve --solver z3 --path .../samples/one-zeroary-constr.smt2 -t
Obtained clauses are in the .../samples/one-zeroary-constr.Original.smt2
file.
Result of the z3
run will be output to .../samples/one-zeroary-constr.Original.Z3.smt2
file.
For one-zeroary-constr
example it will contain four lines:
Result file line | description | |
---|---|---|
0 | rounded transformed file size | in kilobytes |
13176 | solver run memory | in kilobytes |
0 | solver run time | in milliseconds |
SAT ElemFormula | solver result | <solver result> |
Has SMTLIB2 status (sat
, unsat
,..) and invariant representation type if status is sat
.
$ ringen --quiet solve --solver cvc_fmf --path .../samples/prop_20.smt2 -t --tip
The output is sat
.
$ ringen --quiet solve --solver cvc_fmf --in -t
For example, one can copy-paste samples/lemmas_with_new_syntax.smt2
line-by-line obtaining:
smt2> (set-logic HORN)
smt2> (declare-datatypes ((Nat 0)) (((Z) (S (unS Nat)))))
smt2> (declare-fun P (Nat) Bool)
smt2> (lemma P ((x Nat)) (= x Z))
smt2> (lemma P ((y Nat)) (= y (S (S Z))))
smt2> (assert (forall ((x Nat)) (=> (= x Z) (P x))))
smt2> (assert (forall ((x Nat)) (=> (P x) (P (S (S x))))))
smt2> (assert (forall ((x Nat)) (=> (and (P x) (= x (S Z))) false)))
smt2> (check-sat)
sat
smt2>
One could also omit the --quiet
flag to obtain more verbose output (with locations of auxiliary files).