robbepop / stevia Goto Github PK
View Code? Open in Web Editor NEWA simple (unfinished) SMT solver for QF_ABV.
License: Other
A simple (unfinished) SMT solver for QF_ABV.
License: Other
Currently stevia was implemented without proper adjustment on the outer interfaces to the module. The ast module for example has a giantic interface which should and certainly could be minimized. To allow for later decoupling of modules this should be done beforehand.
Stevia requires support for SMTLib2 parsing to make it work with SMTLib2 inputs.
For this the rsmt2 crate provides parsing support, however, its current implementation isn't flexible enough to allow for decoupled integration of other SMT solver than the currently implemented ones (Z3 and CVC4). This issue is described in detail here. Adrien Champion reported that this was a wrong assumption about rsmt2.
For the parsing of SMTLib2 there are effectively two approaches.
The eager approach would simply parse an SMTLib2 input, process it and directly returns the entire parsed construct represented as an apropriate data structure to feed into stevia. This approach is simple, however, has the downside to be very inflexible and may require more memory to store a temporary data structure and maybe even has negative performance implications.
A more flexible and thus superior approach is to define an interface to let an underlying SMT solver know about newly parsed entities. In this situation a proper interface has yet to be found but the advantage is that this should be more optimal for memory consumption and runtime performance.
The following simplifications on expression trees are listed here.
These are not currently implemented in Stevia but are planned or debated for future versions.
(Note: This list of planned simplification routines is not complete!)
If
(ite true a b)
to a
and (ite false a b)
to b
(ite c a a)
to a
(ite (not c) a b)
to (ite c b a)
(ite c (not c) a)
to (ite c false a)
works recursively(ite (< a b) (div a b) 0)
to 0
and handles semantics or relationsEquals
(= a b)
to true
where a
and b
are const and evaluate to the same value(= a b)
to false
where a
and b
are const and evaluate to a distinct value(= a (not a))
to false
and (= a (neg a))
to false
(and (= a b) (= b c))
to (= a b c)
Symbol
Not
(not (not a))
to a
(not c1)
to c2
where c1
is const and c2
is not c1
(not (uge a b))
to (ult a b)
(not (sge a b))
to (slt a b)
(not (ule a b))
to (ult b a)
(not (sle a b))
to (slt b a)
And
(and true true)
to true
(and true false)
to false
(and a (not a))
to false
(and (not a) (not b))
to (not (or a b))
(and (and a b) (and c d))
to (and a b c d)
(and a a b)
to (and a b)
Or
(or false true)
to true
(or false false)
to false
(or a (not a))
to true
(or (not a) (not b))
to (not (and a b))
(or (or a b) (or c d))
to (or a b c d)
(or a a b)
to (or a b)
Xor
(xor true false)
to true
.(xor a a)
to false
(xor a (not a))
to true
Iff (deprecated for equals?)
Implies
(implies a b)
to (or (not a) b)
Parametric Bool
Neg
(- 0)
to 0
(- (- a))
to a
(- c1)
to c2
where c1
is const and c2
is the negation of c1
(- (+ a b c))
to (+ (- a) (- b) (- c))
(- (* a b c))
to (* (- a) b c)
Add
(+ c1 c2)
to c3
where c1
and c2
are both constant and c3 = c1 + c2
.(+ a 0)
to a
(+ a (-a))
to 0
(+ (-a) (-b))
to (- (+ a b))
mul
: (+ a a)
to (* 2 a)
(+ (+ a b) (+ c d))
to (+ a b c d)
(+ a (-a) (* 5 a) (* (-3) a) b)
to (+ (* 2 a) b)
Sub
(- c1 c2)
to c3
where c1
and c2
are both constant and c3 = c1 - c2
.(- a 0)
to a
and (- 0 a)
to (-a)
(- a a)
to 0
(- a b)
to (+ a (- b))
Mul
(* a 1)
to a
(* a 0)
to 0
(* a (/ 1 a))
to 1
(* a n)
to (<< a (log n))
where n
is a power of two.(* (* a b) (* c d))
to (* a b c d)
(mul a (-b) c (-d) (-e) f)
to (mul (-a) b c d e f)
(* (- a) b)
to (- (* a b))
(* a (-b))
to (- (* a b))
(* (- a) (- b))
to (* a b)
Div
(/ a 0)
to Undefined
<- signaling undefined behaviour to the user.(/ a 1)
to a
(/ a a)
to 1
(/ 0 a)
to 0
if a
is not 0
(/ a (/ b c))
to (/ (* a c) b)
. Reason: mul
is easier for the const evaluator.(/ a n)
to (>> a (log n))
where n
is a power of two.(/ c1 c2)
to 0
if (= (< c1 c2) true)
and c1
and c2
are const.(/ (- a) b)
to (- (/ a b))
(/ a (-b))
to (- (/ a b))
(/ (- a) (- b))
to (/ a b)
BitNot
(bvnot (bvnot x))
to x
(bvnot c1)
to c2
where c2
is equal to the bitnot application of c1
.BitAnd
(bitand x x)
to x
(bitand x ..1..)
to x
(bitand x (bitnot x))
to 0
(bitand x ..0..)
to 0
BitOr
(bitor x x)
to x
(bitor x ..0..)
to x
(bitor x (bitnot x))
to 1
(bitor x ..1..)
to ..1..
BitXor
(bitxor x ..0..)
to x
(bitxor x ..1..)
to (bitnot x)
(bitxor x x)
to 0
(bitxor x (bitnot x))
to ..1..
BitNand
BitNor
BitXnor
ShiftLeft
ArithmeticShiftRight
LogicalShiftRight
LessThan
(< c1 c2)
evaluate for all constant c1
and c2
(< x x)
to false
(< x (-y))
to (< y x)
(< (-x) y)
to (< y x)
(< (-x) (-y))
to (< x y)
LessEquals
(ule x y)
to (not (ult y x))
GreaterThan
(ugt x y)
to (ult y x)
GreaterEquals
(uge x y)
to (ule y x)
Signed LessThan
(< c1 c2)
evaluate for all constant c1
and c2
(< x x)
to false
(< x (-y))
to (< y x)
(< (-x) y)
to (< y x)
(< (-x) (-y))
to (< x y)
Signed LessEquals
(sle x y)
to (not (slt y x))
Signed GreaterThan
(sgt x y)
to (slt y x)
Signed GreaterEquals
(sge x y)
to (sle y x)
Concat
Extract
ZeroExtend
SignedExtend
Read
Write
For stevia to be a more or less complete SMT solver the following high-level modules will need to be implemented in one form or another:
With AIG optimizations:
Additional optimizations:
The current Read-over-Write simplification might expand its input exponentially.
This could impose significant performance penalties and should be avoided.
By the newly introduced SymbolProxy
in Context
proxy symbols can be generated to substitute to-be-copied expression trees temporarily. They can be inserted back into the expression tree at a later point where they can be processed in isolation to their former parent until they are merged back again.
The same procedure can and should be implemented for Eliminate-Array-Read and Eliminate-Array-Write simplifications.
Currently the stevia_ast
module interface is extremely polluted because every item is exported on global scope. Only the actual expression
items have their own module.
We could need further modules to separate functionality:
type
: For types and handling types and errors around typing issues.transformer
: For the AST transformer interfaces and utilities.checks
: For (general purpose) checks of the AST invariants.iter
: For iteration methods and structures over the AST.utils
: We also might need a utilities module for everything that acts as convenience or ... utility.Also the expr
sub module should receive another utils
module where all the helper structures like BinaryChildren
are located.
The new stevia_bitvec
crate and its provided Bitvec
implementation is still missing some core QF_BV
functions. Namely, bvcomp
with proper error handling (not panicking), rotate_left
and rotate_right
(supported in the upcoming apint
version 0.3
), and repeat
.
For more information visit this page: http://smtlib.cs.uiowa.edu/logics-all.shtml#QF_BV
Since cargo supports workspaces and since stevias modules (currently ast and simplifier) are far larger than expected it should be ideal for code reuse to seperate them more clearly by restructuring them into libraries connected in the stevia workspace. This makes it possible to implement later sub-libraries that depend on certain other stevia libraries.
Currently the simplification procedure naively simplifies any expression exactly five times since the simplifier is currently not tracking state changes due to successful simplifications. This should be changed to dynamically simplify until a fix-point has been reached.
Simplifier
.simplify
.Find and depend on decent library implementation similar or equal to STP's ABC library for and-inverter-graph (AIG) computation. A pure Rust implementation is favoured over any other implementation to avoid having non-ecosystem dependencies.
The current implementation of Bitvec::is_smax
and Bitvec::is_smin
is suboptimal because there is no native implementation for it in apint
and we have to emulate the logic for it in stevia_bitvec
. To improve this we could try implementing these (or similar) checks in apint
since they might be reasonable to add there because of the already existing constructors unsigned_max_value
etc.
Stevia could profit by implementing or at least providing Nand
, Nor
and Xnor
in addition to And
, Or
and Xor
that currently exist. This could make some simplifications involving negation simpler or at least more performant temporarily.
These additional expression types could be implemented on several different layers.
And
, Or
and Xor
. The downside is that this is quite intransparent to users that might be confused why no actual negated versions are created.Find out what scopes push
& pop
in STP are and how to incorporate them into this SMT solver.
Note: STP has a stack of vectors that acts as assertion scope level. Users may wish to add or remove such scopes to add or remove entire groups of assertions that have been added to the removed scope level. The STP scope design is inefficient and should not be taken over to Stevia. Stevia should model this concept with a single vector for the assertions and another vector for entry points to new scope levels.
Stevia should handle complex array expressions and thus be able to word-level simplify those together with array abstraction refinement.
To be implemented are:
ArrayRead
expressions by replacing them with appropriate equi-satisfiable local- and root expressions.ArrayWrite
expressions by replacing them with appropriate equisatisfiable local- and root expressions.Both simplifications require refinement expressions on the root scope of the input expression which can be refined by lazy insertion similar to how STP handles them via its array abstraction refinement.
Stevia could profit greatly from fuzz testing.
This could be more or less easily implemented at least for SMTLib2 parsing once implemented and for the word-level simplifier. Maybe later even for the bit blaster module.
For this there is a tool called cargo-fuzz
that should work out of the box but we need parsing support for SMTLib2 before we can do any proper fuzz testing at all.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.