summaryrefslogtreecommitdiff
path: root/src/smtlib.ml
AgeCommit message (Collapse)Author
2019-11-07Backport fixes to SMT generation from poly_mapping branchAlasdair Armstrong
2019-10-31Allow sail to be scripted using sailAlasdair
Currently the -is option allows a list of interactive commands to be passed to the interactive toplevel, however this is only capable of executing a sequential list of instructions which is quite limiting. This commit allows sail interactive commands to be invoked from sail functions running in the interpreter which can be freely interleaved with ordinary sail code, for example one could test an assertion at each QEMU/GDB breakpoint like so: $include <aarch64.sail> function main() -> unit = { sail_gdb_start("target-select remote localhost:1234"); while true do { sail_gdb_continue(); // Run until breakpoint sail_gdb_sync(); // Sync register state with QEMU if not(my_assertion()) { print_endline("Assertion failed") } } }
2019-05-21SMT: Use a separate constructor for memory read variablesAlasdair Armstrong
We want to ensure simplication can treat these separately so we don't accidentally simplify away dependencies between reads and write addresses.
2019-05-21SMT: Add control flow node numbers to memory events to track program orderAlasdair Armstrong
Add path conditions to memory events Allow simplication of generated SMT based on constructor kinds
2019-05-17SMT: Finish adding all memory builtins from lib/regfp.sailAlasdair Armstrong
2019-05-16SMT: Improve simplification for generated SMTAlasdair Armstrong
Generate addresses, kinds, and values separately for read and write events. Add an mli interface for jib_smt.ml
2019-05-14SMT: Allow printing SMT with an optional variable prefixAlasdair Armstrong
Allows us to mix generated SMT for two separate threads without name clashes, however we do want to be able to share datatypes so they are not prefixed. Currently the pretty-printer adds the prefix but we may want a smt_def -> smt_def renaming function instead.
2019-05-10SMT: Implement memory events for read_mem and write_memAlasdair
Generate SMT where the memory reads and writes are totally unconstrained, allowing additional constraints to be added that restrict the possible reads and writes based on some memory model.
2019-05-10SMT: Experiment with symbolic memory reads and writesAlasdair Armstrong
2019-05-10SMT: Lazily compute efficient path conditionalsAlasdair
Effectively reverts 7280e7b with a different method that isn't slow, although it's not totally clear that this is correct - it could just be more subtly wrong than before commit 7280e7b. Following is mostly so I can remember what I did to document & write up properly at some point: What we do is compute 'pi' conditions as before by traversing the dominator tree, we each node having a pi condition defined as the conjunction of all guards between it and the start node in the dominator tree. This is imprecise because we have situations like 1 / \ 2 3 | | | 4 | |\ 5 6 9 \ / | 7 10 | 8 where 8 = match_failure, 1 = start and 10 = return. 2, 3, 6 and 9 are guards as they come directly after a control flow split, which always follows a conditional jump. Here the path through the dominator tree for the match_failure is 1->7->8 which contains no guards so the pi condition would be empty. What we do now is walk backwards (CFG must be acyclic at this point) until we hit the join point prior to where we require a path condition. We then take the disjunction of the pi conditions for the join point's predecessors, so 5 and 6 in this case. Which gives us a path condition of 2 | (3 & 6) as the dominator chains are 1->2->5 and 1->3->4->6. I think this works as any split in the control flow must have been caused by a conditional jump followed by distinct guards, so each of the nodes immediately prior to a join point must be dominated by at least one unique guard. It also explains why the pi conditions seem sufficient to choose outcomes of phi functions. If we hit a guard before a join (such as 9 for return's path conditional) we just return the pi condition for that guard, i.e. (3 & 9) for 10. If we reach start then the path condition is simply true.
2019-05-08SMT: Add reals and strings to SMT backendAlasdair Armstrong
Jib_compile now has an option that lets it generate real value literals (VL_real), which we don't want for backends (i.e. C), which don't support them. Reals are encoded as actual reals in SMT, as there isn't really any nice way to encode them as bitvectors. Currently we just have the pure real functions, functions between integers and reals (i.e. floor, to_real, etc) are not supported for now. Strings are likewise encoded as SMTLIB strings, for similar reasons. Jib_smt has ctx.use_real and ctx.use_string which are set when we generate anything real or string related, so we can keep the logic as Arrays+Bitvectors for most Sail that doesn't require either.
2019-05-07Move parser combinators shared by property and model parsing to separate fileAlasdair Armstrong
2019-05-01Jib: Refactor V_callAlasdair Armstrong
Get rid of separate V_op and V_unary constructors. jib.ott now defines the valid operations for V_call including zero/sign extension, in such a way that the operation ctyp can be inferred. Overall this makes the IR less ad-hoc, and means we can share more code between SMT and C. string_of_cval no longer used by c_backend, which now uses sgen_cval following other sgen_ functions in the code generator, meaning string_of_cval doesn't have to produce valid C code anymore and so can be used for backend-agnostic debug and error messages.
2019-04-30SMT: Allow custom queriesAlasdair Armstrong
As an example: $counterexample :query exist match_failure function prop(xs: bits(4)) -> unit = { match xs { _ : bits(3) @ 0b0 => () } } Will return Solver found counterexample: ok xs -> 0x1 as we are asking for an input such that a match failure occurs, meanwhile $counterexample :query ~(exist match_failure) function prop(xs: bits(4)) -> unit = { match xs { _ : bits(3) @ 0b0 => () } } will return 0x0 as we are asking for an input such that no match failure occurs. Note that we can now support properties for non-boolean functions by not including the return event in the query.
2019-04-29SMT: Refactor overflow checks into generic event checking systemAlasdair Armstrong
Have assert events for assertions and overflow events for potential integer overflow. Unclear how these should interact... The order in which such events are applied to the final assertion is potentially quite important. Overflow checks and assertions are now path sensitive, as they should be.
2019-04-27Merge branch 'sail2' into smt_experimentsAlasdair
2019-04-24SMT: Can now recheck some simple models via the interpreterAlasdair
Probably need to clean-up the implementation and merge new_interpreter into this branch before supporting re-checking counterexamples with more things.
2019-04-23SMT: Add parser for generated modelsAlasdair Armstrong
Simple parser-combinator style parser for generated models. It's actually quite tricky to reconstruct the models because we can have: let x = something $counterexample function prop(x: bits(32)) -> bool = ... where the function argument becomes zx/1 rather than zx/0, which is what we'd expect for the argument of a property. Might need to do something smarter with encoding locations into smt names to figure out what SMT variables correspond to which souce variables exactly. The above also previously generated incorrect SMT, which has now been fixed.
2019-04-16SMT: Fix inlining issuesAlasdair Armstrong
2019-04-16SMT: Add struct value literalsAlasdair
Generates much better SMT that assigning each field one-by-one starting with an undefined struct.
2019-04-13SMT: More builtinsAlasdair
Add some tests for arithmetic operations. Some tests fail in either Z3 or CVC4 currently, due to how overflow is handled.
2019-04-10SMT: Add some simple constant folding for generated SMTAlasdair
Make sure struct fields can overlap each other, and function names
2019-04-09SMT: Experimental Jib->SMT translationAlasdair Armstrong
Currently only works with CVC4, test cases are in test/smt. Can prove that RISC-V add instruction actually adds values in registers and that's about it for now.