1. 10 Jan, 2016 1 commit
    • Andrei Paskevich's avatar
      Mlw: allow non-ghost expressions to return (partially) ghost values · 4c79348a
      Andrei Paskevich authored
      this is still work in progress and no testing was done so far.
      
      Highlights of this commit:
      
      - "(ghost 42, 15)" is now a non-ghost expression that can be returned
        from a function and/or matched against a "(ghost x, y)" pattern.
        Only the tuple constructor and direct pattern matching are magical:
        "let z = (ghost 42, 15) in ..." still makes z ghost, and therefore
        "snd (ghost 42, 15)" is ghost, too.
      
      - "if c then e1 else ghost e2" and "let z = e1 in ghost e2" are now
        non-ghost expressions with a ghost result. This means that e1 may
        have visible effects. Of course, if e2 raises exceptions, the whole
        expression is ghostified. Contamination is still done when possible,
        that is, when the contaminated expression has no visible effects.
      
      - "let ghost x = e1 in e2" no longer ghostifies e1.
      
      - "let f (ghost x) = ... in f e1" no longer ghostifies e1.
      
      - new syntax: variables in program patterns may be marked ghost.
        In particular: "let x, ghost y = ...".
      
      - new syntax: the function result type may be written as a partially
        ghost tuple: "val f ... : ghost int" or "any (int, ghost bool)".
        The ghostness annotation is required for top-level and recursive
        functions.
      
      - exceptions can carry partially ghost tuples (API only, WIP)
      4c79348a
  2. 15 Nov, 2015 1 commit
    • Andrei Paskevich's avatar
      Mlw: admit fields with mutable types in private records · f522e56e
      Andrei Paskevich authored
      this should not be problematic as long as these fields do not occur
      in the invariants (actual or refined). In other words, a value of
      a private type exists no matter what is stored in the field.
      
      Also, admit non-private mutable types without actual mutable fields.
      It is actually impossible to create a write effect for such types,
      and the only consequence of being mutable is that they are assigned
      a region, and so every value of such type can be tracked individually.
      One use case for this is a non-private record with an invariant,
      which either has fields with mutable types or has type parameters
      that we wish to instantiate with mutable types. If we modify these
      mutable components, this may break the record's invariant. Now, if
      the record itself is immutable (and thus has no associated region),
      then we must reestablish the invariant immediately, otherwise we
      lose track of the value. Even if this extra flexibility does not
      prove useful in the end, it seems to be harmless.
      
      Also, admit type definitions of the form
        type t 'a = (private|abstract)? mutable? {} invariant*
      which define private empty records (even if not declared private).
      
      Also, "type t 'a" is now equivalent to "type t 'a = private {}".
      f522e56e
  3. 21 Aug, 2015 3 commits
  4. 19 Aug, 2015 1 commit
    • Andrei Paskevich's avatar
      Parser: admit anonymous binders · eaed0078
      Andrei Paskevich authored
      In programs, we do not really care about unnamed typed variables,
      and it is convenient to write ((fun s _ -> s) : int -> bool -> int)
      in logical terms.
      eaed0078
  5. 06 Aug, 2015 2 commits
  6. 30 Jul, 2015 1 commit
  7. 28 Jul, 2015 1 commit
  8. 16 Jul, 2015 2 commits
    • Andrei Paskevich's avatar
      Parser: refactoring · 78683f61
      Andrei Paskevich authored
      78683f61
    • Andrei Paskevich's avatar
      Parser: chained equivalence · 3912a062
      Andrei Paskevich authored
      Translate a chain of equivalences A <-> B <-> C into a conjunction
      (A <-> B) /\ (B <-> C). Implication is weaker than equivalence when
      it occurs to the left of it, and is forbidden at the right hand side.
      In other words, A -> B <-> C <-> D is allowed and translated into
      A -> ((B <-> C) /\ (C <-> D)), and A <-> B -> C is not allowed,
      and requires explicit parentheses.
      3912a062
  9. 15 Jul, 2015 1 commit
    • Andrei Paskevich's avatar
      Parser: relation chaining is guided by the operator group · c67b99bd
      Andrei Paskevich authored
      All infix operations in the weakest priority group (those containing
      at least one of the characters '=', '<', '>', or '~') are considered
      non-associative and the chains (t1 OP t2 OP t3) are translated into
      conjunctions (t1 OP t2 /\ t2 OP t3).
      
      This does not concern implication '->' and equivalence '<->'
      which are right-associative. like the rest of propositional
      connectives.
      c67b99bd
  10. 02 Jul, 2015 2 commits
  11. 27 Jun, 2015 4 commits
  12. 24 Jun, 2015 2 commits
  13. 27 Apr, 2015 1 commit
  14. 21 Mar, 2015 1 commit
  15. 20 Mar, 2015 1 commit
  16. 19 Mar, 2015 1 commit
  17. 05 Jan, 2015 1 commit
  18. 25 Oct, 2014 1 commit
  19. 22 Oct, 2014 1 commit
  20. 20 Sep, 2014 2 commits
  21. 07 Apr, 2014 1 commit
  22. 14 Mar, 2014 1 commit
  23. 05 Mar, 2014 1 commit
  24. 17 Feb, 2014 1 commit
  25. 16 Feb, 2014 1 commit
  26. 14 Feb, 2014 3 commits
    • Andrei Paskevich's avatar
      WhyML: change the syntax of "abstract" · 4fd8b24d
      Andrei Paskevich authored
      The old syntax:   abstract expr [spec]...
      
      The semicolon binds more loosely than "abstract" and
      the specification clauses are optional, so that
      "abstract e1; e2" is the same as "(abstract e1); e2"
      and "abstract e1; e2; ensures {...}" is a syntax error.
      
      The new syntax:   abstract [spec]... expr end
      
      This allows to put sequences of expressions under "abstract"
      without ambiguity and moves the specification clauses to the
      beginning. In other words, "abstract" becomes a "begin" with
      a specification attached. The spec-at-the-top is consistent
      with the syntax of functions and the whole seems to be more
      natural for the intented use of "abstract" (a logical cut).
      4fd8b24d
    • Andrei Paskevich's avatar
      WhyML: admit terminating semi-colons when there is no ambiguity · e66e2a3f
      Andrei Paskevich authored
      Examples:
      
        begin ... expr; end
      
        let fn x y = ... expr ; in ...
      
        match ... with pat -> ... expr ; | pat -> ... expr ; end
      
      In this way, it's much easier to add and remove additional
      assertions at the end of ()-typed blocks.
      e66e2a3f
    • Andrei Paskevich's avatar
      0931fc96
  27. 12 Feb, 2014 1 commit
  28. 20 Jan, 2014 1 commit
    • Andrei Paskevich's avatar
      WhyML: add "diverges", "reads {}", and "writes {}" effect clauses · 83858597
      Andrei Paskevich authored
      - "diverges" states that the computation may not terminate (which
        does not mean that is always diverges: just as any other effect
        annotation, this clause states a possibility of a side effect).
      
      - "reads {}" states that the computation does not access any variable
        except those that are listed elsewhere in the specification (or the
        proper function arguments, if "reads" is in a function spec).
      
      - "writes {}" states that the computation does not modify any mutable
        value.
      
      - If a function definition or an abstract computation may diverge,
        but there is no "diverges" clause in the specification, a warning
        is produced. If a function definition or an abstract computation
        always terminates, but there is a "diverges" clause in the spec,
        an error is produced.
      
      - If there is a "reads" or a "writes" clause in a function definition
        or an abstract computation, then every modified value must be listed
        in "writes" and every accessed external variable not mentioned in
        the spec must be listed in "reads". (Notice that this is a stricter
        requirement than before, when the presence of a "writes" clause
        did not require to specify "reads".) However, one does not have to
        write "reads {}" or "writes {}" if the corresponding lists are empty.
      83858597