1. 13 Jun, 2017 2 commits
    • Andrei Paskevich's avatar
      WhyML: white-box blocks · 516cfd3a
      Andrei Paskevich authored
      Just as abstract blocks, "white-box blocks" are program expressions
      with an additional contract attached to their execution place.
      Contrary to abstract blocks, whiteboxes do not hide their contents
      from the outer computation. In most cases, you would not need
      whiteboxes at all, as the same effect can be achieved by adding
      assertions. Their utility comes from their syntax: the added
      contract clauses bind to the expression and do not require
      additional semicolons, begin-end's, let-in's or try-with's.
      
      Compare:
      
          let x = <expr> in assert { P x }; x
      to  <expr> ensures { P result }
      or  <expr> returns { x -> P x }
      
          if ... then begin let x = <expr> in assert { P x }; x end; ...
      to  if ... then <expr> ensures { P result }; ...
      
          try <expr> with E x -> assert { P x }; raise E x; end
      to  <expr> raises { E x -> P x }
      
      Internally, whiteboxes are just abstract blocks (zero-argument
      anonymous functions executed in-place) with the label "vc:white_box"
      on top. The user never needs to write this label explicitly though.
      516cfd3a
    • Andrei Paskevich's avatar
      Typing: minor · 65844aa6
      Andrei Paskevich authored
      65844aa6
  2. 11 Jun, 2017 2 commits
    • Andrei Paskevich's avatar
      WhyML: tuple terms/expressions do not require parentheses · a1e032f6
      Andrei Paskevich authored
      This makes the syntax cleaner and brings us closer to OCaml.
      
      One incompatibility with the previous grammar is that "ghost"
      binds stronger than the left arrow of assignment, and thus
      ghost assignments have to be written as "ghost (x.f <- v)".
      
      This is unavoidable, because assignment has to be weaker than
      the tuple comma (think "x.f, y.g <- y.g, x.f" or "a[i] <- u,v"),
      and "ghost" has to be stronger than comma, for consistency with
      our patterns and our return types.
      
      The "return" construction is weaker than comma, for "return a,b".
      It is also weaker than assignment, though "return x.f <- b" does
      not make much sense either way.
      
      This change does not concern type expressions, where a tuple
      type must always have its clothes^Wparentheses on: (int, int).
      It might be nice to write "constant pair: int, bool", but on
      the other hand this would break casts like "42: int, true".
      a1e032f6
    • Andrei Paskevich's avatar
      WhyML: match ... with exception ... end · 6aace661
      Andrei Paskevich authored
      6aace661
  3. 10 Jun, 2017 2 commits
    • Andrei Paskevich's avatar
      37384819
    • Andrei Paskevich's avatar
      Mlw: slightly generalize the rules for overloading · 084211c1
      Andrei Paskevich authored
      A symbol is now considered overloadable if it satisfies
      the following conditions:
        - it has at least one parameter
        - it is non-ghost and has fully visible result
        - all of its parameters are non-ghost and have the same type
        - its result is either of the same type as its parameters
          or it is a monomorphic immutable type.
      
      An overloadable symbol can be combined with other symbols of the
      same arity and overloading kind. Otherwise, the new symbol shadows
      the previously defined ones.
      
      This generalisation allows us to overload symbols such as "size"
      or "length", and also symbols of arbitraty non-zero arity.
      
      I am reluctant to generalize this any further, because then we
      won't have reasonable destructible signatures for type inference.
      084211c1
  4. 09 Jun, 2017 3 commits
  5. 08 Jun, 2017 6 commits
    • Andrei Paskevich's avatar
      WhyML: "{qualid}" for logical symbols and snapshotted variables · a44cccbb
      Andrei Paskevich authored
      x.{f} is allowed and can be used for unary applications
      M.{f} is not allowed, use {M.f} instead
      a44cccbb
    • Andrei Paskevich's avatar
      Mlw: partially revert cda6d915: labels do not define exceptions · 2a794b99
      Andrei Paskevich authored
      It is confusing to use the keyword "label" to define an exception.
      Also, the "label L in ..." binds too far and the break point is
      not clearly defined.
      
      We do need some syntactic sugar for
        exception X t in try <expr> with X r -> r
      (at the very least "break" and "continue"), but labels are not it.
      2a794b99
    • Andrei Paskevich's avatar
      c23ddb9d
    • Andrei Paskevich's avatar
      Mlw: for-loops over range types · 2f7b69b5
      Andrei Paskevich authored
      In the surface language, the loop index is always int in
      the loop invariant and all annotations and pure terms inside
      the loop. If you want to access the original range-typed index,
      use "let copy_i = i in" in the program code before your assertion.
      Of course, you cannot do that for the loop invariant, which is
      what we want.
      2f7b69b5
    • Martin Clochard's avatar
      by/so: moved precedence to the same level as arrow · c8cb2b78
      Martin Clochard authored
        Reason for that change: interpret correctly both
        (1) A by B -> C and (2) A -> B by C
        Case (2) is common, and we expect by to take precendence,
        so that A is the context for the proof of B.
        Case (1) is rarer, and is troublesome if by take precendence
        cause (A by B) -> C is almost certainly not what the user
        intended to write. Putting precendence of by/so at the same level as
        the arrow fix this
      c8cb2b78
    • Andrei Paskevich's avatar
      Parser: recognize negative numerals · fe59898d
      Andrei Paskevich authored
      At this moment, there is no semantics change. This commit only
      provides dedicated grammar rules for negated numerals, so that
      we do not have to recognize them later.
      fe59898d
  6. 06 Jun, 2017 4 commits
  7. 05 Jun, 2017 2 commits
    • Andrei Paskevich's avatar
      Mlw: labels can act as local exceptions · cda6d915
      Andrei Paskevich authored
      Useful to break out of the loops:
      
        label Break in
        while ... do
          label Continue in
          ... raise Break ...
          ... raise Continue ...
        done
      
      When a label is put over a non-unit expression,
      raise acts as return:
      
        label Return in
        if ... then raise Return 42; 0
      
      Also, "return <expr>" returns from the innermost function.
      This includes abstract blocks, too, so if you want to return
      across an abstract block, you should rather use a label at
      the top of the main function. TODO/FIXME: maybe we should
      let "return" pass across abstract blocks by default, to
      avoid surprises?
      
      One shortcoming of the labels-as-exceptions is that they cannot
      be used to transmit tuples with ghost elements, nor return ghost
      values from non-ghost expressions. A local exception with an
      explicit mask should be used instead. Similarly, to return
      a partially ghost value from a function, it must have have
      its mask explicitly written (which is a good practice anyway).
      We cannot know the mask of an expr before we construct it,
      but in order to construct it, we need to create the local
      exceptions first.
      
      Another caveat is that while it is possible to catch an exception
      generated by a label, you should avoid to do so. We only declare
      the local exception if the expression under the label _raises_
      the exception, and thus the following code will not typecheck:
      
        label X in (try raise X with X -> () end)
      
      Indeed, the expression in the parentheses does not raise X,
      and so we do not declare a local exception X for this label,
      and so the program contains an undeclared exception symbol.
      cda6d915
    • Andrei Paskevich's avatar
      Mlw: local exceptions in the surface language · b3a73a61
      Andrei Paskevich authored
      current syntax is
      
          exception Return (int, ghost bool) in
          ...
          try
            ...
            raise Return (5, false)
            ...
          with
            Return (i, b) -> ...
          ...
      
      These exceptions can carry mutable and non-monomorphic values.
      They can be raised from local functions defined in the scope
      of the exception declaration.
      b3a73a61
  8. 04 Jun, 2017 1 commit
  9. 03 Jun, 2017 1 commit
  10. 27 May, 2017 1 commit
    • Andrei Paskevich's avatar
      Mlw: support Epure in the surface language (with type inference) · 72714897
      Andrei Paskevich authored
      The current syntax is "{| <term> |}", which is shorter than
      "pure { <term> }", and does not require a keyword. Better
      alternatives are welcome.
      
      As for type inference, we infer the type pf the term under Epure
      without binding destructible type variables in the program.
      In particular,
        let ghost fn x = {| x + 1 |}
      will not typecheck. Indeed, even if we detect that the result
      is [int], the type of the formal parameter [x[ is not inferred
      in the process, and thus stays at ['xi].
      
      Another problem is related to the fact that variable and function
      namespaces are not yet separated when we perform type inference.
      Thus both fuctions
        let ghost fn (x: int) = let x a = a in {| x + 5 |}
      and
        let ghost fn (x: int) = let x a = a in {| x 5 |}
      will not typecheck, since the type of [x] is ['a -> 'a] when
      we infer the type for the Epure term, but it becomes [int],
      when we construct the final program expression. Probably,
      the only reasonable solution is to keep variables and
      functions in the same namespace, so that [x] simply can
      not be used in annotations after being redefined as a
      program function.
      72714897
  11. 11 May, 2017 2 commits
    • Andrei Paskevich's avatar
      Pdecl: split type declarations in chunks · b6e2a7b6
      Andrei Paskevich authored
      Refinement code requires private types to reside in
      separate program declarations. So we split type decls
      into chunks where all non-free types are declared
      separately and only constructible (Ddata) types are
      kept together. The code preserves the original order
      wherever possible.
      
      Also, export ls_of_rs and fd_of_rs from Expr: these are
      used everywhere in src/mlw anyway.
      
      Also, remove some range/float-related "assert false".
      b6e2a7b6
    • Andrei Paskevich's avatar
      Typing: indentation style · 43694d1b
      Andrei Paskevich authored
      43694d1b
  12. 03 May, 2017 1 commit
  13. 01 May, 2017 1 commit
  14. 28 Apr, 2017 3 commits
  15. 23 Apr, 2017 1 commit
  16. 21 Apr, 2017 1 commit
  17. 12 Apr, 2017 1 commit
  18. 07 Mar, 2017 1 commit
    • Clément Fumex's avatar
      + use literals in ieee_float theory · f88de190
      Clément Fumex authored
      + add 'minInt and 'maxInt attributes for range types
      + add 'eb and 'sb attributes for float types
      + make ieee_float realization compatible with Coq 8.4
      f88de190
  19. 28 Feb, 2017 1 commit
    • Clément Fumex's avatar
      Add the ability to · f0547868
      Clément Fumex authored
      * declare range types and float types,
      * use integer (resp. real) literals for those types through casting,
      * specify how to print them in drivers.
      
      Change in syntax
      * use
      
        type t = < range 1 2 >   (* integers from 1 to 2 *)
        type t' = < float 4 12 > (* float with 4 bits in exponent and 12 in mantissa *)
      
        the two projections :
        t'int
        t''real
      
        and the predicate :
        t''isFinite
      
      * Restrict the use of "'" in whyml:
        Users are not allowed to introduce names where a quote symbol
        is followed by a letter. Thus, the following identifiers are
        valid:
      
        t'
        toto'0''
        toto'_phi
      
        whereas toto'phi is not.
      
      Note: we do not yet support negative numbers in range declaration
      and casting of a literal.
      f0547868
  20. 15 Feb, 2017 2 commits
  21. 14 Feb, 2017 1 commit
  22. 06 Feb, 2017 1 commit