summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2019-04-17SMT: Support generic vectors and handle lets between specs and functionsAlasdair Armstrong
If we have e.g. $property val prop : ... let X = 0 function prop(...) = X == ... then we need to ensure that let X is included when we generate the property.
2019-04-17SMT: Unroll simple foreach loopsAlasdair Armstrong
2019-04-16Remove unnecessary assertThomas Bauereiss
2019-04-16SMT: Support toplevel letbindingsAlasdair Armstrong
2019-04-16SMT: Fix inlining issuesAlasdair Armstrong
2019-04-16BugfixingThomas Bauereiss
2019-04-16SMT: Take care to not generate duplicate labelsThomas Bauereiss
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-15Add more SMT builtinsThomas Bauereiss
2019-04-15SMT: Allow partial specializationsAlasdair Armstrong
Change specialisation so we only specialize integer parameters when they are constant. This makes ensures that the integer-specialised code is always type-correct.
2019-04-13SMT: Add count_leading_zeros and more builtinsAlasdair
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-11SMT: Add property and counterexample directiveAlasdair Armstrong
Rather than generating SMT from a function called check_sat, now find any function with a $property directive and generate SMT for it, e.g. $property function prop_cap_round_trip(cap: bits(128)) -> bool = { let cap_rt = capToBits(capBitsToCapability(true, cap)); cap == cap_rt } $property function prop_base_lteq_top(capbits: bits(128)) -> bool = { let c = capBitsToCapability(true, capbits); let (base, top) = getCapBounds(c); let e = unsigned(c.E); e >= 51 | base <= top } The file property.ml has a function for gathering all the properties in a file, as well as a rewrite-pass for properties with type quantifiers, which allows us to handle properties like function prop forall 'n, 'n <= 100. (bv: bits('n)) -> bool = exp by rewriting to (conceptually) function prop(bv: bits(MAX_BIT_WIDTH)) -> bool = if length(bv) > 100 then true else exp The function return is now automatically negated (i.e. always true = unsat, sometimes false = sat), which makes sense for quickcheck-type properties.
2019-04-11SMT: Fixes for more cheri compressed cap propertiesAlasdair
2019-04-10SMT: More builtins and testsAlasdair Armstrong
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: Refactor Jib values to make inlining workAlasdair Armstrong
Had to change the hundreds and hundreds of places such values were used. However this now lets us automatically prove cheri-concentrate properties. Such as showing function prop_cap_round_trip(cap: bits(128)) -> bool = { let cap_rt = capToBits(capBitsToCapability(true, cap)); cap == cap_rt } is always true.
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.
2019-04-06Various bugfixes and improvementsAlasdair
- Rename DeIid to Operator. It corresponds to operator <string> in the syntax. The previous name is from when it was called deinfix in sail1. - Removed things that weren't actually common from pretty_print_common.ml, e.g. printing identifiers is backend specific. The doc_id function here was only used for a very specific use case in pretty_print_lem, so I simplified it and renamed it to doc_sia_id, as it is always used for a SIA.Id whatever that is. - There is some support for anonymous records in constructors, e.g. union Foo ('a : Type) = { MkFoo : { field1 : 'a, field2 : int } } somewhat similar to the enum syntax in Rust. I'm not sure when this was added, but there were a few odd things about it. It was desugared in the preprocessor, rather than initial_check, and the desugaring generated incorrect code for polymorphic anonymous records as above. I moved the code to initial_check, so the pre-processor now just deals with pre-processor things and not generating types, and I fixed the code to work with polymorphic types. This revealed some issues in the C backend w.r.t. polymorphic structs, which is the bulk of this commit. I also added some tests for this feature. - OCaml backend can now generate a valid string_of function for polymorphic structs, previously this would cause the ocaml to fail to compile. - Some cleanup in the Sail ott definition - Add support for E_var in interpreter previously this would just cause the interpreter to fail
2019-04-05Coq: termination measures for mutually recursive functionsBrian Campbell
2019-04-05Fix: Don't remove uncalled polymorphic constructors if they are matched uponAlasdair Armstrong
Previously the specialization would remove any polymorphic union constructor that was never created anywhere in the specification. While this wasn't usually problematic, it does leave an edge case where such a constructor could be matched upon in a pattern, and then the resulting match would fail to compile as it would be matching on a constructor kind that doesn't exists. This should fix that issue by chaging the V_ctor_kind value into an F_ctor_kind fragment. Previously a polymorphic constructor-kind would have been represented by its mangled name, e.g. V_ctor_kind "zSome_unit" would now be represented as V_ctor_kind ("Some", unifiers, ty) where ty is a monomorphic version of the original constructor's type such that ctyp_unify original_ty ty = unifiers and the mangled name we generate is zencode_string ("Some_" ^ string_of_list "_" string_of_ctyp unifiers)
2019-04-05Coq: add missing effectful existential unpacking caseBrian Campbell
2019-04-05Lem: Make generated assertion messages look nicer in prover outputAlasdair
Add a new short_loc_to_string function that produces just the file and line number as a single line. loc_to_string adds a bunch of terminal color codes and other formatting designed for producing pretty error-messages in the terminal, which isn't ideal when the string appears in prover output as part of an assert statement. This is should be purely an aesthetic change.
2019-04-04Coq: correct projection in plain monadic and/orBrian Campbell
2019-04-04Typecheck: Improve typechecking for constructors with tuple typesAlasdair
2019-04-02Coq: replace n_constraints with equivalent bool variablesBrian Campbell
Prevents some type variables that came from unpacking existentials leaking into generated Coq types.
2019-04-01C: Fix end instr usage in jib_optimizeAlasdair Armstrong
2019-04-01C: Add identifier to end instructionAlasdair
Allows us to track the last version of the return variable when the AST in in SSA form.
2019-03-27C: Generate C from sliced specificationsAlasdair Armstrong
2019-03-27Interactive: Refactor sail.ml some moreAlasdair Armstrong
Separate calling the rewriter from the backend-specific parts of sail.ml
2019-03-27Interactive: Refactor sail.mlAlasdair Armstrong
Rather than having a separate variable for each backend X, opt_print_X, just have a single variable opt_print_target, where target contains a string option, such as `Some "lem"` or `Some "ocaml"`, then we have a function target that takes that string and invokes the appropriate backend, so the main function in sail.ml goes from being a giant if-then-else block to a single call to target !opt_target ast env This allows us to implement a :compile <target> command in the interactive toplevel Also implement a :rewrites <target> command which performs all the rewrites for a specific target, so rather than doing e.g. > sail -c -O -o out $FILES one could instead interactively do > sail -i :option -undefined_gen :load $FILES :option -O :option -o out :rewrites c :compile c :quit for the same result. To support this the behavior of the interactive mode has changed slightly. It no longer performs any rewrites at all, so a :rewrites interpreter is currently needed to interpret functions in the interactive toplevel, nor does it automatically set any other flags, so -undefined_gen is needed in this case, which is usually implied by the -c flag.
2019-03-27Rewriter: Finish refactoring rewrite sequencesAlasdair Armstrong
2019-03-26Rewriter: Expose rewrite passes to interactive modeAlasdair Armstrong
Rather than each rewrite being an opaque function, with separate lists of rewrites for each backend, instead put all the rewrites into a single list then have each backend define which of those rewrites it wants to use and in what order. For example, rather than having let rewrite_defs_ocaml = [ ... ("rewrite_undefined", rewrite_undefined_if_gen false); ... ] we would now have let all_rewrites = [ ... ("undefined", Bool_rewriter (fun b -> Basic_rewriter (rewrite_undefined_if_gen b))); ... ] let rewriters_ocaml = [ ... ("undefined", [Bool_arg false]); ... ] let rewrite_defs_ocaml = List.map (fun (name, args) -> (name, instantiate_rewrite (List.assoc name all_rewrites) args)) rewriters_ocaml This means we can introspect on the arguments required for each rewrite, allowing a :rewrite command in the interactive mode which can parse the arguments required for each rewrite, so we can invoke the above rewrite as sail> :rewrite undefined false with completion for the rewrite name based on all_rewrites, and hints for any arguments. The idea behind this is if we want to generate a very custom slice of a specification, we can set it up as a sequence of interpreter commands, e.g. ... :rewrite split execute :slice_roots execute_LOAD :slice_cuts rX wX :slice :rewrite tuple_assignments ... where we slice a spec just after splitting the execute function. This should help in avoiding an endless proliferation of additional options and flags on the command line.
2019-03-26Constant-fold __size calls if possibleThomas Bauereiss
2019-03-26Lem: Work around if-cascade indentation problemThomas Bauereiss
Copied from Coq backend.
2019-03-25Typecheck: Use emod_int/ediv_int in sizeof rewritingAlasdair Armstrong
These are the correct versions for div/mod in the SMT solver
2019-03-22Tidy up of div and mod operators (C implementation was previously ↵Robert Norton
inconsistent with ocaml etc.). Rename div and mod builtins to ediv_int/emod_int and tdiv_int/tmod_int and add corresponding implementations. Add a test with negative operands. This will break existing models but will mean users have to think about which versions they want and won't accidentally use the wrong one.
2019-03-22C: Fix as-patterns in C outputAlasdair Armstrong
Most such patterns are re-written away by various re-writing steps, but for those that arn't they are fairly easy to handle by just having as patterns directly in the ANF-patterns. Fixes #39
2019-03-21Fix: Use doc_binding for printing scattered mapping typesAlasdair Armstrong
Issue with pretty-printing mapping clauses types fixed by both cf7eb8b83 and 0e2f1710a, so remove the redundant clauses. In the parser we allow both ``` | Mapping id { mk_sd (SD_mapping ($2, mk_tannotn)) $startpos $endpos } | Mapping id Colon funcl_typ { mk_sd (SD_mapping ($2, $4)) $startpos $endpos } ``` so we should probably use doc_binding to correctly print any quantifier on the funcl_typ. Although since polymorphism and mappings don't play nicely together right now this likely doesn't occur very often in practice.
2019-03-21Coq: fix bug when multiple type variables map to the same identifierBrian Campbell
2019-03-21Jib: Add types to Phi functionsAlasdair Armstrong
Add a test case to ensure variable types in l-expressions remain the same with flow-sensitive constraints.
2019-03-21Revert some constant propagation experimentationThomas Bauereiss
See comments on e92ff687.
2019-03-21Merge pull request #38 from crabtw/sail2Alasdair Armstrong
Fix scattered mapping printing and output message for missing val spec
2019-03-20Coq: do more (and more uniform) simplificationBrian Campbell
2019-03-20Coq: be more careful about merging Sail variables and type variablesBrian Campbell
In particular, spot variable shadowing and handle (n as 'm) patterns.
2019-03-20Fix scattered mapping printing and output message for missing val specJyun-Yan You
2019-03-19C: Some simplificationAlasdair Armstrong
Remove unused experimental optimizations
2019-03-19Coq: simplify away more trivial boolsBrian Campbell
2019-03-19C: Inlining supportAlasdair Armstrong
Add a function Jib_optimize.inline which can inline functions. To make this more efficient, we can make identifiers unique on a per-function basis.
2019-03-19Coq: more test workBrian Campbell
- add dummy print_bits function - support int(1) like types in axioms