1 The WhyML Language Reference
2 ============================
4 In this chapter, we describe the syntax and semantics of WhyML.
9 Blank characters are space, horizontal tab, carriage return, and line
10 feed. Blanks separate lexemes but are otherwise ignored. Comments are
11 enclosed by ``(*`` and ``*)`` and can be nested. Note that ``(*)`` does
14 Strings are enclosed in double quotes (``"``). The backslash character
15 ``\``, is used for escaping purposes. The following
16 escape sequences are allowed:
18 - ``\`` followed by a *new line* allows for
19 multi-line strings. The leading spaces immediately after the new
21 - ``\\`` and ``\"`` for the backslash and double quote respectively.
23 ``\t`` for the new line feed, carriage return,
24 and horizontal tab character.
25 - ``\DDD``, ``\oOOO``, and
26 ``\xXX``, where ``DDD`` is a decimal value
27 in the interval 0-255, ``OOO`` an octal value in the
28 interval 0-377, and ``XX`` an hexadecimal value.
29 Sequences of this form can be used to encode Unicode characters, in
30 particular non printable ASCII characters.
31 - any other escape sequence results in a parsing error.
33 The syntax for numerical constants is given by the following rules:
37 hex_digit: "0" - "9" | "a" - "f" | "A" - "F"
40 integer: `digit` (`digit` | "_")*
41 : | ("0x" | "0X") `hex_digit` (`hex_digit` | "_")*
42 : | ("0o" | "0O") `oct_digit` (`oct_digit` | "_")*
43 : | ("0b" | "0B") `bin_digit` (`bin_digit` | "_")*
44 real: `digit`+ `exponent`
45 : | `digit`+ "." `digit`* `exponent`?
46 : | `digit`* "." `digit`+ `exponent`?
47 : | ("0x" | "0X") `hex_digit`+ `h_exponent`
48 : | ("0x" | "0X") `hex_digit`+ "." `hex_digit`* `h_exponent`?
49 : | ("0x" | "0X") `hex_digit`* "." `hex_digit`+ `h_exponent`?
50 exponent: ("e" | "E") ("-" | "+")? `digit`+
51 h_exponent: ("p" | "P") ("-" | "+")? `digit`+
52 char: "a" - "z" | "A" - "Z" | "0" - "9"
53 : | " " | "!" | "#" | "$" | "%" | "&" | "'" | "("
54 : | ")" | "*" | "+" | "," | "-" | "." | "/" | ":"
55 : | ";" | "<" | "=" | ">" | "?" | "@" | "[" | "]"
56 : | "^" | "_" | "`" | "\\" | "\n" | "\r" | "\t" | '\"'
57 : | "\" ("0" | "1") `digit` `digit`
58 : | "\" "2" ("0" - "4") `digit`
59 : | "\" "2" "5" ("0" - "5")
60 : | "\x" `hex_digit` `hex_digit`
61 : | "\o" ("0" - "3" ) `oct_digit` `oct_digit`
62 string: '"' `char`* '"'
65 Integer and real constants have arbitrary precision. Integer constants
66 can be given in base 10, 16, 8 or 2. Real constants can be given in
67 base 10 or 16. Notice that the exponent in hexadecimal real constants
68 is written in base 10.
70 Identifiers are composed of letters, digits, underscores, and primes.
71 The syntax distinguishes identifiers that start with a lowercase letter
72 or an underscore (:token:`lident_nq`), identifiers that start with an
73 uppercase letter (:token:`uident_nq`), and identifiers that start with
74 a prime (:token:`qident`, used exclusively for type variables):
77 alpha: "a" - "z" | "A" - "Z"
78 suffix: (`alpha` | "'"* ("0" - "9" | "_")*)* "'"*
79 lident_nq: ("a" - "z") `suffix`* | "_" `suffix`+
80 uident_nq: ("A" - "Z") `suffix`*
81 ident_nq: `lident_nq` | `uident_nq`
82 qident: "'" ("a" - "z") `suffix`*
85 Identifiers that contain a prime followed by a letter, such as
86 ``int32'max``, are reserved for symbols introduced by Why3 and cannot be
87 used for user-defined symbols.
90 lident: `lident_nq` ("'" `alpha` `suffix`)*
91 uident: `lident_nq` ("'" `alpha` `suffix`)*
92 ident: `lident` | `uident`
94 In order to refer to symbols introduced in different namespaces
95 (*scopes*), we can put a dot-separated “qualifier prefix” in front of an
96 identifier (e.g., ``Map.S.get``). This allows us to use the symbol
97 ``get`` from the scope ``Map.S`` without importing it in the current
101 qualifier: (`uident` ".")+
102 lqualid: `qualifier`? `lident`
103 uqualid: `qualifier`? `uident`
106 All parenthesised expressions in WhyML (types, patterns, logical terms,
107 program expressions) admit a qualifier before the opening parenthesis,
108 e.g., ``Map.S.(get m i)``. This imports the indicated scope into the
109 current namespace during the parsing of the expression under the
110 qualifier. For the sake of convenience, the parentheses can be omitted
111 when the expression itself is enclosed in parentheses, square brackets
114 Prefix and infix operators are built from characters organized in four
115 precedence groups (:token:`op_char_1` to :token:`op_char_4`), with optional primes at
119 op_char_1: "=" | "<" | ">" | "~"
121 op_char_3: "*" | "/" | "\" | "%"
122 op_char_4: "!" | "$" | "&" | "?" | "@" | "^" | "." | ":" | "|" | "#"
123 op_char_1234: `op_char_1` | `op_char_2` | `op_char_3` | `op_char_4`
124 op_char_234: `op_char_2` | `op_char_3` | `op_char_4`
125 op_char_34: `op_char_3` | `op_char_4`
126 infix_op_1: `op_char_1234`* `op_char_1` `op_char_1234`* "'"*
127 infix_op_2: `op_char_234`* `op_char_2` `op_char_234`* "'"*
128 infix_op_3: `op_char_34`* `op_char_3` `op_char_34`* "'"*
129 infix_op_4: `op_char_4`+ "'"*
130 prefix_op: `op_char_1234`+ "'"*
131 tight_op: ("!" | "?") `op_char_4`* "'"*
134 Infix operators from a high-numbered group bind stronger than the infix
135 operators from a low-numbered group. For example, infix operator ``.*.``
136 from group 3 would have a higher precedence than infix operator ``->-``
137 from group 1. Prefix operators always bind stronger than infix
138 operators. The so-called “tight operators” are prefix operators that
139 have even higher precedence than the juxtaposition (application)
140 operator, allowing us to write expressions like ``inv !x`` without
143 Finally, any identifier, term, formula, or expression in a
144 WhyML source can be tagged either with a string :token:`attribute` or a
148 attribute: "[@" ... "]"
149 : | "[#" `string` `digit`+ `digit`+ `digit`+ "]"
152 An attribute cannot contain newlines or closing square brackets; leading
153 and trailing spaces are ignored. A location consists of a file name in
154 double quotes, a line number, and starting and ending character
160 WhyML features an ML-style type system with polymorphic types, variants
161 (sum types), and records that can have mutable fields. The syntax for
162 type expressions is the following:
165 type: `lqualid` `type_arg`+ ; polymorphic type symbol
166 : | `type` "->" `type` ; mapping type (right-associative)
168 type_arg: `lqualid` ; monomorphic type symbol (sort)
169 : | `qident` ; type variable
171 : | "(" `type` ("," `type`)+ ")" ; tuple type
172 : | "{" `type` "}" ; snapshot type
173 : | `qualifier`? "(" `type` ")" ; type in a scope
175 .. index:: mapping type
177 Built-in types are ``int`` (arbitrary precision integers), ``real``
178 (real numbers), ``bool``, the arrow type (also called the *mapping
179 type*), and the tuple types. The empty tuple type is also called the
180 *unit type* and can be written as ``unit``.
182 Note that the syntax for type expressions notably differs from the usual
183 ML syntax. In particular, the type of polymorphic lists is written
184 ``list 'a``, and not ``'a list``.
186 .. index:: snapshot type
188 *Snapshot types* are specific to WhyML, they denote the types of ghost
189 values produced by pure logical functions in WhyML programs. A snapshot
190 of an immutable type is the type itself; thus, ``{int}`` is the same as
191 ``int`` and ``{list 'a}`` is the same as ``list 'a``. A snapshot of a
192 mutable type, however, represents a snapshot value which cannot be
193 modified anymore. Thus, a snapshot array ``a`` of type ``{array int}``
194 can be read from (``a[42]`` is accepted) but not written into
195 (``a[42] <- 0`` is rejected). Generally speaking, a program function
196 that expects an argument of a mutable type will accept an argument of
197 the corresponding snapshot type as long as it is not modified by the
203 A significant part of a typical WhyML source file is occupied by
204 non-executable logical content intended for specification and proof:
205 function contracts, assertions, definitions of logical functions and
206 predicates, axioms, lemmas, etc.
212 Logical expressions are called *terms*. Boolean terms are called
213 *formulas*. Internally, Why3 distinguishes the proper formulas (produced
214 by predicate symbols, propositional connectives and quantifiers) and the
215 terms of type ``bool`` (produced by Boolean variables and logical
216 functions that return ``bool``). However, this distinction is not
217 enforced on the syntactical level, and Why3 will perform the necessary
218 conversions behind the scenes.
220 The syntax of WhyML terms is given in :token:`term`.
224 term0: `integer` ; integer constant
225 : | `real` ; real constant
226 : | "true" | "false" ; Boolean constant
227 : | "()" ; empty tuple
228 : | `string` ; string constant
229 : | `qualid` ; qualified identifier
230 : | `qualifier`? "(" `term` ")" ; term in a scope
231 : | `qualifier`? "begin" `term` "end" ; idem
232 : | `tight_op` `term` ; tight operator
233 : | "{" `term_field`+ "}" ; record
234 : | "{" `term` "with" `term_field`+ "}" ; record update
235 : | `term` "." `lqualid` ; record field access
236 : | `term` "[" `term` "]" "'"* ; collection access
237 : | `term` "[" `term` "<-" `term` "]" "'"* ; collection update
238 : | `term` "[" `term` ".." `term` "]" "'"* ; collection slice
239 : | `term` "[" `term` ".." "]" "'"* ; right-open slice
240 : | `term` "[" ".." `term` "]" "'"* ; left-open slice
241 : | "[|" (`term` "=>" `term` ";")* ("_" "=>" `term`)? "|]" ; function literal
242 : | "[|" (`term` ";")+ "|]" ; function literal (domain over nat)
243 : | `term` `term`+ ; application
244 : | `prefix_op` `term` ; prefix operator
245 : | `term` `infix_op_4` `term` ; infix operator 4
246 : | `term` `infix_op_3` `term` ; infix operator 3
247 : | `term` `infix_op_2` `term` ; infix operator 2
248 : | `term` "at" `uident` ; past value
249 : | "old" `term` ; initial value
250 : | `term` `infix_op_1` `term` ; infix operator 1
251 : | "not" `term` ; negation
252 : | `term` "/\" `term` ; conjunction
253 : | `term` "&&" `term` ; asymmetric conjunction
254 : | `term` "\/" `term` ; disjunction
255 : | `term` "||" `term` ; asymmetric disjunction
256 : | `term` "by" `term` ; proof indication
257 : | `term` "so" `term` ; consequence indication
258 : | `term` "->" `term` ; implication
259 : | `term` "<->" `term` ; equivalence
260 : | `term` ":" `type` ; type cast
261 : | `attribute`+ `term` ; attributes
262 : | `term` ("," `term`)+ ; tuple
263 : | `quantifier` `quant_vars` `triggers`? "." `term` ; quantifier
264 : | ... ; (to be continued in `term`)
265 formula: `term` ; no distinction as far as syntax is concerned
266 term_field: `lqualid` "=" `term` ";" ; field = value
267 qualid: `qualifier`? (`lident_ext` | `uident`) ; qualified identifier
268 lident_ext: `lident` ; lowercase identifier
269 : | "(" `ident_op` ")" ; operator identifier
270 : | "(" `ident_op` ")" ("_" | "'") alpha suffix* ; associated identifier
271 ident_op: `infix_op_1` ; infix operator 1
272 : | `infix_op_2` ; infix operator 2
273 : | `infix_op_3` ; infix operator 3
274 : | `infix_op_4` ; infix operator 4
275 : | `prefix_op` "_" ; prefix operator
276 : | `tight_op` "_"? ; tight operator
277 : | "[" "]" "'" * ; collection access
278 : | "[" "<-" "]" "'"* ; collection update
279 : | "[" "]" "'"* "<-" ; in-place update
280 : | "[" ".." "]" "'"* ; collection slice
281 : | "[" "_" ".." "]" "'"* ; right-open slice
282 : | "[" ".." "_" "]" "'"* ; left-open slice
283 quantifier: "forall" | "exists"
284 quant_vars: `quant_cast` ("," `quant_cast`)*
285 quant_cast: `binder`+ (":" `type`)?
286 binder: "_" | `bound_var`
287 bound_var: `lident` `attribute`*
288 triggers: "[" `trigger` ("|" `trigger`)* "]"
289 trigger: `term` ("," `term`)*
293 constructs have the following priorities and associativities, from
294 lowest to greatest priority:
296 +------------------------------------+-----------------+
297 | construct | associativity |
298 +====================================+=================+
299 | ``if then else`` / ``let in`` | – |
300 +------------------------------------+-----------------+
302 +------------------------------------+-----------------+
304 +------------------------------------+-----------------+
305 | ``->`` / ``<->`` / ``by`` / ``so`` | right |
306 +------------------------------------+-----------------+
307 | ``\/`` / ``||`` | right |
308 +------------------------------------+-----------------+
309 | ``/\`` / ``&&`` | right |
310 +------------------------------------+-----------------+
312 +------------------------------------+-----------------+
313 | infix-op level 1 | right |
314 +------------------------------------+-----------------+
315 | ``at`` / ``old`` | – |
316 +------------------------------------+-----------------+
317 | infix-op level 2 | left |
318 +------------------------------------+-----------------+
319 | infix-op level 3 | left |
320 +------------------------------------+-----------------+
321 | infix-op level 4 | left |
322 +------------------------------------+-----------------+
324 +------------------------------------+-----------------+
325 | function application | left |
326 +------------------------------------+-----------------+
327 | brackets / ternary brackets | – |
328 +------------------------------------+-----------------+
330 +------------------------------------+-----------------+
332 For example, as was mentioned above,
333 tight operators have the highest precedence of all operators, so that
334 ``-p.x`` denotes the negation of the record field ``p.x``, whereas
335 ``!p.x`` denotes the field ``x`` of a record stored in the reference
338 Infix operators from groups 2-4 are left-associative. Infix operators
339 from group 1 are right-associative and can be chained. For example, the
340 term ``0 <= i < j < length a`` is parsed as the conjunction of three
341 inequalities ``0 <= i``, ``i < j``, and ``j < length a``.
342 Note that infix symbols of level 1 include equality (``=``) and
343 disequality (``<>``).
345 An operator in parentheses acts as an identifier referring to that
346 operator, for example, in a definition. To distinguish between prefix
347 and infix operators, an underscore symbol is appended at the end: for
348 example, ``(-)`` refers to the binary subtraction and ``(-_)`` to the
349 unary negation. Tight operators cannot be used as infix operators, and
350 thus do not require disambiguation.
352 As with normal identifiers, we can put a qualifier over a parenthesised
353 operator, e.g., ``Map.S.([]) m i``. Also, as noted above, a qualifier
354 can be put over a parenthesised term, and the parentheses can be omitted
355 if the term is a record or a record update.
357 Note the curryfied syntax for function application, though partial
358 application is not allowed (rejected at typing).
360 .. _rubric.collections_syntax:
362 .. index:: bracket; syntax
363 .. index:: collections; syntax; function literals
365 Specific syntax for collections
366 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
368 In addition to prefix and infix operators, WhyML supports several mixfix
369 bracket operators to manipulate various collection types: dictionaries,
370 arrays, sequences, etc.
372 Bracket operators do not have any predefined
373 meaning and may be used to denote access and update operations for
374 various user-defined collection types. We can introduce multiple bracket
375 operations in the same scope by disambiguating them with primes after
376 the closing bracket: for example, ``a[i]`` may denote array access and
377 ``s[i]'`` sequence access. Notice that the in-place update operator
378 ``a[i] <- v`` cannot be used inside logical terms: all effectful
379 operations are restricted to program expressions. To represent the
380 result of a collection update, we should use a pure logical update
381 operator ``a[i <- v]`` instead. WhyML supports “associated” names for
382 operators, obtained by adding a suffix after the parenthesised operator
383 name. For example, an axiom that represents the specification of the
384 infix operator ``(+)`` may be called ``(+)'spec`` or ``(+)_spec``. As
385 with normal identifiers, names with a letter after a prime, such as
386 ``(+)'spec``, can only be introduced by Why3, and not by the user in a
389 WhyML provides a special syntax for `function literals`. The term
390 ``[|t1 => u1; ...; tn => un; _ => default|]``, where ``t1, ..., tn``
391 have some type ``t`` and ``u1, ..., un, default`` some type ``u``,
392 represents a total function of the form ``fun x -> if x = t1 then u1
393 else if ... else if x = tn then un else default``. The default value
394 can be omitted in which case the last value will be taken as the
395 default value. For instance, the function literal ``[|t1 => u1|]``
396 represents the term ``fun x -> if x = t1 then u1 else u1``. When the
397 domain of the function ranges over an initial sequence of the natural
398 numbers it is possible to write ``[|t1;t2;t3|]`` as a shortcut for
399 ``[|0 => t1; 1 => t2; 2 => t3|]``. Function literals cannot be empty.
401 .. index:: at; syntax
402 .. index:: old; syntax
404 The "at" and "old" operators
405 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
407 The ``at`` and ``old`` operators are used inside postconditions and
408 assertions to refer to the value of a mutable program variable at some
409 past moment of execution (see the next section for details). These
410 operators have higher precedence than the infix operators from group 1
411 (:token:`infix_op_1`): ``old i > j`` is parsed as ``(old i) > j`` and not as
414 .. index:: &&, ||, by, so
416 Non-standard connectives
417 ^^^^^^^^^^^^^^^^^^^^^^^^
419 The propositional connectives in WhyML formulas are listed in
420 :token:`term`. The non-standard connectives — asymmetric
421 conjunction (``&&``), asymmetric disjunction (``||``), proof indication
422 (``by``), and consequence indication (``so``) — are used to control the
423 goal-splitting transformations of Why3 and provide integrated proofs for
424 WhyML assertions, postconditions, lemmas, etc. The semantics of these
425 connectives follows the rules below:
427 - A proof task for ``A && B`` is split into separate tasks for ``A``
428 and ``A -> B``. If ``A && B`` occurs as a premise, it behaves as a
431 - A case analysis over ``A || B`` is split into disjoint cases ``A``
432 and ``not A /\ B``. If ``A || B`` occurs as a goal, it behaves as a
435 - An occurrence of ``A by B`` generates a side condition ``B -> A``
436 (the proof justifies the affirmation). When ``A by B`` occurs as a
437 premise, it is reduced to ``A`` (the proof is discarded). When
438 ``A by B`` occurs as a goal, it is reduced to ``B`` (the proof is
441 - An occurrence of ``A so B`` generates a side condition ``A -> B``
442 (the premise justifies the conclusion). When ``A so B`` occurs as a
443 premise, it is reduced to the conjunction (we use both the premise
444 and the conclusion). When ``A so B`` occurs as a goal, it is reduced
445 to ``A`` (the premise is verified).
447 For example, full splitting of the goal
448 ``(A by (exists x. B so C)) && D`` produces four subgoals:
449 ``exists x. B`` (the premise is verified), ``forall x. B -> C`` (the
450 premise justifies the conclusion), ``(exists x. B /\ C) -> A`` (the
451 proof justifies the affirmation), and finally, ``A -> D`` (the proof of
452 ``A`` is discarded and ``A`` is used to prove ``D``).
454 The behavior of the splitting transformations is further controlled by
455 attributes :why3:attribute:`[@stop_split]` and :why3:attribute:`[@case_split]`.
456 Consult the documentation
457 of transformation :why3:transform:`split_goal` in
458 :numref:`sec.transformations` for details.
460 Among the propositional connectives, ``not`` has the highest precedence,
461 ``&&`` has the same precedence as ``/\`` (weaker than negation), ``||``
462 has the same precedence as ``\/`` (weaker than conjunction), ``by``,
463 ``so``, ``->``, and ``<->`` all have the same precedence (weaker than
464 disjunction). All binary connectives except equivalence are
465 right-associative. Equivalence is non-associative and is chained
466 instead: ``A <-> B <-> C`` is transformed into a conjunction of
467 ``A <-> B`` and ``B <-> C``. To reduce ambiguity, WhyML forbids to place
468 a non-parenthesised implication at the right-hand side of an
469 equivalence: ``A <-> B -> C`` is rejected.
471 .. index:: conditionals; syntax
472 .. index:: let; syntax
473 .. index:: pattern-matching; syntax
475 Conditionals, "let" bindings and pattern-matching
476 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
480 : | "if" `term` "then" `term` "else" `term` ; conditional
481 : | "match" `term` "with" `term_case`+ "end" ; pattern matching
482 : | "let" `pattern` "=" `term` "in" `term` ; let-binding
483 : | "let" `symbol` `param`+ "=" `term` "in" `term` ; mapping definition
484 : | "fun" `param`+ "->" `term` ; unnamed mapping
485 term_case: "|" `pattern` "->" `term`
486 pattern: `binder` ; variable or "_"
487 : | "()" ; empty tuple
488 : | "{" (`lqualid` "=" `pattern` ";")+ "}" ; record pattern
489 : | `uqualid` `pattern`* ; constructor
490 : | "ghost" `pattern` ; ghost sub-pattern
491 : | `pattern` "as" "ghost"? `bound_var` ; named sub-pattern
492 : | `pattern` "," `pattern` ; tuple pattern
493 : | `pattern` "|" `pattern` ; "or" pattern
494 : | `qualifier`? "(" `pattern` ")" ; pattern in a scope
495 symbol: `lident_ext` `attribute`* ; user-defined symbol
496 param: `type_arg` ; unnamed typed
497 : | `binder` ; (un)named untyped
498 : | "(" "ghost"? `type` ")" ; unnamed typed
499 : | "(" "ghost"? `binder` ")" ; (un)named untyped
500 : | "(" "ghost"? `binder`+ ":" `type` ")" ; multi-variable typed
502 Above, we find the more advanced term constructions:
503 conditionals, let-bindings, pattern matching, and local function
504 definitions, either via the ``let-in`` construction or the ``fun``
505 keyword. The pure logical functions defined in this way are called
506 *mappings*; they are first-class values of “arrow” type
509 The patterns are similar to those of OCaml, though the ``when`` clauses
510 and numerical constants are not supported. Unlike in OCaml, ``as`` binds
511 stronger than the comma: in the pattern ``(p,q as x)``, variable
512 ``x`` is bound to the value matched by pattern ``q``. Also notice
513 the closing ``end`` after the ``match with`` term. A ``let in``
514 construction with a non-trivial pattern is translated as a
515 ``match with`` term with a single branch.
517 Inside logical terms, pattern matching must be exhaustive: WhyML rejects
518 a term like ``let Some x = o in e``, where ``o`` is a variable of an
519 option type. In program expressions, non-exhaustive pattern matching is
520 accepted and a proof obligation is generated to show that the values not
521 covered cannot occur in execution.
523 The syntax of parameters in user-defined operations—first-class
524 mappings, top-level logical functions and predicates, and program
525 functions—is rather flexible in WhyML. Like in OCaml, the user can
526 specify the name of a parameter without its type and let the type be
527 inferred from the definition. Unlike in OCaml, the user can also specify
528 the type of the parameter without giving its name. This is convenient
529 when the symbol declaration does not provide the actual definition or
530 specification of the symbol, and thus only the type signature is of
531 relevance. For example, one can declare an abstract binary function that
532 adds an element to a set simply by writing
533 ``function add 'a (set 'a): set 'a``. A standalone non-qualified
534 lowercase identifier without attributes is treated as a type name when
535 the definition is not provided, and as a parameter name otherwise.
537 Ghost patterns, ghost variables after ``as``, and ghost parameters in
538 function definitions are only used in program code, and not allowed in
544 The syntax of program expressions is given below. As before, the constructions
545 are listed in the order of decreasing precedence. The rules for tight,
546 prefix, infix, and bracket operators are the same as for logical terms.
547 In particular, the infix operators from group 1 (:token:`infix_op_1`) can be chained. Notice
548 that binary operators ``&&`` and ``||`` denote here the usual lazy
549 conjunction and disjunction, respectively.
552 expr: `integer` ; integer constant
553 : | `real` ; real constant
554 : | "true" | "false" ; Boolean constant
555 : | "()" ; empty tuple
556 : | `string` ; string constant
557 : | `qualid` ; identifier in a scope
558 : | `qualifier`? "(" `expr` ")" ; expression in a scope
559 : | `qualifier`? "begin" `expr` "end" ; idem
560 : | `tight_op` `expr` ; tight operator
561 : | "{" (`lqualid` "=" `expr` ";")+ "}" ; record
562 : | "{" `expr` "with" (`lqualid` "=" `expr` ";")+ "}" ; record update
563 : | `expr` "." `lqualid` ; record field access
564 : | `expr` "[" `expr` "]" "'"* ; collection access
565 : | `expr` "[" `expr` "<-" `expr` "]" "'"* ; collection update
566 : | `expr` "[" `expr` ".." `expr` "]" "'"* ; collection slice
567 : | `expr` "[" `expr` ".." "]" "'"* ; right-open slice
568 : | `expr` "[" ".." `expr` "]" "'"* ; left-open slice
569 : | "[|" (`expr` "=>" `expr` ";")* ("_" "=>" `expr`)? "|]" ; function literal
570 : | "[|" (`expr` ";")+ "|]" ; function literal (domain over nat)
571 : | `expr` `expr`+ ; application
572 : | `prefix_op` `expr` ; prefix operator
573 : | `expr` `infix_op_4` `expr` ; infix operator 4
574 : | `expr` `infix_op_3` `expr` ; infix operator 3
575 : | `expr` `infix_op_2` `expr` ; infix operator 2
576 : | `expr` `infix_op_1` `expr` ; infix operator 1
577 : | "not" `expr` ; negation
578 : | `expr` "&&" `expr` ; lazy conjunction
579 : | `expr` "||" `expr` ; lazy disjunction
580 : | `expr` ":" `type` ; type cast
581 : | `attribute`+ `expr` ; attributes
582 : | "ghost" `expr` ; ghost expression
583 : | `expr` ("," `expr`)+ ; tuple
584 : | `expr` "<-" `expr` ; assignment
585 : | `expr` `spec`+ ; added specification
586 : | "if" `expr` "then" `expr` ("else" `expr`)? ; conditional
587 : | "match" `expr` "with" ("|" `pattern` "->" `expr`)+ "end" ; pattern matching
588 : | `qualifier`? "begin" `spec`+ `expr` "end" ; abstract block
589 : | `expr` ";" `expr` ; sequence
590 : | "let" `pattern` "=" `expr` "in" `expr` ; let-binding
591 : | "let" `fun_defn` "in" `expr` ; local function
592 : | "let" "rec" `fun_defn` ("with" `fun_defn`)* "in" `expr` ; recursive function
593 : | "fun" `param`+ `spec`* "->" `spec`* `expr` ; unnamed function
594 : | "any" `result` `spec`* ; arbitrary value
595 : | "while" `expr` "do" `invariant`* `variant`? `expr` "done" ; while loop
596 : | "for" `lident` "=" `expr` ("to" | "downto") `expr` "do" `invariant`* `expr` "done" ; for loop
597 : | "for" `pattern` "in" `expr` "with" `uident` ("as" `lident_nq`)? "do" `invariant`* `variant`? `expr` "done" ; for each loop
598 : | "break" `lident`? ; loop break
599 : | "continue" `lident`? ; loop continue
600 : | ("assert" | "assume" | "check") "{" `term` "}" ; assertion
601 : | "raise" `uqualid` `expr`? ; exception raising
602 : | "raise" "(" `uqualid` `expr`? ")"
603 : | "try" `expr` "with" ("|" `handler`)+ "end" ; exception catching
604 : | "(" `expr` ")" ; parentheses
605 : | "label" `uident` "in" `expr` ; label
606 handler: `uqualid` `pattern`? "->" `expr` ; exception handler
607 fun_defn: `fun_head` `spec`* "=" `spec`* `expr` ; function definition
608 fun_head: "ghost"? `kind`? `symbol` `param`+ (":" `result`)? ; function header
609 kind: "function" | "predicate" | "lemma" ; function kind
611 : | "(" `ret_type` ("," `ret_type`)* ")"
612 : | "(" `ret_name` ("," `ret_name`)* ")"
613 ret_type: "ghost"? `type` ; unnamed result
614 ret_name: "ghost"? `binder` ":" `type` ; named result
615 spec: "requires" "{" `term` "}" ; pre-condition
616 : | "ensures" "{" `term` "}" ; post-condition
617 : | "returns" "{" ("|" `pattern` "->" `term`)+ "}" ; post-condition
618 : | "raises" "{" ("|" `pattern` "->" `term`)+ "}" ; exceptional post-c.
619 : | "raises" "{" `uqualid` ("," `uqualid`)* "}" ; raised exceptions
620 : | "reads" "{" `lqualid` ("," `lqualid`)* "}" ; external reads
621 : | "writes" "{" `path` ("," `path`)* "}" ; memory writes
622 : | "alias" "{" `alias` ("," `alias`)* "}" ; memory aliases
624 : | "diverges" ; may not terminate
625 : | ("reads" | "writes" | "alias") "{" "}" ; empty effect
626 path: `lqualid` ("." `lqualid`)* ; v.field1.field2
627 alias: `path` "with" `path` ; arg1 with result
628 invariant: "invariant" "{" `term` "}" ; loop and type invariant
629 variant: "variant" "{" `variant_term` ("," `variant_term`)* "}" ; termination variant
630 variant_term: `term` ("with" `lqualid`)? ; variant term + WF-order
632 .. index:: ghost expressions
637 Keyword ``ghost`` marks the expression as ghost code added for
638 verification purposes. Ghost code is removed from the final code
639 intended for execution, and thus cannot affect the computation of the
640 program results nor the content of the observable memory.
642 .. index:: assignment expressions
644 Assignment expressions
645 ^^^^^^^^^^^^^^^^^^^^^^
647 Assignment updates in place a mutable record field or an element of a
648 collection. The former can be done simultaneously on a tuple of values:
649 ``x.f, y.g <- a, b``. The latter form, ``a[i] <- v``, amounts to a call
650 of the ternary bracket operator ``([]<-)`` and cannot be used in a
653 .. index:: auto-dereference
656 Auto-dereference: simplified usage of mutable variables
657 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
659 Some syntactic sugar is provided to ease the use of mutable variables
660 (aka references), in such a way that the bang character is no more
661 needed to access the value of a reference, in both logic and programs.
662 This syntactic sugar summarized in the following table.
664 +-------------------------+-------------------------------+
665 | auto-dereference syntax | desugared to |
666 +=========================+===============================+
667 | ``let &x = ... in`` | ``let (x: ref ...) = ... in`` |
668 +-------------------------+-------------------------------+
669 | ``f x`` | ``f x.contents`` |
670 +-------------------------+-------------------------------+
671 | ``x <- ...`` | ``x.contents <- ...`` |
672 +-------------------------+-------------------------------+
673 | ``let ref x = ...`` | ``let &x = ref ...`` |
674 +-------------------------+-------------------------------+
678 - the ``&`` marker adds the typing constraint ``(x: ref ...)``;
679 - top-level ``let/val ref`` and ``let/val &`` are allowed;
680 - auto-dereferencing works in logic, but such variables
681 cannot be introduced inside logical terms.
685 .. code-block:: whyml
687 let ref x = 0 in while x < 100 do invariant { 0 <= x <= 100 } x <- x + 1 done
689 That syntactic sugar is further extended to pattern matching, function
690 parameters, and reference passing, as follows.
692 +----------------------------------+-----------------------------------------------------+
693 | auto-dereference syntax | desugared to |
694 +==================================+=====================================================+
695 | ``match e with (x,&y) -> y end`` | ``match e with (x,(y: ref ...)) -> y.contents end`` |
696 +----------------------------------+-----------------------------------------------------+
697 | .. code-block:: whyml | .. code-block:: whyml |
699 | let incr (&x: ref int) = | let incr (x: ref int) = |
700 | x <- x + 1 | x.contents <- x.contents + 1 |
702 | let f () = | let f () = |
703 | let ref x = 0 in | let x = ref 0 in |
704 | incr x; | incr x; |
706 +----------------------------------+-----------------------------------------------------+
707 | ``let incr (ref x: int) ...`` | ``let incr (&x: ref int) ...`` |
708 +----------------------------------+-----------------------------------------------------+
710 The type annotation is not required. Let-functions with such formal
711 parameters also prevent the actual argument from auto-dereferencing when
712 used in logic. Pure logical symbols cannot be declared with such
715 Auto-dereference suppression does not work in the middle of a relation
716 chain: in ``0 < x :< 17``, ``x`` will be dereferenced even if ``(:<)``
717 expects a ref-parameter on the left.
719 Finally, that syntactic sugar applies to the caller side:
721 +-------------------------+-----------------------+
722 | auto-dereference syntax | desugared to |
723 +=========================+=======================+
724 | .. code-block:: whyml | .. code-block:: whyml |
726 | let f () = | let f () = |
727 | let ref x = 0 in | let x = ref 0 in |
729 +-------------------------+-----------------------+
731 The ``&`` marker can only be attached to a variable. Works in logic.
733 Ref-binders and ``&``-binders in variable declarations, patterns, and
734 function parameters do not require importing ``ref.Ref``. Any example
735 that does not use references inside data structures can be rewritten by
736 using ref-binders, without importing ``ref.Ref``.
738 Explicit use of type symbol ``ref``, program function ``ref``, or field
739 ``contents`` requires importing ``ref.Ref`` or ``why3.Ref.Ref``.
740 Operations ``(:=)`` and ``(!)`` require importing ``ref.Ref``.
741 Note that operation ``(:=)`` is fully subsumed by direct assignment ``(<-)``.
743 .. index:: evaluation order
748 In applications, arguments are evaluated from right to left. This
749 includes applications of infix operators, with the only exception of
750 lazy operators ``&&`` and ``||`` which evaluate from left to right,
753 .. index:: past program states
758 Referring to past program states using "at" and "old" operators
759 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
761 Within specifications, terms are extended with
762 constructs ``old`` and ``at``. Within a postcondition, ``old t`` refers to
763 the value of term ``t`` in the pre-state. Within the scope of a code label
764 ``L``, introduced with ``label L in ...``, the term ``t at L`` refers to the
765 value of term ``t`` at the program point corresponding to ``L``.
767 Note that ``old`` can be used in annotations contained in the function
768 body as well (assertions, loop invariants), with the exact same meaning: it
769 refers to the pre-state of the function. In particular, ``old t`` in
770 a loop invariant does not refer to the program point right before the
771 loop but to the function entry.
773 Whenever ``old t`` or ``t at L`` refers to a program point at which
774 none of the variables in ``t`` is defined, Why3 emits a warning ``this
775 `at'/`old' operator is never used`` and the operator ``old``/``at`` is
776 ignored. For instance, the following code
778 .. code-block:: whyml
780 let x = ref 0 in assert { old !x = !x }
782 emits a warning and is provable, as it amounts to proving `0=0`.
783 Similarly, if ``old t`` or ``t at L`` refers to a term ``t`` that is
784 immutable, Why3 emits the same warning and ignores the operator.
786 Caveat: Whenever the term ``t`` contains several variables, some of
787 them being meaningful at the corresponding program point but others
788 not being in scope or being immutable, there is *no warning* and the
789 operator ``old``/``at`` is applied where it is defined and ignored
790 elsewhere. This is convenient when writing terms such as ``old a[i]``
791 where ``a`` makes sense in the pre-state but ``i`` does not.
793 .. index:: for loop, invariant; for loop
798 The “for” loop of Why3 has the following general form:
800 .. code-block:: whyml
802 for v=e1 to e2 do invariant { i } e3 done
804 Here, ``v`` is a variable identifier, that is bound by the loop
805 statement and of type ``int`` ; ``e1`` and ``e2`` are program
806 expressions of type ``int``, and ``e3`` is an expression of type
807 ``unit``. The variable ``v`` may occur both in ``i`` and ``e3``, and
808 is not mutable. The execution of such a loop amounts to first evaluate
809 ``e1`` and ``e2`` to values ``n1`` and ``n2``. If ``n1 >= n2`` then
810 the loop is not executed at all, otherwise it is executed iteratively
811 for ``v`` taking all the values between ``n1`` and ``n2`` included.
813 Regarding verification conditions, one must prove that ``i[v <- n1]``
814 holds (invariant initialization) ; and that ``forall n. n1 <= n <= n2
815 /\ i[v <- n] -> i[v <- n+1]`` (invariant preservation). At loop exit,
816 the property which is known is ``i[v <- n2+1]`` (notice the index
817 ``n2+1``). A special case occurs when the initial value ``n1`` is
818 larger than ``n2+1``: in that case the VC generator does not produce
819 any VC to prove, the loop just acts as a no-op instruction. Yet in the
820 case when ``n1 = n2+1``, the formula ``i[v <- n2+1]`` is asserted and
821 thus need to be proved as a VC.
823 The variant with keyword ``downto`` instead of ``to`` iterates
826 It is also possible for ``v`` to be an integer range type (see
827 :numref:`sec.range_types`) instead of an integer.
829 .. index:: for each loop, invariant; for each loop
834 The “for each” loop of Why3 has the following syntax:
836 .. code-block:: whyml
838 for p in e1 with S do invariant/variant... e2 done
840 Here, ``p`` is a pattern, ``S`` is a namespace, and ``e1`` and ``e2``
841 are program expressions. Such a for each loop is syntactic sugar for
844 .. code-block:: whyml
846 let it = S.create e1 in
855 That is, namespace ``S`` is assumed to declare at least a function
856 ``create`` and a function ``next``, and an exception ``Done``. The
857 latter is used to signal the end of the iteration.
858 As shown above, the iterator is named ``it``. It can be referred to
859 within annotations. A different name can be specified, using syntax
862 .. index:: while loop, for loop, break, continue
868 The ``break`` and ``continue`` statements can be used in ``while``,
869 ``for`` and ``for-each`` loops, with the expected semantics. The
870 statements take an optional identifier which can be used to break
871 out of nested loops. This identifier can be defined using ``label``
872 like in the following example:
874 .. code-block:: whyml
881 break A (* abort the outer loop *)
885 .. index:: collections; syntax; function literals
890 Function literals can be written in expressions the same way as they
891 are in terms but there are a few subtleties that one must bear in
892 mind. First of all, if the domain of the literal is of type ``t`` then
893 an equality infix operator ``=`` should exist. For instance, the
894 literal ``[|t1 => u1|]`` with ``t1`` of type ``t``, is only considered
895 well typed if the infix operator ``=`` of type ``t -> t -> bool`` is
896 visible in the current scope. This problem does not exist in terms
897 because the equality in terms is polymorphic.
899 Second, the function literal expression ``[|t1 => u1; t2 => u2; _ =>
900 u3|]`` will be translated into the following expression:
902 .. code-block:: whyml
909 fun x'x -> if x'x = d'i0 then r'i0 else
910 if x'x = d'i1 then r'i1 else
913 .. index:: any expression
915 The ``any`` expression
916 ^^^^^^^^^^^^^^^^^^^^^^
918 The general form of the ``any`` expression is the following.
920 .. code-block:: whyml
922 any <type> <contract>
924 This expression non-deterministically evaluates to a value of the
925 given type that satisfies the contract. For example, the code
927 .. code-block:: whyml
929 let x = any int ensures { 0 <= result < 100 } in
932 will give to ``x`` any non-negative integer value smaller than 100.
934 As for contracts on functions, it is allowed to name the result or
935 even give a pattern for it. For example the following expression
936 returns a pair of integers which first component is smaller than the
939 .. code-block:: whyml
941 any (int,int) returns { (a,b) -> a <= b }
943 Notice that an ``any`` expression is not supposed to have side effects
944 nor raise exceptions, hence its contract cannot include any
945 ``writes`` or ``raises`` clauses.
947 To ensure that this construction is safe, it is mandatory to show that
948 there is always at least one possible value to return. It means that
949 the VC generator produces a proof obligation of form
951 .. code-block:: whyml
953 exists result:<type>. <post-condition>
955 In that respect, notice the difference with the construct
957 .. code-block:: whyml
959 val x:<type> <contract> in x
961 which will not generate any proof obligation, meaning that the
962 existence of the value ``x`` is taken for granted.
969 A WhyML input file is a (possibly empty) list of modules
973 module: "module" `uident_nq` `attribute`* `decl`* "end"
974 decl: "type" `type_decl` ("with" `type_decl`)*
975 : | "constant" `constant_decl`
976 : | "function" `function_decl` ("with" `logic_decl`)*
977 : | "predicate" `predicate_decl` ("with" `logic_decl`)*
978 : | "inductive" `inductive_decl` ("with" `inductive_decl`)*
979 : | "coinductive" `inductive_decl` ("with" `inductive_decl`)*
980 : | "axiom" `ident_nq` ":" `formula`
981 : | "lemma" `ident_nq` ":" `formula`
982 : | "goal" `ident_nq` ":" `formula`
983 : | "use" `imp_exp` `tqualid` ("as" `uident`)?
984 : | "clone" `imp_exp` `tqualid` ("as" `uident`)? `subst`?
985 : | "scope" "import"? `uident_nq` `decl`* "end"
986 : | "import" `uident`
987 : | "let" "ghost"? `lident_nq` `attribute`* `fun_defn`
988 : | "let" "rec" `fun_defn`
989 : | "val" "ghost"? `lident_nq` `attribute`* `pgm_decl`
990 : | "exception" `lident_nq` `attribute`* `type`?
991 type_decl: `lident_nq` `attribute`* ("'" `lident_nq` `attribute`*)* `type_defn`
992 type_defn: ; abstract type
993 : | "=" `type` ; alias type
994 : | "=" "|"? `type_case` ("|" `type_case`)* ; algebraic type
995 : | "=" `vis_mut` "{" `record_field` (";" `record_field`)* "}" `invariant`* `type_witness` ; record type
996 : | "<" "range" `integer` `integer` ">" ; range type
997 : | "<" "float" `integer` `integer` ">" ; float type
998 type_case: `uident` `attribute`* `type_param`*
999 record_field: "ghost"? "mutable"? `lident_nq` `attribute`* ":" `type`
1000 type_witness: "by" "{" `lident_nq` "=" `expr` (";" `lident_nq` "=" `expr`)* "}"
1001 vis_mut: ("abstract" | "private")? "mutable"?
1002 pgm_decl: ":" `type` ; global variable
1003 : | `param` (`spec`* `param`)+ ":" `type` `spec`* ; abstract function
1004 logic_decl: `function_decl`
1005 : | `predicate_decl`
1006 constant_decl: `lident_nq` `attribute`* ":" `type`
1007 : | `lident_nq` `attribute`* ":" `type` "=" `term`
1008 function_decl: `lident_nq` `attribute`* `type_param`* ":" `type`
1009 : | `lident_nq` `attribute`* `type_param`* ":" `type` "=" `term`
1010 predicate_decl: `lident_nq` `attribute`* `type_param`*
1011 : | `lident_nq` `attribute`* `type_param`* "=" `formula`
1012 inductive_decl: `lident_nq` `attribute`* `type_param`* "=" "|"? `ind_case` ("|" `ind_case`)*
1013 ind_case: `ident_nq` `attribute`* ":" `formula`
1014 imp_exp: ("import" | "export")?
1015 subst: "with" ("," `subst_elt`)+
1016 subst_elt: "type" `lqualid` "=" `lqualid`
1017 : | "function" `lqualid` "=" `lqualid`
1018 : | "predicate" `lqualid` "=" `lqualid`
1019 : | "scope" (`uqualid` | ".") "=" (`uqualid` | ".")
1020 : | "lemma" `qualid`
1022 tqualid: `uident` | `ident` ("." `ident`)* "." `uident`
1023 type_param: "'" `lident`
1025 : | "(" `lident`+ ":" `type` ")"
1026 : | "(" `type` ("," `type`)* ")"
1030 .. index:: record type
1036 A record type declaration introduces a new type, with named and typed
1039 .. code-block:: whyml
1041 type t = { a: int; b: bool }
1043 Such a type can be used both in logic and programs.
1044 A new record is built using curly braces and a value for each field,
1045 such as ``{ a = 42; b = true }``. If ``x`` is a value of type ``t``,
1046 its fields are accessed using the dot notation, such as ``x.a``.
1047 Each field happens to be a projection function, so that we can also
1049 A field can be declared ``mutable``, as follows:
1051 .. code-block:: whyml
1053 type t = { mutable a: int; b: bool }
1055 A mutable field can be modified using notation ``x.a <- 42``.
1056 The ``writes`` clause of a function contract can list mutable fields,
1057 e.g., ``writes { x.a }``.
1059 .. index:: type invariant, invariant; type
1060 .. rubric:: Type invariants
1062 Invariants can be attached to record types, as follows:
1064 .. code-block:: whyml
1066 type t = { mutable a: int; b: bool }
1067 invariant { b = true -> a >= 0 }
1069 The semantics of type invariants is as follows. In the logic, a type
1070 invariant always holds.
1071 Consequently, it is no more possible
1072 to build a value using the curly braces (in the logic).
1073 To prevent the introduction of a logical
1074 inconsistency, Why3 generates a VC to show the existence of at least
1075 one record instance satisfying the invariant. It is named ``t'vc``
1076 and has the form ``exists a:int, b:bool. b = true -> a >= 0``. To ease the
1077 verification of this VC, one can provide an explicit witness using the
1078 keyword ``by``, as follows:
1080 .. code-block:: whyml
1082 type t = { mutable a: int; b: bool }
1083 invariant { b = true -> a >= 0 }
1084 by { a = 42; b = true }
1086 It generates a simpler VC, where fields are instantiated accordingly.
1088 In programs, a type invariant is assumed to
1089 hold at function entry and must be restored at function exit.
1090 In the middle, the invariant can be temporarily broken. For instance,
1091 the following function can be verified:
1093 .. code-block:: whyml
1095 let f (x: t) = x.a <- x.a - 1; x.a <- 0
1097 After the first assignment, the invariant does not necessarily hold
1098 anymore. But it is restored before function exit with the second
1101 If the record is passed to another function, then the invariant
1102 must be reestablished (so as to honor the contract of the callee).
1103 For instance, the following function cannot be verified:
1105 .. code-block:: whyml
1107 let f1 (x: t) = x.a <- x.a - 1; f x; x.a <- 0
1109 Indeed, passing ``x`` to function ``f`` requires checking the
1110 invariant first, which does not hold in this example. Similarly, the
1111 invariant must be reestablished if the record is passed to a logical
1112 function or predicate. For instance, the following function cannot be
1115 .. code-block:: whyml
1117 predicate p (x: t) = x.b
1119 let f2 (x: t) = x.a <- x.a - 1; assert { p x }; x.a <- 0
1121 Accessing the record fields, however, does not require restoring the
1122 invariant, both in logic and programs.
1123 For instance, the following function can be verified:
1125 .. code-block:: whyml
1127 let f2 (x: t) = x.a <- x.a - 1; assert { x.a < old x.a }; x.a <- 0
1129 Indeed, the invariant may not hold after the first assignment, but the
1130 assertion is only making use of field access, so there is no need to
1131 reestablish the invariant.
1133 .. index:: private type
1134 .. rubric:: Private types
1136 A record type can be declared ``private``, as follows:
1138 .. code-block:: whyml
1140 type t = private { mutable a: int; b: bool }
1142 The meaning of such a declaration is that one cannot build a record
1143 instance, neither in the logic, nor in programs.
1144 For instance, the following function cannot be defined:
1146 .. code-block:: whyml
1148 let create () = { a = 42; b = true }
1150 One cannot modify mutable fields of private types either.
1151 One may wonder what is the purpose of private types, if one cannot
1152 build values in those types. The purpose is to build
1153 interfaces, to be later refined with actual implementations (see
1154 section :ref:`Module cloning` below). Indeed, if we cannot build
1155 record instances, we can still *declare* operations that
1156 return such records. For instance, we can declare the following two
1159 .. code-block:: whyml
1161 val create (n: int) : t
1162 ensures { result.a = n }
1164 val incr (x: t) : unit
1166 ensures { x.a = old x.a + 1 }
1168 Later, we can *refine* type ``t`` with a type that is not private
1169 anymore, and then implement operations ``create`` and ``incr``.
1171 Private types are often used in conjunction with ghost fields, that
1172 are used to model the contents of data structures. For instance, we
1173 can conveniently model a queue containing integers as follows:
1175 .. code-block:: whyml
1177 type queue = private { mutable ghost s: seq int }
1179 If needed, we could even add invariants (e.g., the sequence ``s`` is
1180 sorted in a priority queue).
1182 .. index:: abstract type
1184 When a private record type only has ghost fields, one can use
1185 ``abstract`` as a convenient shortcut:
1187 .. code-block:: whyml
1189 type queue = abstract { mutable s: seq int }
1191 This is equivalent to the previous declaration.
1193 .. rubric:: Recursive record types
1195 Record types can be recursive, e.g,
1197 .. code-block:: whyml
1199 type t = { a: int; next: option t }
1201 Recursive record types cannot have invariants, cannot have mutable
1202 fields, and cannot be private.
1204 .. index:: algebraic data type
1206 Algebraic data types
1207 ^^^^^^^^^^^^^^^^^^^^
1209 Algebraic data types combine sum and product types.
1210 A simple example of a sum type is that of an option type:
1212 .. code-block:: whyml
1214 type maybe = No | Yes int
1216 Such a declaration introduces a new type ``maybe``, with two
1217 constructors ``No`` and ``Yes``. Constructor ``No`` has no argument
1218 and thus can be used as a constant value. Constructor ``Yes`` has an
1219 argument of type ``int`` and thus can be used to build values such as
1220 ``Yes 42``. Algebraic data types can be polymorphic, e.g.,
1222 .. code-block:: whyml
1224 type option 'a = None | Some 'a
1226 (This type is already part of Why3 standard library, in module
1227 `option.Option <http://why3.lri.fr/stdlib/option.html>`_.)
1229 A data type can be recursive. The archetypal example is the type of
1232 .. code-block:: whyml
1234 type list 'a = Nil | Cons 'a (list 'a)
1236 (This type is already part of Why3 standard library, in module
1237 `list.List <http://why3.lri.fr/stdlib/list.html>`_.)
1239 When a field is common to all constructors, with the same type, it can
1242 .. code-block:: whyml
1245 | MayBe (size: int) (option int)
1246 | Many (size: int) (list int)
1248 Such a named field introduces a projection function. Here, we get a
1249 function ``size`` of type ``t -> int``.
1251 Constructor arguments can be ghost, e.g.,
1253 .. code-block:: whyml
1259 Non-uniform data types are allowed, such as the following type for
1260 `random access lists <http://toccata.lri.fr/gallery/random_access_list.fr.html>`_:
1262 .. code-block:: whyml
1266 | Zero (ral ('a, 'a))
1267 | One 'a (ral ('a, 'a))
1269 Why3 supports polymorphic recursion, both in logic and programs, so
1270 that we can define and verify operations on such types.
1275 A tuple type is a particular case of algebraic data types, with a
1276 single constructor. A tuple type need not be declared by the user; it
1277 is generated on the fly. The syntax for a tuple type is ``(type1,
1280 Note: Record types, introduced in the previous section, also
1281 constitute a particular case of algebraic data types with a single
1282 constructor. There are differences, though. Record types may have
1283 mutable fields, invariants, or private status, while algebraic data
1287 .. index:: range type
1288 .. _sec.range_types:
1293 A declaration of the form ``type r = <range a b>`` defines a type that
1294 projects into the integer range ``[a,b]``. Note that in order to make
1295 such a declaration the theory ``int.Int`` must be imported.
1297 Why3 let you cast an integer literal in a range type (e.g., ``(42:r)``)
1298 and will check at typing that the literal is in range. Defining such a
1299 range type :math:`r` automatically introduces the following:
1301 .. code-block:: whyml
1303 function r'int r : int
1304 constant r'maxInt : int
1305 constant r'minInt : int
1307 The function ``r'int`` projects a term of type ``r`` to its integer
1308 value. The two constants represent the high bound and low bound of the
1311 Unless specified otherwise with the meta :why3:meta:`keep:literal` on ``r``, the
1312 transformation :why3:transform:`eliminate_literal` introduces an axiom
1314 .. code-block:: whyml
1316 axiom r'axiom : forall i:r. r'minInt <= r'int i <= r'maxInt
1318 and replaces all casts of the form ``(42:r)`` with a constant and an
1321 .. code-block:: whyml
1323 constant rliteral7 : r
1324 axiom rliteral7_axiom : r'int rliteral7 = 42
1326 This type is used in the standard library in the theories ``bv.BV8``,
1327 ``bv.BV16``, ``bv.BV32``, ``bv.BV64``.
1329 Floating-point types
1330 ^^^^^^^^^^^^^^^^^^^^
1332 A declaration of the form ``type f = <float eb sb>`` defines a type of
1333 floating-point numbers as specified by the IEEE-754
1334 standard :cite:`ieee754-2008`. Here the literal ``eb``
1335 represents the number of bits in the exponent and the literal ``sb`` the
1336 number of bits in the significand (including the hidden bit). Note that
1337 in order to make such a declaration the theory ``real.Real`` must be
1340 Why3 let you cast a real literal in a float type (e.g., ``(0.5:f)``) and
1341 will check at typing that the literal is representable in the format.
1342 Note that Why3 do not implicitly round a real literal when casting to a
1343 float type, it refuses the cast if the literal is not representable.
1345 Defining such a type ``f`` automatically introduces the following:
1347 .. code-block:: whyml
1349 predicate f'isFinite f
1350 function f'real f : real
1354 As specified by the IEEE standard, float formats includes infinite
1355 values and also a special NaN value (Not-a-Number) to represent results
1356 of undefined operations such as :math:`0/0`. The predicate
1357 ``f'isFinite`` indicates whether its argument is neither infinite nor
1358 NaN. The function ``f'real`` projects a finite term of type ``f`` to its
1359 real value, its result is not specified for non finite terms.
1361 Unless specified otherwise with the meta :why3:meta:`keep:literal` on ``f``, the
1362 transformation :why3:transform:`eliminate_literal` will introduce an axiom
1364 .. code-block:: whyml
1367 forall x:f. f'isFinite x -> -. max_real <=. f'real x <=. max_real
1369 where ``max_real`` is the value of the biggest finite float in the
1370 specified format. The transformation also replaces all casts of the form
1371 ``(0.5:f)`` with a constant and an axiom as in:
1373 .. code-block:: whyml
1375 constant fliteral42 : f
1376 axiom fliteral42_axiom : f'real fliteral42 = 0.5 /\ f'isFinite fliteral42
1378 This type is used in the standard library in the theories
1379 ``ieee_float.Float32`` and ``ieee_float.Float64``.
1385 Function declarations
1386 ^^^^^^^^^^^^^^^^^^^^^
1389 Definition of a program function, with prototype, contract, and body
1392 Declaration of a program function, with prototype and contract only
1395 Definition of a pure (that is, side-effect free) program function
1396 which can also be used in specifications as a logical function
1400 Definition of a pure Boolean program function which can also be
1401 used in specifications as a logical predicate symbol
1404 Declaration of a pure program function which can also be used in
1405 specifications as a logical function symbol
1408 Declaration of a pure Boolean program function which can also be
1409 used in specifications as a logical predicate symbol
1412 Definition or declaration of a logical function symbol which can
1413 also be used as a program function in ghost code
1416 Definition or declaration of a logical predicate symbol which can
1417 also be used as a Boolean program function in ghost code
1420 definition of a special pure program function which serves not as
1421 an actual code to execute but to prove the function's contract as a
1422 lemma: “for all values of parameters, the precondition implies the
1423 postcondition”. This lemma is then added to the logical context and
1424 is made available to provers. If this “lemma-function” produces a
1425 result, the lemma is “for all values of parameters, the
1426 precondition implies the existence of a result that satisfies the
1427 postcondition”. Lemma-functions are mostly used to prove some
1428 property by induction directly in Why3, without resorting to an
1429 external higher-order proof assistant.
1431 Program functions (defined with ``let`` or declared with ``val``) can
1432 additionally be marked ``ghost``, meaning that they can only be used
1433 in the ghost code and never translated into executable code ; or
1434 ``partial``, meaning that their execution can produce observable
1435 effects unaccounted by their specification, and thus they cannot be
1436 used in the ghost code.
1439 .. index:: module cloning
1445 Why3 features a mechanism to make an instance of a module, by
1446 substituting some of its declarations with other symbols. It is called
1449 Let us consider the example of a module implementing
1450 `exponentiation by squaring
1451 <https://en.wikipedia.org/wiki/Exponentiation_by_squaring>`_.
1452 We want to make it as general as possible, so that we can implement it
1453 and verify it only once and then reuse it in various different
1454 contexts, e.g., with integers, floating-point numbers, matrices, etc.
1455 We start our module with the introduction of a monoid:
1457 .. code-block:: whyml
1461 use int.ComputerDivision
1465 val constant one : t
1467 val function mul t t : t
1469 axiom one_neutral: forall x. mul one x = x = mul x one
1471 axiom mul_assoc: forall x y z. mul x (mul y z) = mul (mul x y) z
1473 Then we define a simple exponentiation function, mostly for the
1474 purpose of specification:
1476 .. code-block:: whyml
1479 let rec function exp (x: t) (n: int) : t
1482 = if n = 0 then one else mul x (exp x (n - 1))
1484 In anticipation of the forthcoming verification of exponentiation by
1485 squaring, we prove two lemmas. As they require induction, we use lemma
1488 .. code-block:: whyml
1491 let rec lemma exp_add (x: t) (n m: int)
1492 requires { 0 <= n /\ 0 <= m }
1494 ensures { exp x (n + m) = mul (exp x n) (exp x m) }
1495 = if n > 0 then exp_add x (n - 1) m
1497 let rec lemma exp_mul (x: t) (n m: int)
1498 requires { 0 <= n /\ 0 <= m }
1500 ensures { exp x (n * m) = exp (exp x n) m }
1501 = if m > 0 then exp_mul x n (m - 1)
1503 Finally, we implement and verify exponentiation by squaring, which
1504 completes our module.
1506 .. code-block:: whyml
1509 let fast_exp (x: t) (n: int) : t
1511 ensures { result = exp x n }
1516 invariant { 0 <= q }
1517 invariant { mul r (exp p q) = exp x n }
1519 if mod q 2 = 1 then r <- mul r p;
1527 Note that module ``Exp`` mixes declared symbols (type ``t``, constant
1528 ``one``, function ``mul``) and defined symbols (function ``exp``,
1529 program function ``fast_exp``).
1531 We can now make an instance of module ``Exp``, by substituting some of
1532 its declared symbols (not necessarily all of them) with some other
1533 symbols. For instance, we get exponentiation by squaring on integers
1534 by substituting ``int`` for type ``t``, integer ``1`` for constant
1535 ``one``, and integer multiplication for function ``mul``.
1537 .. code-block:: whyml
1539 module ExponentiationBySquaring
1541 clone Exp with type t = int, val one = one, val mul = (*)
1544 In a substitution such as ``val one = one``,
1545 the left-hand side refers to the namespace of
1546 the module being cloned, while the right-hand side refers to the
1547 current namespace (which here contains a constant ``one`` of type
1550 When a module is cloned, any axiom is automatically turned into a
1551 lemma. Thus, the ``clone`` command above generates two VCs, one for
1552 lemma ``one_neutral`` and another for lemma ``mul_assoc``. If an
1553 axiom should instead remain an axiom, it should be explicitly
1554 indicated in the substitution (using ``axiom mul_assoc`` for
1555 instance). Why3 cannot figure out by itself whether an axiom should be
1556 turned into a lemma, so it goes for the safe path (all axioms are to
1557 be proved) by default.
1559 Lemmas that were proved in the module being cloned (such as
1560 ``exp_add`` and ``exp_mul`` here) are not reproved. They are part
1561 of the resulting namespace, the substitution being applied to
1563 Similarly, functions that were defined in the module being cloned
1564 (such as ``exp`` and ``fast_exp`` here) are not reproved and are part
1565 of the resulting module, the substitution being applied to their
1566 argument types, return type, and definition. For instance, we get a
1567 fresh function ``fast_exp`` of type ``int->int->int``.
1569 We can make plenty other instances of our module ``Exp``.
1570 For instance, we get
1571 `Russian multiplication
1572 <https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication>`_ for free
1573 by instantiating ``Exp`` with zero and addition instead.
1575 .. code-block:: whyml
1577 module Multiplication
1579 clone Exp with type t = int, val one = zero, val mul = (+)
1583 .. index:: standard library
1585 The Why3 Standard Library
1586 -------------------------
1588 The Why3 standard library provides general-purpose modules, to be used
1589 in logic and/or programs. It can be browsed on-line at
1590 http://why3.lri.fr/stdlib/. Each file contains one or several modules.
1591 To ``use`` or ``clone`` a module ``M`` from file :file:`file.mlw`, use the
1592 syntax ``file.M``, since :file:`file.mlw` is available in Why3’s default load
1593 path. For instance, the module of integers and the module of arrays
1594 indexed by integers are imported as follows:
1596 .. code-block:: whyml
1601 A sub-directory :file:`mach/` provides various modules to model machine
1602 arithmetic. For instance, the module of 63-bit integers and the module
1603 of arrays indexed by 63-bit integers are imported as follows:
1605 .. code-block:: whyml
1608 use mach.array.Array63
1610 In particular, the types and operations from these modules are mapped to
1611 native OCaml’s types and operations when Why3 code is extracted to OCaml
1612 (see :numref:`sec.extract`).
1614 Library ``int``: mathematical integers
1615 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1617 The ``int`` library contains several modules whose dependencies are
1618 displayed on Figure :numref:`fig.lib.int`.
1620 .. graphviz:: generated/library-int.dot
1621 :caption: Module dependencies in library ``int``.
1624 The main module is ``Int`` which provides basic operations like addition
1625 and multiplication, and comparisons.
1627 The division of modulo operations are defined in other modules. They
1628 indeed come into two flavors: the module ``EuclideanDivision`` proposes
1629 a version where the result of the modulo is always non-negative, whereas
1630 the module ``ComputerDivision`` provides a version which matches the
1631 standard definition available in programming languages like C, Java or
1632 OCaml. Note that these modules do not provide any divsion or modulo
1633 operations to be used in programs. For those, you must use the module
1634 ``mach.int.Int`` instead, which provides these operations, including
1635 proper pre-conditions, and with the usual infix syntax ``x / y`` and ``x
1638 The detailed documentation of the library is available on-line at
1639 http://why3.lri.fr/stdlib/int.html
1642 Library ``array``: array data structure
1643 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1645 The ``array`` library contains several modules whose dependencies are
1646 displayed on Figure :numref:`fig.lib.array`.
1648 .. graphviz:: generated/library-array.dot
1649 :caption: Module dependencies in library ``array``.
1650 :name: fig.lib.array
1652 The main module is ``Array``, providing the operations for accessing and
1653 updating an array element, with respective syntax ``a[i]`` and ``a[i] <-
1654 e``, and proper pre-conditions for the indexes. The length of an array is
1655 denoted as ``a.length``. A fresh array can be created using ``make l v``
1656 where ``l`` is the desired length and ``v`` is the initial value of each
1659 The detailed documentation of the library is available on-line at
1660 http://why3.lri.fr/stdlib/array.html