NOTES (Antoine Miné, Paris, 15 Septembre 2014)
- Context
This directory contains a proof-of-concept implementation for a new algorithm to search for inductive invariants, using a search method inspired by Constraint Programming. The original idea for the algorithm was proposed by Sriram Sankaranarayanan, inspired from a join work with Charlotte Truchet. The prototype is written in OCaml.
- Prerequisites
-
OCaml: http://ocaml.org (tested with OCaml 4.02, but should work on earlier versions)
-
ZArith: https://forge.ocamlcore.org/projects/zarith (tested with the SVN version, but should work on earlier releases)
-
Menhir: http://gallium.inria.fr/~fpottier/menhir (tested with version 20090505)
-
an SVG viewer (for the graphical output) (your browser can probably do it)
Tested on a 64-bit Linux intel Dell laptop (Gentoo distribution).
- Compilation
Typing "make" should work.
In case of problems, it may be sufficient to change some variables at the top of the Makefile (e.g., set OCAMLOPT to ocamlopt instead of ocamlopt.opt, add a path to ocamlopt, or change ZARITHDIR).
By default, "make" builds native code. The binary is called "solve" You can also build a bytecode version called "solve.b" using "make solve.b"
- Usage
./solve [options]
where is a specification file. For instance:
./solve examples/filter.txt
(On Windows, use "./solve.exe".)
By default, the solver performs several refinement steps. The refinement steps allow improving an inductive invariant if one is found at the preceding step, or give another chance at finding an inductive invariant.
This outputs two results:
-
on the standard output, displays information on the various steps of the search, and whether it is successful;
-
in out/output_X-result-Y.svg, a SVG graphic file that shows the inductive invariant found, after each refinement step X. If Y is "ok", then the step did find an inductive invariant, otherwise it failed.
See the appendix for a list of command-line options and a description of the input language. See exmaples for more example specifications.
APPENDIX
A) Input language
A specification file must contain three blocks, in that order:
init { /* statements / } body { / statements / } goal { / statements */ }
which specify respectively: the entry environment box before entering the loop, the effect of a loop iteration, and the goal invariant box.
The solver tries to find an inductive invariant implying the goal, i.e., a set of boxes included in the goal box, that cover the init box and is invariant by an application the body (the image of every box in the inductive invariant is covered by the inductive invariant itself).
Statements include C-like assignments and if-then-else.
Expressions support +, -, *, / and abs. They are interpreted in arbitrary-precision rationals. In addition to constants, you can use intervals with constant bounds in expressions (model a non-deterministic choice between the interval).
Note that the initial environment and goal invariants are also specified using a list of statements. They simply happen to be assignments of an interval to each variable (we reuse the same interval abstract interpreter as for evaluating the loop body, to simplify).
Variables need not (and cannot) be declared. The invariant and goal environments must assign the same set of variables. Variables assigned in the body statements that are not in the init or goal environments act as temporary: their value is discarded after each loop iteration.
See the examples directory for some sample input files, or the frontend directory for the precise grammar.
B) Option list
See ./solve --help for the full list of options and default values.
--epsilon-size (defaults to 0.01) Boxes smaller than epsilon are no longer split
--epsilon-cover (defaults to 0.1) Boxes with coverage smaller than epsilon are no longer split
--max-iterate (defaults to a large value) Abort the solving after that many iterates
--max-refinement-steps (defaults to 8) Number of refinement iterations, to either improve on an inductive invariant found or to continue searching for an inductive invariant.
--octagon Uses the octagon domain instead of the interval domain.
--verbose Logs on the standard output every action performed by the solver
--check Checks after each action performed by the solver that the state is consistent (very slow, for debugging purpose only)
--svg-width --svg-height Dimension of the output SVG file (defaults to 512x512)
--svg-x --svg-y Which variables to choose when outputing SVG files. Defaults to the first two program variables.
NOTE: SVG output is untested for more than two variables and may be useless; it probably performs a project that stack boxes on top of each other, while computing a 2d slice of a n-dimensional space might be wiser
--svg-steps Outputs SVG image of the state at various iteration stage (in out/outputXXX.svg, where XXX is the iteration number)
--svg-animation Outputs an animated SVG file (in out/output_animation.svg)
--svg-time (defaults to 10) The animation is tailored to last exactly the specified number of seconds. The "framerate" for each iteration is simply this total time divided by the number of iterations to reach an inductive invariant.
--svg-show-partition Shows the limit of the partitions tine SVG output.