Online version of Why3, with Python input format

This version of Why3 is intended for teaching purposes. Its input format is a tiny subset of Python, called "micro-Python" and described below.

Note: the command-line version of Why3 is also supporting this input format, for files with suffix .py.

Syntax of micro-Python

Notation: The grammar of micro-Python is given below in extended Backus-Naur Form, using | for alternation, () for grouping, [] for option, and {} for repetition. Special symbols NEWLINE, INDENT, and DEDENT mark an end of line, the beginning of a new indentation block, and its end, respectively.

Logical annotations are inserted in special comments starting with //@ or /*@. In the following grammar, we only use the former kind, for simplicity, but both kinds are allowed.

      file ::= decl*
      decl ::= py-import | py-function | stmt | logic-declaration
 py-import ::= "from" ident "import" ident { "," ident } NEWLINE
Directives import are ignored during the translation to Why3. They are allowed anyway, such that a Python source code using functions such as randint is accepted by a Python interpreter (see below).

Function definition

py-function ::= "def" ident "(" [ params ] ")" ":" NEWLINE INDENT { spec } { stmt } DEDENT
     params ::= ident { "," ident }

Function specification

   spec ::= "requires" term NEWLINE
          | "ensures"  term NEWLINE
          | "variant"  term { "," term } NEWLINE

Python expression

  expr ::= "None" | "True" | "False" | integer-literal | string-literal
	 | identifier
	 | identifier "[" expr "]"
	 | "-" expr | "not" expr
	 | expr ( "+" | "-" | "*" | "//" | "%" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "and" | "or" ) expr
	 | identifier "(" [ expr { "," expr } ] ")"
	 | "[" [ expr { "," expr } ] "]"
	 | "(" expr ")"

Python statement

       stmt ::= simple_stmt NEWLINE
              | "if" expr ":" suite else_branch
	      | "while" expr ":" loop_body
	      | "for" ident "in" expr ":" loop_body
else_branch ::= /* nothing */
              | "else:" suite
              | "elif" expr ":" suite else_branch
      suite ::= simple_stmt NEWLINE
              | NEWLINE INDENT stmt { stmt } DEDENT
simple_stmt ::= expr
              | "return" expr
              | identifier "=" expr
              | identifier "[" expr "]" "=" expr
              | "break"
	      | "//@" "label" identifier
	      | "//@" ( "assert" | "assume" | "check" ) term
   assignop ::= "=" | "+=" | "-=" | "*=" | "/="
  loop_body ::= simple_stmt NEWLINE
              | NEWLINE INDENT { loop_annot } stmt { stmt } DEDENT
 loop_annot ::= "//@" "invariant" term NEWLINE
              | "//@" "variant" term { "," term } NEWLINE

Logic declaration

  logic-declaration ::= "//@" "function" "int" identifier "(" params ")" NEWLINE
		      | "//@" "predicate" identifier "(" params ")" NEWLINE
Note that logic functions and predicates cannot be given definitions. Yet, they can be axiomatized, using toplevel assume statements.

Logical term

  term ::= identifier
	 | integer-literal
         | "None"
	 | "True"
	 | "False"
	 | "(" term ")"
	 | term "[" term "]"
	 | term "[" term "<-" term "]"
	 | "not" term
	 | "old" "(" term ")"
	 | "at" "(" term "," identifier ")"
	 | "-" term
	 | term ( "->" | "<->" | "or" | "and" ) term
	 | term ( "==" | "!=" | "<" | "<=" | ">" | ">=" ) term
	 | term ( "+" | "-" | "*" | "//" | "% ) term
	 | "if" term "then" term "else term
	 | "let" identifier "=" term "in" term
	 | ( "forall" | "exists" ) ident { "," ident } "." term
	 | identifier "(" [ term { "," term } ] ")"

Built-in functions and predicates

Python code

Logic

Limitations

Python lists are modeled as arrays, whose size cannot be modified.

Verifying a program

Click on the gears button to launch the verification. Verification conditions (VCs) then appear in the right panel, in the Task List tab, and Alt-Ergo is run on each of them with a default time limit (that can be set in the Settings menu).

When a VC is not proved, there are several options: