summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2017-11-15Fix atom - range unification againAlasdair Armstrong
2017-11-15Fix rule for allowing atom to unify with rangeAlasdair Armstrong
2017-11-15Allow user defined operations in nexps (experimental)Alasdair Armstrong
There are several key changes here: 1) This commit allows for user defined operations in n-expressions using the Nexp_app constructor. These operations are linked to operators in the SMT solver, by using the smt extern when defining operations. Notably, this allows integer division and modular arithmetic to be used in types. This is best demonstrated with an example: infixl 7 / infixl 7 % val operator / = { smt: "div", ocaml: "quotient" } : forall 'n 'm, 'm != 0. (atom('n), atom('m)) -> {'o, 'o = 'n / 'm. atom('o)} val mod_atom = { smt: "mod", ocaml: "modulus" } : forall 'n 'm. (atom('n), atom('m)) -> {'o, 'o = mod_atom('n, 'm). atom('o)} val "print_int" : (string, int) -> unit overload operator % = mod_atom val main : unit -> unit function main () = { let 'm : {'x, 'x % 3 = 1. atom('x)} = 4; let 'n = m / 3; _prove(constraint(('m - 1) % 3 = 0)); _prove(constraint('n * 3 + 1 = 'm)); (* let x = 3 / 0; (* Will fail *) *) print_int("n = ", n); () } As can be seen, these nexp ops can be arbitrary user defined operators and even operator overloading works (although there are some caveats). This feature is very experimental, and some things won't work very well once you use custom operators - notably unification. However, this not necissarily a downside, because if restrict yourself to the subset of sail types that correspond to liquid types, then there is never a need to unify n-expressions. Looking further ahead, if we switch to a liquid type system a la minisail, then we no longer need to treat + - and * specially in n-expressions. So possible future refactorings could involve collapsing the Nexp datatype. 2) The typechecker is stricter about valspecs (and other types) being well-formed. This is a breaking change because previously we allowed things like: val f : atom('n) -> atom('n) and now this must be val f : forall 'n. atom('n) -> atom('n) if we want to allow the first syntax, then initial-check should desugar it this way - but it must be well-formed by the time it hits the type-checker, otherwise it's not clear that we do the right thing. Note we can actually have top-level type variables by using top-level let bindings with P_var. There's a future line of refactoring that would make it so that type variables can shadow each other properly (we should do this) - currently they all have to have unique names. 3) atom('n) is no longer syntactic sugar for range('n, 'n). The reason why we want to do this is that if we wanted to be smart about what sail operations can be translated into SMT operations at the type level we care very much that they talk about atoms and not ranges. Why? Because atom is the term level representation of a specific type variable so it's clear how to map between term level functions and type level functions, i.e. (atom('n) -> atom('n)) can be reflected at the type level by a type level function with kind Int -> Int, but the same is not true for range. Furthermore, both are interdefinable as atom('n) -> range('n, 'n) range('n, 'm) -> {'o, 'n <= 'o <= 'm. atom('n)} and I think the second is actually slightly more elegant. This change *should* be backwards compatible, as the type-checker knows how to convert from atom to ranges and unify them with each other, but there may be bugs introduced here...
2017-11-13Record where existentials were created in their names.Alasdair Armstrong
Possibly useful for Brian's monomorphisation code
2017-11-10Fixed ocaml backend so it correctly compiles registers passed by name.Alasdair Armstrong
Added a test case for this behavior
2017-11-10Fixed some tricky typechecking bugsAlasdair Armstrong
2017-11-08Allow functions to be selectively declared external only for some backendsThomas Bauereiss
For example, val test = { ocaml: "test_ocaml" } : unit -> unit will only be external for OCaml. For other backends, it will have to be defined.
2017-11-08Merge branch 'experiments' of https://bitbucket.org/Peter_Sewell/sail into ↵Alasdair Armstrong
experiments
2017-11-08Allow for different extern names for different backendsAlasdair Armstrong
For example: val test = { ocaml: "test_ocaml", lem: "test_lem" } : unit -> unit val main : unit -> unit function main () = { test (); } for a backend not explicitly provided, the extern name would be simply "test" in this case, i.e. the string version of the id. Also fixed some bugs in the ocaml backend.
2017-11-07Fix typo in constraint rewriterThomas Bauereiss
2017-11-07Add builtin for reversing endiannessThomas Bauereiss
2017-11-07Declare prelude functions as externThomas Bauereiss
Also, rename a few functions for uniformity, e.g. bool_and -> and_bool
2017-11-07Fix vector_subrange typoBrian Campbell
2017-11-03Fix ocaml test suiteAlasdair Armstrong
2017-11-03Merge branch 'experiments' of https://bitbucket.org/Peter_Sewell/sail into ↵Alasdair Armstrong
experiments
2017-11-03Fixed a bug where true and false get mixed up in rewriterAlasdair Armstrong
2017-11-03Fix a bug where sail would throw an exception with empty file listAlasdair Armstrong
2017-11-03Make sure simple parameter sizes appear in Lem mwords outputBrian Campbell
2017-11-03Make nexp_simp a little smarterBrian Campbell
2017-11-02Added monomorphism restriction to undefined values.Alasdair Armstrong
What does this mean? Basically undefined values can't be created for types that contain free type variables, so for example: undefined : list(int) is good, but undefined : list('a) is bad. The reason we want to do this is because we can't compile them away statically, and this leads to situations where type-checkable code fails in the rewriter and gives horribly confusing error messages that don't relate to code the user wrote at all. As an example the following used to typecheck, but fail in the rewriter with a confusing error message, whereas now the typechecker should reject all cases which would trigger that failure in rewriting. val test : forall ('a:Type). list('a) -> unit effect {wreg, undef} function test xs = { xs_mut = xs; xs_mut = undefined; (* We don't know what kind of undefined 'a is *) () } There's a slight hitch, namely that in the undefined_type functions created by the -undefined_gen option, we do want to allow functions that have polymorphic undefined values, so that we can generate undefined generators for polymorphic datatypes such as: union option ('a:Type) = { Some : 'a, None } These functions are always have a specific form that allows the rewriter to succesfully remove the polymorphic undefined value for the 'a argument for Sone. As such there's a flag in the typechecking environment for polymorphic undefineds that is enabled when it sees a function with the undefined_ name prefix. Also: Fixed some test cases that were broken due to escape effect being added to assert.
2017-11-02Merge branch 'experiments'Thomas Bauereiss
2017-11-02Fix a few AST and parsing-related bugsThomas Bauereiss
2017-11-02Optionally generate an initial register state for the sequential Lem shallow ↵Thomas Bauereiss
embedding Checks for command-line flag -undefined_gen and uses the undefined value generator functions of the form undefined_typ to initialise registers
2017-11-02Fix translation of repeat-until loops to LemThomas Bauereiss
2017-11-02Handle "undefined" type-level sizes in monomorphisationBrian Campbell
2017-11-01Support bitvector-size-parametric functions in Lem outputBrian Campbell
Translates atom('n) types into itself('n) types that won't be erased Also exports more rewriting functions
2017-11-01Fix some missing nexp simplification in Lem outputBrian Campbell
2017-10-31Fixed wrong image for List-remove.svgAlasdair Armstrong
2017-10-31Added trace viewer application for traces produced by sail -ocaml_traceAlasdair Armstrong
See README file for how to set up and use
2017-10-31Improvements to register read tracing in ocaml backendAlasdair Armstrong
2017-10-31Pretty-print Sail assertions in LemThomas Bauereiss
Map to calls to monadic function assert_exp that throws an exception if the assertion is false
2017-10-31Fix bug in topological sorting of val-specsThomas Bauereiss
Put them before the function they declare
2017-10-31Remove redundant nexp simplification functionThomas Bauereiss
2017-10-27Fixed some ocaml backend related bugsAlasdair Armstrong
2017-10-26Merge branch 'experiments' of https://bitbucket.org/Peter_Sewell/sail into ↵Alasdair Armstrong
experiments
2017-10-26Unfold nexp abbreviations for pretty-printingThomas Bauereiss
2017-10-26Update val specs after rewriting functionsThomas Bauereiss
2017-10-26Experiment with pretty-printing non-atomic nexps in LemThomas Bauereiss
2017-10-26Updated ocaml backend so tracing instrumentation is optional.Alasdair Armstrong
Cleaned up the option list in sail.ml
2017-10-25Allow mutually recursive functionsThomas Bauereiss
2017-10-25Point sail/src makefile at ott file in language/Alasdair Armstrong
2017-10-25List.cons is too newBrian Campbell
2017-10-25Merge branch 'experiments' into mono-experimentsBrian Campbell
2017-10-25Generate ast.ml from ott file and update makefile.Alasdair Armstrong
Fix until loop not being counted as sugar
2017-10-25Merge branch 'experiments' into mono-experimentsBrian Campbell
2017-10-25Alternative low-memory version of barrier_kindCompareBrian Campbell
2017-10-25Avoid name clash in generated LemBrian Campbell
(complains due to added val spec)
2017-10-24Make nexp simplifier handle recursion properlyBrian Campbell
2017-10-24More succinct syntax in new parser for externed valspecs which shareAlasdair Armstrong
the same name between sail and the target
2017-10-24Print type annotations in Lem with type variablesBrian Campbell
(includes variables for bitvector sizes)