diff options
author | Richard L. Ford <richford@microsoft.com> | 2016-01-27 21:35:30 -0800 |
---|---|---|
committer | Richard L. Ford <richford@microsoft.com> | 2016-01-27 21:35:30 -0800 |
commit | fca241c91ba0f27d145bf083a283491844da1da1 (patch) | |
tree | 7ed7a615e2f1a657a0cdb7fef0a889c18f904bd4 | |
parent | 348beb7f706f35256f5fb07349182e252aae8860 (diff) |
Add Dafny reference manual
This version is still a draft, but is mostly complete and
about half reviewed. The manual is written using
Madoko. The sources are in the Docs/DafnyRef directory.
The processed sources are available in the
Docs/DafnyRef/out directory in the form of a single
HTML page or as a PDF.
-rw-r--r-- | Docs/DafnyRef/DafnyRef.bib | 48 | ||||
-rw-r--r-- | Docs/DafnyRef/DafnyRef.mdk | 8331 | ||||
-rw-r--r-- | Docs/DafnyRef/css.sty | 803 | ||||
-rw-r--r-- | Docs/DafnyRef/dafnyx.json | 4 | ||||
-rw-r--r-- | Docs/DafnyRef/ignores.dic | 83 | ||||
-rw-r--r-- | Docs/DafnyRef/krml250.bib | 2026 | ||||
-rw-r--r-- | Docs/DafnyRef/madoko.css | 471 | ||||
-rw-r--r-- | Docs/DafnyRef/out/DafnyRef.html | 8287 | ||||
-rw-r--r-- | Docs/DafnyRef/out/DafnyRef.pdf | bin | 0 -> 563066 bytes | |||
-rw-r--r-- | Docs/DafnyRef/paper-full.bib | 577 | ||||
-rw-r--r-- | Docs/DafnyRef/poc.bib | 523 | ||||
-rw-r--r-- | Docs/DafnyRef/references.bib | 1446 |
12 files changed, 22599 insertions, 0 deletions
diff --git a/Docs/DafnyRef/DafnyRef.bib b/Docs/DafnyRef/DafnyRef.bib new file mode 100644 index 00000000..9a2a5a5b --- /dev/null +++ b/Docs/DafnyRef/DafnyRef.bib @@ -0,0 +1,48 @@ +@Misc{Rise4fun:dafny, + author = {K. Rustan M. Leino}, + title = {Try Dafny In Your Browser}, + note = "Available at \url{http://rise4fun.com/Dafny}" +} +@Misc{MSR:dafny:main, + author = {K. Rustan M. Leino}, + title = {Main Microsoft Research Dafny Web page}, + note = "Available at \url{http://research.microsoft.com/en-us/projects/dafny}" +} +@Misc{MSR:dafny:source, + author = {K. Rustan M. Leino et al}, + title = {Dafny Source Code}, + note = "Available at \url{http://dafny.codeplex.com}" +} +@Misc{MSR:dafny:quickref, + author = {K. Rustan M. Leino}, + title = {Dafny Quick Reference}, + note = "Available at \url{http://research.microsoft.com/en-us/projects/dafny/reference.aspx}" +} +@Misc{Linz:Coco, + author = {Hanspeter M{\"{o}}ssenb{\"{o}}ck and Markus L{\"{o}}berbauer and Albrecht W{\"{o}}{\ss}}, + title = {The Compiler Generator Coco/R}, + howpublished = {Open source from University of Linz}, + year = 2013, + note = "Available at \url{http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/}" +} +@Misc{LEINO:Dafny:Calc, + author = {K. Rustan M. Leino and Nadia Polikarpova}, + title = {Verified Calculations}, + howpublished = {Manuscript KRML 231}, + year = 2013, + note = "Available at \url{http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf}" +} +@Misc{LEINO:Dafny:Coinduction, + author = {K. Rustan M. Leino and Michal Moskal}, + title = {Co-induction Simply: Automatic Co-inductive Proofs in a Program Verifier}, + howpublished = {Manuscript KRML 230}, + year = 2014, + note = "Available at \url{http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf}" +} +@Misc{LEINO:Dafny:DynamicFrames, + author = {K. Rustan M. Leino}, + title = {Dynamic-frame specifications in Dafny}, + howpublished = {JML seminar, Dagstuhl, Germany}, + year = 2009, + note = "Available at \url{http://research.microsoft.com/en-us/um/people/leino/papers/dafny-jml-dagstuhl-2009.pptx}" +} diff --git a/Docs/DafnyRef/DafnyRef.mdk b/Docs/DafnyRef/DafnyRef.mdk new file mode 100644 index 00000000..59db10ab --- /dev/null +++ b/Docs/DafnyRef/DafnyRef.mdk @@ -0,0 +1,8331 @@ +<!--madoko +Title : Draft Dafny Reference Manual +Title Note : Manuscript Dafny Reference&br;&date; &time; +Author : Richard L. Ford +Email : richford@microsoft.com +Author : K. Rustan M. Leino +Email : leino@microsoft.com +Doc Class : [12pt,twoside]article +Package : [left=1.0in, right=0.75in]geometry +Heading Base: 2 +Toc Depth : 5 +Heading Depth: 5 +xMath Mode : dynamic + +Bibliography: DafnyRef.bib +Bibliography: references.bib +Bibliography: paper-full.bib +Bibliography: poc.bib +Bibliography: krml250.bib +Cite All: false + +[INCLUDE=zero] +Tex Header : \setcounter{footnote}{-1} +xPackage : times +xTex Header : \IfFileExists{luximono.sty}{\usepackage[scaled=0.81]{luximono}}{\usepackage[scaled=0.81]{beramono}} +Colorizer: dafny +Colorizer: dafnyx +~Pre,.code1 : replace="//\\forall\s/\(∀[ ]{font-family=serif}\)\ + //\bexists\s/\(∃[ ]{font-family=serif}\)\ + //g" + language=dafnyx + font-size=small +~Pre : margin-left=1em + +~Exercise : .block @Exercise=arabic0 label='[@Exercise]{.Exercise-label}' + before='[**Exercise\ &label;.** ]{.Exercise-before}' + after=' &box;' + +Comment : We use four backticks (````) for grammar productions. We use the Java + colorizer as that seems good enough for grammars. +Colorizer : java + +.pre-fenced4: language=java .grammar-def +.code2 : language=java .grammar-ref + +.grammar-def: replace='//(^|\n)([A-Z]\w+)/\1\([\2]{#1_\L\2\E .ntdef}\)\ + //(^|\n)([a-z]\w+)/\1\([\2]{#2_\L\2\E .ntdef}\)\ + //\/\/.*/\0\ + //\/\*[\s\S]*?\*\//\0\ + //"([^"|\s]*)"/\([\"\1\"]{.terminal}\)\ + //([^\[\(\{\w#.&])([A-Z]\w+)\b/\1\([\2](#1_\L\2\E){.ntref}\)\ + //([^\[\(\{\w#.&])([a-z]\w+)\b/\1\([\2](#2_\L\2\E){.ntref}\)\ + //cg' + +.grammar-ref: replace='//\/\/.*/\0\ + //\/\*[\s\S]*?\*\//\0\ + //"([^"\s]*)"/\([\"\1\"]{.terminal}\)\ + //([^\[\(\{\w#.&])([A-Z]\w+)\b/\1\([\2](#1_\L\2\E){.ntref}\)\ + //([^\[\(\{\w#.&])([a-z]\w+)\b/\1\([\2](#2_\L\2\E){.ntref}\)\ + //^([A-Z]\w+)$/\([\1](#1_\L\1\E){.ntref}\)\ + //^([a-z]\w+)$/\([\1](#2_\L\1\E){.ntref}\)\ + //cg' +.terminal : font-weight=bold color=black +.ntref : color=maroon +.ntdef : color=olive + +.AuthorNote : before="**&author;: **" +~Daan : .AuthorNote color=purple author="Daan" +~Rich : .AuthorNote color=teal author="Rich" +~Rustan : .AuthorNote color=darkgreen author="Rustan" + +.grammar : .framed padding=1ex margin-left=0ex language=java + +Css Header : body { text-rendering=optimizeLegibility } + + +<style> +.code-escaped .comment-color { color: darkgreen } + +.token.java.string { color: black; font-weight: bold } +.token.java.type { color: black; font-weight: normal } +.token.java.operator, +.token.java.delimiter { color: blue; } +</style> + +~ MathDefs +\newcommand{\F}{\mathcal{F}} +\newcommand{\Equal}{\;\;\;=\;\;\;} +\newcommand{\Equiv}{\;\;\equiv\;\;} +\newcommand{\ES}{\;\;} +\newcommand{\ite}[3]{\textrm{if}\ES #1 \ES\textrm{then}\ES #2 \ES\textrm{else}\ES #3} +\newcommand{\Less}{\ll} +\newcommand{\Imp}{\;\Longrightarrow\;} +\renewcommand{\And}{\;\wedge\;} +\newcommand{\Or}{\;\vee\;} +\newcommand{\FBelow}{\ES\dot{\Rightarrow}\ES} +\newcommand{\least}{^{\downarrow}} +\newcommand{\greatest}{^{\uparrow}} +\newcommand{\Dfrac}[2]{% + \ooalign{% + $\genfrac{}{}{1.8pt}0{#1}{#2}$\cr% + $\color{white}\genfrac{}{}{1pt}0{\phantom{#1}}{\phantom{#2}}$}% +} +\newcommand{\DfracA}[2]{% + \ooalign{% + $\genfrac{}{}{1.2pt}0{#1}{#2}$\cr% + $\color{white}\genfrac{}{}{0.6pt}0{\phantom{#1}}{\phantom{#2}}$}% +} +\newcommand{\false}{\mathit{false}} +\newcommand{\true}{\mathit{true}} +\newcommand{\fib}{\mathit{fib}} +\newcommand{\PDownward}{\mathit{PDownward}} +\newcommand{\iterX}[1]{\hat{#1}} +\newcommand{\IterX}[1]{\check{#1}} +\renewcommand\vec[1]{\overrightarrow{#1}} +\newcommand\cev[1]{\overleftarrow{#1}} +\newcommand{\iterY}[1]{\vec{#1}} +\newcommand{\IterY}[1]{\cev{#1}} +\newcommand{\iter}[1]{{{}^{\flat}\!#1}} +\newcommand{\Iter}[1]{{{}^{\sharp}\!#1}} + +% daan's fractions +\newcommand\xstrut{\vrule height 9.4pt depth 4.6pt width 0pt\relax} +\newcommand\xupstrut{\vrule height 9.4pt depth 0pt width 0pt\relax} + +\renewcommand{\Dfrac}[2]{% + \ooalign{% + % first a thick fraction line + $\genfrac{}{}{1.4pt}1{\displaystyle #1\strut}{\displaystyle #2\strut}$\cr% + % and then a thinner white fraction line on top of it + $\color{white}\genfrac{}{}{0.6pt}1{\phantom{\displaystyle #1\strut}}{\phantom{\displaystyle #2\strut}}$}% +} +\renewcommand{\dfrac}[2]{% + \displaystyle\genfrac{}{}{0.4pt}1{\displaystyle #1}{\displaystyle #2}% +} +~ + +--> + +[TITLE] + +~ Abstract +This is the Dafny reference manual which describes the Dafny programming +language and how to use the Dafny verification system. +Parts of this manual are more tutorial in nature in order to help the +user understand how to do proofs with Dafny. +~ + +[TOC] + + +# Introduction + +Dafny [@Leino:Dafny:LPAR16] is a programming language with built-in specification constructs. +The Dafny static program verifier can be used to verify the functional +correctness of programs. + +The Dafny programming language is designed to support the static +verification of programs. It is imperative, sequential, supports generic +classes, methods and functions, dynamic allocation, inductive and +co-inductive datatypes, and specification constructs. The +specifications include pre- and postconditions, frame specifications +(read and write sets), and termination metrics. To further support +specifications, the language also offers updatable ghost variables, +recursive functions, and types like sets and sequences. Specifications +and ghost constructs are used only during verification; the compiler +omits them from the executable code. + +The Dafny verifier is run as part of the compiler. As such, a programmer +interacts with it much in the same way as with the static type +checker—when the tool produces errors, the programmer responds by +changing the program’s type declarations, specifications, and statements. + +The easiest way to try out [Dafny is in your web browser at +rise4fun](http://rise4fun.com/Dafny)[@Rise4fun:dafny]. Once you get a bit +more serious, you may prefer to [download](http://dafny.codeplex.com/) it +to run it on your machine. Although Dafny can be run from the command +line (on Windows or other platforms), the preferred way to run it is in +Microsoft Visual Studio 2012 (or newer) or using emacs, where the Dafny +verifier runs in the background while the programmer is editing the +program. + +The Dafny verifier is powered +by [Boogie](http://research.microsoft.com/boogie) +[@Boogie:Architecture;@Leino:Boogie2-RefMan;@LeinoRuemmer:Boogie2] +and [Z3](https://github.com/z3prover)[@deMouraBjorner:Z3:overview]. + +From verified programs, the Dafny compiler produces code (`.dll` or +`.exe`) for the .NET platform via intermediate C# files. However, the +facilities for interfacing with other .NET code are minimal. + +This is the reference manual for the Dafny verification system. It is +based on the following references: +[@Leino:Dafny:LPAR16;@MSR:dafny:main; +@MSR:dafny:source;@MSR:dafny:quickref; @LEINO:Dafny:Calc; +@LEINO:Dafny:Coinduction; +and the tutorials at @Rise4fun:dafny] + +The main part of the reference manual is in top down order except for an +initial section that deals with the lowest level constructs. + +[Co-induction Simply]: http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf "Co-induction Simply: Automatic Co-inductive Proofs in a Program Verifier" + +## Dafny Example +To give a flavor of Dafny, here is the solution to a competition problem. + +``` +// VSComp 2010, problem 3, find a 0 in a linked list and return how many +// nodes were skipped until the first 0 (or end-of-list) was found. +// Rustan Leino, 18 August 2010. +// +// The difficulty in this problem lies in specifying what the return +// value 'r' denotes and in proving that the program terminates. Both of +// these are addressed by declaring a ghost field 'List' in each +// linked-list node, abstractly representing the linked-list elements +// from the node to the end of the linked list. The specification can +// now talk about that sequence of elements and can use 'r' as an index +// into the sequence, and termination can be proved from the fact that +// all sequences in Dafny are finite. +// +// We only want to deal with linked lists whose 'List' field is properly +// filled in (which can only happen in an acyclic list, for example). To +// that avail, the standard idiom in Dafny is to declare a predicate +// 'Valid()' that is true of an object when the data structure +// representing object's abstract value is properly formed. The +// definition of 'Valid()' is what one intuitively would think of as the +// ''object invariant'', and it is mentioned explicitly in method pre- +// and postconditions. As part of this standard idiom, one also declared +// a ghost variable 'Repr' that is maintained as the set of objects that +// make up the representation of the aggregate object--in this case, the +// Node itself and all its successors. + +class Node { + ghost var List: seq<int> + ghost var Repr: set<Node> + var head: int + var next: Node + + predicate Valid() + reads this, Repr + { + this in Repr && + 1 <= |List| && List[0] == head && + (next == null ==> |List| == 1) && + (next != null ==> + next in Repr && next.Repr <= Repr && this !in next.Repr && + next.Valid() && next.List == List[1..]) + } + + static method Cons(x: int, tail: Node) returns (n: Node) + requires tail == null || tail.Valid() + ensures n != null && n.Valid() + ensures if tail == null then n.List == [x] + else n.List == [x] + tail.List + { + n := new Node; + n.head, n.next := x, tail; + if (tail == null) { + n.List := [x]; + n.Repr := {n}; + } else { + n.List := [x] + tail.List; + n.Repr := {n} + tail.Repr; + } + } +} + +method Search(ll: Node) returns (r: int) + requires ll == null || ll.Valid() + ensures ll == null ==> r == 0 + ensures ll != null ==> + 0 <= r && r <= |ll.List| && + (r < |ll.List| ==> ll.List[r] == 0 && 0 !in ll.List[..r]) && + (r == |ll.List| ==> 0 !in ll.List) +{ + if (ll == null) { + r := 0; + } else { + var jj,i := ll,0; + while (jj != null && jj.head != 0) + invariant jj != null ==> jj.Valid() && i + |jj.List| == |ll.List| && + ll.List[i..] == jj.List + invariant jj == null ==> i == |ll.List| + invariant 0 !in ll.List[..i] + decreases |ll.List| - i + { + jj := jj.next; + i := i + 1; + } + r := i; + } +} + +method Main() +{ + var list: Node := null; + list := list.Cons(0, list); + list := list.Cons(5, list); + list := list.Cons(0, list); + list := list.Cons(8, list); + var r := Search(list); + print "Search returns ", r, "\n"; + assert r == 1; +} +``` + + +# Lexical and Low Level Grammar +Dafny uses the Coco/R lexer and parser generator for its lexer and parser +(<http://www.ssw.uni-linz.ac.at/Research/Projects/Coco>)[@Linz:Coco]. +The Dafny input file to Coco/R is the `Dafny.atg` file in the source tree. +A Coco/R input file consists of code written in the target language +(⪚ C#) intermixed with these special sections: + +0. The Characters section which defines classes of characters that are used + in defining the lexer (Section [#sec-character-classes]). +1. The Tokens section which defines the lexical tokens (Section [#sec-tokens]). +2. The Productions section which defines the grammar. The grammar productions +are distributed in the later parts of this document in the parts where +those constructs are explained. + +The grammar presented in this document was derived from the `Dafny.atg` +file but has been simplified by removing details that, though needed by +the parser, are not needed to understand the grammar. In particular, the +following transformation have been performed. + +* The semantics actions, enclosed by "(." and ".)", where removed. +* There are some elements in the grammar used for error recovery + ("SYNC"). These were removed. +* There are some elements in the grammar for resolving conflicts + ("IF(b)"). These have been removed. +* Some comments related to Coco/R parsing details have been removed. +* A Coco/R grammar is an attributed grammar where the attributes enable + the productions to have input and output parameters. These attributes + were removed except that boolean input parameters that affect + the parsing are kept. + * In our representation we represent these + in a definition by giving the names of the parameters following + the non-terminal name. For example `entity1(allowsX)`. + * In the case of uses of the parameter, the common case is that the + parameter is just passed to a lower-level non-terminal. In that + case we just give the name, e.g. `entity2(allowsX)`. + * If we want to given an explicit value to a parameter, we specify it in + a keyword notation like this: `entity2(allowsX: true)`. + * In some cases the value to be passed depends on the grammatical context. + In such cases we give a description of the conditions under which the + parameter is true, enclosed in parenthesis. For example: + + `FunctionSignatureOrEllipsis_(allowGhostKeyword: ("method" present))` + + means that the `allowGhostKeyword` parameter is true if the + "method" keyword was given in the associated ``FunctionDecl``. + * Where a parameter affects the parsing of a non-terminal we will + explain the effect of the parameter. + + +The names of character sets and tokens start with a lower case +letter but the names of grammar non-terminals start with +an upper-case letter. + +The grammar uses Extended BNF notation. See the [Coco/R Referenced +manual](http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/Doc/UserManual.pdf) +for details. But in summary: + +* identifiers starting with a lower case letter denote +terminal symbols, +* identifiers starting with an upper case letter denote nonterminal +symbols. +* Strings denote themselves. +* `=` separates the sides of a production, ⪚ `A = a b c` +* In the Coco grammars "." terminates a production, but for readability + in this document a production starts with the defined identifier in + the left margin and may be continued on subsequent lines if they + are indented. +* `|` separates alternatives, ⪚ `a b | c | d e` means `a b` or `c or d e` +* `(` `)` groups alternatives, ⪚ (a | b) c means a c or b c +* `[ ]` option, ⪚ `[a] b` means `a b` or `b` +* `{ }` iteration (0 or more times), ⪚ `{a} b` means `b` or `a b` or `a a b` or ... +* We allow `|` inside `[ ]` and `{ }`. So `[a | b]` is short for `[(a | b)]` + and `{a | b}` is short for `{(a | b)}`. +* The first production defines the name of the grammar, in this case `Dafny`. + +In addition to the Coco rules, for the sake of readability we have adopted +these additional conventions. + +* We allow `-` to be used. `a - b` means it matches if it matches `a` but not `b`. +* To aid in explaining the grammar we have added some additional productions +that are not present in the original grammar. We name these with a trailing +underscore. If you inline these where they are referenced, the result should +let you reconstruct the original grammar. + +**For the convenience of the reader, any references to character sets, +tokens, or grammar non-terminals in this document are hyper-links that +will link to the definition of the entity.** + +## Character Classes +This section defines character classes used later in the token definitions. +In this section backslash is used to start an escape sequence, so for example +'\n' denotes the single linefeed character. + +```` +letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +```` +At present, a letter is an ASCII upper or lowercase letter. Other Unicode letters +are not supported. + +```` +digit = "0123456789" +```` +A digit is just one of the base-10 digits. + +```` +posDigit = "123456789" +```` +A ``posDigit`` is a digit, excluding 0. + +```` +hexdigit = "0123456789ABCDEFabcdef" +```` +A ``hexdigit`` character is a digit or one of the letters from 'A' to 'F' in either case. + +```` +special = "'_?" +```` +The _special_ characters are the characters in addition to alphanumeric characters +that are allowed to appear in a Dafny identifier. These are + +* `"'"` because mathematicians like to put primes on identifiers and some ML + programmers like to start names of type parameters with a "'". +* "_" because computer scientists expect to be able to have underscores in identifiers. +* "?" because it is useful to have "?" at the end of names of predicates, + e.g. "Cons?". + +```` +cr = '\r' +```` +A carriage return character. + +```` +lf = '\n' +```` +A line feed character. + +```` +tab = '\t' +```` +A tab character. + +```` +space = ' ' +```` +A space character. + +```` +nondigitIdChar = letter + special +```` +The characters that can be used in an identifier minus the digits. + +```` +idchar = nondigitIdChar + digit +```` +The characters that can be used in an identifier. + +```` +nonidchar = ANY - idchar +```` +Any character except those that can be used in an identifier. + +```` +charChar = ANY - '\'' - '\\' - cr - lf +```` +Characters that can appear in a character constant. + +```` +stringChar = ANY - '"' - '\\' - cr - lf +```` +Characters that can appear in a string constant. + +```` +verbatimStringChar = ANY - '"' +```` +Characters that can appear in a verbatim string. + +### Comments +Comments are in two forms. + +* They may go from "/*" to "*/" and be nested. +* They may go from "//" to the end of the line. + +## Tokens +As with most languages, Dafny syntax is defined in two levels. First the stream +of input characters is broken up into _tokens_. Then these tokens are parsed +using the Dafny grammar. The Dafny tokens are defined in this section. + +### Reserved Words +The following reserved words appear in the Dafny grammar and may not be used +as identifiers of user-defined entities: + +```` +reservedword = + "abstract" | "array" | "as" | "assert" | "assume" | "bool" | "break" | + "calc" | "case" | "char" | "class" | "codatatype" | "colemma" | + "constructor" | "copredicate" | "datatype" | "decreases" | + "default" | "else" | "ensures" | "exists" | "extends" | "false" | + "forall" | "free" | "fresh" | "function" | "ghost" | "if" | "imap" | "import" | + "in" | "include" | "inductive" | "int" | "invariant" | "iset" | "iterator" | "label" | + "lemma" | "map" | "match" | "method" | "modifies" | "modify" | + "module" | "multiset" | "nat" | "new" | "newtype" | "null" | "object" | + "old" | "opened" | "predicate" | "print" | "protected" | + "reads" | "real" | "refines" | "requires" | "return" | "returns" | "seq" | + "set" | "static" | "string" | "then" | "this" | "trait" | "true" | "type" | + "var" | "where" | "while" | "yield" | "yields" | arrayToken + +arrayToken = "array" [ posDigit { digit }] +```` + +An ``arrayToken`` is a reserved word that denotes an array type of +given rank. `array` is an array type of rank 1 (aka a vector). `array2` +is the type of two-dimensional arrays, etc. + +TODO: Is "_" is reserved word? + +### Identifiers + +```` +ident = nondigitIdChar { idchar } - arraytoken - chartoken - reservedword +```` +In general Dafny identifiers are sequences of ``idChar`` characters where +the first character is a ``nondigitIdChar``. However tokens that fit this pattern +are not identifiers if they look like an array type token, a character literal, +or a reserved work. + +### Digits +```` +digits = digit {['_'] digit} +```` + +A sequence of decimal digits, possibly interspersed with underscores for readability. Example: `1_234_567`. +```` +hexdigits = "0x" hexdigit {['_'] hexdigit} +```` + +A hexadecimal constant, possibly interspersed with underscores for readability. +Example: `0xffff_ffff`. + +```` +decimaldigits = digit {['_'] digit} '.' digit {['_'] digit} +```` +A decimal fraction constant, possibly interspersed with underscores for readability. +Example: `123_456.789_123`. + +### Escaped Character +In this section the "\\" characters are literal. +```` +escapedChar = + ( "\\\'" | "\\"" | "\\\\" | "\\0" | "\\n" | "\\r" | "\\t" + | "\\u" hexdigit hexdigit hexdigit hexdigit + ) +```` + +In Dafny character or string literals escaped characters may be used +to specify the presence of the delimiting quote, or back slash, +or null, or new line, or carriage return or tab, or the +Unicode character with given hexadecimal representation. + +### Character Constant Token +```` +charToken = "'" ( charChar | escapedChar ) "'" +```` + +A character constant is enclosed by "'" and includes either a character +from the ``charChar`` set, or an escaped character. Note that although Unicode +letters are not allowed in Dafny identifiers, Dafny does support Unicode +in its character and string constants and in its data. A character +constant has type `char`. + + +### String Constant Token +```` +stringToken = + '"' { stringChar | escapedChar } '"' + | '@' '"' { verbatimStringChar | '"' '"' } '"' +```` + +A string constant is either a normal string constant or a verbatim string constant. +A normal string constant is enclosed by '"' and can contain characters from the +``stringChar`` set and escapes. + +A verbatim string constant is enclosed between '@"' and '"' and can +consists of any characters (including newline characters) except that two +successive double quotes give a way to escape one quote character inside +the string. + +## Low Level Grammar Productions + +### Identifier Variations + +```` +Ident = ident +```` +The ``Ident`` non-terminal is just an ``ident`` token and represents an ordinary +identifier. + +```` +DotSuffix = + ( ident | digits | "requires" | "reads" ) +```` +When using the _dot_ notation to denote a component of a compound entity +the token following the ".", in addition to being an identifier, +can also be a natural number, or one of the keywords `requires` or `reads`. + +* Digits can be used to name fields of classes and destructors of + datatypes. For example, the built-in tuple datatypes have destructors + named 0, 1, 2, etc. Note that as a field or destructor name, internal + underscores matter, so 10 is different from 1_0. +* `m.requires` is used to denote the precondition for method m. +* `m.reads` is used to denote the things that method m may read. + +```` +NoUSIdent = ident - "_" { idChar } +```` +A ``NoUSIdent`` is an identifier except that identifiers with a **leading** +underscore are not allowed. The names of user-defined entities are +required to be ``NoUSIdent``s. We introduce more mnemonic names +for these below (e.g. ``ClassName``). + +```` +WildIdent = NoUSIdent | "_" +```` +Identifier, disallowing leading underscores, except the "wildcard" +identifier "_". When "_" appears it is replaced by a unique generated +identifier distinct from user identifiers. + +### NoUSIdent Synonyms +In the productions for the declaration of user-defined entities the name of the +user-defined entity is required to be an identifier that does not start +with an underscore, i.e., a ``NoUSIdent``. To make the productions more +mnemonic, we introduce the following synonyms for ``NoUSIdent``. + +```` +ModuleName = NoUSIdent +ClassName = NoUSIdent +TraitName = NoUSIdent +DatatypeName = NoUSIdent +DatatypeMemberName = NoUSIdent +NewtypeName = NoUSIdent +NumericTypeName = NoUSIdent +SynonymTypeName = NoUSIdent +IteratorName = NoUSIdent +TypeVariableName = NoUSIdent +MethodName = NoUSIdent +FunctionName = NoUSIdent +PredicateName = NoUSIdent +CopredicateName = NoUSIdent +LabelName = NoUSIdent +AttributeName = NoUSIdent +FieldIdent = NoUSIdent +```` +A ``FieldIdent`` is one of the ways to identify a field. The other is +using digits. + +### Qualified Names +A qualified name starts with the name of the top-level entity and then is followed by +zero or more ``DotSuffix``s which denote a component. Examples: + +* `Module.MyType1` +* `MyTuple.1` +* `MyMethod.requires` + +The grammar does not actually have a production for qualified names +except in the special case of a qualified name that is known to be +a module name, i.e. a ``QualifiedModuleName``. + +### Identifier-Type Combinations +In this section, we describe some nonterminals that combine an identifier and a type. + +```` +IdentType = WildIdent ":" Type +```` +In Dafny, a variable or field is typically declared by giving its name followed by +a ``colon`` and its type. An ``IdentType`` is such a construct. + +```` +GIdentType(allowGhostKeyword) = [ "ghost" ] IdentType +```` +A ``GIdentType`` is a typed entity declaration optionally preceded by "ghost". The _ghost_ +qualifier means the entity is only used during verification but not in the generated code. +Ghost variables are useful for abstractly representing internal state in specifications. +If `allowGhostKeyword` is false then "ghost" is not allowed. + +```` +LocalIdentTypeOptional = WildIdent [ ":" Type ] +```` +A ``LocalIdentTypeOptional`` is used when declaring local variables. In +such a case a value may be specified for the variable in which case the +type may be omitted because it can be inferred from the initial value. +The initial value value may also be omitted. + +```` +IdentTypeOptional = WildIdent [ ":" Type ] +```` +A ``IdentTypeOptional`` is typically used in a context where the type of the identifier +may be inferred from the context. Examples are in pattern matching or quantifiers. + +```` +TypeIdentOptional = [ "ghost" ] ( NoUSIdent | digits ) ":" ] Type +```` +``TypeIdentOptional``s are used in ``FormalsOptionalIds``. This represents situations +where a type is given but there may not be an identifier. + +```` +FormalsOptionalIds = "(" [TypeIdentOptional { "," TypeIdentOptional } ] ")" +```` +A ``FormalsOptionalIds`` is a formal parameter list in which the types are required +but the names of the parameters is optional. This is used in algebraic +datatype definitions. + +### Numeric Literals +```` +Nat = ( digits | hexdigits ) +```` +A ``Nat`` represents a natural number expressed in either decimal or hexadecimal. + +```` +Dec = (decimaldigits ) +```` +A ``Dec`` represents a decimal fraction literal. + +# Programs +```` +Dafny = { IncludeDirective_ } { TopDecl } EOF +```` +At the top level, a Dafny program (stored as files with extension `.dfy`) +is a set of declarations. The declarations introduce (module-level) +methods and functions, as well as types (classes, traits, inductive and +co-inductive datatypes, new_types, type synonyms, opaque types, and +iterators) and modules, where the order of introduction is irrelevant. A +class also contains a set of declarations, introducing fields, methods, +and functions. + +When asked to compile a program, Dafny looks for the existence of a +Main() method. If a legal Main() method is found, the compiler will emit +a `.EXE`; otherwise, it will emit a `.DLL`. + + (If there is more than one Main(), Dafny will try to emit an .EXE, but + this may cause the C# compiler to complain. One could imagine improving + this functionality so that Dafny will produce a polite error message in + this case.) + +In order to be a legal Main() method, the following must be true: + +* The method takes no parameters +* The method is not a ghost method +* The method has no requires clause +* The method has no modifies clause +* If the method is an instance (that is, non-static) method in a class, + then the enclosing class must not declare any constructor + +Note, however, that the following are allowed: + +* The method is allowed to be an instance method as long as the enclosing + class does not declare any constructor. In this case, the runtime + system will allocate an object of the enclosing class and will invoke + Main() on it. +* The method is allowed to have `ensures` clauses +* The method is allowed to have `decreases` clauses, including a + `decreases *`. (If Main() has a `decreases *`, then its execution may + go on forever, but in the absence of a `decreases *` on Main(), Dafny + will have verified that the entire execution will eventually + terminate.) + +An invocation of Dafny may specify a number of source files. +Each Dafny file follows the grammar of the ``Dafny`` non-terminal. + +It consists of a sequence of optional _include_ directives followed by top +level declarations followed by the end of the file. + +## Include Directives +```` +IncludeDirective_ = "include" stringToken +```` + +Include directives have the form ``"include" stringToken`` where +the string token is either a normal string token or a +verbatim string token. The ``stringToken`` is interpreted as the name of +a file that will be included in the Dafny source. These included +files also obey the ``Dafny`` grammar. Dafny parses and processes the +transitive closure of the original source files and all the included files, +but will not invoke the verifier on these unless they have been listed +explicitly on the command line. + +## Top Level Declarations +```` +TopDecl = { { DeclModifier } + ( SubModuleDecl + | ClassDecl + | DatatypeDecl + | NewtypeDecl + | SynonymTypeDecl + | IteratorDecl + | TraitDecl + | ClassMemberDecl(moduleLevelDecl: true) + } +```` +Top-level declarations may appear either at the top level of a Dafny file, +or within a ``SubModuleDecl``. A top-level declaration is one of the following +types of declarations which are described later. + +The ``ClassDecl``, ``DatatypeDecl``, ``NewtypeDecl``, +``SynonymTypeDecl``, ``IteratorDecl``, and ``TraitDecl`` declarations are +type declarations and are describe in Section [#sec-types]. Ordinarily +``ClassMemberDecl``s appear in class declarations but they can also +appear at the top level. In that case they are included as part of an +implicit top-level class and are implicitly `static` (but cannot be +declared as static). In addition a ``ClassMemberDecl`` that appears at +the top level cannot be a ``FieldDecl``. + +## Declaration Modifiers +```` +DeclModifier = + ( "abstract" | "ghost" | "static" | "protected" + | "extern" [ stringToken] + ) +```` + +Top level declarations may be preceded by zero or more declaration +modifiers. Not all of these are allowed in all contexts. + +The "abstract" modifiers may only be used for module declarations. +An abstract module can leave some entities underspecified. +Abstract modules are not compiled to C#. + +The ghost modifier is used to mark entities as being used for +specification only, not for compilation to code. + +The static modifier is used for class members that that +are associated with the class as a whole rather than with +an instance of the class. + +The protected modifier is used to control the visibility of the +body of functions. + +The extern modifier is used to alter the CompileName of +entities. The CompileName is the name for the entity +when translating to Boogie or C#. + +The following table shows modifiers that are available +for each of the kinds of declaration. In the table +we use already-ghost to denote that the item is not +allowed to have the ghost modifier because it is already +implicitly ghost. + ++--------------------------+---------------------------------------+ +| Declaration | allowed modifiers | ++--------------------------+---------------------------------------+ +| module | abstract | +| class | extern | +| trait | - | +| datatype or codatatype | - | +| field | ghost | +| newtype | - | +| synonym types | - | +| iterators | - | +| method | ghost static extern | +| lemma, colemma, comethod | already-ghost static protected | +| inductive lemma | already-ghost static | +| constructor | - | +| function (non-method) | already-ghost static protected | +| function method | already-ghost static protected extern | +| predicate (non-method) | already-ghost static protected | +| predicate method | already-ghost static protected extern | +| inductive predicate | already-ghost static protected | +| copredicate | already-ghost static protected | ++--------------------------+---------------------------------------+ + + +# Modules + +```` +SubModuleDecl = ( ModuleDefinition_ | ModuleImport_ ) +```` + +Structuring a program by breaking it into parts is an important part of +creating large programs. In Dafny, this is accomplished via _modules_. +Modules provide a way to group together related types, classes, methods, +functions, and other modules together, as well as control the scope of +declarations. Modules may import each other for code reuse, and it is +possible to abstract over modules to separate an implementation from an +interface. + +## Declaring New Modules +```` +ModuleDefinition_ = "module" { Attribute } ModuleName + [ [ "exclusively" ] "refines" QualifiedModuleName ] + "{" { TopDecl } "}" +QualifiedModuleName = Ident { "." Ident } +```` +A qualified name that is known to refer to a module. + +A new module is declared with the `module` keyword, followed by the name +of the new module, and a pair of curly braces ({}) enclosing the body +of the module: + +``` +module Mod { + ... +} +``` + +A module body can consist of anything that you could put at the top +level. This includes classes, datatypes, types, methods, functions, etc. + +``` +module Mod { + class C { + var f: int + method m() + } + datatype Option = A(int) | B(int) + type T + method m() + function f(): int +} +``` + +You can also put a module inside another, in a nested fashion: + +``` +module Mod { + module Helpers { + class C { + method doIt() + var f: int + } + } +} +``` + +Then you can refer to the members of the `Helpers` module within the +`Mod` module by prefixing them with "Helpers.". For example: + +``` +module Mod { + module Helpers { ... } + method m() { + var x := new Helpers.C; + x.doIt(); + x.f := 4; + } +} +``` + +Methods and functions defined at the module level are available like +classes, with just the module name prefixing them. They are also +available in the methods and functions of the classes in the same +module. + +``` +module Mod { + module Helpers { + function method addOne(n: nat): nat { + n + 1 + } + } + method m() { + var x := 5; + x := Helpers.addOne(x); // x is now 6 + } +} +``` + +## Importing Modules +```` +ModuleImport_ = "import" ["opened" ] ModuleName + [ "=" QualifiedModuleName + | "as" QualifiedModuleName ["default" QualifiedModuleName ] + ] + [ ";" ] +```` + +Declaring new submodules is useful, but sometimes you want to refer to +things from an existing module, such as a library. In this case, you +can _import_ one module into another. This is done via the `import` +keyword, and there are a few different forms, each of which has a +different meaning. The simplest kind is the concrete import, and has +the form `import A = B`. This declaration creates a reference to the +module `B` (which must already exist), and binds it to the new name +`A`. Note this new name, i.e. `A`, is only bound in the module containing +the import declaration; it does not create a global alias. For +example, if `Helpers` was defined outside of `Mod`, then we could import +it: + +``` +module Helpers { + ... +} +module Mod { + import A = Helpers + method m() { + assert A.addOne(5) == 6; + } +} +``` + +Note that inside `m()`, we have to use `A` instead of `Helpers`, as we bound +it to a different name. The name `Helpers` is not available inside `m()`, +as only names that have been bound inside `Mod` are available. In order +to use the members from another module, it either has to be declared +there with `module` or imported with `import`. + +We don't have to give `Helpers` a new name, though, if we don't want +to. We can write `import Helpers = Helpers` if we want to, and Dafny +even provides the shorthand `import Helpers` for this behavior. You +can't bind two modules with the same name at the same time, so +sometimes you have to use the = version to ensure the names do not +clash. + +The ``QualifiedModuleName`` in the ``ModuleImport_`` starts with a +sibling module of the importing module, or with a submodule of the +importing module. There is no wya to refer to the parent module, only +sibling modules (and their submodules). + +## Opening Modules + +Sometimes, prefixing the members of the module you imported with the +name is tedious and ugly, even if you select a short name when +importing it. In this case, you can import the module as `opened`, +which causes all of its members to be available without adding the +module name. The `opened` keyword must immediately follow `import`, if it +is present. For example, we could write the previous example as: + +``` +module Mod { + import opened Helpers + method m() { + assert addOne(5) == 6; + } +} +``` + +When opening modules, the newly bound members will have low priority, +so they will be hidden by local definitions. This means if you define +a local function called `addOne`, the function from `Helpers` will no +longer be available under that name. When modules are opened, the +original name binding is still present however, so you can always use +the name that was bound to get to anything that is hidden. + +``` +module Mod { + import opened Helpers + function addOne(n: nat): nat { + n - 1 + } + method m() { + assert addOne(5) == 6; // this is now false, + // as this is the function just defined + assert Helpers.addOne(5) == 6; // this is still true + } +} +``` + +If you open two modules that both declare members with the same name, +then neither member can be referred to without a module prefix, as it +would be ambiguous which one was meant. Just opening the two modules +is not an error, however, as long as you don't attempt to use members +with common names. The `opened` keyword can be used with any kind of +`import` declaration, including the module abstraction form. + +## Module Abstraction + +Sometimes, using a specific implementation is unnecessary; instead, +all that is needed is a module that implements some interface. In +that case, you can use an _abstract_ module import. In Dafny, this is +written `import A as B`. This means bind the name `A` as before, but +instead of getting the exact module `B`, you get any module which is a +_adheres_ of `B`. Typically, the module `B` may have abstract type +definitions, classes with bodyless methods, or otherwise be unsuitable +to use directly. Because of the way refinement is defined, any +refinement of `B` can be used safely. For example, if we start with: + +``` +module Interface { + function method addSome(n: nat): nat + ensures addSome(n) > n +} +module Mod { + import A as Interface + method m() { + assert 6 <= A.addSome(5); + } +} +``` + +then we can be more precise if we know that `addSome` actually adds +exactly one. The following module has this behavior. Further, the +postcondition is stronger, so this is actually a refinement of the +Interface module. + +``` +module Implementation { + function method addSome(n: nat): nat + ensures addSome(n) == n + 1 + { + n + 1 + } +} +``` + +We can then substitute `Implementation` for `A` in a new module, by +declaring a refinement of `Mod` which defines `A` to be `Implementation`. + +``` +module Mod2 refines Mod { + import A = Implementation + ... +} +``` + +You can also give an implementation directly, without introducing a +refinement, by giving a default to the abstract import: + +``` +module Interface { + function method addSome(n: nat): nat + ensures addSome(n) > n +} +module Mod { + import A as Interface default Implementation + method m() { + assert 6 <= A.addSome(5); + } +} +module Implementation { + function method addSome(n: nat): nat + ensures addSome(n) == n + 1 + { + n + 1 + } +} +module Mod2 refines Mod { + import A as Interface default Implementation + ... +} +``` + +Regardless of whether there is a default, the only things known about +`A` in this example is that it has a function `addSome` that returns a +strictly bigger result, so even with the default we still can't prove +that `A.addSome(5) == 6`, only that `6 <= A.addSome(5)`. + +When you refine an abstract import into a concrete one, or giving a +default, Dafny checkes that the concrete module is a +refinement of the abstract one. This means that the methods must have +compatible signatures, all the classes and datatypes with their +constructors and fields in the abstract one must be present in the +concrete one, the specifications must be compatible, etc. + +## Module Ordering and Dependencies + +Dafny isn't particular about which order the modules appear in, but +they must follow some rules to be well formed. As a rule of thumb, +there should be a way to order the modules in a program such that each +only refers to things defined **before** it in the source text. That +doesn't mean the modules have to be given in that order. Dafny will +figure out that order for you, assuming you haven't made any circular +references. For example, this is pretty clearly meaningless: + +``` +import A = B +import B = A +``` + +You can have import statements at the toplevel, and you can import +modules defined at the same level: + +``` +import A = B +method m() { + A.whatever(); +} +module B { ... } +``` + +In this case, everything is well defined because we can put `B` first, +followed by the `A` import, and then finally `m()`. If there is no +ordering, then Dafny will give an error, complaining about a cyclic +dependency. + +Note that when rearranging modules and imports, they have to be kept +in the same containing module, which disallows some pathological +module structures. Also, the imports and submodules are always +considered to be first, even at the toplevel. This means that the +following is not well formed: + +``` +method doIt() { } +module M { + method m() { + doIt(); + } +} +``` + +because the module `M` must come before any other kind of members, such +as methods. To define global functions like this, you can put them in +a module (called `Globals`, say) and open it into any module that needs +its functionality. Finally, if you import via a path, such as `import A += B.C`, then this creates a dependency of `A` on `B`, as we need to know +what `B` is (is it abstract or concrete, or a refinement?). + +## Name Resolution + +When Dafny sees something like `A<T>.B<U>.C<V>`, how does it know what each part +refers to? The process Dafny uses to determine what identifier +sequences like this refer to is name resolution. Though the rules may +seem complex, usually they do what you would expect. Dafny first looks +up the initial identifier. Depending on what the first identifier +refers to, the rest of the identifier is looked up in the appropriate +context. + +In terms of the grammar, sequences like the above are represented as +a ``NameSegment`` followed by 0 or more ``Suffix``es. A ``Suffix`` is +more general and the form shown above would be for when the +``Suffix`` is an ``AugmentedDotSuffix_``. + +The resolution is different depending on whether it is in +an expression context or a type context. + +### Expression Context Name Resolution + +The leading ``NameSegment`` is resolved using the first following +rule that succeeds. + +0. Local variables, parameters and bound variables. These are things like + `x`, `y`, and `i` in `var x;, ... returns (y: int)`, and + `forall i :: ....` The declaration chosen is the match from the + innermost matching scope. + +1. If in a class, try to match a member of the class. If the member that + is found is not static an implicit `this` is inserted. This works for + fields, functions, and methods of the current class (if in a static + context, then only static methods and functions are allowed). You can + refer to fields of the current class either as `this.f` or `f`, + assuming of course that `f` hasn't be hidden by one of the above. You + can always prefix this if needed, which cannot be hidden. (Note, a + field whose name is a string of digits must always have some prefix.) + +2. If there is no ``Suffix``, then look for a datatype constructor, if + unambiguous. Any datatypes that don't need qualification (so the + datatype name itself doesn't need a prefix), and also have a uniquely + named constructor, can be referred to just by its name. So if + `datatype List = Cons(List) | Nil` is the only datatype that declares + `Cons` and `Nil` constructors, then you can write `Cons(Cons(Nil))`. + If the constructor name is not unique, then you need to prefix it with + the name of the datatype (for example `List.Cons(List.Nil)))`. This is + done per constructor, not per datatype. + +3. Look for a member of the enclosing module. + +4. Module-level (static) functions and methods + +TODO: Not sure about the following paragraph. +Opened modules are treated at each level, after the declarations in the +current module. Opened modules only affect steps 2, 3 and 5. If a +ambiguous name is found, an error is generated, rather than continuing +down the list. After the first identifier, the rules are basically the +same, except in the new context. For example, if the first identifier is +a module, then the next identifier looks into that module. Opened modules +only apply within the module it is opened into. When looking up into +another module, only things explicitly declared in that module are +considered. + +To resolve expression `E.id`: + +First resolve expression E and any type arguments. + +* If `E` resolved to a module `M`: + 0. If `E.id<T>` is not followed by any further suffixes, look for + unambiguous datatype constructor. + 1. Member of module M: a sub-module (including submodules of imports), + class, datatype, etc. + 2. Static function or method. +* If `E` denotes a type: + 3. Look up id as a member of that type +* If `E` denotes an expression: + 4. Let T be the type of E. Look up id in T. + +### Type Context Name Resolution + +In a type context the priority of ``NameSegment`` resolution is: + +1. Type parameters. + +2. Member of enclosing module (type name or the name of a module). + +To resolve expression `E.id`: + +* If `E` resolved to a module `M`: + 0. Member of module M: a sub-module (including submodules of imports), + class, datatype, etc. +* If `E` denotes a type: + 1. If `allowDanglingDotName`: Return the type of `E` and the given `E.id`, + letting the caller try to make sense of the final dot-name. + TODO: I don't under this sentence. What is `allowDanglingDotName`? + +# Specifications +Specifications describe logical properties of Dafny methods, functions, +lambdas, iterators and loops. They specify preconditions, postconditions, +invariants, what memory locations may be read or modified, and +termination information by means of _specification clauses_. +For each kind of specification zero or more specification +clauses (of the type accepted for that type of specification) +may be given, in any order. + +We document specifications at these levels: + +- At the lowest level are the various kinds of specification clauses, + e.g. a ``RequiresClause_``. +- Next are the specifications for entities that need them, + e.g. a ``MethodSpec``. +- At the top level are the entity declarations that include + the specifications, e.g. ``MethodDecl``. + +This section documents the first two of these in a bottom-up manner. +We first document the clauses and then the specifications +that use them. + +## Specification Clauses + +### Requires Clause + +```` +RequiresClause_ = + "requires" Expression(allowLemma: false, allowLambda: false) +```` + +The **requires** clauses specify preconditions for methods, +functions, lambda expressions and iterators. Dafny checks +that the preconditions are met at all call sites. The +callee may then assume the preconditions hold on entry. + +If no **requires** clause is specified it is taken to be `true`. + +If more than one **requires** clause is given, then the +precondition is the conjunction of all of the expressions +from all of the **requires** clauses. + +### Ensures Clause + +```` +EnsuresClause_ = + "ensures" { Attribute } Expression(allowLemma: false, allowLambda: false) +ForAllEnsuresClause_ = + "ensures" Expression(allowLemma: false, allowLambda: true) +FunctionEnsuresClause_ = + "ensures" Expression(allowLemma: false, allowLambda: false) +```` + +An **ensures** clause specifies the post condition for a +method, function or iterator. + +If no **ensures** clause is specified it is taken to be `true`. + +If more than one **ensures** clause is given, then the +postcondition is the conjunction of all of the expressions +from all of the **ensures** clauses. + +TODO: In the present sources ``FunctionEnsuresClause_`` differs from +``EnsuresClause_`` only in that it is not allowed to specify +``Attribute``s. This seems like a bug and will likely +be fixed in a future version. + +### Decreases Clause +```` +DecreasesClause_(allowWildcard, allowLambda) = + "decreases" { Attribute } DecreasesList(allowWildcard, allowLambda) +FunctionDecreasesClause_(allowWildcard, allowLambda) = + "decreases" DecreasesList(allowWildcard, allowLambda) +```` + +```` +DecreasesList(allowWildcard, allowLambda) = + PossiblyWildExpression(allowLambda) + { "," PossiblyWildExpression(allowLambda) } +```` +If `allowWildcard` is false but one of the +``PossiblyWildExpression``s is a wild-card, an error is +reported. + +TODO: A ``FunctionDecreasesClause_`` is not allowed to specify +``Attribute``s. this will be fixed in a future version. + +**Decreases** clauses are used to prove termination in the +presence of recursion. if more than one **decreases** clause is given +it is as if a single **decreases** clause had been given with the +collected list of arguments. That is, + +``` +decreases A, B +decreases C, D +``` + +is equivalent to + +``` +decreases A, B, C, D +``` + +If any of the expressions in the **decreases** clause are wild (i.e. "*") +then proof of termination will be skipped. + +Termination metrics in Dafny, which are declared by **decreases** clauses, +are lexicographic tuples of expressions. At each recursive (or mutually +recursive) call to a function or method, Dafny checks that the effective +**decreases** clause of the callee is strictly smaller than the effective +**decreases** clause of the caller. + + What does "strictly smaller" mean? Dafny provides a built-in + well-founded order for every type and, in some cases, between types. For + example, the Boolean "false" is strictly smaller than "true", the + integer 78 is strictly smaller than 102, the set `{2,5}` is strictly + smaller than the set `{2,3,5}`, and for "s" of type `seq<Color>` where + `Color` is some inductive datatype, the color `s[0]` is strictly less than + `s` (provided `s` is nonempty). + +What does "effective decreases clause" mean? Dafny always appends a +"top" element to the lexicographic tuple given by the user. This top +element cannot be syntactically denoted in a Dafny program and it never +occurs as a run-time value either. Rather, it is a fictitious value, +which here we will denote \top, such that each value that can ever occur +in a Dafny program is strictly less than \top. Dafny sometimes also +prepends expressions to the lexicographic tuple given by the user. The +effective decreases clause is any such prefix, followed by the +user-provided decreases clause, followed by \top. We said "user-provided +decreases clause", but if the user completely omits a "decreases" clause, +then Dafny will usually make a guess at one, in which case the effective +decreases clause is any prefix followed by the guess followed by \top. +(If you're using the Dafny IDE in Visual Studio, you can hover the mouse +over the name of a recursive function or method, or the "while" keyword +for a loop, to see the "decreases" clause that Dafny guessed, if any.) + +Here is a simple but interesting example: the Fibonacci function. + +``` +function Fib(n: nat) : nat +{ + if n < 2 then n else Fib(n-2) + Fib(n-1) +} + +``` + +In this example, if you hover your mouse over the function name +you will see that Dafny has supplied a `**decreases** n` clause. + +Let's take a look at the kind of example where a mysterious-looking +decreases clause like "Rank, 0" is useful. + +Consider two mutually recursive methods, `A` and `B`: +``` +method A(x: nat) +{ + B(x); +} + +method B(x: nat) +{ + if x != 0 { A(x-1); } +} +``` + +To prove termination of `A` and `B`, Dafny needs to have effective +decreases clauses for A and B such that: + +* the measure for the callee `B(x)` is strictly smaller than the measure + for the caller `A(x)`, and + +* the measure for the callee `A(x-1)` is strictly smaller than the measure + for the caller `B(x)`. + +Satisfying the second of these conditions is easy, but what about the +first? Note, for example, that declaring both `A` and `B` with "decreases x" +does not work, because that won't prove a strict decrease for the call +from `A(x)` to `B(x)`. + +Here's one possibility (for brevity, we will omit the method bodies): +``` +method A(x: nat) + decreases x, 1 + +method B(x: nat) + decreases x, 0 +``` + +For the call from `A(x)` to `B(x)`, the lexicographic tuple `"x, 0"` is +strictly smaller than `"x, 1"`, and for the call from `B(x)` to `A(x-1)`, the +lexicographic tuple `"x-1, 1"` is strictly smaller than `"x, 0"`. + + Two things to note: First, the choice of "0" and "1" as the second + components of these lexicographic tuples is rather arbitrary. It could + just as well have been "false" and "true", respectively, or the sets + `{2,5}` and `{2,3,5}`. Second, the keyword **decreases** often gives rise to + an intuitive English reading of the declaration. For example, you might + say that the recursive calls in the definition of the familiar Fibonacci + function `Fib(n)` "decreases n". But when the lexicographic tuple contains + constants, the English reading of the declaration becomes mysterious and + may give rise to questions like "how can you decrease the constant 0?". + The keyword is just that---a keyword. It says "here comes a list of + expressions that make up the lexicographic tuple we want to use for the + termination measure". What is important is that one effective decreases + clause is compared against another one, and it certainly makes sense to + compare something to a constant (and to compare one constant to + another). + + We can simplify things a little bit by remembering that Dafny appends + \top to the user-supplied decreases clause. For the A-and-B example, + this lets us drop the constant from the **decreases** clause of A: + +``` + method A(x: nat) + decreases x + +method B(x: nat) + decreases x, 0 +``` + +The effective decreases clause of `A` is `"x, \top"` and the effective +decreases clause of `B` is `"x, 0, \top"`. These tuples still satisfy the two +conditions `(x, 0, \top) < (x, \top)` and `(x-1, \top) < (x, 0, \top)`. And +as before, the constant "0" is arbitrary; anything less than \top (which +is any Dafny expression) would work. + +Let's take a look at one more example that better illustrates the utility +of `\top`. Consider again two mutually recursive methods, call them `Outer` +and `Inner`, representing the recursive counterparts of what iteratively +might be two nested loops: +``` +method Outer(x: nat) +{ + // set y to an arbitrary non-negative integer + var y :| 0 <= y; + Inner(x, y); +} + +method Inner(x: nat, y: nat) +{ + if y != 0 { + Inner(x, y-1); + } else if x != 0 { + Outer(x-1); + } +} +``` +The body of `Outer` uses an assign-such-that statement to represent some +computation that takes place before `Inner` is called. It sets "y" to some +arbitrary non-negative value. In a more concrete example, `Inner` would do +some work for each "y" and then continue as `Outer` on the next smaller +"x". + +Using a **decreases** clause `"x, y"` for `Inner` seems natural, but if +we don't have any bound on the size of the `"y"` computed by `Outer`, +there is no expression we can write in **decreases** clause of `Outer` +that is sure to lead to a strictly smaller value for `"y"` when `Inner` +is called. `\top` to the rescue. If we arrange for the effective +decreases clause of `Outer` to be `"x, \top"` and the effective decreases +clause for `Inner` to be `"x, y, \top"`, then we can show the strict +decreases as required. Since `\top` is implicitly appended, the two +decreases clauses declared in the program text can be: +``` +method Outer(x: nat) + decreases x + +method Inner(x: nat, y: nat) + decreases x, y +``` +Moreover, remember that if a function or method has no user-declared +**decreases** clause, Dafny will make a guess. The guess is (usually) +the list of arguments of the function/method, in the order given. This is +exactly the decreases clauses needed here. Thus, Dafny successfully +verifies the program without any explicit decreases clauses: +``` +method Outer(x: nat) +{ + var y :| 0 <= y; + Inner(x, y); +} + +method Inner(x: nat, y: nat) +{ + if y != 0 { + Inner(x, y-1); + } else if x != 0 { + Outer(x-1); + } +} +``` +The ingredients are simple, but the end result may seem like magic. For many users, however, there may be no magic at all -- the end result may be so natural that the user never even has to bothered to think about that there was a need to prove termination in the first place. + + +### Framing +```` +FrameExpression(allowLemma, allowLambda) = + ( Expression(allowLemma, allowLambda) [ FrameField ] + | FrameField ) +```` + +```` +FrameField = "`" Ident +```` + +```` +PossiblyWildFrameExpression(allowLemma) = + ( "*" | FrameExpression(allowLemma, allowLambda: false) ) +```` + +Frame expressions are used to denote the set of memory locations +that a Dafny program element may read or write. A frame +expression is a set expression. The form `{}` (that is, the empty set) +says that no memory locations may be modified, +which is also the default if no **modifies** clause is given explicitly. + +Note that framing only applies to the heap, or memory accessed through +references. Local variables are not stored on the heap, so they cannot be +mentioned (well, they are not in scope in the declaration) in reads +annotations. Note also that types like sets, sequences, and multisets are +value types, and are treated like integers or local variables. Arrays and +objects are reference types, and they are stored on the heap (though as +always there is a subtle distinction between the reference itself and the +value it points to.) + +The ``FrameField`` construct is used to specify a field of a +class object. The identifier following the back-quote is the +name of the field being referenced. +If the `FrameField` is preceded by an expression the expression +must be a reference to an object having that field. +If the `FrameField` is not preceded by an expression then +the frame expression is referring to that field of the current +object. This form is only used from a method of a class. + +The use of ``FrameField`` is discouraged as in practice it has not +been shown to either be more concise or to perform better. +Also, there's (unfortunately) no form of it for array +elements---one could imagine + +``` + modifies a`[j] +``` +Also, ``FrameField`` is not taken into consideration for +lambda expressions. + +### Reads Clause +```` +FunctionReadsClause_ = + "reads" + PossiblyWildFrameExpression (allowLemma: false) + { "," PossiblyWildFrameExpression(allowLemma: false) } +LambdaReadsClause_ = + "reads" PossiblyWildFrameExpression(allowLemma: true) +IteratorReadsClause_ = + "reads" { Attribute } + FrameExpression(allowLemma: false, allowLambda: false) + { "," FrameExpression(allowLemma: false, allowLambda: false) } +PossiblyWildExpression(allowLambda) = + ( "*" | Expression(allowLemma: false, allowLambda) ) +```` + +Functions are not allowed to have side effects but may be restricted in +what they can read. The _reading frame_ of a function (or predicate) is all +the memory locations that the function is allowed to read. The reason we +might limit what a function can read is so that when we write to memory, +we can be sure that functions that did not read that part of memory have +the same value they did before. For example, we might have two arrays, +one of which we know is sorted. If we did not put a reads annotation on +the sorted predicate, then when we modify the unsorted array, we cannot +determine whether the other array stopped being sorted. While we might be +able to give invariants to preserve it in this case, it gets even more +complex when manipulating data structures. In this case, framing is +essential to making the verification process feasible. + +It is not just the body of a function that is subject to **reads** +checks, but also its precondition and the **reads** clause itself. + +A reads clause can list a wildcard ("*"), which allows the enclosing +function to read anything. In many cases, and in particular in all cases +where the function is defined recursively, this makes it next to +impossible to make any use of the function. Nevertheless, as an +experimental feature, the language allows it (and it is sound). +Note that a "*" makes the rest of the frame expression irrelevant. + +A **reads** clause specifies the set of memory locations that a function, +lambda, or iterator may read. If more than one **reads** clause is given +in a specification the effective read set is the union of the sets +specified. If there are no **reads** clauses the effective read set is +empty. If `"*"` is given in a **reads** clause it means any memory may be +read. + +TODO: It would be nice if the different forms of read clauses could be +combined. In a future version the single form of read clause will allow +a list and attributes. + +### Modifies Clause + +```` +ModifiesClause_ = + "modifies" { Attribute } + FrameExpression(allowLemma: false, allowLambda: false) + { "," FrameExpression(allowLemma: false, allowLambda: false) } +```` + +Frames also affect methods. As you might have guessed, methods are not +required to list the things they read. Methods are allowed to read +whatever memory they like, but they are required to list which parts of +memory they modify, with a modifies annotation. They are almost identical +to their reads cousins, except they say what can be changed, rather than +what the value of the function depends on. In combination with reads, +modification restrictions allow Dafny to prove properties of code that +would otherwise be very difficult or impossible. Reads and modifies are +one of the tools that allow Dafny to work on one method at a time, +because they restrict what would otherwise be arbitrary modifications of +memory to something that Dafny can reason about. + +Note that fields of newly allocated objects can always be modified. + +It is also possible to frame what can be modified by a block statement +by means of the block form of the +[modify statement](#sec-modify-statement) (Section [#sec-modify-statement]). + +A **modifies** clause specifies the set of memory locations that a +method, iterator or loop body may modify. If more than one **modifies** +clause is given in a specification, the effective modifies set is the +union of the sets specified. If no **modifies** clause is given the +effective modifies set is empty. A loop can also have a +**modifies** clause. If none is given, the loop gets to modify anything +the enclosing context is allowed to modify. + +### Invariant Clause +```` +InvariantClause_ = + "invariant" { Attribute } + Expression(allowLemma: false, allowLambda: true) +```` + +An **invariant** clause is used to specify an invariant +for a loop. If more than one **invariant** clause is given for +a loop the effective invariant is the conjunction of +the conditions specified. + +The invariant must hold on entry to the loop. And assuming it +is valid on entry, Dafny must be able to prove that it then +holds at the end of the loop. + +## Method Specification +```` +MethodSpec = + { ModifiesClause_ + | RequiresClause_ + | EnsuresClause_ + | DecreasesClause_(allowWildcard: true, allowLambda: false) + } +```` + +A method specification is zero or more **modifies**, **requires**, +**ensures** or **decreases** clauses, in any order. +A method does not have **reads** clauses because methods are allowed to +read any memory. + +## Function Specification +```` +FunctionSpec = + { RequiresClause_ + | FunctionReadsClause_ + | FunctionEnsuresClause_ + | FunctionDecreasesClause_(allowWildcard: false, allowLambda: false) + } +```` + +A function specification is zero or more **reads**, **requires**, +**ensures** or **decreases** clauses, in any order. A function +specification does not have **modifies** clauses because functions are not +allowed to modify any memory. + +## Lambda Specification +```` +LambdaSpec_ = + { LambdaReadsClause_ + | RequiresClause_ + } +```` + +A lambda specification is zero or more **reads** or **requires** clauses. +Lambda specifications do not have **ensures** clauses because the body +is never opaque. +Lambda specifications do not have **decreases** +clauses because they do not have names and thus cannot be recursive. A +lambda specification does not have **modifies** clauses because lambdas +are not allowed to modify any memory. + +## Iterator Specification +```` +IteratorSpec = + { IteratorReadsClause_ + | ModifiesClause_ + | [ "yield" ] RequiresClause_ + | [ "yield" ] EnsuresClause_ + | DecreasesClause_(allowWildcard: false, allowLambda: false) + } +```` + +An iterator specification applies both to the iterator's constructor +method and to its `MoveNext` method. The **reads** and **modifies** +clauses apply to both of them. For the **requires** and **ensures** +clauses, if `yield` is not present they apply to the constructor, +but if `yield` is present they apply to the `MoveNext` method. + +TODO: What is the meaning of a **decreases** clause on an iterator? +Does it apply to `MoveNext`? Make sure our description of +iterators explains these. + +TODO: What is the relationship between the post condition and +the `Valid()` predicate? + +## Loop Specification +```` +LoopSpec = + { InvariantClause_ + | DecreasesClause_(allowWildcard: true, allowLambda: true) + | ModifiesClause_ + } +```` + +A loop specification provides the information Dafny needs to +prove properties of a loop. The ``InvariantClause_`` clause +is effectively a precondition and it along with the +negation of the loop test condition provides the postcondition. +The ``DecreasesClause_`` clause is used to prove termination. + +# Types +```` +Type = DomainType [ "->" Type ] +```` +A Dafny type is a domain type (i.e. a type that can be the domain of a +function type) optionally followed by an arrow and a range type. + +```` +DomainType = + ( BoolType_ | CharType_ | NatType_ | IntType_ | RealType_ | ObjectType_ + | FiniteSetType_ | InfiniteSetType_ | MultisetType_ + | SequenceType_ | StringType_ + | FiniteMapType_ | InfiniteMapType_ | ArrayType_ + | TupleType_ | NamedType_ ) +```` +The domain types comprise the builtin scalar types, the builtin +collection types, tuple types (including as a special case +a parenthesized type) and reference types. + + +Dafny types may be categorized as either value types or reference types. + +## Value Types +The value types are those whose values do not lie in the program heap. +These are: + +* The basic scalar types: `bool`, `char`, `nat`, `int`, `real` +* The built-in collection types: `set`, `multiset`, `seq`, `string`, `map`, `imap` +* Tuple Types +* Inductive and co-inductive types + +Data items having value types are passed by value. Since they are not +considered to occupy _memory_, framing expressions do not reference them. + +## Reference Types +Dafny offers a host of _reference types_. These represent +_references_ to objects allocated dynamically in the program heap. To +access the members of an object, a reference to (that is, a _pointer_ +to or _object identity_ of) the object is _dereferenced_. + +The reference types are class types, traits and array types. + +The special value `null` is part of every reference +type.[^fn-nullable] + +[^fn-nullable]: This will change in a future version of Dafny that + will support both nullable and (by default) non-null reference + types. + +## Named Types +```` +NamedType_ = NameSegmentForTypeName { "." NameSegmentForTypeName } +```` + +A ``NamedType_`` is used to specify a user-defined type by name +(possibly module-qualified). Named types are introduced by +class, trait, inductive, co-inductive, synonym and opaque +type declarations. They are also used to refer to type variables. + +```` +NameSegmentForTypeName = Ident [ GenericInstantiation ] +```` +A ``NameSegmentForTypeName`` is a type name optionally followed by a +``GenericInstantiation`` which supplies type parameters to a generic +type, if needed. It is a special case of a ``NameSegment`` +(See Section [#sec-name-segment]) +that does not allow a ``HashCall``. + +The following sections describe each of these kinds of types in more detail. + +# Basic types + +Dafny offers these basic types: `bool` for booleans, `char` for +characters, `int` and `nat` for integers, and `real` for reals. + +## Booleans +```` +BoolType_ = "bool" +```` + +There are two boolean values and each has a corresponding literal in +the language: `false` and `true`. + +In addition to equality (`==`) and disequality (`!=`), which are +defined on all types, type `bool` supports the following operations: + ++--------------------+------------------------------------+ +| operator | description | ++--------------------+------------------------------------+ +| `<==>` | equivalence (if and only if) | ++--------------------+------------------------------------+ +| `==>` | implication (implies) | +| `<==` | reverse implication (follows from) | ++--------------------+------------------------------------+ +| `&&` | conjunction (and) | +| [\|\|]{.monospace} | disjunction (or) | ++--------------------+------------------------------------+ +| `!` | negation (not) | ++--------------------+------------------------------------+ + +Negation is unary; the others are binary. The table shows the operators +in groups of increasing binding power, with equality binding stronger +than conjunction and disjunction, and weaker than negation. Within +each group, different operators do not associate, so parentheses need +to be used. For example, +``` +A && B || C // error +``` +would be ambiguous and instead has to be written as either +``` +(A && B) || C +``` +or +``` +A && (B || C) +``` +depending on the intended meaning. + +### Equivalence Operator +The expressions `A <==> B` and `A == B` give the same value, but note +that `<==>` is _associative_ whereas `==` is _chaining_. So, +``` +A <==> B <==> C +``` +is the same as +``` +A <==> (B <==> C) +``` +and +``` +(A <==> B) <==> C +``` +whereas +``` +A == B == C +``` +is simply a shorthand for +``` +A == B && B == C +``` + +### Conjunction and Disjunction +Conjunction is associative and so is disjunction. These operators are +_short circuiting (from left to right)_, meaning that their second +argument is evaluated only if the evaluation of the first operand does +not determine the value of the expression. Logically speaking, the +expression `A && B` is defined when `A` is defined and either `A` +evaluates to `false` or `B` is defined. When `A && B` is defined, its +meaning is the same as the ordinary, symmetric mathematical +conjunction ∧. The same holds for `||` and ∨. + +### Implication and Reverse Implication +Implication is _right associative_ and is short-circuiting from left +to right. Reverse implication `B <== A` is exactly the same as +`A ==> B`, but gives the ability to write the operands in the opposite +order. Consequently, reverse implication is _left associative_ and is +short-circuiting from _right to left_. To illustrate the +associativity rules, each of the following four lines expresses the +same property, for any `A`, `B`, and `C` of type `bool`: +``` +A ==> B ==> C +A ==> (B ==> C) // parentheses redundant, since ==> is right associative +C <== B <== A +(C <== B) <== A // parentheses redundant, since <== is left associative +``` +To illustrate the short-circuiting rules, note that the expression +`a.Length` is defined for an array `a` only if `a` is not `null` (see +Section [#sec-reference-types]), which means the following two +expressions are well-formed: +``` +a != null ==> 0 <= a.Length +0 <= a.Length <== a != null +``` +The contrapositive of these two expressions would be: +``` +a.Length < 0 ==> a == null // not well-formed +a == null <== a.Length < 0 // not well-formed +``` +but these expressions are not well-formed, since well-formedness +requires the left (and right, respectively) operand, `a.Length < 0`, +to be well-formed by itself. + +Implication `A ==> B` is equivalent to the disjunction `!A || B`, but +is sometimes (especially in specifications) clearer to read. Since, +`||` is short-circuiting from left to right, note that +``` +a == null || 0 <= a.Length +``` +is well-formed, whereas +``` +0 <= a.Length || a == null // not well-formed +``` +is not. + +In addition, booleans support _logical quantifiers_ (forall and +exists), described in section [#sec-quantifier-expression]. + + +## Numeric types + +```` +IntType_ = "int" +RealType_ = "real" +```` + +Dafny supports _numeric types_ of two kinds, _integer-based_, which +includes the basic type `int` of all integers, and _real-based_, which +includes the basic type `real` of all real numbers. User-defined +numeric types based on `int` and `real`, called _newtypes_, are +described in Section [#sec-newtypes]. Also, the _subset type_ +`nat`, representing the non-negative subrange of `int`, is described +in Section [#sec-subset-types]. + +The language includes a literal for each non-negative integer, like +`0`, `13`, and `1985`. Integers can also be written in hexadecimal +using the prefix "`0x`", as in `0x0`, `0xD`, and `0x7c1` (always with +a lower case `x`, but the hexadecimal digits themselves are case +insensitive). Leading zeros are allowed. To form negative integers, +use the unary minus operator. + +There are also literals for some of the non-negative reals. These are +written as a decimal point with a nonempty sequence of decimal digits +on both sides. For example, `1.0`, `1609.344`, and `0.5772156649`. + +For integers (in both decimal and hexadecimal form) and reals, +any two digits in a literal may be separated by an underscore in order +to improve human readability of the literals. For example: +``` +1_000_000 // easier to read than 1000000 +0_12_345_6789 // strange but legal formatting of 123456789 +0x8000_0000 // same as 0x80000000 -- hex digits are often placed in groups of 4 +0.000_000_000_1 // same as 0.0000000001 -- 1 \([Ångström]{.comment-color}\) +``` + +In addition to equality and disequality, numeric types +support the following relational operations: + ++-----------------+------------------------------------+ +| operator | description | ++-----------------+------------------------------------+ +| [<]{.monospace} | less than | +| `<=` | at most | +| `>=` | at least | +| `>` | greater than | ++-----------------+------------------------------------+ + +Like equality and disequality, these operators are chaining, as long +as they are chained in the "same direction". That is, +``` +A <= B < C == D <= E +``` +is simply a shorthand for +``` +A <= B && B < C && C == D && D <= E +``` +whereas +``` +A < B > C +``` +is not allowed. + +There are also operators on each numeric type: + ++---------------+------------------------------------+ +| operator | description | ++---------------+------------------------------------+ +| `+` | addition (plus) | +| `-` | subtraction (minus) | ++---------------+------------------------------------+ +| `*` | multiplication (times) | +| `/` | division (divided by) | +| `%` | modulus (mod) | ++---------------+------------------------------------+ +| `-` | negation (unary minus) | ++---------------+------------------------------------+ + +The binary operators are left associative, and they associate with +each other in the two groups. The groups are listed in order of +increasing binding power, with equality binding more strongly than the +multiplicative operators and weaker than the unary operator. +Modulus is supported only for integer-based numeric types. Integer +division and modulus are the _Euclidean division and modulus_. This +means that modulus always returns a non-negative, regardless of the +signs of the two operands. More precisely, for any integer `a` and +non-zero integer `b`, +``` +a == a / b * b + a % b +0 <= a % b < B +``` +where `B` denotes the absolute value of `b`. + +Real-based numeric types have a member `Trunc` that returns the +_floor_ of the real value, that is, the largest integer not exceeding +the real value. For example, the following properties hold, for any +`r` and `r'` of type `real`: +``` +3.14.Trunc == 3 +(-2.5).Trunc == -3 +-2.5.Trunc == -2 +real(r.Trunc) <= r +r <= r' ==> r.Trunc <= r'.Trunc +``` +Note in the third line that member access (like `.Trunc`) binds +stronger than unary minus. The fourth line uses the conversion +function `real` from `int` to `real`, as described in Section +[#sec-numeric-conversion-operations]. + +## Characters + +```` +CharType_ = "char" +```` + +Dafny supports a type `char` of _characters_. Character literals are +enclosed in single quotes, as in `'D'`. Their form is described +by the ``charToken`` nonterminal in the grammar. To write a single quote as a +character literal, it is necessary to use an _escape sequence_. +Escape sequences can also be used to write other characters. The +supported escape sequences are as follows: + ++--------------------+------------------------------------------------------------+ +| escape sequence | meaning | ++--------------------+------------------------------------------------------------+ +| `\'` | the character `'` | +| [\\\"]{.monospace} | the character [\"]{.monospace} | +| `\\` | the character `\` | +| `\0` | the null character, same as `\u0000` | +| `\n` | line feed | +| `\r` | carriage return | +| `\t` | horizontal tab | +| `\u\(_xxxx_\)` | universal character whose hexadecimal code is `\(_xxxx_\)` | ++--------------------+------------------------------------------------------------+ + +The escape sequence for a double quote is redundant, because +[\'\"\']{.monospace} and [\'\\\"\']{.monospace} denote the same +character---both forms are provided in order to support the same +escape sequences as for string literals (Section [#sec-strings]). +In the form `\u\(_xxxx_\)`, the `u` is always lower case, but the four +hexadecimal digits are case insensitive. + +Character values are ordered and can be compared using the standard +relational operators: + ++-----------------+------------------------------------+ +| operator | description | ++-----------------+------------------------------------+ +| [<]{.monospace} | less than | +| `<=` | at most | +| `>=` | at least | +| `>` | greater than | ++-----------------+------------------------------------+ + +Sequences of characters represent _strings_, as described in Section +[#sec-strings]. + +The only other operations on characters are obtaining a character +by indexing into a string, and the implicit conversion to string +when used as a parameter of a `print` statement. + +TODO: Are there any conversions between `char` values and numeric values? + +# Type parameters + +```` +GenericParameters = "<" TypeVariableName [ "(" "==" ")" ] + { "," TypeVariableName [ "(" "==" ")" ] } ">" +```` +Many of the types (as well as functions and methods) in Dafny can be +parameterized by types. These _type parameters_ are typically +declared inside angle brackets and can stand for any type. + +It is sometimes necessary to restrict these type parameters so that +they can only be instantiated by certain families of types. As such, +Dafny distinguishes types that support the equality operation +not only in ghost contexts but also in compiled contexts. To indicate +that a type parameter is restricted to such _equality supporting_ +types, the name of the type parameter takes the suffix +"`(==)`".[^fn-type-mode] For example, +``` +method Compare<T(==)>(a: T, b: T) returns (eq: bool) +{ + if a == b { eq := true; } else { eq := false; } +} +``` +is a method whose type parameter is restricted to equality-supporting +types. Again, note that _all_ types support equality in _ghost_ +contexts; the difference is only for non-ghost (that is, compiled) +code. Co-inductive datatypes, function types, as well as inductive +datatypes with ghost parameters are examples of types that are not +equality supporting. + +[^fn-type-mode]: Being equality-supporting is just one of many + _modes_ that one can imagine types in a rich type system to have. + For example, other modes could include having a total order, + being zero-initializable, and possibly being uninhabited. If + Dafny were to support more modes in the future, the "`(\( \))`"-suffix + syntax may be extended. For now, the suffix can only indicate the + equality-supporting mode. + +Dafny has some inference support that makes certain signatures less +cluttered (described in a different part of the Dafny language +reference). In some cases, this support will +infer that a type parameter must be restricted to equality-supporting +types, in which case Dafny adds the "`(==)`" automatically. + +TODO: Need to describe type inference somewhere. + +# Generic Instantiation +```` +GenericInstantiation = "<" Type { "," Type } ">" +```` +When a generic entity is used, actual types must be specified for each +generic parameter. This is done using a ``GenericInstantiation``. +If the `GenericInstantiation` is omitted, type inference will try +to fill these in. + +# Collection types + +Dafny offers several built-in collection types. + +## Sets +```` +FiniteSetType_ = "set" [ GenericInstantiation ] +InfiniteSetType_ = "iset" [ GenericInstantiation ] +```` + +For any type `T`, each value of type `set<T>` is a finite set of +`T` values. + +TODO: +Set membership is determined by equality in the type `T`, +so `set<T>` can be used in a non-ghost context only if `T` is equality +supporting. + +For any type `T`, each value of type `iset<T>` is a potentially infinite +set of `T` values. + +A set can be formed using a _set display_ expression, which is a +possibly empty, unordered, duplicate-insensitive list of expressions +enclosed in curly braces. To illustrate, +``` +{} {2, 7, 5, 3} {4+2, 1+5, a*b} +``` +are three examples of set displays. There is also a _set comprehension_ +expression (with a binder, like in logical quantifications), described in +section [#sec-set-comprehension-expressions]. + +In addition to equality and disequality, set types +support the following relational operations: + ++-----------------+------------------------------------+ +| operator | description | ++-----------------+------------------------------------+ +| [<]{.monospace} | proper subset | +| `<=` | subset | +| `>=` | superset | +| `>` | proper superset | ++-----------------+------------------------------------+ + +Like the arithmetic relational operators, these operators are +chaining. + +Sets support the following binary operators, listed in order of +increasing binding power: + ++---------------+------------------------------------+ +| operator | description | ++---------------+------------------------------------+ +| `!!` | disjointness | ++---------------+------------------------------------+ +| `+` | set union | +| `-` | set difference | ++---------------+------------------------------------+ +| `*` | set intersection | ++---------------+------------------------------------+ + +The associativity rules of `+`, `-`, and `*` are like those of the +arithmetic operators with the same names. The expression `A !! B`, +whose binding power is the same as equality (but which neither +associates nor chains with equality), says that sets `A` and `B` have +no elements in common, that is, it is equivalent to +``` +A * B == {} +``` +However, the disjointness operator is chaining, so `A !! B !! C !! D` +means: +``` +A * B == {} && (A + B) * C == {} && (A + B + C) * D == {} +``` + +In addition, for any set `s` of type `set<T>` or `iset<T>` and any +expression `e` of type `T`, sets support the following operations: + ++---------------------+------------------------------------+ +| expression | description | ++---------------------+------------------------------------+ +| [\|s\|]{.monospace} | set cardinality | +| `e in s` | set membership | +| `e !in s` | set non-membership | ++---------------------+------------------------------------+ + +The expression `e !in s` is a syntactic shorthand for `!(e in s)`. + +## Multisets +```` +MultisetType_ = "multiset" [ GenericInstantiation ] +```` + +A _multiset_ is similar to a set, but keeps track of the multiplicity +of each element, not just its presence or absence. For any type `T`, +each value of type `multiset<T>` is a map from `T` values to natural +numbers denoting each element's multiplicity. Multisets in Dafny +are finite, that is, they contain a finite number of each of a finite +set of elements. Stated differently, a multiset maps only a finite +number of elements to non-zero (finite) multiplicities. + +Like sets, multiset membership is determined by equality in the type +`T`, so `multiset<T>` can be used in a non-ghost context only if `T` +is equality supporting. + +A multiset can be formed using a _multiset display_ expression, which +is a possibly empty, unordered list of expressions enclosed in curly +braces after the keyword `multiset`. To illustrate, +``` +multiset{} multiset{0, 1, 1, 2, 3, 5} multiset{4+2, 1+5, a*b} +``` +are three examples of multiset displays. There is no multiset +comprehension expression. + +In addition to equality and disequality, multiset types +support the following relational operations: + ++-----------------+------------------------------------+ +| operator | description | ++-----------------+------------------------------------+ +| [<]{.monospace} | proper multiset subset | +| `<=` | multiset subset | +| `>=` | multiset superset | +| `>` | proper multiset superset | ++-----------------+------------------------------------+ + +Like the arithmetic relational operators, these operators are +chaining. + +Multisets support the following binary operators, listed in order of +increasing binding power: + ++---------------+------------------------------------+ +| operator | description | ++---------------+------------------------------------+ +| `!!` | multiset disjointness | ++---------------+------------------------------------+ +| `+` | multiset union | +| `-` | multiset difference | ++---------------+------------------------------------+ +| `*` | multiset intersection | ++---------------+------------------------------------+ + +The associativity rules of `+`, `-`, and `*` are like those of the +arithmetic operators with the same names. The `+` operator +adds the multiplicity of corresponding elements, the `-` operator +subtracts them (but 0 is the minimum multiplicity), +and the `*` has multiplicity that is the minimum of the +multiplicity of the operands. + +The expression `A !! B` +says that multisets `A` and `B` have no elements in common, that is, +it is equivalent to +``` +A * B == multiset{} +``` +Like the analogous set operator, `!!` is chaining. + +In addition, for any multiset `s` of type `multiset<T>`, +expression `e` of type `T`, and non-negative integer-based numeric +`n`, multisets support the following operations: + ++---------------------+------------------------------------------+ +| expression | description | ++---------------------+------------------------------------------+ +| [\|s\|]{.monospace} | multiset cardinality | +| `e in s` | multiset membership | +| `e !in s` | multiset non-membership | +| `s[e]` | multiplicity of `e` in `s` | +| `s[e := n]` | multiset update (change of multiplicity) | ++---------------------+------------------------------------------+ + +The expression `e in s` returns `true` if and only if `s[e] != 0`. +The expression `e !in s` is a syntactic shorthand for `!(e in s)`. +The expression `s[e := n]` denotes a multiset like +`s`, but where the multiplicity of element `e` is `n`. Note that +the multiset update `s[e := 0]` results in a multiset like `s` but +without any occurrences of `e` (whether or not `s` has occurrences of +`e` in the first place). As another example, note that +`s - multiset{e}` is equivalent to: +``` +if e in s then s[e := s[e] - 1] else s +``` + +## Sequences +```` +SequenceType_ = "seq" [ GenericInstantiation ] +```` + +For any type `T`, a value of type `seq<T>` denotes a _sequence_ of `T` +elements, that is, a mapping from a finite downward-closed set of natural +numbers (called _indices_) to `T` values. (Thinking of it as a map, +a sequence is therefore something of a dual of a multiset.) + +### Sequence Displays +A sequence can be formed using a _sequence display_ expression, which +is a possibly empty, ordered list of expressions enclosed in square +brackets. To illustrate, +``` +[] [3, 1, 4, 1, 5, 9, 3] [4+2, 1+5, a*b] +``` +are three examples of sequence displays. There is no sequence +comprehension expression. + +### Sequence Relational Operators +In addition to equality and disequality, sequence types +support the following relational operations: + ++-----------------+------------------------------------+ +| operator | description | ++-----------------+------------------------------------+ +| [<]{.monospace} | proper prefix | +| `<=` | prefix | ++-----------------+------------------------------------+ + +Like the arithmetic relational operators, these operators are +chaining. Note the absence of `>` and `>=`. + +### Sequence Concatenation +Sequences support the following binary operator: + ++---------------+------------------------------------+ +| operator | description | ++---------------+------------------------------------+ +| `+` | concatenation | ++---------------+------------------------------------+ + +Operator `+` is associative, like the arithmetic operator with the +same name. + +### Other Sequence Expressions +In addition, for any sequence `s` of type `seq<T>`, expression `e` +of type `T`, integer-based numeric `i` satisfying `0 <= i < |s|`, and +integer-based numerics `lo` and `hi` satisfying +`0 <= lo <= hi <= |s|`, sequences support the following operations: + ++---------------------+----------------------------------------+ +| expression | description | ++---------------------+----------------------------------------+ +| [\|s\|]{.monospace} | sequence length | +| `s[i]` | sequence selection | +| `s[i := e]` | sequence update | +| `e in s` | sequence membership | +| `e !in s` | sequence non-membership | +| `s[lo..hi]` | subsequence | +| `s[lo..]` | drop | +| `s[..hi]` | take | +| `s[\(_slices_\)]` | slice | +| `multiset(s)` | sequence conversion to a `multiset<T>` | ++---------------------+----------------------------------------+ + +Expression `s[i := e]` returns a sequence like `s`, except that the +element at index `i` is `e`. The expression `e in s` says there +exists an index `i` such that `s[i] == e`. It is allowed in non-ghost +contexts only if the element type `T` is equality supporting. +The expression `e !in s` is a syntactic shorthand for `!(e in s)`. + +Expression `s[lo..hi]` yields a sequence formed by taking the first +`hi` elements and then dropping the first `lo` elements. The +resulting sequence thus has length `hi - lo`. Note that `s[0..|s|]` +equals `s`. If the upper bound is omitted, it +defaults to `|s|`, so `s[lo..]` yields the sequence formed by dropping +the first `lo` elements of `s`. If the lower bound is omitted, it +defaults to `0`, so `s[..hi]` yields the sequence formed by taking the +first `hi` elements of `s`. + +In the sequence slice operation, `\(_slices_\)` is a nonempty list of +length designators separated and optionally terminated by a colon, and +there is at least one colon. Each length designator is a non-negative +integer-based numeric, whose sum is no greater than `|s|`. If there +are _k_ colons, the operation produces _k + 1_ consecutive subsequences +from `s`, each of the length indicated by the corresponding length +designator, and returns these as a sequence of +sequences.[^fn-slice-into-tuple] If `\(_slices_\)` is terminated by a +colon, then the length of the last slice extends until the end of `s`, +that is, its length is `|s|` minus the sum of the given length +designators. For example, the following equalities hold, for any +sequence `s` of length at least `10`: +``` +var t := [3.14, 2.7, 1.41, 1985.44, 100.0, 37.2][1:0:3]; +assert |t| == 3 && t[0] == [3.14] && t[1] == []; +assert t[2] == [2.7, 1.41, 1985.44]; +var u := [true, false, false, true][1:1:]; +assert |u| == 3 && u[0][0] && !u[1][0] && u[2] == [false, true]; +assert s[10:][0] == s[..10]; +assert s[10:][1] == s[10..]; +``` + +[^fn-slice-into-tuple]: Now that Dafny supports built-in tuples, the + plan is to change the sequence slice operation to return not a + sequence of subsequences, but a tuple of subsequences. + +The operation `multiset(s)` yields the multiset of elements of +sequence `s`. It is allowed in non-ghost contexts only if the element +type `T` is equality supporting. + +### Strings +```` +StringType_ = "string" +```` + +A special case of a sequence type is `seq<char>`, for which Dafny +provides a synonym: `string`. Strings are like other sequences, but +provide additional syntax for sequence display expressions, namely +_string literals_. There are two forms of the syntax for string +literals: the _standard form_ and the _verbatim form_. + +String literals of the standard form are enclosed in double quotes, as +in `"Dafny"`. To include a double quote in such a string literal, +it is necessary to use an escape sequence. Escape sequences can also +be used to include other characters. The supported escape sequences +are the same as those for character literals, see Section [#sec-characters]. +For example, the Dafny expression `"say \"yes\""` represents the +string `'say "yes"'`. +The escape sequence for a single quote is redundant, because +[\"\'\"]{.monospace} and [\"\\\'\"]{.monospace} denote the same +string---both forms are provided in order to support the same +escape sequences as for character literals. + +String literals of the verbatim form are bracketed by +[@\"]{.monospace} and [\"]{.monospace}, as in `@"Dafny"`. To include +a double quote in such a string literal, it is necessary to use the +escape sequence [\"\"]{.monospace}, that is, to write the character +twice. In the verbatim form, there are no other escape sequences. +Even characters like newline can be written inside the string literal +(hence spanning more than one line in the program text). + +For example, the following three expressions denote the same string: +``` +"C:\\tmp.txt" +@"C:\tmp.txt" +['C', ':', '\\', 't', 'm', 'p', '.', 't', 'x', 't'] +``` + +Since strings are sequences, the relational operators [<]{.monospace} +and `<=` are defined on them. Note, however, that these operators +still denote proper prefix and prefix, respectively, not some kind of +alphabetic comparison as might be desirable, for example, when +sorting strings. + +## Finite and Infinite Maps +```` +FiniteMapType_ = "map" [ GenericInstantiation ] +InfiniteMapType_ = "imap" [ GenericInstantiation ] +```` + +For any types `T` and `U`, a value of type `map<T,U>` denotes a +_(finite) map_ +from `T` to `U`. In other words, it is a look-up table indexed by +`T`. The _domain_ of the map is a finite set of `T` values that have +associated `U` values. Since the keys in the domain are compared +using equality in the type `T`, type `map<T,U>` can be used in a +non-ghost context only if `T` is equality supporting. + +Similarly, for any types `T` and `U`, a value of type `imap<T,U>` +denotes a _(possibly) infinite map_. In most regards, `imap<T,U>` is +like `map<T,U>`, but a map of type `imap<T,U>` is allowed to have an +infinite domain. + +A map can be formed using a _map display_ expression (see ``MapDisplayExpr``), +which is a possibly empty, ordered list of _maplets_, each maplet having the +form `t := u` where `t` is an expression of type `T` and `u` is an +expression of type `U`, enclosed in square brackets after the keyword +`map`. To illustrate, +``` +map[] map[20 := true, 3 := false, 20 := false] map[a+b := c+d] +``` +are three examples of map displays. By using the keyword `imap` +instead of `map`, the map produced will be of type `imap<T,U>` +instead of `map<T,U>`. Note that an infinite map (`imap`) is allowed +to have a finite domain, whereas a finite map (`map`) is not allowed +to have an infinite domain. +If the same key occurs more than +once, only the last occurrence appears in the resulting +map.[^fn-map-display] There is also a _map comprehension expression_, +explained in section [#sec-map-comprehension-expression]. + +[^fn-map-display]: This is likely to change in the future to disallow + multiple occurrences of the same key. + +For any map `fm` of type `map<T,U>`, +any map `m` of type `map<T,U>` or `imap<T,U>`, +any expression `t` of type `T`, +any expression `u` of type `U`, and any `d` in the domain of `m` (that +is, satisfying `d in m`), maps support the following operations: + ++----------------------+------------------------------------+ +| expression | description | ++----------------------+------------------------------------+ +| [\|fm\|]{.monospace} | map cardinality | +| `m[d]` | map selection | +| `m[t := u]` | map update | +| `t in m` | map domain membership | +| `t !in m` | map domain non-membership | ++----------------------+------------------------------------+ + +`|fm|` denotes the number of mappings in `fm`, that is, the +cardinality of the domain of `fm`. Note that the cardinality operator +is not supported for infinite maps. +Expression `m[d]` returns the `U` value that `m` associates with `d`. +Expression `m[t := u]` is a map like `m`, except that the +element at key `t` is `u`. The expression `t in m` says `t` is in the +domain of `m` and `t !in m` is a syntactic shorthand for +`!(t in m)`.[^fn-map-membership] + +[^fn-map-membership]: This is likely to change in the future as + follows: The `in` and `!in` operations will no longer be + supported on maps. Instead, for any map `m`, `m.Domain` will + return its domain as a set and `m.Range` will return, also as a + set, the image of `m` under its domain. + +Here is a small example, where a map `cache` of type `map<int,real>` +is used to cache computed values of Joule-Thomson coefficients for +some fixed gas at a given temperature: +``` +if K in cache { // check if temperature is in domain of cache + coeff := cache[K]; // read result in cache +} else { + coeff := ComputeJouleThomsonCoefficient(K); // do expensive computation + cache := cache[K := coeff]; // update the cache +} +``` + +# Types that stand for other types +```` +SynonymTypeDecl = + ( SynonymTypeDefinition_ | OpaqueTypeDefinition_ ) [ ";" ] +```` +It is sometimes useful to know a type by several names or to treat a +type abstractly. Synonym and opaque types serve this purpose. + +## Type synonyms +```` +SynonymTypeDefinition_ = + "type" { Attribute } SynonymTypeName [ GenericParameters ] "=" Type +```` + +A _type synonym_ declaration: +``` +type Y<T> = G +``` +declares `Y<T>` to be a synonym for the type `G`. Here, `T` is a +nonempty list of type parameters (each of which is optionally +designated with the suffix "`(==)`"), which can be used as free type +variables in `G`. If the synonym has no type parameters, the "`<T>`" +is dropped. In all cases, a type synonym is just a synonym. That is, +there is never a difference, other than possibly in error messages +produced, between `Y<T>` and `G`. + +For example, the names of the following type synonyms may improve the +readability of a program: +``` +type Replacements<T> = map<T,T> +type Vertex = int +``` + +As already described in Section [#sec-strings], `string` is a built-in +type synonym for `seq<char>`, as if it would have been declared as +follows: +``` +type string = seq<char> +``` + +## Opaque types +```` +OpaqueTypeDefinition_ = "type" { Attribute } SynonymTypeName + [ "(" "==" ")" ] [ GenericParameters ] +```` + +A special case of a type synonym is one that is underspecified. Such +a type is declared simply by: +``` +type Y<T> +``` +It is known as an _opaque type_. Its definition can be revealed in a +refining module. To indicate that `Y` designates an +equality-supporting type, "`(==)`" can be written immediately +following the name "`Y`". + +For example, the declarations +``` +type T +function F(t: T): T +``` +can be used to model an uninterpreted function `F` on some +arbitrary type `T`. As another example, +``` +type Monad<T> +``` +can be used abstractly to represent an arbitrary parameterized monad. + +# Well-founded Functions and Extreme Predicates +This section is a tutorial on well-founded functions and extreme predicates. +We place it here in preparation for Section [#sec-class-types] +where function and predicate definitions are described. + +Recursive functions are a core part of computer science and mathematics. +Roughly speaking, when the definition of such a function spells out a +terminating computation from given arguments, we may refer to +it as a _well-founded function_. For example, the common factorial and +Fibonacci functions are well-founded functions. + +There are also other ways to define functions. An important case +regards the definition of a boolean function as an extreme solution +(that is, a least or greatest solution) to some equation. For +computer scientists with interests in logic or programming languages, +these _extreme predicates_ are important because they describe the +judgments that can be justified by a given set of inference rules +(see, e.g., [@CamilleriMelham:InductiveRelations; +@Winskel:FormalSemantics; + @LeroyGrall:CoinductiveBigStep; @Pierce:SoftwareFoundations; + @NipkowKlein:ConcreteSemantics]). + +To benefit from machine-assisted reasoning, it is necessary not just +to understand extreme predicates but also to have techniques for +proving theorems about them. A foundation for this reasoning was +developed by Paulin-Mohring [@PaulinMohring:InductiveCoq] and is the +basis of the constructive logic supported by Coq [@Coq:book] as well +as other proof assistants [@BoveDybjerNorell:BriefAgda; +@SwamyEtAl:Fstar2011]. Essentially, the idea is to represent the +knowledge that an extreme predicate holds by the proof term by which +this knowledge was derived. For a predicate defined as the least +solution, such proof terms are values of an inductive datatype (that +is, finite proof trees), and for the greatest solution, a coinductive +datatype (that is, possibly infinite proof trees). This means that +one can use induction and coinduction when reasoning about these proof +trees. Therefore, these extreme predicates are known as, +respectively, _inductive predicates_ and _coinductive predicates_ (or, +_co-predicates_ for short). Support for extreme predicates is also +available in the proof assistants Isabelle [@Paulson:CADE1994] and HOL +[@Harrison:InductiveDefs]. + +Dafny supports both well-founded functions and extreme predicates. +This section is a tutorial that describes the difference in general +terms, and then describes novel syntactic support in Dafny for +defining and proving lemmas with extreme predicates. Although Dafny's +verifier has at its core a first-order SMT solver, Dafny's logical +encoding makes it possible to reason about fixpoints in an automated +way. + +The encoding for coinductive predicates in Dafny was described previously +[@LeinoMoskal:Coinduction] and is here described in Section +[#sec-co-inductive-datatypes]. + +## Function Definitions + +To define a function $f \colon X \to Y$ in terms of itself, one can +write an equation like + +~ Equation {#eq-general} + f \Equal \F(f) +~ + +where $\mathcal{F}$ is a non-recursive function of type +$(X \to Y) \to X \to Y$. Because it takes a function as an argument, +$\mathcal{F}$ is referred to as a _functor_ (or _functional_, but not to be +confused by the category-theory notion of a functor). +Throughout, I will assume that $\F(f)$ by itself is well defined, +for example that it does not divide by zero. I will also assume that $f$ occurs +only in fully applied calls in $\F(f)$; eta expansion can be applied to +ensure this. If $f$ is a boolean function, that is, if $Y$ is +the type of booleans, then I call $f$ a _predicate_. + +For example, the common Fibonacci function over the +natural numbers can be defined by the equation + +~ Equation + \fib \Equal + \lambda n \bullet\; \ite{n < 2}{n}{\fib(n-2) + \fib(n-1)} +~ + +With the understanding that the argument $n$ is universally +quantified, we can write this equation equivalently as + +~ Equation {#eq-fib} + \fib(n) \Equal + \ite{n < 2}{n}{\fib(n-2) + \fib(n-1)} +~ + +The fact that the function being defined occurs on both sides of the equation +causes concern that we might not be defining the function properly, leading to a +logical inconsistency. In general, there +could be many solutions to an equation like [#eq-general] or there could be none. +Let's consider two ways to make sure we're defining the function uniquely. + +### Well-founded Functions + +A standard way to ensure that equation [#eq-general] has a unique solution in $f$ is +to make sure the recursion is well-founded, which roughly means that the +recursion terminates. This is done by introducing any well-founded +relation $\Less$ on the domain of $f$ and making sure that the argument to each recursive +call goes down in this ordering. More precisely, if we formulate [#eq-general] as + +~ Equation + f(x) \Equal \F'(f) +~ + +then we want to check $E \Less x$ for each call $f(E)$ in $\F'(f)$. When a function +definition satisfies this _decrement condition_, then the function is said to be +_well-founded_. + +For example, to check the decrement condition for $\fib$ in [#eq-fib], we can pick +$\Less$ to be the arithmetic less-than relation on natural numbers and check the +following, for any $n$: + +~ Equation + 2 \leq n \;\;\Imp\;\; n-2 \Less n \;\And\; n-1 \Less n +~ + +Note that we are entitled to using the antecedent $2 \leq n$, because that is the +condition under which the else branch in [#eq-fib] is evaluated. + +A well-founded function is often thought of as "terminating" in the sense +that the recursive _depth_ in evaluating $f$ +on any given argument is finite. That is, there are no infinite descending chains +of recursive calls. However, the evaluation of $f$ on a given argument +may fail to terminate, because its _width_ may be infinite. For example, let $P$ +be some predicate defined on the ordinals and let $\PDownward$ be a predicate on the +ordinals defined by the following equation: + +~ Equation + \PDownward(o) \Equal + P(o) \And \forall p \bullet\; p \Less o \Imp \PDownward(p) +~ + +With $\Less$ as the usual ordering on ordinals, this equation satisfies the decrement +condition, but evaluating $\PDownward(\omega)$ would require evaluating +$\PDownward(n)$ for every natural number $n$. However, what we are concerned +about here is to avoid mathematical inconsistencies, and that is +indeed a consequence of the decrement condition. + +#### Example with Well-founded Functions {#sec-fib-example} + +So that we can later see how inductive proofs are done in Dafny, let's prove that +for any $n$, $\fib(n)$ is even iff $n$ is a multiple of $3$. +We split our task into +two cases. If $n < 2$, then the property follows directly from the definition +of $\fib$. Otherwise, note that exactly one of the three numbers $n-2$, $n-1$, and $n$ +is a multiple of 3. If $n$ is the multiple of 3, then by invoking the +induction hypothesis on $n-2$ +and $n-1$, we obtain that $\fib(n-2) + \fib(n-1)$ is the sum of two odd numbers, +which is even. If $n-2$ or $n-1$ is a multiple of 3, then by invoking the induction +hypothesis on $n-2$ and $n-1$, we obtain that $\fib(n-2) + \fib(n-1)$ is the sum of an +even number and an odd number, which is odd. In this proof, we invoked the induction +hypothesis on $n-2$ and on $n-1$. This is allowed, because both are smaller than +$n$, and hence the invocations go down in the well-founded ordering on natural numbers. + +### Extreme Solutions + +We don't need to exclude the possibility of equation [#eq-general] having multiple +solutions---instead, we can just be clear about which one of them we want. +Let's explore this, after a smidgen of lattice theory. + +For any complete lattice $(Y,\leq)$ and any set $X$, we can by _pointwise extension_ define +a complete lattice $(X \to Y, \FBelow)$, where for any $f,g \colon X \to Y$, + +~ Equation + f \FBelow q \Equiv + \forall x \bullet\; f(x) \leq g(x) +~ + +In particular, if $Y$ is the set of booleans ordered by implication ($\false \leq \true$), +then the set of predicates over any domain $X$ forms a complete lattice. +Tarski's Theorem [@Tarski:theorem] tells us that any monotonic function over a +complete lattice has a least and a greatest fixpoint. In particular, this means that +$\F$ has a least fixpoint and a greatest fixpoint, provided $\F$ is monotonic. + +Speaking about the _set of solutions_ in $f$ to [#eq-general] is the same as speaking +about the _set of fixpoints_ of functor $\F$. In particular, the least and greatest +solutions to [#eq-general] are the same as the least and greatest fixpoints of $\F$. +In casual speak, it happens that we say "fixpoint of [#eq-general]", or more +grotesquely, "fixpoint of $f$" when we really mean "fixpoint of $\F$". + +In conclusion of our little excursion into lattice theory, we have that, under the +proviso of $\F$ being monotonic, the set of solutions in $f$ to [#eq-general] is nonempty, +and among these solutions, there is in the $\FBelow$ ordering a least solution (that is, +a function that returns $\false$ more often than any other) and a greatest solution (that +is, a function that returns $\true$ more often than any other). + +When discussing extreme solutions, I will now restrict my attention to boolean functions +(that is, with $Y$ being the type of booleans). Functor $\F$ is monotonic +if the calls to $f$ in $\F'(f)$ are in _positive positions_ (that is, under an even number +of negations). Indeed, from now on, I will restrict my attention to such monotonic +functors $\F$. + +Let me introduce a running example. Consider the following equation, +where $x$ ranges over the integers: + +~ Equation {#eq-EvenNat} + g(x) \Equal (x = 0 \Or g(x-2)) +~ + +This equation has four solutions in $g$. With $w$ ranging over the integers, they are: + +~ Equation + \begin{array}{r@{}l} + g(x) \Equiv{}& x \in \{w \;|\; 0 \leq w \And w\textrm{ even}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; w\textrm{ even}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; (0 \leq w \And w\textrm{ even}) \Or w\textrm{ odd}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; \true\} + \end{array} +~ + +The first of these is the least solution and the last is the greatest solution. + +In the literature, the definition of an extreme predicate is often given as a set of +_inference rules_. To designate the least solution, a single line separating the +antecedent (on top) from conclusion (on bottom) is used: + +~ Equation {#g-ind-rule} + \frac{}{g(0)} + \qquad\qquad + \frac{g(x-2)}{g(x)} +~ + +Through repeated applications of such rules, one can show that the predicate holds for +a particular value. For example, the _derivation_, or _proof tree_, +to the left in Figure [#fig-proof-trees] shows that $g(6)$ holds. +(In this simple example, the derivation is a rather degenerate proof "tree".) +The use of these inference rules gives rise to a least solution, because proof trees are +accepted only if they are _finite_. + +~ Begin Figure { #fig-proof-trees caption="Left: a finite proof tree that uses the rules of [#g-ind-rule] to establish $g(6)$. Right: an infinite proof tree that uses the rules of [#g-coind-rule] to establish $g(1)$." } +~ Begin Columns +~~ Column { vertical-align=bottom } +~ Math +\dfrac{ + \dfrac{ + \dfrac{ + \dfrac{}{g(0)\xstrut} + }{g(2)\xstrut} + }{g(4)\xstrut} + }{g(6)\xupstrut} +~ +~~ +~~ Column { width=5em } + +~~ +~~ Column { vertical-align=bottom } +~ Math +\Dfrac{ + \Dfrac{ + \Dfrac{ + \Dfrac{ + {}_{\vdots } + }{{g(-5)}} + }{{g(-3)}} + }{{g(-1)}} + }{g(1)} +~ +~~ +~ End Columns +~ End Figure + +When inference rules are to designate the greatest solution, a double +line is used: + +~ Equation {#g-coind-rule} + \Dfrac{}{g(0)} + \qquad\qquad + \Dfrac{g(x-2)}{g(x)} +~ + +In this case, proof trees are allowed to be infinite. For example, the (partial depiction +of the) infinite proof tree on the right in Figure [#fig-proof-trees] shows that $g(1)$ holds. + +Note that derivations may not be unique. For example, in the case of the greatest +solution for $g$, there are two proof trees that establish $g(0)$: one is the finite +proof tree that uses the left-hand rule of [#g-coind-rule] once, the other is the infinite +proof tree that keeps on using the right-hand rule of [#g-coind-rule]. + +### Working with Extreme Predicates + +In general, one cannot evaluate whether or not an extreme predicate holds for some +input, because doing so may take an infinite number of steps. For example, following +the recursive calls in the definition [#eq-EvenNat] to try to evaluate $g(7)$ would never +terminate. However, there are useful ways to establish that an extreme predicate holds +and there are ways to make use of one once it has been established. + +For any $\F$ as in [#eq-general], I define two infinite series of well-founded +functions, $\iter{f}_k$ and $\Iter{f}_k$ +where $k$ ranges over the natural numbers: + +~ Equation {#eq-least-approx} + \iter{f}_k(x) \Equal \left\{ + \begin{array}{ll} + \false & \textrm{if } k = 0 \\ + \F(\iter{f}_{k-1})(x) & \textrm{if } k > 0 + \end{array} + \right. +~ +~ Equation {#eq-greatest-approx} + \Iter{f}_k(x) \Equal \left\{ + \begin{array}{ll} + \true & \textrm{if } k = 0 \\ + \F(\Iter{f}_{k-1})(x) & \textrm{if } k > 0 + \end{array} + \right. +~ + +These functions are called the _iterates_ of $f$, and I will also refer to them +as the _prefix predicates_ of $f$ (or the _prefix predicate_ of $f$, if we think +of $k$ as being a parameter). +Alternatively, we can define $\iter{f}_k$ and $\Iter{f}_k$ without mentioning $x$: +Let $\bot$ denote the function that always returns $\false$, let $\top$ +denote the function that always returns $\true$, and let a superscript on $\F$ denote +exponentiation (for example, $\F^0(f) = f$ and $\F^2(f) = \F(\F(f))$). +Then, [#eq-least-approx] and [#eq-greatest-approx] can be stated equivalently as +$\iter{f}_k = \F^k(\bot)$ and $\Iter{f}_k = \F^k(\top)$. + +For any solution $f$ to equation [#eq-general], we have, for any $k$ and $\ell$ +such that $k \leq \ell$: + +~ Equation {#eq-prefix-postfix} + \iter{f}_k \quad\FBelow\quad + \iter{f}_\ell \quad\FBelow\quad + f \quad\FBelow\quad + \Iter{f}_\ell \quad\FBelow\quad + \Iter{f}_k +~ + +In other words, every $\iter{f}_k$ is a _pre-fixpoint_ of $f$ and every $\Iter{f}_k$ is a _post-fixpoint_ +of $f$. Next, I define two functions, $f\least$ and $f\greatest$, in +terms of the prefix predicates: + +~ Equation {#eq-least-is-exists} + f\least(x) \Equal \exists k \bullet\; \iter{f}_k(x) +~ +~ Equation {#eq-greatest-is-forall} + f\greatest(x) \Equal \forall k \bullet\; \Iter{f}_k(x) +~ + +By [#eq-prefix-postfix], we also have that $f\least$ is a pre-fixpoint of $\F$ and $f\greatest$ +is a post-fixpoint of $\F$. The marvelous thing is that, if $\F$ is _continuous_, then +$f\least$ and $f\greatest$ are the least and greatest fixpoints of $\F$. +These equations let us do proofs by induction when dealing with extreme predicates. +I will explain in Section [#sec-friendliness] how to check for continuity. + +Let's consider two examples, both involving function $g$ in +[#eq-EvenNat]. As it turns out, $g$'s defining functor is continuous, +and therefore I will write $g\least$ and $g\greatest$ to denote the +least and greatest solutions for $g$ in [#eq-EvenNat]. + +#### Example with Least Solution {#sec-example-least-solution} + +The main technique for establishing that $g\least(x)$ holds for some +$x$, that is, proving something of the form $Q \Imp g\least(x)$, is to +construct a proof tree like the one for $g(6)$ in Figure +[#fig-proof-trees]. For a proof in this direction, since we're just +applying the defining equation, the fact that +we're using a least solution for $g$ never plays a role (as long as we +limit ourselves to finite derivations). + +The technique for going in the other direction, proving something _from_ an established +$g\least$ property, that is, showing something of the form $g\least(x) \Imp R$, typically +uses induction on the structure of the proof tree. When the antecedent of our proof +obligation includes a predicate term $g\least(x)$, it is sound to +imagine that we have been given a proof tree for $g\least(x)$. Such a proof tree +would be a data structure---to be more precise, a term in an +_inductive datatype_. +For this reason, least solutions like $g\least$ have been given the +name _inductive predicate_. + +Let's prove $g\least(x) \Imp 0 \leq x \And x \textrm{ even}$. +We split our task into two cases, corresponding to which of the two +proof rules in [#g-ind-rule] was the +last one applied to establish $g\least(x)$. If it was the left-hand rule, then $x=0$, +which makes it easy to establish the conclusion of our proof goal. If it was the +right-hand rule, then we unfold the proof tree one level and obtain $g\least(x-2)$. +Since the proof tree for $g\least(x-2)$ is smaller than where we started, we invoke +the _induction hypothesis_ and obtain $0 \leq (x-2) \And (x-2) \textrm{ even}$, from which +it is easy to establish the conclusion of our proof goal. + +Here's how we do the proof formally using [#eq-least-is-exists]. We massage the +general form of our proof goal: + +|~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| +| | $f\greatest(x) \Imp R$ | +| = | { [#eq-least-is-exists] } | +| | $(\exists k \bullet\; \iter{f}_k(x)) \Imp R$ | +| = | { distribute $\Imp$ over $\exists$ to the left } | +| | $\forall k \bullet\; (\iter{f}_k(x) \Imp R)$ | + +The last line can be proved by induction over $k$. So, in our case, we prove +$\iter{g}_k(x) \Imp 0 \leq x \And x \textrm{ even}$ for every $k$. +If $k=0$, then $\iter{g}_k(x)$ is $\false$, so our goal holds trivially. +If $k > 0$, then $\iter{g}_k(x) = (x = 0 \Or \iter{g}_{k-1}(x-2))$. Our goal holds easily +for the first disjunct ($x=0$). For the other disjunct, +we apply the induction hypothesis (on the smaller $k-1$ and with $x-2$) and +obtain $0 \leq (x-2) \And (x-2) \textrm{ even}$, from which our proof goal +follows. + +#### Example with Greatest Solution {#sec-example-greatest-solution} + +We can think of a given predicate $g\greatest(x)$ as being represented +by a proof tree---in this case a term in a _coinductive datatype_, +since the proof may be infinite. +For this reason, greatest solutions like $g\greatest$ have +been given the name _coinductive predicate_, or _co-predicate_ for short. +The main technique for proving something from a given proof tree, that +is, to prove something of the form $g\greatest(x) \Imp R$, is to +destruct the proof. Since this is just unfolding the defining +equation, the fact that we're using a greatest solution for $g$ never +plays a role (as long as we limit ourselves to a finite number of +unfoldings). + +To go in the other direction, to establish a predicate defined as a greatest solution, +like $Q \Imp g\greatest(x)$, we may need an infinite number of steps. For this purpose, +we can use induction's dual, _coinduction_. Were it not for one little detail, coinduction +is as simple as continuations in programming: the next part of the proof obligation +is delegated to the _coinduction hypothesis_. The little detail is making sure that +it is the "next" part we're passing on for the continuation, not the same part. This +detail is called _productivity_ and corresponds to the requirement in +induction of making sure we're going down a well-founded relation when +applying the induction hypothesis. There are +many sources with more information, see for example the classic account by +Jacobs and Rutten [@JacobsRutten:IntroductionCoalgebra] +or a new attempt by Kozen and Silva +that aims to emphasize the simplicity, not the mystery, of +coinduction [@KozenSilva:Coinduction]. + +Let's prove $\true \Imp g\greatest(x)$. The intuitive coinductive proof goes like this: +According to the right-hand rule of [#g-coind-rule], $g\greatest(x)$ follows if we +establish $g\greatest(x-2)$, and that's easy to do by invoking the coinduction hypothesis. +The "little detail", productivity, is satisfied in this proof because we applied +a rule in [#g-coind-rule] before invoking the coinduction hypothesis. + +For anyone who may have felt that the intuitive proof felt too easy, here is a formal +proof using [#eq-greatest-is-forall], which relies only on induction. We massage the +general form of our proof goal: + +|~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| +| | $Q \Imp f\greatest(x)$ | +| = | { [#eq-greatest-is-forall] } | +| | $Q \Imp \forall k \bullet\; \Iter{f}_k(x)$ | +| = | { distribute $\Imp$ over $\forall$ to the right } | +| | $\forall k \bullet\; Q \Imp \Iter{f}_k(x)$ | + +The last line can be proved by induction over $k$. So, in our case, we prove +$\true \Imp \Iter{g}_k(x)$ for every $k$. +If $k=0$, then $\Iter{g}_k(x)$ is $\true$, so our goal holds trivially. +If $k > 0$, then $\Iter{g}_k(x) = (x = 0 \Or \Iter{g}_{k-1}(x-2))$. We establish the second +disjunct by applying the induction hypothesis (on the smaller $k-1$ and with $x-2$). + +### Other Techniques + +Although in this paper I consider only well-founded functions and extreme +predicates, it is worth mentioning that there are additional ways of making sure that +the set of solutions to [#eq-general] is nonempty. For example, if all calls to $f$ in +$\F'(f)$ are _tail-recursive calls_, then (under the assumption that $Y$ is nonempty) the set of +solutions is nonempty. To see this, consider an attempted evaluation of $f(x)$ that fails +to determine a definite result value because of an infinite chain of calls that applies $f$ +to each value of some subset $X'$ of $X$. Then, apparently, the value of $f$ for any one +of the values in $X'$ is not determined by the equation, but picking any particular result +values for these makes for a consistent definition. +This was pointed out by Manolios and Moore [@ManoliosMoore:PartialFunctions]. +Functions can be underspecified in this way in the proof assistants ACL2 [@ACL2:book] +and HOL [@Krauss:PhD]. + +## Functions in Dafny + +In this section, I explain with examples the support in +Dafny[^fn-on-da-web] for well-founded functions, extreme predicates, +and proofs regarding these. + +[^fn-on-da-web]: Dafny is open source at [dafny.codeplex.com](http://dafny.codeplex.com) and can also be used online at [rise4fun.com/dafny](http://rise4fun.com/dafny). + +### Well-founded Functions in Dafny + +Declarations of well-founded functions are unsurprising. For example, the Fibonacci +function is declared as follows: + +``` +function fib(n: nat): nat +{ + if n < 2 then n else fib(n-2) + fib(n-1) +} +``` + +Dafny verifies that the body (given as an expression in curly braces) is well defined. +This includes decrement checks for recursive (and mutually recursive) calls. Dafny +predefines a well-founded relation on each type and extends it to lexicographic tuples +of any (fixed) length. For example, the well-founded relation $x \Less y$ for integers +is $x < y \And 0 \leq y$, the one for reals is $x \leq y - 1.0 \And 0.0 \leq y$ +(this is the same ordering as for integers, if you read the integer +relation as $x \leq y - 1 \And 0 \leq y$), the one for inductive +datatypes is structural inclusion, +and the one for coinductive datatypes is $\false$. + +Using a `decreases` clause, the programmer can specify the term in this predefined +order. When a function definition omits a `decreases` clause, Dafny makes a simple +guess. This guess (which can be inspected by hovering over the function name in the +Dafny IDE) is very often correct, so users are rarely bothered to provide explicit +`decreases` clauses. + +If a function returns `bool`, one can drop the result type `: bool` and change the +keyword `function` to `predicate`. + +### Proofs in Dafny + +Dafny has `lemma` declarations. These are really just special cases of methods: +they can have pre- and postcondition specifications and their body is a code block. +Here is the lemma we stated and proved in Section [#sec-fib-example]: + +``` +lemma FibProperty(n: nat) + ensures fib(n) % 2 == 0 <==> n % 3 == 0 +{ + if n < 2 { + } else { + FibProperty(n-2); FibProperty(n-1); + } +} +``` + +The postcondition of this lemma (keyword `ensures`) gives the proof +goal. As in any program-correctness logic (e.g., +[@Hoare:AxiomaticBasis]), the postcondition must +be established on every control path through the lemma's body. For +`FibProperty`, I give the proof by +an `if` statement, hence introducing a case split. The then branch is empty, because +Dafny can prove the postcondition automatically in this case. The else branch +performs two recursive calls to the lemma. These are the invocations of the induction +hypothesis and they follow the usual program-correctness rules, +namely: the precondition must hold at the call site, the call must terminate, and then +the caller gets to assume the postcondition upon return. The "proof glue" needed +to complete the proof is done automatically by Dafny. + +Dafny features an aggregate statement using which it is possible to make (possibly +infinitely) many calls at once. For example, the induction hypothesis can be called +at once on all values `n'` smaller than `n`: + +``` +forall n' | 0 <= n' < n { + FibProperty(n'); +} +``` + +For our purposes, this corresponds to _strong induction_. More +generally, the `forall` statement has the form + +``` +forall k | P(k) + ensures Q(k) +{ Statements; } +``` + +Logically, this statement corresponds to _universal introduction_: the body proves that +`Q(k)` holds for an arbitrary `k` such that `P(k)`, and the conclusion of the `forall` statement +is then $\forall k \bullet\; P(k) \Imp Q(k)$. When the body of the `forall` statement is +a single call (or `calc` statement), the `ensures` clause is inferred and can be omitted, +like in our `FibProperty` example. + +Lemma `FibProperty` is simple enough that its whole body can be replaced by the one +`forall` statement above. In fact, Dafny goes one step further: it automatically +inserts such a `forall` statement at the beginning of every lemma [@Leino:induction]. +Thus, `FibProperty` can be declared and proved simply by: + +``` {.para-end} +lemma FibProperty(n: nat) + ensures fib(n) % 2 == 0 <==> n % 3 == 0 +{ } +``` + +Going in the other direction from universal introduction is existential elimination, +also known as Skolemization. Dafny has a statement for this, too: +for any variable `x` and boolean expression `Q`, the +_assign such that_ statement `x :| Q;` says to assign to `x` a value such that `Q` +will hold. A proof obligation when using this statement is to show that there +exists an `x` such that `Q` holds. For example, if the fact +$\exists k \bullet\; 100 \leq \fib(k) < 200$ is known, then the statement +`k :| 100 <= fib(k) < 200;` will assign to `k` some value (chosen arbitrarily) +for which `fib(k)` falls in the given range. + +### Extreme Predicates in Dafny {#sec-friendliness} + +In this previous subsection, I explained that a `predicate` declaration introduces a +well-founded predicate. The declarations for introducing extreme predicates are +`inductive predicate` and `copredicate`. Here is the definition of the least and +greatest solutions of $g$ from above, let's call them `g` and `G`: + +``` +inductive predicate g(x: int) { x == 0 || g(x-2) } +copredicate G(x: int) { x == 0 || G(x-2) } +``` + +When Dafny receives either of these definitions, it automatically declares the corresponding +prefix predicates. Instead of the names $\iter{g}_k$ and $\Iter{g}_k$ that I used above, Dafny +names the prefix predicates `g#[k]` and `G#[k]`, respectively, that is, the name of +the extreme predicate appended with `#`, and the subscript is given as an argument in +square brackets. The definition of the prefix predicate derives from the body of +the extreme predicate and follows the form in [#eq-least-approx] and [#eq-greatest-approx]. +Using a faux-syntax for illustrative purposes, here are the prefix +predicates that Dafny defines automatically from the extreme +predicates `g` and `G`: + +``` +predicate g#[_k: nat](x: int) { _k != 0 && (x == 0 || g#[_k-1](x-2)) } +predicate G#[_k: nat](x: int) { _k != 0 ==> (x == 0 || G#[_k-1](x-2)) } +``` + +The Dafny verifier is aware of the connection between extreme predicates and their +prefix predicates, [#eq-least-is-exists] and [#eq-greatest-is-forall]. + +Remember that to be well defined, the defining functor of an extreme predicate +must be monotonic, and for [#eq-least-is-exists] and [#eq-greatest-is-forall] to hold, +the functor must be continuous. Dafny enforces the former of these by checking that +recursive calls of extreme predicates are in positive positions. The continuity +requirement comes down to checking that they are also in _continuous positions_: +that recursive calls to inductive predicates are +not inside unbounded universal quantifiers and that recursive calls to co-predicates +are not inside unbounded existential quantifiers [@Milner:CCS; @LeinoMoskal:Coinduction]. + +### Proofs about Extreme Predicates + +From what I have presented so far, we can do the formal proofs from Sections +[#sec-example-least-solution] and [#sec-example-greatest-solution]. Here is the +former: + +``` +lemma EvenNat(x: int) + requires g(x) + ensures 0 <= x && x % 2 == 0 +{ + var k: nat :| g#[k](x); + EvenNatAux(k, x); +} +lemma EvenNatAux(k: nat, x: int) + requires g#[k](x) + ensures 0 <= x && x % 2 == 0 +{ + if x == 0 { } else { EvenNatAux(k-1, x-2); } +} +``` + +Lemma `EvenNat` states the property we wish to prove. From its +precondition (keyword `requires`) and +[#eq-least-is-exists], we know there is some `k` that will make the condition in the +assign-such-that statement true. Such a value is then assigned to `k` and passed to +the auxiliary lemma, which promises to establish the proof goal. Given the condition +`g#[k](x)`, the definition of `g#` lets us conclude `k != 0` as well as the disjunction +`x == 0 || g#[k-1](x-2)`. The then branch considers the case of the first disjunct, +from which the proof goal follows automatically. The else branch can then assume +`g#[k-1](x-2)` and calls the induction hypothesis with those parameters. The proof +glue that shows the proof goal for `x` to follow from the proof goal with `x-2` is +done automatically. + +Because Dafny automatically inserts the statement + +``` +forall k', x' | 0 <= k' < k && g#[k'](x') { + EvenNatAux(k', x'); +} +``` + +at the beginning of the body of `EvenNatAux`, the body can be left empty and Dafny +completes the proof automatically. + +Here is the Dafny program that gives the proof from Section [#sec-example-greatest-solution]: + +``` {.para-end} +lemma Always(x: int) + ensures G(x) +{ forall k: nat { AlwaysAux(k, x); } } +lemma AlwaysAux(k: nat, x: int) + ensures G#[k](x) +{ } +``` + +While each of these proofs involves only basic proof rules, the setup feels a bit clumsy, +even with the empty body of the auxiliary lemmas. Moreover, +the proofs do not reflect the intuitive proofs I described in +Section [#sec-example-least-solution] and [#sec-example-greatest-solution]. +These shortcoming are addressed in the next subsection. + +### Nicer Proofs of Extreme Predicates + +The proofs we just saw follow standard forms: +use Skolemization to convert the inductive predicate into a prefix predicate for some `k` +and then do the proof inductively over `k`; respectively, +by induction over `k`, prove the prefix predicate for every `k`, then use +universal introduction to convert to the coinductive predicate. +With the declarations `inductive lemma` and `colemma`, Dafny offers to +set up the proofs +in these standard forms. What is gained is not just fewer characters in the program +text, but also a possible intuitive reading of the proofs. (Okay, to be fair, the +reading is intuitive for simpler proofs; complicated proofs may or may not be intuitive.) + +Somewhat analogous to the creation of prefix predicates from extreme predicates, Dafny +automatically creates a _prefix lemma_ `L#` from each "extreme lemma" `L`. The pre- +and postconditions of a prefix lemma are copied from those of the extreme lemma, +except for the following replacements: +For an inductive lemma, Dafny looks in the precondition to find calls (in positive, continuous +positions) to inductive predicates `P(x)` and replaces these with `P#[_k](x)`. +For a +co-lemma, Dafny looks in the postcondition to find calls (in positive, continuous positions) +to co-predicates `P` (including equality among coinductive datatypes, which is a built-in +co-predicate) and replaces these with `P#[_k](x)`. +In each case, these predicates `P` are the lemma's _focal predicates_. + +The body of the extreme lemma is moved to the prefix lemma, but with +replacing each recursive +call `L(x)` with `L#[_k-1](x)` and replacing each occurrence of a call +to a focal predicate +`P(x)` with `P#[_k-1](x)`. The bodies of the extreme lemmas are then replaced as shown +in the previous subsection. By construction, this new body correctly leads to the +extreme lemma's postcondition. + +Let us see what effect these rewrites have on how one can write proofs. Here are the proofs +of our running example: + +``` +inductive lemma EvenNat(x: int) + requires g(x) + ensures 0 <= x && x % 2 == 0 +{ if x == 0 { } else { EvenNat(x-2); } } +colemma Always(x: int) + ensures G(x) +{ Always(x-2); } +``` + +Both of these proofs follow the intuitive proofs given in Sections +[#sec-example-least-solution] and [#sec-example-greatest-solution]. Note that in these +simple examples, the user is never bothered with either prefix predicates nor +prefix lemmas---the proofs just look like "what you'd expect". + +Since Dafny automatically inserts calls to the induction hypothesis at the beginning of +each lemma, the bodies of the given extreme lemmas `EvenNat` and +`Always` can be empty and Dafny still completes the proofs. +Folks, it doesn't get any simpler than that! + +# Class Types + +```` +ClassDecl = "class" { Attribute } ClassName [ GenericParameters ] + ["extends" Type {"," Type} ] + "{" { { DeclModifier } ClassMemberDecl(moduleLevelDecl: false) } "}" +```` + +```` +ClassMemberDecl(moduleLevelDecl) = + ( FieldDecl | FunctionDecl | + MethodDecl(isGhost: ("ghost" was present), + allowConstructor: !moduleLevelDecl) + ) +```` +The ``ClassMemberDecl`` parameter `moduleLevelDecl` will be true if +the member declaration is at the top level or directly within a +module declaration. It will be false for ``ClassMemberDecl``s +that are part of a class or trait declaration. If `moduleLevelDecl` is +false ``FieldDecl``s are not allowed. + +A _class_ `C` is a reference type declared as follows: +``` +class C<T> extends J1, ..., Jn +{ + \(_members_\) +} +``` +where the list of type parameters `T` is optional and so is +"`extends J1, ..., Jn`", which says that the class extends traits `J1` ... `Jn`. +The members of a class are _fields_, _functions_, and +_methods_. These are accessed or invoked by dereferencing a reference +to a `C` instance. + +A function or method is invoked on an _instance_ +of `C`, unless the function or method is declared `static`. +A function or method that is not `static` is called an +_instance_ function or method. + +An instance function or method takes an implicit _receiver_ +parameter, namely, the instance used to access the member. In the +specification and body of an instance function or method, the receiver +parameter can be referred to explicitly by the keyword `this`. +However, in such places, members of `this` can also be mentioned +without any qualification. To illustrate, the qualified `this.f` and +the unqualified `f` refer to the same field of the same object in the +following example: +``` +class C { + var f: int + method Example() returns (b: bool) + { + b := f == this.f; + } +} +``` +so the method body always assigns `true` to the out-parameter `b`. +There is no semantic difference between qualified and +unqualified accesses to the same receiver and member. + +A `C` instance is created using `new`, for example: +``` +c := new C; +``` + +Note that `new` simply allocates a `C` object and returns a reference +to it; the initial values of its fields are arbitrary values of their +respective types. Therefore, it is common to invoke a method, known +as an _initialization method_, immediately after creation, for +example: +``` +c := new C; +c.InitFromList(xs, 3); +``` +When an initialization method has no out-parameters and modifies no +more than `this`, then the two statements above can be combined into +one: +``` +c := new C.InitFromList(xs, 3); +``` +Note that a class can contain several initialization methods, that +these methods can be invoked at any time, not just as part of a `new`, +and that `new` does not require that an initialization method be +invoked at creation. + +A clas can declare special initializing methods called _constructor methods_. +See Section [#sec-method-declarations]. + +## Field Declarations +```` +FieldDecl = "var" { Attribute } FIdentType { "," FIdentType } +```` +An ``FIdentType`` is used to declare a field. The field name is either an +identifier (that is not allowed to start with a leading underscore) or +some digits. Digits are used if you want to number your fields, e.g. "0", +"1", etc. +```` +FIdentType = ( FieldIdent | digits ) ":" Type +```` + +A field x of some type T is declared as: +``` +var x: T +``` + +A field declaration declares one or more fields of the enclosing class. +Each field is a named part of the state of an object of that class. A +field declaration is similar to but distinct from a variable declaration +statement. Unlike for local variables and bound variables, the type is +required and will not be inferred. + +Unlike method and function declarations, a field declaration +cannot be given at the top level. Fields can be declared in either a +class or a trait. A class that inherits from multiple traits will +have all the fields declared in any of its parent traits. + +Fields that are declared as `ghost` can only be used in specifications, +not in code that will be compiled into executable code. + +Fields may not be declared static. + +`protected` is not allowed for fields. + +## Method Declarations +```` +MethodDecl(isGhost, allowConstructor) = + MethodKeyword { Attribute } [ MethodName ] + ( MethodSignature(isGhost) | SignatureEllipsis_ ) + MethodSpec [ BlockStmt ] +```` +The `isGhost` parameter is true iff the `ghost` keyword +preceded the method declaration. + +If the `allowConstructor` parameter is false then +the ``MethodDecl`` must not be a `constructor` +declaration. + +```` +MethodKeyword = ("method" | "lemma" | "colemma" + | "inductive" "lemma" | "constructor" ) +```` +The method keyword is used to specify special kinds of methods +as explained below. + +```` +MethodSignature(isGhost) = + [ GenericParameters ] + Formals(allowGhost: !isGhost) + [ "returns" Formals(allowGhost: !isGhost) ] +```` +A method signature specifies the method generic parameters, +input parameters and return parameters. +The formal parameters are not allowed to have `ghost` specified +if `ghost` was already specified for the method. + +```` +SignatureEllipsis_ = "..." +```` +A ``SignatureEllipsis_`` is used when a method or function is being redeclared +in module that refines another module. In that case the signature is +copied from the module that is being refined. This works because +Dafny does not support method or function overloading, so the +name of the class method uniquely identifies it without the +signature. + +```` +Formals(allowGhostKeyword) = + "(" [ GIdentType(allowGhostKeyword) + { "," GIdentType(allowGhostKeyword) } ] ")" +```` +The ``Formals`` specifies the names and types of the method input or +output parameters. + +See section [#sec-method-specification] for a description of ``MethodSpec``. + +A method declaration adheres to the ``MethodDecl`` grammar above. +Here is an example of a method declaration. + +``` +method {:att1}{:att2} M<T1, T2>(a: A, b: B, c: C) returns (x: X, y: Y, z: Z) + requires Pre + modifies Frame + ensures Post + decreases Rank +{ + Body +} +``` + +where `:att1` and `:att2` are attributes of the method, +`T1` and `T2` are type parameters of the method (if generic), +`a, b, c` are the method’s in-parameters, `x, y, z` are the +method’s out-parameters, `Pre` is a boolean expression denoting the +method’s precondition, `Frame` denotes a set of objects whose fields may +be updated by the method, `Post` is a boolean expression denoting the +method’s postcondition, `Rank` is the method’s variant function, and +`Body` is a statement that implements the method. `Frame` can be a list +of expressions, each of which is a set of objects or a single object, the +latter standing for the singleton set consisting of that one object. The +method’s frame is the union of these sets, plus the set of objects +allocated by the method body. For example, if `c` and `d` are parameters +of a class type `C`, then + +``` +modifies {c, d} + +modifies {c} + {d} + +modifies c, {d} + +modifies c, d +``` + +all mean the same thing. + +A method can be declared as ghost by preceding the declaration with the +keyword ghost. By default, a method has an implicit receiver parameter, +this. This parameter can be removed by preceding the method declaration +with the keyword static. A static method M in a class C can be invoked by +C.M(…). + +In a class, a method can be declared to be a constructor method by +replacing the keyword `method` with the keyword `constructor`. A constructor +can only be called at the time an object is allocated (see +object-creation examples below), and for a class that contains one or +more constructors, object creation must be done in conjunction with a +call to a constructor. + +An ordinary method is declared with the `method` keyword. +Section [#sec-constructors] explains methods that instead use the +`constructor` keyword. Section [#sec-lemmas] discusses methods that are +declared with the `lemma` keyword. Methods declared with the `inductive` +`lemma` keywords are discussed later in the context of inductive +predicates (see [#sec-inductive-datatypes]). Methods declared with the +`colemma` keyword are discussed later in the context of co-inductive +types, in section [#sec-colemmas]. + +A method without is body is _abstract_. A method is allowed to be +abstract under the following circumstances: + +* It contains an `{:axiom}` attribute +* It contains an `{:imported}` attribute +* It contains a `{:decl}` attribute +* It is a declaration in an abstract module. +Note that when there is no body, Dafny assumes that the *ensures* +clauses are true without proof. + +### Constructors +To write structured object-oriented programs, one often relies on that +objects are constructed only in certain ways. For this purpose, Dafny +provides _constructor (method)s_, which are a restricted form of +initialization methods. A constructor is declared with the keyword +`constructor` instead of `method`. When a class contains a +constructor, every call to `new` for that class must be accompanied +with a call to one of the constructors. Moreover, a constructor +cannot be called at other times, only during object creation. Other +than these restrictions, there is no semantic difference between using +ordinary initialization methods and using constructors. + +The Dafny design allows the constructors to be named, which promotes +using names like `InitFromList` above. Still, many classes have just +one constructor or have a typical constructor. Therefore, Dafny +allows one _anonymous constructor_, that is, a constructor whose name +is essentially "". For example: +``` +class Item { + constructor (x: int, y: int) + // ... +} +``` +When invoking this constructor, the "`.`" is dropped, as in: +``` +m := new Item(45, 29); +``` +Note that an anonymous constructor is just one way to name a +constructor; there can be other constructors as well. + +### Lemmas +Sometimes there are steps of logic required to prove a program correct, +but they are too complex for Dafny to discover and use on its own. When +this happens, we can often give Dafny assistance by providing a lemma. +This is done by declaring a method with the `lemma` keyword. +Lemmas are implicitly ghost methods and the `ghost` keyword cannot +be applied to them. + +For an example, see the `FibProperty` lemma in +Section [#sec-proofs-in-dafny]. + +See [the Dafny Lemmas tutorial](http://rise4fun.com/Dafny/tutorial/Lemmas) +for more examples and hints for using lemmas. + +## Function Declarations + +```` +FunctionDecl = + ( "function" [ "method" ] { Attribute } + FunctionName + FunctionSignatureOrEllipsis_(allowGhostKeyword: ("method" present)) + | "predicate" [ "method" ] { Attribute } + PredicateName + PredicateSignatureOrEllipsis_(allowGhostKeyword: ("method" present)) + | "inductive" "predicate" { Attribute } + PredicateName + PredicateSignatureOrEllipsis_(allowGhostKeyword: false) + | "copredicate" { Attribute } + CopredicateName + PredicateSignatureOrEllipsis_(allowGhostKeyword: false) + ) + FunctionSpec [ FunctionBody ] + +FunctionSignatureOrEllipsis_(allowGhostKeyword) = + FunctionSignature_ | SignatureEllipsis_ +FunctionSignature_(allowGhostKeyword) = + [ GenericParameters ] Formals(allowGhostKeyword) ":" Type + +PredicateSignatureOrEllipsis_(allowGhostKeyword) = + PredicateSignature_(allowGhostKeyword) | SignatureEllipsis_ +PredicateSignature_(allowGhostKeyword) = + [ GenericParameters ] Formals(allowGhostKeyword) + +FunctionBody = "{" Expression(allowLemma: true, allowLambda: true) "}" +```` +In the above productions, allowGhostKeyword is true if the optional +"method" keyword was specified. This allows some of the +formal parameters of a function method to be specified as ghost. + +See section [#sec-function-specification] for a description of ``FunctionSpec``. + +A Dafny function is a pure mathematical function. It is allowed to +read memory that was specified in its `reads` expression but is not +allowed to have any side effects. + +Here is an example function declaration: +``` +function {:att1}{:att2} F<T1, T2>(a: A, b: B, c: C): T + requires Pre + reads Frame + ensures Post + decreases Rank +{ + Body +} +``` + +where `:att1` and `:att2` are attributes of the function, if any, `T1` +and `T2` are type parameters of the function (if generic), `a, b, c` are +the functions’s parameters, `T` is the type of the function’s result, +`Pre` is a boolean expression denoting the function’s precondition, +`Frame` denotes a set of objects whose fields the function body may +depend on, `Post` is a boolean expression denoting the function’s +postcondition, `Rank` is the function’s variant function, and `Body` is +an expression that defines the function return value. The precondition +allows a function to be partial, that is, the precondition says when the +function is defined (and Dafny will verify that every use of the function +meets the precondition). The postcondition is usually not needed, since +the body of the function gives the full definition. However, the +postcondition can be a convenient place to declare properties of the +function that may require an inductive proof to establish. For example: + +```` +function Factorial(n: int): int + requires 0 <= n + ensures 1 <= Factorial(n) +{ + if n == 0 then 1 else Factorial(n-1) * n +} +```` + +says that the result of Factorial is always positive, which Dafny +verifies inductively from the function body. To refer to the function’s +result in the postcondition, use the function itself, as shown in the +example. + +By default, a function is *ghost*, and cannot be called from non-ghost +code. To make it non-ghost, replace the keyword function with the two +keywords "function method". + +By default, a function has an implicit receiver parameter, `this`. This +parameter can be removed by preceding the function declaration with the +keyword `static`. A static function `F` in a class `C` can be invoked +by `C.F(…)`. This can give a convenient way to declare a number of helper +functions in a separate class. + +As for methods, a ``SignatureEllipsis_`` is used when declaring +a function in a module refinement. For example, if module `M0` declares +function `F`, a module `M1` can be declared to refine `M0` and +`M1` can then refine `F`. The refinement function, `M1.F` can have +a ``SignatureEllipsis_`` which means to copy the signature form +`M0.F`. A refinement function can furnish a body for a function +(if `M0.F` does not provide one). It can also add **ensures** +clauses. And if `F` is a predicate, it can add conjuncts to +a previously given body. + +### Function Transparency +A function is said to be _transparent_ in a location if the +contents of the body of the function is visible at that point. +A function is said to be _opaque_ at a location if it is not +transparent. However the ``FunctionSpec`` of a function +is always available. + +A function is usually transparent up to some unrolling level (up to +1, or maybe 2 or 3). If its arguments are all literals it is +transparent all the way. + +But the transparency of a function is affected by the following: + +* whether the function was declared to be protected, and +* whether the function was given the `{:opaque}` attribute (as explained +in Section [#sec-opaque]). + +The following table summarizes where the function is transparent. +The module referenced in the table is the module in which the +function is defined. + ++------------+--------------+-------------+-------------+ +| Protected? | `{:opaque}`? | Transparent | Transparent | +| | | Inside | Outside | +| | | Module | Module | ++:----------:+:------------:+:-----------:+:-----------:+ +| N | N | Y | Y | +| Y | N | Y | N | +| N | Y | N | N | ++------------+--------------+-------------+-------------+ + +When `{:opaque}` is specified for function `g`, `g` is opaque, +however the lemma `reveal_g` is available to give the semantics +of `g` whether in the defining module or outside. + +It currently is not allowed to have both `protected` and +`{:opaque}` specified for a function. + +### Predicates +A function that returns a `bool` results is called a _predicate_. As an +alternative syntax, a predicate can be declared by replacing the `function` +keyword with the `predicate` keyword and omitting a declaration of the +return type. + +### Inductive Predicates and Lemmas +See section [#sec-friendliness] for descriptions +of inductive predicates and lemmas. + +# Trait Types +```` +TraitDecl = "trait" { Attribute } TraitName [ GenericParameters ] + "{" { { DeclModifier } ClassMemberDecl(moduleLevelDecl: false) } "}" +```` + +A _trait_ is an "abstract superclass", or call it an "interface" or +"mixin". Traits are new to Dafny and are likely to evolve for a +while. + +The declaration of a trait is much like that of a class: +``` +trait J +{ + \(_members_\) +} +``` +where `\(_members_\)` can include fields, functions, and methods, but +no constructor methods. The functions and methods are allowed to be +declared `static`. + +A reference type `C` that extends a trait `J` is assignable to `J`, but +not the other way around. The members of `J` are available as members +of `C`. A member in `J` is not allowed to be redeclared in `C`, +except if the member is a non-`static` function or method without a +body in `J`. By doing so, type `C` can supply a stronger +specification and a body for the member. + +`new` is not allowed to be used with traits. Therefore, there is no +object whose allocated type is a trait. But there can of course be +objects of a class `C` that implements a trait `J`, and a reference to +such a `C` object can be used as a value of type `J`. + +As an example, the following trait represents movable geometric shapes: +``` +trait Shape +{ + function method Width(): real + reads this + method Move(dx: real, dy: real) + modifies this + method MoveH(dx: real) + modifies this + { + Move(dx, 0.0); + } +} +``` +Members `Width` and `Move` are _abstract_ (that is, body less) and can +be implemented differently by different classes that extend the trait. +The implementation of method `MoveH` is given in the trait and thus +gets used by all classes that extend `Shape`. Here are two classes +that each extends `Shape`: +``` +class UnitSquare extends Shape +{ + var x: real, y: real + function method Width(): real { // note the empty reads clause + 1.0 + } + method Move(dx: real, dy: real) + modifies this + { + x, y := x + dx, y + dy; + } +} +class LowerRightTriangle extends Shape +{ + var xNW: real, yNW: real, xSE: real, ySE: real + function method Width(): real + reads this + { + xSE - xNW + } + method Move(dx: real, dy: real) + modifies this + { + xNW, yNW, xSE, ySE := xNW + dx, yNW + dy, xSE + dx, ySE + dy; + } +} +``` +Note that the classes can declare additional members, that they supply +implementations for the abstract members of the trait, +that they repeat the member signatures, and that they are responsible +for providing their own member specifications that both strengthen the +corresponding specification in the trait and are satisfied by the +provided body. +Finally, here is some code that creates two class instances and uses +them together as shapes: +``` +var myShapes: seq<Shape>; +var A := new UnitSquare; +myShapes := [A]; +var tri := new LowerRightTriangle; +// myShapes contains two Shape values, of different classes +myShapes := myShapes + [tri]; +// move shape 1 to the right by the width of shape 0 +myShapes[1].MoveH(myShapes[0].Width()); +``` + +# Array Types +```` +ArrayType_ = arrayToken [ GenericInstantiation ] +```` + +Dafny supports mutable fixed-length _array types_ of any positive +dimension. Array types are reference types. + +## One-dimensional arrays + +A one-dimensional array of `n` `T` elements is created as follows: +``` +a := new T[n]; +``` +The initial values of the array elements are arbitrary values of type +`T`. +The length of an array is retrieved using the immutable `Length` +member. For example, the array allocated above satisfies: +``` +a.Length == n +``` + +For any integer-based numeric `i` in the range `0 <= i < a.Length`, +the _array selection_ expression `a[i]` retrieves element `i` (that +is, the element preceded by `i` elements in the array). The +element stored at `i` can be changed to a value `t` using the array +update statement: +``` +a[i] := t; +``` + +Caveat: The type of the array created by `new T[n]` is +`array<T>`. A mistake that is simple to make and that can lead to +befuddlement is to write `array<T>` instead of `T` after `new`. +For example, consider the following: +``` +var a := new array<T>; +var b := new array<T>[n]; +var c := new array<T>(n); // resolution error +var d := new array(n); // resolution error +``` +The first statement allocates an array of type `array<T>`, but of +unknown length. The second allocates an array of type +`array<array<T>>` of length `n`, that is, an array that holds `n` +values of type `array<T>`. The third statement allocates an +array of type `array<T>` and then attempts to invoke an anonymous +constructor on this array, passing argument `n`. Since `array` has no +constructors, let alone an anonymous constructor, this statement +gives rise to an error. If the type-parameter list is omitted for a +type that expects type parameters, Dafny will attempt to fill these +in, so as long as the `array` type parameter can be inferred, it is +okay to leave off the "`<T>`" in the fourth statement above. However, +as with the third statement, `array` has no anonymous constructor, so +an error message is generated. + +One-dimensional arrays support operations that convert a stretch of +consecutive elements into a sequence. For any array `a` of type +`array<T>`, integer-based numerics `lo` and `hi` satisfying +`0 <= lo <= hi <= a.Length`, the following operations each yields a +`seq<T>`: + ++---------------------+------------------------------------+ +| expression | description | ++---------------------+------------------------------------+ +| `a[lo..hi]` | subarray conversion to sequence | +| `a[lo..]` | drop | +| `a[..hi]` | take | +| `a[..]` | array conversion to sequence | ++---------------------+------------------------------------+ + +The expression `a[lo..hi]` takes the first `hi` elements of the array, +then drops the first `lo` elements thereof and returns what remains as +a sequence. The resulting sequence thus has length `hi - lo`. +The other operations are special instances of the first. If `lo` is +omitted, it defaults to `0` and if `hi` is omitted, it defaults to +`a.Length`. +In the last operation, both `lo` and `hi` have been omitted, thus +`a[..]` returns the sequence consisting of all the array elements of +`a`. + +The subarray operations are especially useful in specifications. For +example, the loop invariant of a binary search algorithm that uses +variables `lo` and `hi` to delimit the subarray where the search `key` +may be still found can be expressed as follows: +``` +key !in a[..lo] && key !in a[hi..] +``` +Another use is to say that a certain range of array elements have not +been changed since the beginning of a method: +``` +a[lo..hi] == old(a[lo..hi]) +``` +or since the beginning of a loop: +``` +ghost var prevElements := a[..]; +while // ... + invariant a[lo..hi] == prevElements[lo..hi] +{ + // ... +} +``` +Note that the type of `prevElements` in this example is `seq<T>`, if +`a` has type `array<T>`. + +A final example of the subarray operation lies in expressing that an +array's elements are a permutation of the array's elements at the +beginning of a method, as would be done in most sorting algorithms. +Here, the subarray operation is combined with the sequence-to-multiset +conversion: +``` +multiset(a[..]) == multiset(old(a[..])) +``` + +## Multi-dimensional arrays + +An array of 2 or more dimensions is mostly like a one-dimensional +array, except that `new` takes more length arguments (one for each +dimension), and the array selection expression and the array update +statement take more indices. For example: +``` +matrix := new T[m, n]; +matrix[i, j], matrix[x, y] := matrix[x, y], matrix[i, j]; +``` +create a 2-dimensional array whose dimensions have lengths `m` and +`n`, respectively, and then swaps the elements at `i,j` and `x,y`. +The type of `matrix` is `array2<T>`, and similarly for +higher-dimensional arrays (`array3<T>`, `array4<T>`, etc.). Note, +however, that there is no type `array0<T>`, and what could have been +`array1<T>` is actually named just `array<T>`. + +The `new` operation above requires `m` and `n` to be non-negative +integer-based numerics. These lengths can be retrieved using the +immutable fields `Length0` and `Length1`. For example, the following +holds of the array created above: +``` +matrix.Length0 == m && matrix.Length1 == n +``` +Higher-dimensional arrays are similar (`Length0`, `Length1`, +`Length2`, ...). The array selection expression and array update +statement require that the indices are in bounds. For example, the +swap statement above is well-formed only if: +``` +0 <= i < matrix.Length0 && 0 <= j < matrix.Length1 && +0 <= x < matrix.Length0 && 0 <= y < matrix.Length1 +``` + +In contrast to one-dimensional arrays, there is no operation to +convert stretches of elements from a multi-dimensional array to a +sequence. + +# Type object +```` +ObjectType_ = "object" +```` + +There is a built-in trait `object` that is like a supertype of all +reference types.[^fn-object-trait] Every class automatically extends +object and so does every user-defined trait. The purpose of type `object` +is to enable a uniform treatment of _dynamic frames_. In particular, it +is useful to keep a ghost field (typically named `Repr` for +"representation") of type `set<object>`. + +[^fn-object-trait]: The current compiler restriction that `object` cannot + be used as a type parameter needs to be removed. + +# Iterator types +```` +IteratorDecl = "iterator" { Attribute } IteratorName + ( [ GenericParameters ] + Formals(allowGhostKeyword: true) + [ "yields" Formals(allowGhostKeyword: true) ] + | "..." + ) + IteratorSpec [ BlockStmt ] +```` + +See section [#sec-iterator-specification] for a description of ``IteratorSpec``. + +An _iterator_ provides a programming abstraction for writing code that +iteratively returns elements. These CLU-style iterators are +_co-routines_ in the sense that they keep track of their own program +counter and control can be transferred into and out of the iterator +body. + +An iterator is declared as follows: +``` +iterator Iter<T>(\(_in-params_\)) yields (\(_yield-params_\)) + \(_specification_\) +{ + \(_body_\) +} +``` +where `T` is a list of type parameters (as usual, if there are no type +parameters, "`<T>`" is omitted). This declaration gives rise to a +reference type with the same name, `Iter<T>`. In the signature, +in-parameters and yield-parameters are the iterator's analog of a +method's in-parameters and out-parameters. The difference is that the +out-parameters of a method are returned to a caller just once, whereas +the yield-parameters of an iterator are returned each time the iterator +body performs a `yield`. The body consists of statements, like in a +method body, but with the availability also of `yield` statements. + +From the perspective of an iterator client, the `iterator` declaration +can be understood as generating a class `Iter<T>` with various +members, a simplified version of which is described next. + +The `Iter<T>` class contains an anonymous constructor whose parameters +are the iterator's in-parameters: +``` +predicate Valid() +constructor (\(_in-params_\)) + modifies this + ensures Valid() +``` +An iterator is created using `new` and this anonymous constructor. +For example, an iterator willing to return ten consecutive integers +from `start` can be declared as follows: +``` +iterator Gen(start: int) yields (x: int) +{ + var i := 0; + while i < 10 { + x := start + i; + yield; + i := i + 1; + } +} +``` +An instance of this iterator is created using: +``` +iter := new Gen(30); +``` + +The predicate `Valid()` says when the iterator is in a state where one +can attempt to compute more elements. It is a postcondition of the +constructor and occurs in the specification of the `MoveNext` member: +``` +method MoveNext() returns (more: bool) + requires Valid() + modifies this + ensures more ==> Valid() +``` +Note that the iterator remains valid as long as `MoveNext` returns +`true`. Once `MoveNext` returns `false`, the `MoveNext` method can no +longer be called. Note, the client is under no obligation to keep +calling `MoveNext` until it returns `false`, and the body of the +iterator is allowed to keep returning elements forever. + +The in-parameters of the iterator are stored in immutable fields of +the iterator class. To illustrate in terms of the example above, the +iterator class `Gen` contains the following field: +``` +var start: int +``` +The yield-parameters also result in members of the iterator class: +``` +var x: int +``` +These fields are set by the `MoveNext` method. If `MoveNext` returns +`true`, the latest yield values are available in these fields and the +client can read them from there. + +To aid in writing specifications, the iterator class also contains +ghost members that keep the history of values returned by +`MoveNext`. The names of these ghost fields follow the names of the +yield-parameters with an "`s`" appended to the name (to suggest +plural). Name checking rules make sure these names do not give rise +to ambiguities. The iterator class for `Gen` above thus contains: +``` +ghost var xs: seq<int> +``` +These history fields are changed automatically by `MoveNext`, but are +not assignable by user code. + +Finally, the iterator class contains some special fields for use in +specifications. In particular, the iterator specification gets +recorded in the following immutable fields: +``` +ghost var _reads: set<object> +ghost var _modifies: set<object> +ghost var _decreases0: T0 +ghost var _decreases1: T1 +// ... +``` +where there is a `_decreases\(_i_\): T\(_i_\)` field for each +component of the iterator's `decreases` +clause.[^fn-iterator-field-names] +In addition, there is a field: +``` +ghost var _new: set<object>; +``` +to which any objects allocated on behalf of the iterator body get +added. The iterator body is allowed to remove elements from the +`_new` set, but cannot by assignment to `_new` add any elements. + +[^fn-iterator-field-names]: It would make sense to rename the special + fields `_reads` and `_modifies` to have the same names as the + corresponding keywords, `reads` and `modifies`, as is done for + function values. Also, the various `_decreases\(_i_\)` fields can + combined into one field named `decreases` whose type is a + _n_-tuple. Thse changes may be incorporated into a future version + of Dafny. + +Note, in the precondition of the iterator, which is to hold upon +construction of the iterator, the in-parameters are indeed +in-parameters, not fields of `this`. + +It's regrettably tricky to use iterators. The language really +ought to have a `foreach` statement to make this easier. +Here is an example showing definition and use of an iterator. + +``` +iterator Iter<T>(s: set<T>) yields (x: T) + yield ensures x in s && x !in xs[..|xs|-1]; + ensures s == set z | z in xs; +{ + var r := s; + while (r != {}) + invariant forall z :: z in xs ==> x !in r; // r and xs are disjoint + invariant s == r + set z | z in xs; + { + var y :| y in r; + r, x := r - {y}, y; + yield; + assert y == xs[|xs|-1]; // needed as a lemma to prove loop invariant + } +} + +method UseIterToCopy<T>(s: set<T>) returns (t: set<T>) + ensures s == t; +{ + t := {}; + var m := new Iter(s); + while (true) + invariant m.Valid() && fresh(m._new); + invariant t == set z | z in m.xs; + decreases s - t; + { + var more := m.MoveNext(); + if (!more) { break; } + t := t + {m.x}; + } +} +``` + +<!-- +# Async-task types + +Another experimental feature in Dafny that is likely to undergo some +evolution is _asynchronous methods_. When an asynchronous method is +called, it does not return values for the out-parameters, but instead +returns an instance of an _async-task type_. An asynchronous method +declared in a class `C` with the following signature: +``` +async method AM<T>(\(_in-params_\)) returns (\(_out-params_\)) +``` +also gives rise to an async-task type `AM<T>` (outside the enclosing +class, the name of the type needs the qualification `C.AM<T>`). The +async-task type is a reference type and can be understood as a class +with various members, a simplified version of which is described next. + +Each in-parameter `x` of type `X` of the asynchronous method gives +rise to a immutable ghost field of the async-task type: +``` +ghost var x: X; +``` +Each out-parameter `y` of type `Y` gives rise to a field +``` +var y: Y; +``` +These fields are changed automatically by the time the asynchronous +method is successfully awaited, but are not assignable by user code. + +The async-task type also gets a number of special fields that are used +to keep track of dependencies, outstanding tasks, newly allocated +objects, etc. These fields will be described in more detail as the +design of asynchronous methods evolves. + +--> + +# Function types + +```` +Type = DomainType "->" Type +```` + +Functions are first-class values in Dafny. Function types have the form +`(T) -> U` where `T` is a comma-delimited list of types and `U` is a +type. `T` is called the function's _domain type(s)_ and `U` is its +_range type_. For example, the type of a function +``` +function F(x: int, b: bool): real +``` +is `(int, bool) -> real`. Parameters are not allowed to be ghost. + +To simplify the appearance of the basic case where a function's +domain consist of a list of exactly one type, the parentheses around +the domain type can be dropped in this case, as in `T -> U`. +This innocent simplification requires additional explanation in the +case where that one type is a tuple type, since tuple types are also +written with enclosing parentheses. +If the function takes a single argument that is a tuple, an additional +set of parentheses is needed. For example, the function +``` +function G(pair: (int, bool)): real +``` +has type `((int, bool)) -> real`. Note the necessary double +parentheses. Similarly, a function that takes no arguments is +different from one that takes a 0-tuple as an argument. For instance, +the functions +``` +function NoArgs(): real +function Z(unit: ()): real +``` +have types `() -> real` and `(()) -> real`, respectively. + +The function arrow, `->`, is right associative, so `A -> B -> C` means +`A -> (B -> C)`. The other association requires explicit parentheses: +`(A -> B) -> C`. + +Note that the receiver parameter of a named function is not part of +the type. Rather, it is used when looking up the function and can +then be thought of as being captured into the function definition. +For example, suppose function `F` above is declared in a class `C` and +that `c` references an object of type `C`; then, the following is type +correct: +``` +var f: (int, bool) -> real := c.F; +``` +whereas it would have been incorrect to have written something like: +``` +var f': (C, int, bool) -> real := F; // not correct +``` + +Outside its type signature, each function value has three properties, +described next. + +Every function implicitly takes the heap as an argument. No function +ever depends on the _entire_ heap, however. A property of the +function is its declared upper bound on the set of heap locations it +depends on for a given input. This lets the verifier figure out that +certain heap modifications have no effect on the value returned by a +certain function. For a function `f: T -> U` and a value `t` of type +`T`, the dependency set is denoted `f.reads(t)` and has type +`set<object>`. + +The second property of functions stems from the fact that every function +is potentially _partial_. In other words, a property of a function is its +_precondition_. For a function `f: T -> U`, the precondition of `f` for a +parameter value `t` of type `T` is denoted `f.requires(t)` and has type +`bool`. + +The third property of a function is more obvious---the function's +body. For a function `f: T -> U`, the value that the function yields +for an input `t` of type `T` is denoted `f(t)` and has type `U`. + +Note that `f.reads` and `f.requires` are themselves functions. +Suppose `f` has type `T -> U` and `t` has type `T`. Then, `f.reads` +is a function of type `T -> set<object>` whose `reads` and `requires` +properties are: +``` +f.reads.reads(t) == f.reads(t) +f.reads.requires(t) == true +``` +`f.requires` is a function of type `T -> bool` whose `reads` and +`requires` properties are: +``` +f.requires.reads(t) == f.reads(t) +f.requires.requires(t) == true +``` + +Dafny also support anonymous functions by means of +_lambda expressions_. See section [#sec-lambda-expressions]. + +# Algebraic Datatypes + +Dafny offers two kinds of algebraic datatypes, those defined +inductively and those defined co-inductively. The salient property of +every datatype is that each value of the type uniquely identifies one +of the datatype's constructors and each constructor is injective in +its parameters. + +```` +DatatypeDecl = ( InductiveDatatypeDecl | CoinductiveDatatypeDecl ) +```` + +## Inductive datatypes + +```` +InductiveDatatypeDecl_ = "datatype" { Attribute } DatatypeName [ GenericParameters ] + "=" DatatypeMemberDecl { "|" DatatypeMemberDecl } [ ";" ] +DatatypeMemberDecl = { Attribute } DatatypeMemberName [ FormalsOptionalIds ] +```` + +The values of inductive datatypes can be seen as finite trees where +the leaves are values of basic types, numeric types, reference types, +co-inductive datatypes, or function types. Indeed, values of +inductive datatypes can be compared using Dafny's well-founded +[<]{.monospace} ordering. + +An inductive datatype is declared as follows: +``` +datatype D<T> = \(_Ctors_\) +``` +where `\(_Ctors_\)` is a nonempty `|`-separated list of +_(datatype) constructors_ for the datatype. Each constructor has the +form: +``` +C(\(_params_\)) +``` +where `\(_params_\)` is a comma-delimited list of types, optionally +preceded by a name for the parameter and a colon, and optionally +preceded by the keyword `ghost`. If a constructor has no parameters, +the parentheses after the constructor name can be omitted. If no +constructor takes a parameter, the type is usually called an +_enumeration_; for example: +``` +datatype Friends = Agnes | Agatha | Jermaine | Jack +``` + +For every constructor `C`, Dafny defines a _discriminator_ `C?`, which +is a member that returns `true` if and only if the datatype value has +been constructed using `C`. For every named parameter `p` of a +constructor `C`, Dafny defines a _destructor_ `p`, which is a member +that returns the `p` parameter from the `C` call used to construct the +datatype value; its use requires that `C?` holds. For example, for +the standard `List` type +``` +datatype List<T> = Nil | Cons(head: T, tail: List<T>) +``` +the following holds: +``` +Cons(5, Nil).Cons? && Cons(5, Nil).head == 5 +``` +Note that the expression +``` +Cons(5, Nil).tail.head +``` +is not well-formed, since `Cons(5, Nil).tail` does not satisfy +`Cons?`. + +The names of the destructors must be unique across all the +constructors of the datatype. A constructor can have the same name as +the enclosing datatype; this is especially useful for +single-constructor datatypes, which are often called +_record types_. For example, a record type for black-and-white pixels +might be represented as follows: +``` +datatype Pixel = Pixel(x: int, y: int, on: bool) +``` + +To call a constructor, it is usually necessary only to mention the +name of the constructor, but if this is ambiguous, it is always +possible to qualify the name of constructor by the name of the +datatype. For example, `Cons(5, Nil)` above can be written +``` +List.Cons(5, List.Nil) +``` + +As an alternative to calling a datatype constructor explicitly, a +datatype value can be constructed as a change in one parameter from a +given datatype value using the _datatype update_ expression. For any +`d` whose type is a datatype that includes a constructor `C` that has +a parameter (destructor) named `f` of type `T`, and any expression `t` +of type `T`, +``` +d[f := t] +``` +constructs a value like `d` but whose `f` parameter is `t`. The +operation requires that `d` satisfies `C?`. For example, the +following equality holds: +``` +Cons(4, Nil)[tail := Cons(3, Nil)] == Cons(4, Cons(3, Nil)) +``` + +The datatype update expression also accepts multiple field +names, provided these are distinct. For example, a node of some +inductive datatype for trees may be updated as follows: + +``` +node[left := L, right := R] +``` + +## Tuple types +```` +TupleType_ = "(" [ Type { "," Type } ] ")" +```` + +Dafny builds in record types that correspond to tuples and gives these +a convenient special syntax, namely parentheses. For example, what +might have been declared as: +``` +datatype Pair<T,U> = Pair(0: T, 1: U) +``` +Dafny provides as the type `(T, U)` and the constructor `(t, u)`, as +if the datatype's name were "" and its type arguments are given in +round parentheses, and as if the constructor name were "". Note that +the destructor names are `0` and `1`, which are legal identifier names +for members. For example, showing the use of a tuple destructor, here +is a property that holds of 2-tuples (that is, _pairs_): +``` +(5, true).1 == true +``` + +Dafny declares _n_-tuples where _n_ is 0 or 2 or up. There are no +1-tuples, since parentheses around a single type or a single value have +no semantic meaning. The 0-tuple type, `()`, is often known as the +_unit type_ and its single value, also written `()`, is known as _unit_. + +## Co-inductive datatypes + +```` +CoinductiveDatatypeDecl_ = "codatatype" { Attribute } DatatypeName [ GenericParameters ] + "=" DatatypeMemberDecl { "|" DatatypeMemberDecl } [ ";" ] +```` + +Whereas Dafny insists that there is a way to construct every inductive +datatype value from the ground up, Dafny also supports +_co-inductive datatypes_, whose constructors are evaluated lazily and +hence allows infinite structures. A co-inductive datatype is declared +using the keyword `codatatype`; other than that, it is declared and +used like an inductive datatype. + +For example, +``` +codatatype IList<T> = Nil | Cons(head: T, tail: IList<T>) +codatatype Stream<T> = More(head: T, tail: Stream<T>) +codatatype Tree<T> = Node(left: Tree<T>, value: T, right: Tree<T>) +``` +declare possibly infinite lists (that is, lists that can be either +finite or infinite), infinite streams (that is, lists that are always +infinite), and infinite binary trees (that is, trees where every +branch goes on forever), respectively. + +The paper [Co-induction Simply], by Leino and +Moskal[@LEINO:Dafny:Coinduction], explains Dafny's implementation and +verification of co-inductive types. We capture the key features from that +paper in this section but the reader is referred to that paper for more +complete details and to supply bibliographic references that we have +omitted. + +Mathematical induction is a cornerstone of programming and program +verification. It arises in data definitions (e.g., some algebraic data +structures can be described using induction), it underlies program +semantics (e.g., it explains how to reason about finite iteration and +recursion), and it gets used in proofs (e.g., supporting lemmas about +data structures use inductive proofs). Whereas induction deals with +finite things (data, behavior, etc.), its dual, co-induction, deals with +possibly infinite things. Co-induction, too, is important in programming +and program verification, where it arises in data definitions (e.g., lazy +data structures), semantics (e.g., concurrency), and proofs (e.g., +showing refinement in a co-inductive big-step semantics). It is thus +desirable to have good support for both induction and co-induction in a +system for constructing and reasoning about programs. + +Co-datatypes and co-recursive functions make it possible to use lazily +evaluated data structures (like in Haskell or Agda). Co-predicates, +defined by greatest fix-points, let programs state properties of such +data structures (as can also be done in, for example, Coq). For the +purpose of writing co-inductive proofs in the language, we introduce +co-lemmas. Ostensibly, a co-lemma invokes the co-induction hypothesis +much like an inductive proof invokes the induction hypothesis. Underneath +the hood, our co-inductive proofs are actually approached via induction: +co-lemmas provide a syntactic veneer around this approach. + +The following example gives a taste of how the co-inductive features in +Dafny come together to give straightforward definitions of infinite +matters. +``` +// infinite streams +codatatype IStream<T> = ICons(head: T, tail: IStream) + +// pointwise product of streams +function Mult(a: IStream<int>, b: IStream<int>): IStream<int> +{ ICons(a.head * b.head, Mult(a.tail, b.tail)) } + +// lexicographic order on streams +copredicate Below(a: IStream<int>, b: IStream<int>) +{ a.head <= b.head && ((a.head == b.head) ==> Below(a.tail, b.tail)) } + +// a stream is Below its Square +colemma Theorem_BelowSquare(a: IStream<int>) +ensures Below(a, Mult(a, a)) +{ assert a.head <= Mult(a, a).head; + if a.head == Mult(a, a).head { + Theorem_BelowSquare(a.tail); + } +} + +// an incorrect property and a bogus proof attempt +colemma NotATheorem_SquareBelow(a: IStream<int>) + ensures Below(Mult(a, a), a); // ERROR +{ + NotATheorem_SquareBelow(a); +} +``` + +It defines a type `IStream` of infinite streams, with constructor `ICons` and +destructors `head` and `tail`. Function `Mult` performs pointwise +multiplication on infinite streams of integers, defined using a +co-recursive call (which is evaluated lazily). Co-predicate `Below` is +defined as a greatest fix-point, which intuitively means that the +co-predicate will take on the value true if the recursion goes on forever +without determining a different value. The co-lemma states the theorem +`Below(a, Mult(a, a))`. Its body gives the proof, where the recursive +invocation of the co-lemma corresponds to an invocation of the +co-induction hypothesis. + +The proof of the theorem stated by the first co-lemma lends +itself to the following intuitive reading: To prove that `a` is below +`Mult(a, a)`, check that their heads are ordered and, if the heads are +equal, also prove that the tails are ordered. The second co-lemma states +a property that does not always hold; the verifier is not fooled by the +bogus proof attempt and instead reports the property as unproved. + +We argue that these definitions in Dafny are simple enough to level the +playing field between induction (which is familiar) and co-induction +(which, despite being the dual of induction, is often perceived as eerily +mysterious). Moreover, the automation provided by our SMT-based verifier +reduces the tedium in writing co-inductive proofs. For example, it +verifies `Theorem_BelowSquare` from the program text given above— no +additional lemmas or tactics are needed. In fact, as a consequence of the +automatic-induction heuristic in Dafny, the verifier will +automatically verify Theorem_BelowSquare even given an empty body. + +Just like there are restrictions on when an _inductive hypothesis_ can be +invoked, there are restriction on how a _co-inductive_ hypothesis can be +_used_. These are, of course, taken into consideration by our verifier. +For example, as illustrated by the second co-lemma above, invoking the +co-inductive hypothesis in an attempt to obtain the entire proof goal is +futile. (We explain how this works in section [#sec-colemmas]) Our initial experience +with co-induction in Dafny shows it to provide an intuitive, low-overhead +user experience that compares favorably to even the best of today’s +interactive proof assistants for co-induction. In addition, the +co-inductive features and verification support in Dafny have other +potential benefits. The features are a stepping stone for verifying +functional lazy programs with Dafny. Co-inductive features have also +shown to be useful in defining language semantics, as needed to verify +the correctness of a compiler, so this opens the possibility that +such verifications can benefit from SMT automation. + +### Well-Founded Function/Method Definitions +The Dafny programming language supports functions and methods. A _function_ +in Dafny is a mathematical function (i.e., it is well-defined, +deterministic, and pure), whereas a _method_ is a body of statements that +can mutate the state of the program. A function is defined by its given +body, which is an expression. To ensure that function definitions +are mathematically consistent, Dafny insists that recursive calls be well-founded, +enforced as follows: Dafny computes the call graph of functions. The strongly connected +components within it are _clusters_ of mutually recursive definitions arranged in +a DAG. This stratifies the functions so that a call from one cluster in the DAG to a +lower cluster is allowed arbitrarily. For an intra-cluster call, Dafny prescribes a proof +obligation that gets taken through the program verifier’s reasoning engine. Semantically, +each function activation is labeled by a _rank_—a lexicographic tuple determined +by evaluating the function’s **decreases** clause upon invocation of the function. The +proof obligation for an intra-cluster call is thus that the rank of the callee is strictly less +(in a language-defined well-founded relation) than the rank of the caller. Because +these well-founded checks correspond to proving termination of executable code, we +will often refer to them as “termination checksâ€. The same process applies to methods. + +Lemmas in Dafny are commonly introduced by declaring a method, stating +the property of the lemma in the _postcondition_ (keyword **ensures**) of +the method, perhaps restricting the domain of the lemma by also giving a +_precondition_ (keyword **requires**), and using the lemma by invoking +the method. Lemmas are stated, used, and proved as methods, but +since they have no use at run time, such lemma methods are typically +declared as _ghost_, meaning that they are not compiled into code. The +keyword **lemma** introduces such a method. Control flow statements +correspond to proof techniques—case splits are introduced with if +statements, recursion and loops are used for induction, and method calls +for structuring the proof. Additionally, the statement: +``` +forall x | P(x) { Lemma(x); } +``` +is used to invoke `Lemma(x)` on all `x` for which `P(x)` holds. If +`Lemma(x)` ensures `Q(x)`, then the forall statement establishes +``` +forall x :: P(x) ==> Q(x). +``` + +### Defining Co-inductive Datatypes +Each value of an inductive datatype is finite, in the sense that it can +be constructed by a finite number of calls to datatype constructors. In +contrast, values of a co-inductive datatype, or co-datatype for short, +can be infinite. For example, a co-datatype can be used to represent +infinite trees. + +Syntactically, the declaration of a co-datatype in Dafny looks like that +of a datatype, giving prominence to the constructors (following Coq). The +following example defines a co-datatype Stream of possibly +infinite lists. + +``` +codatatype Stream<T> = SNil | SCons(head: T, tail: Stream) +function Up(n: int): Stream<int> { SCons(n, Up(n+1)) } +function FivesUp(n: int): Stream<int> + decreases 4 - (n - 1) % 5 +{ + if (n % 5 == 0) then + SCons(n, FivesUp(n+1)) + else + FivesUp(n+1) +} +``` + +`Stream` is a co-inductive datatype whose values are possibly infinite +lists. Function `Up` returns a stream consisting of all integers upwards +of `n` and `FivesUp` returns a stream consisting of all multiples of 5 +upwards of `n` . The self-call in `Up` and the first self-call in `FivesUp` +sit in productive positions and are therefore classified as co-recursive +calls, exempt from termination checks. The second self-call in `FivesUp` is +not in a productive position and is therefore subject to termination +checking; in particular, each recursive call must decrease the rank +defined by the **decreases** clause. + +Analogous to the common finite list datatype, Stream declares two +constructors, `SNil` and `SCons`. Values can be destructed using match +expressions and statements. In addition, like for inductive datatypes, +each constructor `C` automatically gives rise to a discriminator `C?` and +each parameter of a constructor can be named in order to introduce a +corresponding destructor. For example, if `xs` is the stream +`SCons(x, ys)`, then `xs.SCons?` and `xs.head == x` hold. In contrast +to datatype declarations, there is no grounding check for +co-datatypes—since a codatatype admits infinite values, the type is +nevertheless inhabited. + +### Creating Values of Co-datatypes +To define values of co-datatypes, one could imagine a “co-function†+language feature: the body of a “co-function†could include possibly +never-ending self-calls that are interpreted by a greatest fix-point +semantics (akin to a **CoFixpoint** in Coq). Dafny uses a different design: +it offers only functions (not “co-functionsâ€), but it classifies each +intra-cluster call as either _recursive_ or _co-recursive_. Recursive calls +are subject to termination checks. Co-recursive calls may be +never-ending, which is what is needed to define infinite values of a +co-datatype. For example, function `Up(n )` in the preceding example is defined as the +stream of numbers from `n` upward: it returns a stream that starts with `n` +and continues as the co-recursive call `Up(n + 1)`. + +To ensure that co-recursive calls give rise to mathematically consistent definitions, +they must occur only in productive positions. This says that it must be possible to determine +each successive piece of a co-datatype value after a finite amount of work. This +condition is satisfied if every co-recursive call is syntactically guarded by a constructor +of a co-datatype, which is the criterion Dafny uses to classify intra-cluster calls as being +either co-recursive or recursive. Calls that are classified as co-recursive are exempt from +termination checks. + +A consequence of the productivity checks and termination checks is that, even in the +absence of talking about least or greatest fix-points of self-calling functions, all functions +in Dafny are deterministic. Since there is no issue of several possible fix-points, +the language allows one function to be involved in both recursive and co-recursive calls, +as we illustrate by the function `FivesUp`. + +### Copredicates +Determining properties of co-datatype values may require an infinite +number of observations. To that avail, Dafny provides _co-predicates_ +which are function declarations that use the `copredicate` keyword. +Self-calls to a co-predicate need not terminate. Instead, the value +defined is the greatest fix-point of the given recurrence equations. +Continuing the preceding example, the following code defines a +co-predicate that holds for exactly those streams whose payload consists +solely of positive integers. The co-predicate definition implicitly also +gives rise to a corresponding prefix predicate, `Pos#`. The syntax for +calling a prefix predicate sets apart the argument that specifies the +prefix length, as shown in the last line; for this figure, we took the +liberty of making up a coordinating syntax for the signature of the +automatically generated prefix predicate (which is not part of +Dafny syntax). + +``` +copredicate Pos(s: Stream<int>) +{ + match s + case SNil => true + case SCons(x, rest) => x > 0 && Pos(rest) +} +// Automatically generated by the Dafny compiler: +predicate Pos#[_k: nat](s: Stream<int>) + decreases _k +{ if _k = 0 then true else + match s + case SNil => true + case SCons(x, rest) => x > 0 && Pos#[_k-1](rest) +} +``` + +Some restrictions apply. To guarantee that the greatest fix-point always +exists, the (implicit functor defining the) co-predicate must be +monotonic. This is enforced by a syntactic restriction on the form of the +body of co-predicates: after conversion to negation normal form (i.e., +pushing negations down to the atoms), intra-cluster calls of +co-predicates must appear only in _positive_ positions—that is, they must +appear as atoms and must not be negated. Additionally, to guarantee +soundness later on, we require that they appear in _co-friendly_ +positions—that is, in negation normal form, when they appear under +existential quantification, the quantification needs to be limited to a +finite range[^fn-copredicate-restriction]. Since the evaluation of a co-predicate might not +terminate, co-predicates are always ghost. There is also a restriction on +the call graph that a cluster containing a co-predicate must contain only +co-predicates, no other kinds of functions. + +[^fn-copredicate-restriction]: Higher-order function support in Dafny is + rather modest and typical reasoning patterns do not involve them, so this + restriction is not as limiting as it would have been in, e.g., Coq. + +A **copredicate** declaration of `P` defines not just a co-predicate, but +also a corresponding _prefix predicate_ `P#`. A prefix predicate is a +finite unrolling of a co-predicate. The prefix predicate is constructed +from the co-predicate by + +* adding a parameter _k of type nat to denote the prefix length, + +* adding the clause "**decreases** `_k;`" to the prefix predicate (the + co-predicate itself is not allowed to have a decreases clause), + +* replacing in the body of the co-predicate every intra-cluster + call `Q(args)` to a copredicate by a call `Q#[_k - 1](args)` + to the corresponding prefix predicate, and then + +* prepending the body with `if _k = 0 then true else`. + +For example, for co-predicate `Pos`, the definition of the prefix +predicate `Pos#` is as suggested above. Syntactically, the prefix-length +argument passed to a prefix predicate to indicate how many times to +unroll the definition is written in square brackets, as in `Pos#[k](s)`. +In the Dafny grammar this is called a ``HashCall``. The definition of +`Pos#` is available only at clusters strictly higher than that of `Pos`; +that is, `Pos` and `Pos#` must not be in the same cluster. In other +words, the definition of `Pos` cannot depend on `Pos#`. + +#### Co-Equality +Equality between two values of a co-datatype is a built-in co-predicate. +It has the usual equality syntax `s == t`, and the corresponding prefix +equality is written `s ==#[k] t`. And similarly for `s != t` +and `s !=#[k] t`. + +### Co-inductive Proofs +From what we have said so far, a program can make use of properties of +co-datatypes. For example, a method that declares `Pos(s)` as a +precondition can rely on the stream `s` containing only positive integers. +In this section, we consider how such properties are established in the +first place. + +#### Properties About Prefix Predicates +Among other possible strategies for establishing co-inductive properties +we take the time-honored approach of reducing co-induction to +induction. More precisely, Dafny passes to the SMT solver an +assumption `D(P)` for every co-predicate `P`, where: + +``` +D(P) = ? x • P(x) <==> ? k • P#[k](x) +``` + +In other words, a co-predicate is true iff its corresponding prefix +predicate is true for all finite unrollings. + +In Sec. 4 of the paper [Co-induction Simply] a soundness theorem of such +assumptions is given, provided the co-predicates meet the co-friendly +restrictions. An example proof of `Pos(Up(n))` for every `n > 0` is +here shown: + +``` +lemma UpPosLemma(n: int) + requires n > 0 + ensures Pos(Up(n)) +{ + forall k | 0 <= k { UpPosLemmaK(k, n); } +} + +lemma UpPosLemmaK(k: nat, n: int) + requires n > 0 + ensures Pos#[k](Up(n)) + decreases k +{ + if k != 0 { + // this establishes Pos#[k-1](Up(n).tail) + UpPosLemmaK(k-1, n+1); + } +} +``` + +The lemma `UpPosLemma` proves `Pos(Up(n))` for every `n > 0`. We first +show `Pos#[k](Up(n ))`, for `n > 0` and an arbitrary `k`, and then use +the forall statement to show `? k • Pos#[k](Up(n))`. Finally, the axiom +`D(Pos)` is used (automatically) to establish the co-predicate. + + +#### Colemmas +As we just showed, with help of the `D` axiom we can now prove a +co-predicate by inductively proving that the corresponding prefix +predicate holds for all prefix lengths `k` . In this section, we introduce +_co-lemma_ declarations, which bring about two benefits. The first benefit +is that co-lemmas are syntactic sugar and reduce the tedium of having to +write explicit quantifications over `k` . The second benefit is that, in +simple cases, the bodies of co-lemmas can be understood as co-inductive +proofs directly. As an example consider the following co-lemma. + +``` +colemma UpPosLemma(n: int) + requires n > 0 + ensures Pos(Up(n)) +{ + UpPosLemma(n+1); +} +``` +This co-lemma can be understood as follows: `UpPosLemma` invokes itself +co-recursively to obtain the proof for `Pos(Up(n).tail)` (since `Up(n).tail` +equals `Up(n+1)`). The proof glue needed to then conclude `Pos(Up(n))` is +provided automatically, thanks to the power of the SMT-based verifier. + +#### Prefix Lemmas +To understand why the above `UpPosLemma` co-lemma code is a sound proof, +let us now describe the details of the desugaring of co-lemmas. In +analogy to how a **copredicate** declaration defines both a co-predicate and +a prefix predicate, a **colemma** declaration defines both a co-lemma and +_prefix lemma_. In the call graph, the cluster containing a co-lemma must +contain only co-lemmas and prefix lemmas, no other methods or function. +By decree, a co-lemma and its corresponding prefix lemma are always +placed in the same cluster. Both co-lemmas and prefix lemmas are always +ghosts. + +The prefix lemma is constructed from the co-lemma by + +* adding a parameter `_k` of type `nat` to denote the prefix length, + +* replacing in the co-lemma’s postcondition the positive co-friendly + occurrences of co-predicates by corresponding prefix predicates, + passing in `_k` as the prefix-length argument, + +* prepending `_k` to the (typically implicit) **decreases** clause of the co-lemma, + +* replacing in the body of the co-lemma every intra-cluster call + `M(args)` to a colemma by a call `M#[_k - 1](args)` to the + corresponding prefix lemma, and then + +* making the body’s execution conditional on `_k != 0`. + +Note that this rewriting removes all co-recursive calls of co-lemmas, +replacing them with recursive calls to prefix lemmas. These recursive +call are, as usual, checked to be terminating. We allow the pre-declared +identifier `_k` to appear in the original body of the +co-lemma.[^fn-co-predicate-co-lemma-diffs] + +[^fn-co-predicate-co-lemma-diffs]: Note, two places where co-predicates + and co-lemmas are not analogous are: co-predicates must not make + recursive calls to their prefix predicates, and co-predicates cannot + mention _k. + +We can now think of the body of the co-lemma as being replaced by a +**forall** call, for every _k_ , to the prefix lemma. By construction, +this new body will establish the colemma’s declared postcondition (on +account of the `D` axiom, and remembering that only the positive +co-friendly occurrences of co-predicates in the co-lemma’s postcondition +are rewritten), so there is no reason for the program verifier to check +it. + +The actual desugaring of our co-lemma `UpPosLemma` is in fact the +previous code for the `UpPosLemma` lemma except that `UpPosLemmaK` is +named `UpPosLemma#` and modulo a minor syntactic difference in how the +`k` argument is passed. + +In the recursive call of the prefix lemma, there is a proof obligation +that the prefixlength argument `_k - 1` is a natural number. +Conveniently, this follows from the fact that the body has been wrapped +in an `if _k != 0` statement. This also means that the postcondition must +hold trivially when `_k = 0`, or else a postcondition violation will be +reported. This is an appropriate design for our desugaring, because +co-lemmas are expected to be used to establish co-predicates, whose +corresponding prefix predicates hold trivially when `_k = 0`. (To prove +other predicates, use an ordinary lemma, not a co-lemma.) + +It is interesting to compare the intuitive understanding of the +co-inductive proof in using a co-lemma with the inductive proof in using +the lemma. Whereas the inductive proof is performing proofs for deeper +and deeper equalities, the co-lemma can be understood as producing the +infinite proof on demand. + +# Newtypes +```` +NewtypeDecl = "newtype" { Attribute } NewtypeName "=" + ( NumericTypeName [ ":" Type ] "|" Expression(allowLemma: false, allowLambda: true) + | Type + ) +```` + +A new numeric type can be declared with the _newtype_ +declaration[^fn-newtype-name], for example: +``` +newtype N = x: M | Q +``` +where `M` is a numeric type and `Q` is a boolean expression that can +use `x` as a free variable. If `M` is an integer-based numeric type, +then so is `N`; if `M` is real-based, then so is `N`. If the type `M` +can be inferred from `Q`, the "`: M`" can be omitted. If `Q` is just +`true`, then the declaration can be given simply as: +``` +newtype N = M +``` +Type `M` is known as the _base type_ of `N`. + +[^fn-newtype-name]: Should `newtype` perhaps be renamed to `numtype`? + +A newtype is a numeric type that supports the same operations as its +base type. The newtype is distinct from and incompatible with other +numeric types; in particular, it is not assignable to its base type +without an explicit conversion. An important difference between the +operations on a newtype and the operations on its base type is that +the newtype operations are defined only if the result satisfies the +predicate `Q`, and likewise for the literals of the +newtype.[^fn-newtype-design-question] + +[^fn-newtype-design-question]: Would it be useful to also + automatically define `predicate N?(m: M) { Q }`? + +For example, suppose `lo` and `hi` are integer-based numerics that +satisfy `0 <= lo <= hi` and consider the following code fragment: +``` +var mid := (lo + hi) / 2; +``` +If `lo` and `hi` have type `int`, then the code fragment is legal; in +particular, it never overflows, since `int` has no upper bound. In +contrast, if `lo` and `hi` are variables of a newtype `int32` declared +as follows: +``` +newtype int32 = x | -0x80000000 <= x < 0x80000000 +``` +then the code fragment is erroneous, since the result of the addition +may fail to satisfy the predicate in the definition of `int32`. The +code fragment can be rewritten as +``` +var mid := lo + (hi - lo) / 2; +``` +in which case it is legal for both `int` and `int32`. + +Since a newtype is incompatible with its base type and since all +results of the newtype's operations are members of the newtype, a +compiler for Dafny is free to specialize the run-time representation +of the newtype. For example, by scrutinizing the definition of +`int32` above, a compiler may decide to store `int32` values using +signed 32-bit integers in the target hardware. + +Note that the bound variable `x` in `Q` has type `M`, not `N`. +Consequently, it may not be possible to state `Q` about the `N` +value. For example, consider the following type of 8-bit 2's +complement integers: +``` +newtype int8 = x: int | -128 <= x < 128 +``` +and consider a variable `c` of type `int8`. The expression +``` +-128 <= c < 128 +``` +is not well-defined, because the comparisons require each operand to +have type `int8`, which means the literal `128` is checked to be of +type `int8`, which it is not. A proper way to write this expression +would be to use a conversion operation, described next, on `c` to +convert it to the base type: +``` +-128 <= int(c) < 128 +``` + +If possible Dafny will represent values of the newtype using +a native data type for the sake of efficiency. This action can +be inhibited or a specific native data type selected by +using the `(:nativeType)` attribute, as explained in +section [#sec-nativetype]. + +There is a restriction that the value `0` must be part of every +newtype.[^fn-newtype-zero] + +[^fn-newtype-zero]: The restriction is due to a current limitation in + the compiler. This will change in the future and will also open + up the possibility for subset types and non-null reference + types. + +## Numeric conversion operations + +For every numeric type `N`, there is a conversion function with the +same name. It is a partial identity function. It is defined when the +given value, which can be of any numeric type, is a member of the type +converted to. When the conversion is from a real-based numeric type +to an integer-based numeric type, the operation requires that the +real-based argument has no fractional part. (To round a real-based +numeric value down to the nearest integer, use the `.Trunc` member, +see Section [#sec-numeric-types].) + +To illustrate using the example from above, if `lo` and `hi` have type +`int32`, then the code fragment can legally be written as follows: +``` +var mid := (int(lo) + int(hi)) / 2; +``` +where the type of `mid` is inferred to be `int`. Since the result +value of the division is a member of type `int32`, one can introduce +yet another conversion operation to make the type of `mid` be `int32`: +``` +var mid := int32((int(lo) + int(hi)) / 2); +``` +If the compiler does specialize the run-time representation for +`int32`, then these statements come at the expense of two, +respectively three, run-time conversions. + +# Subset types +```` +NatType_ = "nat" +```` + +A _subset type_ is a restricted use of an existing type, called +the _base type_ of the subset type. A subset type is like a +combined use of the base type and a predicate on the base +type. + +An assignment from a subset type to its base type is always +allowed. An assignment in the other direction, from the base type to +a subset type, is allowed provided the value assigned does indeed +satisfy the predicate of the subset type. +(Note, in contrast, assignments between a newtype and its base type +are never allowed, even if the value assigned is a value of the target +type. For such assignments, an explicit conversion must be used, see +Section [#sec-numeric-conversion-operations].) + +Dafny supports one subset type, namely the built-in type `nat`, +whose base type is `int`.[^fn-more-subset-types] Type `nat` +designates the non-negative subrange of `int`. A simple example that +puts subset type `nat` to good use is the standard Fibonacci +function: +``` +function Fib(n: nat): nat +{ + if n < 2 then n else Fib(n-2) + Fib(n-1) +} +``` +An equivalent, but clumsy, formulation of this function (modulo the +wording of any error messages produced at call sites) would be to use +type `int` and to write the restricting predicate in pre- and +postconditions: +``` +function Fib(n: int): int + requires 0 <= n; // the function argument must be non-negative + ensures 0 <= Fib(n); // the function result is non-negative +{ + if n < 2 then n else Fib(n-2) + Fib(n-1) +} +``` + +[^fn-more-subset-types]: A future version of Dafny will support + user-defined subset types. + +Type inference will never infer the type of a variable to be a +subset type. It will instead infer the type to be the base type +of the subset type. For example, the type of `x` in +``` +forall x :: P(x) +``` +will be `int`, even if predicate `P` declares its argument to have +type `nat`. + +# Statements +```` +Stmt = ( BlockStmt | AssertStmt | AssumeStmt | PrintStmt | UpdateStmt + | VarDeclStatement | IfStmt | WhileStmt | MatchStmt | ForallStmt + | CalcStmt | ModifyStmt | LabeledStmt_ | BreakStmt_ | ReturnStmt + | YieldStmt | SkeletonStmt + ) +```` +Many of Dafny's statements are similar to those in traditional +programming languages, but a number of them are significantly different. +This grammar production shows the different kinds of Dafny statements. +They are described in subsequent sections. + +## Labeled Statement +```` +LabeledStmt_ = "label" LabelName ":" Stmt +```` +A labeled statement is just the keyword `label` followed by and +identifier which is the label followed by a colon and a +statement. The label may be referenced in a break statement +to transfer control to the location after that statement. + +## Break Statement +```` +BreakStmt_ = "break" ( LabelName | { "break" } ) ";" +```` +A break statement breaks out of one or more loops (if the +statement consists solely of one or more `break` keywords), +or else transfers control to just past the statement +bearing the referenced label, if a label was used. + +## Block Statement +```` +BlockStmt = "{" { Stmt } "}" +```` +A block statement is just a sequence of statements enclosed by curly braces. + +## Return Statement +```` +ReturnStmt = "return" [ Rhs { "," Rhs } ] ";" +```` +A return statement can only be used in a method. It is used +to terminate the execution of the method. +To return a value from a method, the value is assigned to one +of the named return values sometime before a return statement. +In fact, the return values act very much like local variables, +and can be assigned to more than once. Return statements are +used when one wants to return before reaching the end of the +body block of the method. Return statements can be just the +return keyword (where the current value of the out parameters +are used), or they can take a list of values to return. +If a list is given the number of values given must be the +same as the number of named return values. + +## Yield Statement +```` +YieldStmt = "yield" [ Rhs { "," Rhs } ] ";" +```` + +A yield statement can only be used in an iterator. +See section [Iterator types](#sec-iterator-types) for more details +about iterators. + +The body of an iterator is a _co-routine_. It is used +to yield control to its caller, signaling that a new +set of values for the iterator's yield parameters (if any) +are available. Values are assigned to the yield parameters +at or before a yield statement. +In fact, the yield parameters act very much like local variables, +and can be assigned to more than once. Yield statements are +used when one wants to return new yield parameter values +to the caller. Yield statements can be just the +**yield** keyword (where the current value of the yield parameters +are used), or they can take a list of values to yield. +If a list is given the number of values given must be the +same as the number of named return yield parameters. + +## Update Statement +```` +UpdateStmt = Lhs { "," Lhs } + ( ":=" Rhs { "," Rhs } + | ":|" [ "assume" ] Expression(allowLemma: false, allowLambda: true) + ) + ";"" +```` + +The update statement has two forms. The first more normal form +allows for parallel assignment of right-hand-side values to the +left-hand side. For example `x,y := y,x` to swap the values +of `x` and `y`. Of course the common case will have only one +rhs and one lhs. + +The form that uses "`:|`" assigns some values to the left-hand-side +variables such that the boolean expression on the right hand side +is satisfied. This can be used to make a choice as in the +following example where we choose an element in a set. + +``` +function PickOne<T>(s: set<T>): T + requires s != {} +{ + var x :| x in s; x +} +``` + +Dafny will report an error if it cannot prove that values +exist which satisfy the condition. + +In addition, though the choice is arbitrary, given identical +circumstances the choice will be made consistently. + + +In the actual grammar two additional forms are recognized for +purposes of error detection. The form: + +```` +Lhs { Attribute} ; +```` + +is assumed to be a mal-formed call. + +The form + +```` +Lhs ":" +```` + +is diagnosed as a label in which the user forgot the **label** keyword. + +## Variable Declaration Statement +```` +VarDeclStatement = [ "ghost" ] "var" { Attribute } + ( + LocalIdentTypeOptional { "," { Attribute } LocalIdentTypeOptional } + [ ":=" Rhs { "," Rhs } + | { Attribute } ":|" [ "assume" ] Expression(allowLemma: false, allowLambda: true) + ] + | + "(" CasePattern { "," CasePattern } ")" + ":=" Expression(allowLemma: false, allowLambda: true) + ) + ";" +```` + +A ``VarDeclStatement`` is used to declare one or more local variables in a method or function. +The type of each local variable must be given unless the variable is given an initial +value in which case the type will be inferred. If initial values are given, the number of +values must match the number of variables declared. + +Note that the type of each variable must be given individually. The following code + +``` +var x, y : int; +``` +does not declare both `x` and `y` to be of type `int`. Rather it will give an +error explaining that the type of `x` is underspecified. + +The lefthand side can also contain a tuple of patterns which will be +matched against the right-hand-side. For example: + +``` +function returnsTuple() : (int, int) +{ + (5, 10) +} + +function usesTuple() : int +{ + var (x, y) := returnsTuple(); + x + y +} +``` + +## Guards +```` +Guard = ( "*" | "(" "*" ")" | Expression(allowLemma: true, allowLambda: true) ) +```` +Guards are used in `if` and `while` statements as boolean expressions. Guards +take two forms. + +The first and most common form is just a boolean expression. + +The second form is either `*` or `(*)`. These have the same meaning. An +unspecified boolean value is returned. The value returned +may be different each time it is executed. + +## Binding Guards +```` +BindingGuard(allowLambda) = + IdentTypeOptional { "," IdentTypeOptional } { Attribute } + ":|" Expression(allowLemma: true, allowLambda) +```` + +A ``BindingGuard`` is used as a condition in an ``IfStmt``. +It binds the identifiers declared in the ``IdentTypeOptional``s. +If there exists one or more assignments of values to the bound identifiers +for which ``Expression`` is true, then the ``BindingGuard`` +returns true and the identifiers are bound to values that make the +``Expression`` true. + +The identifiers bound by ``BindingGuard`` are ghost variables +and cannot be assigned to non-ghost variables. They are only +used in specification contexts. + +Here is an example: + +``` +predicate P(n: int) +{ + n % 2 == 0 +} + +method M1() returns (ghost y: int) + requires exists x :: P(x) + ensures P(y) +{ + if x : int :| P(x) { + y := x; + } +} +``` + +## If Statement +```` +IfStmt = "if" + ( IfAlternativeBlock + | + ( BindingGuard(allowLambda: true) + | Guard + | "..." + ) + BlockStmt [ "else" ( IfStmt | BlockStmt ) ] + ) +```` + +In the simplest form an `if` statement uses a guard that is a boolean +expression. It then has the same form as in C# and other common +programming languages. For example + +``` + if x < 0 { + x := -x; + } +``` + +If the guard is an asterisk then a non-deterministic choice is made: + +``` + if * { + print "True"; + } else { + print "False"; + } +``` + +```` +IfAlternativeBlock = + "{" { "case" + ( + BindingGuard(allowLambda:false) + | Expression(allowLemma: true, allowLambda: false) + ) "=>" { Stmt } } "}" . +```` + +The `if` statement using the `IfAlternativeBlock` form is similar to the +`if ... fi` construct used in the book "A Discipline of Programming" by +Edsger W. Dijkstra. It is used for a multi-branch `if`. + +For example: +``` + if { + case x <= y => max := y; + case y <= x => max := y; + } +``` + +In this form the expressions following the `case` keyword are called +_guards_. The statement is evaluated by evaluating the guards in an +undetermined order until one is found that is `true` or else all have +evaluated to `false`. If none of them evaluate to `true` then the `if` +statement does nothing. Otherwise the statements to the right of `=>` +for the guard that evaluated to `true` are executed. + +## While Statement +```` +WhileStmt = "while" + ( LoopSpecWhile WhileAlternativeBlock + | ( Guard | "..." ) LoopSpec + ( BlockStmt + | "..." + | /* go body-less */ + ) + ) +```` + +```` +WhileAlternativeBlock = + "{" { "case" Expression(allowLemma: true, allowLambda: false) "=>" { Stmt } } "}" . +```` + +See section [#sec-loop-specification] for a description of ``LoopSpec``. + +The `while` statement is Dafny's only loop statement. It has two general +forms. + +The first form is similar to a while loop in a C-like language. For +example: + +``` + var i := 0; + while i < 5 { + i := i + 1; + } +``` + +In this form the condition following the `while` is one of these: + +* A boolean expression. If true it means execute one more +iteration of the loop. If false then terminate the loop. +* An asterisk (`*`), meaning non-deterministically yield either +`true` or `false` as the value of the condition +* An ellipsis (`...`), which makes the while statement a _skeleton_ +`while` statement. TODO: What does that mean? + +The _body_ of the loop is usually a block statement, but it can also +be a _skeleton_, denoted by ellipsis, or missing altogether. +TODO: Wouldn't a missing body cause problems? Isn't it clearer to have +a block statement with no statements inside? + +The second form uses the `WhileAlternativeBlock`. It is similar to the +`do ... od` construct used in the book "A Discipline of Programming" by +Edsger W. Dijkstra. For example: + +``` + while + decreases if 0 <= r then r else -r; + { + case r < 0 => + r := r + 1; + case 0 < r => + r := r - 1; + } +``` +For this form the guards are evaluated in some undetermined order +until one is found that is true, in which case the corresponding statements +are executed. If none of the guards evaluates to true then the +loop execution is terminated. + +### Loop Specifications +For some simple loops such as those mentioned previously Dafny can figure +out what the loop is doing without more help. However in general the user +must provide more information in order to help Dafny prove the effect of +the loop. This information is provided by a ``LoopSpec``. A +``LoopSpec`` provides information about invariants, termination, and +what the loop modifies. ``LoopSpecs`` are explained in +section [#sec-loop-specification]. However the following sections +present additional rationale and tutorial on loop specifications. + +#### Loop Invariants + +`While` loops present a problem for Dafny. There is no way for Dafny to +know in advance how many times the code will go around the loop. But +Dafny needs to consider all paths through a program, which could include +going around the loop any number of times. To make it possible for Dafny +to work with loops, you need to provide loop invariants, another kind of +annotation. + +A loop invariant is an expression that holds upon entering a loop, and +after every execution of the loop body. It captures something that is +invariant, i.e. does not change, about every step of the loop. Now, +obviously we are going to want to change variables, etc. each time around +the loop, or we wouldn't need the loop. Like pre- and postconditions, an +invariant is a property that is preserved for each execution of the loop, +expressed using the same boolean expressions we have seen. For example, + +``` +var i := 0; +while i < n + invariant 0 <= i +{ + i := i + 1; +} +``` + +When you specify an invariant, Dafny proves two things: the invariant +holds upon entering the loop, and it is preserved by the loop. By +preserved, we mean that assuming that the invariant holds at the +beginning of the loop, we must show that executing the loop body once +makes the invariant hold again. Dafny can only know upon analyzing the +loop body what the invariants say, in addition to the loop guard (the +loop condition). Just as Dafny will not discover properties of a method +on its own, it will not know any but the most basic properties of a loop +are preserved unless it is told via an invariant. + +#### Loop Termination + +Dafny proves that code terminates, i.e. does not loop forever, by using +`decreases` annotations. For many things, Dafny is able to guess the right +annotations, but sometimes it needs to be made explicit. In fact, for all +of the code we have seen so far, Dafny has been able to do this proof on +its own, which is why we haven't seen the decreases annotation explicitly +yet. There are two places Dafny proves termination: loops and recursion. +Both of these situations require either an explicit annotation or a +correct guess by Dafny. + +A `decreases` annotation, as its name suggests, gives Dafny an expression +that decreases with every loop iteration or recursive call. There are two +conditions that Dafny needs to verify when using a decreases expression: + +* that the expression actually gets smaller, and +* that it is bounded. + +Many times, an integral value (natural or plain integer) is the quantity +that decreases, but other things that can be used as well. In the case of +integers, the bound is assumed to be zero. For example, the following is +a proper use of decreases on a loop (with its own keyword, of course): + +``` + while 0 < i + invariant 0 <= i + decreases i + { + i := i - 1; + } +``` + +Here Dafny has all the ingredients it needs to prove termination. The +variable i gets smaller each loop iteration, and is bounded below by +zero. This is fine, except the loop is backwards from most loops, which +tend to count up instead of down. In this case, what decreases is not the +counter itself, but rather the distance between the counter and the upper +bound. A simple trick for dealing with this situation is given below: + +``` + while i < n + invariant 0 <= i <= n + decreases n - i + { + i := i + 1; + } +``` + +This is actually Dafny's guess for this situation, as it sees `i < n` and +assumes that `n - i` is the quantity that decreases. The upper bound of the +loop invariant implies that `0 <= n – i`, and gives Dafny a lower bound on +the quantity. This also works when the bound `n` is not constant, such as +in the binary search algorithm, where two quantities approach each other, +and neither is fixed. + +If the **decreases** clause of a loop specified "*", then no +termination check will be performed. Use of this feature is sound only with +respect to partial correctness. + +#### Loop Framing +In some cases we also must specify what memory locations the loop body +is allowed to modify. This is done using a `modifies` clause. +See the discussion of framing in methods for a fuller discussion. + +## Match Statement +```` +MatchStmt = "match" Expression(allowLemma: true, allowLambda: true) + ( "{" { CaseStatement } "}" + | { CaseStatement } + ) + +CaseStatement = CaseBinding_ "=>" { Stmt } +```` + +The `match` statement is used to do case analysis on a value of inductive +or co-inductive type. The form with no leading ``Ident`` is for matching +tuples. The expression after the `match` keyword is the (co)inductive +value being matched. The expression is evaluated and then matched against +each of the case clauses. + +There must be a case clause for each constructor of the data type. +The identifier after the `case` keyword in a case clause, if present, +must be the name of one of the data type's constructors. +If the constructor takes parameters then a parenthesis-enclosed +list of identifiers (with optional type) must follow the +constructor. There must be as many identifiers as the constructor +has parameters. If the optional type is given it must be the same +as the type of the corresponding parameter of the constructor. +If no type is given then the type of the corresponding parameter +is the type assigned to the identifier. + +When an inductive value that was created using constructor +expression `C1(v1, v2)` is matched against a case clause +`C2(x1, x2`), there is a match provided that `C1` and `C2` are the +same constructor. In that case `x1` is bound to value `v1` and +`x2` is bound to `v2`. The identifiers in the case pattern +are not mutable. Here is an example of the use of a `match` statement. + +``` +datatype Tree = Empty | Node(left: Tree, data: int, right: Tree) + +// Return the sum of the data in a tree. +method Sum(x: Tree) returns (r: int) +{ + match x { + case Empty => r := -1; + case Node(t1 : Tree, d, t2) => { + var v1 := Sum(t1); + var v2 := Sum(t2); + r := v1 + d + v2; + } + } +} +``` + +Note that the `Sum` method is recursive yet has no `decreases` annotation. +In this case it is not needed because Dafny is able to deduce that +`t1` and `t2` are _smaller_ (structurally) than `x`. If `Tree` had been +coinductive this would not have been possible since `x` might have been +infinite. + +## Assert Statement +```` +AssertStmt = + "assert" { Attribute } + ( Expression(allowLemma: false, allowLambda: true) + | "..." + ) ";" +```` + +`Assert` statements are used to express logical proposition that are +expected to be true. Dafny will attempt to prove that the assertion +is true and give an error if not. Once it has proved the assertion +it can then use its truth to aid in following deductions. +Thus if Dafny is having a difficult time verifying a method +the user may help by inserting assertions that Dafny can prove, +and whose true may aid in the larger verification effort. + +If the proposition is `...` then (TODO: what does this mean?). + +## Assume Statement +```` +AssumeStmt = + "assume" { Attribute } + ( Expression(allowLemma: false, allowLambda: true) + | "..." + ) ";" +```` + +The `Assume` statement lets the user specify a logical proposition +that Dafny may assume to be true without proof. If in fact the +proposition is not true this may lead to invalid conclusions. + +An `Assume` statement would ordinarily be used as part of a larger +verification effort where verification of some other part of +the program required the proposition. By using the `Assume` statement +the other verification can proceed. Then when that is completed the +user would come back and replace the `assume` with `assert`. + +If the proposition is `...` then (TODO: what does this mean?). + +## Print Statement +```` +PrintStmt = + "print" Expression(allowLemma: false, allowLambda: true) + { "," Expression(allowLemma: false, allowLambda: true) } ";" +```` + +The `print` statement is used to print the values of a comma-separated +list of expressions to the console. The generated C# code uses +the `System.Object.ToString()` method to convert the values to printable +strings. The expressions may of course include strings that are used +for captions. There is no implicit new line added, so to get a new +line you should include "\n" as part of one of the expressions. +Dafny automatically creates overrides for the ToString() method +for Dafny data types. For example, + +``` +datatype Tree = Empty | Node(left: Tree, data: int, right: Tree) +method Main() +{ + var x : Tree := Node(Node(Empty, 1, Empty), 2, Empty); + print "x=", x, "\n"; +} +``` + +produces this output: + +``` +x=Tree.Node(Tree.Node(Tree.Empty, 1, Tree.Empty), 2, Tree.Empty) +``` + +## Forall Statement +```` +ForallStmt = "forall" + ( "(" [ QuantifierDomain ] ")" + | [ QuantifierDomain ] + ) + { [ "free" ] ForAllEnsuresClause_ } + [ BlockStmt ] +```` + +The `forall` statement executes ensures expressions or a body in +parallel for all quantified values in the specified range. +The use of the `parallel` keyword is deprecated. Use +`forall` instead. There are several variant uses of the `forall` +statement. And there are a number of restrictions. + +In particular a `forall` statement can be classified as one of the following: + +* _Assign_ - the `forall` statement is used for simultaneous assignment. +The target must be an array element or an object field. +* _Call_ - The body consists of a single call to a method without side effects +* _Proof_ - The `forall` has `ensure` expressions which are effectively +quantified or proved by the body (if present). + +An _assign_ `forall` statement is to perform simultaneous assignment. +The following is an excerpt of an example given by Leino in +[Developing Verified Programs with Dafny][leino233]. +When the buffer holding the queue needs to be resized, +the `forall` statement is used to simultaneously copy the old contents +into the new buffer. + +[leino233]: http://research.microsoft.com/en-us/um/people/leino/papers/krml233.pdf + +``` +class {:autocontracts} SimpleQueue<Data> +{ + ghost var Contents: seq<Data>; + var a: array<Data>; // Buffer holding contents of queue. + var m: int // Index head of queue. + var n: int; // Index just past end of queue + ... + method Enqueue(d: Data) + ensures Contents == old(Contents) + [d] + { + if n == a.Length { + var b := a; + if m == 0 { b := new Data[2 * a.Length]; } + forall (i | 0 <= i < n - m) { + b[i] := a[m + i]; + } + a, m, n := b, 0, n - m; + } + a[n], n, Contents := d, n + 1, Contents + [d]; + } +} +``` + +Here is an example of a _call_ `forall` statement and the +callee. This is contained in the CloudMake-ConsistentBuilds.dfy +test in the Dafny repository. + +``` +forall (cmd', deps', e' | Hash(Loc(cmd', deps', e')) == Hash(Loc(cmd, deps, e))) { + HashProperty(cmd', deps', e', cmd, deps, e); +} + +ghost method HashProperty(cmd: Expression, deps: Expression, ext: string, + cmd': Expression, deps': Expression, ext': string) + requires Hash(Loc(cmd, deps, ext)) == Hash(Loc(cmd', deps', ext')) + ensures cmd == cmd' && deps == deps' && ext == ext' +``` + +From the same file here is an example of a _proof_ `forall` statement. + +``` +forall (p | p in DomSt(stCombinedC.st) && p in DomSt(stExecC.st)) + ensures GetSt(p, stCombinedC.st) == GetSt(p, stExecC.st) +{ + assert DomSt(stCombinedC.st) <= DomSt(stExecC.st); + assert stCombinedC.st == Restrict(DomSt(stCombinedC.st), stExecC.st); +} +``` + +More generally the statement +``` +forall x | P(x) { Lemma(x); } +``` +is used to invoke `Lemma(x)` on all `x` for which `P(x)` holds. If +`Lemma(x)` ensures `Q(x)`, then the forall statement establishes +``` +forall x :: P(x) ==> Q(x). +``` + +The `forall` statement is also used extensively in the desugared forms of +co-predicates and co-lemmas. See section [#sec-co-inductive-datatypes]. + +TODO: List all of the restrictions on the `forall` statement. + +## Modify Statement +```` +ModifyStmt = + "modify" { Attribute } + ( FrameExpression(allowLemma: false, allowLambda: true) + { "," FrameExpression(allowLemma: false, allowLambda: true) } + | "..." + ) + ( BlockStmt | ";" ) +```` + +The `modify` statement has two forms which have two different +purposes. + +When the `modify` statement ends with a semi-colon rather than +a block statement its effect is to say that some undetermined +modifications have been made to any or all of the memory +locations specified by the [frame expressions](#sec-frame-expressions). +In the following example, a value is assigned to field `x` +followed by a `modify` statement that may modify any field +in the object. After that we can no longer prove that the field +`x` still has the value we assigned to it. + +``` +class MyClass { + var x: int; + method N() + modifies this + { + x := 18; + modify this; + assert x == 18; // error: cannot conclude this here + } +} +``` + +When the `modify` statement is followed by a block statement +we are instead specifying what can be modified in that +block statement. Namely, only memory locations specified +by the frame expressions of the block `modify` statement +may be modified. Consider the following example. + +``` +class ModifyBody { + var x: int; + var y: int; + method M0() + modifies this + { + modify {} { + x := 3; // error: violates modifies clause of the modify statement + } + } + method M1() + modifies this + { + modify {} { + var o := new ModifyBody; + o.x := 3; // fine + } + } + method M2() + modifies this + { + modify this { + x := 3; + } + } +} +``` + +The first `modify` statement in the example has an empty +frame expression so it cannot modify any memory locations. +So an error is reported when it tries to modify field `x`. + +The second `modify` statement also has an empty frame +expression. But it allocates a new object and modifies it. +Thus we see that the frame expressions on a block `modify` +statement only limits what may be modified of existing +memory. It does not limit what may be modified in +new memory that is allocated. + +The third `modify` statement has a frame expression that +allows it to modify any of the fields of the current object, +so the modification of field `x` is allowed. + +## Calc Statement +```` +CalcStmt = "calc" { Attribute } [ CalcOp ] "{" CalcBody "}" +CalcBody = { CalcLine [ CalcOp ] Hints } +CalcLine = Expression(allowLemma: false, allowLambda: true) ";" +Hints = { ( BlockStmt | CalcStmt ) } +CalcOp = + ( "==" [ "#" "[" Expression(allowLemma: true, allowLambda: true) "]" ] + | "<" | ">" + | "!=" | "<=" | ">=" + | "<==>" | "==>" | "<==" + ) +```` + +The `calc` statement supports _calculational proofs_ using a language feature called _program-oriented calculations_ (poC). This feature was introduced and explained in the [Verified Calculations] paper by +Leino and Polikarpova[@LEINO:Dafny:Calc]. Please see that paper for a more complete explanation +of the `calc` statement. We here mention only the highlights. + +[Verified Calculations]: http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf + +Calculational proofs are proofs by stepwise formula manipulation +as is taught in elementary algebra. The typical example is to prove +an equality by starting with a left-hand-side, and through a series of +transformations morph it into the desired right-hand-side. + +Non-syntactic rules further restrict hints to only ghost and side-effect +free statements, as well as impose a constraint that only +chain-compatible operators can be used together in a calculation. The +notion of chain-compatibility is quite intuitive for the operators +supported by poC; for example, it is clear that "<" and ">" cannot be used within +the same calculation, as there would be no relation to conclude between +the first and the last line. See the [paper][Verified Calculations] for +a more formal treatment of chain-compatibility. + +Note that we allow a single occurrence of the intransitive operator "!=" to +appear in a chain of equalities (that is, "!=" is chain-compatible with +equality but not with any other operator, including itself). Calculations +with fewer than two lines are allowed, but have no effect. If a step +operator is omitted, it defaults to the calculation-wide operator, +defined after the `calc` keyword. If that operator if omitted, it defaults +to equality. + +Here is an example using `calc` statements to prove an elementary +algebraic identity. As it turns out Dafny is able to prove this without +the `calc` statements, but it helps to illustrate the syntax. + +``` +lemma docalc(x : int, y: int) + ensures (x + y) * (x + y) == x * x + 2 * x * y + y * y +{ + calc { + (x + y) * (x + y); == + // distributive law: (a + b) * c == a * c + b * c + x * (x + y) + y * (x + y); == + // distributive law: a * (b + c) == a * b + a * c + x * x + x * y + y * x + y * y; == + calc { + y * x; == + x * y; + } + x * x + x * y + x * y + y * y; == + calc { + x * y + x * y; == + // a = 1 * a + 1 * x * y + 1 * x * y; == + // Distributive law + (1 + 1) * x * y; == + 2 * x * y; + } + x * x + 2 * x * y + y * y; + } +} +``` + +Here we started with `(x + y) * (x + y)` as the left-hand-side +expressions and gradually transformed it using distributive, +commutative and other laws into the desired right-hand-side. + +The justification for the steps are given as comments, or as +nested `calc` statements that prove equality of some sub-parts +of the expression. + +The `==` to the right of the semicolons show the relation between +that expression and the next. Because of the transitivity of +equality we can then conclude that the original left-hand-side is +equal to the final expression. + +We can avoid having to supply the relational operator between +every pair of expressions by giving a default operator between +the `calc` keyword and the opening brace as shown in this abbreviated +version of the above calc statement: + +``` +calc == { + (x + y) * (x + y); + x * (x + y) + y * (x + y); + x * x + x * y + y * x + y * y; + x * x + x * y + x * y + y * y; + x * x + 2 * x * y + y * y; +} +``` + +And since equality is the default operator we could have omitted +it after the `calc` keyword. +The purpose of the block statements or the `calc` statements between +the expressions is to provide hints to aid Dafny in proving that +step. As shown in the example, comments can also be used to aid +the human reader in cases where Dafny can prove the step automatically. + +## Skeleton Statement +```` +SkeletonStmt = + "..." + ["where" Ident {"," Ident } ":=" + Expression(allowLemma: false, allowLambda: true) + {"," Expression(allowLemma: false, allowLambda: true) } + ] ";" +```` + +# Expressions +The grammar of Dafny expressions follows a hierarchy that +reflects the precedence of Dafny operators. The following +table shows the Dafny operators and their precedence +in order of increasing binding power. + ++--------------------------+------------------------------------+ +| operator | description | ++--------------------------+------------------------------------+ +| `;` | In LemmaCall;Expression | ++--------------------------+------------------------------------+ +| `<==>`, ⇔ | equivalence (if and only if) | ++--------------------------+------------------------------------+ +| `==>`, ⇒ | implication (implies) | +| `<==`, ⇐ | reverse implication (follows from) | ++--------------------------+------------------------------------+ +| `&&`, ∧ | conjunction (and) | +| [\|\|]{.monospace}, ∨ | disjunction (or) | ++--------------------------+------------------------------------+ +| `!`, ¬ | negation (not) | ++--------------------------+------------------------------------+ +| `==` | equality | +| `==#[k]` | prefix equality (co-inductive) | +| `!=` | disequality | +| `!=#[k]` | prefix disequality (co-inductive) | +| [<]{.monospace} | less than | +| `<=` | at most | +| `>=` | at least | +| `>` | greater than | +| `in` | collection membership | +| `!in` | collection non-membership | +| `!!` | disjointness | ++--------------------------+------------------------------------+ +| `+` | addition (plus) | +| `-` | subtraction (minus) | ++--------------------------+------------------------------------+ +| `*` | multiplication (times) | +| `/` | division (divided by) | +| `%` | modulus (mod) | ++--------------------------+------------------------------------+ +| `-` | arithmetic negation (unary minus) | +| `!`, ¬ | logical negation | +| Primary Expressions | | ++--------------------------+------------------------------------+ + +We are calling the ``UnaryExpression``s that are neither +arithmetic nor logical negation the _primary expressions_. +They are the most tightly bound. + +In the grammar entries below we explain the meaning when the +operator for that precedence level is present. If the +operator is not present then we just descend to the +next precedence level. + +## Top-level expressions +```` +Expression(allowLemma, allowLambda) = + EquivExpression(allowLemma, allowLambda) + [ ";" Expression(allowLemma, allowLambda) ] +```` + +The "allowLemma" argument says whether or not the expression +to be parsed is allowed to have the form S;E where S is a call to a lemma. +"allowLemma" should be passed in as "false" whenever the expression to +be parsed sits in a context that itself is terminated by a semi-colon. + +The "allowLambda" says whether or not the expression to be parsed is +allowed to be a lambda expression. More precisely, an identifier or +parenthesized-enclosed comma-delimited list of identifiers is allowed to +continue as a lambda expression (that is, continue with a "reads", "requires", +or "=>") only if "allowLambda" is true. This affects function/method/iterator +specifications, if/while statements with guarded alternatives, and expressions +in the specification of a lambda expression itself. + +Sometimes an expression will fail unless some relevant fact is known. +In the following example the `F_Fails` function fails to verify +because the `Fact(n)` divisor may be zero. But preceding +the expression by a lemma that ensures that the denominator +is not zero allows function `F_Succeeds` to succeed. +``` +function Fact(n: nat): nat +{ + if n == 0 then 1 else n * Fact(n-1) +} + +lemma L(n: nat) + ensures 1 <= Fact(n) +{ +} + +function F_Fails(n: nat): int +{ + 50 / Fact(n) // error: possible division by zero +} + +function F_Succeeds(n: nat): int +{ + L(n); + 50 / Fact(n) +} +``` + +## Equivalence Expressions +```` +EquivExpression(allowLemma, allowLambda) = + ImpliesExpliesExpression(allowLemma, allowLambda) + { "<==>" ImpliesExpliesExpression(allowLemma, allowLambda) } +```` +An ``EquivExpression`` that contains one or more "<==>"s is +a boolean expression and all the contained ``ImpliesExpliesExpression`` +must also be boolean expressions. In that case each "<==>" +operator tests for logical equality which is the same as +ordinary equality. + +See section [#sec-equivalence-operator] for an explanation of the +`<==>` operator as compared with the `==` operator. + +## Implies or Explies Expressions +```` +ImpliesExpliesExpression(allowLemma, allowLambda) = + LogicalExpression(allowLemma, allowLambda) + [ ( "==>" ImpliesExpression(allowLemma, allowLambda) + | "<==" LogicalExpression(allowLemma, allowLambda) + { "<==" LogicalExpression(allowLemma, allowLambda) } + ) + ] + +ImpliesExpression(allowLemma, allowLambda) = + LogicalExpression(allowLemma, allowLambda) + [ "==>" ImpliesExpression(allowLemma, allowLambda) ] +```` + +See section [#sec-implication-and-reverse-implication] for an explanation +of the `==>` and `<==` operators. + +## Logical Expressions + +```` +LogicalExpression(allowLemma, allowLambda) = + RelationalExpression(allowLemma, allowLambda) + [ ( "&&" RelationalExpression(allowLemma, allowLambda) + { "&&" RelationalExpression(allowLemma, allowLambda) } + | "||" RelationalExpression(allowLemma, allowLambda) + { "||" RelationalExpression(allowLemma, allowLambda) } + ) + ] +```` + +See section [#sec-conjunction-and-disjunction] for an explanation +of the `&&` (or ∧) and `||` (or ∨) operators. + +## Relational Expressions +```` +RelationalExpression(allowLemma, allowLambda) = + Term(allowLemma, allowLambda) + [ RelOp Term(allowLemma, allowLambda) + { RelOp Term(allowLemma, allowLambda) } ] + +RelOp = + ( "==" [ "#" "[" Expression(allowLemma: true, allowLambda: true) "]" ] + | "<" | ">" | "<=" | ">=" + | "!=" [ "#" "[" Expression(allowLemma: true, allowLambda: true) "]" ] + | "in" + | "!in" + | "!!" + ) + +```` + +The relation expressions that have a ``RelOp`` compare two or more terms. +As explained in section [#sec-basic-types], `==`, `!=`, ``<``, `>`, `<=`, and `>=` +and their corresponding Unicode equivalents are _chaining_. + +The `in` and `!in` operators apply to collection types as explained in +section [#sec-collection-types] and represent membership or non-membership +respectively. + +The `!!` represents disjointness for sets and multisets as explained in +sections [#sec-sets] and [#sec-multisets]. + +Note that `x ==#[k] y` is the prefix equality operator that compares +co-inductive values for equality to a nesting level of k, as +explained in section [#sec-co-equality]. + +## Terms +```` +Term(allowLemma, allowLambda) = + Factor(allowLemma, allowLambda) + { AddOp Factor(allowLemma, allowLambda) } +AddOp = ( "+" | "-" ) +```` + +`Terms` combine `Factors` by adding or subtracting. +Addition has these meanings for different types: + +* Arithmetic addition for numeric types (section [#sec-numeric-types]). +* Union for sets and multisets (sections [#sec-sets] and [#sec-multisets]) +* Concatenation for sequences (section [#sec-sequences]) + +Subtraction is arithmetic subtraction for numeric types, and set or multiset +difference for sets and multisets. + +## Factors +```` +Factor(allowLemma, allowLambda) = + UnaryExpression(allowLemma, allowLambda) + { MulOp UnaryExpression(allowLemma, allowLambda) } +MulOp = ( "*" | "/" | "%" ) +```` + +A ``Factor`` combines ``UnaryExpression``s using multiplication, +division, or modulus. For numeric types these are explained in +section [#sec-numeric-types]. + +Only `*` has a non-numeric application. It represents set or multiset +intersection as explained in sections [#sec-sets] and [#sec-multisets]. + +## Unary Expressions + +```` +UnaryExpression(allowLemma, allowLambda) = + ( "-" UnaryExpression(allowLemma, allowLambda) + | "!" UnaryExpression(allowLemma, allowLambda) + | PrimaryExpression_(allowLemma, allowLambda) + ) + +```` + +A ``UnaryExpression`` applies either numeric (section [#sec-numeric-types]) +or logical (section [#sec-booleans]) negation to its operand. + +## Primary Expressions +<!-- These are introduced for explanatory purposes as are not in the grammar. --> +```` +PrimaryExpression_(allowLemma, allowLambda) = + ( MapDisplayExpr { Suffix } + | LambdaExpression(allowLemma) + | EndlessExpression(allowLemma, allowLambda) + | NameSegment { Suffix } + | SeqDisplayExpr { Suffix } + | SetDisplayExpr { Suffix } + | MultiSetExpr { Suffix } + | ConstAtomExpression { Suffix } + ) + +```` + +After descending through all the binary and unary operators we arrive at +the primary expressions which are explained in subsequent sections. As +can be seen, a number of these can be followed by 0 or more ``Suffix``es +to select a component of the value. + +If the `allowLambda` is false then ``LambdaExpression``s are not +recognized in this context. + +## Lambda expressions +```` +LambdaExpression(allowLemma) = + ( WildIdent + | "(" [ IdentTypeOptional { "," IdentTypeOptional } ] ")" + ) + LambdaSpec_ + LambdaArrow Expression(allowLemma, allowLambda: true) + +LambdaArrow = ( "=>" | "->" ) +```` + +See section [#sec-lambda-specification] for a description of ``LambdaSpec``. + +In addition to named functions, Dafny supports expressions that define +functions. These are called _lambda (expression)s_ (some languages +know them as _anonymous functions_). A lambda expression has the +form: +``` +(\(_params_\)) \(_specification_\) => \(_body_\) +``` +where `\(_params_\)` is a comma-delimited list of parameter +declarations, each of which has the form `x` or `x: T`. The type `T` +of a parameter can be omitted when it can be inferred. If the +identifier `x` is not needed, it can be replaced by "`_`". If +`\(_params_\)` consists of a single parameter `x` (or `_`) without an +explicit type, then the parentheses can be dropped; for example, the +function that returns the successor of a given integer can be written +as the following lambda expression: +``` +x => x + 1 +``` + +The `\(_specification_\)` is a list of clauses `requires E` or +`reads W`, where `E` is a boolean expression and `W` is a frame +expression. + +`\(_body_\)` is an expression that defines the function's return +value. The body must be well-formed for all possible values of the +parameters that satisfy the precondition (just like the bodies of +named functions and methods). In some cases, this means it is +necessary to write explicit `requires` and `reads` clauses. For +example, the lambda expression +``` +x requires x != 0 => 100 / x +``` +would not be well-formed if the `requires` clause were omitted, +because of the possibility of division-by-zero. + +In settings where functions cannot be partial and there are no +restrictions on reading the heap, the _eta expansion_ of a function +`F: T -> U` (that is, the wrapping of `F` inside a lambda expression +in such a way that the lambda expression is equivalent to `F`) would +be written `x => F(x)`. In Dafny, eta expansion must also account for +the precondition and reads set of the function, so the eta expansion +of `F` looks like: +``` +x requires F.requires(x) reads F.reads(x) => F(x) +``` + +## Left-Hand-Side Expressions +```` +Lhs = + ( NameSegment { Suffix } + | ConstAtomExpression Suffix { Suffix } + ) +```` + +A left-hand-side expression is only used on the left hand +side of an ``UpdateStmt``. + +TODO: Try to give examples showing how these kinds of +left-hand-sides are possible. + +## Right-Hand-Side Expressions +```` +Rhs = + ( ArrayAllocation_ + | ObjectAllocation_ + | Expression(allowLemma: false, allowLambda: true) + | HavocRhs_ + ) + { Attribute } +```` + +An ``Rhs`` is either array allocation, an object allocation, +an expression, or a havoc right-hand-side, optionally followed +by one or more ``Attribute``s. + +Right-hand-side expressions appear in the following constructs: +``ReturnStmt``, ``YieldStmt``, ``UpdateStmt``, or ``VarDeclStatement``. +These are the only contexts in which arrays or objects may be +allocated, or in which havoc may be produced. + +## Array Allocation +```` +ArrayAllocation_ = "new" Type "[" Expressions "]" +```` + +This allocates a new single or multi-dimensional array as explained in +section [#sec-array-types]. + +## Object Allocation +```` +ObjectAllocation_ = "new" Type [ "(" [ Expressions ] ")" ] +```` + +This allocated a new object of a class type as explained +in section [#sec-class-types]. + +## Havoc Right-Hand-Side +```` +HavocRhs_ = "*" +```` +A havoc right-hand-side produces an arbitrary value of its associated +type. To get a more constrained arbitrary value the "assign-such-that" +operator (`:|`) can be used. See section [#sec-update-statement]. + +## Constant Or Atomic Expressions +```` +ConstAtomExpression = + ( LiteralExpression_ + | FreshExpression_ + | OldExpression_ + | CardinalityExpression_ + | NumericConversionExpression_ + | ParensExpression + ) +```` +A ``ConstAtomExpression`` represent either a constant of some type, or an +atomic expression. A ``ConstAtomExpression`` is never an l-value. Also, a +``ConstAtomExpression`` is never followed by an open parenthesis (but could +very well have a suffix that starts with a period or a square bracket). +(The "Also..." part may change if expressions in Dafny could yield +functions.) + +## Literal Expressions +```` +LiteralExpression_ = + ( "false" | "true" | "null" | Nat | Dec | + charToken | stringToken | "this") +```` +A literal expression is a boolean literal, a null object reference, +an unsigned integer or real literal, a character or string literal, +or "this" which denote the current object in the context of +an instance method or function. + +## Fresh Expressions +```` +FreshExpression_ = "fresh" "(" Expression(allowLemma: true, allowLambda: true) ")" +```` + +`fresh(e)` returns a boolean value that is true if +the objects referenced in expression `e` were all +freshly allocated in the current method invocation. +The argument of `fresh` must be either an object reference +or a collection of object references. + +## Old Expressions +```` +OldExpression_ = "old" "(" Expression(allowLemma: true, allowLambda: true) ")" +```` + +An _old expression_ is used in postconditions. `old(e)` evaluates to +the value expression `e` had on entry to the current method. + +## Cardinality Expressions +```` +CardinalityExpression_ = "|" Expression(allowLemma: true, allowLambda: true) "|" +```` + +For a collection expression `c`, `|c|` is the cardinality of `c`. For a +set or sequence the cardinality is the number of elements. For +a multiset the cardinality is the sum of the multiplicities of the +elements. For a map the cardinality is the cardinality of the +domain of the map. Cardinality is not defined for infinite maps. +For more see section [#sec-collection-types]. + +## Numeric Conversion Expressions +```` +NumericConversionExpression_ = + ( "int" | "real" ) "(" Expression(allowLemma: true, allowLambda: true) ")" +```` +Numeric conversion expressions give the name of the target type +followed by the expression being converted in parentheses. +This production is for `int` and `real` as the target types +but this also applies more generally to other numeric types, +e.g. `newtypes`. See section [#sec-numeric-conversion-operations]. + +## Parenthesized Expression +```` +ParensExpression = + "(" [ Expressions ] ")" +```` +A ``ParensExpression`` is a list of zero or more expressions +enclosed in parentheses. + +If there is exactly one expression enclosed then the value is just +the value of that expression. + +If there are zero or more than one the result is a `tuple` value. +See section [#sec-tuple-types]. + +## Sequence Display Expression +```` +SeqDisplayExpr = "[" [ Expressions ] "]" +```` +A sequence display expression provide a way to constructing +a sequence with given values. For example + +``` +[1, 2, 3] +``` +is a sequence with three elements in it. +See section [#sec-sequences] for more information on +sequences. + +## Set Display Expression +```` +SetDisplayExpr = [ "iset" ] "{" [ Expressions ] "}" +```` + +A set display expression provide a way to constructing +a set with given elements. If the keyword `iset` is present +then a potentially infinite set is constructed. + +For example + +``` +{1, 2, 3} +``` +is a set with three elements in it. +See section [#sec-sets] for more information on +sets. + +## Multiset Display or Cast Expression +```` +MultiSetExpr = + "multiset" + ( "{" [ Expressions ] "}" + | "(" Expression(allowLemma: true, allowLambda: true) ")" + ) +```` + +A multiset display expression provide a way to constructing +a multiset with given elements and multiplicity. For example + +``` +multiset{1, 1, 2, 3} +``` +is a multiset with three elements in it. The number 1 has a multiplicity of 2, +the others a multiplicity of 1. + +On the other hand, a multiset cast expression converts a set or a sequence +into a multiset as shown here: + +``` +var s : set<int> := {1, 2, 3}; +var ms : multiset<int> := multiset(s); +ms := ms + multiset{1}; +var sq : seq<int> := [1, 1, 2, 3]; +var ms2 : multiset<int> := multiset(sq); +assert ms == ms2; +``` + +See section [#sec-multisets] for more information on +multisets. + +## Map Display Expression +```` +MapDisplayExpr = ("map" | "imap" ) "[" [ MapLiteralExpressions ] "]" +MapLiteralExpressions = + Expression(allowLemma: true, allowLambda: true) + ":=" Expression(allowLemma: true, allowLambda: true) + { "," Expression(allowLemma: true, allowLambda: true) + ":=" Expression(allowLemma: true, allowLambda: true) + } +```` + +A map display expression builds a finite or potentially infinite +map from explicit ``MapLiteralExpressions``. For example: + +``` +var m := map[1 := "a", 2 := "b"]; +ghost var im := imap[1 := "a", 2 := "b"]; +``` + +Note that `imap`s may only appear in ghost contexts. See +section [#sec-finite-and-infinite-maps] for more details on maps and imaps. + +## Endless Expression +```` +EndlessExpression(allowLemma, allowLambda) = + ( IfExpression_(allowLemma, allowLambda) + | MatchExpression(allowLemma, allowLambda) + | QuantifierExpression(allowLemma, allowLambda) + | SetComprehensionExpr(allowLemma, allowLambda) + | StmtInExpr Expression(allowLemma, allowLambda) + | LetExpr(allowLemma, allowLambda) + | MapComprehensionExpr(allowLemma, allowLambda) + ) +```` +<!-- Experimental - do not document. + | NamedExpr(allowLemma, allowLambda) +--> + +``EndlessExpression`` gets it name from the fact that all its alternate +productions have no terminating symbol to end them, but rather they +all end with an ``Expression`` at the end. The various +``EndlessExpression`` alternatives are described below. + +## If Expression +```` +IfExpression_(allowLemma, allowLambda) = + "if" Expression(allowLemma: true, allowLambda: true) + "then" Expression(allowLemma: true, allowLambda: true) + "else" Expression(allowLemma, allowLambda) +```` + +The ``IfExpression`` is a conditional expression. It first evaluates +the expression following the `if`. If it evaluates to `true` then +it evaluates the expression following the `then` and that is the +result of the expression. If it evaluates to `false` then the +expression following the `else` is evaluated and that is the result +of the expression. It is important that only the selected expression +is evaluated as the following example shows. + +``` +var k := 10 / x; // error, may divide by 0. +var m := if x != 0 then 10 / x else 1; // ok, guarded +``` + +## Case Bindings and Patterns +```` +CaseBinding_ = + "case" + ( Ident [ "(" CasePattern { "," CasePattern } ")" ] + | "(" CasePattern { "," CasePattern } ")" + ) + +CasePattern = + ( Ident "(" [ CasePattern { "," CasePattern } ] ")" + | "(" [ CasePattern { "," Casepattern } ] ")" + | IdentTypeOptional + ) +```` + +Case bindings and patterns are used for (possibly nested) +pattern matching on inductive or coinductive values. +The ``CaseBinding_`` construct is used in +``CaseStatement`` and ``CaseExpression``s. +Besides its use in ``CaseBinding_``, ``CasePattern``s are used +in ``LetExpr``s and ``VarDeclStatement``s. + +When matching an inductive or coinductive value in +a ``MatchStmt`` or ``MatchExpression``, there must be +a ``CaseBinding_`` for each constructor. A tuple is +considered to have a single constructor. +The ``Ident`` of the ``CaseBinding_`` must match the name +of a constructor (or in the case of a tuple the ``Ident`` is +absent and the second alternative is chosen). +The ``CasePattern``s inside the parenthesis are then +matched against the argument that were given to the +constructor when the value was constructed. +The number of ``CasePattern``s must match the number +of parameters to the constructor (or the arity of the +tuple). + +The ``CasePattern``s may be nested. The set of non-constructor-name +identifiers contained in a ``CaseBinding_`` must be distinct. +They are bound to the corresponding values in the value being +matched. + +## Match Expression + +```` +MatchExpression(allowLemma, allowLambda) = + "match" Expression(allowLemma, allowLambda) + ( "{" { CaseExpression(allowLemma: true, allowLambda: true) } "}" + | { CaseExpression(allowLemma, allowLambda) } + ) + +CaseExpression(allowLemma, allowLambda) = + CaseBinding_ "=>" Expression(allowLemma, allowLambda) +```` + +A ``MatchExpression`` is used to conditionally evaluate and select an +expression depending on the value of an algebraic type, i.e. an inductive +type, or a co-inductive type. + +The ``Expression`` following the `match` keyword is called the +_selector_. There must be a ``CaseExpression`` for each constructor of +the type of the selector. The ``Ident`` following the `case` keyword in a +``CaseExpression`` is the name of a constructor of the selector's type. +It may be absent if the expression being matched is a tuple since these +have no constructor name. + +If the constructor has parameters then in the ``CaseExpression`` the +constructor name must be followed by a parenthesized list of ``CasePattern``s. +If the constructor has no parameters then the +``CaseExpression`` must not have a following ``CasePattern`` list. +All of the identifiers in the ``CasePattern``s must be distinct. +If types for the identifiers are not given then types are inferred +from the types of the constructor's parameters. If types are +given then they must agree with the types of the +corresponding parameters. + +A ``MatchExpression`` is evaluated by first evaluating the selector. +Then the ``CaseClause`` is selected for the constructor that was +used to construct the evaluated selector. If the constructor had +parameters then the actual values used to construct the selector +value are bound to the identifiers in the identifier list. +The expression to the right of the `=>` in the ``CaseClause`` is then +evaluated in the environment enriched by this binding. The result +of that evaluation is the result of the ``MatchExpression``. + +Note that the braces enclosing the ``CaseClause``s may be omitted. + +## Quantifier Expression +```` +QuantifierExpression(allowLemma, allowLambda) = + ( "forall" | "exists" ) QuantifierDomain "::" + Expression(allowLemma, allowLambda) + +QuantifierDomain = + IdentTypeOptional { "," IdentTypeOptional } { Attribute } + [ "|" Expression(allowLemma: true, allowLambda: true) ] +```` + +A ``QuantifierExpression`` is a boolean expression that specifies that a +given expression (the one following the "::") is true for all (for +**forall**) or some (for **exists**) combination of values of the +quantified variables, namely those in the ``QuantifierDomain``. + +Here are some examples: +``` +assert forall x : nat | x <= 5 :: x * x <= 25; +(forall n :: 2 <= n ==> (exists d :: n < d && d < 2*n)) +``` + +or using the Unicode symbols: + +``` +assert \(∀\) x : nat | x <= 5 \(•\) x * x <= 25; +(\(∀\) n \(•\) 2 <= n ==> (\(∃\) d \(•\) n < d && d < 2*n)) +``` + +The quantifier identifiers are _bound_ within the scope of the +expressions in the ``QuantifierExpression``. + +It types are not given for the quantified identifiers then Dafny +attempts to infer their types from the context of the expressions. +It this is not possible the program is in error. + + +## Set Comprehension Expressions +```` +SetComprehensionExpr(allowLemma, allowLambda) = + [ "set" | "iset" ] + IdentTypeOptional { "," IdentTypeOptional } { Attribute } + "|" Expression(allowLemma, allowLambda) + [ "::" Expression(allowLemma, allowLambda) ] +```` + +A set comprehension expression is an expressions that yields a set +(possibly infinite if `iset` is used) that +satisfies specified conditions. There are two basic forms. + +If there is only one quantified variable the optional ``"::" Expression`` +need not be supplied, in which case it is as if it had been supplied +and the expression consists solely of the quantified variable. +That is, + +``` +set x : T | P(x) +``` + +is equivalent to + +``` +set x : T | P(x) :: x +``` + +For the full form + +``` +var S := set x1:T1, x2:T2 ... | P(x1, x2, ...) :: Q(x1, x2, ...) +``` + +the elements of `S` will be all values resulting from evaluation of `Q(x1, x2, ...)` +for all combinations of quantified variables `x1, x2, ...` such that +predicate `P(x1, x2, ...)` holds. For example, + +``` +var S := set x:nat, y:nat | x < 2 && y < 2 :: (x, y) +``` +would yield `S == {(0, 0), (0, 1), (1, 0), (1,1) }` + +The types on the quantified variables are optional and if not given Dafny +will attempt to infer them from the contexts in which they are used in the +`P` or `Q` expressions. + +If a finite set was specified ("set" keyword used), Dafny must be able to prove that the +result is finite otherwise the set comprehension expression will not be +accepted. + +Set comprehensions involving reference types such as + +``` +set o: object | true +``` + +are allowed in ghost contexts. In particular, in ghost contexts, the +check that the result is finite should allow any set comprehension +where the bound variable is of a reference type. In non-ghost contexts, +it is not allowed, because--even though the resulting set would be +finite--it is not pleasant or practical to compute at run time. + +## Statements in an Expression +```` +StmtInExpr = ( AssertStmt | AssumeStmt | CalcStmt ) +```` + +A ``StmtInExpr`` is a kind of statement that is allowed to +precede an expression in order to ensure that the expression +can be evaluated without error. For example: + +``` +assume x != 0; 10/x +``` + +`Assert`, `assume` and `calc` statements can be used in this way. + +## Let Expression + +```` +LetExpr(allowLemma, allowLambda) = + [ "ghost" ] "var" CasePattern { "," CasePattern } + ( ":=" | { Attribute } ":|" ) + Expression(allowLemma: false, allowLambda: true) + { "," Expression(allowLemma: false, allowLambda: true) } ";" + Expression(allowLemma, allowLambda) +```` + +A `let` expression allows binding of intermediate values to identifiers +for use in an expression. The start of the `let` expression is +signaled by the `var` keyword. They look much like a local variable +declaration except the scope of the variable only extends to the +enclosed expression. + +For example: +``` +var sum := x + y; sum * sum +``` + +In the simple case the ``CasePattern`` is just an identifier with optional +type (which if missing is inferred from the rhs). + +The more complex case allows destructuring of constructor expressions. +For example: + +``` +datatype Stuff = SCons(x: int, y: int) | Other +function GhostF(z: Stuff): int + requires z.SCons? +{ + var SCons(u, v) := z; var sum := u + v; sum * sum +} +``` + +## Map Comprehension Expression +```` +MapComprehensionExpr(allowLemma, allowLambda) = + ( "map" | "imap" ) IdentTypeOptional { Attribute } + [ "|" Expression(allowLemma: true, allowLambda: true) ] + "::" Expression(allowLemma, allowLambda) +```` + +A ``MapComprehensionExpr`` defines a finite or infinite map value +by defining a domain (using the ``IdentTypeOptional`` and the optional +condition following the "|") and for each value in the domain, +giving the mapped value using the expression following the "::". + +For example: +``` +function square(x : int) : int { x * x } +method test() +{ + var m := map x : int | 0 <= x <= 10 :: x * x; + ghost var im := imap x : int :: x * x; + ghost var im2 := imap x : int :: square(x); +} +``` + +Dafny maps must be finite, so the domain must be constrained to be finite. +But imaps may be infinite as the example shows. The last example shows +creation of an infinite map that gives the same results as a function. + +<!-- Experimental - do not document. + +## Named Expression +```` +NamedExpr(allowLemma, allowLambda) = + "label" LabelName ":" Expression(allowLemma, allowLambda) +```` + +A ``NamedExpr`` is an expression that has been tagged with a name. +For example: +``` +label squareit: x * x +``` + +This is an experimental feature. +TODO: When is this useful. Is there any way to refer to the label? +Should we remove the description? +--> + +## Name Segment +```` +NameSegment = Ident [ GenericInstantiation | HashCall ] +```` + +A ``NameSegment`` names a Dafny entity by giving its declared +name optionally followed by information to +make the name more complete. For the simple case it is +just an identifier. + +If the identifier is for a generic entity it is followed by +a ``GenericInstantiation`` which provides actual types for +the type parameters. + +To reference a prefix predicate (see section [#sec-copredicates]) or +prefix lemma (see section [#sec-prefix-lemmas]), the identifier +must be the name of the copredicate or colemma and it must be +followed by a ``HashCall``. + +## Hash Call +```` +HashCall = "#" [ GenericInstantiation ] + "[" Expression(allowLemma: true, allowLambda: true) "]" + "(" [ Expressions ] ")" +```` +A ``HashCall`` is used to call the prefix for a copredicate or colemma. +In the non-generic case it just insert `"#[k]"` before the call argument +list where k is the number of recursion levels. + +In the case where the `colemma` is generic, the generic type +argument is given before. Here is an example: + +``` +codatatype Stream<T> = Nil | Cons(head: int, stuff: T, tail: Stream) + +function append(M: Stream, N: Stream): Stream +{ + match M + case Nil => N + case Cons(t, s, M') => Cons(t, s, append(M', N)) +} + +function zeros<T>(s : T): Stream<T> +{ + Cons(0, s, zeros(s)) +} + +function ones<T>(s: T): Stream<T> +{ + Cons(1, s, ones(s)) +} + +copredicate atmost(a: Stream, b: Stream) +{ + match a + case Nil => true + case Cons(h,s,t) => b.Cons? && h <= b.head && atmost(t, b.tail) +} + +colemma {:induction false} Theorem0<T>(s: T) + ensures atmost(zeros(s), ones(s)) +{ + // the following shows two equivalent ways to getting essentially the + // co-inductive hypothesis + if (*) { + Theorem0#<T>[_k-1](s); + } else { + Theorem0(s); + } +} + +``` + +where the ``HashCall`` is `"Theorem0#<T>[_k-1](s);"`. +See sections [#sec-copredicates] and [#sec-prefix-lemmas]. + +## Suffix +```` +Suffix = + ( AugmentedDotSuffix_ + | DatatypeUpdateSuffix_ + | SubsequenceSuffix_ + | SlicesByLengthSuffix_ + | SequenceUpdateSuffix_ + | SelectionSuffix_ + | ArgumentListSuffix_ + ) +```` + +The ``Suffix`` non-terminal describes ways of deriving a new value from +the entity to which the suffix is appended. There are six kinds +of suffixes which are described below. + +### Augmented Dot Suffix +```` +AugmentedDotSuffix_ = ". " DotSuffix [ GenericInstantiation | HashCall ] +```` + +An augmented dot suffix consists of a simple ``DotSuffix`` optionally +followed by either + +* a ``GenericInstantiation`` (for the case where the item +selected by the ``DotSuffix`` is generic), or +* a ``HashCall`` for the case where we want to call a prefix copredicate + or colemma. The result is the result of calling the prefix copredicate + or colemma. + +### Datatype Update Suffix + +```` +DatatypeUpdateSuffix_ = + "." "(" MemberBindingUpdate { "," MemberBindingUpdate } ")" + +MemberBindingUpdate = + ( ident | digits ) ":=" Expression(allowLemma: true, allowLambda: true) +```` + +A datatype update suffix is used to produce a new datatype value +that is the same as an old datatype value except that the +value corresponding to a given destructor has the specified value. +In a ``MemberBindingUpdate``, the ``ident`` or ``digits`` is the +name of a destructor (i.e. formal parameter name) for one of the +constructors of the datatype. The expression to the right of the +":=" is the new value for that formal. + +All of the destructors in a ``DatatypeUpdateSuffix_`` must be +for the same constructor, and if they do not cover all of the +destructors for that constructor then the datatype value being +updated must have a value derived from that same constructor. + +Here is an example: + +``` +module NewSyntax { +datatype MyDataType = MyConstructor(myint:int, mybool:bool) + | MyOtherConstructor(otherbool:bool) + | MyNumericConstructor(42:int) + +method test(datum:MyDataType, x:int) + returns (abc:MyDataType, def:MyDataType, ghi:MyDataType, jkl:MyDataType) + requires datum.MyConstructor?; + ensures abc == datum.(myint := x + 2); + ensures def == datum.(otherbool := !datum.mybool); + ensures ghi == datum.(myint := 2).(mybool := false); + // Resolution error: no non_destructor in MyDataType + //ensures jkl == datum.(non_destructor := 5); + ensures jkl == datum.(42 := 7); +{ + abc := MyConstructor(x + 2, datum.mybool); + abc := datum.(myint := x + 2); + def := MyOtherConstructor(!datum.mybool); + ghi := MyConstructor(2, false); + jkl := datum.(42 := 7); + + assert abc.(myint := abc.myint - 2) == datum.(myint := x); +} +} +``` + + + +### Subsequence Suffix +```` +SubsequenceSuffix_ = + "[" [ Expression(allowLemma: true, allowLambda: true) ] + ".." [ Expression(allowLemma: true, allowLambda: true) ] + "]" +```` +A subsequence suffix applied to a sequence produces a new sequence whose +elements are taken from a contiguous part of the original sequence. For +example, expression `s[lo..hi]` for sequence `s`, and integer-based +numerics `lo` and `hi` satisfying `0 <= lo <= hi <= |s|`. See +section [#sec-other-sequence-expressions] for details. + +### Slices By Length Suffix +```` +SlicesByLengthSuffix_ = + "[" Expression(allowLemma: true, allowLambda: true) + ":" Expression(allowLemma: true, allowLambda: true) + { ":" Expression(allowLemma: true, allowLambda: true) } + [ ":" ] + "]" +```` + +Applying a ``SlicesByLengthSuffix_`` to a sequence produces a +sequence of subsequences of the original sequence. +See section [#sec-other-sequence-expressions] for details. + +### Sequence Update Suffix +```` +SequenceUpdateSuffix_ = + "[" Expression(allowLemma: true, allowLambda: true) + ":=" Expression(allowLemma: true, allowLambda: true) + "]" +```` + +For a sequence `s` and expressions `i` and `v`, the expression +`s[i := v]` is the same as the sequence `s` except that at +index `i` it has value `v`. + +### Selection Suffix +```` +SelectionSuffix_ = + "[" Expression(allowLemma: true, allowLambda: true) + { "," Expression(allowLemma: true, allowLambda: true) } + "]" +```` + +If a ``SelectionSuffix_`` has only one expression in it, it is a +zero-based index that may be used to select a single element of a +sequence or from a single-dimensional array. + +If a ``SelectionSuffix_`` has more than one expression in it, then +it is a list of indices to index into a multi-dimensional array. +The rank of the array must be the same as the number of indices. + +### Argument List Suffix +```` +ArgumentListSuffix_ = "(" [ Expressions ] ")" +```` + +An argument list suffix is a parenthesized list of expressions that +are the arguments to pass to a method or function that is being +called. Applying such a suffix caused the method or function +to be called and the result is the result of the call. + +## Expression Lists +```` +Expressions = + Expression(allowLemma: true, allowLambda: true) + { "," Expression(allowLemma: true, allowLambda: true) } +```` + +The ``Expressions`` non-terminal represents a list of +one or more expressions separated by a comma. + +# Module Refinement +TODO: Write this section. + +# Attributes +```` +Attribute = "{" ":" AttributeName [ Expressions ] "}" +```` +Dafny allows many of its entities to be annotated with _Attributes_. +The grammar shows where the attribute annotations may appear. + +Here is an example of an attribute from the Dafny test suite: + +``` +{:MyAttribute "hello", "hi" + "there", 57} +``` + +In general an attribute may have any name the user chooses. It may be +followed by a comma separated list of expressions. These expressions will +be resolved and type-checked in the context where the attribute appears. + +## Dafny Attribute Implementation Details +In the Dafny implementation the `Attributes` type holds the name of +the attribute, a list of ``Expression`` arguments and a link to the +previous Attributes object for that Dafny entity. So for each +Dafny entity that has attributes we have a list of them. + +Dafny stores attributes on the following kinds of entities: +Declaration (base class), ModuleDefinition, Statement, +AssignmentRhs, LocalVariable, LetExpr, ComprehensionExpr, +MaybeFreeExpression, Specification. + +TODO: Dafny internals information should go into a separate +document on Dafny internals. + +## Dafny Attributes +All entities that Dafny translates to Boogie have their attributes +passed on to Boogie except for the `{:axiom}` attribute (which +conflicts with Boogie usage) and the `{:trigger}` attribute which is +instead converted into a Boogie quantifier _trigger_. See Section 11 of +[@Leino:Boogie2-RefMan]. + +Dafny has special processing for some attributes. For some attributes the +setting is only looked for on the entity of interest. For others we start +at the entity and if the attribute is not there, look up in the hierarchy +(enclosing class and enclosing modules). The latter case is checked by +the ContainsBoolAtAnyLevel method in the Dafny source. The attribute +declaration closest to the entity overrides those further away. + +For attributes with a single boolean expression argument, the attribute +with no argument is interpreted as if it were true. + +The attributes that are processed specially by Dafny are described in the +following sections. + +### assumption +This attribute can only be placed on a local ghost bool +variable of a method. Its declaration cannot have a rhs, but it is +allowed to participate as the lhs of exactly one assignment of the +form: `b := b && expr;`. Such a variable declaration translates in the +Boogie output to a declaration followed by an `assume b` command. TODO: +What is the motivation for this? + +### autoReq boolExpr +For a function declaration, if this attribute is set true at the nearest +level, then its `requires` clause is strengthed sufficiently so that +it may call the functions that it calls. + +For following example +``` +function f(x:int) : bool + requires x > 3 +{ + x > 7 +} + +// Should succeed thanks to auto_reqs +function {:autoReq} g(y:int, b:bool) : bool +{ + if b then f(y + 2) else f(2*y) +} +``` +the `{:autoReq}` attribute causes Dafny to +deduce a `requires` clause for g as if it had been +declared +``` +function g(y:int, b:bool) : bool + requires if b then y + 2 > 3 else 2 * y > 3 +{ + if b then f(y + 2) else f(2*y) +} +``` + +### autocontracts +Dynamic frames [@Kassios:FM2006;@SmansEtAl:VeriCool;@SmansEtAl:ImplicitDynamicFrames; +@LEINO:Dafny:DynamicFrames] +are frame expressions that can vary dynamically during +program execution. AutoContracts is an experimental feature that will +fill much of the dynamic-frames boilerplate into a class. + +From the user's perspective, what needs to be done is simply: + +* mark the class with {:autocontracts} +* declare a function (or predicate) called Valid() + + +AutoContracts will then: + +* Declare: +``` + ghost var Repr: set(object); +``` + +* For function/predicate Valid(), insert: +``` + reads this, Repr +``` +* Into body of Valid(), insert (at the beginning of the body): +``` + this in Repr && null !in Repr +``` +* and also insert, for every array-valued field A declared in the class: +``` + (A != null ==> A in Repr) && +``` +* and for every field F of a class type T where T has a field called Repr, also insert: +``` + (F != null ==> F in Repr && F.Repr SUBSET Repr && this !in Repr) +``` +* Except, if A or F is declared with {:autocontracts false}, then the implication will not +be added. + +* For every constructor, add: +``` + modifies this + ensures Valid() && fresh(Repr - {this}) +``` +* At the end of the body of the constructor, add: +``` + Repr := {this}; + if (A != null) { Repr := Repr + {A}; } + if (F != null) { Repr := Repr + {F} + F.Repr; } +``` +* For every method, add: + +``` + requires Valid() + modifies Repr + ensures Valid() && fresh(Repr - old(Repr)) +``` +* At the end of the body of the method, add: +``` + if (A != null) { Repr := Repr + {A}; } + if (F != null) { Repr := Repr + {F} + F.Repr; } +``` + +### axiom +The `{:axiom}` attribute may be placed on a function or method. +It means that the post-condition may be assumed to be true +without proof. In that case also the body of the function or +method may be omitted. + +The `{:axiom}` attribute is also used for generated `reveal_*` +lemmas as shown in Section [#sec-opaque]. + +### compile +The `{:compile}` attribute takes a boolean argument. It may be applied to +any top-level declaration. If that argument is false then that declaration +will not be compiled into .Net code. + +### decl +The `{:decl}` attribute may be placed on a method declaration. It +inhibits the error message that has would be given when the method has a +`ensures` clauses but no body. + +TODO: There are no examples of this in the Dafny tests. What is the motivation +for this? + +### fuel +The fuel attributes is used to specify how much "fuel" a function should have, +i.e., how many times Z3 is permitted to unfold it's definition. The +new {:fuel} annotation can be added to the function itself, it which +case it will apply to all uses of that function, or it can overridden +within the scope of a module, function, method, iterator, calc, forall, +while, assert, or assume. The general format is: + +``` +{:fuel functionName,lowFuel,highFuel} +``` + +When applied as an annotation to the function itself, omit +functionName. If highFuel is omitted, it defaults to lowFuel + 1. + +The default fuel setting for recursive functions is 1,2. Setting the +fuel higher, say, to 3,4, will give more unfoldings, which may make +some proofs go through with less programmer assistance (e.g., with +fewer assert statements), but it may also increase verification time, +so use it with care. Setting the fuel to 0,0 is similar to making the +definition opaque, except when used with all literal arguments. + +### heapQuantifier +The `{:heapQuantifier}` attribute may be used on a ``QuantifierExpression``. +When it appears in a quantifier expression it is as if a new heap-valued +quantifier variable was added to the quantification. Consider this code +that is one of the invariants of a while loop. + +``` +invariant forall u {:heapQuantifier} :: f(u) == u + r +``` + +The quantifier is translated into the following Boogie: + +``` +(forall q$heap#8: Heap, u#5: int :: + {:heapQuantifier} + $IsGoodHeap(q$heap#8) && ($Heap == q$heap#8 || $HeapSucc($Heap, q$heap#8)) + ==> $Unbox(Apply1(TInt, TInt, f#0, q$heap#8, $Box(u#5))): int == u#5 + r#0); +``` + +What this is saying is that the quantified expression, `f(u) == u + r`, +which may depend on the heap, is also valid for any good heap that is either the +same as the current heap, or that is derived from it by heap update operations. + +TODO: I think this means that the quantified expression is actually independent of the +heap. Is that true? + +### imported +If a ``MethodDecl`` or ``FunctionDecl`` has an `{:imported}` attribute, +then it is allowed to have a empty body even though it has an **ensures** +clause. Ordinarily a body would be required in order to provide the +proof of the **ensures** clause (but the `(:axiom)` attribute also +provides this facility, so the need for `(:imported)` is not clear.) +A method or function declaration may be given the `(:imported)` attribute. This suppresses +the error message that would be given if a method or function with an `ensures` clause +does not have a body. + +TODO: When would this be used? An example would be helpful. + +TODO: When is this useful or valid? + +### induction +The `{:induction}` attribute controls the application of +proof by induction to two contexts. Given a list of +variables on which induction might be applied, the +`{:induction}` attribute selects a sub-list of those +variables (in the same order) to which to apply induction. + +TODO: Would there be any advantage to taking the order +from the attribute, rather than preserving the original +order? That would seem to give the user more control. + +The two contexts are: + +* A method, in which case the bound variables are all the + in-parameters of the method. +* A quantifier expression, in which case the bound variables + are the bound variables of the quantifier expression. + +The form of the `{:induction}` attribute is one of the following: + +* `{:induction}` -- apply induction to all bound variables +* `{:induction false}` -- suppress induction, that is, don't apply it to any bound variable +* `{:induction L}` where `L` is a list consisting entirely of bound variables +-- apply induction to the specified bound variables +* `{:induction X}` where `X` is anything else -- treat the same as +{:induction}, that is, apply induction to all bound variables. For this +usage conventionally `X` is `true`. + +Here is an example of using it on a quantifier expression: +``` +ghost method Fill_J(s: seq<int>) + requires forall i :: 1 <= i < |s| ==> s[i-1] <= s[i] + ensures forall i,j {:induction j} :: 0 <= i < j < |s| ==> s[i] <= s[j] +{ +} +``` + +### layerQuantifier +When Dafny is translating a quantified expression, if it has +a `{:layerQuantifier}` attribute an additional quantifier +variable is added to the quantifier bound variables. +This variable as the predefined _LayerType_. +A `{:layerQuantifier}` attribute may be placed on a quantifier expression. +Translation of Dafny into Boogie defines a _LayerType_ which has defined zero and +successor constructors. + +The Dafny source has the comment that "if a function is recursive, +then make the reveal lemma quantifier a layerQuantifier." +And in that case it adds the attribute to the quantifier. + +There is no explicit user of the `{:layerQuantifier}` attribute +in the Dafny tests. So I believe this attribute is only used +internally by Dafny and not externally. + +TODO: Need more complete explanation of this attribute. + +### nativeType {#sec-nativetype} +The `{:nativeType}` attribute may only be used on a ``NewtypeDecl`` +where the base type is an integral type. It can take one of the following +forms: + +* `{:nativeType}` - With no parameters it has no effect and the ``NewtypeDecl`` +have its default behavior which is to choose a native type that can hold any +value satisfying the constraints, if possible, otherwise BigInteger is used. +* `{:nativeType true}` - Also gives default ``NewtypeDecl`` behavior, +but gives an error if base type is not integral. +* `{:nativeType false}` - Inhibits using a native type. BigInteger is used +for integral types and BitRational for real types. +* `{:nativeType "typename"}` - This form has an native integral +type name as a string literal. Acceptable values are: "byte", +"sbyte", "ushort", "short", "uint", "int", "ulong" and "long". +An error is reported if the given data type cannot hold all the +values that satisfy the constraint. + + +### opaque {#sec-opaque} +Ordinarily the body of a function is transparent to its users but +sometimes it is useful to hide it. If a function `f` is given the +`{:opaque}` attribute then Dafny hides the body of the function, +so that it can only be seen within its recursive clique (if any), +or if the programmer specifically asks to see it via the `reveal_f()` lemma. + +We create a lemma to allow the user to selectively reveal the function's body +That is, given: + +``` + function {:opaque} foo(x:int, y:int) : int + requires 0 <= x < 5 + requires 0 <= y < 5 + ensures foo(x, y) < 10 + { x + y } +``` + +We produce: + +``` + lemma {:axiom} reveal_foo() + ensures forall x:int, y:int {:trigger foo(x,y)} :: + 0 <= x < 5 && 0 <= y < 5 ==> foo(x,y) == foo_FULL(x,y) +``` + +where `foo_FULL` is a copy of `foo` which does not have its body +hidden. In addition `foo_FULL` is given the +`{:opaque_full}` and `{:auto_generated}` attributes in addition +to the `{:opaque}` attribute (which it got because it is a copy of `foo`). + +### opaque full +The `{:opaque_full}` attribute is used to mark the _full_ version +of an opaque function. See Section [#sec-opaque]. + +### prependAssertToken +This is used internally in Dafny as part of module refinement. +It is an attribute on an assert statement. +The Dafny code has the following comment: + +``` +// Clone the expression, but among the new assert's attributes, indicate +// that this assertion is supposed to be translated into a check. That is, +// it is not allowed to be just assumed in the translation, despite the fact +// that the condition is inherited. +``` + +TODO: Decide if we want to describe this in more detail, or whether +the functionality is already adequately described where +refinement is described. + +### tailrecursion +This attribute is used on a method declarations. It has a boolean argument. + +If specified with a false value it means the user specifically +requested no tail recursion, so none is done. + +If specified with a true value, or if not specified +then tail recursive optimization will be attempted subject to +the following conditions: + +* It is an error if the method is a ghost method and tail +recursion was explicitly requested. +* Only direct recursion is supported, not mutually recursive methods. +* If `{:tailrecursion true}` was specified but the code does not allow it +an error message is given. + +### timeLimitMultiplier +This attribute may be placed on a method or function declaration +and has an integer argument. If `{:timeLimitMultiplier X}` was +specified a `{:timelimit Y}` attributed is passed on to Boogie +where `Y` is `X` times either the default verification time limit +for a function or method, or times the value specified by the +Boogie `timelimit` command-line option. + +### trigger +Trigger attributes are used on quantifiers and comprehensions. +They are translated into Boogie triggers. + +### typeQuantifier +The `{:typeQuantifier}` must be used on a quantifier if it +quantifies over types. + + +## Boogie Attributes +Use the Boogie "/attrHelp" option to get the list of attributes +that Boogie recognizes and their meaning. Here is the output at +the time of this writing. Dafny passes attributes that have +been specified to the Boogie. + +``` +Boogie: The following attributes are supported by this implementation. + + ---- On top-level declarations --------------------------------------------- + + {:ignore} + Ignore the declaration (after checking for duplicate names). + + {:extern} + If two top-level declarations introduce the same name (for example, two + constants with the same name or two procedures with the same name), then + Boogie usually produces an error message. However, if at least one of + the declarations is declared with :extern, one of the declarations is + ignored. If both declarations are :extern, Boogie arbitrarily chooses + one of them to keep; otherwise, Boogie ignore the :extern declaration + and keeps the other. + + {:checksum <string>} + Attach a checksum to be used for verification result caching. + + ---- On implementations and procedures ------------------------------------- + + {:inline N} + Inline given procedure (can be also used on implementation). + N should be a non-negative number and represents the inlining depth. + With /inline:assume call is replaced with "assume false" once inlining depth is reached. + With /inline:assert call is replaced with "assert false" once inlining depth is reached. + With /inline:spec call is left as is once inlining depth is reached. + With the above three options, methods with the attribute {:inline N} are not verified. + With /inline:none the entire attribute is ignored. + + {:verify false} + Skip verification of an implementation. + + {:vcs_max_cost N} + {:vcs_max_splits N} + {:vcs_max_keep_going_splits N} + Per-implementation versions of + /vcsMaxCost, /vcsMaxSplits and /vcsMaxKeepGoingSplits. + + {:selective_checking true} + Turn all asserts into assumes except for the ones reachable from + assumptions marked with the attribute {:start_checking_here}. + Thus, "assume {:start_checking_here} something;" becomes an inverse + of "assume false;": the first one disables all verification before + it, and the second one disables all verification after. + + {:priority N} + Assign a positive priority 'N' to an implementation to control the order + in which implementations are verified (default: N = 1). + + {:id <string>} + Assign a unique ID to an implementation to be used for verification + result caching (default: "<impl. name>:0"). + + {:timeLimit N} + Set the time limit for a given implementation. + + ---- On functions ---------------------------------------------------------- + + {:builtin "spec"} + {:bvbuiltin "spec"} + Rewrite the function to built-in prover function symbol 'fn'. + + {:inline} + {:inline true} + Expand function according to its definition before going to the prover. + + {:never_pattern true} + Terms starting with this function symbol will never be + automatically selected as patterns. It does not prevent them + from being used inside the triggers, and does not affect explicit + trigger annotations. Internally it works by adding {:nopats ...} + annotations to quantifiers. + + {:identity} + {:identity true} + If the function has 1 argument and the use of it has type X->X for + some X, then the abstract interpreter will treat the function as an + identity function. Note, the abstract interpreter trusts the + attribute--it does not try to verify that the function really is an + identity function. + + ---- On variables ---------------------------------------------------------- + + {:existential true} + Marks a global Boolean variable as existentially quantified. If + used in combination with option /contractInfer Boogie will check + whether there exists a Boolean assignment to the existentials + that makes all verification conditions valid. Without option + /contractInfer the attribute is ignored. + + ---- On assert statements -------------------------------------------------- + + {:subsumption n} + Overrides the /subsumption command-line setting for this assertion. + + {:split_here} + Verifies code leading to this point and code leading from this point + to the next split_here as separate pieces. May help with timeouts. + May also occasionally double-report errors. + + ---- The end --------------------------------------------------------------- + +``` + +However a scan of Boogie's sources shows it checks for the +following attributes. + +* `{:$}` +* `{:$renamed$}` +* `{:InlineAssume}` +* `{:PossiblyUnreachable}` +* `{:__dominator_enabled}` +* `{:__enabled}` +* `{:a##post##}` +* `{:absdomain}` +* `{:ah}` +* `{:assumption}` +* `{:assumption_variable_initialization}` +* `{:atomic}` +* `{:aux}` +* `{:both}` +* `{:bvbuiltin}` +* `{:candidate}` +* `{:captureState}` +* `{:checksum}` +* `{:constructor}` +* `{:datatype}` +* `{:do_not_predicate}` +* `{:entrypoint}` +* `{:existential}` +* `{:exitAssert}` +* `{:expand}` +* `{:extern}` +* `{:hidden}` +* `{:ignore}` +* `{:inline}` +* `{:left}` +* `{:linear}` +* `{:linear_in}` +* `{:linear_out}` +* `{:msg}` +* `{:name}` +* `{:originated_from_invariant}` +* `{:partition}` +* `{:positive}` +* `{:post}` +* `{:pre}` +* `{:precondition_previous_snapshot}` +* `{:qid}` +* `{:right}` +* `{:selective_checking}` +* `{:si_fcall}` +* `{:si_unique_call}` +* `{:sourcefile}` +* `{:sourceline}` +* `{:split_here}` +* `{:stage_active}` +* `{:stage_complete}` +* `{:staged_houdini_tag}` +* `{:start_checking_here}` +* `{:subsumption}` +* `{:template}` +* `{:terminates}` +* `{:upper}` +* `{:verified_under}` +* `{:weight}` +* `{:yields}` + +# Dafny User's Guide +## Installing Dafny From Binaries +## Building Dafny from Source +The current version of Dafny only works with Visual Studio 2012, +so if you intend to run Dafny from withing Visual Studio you must +install Visual Studio 2012. + +Dafny performs its verification by translating the Dafny source into +the Boogie intermediate verification language. So Dafny references +data structures defined in the Boogie project. So the first step +is to clone and build Boogie from sources. See +<https://github.com/boogie-org/boogie>. + +Follow these steps. + +Let _work_ be a working directory. + +Clone Boogie using + +``` +cd work +git clone https://github.com/boogie-org/boogie.git +``` + +Build Boogie using the directions from the Boogie web site, +which for Windows currently are: + +1. Open Source\Boogie.sln in Visual Studio +2. Right click the Boogie solution in the Solution Explorer and click Enable NuGet Package Restore. You will probably get a prompt asking to confirm this. Choose Yes. +3. Click BUILD > Build Solution. + +Clone Dafny using Mercurial. The Dafny directory must be a sibling +of the Boogie directory in order for it to find the Boogie files it needs. + +``` +cd work +hg clone https://hg.codeplex.com/dafny +``` + +Download and install the Visual Studio 2012 SDK from + +* <https://www.microsoft.com/en-us/download/details.aspx?id=30668>. + +This is needed to build the Visual Studio Extension that +runs Dafny from within Visual Studio 2012. + +Build the command-line Dafny executables. +1. Open dafny\Source\Dafny.sln in Visual Studio +2. Click BUILD > Build Solution. + +Build and install the Dafny Visual Studio extensions + +1. Open dafny/Source/DafnyExtension.sln in Visual Studio +2. Click BUILD > Build Solution. +3. This builds DafnyLanguageService.vsix and DafnyMenu.vsix +in the dafny/Binaries directory. +4. Install these by clicking on them from Windows Explorer. When +prompted, only check installing into Visual Studio 2012. + +## Using Dafny From Visual Studio +To test your installation, you can open Dafny test files +from the dafny/Test subdirectory in Visual Studio 2012. +You will want to use "VIEW/Error List" to ensure that +you see any errors that Dafny detects, and +"VIEW/Output" to see the result of any compilation. + +An example of a valid Dafny test is + +``` +dafny\Test\vstte2012\Tree.dfy +``` + +You can choose "Dafny/Compile" to compile the Dafny +program to C#. Doing that for the above test +produces `Tree.cs` and `Tree.dll` (since this test does +not have a main program). + +The following file: + +``` +D:\gh\dafny\Test\dafny0\Array.dfy +``` + +is an example of a Dafny file with verification errors. +The source will show red squiggles or dots where there +are errors, and the Error List window will describe the +errors. + +## Using Dafny From the Command Line +### Dafny Command Line Options +The command `Dafny.exe /?` gives the following description of +options that can be passed to Dafny. + +``` + ---- Dafny options --------------------------------------------------------- + + Multiple .dfy files supplied on the command line are concatenated into one + Dafny program. + + /dprelude:<file> + choose Dafny prelude file + /dprint:<file> + print Dafny program after parsing it + (use - as <file> to print to console) + /printMode:<Everything|NoIncludes|NoGhost> + NoIncludes disables printing of {:verify false} methods incorporated via the + include mechanism, as well as datatypes and fields included from other files. + NoGhost disables printing of functions, ghost methods, and proof statements + in implementation methods. It also disables anything NoIncludes disables. + /rprint:<file> + print Dafny program after resolving it + (use - as <file> to print to console) + /dafnyVerify:<n> + 0 - stop after typechecking + 1 - continue on to translation, verification, and compilation + /compile:<n> 0 - do not compile Dafny program + 1 (default) - upon successful verification of the Dafny + program, compile Dafny program to .NET assembly + Program.exe (if the program has a Main method) or + Program.dll (othewise), where Program.dfy is the name + of the last .dfy file on the command line + 2 - always attempt to compile Dafny program to C# program + out.cs, regardless of verification outcome + 3 - if there is a Main method and there are no verification + errors, compiles program in memory (i.e., does not write + an output file) and runs it + /spillTargetCode:<n> + 0 (default) - don't write the compiled Dafny program (but + still compile it, if /compile indicates to do so) + 1 - write the compiled Dafny program as a .cs file + /dafnycc Disable features not supported by DafnyCC + /noCheating:<n> + 0 (default) - allow assume statements and free invariants + 1 - treat all assumptions as asserts, and drop free. + /induction:<n> + 0 - never do induction, not even when attributes request it + 1 - only apply induction when attributes request it + 2 - apply induction as requested (by attributes) and also + for heuristically chosen quantifiers + 3 (default) - apply induction as requested, and for + heuristically chosen quantifiers and ghost methods + /inductionHeuristic:<n> + 0 - least discriminating induction heuristic (that is, lean + toward applying induction more often) + 1,2,3,4,5 - levels in between, ordered as follows as far as + how discriminating they are: 0 < 1 < 2 < (3,4) < 5 < 6 + 6 (default) - most discriminating + /noIncludes Ignore include directives + /noNLarith Reduce Z3's knowledge of non-linear arithmetic (*,/,%). + Results in more manual work, but also produces more predictable behavior. + /autoReqPrint:<file> + Print out requirements that were automatically generated by autoReq. + /noAutoReq Ignore autoReq attributes + /allowGlobals Allow the implicit class '_default' to contain fields, instance functions, + and instance methods. These class members are declared at the module scope, + outside of explicit classes. This command-line option is provided to simply + a transition from the behavior in the language prior to version 1.9.3, from + which point onward all functions and methods declared at the module scope are + implicitly static and fields declarations are not allowed at the module scope. + The reference manual is written assuming this option is not given. + + + /nologo suppress printing of version number, copyright message + /env:<n> print command line arguments + 0 - never, 1 (default) - during BPL print and prover log, + 2 - like 1 and also to standard output + /wait await Enter from keyboard before terminating program + /xml:<file> also produce output in XML format to <file> + + ---- Boogie options -------------------------------------------------------- + + Multiple .bpl files supplied on the command line are concatenated into one + Boogie program. + + /proc:<p> : limits which procedures to check + /noResolve : parse only + /noTypecheck : parse and resolve only + + /print:<file> : print Boogie program after parsing it + (use - as <file> to print to console) + /pretty:<n> + 0 - print each Boogie statement on one line (faster). + 1 (default) - pretty-print with some line breaks. + /printWithUniqueIds : print augmented information that uniquely + identifies variables + /printUnstructured : with /print option, desugars all structured statements + /printDesugared : with /print option, desugars calls + + /overlookTypeErrors : skip any implementation with resolution or type + checking errors + + /loopUnroll:<n> + unroll loops, following up to n back edges (and then some) + /soundLoopUnrolling + sound loop unrolling + /printModel:<n> + 0 (default) - do not print Z3's error model + 1 - print Z3's error model + 2 - print Z3's error model plus reverse mappings + 4 - print Z3's error model in a more human readable way + /printModelToFile:<file> + print model to <file> instead of console + /mv:<file> Specify file where to save the model in BVD format + /enhancedErrorMessages:<n> + 0 (default) - no enhanced error messages + 1 - Z3 error model enhanced error messages + + /printCFG:<prefix> : print control flow graph of each implementation in + Graphviz format to files named: + <prefix>.<procedure name>.dot + + /useBaseNameForFileName : When parsing use basename of file for tokens instead + of the path supplied on the command line + + ---- Inference options ----------------------------------------------------- + + /infer:<flags> + use abstract interpretation to infer invariants + The default is /infer:i + <flags> are as follows (missing <flags> means all) + i = intervals + c = constant propagation + d = dynamic type + n = nullness + p = polyhedra for linear inequalities + t = trivial bottom/top lattice (cannot be combined with + other domains) + j = stronger intervals (cannot be combined with other + domains) + or the following (which denote options, not domains): + s = debug statistics + 0..9 = number of iterations before applying a widen (default=0) + /noinfer turn off the default inference, and overrides the /infer + switch on its left + /checkInfer instrument inferred invariants as asserts to be checked by + theorem prover + /interprocInfer + perform interprocedural inference (deprecated, not supported) + /contractInfer + perform procedure contract inference + /instrumentInfer + h - instrument inferred invariants only at beginning of + loop headers (default) + e - instrument inferred invariants at beginning and end + of every block (this mode is intended for use in + debugging of abstract domains) + /printInstrumented + print Boogie program after it has been instrumented with + invariants + + ---- Debugging and general tracing options --------------------------------- + + /trace blurt out various debug trace information + /traceTimes output timing information at certain points in the pipeline + /tracePOs output information about the number of proof obligations + (also included in the /trace output) + /log[:method] Print debug output during translation + + /break launch and break into debugger + + ---- Verification-condition generation options ----------------------------- + + /liveVariableAnalysis:<c> + 0 = do not perform live variable analysis + 1 = perform live variable analysis (default) + 2 = perform interprocedural live variable analysis + /noVerify skip VC generation and invocation of the theorem prover + /verifySnapshots:<n> + verify several program snapshots (named <filename>.v0.bpl + to <filename>.vN.bpl) using verification result caching: + 0 - do not use any verification result caching (default) + 1 - use the basic verification result caching + 2 - use the more advanced verification result caching + /verifySeparately + verify each input program separately + /removeEmptyBlocks:<c> + 0 - do not remove empty blocks during VC generation + 1 - remove empty blocks (default) + /coalesceBlocks:<c> + 0 = do not coalesce blocks + 1 = coalesce blocks (default) + /vc:<variety> n = nested block (default for /prover:Simplify), + m = nested block reach, + b = flat block, r = flat block reach, + s = structured, l = local, + d = dag (default, except with /prover:Simplify) + doomed = doomed + /traceverify print debug output during verification condition generation + /subsumption:<c> + apply subsumption to asserted conditions: + 0 - never, 1 - not for quantifiers, 2 (default) - always + /alwaysAssumeFreeLoopInvariants + usually, a free loop invariant (or assume + statement in that position) is ignored in checking contexts + (like other free things); this option includes these free + loop invariants as assumes in both contexts + /inline:<i> use inlining strategy <i> for procedures with the :inline + attribute, see /attrHelp for details: + none + assume (default) + assert + spec + /printInlined + print the implementation after inlining calls to + procedures with the :inline attribute (works with /inline) + /lazyInline:1 + Use the lazy inlining algorithm + /stratifiedInline:1 + Use the stratified inlining algorithm + /fixedPointEngine:<engine> + Use the specified fixed point engine for inference + /recursionBound:<n> + Set the recursion bound for stratified inlining to + be n (default 500) + /inferLeastForUnsat:<str> + Infer the least number of constants (whose names + are prefixed by <str>) that need to be set to + true for the program to be correct. This turns + on stratified inlining. + /smoke Soundness Smoke Test: try to stick assert false; in some + places in the BPL and see if we can still prove it + /smokeTimeout:<n> + Timeout, in seconds, for a single theorem prover + invocation during smoke test, defaults to 10. + /causalImplies + Translate Boogie's A ==> B into prover's A ==> A && B. + /typeEncoding:<m> + how to encode types when sending VC to theorem prover + n = none (unsound) + p = predicates (default) + a = arguments + m = monomorphic + /monomorphize + Do not abstract map types in the encoding (this is an + experimental feature that will not do the right thing if + the program uses polymorphism) + /reflectAdd In the VC, generate an auxiliary symbol, elsewhere defined + to be +, instead of +. + + ---- Verification-condition splitting -------------------------------------- + + /vcsMaxCost:<f> + VC will not be split unless the cost of a VC exceeds this + number, defaults to 2000.0. This does NOT apply in the + keep-going mode after first round of splitting. + /vcsMaxSplits:<n> + Maximal number of VC generated per method. In keep + going mode only applies to the first round. + Defaults to 1. + /vcsMaxKeepGoingSplits:<n> + If set to more than 1, activates the keep + going mode, where after the first round of splitting, + VCs that timed out are split into <n> pieces and retried + until we succeed proving them, or there is only one + assertion on a single path and it timeouts (in which + case error is reported for that assertion). + Defaults to 1. + /vcsKeepGoingTimeout:<n> + Timeout in seconds for a single theorem prover + invocation in keep going mode, except for the final + single-assertion case. Defaults to 1s. + /vcsFinalAssertTimeout:<n> + Timeout in seconds for the single last + assertion in the keep going mode. Defaults to 30s. + /vcsPathJoinMult:<f> + If more than one path join at a block, by how much + multiply the number of paths in that block, to accomodate + for the fact that the prover will learn something on one + paths, before proceeding to another. Defaults to 0.8. + /vcsPathCostMult:<f1> + /vcsAssumeMult:<f2> + The cost of a block is + (<assert-cost> + <f2>*<assume-cost>) * + (1.0 + <f1>*<entering-paths>) + <f1> defaults to 1.0, <f2> defaults to 0.01. + The cost of a single assertion or assumption is + currently always 1.0. + /vcsPathSplitMult:<f> + If the best path split of a VC of cost A is into + VCs of cost B and C, then the split is applied if + A >= <f>*(B+C), otherwise assertion splitting will be + applied. Defaults to 0.5 (always do path splitting if + possible), set to more to do less path splitting + and more assertion splitting. + /vcsDumpSplits + For split #n dump split.n.dot and split.n.bpl. + Warning: Affects error reporting. + /vcsCores:<n> + Try to verify <n> VCs at once. Defaults to 1. + /vcsLoad:<f> Sets vcsCores to the machine's ProcessorCount * f, + rounded to the nearest integer (where 0.0 <= f <= 3.0), + but never to less than 1. + + ---- Prover options -------------------------------------------------------- + + /errorLimit:<num> + Limit the number of errors produced for each procedure + (default is 5, some provers may support only 1) + /timeLimit:<num> + Limit the number of seconds spent trying to verify + each procedure + /errorTrace:<n> + 0 - no Trace labels in the error output, + 1 (default) - include useful Trace labels in error output, + 2 - include all Trace labels in the error output + /vcBrackets:<b> + bracket odd-charactered identifier names with |'s. <b> is: + 0 - no (default with non-/prover:Simplify), + 1 - yes (default with /prover:Simplify) + /prover:<tp> use theorem prover <tp>, where <tp> is either the name of + a DLL containing the prover interface located in the + Boogie directory, or a full path to a DLL containing such + an interface. The standard interfaces shipped include: + SMTLib (default, uses the SMTLib2 format and calls Z3) + Z3 (uses Z3 with the Simplify format) + Simplify + ContractInference (uses Z3) + Z3api (Z3 using Managed .NET API) + /proverOpt:KEY[=VALUE] + Provide a prover-specific option (short form /p). + /proverLog:<file> + Log input for the theorem prover. Like filenames + supplied as arguments to other options, <file> can use the + following macros: + @TIME@ expands to the current time + @PREFIX@ expands to the concatenation of strings given + by /logPrefix options + @FILE@ expands to the last filename specified on the + command line + In addition, /proverLog can also use the macro '@PROC@', + which causes there to be one prover log file per + verification condition, and the macro then expands to the + name of the procedure that the verification condition is for. + /logPrefix:<str> + Defines the expansion of the macro '@PREFIX@', which can + be used in various filenames specified by other options. + /proverLogAppend + Append (not overwrite) the specified prover log file + /proverWarnings + 0 (default) - don't print, 1 - print to stdout, + 2 - print to stderr + /proverMemoryLimit:<num> + Limit on the virtual memory for prover before + restart in MB (default:100MB) + /restartProver + Restart the prover after each query + /proverShutdownLimit<num> + Time between closing the stream to the prover and + killing the prover process (default: 0s) + /platform:<ptype>,<location> + ptype = v11,v2,cli1 + location = platform libraries directory + + Simplify specific options: + /simplifyMatchDepth:<num> + Set Simplify prover's matching depth limit + + Z3 specific options: + /z3opt:<arg> specify additional Z3 options + /z3multipleErrors + report multiple counterexamples for each error + /useArrayTheory + use Z3's native theory (as opposed to axioms). Currently + implies /monomorphize. + /useSmtOutputFormat + Z3 outputs a model in the SMTLIB2 format. + /z3types generate multi-sorted VC that make use of Z3 types + /z3lets:<n> 0 - no LETs, 1 - only LET TERM, 2 - only LET FORMULA, + 3 - (default) any + /z3exe:<path> + path to Z3 executable + + CVC4 specific options: + /cvc4exe:<path> + path to CVC4 executable + +``` + + +# References +[BIB] + diff --git a/Docs/DafnyRef/css.sty b/Docs/DafnyRef/css.sty new file mode 100644 index 00000000..aab82e69 --- /dev/null +++ b/Docs/DafnyRef/css.sty @@ -0,0 +1,803 @@ +%---------------------------------------------------------------------------
+% Copyright 2013 Microsoft Corporation.
+%
+% This is free software; you can redistribute it and/or modify it under the
+% terms of the Apache License, Version 2.0. A copy of the License can be
+% found in the file "license.txt" at the root of this distribution.
+%---------------------------------------------------------------------------
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+
+\RequirePackage{iftex}
+\RequirePackage{etoolbox}
+\RequirePackage{xkeyval}
+\RequirePackage[table]{xcolor}
+\RequirePackage{mdframed}
+\RequirePackage{graphicx}
+\RequirePackage{tablefootnote}
+
+% font selection
+\ifXeTeX\RequirePackage{fontspec}\else
+\ifLuaTeX\RequirePackage{fontspec}\else
+\providecommand{\fontspec}[2][]{}
+\fi\fi
+
+
+% Define CSS 17 standard colors
+\definecolor{Red}{HTML}{FF0000}
+\definecolor{Lime}{HTML}{00FF00}
+\definecolor{Blue}{HTML}{0000FF}
+
+\definecolor{Yellow}{HTML}{FFFF00}
+\definecolor{Cyan}{HTML}{00FFFF}
+\definecolor{Magenta}{HTML}{FF00FF}
+
+\definecolor{Navy}{HTML}{000080}
+\definecolor{Maroon}{HTML}{800000}
+\definecolor{Green}{HTML}{008000}
+
+\definecolor{Teal}{HTML}{008080}
+\definecolor{Purple}{HTML}{800080}
+\definecolor{Olive}{HTML}{808000}
+
+\definecolor{Black}{HTML}{000000}
+\definecolor{Dimgray}{HTML}{696969}
+\definecolor{Gray}{HTML}{808080}
+\definecolor{Darkgray}{HTML}{A9A9A9}
+\definecolor{Silver}{HTML}{C0C0C0}
+\definecolor{Lightgray}{HTML}{D3D3D3}
+\definecolor{Gainsboro}{HTML}{DCDCDC}
+\definecolor{Floralwhite}{HTML}{FFFAF0}
+\definecolor{Ivory}{HTML}{FFFFF0}
+\definecolor{White}{HTML}{FFFFFF}
+
+\definecolor{Orange}{HTML}{FFA500}
+\definecolor{Aqua}{HTML}{00FFFF}
+\definecolor{Fuchsia}{HTML}{FF00FF}
+
+\newcommand{\@swap}[2]{#2{#1}}
+\newcommand{\@expandafter}[2]{\expandafter\@swap\expandafter{#2}{#1}}
+
+\newcommand{\eifstrequal}{\expandafter\ifstrequal\expandafter}
+\newcommand{\eeifstrequal}[2]{\@expandafter{\eifstrequal{#1}}{#2}}
+
+\providecommand\providelength[1]{%
+ \begingroup
+ \escapechar\m@ne
+ \xdef\@gtempa{\string#1}%
+ \endgroup
+ \@ifundefined{\@gtempa}%
+ {\newskip#1}%
+ {}%
+}
+
+% is a string an element of a list of (comma separated) strings
+\newcommand{\eifstrelement}[4]{%
+ \def\@found{}%
+ \@for\@ii:=#2\do{%
+ \eeifstrequal{\@ii}{#1}{\def\@found{true}}{}%
+ }%
+ \ifdefvoid{\@found}{#4}{#3}%
+}
+
+% do two lists of strings intersect?
+\newcommand{\ifintersect}[4]{%
+ \def\@intersect{}%
+ \@for\@sname:=#1\do{%
+ \ifdefvoid{\@intersect}{%
+ \eifstrelement{\@sname}{#2}{\def\@intersect{true}}{}%
+ }{}%
+ }%
+ \ifdefvoid{\@intersect}{#4}{#3}%
+}
+
+% get string head and tail
+\def\strsplit#1{\expandafter\strsplitx#1\empty\empty\empty}
+\def\strsplitx#1#2\empty{%
+ \edef\strhead{#1}%
+ \edef\strtail{#2}%
+}
+
+% normalize colors: to lowercase and then capitalize
+\newcommand{\cssDefNormalizeColor}[2]{%
+ \expandafter\@cssNormColor#2\empty{#1}\empty%
+}
+\def\@cssNormColor#1#2\empty#3\empty{%
+ \uppercase{\def\@hd{#1}}\lowercase{\def\@tl{#2}}%
+ \expandafter\global\expandafter\edef\csname #3\endcsname{\@hd\@tl}%
+}
+
+
+% ---------------------------------------------------
+% Some TeX stuff to compose functions
+% ---------------------------------------------------
+\newcommand{\apptox}[2]{% apptox{\cmd1}{\cmd2} == newcommand{\cmd1'}[1]{\cmd1{\cmd2{#1}}}
+ \providecommand{#1}[1]{##1}% define it if necessary (as identity)
+ \protected@edef#1##1{#1{\protect #2{##1}}}%
+}
+
+\newcommand{\pretox}[2]{% pretox{\cmd1}{\cmd2} == newcommand{\cmd1'}[1]{\cmd2{\cmd1{#1}}}
+ \providecommand{#1}[1]{##1}%
+ \protected@edef#1##1{\protect #2{#1{##1}}}%
+}
+
+%-------------------------------------------------------------
+% Save footnotes inside mdframed and minipage environments
+%-------------------------------------------------------------
+\newif\if@saveFootnotes
+\newcommand{\cssSaveFootnotes}%
+ {\if@saveFootnotes\else%
+ \let\footnote\tablefootnote%
+ \fi%
+ \@saveFootnotestrue}%
+\newcommand{\cssRestoreFootnotes}%
+ {\if@saveFootnotes\else%
+ \tfn@tablefootnoteprintout%
+ \gdef\tfn@fnt{0}%
+ \fi}%
+
+%-------------------------------------------------------------
+% Setup mdframed with default values
+%-------------------------------------------------------------
+\newlength{\cssPixel}\setlength{\cssPixel}{0.4pt}% assume 180 dpi
+\mdfsetup{%
+ leftmargin=0pt,%
+ rightmargin=0pt,%
+ skipabove=0pt,%
+ skipbelow=0pt,%
+ innertopmargin=0pt,%
+ innerbottommargin=0pt,%
+ innerleftmargin=0pt,%
+ innerrightmargin=0pt,%
+ middlelinewidth=0pt,%
+ linewidth=0pt,%
+ outerlinewidth=0pt,innerlinewidth=0pt%
+}
+
+
+% ---------------------------------------------------
+% Basic command to process attributes passed to TeX
+% ---------------------------------------------------
+\newif\if@usewrap
+\newcommand{\@doBefore}{}
+\newcommand{\@doAfter}{}
+\newcommand{\@wrapCmd}[1]{#1}
+
+\newcommand{\@cssUseCmd}{\renewcommand{\@wrapCmd}[1]{##1}\@usewraptrue}
+\newcommand{\@cssUseEnv}{\renewcommand{\@doBefore}{}\renewcommand{\@doAfter}{}\@usewrapfalse}
+
+\newcommand{\@cssApplyCmd}[1]{{\@wrapCmd{#1}}}
+\newcommand{\@cssApplyBefore}{\@doBefore{}}
+\newcommand{\@cssApplyAfter}{\@doAfter{}}
+
+\newcommand{\@cssProcessAttrs}[2]{%
+ \setkeys*{cssx}{#1}\setrmkeys*{csspre}\setrmkeys*{css}\setrmkeys*{csspost}% defaults
+ \@cssApplyRulesFor{parentclass}{css}{\cssParentClass}%
+ \setkeys*{cssx}{#2}\setrmkeys*{csspre}\setrmkeys*{css}\setrmkeys*{csspost}% regular
+ \protected@edef\cssParentClass{\cssClass}%
+}
+
+
+\newcommand{\@cmdBefore}[2]{#1#2}
+\newcommand{\@cmdAfter}[2]{#2#1}
+
+\newcommand{\cssWrapCmd}[1]{\apptox{\@wrapCmd}{#1}}
+\newcommand{\cssDoBefore}[1]{\if@usewrap\cssWrapCmd{\@cmdBefore{#1}}\else #1\fi}
+\newcommand{\cssDoAfter}[1]{\if@usewrap\cssWrapCmd{\@cmdAfter{#1}}\else\preto\@doAfter{#1}\fi}
+
+\newcommand{\cssDoEnv}[1]{\cssDoBefore{\protect\begin{#1}}\cssDoAfter{\protect\end{#1}}}
+\newcommand{\cssDoEnvOpt}[2]{\cssDoBefore{\begin{#1}[#2]}\cssDoAfter{\end{#1}}}
+\newcommand{\cssDoEnvArg}[2]{\cssDoBefore{\begin{#1}{#2}}\cssDoAfter{\end{#1}}}
+\newcommand{\cssDoEnvArgII}[3]{\cssDoBefore{\begin{#1}{#2}{#3}}\cssDoAfter{\end{#1}}}
+
+\newcommand{\newKey}[4][]{\define@key{#2}{#3}[#1]{#4}}
+\newcommand{\newLength}[2]{\providelength{#1}\setlength{#1}{#2}}
+
+
+\newcommand{\@cssReset}{}
+\newcommand{\cssAddReset}[1]{\appto{\@cssReset}{#1}}
+\newcommand{\cssNewResetCommand}[2]{\newcommand{#1}{#2}\cssAddReset{\renewcommand{#1}{#2}}}
+
+\newlength{\cssFill}
+\setlength{\cssFill}{2sp plus 1fill minus 2sp} % make \fill unequal to 0pt, and detectable as 2sp
+
+\newcommand{\cssNewLengthKey}[4][0pt]{%
+ \newLength{#4}{#1}%
+ \newKey{#2}{#3}{%
+ \ifstrequal{##1}{auto}{\setlength{#4}{\cssFill}}{\setlength{#4}{##1}}%
+ }%
+ \cssAddReset{\setlength{#4}{#1}}%
+}
+
+
+\newcommand{\cssNewKeyNoReset}[4]{%
+ \newcommand{#3}{#4}%
+ \newKey{#1}{#2}{\renewcommand{#3}{##1}}%
+}
+
+\newcommand{\cssNewKey}[4]{%
+ \cssNewResetCommand{#3}{#4}%
+ \newKey{#1}{#2}{%(#2=##1)%debug key setting
+ \renewcommand{#3}{##1}}%
+}
+\newcommand{\cssNewKeyX}[5]{%
+ \cssNewResetCommand{#3}{#4}%
+ \newKey{#1}{#2}{\renewcommand{#3}{##1}#5{##1}}%
+}
+\newcommand{\cssNewListKey}[4]{%
+ \cssNewResetCommand{#3}{#4}%
+ \newKey{#1}{#2}{\appto{#3}{,##1}}%
+}
+\newcommand{\cssNewListKeyX}[5]{%
+ \cssNewResetCommand{#3}{#4}%
+ \newKey{#1}{#2}{\appto{#3}{,##1}#5{##1}}%
+}
+\newcommand{\cssNewPseudoKey}[3]{%
+ \newKey{#1}{#2}{\setkeys{#1}{#3}}%
+}
+
+%-------------------------------------------------------------
+% css: display
+%-------------------------------------------------------------
+\cssNewKey{css}{display}{\cssDisplay}{block}
+
+%-------------------------------------------------------------
+% css: width, height, and margins
+%-------------------------------------------------------------
+
+\cssNewLengthKey{css}{margin-left}{\cssMarginLeft}
+\cssNewLengthKey{css}{margin-right}{\cssMarginRight}
+\cssNewLengthKey{css}{margin-top}{\cssMarginTop}
+\cssNewLengthKey{css}{margin-bottom}{\cssMarginBottom}
+\cssNewLengthKey[1sp]{css}{width}{\cssWidth}
+\cssNewLengthKey[1sp]{css}{height}{\cssHeight}
+\cssNewKey{css}{vertical-align}{\cssVerticalAlign}{}
+
+\cssNewPseudoKey{css}{margin}{margin-top=#1,margin-bottom=#1,margin-left=#1,margin-right=#1}
+
+
+\newcommand{\@cssProcessMargins}{%
+ \eifstrequal{\cssDisplay}{block}%
+ {\@cssBlockEndPar\@cssBlockMargins}%
+ {\eifstrequal{\cssDisplay}{block-inline}%
+ {\@cssBlockMargins}%
+ {\@cssInlineMargins}%
+ }%
+}
+
+\newcommand{\@cssBlockEndPar}{%
+ \cssIfHasClass{para-continue,para-block}{}{\cssDoAfter{\relax\ifhmode\par\global\hangindent=0pt\fi}}%
+}
+
+\newif\if@hasdim
+
+\newlength{\cssHeightFull} % height including padding and border
+\newlength{\cssWidthFull} % width including padding and border
+\newLength{\@cssMarginAfter}{0pt}
+\newLength{\@cssParSkip}{\parskip}
+\newLength{\@cssParIndent}{\parindent}
+\newcommand{\@cssFixMathSpacing}{\strut\vspace{-\baselineskip}} % fixes weird abovedisplay skip spacing
+\newcommand{\@cssBlockMargins}{%
+ \@hasdimfalse
+ \ifdim\cssWidth=1sp\setlength{\cssWidthFull}{1sp}\else\@hasdimtrue\fi
+ \ifdim\cssHeight=1sp\setlength{\cssHeightFull}{1sp}\else\@hasdimtrue\fi
+ \if@hasdim%
+ % set full height and width
+ \setlength{\cssWidthFull}{\dimexpr\cssWidth+\cssPaddingLeft+\cssPaddingRight\relax}%
+ \eifstrequal{\cssBorderLeftStyle}{none}{}{\addtolength{\cssWidthFull}{\cssBorderWidth}}%
+ \eifstrequal{\cssBorderRightStyle}{none}{}{\addtolength{\cssWidthFull}{\cssBorderWidth}}%
+ \setlength{\cssHeightFull}{\dimexpr\cssHeight+\cssPaddingTop+\cssPaddingBottom\relax}%
+ \eifstrequal{\cssBorderTopStyle}{none}{}{\addtolength{\cssHeightFull}{\cssBorderWidth}}%
+ \eifstrequal{\cssBorderBottomStyle}{none}{}{\addtolength{\cssHeightFull}{\cssBorderWidth}}%
+ % set default width?
+ \ifdim\cssWidth=1sp% in this case, cssWidthFull is just padding and borders
+ \setlength{\cssWidth}{\dimexpr\linewidth-\cssWidthFull-\cssMarginLeft-\cssMarginRight}%
+ \addtolength{\cssWidthFull}{\cssWidth}%
+ \fi%
+ %minipage
+ \ifdim\cssMarginTop=0pt\else\cssDoBefore{\vspace{\cssMarginTop}}\fi
+ \ifdim\cssMarginLeft=0pt\else\cssDoBefore{\hspace*{\cssMarginLeft}}\fi
+ \setlength{\@cssParIndent}{\parindent}% save parskip and parindent since minipage resets it
+ \setlength{\@cssParSkip}{\parskip}%
+ \eifstrequal{\cssVerticalAlign}{bottom}{\def\@cssValign{b}}%
+ {\eifstrequal{\cssVerticalAlign}{center}{\def\@cssValign{c}}%
+ {\eifstrequal{\cssVerticalAlign}{top}{\def\@cssValign{t}}%
+ {\def\@cssValign{c}}}}% including `middle`
+ \ifdim\cssHeight=1sp%
+ \cssDoBefore{\begin{minipage}[\@cssValign]{\cssWidthFull}}%
+ \else
+ \cssDoBefore{\begin{minipage}[\@cssValign][\cssHeightFull]{\cssWidthFull}}%
+ \fi
+ \cssDoBefore{\cssSaveFootnotes\setlength{\parskip}{\@cssParSkip}\setlength{\parindent}{\@cssParIndent}}%
+ %note: DoAfter prepends, so in opposite order
+ \ifdim\cssMarginBottom=0pt\else\cssDoAfter{\vspace{\cssMarginBottom}}\fi
+ \ifdim\cssMarginRight=0pt\else\cssDoAfter{\hspace*{\cssMarginRight}}\fi
+ \cssDoAfter{\end{minipage}\cssRestoreFootnotes}%
+ \else
+ % no height/width: trivlist
+ \@hasdimfalse
+ \ifdim\cssMarginLeft=0pt\else\@hasdimtrue\fi
+ \ifdim\cssMarginRight=0pt\else\@hasdimtrue\fi
+ \ifdim\cssMarginTop=0pt\else\@hasdimtrue\fi
+ \ifdim\cssMarginBottom=0pt\else\@hasdimtrue\fi
+ \if@hasdim
+ \setlength{\@cssMarginAfter}{\dimexpr\cssMarginBottom-\cssMarginTop\relax}%
+ \cssDoEnvArgII{list}{}{%
+ \leftmargin=\cssMarginLeft%
+ \rightmargin=\cssMarginRight%
+ \topsep=\cssMarginTop%
+ \itemsep=0pt%
+ \parsep=0pt%
+ \parskip=0pt%
+ \partopsep=0pt%
+ \listparindent=\parindent%
+ }%
+ \ifdim\@cssMarginAfter=0pt\else\cssDoAfter{\vspace{\@cssMarginAfter}}\fi%
+ \cssIfHasClass{math-display}%
+ {\cssDoBefore{\item\@cssFixMathSpacing}}%
+ {\cssDoBefore{\item}}% \fi
+ \fi
+ \fi
+}
+
+\newcommand{\@cssHide}[1]{}
+\newcommand{\@cssInlineMargins}{%
+ \ifdim\cssMarginLeft=0pt\else\cssDoBefore{\hspace*{\cssMarginLeft}}\fi
+ \ifdim\cssMarginRight=0pt\else\cssDoAfter{\hspace*{\cssMarginRight}}\fi
+ \ifdim\cssMarginBottom=0pt\else\cssDoBefore{\rule[-\cssMarginBottom]{0pt}{\cssMarginBottom}}\fi
+ \ifdim\cssMarginTop=0pt\else\cssDoBefore{\rule{0pt}{\dimexpr\baselineskip*0.7+\cssMarginTop\relax}}\fi
+ \eifstrequal{\cssDisplay}{hidden}{%
+ \cssWrapCmd{\@cssHide}%
+ }{}%
+}
+
+%-------------------------------------------------------------
+% css: Borders and padding
+%-------------------------------------------------------------
+
+\cssNewLengthKey{css}{padding-left}{\cssPaddingLeft}
+\cssNewLengthKey{css}{padding-right}{\cssPaddingRight}
+\cssNewLengthKey{css}{padding-top}{\cssPaddingTop}
+\cssNewLengthKey{css}{padding-bottom}{\cssPaddingBottom}
+
+\newlength{\cssBorderWidthTotal}
+\cssNewLengthKey[\cssPixel]{css}{border-width}{\cssBorderWidth}
+\cssNewKey{css}{border-color}{\cssBorderColor}{black}
+\cssNewKey{css}{border-top-style}{\cssBorderTopStyle}{none}
+\cssNewKey{css}{border-bottom-style}{\cssBorderBottomStyle}{none}
+\cssNewKey{css}{border-left-style}{\cssBorderLeftStyle}{none}
+\cssNewKey{css}{border-right-style}{\cssBorderRightStyle}{none}
+\cssNewKey{css}{background-color}{\cssBackgroundColor}{white}
+
+\cssNewPseudoKey{css}{padding}{padding-top=#1,padding-bottom=#1,padding-right=#1,padding-left=#1}
+
+\cssNewPseudoKey{css}{border-style}%
+ {border-top-style=#1,border-bottom-style=#1,border-left-style=#1,border-right-style=#1}
+
+\newcommand{\@cssProcessPadding}{%
+ \eifstrequal{\cssDisplay}{block}%
+ {\@cssBlockPadding}%
+ {\eifstrequal{\cssDisplay}{block-inline}%
+ {\@cssBlockPadding}%
+ {\@cssInlinePadding}%
+ }}
+
+% Special math-framed environment that fixes vertical spacing around math display
+\newenvironment{mdmathframed}[1][]%
+ {\begin{mdframed}[#1]\@cssFixMathSpacing}%
+ {\@cssFixMathSpacing\end{mdframed}}
+
+
+\newif\if@needframe
+\newLength{\@cssPaddingLength}{0pt}
+\newcommand{\@cssFramedArgs}{}
+\newcommand{\@cssBorderStyleAll}{}
+\newcommand{\@cssBlockPadding}{%
+ \@needframefalse%
+ \eifstrequal{\cssBorderTopStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderBottomStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderLeftStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderRightStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBackgroundColor}{white}{}{\@needframetrue}%
+ \ifdim\cssPaddingTop=0pt\else\@needframetrue\fi
+ \ifdim\cssPaddingBottom=0pt\else\@needframetrue\fi
+ \ifdim\cssPaddingLeft=0pt\else\@needframetrue\fi
+ \ifdim\cssPaddingRight=0pt\else\@needframetrue\fi
+ \strsplit{\cssBackgroundColor}%
+ \eifstrequal{\strhead}{\#}%
+ {\definecolor{Temp}{HTML}{\strtail}\edef\@@bcolor{Temp}}%
+ {\cssDefNormalizeColor{@bcolor}{\cssBackgroundColor}\edef\@@bcolor{\@bcolor}}%
+ %\expandafter\lowercase\expandafter{\expandafter\def\expandafter\bcolor\expandafter{\cssBackgroundColor}}%
+ \if@needframe%
+ \cssDoAfter{\cssRestoreFootnotes}% first, because post commands are pre-pended
+ \renewcommand{\@cssFramedArgs}{%
+ innertopmargin=\the\cssPaddingTop,%
+ innerbottommargin=\the\cssPaddingBottom,%
+ innerleftmargin=\the\cssPaddingLeft,%
+ innerrightmargin=\the\cssPaddingRight,%
+ linewidth=\the\cssBorderWidth,%
+ linecolor=\cssBorderColor,%
+ backgroundcolor=\@@bcolor%
+ }%
+ \setlength{\cssBorderWidthTotal}{0pt}%
+ \eifstrequal{\cssBorderTopStyle}{none}{\appto{\@cssFramedArgs}{,topline=false}}{}%
+ \eifstrequal{\cssBorderBottomStyle}{none}{\appto{\@cssFramedArgs}{,bottomline=false}}{}%
+ \eifstrequal{\cssBorderLeftStyle}{none}{\appto{\@cssFramedArgs}{,leftline=false}}%
+ {\addtolength{\cssBorderWidthTotal}{\cssBorderWidth}}%
+ \eifstrequal{\cssBorderRightStyle}{none}{\appto{\@cssFramedArgs}{,rightline=false}}%
+ {\addtolength{\cssBorderWidthTotal}{\cssBorderWidth}}%
+ \cssIfHasClass{math-display}%
+ {\@expandafter{\cssDoEnvOpt{mdmathframed}}{\@cssFramedArgs}}%
+ {\@expandafter{\cssDoEnvOpt{mdframed}}{\@cssFramedArgs}}%
+ % insert a minipage if height or width was set so the frame is as large
+ \@hasdimfalse
+ \ifdim\cssWidth=1sp\else\@hasdimtrue\fi
+ \ifdim\cssHeight=1sp\else\@hasdimtrue\fi
+ \if@hasdim%
+ \ifdim\cssHeight=1sp%
+ \cssDoBefore{\begin{minipage}{\cssWidth}}%
+ \else
+ \cssDoBefore{\begin{minipage}[t][\cssHeight]{\cssWidth}}%
+ \fi
+ \cssDoBefore{\setlength{\parskip}{\@cssParSkip}\setlength{\parindent}{\@cssParIndent}}%
+ %note: DoAfter prepends, so in opposite order
+ \cssDoAfter{\end{minipage}}%
+ \fi
+ \cssDoBefore{\cssSaveFootnotes}%
+ \fi
+}
+
+\newcommand{\@robustFramebox}[2]{%
+ \eifstrequal{\cssTextAlign}{center}{\framebox[#1][c]{#2}}%
+ {\eifstrequal{\cssTextAlign}{right}{\framebox[#1][r]{#2}}%
+ {\framebox[#1][l]{#2}}}%
+}
+
+\newcommand{\@robustMakebox}[2]{%
+ \eifstrequal{\cssDisplay}{table-cell}%
+ {\@robustTableParbox{#1}{#2}}%
+ {\eifstrequal{\cssTextAlign}{center}{\makebox[#1][c]{#2}}%
+ {\eifstrequal{\cssTextAlign}{right}{\makebox[#1][r]{#2}}%
+ {\makebox[#1][l]{#2}}}}%
+}
+
+\newcommand{\@robustRaisebox}[2]{%
+ \raisebox{#1}{#2}%
+}
+
+\newcommand{\@robustHeight}[1]{%
+ \eifstrequal{\cssVerticalAlign}{top}%
+ {\raisebox{0pt}[0pt][\cssHeight]{#1}}%
+ {\eifstrequal{\cssVerticalAlign}{middle}%
+ {\raisebox{0pt}[0.5\cssHeight][0.5\cssHeight]{#1}}%
+ {\eifstrequal{\cssVerticalAlign}{baseline}%
+ {\raisebox{0pt}[\dimexpr\cssHeight-\depth\relax][\depth]{#1}}%
+ {\raisebox{0pt}[\cssHeight][0pt]{#1}}% bottom
+ }}%
+}
+
+\newcommand{\@robustTableParbox}[2]{%
+ \eifstrequal{\cssVerticalAlign}{top}{\def\@cssValign{t}}%
+ {\eifstrequal{\cssVerticalAlign}{center}{\def\@cssValign{c}}%
+ {\eifstrequal{\cssVerticalAlign}{middle}{\def\@cssValign{c}}}%
+ {\def\@cssValign{b}}}%
+ \ifdim\cssHeight=1sp%
+ \parbox[\@cssValign]{#1}{#2}%
+ \else%
+ \parbox[\@cssValign][\cssHeight]{#1}{#2}%
+ \fi%
+}
+
+\newcommand{\@cssInlinePadding}{%
+ \eifstrequal{\cssBackgroundColor}{}{}%
+ {\eifstrequal{\cssBackgroundColor}{white}{}%
+ {\strsplit{\cssBackgroundColor}%
+ \eifstrequal{\strhead}{\#}%
+ {\cssWrapCmd{\protect\colorbox[HTML]{\strtail}}}%
+ {\cssWrapCmd{\@robustColorbox{\cssBackgroundColor}}}%
+ }%
+ }%
+ \@needframefalse%
+ \eifstrequal{\cssBorderTopStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderBottomStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderLeftStyle}{none}{}{\@needframetrue}%
+ \eifstrequal{\cssBorderRightStyle}{none}{}{\@needframetrue}%
+ \if@needframe%
+ \setlength{\fboxrule}{\cssBorderWidth}%
+ \ifdim\cssWidth=1sp%
+ \cssWrapCmd{\fbox}%
+ \else
+ \cssWrapCmd{\@robustFramebox{\cssWidth}}%
+ \fi
+ \else
+ \ifdim\cssWidth=1sp\else
+ \cssWrapCmd{\@robustMakebox{\cssWidth}}%
+ \fi
+ \fi
+ % height?
+ \ifdim\cssHeight=1sp\else\cssWrapCmd{\@robustHeight}\fi
+ % raisebox?
+ \eifstrequal{\cssDisplay}{inline}{%
+ \eifstrequal{\cssVerticalAlign}{}{}%
+ {\eifstrequal{\cssVerticalAlign}{top}{}%
+ {\eifstrequal{\cssVerticalAlign}{bottom}{}%
+ {\eifstrequal{\cssVerticalAlign}{middle}{}%
+ {\eifstrequal{\cssVerticalAlign}{baseline}{}%
+ {\cssWrapCmd{\@robustRaisebox{\cssVerticalAlign}}%
+ }}}}}%
+ }{}%
+ % padding
+ \if@needframe
+ \setlength{\fboxsep}{\cssPaddingTop}% todo: define our own box so we can set paddingtop/bot separately
+ \ifdim\cssPaddingBottom>\fboxsep\setlength{\fboxsep}{\cssPaddingBottom}\fi
+ \ifdim\cssPaddingLeft=\fboxsep\else\hspace*{\dimexpr\cssPaddingLeft-\fboxsep\relax}\fi
+ \ifdim\cssPaddingRight=\fboxsep\else\hspace*{\dimexpr\cssPaddingRight-\fboxsep\relax}\fi
+ \else
+ \ifdim\cssPaddingLeft=0pt\else\cssDoBefore{\hspace*{\cssPaddingLeft}}\fi
+ \ifdim\cssPaddingRight=0pt\else\cssDoAfter{\hspace*{\cssPaddingRight}}\fi
+ \ifdim\cssPaddingBottom=0pt\else\cssDoBefore{\protect\rule[-\cssPaddingBottom]{0pt}{\cssPaddingBottom}}\fi
+ \ifdim\cssPaddingTop=0pt\else\cssDoBefore{\protect\rule{0pt}{\dimexpr\cssPaddingTop+0.8em\relax}}\fi
+ \fi
+}
+
+%-------------------------------------------------------------
+% css: Textalign, textindent etc
+%-------------------------------------------------------------
+
+\cssNewLengthKey{css}{text-indent}{\cssTextIndent}
+\cssNewKey{css}{text-align}{\cssTextAlign}{justify}
+\cssNewLengthKey{css}{line-height}{\cssLineHeight}
+\cssNewKey{css}{float}{\cssFloat}{}
+
+\DeclareRobustCommand{\@robustColor}[1]{%
+ \cssDefNormalizeColor{@fcolor}{#1}\color{\@fcolor}%
+}
+\DeclareRobustCommand{\@robustColorbox}[2]{%
+ \cssDefNormalizeColor{@bcolor}{#1}\colorbox{\@bcolor}{#2}%
+}
+
+
+\newcommand{\@cssProcessText}{%
+ \eifstrequal{\cssDisplay}{block}%
+ {\@cssBlockText}%
+ {\eifstrequal{\cssDisplay}{block-inline}%
+ {\@cssBlockText}%
+ {\eifstrequal{\cssDisplay}{table-cell}%
+ {\@cssBlockText}%
+ {\@cssInlineText}%
+ }}}
+
+\newcommand{\@cssBlockText}{%
+ \eifstrequal{\cssId}{}{}{\label{\cssId}}% set label
+ \eifstrequal{\cssTextAlign}{left}%
+ {\cssDoBefore{\protect\raggedright}}%
+ {\eifstrequal{\cssTextAlign}{right}%
+ {\cssDoBefore{\protect\raggedleft}}%
+ {\eifstrequal{\cssTextAlign}{center}%
+ {\cssDoBefore{\protect\centering}}%
+ {}}}%
+ \ifdim\cssLineHeight=0pt\else\setlength{\baselineskip}{\cssLineHeight}\fi
+ \noindent\ifdim\cssTextIndent=0pt\else\hspace*{\cssTextIndent}\fi
+}
+
+\newcommand{\@cssInlineText}{%
+ \eifstrequal{\cssId}{}{}{\label{\cssId}}% set label
+ \eifstrequal{\cssFloat}{left}%
+ {\cssDoAfter{\hspace*{\fill}}}%
+ {\eifstrequal{\cssFloat}{right}%
+ {\cssDoBefore{\hspace*{\fill}}}%
+ {\eifstrequal{\cssFloat}{center}%
+ {\cssDoAfter{\hspace*{\fill}}\cssDoBefore{\hspace*{\fill}}}%
+ {}}}%
+ \ifdim\cssLineHeight=0pt\else\cssDoBefore{\rule{0pt}{\cssLineHeight}}\fi
+}
+
+%-------------------------------------------------------------
+% css: Font attributes
+%-------------------------------------------------------------
+
+\cssNewKey{css}{font-weight}{\cssFontWeight}{}
+\cssNewKey{css}{font-variant}{\cssFontVariant}{}
+\cssNewKey{css}{font-style}{\cssFontStyle}{}
+\cssNewKey{css}{font-size}{\cssFontSize}{}
+\cssNewKey{css}{font-family}{\cssFontFamily}{}
+\cssNewKey{css}{color}{\cssColor}{}
+\cssNewKey{css}{penalty}{\cssPenalty}{}
+
+\newcommand{\@cssProcessFont}{%
+ % font family
+ \edef\@fontFamily{\cssFontFamily}%
+ \@for\@ii:=\cssFontFamily\do{% find the last argument in a comma separated list
+ \edef\@fontFamily{\@ii}%
+ }%
+ \eifstrequal{\@fontFamily}{}{}% quick test
+ {\eifstrequal{\@fontFamily}{monospace}%
+ {\cssDoBefore\ttfamily}%
+ {\eifstrequal{\@fontFamily}{serif}%
+ {\cssDoBefore\rmfamily}%
+ {\eifstrequal{\@fontFamily}{sans-serif}%
+ {\cssDoBefore\sffamily}%
+ {\eifstrequal{\@fontFamily}{normal}%
+ {\cssDoBefore\rmfamily}%
+ {\cssDoBefore{\fontspec{\@fontFamily}}}%
+ }}}}%
+ %
+ \eifstrequal{\cssFontWeight}{bold}%
+ {\cssDoBefore\bfseries}%
+ {\eifstrequal{\cssFontWeight}{normal}%
+ {\cssDoBefore\mdseries}%
+ {}}%
+ \eifstrequal{\cssFontVariant}{small-caps}%
+ {\cssDoBefore\scshape}%
+ {\eifstrequal{\cssFontVariant}{normal}%
+ {\cssDoBefore\upshape}%
+ {}}%
+ \eifstrequal{\cssFontStyle}{italic}%
+ {\cssDoBefore\itshape\hspace{-0.2ex}}%
+ {\eifstrequal{\cssFontStyle}{oblique}%
+ {\cssDoBefore\slshape}%
+ {\eifstrequal{\cssFontStyle}{normal}%
+ {\cssDoBefore\upshape}%
+ {}}}%
+ \eifstrequal{\cssFontSize}{}{}% quick test
+ {\eifstrequal{\cssFontSize}{xx-small}%
+ {\cssDoBefore\tiny}%
+ {\eifstrequal{\cssFontSize}{x-small}%
+ {\cssDoBefore\scriptsize}%
+ {\eifstrequal{\cssFontSize}{small}%
+ {\cssDoBefore\small}%
+ {\eifstrequal{\cssFontSize}{medium}%
+ {\cssDoBefore\normalsize}%
+ {\eifstrequal{\cssFontSize}{large}%
+ {\cssDoBefore\large}%
+ {\eifstrequal{\cssFontSize}{x-large}%
+ {\cssDoBefore\Large}%
+ {\eifstrequal{\cssFontSize}{xx-large}%
+ {\cssDoBefore\LARGE}%
+ {}}}}}}}}%
+ %
+ \eifstrequal{\cssColor}{}{}%
+ {\strsplit{\cssColor}%
+ \eifstrequal{\strhead}{\#}%
+ {\cssDoBefore{\protect\color[HTML]{\strtail}}}%
+ {\cssDoBefore{\@robustColor{\cssColor}}}%
+ }%
+ %
+ \eifstrequal{\cssPenalty}{}{}%
+ {\penalty \cssPenalty\relax}%
+}
+
+
+
+
+%-------------------------------------------------------------
+% Generic css rules for certain classes, ids, or elements
+%-------------------------------------------------------------
+\newcommand{\cssRule}[3]{%
+ \@for\@ii:=#2\do{%
+ \csappto{@rule@#1@\@ii}{,#3}%
+ }%
+}%
+
+\newcommand{\cssRuleDo}[3]{%
+ \@for\@ii:=#2\do{%
+ \csappto{@ruleDo@#1@\@ii}{#3}%
+ }%
+}%
+
+
+\newcommand{\@cssApplyRulesFor}[3]{%
+ \@for\@ii:=#3\do{%
+ \ifcsmacro{@rule@#1@\@ii}{%
+ \edef\@args{\csname @rule@#1@\@ii\endcsname}%
+ \@expandafter{\setkeys{#2}}{\@args}%
+ }{}%
+ }%
+}
+
+\newcommand{\@cssApplyDoRulesFor}[3]{%
+ \@for\@ii:=#3\do{%
+ \ifcsmacro{@ruleDo@#1@\@ii}{%
+ \csname @ruleDo@#1@\@ii\endcsname%
+ }{}%
+ }%
+}
+
+\newcommand{\cssIfHasClass}[3]{%
+ \def\@found{}%
+ \@for\@ii:=\cssClass\do{%
+ \@for\@cname:=#1\do{%
+ \eeifstrequal{\@ii}{\@cname}{%
+ \def\@found{true}%
+ }{}%
+ }%
+ }%
+ \ifdefvoid{\@found}{#3}{#2}%
+}
+
+
+\newcommand{\cssClassRule}[2]{\cssRule{class}{#1}{#2}}
+\newcommand{\cssElemRule}[2]{\cssRule{elem}{#1}{#2}}
+\newcommand{\cssIdRule}[2]{\cssRule{id}{#1}{#2}}
+
+\cssNewListKeyX{cssx}{class}{\cssClass}{}{\@cssApplyRulesFor{class}{css}}
+\cssNewKeyX{cssx}{elem}{\cssElem}{}{\@cssApplyRulesFor{elem}{css}}
+\cssNewKeyX{cssx}{id}{\cssId}{}{\@cssApplyRulesFor{id}{css}}
+
+
+\newcommand{\cssClassRuleDo}[2]{\cssRuleDo{class}{#1}{#2}}
+\newcommand{\cssClassRuleCmd}[2]{\cssClassRuleDo{#1}{\cssWrapCmd{#2}}}
+\newcommand{\cssClassRuleDoBefore}[2]{\cssClassRuleDo{#1}{\cssDoBefore{#2}}}
+\newcommand{\cssClassRuleDoAfter}[2]{\cssClassRuleDo{#1}{\cssDoAfter{#2}}}
+\newcommand{\cssClassRuleEnv}[2]{\cssClassRuleDoBefore{#1}{\begin{#2}}\cssClassRuleDoAfter{#1}{#2}}
+
+\newcommand{\cssElemRuleDo}[2]{\cssRuleDo{class}{#1}{#2}}
+\newcommand{\cssElemRuleCmd}[2]{\cssElemRuleDo{#1}{\cssWrapCmd{#2}}}
+\newcommand{\cssElemRuleDoBefore}[2]{\cssElemRuleDo{#1}{\cssDoBefore{#2}}}
+\newcommand{\cssElemRuleDoAfter}[2]{\cssElemRuleDo{#1}{\cssDoAfter{#2}}}
+\newcommand{\cssElemRuleEnv}[2]{\cssElemRuleDo{#1}{\cssDoEnv{#2}}}
+
+\newcommand{\@cssClassDoRules}{\@cssApplyDoRulesFor{class}{css}{\cssClass}}
+\newcommand{\@cssElemDoRules}{%
+ \@cssApplyDoRulesFor{elem}{css}{\cssElem}%
+ \@cssApplyDoRulesFor{id}{css}{\cssId}%
+}
+
+\newcommand{\cssParentClass}{}
+\newcommand{\cssParentClassRule}[2]{\cssRule{parentclass}{#1}{#2}}
+
+
+%-------------------------------------------------------------
+%
+%-------------------------------------------------------------
+
+\newenvironment{cssBlockX}[2]%
+ {\@cssReset\@cssUseEnv\@cssProcessAttrs{#1}{#2}%
+ \@cssElemDoRules%
+ \@cssProcessMargins\@cssProcessPadding%
+ \@cssClassDoRules%
+ \@cssProcessText\@cssProcessFont%
+ \@cssApplyBefore}%
+ {\@cssApplyAfter}
+
+\newenvironment{cssBlock}[1][]%
+ {\begin{cssBlockX}{}{#1}}{\end{cssBlockX}}
+
+\newcommand{\cssInlineX}[4]%
+ {\@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline,#1}{#2}%
+ \@cssElemDoRules%
+ \@cssProcessMargins\@cssProcessPadding%
+ \@cssClassDoRules%
+ #3%
+ \@cssProcessText\@cssProcessFont%
+ \@cssApplyCmd{#4}%
+ }%
+
+\newcommand{\cssInline}[2][]{\cssInlineX{}{#1}{}{#2}}
+\newcommand{\cssInlineCmd}[3][]{\cssInlineX{}{#1}{\cssWrapCmd{#2}}{#3}}
+
+\newcommand{\cssNewBlockElem}[3]{%
+ \newenvironment{#1}[1][]{\begin{cssBlockX}{elem=#2,#3}{##1}}{\end{cssBlockX}}}
+
+\newcommand{\cssNewInlineElem}[3]{%
+ \newcommand{#1}[2][]{\cssInlineX{elem=#2,#3}{##1}{}{##2}}}
+
+
+\newcommand{\cssNewInlineElemCmd}[4]{%
+ \newcommand{#1}[2][]{\cssInlineX{elem=#2,#3}{##1}{\cssWrapCmd{#4}}{##2}}}
+
+\newcommand{\cssInitKeys}[1]{%
+ \@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline}{#1}%
+}
+
+% cssText is just for font attributes; no padding or margins
+\newcommand{\cssTextX}[2]%
+ {\@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline}{#1}%
+ \@cssElemDoRules%
+ %\@cssProcessMargins\@cssProcessPadding%
+ \@cssClassDoRules%
+ \@cssProcessText\@cssProcessFont%
+ \@cssApplyCmd{#2}%
+ }%
+
+
+\newcommand{\cssText}[2][]{\cssTextX{#1}{#2}}
diff --git a/Docs/DafnyRef/dafnyx.json b/Docs/DafnyRef/dafnyx.json new file mode 100644 index 00000000..be06bfa1 --- /dev/null +++ b/Docs/DafnyRef/dafnyx.json @@ -0,0 +1,4 @@ +{ "name": "dafnyx",
+ "extend": "dafny",
+ "extraKeywords": ["inductive"]
+}
\ No newline at end of file diff --git a/Docs/DafnyRef/ignores.dic b/Docs/DafnyRef/ignores.dic new file mode 100644 index 00000000..f492d28b --- /dev/null +++ b/Docs/DafnyRef/ignores.dic @@ -0,0 +1,83 @@ +Dafny +lexer +Datatypes +initializable +Multisets +multiset +multisets +disequality +maplets +maplet +datatypes +datatype +datatype's +Dafny's +destructors +nullable +subarray +indices +mixin +supertype +CLU +Async +async +Newtypes +newtype +newtype's +pre +BNF +Polikarpova +Paqui +backticks +colorizer +Daan's +Btw +Codeplex +formedness +forall +newtypes +TODO +updatable +toplevel +bodyless +bool +calc +codatatype +colemma +comethod +copredicate +nat +wildcard +Builtin +builtin +inline +NoUSIdent +iff +timeLimitMultiplier +prependAssertToken +ModuleDefinition +AssignmentRhs +LocalVariable +LetExpr +MaybeFreeExpression +attrHelp +EXE +IDE +SkippingLemma +deconstructing +Leino +Moskal +Agda +Coq +pointwise +SMT +BelowSquare +CoFixpoint +Copredicates +prepending +unrollings +Colemmas +Explies +imaps +NamedExpr +strengthed
\ No newline at end of file diff --git a/Docs/DafnyRef/krml250.bib b/Docs/DafnyRef/krml250.bib new file mode 100644 index 00000000..f30547f7 --- /dev/null +++ b/Docs/DafnyRef/krml250.bib @@ -0,0 +1,2026 @@ +@string{lncs = "LNCS"}
+
+@InCollection{Leino:Dafny:MOD2008,
+ author = {K. Rustan M. Leino},
+ title = {Specification and verification of object-oriented software},
+ booktitle = {Engineering Methods and Tools for Software Safety and Security},
+ pages = {231-266},
+ publisher = {IOS Press},
+ year = {2009},
+ editor = {Manfred Broy and Wassiou Sitou and Tony Hoare},
+ volume = {22},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ note = {Summer School Marktoberdorf 2008 lecture notes},
+}
+
+@inproceedings{Why:Platform,
+ author = {Jean-Christophe Filli{\^a}tre and Claude March{\'e}},
+ title = {The {Why}/{Krakatoa}/{Caduceus} Platform for Deductive Program Verification},
+ booktitle = {Computer Aided Verification, 19th International Conference, CAV 2007},
+ editor = {Werner Damm and Holger Hermanns},
+ volume = {4590},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2007},
+ pages = {173--177}
+}
+
+@InProceedings{BarrettTinelli:CVC3,
+ author = {Clark Barrett and Cesare Tinelli},
+ title = {{CVC3}},
+ booktitle = {Computer Aided Verification, 19th International Conference, CAV 2007},
+ editor = {Werner Damm and Holger Hermanns},
+ volume = {4590},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2007},
+ pages = {298-302},
+}
+
+@InProceedings{HubertMarche:SchorrWaite,
+ author = {Thierry Hubert and Claude March{\'e}},
+ title = {A case study of {C} source code verification: the
+ {S}chorr-{W}aite algorithm},
+ booktitle = {Third IEEE International Conference on Software
+ Engineering and Formal Methods (SEFM 2005)},
+ editor = {Bernhard K. Aichernig and Bernhard Beckert},
+ publisher = {IEEE Computer Society },
+ month = sep,
+ year = {2005},
+ pages = {190-199},
+}
+
+@Article{BroyPepper:SchorrWaite,
+ author = {Manfred Broy and Peter Pepper},
+ title = {Combining Algebraic and Algorithmic Reasoning: An
+ Approach to the {S}chorr-{W}aite Algorithm},
+ journal = toplas,
+ volume = {4},
+ number = {3},
+ month = jul,
+ year = {1982},
+ pages = {362-381},
+}
+
+@Article{MehtaNipkow:SchorrWaite,
+ author = {Farhad Mehta and Tobias Nipkow},
+ title = {Proving pointer programs in higher-order logic},
+ journal = {Information and Computation},
+ year = {2005},
+ volume = {199},
+ number = {1--2},
+ pages = {200-227},
+ month = may # "--" # jun,
+}
+
+@InProceedings{BallEtAll:ScalableChecking,
+ author = {Thomas Ball and Brian Hackett and Shuvendu K. Lahiri
+ and Shaz Qadeer and Julien Vanegue},
+ title = {Towards Scalable Modular Checking of User-Defined Properties},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ (VSTTE 2010)},
+ editor = {Gary T. Leavens and Peter O'Hearn and Sriram K. Rajamani},
+ volume = {6217},
+ series = lncs,
+ publisher = {Springer},
+ month = aug,
+ year = {2010},
+ pages = {1-24},
+}
+
+@InProceedings{RegisGianasPottier:FunctionalHoare,
+ author = {Yann R{\'e}gis-Gianas and Fran{\,c}ois Pottier},
+ title = {A {H}oare Logic for Call-by-Value Functional Programs},
+ booktitle = {Mathematics of Program Construction, 9th International Conference, MPC 2008},
+ pages = {305-335},
+ year = {2008},
+ editor = {Philippe Audebaud and Christine Paulin-Mohring},
+ volume = {5133},
+ series = lncs,
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{VeanesEtAl:SpecExplorer,
+ author = {Margus Veanes and Colin Campbell and Wolfgang
+ Grieskamp and Wolfram Schulte and Nikolai Tillmann
+ and Lev Nachmanson},
+ title = {Model-Based Testing of Object-Oriented Reactive
+ Systems with {Spec} {Explorer}},
+ booktitle = {Formal Methods and Testing},
+ pages = {39-76},
+ year = {2008},
+ editor = {Robert M. Hierons and Jonathan P. Bowen and Mark Harman},
+ volume = {4949},
+ series = lncs,
+ publisher = {Springer},
+}
+
+@book{Dijkstra:Discipline,
+ author = "Edsger W. Dijkstra",
+ title = "A Discipline of Programming",
+ publisher = "Prentice Hall",
+ address = "Englewood Cliffs, NJ",
+ year = 1976
+}
+
+@InProceedings{LeinoMueller:ESOP2009,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller},
+ title = {A Basis for Verifying Multi-threaded Programs},
+ booktitle = {Programming Languages and Systems, 18th European
+ Symposium on Programming, ESOP 2009},
+ editor = {Giuseppe Castagna},
+ volume = {5502},
+ series = lncs,
+ publisher = {Springer},
+ month = mar,
+ year = 2009,
+ pages = {378-393},
+}
+
+@InProceedings{LeinoRuemmer:Boogie2,
+ author = {K. Rustan M. Leino and Philipp R{\"u}mmer},
+ title = {A Polymorphic Intermediate Verification Language:
+ Design and Logical Encoding},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 16th International Conference,
+ TACAS 2010},
+ editor = {Javier Esparza and Rupak Majumdar},
+ series = lncs,
+ volume = 6015,
+ publisher = {Springer},
+ month = mar,
+ year = 2010,
+ pages = {312-327},
+}
+
+@book{LiskovGuttag:book,
+ author = "Barbara Liskov and John Guttag",
+ title = "Abstraction and Specification in Program Development",
+ publisher = "MIT Press",
+ series = "MIT Electrical Engineering and Computer Science Series",
+ year = 1986
+}
+
+@TechReport{DahlEtAl:Simula67,
+ author = {Ole-Johan Dahl and Bj{\o}rn Myhrhaug and Kristen Nygaard},
+ title = {Common Base Language},
+ institution = {Norwegian Computing Center},
+ type = {Publication},
+ number = {S-22},
+ month = oct,
+ year = 1970,
+}
+
+@inproceedings{LeinoMueller:ModelFields,
+ author = {K. Rustan M. Leino and
+ Peter M{\"u}ller},
+ title = {A Verification Methodology for Model Fields},
+ booktitle = "Programming Languages and Systems, 15th European Symposium on Programming, ESOP 2006",
+ editor = "Peter Sestoft",
+ series = lncs,
+ volume = 3924,
+ publisher = "Springer",
+ month = mar,
+ year = 2006,
+ pages = {115-130},
+}
+
+@InProceedings{CarterEtAl:UsingPerfectDeveloper,
+ author = {Gareth Carter and Rosemary Monahan and Joseph M. Morris},
+ title = {Software Refinement with {P}erfect {D}eveloper},
+ booktitle = {Third IEEE International Conference on Software
+ Engineering and Formal Methods (SEFM 2005)},
+ pages = {363-373},
+ editor = {Bernhard K. Aichernig and Bernhard Beckert},
+ month = sep,
+ year = {2005},
+ publisher = {IEEE Computer Society},
+}
+
+@InProceedings{Abrial:SchorrWaite,
+ author = {Jean-Raymond Abrial},
+ title = {Event Based Sequential Program Development:
+ Application to Constructing a Pointer Program},
+ booktitle = {FME 2003: Formal Methods, International Symposium of
+ Formal Methods Europe},
+ editor = {Keijiro Araki and Stefania Gnesi and Dino Mandrioli},
+ volume = {2805},
+ series = lncs,
+ publisher = {Springer},
+ month = sep,
+ year = {2003},
+ pages = {51-74},
+}
+
+@article{Barnett-etal04,
+ author = {Mike Barnett and Robert DeLine and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Wolfram Schulte},
+ title = {Verification of Object-Oriented Programs with Invariants},
+ journal = {Journal of Object Technology},
+ volume = 3,
+ number = 6,
+ year = 2004,
+ pages = {27-56},
+}
+
+@InProceedings{SmansEtAl:ImplicitDynamicFrames,
+ author = {Jan Smans and Bart Jacobs and Frank Piessens},
+ title = {Implicit Dynamic Frames: Combining Dynamic Frames
+ and Separation Logic},
+ booktitle = {ECOOP 2009 --- Object-Oriented Programming, 23rd
+ European Conference},
+ editor = {Sophia Drossopoulou},
+ volume = {5653},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2009},
+ pages = {148-172},
+}
+
+@inproceedings{GriesPrins:Encapsulation,
+ author = "David Gries and Jan Prins",
+ title = "A New Notion of Encapsulation",
+ booktitle = "Proceedings of the {ACM} {SIGPLAN} 85
+ Symposium on Language Issues in Programming Environments",
+ publisher = "ACM",
+ series = "SIGPLAN Notices 20",
+ number = 7,
+ month = jul,
+ year = 1985,
+ pages = "131-139"
+}
+
+@InProceedings{YangHawblitzel:Verve,
+ author = {Jean Yang and Chris Hawblitzel},
+ title = {Safe to the last instruction: automated verification of a type-safe operating system},
+ booktitle = {Proceedings of the 2010 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2010},
+ editor = {Benjamin G. Zorn and Alexander Aiken},
+ month = jun,
+ year = {2010},
+ publisher = {ACM},
+ pages = {99-110},
+}
+
+@Book{BoyerMoore:book,
+ author = {Robert S. Boyer and J Strother Moore},
+ title = {A Computational Logic},
+ publisher = {Academic Press},
+ series = {ACM Monograph Series},
+ year = {1979},
+}
+
+@article{HoareWirth:Pascal,
+ author = "C. A. R. Hoare and N. Wirth",
+ title = "An axiomatic definition of the programming language {PASCAL}",
+ journal = acta,
+ volume = 2,
+ number = 4,
+ year = 1973,
+ pages = "335-355"
+}
+
+@article{Hoare:AxiomaticBasis,
+ author = "C. A. R. Hoare",
+ title = "An axiomatic basis for computer programming",
+ journal = cacm,
+ volume = 12,
+ number = 10,
+ year = 1969,
+ month = oct,
+ pages = "576--580,583"
+}
+
+@InProceedings{LeinoMoskal:vacid0-notYetConfirmed,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {{VACID-0}: {V}erification of {A}mple {C}orrectness
+ of {I}nvariants of {D}ata-structures, Edition 0},
+ booktitle = {VS-Tools & Experiments},
+ year = 2010,
+ editor = {Rajeev Joshi and Tiziana Margaria and Peter
+ M{\"u}ller and David Naumann and Hongseok Yang},
+ series = {VSTTE 2010 Workshop Proceedings},
+ publisher = {ETH Zurich Technical Report 676},
+ month = aug,
+}
+
+@InCollection{Chalice:tutorial,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller and Jan Smans},
+ title = {Verification of Concurrent Programs with {C}halice},
+ booktitle = {Foundations of Security Analysis and Design {V}: {FOSAD} 2007/2008/2009 Tutorial Lectures},
+ editor = {Alessandro Aldini and Gilles Barthe and Roberto Gorrieri},
+ volume = {5705},
+ series = lncs,
+ publisher = {Springer},
+ year = {2009},
+ pages = {195-222}
+}
+
+@inproceedings{LeinoMuellerSmans10,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller and Jan Smans},
+ title = {Deadlock-Free Channels and Locks},
+ booktitle = {Programming Languages and Systems, 19th European Symposium on Programming, ESOP 2010},
+ editor = {Andrew D. Gordon},
+ volume = {6012},
+ series = lncs,
+ publisher = {Springer},
+ month = mar,
+ year = {2010},
+ pages = {407-426}
+}
+
+@Book{BundyEtAl:Rippling,
+ author = {Alan Bundy and David Basin and Dieter Hutter and Andrew Ireland},
+ title = {Rippling: Meta-level Guidance for Mathematical Reasoning},
+ publisher = {Cambridge University Press},
+ volume = {56},
+ series = {Cambridge Tracts in Theoretical Computer Science},
+ year = {2005},
+}
+
+@book{Gries:Science,
+ author = "David Gries",
+ title = "The Science of Programming",
+ publisher = "Springer-Verlag",
+ series = "Texts and Monographs in Computer Science",
+ year = 1981
+}
+
+@Book{DijkstraFeijen:Book,
+ author = "Edsger W. Dijkstra and W. H. J. Feijen",
+ title = "A Method of Programming",
+ publisher = "Addison-Wesley",
+ month = jul,
+ year = 1988,
+}
+
+@book{Kaldewaij:Programming,
+ author = "Anne Kaldewaij",
+ title = "Programming: The Derivation of Algorithms",
+ publisher = "Prentice-Hall International",
+ year = 1990,
+ series = "Series in Computer Science",
+}
+
+@InProceedings{LeinoMonahan:VSTTE2010,
+ author = {K. Rustan M. Leino and Rosemary Monahan},
+ title = {Dafny Meets the Verification Benchmarks Challenge},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ Third International Conference, VSTTE 2010},
+ pages = {112-126},
+ year = {2010},
+ editor = {Gary T. Leavens and Peter W. O'Hearn and Sriram K. Rajamani},
+ volume = {6217},
+ series = lncs,
+ month = aug,
+ publisher = {Springer},
+}
+
+@InProceedings{VSComp2010:report,
+ author = {Vladimir Klebanov and Peter M{\"u}ller and Natarajan Shankar and
+ Gary T. Leavens and Valentin W{\"u}stholz and Eyad Alkassar and
+ Rob Arthan and Derek Bronish and Rod Chapman and Ernie Cohen and
+ Mark Hillebrand and Bart Jacobs and K. Rustan M. Leino and
+ Rosemary Monahan and Frank Piessens and Nadia Polikarpova and
+ Tom Ridge and Jan Smans and Stephan Tobies and Thomas Tuerk and
+ Mattias Ulbrich and Benjamin Wei{\ss}},
+ title = {The 1st Verified Software Competition: Experience Report},
+ booktitle = {FM 2011: Formal Methods --- 17th International
+ Symposium on Formal Methods},
+ pages = {154-168},
+ year = {2011},
+ editor = {Michael Butler and Wolfram Schulte},
+ volume = {6664},
+ series = lncs,
+ month = jun,
+ publisher = {Springer},
+}
+
+@InProceedings{Leino:Dafny:LPAR16,
+ author = {K. Rustan M. Leino},
+ title = {Dafny: An Automatic Program Verifier for Functional Correctness},
+ booktitle = {LPAR-16},
+ year = {2010},
+ volume = {6355},
+ series = lncs,
+ publisher = {Springer},
+ pages = {348-370},
+}
+
+@book{BackVonWright:Book,
+ author = "Ralph-Johan Back and von Wright, Joakim",
+ title = "Refinement Calculus: A Systematic Introduction",
+ series = "Graduate Texts in Computer Science",
+ publisher = "Springer-Verlag",
+ year = 1998
+}
+
+@Article{BalzerCheathamGreen:1990s,
+ author = {Robert Balzer and {Cheatham, Jr.}, Thomas E. and Cordell Green},
+ title = {Software Technology in the 1990's: Using a New Paradigm},
+ journal = {IEEE Computer},
+ year = {1983},
+ volume = {16},
+ number = {11},
+ pages = {39-45 },
+ month = nov,
+}
+
+@InProceedings{Zloof:QBE,
+ author = {Mosh{\'e} M. Zloof},
+ title = {Query by Example},
+ booktitle = {American Federation of Information Processing
+ Societies: 1975 National Computer Conference},
+ pages = {431-438},
+ year = {1975},
+ month = may,
+ publisher = {AFIPS Press },
+}
+
+@InProceedings{HarrisGulwani:PLDI2011,
+ author = {William R. Harris and Sumit Gulwani},
+ title = {Spreadsheet table transformations from examples},
+ booktitle = {Proceedings of the 32nd ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2011},
+ pages = {317-328},
+ year = {2011},
+ editor = {Mary W. Hall and David A. Padua},
+ month = jun,
+ publisher = {ACM},
+}
+
+@Article{Smith:KIDS-overview,
+ author = "Douglas R. Smith",
+ title = "{KIDS}: A Semi-Automatic Program Development System",
+ journal = {IEEE Transactions on Software Engineering },
+ volume = 16,
+ number = 9,
+ month = sep,
+ year = 1990,
+ pages = "1024-1043",
+}
+
+@Article{RodinToolset,
+ author = {Jean-Raymond Abrial and Michael Butler and Stefan
+ Hallerstede and Thai Son Hoang and Farhad Mehta and
+ Laurent Voisin},
+ title = {Rodin: An Open Toolset for Modelling and Reasoning in {Event-B}},
+ journal = {International Journal on Software Tools for Technology Transfer},
+ year = {2010},
+ month = apr,
+}
+
+@Article{Summers:LISP-from-examples,
+ author = {Phillip D. Summers},
+ title = {A Methodology for {LISP} Program Construction from Examples},
+ journal = jacm,
+ year = {1977},
+ volume = {24},
+ number = {1},
+ pages = {161-175},
+ month = jan,
+}
+
+@InProceedings{Pex:overview,
+ author = {Nikolai Tillmann and de Halleux, Jonathan},
+ title = {Pex---White Box Test Generation for {.NET}},
+ booktitle = {Tests and Proofs, Second International Conference, TAP 2008},
+ pages = {134-153},
+ year = {2008},
+ editor = {Bernhard Beckert and Reiner H{\"a}hnle},
+ series = lncs,
+ volume = {4966},
+ month = apr,
+ publisher = {Springer},
+}
+
+@InProceedings{GodefroidKlarlundSen:DART,
+ author = {Patrice Godefroid and Nils Klarlund and Koushik Sen},
+ title = {{DART}: directed automated random testing},
+ booktitle = {Proceedings of the ACM SIGPLAN 2005 Conference on
+ Programming Language Design and Implementation},
+ pages = {213-223},
+ year = {2005},
+ editor = {Vivek Sarkar and Mary W. Hall},
+ month = jun,
+ publisher = {ACM},
+}
+
+@PhdThesis{Monahan:thesis,
+ author = {Rosemary Monahan},
+ title = {Data Refinement in Object-Oriented Verification},
+ school = {Dublin City University},
+ year = {2010},
+}
+
+@InProceedings{Denali:pldi2002,
+ author = {Rajeev Joshi and Greg Nelson and Keith H. Randall},
+ title = {Denali: A Goal-directed Superoptimizer},
+ booktitle = {Proceedings of the 2002 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation
+ (PLDI)},
+ pages = {304-314},
+ year = {2002},
+ month = jun,
+ publisher = {ACM},
+}
+@Book{SETL,
+ author = {J. T. Schwartz and R. B. K. Dewar and E. Dubinsky and E. Schonberg},
+ title = {Programming with Sets: An Introduction to {SETL}},
+ series = {Texts and Monographs in Computer Science},
+ publisher = {Springer},
+ year = {1986},
+}
+
+@InProceedings{KuncakEtAl:PLDI2010,
+ author = {Viktor Kuncak and Mika{\"e}l Mayer and Ruzica Piskac
+ and Philippe Suter},
+ title = {Complete functional synthesis},
+ booktitle = {Proceedings of the 2010 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2010},
+ pages = {316-329},
+ year = {2010},
+ editor = {Benjamin G. Zorn and Alexander Aiken},
+ month = jun,
+ publisher = {ACM},
+}
+
+@Article{JML:ToolSuite:STTT,
+ author = {Lilian Burdy and Yoonsik Cheon and David R. Cok and
+ Michael D. Ernst and Joseph R. Kiniry and Gary T. Leavens and
+ K. Rustan M. Leino and Erik Poll},
+ title = {An overview of {JML} tools and applications},
+ journal = {International Journal on Software Tools
+ for Technology Transfer},
+ volume = 7,
+ number = 3,
+ publisher = {Springer},
+ month = jun,
+ year = 2005,
+ pages = {212-232},
+}
+
+@InProceedings{Green:ProblemSolving,
+ author = {Cordell Green},
+ title = {Application of Theorem Proving to Problem Solving},
+ booktitle = {Proceedings of the 1st International Joint Conference on Artificial Intelligence},
+ editor = {Donald E. Walker and Lewis M. Norton},
+ pages = {219-240},
+ year = {1969},
+ month = may,
+ publisher = {William Kaufmann},
+}
+
+@Article{MannaWaldinger:CACM1971,
+ author = {Zohar Manna and Richard J. Waldinger},
+ title = {Towards automatic program synthesis},
+ journal = cacm,
+ year = {1971},
+ volume = {14},
+ number = {3},
+ pages = {151-165},
+ month = mar,
+}
+
+@Article{RichWaters:ProgAppren,
+ author = {Charles Rich and Richard C. Waters},
+ title = {The {P}rogrammer's {A}pprentice: A Research Overview},
+ journal = {IEEE Computer},
+ year = {1988},
+ volume = {21},
+ number = {11},
+ pages = {10-25},
+ month = nov,
+}
+
+@InProceedings{Green:PSI,
+ author = {Cordell Green},
+ title = {The Design of the {PSI} Program Synthesis System},
+ booktitle = {Proceedings of the 2nd International Conference on Software Engineering},
+ pages = {4-18},
+ year = {1976},
+ month = oct,
+ publisher = {IEEE Computer Society},
+}
+
+@Article{SpecSharp:Retrospective:CACM,
+ author = {Mike Barnett and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Peter M{\"u}ller and
+ Wolfram Schulte and Herman Venter},
+ title = {Specification and Verification: The {Spec\#} Experience},
+ journal = cacm,
+ volume = {54},
+ number = {6},
+ pages = {81-91},
+ month = jun,
+ year = 2011,
+}
+
+@article{Filipovic:SepLogicRefinement,
+ author = {Ivana Filipovi{\'c} and Peter O'Hearn and
+ Noah Torp-Smith and Hongseok Yang},
+ title = {Blaming the client: on data refinement in the presence of pointers},
+ journal = {Formal Aspects of Computing},
+ volume = {22},
+ number = {5},
+ month = sep,
+ year = {2010},
+ pages = {547-583},
+}
+
+@inproceedings{Grandy:JavaRefinement,
+ author = {Grandy, Holger and Stenzel, Kurt and Reif, Wolfgang},
+ title = {A refinement method for {J}ava programs},
+ booktitle = {Formal Methods for Open Object-Based Distributed Systems, 9th IFIP WG 6.1 International Conference, FMOODS 2007},
+ editor = {Marcello M. Bonsangue and Einar Broch Johnsen},
+ series = lncs,
+ number = {4468},
+ month = jun,
+ year = {2007},
+ publisher = {Springer},
+ pages = {221--235},
+}
+
+@InCollection{KoenigLeino:MOD2011,
+ author = {Jason Koenig and K. Rustan M. Leino},
+ title = {Getting Started with {D}afny: A Guide},
+ booktitle = {Software Safety and Security: Tools for Analysis and Verification},
+ pages = {152-181},
+ publisher = {IOS Press},
+ year = {2012},
+ editor = {Tobias Nipkow and Orna Grumberg and Benedikt Hauptmann},
+ volume = {33},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ note = {Summer School Marktoberdorf 2011 lecture notes},
+}
+
+@InProceedings{VonWright:ExtendingWindowInference,
+ author = {von Wright, Joakim},
+ title = {Extending Window Inference},
+ booktitle = {Theorem Proving in Higher Order Logics, 11th International Conference, TPHOLs'98},
+ pages = {17-32},
+ year = {1998},
+ editor = {Jim Grundy and Malcolm C. Newey},
+ volume = {1479},
+ series = lncs,
+ publisher = {Springer},
+}
+
+@InProceedings{BauerWenzel:IsarExperience,
+ author = {Gertrud Bauer and Markus Wenzel},
+ title = {Calculational reasoning revisited: an {I}sabelle/{I}sar experience},
+ booktitle = {Theorem Proving in Higher Order Logics, 14th International Conference, TPHOLs 2001},
+ pages = {75-90},
+ year = {2001},
+ editor = {Richard J. Boulton and Paul B. Jackson},
+ volume = {2152},
+ series = lncs,
+ month = sep,
+ publisher = {Springer},
+}
+
+@InProceedings{Leino:induction,
+ author = {K. Rustan M. Leino},
+ title = {Automating Induction with an {SMT} Solver},
+ booktitle = {VMCAI 2012},
+ pages = {315-331},
+ year = {2012},
+ volume = {7148},
+ series = lncs,
+ month = jan,
+ publisher = {Springer},
+}
+
+@InProceedings{LGLM:BVD,
+ author = {Le Goues, Claire and K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {The {B}oogie {V}erification {D}ebugger (Tool Paper)},
+ booktitle = {Software Engineering and Formal Methods --- 9th International Conference, SEFM 2011},
+ pages = {407-414},
+ year = {2011},
+ editor = {Gilles Barthe and Alberto Pardo and Gerardo Schneider},
+ volume = {7041},
+ series = lncs,
+ month = nov,
+ publisher = {Springer},
+}
+
+@InProceedings{Filliatre:2lines,
+ author = {Jean-Christophe Filli{\^a}tre},
+ title = {Verifying two lines of {C} with {Why3}: an exercise in
+ program verification},
+ booktitle = {Verified Software: Theories, Tools, Experiments ---
+ 4th International Conference, VSTTE 2012},
+ pages = {83-97},
+ year = {2012},
+ editor = {Rajeev Joshi and Peter M{\"u}ller and Andreas Podelski},
+ volume = {7152},
+ series = lncs,
+ month = jan,
+ publisher = {Springer},
+}
+
+@InCollection{LeinoMoskal:UsableProgramVerification,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Usable Auto-Active Verification},
+ booktitle = {UV10 (Usable Verification) workshop},
+ year = {2010},
+ editor = {Tom Ball and Lenore Zuck and N. Shankar},
+ month = nov,
+ publisher = {\url{http://fm.csl.sri.com/UV10/}},
+}
+
+@InProceedings{LeinoMonahan:Comprehensions,
+ author = {K. Rustan M. Leino and Rosemary Monahan},
+ title = {Reasoning about Comprehensions with First-Order {SMT} Solvers},
+ booktitle = {Proceedings of the 2009 ACM Symposium on Applied Computing (SAC)},
+ editor = {Sung Y. Shin and Sascha Ossowski},
+ publisher = {ACM},
+ month = mar,
+ year = 2009,
+ pages = {615-622},
+}
+
+@TechReport{VeriFast:TR,
+ author = {Bart Jacobs and Frank Piessens},
+ title = {The {VeriFast} program verifier},
+ institution = {Dept. of Computer Science, Katholieke Universiteit Leuven},
+ year = {2008},
+ number = {CW-520},
+}
+
+@book{DijkstraScholten:book,
+ author = "Edsger W. Dijkstra and Carel S. Scholten",
+ title = "Predicate Calculus and Program Semantics",
+ publisher = "Springer-Verlag",
+ series = "Texts and Monographs in Computer Science",
+ year = 1990
+}
+
+@Book{Coq:book,
+ author = {Yves Bertot and Pierre Cast{\'e}ran},
+ title = {{C}oq'{A}rt: The Calculus of Inductive Constructions},
+ publisher = {Springer},
+ year = {2004},
+ series = {Texts in Theoretical Comp. Sci.},
+}
+
+@Book{ACL2:book,
+ author = {Matt Kaufmann and Panagiotis Manolios and J Strother Moore},
+ title = {Computer-Aided Reasoning: An Approach},
+ publisher = {Kluwer Academic Publishers},
+ year = {2000},
+}
+
+@InProceedings{Coq:Coinduction,
+ author = {Eduardo Gim{\'e}nez},
+ title = {An Application of Co-inductive Types in {Coq}: Verification of the Alternating Bit Protocol},
+ booktitle = {Types for Proofs and Programs, International Workshop TYPES'95},
+ pages = {135-152},
+ year = {1996},
+ editor = {Stefano Berardi and Mario Coppo},
+ volume = 1158,
+ series = lncs,
+ publisher = {Springer},
+}
+
+@InCollection{JacobsRutten:IntroductionCoalgebra,
+ author = {Bart Jacobs and Jan Rutten},
+ title = {An Introduction to (Co)Algebra and (Co)Induction},
+ booktitle = {Advanced Topics in Bisimulation and Coinduction},
+ series = {Cambridge Tracts in Theoretical Comp. Sci.},
+ number = {52},
+ publisher = {Cambridge Univ. Press},
+ year = {2011},
+ pages = {38-99},
+}
+
+@InProceedings{SonnexEtAl:Zeno,
+ author = {William Sonnex and Sophia Drossopoulou and Susan Eisenbach},
+ title = {Zeno: An Automated Prover for Properties of Recursive
+ Data Structures},
+ booktitle = {Tools and Algorithms for the Construction and Analysis of
+ Systems --- 18th International Conference, TACAS 2012},
+ editor = {Cormac Flanagan and Barbara K{\"o}nig},
+ volume = {7214},
+ series = lncs,
+ year = {2012},
+ month = mar # "--" # apr,
+ publisher = {Springer},
+ pages = {407-421},
+}
+
+@InProceedings{JohanssonEtAl:IPT2010,
+ author = {Moa Johansson and Lucas Dixon and Alan Bundy},
+ title = {Case-Analysis for {R}ippling and Inductive Proof},
+ booktitle = {Interactive Theorem Proving, First International Conference, ITP 2010},
+ editor = {Matt Kaufmann and Lawrence C. Paulson},
+ volume = {6172},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2010},
+ pages = {291-306},
+}
+
+@Article{HatcliffEtAl:BISL,
+ author = {John Hatcliff and Gary T. Leavens and
+ K. Rustan M. Leino and Peter M{\"u}ller and Matthew Parkinson},
+ title = {Behavioral interface specification languages},
+ journal = {ACM Computing Surveys},
+ volume = {44},
+ number = {3},
+ note = {Article 16},
+ month = jun,
+ year = {2012},
+}
+
+@InProceedings{BoehmeNipkow:Sledgehammer,
+ author = {Sascha B{\"o}hme and Tobias Nipkow},
+ title = {Sledgehammer: {J}udgement {D}ay},
+ booktitle = {Automated Reasoning, 5th International Joint Conference, IJCAR 2010},
+ editor = {J{\"u}rgen Giesl and Reiner H{\"a}hnle},
+ year = {2010},
+ pages = {107-121},
+ volume = {6173},
+ series = lncs,
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{Dafny:LASER2011,
+ author = {Luke Herbert and K. Rustan M. Leino and Jose Quaresma},
+ title = {Using {Dafny}, an Automatic Program Verifier},
+ booktitle = {Tools for Practical Software Verification, {LASER}, International Summer School 2011},
+ editor = {Bertrand Meyer and Martin Nordio},
+ volume = {7682},
+ series = lncs,
+ year = {2012},
+ pages = {156-181},
+ publisher = {Springer},
+}
+
+@Article{Leroy:CompCert:CACM,
+ author = {Xavier Leroy},
+ title = {Formal verification of a realistic compiler},
+ journal = cacm,
+ volume = {52},
+ number = {7},
+ year = {2009},
+ pages = {107-115},
+}
+
+@InProceedings{Leino:ITP2013,
+ author = {K. Rustan M. Leino},
+ title = {Automating Theorem Proving with {SMT}},
+ booktitle = {ITP 2013},
+ year = {2013},
+ volume = {7998},
+ series = lncs,
+ pages = {2-16},
+ month = jul,
+ publisher = {Springer},
+}
+
+@techreport{Nelson:thesis,
+ author = "Charles Gregory Nelson",
+ title = "Techniques for Program Verification",
+ institution = "Xerox PARC",
+ month = jun,
+ year = 1981,
+ number = "CSL-81-10",
+ note = "The author's PhD thesis"
+}
+
+@InProceedings{LernerMillsteinChambers:VerifiedOptimizations,
+ author = {Sorin Lerner and Todd Millstein and Craig Chambers},
+ title = {Automatically proving the correctness of compiler optimizations},
+ booktitle = {Proceedings of the ACM SIGPLAN 2003 Conference on
+ Programming Language Design and Implementation 2003},
+ year = {2003},
+ editor = {Ron Cytron and Rajiv Gupta},
+ pages = {220-231},
+ month = jun,
+ publisher = {ACM},
+}
+
+@InProceedings{BoyerHunt:ACL2,
+ author = {Robert S. Boyer and Hunt, Jr., Warren A.},
+ title = {Function Memoization and Unique Object Representation for {ACL2} Functions},
+ booktitle = {Proceedings of the Sixth International Workshop on
+ the ACL2 Theorem Prover and its Applications, ACL2 2006},
+ editor = {Panagiotis Manolios and Matthew Wilding},
+ month = aug,
+ year = {2006},
+ pages = {81--89},
+ publisher = {ACM},
+}
+
+@inproceedings{LeinoWuestholz:DafnyIDE,
+ author = {K. Rustan M. Leino and
+ Valentin W{\"{u}}stholz},
+ title = {The {D}afny Integrated Development Environment},
+ booktitle = {Proceedings 1st Workshop on Formal Integrated Development Environment,
+ {F-IDE} 2014},
+ month = apr,
+ year = {2014},
+ pages = {3--15},
+ editor = {Catherine Dubois and
+ Dimitra Giannakopoulou and
+ Dominique M{\'{e}}ry},
+ series = {{EPTCS}},
+ volume = {149},
+}
+
+@inproceedings{BarnettLeino:Weakest,
+ author = {Mike Barnett and K. Rustan M. Leino},
+ title = {Weakest-precondition of unstructured programs},
+ booktitle = {Proceedings of the 2005 ACM SIGPLAN-SIGSOFT Workshop on
+ Program Analysis For Software Tools and Engineering,
+ PASTE'05},
+ editor = {Michael D. Ernst and Thomas P. Jensen},
+ month = sep,
+ year = {2005},
+ pages = {82-87},
+ publisher = {ACM},
+}
+
+@InProceedings{AutoProof:TACAS2015,
+ author = {Julian Tschannen and Carlo A. Furia and Martin Nordio and Nadia Polikarpova},
+ title = {{AutoProof}: Auto-Active Functional Verification of Object-Oriented Programs},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems --- 21st International Conference,
+ TACAS 2015},
+ OPTyear = {2015},
+ editor = {Christel Baier and Cesare Tinelli},
+ volume = {9035},
+ series = lncs,
+ pages = {566-580},
+ month = apr,
+ publisher = {Springer},
+}
+
+@Article{Doyle:TMS,
+ author = {Jon Doyle},
+ title = {A Truth Maintenance System},
+ journal = {Artificial Intelligence},
+ year = {1979},
+ month = nov,
+ volume = {12},
+ number = {3},
+ pages = {231-272},
+}
+
+@InProceedings{LeinoMueller:SpecSharp:Tutorial,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller},
+ title = {Using the {Spec\#} Language, Methodology, and Tools to Write Bug-Free Programs},
+ booktitle = {LASER Summer School 2007/2008},
+ editor = {Peter M{\"u}ller},
+ series = lncs,
+ volume = 6029,
+ year = 2010,
+ publisher = {Springer},
+ pages = {91-139},
+}
+
+@inproceedings{TFNP-TACAS15,
+ author = {Julian Tschannen and Carlo A. Furia and Martin Nordio and Nadia Polikarpova},
+ title = {{AutoProof}: Auto-active Functional Verification of Object-oriented Programs},
+ booktitle = {Tools and Algorithms for the Construction and Analysis of Systems --- 21st International Conference, TACAS 2015},
+ editor = {Christel Baier and Cesare Tinelli},
+ series = lncs,
+ volume = {9035},
+ month = apr,
+ year = {2015},
+ publisher = {Springer},
+ pages = {566-580},
+}
+
+@inproceedings{PTFM-FM14,
+ author = {Nadia Polikarpova and Julian Tschannen and Carlo A. Furia and Bertrand Meyer},
+ title = {Flexible Invariants Through Semantic Collaboration},
+ booktitle = {FM 2014},
+ series = lncs,
+ volume = {8442},
+ publisher = {Springer},
+ month = may,
+ year = {2014},
+ pages = {514-530}
+}
+
+@InProceedings{VeriFast:Java:tutorial,
+ author = {Jan Smans and Bart Jacobs and Frank Piessens},
+ title = {{VeriFast} for {J}ava: A Tutorial},
+ booktitle = {Aliasing in Object-Oriented Programming. Types, Analysis and Verification},
+ year = {2013},
+ editor = {Dave Clarke and James Noble and Tobias Wrigstad},
+ volume = {7850},
+ series = lncs,
+ pages = {407-442},
+ publisher = {Springer},
+}
+
+@InProceedings{Traits:ECOOP2003,
+ author = {Nathanael Sch{\"a}rli and St{\'e}phane Ducasse and Oscar Nierstrasz and Andrew P. Black},
+ title = {Traits: Composable Units of Behaviour},
+ booktitle = {ECOOP 2003 --- Object-Oriented Programming, 17th European Conference},
+ editor = {Luca Cardelli},
+ series = lncs,
+ volume = {2743},
+ pages = {248-274},
+ month = jul,
+ year = {2003},
+ publisher = {Springer},
+}
+
+@Article{Traits:logic,
+ author = {Ferruccio Damiani and Johan Dovland and Einar Broch Johnsen and Ina Schaefer},
+ title = {Verifying traits: an incremental proof system for fine-grained reuse},
+ journal = {Formal Aspects of Computing},
+ volume = {26},
+ number = {4},
+ pages = {761-793},
+ month = jul,
+ year = {2014},
+}
+
+@inproceedings{LeinoPolikarpova:calc,
+ author = {K. Rustan M. Leino and
+ Nadia Polikarpova},
+ title = {Verified Calculations},
+ booktitle = {VSTTE 2013},
+ series = lncs,
+ volume = 8164,
+ year = {2014},
+ pages = {170-190},
+ publisher = {Springer},
+}
+
+@Article{LeinoYessenov:ChaliceRefinement,
+ author = {K. Rustan M. Leino and Kuat Yessenov},
+ title = {Stepwise refinement of heap-manipulating code in {C}halice},
+ journal = {Formal Aspects of Computing},
+ year = {2012},
+ volume = {24},
+ number = {4--6},
+ pages = {519--535},
+ month = jul,
+}
+
+@article{Wirth:StepwiseRefinment,
+ author = "N. Wirth",
+ title = "{Program Development by Stepwise Refinement}",
+ journal = cacm,
+ volume = 14,
+ year = 1971,
+ pages = "221-227"
+}
+
+@article{Dijkstra:Refinement,
+ author = "E. W. Dijkstra",
+ title = "A constructive approach to the problem of program correctness",
+ journal = "BIT",
+ volume = 8,
+ year = 1968,
+ pages = "174-186"
+}
+
+@phdthesis{Back:thesis,
+ author = "R.-J. R. Back",
+ title = "On the Correctness of Refinement Steps in Program Development",
+ school = "University of Helsinki",
+ year = 1978,
+ note = "Report A-1978-4"
+}
+
+@article{Morgan:SpecStmt,
+ author = "Carroll Morgan",
+ title = "The Specification Statement",
+ journal = toplas,
+ volume = 10,
+ number = 3,
+ year = 1988,
+ month = jul,
+ pages = "403-419"
+}
+
+@book{Morgan:book,
+ author = "Carroll Morgan",
+ title = "Programming from Specifications",
+ publisher = "Prentice-Hall International",
+ series = "Series in Computer Science",
+ year = 1990
+}
+
+@article{Morris:Refinement,
+ author = "Joseph M. Morris",
+ title = "A theoretical basis for stepwise refinement and the
+ programming calculus",
+ journal = scp,
+ volume = 9,
+ number = 3,
+ month = dec,
+ year = 1987,
+ pages = "287-306"
+}
+
+@article{GriesVolpano:Transform,
+ author = "David Gries and Dennis Volpano",
+ title = "The Transform --- a New Language Construct",
+ journal = "Structured Programming",
+ volume = 11,
+ number = 1,
+ year = 1990,
+ pages = "1-10"
+}
+
+@Book{Abrial:BBook,
+ author = "J.-R. Abrial",
+ title = "The {B}-Book: Assigning Programs to Meanings",
+ publisher = "Cambridge University Press",
+ year = 1996
+}
+
+@Book{Jones:VDM:book,
+ Author = "Cliff B. Jones",
+ Title = "Systematic Software Development Using {VDM}",
+ Publisher = "Prentice Hall",
+ Series = "International Series in Computer Science",
+ Address = "Englewood Cliffs, N.J.",
+ Edition = "Second",
+ Year = 1990
+}
+
+@Book{Abrial:EventB:book,
+ author = {Jean-Raymond Abrial},
+ title = {Modeling in {Event-B}: System and Software Engineering},
+ publisher = {Cambridge University Press},
+ year = {2010},
+}
+
+@Misc{ClearSy:AtelierB,
+ author = {ClearSy},
+ title = {Atelier {B}},
+ howpublished = {\url{http://www.atelierb.eu/}},
+}
+
+@InProceedings{Abrial:FM-in-practice,
+ author = {Jean-Raymond Abrial},
+ title = {Formal methods in industry: achievements, problems, future},
+ booktitle = {28th International Conference on Software Engineering (ICSE 2006)},
+ editor = {Leon J. Osterweil and H. Dieter Rombach and Mary Lou Soffa},
+ month = may,
+ year = {2006},
+ publisher = {ACM},
+ pages = {761-768},
+}
+
+@InProceedings{MartinEtAl:AsynchMIPS,
+ author = {Alain J. Martin and Andrew Lines and Rajit Manohar
+ and Mika Nystr{\"o}m and Paul I. P{\'e}nzes and
+ Robert Southworth and Uri Cummings},
+ title = {The Design of an Asynchronous {MIPS} {R3000} Microprocessor},
+ booktitle = {17th Conference on Advanced Research in VLSI {ARVLSI '97}},
+ month = sep,
+ year = {1997},
+ publisher = {IEEE Computer Society},
+ pages = {164-181},
+}
+
+@Book{Abrial:EventB-book,
+ author = {Jean-Raymond Abrial},
+ title = {Modeling in {Event-B}: System and Software Engineering},
+ publisher = {Cambridge University Press},
+ year = {2010},
+}
+
+@Article{BackSere:ActionSystems,
+ author = {Ralph-Johan Back and Kaisa Sere},
+ title = {Stepwise Refinement of Action Systems},
+ journal = {Structured Programming},
+ year = {1991},
+ volume = {12},
+ number = {1},
+ pages = {17-30},
+}
+
+@InProceedings{VCC:overview,
+ author = {Ernie Cohen and Markus Dahlweid and Mark Hillebrand and Dirk Leinenbach and
+ Micha{\l} Moskal and Thomas Santen and Wolfram Schulte and Stephan Tobies},
+ title = {{VCC}: A Practical System for Verifying Concurrent {C}},
+ booktitle = {Theorem Proving in Higher Order Logics, 22nd International Conference, TPHOLs 2009},
+ editor = {Stefan Berghofer and Tobias Nipkow and Christian Urban and Makarius Wenzel},
+ volume = {5674},
+ series = LNCS,
+ publisher = {Springer},
+ month = aug,
+ year = {2009},
+ pages = {23-42},
+}
+
+@InProceedings{BallEtAll:ScalableChecking,
+ author = {Thomas Ball and Brian Hackett and Shuvendu K. Lahiri
+ and Shaz Qadeer and Julien Vanegue},
+ title = {Towards Scalable Modular Checking of User-Defined Properties},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ (VSTTE 2010)},
+ editor = {Gary T. Leavens and Peter O'Hearn and Sriram K. Rajamani},
+ volume = {6217},
+ series = lncs,
+ publisher = {Springer},
+ month = aug,
+ year = {2010},
+ pages = {1-24},
+}
+
+@techreport{ESC:rr,
+ author = "David L. Detlefs and K. Rustan M. Leino and Greg Nelson
+ and James B. Saxe",
+ title = "Extended static checking",
+ institution = "Compaq Systems Research Center",
+ month = dec,
+ year = 1998,
+ type = "Research Report",
+ number = 159
+}
+
+@InProceedings{VeanesEtAl:SpecExplorer,
+ author = {Margus Veanes and Colin Campbell and Wolfgang
+ Grieskamp and Wolfram Schulte and Nikolai Tillmann
+ and Lev Nachmanson},
+ title = {Model-Based Testing of Object-Oriented Reactive
+ Systems with {Spec} {Explorer}},
+ booktitle = {Formal Methods and Testing},
+ pages = {39-76},
+ year = {2008},
+ editor = {Robert M. Hierons and Jonathan P. Bowen and Mark Harman},
+ volume = {4949},
+ series = lncs,
+ publisher = {Springer},
+}
+
+@article{Hoare:DataRepresentations,
+ author = "C. A. R. Hoare",
+ title = "Proof of correctness of data representations",
+ journal = acta,
+ volume = 1,
+ number = 4,
+ year = 1972,
+ pages = "271-281"
+}
+
+@manual{baudin09acsl,
+ title = {{ACSL}: {ANSI}/{ISO} {C} Specification Language, version 1.4},
+ author = {Patrick Baudin and Jean-Christophe Filli{\^a}tre and
+ Claude March{\'e} and Benjamin Monate and Yannick
+ Moy and Virgile Prevosto},
+ year = 2009,
+ note = {\url{http://frama-c.com/}}
+}
+
+@InProceedings{BarnettEtAl:Boogie,
+ author = "Mike Barnett and Bor-Yuh Evan Chang and Robert DeLine and
+ Bart Jacobs and K. Rustan M. Leino",
+ title = "{B}oogie: A Modular Reusable Verifier for Object-Oriented Programs",
+ booktitle = "Formal Methods for Components and Objects: 4th
+ International Symposium, FMCO 2005",
+ editor = "de Boer, Frank S. and Marcello M. Bonsangue and
+ Susanne Graf and de Roever, Willem-Paul",
+ series = lncs,
+ volume = 4111,
+ publisher = "Springer",
+ month = sep,
+ year = 2006,
+ pages = "364-387"
+}
+
+@inproceedings{deMouraBjorner:Z3:overview,
+ author = "de Moura, Leonardo and Nikolaj Bj{\o}rner",
+ title = {{Z3}: An efficient {SMT} solver},
+ booktitle = {TACAS 2008},
+ series = lncs,
+ volume = 4963,
+ publisher = {Springer},
+ month = mar # "--" # apr,
+ year = 2008,
+ pages = {337-340},
+}
+
+@Article{Back-Mikhajlova-vonWright:ClassRefinement,
+ author = {Ralph-Johan Back and Anna Mikhaljova and von Wright, Joakim},
+ title = {Class Refinement as Semantics of Correct Object Substitutability},
+ journal = {Formal Aspects of Computing},
+ volume = {12},
+ number = {1},
+ year = {2000},
+ month = oct,
+ pages = {18-40},
+}
+
+@InProceedings{MikhajlovaSekerinski:ClassRefinement,
+ author = {Anna Mikhaljova and Emil Sekerinski},
+ title = {Class Refinement and Interface Refinement in Object-Oriented Programs},
+ booktitle = {FME '97: Industrial Applications and Strengthened
+ Foundations of Formal Methods, 4th International
+ Symposium of Formal Methods Europe},
+ editor = {John S. Fitzgerald and Cliff B. Jones and Peter Lucas},
+ volume = {1313 },
+ series = lncs,
+ publisher = {Springer},
+ month = sep,
+ year = {1997},
+ pages = {82-101},
+}
+
+@InProceedings{LeinoMueller:ESOP2009,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller},
+ title = {A Basis for Verifying Multi-threaded Programs},
+ booktitle = {Programming Languages and Systems, 18th European
+ Symposium on Programming, ESOP 2009},
+ editor = {Giuseppe Castagna},
+ volume = {5502},
+ series = lncs,
+ publisher = {Springer},
+ month = mar,
+ year = 2009,
+ pages = {378-393},
+}
+
+@InCollection{Chalice:tutorial,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller and Jan Smans},
+ title = {Verification of Concurrent Programs with {C}halice},
+ booktitle = {Foundations of Security Analysis and Design {V}: {FOSAD} 2007/2008/2009 Tutorial Lectures},
+ editor = {Alessandro Aldini and Gilles Barthe and Robert Gorrieri},
+ volume = {5705},
+ series = lncs,
+ publisher = {Springer},
+ year = {2009},
+ pages = {195-222},
+}
+
+@InProceedings{LeinoRuemmer:Boogie2,
+ author = {K. Rustan M. Leino and Philipp R{\"u}mmer},
+ title = {A Polymorphic Intermediate Verification Language:
+ Design and Logical Encoding},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 16th International Conference,
+ TACAS 2010},
+ editor = {Javier Esparza and Rupak Majumdar},
+ series = lncs,
+ volume = 6015,
+ publisher = {Springer},
+ month = mar,
+ year = 2010,
+ pages = {312-327},
+}
+
+@book{LiskovGuttag:book,
+ author = "Barbara Liskov and John Guttag",
+ title = "Abstraction and Specification in Program Development",
+ publisher = "MIT Press",
+ series = "MIT Electrical Engineering and Computer Science Series",
+ year = 1986
+}
+
+@TechReport{DahlEtAl:Simula67,
+ author = {Ole-Johan Dahl and Bj{\o}rn Myhrhaug and Kristen Nygaard},
+ title = {Common Base Language},
+ institution = {Norwegian Computing Center},
+ type = {Publication},
+ number = {S-22},
+ month = oct,
+ year = 1970,
+}
+
+@InProceedings{tafat10foveoos,
+ author = {Asma Tafat and Sylvain Boulm\'e and Claude March\'e},
+ title = {A Refinement Methodology for Object-Oriented Programs},
+ booktitle = {Formal Verification of Object-Oriented Software, Papers
+ Presented at the International Conference},
+ editor = {Bernhard Beckert and Claude March\'e},
+ month = jun,
+ year = 2010,
+ pages = {143--159},
+}
+
+@inproceedings{LeinoMueller:ModelFields,
+ author = {K. Rustan M. Leino and
+ Peter M{\"u}ller},
+ title = {A Verification Methodology for Model Fields},
+ booktitle = "Programming Languages and Systems, 15th European Symposium on Programming, ESOP 2006",
+ editor = "Peter Sestoft",
+ series = lncs,
+ volume = 3924,
+ publisher = "Springer",
+ month = mar,
+ year = 2006,
+ pages = {115-130},
+}
+
+@InProceedings{CarterEtAl:UsingPerfectDeveloper,
+ author = {Gareth Carter and Rosemary Monahan and Joseph M. Morris},
+ title = {Software Refinement with {P}erfect {D}eveloper},
+ booktitle = {Third IEEE International Conference on Software
+ Engineering and Formal Methods (SEFM 2005)},
+ pages = {363-373},
+ editor = {Bernhard K. Aichernig and Bernhard Beckert},
+ month = sep,
+ year = {2005},
+ publisher = {IEEE Computer Society},
+}
+
+@InProceedings{Abrial:SchorrWaite,
+ author = {Jean-Raymond Abrial},
+ title = {Event Based Sequential Program Development:
+ Application to Constructing a Pointer Program},
+ booktitle = {FME 2003: Formal Methods, International Symposium of
+ Formal Methods Europe},
+ editor = {Keijiro Araki and Stefania Gnesi and Dino Mandrioli},
+ volume = {2805},
+ series = lncs,
+ publisher = {Springer},
+ month = sep,
+ year = {2003},
+ pages = {51-74},
+}
+
+@article{Barnett-etal04,
+ author = {Mike Barnett and Robert DeLine and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Wolfram Schulte},
+ title = {Verification of Object-Oriented Programs with Invariants},
+ journal = {Journal of Object Technology},
+ volume = 3,
+ number = 6,
+ year = 2004,
+ pages = {27-56},
+}
+
+@TechReport{HatcliffEtAl:survey-tr,
+ author = {John Hatcliff and Gary T. Leavens and K. Rustan M. Leino and
+ Peter M{\"u}ller and Matthew Parkinson},
+ title = {Behavioral Interface Specification Languages},
+ institution = {University of Central Florida, School of EECS},
+ month = oct,
+ year = {2010},
+ number = {CS-TR-09-01a},
+}
+
+@Article{HatcliffEtAl:survey:journal:tentativeInfo,
+ author = {John Hatcliff and Gary T. Leavens and K. Rustan M. Leino and
+ Peter M{\"u}ller and Matthew Parkinson},
+ title = {Behavioral Interface Specification Languages},
+ journal = {ACM Computing Surveys},
+ year = {2012},
+ volume = {44},
+ number = {3},
+ month = may,
+}
+
+@inproceedings{Boyland:SAS2003,
+ author = {John Boyland},
+ title = {Checking Interference with Fractional Permissions},
+ booktitle = "Static Analysis, 10th International Symposium, SAS 2003",
+ editor = {Radhia Cousot},
+ series = lncs,
+ volume = 2694,
+ publisher = "Springer",
+ year = 2003,
+ pages = {55-72}
+}
+
+@InProceedings{SmansEtAl:ImplicitDynamicFrames,
+ author = {Jan Smans and Bart Jacobs and Frank Piessens},
+ title = {Implicit Dynamic Frames: Combining Dynamic Frames
+ and Separation Logic},
+ booktitle = {ECOOP 2009 --- Object-Oriented Programming, 23rd
+ European Conference},
+ editor = {Sophia Drossopoulou},
+ volume = {5653},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2009},
+ pages = {148-172},
+}
+
+@Misc{Escher,
+ author = "{Escher Technologies, Inc.}",
+ title = "Getting started with {P}erfect",
+ howpublished = "\url{http://www.eschertech.com}",
+ year = 2001
+}
+
+@Article{LeinoNelson:tome,
+ author = "K. Rustan M. Leino and Greg Nelson",
+ title = "Data abstraction and information hiding",
+ journal = toplas,
+ month = sep,
+ year = 2002,
+ volume = 24,
+ number = 5,
+ pages = "491-553"
+}
+
+@InProceedings{Clarke-Drossopoulou02,
+ author = {Dave Clarke and Sophia Drossopoulou},
+ title = {Ownership, encapsulation and the disjointness of
+ type and effect},
+ booktitle = {Proceedings of the 2002 ACM SIGPLAN Conference on
+ Object-Oriented Programming Systems, Languages and
+ Applications, OOPSLA 2002},
+ publisher = {ACM},
+ Month = nov,
+ Year = 2002,
+ pages = {292--310},
+}
+
+@InProceedings{Reynolds:SepLogic,
+ author = {John C. Reynolds},
+ title = {Separation Logic: A Logic for Shared Mutable Data Structures},
+ booktitle = {17th IEEE Symposium on Logic in Computer Science (LICS 2002)},
+ publisher = {IEEE Computer Society},
+ year = {2002},
+ month = jul,
+ pages = {55-74},
+}
+
+# References supplied by the reviewers.
+# Added 12/20/11.
+
+@incollection{Potet:BComposition,
+ author = {Potet, Marie and Rouzaud, Yann},
+ affiliation = {LSR-IMAG Grenoble France},
+ title = {Composition and refinement in the B-method},
+ booktitle = {B98: Recent Advances in the Development and Use of the B Method},
+ series = lncs,
+ editor = {Bert, Didier},
+ publisher = {Springer Berlin / Heidelberg},
+ isbn = {978-3-540-64405-7},
+ keyword = {Computer Science},
+ pages = {46-65},
+ volume = {1393},
+ url = {http://dx.doi.org/10.1007/BFb0053355},
+ note = {10.1007/BFb0053355},
+ year = {1998}
+}
+
+@inproceedings{Grandy:JavaRefinement,
+ author = {Grandy, Holger and Stenzel, Kurt and Reif, Wolfgang},
+ title = {A refinement method for {J}ava programs},
+ booktitle = {Formal Methods for Open Object-Based Distributed Systems, 9th IFIP WG 6.1 International Conference, FMOODS 2007},
+ editor = {Marcello M. Bonsangue and Einar Broch Johnsen},
+ series = lncs,
+ number = {4468},
+ month = jun,
+ year = {2007},
+ publisher = {Springer},
+ pages = {221--235},
+}
+
+@inproceedings{Wehrheim:Subtypes,
+ author = {Heike Wehrheim},
+ title = {Checking Behavioural Subtypes via Refinement},
+ booktitle = {FMOODS},
+ year = {2002},
+ pages = {79-93},
+ crossref = {DBLP:conf/fmoods/2002},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{Banerjee:ownership,
+ author = {Banerjee, Anindya and Naumann, David A.},
+ title = {Ownership confinement ensures representation independence for object-oriented programs},
+ journal = jacm,
+ volume = {52},
+ issue = {6},
+ month = {November},
+ year = {2005},
+ issn = {0004-5411},
+ pages = {894--960},
+ numpages = {67},
+ url = {http://doi.acm.org/10.1145/1101821.1101824},
+ doi = {http://doi.acm.org/10.1145/1101821.1101824},
+ acmid = {1101824},
+ publisher = {ACM},
+ address = {New York, NY, USA},
+ keywords = {Alias control, confinement, data refinement, relational parametricity, simulation},
+}
+
+@Article{SpecSharp:Retrospective:CACM,
+ author = {Mike Barnett and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Peter M{\"u}ller and
+ Wolfram Schulte and Herman Venter},
+ title = {Specification and Verification: The {Spec\#} Experience},
+ journal = cacm,
+ volume = {54},
+ number = {6},
+ pages = {81-91},
+ month = jun,
+ year = 2011,
+}
+
+@InProceedings{Heule:FractionsWithoutFractions,
+ author = {Stefan Heule and K. Rustan M. Leino and Peter
+ M{\"u}ller and Alexander J. Summers},
+ title = {Fractional Permissions without the Fractions},
+ booktitle = {13th Workshop on Formal Techniques for Java-like
+ Programs, FTfJP 2011},
+ year = {2011},
+ month = jul,
+}
+
+@incollection{Morgan:Capjunctive,
+ author = "Carroll Morgan",
+ title = "The Cuppest Capjunctive Capping, and {G}alois",
+ editor = "A. W. Roscoe",
+ booktitle = "A Classical Mind: Essays in Honour of C.A.R. Hoare",
+ publisher = "Prentice-Hall",
+ series = "International Series in Computer Science",
+ pages = "317-332",
+ year = 1994
+}
+
+@Article{Morgan:CompositionalNoninterference,
+ author = {Carroll Morgan},
+ title = {Compositional noninterference from first principles},
+ journal = fac,
+ year = {2012},
+ volume = {24},
+ number = {1},
+ pages = {3-26},
+}
+
+@article{DenningDenning:Certification,
+ author = "Dorothy E. Denning and Peter J. Denning",
+ title = "Certification of Programs for Secure Information Flow",
+ journal = cacm,
+ volume = 20,
+ number = 7,
+ month = jul,
+ year = 1977,
+ pages = "504-513"
+}
+
+@article{Jones:Interference,
+ author = "C. B. Jones",
+ title = "Accommodating interference in the formal design of
+ concurrent object-based programs",
+ journal = "Formal Methods in System Design",
+ volume = 8,
+ number = 2,
+ pages = "105-122",
+ month = mar,
+ year = 1996
+}
+
+@Book{Jackson:Alloy:book,
+ author = {Daniel Jackson},
+ title = {Software Abstractions: Logic, Language, and Analysis},
+ publisher = {MIT Press},
+ year = {2006},
+}
+
+@inproceedings{LeuschelButler:FME03,
+ author = {Michael Leuschel and Michael Butler},
+ title = {Pro{B}: A Model Checker for {B}},
+ booktitle = {FME 2003: Formal Methods},
+ editor = {Araki, Keijiro and Gnesi, Stefania and Mandrioli, Dino},
+ publisher = {Springer},
+ series = lncs,
+ number = {2805},
+ year = 2003,
+ pages = {855-874},
+}
+
+@InProceedings{ParkinsonBierman:POPL2005,
+ author = {Matthew J. Parkinson and Gavin M. Bierman},
+ title = {Separation logic and abstraction},
+ booktitle = {Proceedings of the 32nd ACM SIGPLAN-SIGACT Symposium
+ on Principles of Programming Languages, POPL 2005},
+ publisher = {ACM},
+ month = jan,
+ year = {2005},
+ pages = {247-258},
+}
+
+@Article{LiskovWing94,
+ author = "Barbara Liskov and Jeannette M. Wing",
+ title = "A Behavioral Notion of Subtyping",
+ journal = toplas,
+ year = 1994,
+ volume = 16,
+ number = 6
+}
+
+@book{WoodcockDavies:UsingZ,
+ title = "Using {Z}: Specification, Refinement, and Proof",
+ author = "Jim Woodcock and Jim Davies",
+ year = "1996",
+ publisher = "Prentice Hall International",
+}
+
+@Article{Leavens:ModularOOSpecs,
+ author = {Gary T. Leavens},
+ title = {Modular Specification and Verification of Object-Oriented Programs},
+ journal = {IEEE Software},
+ year = {1991},
+ volume = {8},
+ number = {4},
+ pages = {72-80},
+}
+
+@InProceedings{ShieldHayes:InvsAndDynConstraints,
+ author = {Jamie Shield and Ian J. Hayes},
+ title = {Refining Object-Oriented Invariants and Dynamic Constraints},
+ booktitle = {9th Asia-Pacific Software Engineering Conference (APSEC 2002)},
+ pages = {52-61},
+ year = {2002},
+ publisher = {IEEE Computer Society},
+}
+
+@TechReport{Chalice:predicates:TR,
+ author = {S. Heule and I. T. Kassios and P. M\"uller and A. J. Summers},
+ title = {Verification Condition Generation for Permission Logics with Abstraction Functions},
+ institution = {ETH Zurich},
+ year = {2012},
+ number = {761}
+}
+
+@InCollection{KleinEtAl:DataRefinement,
+ author = {Gerwin Klein and Thomas Sewell and Simon Winwood},
+ title = {Refinement in the formal verification of {seL4}},
+ booktitle = {Design and Verification of Microprocessor Systems for High-Assurance Applications},
+ editor = {David S. Hardin},
+ pages = {323--339},
+ month = Mar,
+ year = {2010},
+ publisher = {Springer},
+}
+
+@InProceedings{DharaLeavens:forcing,
+ author = {Krishna Kishore Dhara and Gary T. Leavens},
+ title = {Forcing Behavioral Subtyping through Specification Inheritance},
+ booktitle = {18th International Conference on Software Engineering},
+ year = {1996},
+ editor = {H. Dieter Rombach and T. S. E. Maibaum and Marvin V. Zelkowitz},
+ pages = {258-267},
+ month = mar,
+ publisher = {IEEE Computer Society},
+}
+
+@InProceedings{SpiritOfGhostCode,
+ author = {Jean-Christophe Filli{\^a}tre and L{\'e}on Gondelman and Andrei Paskevich},
+ title = {The Spirit of Ghost Code},
+ booktitle = {Computer Aided Verification --- 26th International Conference, CAV 2014},
+ year = {2014},
+ editor = {Armin Biere and Roderick Bloem},
+ series = lncs,
+ volume = {8559},
+ pages = {1-16},
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{Dafny:traits,
+ author = {Reza Ahmadi and K. Rustan M. Leino and Jyrki Nummenmaa},
+ title = {Automatic Verification of {D}afny Programs with Traits},
+ booktitle = {Formal Techniques for {J}ava-like Programs, FTfJP 2015},
+ year = {2015},
+ editor = {Rosemary Monahan},
+ publisher = {ACM},
+}
+
+@InProceedings{Dafny:Cloudmake,
+ author = {Maria Christakis and K. Rustan M. Leino and Wolfram Schulte},
+ title = {Formalizing and Verifying a Modern Build Language},
+ booktitle = {FM 2014: Formal Methods --- 19th International Symposium},
+ year = {2014},
+ editor = {Cliff B. Jones and Pekka Pihlajasaari and Jun Sun},
+ volume = {8442},
+ series = lncs,
+ pages = {643-657},
+ month = may,
+ publisher = {Springer},
+}
+
+@Misc{Leino:SPLASH2012:keynote,
+ author = {K. Rustan M. Leino},
+ title = {Staged Program Development},
+ howpublished = {SPLASH 2012 keynote},
+ note = {InfoQ video, \url{http://www.infoq.com/presentations/Staged-Program-Development}},
+ month = oct,
+ year = {2012},
+}
+
+@article{Parnas:secret,
+ author = "D. L. Parnas",
+ title = "On the criteria to be used in decomposing systems into modules",
+ journal = cacm,
+ volume = 15,
+ number = 12,
+ month = dec,
+ year = 1972,
+ pages = "1053-1058",
+ note = "Reprinted as {\tt www.acm.org/classics/may96/}"
+}
+
+@InProceedings{KIV:overview,
+ author = {Wolfgang Reif},
+ title = {The {KIV} System: Systematic Construction of Verified Software},
+ booktitle = {Automated Deduction --- CADE-11, 11th International Conference
+ on Automated Deduction},
+ editor = {Deepak Kapur},
+ series = lncs,
+ volume = {607},
+ publisher = {Springer},
+ pages = {753-757},
+ month = jun,
+ year = {1992},
+}
+
+@InProceedings{LeinoMoskal:Coinduction,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Co-induction Simply --- Automatic Co-inductive Proofs in a Program Verifier},
+ booktitle = {FM 2014},
+ series = lncs,
+ volume = {8442},
+ publisher = {Springer},
+ month = may,
+ year = {2014},
+ pages = {382-398},
+}
+
+@Article{Tarski:theorem,
+ author = "Alfred Tarski",
+ title = "A lattice-theoretical fixpoint theorem and its applications",
+ journal = "Pacific Journal of Mathematics",
+ year = 1955,
+ volume = 5,
+ pages = "285-309"
+}
+
+@TechReport{KozenSilva:Coinduction,
+ author = {Dexter Kozen and Alexandra Silva},
+ title = {Practical coinduction},
+ institution = {Comp. and Inf. Science, Cornell Univ.},
+ year = {2012},
+ number = {\url{http://hdl.handle.net/1813/30510}},
+}
+
+@book{Milner:CCS,
+ author = "Robin Milner",
+ title = {A Calculus of Communicating Systems},
+ year = {1982},
+ publisher = {Springer},
+}
+
+@Book{NipkowKlein:ConcreteSemantics,
+ author = {Tobias Nipkow and Gerwin Klein},
+ title = {Concrete Semantics with {I}sabelle/{HOL}},
+ publisher = {Springer},
+ year = {2014},
+}
+
+@Book{Pierce:SoftwareFoundations,
+ author = {Benjamin C. Pierce and Chris Casinghino and
+ Marco Gaboardi and Michael Greenberg and
+ C{\u{a}}t{\u{a}}lin Hri\c{t}cu and Vilhelm Sj{\"o}berg and
+ Brent Yorgey},
+ title = {Software Foundations},
+ publisher = {\url{http://www.cis.upenn.edu/~bcpierce/sf}},
+ year = {2015},
+ edition = {version 3.2},
+ month = jan,
+}
+
+@InProceedings{ClochardEtAl:SemanticsInWhy3,
+ author = {Martin Clochard and Jean-Christophe
+ Filli\^atre and Claude March\'e and Andrei Paskevich},
+ title = {Formalizing Semantics with an Automatic Program Verifier},
+ booktitle = {VSTTE 2014},
+ volume = {8471},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2014},
+ pages = {37--51},
+}
+
+@Article{LeroyGrall:CoinductiveBigStep,
+ author = {Xavier Leroy and Herv\'e Grall},
+ title = {Coinductive big-step operational semantics},
+ journal = {Information and Computation},
+ volume = {207},
+ number = {2},
+ pages = {284-304},
+ month = feb,
+ year = {2009},
+}
+
+@InProceedings{SwamyEtAl:Fstar2011,
+ author = {Nikhil Swamy and Juan Chen and C{\'e}dric Fournet and
+ Pierre-Yves Strub and Karthikeyan Bhargavan and Jean Yang},
+ title = {Secure distributed programming with value-dependent types},
+ booktitle = {ICFP 2011},
+ publisher = {ACM},
+ month = sep,
+ year = {2011},
+ pages = {266-278},
+}
+
+@Book{Nipkow-Paulson-Wenzel02,
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ title = {{Isabelle/HOL} --- A Proof Assistant for Higher-Order Logic},
+ publisher = {Springer},
+ year = 2002,
+ volume = 2283,
+ series = LNCS,
+}
+
+@InProceedings{BoveDybjerNorell:BriefAgda,
+ author = {Ana Bove and Peter Dybjer and Ulf Norell},
+ title = {A Brief Overview of {A}gda --- A Functional Language with Dependent Types},
+ booktitle = {TPHOLs 2009},
+ series = lncs,
+ volume = {5674},
+ publisher = {Springer},
+ month = aug,
+ year = {2009},
+ pages = {73-78},
+}
+
+@InProceedings{PaulinMohring:InductiveCoq,
+ author = {Christine Paulin-Mohring},
+ title = {Inductive Definitions in the system {C}oq --- Rules and Properties},
+ booktitle = {TLCA '93},
+ series = lncs,
+ volume = {664},
+ pages = {328-345},
+ year = {1993},
+ publisher = {Springer},
+}
+
+@TechReport{CamilleriMelham:InductiveRelations,
+ author = {Juanito Camilleri and Tom Melham},
+ title = {Reasoning with Inductively Defined Relations
+ in the {HOL} Theorem Prover},
+ institution = {University of Cambridge Computer Laboratory},
+ year = {1992},
+ number = {265},
+ OPTmonth = aug,
+}
+
+@Book{Winskel:FormalSemantics,
+ author = {Glynn Winskel},
+ title = {The Formal Semantics of Programming Languages: An Introduction},
+ publisher = {MIT Press},
+ year = {1993},
+}
+
+@inproceedings{Paulson:CADE1994,
+ author = {Lawrence C. Paulson},
+ title = {A Fixedpoint Approach to Implementing (Co)Inductive Definitions},
+ booktitle = {CADE-12},
+ editor = {Alan Bundy},
+ volume = {814},
+ series = lncs,
+ publisher = {Springer},
+ year = {1994},
+ pages = {148-161},
+}
+
+@InProceedings{Harrison:InductiveDefs,
+ author = {John Harrison},
+ title = {Inductive Definitions: Automation and Application},
+ booktitle = {TPHOLs 1995},
+ year = {1995},
+ editor = {E. Thomas Schubert and Phillip J. Windley and Jim Alves-Foss},
+ volume = {971},
+ series = lncs,
+ pages = {200-213},
+ publisher = {Springer},
+}
+
+@Article{ManoliosMoore:PartialFunctions,
+ author = {Panagiotis Manolios and J Strother Moore},
+ title = {Partial Functions in {ACL2}},
+ journal = {Journal of Automated Reasoning},
+ year = {2003},
+ volume = {31},
+ number = {2},
+ pages = {107-127},
+}
+
+@PhdThesis{Krauss:PhD,
+ author = {Alexander Krauss},
+ title = {Automating Recursive Definitions and Termination Proofs in Higher-Order Logic},
+ school = {Technische Universit{\"a}t M{\"u}nchen},
+ year = {2009},
+}
+
diff --git a/Docs/DafnyRef/madoko.css b/Docs/DafnyRef/madoko.css new file mode 100644 index 00000000..2a2d7279 --- /dev/null +++ b/Docs/DafnyRef/madoko.css @@ -0,0 +1,471 @@ +/* --------------------------------------------------- + Various settings to display madoko elements correctly. + For example, lines in tables or a table of contents. + + All rules use specific madoko classes and never just + a generic element. This means one can safely include + this CSS into any web page without affecting non-madoko + content. +----------------------------------------------------*/ + +/* The table of contents */ +.madoko .toc>.tocblock .tocblock .tocblock { + margin-left: 2.5em; +} + +.madoko .toc>.tocblock .tocblock { + margin-left: 1.7em; +} + +.madoko .toc>.tocblock>.tocitem { + font-weight: bold; +} + +.madoko .toc { + margin-top: 1em; +} + +/* Paragraphs */ +.madoko p.para-continue { + margin-bottom: 0pt; +} + +.madoko .para-block+p { + margin-top: 0pt; +} + +.madoko ul.para-block, .madoko ol.para-block { + margin-top: 0pt; + margin-bottom: 0pt; +} + +.madoko ul.para-end, .madoko ol.para-end { + margin-bottom: 1em; +} + +.madoko dl { + margin-left: 0em; +} + +.madoko blockquote { + border-left: 5px Gainsboro solid; + padding-left: 1ex; + margin-left: 1em; +} + +/* Local page links do not get an underline unless hovering */ +.madoko a.localref { + text-decoration: none; +} +.madoko a.localref:hover { + text-decoration: underline; +} + +/* Footnotes */ +.madoko .footnotes { + font-size: smaller; + margin-top: 2em; +} + +.madoko .footnotes hr { + width: 50%; + text-align: left; +} + +.madoko .footnote { + margin-left: 1em; +} +.madoko .footnote-before { + margin-left: -1em; + width: 1em; + display: inline-block; +} + +/* Alignment */ +.madoko .align-center, .madoko .align-center>p { + text-align: center !important; +} + +.madoko .align-center pre { + text-align: left; +} + +.madoko .align-center>* { + margin-left: auto !important; + margin-right: auto !important; +} + +.madoko .align-left, .madoko .align-left>p { + text-align: left !important; +} + +.madoko .align-left>* { + margin-left: 0pt !important; + margin-right: auto !important; +} + +.madoko .align-right, .madoko .align-right>p { + text-align: right !important; +} + +.madoko .align-right>* { + margin-left: auto !important; + margin-right: 0pt !important; +} + +.madoko .align-center>table, +.madoko .align-left>table, +.madoko .align-right>table { + text-align: left !important; +} + + +/* Equations, Figure's etc. */ +.madoko .equation-before { + float: right; +} + + +/* Bibliography */ +.madoko .bibitem { + font-size: smaller; +} + +.madoko .bib-numeric .bibitem { + margin-left: 3em; + text-indent: -3em; +} + +.madoko .bibitem-before { + display: none; +} + +.madoko .bib-numeric .bibitem-before { + display: inline-block; + width: 3em; + text-align: right; +} + +.madoko .bibliography { +} + +.madoko .bibsearch { + font-size: x-small; + text-decoration:none; + color: black; + font-family: "Segoe UI Symbol", Symbola; +} + +/* General */ +.madoko .block, .madoko .figure, .madoko .bibitem, .madoko .equation, .madoko div.math { + margin-top: 1ex; + margin-bottom: 1ex; +} + +.madoko .figure { + padding: 0.5em; + margin-left: 0pt; + margin-right: 0pt; +} + +.madoko .hidden { + display: none; +} + +.madoko .invisible { + visibility: hidden; +} + +.madoko.preview .invisible { + visibility: visible; + opacity: 0.5; +} + +.madoko code.code, .madoko span.code { + white-space: pre-wrap; +} + +.madoko hr, hr.madoko { + border: none; + border-bottom: black solid 1px; + margin-bottom: 0.5ex; +} + +.madoko .framed>*:first-child { + margin-top: 0pt; +} +.madoko .framed>*:last-child { + margin-bottom: 0pt; +} + + +/* Title, authors */ +.madoko .title { + font-size: xx-large; + font-weight: bold; + margin-bottom: 1ex; +} + +.madoko .subtitle { + font-size: x-large; + margin-bottom: 1ex; + margin-top: -1ex; +} + +.madoko .titleblock>* { + margin-left: auto; + margin-right: auto; + text-align: center; +} + +.madoko .titleblock table { + width: 80%; +} + +.madoko .authorblock .author { + font-size: large; +} + +.madoko .titlenote { + margin-top: -0.5ex; + margin-bottom: 1.5ex; +} + +/* Lists */ + +.madoko ul.list-star { + list-style-type: disc; +} + +.madoko ul.list-dash { + list-style-type: none !important; +} + +.madoko ul.list-dash > li:before { + content: "\2013"; + position: absolute; + margin-left: -1em; +} + +.madoko ul.list-plus { + list-style-type: square; +} + +/* Tables */ +.madoko table.madoko { + border-collapse: collapse; +} +.madoko td, .madoko th { + padding: 0ex 0.5ex; + margin: 0pt; + vertical-align: top; +} + +.madoko .cell-border-left { + border-left: 1px solid black; +} +.madoko .cell-border-right { + border-right: 1px solid black; +} + + +.madoko thead>tr:first-child>.cell-line, +.madoko tbody:first-child>tr:first-child>.cell-line { + border-top: 1px solid black; + border-bottom: none; +} + +.madoko .cell-line, .madoko .cell-double-line { + border-bottom: 1px solid black; + border-top: none; +} + +.madoko .cell-double-line { + border-top: 1px solid black; + padding-top: 1.5px !important; +} + + +/* Math Pre */ +.madoko .input-mathpre .MathJax_Display { + text-align: left !important; +} + +.madoko div.input-mathpre { + text-align: left; + margin-top: 1.5ex; + margin-bottom: 1ex; +} + +.madoko .math-rendering { + color: gray; +} + +/* Math */ +.madoko .mathdisplay { + text-align: center; +} + + +/*--------------------------------------------------------------------------- + Default style for syntax highlighting +---------------------------------------------------------------------------*/ + +.highlighted { color: black; } +.highlighted .token.identifier { } +.highlighted .token.operators { } +.highlighted .token.keyword { color: blue } +.highlighted .token.string { color: maroon } +.highlighted .token.string.escape { color: gray } +.highlighted .token.comment { color: darkgreen } +.highlighted .token.comment.doc { font-style: normal } +.highlighted .token.constant { color: purple; } +.highlighted .token.entity { } +.highlighted .token.tag { color: blue } +.highlighted .token.info-token { color: black } +.highlighted .token.warn-token { color: black } +.highlighted .token.error-token { color: darkred } +.highlighted .token.debug-token { color: gray } +.highlighted .token.regexp { color: maroon } +.highlighted .token.attribute.name { color: navy } +.highlighted .token.attribute.value { color: maroon } +.highlighted .token.constructor { color: purple } +.highlighted .token.namespace { color: navy } +.highlighted .token.header { color: navy } +.highlighted .token.type { color: teal } +.highlighted .token.type.delimiter { color: teal; } +.highlighted .token.predefined { color: navy } +.highlighted .token.invalid { border-bottom: red dotted 1px } +.highlighted .token.code { color: maroon } +.highlighted .token.code.keyword { color: navy } +.highlighted .token.typevar { font-style: italic; } + +.highlighted .token.delimiter { } /* .[curly,square,parenthesis,angle,array,bracket] */ +.highlighted .token.number { } /* .[hex,octal,binary,float] */ +.highlighted .token.variable { } /* .[name,value] */ +.highlighted .token.meta { color: navy } /* .[content] */ + +.highlighted .token.bold { font-weight: bold; } +.highlighted .token.italic { font-style: italic; } + + +/* Pretty formatting of code */ +.madoko pre.pretty, .madoko code.pretty { + font-family: Cambria,Times,Georgia,serif; + font-size: 100%; +} + +.madoko .pretty table { + border-collapse: collapse; +} +.madoko .pretty td { + padding: 0em; +} +.madoko .pretty td.empty { + min-width: 1.5ex; +} +.madoko .pretty td.expander { + width: 100em; +} +.madoko .pretty .token.identifier { font-style: italic } +.madoko .pretty .token.constructor { font-style: italic } + + +/* --------------------------------------------------- + Styling for full documents +----------------------------------------------------*/ +body.madoko, .madoko-body { + font-family: Cambria,"Times New Roman","Liberation Serif","Times",serif; + -webkit-text-size-adjust: 100%; /* so math displays well on mobile devices */ +} + +body.madoko, .madoko-body { + padding: 0em 2em; + max-width: 88ex; /* about 88 characters */ + margin: 1em auto; +} + +body.madoko.preview { + padding: 0em 1em; +} + +.madoko p, +.madoko li { + text-align: justify; +} + +/* style headings nicer, especially h5 and h6 */ +.madoko h1, .madoko h2, .madoko h3, .madoko h4 { + margin-top: 1.22em; + margin-bottom: 1ex; +} +.madoko h1+p, .madoko h2+p, .madoko h3+p, .madoko h4+p, .madoko h5+p { + margin-top: 1ex; +} +.madoko h5, .madoko h6 { + margin-top: 1ex; + font-size: 1em; +} +.madoko h5 { + margin-bottom: 0.5ex; +} +.madoko h5 + p { + margin-top: 0.5ex; +} +.madoko h6 { + margin-bottom: 0pt; +} +.madoko h6 + p { + margin-top: 0pt; +} + + +/* Fix monospace display (see http://code.stephenmorley.org/html-and-css/fixing-browsers-broken-monospace-font-handling/) */ +.madoko pre, .madoko code, .madoko kbd, .madoko samp, .madoko tt, .madoko .monospace, .madoko .token.indent, .madoko .reveal pre, .madoko .reveal code, .madoko .email { + font-family: Consolas,"Andale Mono WT","Andale Mono",Lucida Console,Monaco,monospace,monospace; + font-size: 0.85em; +} +.madoko pre code, .madoko .token.indent { + font-size: 0.95em; +} + +.madoko pre code { + font-family: inherit !important; +} + +/* Code prettify */ +.madoko ol.linenums li { + background-color: white; + list-style-type: decimal; +} + +/* Merging */ +.madoko .remote { + background-color: #F0FFF0; +} +.madoko .remote + * { + margin-top: 0pt; +} + +/* --------------------------------------------------- + Print settings +----------------------------------------------------*/ + +@media print { + body.madoko, .madoko-body { + font-size: 10pt; + } + @page { + margin: 1in 1.5in; + } +} + +/* --------------------------------------------------- + Mobile device settings +----------------------------------------------------*/ + +@media only screen and (max-device-width:1024px) { + body.madoko, .madoko-body { + padding: 0em 1em; + } +} diff --git a/Docs/DafnyRef/out/DafnyRef.html b/Docs/DafnyRef/out/DafnyRef.html new file mode 100644 index 00000000..80843e5f --- /dev/null +++ b/Docs/DafnyRef/out/DafnyRef.html @@ -0,0 +1,8287 @@ +<!DOCTYPE html> +<html lang="en-US"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <meta name="generator" content="Madoko, version 1.0.0-rc3" /> + <meta name="viewport" content="initial-scale=1.0" /> + <meta name="author" content="K. Rustan M. Leino" /> + <meta name="description" content="Leino mode: Start numbering at 0" /> + <title>Draft Dafny Reference Manual</title> + <style type="text/css" class="link"> + /*# sourceURL=madoko.css */ + + .madoko .toc>.tocblock .tocblock .tocblock { + margin-left: 2.5em; + } + .madoko .toc>.tocblock .tocblock { + margin-left: 1.7em; + } + .madoko .toc>.tocblock>.tocitem { + font-weight: bold; + } + .madoko .toc { + margin-top: 1em; + } + .madoko p.para-continue { + margin-bottom: 0pt; + } + .madoko .para-block+p { + margin-top: 0pt; + } + .madoko ul.para-block, .madoko ol.para-block { + margin-top: 0pt; + margin-bottom: 0pt; + } + .madoko ul.para-end, .madoko ol.para-end { + margin-bottom: 1em; + } + .madoko dl { + margin-left: 0em; + } + .madoko blockquote { + border-left: 5px Gainsboro solid; + padding-left: 1ex; + margin-left: 1em; + } + .madoko a.localref { + text-decoration: none; + } + .madoko a.localref:hover { + text-decoration: underline; + } + .madoko .footnotes { + font-size: smaller; + margin-top: 2em; + } + .madoko .footnotes hr { + width: 50%; + text-align: left; + } + .madoko .footnote { + margin-left: 1em; + } + .madoko .footnote-before { + margin-left: -1em; + width: 1em; + display: inline-block; + } + .madoko .align-center, .madoko .align-center>p { + text-align: center !important; + } + .madoko .align-center pre { + text-align: left; + } + .madoko .align-center>* { + margin-left: auto !important; + margin-right: auto !important; + } + .madoko .align-left, .madoko .align-left>p { + text-align: left !important; + } + .madoko .align-left>* { + margin-left: 0pt !important; + margin-right: auto !important; + } + .madoko .align-right, .madoko .align-right>p { + text-align: right !important; + } + .madoko .align-right>* { + margin-left: auto !important; + margin-right: 0pt !important; + } + .madoko .align-center>table, + .madoko .align-left>table, + .madoko .align-right>table { + text-align: left !important; + } + .madoko .equation-before { + float: right; + } + .madoko .bibitem { + font-size: smaller; + } + .madoko .bib-numeric .bibitem { + margin-left: 3em; + text-indent: -3em; + } + .madoko .bibitem-before { + display: none; + } + .madoko .bib-numeric .bibitem-before { + display: inline-block; + width: 3em; + text-align: right; + } + .madoko .bibliography { + } + .madoko .bibsearch { + font-size: x-small; + text-decoration:none; + color: black; + font-family: "Segoe UI Symbol", Symbola; + } + .madoko .block, .madoko .figure, .madoko .bibitem, .madoko .equation, .madoko div.math { + margin-top: 1ex; + margin-bottom: 1ex; + } + .madoko .figure { + padding: 0.5em; + margin-left: 0pt; + margin-right: 0pt; + } + .madoko .hidden { + display: none; + } + .madoko .invisible { + visibility: hidden; + } + .madoko.preview .invisible { + visibility: visible; + opacity: 0.5; + } + .madoko code.code, .madoko span.code { + white-space: pre-wrap; + } + .madoko hr, hr.madoko { + border: none; + border-bottom: black solid 1px; + margin-bottom: 0.5ex; + } + .madoko .framed>*:first-child { + margin-top: 0pt; + } + .madoko .framed>*:last-child { + margin-bottom: 0pt; + } + .madoko .title { + font-size: xx-large; + font-weight: bold; + margin-bottom: 1ex; + } + .madoko .subtitle { + font-size: x-large; + margin-bottom: 1ex; + margin-top: -1ex; + } + .madoko .titleblock>* { + margin-left: auto; + margin-right: auto; + text-align: center; + } + .madoko .titleblock table { + width: 80%; + } + .madoko .authorblock .author { + font-size: large; + } + .madoko .titlenote { + margin-top: -0.5ex; + margin-bottom: 1.5ex; + } + .madoko ul.list-star { + list-style-type: disc; + } + .madoko ul.list-dash { + list-style-type: none !important; + } + .madoko ul.list-dash > li:before { + content: "\2013"; + position: absolute; + margin-left: -1em; + } + .madoko ul.list-plus { + list-style-type: square; + } + .madoko table.madoko { + border-collapse: collapse; + } + .madoko td, .madoko th { + padding: 0ex 0.5ex; + margin: 0pt; + vertical-align: top; + } + .madoko .cell-border-left { + border-left: 1px solid black; + } + .madoko .cell-border-right { + border-right: 1px solid black; + } + .madoko thead>tr:first-child>.cell-line, + .madoko tbody:first-child>tr:first-child>.cell-line { + border-top: 1px solid black; + border-bottom: none; + } + .madoko .cell-line, .madoko .cell-double-line { + border-bottom: 1px solid black; + border-top: none; + } + .madoko .cell-double-line { + border-top: 1px solid black; + padding-top: 1.5px !important; + } + .madoko .input-mathpre .MathJax_Display { + text-align: left !important; + } + .madoko div.input-mathpre { + text-align: left; + margin-top: 1.5ex; + margin-bottom: 1ex; + } + .madoko .math-rendering { + color: gray; + } + .madoko .mathdisplay { + text-align: center; + } + .highlighted { color: black; } + .highlighted .token.identifier { } + .highlighted .token.operators { } + .highlighted .token.keyword { color: blue } + .highlighted .token.string { color: maroon } + .highlighted .token.string.escape { color: gray } + .highlighted .token.comment { color: darkgreen } + .highlighted .token.comment.doc { font-style: normal } + .highlighted .token.constant { color: purple; } + .highlighted .token.entity { } + .highlighted .token.tag { color: blue } + .highlighted .token.info-token { color: black } + .highlighted .token.warn-token { color: black } + .highlighted .token.error-token { color: darkred } + .highlighted .token.debug-token { color: gray } + .highlighted .token.regexp { color: maroon } + .highlighted .token.attribute.name { color: navy } + .highlighted .token.attribute.value { color: maroon } + .highlighted .token.constructor { color: purple } + .highlighted .token.namespace { color: navy } + .highlighted .token.header { color: navy } + .highlighted .token.type { color: teal } + .highlighted .token.type.delimiter { color: teal; } + .highlighted .token.predefined { color: navy } + .highlighted .token.invalid { border-bottom: red dotted 1px } + .highlighted .token.code { color: maroon } + .highlighted .token.code.keyword { color: navy } + .highlighted .token.typevar { font-style: italic; } + .highlighted .token.delimiter { } + .highlighted .token.number { } + .highlighted .token.variable { } + .highlighted .token.meta { color: navy } + .highlighted .token.bold { font-weight: bold; } + .highlighted .token.italic { font-style: italic; } + .madoko pre.pretty, .madoko code.pretty { + font-family: Cambria,Times,Georgia,serif; + font-size: 100%; + } + .madoko .pretty table { + border-collapse: collapse; + } + .madoko .pretty td { + padding: 0em; + } + .madoko .pretty td.empty { + min-width: 1.5ex; + } + .madoko .pretty td.expander { + width: 100em; + } + .madoko .pretty .token.identifier { font-style: italic } + .madoko .pretty .token.constructor { font-style: italic } + body.madoko, .madoko-body { + font-family: Cambria,"Times New Roman","Liberation Serif","Times",serif; + -webkit-text-size-adjust: 100%; + } + body.madoko, .madoko-body { + padding: 0em 2em; + max-width: 88ex; + margin: 1em auto; + } + body.madoko.preview { + padding: 0em 1em; + } + .madoko p, + .madoko li { + text-align: justify; + } + .madoko h1, .madoko h2, .madoko h3, .madoko h4 { + margin-top: 1.22em; + margin-bottom: 1ex; + } + .madoko h1+p, .madoko h2+p, .madoko h3+p, .madoko h4+p, .madoko h5+p { + margin-top: 1ex; + } + .madoko h5, .madoko h6 { + margin-top: 1ex; + font-size: 1em; + } + .madoko h5 { + margin-bottom: 0.5ex; + } + .madoko h5 + p { + margin-top: 0.5ex; + } + .madoko h6 { + margin-bottom: 0pt; + } + .madoko h6 + p { + margin-top: 0pt; + } + .madoko pre, .madoko code, .madoko kbd, .madoko samp, .madoko tt, .madoko .monospace, .madoko .token.indent, .madoko .reveal pre, .madoko .reveal code, .madoko .email { + font-family: Consolas,"Andale Mono WT","Andale Mono",Lucida Console,Monaco,monospace,monospace; + font-size: 0.85em; + } + .madoko pre code, .madoko .token.indent { + font-size: 0.95em; + } + .madoko pre code { + font-family: inherit !important; + } + .madoko ol.linenums li { + background-color: white; + list-style-type: decimal; + } + .madoko .remote { + background-color: #F0FFF0; + } + .madoko .remote + * { + margin-top: 0pt; + } + @media print { + body.madoko, .madoko-body { + font-size: 10pt; + } + @page { + margin: 1in 1.5in; + } + } + @media only screen and (max-device-width:1024px) { + body.madoko, .madoko-body { + padding: 0em 1em; + } + } + + </style> + + <style> + body { text-rendering=optimizeLegibility } + </style> + </head> +<body class="madoko"> + +<div class="body madoko" style="line-adjust:0"> +<style> +.code-escaped .comment-color { color: darkgreen } + +.token.java.string { color: black; font-weight: bold } +.token.java.type { color: black; font-weight: normal } +.token.java.operator, +.token.java.delimiter { color: blue; } +</style> + + + +<div class="mathdefs input-mathdefs"></div> +<div class="titleblock align-center para-block" style="text-align:center;line-adjust:0"> +<div class="titleheader align-center" style="text-align:center;line-adjust:0"> +<div class="title para-block" style="font-size:xx-large;font-weight:bold;margin-bottom:0.5ex;line-adjust:0">Draft Dafny Reference Manual</div> +<div class="titlenote para-block" style="line-adjust:0">Manuscript Dafny Reference<br> +2016-01-27 21:22</div></div> +<div class="authors align-center" style="text-align:center;width:80%;line-adjust:0"><table class="authorrow columns block" style="margin-top:2ex;width:100%;line-adjust:0"> +<tbody><tr><td class="author column" style="text-align:center;line-adjust:0"> +<div class="authorname" style="font-size:large;line-adjust:0">Richard L. Ford</div> +<div class="authoremail email" style="line-adjust:0">richford@microsoft.com</div></td><td class="author column" style="text-align:center;line-adjust:0"> +<div class="authorname" style="font-size:large;line-adjust:0">K. Rustan M. Leino</div> +<div class="authoremail email" style="line-adjust:0">leino@microsoft.com</div></td></tr></tbody></table></div></div> +<div class="abstract" style="margin-left:3em;margin-right:3em;font-size:small"> +<p class="p noindent"><strong class="strong-star2">Abstract.</strong> This is the Dafny reference manual which describes the Dafny programming +language and how to use the Dafny verification system. +Parts of this manual are more tutorial in nature in order to help the +user understand how to do proofs with Dafny.</p></div><span data-line=""></span> +<nav class="toc toc-contents"><h2 id="sec-contents" class="clearnum h1 heading-contents" data-heading-depth="1" style="display:block">Contents</h2> +<div class="tocblock tocblock1"> +<div class="tocitem tocitem1" data-toc-target="sec-introduction" data-toc-depth="1" data-toc-line="[0]{.heading-label}. Introduction" style="toctarget:sec-introduction"><a href="#sec-introduction" class="localref"><span class="heading-label">0</span>. Introduction</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-dafny-example" data-toc-depth="2" data-toc-line="[0.0]{.heading-label}. Dafny Example" style="toctarget:sec-dafny-example"><a href="#sec-dafny-example" class="localref"><span class="heading-label">0.0</span>. Dafny Example</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-lexical-and-low-level-grammar" data-toc-depth="1" data-toc-line="[1]{.heading-label}. Lexical and Low Level Grammar" style="toctarget:sec-lexical-and-low-level-grammar"><a href="#sec-lexical-and-low-level-grammar" class="localref"><span class="heading-label">1</span>. Lexical and Low Level Grammar</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-character-classes" data-toc-depth="2" data-toc-line="[1.0]{.heading-label}. Character Classes" style="toctarget:sec-character-classes"><a href="#sec-character-classes" class="localref"><span class="heading-label">1.0</span>. Character Classes</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-comments" data-toc-depth="3" data-toc-line="[1.0.0]{.heading-label}. Comments" style="toctarget:sec-comments"><a href="#sec-comments" class="localref"><span class="heading-label">1.0.0</span>. Comments</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-tokens" data-toc-depth="2" data-toc-line="[1.1]{.heading-label}. Tokens" style="toctarget:sec-tokens"><a href="#sec-tokens" class="localref"><span class="heading-label">1.1</span>. Tokens</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-reserved-words" data-toc-depth="3" data-toc-line="[1.1.0]{.heading-label}. Reserved Words" style="toctarget:sec-reserved-words"><a href="#sec-reserved-words" class="localref"><span class="heading-label">1.1.0</span>. Reserved Words</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-identifiers" data-toc-depth="3" data-toc-line="[1.1.1]{.heading-label}. Identifiers" style="toctarget:sec-identifiers"><a href="#sec-identifiers" class="localref"><span class="heading-label">1.1.1</span>. Identifiers</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-digits" data-toc-depth="3" data-toc-line="[1.1.2]{.heading-label}. Digits" style="toctarget:sec-digits"><a href="#sec-digits" class="localref"><span class="heading-label">1.1.2</span>. Digits</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-escaped-character" data-toc-depth="3" data-toc-line="[1.1.3]{.heading-label}. Escaped Character" style="toctarget:sec-escaped-character"><a href="#sec-escaped-character" class="localref"><span class="heading-label">1.1.3</span>. Escaped Character</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-character-constant-token" data-toc-depth="3" data-toc-line="[1.1.4]{.heading-label}. Character Constant Token" style="toctarget:sec-character-constant-token"><a href="#sec-character-constant-token" class="localref"><span class="heading-label">1.1.4</span>. Character Constant Token</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-string-constant-token" data-toc-depth="3" data-toc-line="[1.1.5]{.heading-label}. String Constant Token" style="toctarget:sec-string-constant-token"><a href="#sec-string-constant-token" class="localref"><span class="heading-label">1.1.5</span>. String Constant Token</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-low-level-grammar-productions" data-toc-depth="2" data-toc-line="[1.2]{.heading-label}. Low Level Grammar Productions" style="toctarget:sec-low-level-grammar-productions"><a href="#sec-low-level-grammar-productions" class="localref"><span class="heading-label">1.2</span>. Low Level Grammar Productions</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-identifier-variations" data-toc-depth="3" data-toc-line="[1.2.0]{.heading-label}. Identifier Variations" style="toctarget:sec-identifier-variations"><a href="#sec-identifier-variations" class="localref"><span class="heading-label">1.2.0</span>. Identifier Variations</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-nousident-synonyms" data-toc-depth="3" data-toc-line="[1.2.1]{.heading-label}. NoUSIdent Synonyms" style="toctarget:sec-nousident-synonyms"><a href="#sec-nousident-synonyms" class="localref"><span class="heading-label">1.2.1</span>. NoUSIdent Synonyms</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-qualified-names" data-toc-depth="3" data-toc-line="[1.2.2]{.heading-label}. Qualified Names" style="toctarget:sec-qualified-names"><a href="#sec-qualified-names" class="localref"><span class="heading-label">1.2.2</span>. Qualified Names</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-identifier-type-combinations" data-toc-depth="3" data-toc-line="[1.2.3]{.heading-label}. Identifier-Type Combinations" style="toctarget:sec-identifier-type-combinations"><a href="#sec-identifier-type-combinations" class="localref"><span class="heading-label">1.2.3</span>. Identifier-Type Combinations</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-numeric-literals" data-toc-depth="3" data-toc-line="[1.2.4]{.heading-label}. Numeric Literals" style="toctarget:sec-numeric-literals"><a href="#sec-numeric-literals" class="localref"><span class="heading-label">1.2.4</span>. Numeric Literals</a></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-programs" data-toc-depth="1" data-toc-line="[2]{.heading-label}. Programs" style="toctarget:sec-programs"><a href="#sec-programs" class="localref"><span class="heading-label">2</span>. Programs</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-include-directives" data-toc-depth="2" data-toc-line="[2.0]{.heading-label}. Include Directives" style="toctarget:sec-include-directives"><a href="#sec-include-directives" class="localref"><span class="heading-label">2.0</span>. Include Directives</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-top-level-declarations" data-toc-depth="2" data-toc-line="[2.1]{.heading-label}. Top Level Declarations" style="toctarget:sec-top-level-declarations"><a href="#sec-top-level-declarations" class="localref"><span class="heading-label">2.1</span>. Top Level Declarations</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-declaration-modifiers" data-toc-depth="2" data-toc-line="[2.2]{.heading-label}. Declaration Modifiers" style="toctarget:sec-declaration-modifiers"><a href="#sec-declaration-modifiers" class="localref"><span class="heading-label">2.2</span>. Declaration Modifiers</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-modules" data-toc-depth="1" data-toc-line="[3]{.heading-label}. Modules" style="toctarget:sec-modules"><a href="#sec-modules" class="localref"><span class="heading-label">3</span>. Modules</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-declaring-new-modules" data-toc-depth="2" data-toc-line="[3.0]{.heading-label}. Declaring New Modules" style="toctarget:sec-declaring-new-modules"><a href="#sec-declaring-new-modules" class="localref"><span class="heading-label">3.0</span>. Declaring New Modules</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-importing-modules" data-toc-depth="2" data-toc-line="[3.1]{.heading-label}. Importing Modules" style="toctarget:sec-importing-modules"><a href="#sec-importing-modules" class="localref"><span class="heading-label">3.1</span>. Importing Modules</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-opening-modules" data-toc-depth="2" data-toc-line="[3.2]{.heading-label}. Opening Modules" style="toctarget:sec-opening-modules"><a href="#sec-opening-modules" class="localref"><span class="heading-label">3.2</span>. Opening Modules</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-module-abstraction" data-toc-depth="2" data-toc-line="[3.3]{.heading-label}. Module Abstraction" style="toctarget:sec-module-abstraction"><a href="#sec-module-abstraction" class="localref"><span class="heading-label">3.3</span>. Module Abstraction</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-module-ordering-and-dependencies" data-toc-depth="2" data-toc-line="[3.4]{.heading-label}. Module Ordering and Dependencies" style="toctarget:sec-module-ordering-and-dependencies"><a href="#sec-module-ordering-and-dependencies" class="localref"><span class="heading-label">3.4</span>. Module Ordering and Dependencies</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-name-resolution" data-toc-depth="2" data-toc-line="[3.5]{.heading-label}. Name Resolution" style="toctarget:sec-name-resolution"><a href="#sec-name-resolution" class="localref"><span class="heading-label">3.5</span>. Name Resolution</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-expression-context-name-resolution" data-toc-depth="3" data-toc-line="[3.5.0]{.heading-label}. Expression Context Name Resolution" style="toctarget:sec-expression-context-name-resolution"><a href="#sec-expression-context-name-resolution" class="localref"><span class="heading-label">3.5.0</span>. Expression Context Name Resolution</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-type-context-name-resolution" data-toc-depth="3" data-toc-line="[3.5.1]{.heading-label}. Type Context Name Resolution" style="toctarget:sec-type-context-name-resolution"><a href="#sec-type-context-name-resolution" class="localref"><span class="heading-label">3.5.1</span>. Type Context Name Resolution</a></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-specifications" data-toc-depth="1" data-toc-line="[4]{.heading-label}. Specifications" style="toctarget:sec-specifications"><a href="#sec-specifications" class="localref"><span class="heading-label">4</span>. Specifications</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-specification-clauses" data-toc-depth="2" data-toc-line="[4.0]{.heading-label}. Specification Clauses" style="toctarget:sec-specification-clauses"><a href="#sec-specification-clauses" class="localref"><span class="heading-label">4.0</span>. Specification Clauses</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-requires-clause" data-toc-depth="3" data-toc-line="[4.0.0]{.heading-label}. Requires Clause" style="toctarget:sec-requires-clause"><a href="#sec-requires-clause" class="localref"><span class="heading-label">4.0.0</span>. Requires Clause</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-ensures-clause" data-toc-depth="3" data-toc-line="[4.0.1]{.heading-label}. Ensures Clause" style="toctarget:sec-ensures-clause"><a href="#sec-ensures-clause" class="localref"><span class="heading-label">4.0.1</span>. Ensures Clause</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-decreases-clause" data-toc-depth="3" data-toc-line="[4.0.2]{.heading-label}. Decreases Clause" style="toctarget:sec-decreases-clause"><a href="#sec-decreases-clause" class="localref"><span class="heading-label">4.0.2</span>. Decreases Clause</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-framing" data-toc-depth="3" data-toc-line="[4.0.3]{.heading-label}. Framing" style="toctarget:sec-framing"><a href="#sec-framing" class="localref"><span class="heading-label">4.0.3</span>. Framing</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-reads-clause" data-toc-depth="3" data-toc-line="[4.0.4]{.heading-label}. Reads Clause" style="toctarget:sec-reads-clause"><a href="#sec-reads-clause" class="localref"><span class="heading-label">4.0.4</span>. Reads Clause</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-modifies-clause" data-toc-depth="3" data-toc-line="[4.0.5]{.heading-label}. Modifies Clause" style="toctarget:sec-modifies-clause"><a href="#sec-modifies-clause" class="localref"><span class="heading-label">4.0.5</span>. Modifies Clause</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-invariant-clause" data-toc-depth="3" data-toc-line="[4.0.6]{.heading-label}. Invariant Clause" style="toctarget:sec-invariant-clause"><a href="#sec-invariant-clause" class="localref"><span class="heading-label">4.0.6</span>. Invariant Clause</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-method-specification" data-toc-depth="2" data-toc-line="[4.1]{.heading-label}. Method Specification" style="toctarget:sec-method-specification"><a href="#sec-method-specification" class="localref"><span class="heading-label">4.1</span>. Method Specification</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-function-specification" data-toc-depth="2" data-toc-line="[4.2]{.heading-label}. Function Specification" style="toctarget:sec-function-specification"><a href="#sec-function-specification" class="localref"><span class="heading-label">4.2</span>. Function Specification</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-lambda-specification" data-toc-depth="2" data-toc-line="[4.3]{.heading-label}. Lambda Specification" style="toctarget:sec-lambda-specification"><a href="#sec-lambda-specification" class="localref"><span class="heading-label">4.3</span>. Lambda Specification</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-iterator-specification" data-toc-depth="2" data-toc-line="[4.4]{.heading-label}. Iterator Specification" style="toctarget:sec-iterator-specification"><a href="#sec-iterator-specification" class="localref"><span class="heading-label">4.4</span>. Iterator Specification</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-loop-specification" data-toc-depth="2" data-toc-line="[4.5]{.heading-label}. Loop Specification" style="toctarget:sec-loop-specification"><a href="#sec-loop-specification" class="localref"><span class="heading-label">4.5</span>. Loop Specification</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-types" data-toc-depth="1" data-toc-line="[5]{.heading-label}. Types" style="toctarget:sec-types"><a href="#sec-types" class="localref"><span class="heading-label">5</span>. Types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-value-types" data-toc-depth="2" data-toc-line="[5.0]{.heading-label}. Value Types" style="toctarget:sec-value-types"><a href="#sec-value-types" class="localref"><span class="heading-label">5.0</span>. Value Types</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-reference-types" data-toc-depth="2" data-toc-line="[5.1]{.heading-label}. Reference Types" style="toctarget:sec-reference-types"><a href="#sec-reference-types" class="localref"><span class="heading-label">5.1</span>. Reference Types</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-named-types" data-toc-depth="2" data-toc-line="[5.2]{.heading-label}. Named Types" style="toctarget:sec-named-types"><a href="#sec-named-types" class="localref"><span class="heading-label">5.2</span>. Named Types</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-basic-types" data-toc-depth="1" data-toc-line="[6]{.heading-label}. Basic types" style="toctarget:sec-basic-types"><a href="#sec-basic-types" class="localref"><span class="heading-label">6</span>. Basic types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-booleans" data-toc-depth="2" data-toc-line="[6.0]{.heading-label}. Booleans" style="toctarget:sec-booleans"><a href="#sec-booleans" class="localref"><span class="heading-label">6.0</span>. Booleans</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-equivalence-operator" data-toc-depth="3" data-toc-line="[6.0.0]{.heading-label}. Equivalence Operator" style="toctarget:sec-equivalence-operator"><a href="#sec-equivalence-operator" class="localref"><span class="heading-label">6.0.0</span>. Equivalence Operator</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-conjunction-and-disjunction" data-toc-depth="3" data-toc-line="[6.0.1]{.heading-label}. Conjunction and Disjunction" style="toctarget:sec-conjunction-and-disjunction"><a href="#sec-conjunction-and-disjunction" class="localref"><span class="heading-label">6.0.1</span>. Conjunction and Disjunction</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-implication-and-reverse-implication" data-toc-depth="3" data-toc-line="[6.0.2]{.heading-label}. Implication and Reverse Implication" style="toctarget:sec-implication-and-reverse-implication"><a href="#sec-implication-and-reverse-implication" class="localref"><span class="heading-label">6.0.2</span>. Implication and Reverse Implication</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-numeric-types" data-toc-depth="2" data-toc-line="[6.1]{.heading-label}. Numeric types" style="toctarget:sec-numeric-types"><a href="#sec-numeric-types" class="localref"><span class="heading-label">6.1</span>. Numeric types</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-characters" data-toc-depth="2" data-toc-line="[6.2]{.heading-label}. Characters" style="toctarget:sec-characters"><a href="#sec-characters" class="localref"><span class="heading-label">6.2</span>. Characters</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-type-parameters" data-toc-depth="1" data-toc-line="[7]{.heading-label}. Type parameters" style="toctarget:sec-type-parameters"><a href="#sec-type-parameters" class="localref"><span class="heading-label">7</span>. Type parameters</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-generic-instantiation" data-toc-depth="1" data-toc-line="[8]{.heading-label}. Generic Instantiation" style="toctarget:sec-generic-instantiation"><a href="#sec-generic-instantiation" class="localref"><span class="heading-label">8</span>. Generic Instantiation</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-collection-types" data-toc-depth="1" data-toc-line="[9]{.heading-label}. Collection types" style="toctarget:sec-collection-types"><a href="#sec-collection-types" class="localref"><span class="heading-label">9</span>. Collection types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-sets" data-toc-depth="2" data-toc-line="[9.0]{.heading-label}. Sets" style="toctarget:sec-sets"><a href="#sec-sets" class="localref"><span class="heading-label">9.0</span>. Sets</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-multisets" data-toc-depth="2" data-toc-line="[9.1]{.heading-label}. Multisets" style="toctarget:sec-multisets"><a href="#sec-multisets" class="localref"><span class="heading-label">9.1</span>. Multisets</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-sequences" data-toc-depth="2" data-toc-line="[9.2]{.heading-label}. Sequences" style="toctarget:sec-sequences"><a href="#sec-sequences" class="localref"><span class="heading-label">9.2</span>. Sequences</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-sequence-displays" data-toc-depth="3" data-toc-line="[9.2.0]{.heading-label}. Sequence Displays" style="toctarget:sec-sequence-displays"><a href="#sec-sequence-displays" class="localref"><span class="heading-label">9.2.0</span>. Sequence Displays</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-sequence-relational-operators" data-toc-depth="3" data-toc-line="[9.2.1]{.heading-label}. Sequence Relational Operators" style="toctarget:sec-sequence-relational-operators"><a href="#sec-sequence-relational-operators" class="localref"><span class="heading-label">9.2.1</span>. Sequence Relational Operators</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-sequence-concatenation" data-toc-depth="3" data-toc-line="[9.2.2]{.heading-label}. Sequence Concatenation" style="toctarget:sec-sequence-concatenation"><a href="#sec-sequence-concatenation" class="localref"><span class="heading-label">9.2.2</span>. Sequence Concatenation</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-other-sequence-expressions" data-toc-depth="3" data-toc-line="[9.2.3]{.heading-label}. Other Sequence Expressions" style="toctarget:sec-other-sequence-expressions"><a href="#sec-other-sequence-expressions" class="localref"><span class="heading-label">9.2.3</span>. Other Sequence Expressions</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-strings" data-toc-depth="3" data-toc-line="[9.2.4]{.heading-label}. Strings" style="toctarget:sec-strings"><a href="#sec-strings" class="localref"><span class="heading-label">9.2.4</span>. Strings</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-finite-and-infinite-maps" data-toc-depth="2" data-toc-line="[9.3]{.heading-label}. Finite and Infinite Maps" style="toctarget:sec-finite-and-infinite-maps"><a href="#sec-finite-and-infinite-maps" class="localref"><span class="heading-label">9.3</span>. Finite and Infinite Maps</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-types-that-stand-for-other-types" data-toc-depth="1" data-toc-line="[10]{.heading-label}. Types that stand for other types" style="toctarget:sec-types-that-stand-for-other-types"><a href="#sec-types-that-stand-for-other-types" class="localref"><span class="heading-label">10</span>. Types that stand for other types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-type-synonyms" data-toc-depth="2" data-toc-line="[10.0]{.heading-label}. Type synonyms" style="toctarget:sec-type-synonyms"><a href="#sec-type-synonyms" class="localref"><span class="heading-label">10.0</span>. Type synonyms</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-opaque-types" data-toc-depth="2" data-toc-line="[10.1]{.heading-label}. Opaque types" style="toctarget:sec-opaque-types"><a href="#sec-opaque-types" class="localref"><span class="heading-label">10.1</span>. Opaque types</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-well-founded-functions-and-extreme-predicates" data-toc-depth="1" data-toc-line="[11]{.heading-label}. Well-founded Functions and Extreme Predicates" style="toctarget:sec-well-founded-functions-and-extreme-predicates"><a href="#sec-well-founded-functions-and-extreme-predicates" class="localref"><span class="heading-label">11</span>. Well-founded Functions and Extreme Predicates</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-function-definitions" data-toc-depth="2" data-toc-line="[11.0]{.heading-label}. Function Definitions" style="toctarget:sec-function-definitions"><a href="#sec-function-definitions" class="localref"><span class="heading-label">11.0</span>. Function Definitions</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-well-founded-functions" data-toc-depth="3" data-toc-line="[11.0.0]{.heading-label}. Well-founded Functions" style="toctarget:sec-well-founded-functions"><a href="#sec-well-founded-functions" class="localref"><span class="heading-label">11.0.0</span>. Well-founded Functions</a></div> +<div class="tocblock tocblock4"> +<div class="tocitem tocitem4" data-toc-target="sec-fib-example" data-toc-depth="4" data-toc-line="[11.0.0.0]{.heading-label}. Example with Well-founded Functions" style="toctarget:sec-fib-example"><a href="#sec-fib-example" class="localref"><span class="heading-label">11.0.0.0</span>. Example with Well-founded Functions</a></div></div> +<div class="tocitem tocitem3" data-toc-target="sec-extreme-solutions" data-toc-depth="3" data-toc-line="[11.0.1]{.heading-label}. Extreme Solutions" style="toctarget:sec-extreme-solutions"><a href="#sec-extreme-solutions" class="localref"><span class="heading-label">11.0.1</span>. Extreme Solutions</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-working-with-extreme-predicates" data-toc-depth="3" data-toc-line="[11.0.2]{.heading-label}. Working with Extreme Predicates" style="toctarget:sec-working-with-extreme-predicates"><a href="#sec-working-with-extreme-predicates" class="localref"><span class="heading-label">11.0.2</span>. Working with Extreme Predicates</a></div> +<div class="tocblock tocblock4"> +<div class="tocitem tocitem4" data-toc-target="sec-example-least-solution" data-toc-depth="4" data-toc-line="[11.0.2.0]{.heading-label}. Example with Least Solution" style="toctarget:sec-example-least-solution"><a href="#sec-example-least-solution" class="localref"><span class="heading-label">11.0.2.0</span>. Example with Least Solution</a></div> +<div class="tocitem tocitem4" data-toc-target="sec-example-greatest-solution" data-toc-depth="4" data-toc-line="[11.0.2.1]{.heading-label}. Example with Greatest Solution" style="toctarget:sec-example-greatest-solution"><a href="#sec-example-greatest-solution" class="localref"><span class="heading-label">11.0.2.1</span>. Example with Greatest Solution</a></div></div> +<div class="tocitem tocitem3" data-toc-target="sec-other-techniques" data-toc-depth="3" data-toc-line="[11.0.3]{.heading-label}. Other Techniques" style="toctarget:sec-other-techniques"><a href="#sec-other-techniques" class="localref"><span class="heading-label">11.0.3</span>. Other Techniques</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-functions-in-dafny" data-toc-depth="2" data-toc-line="[11.1]{.heading-label}. Functions in Dafny" style="toctarget:sec-functions-in-dafny"><a href="#sec-functions-in-dafny" class="localref"><span class="heading-label">11.1</span>. Functions in Dafny</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-well-founded-functions-in-dafny" data-toc-depth="3" data-toc-line="[11.1.0]{.heading-label}. Well-founded Functions in Dafny" style="toctarget:sec-well-founded-functions-in-dafny"><a href="#sec-well-founded-functions-in-dafny" class="localref"><span class="heading-label">11.1.0</span>. Well-founded Functions in Dafny</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-proofs-in-dafny" data-toc-depth="3" data-toc-line="[11.1.1]{.heading-label}. Proofs in Dafny" style="toctarget:sec-proofs-in-dafny"><a href="#sec-proofs-in-dafny" class="localref"><span class="heading-label">11.1.1</span>. Proofs in Dafny</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-friendliness" data-toc-depth="3" data-toc-line="[11.1.2]{.heading-label}. Extreme Predicates in Dafny" style="toctarget:sec-friendliness"><a href="#sec-friendliness" class="localref"><span class="heading-label">11.1.2</span>. Extreme Predicates in Dafny</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-proofs-about-extreme-predicates" data-toc-depth="3" data-toc-line="[11.1.3]{.heading-label}. Proofs about Extreme Predicates" style="toctarget:sec-proofs-about-extreme-predicates"><a href="#sec-proofs-about-extreme-predicates" class="localref"><span class="heading-label">11.1.3</span>. Proofs about Extreme Predicates</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-nicer-proofs-of-extreme-predicates" data-toc-depth="3" data-toc-line="[11.1.4]{.heading-label}. Nicer Proofs of Extreme Predicates" style="toctarget:sec-nicer-proofs-of-extreme-predicates"><a href="#sec-nicer-proofs-of-extreme-predicates" class="localref"><span class="heading-label">11.1.4</span>. Nicer Proofs of Extreme Predicates</a></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-class-types" data-toc-depth="1" data-toc-line="[12]{.heading-label}. Class Types" style="toctarget:sec-class-types"><a href="#sec-class-types" class="localref"><span class="heading-label">12</span>. Class Types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-field-declarations" data-toc-depth="2" data-toc-line="[12.0]{.heading-label}. Field Declarations" style="toctarget:sec-field-declarations"><a href="#sec-field-declarations" class="localref"><span class="heading-label">12.0</span>. Field Declarations</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-method-declarations" data-toc-depth="2" data-toc-line="[12.1]{.heading-label}. Method Declarations" style="toctarget:sec-method-declarations"><a href="#sec-method-declarations" class="localref"><span class="heading-label">12.1</span>. Method Declarations</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-constructors" data-toc-depth="3" data-toc-line="[12.1.0]{.heading-label}. Constructors" style="toctarget:sec-constructors"><a href="#sec-constructors" class="localref"><span class="heading-label">12.1.0</span>. Constructors</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-lemmas" data-toc-depth="3" data-toc-line="[12.1.1]{.heading-label}. Lemmas" style="toctarget:sec-lemmas"><a href="#sec-lemmas" class="localref"><span class="heading-label">12.1.1</span>. Lemmas</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-function-declarations" data-toc-depth="2" data-toc-line="[12.2]{.heading-label}. Function Declarations" style="toctarget:sec-function-declarations"><a href="#sec-function-declarations" class="localref"><span class="heading-label">12.2</span>. Function Declarations</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-function-transparency" data-toc-depth="3" data-toc-line="[12.2.0]{.heading-label}. Function Transparency" style="toctarget:sec-function-transparency"><a href="#sec-function-transparency" class="localref"><span class="heading-label">12.2.0</span>. Function Transparency</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-predicates" data-toc-depth="3" data-toc-line="[12.2.1]{.heading-label}. Predicates" style="toctarget:sec-predicates"><a href="#sec-predicates" class="localref"><span class="heading-label">12.2.1</span>. Predicates</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-inductive-predicates-and-lemmas" data-toc-depth="3" data-toc-line="[12.2.2]{.heading-label}. Inductive Predicates and Lemmas" style="toctarget:sec-inductive-predicates-and-lemmas"><a href="#sec-inductive-predicates-and-lemmas" class="localref"><span class="heading-label">12.2.2</span>. Inductive Predicates and Lemmas</a></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-trait-types" data-toc-depth="1" data-toc-line="[13]{.heading-label}. Trait Types" style="toctarget:sec-trait-types"><a href="#sec-trait-types" class="localref"><span class="heading-label">13</span>. Trait Types</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-array-types" data-toc-depth="1" data-toc-line="[14]{.heading-label}. Array Types" style="toctarget:sec-array-types"><a href="#sec-array-types" class="localref"><span class="heading-label">14</span>. Array Types</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-one-dimensional-arrays" data-toc-depth="2" data-toc-line="[14.0]{.heading-label}. One-dimensional arrays" style="toctarget:sec-one-dimensional-arrays"><a href="#sec-one-dimensional-arrays" class="localref"><span class="heading-label">14.0</span>. One-dimensional arrays</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-multi-dimensional-arrays" data-toc-depth="2" data-toc-line="[14.1]{.heading-label}. Multi-dimensional arrays" style="toctarget:sec-multi-dimensional-arrays"><a href="#sec-multi-dimensional-arrays" class="localref"><span class="heading-label">14.1</span>. Multi-dimensional arrays</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-type-object" data-toc-depth="1" data-toc-line="[15]{.heading-label}. Type object" style="toctarget:sec-type-object"><a href="#sec-type-object" class="localref"><span class="heading-label">15</span>. Type object</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-iterator-types" data-toc-depth="1" data-toc-line="[16]{.heading-label}. Iterator types" style="toctarget:sec-iterator-types"><a href="#sec-iterator-types" class="localref"><span class="heading-label">16</span>. Iterator types</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-function-types" data-toc-depth="1" data-toc-line="[17]{.heading-label}. Function types" style="toctarget:sec-function-types"><a href="#sec-function-types" class="localref"><span class="heading-label">17</span>. Function types</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-algebraic-datatypes" data-toc-depth="1" data-toc-line="[18]{.heading-label}. Algebraic Datatypes" style="toctarget:sec-algebraic-datatypes"><a href="#sec-algebraic-datatypes" class="localref"><span class="heading-label">18</span>. Algebraic Datatypes</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-inductive-datatypes" data-toc-depth="2" data-toc-line="[18.0]{.heading-label}. Inductive datatypes" style="toctarget:sec-inductive-datatypes"><a href="#sec-inductive-datatypes" class="localref"><span class="heading-label">18.0</span>. Inductive datatypes</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-tuple-types" data-toc-depth="2" data-toc-line="[18.1]{.heading-label}. Tuple types" style="toctarget:sec-tuple-types"><a href="#sec-tuple-types" class="localref"><span class="heading-label">18.1</span>. Tuple types</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-co-inductive-datatypes" data-toc-depth="2" data-toc-line="[18.2]{.heading-label}. Co-inductive datatypes" style="toctarget:sec-co-inductive-datatypes"><a href="#sec-co-inductive-datatypes" class="localref"><span class="heading-label">18.2</span>. Co-inductive datatypes</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-well-founded-functionmethod-definitions" data-toc-depth="3" data-toc-line="[18.2.0]{.heading-label}. Well-Founded Function/Method Definitions" style="toctarget:sec-well-founded-functionmethod-definitions"><a href="#sec-well-founded-functionmethod-definitions" class="localref"><span class="heading-label">18.2.0</span>. Well-Founded Function/Method Definitions</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-defining-co-inductive-datatypes" data-toc-depth="3" data-toc-line="[18.2.1]{.heading-label}. Defining Co-inductive Datatypes" style="toctarget:sec-defining-co-inductive-datatypes"><a href="#sec-defining-co-inductive-datatypes" class="localref"><span class="heading-label">18.2.1</span>. Defining Co-inductive Datatypes</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-creating-values-of-co-datatypes" data-toc-depth="3" data-toc-line="[18.2.2]{.heading-label}. Creating Values of Co-datatypes" style="toctarget:sec-creating-values-of-co-datatypes"><a href="#sec-creating-values-of-co-datatypes" class="localref"><span class="heading-label">18.2.2</span>. Creating Values of Co-datatypes</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-copredicates" data-toc-depth="3" data-toc-line="[18.2.3]{.heading-label}. Copredicates" style="toctarget:sec-copredicates"><a href="#sec-copredicates" class="localref"><span class="heading-label">18.2.3</span>. Copredicates</a></div> +<div class="tocblock tocblock4"> +<div class="tocitem tocitem4" data-toc-target="sec-co-equality" data-toc-depth="4" data-toc-line="[18.2.3.0]{.heading-label}. Co-Equality" style="toctarget:sec-co-equality"><a href="#sec-co-equality" class="localref"><span class="heading-label">18.2.3.0</span>. Co-Equality</a></div></div> +<div class="tocitem tocitem3" data-toc-target="sec-co-inductive-proofs" data-toc-depth="3" data-toc-line="[18.2.4]{.heading-label}. Co-inductive Proofs" style="toctarget:sec-co-inductive-proofs"><a href="#sec-co-inductive-proofs" class="localref"><span class="heading-label">18.2.4</span>. Co-inductive Proofs</a></div> +<div class="tocblock tocblock4"> +<div class="tocitem tocitem4" data-toc-target="sec-properties-about-prefix-predicates" data-toc-depth="4" data-toc-line="[18.2.4.0]{.heading-label}. Properties About Prefix Predicates" style="toctarget:sec-properties-about-prefix-predicates"><a href="#sec-properties-about-prefix-predicates" class="localref"><span class="heading-label">18.2.4.0</span>. Properties About Prefix Predicates</a></div> +<div class="tocitem tocitem4" data-toc-target="sec-colemmas" data-toc-depth="4" data-toc-line="[18.2.4.1]{.heading-label}. Colemmas" style="toctarget:sec-colemmas"><a href="#sec-colemmas" class="localref"><span class="heading-label">18.2.4.1</span>. Colemmas</a></div> +<div class="tocitem tocitem4" data-toc-target="sec-prefix-lemmas" data-toc-depth="4" data-toc-line="[18.2.4.2]{.heading-label}. Prefix Lemmas" style="toctarget:sec-prefix-lemmas"><a href="#sec-prefix-lemmas" class="localref"><span class="heading-label">18.2.4.2</span>. Prefix Lemmas</a></div></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-newtypes" data-toc-depth="1" data-toc-line="[19]{.heading-label}. Newtypes" style="toctarget:sec-newtypes"><a href="#sec-newtypes" class="localref"><span class="heading-label">19</span>. Newtypes</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-numeric-conversion-operations" data-toc-depth="2" data-toc-line="[19.0]{.heading-label}. Numeric conversion operations" style="toctarget:sec-numeric-conversion-operations"><a href="#sec-numeric-conversion-operations" class="localref"><span class="heading-label">19.0</span>. Numeric conversion operations</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-subset-types" data-toc-depth="1" data-toc-line="[20]{.heading-label}. Subset types" style="toctarget:sec-subset-types"><a href="#sec-subset-types" class="localref"><span class="heading-label">20</span>. Subset types</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-statements" data-toc-depth="1" data-toc-line="[21]{.heading-label}. Statements" style="toctarget:sec-statements"><a href="#sec-statements" class="localref"><span class="heading-label">21</span>. Statements</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-labeled-statement" data-toc-depth="2" data-toc-line="[21.0]{.heading-label}. Labeled Statement" style="toctarget:sec-labeled-statement"><a href="#sec-labeled-statement" class="localref"><span class="heading-label">21.0</span>. Labeled Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-break-statement" data-toc-depth="2" data-toc-line="[21.1]{.heading-label}. Break Statement" style="toctarget:sec-break-statement"><a href="#sec-break-statement" class="localref"><span class="heading-label">21.1</span>. Break Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-block-statement" data-toc-depth="2" data-toc-line="[21.2]{.heading-label}. Block Statement" style="toctarget:sec-block-statement"><a href="#sec-block-statement" class="localref"><span class="heading-label">21.2</span>. Block Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-return-statement" data-toc-depth="2" data-toc-line="[21.3]{.heading-label}. Return Statement" style="toctarget:sec-return-statement"><a href="#sec-return-statement" class="localref"><span class="heading-label">21.3</span>. Return Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-yield-statement" data-toc-depth="2" data-toc-line="[21.4]{.heading-label}. Yield Statement" style="toctarget:sec-yield-statement"><a href="#sec-yield-statement" class="localref"><span class="heading-label">21.4</span>. Yield Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-update-statement" data-toc-depth="2" data-toc-line="[21.5]{.heading-label}. Update Statement" style="toctarget:sec-update-statement"><a href="#sec-update-statement" class="localref"><span class="heading-label">21.5</span>. Update Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-variable-declaration-statement" data-toc-depth="2" data-toc-line="[21.6]{.heading-label}. Variable Declaration Statement" style="toctarget:sec-variable-declaration-statement"><a href="#sec-variable-declaration-statement" class="localref"><span class="heading-label">21.6</span>. Variable Declaration Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-guards" data-toc-depth="2" data-toc-line="[21.7]{.heading-label}. Guards" style="toctarget:sec-guards"><a href="#sec-guards" class="localref"><span class="heading-label">21.7</span>. Guards</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-binding-guards" data-toc-depth="2" data-toc-line="[21.8]{.heading-label}. Binding Guards" style="toctarget:sec-binding-guards"><a href="#sec-binding-guards" class="localref"><span class="heading-label">21.8</span>. Binding Guards</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-if-statement" data-toc-depth="2" data-toc-line="[21.9]{.heading-label}. If Statement" style="toctarget:sec-if-statement"><a href="#sec-if-statement" class="localref"><span class="heading-label">21.9</span>. If Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-while-statement" data-toc-depth="2" data-toc-line="[21.10]{.heading-label}. While Statement" style="toctarget:sec-while-statement"><a href="#sec-while-statement" class="localref"><span class="heading-label">21.10</span>. While Statement</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-loop-specifications" data-toc-depth="3" data-toc-line="[21.10.0]{.heading-label}. Loop Specifications" style="toctarget:sec-loop-specifications"><a href="#sec-loop-specifications" class="localref"><span class="heading-label">21.10.0</span>. Loop Specifications</a></div> +<div class="tocblock tocblock4"> +<div class="tocitem tocitem4" data-toc-target="sec-loop-invariants" data-toc-depth="4" data-toc-line="[21.10.0.0]{.heading-label}. Loop Invariants" style="toctarget:sec-loop-invariants"><a href="#sec-loop-invariants" class="localref"><span class="heading-label">21.10.0.0</span>. Loop Invariants</a></div> +<div class="tocitem tocitem4" data-toc-target="sec-loop-termination" data-toc-depth="4" data-toc-line="[21.10.0.1]{.heading-label}. Loop Termination" style="toctarget:sec-loop-termination"><a href="#sec-loop-termination" class="localref"><span class="heading-label">21.10.0.1</span>. Loop Termination</a></div> +<div class="tocitem tocitem4" data-toc-target="sec-loop-framing" data-toc-depth="4" data-toc-line="[21.10.0.2]{.heading-label}. Loop Framing" style="toctarget:sec-loop-framing"><a href="#sec-loop-framing" class="localref"><span class="heading-label">21.10.0.2</span>. Loop Framing</a></div></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-match-statement" data-toc-depth="2" data-toc-line="[21.11]{.heading-label}. Match Statement" style="toctarget:sec-match-statement"><a href="#sec-match-statement" class="localref"><span class="heading-label">21.11</span>. Match Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-assert-statement" data-toc-depth="2" data-toc-line="[21.12]{.heading-label}. Assert Statement" style="toctarget:sec-assert-statement"><a href="#sec-assert-statement" class="localref"><span class="heading-label">21.12</span>. Assert Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-assume-statement" data-toc-depth="2" data-toc-line="[21.13]{.heading-label}. Assume Statement" style="toctarget:sec-assume-statement"><a href="#sec-assume-statement" class="localref"><span class="heading-label">21.13</span>. Assume Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-print-statement" data-toc-depth="2" data-toc-line="[21.14]{.heading-label}. Print Statement" style="toctarget:sec-print-statement"><a href="#sec-print-statement" class="localref"><span class="heading-label">21.14</span>. Print Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-forall-statement" data-toc-depth="2" data-toc-line="[21.15]{.heading-label}. Forall Statement" style="toctarget:sec-forall-statement"><a href="#sec-forall-statement" class="localref"><span class="heading-label">21.15</span>. Forall Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-modify-statement" data-toc-depth="2" data-toc-line="[21.16]{.heading-label}. Modify Statement" style="toctarget:sec-modify-statement"><a href="#sec-modify-statement" class="localref"><span class="heading-label">21.16</span>. Modify Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-calc-statement" data-toc-depth="2" data-toc-line="[21.17]{.heading-label}. Calc Statement" style="toctarget:sec-calc-statement"><a href="#sec-calc-statement" class="localref"><span class="heading-label">21.17</span>. Calc Statement</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-skeleton-statement" data-toc-depth="2" data-toc-line="[21.18]{.heading-label}. Skeleton Statement" style="toctarget:sec-skeleton-statement"><a href="#sec-skeleton-statement" class="localref"><span class="heading-label">21.18</span>. Skeleton Statement</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-expressions" data-toc-depth="1" data-toc-line="[22]{.heading-label}. Expressions" style="toctarget:sec-expressions"><a href="#sec-expressions" class="localref"><span class="heading-label">22</span>. Expressions</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-top-level-expressions" data-toc-depth="2" data-toc-line="[22.0]{.heading-label}. Top-level expressions" style="toctarget:sec-top-level-expressions"><a href="#sec-top-level-expressions" class="localref"><span class="heading-label">22.0</span>. Top-level expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-equivalence-expressions" data-toc-depth="2" data-toc-line="[22.1]{.heading-label}. Equivalence Expressions" style="toctarget:sec-equivalence-expressions"><a href="#sec-equivalence-expressions" class="localref"><span class="heading-label">22.1</span>. Equivalence Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-implies-or-explies-expressions" data-toc-depth="2" data-toc-line="[22.2]{.heading-label}. Implies or Explies Expressions" style="toctarget:sec-implies-or-explies-expressions"><a href="#sec-implies-or-explies-expressions" class="localref"><span class="heading-label">22.2</span>. Implies or Explies Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-logical-expressions" data-toc-depth="2" data-toc-line="[22.3]{.heading-label}. Logical Expressions" style="toctarget:sec-logical-expressions"><a href="#sec-logical-expressions" class="localref"><span class="heading-label">22.3</span>. Logical Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-relational-expressions" data-toc-depth="2" data-toc-line="[22.4]{.heading-label}. Relational Expressions" style="toctarget:sec-relational-expressions"><a href="#sec-relational-expressions" class="localref"><span class="heading-label">22.4</span>. Relational Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-terms" data-toc-depth="2" data-toc-line="[22.5]{.heading-label}. Terms" style="toctarget:sec-terms"><a href="#sec-terms" class="localref"><span class="heading-label">22.5</span>. Terms</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-factors" data-toc-depth="2" data-toc-line="[22.6]{.heading-label}. Factors" style="toctarget:sec-factors"><a href="#sec-factors" class="localref"><span class="heading-label">22.6</span>. Factors</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-unary-expressions" data-toc-depth="2" data-toc-line="[22.7]{.heading-label}. Unary Expressions" style="toctarget:sec-unary-expressions"><a href="#sec-unary-expressions" class="localref"><span class="heading-label">22.7</span>. Unary Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-primary-expressions" data-toc-depth="2" data-toc-line="[22.8]{.heading-label}. Primary Expressions" style="toctarget:sec-primary-expressions"><a href="#sec-primary-expressions" class="localref"><span class="heading-label">22.8</span>. Primary Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-lambda-expressions" data-toc-depth="2" data-toc-line="[22.9]{.heading-label}. Lambda expressions" style="toctarget:sec-lambda-expressions"><a href="#sec-lambda-expressions" class="localref"><span class="heading-label">22.9</span>. Lambda expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-left-hand-side-expressions" data-toc-depth="2" data-toc-line="[22.10]{.heading-label}. Left-Hand-Side Expressions" style="toctarget:sec-left-hand-side-expressions"><a href="#sec-left-hand-side-expressions" class="localref"><span class="heading-label">22.10</span>. Left-Hand-Side Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-right-hand-side-expressions" data-toc-depth="2" data-toc-line="[22.11]{.heading-label}. Right-Hand-Side Expressions" style="toctarget:sec-right-hand-side-expressions"><a href="#sec-right-hand-side-expressions" class="localref"><span class="heading-label">22.11</span>. Right-Hand-Side Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-array-allocation" data-toc-depth="2" data-toc-line="[22.12]{.heading-label}. Array Allocation" style="toctarget:sec-array-allocation"><a href="#sec-array-allocation" class="localref"><span class="heading-label">22.12</span>. Array Allocation</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-object-allocation" data-toc-depth="2" data-toc-line="[22.13]{.heading-label}. Object Allocation" style="toctarget:sec-object-allocation"><a href="#sec-object-allocation" class="localref"><span class="heading-label">22.13</span>. Object Allocation</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-havoc-right-hand-side" data-toc-depth="2" data-toc-line="[22.14]{.heading-label}. Havoc Right-Hand-Side" style="toctarget:sec-havoc-right-hand-side"><a href="#sec-havoc-right-hand-side" class="localref"><span class="heading-label">22.14</span>. Havoc Right-Hand-Side</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-constant-or-atomic-expressions" data-toc-depth="2" data-toc-line="[22.15]{.heading-label}. Constant Or Atomic Expressions" style="toctarget:sec-constant-or-atomic-expressions"><a href="#sec-constant-or-atomic-expressions" class="localref"><span class="heading-label">22.15</span>. Constant Or Atomic Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-literal-expressions" data-toc-depth="2" data-toc-line="[22.16]{.heading-label}. Literal Expressions" style="toctarget:sec-literal-expressions"><a href="#sec-literal-expressions" class="localref"><span class="heading-label">22.16</span>. Literal Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-fresh-expressions" data-toc-depth="2" data-toc-line="[22.17]{.heading-label}. Fresh Expressions" style="toctarget:sec-fresh-expressions"><a href="#sec-fresh-expressions" class="localref"><span class="heading-label">22.17</span>. Fresh Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-old-expressions" data-toc-depth="2" data-toc-line="[22.18]{.heading-label}. Old Expressions" style="toctarget:sec-old-expressions"><a href="#sec-old-expressions" class="localref"><span class="heading-label">22.18</span>. Old Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-cardinality-expressions" data-toc-depth="2" data-toc-line="[22.19]{.heading-label}. Cardinality Expressions" style="toctarget:sec-cardinality-expressions"><a href="#sec-cardinality-expressions" class="localref"><span class="heading-label">22.19</span>. Cardinality Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-numeric-conversion-expressions" data-toc-depth="2" data-toc-line="[22.20]{.heading-label}. Numeric Conversion Expressions" style="toctarget:sec-numeric-conversion-expressions"><a href="#sec-numeric-conversion-expressions" class="localref"><span class="heading-label">22.20</span>. Numeric Conversion Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-parenthesized-expression" data-toc-depth="2" data-toc-line="[22.21]{.heading-label}. Parenthesized Expression" style="toctarget:sec-parenthesized-expression"><a href="#sec-parenthesized-expression" class="localref"><span class="heading-label">22.21</span>. Parenthesized Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-sequence-display-expression" data-toc-depth="2" data-toc-line="[22.22]{.heading-label}. Sequence Display Expression" style="toctarget:sec-sequence-display-expression"><a href="#sec-sequence-display-expression" class="localref"><span class="heading-label">22.22</span>. Sequence Display Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-set-display-expression" data-toc-depth="2" data-toc-line="[22.23]{.heading-label}. Set Display Expression" style="toctarget:sec-set-display-expression"><a href="#sec-set-display-expression" class="localref"><span class="heading-label">22.23</span>. Set Display Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-multiset-display-or-cast-expression" data-toc-depth="2" data-toc-line="[22.24]{.heading-label}. Multiset Display or Cast Expression" style="toctarget:sec-multiset-display-or-cast-expression"><a href="#sec-multiset-display-or-cast-expression" class="localref"><span class="heading-label">22.24</span>. Multiset Display or Cast Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-map-display-expression" data-toc-depth="2" data-toc-line="[22.25]{.heading-label}. Map Display Expression" style="toctarget:sec-map-display-expression"><a href="#sec-map-display-expression" class="localref"><span class="heading-label">22.25</span>. Map Display Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-endless-expression" data-toc-depth="2" data-toc-line="[22.26]{.heading-label}. Endless Expression" style="toctarget:sec-endless-expression"><a href="#sec-endless-expression" class="localref"><span class="heading-label">22.26</span>. Endless Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-if-expression" data-toc-depth="2" data-toc-line="[22.27]{.heading-label}. If Expression" style="toctarget:sec-if-expression"><a href="#sec-if-expression" class="localref"><span class="heading-label">22.27</span>. If Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-case-bindings-and-patterns" data-toc-depth="2" data-toc-line="[22.28]{.heading-label}. Case Bindings and Patterns" style="toctarget:sec-case-bindings-and-patterns"><a href="#sec-case-bindings-and-patterns" class="localref"><span class="heading-label">22.28</span>. Case Bindings and Patterns</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-match-expression" data-toc-depth="2" data-toc-line="[22.29]{.heading-label}. Match Expression" style="toctarget:sec-match-expression"><a href="#sec-match-expression" class="localref"><span class="heading-label">22.29</span>. Match Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-quantifier-expression" data-toc-depth="2" data-toc-line="[22.30]{.heading-label}. Quantifier Expression" style="toctarget:sec-quantifier-expression"><a href="#sec-quantifier-expression" class="localref"><span class="heading-label">22.30</span>. Quantifier Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-set-comprehension-expressions" data-toc-depth="2" data-toc-line="[22.31]{.heading-label}. Set Comprehension Expressions" style="toctarget:sec-set-comprehension-expressions"><a href="#sec-set-comprehension-expressions" class="localref"><span class="heading-label">22.31</span>. Set Comprehension Expressions</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-statements-in-an-expression" data-toc-depth="2" data-toc-line="[22.32]{.heading-label}. Statements in an Expression" style="toctarget:sec-statements-in-an-expression"><a href="#sec-statements-in-an-expression" class="localref"><span class="heading-label">22.32</span>. Statements in an Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-let-expression" data-toc-depth="2" data-toc-line="[22.33]{.heading-label}. Let Expression" style="toctarget:sec-let-expression"><a href="#sec-let-expression" class="localref"><span class="heading-label">22.33</span>. Let Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-map-comprehension-expression" data-toc-depth="2" data-toc-line="[22.34]{.heading-label}. Map Comprehension Expression" style="toctarget:sec-map-comprehension-expression"><a href="#sec-map-comprehension-expression" class="localref"><span class="heading-label">22.34</span>. Map Comprehension Expression</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-name-segment" data-toc-depth="2" data-toc-line="[22.35]{.heading-label}. Name Segment" style="toctarget:sec-name-segment"><a href="#sec-name-segment" class="localref"><span class="heading-label">22.35</span>. Name Segment</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-hash-call" data-toc-depth="2" data-toc-line="[22.36]{.heading-label}. Hash Call" style="toctarget:sec-hash-call"><a href="#sec-hash-call" class="localref"><span class="heading-label">22.36</span>. Hash Call</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-suffix" data-toc-depth="2" data-toc-line="[22.37]{.heading-label}. Suffix" style="toctarget:sec-suffix"><a href="#sec-suffix" class="localref"><span class="heading-label">22.37</span>. Suffix</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-augmented-dot-suffix" data-toc-depth="3" data-toc-line="[22.37.0]{.heading-label}. Augmented Dot Suffix" style="toctarget:sec-augmented-dot-suffix"><a href="#sec-augmented-dot-suffix" class="localref"><span class="heading-label">22.37.0</span>. Augmented Dot Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-datatype-update-suffix" data-toc-depth="3" data-toc-line="[22.37.1]{.heading-label}. Datatype Update Suffix" style="toctarget:sec-datatype-update-suffix"><a href="#sec-datatype-update-suffix" class="localref"><span class="heading-label">22.37.1</span>. Datatype Update Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-subsequence-suffix" data-toc-depth="3" data-toc-line="[22.37.2]{.heading-label}. Subsequence Suffix" style="toctarget:sec-subsequence-suffix"><a href="#sec-subsequence-suffix" class="localref"><span class="heading-label">22.37.2</span>. Subsequence Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-slices-by-length-suffix" data-toc-depth="3" data-toc-line="[22.37.3]{.heading-label}. Slices By Length Suffix" style="toctarget:sec-slices-by-length-suffix"><a href="#sec-slices-by-length-suffix" class="localref"><span class="heading-label">22.37.3</span>. Slices By Length Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-sequence-update-suffix" data-toc-depth="3" data-toc-line="[22.37.4]{.heading-label}. Sequence Update Suffix" style="toctarget:sec-sequence-update-suffix"><a href="#sec-sequence-update-suffix" class="localref"><span class="heading-label">22.37.4</span>. Sequence Update Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-selection-suffix" data-toc-depth="3" data-toc-line="[22.37.5]{.heading-label}. Selection Suffix" style="toctarget:sec-selection-suffix"><a href="#sec-selection-suffix" class="localref"><span class="heading-label">22.37.5</span>. Selection Suffix</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-argument-list-suffix" data-toc-depth="3" data-toc-line="[22.37.6]{.heading-label}. Argument List Suffix" style="toctarget:sec-argument-list-suffix"><a href="#sec-argument-list-suffix" class="localref"><span class="heading-label">22.37.6</span>. Argument List Suffix</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-expression-lists" data-toc-depth="2" data-toc-line="[22.38]{.heading-label}. Expression Lists" style="toctarget:sec-expression-lists"><a href="#sec-expression-lists" class="localref"><span class="heading-label">22.38</span>. Expression Lists</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-module-refinement" data-toc-depth="1" data-toc-line="[23]{.heading-label}. Module Refinement" style="toctarget:sec-module-refinement"><a href="#sec-module-refinement" class="localref"><span class="heading-label">23</span>. Module Refinement</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-attributes" data-toc-depth="1" data-toc-line="[24]{.heading-label}. Attributes" style="toctarget:sec-attributes"><a href="#sec-attributes" class="localref"><span class="heading-label">24</span>. Attributes</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-dafny-attribute-implementation-details" data-toc-depth="2" data-toc-line="[24.0]{.heading-label}. Dafny Attribute Implementation Details" style="toctarget:sec-dafny-attribute-implementation-details"><a href="#sec-dafny-attribute-implementation-details" class="localref"><span class="heading-label">24.0</span>. Dafny Attribute Implementation Details</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-dafny-attributes" data-toc-depth="2" data-toc-line="[24.1]{.heading-label}. Dafny Attributes" style="toctarget:sec-dafny-attributes"><a href="#sec-dafny-attributes" class="localref"><span class="heading-label">24.1</span>. Dafny Attributes</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-assumption" data-toc-depth="3" data-toc-line="[24.1.0]{.heading-label}. assumption" style="toctarget:sec-assumption"><a href="#sec-assumption" class="localref"><span class="heading-label">24.1.0</span>. assumption</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-autoreq-boolexpr" data-toc-depth="3" data-toc-line="[24.1.1]{.heading-label}. autoReq boolExpr" style="toctarget:sec-autoreq-boolexpr"><a href="#sec-autoreq-boolexpr" class="localref"><span class="heading-label">24.1.1</span>. autoReq boolExpr</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-autocontracts" data-toc-depth="3" data-toc-line="[24.1.2]{.heading-label}. autocontracts" style="toctarget:sec-autocontracts"><a href="#sec-autocontracts" class="localref"><span class="heading-label">24.1.2</span>. autocontracts</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-axiom" data-toc-depth="3" data-toc-line="[24.1.3]{.heading-label}. axiom" style="toctarget:sec-axiom"><a href="#sec-axiom" class="localref"><span class="heading-label">24.1.3</span>. axiom</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-compile" data-toc-depth="3" data-toc-line="[24.1.4]{.heading-label}. compile" style="toctarget:sec-compile"><a href="#sec-compile" class="localref"><span class="heading-label">24.1.4</span>. compile</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-decl" data-toc-depth="3" data-toc-line="[24.1.5]{.heading-label}. decl" style="toctarget:sec-decl"><a href="#sec-decl" class="localref"><span class="heading-label">24.1.5</span>. decl</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-fuel" data-toc-depth="3" data-toc-line="[24.1.6]{.heading-label}. fuel" style="toctarget:sec-fuel"><a href="#sec-fuel" class="localref"><span class="heading-label">24.1.6</span>. fuel</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-heapquantifier" data-toc-depth="3" data-toc-line="[24.1.7]{.heading-label}. heapQuantifier" style="toctarget:sec-heapquantifier"><a href="#sec-heapquantifier" class="localref"><span class="heading-label">24.1.7</span>. heapQuantifier</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-imported" data-toc-depth="3" data-toc-line="[24.1.8]{.heading-label}. imported" style="toctarget:sec-imported"><a href="#sec-imported" class="localref"><span class="heading-label">24.1.8</span>. imported</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-induction" data-toc-depth="3" data-toc-line="[24.1.9]{.heading-label}. induction" style="toctarget:sec-induction"><a href="#sec-induction" class="localref"><span class="heading-label">24.1.9</span>. induction</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-layerquantifier" data-toc-depth="3" data-toc-line="[24.1.10]{.heading-label}. layerQuantifier" style="toctarget:sec-layerquantifier"><a href="#sec-layerquantifier" class="localref"><span class="heading-label">24.1.10</span>. layerQuantifier</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-nativetype" data-toc-depth="3" data-toc-line="[24.1.11]{.heading-label}. nativeType" style="toctarget:sec-nativetype"><a href="#sec-nativetype" class="localref"><span class="heading-label">24.1.11</span>. nativeType</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-opaque" data-toc-depth="3" data-toc-line="[24.1.12]{.heading-label}. opaque" style="toctarget:sec-opaque"><a href="#sec-opaque" class="localref"><span class="heading-label">24.1.12</span>. opaque</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-opaque-full" data-toc-depth="3" data-toc-line="[24.1.13]{.heading-label}. opaque full" style="toctarget:sec-opaque-full"><a href="#sec-opaque-full" class="localref"><span class="heading-label">24.1.13</span>. opaque full</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-prependasserttoken" data-toc-depth="3" data-toc-line="[24.1.14]{.heading-label}. prependAssertToken" style="toctarget:sec-prependasserttoken"><a href="#sec-prependasserttoken" class="localref"><span class="heading-label">24.1.14</span>. prependAssertToken</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-tailrecursion" data-toc-depth="3" data-toc-line="[24.1.15]{.heading-label}. tailrecursion" style="toctarget:sec-tailrecursion"><a href="#sec-tailrecursion" class="localref"><span class="heading-label">24.1.15</span>. tailrecursion</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-timelimitmultiplier" data-toc-depth="3" data-toc-line="[24.1.16]{.heading-label}. timeLimitMultiplier" style="toctarget:sec-timelimitmultiplier"><a href="#sec-timelimitmultiplier" class="localref"><span class="heading-label">24.1.16</span>. timeLimitMultiplier</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-trigger" data-toc-depth="3" data-toc-line="[24.1.17]{.heading-label}. trigger" style="toctarget:sec-trigger"><a href="#sec-trigger" class="localref"><span class="heading-label">24.1.17</span>. trigger</a></div> +<div class="tocitem tocitem3" data-toc-target="sec-typequantifier" data-toc-depth="3" data-toc-line="[24.1.18]{.heading-label}. typeQuantifier" style="toctarget:sec-typequantifier"><a href="#sec-typequantifier" class="localref"><span class="heading-label">24.1.18</span>. typeQuantifier</a></div></div> +<div class="tocitem tocitem2" data-toc-target="sec-boogie-attributes" data-toc-depth="2" data-toc-line="[24.2]{.heading-label}. Boogie Attributes" style="toctarget:sec-boogie-attributes"><a href="#sec-boogie-attributes" class="localref"><span class="heading-label">24.2</span>. Boogie Attributes</a></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-dafny-users-guide" data-toc-depth="1" data-toc-line="[25]{.heading-label}. Dafny User\'s Guide" style="toctarget:sec-dafny-users-guide"><a href="#sec-dafny-users-guide" class="localref"><span class="heading-label">25</span>. Dafny User's Guide</a></div> +<div class="tocblock tocblock2"> +<div class="tocitem tocitem2" data-toc-target="sec-installing-dafny-from-binaries" data-toc-depth="2" data-toc-line="[25.0]{.heading-label}. Installing Dafny From Binaries" style="toctarget:sec-installing-dafny-from-binaries"><a href="#sec-installing-dafny-from-binaries" class="localref"><span class="heading-label">25.0</span>. Installing Dafny From Binaries</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-building-dafny-from-source" data-toc-depth="2" data-toc-line="[25.1]{.heading-label}. Building Dafny from Source" style="toctarget:sec-building-dafny-from-source"><a href="#sec-building-dafny-from-source" class="localref"><span class="heading-label">25.1</span>. Building Dafny from Source</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-using-dafny-from-visual-studio" data-toc-depth="2" data-toc-line="[25.2]{.heading-label}. Using Dafny From Visual Studio" style="toctarget:sec-using-dafny-from-visual-studio"><a href="#sec-using-dafny-from-visual-studio" class="localref"><span class="heading-label">25.2</span>. Using Dafny From Visual Studio</a></div> +<div class="tocitem tocitem2" data-toc-target="sec-using-dafny-from-the-command-line" data-toc-depth="2" data-toc-line="[25.3]{.heading-label}. Using Dafny From the Command Line" style="toctarget:sec-using-dafny-from-the-command-line"><a href="#sec-using-dafny-from-the-command-line" class="localref"><span class="heading-label">25.3</span>. Using Dafny From the Command Line</a></div> +<div class="tocblock tocblock3"> +<div class="tocitem tocitem3" data-toc-target="sec-dafny-command-line-options" data-toc-depth="3" data-toc-line="[25.3.0]{.heading-label}. Dafny Command Line Options" style="toctarget:sec-dafny-command-line-options"><a href="#sec-dafny-command-line-options" class="localref"><span class="heading-label">25.3.0</span>. Dafny Command Line Options</a></div></div></div> +<div class="tocitem tocitem1" data-toc-target="sec-references" data-toc-depth="1" data-toc-line="[26]{.heading-label}. References" style="toctarget:sec-references"><a href="#sec-references" class="localref"><span class="heading-label">26</span>. References</a></div> +<div class="tocitem tocitem1" data-toc-target="sec-references" data-toc-depth="1" data-toc-line="References" style="toctarget:sec-references"><a href="#sec-references" class="localref">References</a></div></div></nav><h2 id="sec-introduction" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">0</span>. </span>Introduction</h2> +<p class="p noindent">Dafny <span class="citations" style="target-element:bibitem">[<a href="#leino:dafny:lpar16" title="K. Rustan M. Leino. +Dafny: An automatic program verifier for functional correctness." class="bibref localref" style="target-element:bibitem"><span class="cite-number">18</span></a>]</span> is a programming language with built-in specification constructs. +The Dafny static program verifier can be used to verify the functional +correctness of programs. +</p> +<p class="p indent">The Dafny programming language is designed to support the static +verification of programs. It is imperative, sequential, supports generic +classes, methods and functions, dynamic allocation, inductive and +co-inductive datatypes, and specification constructs. The +specifications include pre- and postconditions, frame specifications +(read and write sets), and termination metrics. To further support +specifications, the language also offers updatable ghost variables, +recursive functions, and types like sets and sequences. Specifications +and ghost constructs are used only during verification; the compiler +omits them from the executable code. +</p> +<p class="p indent">The Dafny verifier is run as part of the compiler. As such, a programmer +interacts with it much in the same way as with the static type +checker—when the tool produces errors, the programmer responds by +changing the program’s type declarations, specifications, and statements. +</p> +<p class="p indent">The easiest way to try out <a href="http://rise4fun.com/Dafny">Dafny is in your web browser at +rise4fun</a><span class="citations" style="target-element:bibitem">[<a href="#rise4fun:dafny" title="K. Rustan M. Leino. +Try dafny in your browser, c." class="bibref localref" style="target-element:bibitem"><span class="cite-number">15</span></a>]</span>. Once you get a bit +more serious, you may prefer to <a href="http://dafny.codeplex.com/">download</a> it +to run it on your machine. Although Dafny can be run from the command +line (on Windows or other platforms), the preferred way to run it is in +Microsoft Visual Studio 2012 (or newer) or using emacs, where the Dafny +verifier runs in the background while the programmer is editing the +program. +</p> +<p class="p indent">The Dafny verifier is powered +by <a href="http://research.microsoft.com/boogie">Boogie</a> +<span class="citations" style="target-element:bibitem">[<a href="#boogie:architecture" title="Mike Barnett, Bor-Yuh Evan Chang, Robert DeLine, Bart Jacobs, and K. Rustan M. Leino. +Boogie: A modular reusable verifier for object-oriented programs. +In Frank S. de Boer, Marcello M. Bonsangue, Susanne Graf, and Willem-Paul de Roever, editors, Formal Methods for Components and Objects: 4th International Symposium, FMCO 2005, volume 4111, pages 364–387. Springer, September 2006." class="bibref localref" style="target-element:bibitem"><span class="cite-number">0</span></a>, <a href="#leino:boogie2-refman" title="K. Rustan M. Leino. +This is Boogie 2." class="bibref localref" style="target-element:bibitem"><span class="cite-number">16</span></a>, <a href="#leinoruemmer:boogie2" title="K. Rustan M. Leino and Philipp Rümmer. +A polymorphic intermediate verification language: Design and logical encoding. +In Javier Esparza and Rupak Majumdar, editors, Tools and Algorithms for the Construction and Analysis of Systems, 16th International Conference, TACAS 2010, volume 6015, pages 312–327. Springer, March 2010." class="bibref localref" style="target-element:bibitem"><span class="cite-number">23</span></a>]</span> +and <a href="https://github.com/z3prover">Z3</a><span class="citations" style="target-element:bibitem">[<a href="#demourabjorner:z3:overview" title="Leonardo de Moura and Nikolaj Bjørner. +Z3: An efficient SMT solver." class="bibref localref" style="target-element:bibitem"><span class="cite-number">4</span></a>]</span>. +</p> +<p class="p indent">From verified programs, the Dafny compiler produces code (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.dll</code> or +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.exe</code>) for the .NET platform via intermediate C# files. However, the +facilities for interfacing with other .NET code are minimal. +</p> +<p class="p indent">This is the reference manual for the Dafny verification system. It is +based on the following references: +<span class="citations" style="target-element:bibitem">[<a href="#msr:dafny:source" title="K. Rustan M. Leino et al. +Dafny source code." class="bibref localref" style="target-element:bibitem"><span class="cite-number">5</span></a>, <a href="#msr:dafny:main" title="K. Rustan M. Leino. +Main microsoft research dafny web page, a." class="bibref localref" style="target-element:bibitem"><span class="cite-number">13</span></a>–<a href="#rise4fun:dafny" title="K. Rustan M. Leino. +Try dafny in your browser, c." class="bibref localref" style="target-element:bibitem"><span class="cite-number">15</span></a>, <a href="#leino:dafny:lpar16" title="K. Rustan M. Leino. +Dafny: An automatic program verifier for functional correctness." class="bibref localref" style="target-element:bibitem"><span class="cite-number">18</span></a>, <a href="#leino:dafny:coinduction" title="K. Rustan M. Leino and Michal Moskal. +Co-induction simply: Automatic co-inductive proofs in a program verifier. +Manuscript KRML 230, 2014a. +Available at http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf." class="bibref localref" style="target-element:bibitem"><span class="cite-number">20</span></a>, <a href="#leino:dafny:calc" title="K. Rustan M. Leino and Nadia Polikarpova. +Verified calculations." class="bibref localref" style="target-element:bibitem"><span class="cite-number">22</span></a>]</span> +</p> +<p class="p indent">The main part of the reference manual is in top down order except for an +initial section that deals with the lowest level constructs. +</p><h3 id="sec-dafny-example" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">0.0</span>. </span>Dafny Example</h3> +<p class="p noindent">To give a flavor of Dafny, here is the solution to a competition problem. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:darkgreen">// VSComp 2010, problem 3, find a 0 in a linked list and return how many</span> +<span style="color:darkgreen">// nodes were skipped until the first 0 (or end-of-list) was found.</span> +<span style="color:darkgreen">// Rustan Leino, 18 August 2010.</span> +<span style="color:darkgreen">// </span> +<span style="color:darkgreen">// The difficulty in this problem lies in specifying what the return</span> +<span style="color:darkgreen">// value 'r' denotes and in proving that the program terminates. Both of</span> +<span style="color:darkgreen">// these are addressed by declaring a ghost field 'List' in each</span> +<span style="color:darkgreen">// linked-list node, abstractly representing the linked-list elements</span> +<span style="color:darkgreen">// from the node to the end of the linked list. The specification can</span> +<span style="color:darkgreen">// now talk about that sequence of elements and can use 'r' as an index</span> +<span style="color:darkgreen">// into the sequence, and termination can be proved from the fact that</span> +<span style="color:darkgreen">// all sequences in Dafny are finite.</span> +<span style="color:darkgreen">// </span> +<span style="color:darkgreen">// We only want to deal with linked lists whose 'List' field is properly</span> +<span style="color:darkgreen">// filled in (which can only happen in an acyclic list, for example). To</span> +<span style="color:darkgreen">// that avail, the standard idiom in Dafny is to declare a predicate</span> +<span style="color:darkgreen">// 'Valid()' that is true of an object when the data structure</span> +<span style="color:darkgreen">// representing object's abstract value is properly formed. The</span> +<span style="color:darkgreen">// definition of 'Valid()' is what one intuitively would think of as the</span> +<span style="color:darkgreen">// ''object invariant'', and it is mentioned explicitly in method pre-</span> +<span style="color:darkgreen">// and postconditions. As part of this standard idiom, one also declared</span> +<span style="color:darkgreen">// a ghost variable 'Repr' that is maintained as the set of objects that</span> +<span style="color:darkgreen">// make up the representation of the aggregate object--in this case, the</span> +<span style="color:darkgreen">// Node itself and all its successors.</span> + +<span style="color:blue">class</span> Node { + <span style="color:blue">ghost</span> <span style="color:blue">var</span> List: <span style="color:teal">seq</span><<span style="color:teal">int</span>> + <span style="color:blue">ghost</span> <span style="color:blue">var</span> Repr: <span style="color:teal">set</span><Node> + <span style="color:blue">var</span> head: <span style="color:teal">int</span> + <span style="color:blue">var</span> next: Node + + <span style="color:blue">predicate</span> Valid() + <span style="color:purple">reads</span> <span style="color:blue">this</span>, Repr + { + <span style="color:blue">this</span> <span style="color:blue">in</span> Repr && + <span class="constant" style="color:purple">1</span> <= |List| && List[<span class="constant" style="color:purple">0</span>] == head && + (next == <span style="color:blue">null</span> ==> |List| == <span class="constant" style="color:purple">1</span>) && + (next != <span style="color:blue">null</span> ==> + next <span style="color:blue">in</span> Repr && next.Repr <= Repr && <span style="color:blue">this</span> !<span style="color:blue">in</span> next.Repr && + next.Valid() && next.List == List[<span class="constant" style="color:purple">1</span>..]) + } + + <span style="color:blue">static</span> <span style="color:blue">method</span> Cons(x: <span style="color:teal">int</span>, tail: Node) <span style="color:blue">returns</span> (n: Node) + <span style="color:purple">requires</span> tail == <span style="color:blue">null</span> || tail.Valid() + <span style="color:purple">ensures</span> n != <span style="color:blue">null</span> && n.Valid() + <span style="color:purple">ensures</span> <span style="color:blue">if</span> tail == <span style="color:blue">null</span> <span style="color:blue">then</span> n.List == [x] + <span style="color:blue">else</span> n.List == [x] + tail.List + { + n <span style="color:blue">:=</span> <span style="color:blue">new</span> Node; + n.head, n.next <span style="color:blue">:=</span> x, tail; + <span style="color:blue">if</span> (tail == <span style="color:blue">null</span>) { + n.List <span style="color:blue">:=</span> [x]; + n.Repr <span style="color:blue">:=</span> {n}; + } <span style="color:blue">else</span> { + n.List <span style="color:blue">:=</span> [x] + tail.List; + n.Repr <span style="color:blue">:=</span> {n} + tail.Repr; + } + } +} + +<span style="color:blue">method</span> Search(ll: Node) <span style="color:blue">returns</span> (r: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> ll == <span style="color:blue">null</span> || ll.Valid() + <span style="color:purple">ensures</span> ll == <span style="color:blue">null</span> ==> r == <span class="constant" style="color:purple">0</span> + <span style="color:purple">ensures</span> ll != <span style="color:blue">null</span> ==> + <span class="constant" style="color:purple">0</span> <= r && r <= |ll.List| && + (r < |ll.List| ==> ll.List[r] == <span class="constant" style="color:purple">0</span> && <span class="constant" style="color:purple">0</span> !<span style="color:blue">in</span> ll.List[..r]) && + (r == |ll.List| ==> <span class="constant" style="color:purple">0</span> !<span style="color:blue">in</span> ll.List) +{ + <span style="color:blue">if</span> (ll == <span style="color:blue">null</span>) { + r <span style="color:blue">:=</span> <span class="constant" style="color:purple">0</span>; + } <span style="color:blue">else</span> { + <span style="color:blue">var</span> jj,i <span style="color:blue">:=</span> ll,<span class="constant" style="color:purple">0</span>; + <span style="color:blue">while</span> (jj != <span style="color:blue">null</span> && jj.head != <span class="constant" style="color:purple">0</span>) + <span style="color:purple">invariant</span> jj != <span style="color:blue">null</span> ==> jj.Valid() && i + |jj.List| == |ll.List| && + ll.List[i..] == jj.List + <span style="color:purple">invariant</span> jj == <span style="color:blue">null</span> ==> i == |ll.List| + <span style="color:purple">invariant</span> <span class="constant" style="color:purple">0</span> !<span style="color:blue">in</span> ll.List[..i] + <span style="color:purple">decreases</span> |ll.List| - i + { + jj <span style="color:blue">:=</span> jj.next; + i <span style="color:blue">:=</span> i + <span class="constant" style="color:purple">1</span>; + } + r <span style="color:blue">:=</span> i; + } +} + +<span style="color:blue">method</span> Main() +{ + <span style="color:blue">var</span> list: Node <span style="color:blue">:=</span> <span style="color:blue">null</span>; + list <span style="color:blue">:=</span> list.Cons(<span class="constant" style="color:purple">0</span>, list); + list <span style="color:blue">:=</span> list.Cons(<span class="constant" style="color:purple">5</span>, list); + list <span style="color:blue">:=</span> list.Cons(<span class="constant" style="color:purple">0</span>, list); + list <span style="color:blue">:=</span> list.Cons(<span class="constant" style="color:purple">8</span>, list); + <span style="color:blue">var</span> r <span style="color:blue">:=</span> Search(list); + <span style="color:blue">print</span> <span style="color:maroon">"</span><span style="color:maroon">Search returns </span><span style="color:maroon">"</span>, r, <span style="color:maroon">"</span><span style="color:gray">\n</span><span style="color:maroon">"</span>; + <span style="color:blue">assert</span> r == <span class="constant" style="color:purple">1</span>; +}</code></pre><h2 id="sec-lexical-and-low-level-grammar" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">1</span>. </span>Lexical and Low Level Grammar</h2> +<p class="p noindent">Dafny uses the Coco/R lexer and parser generator for its lexer and parser +(<a href="http://www.ssw.uni-linz.ac.at/Research/Projects/Coco">http://www.ssw.uni-linz.ac.at/Research/Projects/Coco</a>)<span class="citations" style="target-element:bibitem">[<a href="#linz:coco" title="Hanspeter Mössenböck, Markus Löberbauer, and Albrecht Wöß. +The compiler generator coco/r. +Open source from University of Linz, 2013. +Available at http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/." class="bibref localref" style="target-element:bibitem"><span class="cite-number">27</span></a>]</span>. +The Dafny input file to Coco/R is the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Dafny.atg</code> file in the source tree. +A Coco/R input file consists of code written in the target language +(e.g. C#) intermixed with these special sections: +</p> +<ol class="ol compact" start="0"> +<li class="li ol-li compact-li">The Characters section which defines classes of characters that are used +in defining the lexer (Section <a href="#sec-character-classes" title="1.0. Character Classes" class="localref" style="target-element:h2"><span class="heading-label">1.0</span></a>). +</li> +<li class="li ol-li compact-li">The Tokens section which defines the lexical tokens (Section <a href="#sec-tokens" title="1.1. Tokens" class="localref" style="target-element:h2"><span class="heading-label">1.1</span></a>). +</li> +<li class="li ol-li compact-li">The Productions section which defines the grammar. The grammar productions +are distributed in the later parts of this document in the parts where +those constructs are explained. +</li></ol> + +<p class="p noindent">The grammar presented in this document was derived from the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Dafny.atg</code> +file but has been simplified by removing details that, though needed by +the parser, are not needed to understand the grammar. In particular, the +following transformation have been performed. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">The semantics actions, enclosed by “(.” and “.)”, where removed. +</li> +<li class="li ul-li list-star-li compact-li">There are some elements in the grammar used for error recovery +(“SYNC”). These were removed. +</li> +<li class="li ul-li list-star-li compact-li">There are some elements in the grammar for resolving conflicts +(“IF(b)”). These have been removed. +</li> +<li class="li ul-li list-star-li compact-li">Some comments related to Coco/R parsing details have been removed. +</li> +<li class="li ul-li list-star-li compact-li">A Coco/R grammar is an attributed grammar where the attributes enable +the productions to have input and output parameters. These attributes +were removed except that boolean input parameters that affect +the parsing are kept. + +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">In our representation we represent these +in a definition by giving the names of the parameters following +the non-terminal name. For example <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">entity1(allowsX)</code>. +</li> +<li class="li ul-li list-star-li compact-li">In the case of uses of the parameter, the common case is that the +parameter is just passed to a lower-level non-terminal. In that +case we just give the name, e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">entity2(allowsX)</code>. +</li> +<li class="li ul-li list-star-li compact-li">If we want to given an explicit value to a parameter, we specify it in +a keyword notation like this: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">entity2(allowsX: <span style="color:blue">true</span>)</code>. +</li> +<li class="li ul-li list-star-li compact-li"> +<p>In some cases the value to be passed depends on the grammatical context. +In such cases we give a description of the conditions under which the +parameter is true, enclosed in parenthesis. For example: +</p> +<p> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FunctionSignatureOrEllipsis_(allowGhostKeyword: (<span style="color:maroon">"</span><span style="color:maroon">method</span><span style="color:maroon">"</span> present))</code> +</p>means that the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowGhostKeyword</code> parameter is true if the +“method” keyword was given in the associated <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functiondecl" class="ntref localref" style="color:maroon">FunctionDecl</a></span></code>. +</li> +<li class="li ul-li list-star-li compact-li">Where a parameter affects the parsing of a non-terminal we will +explain the effect of the parameter. +</li></ul></li></ul> + +<p class="p noindent">The names of character sets and tokens start with a lower case +letter but the names of grammar non-terminals start with +an upper-case letter. +</p> +<p class="p indent">The grammar uses Extended BNF notation. See the <a href="http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/Doc/UserManual.pdf">Coco/R Referenced +manual</a> +for details. But in summary: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">identifiers starting with a lower case letter denote +terminal symbols, +</li> +<li class="li ul-li list-star-li compact-li">identifiers starting with an upper case letter denote nonterminal +symbols. +</li> +<li class="li ul-li list-star-li compact-li">Strings denote themselves. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">=</code> separates the sides of a production, e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A = a b c</code> +</li> +<li class="li ul-li list-star-li compact-li">In the Coco grammars “.” terminates a production, but for readability +in this document a production starts with the defined identifier in +the left margin and may be continued on subsequent lines if they +are indented. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|</code> separates alternatives, e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a b | c | d e</code> means <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a b</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c or d e</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(</code> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">)</code> groups alternatives, e.g. (a | b) c means a c or b c +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">[ ]</code> option, e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">[a] b</code> means <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a b</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{ }</code> iteration (0 or more times), e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{a} b</code> means <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a b</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a a b</code> or … +</li> +<li class="li ul-li list-star-li compact-li">We allow <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|</code> inside <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">[ ]</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{ }</code>. So <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">[a | b]</code> is short for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">[(a | b)]</code> +and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{a | b}</code> is short for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{(a | b)}</code>. +</li> +<li class="li ul-li list-star-li compact-li">The first production defines the name of the grammar, in this case <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Dafny</code>. +</li></ul> + +<p class="p noindent">In addition to the Coco rules, for the sake of readability we have adopted +these additional conventions. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">We allow <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> to be used. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a - b</code> means it matches if it matches <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> but not <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code>. +</li> +<li class="li ul-li list-star-li compact-li">To aid in explaining the grammar we have added some additional productions +that are not present in the original grammar. We name these with a trailing +underscore. If you inline these where they are referenced, the result should +let you reconstruct the original grammar. +</li></ul> + +<p class="p noindent"><strong class="strong-star2">For the convenience of the reader, any references to character sets, +tokens, or grammar non-terminals in this document are hyper-links that +will link to the definition of the entity.</strong> +</p><h3 id="sec-character-classes" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">1.0</span>. </span>Character Classes</h3> +<p class="p noindent">This section defines character classes used later in the token definitions. +In this section backslash is used to start an escape sequence, so for example +‘\n’ denotes the single linefeed character. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_letter" class="ntdef" style="color:olive">letter</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"</span></span></code></pre> +<p class="p noindent para-continued">At present, a letter is an ASCII upper or lowercase letter. Other Unicode letters +are not supported. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_digit" class="ntdef" style="color:olive">digit</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"0123456789"</span></span></code></pre> +<p class="p noindent para-continued">A digit is just one of the base-10 digits. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_posdigit" class="ntdef" style="color:olive">posDigit</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"123456789"</span></span></code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_posdigit" class="ntref localref" style="color:maroon">posDigit</a></span></code> is a digit, excluding 0. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_hexdigit" class="ntdef" style="color:olive">hexdigit</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"0123456789ABCDEFabcdef"</span></span></code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span></code> character is a digit or one of the letters from ‘A’ to ‘F’ in either case. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_special" class="ntdef" style="color:olive">special</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"'_?"</span></span></code></pre> +<p class="p noindent para-continued">The <em class="em-low1">special</em> characters are the characters in addition to alphanumeric characters +that are allowed to appear in a Dafny identifier. These are +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">'</span><span style="color:maroon">"</span></code> because mathematicians like to put primes on identifiers and some ML +programmers like to start names of type parameters with a “'”. +</li> +<li class="li ul-li list-star-li compact-li">“_” because computer scientists expect to be able to have underscores in identifiers. +</li> +<li class="li ul-li list-star-li compact-li">“?” because it is useful to have “?” at the end of names of predicates, +e.g. “Cons?”. +</li></ul> + +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_cr" class="ntdef" style="color:olive">cr</span></span> = <span style="color:maroon">'</span><span style="color:gray">\r</span><span style="color:maroon">'</span></code></pre> +<p class="p noindent para-continued">A carriage return character. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_lf" class="ntdef" style="color:olive">lf</span></span> = <span style="color:maroon">'</span><span style="color:gray">\n</span><span style="color:maroon">'</span></code></pre> +<p class="p noindent para-continued">A line feed character. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_tab" class="ntdef" style="color:olive">tab</span></span> = <span style="color:maroon">'</span><span style="color:gray">\t</span><span style="color:maroon">'</span></code></pre> +<p class="p noindent para-continued">A tab character. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_space" class="ntdef" style="color:olive">space</span></span> = <span style="color:maroon">' '</span></code></pre> +<p class="p noindent para-continued">A space character. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_nondigitidchar" class="ntdef" style="color:olive">nondigitIdChar</span></span> = <span class="code-escaped"><a href="#2_letter" class="ntref localref" style="color:maroon">letter</a></span> + <span class="code-escaped"><a href="#2_special" class="ntref localref" style="color:maroon">special</a></span></code></pre> +<p class="p noindent para-continued">The characters that can be used in an identifier minus the digits. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_idchar" class="ntdef" style="color:olive">idchar</span></span> = <span class="code-escaped"><a href="#2_nondigitidchar" class="ntref localref" style="color:maroon">nondigitIdChar</a></span> + <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span></code></pre> +<p class="p noindent para-continued">The characters that can be used in an identifier. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_nonidchar" class="ntdef" style="color:olive">nonidchar</span></span> = <span class="code-escaped"><a href="#1_any" class="ntref localref" style="color:maroon">ANY</a></span> - <span class="code-escaped"><a href="#2_idchar" class="ntref localref" style="color:maroon">idchar</a></span></code></pre> +<p class="p noindent para-continued">Any character except those that can be used in an identifier. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_charchar" class="ntdef" style="color:olive">charChar</span></span> = <span class="code-escaped"><a href="#1_any" class="ntref localref" style="color:maroon">ANY</a></span> - <span style="color:maroon">'</span><span style="color:gray">\'</span><span style="color:maroon">'</span> - <span style="color:maroon">'</span><span style="color:gray">\\</span><span style="color:maroon">'</span> - <span class="code-escaped"><a href="#2_cr" class="ntref localref" style="color:maroon">cr</a></span> - <span class="code-escaped"><a href="#2_lf" class="ntref localref" style="color:maroon">lf</a></span></code></pre> +<p class="p noindent para-continued">Characters that can appear in a character constant. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_stringchar" class="ntdef" style="color:olive">stringChar</span></span> = <span class="code-escaped"><a href="#1_any" class="ntref localref" style="color:maroon">ANY</a></span> - <span style="color:maroon">'"'</span> - <span style="color:maroon">'</span><span style="color:gray">\\</span><span style="color:maroon">'</span> - <span class="code-escaped"><a href="#2_cr" class="ntref localref" style="color:maroon">cr</a></span> - <span class="code-escaped"><a href="#2_lf" class="ntref localref" style="color:maroon">lf</a></span></code></pre> +<p class="p noindent para-continued">Characters that can appear in a string constant. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_verbatimstringchar" class="ntdef" style="color:olive">verbatimStringChar</span></span> = <span class="code-escaped"><a href="#1_any" class="ntref localref" style="color:maroon">ANY</a></span> - <span style="color:maroon">'"'</span></code></pre> +<p class="p noindent para-continued">Characters that can appear in a verbatim string. +</p><h4 id="sec-comments" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.0.0</span>. </span>Comments</h4> +<p class="p noindent">Comments are in two forms. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">They may go from “/*” to “*/” and be nested. +</li> +<li class="li ul-li list-star-li compact-li">They may go from “//” to the end of the line. +</li></ul> +<h3 id="sec-tokens" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">1.1</span>. </span>Tokens</h3> +<p class="p noindent">As with most languages, Dafny syntax is defined in two levels. First the stream +of input characters is broken up into <em class="em-low1">tokens</em>. Then these tokens are parsed +using the Dafny grammar. The Dafny tokens are defined in this section. +</p><h4 id="sec-reserved-words" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.0</span>. </span>Reserved Words</h4> +<p class="p noindent">The following reserved words appear in the Dafny grammar and may not be used +as identifiers of user-defined entities: +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_reservedword" class="ntdef" style="color:olive">reservedword</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"abstract"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"array"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"as"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assert"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assume"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"bool"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"break"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"calc"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"case"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"char"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"class"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"codatatype"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"colemma"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"constructor"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"copredicate"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"datatype"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"decreases"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"default"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"else"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ensures"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"exists"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"extends"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"false"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"forall"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"free"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"fresh"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"function"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"if"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"imap"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"import"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"in"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"include"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"inductive"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"int"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"invariant"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iset"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iterator"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"label"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"lemma"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"map"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"match"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"modifies"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"modify"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"module"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"multiset"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"nat"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"new"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"newtype"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"null"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"object"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"old"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"opened"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"predicate"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"print"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"protected"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"reads"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"real"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"refines"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"requires"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"return"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"returns"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"seq"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"set"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"static"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"string"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"then"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"this"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"trait"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"true"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"type"</span></span> | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"var"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"where"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"while"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yield"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yields"</span></span> | <span class="code-escaped"><a href="#2_arraytoken" class="ntref localref" style="color:maroon">arrayToken</a></span> + +<span class="code-escaped"><span id="2_arraytoken" class="ntdef" style="color:olive">arrayToken</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"array"</span></span> [ <span class="code-escaped"><a href="#2_posdigit" class="ntref localref" style="color:maroon">posDigit</a></span> { <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span> }]</code></pre> +<p class="p noindent para-continued">An <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_arraytoken" class="ntref localref" style="color:maroon">arrayToken</a></span></code> is a reserved word that denotes an array type of +given rank. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span></code> is an array type of rank 1 (aka a vector). <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array2</span></code> +is the type of two-dimensional arrays, etc. +</p> +<p class="p indent">TODO: Is “_” is reserved word? +</p><h4 id="sec-identifiers" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.1</span>. </span>Identifiers</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_ident" class="ntdef" style="color:olive">ident</span></span> = <span class="code-escaped"><a href="#2_nondigitidchar" class="ntref localref" style="color:maroon">nondigitIdChar</a></span> { <span class="code-escaped"><a href="#2_idchar" class="ntref localref" style="color:maroon">idchar</a></span> } - <span class="code-escaped"><a href="#2_arraytoken" class="ntref localref" style="color:maroon">arraytoken</a></span> - <span class="code-escaped"><a href="#2_chartoken" class="ntref localref" style="color:maroon">chartoken</a></span> - <span class="code-escaped"><a href="#2_reservedword" class="ntref localref" style="color:maroon">reservedword</a></span> </code></pre> +<p class="p noindent para-continued">In general Dafny identifiers are sequences of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_idchar" class="ntref localref" style="color:maroon">idChar</a></span></code> characters where +the first character is a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_nondigitidchar" class="ntref localref" style="color:maroon">nondigitIdChar</a></span></code>. However tokens that fit this pattern +are not identifiers if they look like an array type token, a character literal, +or a reserved work. +</p><h4 id="sec-digits" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.2</span>. </span>Digits</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_digits" class="ntdef" style="color:olive">digits</span></span> = <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span> {[<span style="color:maroon">'_'</span>] <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span>}</code></pre> +<p class="p noindent para-continued">A sequence of decimal digits, possibly interspersed with underscores for readability. Example: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">1_234_567</span></code>. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_hexdigits" class="ntdef" style="color:olive">hexdigits</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"0x"</span></span> <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span> {[<span style="color:maroon">'_'</span>] <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span>}</code></pre> +<p class="p noindent para-continued">A hexadecimal constant, possibly interspersed with underscores for readability. +Example: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0xffff_ffff</span></code>. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_decimaldigits" class="ntdef" style="color:olive">decimaldigits</span></span> = <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span> {[<span style="color:maroon">'_'</span>] <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span>} <span style="color:maroon">'.'</span> <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span> {[<span style="color:maroon">'_'</span>] <span class="code-escaped"><a href="#2_digit" class="ntref localref" style="color:maroon">digit</a></span>}</code></pre> +<p class="p noindent para-continued">A decimal fraction constant, possibly interspersed with underscores for readability. +Example: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">123_456.789_123</span></code>. +</p><h4 id="sec-escaped-character" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.3</span>. </span>Escaped Character</h4> +<p class="p noindent">In this section the “\” characters are literal. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_escapedchar" class="ntdef" style="color:olive">escapedChar</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\'"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\""</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\\"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\0"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\n"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\r"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\t"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"\u"</span></span> <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span> <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span> <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span> <span class="code-escaped"><a href="#2_hexdigit" class="ntref localref" style="color:maroon">hexdigit</a></span> + )</code></pre> +<p class="p noindent para-continued">In Dafny character or string literals escaped characters may be used +to specify the presence of the delimiting quote, or back slash, +or null, or new line, or carriage return or tab, or the +Unicode character with given hexadecimal representation. + +</p><h4 id="sec-character-constant-token" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.4</span>. </span>Character Constant Token</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_chartoken" class="ntdef" style="color:olive">charToken</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"'"</span></span> ( <span class="code-escaped"><a href="#2_charchar" class="ntref localref" style="color:maroon">charChar</a></span> | <span class="code-escaped"><a href="#2_escapedchar" class="ntref localref" style="color:maroon">escapedChar</a></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"'"</span></span> </code></pre> +<p class="p noindent para-continued">A character constant is enclosed by “'” and includes either a character +from the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_charchar" class="ntref localref" style="color:maroon">charChar</a></span></code> set, or an escaped character. Note that although Unicode +letters are not allowed in Dafny identifiers, Dafny does support Unicode +in its character and string constants and in its data. A character +constant has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">char</span></code>. +</p><h4 id="sec-string-constant-token" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.1.5</span>. </span>String Constant Token</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_stringtoken" class="ntdef" style="color:olive">stringToken</span></span> = + <span style="color:maroon">'"'</span> { <span class="code-escaped"><a href="#2_stringchar" class="ntref localref" style="color:maroon">stringChar</a></span> | <span class="code-escaped"><a href="#2_escapedchar" class="ntref localref" style="color:maroon">escapedChar</a></span> } <span style="color:maroon">'"'</span> + | <span style="color:maroon">'@'</span> <span style="color:maroon">'"'</span> { <span class="code-escaped"><a href="#2_verbatimstringchar" class="ntref localref" style="color:maroon">verbatimStringChar</a></span> | <span style="color:maroon">'"'</span> <span style="color:maroon">'"'</span> } <span style="color:maroon">'"'</span></code></pre> +<p class="p noindent para-continued">A string constant is either a normal string constant or a verbatim string constant. +A normal string constant is enclosed by ‘"’ and can contain characters from the +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_stringchar" class="ntref localref" style="color:maroon">stringChar</a></span></code> set and escapes. +</p> +<p class="p indent">A verbatim string constant is enclosed between ‘@"’ and ‘"’ and can +consists of any characters (including newline characters) except that two +successive double quotes give a way to escape one quote character inside +the string. +</p><h3 id="sec-low-level-grammar-productions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">1.2</span>. </span>Low Level Grammar Productions</h3><h4 id="sec-identifier-variations" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.2.0</span>. </span>Identifier Variations</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_ident" class="ntdef" style="color:olive">Ident</span></span> = <span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span> </code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span></code> non-terminal is just an <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span></code> token and represents an ordinary +identifier. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_dotsuffix" class="ntdef" style="color:olive">DotSuffix</span></span> = + ( <span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span> | <span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"requires"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"reads"</span></span> ) </code></pre> +<p class="p noindent para-continued">When using the <em class="em-low1">dot</em> notation to denote a component of a compound entity +the token following the “.”, in addition to being an identifier, +can also be a natural number, or one of the keywords <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code>. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">Digits can be used to name fields of classes and destructors of +datatypes. For example, the built-in tuple datatypes have destructors +named 0, 1, 2, etc. Note that as a field or destructor name, internal +underscores matter, so 10 is different from 1_0. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m.<span style="color:purple">requires</span></code> is used to denote the precondition for method m. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m.<span style="color:purple">reads</span></code> is used to denote the things that method m may read. +</li></ul> + +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_nousident" class="ntdef" style="color:olive">NoUSIdent</span></span> = <span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span> - <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"_"</span></span> { <span class="code-escaped"><a href="#2_idchar" class="ntref localref" style="color:maroon">idChar</a></span> }</code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span></code> is an identifier except that identifiers with a <strong class="strong-star2">leading</strong> +underscore are not allowed. The names of user-defined entities are +required to be <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span></code>s. We introduce more mnemonic names +for these below (e.g. <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classname" class="ntref localref" style="color:maroon">ClassName</a></span></code>). +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_wildident" class="ntdef" style="color:olive">WildIdent</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"_"</span></span> </code></pre> +<p class="p noindent para-continued">Identifier, disallowing leading underscores, except the “wildcard” +identifier “_”. When “_” appears it is replaced by a unique generated +identifier distinct from user identifiers. +</p><h4 id="sec-nousident-synonyms" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.2.1</span>. </span>NoUSIdent Synonyms</h4> +<p class="p noindent">In the productions for the declaration of user-defined entities the name of the +user-defined entity is required to be an identifier that does not start +with an underscore, i.e., a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span></code>. To make the productions more +mnemonic, we introduce the following synonyms for <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span></code>. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_modulename" class="ntdef" style="color:olive">ModuleName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_classname" class="ntdef" style="color:olive">ClassName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_traitname" class="ntdef" style="color:olive">TraitName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_datatypename" class="ntdef" style="color:olive">DatatypeName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_datatypemembername" class="ntdef" style="color:olive">DatatypeMemberName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_newtypename" class="ntdef" style="color:olive">NewtypeName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_numerictypename" class="ntdef" style="color:olive">NumericTypeName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_synonymtypename" class="ntdef" style="color:olive">SynonymTypeName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_iteratorname" class="ntdef" style="color:olive">IteratorName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_typevariablename" class="ntdef" style="color:olive">TypeVariableName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_methodname" class="ntdef" style="color:olive">MethodName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_functionname" class="ntdef" style="color:olive">FunctionName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_predicatename" class="ntdef" style="color:olive">PredicateName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_copredicatename" class="ntdef" style="color:olive">CopredicateName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_labelname" class="ntdef" style="color:olive">LabelName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_attributename" class="ntdef" style="color:olive">AttributeName</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> +<span class="code-escaped"><span id="1_fieldident" class="ntdef" style="color:olive">FieldIdent</span></span> = <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_fieldident" class="ntref localref" style="color:maroon">FieldIdent</a></span></code> is one of the ways to identify a field. The other is +using digits. +</p><h4 id="sec-qualified-names" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.2.2</span>. </span>Qualified Names</h4> +<p class="p noindent">A qualified name starts with the name of the top-level entity and then is followed by +zero or more <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dotsuffix" class="ntref localref" style="color:maroon">DotSuffix</a></span></code>s which denote a component. Examples: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Module.MyType1</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MyTuple.<span class="constant" style="color:purple">1</span></code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MyMethod.<span style="color:purple">requires</span></code> +</li></ul> + +<p class="p noindent">The grammar does not actually have a production for qualified names +except in the special case of a qualified name that is known to be +a module name, i.e. a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span></code>. +</p><h4 id="sec-identifier-type-combinations" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.2.3</span>. </span>Identifier-Type Combinations</h4> +<p class="p noindent">In this section, we describe some nonterminals that combine an identifier and a type. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_identtype" class="ntdef" style="color:olive">IdentType</span></span> = <span class="code-escaped"><a href="#1_wildident" class="ntref localref" style="color:maroon">WildIdent</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span></code></pre> +<p class="p noindent para-continued">In Dafny, a variable or field is typically declared by giving its name followed by +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_colon" class="ntref localref" style="color:maroon">colon</a></span></code> and its type. An <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_identtype" class="ntref localref" style="color:maroon">IdentType</a></span></code> is such a construct. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_gidenttype" class="ntdef" style="color:olive">GIdentType</span></span>(allowGhostKeyword) = [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> ] <span class="code-escaped"><a href="#1_identtype" class="ntref localref" style="color:maroon">IdentType</a></span></code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_gidenttype" class="ntref localref" style="color:maroon">GIdentType</a></span></code> is a typed entity declaration optionally preceded by “ghost”. The <em class="em-low1">ghost</em> +qualifier means the entity is only used during verification but not in the generated code. +Ghost variables are useful for abstractly representing internal state in specifications. +If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowGhostKeyword</code> is false then “ghost” is not allowed. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_localidenttypeoptional" class="ntdef" style="color:olive">LocalIdentTypeOptional</span></span> = <span class="code-escaped"><a href="#1_wildident" class="ntref localref" style="color:maroon">WildIdent</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> ] </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_localidenttypeoptional" class="ntref localref" style="color:maroon">LocalIdentTypeOptional</a></span></code> is used when declaring local variables. In +such a case a value may be specified for the variable in which case the +type may be omitted because it can be inferred from the initial value. +The initial value value may also be omitted. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_identtypeoptional" class="ntdef" style="color:olive">IdentTypeOptional</span></span> = <span class="code-escaped"><a href="#1_wildident" class="ntref localref" style="color:maroon">WildIdent</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> ] </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span></code> is typically used in a context where the type of the identifier +may be inferred from the context. Examples are in pattern matching or quantifiers. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_typeidentoptional" class="ntdef" style="color:olive">TypeIdentOptional</span></span> = [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> ] ( <span class="code-escaped"><a href="#1_nousident" class="ntref localref" style="color:maroon">NoUSIdent</a></span> | <span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> ] <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span></code></pre> +<p class="p noindent para-continued"><code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_typeidentoptional" class="ntref localref" style="color:maroon">TypeIdentOptional</a></span></code>s are used in <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_formalsoptionalids" class="ntref localref" style="color:maroon">FormalsOptionalIds</a></span></code>. This represents situations +where a type is given but there may not be an identifier. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_formalsoptionalids" class="ntdef" style="color:olive">FormalsOptionalIds</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [<span style="color:teal">TypeIdentOptional</span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_typeidentoptional" class="ntref localref" style="color:maroon">TypeIdentOptional</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_formalsoptionalids" class="ntref localref" style="color:maroon">FormalsOptionalIds</a></span></code> is a formal parameter list in which the types are required +but the names of the parameters is optional. This is used in algebraic +datatype definitions. +</p><h4 id="sec-numeric-literals" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">1.2.4</span>. </span>Numeric Literals</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_nat" class="ntdef" style="color:olive">Nat</span></span> = ( <span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span> | <span class="code-escaped"><a href="#2_hexdigits" class="ntref localref" style="color:maroon">hexdigits</a></span> ) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_nat" class="ntref localref" style="color:maroon">Nat</a></span></code> represents a natural number expressed in either decimal or hexadecimal. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_dec" class="ntdef" style="color:olive">Dec</span></span> = (decimaldigits ) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dec" class="ntref localref" style="color:maroon">Dec</a></span></code> represents a decimal fraction literal. +</p><h2 id="sec-programs" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">2</span>. </span>Programs</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_dafny" class="ntdef" style="color:olive">Dafny</span></span> = { <span class="code-escaped"><a href="#1_includedirective_" class="ntref localref" style="color:maroon">IncludeDirective_</a></span> } { <span class="code-escaped"><a href="#1_topdecl" class="ntref localref" style="color:maroon">TopDecl</a></span> } <span class="code-escaped"><a href="#1_eof" class="ntref localref" style="color:maroon">EOF</a></span> </code></pre> +<p class="p noindent para-continued">At the top level, a Dafny program (stored as files with extension <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.dfy</code>) +is a set of declarations. The declarations introduce (module-level) +methods and functions, as well as types (classes, traits, inductive and +co-inductive datatypes, new_types, type synonyms, opaque types, and +iterators) and modules, where the order of introduction is irrelevant. A +class also contains a set of declarations, introducing fields, methods, +and functions. +</p> +<p class="p indent">When asked to compile a program, Dafny looks for the existence of a +Main() method. If a legal Main() method is found, the compiler will emit +a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.EXE</code>; otherwise, it will emit a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.DLL</code>. +</p> +<p class="p indent"> (If there is more than one Main(), Dafny will try to emit an .EXE, but + this may cause the C# compiler to complain. One could imagine improving + this functionality so that Dafny will produce a polite error message in + this case.) +</p> +<p class="p indent">In order to be a legal Main() method, the following must be true: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">The method takes no parameters +</li> +<li class="li ul-li list-star-li compact-li">The method is not a ghost method +</li> +<li class="li ul-li list-star-li compact-li">The method has no requires clause +</li> +<li class="li ul-li list-star-li compact-li">The method has no modifies clause +</li> +<li class="li ul-li list-star-li compact-li">If the method is an instance (that is, non-static) method in a class, +then the enclosing class must not declare any constructor +</li></ul> + +<p class="p noindent">Note, however, that the following are allowed: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">The method is allowed to be an instance method as long as the enclosing +class does not declare any constructor. In this case, the runtime +system will allocate an object of the enclosing class and will invoke +Main() on it. +</li> +<li class="li ul-li list-star-li compact-li">The method is allowed to have <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">ensures</span></code> clauses +</li> +<li class="li ul-li list-star-li compact-li">The method is allowed to have <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> clauses, including a +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span> *</code>. (If Main() has a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span> *</code>, then its execution may +go on forever, but in the absence of a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span> *</code> on Main(), Dafny +will have verified that the entire execution will eventually +terminate.) +</li></ul> + +<p class="p noindent">An invocation of Dafny may specify a number of source files. +Each Dafny file follows the grammar of the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dafny" class="ntref localref" style="color:maroon">Dafny</a></span></code> non-terminal. +</p> +<p class="p indent">It consists of a sequence of optional <em class="em-low1">include</em> directives followed by top +level declarations followed by the end of the file. +</p><h3 id="sec-include-directives" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">2.0</span>. </span>Include Directives</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_includedirective_" class="ntdef" style="color:olive">IncludeDirective_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"include"</span></span> <span class="code-escaped"><a href="#2_stringtoken" class="ntref localref" style="color:maroon">stringToken</a></span> </code></pre> +<p class="p noindent para-continued">Include directives have the form <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"include"</span></span> <span class="code-escaped"><a href="#2_stringtoken" class="ntref localref" style="color:maroon">stringToken</a></span></code> where +the string token is either a normal string token or a +verbatim string token. The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_stringtoken" class="ntref localref" style="color:maroon">stringToken</a></span></code> is interpreted as the name of +a file that will be included in the Dafny source. These included +files also obey the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dafny" class="ntref localref" style="color:maroon">Dafny</a></span></code> grammar. Dafny parses and processes the +transitive closure of the original source files and all the included files, +but will not invoke the verifier on these unless they have been listed +explicitly on the command line. +</p><h3 id="sec-top-level-declarations" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">2.1</span>. </span>Top Level Declarations</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_topdecl" class="ntdef" style="color:olive">TopDecl</span></span> = { { <span class="code-escaped"><a href="#1_declmodifier" class="ntref localref" style="color:maroon">DeclModifier</a></span> } + ( <span class="code-escaped"><a href="#1_submoduledecl" class="ntref localref" style="color:maroon">SubModuleDecl</a></span> + | <span class="code-escaped"><a href="#1_classdecl" class="ntref localref" style="color:maroon">ClassDecl</a></span> + | <span class="code-escaped"><a href="#1_datatypedecl" class="ntref localref" style="color:maroon">DatatypeDecl</a></span> + | <span class="code-escaped"><a href="#1_newtypedecl" class="ntref localref" style="color:maroon">NewtypeDecl</a></span> + | <span class="code-escaped"><a href="#1_synonymtypedecl" class="ntref localref" style="color:maroon">SynonymTypeDecl</a></span> + | <span class="code-escaped"><a href="#1_iteratordecl" class="ntref localref" style="color:maroon">IteratorDecl</a></span> + | <span class="code-escaped"><a href="#1_traitdecl" class="ntref localref" style="color:maroon">TraitDecl</a></span> + | <span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span>(moduleLevelDecl: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + } </code></pre> +<p class="p noindent para-continued">Top-level declarations may appear either at the top level of a Dafny file, +or within a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_submoduledecl" class="ntref localref" style="color:maroon">SubModuleDecl</a></span></code>. A top-level declaration is one of the following +types of declarations which are described later. +</p> +<p class="p indent">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classdecl" class="ntref localref" style="color:maroon">ClassDecl</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_datatypedecl" class="ntref localref" style="color:maroon">DatatypeDecl</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_newtypedecl" class="ntref localref" style="color:maroon">NewtypeDecl</a></span></code>, +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_synonymtypedecl" class="ntref localref" style="color:maroon">SynonymTypeDecl</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_iteratordecl" class="ntref localref" style="color:maroon">IteratorDecl</a></span></code>, and <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_traitdecl" class="ntref localref" style="color:maroon">TraitDecl</a></span></code> declarations are +type declarations and are describe in Section <a href="#sec-types" title="5. Types" class="localref" style="target-element:h1"><span class="heading-label">5</span></a>. Ordinarily +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span></code>s appear in class declarations but they can also +appear at the top level. In that case they are included as part of an +implicit top-level class and are implicitly <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code> (but cannot be +declared as static). In addition a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span></code> that appears at +the top level cannot be a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_fielddecl" class="ntref localref" style="color:maroon">FieldDecl</a></span></code>. +</p><h3 id="sec-declaration-modifiers" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">2.2</span>. </span>Declaration Modifiers</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_declmodifier" class="ntdef" style="color:olive">DeclModifier</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"abstract"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"static"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"protected"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"extern"</span></span> [ <span class="code-escaped"><a href="#2_stringtoken" class="ntref localref" style="color:maroon">stringToken</a></span>] + )</code></pre> +<p class="p noindent para-continued">Top level declarations may be preceded by zero or more declaration +modifiers. Not all of these are allowed in all contexts. +</p> +<p class="p indent">The “abstract” modifiers may only be used for module declarations. +An abstract module can leave some entities underspecified. +Abstract modules are not compiled to C#. +</p> +<p class="p indent">The ghost modifier is used to mark entities as being used for +specification only, not for compilation to code. +</p> +<p class="p indent">The static modifier is used for class members that that +are associated with the class as a whole rather than with +an instance of the class. +</p> +<p class="p indent">The protected modifier is used to control the visibility of the +body of functions. +</p> +<p class="p indent">The extern modifier is used to alter the CompileName of +entities. The CompileName is the name for the entity +when translating to Boogie or C#. +</p> +<p class="p indent">The following table shows modifiers that are available +for each of the kinds of declaration. In the table +we use already-ghost to denote that the item is not +allowed to have the ghost modifier because it is already +implicitly ghost. +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> Declaration </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> allowed modifiers </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> module </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> abstract </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> class </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> extern </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> trait </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> - </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> datatype or codatatype </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> - </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> field </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> ghost </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="6" data-col="1"> newtype </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> - </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="7" data-col="1"> synonym types </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="7" data-col="2"> - </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="8" data-col="1"> iterators </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="8" data-col="2"> - </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="9" data-col="1"> method </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="9" data-col="2"> ghost static extern </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="10" data-col="1"> lemma, colemma, comethod </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="10" data-col="2"> already-ghost static protected </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="11" data-col="1"> inductive lemma </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="11" data-col="2"> already-ghost static </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="12" data-col="1"> constructor </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="12" data-col="2"> - </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="13" data-col="1"> function (non-method) </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="13" data-col="2"> already-ghost static protected </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="14" data-col="1"> function method </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="14" data-col="2"> already-ghost static protected extern </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="15" data-col="1"> predicate (non-method) </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="15" data-col="2"> already-ghost static protected </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="16" data-col="1"> predicate method </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="16" data-col="2"> already-ghost static protected extern </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="17" data-col="1"> inductive predicate </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="17" data-col="2"> already-ghost static protected </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="18" data-col="1"> copredicate </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="18" data-col="2"> already-ghost static protected </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="18" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="18" data-col="2"></td></tr></tbody></table><h2 id="sec-modules" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">3</span>. </span>Modules</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_submoduledecl" class="ntdef" style="color:olive">SubModuleDecl</span></span> = ( <span class="code-escaped"><a href="#1_moduledefinition_" class="ntref localref" style="color:maroon">ModuleDefinition_</a></span> | <span class="code-escaped"><a href="#1_moduleimport_" class="ntref localref" style="color:maroon">ModuleImport_</a></span> ) </code></pre> +<p class="p noindent para-continued">Structuring a program by breaking it into parts is an important part of +creating large programs. In Dafny, this is accomplished via <em class="em-low1">modules</em>. +Modules provide a way to group together related types, classes, methods, +functions, and other modules together, as well as control the scope of +declarations. Modules may import each other for code reuse, and it is +possible to abstract over modules to separate an implementation from an +interface. +</p><h3 id="sec-declaring-new-modules" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.0</span>. </span>Declaring New Modules</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_moduledefinition_" class="ntdef" style="color:olive">ModuleDefinition_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"module"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_modulename" class="ntref localref" style="color:maroon">ModuleName</a></span> + [ [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"exclusively"</span></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"refines"</span></span> <span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><a href="#1_topdecl" class="ntref localref" style="color:maroon">TopDecl</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> +<span class="code-escaped"><span id="1_qualifiedmodulename" class="ntdef" style="color:olive">QualifiedModuleName</span></span> = <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"."</span></span> <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> } </code></pre> +<p class="p noindent para-continued">A qualified name that is known to refer to a module. +</p> +<p class="p indent">A new module is declared with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">module</span></code> keyword, followed by the name +of the new module, and a pair of curly braces ({}) enclosing the body +of the module: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + ... +}</code></pre> +<p class="p noindent para-continued">A module body can consist of anything that you could put at the top +level. This includes classes, datatypes, types, methods, functions, etc. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">class</span> C { + <span style="color:blue">var</span> f: <span style="color:teal">int</span> + <span style="color:blue">method</span> m() + } + <span style="color:blue">datatype</span> Option = A(<span style="color:teal">int</span>) | B(<span style="color:teal">int</span>) + <span style="color:blue">type</span> T + <span style="color:blue">method</span> m() + <span style="color:blue">function</span> f(): <span style="color:teal">int</span> +}</code></pre> +<p class="p noindent para-continued">You can also put a module inside another, in a nested fashion: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">module</span> Helpers { + <span style="color:blue">class</span> C { + <span style="color:blue">method</span> doIt() + <span style="color:blue">var</span> f: <span style="color:teal">int</span> + } + } +}</code></pre> +<p class="p noindent para-continued">Then you can refer to the members of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code> module within the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mod</code> module by prefixing them with “Helpers.”. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">module</span> Helpers { ... } + <span style="color:blue">method</span> m() { + <span style="color:blue">var</span> x <span style="color:blue">:=</span> <span style="color:blue">new</span> Helpers.C; + x.doIt(); + x.f <span style="color:blue">:=</span> <span class="constant" style="color:purple">4</span>; + } +}</code></pre> +<p class="p noindent para-continued">Methods and functions defined at the module level are available like +classes, with just the module name prefixing them. They are also +available in the methods and functions of the classes in the same +module. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">module</span> Helpers { + <span style="color:blue">function</span> <span style="color:blue">method</span> addOne(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> { + n + <span class="constant" style="color:purple">1</span> + } + } + <span style="color:blue">method</span> m() { + <span style="color:blue">var</span> x <span style="color:blue">:=</span> <span class="constant" style="color:purple">5</span>; + x <span style="color:blue">:=</span> Helpers.addOne(x); <span style="color:darkgreen">// x is now 6</span> + } +}</code></pre><h3 id="sec-importing-modules" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.1</span>. </span>Importing Modules</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_moduleimport_" class="ntdef" style="color:olive">ModuleImport_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"import"</span></span> [<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"opened"</span></span> ] <span class="code-escaped"><a href="#1_modulename" class="ntref localref" style="color:maroon">ModuleName</a></span> + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"="</span></span> <span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"as"</span></span> <span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span> [<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"default"</span></span> <span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span> ] + ] + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> ] </code></pre> +<p class="p noindent para-continued">Declaring new submodules is useful, but sometimes you want to refer to +things from an existing module, such as a library. In this case, you +can <em class="em-low1">import</em> one module into another. This is done via the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span></code> +keyword, and there are a few different forms, each of which has a +different meaning. The simplest kind is the concrete import, and has +the form <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span> A = B</code>. This declaration creates a reference to the +module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> (which must already exist), and binds it to the new name +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code>. Note this new name, i.e. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code>, is only bound in the module containing +the import declaration; it does not create a global alias. For +example, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code> was defined outside of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mod</code>, then we could import +it: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Helpers { + ... +} +<span style="color:blue">module</span> Mod { + <span style="color:blue">import</span> A = Helpers + <span style="color:blue">method</span> m() { + <span style="color:blue">assert</span> A.addOne(<span class="constant" style="color:purple">5</span>) == <span class="constant" style="color:purple">6</span>; + } +}</code></pre> +<p class="p noindent para-continued">Note that inside <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m()</code>, we have to use <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> instead of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code>, as we bound +it to a different name. The name <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code> is not available inside <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m()</code>, +as only names that have been bound inside <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mod</code> are available. In order +to use the members from another module, it either has to be declared +there with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">module</span></code> or imported with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span></code>. +</p> +<p class="p indent">We don't have to give <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code> a new name, though, if we don't want +to. We can write <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span> Helpers = Helpers</code> if we want to, and Dafny +even provides the shorthand <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span> Helpers</code> for this behavior. You +can't bind two modules with the same name at the same time, so +sometimes you have to use the = version to ensure the names do not +clash. +</p> +<p class="p indent">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_qualifiedmodulename" class="ntref localref" style="color:maroon">QualifiedModuleName</a></span></code> in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_moduleimport_" class="ntref localref" style="color:maroon">ModuleImport_</a></span></code> starts with a +sibling module of the importing module, or with a submodule of the +importing module. There is no wya to refer to the parent module, only +sibling modules (and their submodules). +</p><h3 id="sec-opening-modules" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.2</span>. </span>Opening Modules</h3> +<p class="p noindent">Sometimes, prefixing the members of the module you imported with the +name is tedious and ugly, even if you select a short name when +importing it. In this case, you can import the module as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">opened</span></code>, +which causes all of its members to be available without adding the +module name. The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">opened</span></code> keyword must immediately follow <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span></code>, if it +is present. For example, we could write the previous example as: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">import</span> <span style="color:blue">opened</span> Helpers + <span style="color:blue">method</span> m() { + <span style="color:blue">assert</span> addOne(<span class="constant" style="color:purple">5</span>) == <span class="constant" style="color:purple">6</span>; + } +}</code></pre> +<p class="p noindent para-continued">When opening modules, the newly bound members will have low priority, +so they will be hidden by local definitions. This means if you define +a local function called <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">addOne</code>, the function from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Helpers</code> will no +longer be available under that name. When modules are opened, the +original name binding is still present however, so you can always use +the name that was bound to get to anything that is hidden. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod { + <span style="color:blue">import</span> <span style="color:blue">opened</span> Helpers + <span style="color:blue">function</span> addOne(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> { + n - <span class="constant" style="color:purple">1</span> + } + <span style="color:blue">method</span> m() { + <span style="color:blue">assert</span> addOne(<span class="constant" style="color:purple">5</span>) == <span class="constant" style="color:purple">6</span>; <span style="color:darkgreen">// this is now false,</span> + <span style="color:darkgreen">// as this is the function just defined</span> + <span style="color:blue">assert</span> Helpers.addOne(<span class="constant" style="color:purple">5</span>) == <span class="constant" style="color:purple">6</span>; <span style="color:darkgreen">// this is still true</span> + } +}</code></pre> +<p class="p noindent para-continued">If you open two modules that both declare members with the same name, +then neither member can be referred to without a module prefix, as it +would be ambiguous which one was meant. Just opening the two modules +is not an error, however, as long as you don't attempt to use members +with common names. The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">opened</span></code> keyword can be used with any kind of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span></code> declaration, including the module abstraction form. +</p><h3 id="sec-module-abstraction" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.3</span>. </span>Module Abstraction</h3> +<p class="p noindent">Sometimes, using a specific implementation is unnecessary; instead, +all that is needed is a module that implements some interface. In +that case, you can use an <em class="em-low1">abstract</em> module import. In Dafny, this is +written <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span> A <span style="color:blue">as</span> B</code>. This means bind the name <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> as before, but +instead of getting the exact module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>, you get any module which is a +<em class="em-low1">adheres</em> of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>. Typically, the module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> may have abstract type +definitions, classes with bodyless methods, or otherwise be unsuitable +to use directly. Because of the way refinement is defined, any +refinement of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> can be used safely. For example, if we start with: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Interface { + <span style="color:blue">function</span> <span style="color:blue">method</span> addSome(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> + <span style="color:purple">ensures</span> addSome(n) > n +} +<span style="color:blue">module</span> Mod { + <span style="color:blue">import</span> A <span style="color:blue">as</span> Interface + <span style="color:blue">method</span> m() { + <span style="color:blue">assert</span> <span class="constant" style="color:purple">6</span> <= A.addSome(<span class="constant" style="color:purple">5</span>); + } +}</code></pre> +<p class="p noindent para-continued">then we can be more precise if we know that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">addSome</code> actually adds +exactly one. The following module has this behavior. Further, the +postcondition is stronger, so this is actually a refinement of the +Interface module. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Implementation { + <span style="color:blue">function</span> <span style="color:blue">method</span> addSome(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> + <span style="color:purple">ensures</span> addSome(n) == n + <span class="constant" style="color:purple">1</span> + { + n + <span class="constant" style="color:purple">1</span> + } +}</code></pre> +<p class="p noindent para-continued">We can then substitute <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Implementation</code> for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> in a new module, by +declaring a refinement of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mod</code> which defines <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Implementation</code>. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Mod2 <span style="color:blue">refines</span> Mod { + <span style="color:blue">import</span> A = Implementation + ... +}</code></pre> +<p class="p noindent para-continued">You can also give an implementation directly, without introducing a +refinement, by giving a default to the abstract import: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> Interface { + <span style="color:blue">function</span> <span style="color:blue">method</span> addSome(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> + <span style="color:purple">ensures</span> addSome(n) > n +} +<span style="color:blue">module</span> Mod { + <span style="color:blue">import</span> A <span style="color:blue">as</span> Interface <span style="color:blue">default</span> Implementation + <span style="color:blue">method</span> m() { + <span style="color:blue">assert</span> <span class="constant" style="color:purple">6</span> <= A.addSome(<span class="constant" style="color:purple">5</span>); + } +} +<span style="color:blue">module</span> Implementation { + <span style="color:blue">function</span> <span style="color:blue">method</span> addSome(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> + <span style="color:purple">ensures</span> addSome(n) == n + <span class="constant" style="color:purple">1</span> + { + n + <span class="constant" style="color:purple">1</span> + } +} +<span style="color:blue">module</span> Mod2 <span style="color:blue">refines</span> Mod { + <span style="color:blue">import</span> A <span style="color:blue">as</span> Interface <span style="color:blue">default</span> Implementation + ... +}</code></pre> +<p class="p noindent para-continued">Regardless of whether there is a default, the only things known about +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> in this example is that it has a function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">addSome</code> that returns a +strictly bigger result, so even with the default we still can't prove +that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A.addSome(<span class="constant" style="color:purple">5</span>) == <span class="constant" style="color:purple">6</span></code>, only that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">6</span> <= A.addSome(<span class="constant" style="color:purple">5</span>)</code>. +</p> +<p class="p indent">When you refine an abstract import into a concrete one, or giving a +default, Dafny checkes that the concrete module is a +refinement of the abstract one. This means that the methods must have +compatible signatures, all the classes and datatypes with their +constructors and fields in the abstract one must be present in the +concrete one, the specifications must be compatible, etc. +</p><h3 id="sec-module-ordering-and-dependencies" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.4</span>. </span>Module Ordering and Dependencies</h3> +<p class="p noindent">Dafny isn't particular about which order the modules appear in, but +they must follow some rules to be well formed. As a rule of thumb, +there should be a way to order the modules in a program such that each +only refers to things defined <strong class="strong-star2">before</strong> it in the source text. That +doesn't mean the modules have to be given in that order. Dafny will +figure out that order for you, assuming you haven't made any circular +references. For example, this is pretty clearly meaningless: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">import</span> A = B +<span style="color:blue">import</span> B = A</code></pre> +<p class="p noindent para-continued">You can have import statements at the toplevel, and you can import +modules defined at the same level: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">import</span> A = B +<span style="color:blue">method</span> m() { + A.whatever(); +} +<span style="color:blue">module</span> B { ... }</code></pre> +<p class="p noindent para-continued">In this case, everything is well defined because we can put <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> first, +followed by the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> import, and then finally <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m()</code>. If there is no +ordering, then Dafny will give an error, complaining about a cyclic +dependency. +</p> +<p class="p indent">Note that when rearranging modules and imports, they have to be kept +in the same containing module, which disallows some pathological +module structures. Also, the imports and submodules are always +considered to be first, even at the toplevel. This means that the +following is not well formed: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> doIt() { } +<span style="color:blue">module</span> M { + <span style="color:blue">method</span> m() { + doIt(); + } +}</code></pre> +<p class="p noindent para-continued">because the module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> must come before any other kind of members, such +as methods. To define global functions like this, you can put them in +a module (called <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Globals</code>, say) and open it into any module that needs +its functionality. Finally, if you import via a path, such as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">import</span> A += B.C</code>, then this creates a dependency of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> on <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>, as we need to know +what <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> is (is it abstract or concrete, or a refinement?). +</p><h3 id="sec-name-resolution" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">3.5</span>. </span>Name Resolution</h3> +<p class="p noindent">When Dafny sees something like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A<T>.B<U>.C<V></code>, how does it know what each part +refers to? The process Dafny uses to determine what identifier +sequences like this refer to is name resolution. Though the rules may +seem complex, usually they do what you would expect. Dafny first looks +up the initial identifier. Depending on what the first identifier +refers to, the rest of the identifier is looked up in the appropriate +context. +</p> +<p class="p indent">In terms of the grammar, sequences like the above are represented as +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span></code> followed by 0 or more <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code>es. A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code> is +more general and the form shown above would be for when the +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code> is an <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_augmenteddotsuffix_" class="ntref localref" style="color:maroon">AugmentedDotSuffix_</a></span></code>. +</p> +<p class="p indent">The resolution is different depending on whether it is in +an expression context or a type context. +</p><h4 id="sec-expression-context-name-resolution" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">3.5.0</span>. </span>Expression Context Name Resolution</h4> +<p class="p noindent">The leading <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span></code> is resolved using the first following +rule that succeeds. +</p> +<ol class="ol loose" start="0"> +<li class="li ol-li loose-li"> +<p>Local variables, parameters and bound variables. These are things like +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">y</code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">var</span> x;, ... <span style="color:blue">returns</span> (y: <span style="color:teal">int</span>)</code>, and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span> i :: ....</code> The declaration chosen is the match from the +innermost matching scope. +</p></li> +<li class="li ol-li loose-li"> +<p>If in a class, try to match a member of the class. If the member that +is found is not static an implicit <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code> is inserted. This works for +fields, functions, and methods of the current class (if in a static +context, then only static methods and functions are allowed). You can +refer to fields of the current class either as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span>.f</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code>, +assuming of course that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> hasn't be hidden by one of the above. You +can always prefix this if needed, which cannot be hidden. (Note, a +field whose name is a string of digits must always have some prefix.) +</p></li> +<li class="li ol-li loose-li"> +<p>If there is no <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code>, then look for a datatype constructor, if +unambiguous. Any datatypes that don't need qualification (so the +datatype name itself doesn't need a prefix), and also have a uniquely +named constructor, can be referred to just by its name. So if +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">datatype</span> List = Cons(List) | Nil</code> is the only datatype that declares +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Cons</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Nil</code> constructors, then you can write <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Cons(Cons(Nil))</code>. +If the constructor name is not unique, then you need to prefix it with +the name of the datatype (for example <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">List.Cons(List.Nil)))</code>. This is +done per constructor, not per datatype. +</p></li> +<li class="li ol-li loose-li"> +<p>Look for a member of the enclosing module. +</p></li> +<li class="li ol-li loose-li"> +<p>Module-level (static) functions and methods +</p></li></ol> + +<p class="p noindent">TODO: Not sure about the following paragraph. +Opened modules are treated at each level, after the declarations in the +current module. Opened modules only affect steps 2, 3 and 5. If a +ambiguous name is found, an error is generated, rather than continuing +down the list. After the first identifier, the rules are basically the +same, except in the new context. For example, if the first identifier is +a module, then the next identifier looks into that module. Opened modules +only apply within the module it is opened into. When looking up into +another module, only things explicitly declared in that module are +considered. +</p> +<p class="p indent">To resolve expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E.id</code>: +</p> +<p class="p indent">First resolve expression E and any type arguments. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> resolved to a module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code>: + +<ol class="ol compact" start="0"> +<li class="li ol-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E.id<T></code> is not followed by any further suffixes, look for +unambiguous datatype constructor. +</li> +<li class="li ol-li compact-li">Member of module M: a sub-module (including submodules of imports), +class, datatype, etc. +</li> +<li class="li ol-li compact-li">Static function or method. +</li></ol></li> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> denotes a type: + +<ol class="ol compact" start="3"> +<li class="li ol-li compact-li">Look up id as a member of that type +</li></ol></li> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> denotes an expression: + +<ol class="ol compact" start="4"> +<li class="li ol-li compact-li">Let T be the type of E. Look up id in T. +</li></ol></li></ul> +<h4 id="sec-type-context-name-resolution" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">3.5.1</span>. </span>Type Context Name Resolution</h4> +<p class="p noindent">In a type context the priority of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span></code> resolution is: +</p> +<ol class="ol loose"> +<li class="li ol-li loose-li"> +<p>Type parameters. +</p></li> +<li class="li ol-li loose-li"> +<p>Member of enclosing module (type name or the name of a module). +</p></li></ol> + +<p class="p noindent">To resolve expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E.id</code>: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> resolved to a module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code>: + +<ol class="ol compact" start="0"> +<li class="li ol-li compact-li">Member of module M: a sub-module (including submodules of imports), +class, datatype, etc. +</li></ol></li> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> denotes a type: + +<ol class="ol compact"> +<li class="li ol-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowDanglingDotName</code>: Return the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> and the given <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E.id</code>, +letting the caller try to make sense of the final dot-name. +TODO: I don't under this sentence. What is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowDanglingDotName</code>? +</li></ol></li></ul> +<h2 id="sec-specifications" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">4</span>. </span>Specifications</h2> +<p class="p noindent">Specifications describe logical properties of Dafny methods, functions, +lambdas, iterators and loops. They specify preconditions, postconditions, +invariants, what memory locations may be read or modified, and +termination information by means of <em class="em-low1">specification clauses</em>. +For each kind of specification zero or more specification +clauses (of the type accepted for that type of specification) +may be given, in any order. +</p> +<p class="p indent">We document specifications at these levels: +</p> +<ul class="ul list-dash compact"> +<li class="li ul-li list-dash-li compact-li">At the lowest level are the various kinds of specification clauses, +e.g. a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_requiresclause_" class="ntref localref" style="color:maroon">RequiresClause_</a></span></code>. +</li> +<li class="li ul-li list-dash-li compact-li">Next are the specifications for entities that need them, +e.g. a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methodspec" class="ntref localref" style="color:maroon">MethodSpec</a></span></code>. +</li> +<li class="li ul-li list-dash-li compact-li">At the top level are the entity declarations that include +the specifications, e.g. <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methoddecl" class="ntref localref" style="color:maroon">MethodDecl</a></span></code>. +</li></ul> + +<p class="p noindent">This section documents the first two of these in a bottom-up manner. +We first document the clauses and then the specifications +that use them. +</p><h3 id="sec-specification-clauses" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.0</span>. </span>Specification Clauses</h3><h4 id="sec-requires-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.0</span>. </span>Requires Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_requiresclause_" class="ntdef" style="color:olive">RequiresClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"requires"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>)</code></pre> +<p class="p noindent para-continued">The <strong class="strong-star2">requires</strong> clauses specify preconditions for methods, +functions, lambda expressions and iterators. Dafny checks +that the preconditions are met at all call sites. The +callee may then assume the preconditions hold on entry. +</p> +<p class="p indent">If no <strong class="strong-star2">requires</strong> clause is specified it is taken to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>. +</p> +<p class="p indent">If more than one <strong class="strong-star2">requires</strong> clause is given, then the +precondition is the conjunction of all of the expressions +from all of the <strong class="strong-star2">requires</strong> clauses. +</p><h4 id="sec-ensures-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.1</span>. </span>Ensures Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_ensuresclause_" class="ntdef" style="color:olive">EnsuresClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ensures"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) +<span class="code-escaped"><span id="1_forallensuresclause_" class="ntdef" style="color:olive">ForAllEnsuresClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ensures"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) +<span class="code-escaped"><span id="1_functionensuresclause_" class="ntdef" style="color:olive">FunctionEnsuresClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ensures"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>)</code></pre> +<p class="p noindent para-continued">An <strong class="strong-star2">ensures</strong> clause specifies the post condition for a +method, function or iterator. +</p> +<p class="p indent">If no <strong class="strong-star2">ensures</strong> clause is specified it is taken to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>. +</p> +<p class="p indent">If more than one <strong class="strong-star2">ensures</strong> clause is given, then the +postcondition is the conjunction of all of the expressions +from all of the <strong class="strong-star2">ensures</strong> clauses. +</p> +<p class="p indent">TODO: In the present sources <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functionensuresclause_" class="ntref localref" style="color:maroon">FunctionEnsuresClause_</a></span></code> differs from +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ensuresclause_" class="ntref localref" style="color:maroon">EnsuresClause_</a></span></code> only in that it is not allowed to specify +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span></code>s. This seems like a bug and will likely +be fixed in a future version. +</p><h4 id="sec-decreases-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.2</span>. </span>Decreases Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_decreasesclause_" class="ntdef" style="color:olive">DecreasesClause_</span></span>(allowWildcard, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"decreases"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_decreaseslist" class="ntref localref" style="color:maroon">DecreasesList</a></span>(allowWildcard, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) +<span class="code-escaped"><span id="1_functiondecreasesclause_" class="ntdef" style="color:olive">FunctionDecreasesClause_</span></span>(allowWildcard, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"decreases"</span></span> <span class="code-escaped"><a href="#1_decreaseslist" class="ntref localref" style="color:maroon">DecreasesList</a></span>(allowWildcard, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>)</code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_decreaseslist" class="ntdef" style="color:olive">DecreasesList</span></span>(allowWildcard, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_possiblywildexpression" class="ntref localref" style="color:maroon">PossiblyWildExpression</a></span>(allowLambda) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_possiblywildexpression" class="ntref localref" style="color:maroon">PossiblyWildExpression</a></span>(allowLambda) } </code></pre> +<p class="p noindent para-continued">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowWildcard</code> is false but one of the +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_possiblywildexpression" class="ntref localref" style="color:maroon">PossiblyWildExpression</a></span></code>s is a wild-card, an error is +reported. +</p> +<p class="p indent">TODO: A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functiondecreasesclause_" class="ntref localref" style="color:maroon">FunctionDecreasesClause_</a></span></code> is not allowed to specify +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span></code>s. this will be fixed in a future version. +</p> +<p class="p indent"><strong class="strong-star2">Decreases</strong> clauses are used to prove termination in the +presence of recursion. if more than one <strong class="strong-star2">decreases</strong> clause is given +it is as if a single <strong class="strong-star2">decreases</strong> clause had been given with the +collected list of arguments. That is, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:purple">decreases</span> A, B +<span style="color:purple">decreases</span> C, D</code></pre> +<p class="p noindent para-continued">is equivalent to +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:purple">decreases</span> A, B, C, D</code></pre> +<p class="p noindent para-continued">If any of the expressions in the <strong class="strong-star2">decreases</strong> clause are wild (i.e. “*”) +then proof of termination will be skipped. +</p> +<p class="p indent">Termination metrics in Dafny, which are declared by <strong class="strong-star2">decreases</strong> clauses, +are lexicographic tuples of expressions. At each recursive (or mutually +recursive) call to a function or method, Dafny checks that the effective +<strong class="strong-star2">decreases</strong> clause of the callee is strictly smaller than the effective +<strong class="strong-star2">decreases</strong> clause of the caller. +</p> +<p class="p indent"> What does “strictly smaller” mean? Dafny provides a built-in + well-founded order for every type and, in some cases, between types. For + example, the Boolean “false” is strictly smaller than “true”, the + integer 78 is strictly smaller than 102, the set <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span class="constant" style="color:purple">2</span>,<span class="constant" style="color:purple">5</span>}</code> is strictly + smaller than the set <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span class="constant" style="color:purple">2</span>,<span class="constant" style="color:purple">3</span>,<span class="constant" style="color:purple">5</span>}</code>, and for “s” of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><Color></code> where + <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Color</code> is some inductive datatype, the color <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[<span class="constant" style="color:purple">0</span>]</code> is strictly less than + <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> (provided <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> is nonempty). +</p> +<p class="p indent">What does “effective decreases clause” mean? Dafny always appends a +“top” element to the lexicographic tuple given by the user. This top +element cannot be syntactically denoted in a Dafny program and it never +occurs as a run-time value either. Rather, it is a fictitious value, +which here we will denote \top, such that each value that can ever occur +in a Dafny program is strictly less than \top. Dafny sometimes also +prepends expressions to the lexicographic tuple given by the user. The +effective decreases clause is any such prefix, followed by the +user-provided decreases clause, followed by \top. We said “user-provided +decreases clause”, but if the user completely omits a “decreases” clause, +then Dafny will usually make a guess at one, in which case the effective +decreases clause is any prefix followed by the guess followed by \top. +(If you're using the Dafny IDE in Visual Studio, you can hover the mouse +over the name of a recursive function or method, or the “while” keyword +for a loop, to see the “decreases” clause that Dafny guessed, if any.) +</p> +<p class="p indent">Here is a simple but interesting example: the Fibonacci function. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> Fib(n: <span style="color:teal">nat</span>) : <span style="color:teal">nat</span> +{ + <span style="color:blue">if</span> n < <span class="constant" style="color:purple">2</span> <span style="color:blue">then</span> n <span style="color:blue">else</span> Fib(n-<span class="constant" style="color:purple">2</span>) + Fib(n-<span class="constant" style="color:purple">1</span>) +} +</code></pre> +<p class="p noindent para-continued">In this example, if you hover your mouse over the function name +you will see that Dafny has supplied a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">**<span style="color:purple">decreases</span>** n</code> clause. +</p> +<p class="p indent">Let's take a look at the kind of example where a mysterious-looking +decreases clause like “Rank, 0” is useful. +</p> +<p class="p indent">Consider two mutually recursive methods, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> A(x: <span style="color:teal">nat</span>) +{ + B(x); +} + +<span style="color:blue">method</span> B(x: <span style="color:teal">nat</span>) +{ + <span style="color:blue">if</span> x != <span class="constant" style="color:purple">0</span> { A(x-<span class="constant" style="color:purple">1</span>); } +}</code></pre> +<p class="p noindent para-continued">To prove termination of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>, Dafny needs to have effective +decreases clauses for A and B such that: +</p> +<ul class="ul list-star loose"> +<li class="li ul-li list-star-li loose-li"> +<p>the measure for the callee <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B(x)</code> is strictly smaller than the measure +for the caller <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A(x)</code>, and +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>the measure for the callee <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A(x-<span class="constant" style="color:purple">1</span>)</code> is strictly smaller than the measure +for the caller <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B(x)</code>. +</p></li></ul> + +<p class="p noindent">Satisfying the second of these conditions is easy, but what about the +first? Note, for example, that declaring both <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> with “decreases x” +does not work, because that won't prove a strict decrease for the call +from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A(x)</code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B(x)</code>. +</p> +<p class="p indent">Here's one possibility (for brevity, we will omit the method bodies): +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> A(x: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x, <span class="constant" style="color:purple">1</span> + +<span style="color:blue">method</span> B(x: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x, <span class="constant" style="color:purple">0</span></code></pre> +<p class="p noindent para-continued">For the call from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A(x)</code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B(x)</code>, the lexicographic tuple <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, 0</span><span style="color:maroon">"</span></code> is +strictly smaller than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, 1</span><span style="color:maroon">"</span></code>, and for the call from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B(x)</code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A(x-<span class="constant" style="color:purple">1</span>)</code>, the +lexicographic tuple <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x-1, 1</span><span style="color:maroon">"</span></code> is strictly smaller than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, 0</span><span style="color:maroon">"</span></code>. +</p> +<p class="p indent"> Two things to note: First, the choice of “0” and “1” as the second + components of these lexicographic tuples is rather arbitrary. It could + just as well have been “false” and “true”, respectively, or the sets + <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span class="constant" style="color:purple">2</span>,<span class="constant" style="color:purple">5</span>}</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span class="constant" style="color:purple">2</span>,<span class="constant" style="color:purple">3</span>,<span class="constant" style="color:purple">5</span>}</code>. Second, the keyword <strong class="strong-star2">decreases</strong> often gives rise to + an intuitive English reading of the declaration. For example, you might + say that the recursive calls in the definition of the familiar Fibonacci + function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Fib(n)</code> “decreases n”. But when the lexicographic tuple contains + constants, the English reading of the declaration becomes mysterious and + may give rise to questions like “how can you decrease the constant 0?”. + The keyword is just that—a keyword. It says “here comes a list of + expressions that make up the lexicographic tuple we want to use for the + termination measure”. What is important is that one effective decreases + clause is compared against another one, and it certainly makes sense to + compare something to a constant (and to compare one constant to + another). +</p> +<p class="p indent"> We can simplify things a little bit by remembering that Dafny appends + \top to the user-supplied decreases clause. For the A-and-B example, + this lets us drop the constant from the <strong class="strong-star2">decreases</strong> clause of A: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">method</span> A(x: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x + +<span style="color:blue">method</span> B(x: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x, <span class="constant" style="color:purple">0</span></code></pre> +<p class="p noindent para-continued">The effective decreases clause of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, </span><span style="color:gray">\t</span><span style="color:maroon">op</span><span style="color:maroon">"</span></code> and the effective +decreases clause of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, 0, </span><span style="color:gray">\t</span><span style="color:maroon">op</span><span style="color:maroon">"</span></code>. These tuples still satisfy the two +conditions <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(x, <span class="constant" style="color:purple">0</span>, \top) < (x, \top)</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(x-<span class="constant" style="color:purple">1</span>, \top) < (x, <span class="constant" style="color:purple">0</span>, \top)</code>. And +as before, the constant “0” is arbitrary; anything less than \top (which +is any Dafny expression) would work. +</p> +<p class="p indent">Let's take a look at one more example that better illustrates the utility +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\top</code>. Consider again two mutually recursive methods, call them <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code> +and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code>, representing the recursive counterparts of what iteratively +might be two nested loops: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> Outer(x: <span style="color:teal">nat</span>) +{ + <span style="color:darkgreen">// set y to an arbitrary non-negative integer</span> + <span style="color:blue">var</span> y <span style="color:blue">:|</span> <span class="constant" style="color:purple">0</span> <= y; + Inner(x, y); +} + +<span style="color:blue">method</span> Inner(x: <span style="color:teal">nat</span>, y: <span style="color:teal">nat</span>) +{ + <span style="color:blue">if</span> y != <span class="constant" style="color:purple">0</span> { + Inner(x, y-<span class="constant" style="color:purple">1</span>); + } <span style="color:blue">else</span> <span style="color:blue">if</span> x != <span class="constant" style="color:purple">0</span> { + Outer(x-<span class="constant" style="color:purple">1</span>); + } +}</code></pre> +<p class="p noindent para-continued">The body of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code> uses an assign-such-that statement to represent some +computation that takes place before <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code> is called. It sets “y” to some +arbitrary non-negative value. In a more concrete example, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code> would do +some work for each “y” and then continue as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code> on the next smaller +“x”. +</p> +<p class="p indent">Using a <strong class="strong-star2">decreases</strong> clause <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, y</span><span style="color:maroon">"</span></code> for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code> seems natural, but if +we don't have any bound on the size of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">y</span><span style="color:maroon">"</span></code> computed by <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code>, +there is no expression we can write in <strong class="strong-star2">decreases</strong> clause of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code> +that is sure to lead to a strictly smaller value for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">y</span><span style="color:maroon">"</span></code> when <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code> +is called. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\top</code> to the rescue. If we arrange for the effective +decreases clause of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Outer</code> to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, </span><span style="color:gray">\t</span><span style="color:maroon">op</span><span style="color:maroon">"</span></code> and the effective decreases +clause for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Inner</code> to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">x, y, </span><span style="color:gray">\t</span><span style="color:maroon">op</span><span style="color:maroon">"</span></code>, then we can show the strict +decreases as required. Since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\top</code> is implicitly appended, the two +decreases clauses declared in the program text can be: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> Outer(x: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x + +<span style="color:blue">method</span> Inner(x: <span style="color:teal">nat</span>, y: <span style="color:teal">nat</span>) + <span style="color:purple">decreases</span> x, y</code></pre> +<p class="p noindent para-continued">Moreover, remember that if a function or method has no user-declared +<strong class="strong-star2">decreases</strong> clause, Dafny will make a guess. The guess is (usually) +the list of arguments of the function/method, in the order given. This is +exactly the decreases clauses needed here. Thus, Dafny successfully +verifies the program without any explicit decreases clauses: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> Outer(x: <span style="color:teal">nat</span>) +{ + <span style="color:blue">var</span> y <span style="color:blue">:|</span> <span class="constant" style="color:purple">0</span> <= y; + Inner(x, y); +} + +<span style="color:blue">method</span> Inner(x: <span style="color:teal">nat</span>, y: <span style="color:teal">nat</span>) +{ + <span style="color:blue">if</span> y != <span class="constant" style="color:purple">0</span> { + Inner(x, y-<span class="constant" style="color:purple">1</span>); + } <span style="color:blue">else</span> <span style="color:blue">if</span> x != <span class="constant" style="color:purple">0</span> { + Outer(x-<span class="constant" style="color:purple">1</span>); + } +}</code></pre> +<p class="p noindent para-continued">The ingredients are simple, but the end result may seem like magic. For many users, however, there may be no magic at all – the end result may be so natural that the user never even has to bothered to think about that there was a need to prove termination in the first place. +</p><h4 id="sec-framing" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.3</span>. </span>Framing</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_frameexpression" class="ntdef" style="color:olive">FrameExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) [ <span class="code-escaped"><a href="#1_framefield" class="ntref localref" style="color:maroon">FrameField</a></span> ] + | <span class="code-escaped"><a href="#1_framefield" class="ntref localref" style="color:maroon">FrameField</a></span> )</code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_framefield" class="ntdef" style="color:olive">FrameField</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"`"</span></span> <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> </code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_possiblywildframeexpression" class="ntdef" style="color:olive">PossiblyWildFrameExpression</span></span>(allowLemma) = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span> | <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) )</code></pre> +<p class="p noindent para-continued">Frame expressions are used to denote the set of memory locations +that a Dafny program element may read or write. A frame +expression is a set expression. The form <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{}</code> (that is, the empty set) +says that no memory locations may be modified, +which is also the default if no <strong class="strong-star2">modifies</strong> clause is given explicitly. +</p> +<p class="p indent">Note that framing only applies to the heap, or memory accessed through +references. Local variables are not stored on the heap, so they cannot be +mentioned (well, they are not in scope in the declaration) in reads +annotations. Note also that types like sets, sequences, and multisets are +value types, and are treated like integers or local variables. Arrays and +objects are reference types, and they are stored on the heap (though as +always there is a subtle distinction between the reference itself and the +value it points to.) +</p> +<p class="p indent">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_framefield" class="ntref localref" style="color:maroon">FrameField</a></span></code> construct is used to specify a field of a +class object. The identifier following the back-quote is the +name of the field being referenced. +If the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FrameField</code> is preceded by an expression the expression +must be a reference to an object having that field. +If the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FrameField</code> is not preceded by an expression then +the frame expression is referring to that field of the current +object. This form is only used from a method of a class. +</p> +<p class="p indent">The use of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_framefield" class="ntref localref" style="color:maroon">FrameField</a></span></code> is discouraged as in practice it has not +been shown to either be more concise or to perform better. +Also, there's (unfortunately) no form of it for array +elements—one could imagine +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:purple">modifies</span> a`[j]</code></pre> +<p class="p noindent para-continued">Also, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_framefield" class="ntref localref" style="color:maroon">FrameField</a></span></code> is not taken into consideration for +lambda expressions. +</p><h4 id="sec-reads-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.4</span>. </span>Reads Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_functionreadsclause_" class="ntdef" style="color:olive">FunctionReadsClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"reads"</span></span> + <span class="code-escaped"><a href="#1_possiblywildframeexpression" class="ntref localref" style="color:maroon">PossiblyWildFrameExpression</a></span> (allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_possiblywildframeexpression" class="ntref localref" style="color:maroon">PossiblyWildFrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) } +<span class="code-escaped"><span id="1_lambdareadsclause_" class="ntdef" style="color:olive">LambdaReadsClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"reads"</span></span> <span class="code-escaped"><a href="#1_possiblywildframeexpression" class="ntref localref" style="color:maroon">PossiblyWildFrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) +<span class="code-escaped"><span id="1_iteratorreadsclause_" class="ntdef" style="color:olive">IteratorReadsClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"reads"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) } +<span class="code-escaped"><span id="1_possiblywildexpression" class="ntdef" style="color:olive">PossiblyWildExpression</span></span>(allowLambda) = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span> | <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) ) </code></pre> +<p class="p noindent para-continued">Functions are not allowed to have side effects but may be restricted in +what they can read. The <em class="em-low1">reading frame</em> of a function (or predicate) is all +the memory locations that the function is allowed to read. The reason we +might limit what a function can read is so that when we write to memory, +we can be sure that functions that did not read that part of memory have +the same value they did before. For example, we might have two arrays, +one of which we know is sorted. If we did not put a reads annotation on +the sorted predicate, then when we modify the unsorted array, we cannot +determine whether the other array stopped being sorted. While we might be +able to give invariants to preserve it in this case, it gets even more +complex when manipulating data structures. In this case, framing is +essential to making the verification process feasible. +</p> +<p class="p indent">It is not just the body of a function that is subject to <strong class="strong-star2">reads</strong> +checks, but also its precondition and the <strong class="strong-star2">reads</strong> clause itself. +</p> +<p class="p indent">A reads clause can list a wildcard (“*”), which allows the enclosing +function to read anything. In many cases, and in particular in all cases +where the function is defined recursively, this makes it next to +impossible to make any use of the function. Nevertheless, as an +experimental feature, the language allows it (and it is sound). +Note that a “*” makes the rest of the frame expression irrelevant. +</p> +<p class="p indent">A <strong class="strong-star2">reads</strong> clause specifies the set of memory locations that a function, +lambda, or iterator may read. If more than one <strong class="strong-star2">reads</strong> clause is given +in a specification the effective read set is the union of the sets +specified. If there are no <strong class="strong-star2">reads</strong> clauses the effective read set is +empty. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">*</span><span style="color:maroon">"</span></code> is given in a <strong class="strong-star2">reads</strong> clause it means any memory may be +read. +</p> +<p class="p indent">TODO: It would be nice if the different forms of read clauses could be +combined. In a future version the single form of read clause will allow +a list and attributes. +</p><h4 id="sec-modifies-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.5</span>. </span>Modifies Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_modifiesclause_" class="ntdef" style="color:olive">ModifiesClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"modifies"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) }</code></pre> +<p class="p noindent para-continued">Frames also affect methods. As you might have guessed, methods are not +required to list the things they read. Methods are allowed to read +whatever memory they like, but they are required to list which parts of +memory they modify, with a modifies annotation. They are almost identical +to their reads cousins, except they say what can be changed, rather than +what the value of the function depends on. In combination with reads, +modification restrictions allow Dafny to prove properties of code that +would otherwise be very difficult or impossible. Reads and modifies are +one of the tools that allow Dafny to work on one method at a time, +because they restrict what would otherwise be arbitrary modifications of +memory to something that Dafny can reason about. +</p> +<p class="p indent">Note that fields of newly allocated objects can always be modified. +</p> +<p class="p indent">It is also possible to frame what can be modified by a block statement +by means of the block form of the +<a href="#sec-modify-statement" class="localref">modify statement</a> (Section <a href="#sec-modify-statement" title="21.16. Modify Statement" class="localref" style="target-element:h2"><span class="heading-label">21.16</span></a>). +</p> +<p class="p indent">A <strong class="strong-star2">modifies</strong> clause specifies the set of memory locations that a +method, iterator or loop body may modify. If more than one <strong class="strong-star2">modifies</strong> +clause is given in a specification, the effective modifies set is the +union of the sets specified. If no <strong class="strong-star2">modifies</strong> clause is given the +effective modifies set is empty. A loop can also have a +<strong class="strong-star2">modifies</strong> clause. If none is given, the loop gets to modify anything +the enclosing context is allowed to modify. +</p><h4 id="sec-invariant-clause" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">4.0.6</span>. </span>Invariant Clause</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_invariantclause_" class="ntdef" style="color:olive">InvariantClause_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"invariant"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>)</code></pre> +<p class="p noindent para-continued">An <strong class="strong-star2">invariant</strong> clause is used to specify an invariant +for a loop. If more than one <strong class="strong-star2">invariant</strong> clause is given for +a loop the effective invariant is the conjunction of +the conditions specified. +</p> +<p class="p indent">The invariant must hold on entry to the loop. And assuming it +is valid on entry, Dafny must be able to prove that it then +holds at the end of the loop. +</p><h3 id="sec-method-specification" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.1</span>. </span>Method Specification</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_methodspec" class="ntdef" style="color:olive">MethodSpec</span></span> = + { <span class="code-escaped"><a href="#1_modifiesclause_" class="ntref localref" style="color:maroon">ModifiesClause_</a></span> + | <span class="code-escaped"><a href="#1_requiresclause_" class="ntref localref" style="color:maroon">RequiresClause_</a></span> + | <span class="code-escaped"><a href="#1_ensuresclause_" class="ntref localref" style="color:maroon">EnsuresClause_</a></span> + | <span class="code-escaped"><a href="#1_decreasesclause_" class="ntref localref" style="color:maroon">DecreasesClause_</a></span>(allowWildcard: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + } </code></pre> +<p class="p noindent para-continued">A method specification is zero or more <strong class="strong-star2">modifies</strong>, <strong class="strong-star2">requires</strong>, +<strong class="strong-star2">ensures</strong> or <strong class="strong-star2">decreases</strong> clauses, in any order. +A method does not have <strong class="strong-star2">reads</strong> clauses because methods are allowed to +read any memory. +</p><h3 id="sec-function-specification" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.2</span>. </span>Function Specification</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_functionspec" class="ntdef" style="color:olive">FunctionSpec</span></span> = + { <span class="code-escaped"><a href="#1_requiresclause_" class="ntref localref" style="color:maroon">RequiresClause_</a></span> + | <span class="code-escaped"><a href="#1_functionreadsclause_" class="ntref localref" style="color:maroon">FunctionReadsClause_</a></span> + | <span class="code-escaped"><a href="#1_functionensuresclause_" class="ntref localref" style="color:maroon">FunctionEnsuresClause_</a></span> + | <span class="code-escaped"><a href="#1_functiondecreasesclause_" class="ntref localref" style="color:maroon">FunctionDecreasesClause_</a></span>(allowWildcard: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + } </code></pre> +<p class="p noindent para-continued">A function specification is zero or more <strong class="strong-star2">reads</strong>, <strong class="strong-star2">requires</strong>, +<strong class="strong-star2">ensures</strong> or <strong class="strong-star2">decreases</strong> clauses, in any order. A function +specification does not have <strong class="strong-star2">modifies</strong> clauses because functions are not +allowed to modify any memory. +</p><h3 id="sec-lambda-specification" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.3</span>. </span>Lambda Specification</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_lambdaspec_" class="ntdef" style="color:olive">LambdaSpec_</span></span> = + { <span class="code-escaped"><a href="#1_lambdareadsclause_" class="ntref localref" style="color:maroon">LambdaReadsClause_</a></span> + | <span class="code-escaped"><a href="#1_requiresclause_" class="ntref localref" style="color:maroon">RequiresClause_</a></span> + } </code></pre> +<p class="p noindent para-continued">A lambda specification is zero or more <strong class="strong-star2">reads</strong> or <strong class="strong-star2">requires</strong> clauses. +Lambda specifications do not have <strong class="strong-star2">ensures</strong> clauses because the body +is never opaque. +Lambda specifications do not have <strong class="strong-star2">decreases</strong> +clauses because they do not have names and thus cannot be recursive. A +lambda specification does not have <strong class="strong-star2">modifies</strong> clauses because lambdas +are not allowed to modify any memory. +</p><h3 id="sec-iterator-specification" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.4</span>. </span>Iterator Specification</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_iteratorspec" class="ntdef" style="color:olive">IteratorSpec</span></span> = + { <span class="code-escaped"><a href="#1_iteratorreadsclause_" class="ntref localref" style="color:maroon">IteratorReadsClause_</a></span> + | <span class="code-escaped"><a href="#1_modifiesclause_" class="ntref localref" style="color:maroon">ModifiesClause_</a></span> + | [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yield"</span></span> ] <span class="code-escaped"><a href="#1_requiresclause_" class="ntref localref" style="color:maroon">RequiresClause_</a></span> + | [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yield"</span></span> ] <span class="code-escaped"><a href="#1_ensuresclause_" class="ntref localref" style="color:maroon">EnsuresClause_</a></span> + | <span class="code-escaped"><a href="#1_decreasesclause_" class="ntref localref" style="color:maroon">DecreasesClause_</a></span>(allowWildcard: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + } </code></pre> +<p class="p noindent para-continued">An iterator specification applies both to the iterator's constructor +method and to its <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> method. The <strong class="strong-star2">reads</strong> and <strong class="strong-star2">modifies</strong> +clauses apply to both of them. For the <strong class="strong-star2">requires</strong> and <strong class="strong-star2">ensures</strong> +clauses, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">yield</span></code> is not present they apply to the constructor, +but if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">yield</span></code> is present they apply to the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> method. +</p> +<p class="p indent">TODO: What is the meaning of a <strong class="strong-star2">decreases</strong> clause on an iterator? +Does it apply to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code>? Make sure our description of +iterators explains these. +</p> +<p class="p indent">TODO: What is the relationship between the post condition and +the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Valid()</code> predicate? + +</p><h3 id="sec-loop-specification" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">4.5</span>. </span>Loop Specification</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_loopspec" class="ntdef" style="color:olive">LoopSpec</span></span> = + { <span class="code-escaped"><a href="#1_invariantclause_" class="ntref localref" style="color:maroon">InvariantClause_</a></span> + | <span class="code-escaped"><a href="#1_decreasesclause_" class="ntref localref" style="color:maroon">DecreasesClause_</a></span>(allowWildcard: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><a href="#1_modifiesclause_" class="ntref localref" style="color:maroon">ModifiesClause_</a></span> + } </code></pre> +<p class="p noindent para-continued">A loop specification provides the information Dafny needs to +prove properties of a loop. The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_invariantclause_" class="ntref localref" style="color:maroon">InvariantClause_</a></span></code> clause +is effectively a precondition and it along with the +negation of the loop test condition provides the postcondition. +The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_decreasesclause_" class="ntref localref" style="color:maroon">DecreasesClause_</a></span></code> clause is used to prove termination. +</p><h2 id="sec-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">5</span>. </span>Types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_type" class="ntdef" style="color:olive">Type</span></span> = <span class="code-escaped"><a href="#1_domaintype" class="ntref localref" style="color:maroon">DomainType</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"->"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> ] </code></pre> +<p class="p noindent para-continued">A Dafny type is a domain type (i.e. a type that can be the domain of a +function type) optionally followed by an arrow and a range type. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_domaintype" class="ntdef" style="color:olive">DomainType</span></span> = + ( <span class="code-escaped"><a href="#1_booltype_" class="ntref localref" style="color:maroon">BoolType_</a></span> | <span class="code-escaped"><a href="#1_chartype_" class="ntref localref" style="color:maroon">CharType_</a></span> | <span class="code-escaped"><a href="#1_nattype_" class="ntref localref" style="color:maroon">NatType_</a></span> | <span class="code-escaped"><a href="#1_inttype_" class="ntref localref" style="color:maroon">IntType_</a></span> | <span class="code-escaped"><a href="#1_realtype_" class="ntref localref" style="color:maroon">RealType_</a></span> | <span class="code-escaped"><a href="#1_objecttype_" class="ntref localref" style="color:maroon">ObjectType_</a></span> + | <span class="code-escaped"><a href="#1_finitesettype_" class="ntref localref" style="color:maroon">FiniteSetType_</a></span> | <span class="code-escaped"><a href="#1_infinitesettype_" class="ntref localref" style="color:maroon">InfiniteSetType_</a></span> | <span class="code-escaped"><a href="#1_multisettype_" class="ntref localref" style="color:maroon">MultisetType_</a></span> + | <span class="code-escaped"><a href="#1_sequencetype_" class="ntref localref" style="color:maroon">SequenceType_</a></span> | <span class="code-escaped"><a href="#1_stringtype_" class="ntref localref" style="color:maroon">StringType_</a></span> + | <span class="code-escaped"><a href="#1_finitemaptype_" class="ntref localref" style="color:maroon">FiniteMapType_</a></span> | <span class="code-escaped"><a href="#1_infinitemaptype_" class="ntref localref" style="color:maroon">InfiniteMapType_</a></span> | <span class="code-escaped"><a href="#1_arraytype_" class="ntref localref" style="color:maroon">ArrayType_</a></span> + | <span class="code-escaped"><a href="#1_tupletype_" class="ntref localref" style="color:maroon">TupleType_</a></span> | <span class="code-escaped"><a href="#1_namedtype_" class="ntref localref" style="color:maroon">NamedType_</a></span> ) </code></pre> +<p class="p noindent para-continued">The domain types comprise the builtin scalar types, the builtin +collection types, tuple types (including as a special case +a parenthesized type) and reference types. +</p> +<p class="p indent">Dafny types may be categorized as either value types or reference types. +</p><h3 id="sec-value-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">5.0</span>. </span>Value Types</h3> +<p class="p noindent">The value types are those whose values do not lie in the program heap. +These are: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">The basic scalar types: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">char</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code> +</li> +<li class="li ul-li list-star-li compact-li">The built-in collection types: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">string</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span></code> +</li> +<li class="li ul-li list-star-li compact-li">Tuple Types +</li> +<li class="li ul-li list-star-li compact-li">Inductive and co-inductive types +</li></ul> + +<p class="p noindent">Data items having value types are passed by value. Since they are not +considered to occupy <em class="em-low1">memory</em>, framing expressions do not reference them. +</p><h3 id="sec-reference-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">5.1</span>. </span>Reference Types</h3> +<p class="p noindent">Dafny offers a host of <em class="em-low1">reference types</em>. These represent +<em class="em-low1">references</em> to objects allocated dynamically in the program heap. To +access the members of an object, a reference to (that is, a <em class="em-low1">pointer</em> +to or <em class="em-low1">object identity</em> of) the object is <em class="em-low1">dereferenced</em>. +</p> +<p class="p indent">The reference types are class types, traits and array types. +</p> +<p class="p indent">The special value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">null</span></code> is part of every reference +type.<sup id="back-fn-fn-nullable" ><a href="#fn-fn-nullable" title="0.This will change in a future version of Dafny that +will support both nullable and (by default) non-null reference +types. +↩" class="footnote-ref localref" ><span class="footnote-label">0</span></a></sup> +</p><h3 id="sec-named-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">5.2</span>. </span>Named Types</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_namedtype_" class="ntdef" style="color:olive">NamedType_</span></span> = <span class="code-escaped"><a href="#1_namesegmentfortypename" class="ntref localref" style="color:maroon">NameSegmentForTypeName</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"."</span></span> <span class="code-escaped"><a href="#1_namesegmentfortypename" class="ntref localref" style="color:maroon">NameSegmentForTypeName</a></span> }</code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namedtype_" class="ntref localref" style="color:maroon">NamedType_</a></span></code> is used to specify a user-defined type by name +(possibly module-qualified). Named types are introduced by +class, trait, inductive, co-inductive, synonym and opaque +type declarations. They are also used to refer to type variables. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_namesegmentfortypename" class="ntdef" style="color:olive">NameSegmentForTypeName</span></span> = <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegmentfortypename" class="ntref localref" style="color:maroon">NameSegmentForTypeName</a></span></code> is a type name optionally followed by a +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span></code> which supplies type parameters to a generic +type, if needed. It is a special case of a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span></code> +(See Section <a href="#sec-name-segment" title="22.35. Name Segment" class="localref" style="target-element:h2"><span class="heading-label">22.35</span></a>) +that does not allow a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code>. +</p> +<p class="p indent">The following sections describe each of these kinds of types in more detail. +</p><h2 id="sec-basic-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">6</span>. </span>Basic types</h2> +<p class="p noindent">Dafny offers these basic types: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code> for booleans, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">char</span></code> for +characters, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code> for integers, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code> for reals. +</p><h3 id="sec-booleans" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">6.0</span>. </span>Booleans</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_booltype_" class="ntdef" style="color:olive">BoolType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"bool"</span></span> </code></pre> +<p class="p noindent para-continued">There are two boolean values and each has a corresponding literal in +the language: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>. +</p> +<p class="p indent">In addition to equality (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code>) and disequality (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!=</code>), which are +defined on all types, type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code> supports the following operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==></code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> equivalence (if and only if) </td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-row="1" data-col="1"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-row="1" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==></code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> implication (implies) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> reverse implication (follows from) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="3" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="3" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">&&</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> conjunction (and) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> <span class="monospace">||</span> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> disjunction (or) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="5" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="5" data-col="2"></td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="6" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> negation (not) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="6" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="6" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Negation is unary; the others are binary. The table shows the operators +in groups of increasing binding power, with equality binding stronger +than conjunction and disjunction, and weaker than negation. Within +each group, different operators do not associate, so parentheses need +to be used. For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A && B || C <span style="color:darkgreen">// error</span></code></pre> +<p class="p noindent para-continued">would be ambiguous and instead has to be written as either +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>(A && B) || C</code></pre> +<p class="p noindent para-continued">or +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A && (B || C)</code></pre> +<p class="p noindent para-continued">depending on the intended meaning. +</p><h4 id="sec-equivalence-operator" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">6.0.0</span>. </span>Equivalence Operator</h4> +<p class="p noindent">The expressions <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A <==> B</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A == B</code> give the same value, but note +that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==></code> is <em class="em-low1">associative</em> whereas <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code> is <em class="em-low1">chaining</em>. So, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A <==> B <==> C</code></pre> +<p class="p noindent para-continued">is the same as +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A <==> (B <==> C)</code></pre> +<p class="p noindent para-continued">and +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>(A <==> B) <==> C</code></pre> +<p class="p noindent para-continued">whereas +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A == B == C</code></pre> +<p class="p noindent para-continued">is simply a shorthand for +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A == B && B == C</code></pre><h4 id="sec-conjunction-and-disjunction" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">6.0.1</span>. </span>Conjunction and Disjunction</h4> +<p class="p noindent">Conjunction is associative and so is disjunction. These operators are +<em class="em-low1">short circuiting (from left to right)</em>, meaning that their second +argument is evaluated only if the evaluation of the first operand does +not determine the value of the expression. Logically speaking, the +expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A && B</code> is defined when <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> is defined and either <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> +evaluates to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> is defined. When <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A && B</code> is defined, its +meaning is the same as the ordinary, symmetric mathematical +conjunction ∧. The same holds for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">||</code> and ∨. +</p><h4 id="sec-implication-and-reverse-implication" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">6.0.2</span>. </span>Implication and Reverse Implication</h4> +<p class="p noindent">Implication is <em class="em-low1">right associative</em> and is short-circuiting from left +to right. Reverse implication <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B <== A</code> is exactly the same as +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A ==> B</code>, but gives the ability to write the operands in the opposite +order. Consequently, reverse implication is <em class="em-low1">left associative</em> and is +short-circuiting from <em class="em-low1">right to left</em>. To illustrate the +associativity rules, each of the following four lines expresses the +same property, for any <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A ==> B ==> C +A ==> (B ==> C) <span style="color:darkgreen">// parentheses redundant, since ==> is right associative</span> +C <== B <== A +(C <== B) <== A <span style="color:darkgreen">// parentheses redundant, since <== is left associative</span></code></pre> +<p class="p noindent para-continued">To illustrate the short-circuiting rules, note that the expression +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a.Length</code> is defined for an array <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> only if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> is not <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">null</span></code> (see +Section <a href="#sec-reference-types" title="5.1. Reference Types" class="localref" style="target-element:h2"><span class="heading-label">5.1</span></a>), which means the following two +expressions are well-formed: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a != <span style="color:blue">null</span> ==> <span class="constant" style="color:purple">0</span> <= a.Length +<span class="constant" style="color:purple">0</span> <= a.Length <== a != <span style="color:blue">null</span></code></pre> +<p class="p noindent para-continued">The contrapositive of these two expressions would be: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a.Length < <span class="constant" style="color:purple">0</span> ==> a == <span style="color:blue">null</span> <span style="color:darkgreen">// not well-formed</span> +a == <span style="color:blue">null</span> <== a.Length < <span class="constant" style="color:purple">0</span> <span style="color:darkgreen">// not well-formed</span></code></pre> +<p class="p noindent para-continued">but these expressions are not well-formed, since well-formedness +requires the left (and right, respectively) operand, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a.Length < <span class="constant" style="color:purple">0</span></code>, +to be well-formed by itself. +</p> +<p class="p indent">Implication <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A ==> B</code> is equivalent to the disjunction <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!A || B</code>, but +is sometimes (especially in specifications) clearer to read. Since, +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">||</code> is short-circuiting from left to right, note that +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a == <span style="color:blue">null</span> || <span class="constant" style="color:purple">0</span> <= a.Length</code></pre> +<p class="p noindent para-continued">is well-formed, whereas +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="constant" style="color:purple">0</span> <= a.Length || a == <span style="color:blue">null</span> <span style="color:darkgreen">// not well-formed</span></code></pre> +<p class="p noindent para-continued">is not. +</p> +<p class="p indent">In addition, booleans support <em class="em-low1">logical quantifiers</em> (forall and +exists), described in section <a href="#sec-quantifier-expression" title="22.30. Quantifier Expression" class="localref" style="target-element:h2"><span class="heading-label">22.30</span></a>. +</p><h3 id="sec-numeric-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">6.1</span>. </span>Numeric types</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_inttype_" class="ntdef" style="color:olive">IntType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"int"</span></span> +<span class="code-escaped"><span id="1_realtype_" class="ntdef" style="color:olive">RealType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"real"</span></span> </code></pre> +<p class="p noindent para-continued">Dafny supports <em class="em-low1">numeric types</em> of two kinds, <em class="em-low1">integer-based</em>, which +includes the basic type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> of all integers, and <em class="em-low1">real-based</em>, which +includes the basic type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code> of all real numbers. User-defined +numeric types based on <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code>, called <em class="em-low1">newtypes</em>, are +described in Section <a href="#sec-newtypes" title="19. Newtypes" class="localref" style="target-element:h1"><span class="heading-label">19</span></a>. Also, the <em class="em-low1">subset type</em> +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code>, representing the non-negative subrange of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>, is described +in Section <a href="#sec-subset-types" title="20. Subset types" class="localref" style="target-element:h1"><span class="heading-label">20</span></a>. +</p> +<p class="p indent">The language includes a literal for each non-negative integer, like +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">13</span></code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">1985</span></code>. Integers can also be written in hexadecimal +using the prefix “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span>x</code>”, as in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0x0</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0xD</span></code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0x7c1</span></code> (always with +a lower case <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code>, but the hexadecimal digits themselves are case +insensitive). Leading zeros are allowed. To form negative integers, +use the unary minus operator. +</p> +<p class="p indent">There are also literals for some of the non-negative reals. These are +written as a decimal point with a nonempty sequence of decimal digits +on both sides. For example, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">1.0</span></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">1609.344</span></code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0.5772156649</span></code>. +</p> +<p class="p indent">For integers (in both decimal and hexadecimal form) and reals, +any two digits in a literal may be separated by an underscore in order +to improve human readability of the literals. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="constant" style="color:purple">1_000_000</span> <span style="color:darkgreen">// easier to read than 1000000</span> +<span class="constant" style="color:purple">0_12_345_6789</span> <span style="color:darkgreen">// strange but legal formatting of 123456789</span> +<span class="constant" style="color:purple">0x8000_0000</span> <span style="color:darkgreen">// same as 0x80000000 -- hex digits are often placed in groups of 4</span> +<span class="constant" style="color:purple">0.000_000_000_1</span> <span style="color:darkgreen">// same as 0.0000000001 -- 1 </span><span class="code-escaped"><span class="comment-color">Ångström</span></span></code></pre> +<p class="p noindent para-continued">In addition to equality and disequality, numeric types +support the following relational operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> less than </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> at most </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> at least </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> greater than </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Like equality and disequality, these operators are chaining, as long +as they are chained in the “same direction”. That is, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A <= B < C == D <= E</code></pre> +<p class="p noindent para-continued">is simply a shorthand for +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A <= B && B < C && C == D && D <= E</code></pre> +<p class="p noindent para-continued">whereas +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A < B > C</code></pre> +<p class="p noindent para-continued">is not allowed. +</p> +<p class="p indent">There are also operators on each numeric type: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> addition (plus) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> subtraction (minus) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="2" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="2" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> multiplication (times) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">/</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> division (divided by) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">%</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> modulus (mod) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="5" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="5" data-col="2"></td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="6" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> negation (unary minus) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="6" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="6" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The binary operators are left associative, and they associate with +each other in the two groups. The groups are listed in order of +increasing binding power, with equality binding more strongly than the +multiplicative operators and weaker than the unary operator. +Modulus is supported only for integer-based numeric types. Integer +division and modulus are the <em class="em-low1">Euclidean division and modulus</em>. This +means that modulus always returns a non-negative, regardless of the +signs of the two operands. More precisely, for any integer <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> and +non-zero integer <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code>, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a == a / b * b + a % b +<span class="constant" style="color:purple">0</span> <= a % b < B</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> denotes the absolute value of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code>. +</p> +<p class="p indent">Real-based numeric types have a member <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Trunc</code> that returns the +<em class="em-low1">floor</em> of the real value, that is, the largest integer not exceeding +the real value. For example, the following properties hold, for any +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">r</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">r'</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="constant" style="color:purple">3.14</span>.Trunc == <span class="constant" style="color:purple">3</span> +(-<span class="constant" style="color:purple">2.5</span>).Trunc == -<span class="constant" style="color:purple">3</span> +-<span class="constant" style="color:purple">2.5</span>.Trunc == -<span class="constant" style="color:purple">2</span> +<span style="color:teal">real</span>(r.Trunc) <= r +r <= r' ==> r.Trunc <= r'.Trunc</code></pre> +<p class="p noindent para-continued">Note in the third line that member access (like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.Trunc</code>) binds +stronger than unary minus. The fourth line uses the conversion +function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code> from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code>, as described in Section +<a href="#sec-numeric-conversion-operations" title="19.0. Numeric conversion operations" class="localref" style="target-element:h2"><span class="heading-label">19.0</span></a>. +</p><h3 id="sec-characters" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">6.2</span>. </span>Characters</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_chartype_" class="ntdef" style="color:olive">CharType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"char"</span></span> </code></pre> +<p class="p noindent para-continued">Dafny supports a type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">char</span></code> of <em class="em-low1">characters</em>. Character literals are +enclosed in single quotes, as in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">'D'</span></code>. Their form is described +by the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_chartoken" class="ntref localref" style="color:maroon">charToken</a></span></code> nonterminal in the grammar. To write a single quote as a +character literal, it is necessary to use an <em class="em-low1">escape sequence</em>. +Escape sequences can also be used to write other characters. The +supported escape sequences are as follows: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> escape sequence </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> meaning </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\'</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> the character <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">'</code> </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <span class="monospace">\"</span> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> the character <span class="monospace">"</span> </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\\</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> the character <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\</code> </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\<span class="constant" style="color:purple">0</span></code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> the null character, same as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\u0000</code> </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\n</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> line feed </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="6" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\r</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> carriage return </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="7" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\t</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="7" data-col="2"> horizontal tab </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="8" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\u<span class="code-escaped"><em class="em-low1">xxxx</em></span></code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="8" data-col="2"> universal character whose hexadecimal code is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">xxxx</em></span></code> </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="8" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="8" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The escape sequence for a double quote is redundant, because +<span class="monospace">'"'</span> and <span class="monospace">'\"'</span> denote the same +character—both forms are provided in order to support the same +escape sequences as for string literals (Section <a href="#sec-strings" title="9.2.4. Strings" class="localref" style="target-element:h3"><span class="heading-label">9.2.4</span></a>). +In the form <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">\u<span class="code-escaped"><em class="em-low1">xxxx</em></span></code>, the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">u</code> is always lower case, but the four +hexadecimal digits are case insensitive. +</p> +<p class="p indent">Character values are ordered and can be compared using the standard +relational operators: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> less than </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> at most </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> at least </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> greater than </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Sequences of characters represent <em class="em-low1">strings</em>, as described in Section +<a href="#sec-strings" title="9.2.4. Strings" class="localref" style="target-element:h3"><span class="heading-label">9.2.4</span></a>. +</p> +<p class="p indent">The only other operations on characters are obtaining a character +by indexing into a string, and the implicit conversion to string +when used as a parameter of a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">print</span></code> statement. +</p> +<p class="p indent">TODO: Are there any conversions between <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">char</span></code> values and numeric values? +</p><h2 id="sec-type-parameters" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">7</span>. </span>Type parameters</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_genericparameters" class="ntdef" style="color:olive">GenericParameters</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<"</span></span> <span class="code-escaped"><a href="#1_typevariablename" class="ntref localref" style="color:maroon">TypeVariableName</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=="</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> ] + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_typevariablename" class="ntref localref" style="color:maroon">TypeVariableName</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=="</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> ] } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">"</span></span> </code></pre> +<p class="p noindent para-continued">Many of the types (as well as functions and methods) in Dafny can be +parameterized by types. These <em class="em-low1">type parameters</em> are typically +declared inside angle brackets and can stand for any type. +</p> +<p class="p indent">It is sometimes necessary to restrict these type parameters so that +they can only be instantiated by certain families of types. As such, +Dafny distinguishes types that support the equality operation +not only in ghost contexts but also in compiled contexts. To indicate +that a type parameter is restricted to such <em class="em-low1">equality supporting</em> +types, the name of the type parameter takes the suffix +“<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(==)</code>”.<sup id="back-fn-fn-type-mode" ><a href="#fn-fn-type-mode" title="1.Being equality-supporting is just one of many +modes that one can imagine types in a rich type system to have. +For example, other modes could include having a total order, +being zero-initializable, and possibly being uninhabited. If +Dafny were to support more modes in the future, the “( )”-suffix +syntax may be extended. For now, the suffix can only indicate the +equality-supporting mode. +↩" class="footnote-ref localref" ><span class="footnote-label">1</span></a></sup> For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> Compare<T(==)>(a: T, b: T) <span style="color:blue">returns</span> (eq: <span style="color:teal">bool</span>) +{ + <span style="color:blue">if</span> a == b { eq <span style="color:blue">:=</span> <span style="color:blue">true</span>; } <span style="color:blue">else</span> { eq <span style="color:blue">:=</span> <span style="color:blue">false</span>; } +}</code></pre> +<p class="p noindent para-continued">is a method whose type parameter is restricted to equality-supporting +types. Again, note that <em class="em-low1">all</em> types support equality in <em class="em-low1">ghost</em> +contexts; the difference is only for non-ghost (that is, compiled) +code. Co-inductive datatypes, function types, as well as inductive +datatypes with ghost parameters are examples of types that are not +equality supporting. +</p> +<p class="p indent">Dafny has some inference support that makes certain signatures less +cluttered (described in a different part of the Dafny language +reference). In some cases, this support will +infer that a type parameter must be restricted to equality-supporting +types, in which case Dafny adds the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(==)</code>” automatically. +</p> +<p class="p indent">TODO: Need to describe type inference somewhere. +</p><h2 id="sec-generic-instantiation" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">8</span>. </span>Generic Instantiation</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_genericinstantiation" class="ntdef" style="color:olive">GenericInstantiation</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">"</span></span> </code></pre> +<p class="p noindent para-continued">When a generic entity is used, actual types must be specified for each +generic parameter. This is done using a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span></code>. +If the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">GenericInstantiation</code> is omitted, type inference will try +to fill these in. +</p><h2 id="sec-collection-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">9</span>. </span>Collection types</h2> +<p class="p noindent">Dafny offers several built-in collection types. +</p><h3 id="sec-sets" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">9.0</span>. </span>Sets</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_finitesettype_" class="ntdef" style="color:olive">FiniteSetType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"set"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] +<span class="code-escaped"><span id="1_infinitesettype_" class="ntdef" style="color:olive">InfiniteSetType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iset"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ]</code></pre> +<p class="p noindent para-continued">For any type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, each value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span><T></code> is a finite set of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> values. +</p> +<p class="p indent">TODO: +Set membership is determined by equality in the type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, +so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span><T></code> can be used in a non-ghost context only if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is equality +supporting. +</p> +<p class="p indent">For any type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, each value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">iset</span><T></code> is a potentially infinite +set of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> values. +</p> +<p class="p indent">A set can be formed using a <em class="em-low1">set display</em> expression, which is a +possibly empty, unordered, duplicate-insensitive list of expressions +enclosed in curly braces. To illustrate, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>{} {<span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">7</span>, <span class="constant" style="color:purple">5</span>, <span class="constant" style="color:purple">3</span>} {<span class="constant" style="color:purple">4</span>+<span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">1</span>+<span class="constant" style="color:purple">5</span>, a*b}</code></pre> +<p class="p noindent para-continued">are three examples of set displays. There is also a <em class="em-low1">set comprehension</em> +expression (with a binder, like in logical quantifications), described in +section <a href="#sec-set-comprehension-expressions" title="22.31. Set Comprehension Expressions" class="localref" style="target-element:h2"><span class="heading-label">22.31</span></a>. +</p> +<p class="p indent">In addition to equality and disequality, set types +support the following relational operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> proper subset </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> subset </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> superset </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> proper superset </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Like the arithmetic relational operators, these operators are +chaining. +</p> +<p class="p indent">Sets support the following binary operators, listed in order of +increasing binding power: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!!</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> disjointness </td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-row="1" data-col="1"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-row="1" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> set union </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> set difference </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="3" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="3" data-col="2"></td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> set intersection </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The associativity rules of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> are like those of the +arithmetic operators with the same names. The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A !! B</code>, +whose binding power is the same as equality (but which neither +associates nor chains with equality), says that sets <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> have +no elements in common, that is, it is equivalent to +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A * B == {}</code></pre> +<p class="p noindent para-continued">However, the disjointness operator is chaining, so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A !! B !! C !! D</code> +means: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A * B == {} && (A + B) * C == {} && (A + B + C) * D == {}</code></pre> +<p class="p noindent para-continued">In addition, for any set <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span><T></code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">iset</span><T></code> and any +expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, sets support the following operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> expression </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace">|s|</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> set cardinality </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e <span style="color:blue">in</span> s</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> set membership </td></tr> +<tr><td class="tbody tr-odd tr-last col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> </td><td class="tbody tr-odd tr-last col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> set non-membership </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="3" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="3" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> is a syntactic shorthand for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!(e <span style="color:blue">in</span> s)</code>. +</p><h3 id="sec-multisets" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">9.1</span>. </span>Multisets</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_multisettype_" class="ntdef" style="color:olive">MultisetType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"multiset"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] </code></pre> +<p class="p noindent para-continued">A <em class="em-low1">multiset</em> is similar to a set, but keeps track of the multiplicity +of each element, not just its presence or absence. For any type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, +each value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span><T></code> is a map from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> values to natural +numbers denoting each element's multiplicity. Multisets in Dafny +are finite, that is, they contain a finite number of each of a finite +set of elements. Stated differently, a multiset maps only a finite +number of elements to non-zero (finite) multiplicities. +</p> +<p class="p indent">Like sets, multiset membership is determined by equality in the type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span><T></code> can be used in a non-ghost context only if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> +is equality supporting. +</p> +<p class="p indent">A multiset can be formed using a <em class="em-low1">multiset display</em> expression, which +is a possibly empty, unordered list of expressions enclosed in curly +braces after the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span></code>. To illustrate, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">multiset</span>{} <span style="color:teal">multiset</span>{<span class="constant" style="color:purple">0</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>, <span class="constant" style="color:purple">5</span>} <span style="color:teal">multiset</span>{<span class="constant" style="color:purple">4</span>+<span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">1</span>+<span class="constant" style="color:purple">5</span>, a*b}</code></pre> +<p class="p noindent para-continued">are three examples of multiset displays. There is no multiset +comprehension expression. +</p> +<p class="p indent">In addition to equality and disequality, multiset types +support the following relational operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> proper multiset subset </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> multiset subset </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> multiset superset </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> proper multiset superset </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Like the arithmetic relational operators, these operators are +chaining. +</p> +<p class="p indent">Multisets support the following binary operators, listed in order of +increasing binding power: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!!</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> multiset disjointness </td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-row="1" data-col="1"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-row="1" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> multiset union </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> multiset difference </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="3" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="3" data-col="2"></td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> multiset intersection </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The associativity rules of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> are like those of the +arithmetic operators with the same names. The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> operator +adds the multiplicity of corresponding elements, the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> operator +subtracts them (but 0 is the minimum multiplicity), +and the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> has multiplicity that is the minimum of the +multiplicity of the operands. +</p> +<p class="p indent">The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A !! B</code> +says that multisets <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">B</code> have no elements in common, that is, +it is equivalent to +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>A * B == <span style="color:teal">multiset</span>{}</code></pre> +<p class="p noindent para-continued">Like the analogous set operator, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!!</code> is chaining. +</p> +<p class="p indent">In addition, for any multiset <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span><T></code>, +expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, and non-negative integer-based numeric +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>, multisets support the following operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> expression </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace">|s|</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> multiset cardinality </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e <span style="color:blue">in</span> s</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> multiset membership </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> multiset non-membership </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[e]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> multiplicity of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> </td></tr> +<tr><td class="tbody tr-odd tr-last col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[e <span style="color:blue">:=</span> n]</code> </td><td class="tbody tr-odd tr-last col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> multiset update (change of multiplicity) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="5" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="5" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e <span style="color:blue">in</span> s</code> returns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> if and only if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[e] != <span class="constant" style="color:purple">0</span></code>. +The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> is a syntactic shorthand for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!(e <span style="color:blue">in</span> s)</code>. +The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[e <span style="color:blue">:=</span> n]</code> denotes a multiset like +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>, but where the multiplicity of element <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>. Note that +the multiset update <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[e <span style="color:blue">:=</span> <span class="constant" style="color:purple">0</span>]</code> results in a multiset like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> but +without any occurrences of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> (whether or not <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> has occurrences of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> in the first place). As another example, note that +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s - <span style="color:teal">multiset</span>{e}</code> is equivalent to: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">if</span> e <span style="color:blue">in</span> s <span style="color:blue">then</span> s[e <span style="color:blue">:=</span> s[e] - <span class="constant" style="color:purple">1</span>] <span style="color:blue">else</span> s</code></pre><h3 id="sec-sequences" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">9.2</span>. </span>Sequences</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_sequencetype_" class="ntdef" style="color:olive">SequenceType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"seq"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] </code></pre> +<p class="p noindent para-continued">For any type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, a value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><T></code> denotes a <em class="em-low1">sequence</em> of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> +elements, that is, a mapping from a finite downward-closed set of natural +numbers (called <em class="em-low1">indices</em>) to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> values. (Thinking of it as a map, +a sequence is therefore something of a dual of a multiset.) +</p><h4 id="sec-sequence-displays" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">9.2.0</span>. </span>Sequence Displays</h4> +<p class="p noindent">A sequence can be formed using a <em class="em-low1">sequence display</em> expression, which +is a possibly empty, ordered list of expressions enclosed in square +brackets. To illustrate, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>[] [<span class="constant" style="color:purple">3</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">4</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">5</span>, <span class="constant" style="color:purple">9</span>, <span class="constant" style="color:purple">3</span>] [<span class="constant" style="color:purple">4</span>+<span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">1</span>+<span class="constant" style="color:purple">5</span>, a*b]</code></pre> +<p class="p noindent para-continued">are three examples of sequence displays. There is no sequence +comprehension expression. +</p><h4 id="sec-sequence-relational-operators" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">9.2.1</span>. </span>Sequence Relational Operators</h4> +<p class="p noindent">In addition to equality and disequality, sequence types +support the following relational operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> proper prefix </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> prefix </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="2" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="2" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Like the arithmetic relational operators, these operators are +chaining. Note the absence of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code>. +</p><h4 id="sec-sequence-concatenation" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">9.2.2</span>. </span>Sequence Concatenation</h4> +<p class="p noindent">Sequences support the following binary operator: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-last tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> </td><td class="tbody tr-odd tr-last tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> concatenation </td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-row="1" data-col="1"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-row="1" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Operator <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> is associative, like the arithmetic operator with the +same name. +</p><h4 id="sec-other-sequence-expressions" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">9.2.3</span>. </span>Other Sequence Expressions</h4> +<p class="p noindent">In addition, for any sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><T></code>, expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> +of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, integer-based numeric <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> satisfying <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= i < |s|</code>, and +integer-based numerics <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> satisfying +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= lo <= hi <= |s|</code>, sequences support the following operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> expression </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace">|s|</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> sequence length </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[i]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> sequence selection </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[i <span style="color:blue">:=</span> e]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> sequence update </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e <span style="color:blue">in</span> s</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> sequence membership </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> sequence non-membership </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="6" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[lo..hi]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> subsequence </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="7" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[lo..]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="7" data-col="2"> drop </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="8" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[..hi]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="8" data-col="2"> take </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="9" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[<span class="code-escaped"><em class="em-low1">slices</em></span>]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="9" data-col="2"> slice </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="10" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span>(s)</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="10" data-col="2"> sequence conversion to a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span><T></code> </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="10" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="10" data-col="2"></td></tr></tbody></table> +<p class="p noindent">Expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[i <span style="color:blue">:=</span> e]</code> returns a sequence like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>, except that the +element at index <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code>. The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e <span style="color:blue">in</span> s</code> says there +exists an index <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> such that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[i] == e</code>. It is allowed in non-ghost +contexts only if the element type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is equality supporting. +The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e !<span style="color:blue">in</span> s</code> is a syntactic shorthand for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!(e <span style="color:blue">in</span> s)</code>. +</p> +<p class="p indent">Expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[lo..hi]</code> yields a sequence formed by taking the first +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> elements and then dropping the first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> elements. The +resulting sequence thus has length <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi - lo</code>. Note that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[<span class="constant" style="color:purple">0</span>..|s|]</code> +equals <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>. If the upper bound is omitted, it +defaults to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|s|</code>, so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[lo..]</code> yields the sequence formed by dropping +the first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> elements of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>. If the lower bound is omitted, it +defaults to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span></code>, so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[..hi]</code> yields the sequence formed by taking the +first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> elements of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>. +</p> +<p class="p indent">In the sequence slice operation, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">slices</em></span></code> is a nonempty list of +length designators separated and optionally terminated by a colon, and +there is at least one colon. Each length designator is a non-negative +integer-based numeric, whose sum is no greater than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|s|</code>. If there +are <em class="em-low1">k</em> colons, the operation produces <em class="em-low1">k + 1</em> consecutive subsequences +from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>, each of the length indicated by the corresponding length +designator, and returns these as a sequence of +sequences.<sup id="back-fn-fn-slice-into-tuple" ><a href="#fn-fn-slice-into-tuple" title="2.Now that Dafny supports built-in tuples, the +plan is to change the sequence slice operation to return not a +sequence of subsequences, but a tuple of subsequences. +↩" class="footnote-ref localref" ><span class="footnote-label">2</span></a></sup> If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">slices</em></span></code> is terminated by a +colon, then the length of the last slice extends until the end of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>, +that is, its length is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|s|</code> minus the sum of the given length +designators. For example, the following equalities hold, for any +sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> of length at least <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">10</span></code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> t <span style="color:blue">:=</span> [<span class="constant" style="color:purple">3.14</span>, <span class="constant" style="color:purple">2.7</span>, <span class="constant" style="color:purple">1.41</span>, <span class="constant" style="color:purple">1985.44</span>, <span class="constant" style="color:purple">100.0</span>, <span class="constant" style="color:purple">37.2</span>][<span class="constant" style="color:purple">1</span>:<span class="constant" style="color:purple">0</span>:<span class="constant" style="color:purple">3</span>]; +<span style="color:blue">assert</span> |t| == <span class="constant" style="color:purple">3</span> && t[<span class="constant" style="color:purple">0</span>] == [<span class="constant" style="color:purple">3.14</span>] && t[<span class="constant" style="color:purple">1</span>] == []; +<span style="color:blue">assert</span> t[<span class="constant" style="color:purple">2</span>] == [<span class="constant" style="color:purple">2.7</span>, <span class="constant" style="color:purple">1.41</span>, <span class="constant" style="color:purple">1985.44</span>]; +<span style="color:blue">var</span> u <span style="color:blue">:=</span> [<span style="color:blue">true</span>, <span style="color:blue">false</span>, <span style="color:blue">false</span>, <span style="color:blue">true</span>][<span class="constant" style="color:purple">1</span>:<span class="constant" style="color:purple">1</span>:]; +<span style="color:blue">assert</span> |u| == <span class="constant" style="color:purple">3</span> && u[<span class="constant" style="color:purple">0</span>][<span class="constant" style="color:purple">0</span>] && !u[<span class="constant" style="color:purple">1</span>][<span class="constant" style="color:purple">0</span>] && u[<span class="constant" style="color:purple">2</span>] == [<span style="color:blue">false</span>, <span style="color:blue">true</span>]; +<span style="color:blue">assert</span> s[<span class="constant" style="color:purple">10</span>:][<span class="constant" style="color:purple">0</span>] == s[..<span class="constant" style="color:purple">10</span>]; +<span style="color:blue">assert</span> s[<span class="constant" style="color:purple">10</span>:][<span class="constant" style="color:purple">1</span>] == s[<span class="constant" style="color:purple">10</span>..];</code></pre> +<p class="p noindent para-continued">The operation <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">multiset</span>(s)</code> yields the multiset of elements of +sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>. It is allowed in non-ghost contexts only if the element +type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is equality supporting. +</p><h4 id="sec-strings" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">9.2.4</span>. </span>Strings</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_stringtype_" class="ntdef" style="color:olive">StringType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"string"</span></span> </code></pre> +<p class="p noindent para-continued">A special case of a sequence type is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><<span style="color:teal">char</span>></code>, for which Dafny +provides a synonym: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">string</span></code>. Strings are like other sequences, but +provide additional syntax for sequence display expressions, namely +<em class="em-low1">string literals</em>. There are two forms of the syntax for string +literals: the <em class="em-low1">standard form</em> and the <em class="em-low1">verbatim form</em>. +</p> +<p class="p indent">String literals of the standard form are enclosed in double quotes, as +in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">Dafny</span><span style="color:maroon">"</span></code>. To include a double quote in such a string literal, +it is necessary to use an escape sequence. Escape sequences can also +be used to include other characters. The supported escape sequences +are the same as those for character literals, see Section <a href="#sec-characters" title="6.2. Characters" class="localref" style="target-element:h2"><span class="heading-label">6.2</span></a>. +For example, the Dafny expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">say </span><span style="color:gray">\"</span><span style="color:maroon">yes</span><span style="color:gray">\"</span><span style="color:maroon">"</span></code> represents the +string <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">'say <span style="color:maroon">"</span><span style="color:maroon">yes</span><span style="color:maroon">"</span>'</code>. +The escape sequence for a single quote is redundant, because +<span class="monospace">"'"</span> and <span class="monospace">"\'"</span> denote the same +string—both forms are provided in order to support the same +escape sequences as for character literals. +</p> +<p class="p indent">String literals of the verbatim form are bracketed by +<span class="monospace">@"</span> and <span class="monospace">"</span>, as in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">@"</span><span style="color:maroon">Dafny</span><span style="color:maroon">"</span></code>. To include +a double quote in such a string literal, it is necessary to use the +escape sequence <span class="monospace">""</span>, that is, to write the character +twice. In the verbatim form, there are no other escape sequences. +Even characters like newline can be written inside the string literal +(hence spanning more than one line in the program text). +</p> +<p class="p indent">For example, the following three expressions denote the same string: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:maroon">"</span><span style="color:maroon">C:</span><span style="color:gray">\\</span><span style="color:maroon">tmp.txt</span><span style="color:maroon">"</span> +<span style="color:maroon">@"</span><span style="color:maroon">C:\tmp.txt</span><span style="color:maroon">"</span> +[<span style="color:maroon">'C'</span>, <span style="color:maroon">':'</span>, <span style="color:maroon">'</span><span style="color:gray">\\</span><span style="color:maroon">'</span>, <span style="color:maroon">'t'</span>, <span style="color:maroon">'m'</span>, <span style="color:maroon">'p'</span>, <span style="color:maroon">'.'</span>, <span style="color:maroon">'t'</span>, <span style="color:maroon">'x'</span>, <span style="color:maroon">'t'</span>]</code></pre> +<p class="p noindent para-continued">Since strings are sequences, the relational operators <span class="monospace"><</span> +and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> are defined on them. Note, however, that these operators +still denote proper prefix and prefix, respectively, not some kind of +alphabetic comparison as might be desirable, for example, when +sorting strings. +</p><h3 id="sec-finite-and-infinite-maps" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">9.3</span>. </span>Finite and Infinite Maps</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_finitemaptype_" class="ntdef" style="color:olive">FiniteMapType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"map"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] +<span class="code-escaped"><span id="1_infinitemaptype_" class="ntdef" style="color:olive">InfiniteMapType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"imap"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] </code></pre> +<p class="p noindent para-continued">For any types <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>, a value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code> denotes a +<em class="em-low1">(finite) map</em> +from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>. In other words, it is a look-up table indexed by +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>. The <em class="em-low1">domain</em> of the map is a finite set of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> values that have +associated <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code> values. Since the keys in the domain are compared +using equality in the type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code> can be used in a +non-ghost context only if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is equality supporting. +</p> +<p class="p indent">Similarly, for any types <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>, a value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span><T,U></code> +denotes a <em class="em-low1">(possibly) infinite map</em>. In most regards, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span><T,U></code> is +like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code>, but a map of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span><T,U></code> is allowed to have an +infinite domain. +</p> +<p class="p indent">A map can be formed using a <em class="em-low1">map display</em> expression (see <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_mapdisplayexpr" class="ntref localref" style="color:maroon">MapDisplayExpr</a></span></code>), +which is a possibly empty, ordered list of <em class="em-low1">maplets</em>, each maplet having the +form <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t <span style="color:blue">:=</span> u</code> where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> is an expression of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">u</code> is an +expression of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>, enclosed in square brackets after the keyword +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span></code>. To illustrate, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">map</span>[] <span style="color:teal">map</span>[<span class="constant" style="color:purple">20</span> <span style="color:blue">:=</span> <span style="color:blue">true</span>, <span class="constant" style="color:purple">3</span> <span style="color:blue">:=</span> <span style="color:blue">false</span>, <span class="constant" style="color:purple">20</span> <span style="color:blue">:=</span> <span style="color:blue">false</span>] <span style="color:teal">map</span>[a+b <span style="color:blue">:=</span> c+d]</code></pre> +<p class="p noindent para-continued">are three examples of map displays. By using the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span></code> +instead of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span></code>, the map produced will be of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span><T,U></code> +instead of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code>. Note that an infinite map (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span></code>) is allowed +to have a finite domain, whereas a finite map (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span></code>) is not allowed +to have an infinite domain. +If the same key occurs more than +once, only the last occurrence appears in the resulting +map.<sup id="back-fn-fn-map-display" ><a href="#fn-fn-map-display" title="3.This is likely to change in the future to disallow +multiple occurrences of the same key. +↩" class="footnote-ref localref" ><span class="footnote-label">3</span></a></sup> There is also a <em class="em-low1">map comprehension expression</em>, +explained in section <a href="#sec-map-comprehension-expression" title="22.34. Map Comprehension Expression" class="localref" style="target-element:h2"><span class="heading-label">22.34</span></a>. +</p> +<p class="p indent">For any map <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">fm</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code>, +any map <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><T,U></code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span><T,U></code>, +any expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, +any expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">u</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>, and any <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code> in the domain of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> (that +is, satisfying <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d <span style="color:blue">in</span> m</code>), maps support the following operations: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> expression </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <span class="monospace">|fm|</span> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> map cardinality </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m[d]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> map selection </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m[t <span style="color:blue">:=</span> u]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> map update </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t <span style="color:blue">in</span> m</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> map domain membership </td></tr> +<tr><td class="tbody tr-odd tr-last col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t !<span style="color:blue">in</span> m</code> </td><td class="tbody tr-odd tr-last col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> map domain non-membership </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="5" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="5" data-col="2"></td></tr></tbody></table> +<p class="p noindent"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|fm|</code> denotes the number of mappings in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">fm</code>, that is, the +cardinality of the domain of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">fm</code>. Note that the cardinality operator +is not supported for infinite maps. +Expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m[d]</code> returns the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code> value that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> associates with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code>. +Expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m[t <span style="color:blue">:=</span> u]</code> is a map like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code>, except that the +element at key <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">u</code>. The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t <span style="color:blue">in</span> m</code> says <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> is in the +domain of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t !<span style="color:blue">in</span> m</code> is a syntactic shorthand for +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!(t <span style="color:blue">in</span> m)</code>.<sup id="back-fn-fn-map-membership" ><a href="#fn-fn-map-membership" title="4.This is likely to change in the future as +follows: The in and !in operations will no longer be +supported on maps. Instead, for any map m, m.Domain will +return its domain as a set and m.Range will return, also as a +set, the image of m under its domain. +↩" class="footnote-ref localref" ><span class="footnote-label">4</span></a></sup> +</p> +<p class="p indent">Here is a small example, where a map <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">cache</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">map</span><<span style="color:teal">int</span>,<span style="color:teal">real</span>></code> +is used to cache computed values of Joule-Thomson coefficients for +some fixed gas at a given temperature: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">if</span> K <span style="color:blue">in</span> cache { <span style="color:darkgreen">// check if temperature is in domain of cache</span> + coeff <span style="color:blue">:=</span> cache[K]; <span style="color:darkgreen">// read result in cache</span> +} <span style="color:blue">else</span> { + coeff <span style="color:blue">:=</span> ComputeJouleThomsonCoefficient(K); <span style="color:darkgreen">// do expensive computation</span> + cache <span style="color:blue">:=</span> cache[K <span style="color:blue">:=</span> coeff]; <span style="color:darkgreen">// update the cache</span> +}</code></pre><h2 id="sec-types-that-stand-for-other-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">10</span>. </span>Types that stand for other types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_synonymtypedecl" class="ntdef" style="color:olive">SynonymTypeDecl</span></span> = + ( <span class="code-escaped"><a href="#1_synonymtypedefinition_" class="ntref localref" style="color:maroon">SynonymTypeDefinition_</a></span> | <span class="code-escaped"><a href="#1_opaquetypedefinition_" class="ntref localref" style="color:maroon">OpaqueTypeDefinition_</a></span> ) [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> ] </code></pre> +<p class="p noindent para-continued">It is sometimes useful to know a type by several names or to treat a +type abstractly. Synonym and opaque types serve this purpose. +</p><h3 id="sec-type-synonyms" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">10.0</span>. </span>Type synonyms</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_synonymtypedefinition_" class="ntdef" style="color:olive">SynonymTypeDefinition_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"type"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_synonymtypename" class="ntref localref" style="color:maroon">SynonymTypeName</a></span> [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"="</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span></code></pre> +<p class="p noindent para-continued">A <em class="em-low1">type synonym</em> declaration: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> Y<T> = G</code></pre> +<p class="p noindent para-continued">declares <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Y<T></code> to be a synonym for the type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G</code>. Here, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is a +nonempty list of type parameters (each of which is optionally +designated with the suffix “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(==)</code>”), which can be used as free type +variables in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G</code>. If the synonym has no type parameters, the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><T></code>” +is dropped. In all cases, a type synonym is just a synonym. That is, +there is never a difference, other than possibly in error messages +produced, between <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Y<T></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G</code>. +</p> +<p class="p indent">For example, the names of the following type synonyms may improve the +readability of a program: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> Replacements<T> = <span style="color:teal">map</span><T,T> +<span style="color:blue">type</span> Vertex = <span style="color:teal">int</span></code></pre> +<p class="p noindent para-continued">As already described in Section <a href="#sec-strings" title="9.2.4. Strings" class="localref" style="target-element:h3"><span class="heading-label">9.2.4</span></a>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">string</span></code> is a built-in +type synonym for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><<span style="color:teal">char</span>></code>, as if it would have been declared as +follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> <span style="color:teal">string</span> = <span style="color:teal">seq</span><<span style="color:teal">char</span>></code></pre><h3 id="sec-opaque-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">10.1</span>. </span>Opaque types</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_opaquetypedefinition_" class="ntdef" style="color:olive">OpaqueTypeDefinition_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"type"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_synonymtypename" class="ntref localref" style="color:maroon">SynonymTypeName</a></span> + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=="</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> ] [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] </code></pre> +<p class="p noindent para-continued">A special case of a type synonym is one that is underspecified. Such +a type is declared simply by: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> Y<T></code></pre> +<p class="p noindent para-continued">It is known as an <em class="em-low1">opaque type</em>. Its definition can be revealed in a +refining module. To indicate that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Y</code> designates an +equality-supporting type, “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(==)</code>” can be written immediately +following the name “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Y</code>”. +</p> +<p class="p indent">For example, the declarations +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> T +<span style="color:blue">function</span> F(t: T): T</code></pre> +<p class="p noindent para-continued">can be used to model an uninterpreted function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> on some +arbitrary type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>. As another example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">type</span> Monad<T></code></pre> +<p class="p noindent para-continued">can be used abstractly to represent an arbitrary parameterized monad. +</p><h2 id="sec-well-founded-functions-and-extreme-predicates" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">11</span>. </span>Well-founded Functions and Extreme Predicates</h2> +<p class="p noindent">This section is a tutorial on well-founded functions and extreme predicates. +We place it here in preparation for Section <a href="#sec-class-types" title="12. Class Types" class="localref" style="target-element:h1"><span class="heading-label">12</span></a> +where function and predicate definitions are described. +</p> +<p class="p indent">Recursive functions are a core part of computer science and mathematics. +Roughly speaking, when the definition of such a function spells out a +terminating computation from given arguments, we may refer to +it as a <em class="em-low1">well-founded function</em>. For example, the common factorial and +Fibonacci functions are well-founded functions. +</p> +<p class="p indent">There are also other ways to define functions. An important case +regards the definition of a boolean function as an extreme solution +(that is, a least or greatest solution) to some equation. For +computer scientists with interests in logic or programming languages, +these <em class="em-low1">extreme predicates</em> are important because they describe the +judgments that can be justified by a given set of inference rules +(see, e.g., <span class="citations" style="target-element:bibitem">[<a href="#camillerimelham:inductiverelations" title="Juanito Camilleri and Tom Melham. +Reasoning with inductively defined relations in the HOL theorem prover. +Technical Report 265, University of Cambridge Computer Laboratory, 1992." class="bibref localref" style="target-element:bibitem"><span class="cite-number">3</span></a>, <a href="#leroygrall:coinductivebigstep" title="Xavier Leroy and Hervé Grall. +Coinductive big-step operational semantics." class="bibref localref" style="target-element:bibitem"><span class="cite-number">24</span></a>, <a href="#nipkowklein:concretesemantics" title="Tobias Nipkow and Gerwin Klein. +Concrete Semantics with Isabelle/HOL." class="bibref localref" style="target-element:bibitem"><span class="cite-number">28</span></a>, <a href="#pierce:softwarefoundations" title="Benjamin C. Pierce, Chris Casinghino, Marco Gaboardi, Michael Greenberg, Catalin Hriţcu, Vilhelm Sjöberg, and Brent Yorgey. +Software Foundations. +http://www.cis.upenn.edu/~bcpierce/sf, version 3.2 edition, January 2015." class="bibref localref" style="target-element:bibitem"><span class="cite-number">31</span></a>, <a href="#winskel:formalsemantics" title="Glynn Winskel. +The Formal Semantics of Programming Languages: An Introduction. +MIT Press, 1993." class="bibref localref" style="target-element:bibitem"><span class="cite-number">36</span></a>]</span>). +</p> +<p class="p indent">To benefit from machine-assisted reasoning, it is necessary not just +to understand extreme predicates but also to have techniques for +proving theorems about them. A foundation for this reasoning was +developed by Paulin-Mohring <span class="citations" style="target-element:bibitem">[<a href="#paulinmohring:inductivecoq" title="Christine Paulin-Mohring. +Inductive definitions in the system Coq — rules and properties." class="bibref localref" style="target-element:bibitem"><span class="cite-number">29</span></a>]</span> and is the +basis of the constructive logic supported by Coq <span class="citations" style="target-element:bibitem">[<a href="#coq:book" title="Yves Bertot and Pierre Castéran. +Interactive Theorem Proving and Program Development — Coq'Art: The Calculus of Inductive Constructions. +Texts in Theoretical Computer Science. Springer, 2004." class="bibref localref" style="target-element:bibitem"><span class="cite-number">1</span></a>]</span> as well +as other proof assistants <span class="citations" style="target-element:bibitem">[<a href="#bovedybjernorell:briefagda" title="Ana Bove, Peter Dybjer, and Ulf Norell. +A brief overview of Agda — a functional language with dependent types. +In Stefan Berghofer, Tobias Nipkow, Christian Urban, and Makarius Wenzel, editors, Theorem Proving in Higher Order Logics, 22nd International Conference, TPHOLs 2009, volume 5674 of Lecture Notes in Computer Science, pages 73–78. Springer, August 2009." class="bibref localref" style="target-element:bibitem"><span class="cite-number">2</span></a>, <a href="#swamyetal:fstar2011" title="Nikhil Swamy, Juan Chen, Cédric Fournet, Pierre-Yves Strub, Karthikeyan Bhargavan, and Jean Yang. +Secure distributed programming with value-dependent types. +In ICFP 2011, pages 266–278. ACM, September 2011." class="bibref localref" style="target-element:bibitem"><span class="cite-number">34</span></a>]</span>. Essentially, the idea is to represent the +knowledge that an extreme predicate holds by the proof term by which +this knowledge was derived. For a predicate defined as the least +solution, such proof terms are values of an inductive datatype (that +is, finite proof trees), and for the greatest solution, a coinductive +datatype (that is, possibly infinite proof trees). This means that +one can use induction and coinduction when reasoning about these proof +trees. Therefore, these extreme predicates are known as, +respectively, <em class="em-low1">inductive predicates</em> and <em class="em-low1">coinductive predicates</em> (or, +<em class="em-low1">co-predicates</em> for short). Support for extreme predicates is also +available in the proof assistants Isabelle <span class="citations" style="target-element:bibitem">[<a href="#paulson:cade1994" title="Lawrence C. Paulson. +A fixedpoint approach to implementing (co)inductive definitions." class="bibref localref" style="target-element:bibitem"><span class="cite-number">30</span></a>]</span> and HOL +<span class="citations" style="target-element:bibitem">[<a href="#harrison:inductivedefs" title="John Harrison. +Inductive definitions: Automation and application." class="bibref localref" style="target-element:bibitem"><span class="cite-number">6</span></a>]</span>. +</p> +<p class="p indent">Dafny supports both well-founded functions and extreme predicates. +This section is a tutorial that describes the difference in general +terms, and then describes novel syntactic support in Dafny for +defining and proving lemmas with extreme predicates. Although Dafny's +verifier has at its core a first-order SMT solver, Dafny's logical +encoding makes it possible to reason about fixpoints in an automated +way. +</p> +<p class="p indent">The encoding for coinductive predicates in Dafny was described previously +<span class="citations" style="target-element:bibitem">[<a href="#leinomoskal:coinduction" title="K. Rustan M. Leino and Michał Moskal. +Co-induction simply — automatic co-inductive proofs in a program verifier. +In FM 2014, volume 8442 of LNCS, pages 382–398. Springer, May 2014b." class="bibref localref" style="target-element:bibitem"><span class="cite-number">21</span></a>]</span> and is here described in Section +<a href="#sec-co-inductive-datatypes" title="18.2. Co-inductive datatypes" class="localref" style="target-element:h2"><span class="heading-label">18.2</span></a>. +</p><h3 id="sec-function-definitions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">11.0</span>. </span>Function Definitions</h3> +<p class="p noindent para-continue">To define a function <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:4.8277em" viewBox='-0.2 25.78 45.978 9.466' ><desc>$f \colon X \to Y$</desc><g id='page1'><use x='0' xlink:href='#g3-102' y='33.004'/><use x='7.039' xlink:href='#g5-58' y='33.004'/><use x='13.127' xlink:href='#g3-88' y='33.004'/><use x='24.899' xlink:href='#g1-33' y='33.004'/><use x='37.592' xlink:href='#g3-89' y='33.004'/></g></svg> in terms of itself, one can +write an equation like +</p> +<div id="eq-general" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(0)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:5.9833em" viewBox='195.957 27.324 56.984 10.363' ><desc>\[ f \Equal \F(f) +\]</desc><g id='page2'><use x='196.157' xlink:href='#g3-102' y='34.996'/><use x='213.158' xlink:href='#g5-61' y='34.996'/><use x='231.947' xlink:href='#g1-70' y='34.996'/><use x='240.07' xlink:href='#g5-40' y='34.996'/><use x='243.93' xlink:href='#g3-102' y='34.996'/><use x='249.862' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">where <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-0.2 25.919 8.669 7.603' ><desc>$\mathcal{F}$</desc><g id='page5'><use x='0' xlink:href='#g1-70' y='33.004'/></g></svg> is a non-recursive function of type +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:9.2896em" viewBox='-18.2 25.332 88.472 10.363' ><desc>$(X \to Y) \to X \to Y$</desc><g id='page4'><use x='-18' xlink:href='#g5-40' y='33.004'/><use x='-14.14' xlink:href='#g3-88' y='33.004'/><use x='-2.368' xlink:href='#g1-33' y='33.004'/><use x='10.325' xlink:href='#g3-89' y='33.004'/><use x='18.301' xlink:href='#g5-41' y='33.004'/><use x='24.928' xlink:href='#g1-33' y='33.004'/><use x='37.621' xlink:href='#g3-88' y='33.004'/><use x='49.393' xlink:href='#g1-33' y='33.004'/><use x='62.086' xlink:href='#g3-89' y='33.004'/></g></svg>. Because it takes a function as an argument, +<svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-0.2 25.919 8.669 7.603' ><desc>$\mathcal{F}$</desc><g id='page5'><use x='0' xlink:href='#g1-70' y='33.004'/></g></svg> is referred to as a <em class="em-low1">functor</em> (or <em class="em-low1">functional</em>, but not to be +confused by the category-theory notion of a functor). +Throughout, I will assume that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.3294em" viewBox='-18.2 25.332 22.185 10.363' ><desc>$\F(f)$</desc><g id='page8'><use x='-18' xlink:href='#g1-70' y='33.004'/><use x='-9.877' xlink:href='#g5-40' y='33.004'/><use x='-6.017' xlink:href='#g3-102' y='33.004'/><use x='-0.085' xlink:href='#g5-41' y='33.004'/></g></svg> by itself is well defined, +for example that it does not divide by zero. I will also assume that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> occurs +only in fully applied calls in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.3294em" viewBox='-18.2 25.332 22.185 10.363' ><desc>$\F(f)$</desc><g id='page8'><use x='-18' xlink:href='#g1-70' y='33.004'/><use x='-9.877' xlink:href='#g5-40' y='33.004'/><use x='-6.017' xlink:href='#g3-102' y='33.004'/><use x='-0.085' xlink:href='#g5-41' y='33.004'/></g></svg>; eta expansion can be applied to +ensure this. If <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> is a boolean function, that is, if <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.8805em" viewBox='-18.2 25.999 8.386 7.204' ><desc>$Y$</desc><g id='page210'><use x='-18' xlink:href='#g3-89' y='33.004'/></g></svg> is +the type of booleans, then I call <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> a <em class="em-low1">predicate</em>. +</p> +<p class="p indent para-continue">For example, the common Fibonacci function over the +natural numbers can be defined by the equation +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(1)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:27.1042em" viewBox='95.112 27.324 258.135 10.363' ><desc>\[ \fib \Equal + \lambda n \bullet\; \ite{n < 2}{n}{\fib(n-2) + \fib(n-1)} +\]</desc><g id='page12'><use x='95.561' xlink:href='#g0-12' y='34.996'/><use x='101.142' xlink:href='#g0-98' y='34.996'/><use x='117.444' xlink:href='#g5-61' y='34.996'/><use x='136.233' xlink:href='#g3-21' y='34.996'/><use x='142.022' xlink:href='#g3-110' y='34.996'/><use x='150.194' xlink:href='#g1-15' y='34.996'/><use x='160.138' xlink:href='#g5-105' y='34.996'/><use x='162.895' xlink:href='#g5-102' y='34.996'/><use x='171.484' xlink:href='#g3-110' y='34.996'/><use x='180.209' xlink:href='#g3-60' y='34.996'/><use x='190.696' xlink:href='#g5-50' y='34.996'/><use x='201.194' xlink:href='#g5-116' y='34.996'/><use x='205.053' xlink:href='#g5-104' y='34.996'/><use x='210.568' xlink:href='#g5-101' y='34.996'/><use x='214.979' xlink:href='#g5-110' y='34.996'/><use x='226.1' xlink:href='#g3-110' y='34.996'/><use x='237.592' xlink:href='#g5-101' y='34.996'/><use x='242.004' xlink:href='#g5-108' y='34.996'/><use x='244.761' xlink:href='#g5-115' y='34.996'/><use x='248.676' xlink:href='#g5-101' y='34.996'/><use x='258.68' xlink:href='#g0-12' y='34.996'/><use x='264.26' xlink:href='#g0-98' y='34.996'/><use x='269.493' xlink:href='#g5-40' y='34.996'/><use x='273.352' xlink:href='#g3-110' y='34.996'/><use x='281.524' xlink:href='#g1-0' y='34.996'/><use x='291.458' xlink:href='#g5-50' y='34.996'/><use x='296.42' xlink:href='#g5-41' y='34.996'/><use x='302.494' xlink:href='#g5-43' y='34.996'/><use x='312.428' xlink:href='#g0-12' y='34.996'/><use x='318.008' xlink:href='#g0-98' y='34.996'/><use x='323.241' xlink:href='#g5-40' y='34.996'/><use x='327.1' xlink:href='#g3-110' y='34.996'/><use x='335.272' xlink:href='#g1-0' y='34.996'/><use x='345.206' xlink:href='#g5-49' y='34.996'/><use x='350.168' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued para-continue">With the understanding that the argument <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg> is universally +quantified, we can write this equation equivalently as +</p> +<div id="eq-fib" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(2)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:26.0302em" viewBox='100.232 27.324 247.907 10.363' ><desc>\[ \fib(n) \Equal + \ite{n < 2}{n}{\fib(n-2) + \fib(n-1)} +\]</desc><g id='page14'><use x='100.681' xlink:href='#g0-12' y='34.996'/><use x='106.261' xlink:href='#g0-98' y='34.996'/><use x='111.494' xlink:href='#g5-40' y='34.996'/><use x='115.354' xlink:href='#g3-110' y='34.996'/><use x='121.311' xlink:href='#g5-41' y='34.996'/><use x='136.241' xlink:href='#g5-61' y='34.996'/><use x='155.03' xlink:href='#g5-105' y='34.996'/><use x='157.787' xlink:href='#g5-102' y='34.996'/><use x='166.376' xlink:href='#g3-110' y='34.996'/><use x='175.101' xlink:href='#g3-60' y='34.996'/><use x='185.588' xlink:href='#g5-50' y='34.996'/><use x='196.085' xlink:href='#g5-116' y='34.996'/><use x='199.945' xlink:href='#g5-104' y='34.996'/><use x='205.459' xlink:href='#g5-101' y='34.996'/><use x='209.871' xlink:href='#g5-110' y='34.996'/><use x='220.992' xlink:href='#g3-110' y='34.996'/><use x='232.484' xlink:href='#g5-101' y='34.996'/><use x='236.895' xlink:href='#g5-108' y='34.996'/><use x='239.652' xlink:href='#g5-115' y='34.996'/><use x='243.567' xlink:href='#g5-101' y='34.996'/><use x='253.572' xlink:href='#g0-12' y='34.996'/><use x='259.152' xlink:href='#g0-98' y='34.996'/><use x='264.384' xlink:href='#g5-40' y='34.996'/><use x='268.244' xlink:href='#g3-110' y='34.996'/><use x='276.416' xlink:href='#g1-0' y='34.996'/><use x='286.349' xlink:href='#g5-50' y='34.996'/><use x='291.312' xlink:href='#g5-41' y='34.996'/><use x='297.386' xlink:href='#g5-43' y='34.996'/><use x='307.32' xlink:href='#g0-12' y='34.996'/><use x='312.9' xlink:href='#g0-98' y='34.996'/><use x='318.132' xlink:href='#g5-40' y='34.996'/><use x='321.992' xlink:href='#g3-110' y='34.996'/><use x='330.164' xlink:href='#g1-0' y='34.996'/><use x='340.097' xlink:href='#g5-49' y='34.996'/><use x='345.06' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">The fact that the function being defined occurs on both sides of the equation +causes concern that we might not be defining the function properly, leading to a +logical inconsistency. In general, there +could be many solutions to an equation like <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> or there could be none. +Let's consider two ways to make sure we're defining the function uniquely. +</p><h4 id="sec-well-founded-functions" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.0.0</span>. </span>Well-founded Functions</h4> +<p class="p noindent para-continue">A standard way to ensure that equation <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> has a unique solution in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> is +to make sure the recursion is well-founded, which roughly means that the +recursion terminates. This is done by introducing any well-founded +relation <svg class="math-inline math-render-svg math" style="vertical-align:-0.0685em;height:0.7031em;width:1.0852em" viewBox='-18.2 27.165 10.335 6.696' ><desc>$\Less$</desc><g id='page32'><use x='-18' xlink:href='#g1-28' y='33.004'/></g></svg> on the domain of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> and making sure that the argument to each recursive +call goes down in this ordering. More precisely, if we formulate <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> as +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(3)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.1448em;width:7.6831em" viewBox='187.838 26.784 73.172 10.903' ><desc>\[ f(x) \Equal \F'(f) +\]</desc><g id='page18'><use x='188.038' xlink:href='#g3-102' y='34.996'/><use x='193.97' xlink:href='#g5-40' y='34.996'/><use x='197.83' xlink:href='#g3-120' y='34.996'/><use x='203.502' xlink:href='#g5-41' y='34.996'/><use x='218.432' xlink:href='#g5-61' y='34.996'/><use x='237.221' xlink:href='#g1-70' y='34.996'/><use x='245.344' xlink:href='#g2-48' y='30.883'/><use x='248.139' xlink:href='#g5-40' y='34.996'/><use x='251.999' xlink:href='#g3-102' y='34.996'/><use x='257.931' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">then we want to check <svg class="math-inline math-render-svg math" style="vertical-align:-0.0655em;height:0.8224em;width:3.0916em" viewBox='-0.2 26.029 29.444 7.832' ><desc>$E \Less x$</desc><g id='page19'><use x='0' xlink:href='#g3-69' y='33.004'/><use x='10.668' xlink:href='#g1-28' y='33.004'/><use x='23.361' xlink:href='#g3-120' y='33.004'/></g></svg> for each call <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.3061em" viewBox='-18.2 25.332 21.963 10.363' ><desc>$f(E)$</desc><g id='page20'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.068' xlink:href='#g5-40' y='33.004'/><use x='-8.208' xlink:href='#g3-69' y='33.004'/><use x='-0.307' xlink:href='#g5-41' y='33.004'/></g></svg> in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2936em;height:1.0924em;width:2.6229em" viewBox='-0.2 25.29 24.98 10.404' ><desc>$\F'(f)$</desc><g id='page209'><use x='0' xlink:href='#g1-70' y='33.004'/><use x='8.123' xlink:href='#g2-48' y='29.388'/><use x='10.918' xlink:href='#g5-40' y='33.004'/><use x='14.778' xlink:href='#g3-102' y='33.004'/><use x='20.71' xlink:href='#g5-41' y='33.004'/></g></svg>. When a function +definition satisfies this <em class="em-low1">decrement condition</em>, then the function is said to be +<em class="em-low1">well-founded</em>. +</p> +<p class="p indent para-continue">For example, to check the decrement condition for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:1.2046em" viewBox='-0.449 25.78 11.472 9.466' ><desc>$\fib$</desc><g id='page41'><use x='0' xlink:href='#g0-12' y='33.004'/><use x='5.58' xlink:href='#g0-98' y='33.004'/></g></svg> in <a href="#eq-fib" class="localref" style="target-element:equation"><span class="equation-label">(2)</span></a>, we can pick +<svg class="math-inline math-render-svg math" style="vertical-align:-0.0685em;height:0.7031em;width:1.0852em" viewBox='-18.2 27.165 10.335 6.696' ><desc>$\Less$</desc><g id='page32'><use x='-18' xlink:href='#g1-28' y='33.004'/></g></svg> to be the arithmetic less-than relation on natural numbers and check the +following, for any <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg>: +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(4)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:0.8820em;width:18.2190em" viewBox='155.898 28.161 173.514 8.4' ><desc>\[ 2 \leq n \;\;\Imp\;\; n-2 \Less n \;\And\; n-1 \Less n +\]</desc><g id='page25'><use x='156.098' xlink:href='#g5-50' y='34.996'/><use x='163.828' xlink:href='#g1-20' y='34.996'/><use x='174.316' xlink:href='#g3-110' y='34.996'/><use x='191.343' xlink:href='#g5-61' y='34.996'/><use x='197.402' xlink:href='#g1-41' y='34.996'/><use x='218.397' xlink:href='#g3-110' y='34.996'/><use x='226.568' xlink:href='#g1-0' y='34.996'/><use x='236.502' xlink:href='#g5-50' y='34.996'/><use x='244.232' xlink:href='#g1-28' y='34.996'/><use x='256.925' xlink:href='#g3-110' y='34.996'/><use x='270.631' xlink:href='#g1-94' y='34.996'/><use x='284.996' xlink:href='#g3-110' y='34.996'/><use x='293.168' xlink:href='#g1-0' y='34.996'/><use x='303.101' xlink:href='#g5-49' y='34.996'/><use x='310.831' xlink:href='#g1-28' y='34.996'/><use x='323.524' xlink:href='#g3-110' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">Note that we are entitled to using the antecedent <svg class="math-inline math-render-svg math" style="vertical-align:-0.1747em;height:0.8820em;width:2.5814em" viewBox='-18.2 26.168 24.585 8.4' ><desc>$2 \leq n$</desc><g id='page26'><use x='-18' xlink:href='#g5-50' y='33.004'/><use x='-10.27' xlink:href='#g1-20' y='33.004'/><use x='0.217' xlink:href='#g3-110' y='33.004'/></g></svg>, because that is the +condition under which the else branch in <a href="#eq-fib" class="localref" style="target-element:equation"><span class="equation-label">(2)</span></a> is evaluated. +</p> +<p class="p indent para-continue">A well-founded function is often thought of as “terminating” in the sense +that the recursive <em class="em-low1">depth</em> in evaluating <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> +on any given argument is finite. That is, there are no infinite descending chains +of recursive calls. However, the evaluation of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> on a given argument +may fail to terminate, because its <em class="em-low1">width</em> may be infinite. For example, let <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.8574em" viewBox='-0.2 25.999 8.166 7.204' ><desc>$P$</desc><g id='page29'><use x='0' xlink:href='#g3-80' y='33.004'/></g></svg> +be some predicate defined on the ordinals and let <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:5.6203em" viewBox='-18.2 25.89 53.527 7.424' ><desc>$\PDownward$</desc><g id='page30'><use x='-18' xlink:href='#g0-80' y='33.004'/><use x='-11.267' xlink:href='#g0-68' y='33.004'/><use x='-3.774' xlink:href='#g0-111' y='33.004'/><use x='1.299' xlink:href='#g0-119' y='33.004'/><use x='7.894' xlink:href='#g0-110' y='33.004'/><use x='13.474' xlink:href='#g0-119' y='33.004'/><use x='20.069' xlink:href='#g0-97' y='33.004'/><use x='25.142' xlink:href='#g0-114' y='33.004'/><use x='28.818' xlink:href='#g0-100' y='33.004'/></g></svg> be a predicate on the +ordinals defined by the following equation: +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(5)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:28.6237em" viewBox='105.997 27.324 272.607 10.363' ><desc>\[ \PDownward(o) \Equal + P(o) \And \forall p \bullet\; p \Less o \Imp \PDownward(p) +\]</desc><g id='page31'><use x='106.197' xlink:href='#g0-80' y='34.996'/><use x='112.93' xlink:href='#g0-68' y='34.996'/><use x='120.424' xlink:href='#g0-111' y='34.996'/><use x='125.497' xlink:href='#g0-119' y='34.996'/><use x='132.091' xlink:href='#g0-110' y='34.996'/><use x='137.672' xlink:href='#g0-119' y='34.996'/><use x='144.267' xlink:href='#g0-97' y='34.996'/><use x='149.339' xlink:href='#g0-114' y='34.996'/><use x='153.015' xlink:href='#g0-100' y='34.996'/><use x='159.314' xlink:href='#g5-40' y='34.996'/><use x='163.174' xlink:href='#g3-111' y='34.996'/><use x='167.985' xlink:href='#g5-41' y='34.996'/><use x='182.915' xlink:href='#g5-61' y='34.996'/><use x='201.704' xlink:href='#g3-80' y='34.996'/><use x='209.46' xlink:href='#g5-40' y='34.996'/><use x='213.32' xlink:href='#g3-111' y='34.996'/><use x='218.131' xlink:href='#g5-41' y='34.996'/><use x='226.972' xlink:href='#g1-94' y='34.996'/><use x='238.57' xlink:href='#g1-56' y='34.996'/><use x='244.084' xlink:href='#g3-112' y='34.996'/><use x='251.292' xlink:href='#g1-15' y='34.996'/><use x='261.236' xlink:href='#g3-112' y='34.996'/><use x='268.997' xlink:href='#g1-28' y='34.996'/><use x='281.689' xlink:href='#g3-111' y='34.996'/><use x='292.035' xlink:href='#g5-61' y='34.996'/><use x='298.095' xlink:href='#g1-41' y='34.996'/><use x='313.555' xlink:href='#g0-80' y='34.996'/><use x='320.287' xlink:href='#g0-68' y='34.996'/><use x='327.781' xlink:href='#g0-111' y='34.996'/><use x='332.854' xlink:href='#g0-119' y='34.996'/><use x='339.449' xlink:href='#g0-110' y='34.996'/><use x='345.029' xlink:href='#g0-119' y='34.996'/><use x='351.624' xlink:href='#g0-97' y='34.996'/><use x='356.697' xlink:href='#g0-114' y='34.996'/><use x='360.373' xlink:href='#g0-100' y='34.996'/><use x='366.672' xlink:href='#g5-40' y='34.996'/><use x='370.532' xlink:href='#g3-112' y='34.996'/><use x='375.525' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">With <svg class="math-inline math-render-svg math" style="vertical-align:-0.0685em;height:0.7031em;width:1.0852em" viewBox='-18.2 27.165 10.335 6.696' ><desc>$\Less$</desc><g id='page32'><use x='-18' xlink:href='#g1-28' y='33.004'/></g></svg> as the usual ordering on ordinals, this equation satisfies the decrement +condition, but evaluating <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:7.1171em" viewBox='-0.2 25.332 67.782 10.363' ><desc>$\PDownward(\omega)$</desc><g id='page33'><use x='0' xlink:href='#g0-80' y='33.004'/><use x='6.733' xlink:href='#g0-68' y='33.004'/><use x='14.226' xlink:href='#g0-111' y='33.004'/><use x='19.299' xlink:href='#g0-119' y='33.004'/><use x='25.894' xlink:href='#g0-110' y='33.004'/><use x='31.474' xlink:href='#g0-119' y='33.004'/><use x='38.069' xlink:href='#g0-97' y='33.004'/><use x='43.142' xlink:href='#g0-114' y='33.004'/><use x='46.818' xlink:href='#g0-100' y='33.004'/><use x='53.117' xlink:href='#g5-40' y='33.004'/><use x='56.977' xlink:href='#g3-33' y='33.004'/><use x='63.513' xlink:href='#g5-41' y='33.004'/></g></svg> would require evaluating +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:7.0565em" viewBox='-18.2 25.332 67.205 10.363' ><desc>$\PDownward(n)$</desc><g id='page34'><use x='-18' xlink:href='#g0-80' y='33.004'/><use x='-11.267' xlink:href='#g0-68' y='33.004'/><use x='-3.774' xlink:href='#g0-111' y='33.004'/><use x='1.299' xlink:href='#g0-119' y='33.004'/><use x='7.894' xlink:href='#g0-110' y='33.004'/><use x='13.474' xlink:href='#g0-119' y='33.004'/><use x='20.069' xlink:href='#g0-97' y='33.004'/><use x='25.142' xlink:href='#g0-114' y='33.004'/><use x='28.818' xlink:href='#g0-100' y='33.004'/><use x='35.117' xlink:href='#g5-40' y='33.004'/><use x='38.977' xlink:href='#g3-110' y='33.004'/><use x='44.935' xlink:href='#g5-41' y='33.004'/></g></svg> for every natural number <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg>. However, what we are concerned +about here is to avoid mathematical inconsistencies, and that is +indeed a consequence of the decrement condition. +</p><h5 id="sec-fib-example" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">11.0.0.0</span>. </span>Example with Well-founded Functions</h5> +<p class="p noindent">So that we can later see how inductive proofs are done in Dafny, let's prove that +for any <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg>, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.6406em" viewBox='-0.449 25.332 25.149 10.363' ><desc>$\fib(n)$</desc><g id='page37'><use x='0' xlink:href='#g0-12' y='33.004'/><use x='5.58' xlink:href='#g0-98' y='33.004'/><use x='10.813' xlink:href='#g5-40' y='33.004'/><use x='14.673' xlink:href='#g3-110' y='33.004'/><use x='20.63' xlink:href='#g5-41' y='33.004'/></g></svg> is even iff <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg> is a multiple of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7617em;width:0.5642em" viewBox='-0.2 26.168 5.373 7.254' ><desc>$3$</desc><g id='page39'><use x='0' xlink:href='#g5-51' y='33.004'/></g></svg>. +We split our task into +two cases. If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0656em;height:0.7806em;width:2.5814em" viewBox='-18.2 26.168 24.585 7.434' ><desc>$n < 2$</desc><g id='page40'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.275' xlink:href='#g3-60' y='33.004'/><use x='1.212' xlink:href='#g5-50' y='33.004'/></g></svg>, then the property follows directly from the definition +of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:1.2046em" viewBox='-0.449 25.78 11.472 9.466' ><desc>$\fib$</desc><g id='page41'><use x='0' xlink:href='#g0-12' y='33.004'/><use x='5.58' xlink:href='#g0-98' y='33.004'/></g></svg>. Otherwise, note that exactly one of the three numbers <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-18.2 26.168 23.478 7.145' ><desc>$n-2$</desc><g id='page54'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.829' xlink:href='#g1-0' y='33.004'/><use x='0.105' xlink:href='#g5-50' y='33.004'/></g></svg>, <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-0.2 26.168 23.478 7.145' ><desc>$n-1$</desc><g id='page55'><use x='0' xlink:href='#g3-110' y='33.004'/><use x='8.171' xlink:href='#g1-0' y='33.004'/><use x='18.105' xlink:href='#g5-49' y='33.004'/></g></svg>, and <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg> +is a multiple of 3. If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg> is the multiple of 3, then by invoking the +induction hypothesis on <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-18.2 26.168 23.478 7.145' ><desc>$n-2$</desc><g id='page54'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.829' xlink:href='#g1-0' y='33.004'/><use x='0.105' xlink:href='#g5-50' y='33.004'/></g></svg> +and <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-0.2 26.168 23.478 7.145' ><desc>$n-1$</desc><g id='page55'><use x='0' xlink:href='#g3-110' y='33.004'/><use x='8.171' xlink:href='#g1-0' y='33.004'/><use x='18.105' xlink:href='#g5-49' y='33.004'/></g></svg>, we obtain that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:10.0808em" viewBox='-0.449 25.332 96.008 10.363' ><desc>$\fib(n-2) + \fib(n-1)$</desc><g id='page53'><use x='0' xlink:href='#g0-12' y='33.004'/><use x='5.58' xlink:href='#g0-98' y='33.004'/><use x='10.813' xlink:href='#g5-40' y='33.004'/><use x='14.673' xlink:href='#g3-110' y='33.004'/><use x='22.844' xlink:href='#g1-0' y='33.004'/><use x='32.778' xlink:href='#g5-50' y='33.004'/><use x='37.741' xlink:href='#g5-41' y='33.004'/><use x='43.814' xlink:href='#g5-43' y='33.004'/><use x='53.748' xlink:href='#g0-12' y='33.004'/><use x='59.328' xlink:href='#g0-98' y='33.004'/><use x='64.561' xlink:href='#g5-40' y='33.004'/><use x='68.421' xlink:href='#g3-110' y='33.004'/><use x='76.592' xlink:href='#g1-0' y='33.004'/><use x='86.526' xlink:href='#g5-49' y='33.004'/><use x='91.489' xlink:href='#g5-41' y='33.004'/></g></svg> is the sum of two odd numbers, +which is even. If <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-18.2 26.168 23.478 7.145' ><desc>$n-2$</desc><g id='page54'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.829' xlink:href='#g1-0' y='33.004'/><use x='0.105' xlink:href='#g5-50' y='33.004'/></g></svg> or <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-0.2 26.168 23.478 7.145' ><desc>$n-1$</desc><g id='page55'><use x='0' xlink:href='#g3-110' y='33.004'/><use x='8.171' xlink:href='#g1-0' y='33.004'/><use x='18.105' xlink:href='#g5-49' y='33.004'/></g></svg> is a multiple of 3, then by invoking the induction +hypothesis on <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-18.2 26.168 23.478 7.145' ><desc>$n-2$</desc><g id='page54'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.829' xlink:href='#g1-0' y='33.004'/><use x='0.105' xlink:href='#g5-50' y='33.004'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-0.2 26.168 23.478 7.145' ><desc>$n-1$</desc><g id='page55'><use x='0' xlink:href='#g3-110' y='33.004'/><use x='8.171' xlink:href='#g1-0' y='33.004'/><use x='18.105' xlink:href='#g5-49' y='33.004'/></g></svg>, we obtain that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:10.0808em" viewBox='-0.449 25.332 96.008 10.363' ><desc>$\fib(n-2) + \fib(n-1)$</desc><g id='page53'><use x='0' xlink:href='#g0-12' y='33.004'/><use x='5.58' xlink:href='#g0-98' y='33.004'/><use x='10.813' xlink:href='#g5-40' y='33.004'/><use x='14.673' xlink:href='#g3-110' y='33.004'/><use x='22.844' xlink:href='#g1-0' y='33.004'/><use x='32.778' xlink:href='#g5-50' y='33.004'/><use x='37.741' xlink:href='#g5-41' y='33.004'/><use x='43.814' xlink:href='#g5-43' y='33.004'/><use x='53.748' xlink:href='#g0-12' y='33.004'/><use x='59.328' xlink:href='#g0-98' y='33.004'/><use x='64.561' xlink:href='#g5-40' y='33.004'/><use x='68.421' xlink:href='#g3-110' y='33.004'/><use x='76.592' xlink:href='#g1-0' y='33.004'/><use x='86.526' xlink:href='#g5-49' y='33.004'/><use x='91.489' xlink:href='#g5-41' y='33.004'/></g></svg> is the sum of an +even number and an odd number, which is odd. In this proof, we invoked the induction +hypothesis on <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-18.2 26.168 23.478 7.145' ><desc>$n-2$</desc><g id='page54'><use x='-18' xlink:href='#g3-110' y='33.004'/><use x='-9.829' xlink:href='#g1-0' y='33.004'/><use x='0.105' xlink:href='#g5-50' y='33.004'/></g></svg> and on <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4652em" viewBox='-0.2 26.168 23.478 7.145' ><desc>$n-1$</desc><g id='page55'><use x='0' xlink:href='#g3-110' y='33.004'/><use x='8.171' xlink:href='#g1-0' y='33.004'/><use x='18.105' xlink:href='#g5-49' y='33.004'/></g></svg>. This is allowed, because both are smaller than +<svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6686em" viewBox='-18.2 28.4 6.368 4.913' ><desc>$n$</desc><g id='page56'><use x='-18' xlink:href='#g3-110' y='33.004'/></g></svg>, and hence the invocations go down in the well-founded ordering on natural numbers. +</p><h4 id="sec-extreme-solutions" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.0.1</span>. </span>Extreme Solutions</h4> +<p class="p noindent">We don't need to exclude the possibility of equation <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> having multiple +solutions—instead, we can just be clear about which one of them we want. +Let's explore this, after a smidgen of lattice theory. +</p> +<p class="p indent para-continue">For any complete lattice <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.7912em" viewBox='-0.2 25.332 26.583 10.363' ><desc>$(Y,\leq)$</desc><g id='page57'><use x='0' xlink:href='#g5-40' y='33.004'/><use x='3.86' xlink:href='#g3-89' y='33.004'/><use x='10.176' xlink:href='#g3-59' y='33.004'/><use x='14.593' xlink:href='#g1-20' y='33.004'/><use x='22.313' xlink:href='#g5-41' y='33.004'/></g></svg> and any set <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.9886em" viewBox='-18.2 25.999 9.415 7.204' ><desc>$X$</desc><g id='page214'><use x='-18' xlink:href='#g3-88' y='33.004'/></g></svg>, we can by <em class="em-low1">pointwise extension</em> define +a complete lattice <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:6.7578em" viewBox='-0.2 25.332 64.36 10.363' ><desc>$(X \to Y, \FBelow)$</desc><g id='page59'><use x='0' xlink:href='#g5-40' y='33.004'/><use x='3.86' xlink:href='#g3-88' y='33.004'/><use x='15.632' xlink:href='#g1-33' y='33.004'/><use x='28.325' xlink:href='#g3-89' y='33.004'/><use x='34.64' xlink:href='#g3-59' y='33.004'/><use x='48.19' xlink:href='#g5-95' y='33.004'/><use x='44.593' xlink:href='#g1-41' y='33.004'/><use x='60.09' xlink:href='#g5-41' y='33.004'/></g></svg>, where for any <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:5.7680em" viewBox='-18.2 25.78 54.933 9.466' ><desc>$f,g \colon X \to Y$</desc><g id='page60'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.622' xlink:href='#g3-59' y='33.004'/><use x='-8.204' xlink:href='#g3-103' y='33.004'/><use x='-2.006' xlink:href='#g5-58' y='33.004'/><use x='4.082' xlink:href='#g3-88' y='33.004'/><use x='15.854' xlink:href='#g1-33' y='33.004'/><use x='28.547' xlink:href='#g3-89' y='33.004'/></g></svg>, +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(6)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:13.6397em" viewBox='177.414 27.324 129.902 10.363' ><desc>\[ f \FBelow q \Equiv + \forall x \bullet\; f(x) \leq g(x) +\]</desc><g id='page61'><use x='177.614' xlink:href='#g3-102' y='34.996'/><use x='192.678' xlink:href='#g5-95' y='34.996'/><use x='189.08' xlink:href='#g1-41' y='34.996'/><use x='204.577' xlink:href='#g3-113' y='34.996'/><use x='217.668' xlink:href='#g1-17' y='34.996'/><use x='233.689' xlink:href='#g1-56' y='34.996'/><use x='239.204' xlink:href='#g3-120' y='34.996'/><use x='247.09' xlink:href='#g1-15' y='34.996'/><use x='257.034' xlink:href='#g3-102' y='34.996'/><use x='262.966' xlink:href='#g5-40' y='34.996'/><use x='266.826' xlink:href='#g3-120' y='34.996'/><use x='272.498' xlink:href='#g5-41' y='34.996'/><use x='279.126' xlink:href='#g1-20' y='34.996'/><use x='289.613' xlink:href='#g3-103' y='34.996'/><use x='294.704' xlink:href='#g5-40' y='34.996'/><use x='298.564' xlink:href='#g3-120' y='34.996'/><use x='304.237' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">In particular, if <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.8805em" viewBox='-18.2 25.999 8.386 7.204' ><desc>$Y$</desc><g id='page210'><use x='-18' xlink:href='#g3-89' y='33.004'/></g></svg> is the set of booleans ordered by implication (<svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:5.4810em" viewBox='-0.449 25.78 52.2 9.466' ><desc>$\false \leq \true$</desc><g id='page63'><use x='0' xlink:href='#g0-102' y='33.004'/><use x='3.044' xlink:href='#g0-97' y='33.004'/><use x='8.117' xlink:href='#g0-108' y='33.004'/><use x='10.653' xlink:href='#g0-115' y='33.004'/><use x='14.712' xlink:href='#g0-101' y='33.004'/><use x='22.865' xlink:href='#g1-20' y='33.004'/><use x='33.353' xlink:href='#g0-116' y='33.004'/><use x='36.65' xlink:href='#g0-114' y='33.004'/><use x='40.835' xlink:href='#g0-117' y='33.004'/><use x='46.162' xlink:href='#g0-101' y='33.004'/></g></svg>), +then the set of predicates over any domain <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.9886em" viewBox='-18.2 25.999 9.415 7.204' ><desc>$X$</desc><g id='page214'><use x='-18' xlink:href='#g3-88' y='33.004'/></g></svg> forms a complete lattice. +Tarski's Theorem <span class="citations" style="target-element:bibitem">[<a href="#tarski:theorem" title="Alfred Tarski. +A lattice-theoretical fixpoint theorem and its applications." class="bibref localref" style="target-element:bibitem"><span class="cite-number">35</span></a>]</span> tells us that any monotonic function over a +complete lattice has a least and a greatest fixpoint. In particular, this means that +<svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> has a least fixpoint and a greatest fixpoint, provided <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> is monotonic. +</p> +<p class="p indent">Speaking about the <em class="em-low1">set of solutions</em> in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> to <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> is the same as speaking +about the <em class="em-low1">set of fixpoints</em> of functor <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>. In particular, the least and greatest +solutions to <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> are the same as the least and greatest fixpoints of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>. +In casual speak, it happens that we say “fixpoint of <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a>”, or more +grotesquely, “fixpoint of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg>” when we really mean “fixpoint of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>”. +</p> +<p class="p indent">In conclusion of our little excursion into lattice theory, we have that, under the +proviso of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> being monotonic, the set of solutions in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> to <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> is nonempty, +and among these solutions, there is in the <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7680em;width:2.2514em" viewBox='-18.2 26.139 21.442 7.314' ><desc>$\FBelow$</desc><g id='page74'><use x='-8.868' xlink:href='#g5-95' y='33.004'/><use x='-12.465' xlink:href='#g1-41' y='33.004'/></g></svg> ordering a least solution (that is, +a function that returns <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:2.1795em" viewBox='-0.449 25.78 20.757 9.466' ><desc>$\false$</desc><g id='page221'><use x='0' xlink:href='#g0-102' y='33.004'/><use x='3.044' xlink:href='#g0-97' y='33.004'/><use x='8.117' xlink:href='#g0-108' y='33.004'/><use x='10.653' xlink:href='#g0-115' y='33.004'/><use x='14.712' xlink:href='#g0-101' y='33.004'/></g></svg> more often than any other) and a greatest solution (that +is, a function that returns <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7083em;width:1.9529em" viewBox='-0.2 26.567 18.599 6.746' ><desc>$\true$</desc><g id='page203'><use x='0' xlink:href='#g0-116' y='33.004'/><use x='3.297' xlink:href='#g0-114' y='33.004'/><use x='7.483' xlink:href='#g0-117' y='33.004'/><use x='12.809' xlink:href='#g0-101' y='33.004'/></g></svg> more often than any other). +</p> +<p class="p indent">When discussing extreme solutions, I will now restrict my attention to boolean functions +(that is, with <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.8805em" viewBox='-18.2 25.999 8.386 7.204' ><desc>$Y$</desc><g id='page210'><use x='-18' xlink:href='#g3-89' y='33.004'/></g></svg> being the type of booleans). Functor <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> is monotonic +if the calls to <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2936em;height:1.0924em;width:2.6229em" viewBox='-0.2 25.29 24.98 10.404' ><desc>$\F'(f)$</desc><g id='page209'><use x='0' xlink:href='#g1-70' y='33.004'/><use x='8.123' xlink:href='#g2-48' y='29.388'/><use x='10.918' xlink:href='#g5-40' y='33.004'/><use x='14.778' xlink:href='#g3-102' y='33.004'/><use x='20.71' xlink:href='#g5-41' y='33.004'/></g></svg> are in <em class="em-low1">positive positions</em> (that is, under an even number +of negations). Indeed, from now on, I will restrict my attention to such monotonic +functors <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>. +</p> +<p class="p indent para-continue">Let me introduce a running example. Consider the following equation, +where <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6387em" viewBox='-0.2 28.4 6.083 4.913' ><desc>$x$</desc><g id='page151'><use x='0' xlink:href='#g3-120' y='33.004'/></g></svg> ranges over the integers: +</p> +<div id="eq-evennat" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(7)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.0881em;width:13.8122em" viewBox='176.57 27.324 131.545 10.363' ><desc>\[ g(x) \Equal (x = 0 \Or g(x-2)) +\]</desc><g id='page83'><use x='176.77' xlink:href='#g3-103' y='34.996'/><use x='181.861' xlink:href='#g5-40' y='34.996'/><use x='185.721' xlink:href='#g3-120' y='34.996'/><use x='191.394' xlink:href='#g5-41' y='34.996'/><use x='206.323' xlink:href='#g5-61' y='34.996'/><use x='225.112' xlink:href='#g5-40' y='34.996'/><use x='228.972' xlink:href='#g3-120' y='34.996'/><use x='237.412' xlink:href='#g5-61' y='34.996'/><use x='247.899' xlink:href='#g5-48' y='34.996'/><use x='257.843' xlink:href='#g1-95' y='34.996'/><use x='269.441' xlink:href='#g3-103' y='34.996'/><use x='274.533' xlink:href='#g5-40' y='34.996'/><use x='278.393' xlink:href='#g3-120' y='34.996'/><use x='286.279' xlink:href='#g1-0' y='34.996'/><use x='296.213' xlink:href='#g5-50' y='34.996'/><use x='301.176' xlink:href='#g5-41' y='34.996'/><use x='305.035' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued para-continue">This equation has four solutions in <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg>. With <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.8173em" viewBox='-0.2 28.4 7.784 4.913' ><desc>$w$</desc><g id='page85'><use x='0' xlink:href='#g3-119' y='33.004'/></g></svg> ranging over the integers, they are: +</p> +<div class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(8)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:4.8539em;width:22.0048em" viewBox='119.698 24.734 209.57 46.228' ><desc>\[ \begin{array}{r@{}l} + g(x) \Equiv{}& x \in \{w \;|\; 0 \leq w \And w\textrm{ even}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; w\textrm{ even}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; (0 \leq w \And w\textrm{ even}) \Or w\textrm{ odd}\} \\ + g(x) \Equiv{}& x \in \{w \;|\; \true\} + \end{array} +\]</desc><g id='page86'><use x='119.898' xlink:href='#g3-103' y='32.406'/><use x='124.989' xlink:href='#g5-40' y='32.406'/><use x='128.849' xlink:href='#g3-120' y='32.406'/><use x='134.522' xlink:href='#g5-41' y='32.406'/><use x='146.684' xlink:href='#g1-17' y='32.406'/><use x='162.802' xlink:href='#g3-120' y='32.406'/><use x='171.242' xlink:href='#g1-50' y='32.406'/><use x='180.627' xlink:href='#g1-102' y='32.406'/><use x='185.589' xlink:href='#g3-119' y='32.406'/><use x='195.73' xlink:href='#g1-106' y='32.406'/><use x='201.255' xlink:href='#g5-48' y='32.406'/><use x='208.985' xlink:href='#g1-20' y='32.406'/><use x='219.472' xlink:href='#g3-119' y='32.406'/><use x='231.827' xlink:href='#g1-94' y='32.406'/><use x='243.425' xlink:href='#g3-119' y='32.406'/><use x='254.12' xlink:href='#g5-101' y='32.406'/><use x='258.531' xlink:href='#g5-118' y='32.406'/><use x='263.493' xlink:href='#g5-101' y='32.406'/><use x='267.904' xlink:href='#g5-110' y='32.406'/><use x='273.492' xlink:href='#g1-103' y='32.406'/><use x='119.898' xlink:href='#g3-103' y='44.361'/><use x='124.989' xlink:href='#g5-40' y='44.361'/><use x='128.849' xlink:href='#g3-120' y='44.361'/><use x='134.522' xlink:href='#g5-41' y='44.361'/><use x='146.684' xlink:href='#g1-17' y='44.361'/><use x='162.802' xlink:href='#g3-120' y='44.361'/><use x='171.242' xlink:href='#g1-50' y='44.361'/><use x='180.627' xlink:href='#g1-102' y='44.361'/><use x='185.589' xlink:href='#g3-119' y='44.361'/><use x='195.73' xlink:href='#g1-106' y='44.361'/><use x='201.255' xlink:href='#g3-119' y='44.361'/><use x='211.95' xlink:href='#g5-101' y='44.361'/><use x='216.361' xlink:href='#g5-118' y='44.361'/><use x='221.323' xlink:href='#g5-101' y='44.361'/><use x='225.734' xlink:href='#g5-110' y='44.361'/><use x='231.321' xlink:href='#g1-103' y='44.361'/><use x='119.898' xlink:href='#g3-103' y='56.316'/><use x='124.989' xlink:href='#g5-40' y='56.316'/><use x='128.849' xlink:href='#g3-120' y='56.316'/><use x='134.522' xlink:href='#g5-41' y='56.316'/><use x='146.684' xlink:href='#g1-17' y='56.316'/><use x='162.802' xlink:href='#g3-120' y='56.316'/><use x='171.242' xlink:href='#g1-50' y='56.316'/><use x='180.627' xlink:href='#g1-102' y='56.316'/><use x='185.589' xlink:href='#g3-119' y='56.316'/><use x='195.73' xlink:href='#g1-106' y='56.316'/><use x='201.255' xlink:href='#g5-40' y='56.316'/><use x='205.115' xlink:href='#g5-48' y='56.316'/><use x='212.845' xlink:href='#g1-20' y='56.316'/><use x='223.332' xlink:href='#g3-119' y='56.316'/><use x='235.687' xlink:href='#g1-94' y='56.316'/><use x='247.285' xlink:href='#g3-119' y='56.316'/><use x='257.98' xlink:href='#g5-101' y='56.316'/><use x='262.391' xlink:href='#g5-118' y='56.316'/><use x='267.353' xlink:href='#g5-101' y='56.316'/><use x='271.764' xlink:href='#g5-110' y='56.316'/><use x='277.352' xlink:href='#g5-41' y='56.316'/><use x='286.193' xlink:href='#g1-95' y='56.316'/><use x='297.791' xlink:href='#g3-119' y='56.316'/><use x='308.486' xlink:href='#g5-111' y='56.316'/><use x='313.725' xlink:href='#g5-100' y='56.316'/><use x='319.239' xlink:href='#g5-100' y='56.316'/><use x='324.813' xlink:href='#g1-103' y='56.316'/><use x='119.898' xlink:href='#g3-103' y='68.271'/><use x='124.989' xlink:href='#g5-40' y='68.271'/><use x='128.849' xlink:href='#g3-120' y='68.271'/><use x='134.522' xlink:href='#g5-41' y='68.271'/><use x='146.684' xlink:href='#g1-17' y='68.271'/><use x='162.802' xlink:href='#g3-120' y='68.271'/><use x='171.242' xlink:href='#g1-50' y='68.271'/><use x='180.627' xlink:href='#g1-102' y='68.271'/><use x='185.589' xlink:href='#g3-119' y='68.271'/><use x='195.73' xlink:href='#g1-106' y='68.271'/><use x='201.255' xlink:href='#g0-116' y='68.271'/><use x='204.552' xlink:href='#g0-114' y='68.271'/><use x='208.737' xlink:href='#g0-117' y='68.271'/><use x='214.064' xlink:href='#g0-101' y='68.271'/><use x='219.443' xlink:href='#g1-103' y='68.271'/></g></svg></div></div> +<p class="p noindent para-continued">The first of these is the least solution and the last is the greatest solution. +</p> +<p class="p indent para-continue">In the literature, the definition of an extreme predicate is often given as a set of +<em class="em-low1">inference rules</em>. To designate the least solution, a single line separating the +antecedent (on top) from conclusion (on bottom) is used: +</p> +<div id="g-ind-rule" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(9)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:2.5133em;width:10.1001em" viewBox='194.905 23.837 96.191 23.936' ><desc>\[ \frac{}{g(0)} + \qquad\qquad + \frac{g(x-2)}{g(x)} +\]</desc><g id='page87'><rect height='0.398' width='17.839' x='195.105' y='35.559'/><use x='195.105' xlink:href='#g3-103' y='45.083'/><use x='200.196' xlink:href='#g5-40' y='45.083'/><use x='204.056' xlink:href='#g5-48' y='45.083'/><use x='209.019' xlink:href='#g5-41' y='45.083'/><use x='255.186' xlink:href='#g3-103' y='31.509'/><use x='260.277' xlink:href='#g5-40' y='31.509'/><use x='264.137' xlink:href='#g3-120' y='31.509'/><use x='272.024' xlink:href='#g1-0' y='31.509'/><use x='281.957' xlink:href='#g5-50' y='31.509'/><use x='286.92' xlink:href='#g5-41' y='31.509'/><rect height='0.398' width='35.71' x='255.186' y='35.559'/><use x='263.765' xlink:href='#g3-103' y='45.083'/><use x='268.856' xlink:href='#g5-40' y='45.083'/><use x='272.716' xlink:href='#g3-120' y='45.083'/><use x='278.389' xlink:href='#g5-41' y='45.083'/></g></svg></div></div> +<p class="p noindent para-continued">Through repeated applications of such rules, one can show that the predicate holds for +a particular value. For example, the <em class="em-low1">derivation</em>, or <em class="em-low1">proof tree</em>, +to the left in Figure <a href="#fig-proof-trees" title="Left: a finite proof tree that uses the rules of (9) to establish $g(6)$. Right: an infinite proof tree that uses the rules of (10) to establish $g(1)$." class="localref" style="target-element:figure"><span class="figure-label">0</span></a> shows that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-18.2 25.332 18.184 10.363' ><desc>$g(6)$</desc><g id='page154'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g5-40' y='33.004'/><use x='-9.049' xlink:href='#g5-54' y='33.004'/><use x='-4.086' xlink:href='#g5-41' y='33.004'/></g></svg> holds. +(In this simple example, the derivation is a rather degenerate proof “tree”.) +The use of these inference rules gives rise to a least solution, because proof trees are +accepted only if they are <em class="em-low1">finite</em>. +</p> +<figure id="fig-proof-trees" class="figure floating align-center float" style="text-align:center;float-env:figure;float-name:Figure"><table class="columns block"> +<tbody><tr><td class="column" style="vertical-align:bottom"> +<div class="math para-block"> +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:6.1406em;width:2.6683em" viewBox='230.294 25.07 25.412 58.482' ><desc>\[\dfrac{ + \dfrac{ + \dfrac{ + \dfrac{}{g(0)\xstrut} + }{g(2)\xstrut} + }{g(4)\xstrut} + }{g(6)\xupstrut} +\]</desc><g id='page91'><rect height='0.398' width='17.839' x='234.08' y='25.27'/><use x='234.08' xlink:href='#g3-103' y='35.432'/><use x='239.172' xlink:href='#g5-40' y='35.432'/><use x='243.032' xlink:href='#g5-48' y='35.432'/><use x='247.994' xlink:href='#g5-41' y='35.432'/><rect height='0.398' width='20.23' x='232.885' y='40.413'/><use x='234.08' xlink:href='#g3-103' y='50.575'/><use x='239.172' xlink:href='#g5-40' y='50.575'/><use x='243.032' xlink:href='#g5-50' y='50.575'/><use x='247.994' xlink:href='#g5-41' y='50.575'/><rect height='0.398' width='22.621' x='231.689' y='55.556'/><use x='234.08' xlink:href='#g3-103' y='65.718'/><use x='239.172' xlink:href='#g5-40' y='65.718'/><use x='243.032' xlink:href='#g5-52' y='65.718'/><use x='247.994' xlink:href='#g5-41' y='65.718'/><rect height='0.398' width='25.012' x='230.494' y='70.7'/><use x='234.08' xlink:href='#g3-103' y='80.861'/><use x='239.172' xlink:href='#g5-40' y='80.861'/><use x='243.032' xlink:href='#g5-54' y='80.861'/><use x='247.994' xlink:href='#g5-41' y='80.861'/></g></svg></div></div></td><td class="column" style="width:5em"></td><td class="column" style="vertical-align:bottom"> +<div class="math para-block"> +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:7.2767em;width:3.4819em" viewBox='208.419 -23.645 33.161 69.302' ><desc>\[\Dfrac{ + \Dfrac{ + \Dfrac{ + \Dfrac{ + {}_{\vdots } + }{{g(-5)}} + }{{g(-3)}} + }{{g(-1)}} + }{g(1)} +\]</desc><g id='page92'><use x='223.367' xlink:href='#g5-46' y='-22.389'/><use x='223.367' xlink:href='#g5-46' y='-18.404'/><use x='223.367' xlink:href='#g5-46' y='-14.419'/><rect height='1.395' width='25.588' x='212.206' y='-13.024'/><use x='212.206' xlink:href='#g3-103' y='-1.866'/><use x='217.298' xlink:href='#g5-40' y='-1.866'/><use x='221.157' xlink:href='#g1-0' y='-1.866'/><use x='228.877' xlink:href='#g5-53' y='-1.866'/><use x='233.84' xlink:href='#g5-41' y='-1.866'/><rect fill='#ffffff' height='0.598' width='25.588' x='212.206' y='-12.625'/><rect height='1.395' width='27.979' x='211.01' y='1.92'/><use x='212.206' xlink:href='#g3-103' y='13.078'/><use x='217.298' xlink:href='#g5-40' y='13.078'/><use x='221.157' xlink:href='#g1-0' y='13.078'/><use x='228.877' xlink:href='#g5-51' y='13.078'/><use x='233.84' xlink:href='#g5-41' y='13.078'/><rect fill='#ffffff' height='0.598' width='27.979' x='211.01' y='2.319'/><rect height='1.395' width='30.37' x='209.815' y='16.864'/><use x='212.206' xlink:href='#g3-103' y='28.022'/><use x='217.298' xlink:href='#g5-40' y='28.022'/><use x='221.157' xlink:href='#g1-0' y='28.022'/><use x='228.877' xlink:href='#g5-49' y='28.022'/><use x='233.84' xlink:href='#g5-41' y='28.022'/><rect fill='#ffffff' height='0.598' width='30.37' x='209.815' y='17.263'/><rect height='1.395' width='32.761' x='208.619' y='31.808'/><use x='216.08' xlink:href='#g3-103' y='42.966'/><use x='221.172' xlink:href='#g5-40' y='42.966'/><use x='225.032' xlink:href='#g5-49' y='42.966'/><use x='229.995' xlink:href='#g5-41' y='42.966'/><rect fill='#ffffff' height='0.598' width='32.761' x='208.619' y='32.207'/></g></svg></div></div></td></tr></tbody></table> +<hr class="figureline madoko" style="display:block"> + +<div class="p noindent"><fig-caption class="figure-caption"><span class="caption-before"><strong class="strong-star2">Figure <span class="figure-label">0</span>.</strong> </span><span class="caption-text">Left: a finite proof tree that uses the rules of <a href="#g-ind-rule" class="localref" style="target-element:equation"><span class="equation-label">(9)</span></a> to establish <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-18.2 25.332 18.184 10.363' ><desc>$g(6)$</desc><g id='page154'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g5-40' y='33.004'/><use x='-9.049' xlink:href='#g5-54' y='33.004'/><use x='-4.086' xlink:href='#g5-41' y='33.004'/></g></svg>. Right: an infinite proof tree that uses the rules of <a href="#g-coind-rule" class="localref" style="target-element:equation"><span class="equation-label">(10)</span></a> to establish <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-0.2 25.332 18.184 10.363' ><desc>$g(1)$</desc><g id='page155'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g5-40' y='33.004'/><use x='8.951' xlink:href='#g5-49' y='33.004'/><use x='13.914' xlink:href='#g5-41' y='33.004'/></g></svg>.</span></fig-caption></div></figure> +<p class="p indent para-continue">When inference rules are to designate the greatest solution, a double +line is used: +</p> +<div id="g-coind-rule" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(10)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:2.7827em;width:10.1001em" viewBox='194.905 19.155 96.191 26.502' ><desc>\[ \Dfrac{}{g(0)} + \qquad\qquad + \Dfrac{g(x-2)}{g(x)} +\]</desc><g id='page95'><rect height='1.395' width='17.839' x='195.105' y='31.808'/><use x='195.105' xlink:href='#g3-103' y='42.966'/><use x='200.196' xlink:href='#g5-40' y='42.966'/><use x='204.056' xlink:href='#g5-48' y='42.966'/><use x='209.019' xlink:href='#g5-41' y='42.966'/><rect fill='#ffffff' height='0.598' width='17.839' x='195.105' y='32.207'/><use x='255.186' xlink:href='#g3-103' y='26.827'/><use x='260.277' xlink:href='#g5-40' y='26.827'/><use x='264.137' xlink:href='#g3-120' y='26.827'/><use x='272.024' xlink:href='#g1-0' y='26.827'/><use x='281.957' xlink:href='#g5-50' y='26.827'/><use x='286.92' xlink:href='#g5-41' y='26.827'/><rect height='1.395' width='35.71' x='255.186' y='31.808'/><use x='263.765' xlink:href='#g3-103' y='42.966'/><use x='268.856' xlink:href='#g5-40' y='42.966'/><use x='272.716' xlink:href='#g3-120' y='42.966'/><use x='278.389' xlink:href='#g5-41' y='42.966'/><rect fill='#ffffff' height='0.598' width='35.71' x='255.186' y='32.207'/></g></svg></div></div> +<p class="p noindent para-continued">In this case, proof trees are allowed to be infinite. For example, the (partial depiction +of the) infinite proof tree on the right in Figure <a href="#fig-proof-trees" title="Left: a finite proof tree that uses the rules of (9) to establish $g(6)$. Right: an infinite proof tree that uses the rules of (10) to establish $g(1)$." class="localref" style="target-element:figure"><span class="figure-label">0</span></a> shows that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-0.2 25.332 18.184 10.363' ><desc>$g(1)$</desc><g id='page155'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g5-40' y='33.004'/><use x='8.951' xlink:href='#g5-49' y='33.004'/><use x='13.914' xlink:href='#g5-41' y='33.004'/></g></svg> holds. +</p> +<p class="p indent">Note that derivations may not be unique. For example, in the case of the greatest +solution for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg>, there are two proof trees that establish <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-18.2 25.332 18.184 10.363' ><desc>$g(0)$</desc><g id='page100'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g5-40' y='33.004'/><use x='-9.049' xlink:href='#g5-48' y='33.004'/><use x='-4.086' xlink:href='#g5-41' y='33.004'/></g></svg>: one is the finite +proof tree that uses the left-hand rule of <a href="#g-coind-rule" class="localref" style="target-element:equation"><span class="equation-label">(10)</span></a> once, the other is the infinite +proof tree that keeps on using the right-hand rule of <a href="#g-coind-rule" class="localref" style="target-element:equation"><span class="equation-label">(10)</span></a>. +</p><h4 id="sec-working-with-extreme-predicates" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.0.2</span>. </span>Working with Extreme Predicates</h4> +<p class="p noindent">In general, one cannot evaluate whether or not an extreme predicate holds for some +input, because doing so may take an infinite number of steps. For example, following +the recursive calls in the definition <a href="#eq-evennat" class="localref" style="target-element:equation"><span class="equation-label">(7)</span></a> to try to evaluate <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-0.2 25.332 18.184 10.363' ><desc>$g(7)$</desc><g id='page101'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g5-40' y='33.004'/><use x='8.951' xlink:href='#g5-55' y='33.004'/><use x='13.914' xlink:href='#g5-41' y='33.004'/></g></svg> would never +terminate. However, there are useful ways to establish that an extreme predicate holds +and there are ways to make use of one once it has been established. +</p> +<p class="p indent para-continue">For any <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> as in <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a>, I define two infinite series of well-founded +functions, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2874em;height:1.2339em;width:1.3989em" viewBox='-0.2 23.958 13.323 11.751' ><desc>$\iter{f}_k$</desc><g id='page129'><use x='0' xlink:href='#g4-91' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2913em;height:1.2090em;width:1.3989em" viewBox='-0.2 24.195 13.323 11.514' ><desc>$\Iter{f}_k$</desc><g id='page131'><use x='0' xlink:href='#g4-93' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> +where <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg> ranges over the natural numbers: +</p> +<div id="eq-least-approx" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(11)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:2.5515em;width:17.2078em" viewBox='139.707 24.076 163.884 24.3' ><desc>\[ \iter{f}_k(x) \Equal \left\{ + \begin{array}{ll} + \false & \textrm{if } k = 0 \\ + \F(\iter{f}_{k-1})(x) & \textrm{if } k > 0 + \end{array} + \right. +\]</desc><g id='page106'><use x='139.907' xlink:href='#g4-91' y='34.608'/><use x='141.969' xlink:href='#g3-102' y='38.722'/><use x='147.918' xlink:href='#g4-107' y='41.157'/><use x='152.82' xlink:href='#g5-40' y='38.722'/><use x='156.68' xlink:href='#g3-120' y='38.722'/><use x='162.353' xlink:href='#g5-41' y='38.722'/><use x='177.282' xlink:href='#g5-61' y='38.722'/><use x='196.071' xlink:href='#g7-26' y='24.674'/><use x='208.524' xlink:href='#g0-102' y='32.406'/><use x='211.568' xlink:href='#g0-97' y='32.406'/><use x='216.641' xlink:href='#g0-108' y='32.406'/><use x='219.178' xlink:href='#g0-115' y='32.406'/><use x='223.236' xlink:href='#g0-101' y='32.406'/><use x='270.94' xlink:href='#g5-105' y='32.406'/><use x='273.697' xlink:href='#g5-102' y='32.406'/><use x='280.072' xlink:href='#g3-107' y='32.406'/><use x='288.32' xlink:href='#g5-61' y='32.406'/><use x='298.808' xlink:href='#g5-48' y='32.406'/><use x='208.524' xlink:href='#g1-70' y='44.838'/><use x='216.648' xlink:href='#g5-40' y='44.838'/><use x='220.508' xlink:href='#g4-91' y='41.223'/><use x='222.569' xlink:href='#g3-102' y='44.838'/><use x='228.519' xlink:href='#g4-107' y='47.273'/><use x='232.907' xlink:href='#g2-0' y='47.273'/><use x='239.111' xlink:href='#g6-49' y='47.273'/><use x='243.619' xlink:href='#g5-41' y='44.838'/><use x='247.479' xlink:href='#g5-40' y='44.838'/><use x='251.339' xlink:href='#g3-120' y='44.838'/><use x='257.011' xlink:href='#g5-41' y='44.838'/><use x='270.94' xlink:href='#g5-105' y='44.838'/><use x='273.697' xlink:href='#g5-102' y='44.838'/><use x='280.072' xlink:href='#g3-107' y='44.838'/><use x='288.32' xlink:href='#g3-62' y='44.838'/><use x='298.808' xlink:href='#g5-48' y='44.838'/></g></svg></div></div> +<div id="eq-greatest-approx" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(12)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:2.5515em;width:17.2078em" viewBox='157.707 23.882 163.884 24.3' ><desc>\[ \Iter{f}_k(x) \Equal \left\{ + \begin{array}{ll} + \true & \textrm{if } k = 0 \\ + \F(\Iter{f}_{k-1})(x) & \textrm{if } k > 0 + \end{array} + \right. +\]</desc><g id='page107'><use x='157.907' xlink:href='#g4-93' y='34.414'/><use x='159.969' xlink:href='#g3-102' y='38.528'/><use x='165.918' xlink:href='#g4-107' y='40.963'/><use x='170.82' xlink:href='#g5-40' y='38.528'/><use x='174.68' xlink:href='#g3-120' y='38.528'/><use x='180.353' xlink:href='#g5-41' y='38.528'/><use x='195.282' xlink:href='#g5-61' y='38.528'/><use x='214.071' xlink:href='#g7-26' y='24.48'/><use x='226.524' xlink:href='#g0-116' y='32.406'/><use x='229.822' xlink:href='#g0-114' y='32.406'/><use x='234.007' xlink:href='#g0-117' y='32.406'/><use x='239.334' xlink:href='#g0-101' y='32.406'/><use x='288.94' xlink:href='#g5-105' y='32.406'/><use x='291.697' xlink:href='#g5-102' y='32.406'/><use x='298.072' xlink:href='#g3-107' y='32.406'/><use x='306.32' xlink:href='#g5-61' y='32.406'/><use x='316.808' xlink:href='#g5-48' y='32.406'/><use x='226.524' xlink:href='#g1-70' y='44.451'/><use x='234.648' xlink:href='#g5-40' y='44.451'/><use x='238.508' xlink:href='#g4-93' y='40.835'/><use x='240.569' xlink:href='#g3-102' y='44.451'/><use x='246.519' xlink:href='#g4-107' y='46.886'/><use x='250.907' xlink:href='#g2-0' y='46.886'/><use x='257.111' xlink:href='#g6-49' y='46.886'/><use x='261.619' xlink:href='#g5-41' y='44.451'/><use x='265.479' xlink:href='#g5-40' y='44.451'/><use x='269.339' xlink:href='#g3-120' y='44.451'/><use x='275.011' xlink:href='#g5-41' y='44.451'/><use x='288.94' xlink:href='#g5-105' y='44.451'/><use x='291.697' xlink:href='#g5-102' y='44.451'/><use x='298.072' xlink:href='#g3-107' y='44.451'/><use x='306.32' xlink:href='#g3-62' y='44.451'/><use x='316.808' xlink:href='#g5-48' y='44.451'/></g></svg></div></div> +<p class="p noindent para-continued">These functions are called the <em class="em-low1">iterates</em> of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg>, and I will also refer to them +as the <em class="em-low1">prefix predicates</em> of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> (or the <em class="em-low1">prefix predicate</em> of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg>, if we think +of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg> as being a parameter). +Alternatively, we can define <svg class="math-inline math-render-svg math" style="vertical-align:-0.2874em;height:1.2339em;width:1.3989em" viewBox='-0.2 23.958 13.323 11.751' ><desc>$\iter{f}_k$</desc><g id='page129'><use x='0' xlink:href='#g4-91' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2913em;height:1.2090em;width:1.3989em" viewBox='-0.2 24.195 13.323 11.514' ><desc>$\Iter{f}_k$</desc><g id='page131'><use x='0' xlink:href='#g4-93' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> without mentioning <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6387em" viewBox='-0.2 28.4 6.083 4.913' ><desc>$x$</desc><g id='page151'><use x='0' xlink:href='#g3-120' y='33.004'/></g></svg>: +Let <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7408em;width:0.8537em" viewBox='-0.2 26.149 8.13 7.055' ><desc>$\bot$</desc><g id='page115'><use x='0' xlink:href='#g1-63' y='33.004'/></g></svg> denote the function that always returns <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:2.1795em" viewBox='-0.449 25.78 20.757 9.466' ><desc>$\false$</desc><g id='page221'><use x='0' xlink:href='#g0-102' y='33.004'/><use x='3.044' xlink:href='#g0-97' y='33.004'/><use x='8.117' xlink:href='#g0-108' y='33.004'/><use x='10.653' xlink:href='#g0-115' y='33.004'/><use x='14.712' xlink:href='#g0-101' y='33.004'/></g></svg>, let <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7408em;width:0.8537em" viewBox='-0.2 26.149 8.13 7.055' ><desc>$\top$</desc><g id='page117'><use x='0' xlink:href='#g1-62' y='33.004'/></g></svg> +denote the function that always returns <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7083em;width:1.9529em" viewBox='-0.2 26.567 18.599 6.746' ><desc>$\true$</desc><g id='page203'><use x='0' xlink:href='#g0-116' y='33.004'/><use x='3.297' xlink:href='#g0-114' y='33.004'/><use x='7.483' xlink:href='#g0-117' y='33.004'/><use x='12.809' xlink:href='#g0-101' y='33.004'/></g></svg>, and let a superscript on <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> denote +exponentiation (for example, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2958em;height:1.1694em;width:4.8132em" viewBox='-18.2 24.558 45.84 11.137' ><desc>$\F^0(f) = f$</desc><g id='page120'><use x='-18' xlink:href='#g1-70' y='33.004'/><use x='-9.877' xlink:href='#g6-48' y='29.388'/><use x='-5.407' xlink:href='#g5-40' y='33.004'/><use x='-1.547' xlink:href='#g3-102' y='33.004'/><use x='4.384' xlink:href='#g5-41' y='33.004'/><use x='11.011' xlink:href='#g5-61' y='33.004'/><use x='21.499' xlink:href='#g3-102' y='33.004'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2958em;height:1.1694em;width:8.1402em" viewBox='-0.2 24.558 77.526 11.137' ><desc>$\F^2(f) = \F(\F(f))$</desc><g id='page121'><use x='0' xlink:href='#g1-70' y='33.004'/><use x='8.123' xlink:href='#g6-50' y='29.388'/><use x='12.593' xlink:href='#g5-40' y='33.004'/><use x='16.452' xlink:href='#g3-102' y='33.004'/><use x='22.384' xlink:href='#g5-41' y='33.004'/><use x='29.011' xlink:href='#g5-61' y='33.004'/><use x='39.499' xlink:href='#g1-70' y='33.004'/><use x='47.622' xlink:href='#g5-40' y='33.004'/><use x='51.482' xlink:href='#g1-70' y='33.004'/><use x='59.605' xlink:href='#g5-40' y='33.004'/><use x='63.465' xlink:href='#g3-102' y='33.004'/><use x='69.397' xlink:href='#g5-41' y='33.004'/><use x='73.256' xlink:href='#g5-41' y='33.004'/></g></svg>). +Then, <a href="#eq-least-approx" class="localref" style="target-element:equation"><span class="equation-label">(11)</span></a> and <a href="#eq-greatest-approx" class="localref" style="target-element:equation"><span class="equation-label">(12)</span></a> can be stated equivalently as +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2921em;height:1.2339em;width:5.7795em" viewBox='-18.2 23.958 55.043 11.751' ><desc>$\iter{f}_k = \F^k(\bot)$</desc><g id='page122'><use x='-18' xlink:href='#g4-91' y='29.388'/><use x='-15.938' xlink:href='#g3-102' y='33.004'/><use x='-9.988' xlink:href='#g4-107' y='35.439'/><use x='-2.319' xlink:href='#g5-61' y='33.004'/><use x='8.168' xlink:href='#g1-70' y='33.004'/><use x='16.291' xlink:href='#g4-107' y='29.388'/><use x='21.193' xlink:href='#g5-40' y='33.004'/><use x='25.053' xlink:href='#g1-63' y='33.004'/><use x='32.773' xlink:href='#g5-41' y='33.004'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2960em;height:1.2090em;width:5.7795em" viewBox='-0.2 24.195 55.043 11.514' ><desc>$\Iter{f}_k = \F^k(\top)$</desc><g id='page123'><use x='0' xlink:href='#g4-93' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/><use x='15.681' xlink:href='#g5-61' y='33.004'/><use x='26.168' xlink:href='#g1-70' y='33.004'/><use x='34.291' xlink:href='#g4-107' y='29.388'/><use x='39.193' xlink:href='#g5-40' y='33.004'/><use x='43.053' xlink:href='#g1-62' y='33.004'/><use x='50.773' xlink:href='#g5-41' y='33.004'/></g></svg>. +</p> +<p class="p indent para-continue">For any solution <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> to equation <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a>, we have, for any <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7920em;width:0.4773em" viewBox='-18.2 25.78 4.546 7.543' ><desc>$\ell$</desc><g id='page126'><use x='-18' xlink:href='#g3-96' y='33.004'/></g></svg> +such that <svg class="math-inline math-render-svg math" style="vertical-align:-0.1721em;height:0.9228em;width:2.4445em" viewBox='-0.2 25.78 23.281 8.789' ><desc>$k \leq \ell$</desc><g id='page127'><use x='0' xlink:href='#g3-107' y='33.004'/><use x='8.248' xlink:href='#g1-20' y='33.004'/><use x='18.735' xlink:href='#g3-96' y='33.004'/></g></svg>: +</p> +<div id="eq-prefix-postfix" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(13)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.2876em;width:22.9665em" viewBox='115.152 25.452 218.729 12.263' ><desc>\[ \iter{f}_k \quad\FBelow\quad + \iter{f}_\ell \quad\FBelow\quad + f \quad\FBelow\quad + \Iter{f}_\ell \quad\FBelow\quad + \Iter{f}_k +\]</desc><g id='page128'><use x='115.352' xlink:href='#g4-91' y='30.883'/><use x='117.414' xlink:href='#g3-102' y='34.996'/><use x='123.364' xlink:href='#g4-107' y='37.431'/><use x='147.361' xlink:href='#g5-95' y='34.996'/><use x='143.763' xlink:href='#g1-41' y='34.996'/><use x='169.223' xlink:href='#g4-91' y='30.883'/><use x='171.285' xlink:href='#g3-102' y='34.996'/><use x='177.235' xlink:href='#g4-96' y='37.431'/><use x='200.163' xlink:href='#g5-95' y='34.996'/><use x='196.565' xlink:href='#g1-41' y='34.996'/><use x='222.025' xlink:href='#g3-102' y='34.996'/><use x='247.052' xlink:href='#g5-95' y='34.996'/><use x='243.454' xlink:href='#g1-41' y='34.996'/><use x='268.914' xlink:href='#g4-93' y='30.883'/><use x='270.976' xlink:href='#g3-102' y='34.996'/><use x='276.926' xlink:href='#g4-96' y='37.431'/><use x='299.854' xlink:href='#g5-95' y='34.996'/><use x='296.256' xlink:href='#g1-41' y='34.996'/><use x='321.716' xlink:href='#g4-93' y='30.883'/><use x='323.778' xlink:href='#g3-102' y='34.996'/><use x='329.728' xlink:href='#g4-107' y='37.431'/></g></svg></div></div> +<p class="p noindent para-continued para-continue">In other words, every <svg class="math-inline math-render-svg math" style="vertical-align:-0.2874em;height:1.2339em;width:1.3989em" viewBox='-0.2 23.958 13.323 11.751' ><desc>$\iter{f}_k$</desc><g id='page129'><use x='0' xlink:href='#g4-91' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> is a <em class="em-low1">pre-fixpoint</em> of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> and every <svg class="math-inline math-render-svg math" style="vertical-align:-0.2913em;height:1.2090em;width:1.3989em" viewBox='-0.2 24.195 13.323 11.514' ><desc>$\Iter{f}_k$</desc><g id='page131'><use x='0' xlink:href='#g4-93' y='29.388'/><use x='2.062' xlink:href='#g3-102' y='33.004'/><use x='8.012' xlink:href='#g4-107' y='35.439'/></g></svg> is a <em class="em-low1">post-fixpoint</em> +of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg>. Next, I define two functions, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-18.2 24.348 10.922 10.898' ><desc>$f\least$</desc><g id='page142'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.068' xlink:href='#g2-35' y='29.388'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-0.2 24.348 10.922 10.898' ><desc>$f\greatest$</desc><g id='page143'><use x='0' xlink:href='#g3-102' y='33.004'/><use x='5.932' xlink:href='#g2-34' y='29.388'/></g></svg>, in +terms of the prefix predicates: +</p> +<div id="eq-least-is-exists" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(14)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.2861em;width:10.7773em" viewBox='191.086 25.452 102.641 12.249' ><desc>\[ f\least(x) \Equal \exists k \bullet\; \iter{f}_k(x) +\]</desc><g id='page135'><use x='191.286' xlink:href='#g3-102' y='34.996'/><use x='197.218' xlink:href='#g2-35' y='30.883'/><use x='201.798' xlink:href='#g5-40' y='34.996'/><use x='205.658' xlink:href='#g3-120' y='34.996'/><use x='211.331' xlink:href='#g5-41' y='34.996'/><use x='226.26' xlink:href='#g5-61' y='34.996'/><use x='245.049' xlink:href='#g1-57' y='34.996'/><use x='250.563' xlink:href='#g3-107' y='34.996'/><use x='258.258' xlink:href='#g1-15' y='34.996'/><use x='268.202' xlink:href='#g4-91' y='30.883'/><use x='270.263' xlink:href='#g3-102' y='34.996'/><use x='276.213' xlink:href='#g4-107' y='37.431'/><use x='281.115' xlink:href='#g5-40' y='34.996'/><use x='284.975' xlink:href='#g3-120' y='34.996'/><use x='290.648' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<div id="eq-greatest-is-forall" class="equation para-block" style="line-adjust:0"><span class="equation-before"><span class="equation-label">(15)</span></span> + +<div class="mathdisplay para-block input-math" data-math-needpdf="" style="line-adjust:0"><svg class="mathdisplay math-display math-render-svg math" data-math-needpdf="" style="vertical-align:-0.0210em;height:1.2613em;width:10.7773em" viewBox='173.086 25.689 102.641 12.012' ><desc>\[ f\greatest(x) \Equal \forall k \bullet\; \Iter{f}_k(x) +\]</desc><g id='page136'><use x='173.286' xlink:href='#g3-102' y='34.996'/><use x='179.218' xlink:href='#g2-34' y='30.883'/><use x='183.798' xlink:href='#g5-40' y='34.996'/><use x='187.658' xlink:href='#g3-120' y='34.996'/><use x='193.331' xlink:href='#g5-41' y='34.996'/><use x='208.26' xlink:href='#g5-61' y='34.996'/><use x='227.049' xlink:href='#g1-56' y='34.996'/><use x='232.563' xlink:href='#g3-107' y='34.996'/><use x='240.258' xlink:href='#g1-15' y='34.996'/><use x='250.202' xlink:href='#g4-93' y='30.883'/><use x='252.263' xlink:href='#g3-102' y='34.996'/><use x='258.213' xlink:href='#g4-107' y='37.431'/><use x='263.115' xlink:href='#g5-40' y='34.996'/><use x='266.975' xlink:href='#g3-120' y='34.996'/><use x='272.648' xlink:href='#g5-41' y='34.996'/></g></svg></div></div> +<p class="p noindent para-continued">By <a href="#eq-prefix-postfix" class="localref" style="target-element:equation"><span class="equation-label">(13)</span></a>, we also have that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-18.2 24.348 10.922 10.898' ><desc>$f\least$</desc><g id='page142'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.068' xlink:href='#g2-35' y='29.388'/></g></svg> is a pre-fixpoint of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-0.2 24.348 10.922 10.898' ><desc>$f\greatest$</desc><g id='page143'><use x='0' xlink:href='#g3-102' y='33.004'/><use x='5.932' xlink:href='#g2-34' y='29.388'/></g></svg> +is a post-fixpoint of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>. The marvelous thing is that, if <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg> is <em class="em-low1">continuous</em>, then +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-18.2 24.348 10.922 10.898' ><desc>$f\least$</desc><g id='page142'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.068' xlink:href='#g2-35' y='29.388'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.1468em" viewBox='-0.2 24.348 10.922 10.898' ><desc>$f\greatest$</desc><g id='page143'><use x='0' xlink:href='#g3-102' y='33.004'/><use x='5.932' xlink:href='#g2-34' y='29.388'/></g></svg> are the least and greatest fixpoints of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7983em;width:0.9102em" viewBox='-18.2 25.919 8.669 7.603' ><desc>$\F$</desc><g id='page144'><use x='-18' xlink:href='#g1-70' y='33.004'/></g></svg>. +These equations let us do proofs by induction when dealing with extreme predicates. +I will explain in Section <a href="#sec-friendliness" title="11.1.2. Extreme Predicates in Dafny" class="localref" style="target-element:h3"><span class="heading-label">11.1.2</span></a> how to check for continuity. +</p> +<p class="p indent">Let's consider two examples, both involving function <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg> in +<a href="#eq-evennat" class="localref" style="target-element:equation"><span class="equation-label">(7)</span></a>. As it turns out, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg>'s defining functor is continuous, +and therefore I will write <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.0586em" viewBox='-0.2 24.348 10.082 10.898' ><desc>$g\least$</desc><g id='page161'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.0586em" viewBox='-18.2 24.348 10.082 10.898' ><desc>$g\greatest$</desc><g id='page186'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-34' y='29.388'/></g></svg> to denote the +least and greatest solutions for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg> in <a href="#eq-evennat" class="localref" style="target-element:equation"><span class="equation-label">(7)</span></a>. +</p><h5 id="sec-example-least-solution" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">11.0.2.0</span>. </span>Example with Least Solution</h5> +<p class="p noindent">The main technique for establishing that <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\least(x)$</desc><g id='page163'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg> holds for some +<svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.5159em;width:0.6387em" viewBox='-0.2 28.4 6.083 4.913' ><desc>$x$</desc><g id='page151'><use x='0' xlink:href='#g3-120' y='33.004'/></g></svg>, that is, proving something of the form <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.1294em" viewBox='-18.2 24.348 58.375 11.346' ><desc>$Q \Imp g\least(x)$</desc><g id='page152'><use x='-18' xlink:href='#g3-81' y='33.004'/><use x='-4.619' xlink:href='#g5-61' y='33.004'/><use x='1.441' xlink:href='#g1-41' y='33.004'/><use x='16.901' xlink:href='#g3-103' y='33.004'/><use x='21.992' xlink:href='#g2-35' y='29.388'/><use x='26.572' xlink:href='#g5-40' y='33.004'/><use x='30.432' xlink:href='#g3-120' y='33.004'/><use x='36.105' xlink:href='#g5-41' y='33.004'/></g></svg>, is to +construct a proof tree like the one for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:1.9093em" viewBox='-18.2 25.332 18.184 10.363' ><desc>$g(6)$</desc><g id='page154'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g5-40' y='33.004'/><use x='-9.049' xlink:href='#g5-54' y='33.004'/><use x='-4.086' xlink:href='#g5-41' y='33.004'/></g></svg> in Figure +<a href="#fig-proof-trees" title="Left: a finite proof tree that uses the rules of (9) to establish $g(6)$. Right: an infinite proof tree that uses the rules of (10) to establish $g(1)$." class="localref" style="target-element:figure"><span class="figure-label">0</span></a>. For a proof in this direction, since we're just +applying the defining equation, the fact that +we're using a least solution for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg> never plays a role (as long as we +limit ourselves to finite derivations). +</p> +<p class="p indent">The technique for going in the other direction, proving something <em class="em-low1">from</em> an established +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.0586em" viewBox='-0.2 24.348 10.082 10.898' ><desc>$g\least$</desc><g id='page161'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/></g></svg> property, that is, showing something of the form <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.1048em" viewBox='-18.2 24.348 58.141 11.346' ><desc>$g\least(x) \Imp R$</desc><g id='page158'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-35' y='29.388'/><use x='-8.328' xlink:href='#g5-40' y='33.004'/><use x='-4.468' xlink:href='#g3-120' y='33.004'/><use x='1.204' xlink:href='#g5-41' y='33.004'/><use x='10.599' xlink:href='#g5-61' y='33.004'/><use x='16.658' xlink:href='#g1-41' y='33.004'/><use x='32.118' xlink:href='#g3-82' y='33.004'/></g></svg>, typically +uses induction on the structure of the proof tree. When the antecedent of our proof +obligation includes a predicate term <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\least(x)$</desc><g id='page163'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg>, it is sound to +imagine that we have been given a proof tree for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\least(x)$</desc><g id='page163'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg>. Such a proof tree +would be a data structure—to be more precise, a term in an +<em class="em-low1">inductive datatype</em>. +For this reason, least solutions like <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.0586em" viewBox='-0.2 24.348 10.082 10.898' ><desc>$g\least$</desc><g id='page161'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/></g></svg> have been given the +name <em class="em-low1">inductive predicate</em>. +</p> +<p class="p indent">Let's prove <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:12.5331em" viewBox='-18.2 24.348 119.363 11.346' ><desc>$g\least(x) \Imp 0 \leq x \And x \textrm{ even}$</desc><g id='page162'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-35' y='29.388'/><use x='-8.328' xlink:href='#g5-40' y='33.004'/><use x='-4.468' xlink:href='#g3-120' y='33.004'/><use x='1.204' xlink:href='#g5-41' y='33.004'/><use x='10.599' xlink:href='#g5-61' y='33.004'/><use x='16.658' xlink:href='#g1-41' y='33.004'/><use x='32.118' xlink:href='#g5-48' y='33.004'/><use x='39.848' xlink:href='#g1-20' y='33.004'/><use x='50.335' xlink:href='#g3-120' y='33.004'/><use x='60.989' xlink:href='#g1-94' y='33.004'/><use x='72.587' xlink:href='#g3-120' y='33.004'/><use x='81.581' xlink:href='#g5-101' y='33.004'/><use x='85.992' xlink:href='#g5-118' y='33.004'/><use x='90.954' xlink:href='#g5-101' y='33.004'/><use x='95.365' xlink:href='#g5-110' y='33.004'/></g></svg>. +We split our task into two cases, corresponding to which of the two +proof rules in <a href="#g-ind-rule" class="localref" style="target-element:equation"><span class="equation-label">(9)</span></a> was the +last one applied to establish <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\least(x)$</desc><g id='page163'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-35' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg>. If it was the left-hand rule, then <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7617em;width:2.5515em" viewBox='-0.2 26.168 24.3 7.254' ><desc>$x=0$</desc><g id='page181'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='8.44' xlink:href='#g5-61' y='33.004'/><use x='18.927' xlink:href='#g5-48' y='33.004'/></g></svg>, +which makes it easy to establish the conclusion of our proof goal. If it was the +right-hand rule, then we unfold the proof tree one level and obtain <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:4.2613em" viewBox='-18.2 24.348 40.584 11.346' ><desc>$g\least(x-2)$</desc><g id='page166'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-35' y='29.388'/><use x='-8.328' xlink:href='#g5-40' y='33.004'/><use x='-4.468' xlink:href='#g3-120' y='33.004'/><use x='3.418' xlink:href='#g1-0' y='33.004'/><use x='13.352' xlink:href='#g5-50' y='33.004'/><use x='18.314' xlink:href='#g5-41' y='33.004'/></g></svg>. +Since the proof tree for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:4.2613em" viewBox='-18.2 24.348 40.584 11.346' ><desc>$g\least(x-2)$</desc><g id='page166'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-35' y='29.388'/><use x='-8.328' xlink:href='#g5-40' y='33.004'/><use x='-4.468' xlink:href='#g3-120' y='33.004'/><use x='3.418' xlink:href='#g1-0' y='33.004'/><use x='13.352' xlink:href='#g5-50' y='33.004'/><use x='18.314' xlink:href='#g5-41' y='33.004'/></g></svg> is smaller than where we started, we invoke +the <em class="em-low1">induction hypothesis</em> and obtain <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:12.4850em" viewBox='-18.2 25.332 118.905 10.363' ><desc>$0 \leq (x-2) \And (x-2) \textrm{ even}$</desc><g id='page184'><use x='-18' xlink:href='#g5-48' y='33.004'/><use x='-10.27' xlink:href='#g1-20' y='33.004'/><use x='0.217' xlink:href='#g5-40' y='33.004'/><use x='4.077' xlink:href='#g3-120' y='33.004'/><use x='11.964' xlink:href='#g1-0' y='33.004'/><use x='21.897' xlink:href='#g5-50' y='33.004'/><use x='26.86' xlink:href='#g5-41' y='33.004'/><use x='35.701' xlink:href='#g1-94' y='33.004'/><use x='47.299' xlink:href='#g5-40' y='33.004'/><use x='51.159' xlink:href='#g3-120' y='33.004'/><use x='59.046' xlink:href='#g1-0' y='33.004'/><use x='68.979' xlink:href='#g5-50' y='33.004'/><use x='73.942' xlink:href='#g5-41' y='33.004'/><use x='81.123' xlink:href='#g5-101' y='33.004'/><use x='85.534' xlink:href='#g5-118' y='33.004'/><use x='90.496' xlink:href='#g5-101' y='33.004'/><use x='94.907' xlink:href='#g5-110' y='33.004'/></g></svg>, from which +it is easy to establish the conclusion of our proof goal. +</p> +<p class="p indent">Here's how we do the proof formally using <a href="#eq-least-is-exists" class="localref" style="target-element:equation"><span class="equation-label">(14)</span></a>. We massage the +general form of our proof goal: +</p><table class="madoko block"> +<tbody><tr><td class="tbody tr-odd tr-first col col-odd col-first" data-row="1" data-col="1"> </td><td class="tbody tr-odd tr-first col col-even col-last" data-row="1" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.1931em" viewBox='-18.2 24.348 58.982 11.346' ><desc>$f\greatest(x) \Imp R$</desc><g id='page168'><use x='-18' xlink:href='#g3-102' y='33.004'/><use x='-12.068' xlink:href='#g2-34' y='29.388'/><use x='-7.488' xlink:href='#g5-40' y='33.004'/><use x='-3.628' xlink:href='#g3-120' y='33.004'/><use x='2.044' xlink:href='#g5-41' y='33.004'/><use x='11.439' xlink:href='#g5-61' y='33.004'/><use x='17.498' xlink:href='#g1-41' y='33.004'/><use x='32.958' xlink:href='#g3-82' y='33.004'/></g></svg> </td></tr> +<tr><td class="tbody tr-even col col-odd col-first" data-row="2" data-col="1"> = </td><td class="tbody tr-even col col-even col-last" data-row="2" data-col="2">      { <a href="#eq-least-is-exists" class="localref" style="target-element:equation"><span class="equation-label">(14)</span></a> } </td></tr> +<tr><td class="tbody tr-odd col col-odd col-first" data-row="3" data-col="1"> </td><td class="tbody tr-odd col col-even col-last" data-row="3" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2921em;height:1.2339em;width:9.6869em" viewBox='-0.2 23.958 92.256 11.751' ><desc>$(\exists k \bullet\; \iter{f}_k(x)) \Imp R$</desc><g id='page169'><use x='0' xlink:href='#g5-40' y='33.004'/><use x='3.86' xlink:href='#g1-57' y='33.004'/><use x='9.374' xlink:href='#g3-107' y='33.004'/><use x='17.069' xlink:href='#g1-15' y='33.004'/><use x='27.013' xlink:href='#g4-91' y='29.388'/><use x='29.074' xlink:href='#g3-102' y='33.004'/><use x='35.024' xlink:href='#g4-107' y='35.439'/><use x='39.926' xlink:href='#g5-40' y='33.004'/><use x='43.786' xlink:href='#g3-120' y='33.004'/><use x='49.459' xlink:href='#g5-41' y='33.004'/><use x='53.319' xlink:href='#g5-41' y='33.004'/><use x='62.713' xlink:href='#g5-61' y='33.004'/><use x='68.773' xlink:href='#g1-41' y='33.004'/><use x='84.233' xlink:href='#g3-82' y='33.004'/></g></svg> </td></tr> +<tr><td class="tbody tr-even col col-odd col-first" data-row="4" data-col="1"> = </td><td class="tbody tr-even col col-even col-last" data-row="4" data-col="2">      { distribute <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.6173em;width:2.3025em" viewBox='-0.2 27.573 21.929 5.879' ><desc>$\Imp$</desc><g id='page195'><use x='2.767' xlink:href='#g5-61' y='33.004'/><use x='8.827' xlink:href='#g1-41' y='33.004'/></g></svg> over <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7680em;width:0.6220em" viewBox='-0.2 25.89 5.924 7.314' ><desc>$\exists$</desc><g id='page171'><use x='0' xlink:href='#g1-57' y='33.004'/></g></svg> to the left } </td></tr> +<tr><td class="tbody tr-odd tr-last col col-odd col-first" data-row="5" data-col="1"> </td><td class="tbody tr-odd tr-last col col-even col-last" data-row="5" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2921em;height:1.2339em;width:9.6869em" viewBox='-18.2 23.958 92.256 11.751' ><desc>$\forall k \bullet\; (\iter{f}_k(x) \Imp R)$</desc><g id='page172'><use x='-18' xlink:href='#g1-56' y='33.004'/><use x='-12.486' xlink:href='#g3-107' y='33.004'/><use x='-4.791' xlink:href='#g1-15' y='33.004'/><use x='5.153' xlink:href='#g5-40' y='33.004'/><use x='9.013' xlink:href='#g4-91' y='29.388'/><use x='11.074' xlink:href='#g3-102' y='33.004'/><use x='17.024' xlink:href='#g4-107' y='35.439'/><use x='21.926' xlink:href='#g5-40' y='33.004'/><use x='25.786' xlink:href='#g3-120' y='33.004'/><use x='31.459' xlink:href='#g5-41' y='33.004'/><use x='40.853' xlink:href='#g5-61' y='33.004'/><use x='46.913' xlink:href='#g1-41' y='33.004'/><use x='62.373' xlink:href='#g3-82' y='33.004'/><use x='69.986' xlink:href='#g5-41' y='33.004'/></g></svg> </td></tr></tbody></table> +<p class="p noindent">The last line can be proved by induction over <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg>. So, in our case, we prove +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2921em;height:1.2339em;width:12.7852em" viewBox='-18.2 23.958 121.764 11.751' ><desc>$\iter{g}_k(x) \Imp 0 \leq x \And x \textrm{ even}$</desc><g id='page174'><use x='-18' xlink:href='#g4-91' y='29.388'/><use x='-15.938' xlink:href='#g3-103' y='33.004'/><use x='-10.829' xlink:href='#g4-107' y='35.439'/><use x='-5.927' xlink:href='#g5-40' y='33.004'/><use x='-2.067' xlink:href='#g3-120' y='33.004'/><use x='3.605' xlink:href='#g5-41' y='33.004'/><use x='13' xlink:href='#g5-61' y='33.004'/><use x='19.059' xlink:href='#g1-41' y='33.004'/><use x='34.519' xlink:href='#g5-48' y='33.004'/><use x='42.25' xlink:href='#g1-20' y='33.004'/><use x='52.737' xlink:href='#g3-120' y='33.004'/><use x='63.391' xlink:href='#g1-94' y='33.004'/><use x='74.989' xlink:href='#g3-120' y='33.004'/><use x='83.982' xlink:href='#g5-101' y='33.004'/><use x='88.394' xlink:href='#g5-118' y='33.004'/><use x='93.355' xlink:href='#g5-101' y='33.004'/><use x='97.767' xlink:href='#g5-110' y='33.004'/></g></svg> for every <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg>. +If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7910em;width:2.5313em" viewBox='-0.2 25.89 24.108 7.533' ><desc>$k=0$</desc><g id='page201'><use x='0' xlink:href='#g3-107' y='33.004'/><use x='8.248' xlink:href='#g5-61' y='33.004'/><use x='18.735' xlink:href='#g5-48' y='33.004'/></g></svg>, then <svg class="math-inline math-render-svg math" style="vertical-align:-0.2921em;height:1.2339em;width:2.7169em" viewBox='-0.2 23.958 25.875 11.751' ><desc>$\iter{g}_k(x)$</desc><g id='page177'><use x='0' xlink:href='#g4-91' y='29.388'/><use x='2.062' xlink:href='#g3-103' y='33.004'/><use x='7.171' xlink:href='#g4-107' y='35.439'/><use x='12.073' xlink:href='#g5-40' y='33.004'/><use x='15.933' xlink:href='#g3-120' y='33.004'/><use x='21.605' xlink:href='#g5-41' y='33.004'/></g></svg> is <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:2.1795em" viewBox='-0.449 25.78 20.757 9.466' ><desc>$\false$</desc><g id='page221'><use x='0' xlink:href='#g0-102' y='33.004'/><use x='3.044' xlink:href='#g0-97' y='33.004'/><use x='8.117' xlink:href='#g0-108' y='33.004'/><use x='10.653' xlink:href='#g0-115' y='33.004'/><use x='14.712' xlink:href='#g0-101' y='33.004'/></g></svg>, so our goal holds trivially. +If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0642em;height:0.8099em;width:2.5313em" viewBox='-18.2 25.89 24.108 7.713' ><desc>$k > 0$</desc><g id='page204'><use x='-18' xlink:href='#g3-107' y='33.004'/><use x='-9.752' xlink:href='#g3-62' y='33.004'/><use x='0.735' xlink:href='#g5-48' y='33.004'/></g></svg>, then <svg class="math-inline math-render-svg math" style="vertical-align:-0.3537em;height:1.2339em;width:14.7097em" viewBox='-18.2 23.958 140.092 11.751' ><desc>$\iter{g}_k(x) = (x = 0 \Or \iter{g}_{k-1}(x-2))$</desc><g id='page180'><use x='-18' xlink:href='#g4-91' y='29.388'/><use x='-15.938' xlink:href='#g3-103' y='33.004'/><use x='-10.829' xlink:href='#g4-107' y='35.439'/><use x='-5.927' xlink:href='#g5-40' y='33.004'/><use x='-2.067' xlink:href='#g3-120' y='33.004'/><use x='3.605' xlink:href='#g5-41' y='33.004'/><use x='10.233' xlink:href='#g5-61' y='33.004'/><use x='20.72' xlink:href='#g5-40' y='33.004'/><use x='24.58' xlink:href='#g3-120' y='33.004'/><use x='33.02' xlink:href='#g5-61' y='33.004'/><use x='43.507' xlink:href='#g5-48' y='33.004'/><use x='53.451' xlink:href='#g1-95' y='33.004'/><use x='65.049' xlink:href='#g4-91' y='29.388'/><use x='67.111' xlink:href='#g3-103' y='33.004'/><use x='72.22' xlink:href='#g4-107' y='35.439'/><use x='76.608' xlink:href='#g2-0' y='35.439'/><use x='82.811' xlink:href='#g6-49' y='35.439'/><use x='87.32' xlink:href='#g5-40' y='33.004'/><use x='91.18' xlink:href='#g3-120' y='33.004'/><use x='99.066' xlink:href='#g1-0' y='33.004'/><use x='109' xlink:href='#g5-50' y='33.004'/><use x='113.962' xlink:href='#g5-41' y='33.004'/><use x='117.822' xlink:href='#g5-41' y='33.004'/></g></svg>. Our goal holds easily +for the first disjunct (<svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7617em;width:2.5515em" viewBox='-0.2 26.168 24.3 7.254' ><desc>$x=0$</desc><g id='page181'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='8.44' xlink:href='#g5-61' y='33.004'/><use x='18.927' xlink:href='#g5-48' y='33.004'/></g></svg>). For the other disjunct, +we apply the induction hypothesis (on the smaller <svg class="math-inline math-render-svg math" style="vertical-align:-0.1045em;height:0.7795em;width:2.4151em" viewBox='-18.2 25.89 23.001 7.424' ><desc>$k-1$</desc><g id='page206'><use x='-18' xlink:href='#g3-107' y='33.004'/><use x='-10.305' xlink:href='#g1-0' y='33.004'/><use x='-0.372' xlink:href='#g5-49' y='33.004'/></g></svg> and with <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4353em" viewBox='-0.2 26.168 23.193 7.145' ><desc>$x-2$</desc><g id='page207'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='7.887' xlink:href='#g1-0' y='33.004'/><use x='17.82' xlink:href='#g5-50' y='33.004'/></g></svg>) and +obtain <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:12.4850em" viewBox='-18.2 25.332 118.905 10.363' ><desc>$0 \leq (x-2) \And (x-2) \textrm{ even}$</desc><g id='page184'><use x='-18' xlink:href='#g5-48' y='33.004'/><use x='-10.27' xlink:href='#g1-20' y='33.004'/><use x='0.217' xlink:href='#g5-40' y='33.004'/><use x='4.077' xlink:href='#g3-120' y='33.004'/><use x='11.964' xlink:href='#g1-0' y='33.004'/><use x='21.897' xlink:href='#g5-50' y='33.004'/><use x='26.86' xlink:href='#g5-41' y='33.004'/><use x='35.701' xlink:href='#g1-94' y='33.004'/><use x='47.299' xlink:href='#g5-40' y='33.004'/><use x='51.159' xlink:href='#g3-120' y='33.004'/><use x='59.046' xlink:href='#g1-0' y='33.004'/><use x='68.979' xlink:href='#g5-50' y='33.004'/><use x='73.942' xlink:href='#g5-41' y='33.004'/><use x='81.123' xlink:href='#g5-101' y='33.004'/><use x='85.534' xlink:href='#g5-118' y='33.004'/><use x='90.496' xlink:href='#g5-101' y='33.004'/><use x='94.907' xlink:href='#g5-110' y='33.004'/></g></svg>, from which our proof goal +follows. +</p><h5 id="sec-example-greatest-solution" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">11.0.2.1</span>. </span>Example with Greatest Solution</h5> +<p class="p noindent">We can think of a given predicate <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\greatest(x)$</desc><g id='page191'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-34' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg> as being represented +by a proof tree—in this case a term in a <em class="em-low1">coinductive datatype</em>, +since the proof may be infinite. +For this reason, greatest solutions like <svg class="math-inline math-render-svg math" style="vertical-align:-0.2342em;height:1.1443em;width:1.0586em" viewBox='-18.2 24.348 10.082 10.898' ><desc>$g\greatest$</desc><g id='page186'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-34' y='29.388'/></g></svg> have +been given the name <em class="em-low1">coinductive predicate</em>, or <em class="em-low1">co-predicate</em> for short. +The main technique for proving something from a given proof tree, that +is, to prove something of the form <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.1048em" viewBox='-0.2 24.348 58.141 11.346' ><desc>$g\greatest(x) \Imp R$</desc><g id='page187'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-34' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/><use x='28.599' xlink:href='#g5-61' y='33.004'/><use x='34.658' xlink:href='#g1-41' y='33.004'/><use x='50.118' xlink:href='#g3-82' y='33.004'/></g></svg>, is to +destruct the proof. Since this is just unfolding the defining +equation, the fact that we're using a greatest solution for <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg> never +plays a role (as long as we limit ourselves to a finite number of +unfoldings). +</p> +<p class="p indent">To go in the other direction, to establish a predicate defined as a greatest solution, +like <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.1294em" viewBox='-0.2 24.348 58.375 11.346' ><desc>$Q \Imp g\greatest(x)$</desc><g id='page189'><use x='0' xlink:href='#g3-81' y='33.004'/><use x='13.381' xlink:href='#g5-61' y='33.004'/><use x='19.441' xlink:href='#g1-41' y='33.004'/><use x='34.901' xlink:href='#g3-103' y='33.004'/><use x='39.992' xlink:href='#g2-34' y='29.388'/><use x='44.572' xlink:href='#g5-40' y='33.004'/><use x='48.432' xlink:href='#g3-120' y='33.004'/><use x='54.105' xlink:href='#g5-41' y='33.004'/></g></svg>, we may need an infinite number of steps. For this purpose, +we can use induction's dual, <em class="em-low1">coinduction</em>. Were it not for one little detail, coinduction +is as simple as continuations in programming: the next part of the proof obligation +is delegated to the <em class="em-low1">coinduction hypothesis</em>. The little detail is making sure that +it is the “next” part we're passing on for the continuation, not the same part. This +detail is called <em class="em-low1">productivity</em> and corresponds to the requirement in +induction of making sure we're going down a well-founded relation when +applying the induction hypothesis. There are +many sources with more information, see for example the classic account by +Jacobs and Rutten <span class="citations" style="target-element:bibitem">[<a href="#jacobsrutten:introductioncoalgebra" title="Bart Jacobs and Jan Rutten. +An introduction to (co)algebra and (co)induction." class="bibref localref" style="target-element:bibitem"><span class="cite-number">8</span></a>]</span> +or a new attempt by Kozen and Silva +that aims to emphasize the simplicity, not the mystery, of +coinduction <span class="citations" style="target-element:bibitem">[<a href="#kozensilva:coinduction" title="Dexter Kozen and Alexandra Silva. +Practical coinduction." class="bibref localref" style="target-element:bibitem"><span class="cite-number">11</span></a>]</span>. +</p> +<p class="p indent">Let's prove <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:7.2153em" viewBox='-18.2 24.348 68.717 11.346' ><desc>$\true \Imp g\greatest(x)$</desc><g id='page190'><use x='-18' xlink:href='#g0-116' y='33.004'/><use x='-14.703' xlink:href='#g0-114' y='33.004'/><use x='-10.517' xlink:href='#g0-117' y='33.004'/><use x='-5.191' xlink:href='#g0-101' y='33.004'/><use x='5.723' xlink:href='#g5-61' y='33.004'/><use x='11.783' xlink:href='#g1-41' y='33.004'/><use x='27.243' xlink:href='#g3-103' y='33.004'/><use x='32.334' xlink:href='#g2-34' y='29.388'/><use x='36.914' xlink:href='#g5-40' y='33.004'/><use x='40.774' xlink:href='#g3-120' y='33.004'/><use x='46.447' xlink:href='#g5-41' y='33.004'/></g></svg>. The intuitive coinductive proof goes like this: +According to the right-hand rule of <a href="#g-coind-rule" class="localref" style="target-element:equation"><span class="equation-label">(10)</span></a>, <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:2.4648em" viewBox='-0.2 24.348 23.474 11.346' ><desc>$g\greatest(x)$</desc><g id='page191'><use x='0' xlink:href='#g3-103' y='33.004'/><use x='5.092' xlink:href='#g2-34' y='29.388'/><use x='9.672' xlink:href='#g5-40' y='33.004'/><use x='13.532' xlink:href='#g3-120' y='33.004'/><use x='19.204' xlink:href='#g5-41' y='33.004'/></g></svg> follows if we +establish <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:4.2613em" viewBox='-18.2 24.348 40.584 11.346' ><desc>$g\greatest(x-2)$</desc><g id='page192'><use x='-18' xlink:href='#g3-103' y='33.004'/><use x='-12.908' xlink:href='#g2-34' y='29.388'/><use x='-8.328' xlink:href='#g5-40' y='33.004'/><use x='-4.468' xlink:href='#g3-120' y='33.004'/><use x='3.418' xlink:href='#g1-0' y='33.004'/><use x='13.352' xlink:href='#g5-50' y='33.004'/><use x='18.314' xlink:href='#g5-41' y='33.004'/></g></svg>, and that's easy to do by invoking the coinduction hypothesis. +The “little detail”, productivity, is satisfied in this proof because we applied +a rule in <a href="#g-coind-rule" class="localref" style="target-element:equation"><span class="equation-label">(10)</span></a> before invoking the coinduction hypothesis. +</p> +<p class="p indent">For anyone who may have felt that the intuitive proof felt too easy, here is a formal +proof using <a href="#eq-greatest-is-forall" class="localref" style="target-element:equation"><span class="equation-label">(15)</span></a>, which relies only on induction. We massage the +general form of our proof goal: +</p><table class="madoko block"> +<tbody><tr><td class="tbody tr-odd tr-first col col-odd col-first" data-row="1" data-col="1"> </td><td class="tbody tr-odd tr-first col col-even col-last" data-row="1" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2920em;height:1.1913em;width:6.2176em" viewBox='-0.2 24.348 59.215 11.346' ><desc>$Q \Imp f\greatest(x)$</desc><g id='page193'><use x='0' xlink:href='#g3-81' y='33.004'/><use x='13.381' xlink:href='#g5-61' y='33.004'/><use x='19.441' xlink:href='#g1-41' y='33.004'/><use x='34.901' xlink:href='#g3-102' y='33.004'/><use x='40.832' xlink:href='#g2-34' y='29.388'/><use x='45.413' xlink:href='#g5-40' y='33.004'/><use x='49.272' xlink:href='#g3-120' y='33.004'/><use x='54.945' xlink:href='#g5-41' y='33.004'/></g></svg> </td></tr> +<tr><td class="tbody tr-even col col-odd col-first" data-row="2" data-col="1"> = </td><td class="tbody tr-even col col-even col-last" data-row="2" data-col="2">      { <a href="#eq-greatest-is-forall" class="localref" style="target-element:equation"><span class="equation-label">(15)</span></a> } </td></tr> +<tr><td class="tbody tr-odd col col-odd col-first" data-row="3" data-col="1"> </td><td class="tbody tr-odd col col-even col-last" data-row="3" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2960em;height:1.2090em;width:8.9007em" viewBox='-18.2 24.195 84.769 11.514' ><desc>$Q \Imp \forall k \bullet\; \Iter{f}_k(x)$</desc><g id='page194'><use x='-18' xlink:href='#g3-81' y='33.004'/><use x='-4.619' xlink:href='#g5-61' y='33.004'/><use x='1.441' xlink:href='#g1-41' y='33.004'/><use x='16.901' xlink:href='#g1-56' y='33.004'/><use x='22.415' xlink:href='#g3-107' y='33.004'/><use x='30.11' xlink:href='#g1-15' y='33.004'/><use x='40.054' xlink:href='#g4-93' y='29.388'/><use x='42.115' xlink:href='#g3-102' y='33.004'/><use x='48.065' xlink:href='#g4-107' y='35.439'/><use x='52.967' xlink:href='#g5-40' y='33.004'/><use x='56.827' xlink:href='#g3-120' y='33.004'/><use x='62.5' xlink:href='#g5-41' y='33.004'/></g></svg> </td></tr> +<tr><td class="tbody tr-even col col-odd col-first" data-row="4" data-col="1"> = </td><td class="tbody tr-even col col-even col-last" data-row="4" data-col="2">      { distribute <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.6173em;width:2.3025em" viewBox='-0.2 27.573 21.929 5.879' ><desc>$\Imp$</desc><g id='page195'><use x='2.767' xlink:href='#g5-61' y='33.004'/><use x='8.827' xlink:href='#g1-41' y='33.004'/></g></svg> over <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7910em;width:0.6236em" viewBox='-18.2 25.89 5.939 7.533' ><desc>$\forall$</desc><g id='page196'><use x='-18' xlink:href='#g1-56' y='33.004'/></g></svg> to the right } </td></tr> +<tr><td class="tbody tr-odd tr-last col col-odd col-first" data-row="5" data-col="1"> </td><td class="tbody tr-odd tr-last col col-even col-last" data-row="5" data-col="2"> <svg class="math-inline math-render-svg math" style="vertical-align:-0.2960em;height:1.2090em;width:8.9007em" viewBox='-0.2 24.195 84.769 11.514' ><desc>$\forall k \bullet\; Q \Imp \Iter{f}_k(x)$</desc><g id='page197'><use x='0' xlink:href='#g1-56' y='33.004'/><use x='5.514' xlink:href='#g3-107' y='33.004'/><use x='13.209' xlink:href='#g1-15' y='33.004'/><use x='23.153' xlink:href='#g3-81' y='33.004'/><use x='36.534' xlink:href='#g5-61' y='33.004'/><use x='42.593' xlink:href='#g1-41' y='33.004'/><use x='58.054' xlink:href='#g4-93' y='29.388'/><use x='60.115' xlink:href='#g3-102' y='33.004'/><use x='66.065' xlink:href='#g4-107' y='35.439'/><use x='70.967' xlink:href='#g5-40' y='33.004'/><use x='74.827' xlink:href='#g3-120' y='33.004'/><use x='80.5' xlink:href='#g5-41' y='33.004'/></g></svg> </td></tr></tbody></table> +<p class="p noindent">The last line can be proved by induction over <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg>. So, in our case, we prove +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2960em;height:1.2090em;width:7.4674em" viewBox='-0.2 24.195 71.118 11.514' ><desc>$\true \Imp \Iter{g}_k(x)$</desc><g id='page199'><use x='0' xlink:href='#g0-116' y='33.004'/><use x='3.297' xlink:href='#g0-114' y='33.004'/><use x='7.483' xlink:href='#g0-117' y='33.004'/><use x='12.809' xlink:href='#g0-101' y='33.004'/><use x='23.723' xlink:href='#g5-61' y='33.004'/><use x='29.783' xlink:href='#g1-41' y='33.004'/><use x='45.243' xlink:href='#g4-93' y='29.388'/><use x='47.305' xlink:href='#g3-103' y='33.004'/><use x='52.414' xlink:href='#g4-107' y='35.439'/><use x='57.316' xlink:href='#g5-40' y='33.004'/><use x='61.176' xlink:href='#g3-120' y='33.004'/><use x='66.848' xlink:href='#g5-41' y='33.004'/></g></svg> for every <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7795em;width:0.6186em" viewBox='-18.2 25.89 5.891 7.424' ><desc>$k$</desc><g id='page200'><use x='-18' xlink:href='#g3-107' y='33.004'/></g></svg>. +If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7910em;width:2.5313em" viewBox='-0.2 25.89 24.108 7.533' ><desc>$k=0$</desc><g id='page201'><use x='0' xlink:href='#g3-107' y='33.004'/><use x='8.248' xlink:href='#g5-61' y='33.004'/><use x='18.735' xlink:href='#g5-48' y='33.004'/></g></svg>, then <svg class="math-inline math-render-svg math" style="vertical-align:-0.2960em;height:1.2090em;width:2.7169em" viewBox='-18.2 24.195 25.875 11.514' ><desc>$\Iter{g}_k(x)$</desc><g id='page202'><use x='-18' xlink:href='#g4-93' y='29.388'/><use x='-15.938' xlink:href='#g3-103' y='33.004'/><use x='-10.829' xlink:href='#g4-107' y='35.439'/><use x='-5.927' xlink:href='#g5-40' y='33.004'/><use x='-2.067' xlink:href='#g3-120' y='33.004'/><use x='3.605' xlink:href='#g5-41' y='33.004'/></g></svg> is <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7083em;width:1.9529em" viewBox='-0.2 26.567 18.599 6.746' ><desc>$\true$</desc><g id='page203'><use x='0' xlink:href='#g0-116' y='33.004'/><use x='3.297' xlink:href='#g0-114' y='33.004'/><use x='7.483' xlink:href='#g0-117' y='33.004'/><use x='12.809' xlink:href='#g0-101' y='33.004'/></g></svg>, so our goal holds trivially. +If <svg class="math-inline math-render-svg math" style="vertical-align:-0.0642em;height:0.8099em;width:2.5313em" viewBox='-18.2 25.89 24.108 7.713' ><desc>$k > 0$</desc><g id='page204'><use x='-18' xlink:href='#g3-107' y='33.004'/><use x='-9.752' xlink:href='#g3-62' y='33.004'/><use x='0.735' xlink:href='#g5-48' y='33.004'/></g></svg>, then <svg class="math-inline math-render-svg math" style="vertical-align:-0.3577em;height:1.2090em;width:14.7097em" viewBox='-0.2 24.195 140.092 11.514' ><desc>$\Iter{g}_k(x) = (x = 0 \Or \Iter{g}_{k-1}(x-2))$</desc><g id='page205'><use x='0' xlink:href='#g4-93' y='29.388'/><use x='2.062' xlink:href='#g3-103' y='33.004'/><use x='7.171' xlink:href='#g4-107' y='35.439'/><use x='12.073' xlink:href='#g5-40' y='33.004'/><use x='15.933' xlink:href='#g3-120' y='33.004'/><use x='21.605' xlink:href='#g5-41' y='33.004'/><use x='28.233' xlink:href='#g5-61' y='33.004'/><use x='38.72' xlink:href='#g5-40' y='33.004'/><use x='42.58' xlink:href='#g3-120' y='33.004'/><use x='51.02' xlink:href='#g5-61' y='33.004'/><use x='61.507' xlink:href='#g5-48' y='33.004'/><use x='71.451' xlink:href='#g1-95' y='33.004'/><use x='83.049' xlink:href='#g4-93' y='29.388'/><use x='85.111' xlink:href='#g3-103' y='33.004'/><use x='90.22' xlink:href='#g4-107' y='35.439'/><use x='94.608' xlink:href='#g2-0' y='35.439'/><use x='100.811' xlink:href='#g6-49' y='35.439'/><use x='105.32' xlink:href='#g5-40' y='33.004'/><use x='109.18' xlink:href='#g3-120' y='33.004'/><use x='117.066' xlink:href='#g1-0' y='33.004'/><use x='127' xlink:href='#g5-50' y='33.004'/><use x='131.962' xlink:href='#g5-41' y='33.004'/><use x='135.822' xlink:href='#g5-41' y='33.004'/></g></svg>. We establish the second +disjunct by applying the induction hypothesis (on the smaller <svg class="math-inline math-render-svg math" style="vertical-align:-0.1045em;height:0.7795em;width:2.4151em" viewBox='-18.2 25.89 23.001 7.424' ><desc>$k-1$</desc><g id='page206'><use x='-18' xlink:href='#g3-107' y='33.004'/><use x='-10.305' xlink:href='#g1-0' y='33.004'/><use x='-0.372' xlink:href='#g5-49' y='33.004'/></g></svg> and with <svg class="math-inline math-render-svg math" style="vertical-align:-0.1069em;height:0.7502em;width:2.4353em" viewBox='-0.2 26.168 23.193 7.145' ><desc>$x-2$</desc><g id='page207'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='7.887' xlink:href='#g1-0' y='33.004'/><use x='17.82' xlink:href='#g5-50' y='33.004'/></g></svg>). +</p><h4 id="sec-other-techniques" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.0.3</span>. </span>Other Techniques</h4> +<p class="p noindent">Although in this paper I consider only well-founded functions and extreme +predicates, it is worth mentioning that there are additional ways of making sure that +the set of solutions to <a href="#eq-general" class="localref" style="target-element:equation"><span class="equation-label">(0)</span></a> is nonempty. For example, if all calls to <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> in +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2936em;height:1.0924em;width:2.6229em" viewBox='-0.2 25.29 24.98 10.404' ><desc>$\F'(f)$</desc><g id='page209'><use x='0' xlink:href='#g1-70' y='33.004'/><use x='8.123' xlink:href='#g2-48' y='29.388'/><use x='10.918' xlink:href='#g5-40' y='33.004'/><use x='14.778' xlink:href='#g3-102' y='33.004'/><use x='20.71' xlink:href='#g5-41' y='33.004'/></g></svg> are <em class="em-low1">tail-recursive calls</em>, then (under the assumption that <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.8805em" viewBox='-18.2 25.999 8.386 7.204' ><desc>$Y$</desc><g id='page210'><use x='-18' xlink:href='#g3-89' y='33.004'/></g></svg> is nonempty) the set of +solutions is nonempty. To see this, consider an attempted evaluation of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:2.0721em" viewBox='-0.2 25.332 19.734 10.363' ><desc>$f(x)$</desc><g id='page211'><use x='0' xlink:href='#g3-102' y='33.004'/><use x='5.932' xlink:href='#g5-40' y='33.004'/><use x='9.792' xlink:href='#g3-120' y='33.004'/><use x='15.464' xlink:href='#g5-41' y='33.004'/></g></svg> that fails +to determine a definite result value because of an infinite chain of calls that applies <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> +to each value of some subset <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.8310em;width:1.2821em" viewBox='-18.2 25.29 12.21 7.914' ><desc>$X'$</desc><g id='page216'><use x='-18' xlink:href='#g3-88' y='33.004'/><use x='-8.995' xlink:href='#g2-48' y='29.388'/></g></svg> of <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.7564em;width:0.9886em" viewBox='-18.2 25.999 9.415 7.204' ><desc>$X$</desc><g id='page214'><use x='-18' xlink:href='#g3-88' y='33.004'/></g></svg>. Then, apparently, the value of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:0.6659em" viewBox='-0.2 25.78 6.342 9.466' ><desc>$f$</desc><g id='page215'><use x='0' xlink:href='#g3-102' y='33.004'/></g></svg> for any one +of the values in <svg class="math-inline math-render-svg math" style="vertical-align:-0.0210em;height:0.8310em;width:1.2821em" viewBox='-18.2 25.29 12.21 7.914' ><desc>$X'$</desc><g id='page216'><use x='-18' xlink:href='#g3-88' y='33.004'/><use x='-8.995' xlink:href='#g2-48' y='29.388'/></g></svg> is not determined by the equation, but picking any particular result +values for these makes for a consistent definition. +This was pointed out by Manolios and Moore <span class="citations" style="target-element:bibitem">[<a href="#manoliosmoore:partialfunctions" title="Panagiotis Manolios and J Strother Moore. +Partial functions in ACL2." class="bibref localref" style="target-element:bibitem"><span class="cite-number">25</span></a>]</span>. +Functions can be underspecified in this way in the proof assistants ACL2 <span class="citations" style="target-element:bibitem">[<a href="#acl2:book" title="Matt Kaufmann, Panagiotis Manolios, and J Strother Moore. +Computer-Aided Reasoning: An Approach." class="bibref localref" style="target-element:bibitem"><span class="cite-number">10</span></a>]</span> +and HOL <span class="citations" style="target-element:bibitem">[<a href="#krauss:phd" title="Alexander Krauss. +Automating Recursive Definitions and Termination Proofs in Higher-Order Logic. +PhD thesis, Technische Universität München, 2009." class="bibref localref" style="target-element:bibitem"><span class="cite-number">12</span></a>]</span>. +</p><h3 id="sec-functions-in-dafny" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">11.1</span>. </span>Functions in Dafny</h3> +<p class="p noindent">In this section, I explain with examples the support in +Dafny<sup id="back-fn-fn-on-da-web" ><a href="#fn-fn-on-da-web" title="5.Dafny is open source at dafny.codeplex.com and can also be used online at rise4fun.com/dafny. +↩" class="footnote-ref localref" ><span class="footnote-label">5</span></a></sup> for well-founded functions, extreme predicates, +and proofs regarding these. +</p><h4 id="sec-well-founded-functions-in-dafny" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.1.0</span>. </span>Well-founded Functions in Dafny</h4> +<p class="p noindent">Declarations of well-founded functions are unsurprising. For example, the Fibonacci +function is declared as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> fib(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> +{ + <span style="color:blue">if</span> n < <span class="constant" style="color:purple">2</span> <span style="color:blue">then</span> n <span style="color:blue">else</span> fib(n-<span class="constant" style="color:purple">2</span>) + fib(n-<span class="constant" style="color:purple">1</span>) +}</code></pre> +<p class="p noindent para-continued">Dafny verifies that the body (given as an expression in curly braces) is well defined. +This includes decrement checks for recursive (and mutually recursive) calls. Dafny +predefines a well-founded relation on each type and extends it to lexicographic tuples +of any (fixed) length. For example, the well-founded relation <svg class="math-inline math-render-svg math" style="vertical-align:-0.2459em;height:0.8485em;width:2.8104em" viewBox='-0.2 27.165 26.766 8.081' ><desc>$x \Less y$</desc><g id='page217'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='8.44' xlink:href='#g1-28' y='33.004'/><use x='21.133' xlink:href='#g3-121' y='33.004'/></g></svg> for integers +is <svg class="math-inline math-render-svg math" style="vertical-align:-0.2419em;height:0.9531em;width:6.7810em" viewBox='-18.2 26.168 64.581 9.077' ><desc>$x < y \And 0 \leq y$</desc><g id='page218'><use x='-18' xlink:href='#g3-120' y='33.004'/><use x='-9.56' xlink:href='#g3-60' y='33.004'/><use x='0.927' xlink:href='#g3-121' y='33.004'/><use x='11.132' xlink:href='#g1-94' y='33.004'/><use x='22.73' xlink:href='#g5-48' y='33.004'/><use x='30.46' xlink:href='#g1-20' y='33.004'/><use x='40.947' xlink:href='#g3-121' y='33.004'/></g></svg>, the one for reals is <svg class="math-inline math-render-svg math" style="vertical-align:-0.2419em;height:0.9531em;width:10.1988em" viewBox='-0.2 26.168 97.131 9.077' ><desc>$x \leq y - 1.0 \And 0.0 \leq y$</desc><g id='page219'><use x='0' xlink:href='#g3-120' y='33.004'/><use x='8.44' xlink:href='#g1-20' y='33.004'/><use x='18.927' xlink:href='#g3-121' y='33.004'/><use x='26.365' xlink:href='#g1-0' y='33.004'/><use x='36.298' xlink:href='#g5-49' y='33.004'/><use x='41.261' xlink:href='#g3-58' y='33.004'/><use x='44.018' xlink:href='#g5-48' y='33.004'/><use x='53.962' xlink:href='#g1-94' y='33.004'/><use x='65.56' xlink:href='#g5-48' y='33.004'/><use x='70.523' xlink:href='#g3-58' y='33.004'/><use x='73.28' xlink:href='#g5-48' y='33.004'/><use x='81.01' xlink:href='#g1-20' y='33.004'/><use x='91.497' xlink:href='#g3-121' y='33.004'/></g></svg> +(this is the same ordering as for integers, if you read the integer +relation as <svg class="math-inline math-render-svg math" style="vertical-align:-0.2419em;height:0.9531em;width:8.5776em" viewBox='-18.2 26.168 81.691 9.077' ><desc>$x \leq y - 1 \And 0 \leq y$</desc><g id='page220'><use x='-18' xlink:href='#g3-120' y='33.004'/><use x='-9.56' xlink:href='#g1-20' y='33.004'/><use x='0.927' xlink:href='#g3-121' y='33.004'/><use x='8.365' xlink:href='#g1-0' y='33.004'/><use x='18.298' xlink:href='#g5-49' y='33.004'/><use x='28.242' xlink:href='#g1-94' y='33.004'/><use x='39.84' xlink:href='#g5-48' y='33.004'/><use x='47.571' xlink:href='#g1-20' y='33.004'/><use x='58.058' xlink:href='#g3-121' y='33.004'/></g></svg>), the one for inductive +datatypes is structural inclusion, +and the one for coinductive datatypes is <svg class="math-inline math-render-svg math" style="vertical-align:-0.2384em;height:0.9939em;width:2.1795em" viewBox='-0.449 25.78 20.757 9.466' ><desc>$\false$</desc><g id='page221'><use x='0' xlink:href='#g0-102' y='33.004'/><use x='3.044' xlink:href='#g0-97' y='33.004'/><use x='8.117' xlink:href='#g0-108' y='33.004'/><use x='10.653' xlink:href='#g0-115' y='33.004'/><use x='14.712' xlink:href='#g0-101' y='33.004'/></g></svg>. +</p> +<p class="p indent">Using a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> clause, the programmer can specify the term in this predefined +order. When a function definition omits a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> clause, Dafny makes a simple +guess. This guess (which can be inspected by hovering over the function name in the +Dafny IDE) is very often correct, so users are rarely bothered to provide explicit +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> clauses. +</p> +<p class="p indent">If a function returns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code>, one can drop the result type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">: <span style="color:teal">bool</span></code> and change the +keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">function</span></code> to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">predicate</span></code>. +</p><h4 id="sec-proofs-in-dafny" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.1.1</span>. </span>Proofs in Dafny</h4> +<p class="p noindent">Dafny has <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">lemma</span></code> declarations. These are really just special cases of methods: +they can have pre- and postcondition specifications and their body is a code block. +Here is the lemma we stated and proved in Section <a href="#sec-fib-example" title="11.0.0.0. Example with Well-founded Functions" class="localref" style="target-element:h4"><span class="heading-label">11.0.0.0</span></a>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> FibProperty(n: <span style="color:teal">nat</span>) + <span style="color:purple">ensures</span> fib(n) % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> <==> n % <span class="constant" style="color:purple">3</span> == <span class="constant" style="color:purple">0</span> +{ + <span style="color:blue">if</span> n < <span class="constant" style="color:purple">2</span> { + } <span style="color:blue">else</span> { + FibProperty(n-<span class="constant" style="color:purple">2</span>); FibProperty(n-<span class="constant" style="color:purple">1</span>); + } +}</code></pre> +<p class="p noindent para-continued">The postcondition of this lemma (keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">ensures</span></code>) gives the proof +goal. As in any program-correctness logic (e.g., +<span class="citations" style="target-element:bibitem">[<a href="#hoare:axiomaticbasis" title="C. A. R. Hoare. +An axiomatic basis for computer programming." class="bibref localref" style="target-element:bibitem"><span class="cite-number">7</span></a>]</span>), the postcondition must +be established on every control path through the lemma's body. For +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FibProperty</code>, I give the proof by +an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code> statement, hence introducing a case split. The then branch is empty, because +Dafny can prove the postcondition automatically in this case. The else branch +performs two recursive calls to the lemma. These are the invocations of the induction +hypothesis and they follow the usual program-correctness rules, +namely: the precondition must hold at the call site, the call must terminate, and then +the caller gets to assume the postcondition upon return. The “proof glue” needed +to complete the proof is done automatically by Dafny. +</p> +<p class="p indent">Dafny features an aggregate statement using which it is possible to make (possibly +infinitely) many calls at once. For example, the induction hypothesis can be called +at once on all values <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n'</code> smaller than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> n' | <span class="constant" style="color:purple">0</span> <= n' < n { + FibProperty(n'); +}</code></pre> +<p class="p noindent para-continued">For our purposes, this corresponds to <em class="em-low1">strong induction</em>. More +generally, the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement has the form +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> k | P(k) + <span style="color:purple">ensures</span> Q(k) +{ Statements; }</code></pre> +<p class="p noindent para-continued">Logically, this statement corresponds to <em class="em-low1">universal introduction</em>: the body proves that +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q(k)</code> holds for an arbitrary <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> such that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(k)</code>, and the conclusion of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement +is then <svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:9.7252em" viewBox='-18.2 25.332 92.621 10.363' ><desc>$\forall k \bullet\; P(k) \Imp Q(k)$</desc><g id='page222'><use x='-18' xlink:href='#g1-56' y='33.004'/><use x='-12.486' xlink:href='#g3-107' y='33.004'/><use x='-4.791' xlink:href='#g1-15' y='33.004'/><use x='5.153' xlink:href='#g3-80' y='33.004'/><use x='12.909' xlink:href='#g5-40' y='33.004'/><use x='16.769' xlink:href='#g3-107' y='33.004'/><use x='22.249' xlink:href='#g5-41' y='33.004'/><use x='31.644' xlink:href='#g5-61' y='33.004'/><use x='37.703' xlink:href='#g1-41' y='33.004'/><use x='53.164' xlink:href='#g3-81' y='33.004'/><use x='61.01' xlink:href='#g5-40' y='33.004'/><use x='64.87' xlink:href='#g3-107' y='33.004'/><use x='70.351' xlink:href='#g5-41' y='33.004'/></g></svg>. When the body of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement is +a single call (or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statement), the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">ensures</span></code> clause is inferred and can be omitted, +like in our <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FibProperty</code> example. +</p> +<p class="p indent">Lemma <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FibProperty</code> is simple enough that its whole body can be replaced by the one +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement above. In fact, Dafny goes one step further: it automatically +inserts such a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement at the beginning of every lemma <span class="citations" style="target-element:bibitem">[<a href="#leino:induction" title="K. Rustan M. Leino. +Automating induction with an SMT solver." class="bibref localref" style="target-element:bibitem"><span class="cite-number">19</span></a>]</span>. +Thus, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FibProperty</code> can be declared and proved simply by: +</p> +<pre class="para-block para-end pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> FibProperty(n: <span style="color:teal">nat</span>) + <span style="color:purple">ensures</span> fib(n) % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> <==> n % <span class="constant" style="color:purple">3</span> == <span class="constant" style="color:purple">0</span> +{ }</code></pre> +<p class="p indent">Going in the other direction from universal introduction is existential elimination, +also known as Skolemization. Dafny has a statement for this, too: +for any variable <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> and boolean expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code>, the +<em class="em-low1">assign such that</em> statement <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x <span style="color:blue">:|</span> Q;</code> says to assign to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> a value such that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> +will hold. A proof obligation when using this statement is to show that there +exists an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> such that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> holds. For example, if the fact +<svg class="math-inline math-render-svg math" style="vertical-align:-0.2930em;height:1.0881em;width:10.9055em" viewBox='-0.2 25.332 103.862 10.363' ><desc>$\exists k \bullet\; 100 \leq \fib(k) < 200$</desc><g id='page223'><use x='0' xlink:href='#g1-57' y='33.004'/><use x='5.514' xlink:href='#g3-107' y='33.004'/><use x='13.209' xlink:href='#g1-15' y='33.004'/><use x='23.153' xlink:href='#g5-49' y='33.004'/><use x='28.116' xlink:href='#g5-48' y='33.004'/><use x='33.078' xlink:href='#g5-48' y='33.004'/><use x='40.808' xlink:href='#g1-20' y='33.004'/><use x='51.295' xlink:href='#g0-12' y='33.004'/><use x='56.876' xlink:href='#g0-98' y='33.004'/><use x='62.108' xlink:href='#g5-40' y='33.004'/><use x='65.968' xlink:href='#g3-107' y='33.004'/><use x='71.449' xlink:href='#g5-41' y='33.004'/><use x='78.076' xlink:href='#g3-60' y='33.004'/><use x='88.563' xlink:href='#g5-50' y='33.004'/><use x='93.526' xlink:href='#g5-48' y='33.004'/><use x='98.489' xlink:href='#g5-48' y='33.004'/></g></svg> is known, then the statement +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k <span style="color:blue">:|</span> <span class="constant" style="color:purple">100</span> <= fib(k) < <span class="constant" style="color:purple">200</span>;</code> will assign to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> some value (chosen arbitrarily) +for which <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">fib(k)</code> falls in the given range. +</p><h4 id="sec-friendliness" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.1.2</span>. </span>Extreme Predicates in Dafny</h4> +<p class="p noindent">In this previous subsection, I explained that a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">predicate</span></code> declaration introduces a +well-founded predicate. The declarations for introducing extreme predicates are +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">inductive</span> <span style="color:blue">predicate</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">copredicate</span></code>. Here is the definition of the least and +greatest solutions of <svg class="math-inline math-render-svg math" style="vertical-align:-0.2446em;height:0.7188em;width:0.5777em" viewBox='-18.2 28.4 5.502 6.846' ><desc>$g$</desc><g id='page224'><use x='-18' xlink:href='#g3-103' y='33.004'/></g></svg> from above, let's call them <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">inductive</span> <span style="color:blue">predicate</span> g(x: <span style="color:teal">int</span>) { x == <span class="constant" style="color:purple">0</span> || g(x-<span class="constant" style="color:purple">2</span>) } +<span style="color:blue">copredicate</span> G(x: <span style="color:teal">int</span>) { x == <span class="constant" style="color:purple">0</span> || G(x-<span class="constant" style="color:purple">2</span>) }</code></pre> +<p class="p noindent para-continued">When Dafny receives either of these definitions, it automatically declares the corresponding +prefix predicates. Instead of the names <svg class="math-inline math-render-svg math" style="vertical-align:-0.2874em;height:1.2339em;width:1.3107em" viewBox='-0.2 23.958 12.483 11.751' ><desc>$\iter{g}_k$</desc><g id='page225'><use x='0' xlink:href='#g4-91' y='29.388'/><use x='2.062' xlink:href='#g3-103' y='33.004'/><use x='7.171' xlink:href='#g4-107' y='35.439'/></g></svg> and <svg class="math-inline math-render-svg math" style="vertical-align:-0.2913em;height:1.2090em;width:1.3107em" viewBox='-18.2 24.195 12.483 11.514' ><desc>$\Iter{g}_k$</desc><g id='page226'><use x='-18' xlink:href='#g4-93' y='29.388'/><use x='-15.938' xlink:href='#g3-103' y='33.004'/><use x='-10.829' xlink:href='#g4-107' y='35.439'/></g></svg> that I used above, Dafny +names the prefix predicates <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g#[k]</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G#[k]</code>, respectively, that is, the name of +the extreme predicate appended with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">#</code>, and the subscript is given as an argument in +square brackets. The definition of the prefix predicate derives from the body of +the extreme predicate and follows the form in <a href="#eq-least-approx" class="localref" style="target-element:equation"><span class="equation-label">(11)</span></a> and <a href="#eq-greatest-approx" class="localref" style="target-element:equation"><span class="equation-label">(12)</span></a>. +Using a faux-syntax for illustrative purposes, here are the prefix +predicates that Dafny defines automatically from the extreme +predicates <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">G</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">predicate</span> g#[_k: <span style="color:teal">nat</span>](x: <span style="color:teal">int</span>) { _k != <span class="constant" style="color:purple">0</span> && (x == <span class="constant" style="color:purple">0</span> || g#[_k-<span class="constant" style="color:purple">1</span>](x-<span class="constant" style="color:purple">2</span>)) } +<span style="color:blue">predicate</span> G#[_k: <span style="color:teal">nat</span>](x: <span style="color:teal">int</span>) { _k != <span class="constant" style="color:purple">0</span> ==> (x == <span class="constant" style="color:purple">0</span> || G#[_k-<span class="constant" style="color:purple">1</span>](x-<span class="constant" style="color:purple">2</span>)) }</code></pre> +<p class="p noindent para-continued">The Dafny verifier is aware of the connection between extreme predicates and their +prefix predicates, <a href="#eq-least-is-exists" class="localref" style="target-element:equation"><span class="equation-label">(14)</span></a> and <a href="#eq-greatest-is-forall" class="localref" style="target-element:equation"><span class="equation-label">(15)</span></a>. +</p> +<p class="p indent">Remember that to be well defined, the defining functor of an extreme predicate +must be monotonic, and for <a href="#eq-least-is-exists" class="localref" style="target-element:equation"><span class="equation-label">(14)</span></a> and <a href="#eq-greatest-is-forall" class="localref" style="target-element:equation"><span class="equation-label">(15)</span></a> to hold, +the functor must be continuous. Dafny enforces the former of these by checking that +recursive calls of extreme predicates are in positive positions. The continuity +requirement comes down to checking that they are also in <em class="em-low1">continuous positions</em>: +that recursive calls to inductive predicates are +not inside unbounded universal quantifiers and that recursive calls to co-predicates +are not inside unbounded existential quantifiers <span class="citations" style="target-element:bibitem">[<a href="#leinomoskal:coinduction" title="K. Rustan M. Leino and Michał Moskal. +Co-induction simply — automatic co-inductive proofs in a program verifier. +In FM 2014, volume 8442 of LNCS, pages 382–398. Springer, May 2014b." class="bibref localref" style="target-element:bibitem"><span class="cite-number">21</span></a>, <a href="#milner:ccs" title="Robin Milner. +A Calculus of Communicating Systems." class="bibref localref" style="target-element:bibitem"><span class="cite-number">26</span></a>]</span>. +</p><h4 id="sec-proofs-about-extreme-predicates" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.1.3</span>. </span>Proofs about Extreme Predicates</h4> +<p class="p noindent">From what I have presented so far, we can do the formal proofs from Sections +<a href="#sec-example-least-solution" title="11.0.2.0. Example with Least Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.0</span></a> and <a href="#sec-example-greatest-solution" title="11.0.2.1. Example with Greatest Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.1</span></a>. Here is the +former: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> EvenNat(x: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> g(x) + <span style="color:purple">ensures</span> <span class="constant" style="color:purple">0</span> <= x && x % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> +{ + <span style="color:blue">var</span> k: <span style="color:teal">nat</span> <span style="color:blue">:|</span> g#[k](x); + EvenNatAux(k, x); +} +<span style="color:blue">lemma</span> EvenNatAux(k: <span style="color:teal">nat</span>, x: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> g#[k](x) + <span style="color:purple">ensures</span> <span class="constant" style="color:purple">0</span> <= x && x % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> +{ + <span style="color:blue">if</span> x == <span class="constant" style="color:purple">0</span> { } <span style="color:blue">else</span> { EvenNatAux(k-<span class="constant" style="color:purple">1</span>, x-<span class="constant" style="color:purple">2</span>); } +}</code></pre> +<p class="p noindent para-continued">Lemma <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">EvenNat</code> states the property we wish to prove. From its +precondition (keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code>) and +<a href="#eq-least-is-exists" class="localref" style="target-element:equation"><span class="equation-label">(14)</span></a>, we know there is some <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> that will make the condition in the +assign-such-that statement true. Such a value is then assigned to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> and passed to +the auxiliary lemma, which promises to establish the proof goal. Given the condition +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g#[k](x)</code>, the definition of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g#</code> lets us conclude <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k != <span class="constant" style="color:purple">0</span></code> as well as the disjunction +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x == <span class="constant" style="color:purple">0</span> || g#[k-<span class="constant" style="color:purple">1</span>](x-<span class="constant" style="color:purple">2</span>)</code>. The then branch considers the case of the first disjunct, +from which the proof goal follows automatically. The else branch can then assume +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g#[k-<span class="constant" style="color:purple">1</span>](x-<span class="constant" style="color:purple">2</span>)</code> and calls the induction hypothesis with those parameters. The proof +glue that shows the proof goal for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> to follow from the proof goal with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x-<span class="constant" style="color:purple">2</span></code> is +done automatically. +</p> +<p class="p indent">Because Dafny automatically inserts the statement +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> k', x' | <span class="constant" style="color:purple">0</span> <= k' < k && g#[k'](x') { + EvenNatAux(k', x'); +}</code></pre> +<p class="p noindent para-continued">at the beginning of the body of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">EvenNatAux</code>, the body can be left empty and Dafny +completes the proof automatically. +</p> +<p class="p indent">Here is the Dafny program that gives the proof from Section <a href="#sec-example-greatest-solution" title="11.0.2.1. Example with Greatest Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.1</span></a>: +</p> +<pre class="para-block para-end pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> Always(x: <span style="color:teal">int</span>) + <span style="color:purple">ensures</span> G(x) +{ <span style="color:blue">forall</span> k: <span style="color:teal">nat</span> { AlwaysAux(k, x); } } +<span style="color:blue">lemma</span> AlwaysAux(k: <span style="color:teal">nat</span>, x: <span style="color:teal">int</span>) + <span style="color:purple">ensures</span> G#[k](x) +{ }</code></pre> +<p class="p indent">While each of these proofs involves only basic proof rules, the setup feels a bit clumsy, +even with the empty body of the auxiliary lemmas. Moreover, +the proofs do not reflect the intuitive proofs I described in +Section <a href="#sec-example-least-solution" title="11.0.2.0. Example with Least Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.0</span></a> and <a href="#sec-example-greatest-solution" title="11.0.2.1. Example with Greatest Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.1</span></a>. +These shortcoming are addressed in the next subsection. +</p><h4 id="sec-nicer-proofs-of-extreme-predicates" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">11.1.4</span>. </span>Nicer Proofs of Extreme Predicates</h4> +<p class="p noindent">The proofs we just saw follow standard forms: +use Skolemization to convert the inductive predicate into a prefix predicate for some <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> +and then do the proof inductively over <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code>; respectively, +by induction over <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code>, prove the prefix predicate for every <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code>, then use +universal introduction to convert to the coinductive predicate. +With the declarations <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">inductive</span> <span style="color:blue">lemma</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">colemma</span></code>, Dafny offers to +set up the proofs +in these standard forms. What is gained is not just fewer characters in the program +text, but also a possible intuitive reading of the proofs. (Okay, to be fair, the +reading is intuitive for simpler proofs; complicated proofs may or may not be intuitive.) +</p> +<p class="p indent">Somewhat analogous to the creation of prefix predicates from extreme predicates, Dafny +automatically creates a <em class="em-low1">prefix lemma</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">L#</code> from each “extreme lemma” <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">L</code>. The pre- +and postconditions of a prefix lemma are copied from those of the extreme lemma, +except for the following replacements: +For an inductive lemma, Dafny looks in the precondition to find calls (in positive, continuous +positions) to inductive predicates <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(x)</code> and replaces these with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P#[_k](x)</code>. +For a +co-lemma, Dafny looks in the postcondition to find calls (in positive, continuous positions) +to co-predicates <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code> (including equality among coinductive datatypes, which is a built-in +co-predicate) and replaces these with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P#[_k](x)</code>. +In each case, these predicates <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code> are the lemma's <em class="em-low1">focal predicates</em>. +</p> +<p class="p indent">The body of the extreme lemma is moved to the prefix lemma, but with +replacing each recursive +call <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">L(x)</code> with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">L#[_k-<span class="constant" style="color:purple">1</span>](x)</code> and replacing each occurrence of a call +to a focal predicate +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(x)</code> with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P#[_k-<span class="constant" style="color:purple">1</span>](x)</code>. The bodies of the extreme lemmas are then replaced as shown +in the previous subsection. By construction, this new body correctly leads to the +extreme lemma's postcondition. +</p> +<p class="p indent">Let us see what effect these rewrites have on how one can write proofs. Here are the proofs +of our running example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">inductive</span> <span style="color:blue">lemma</span> EvenNat(x: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> g(x) + <span style="color:purple">ensures</span> <span class="constant" style="color:purple">0</span> <= x && x % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> +{ <span style="color:blue">if</span> x == <span class="constant" style="color:purple">0</span> { } <span style="color:blue">else</span> { EvenNat(x-<span class="constant" style="color:purple">2</span>); } } +<span style="color:blue">colemma</span> Always(x: <span style="color:teal">int</span>) + <span style="color:purple">ensures</span> G(x) +{ Always(x-<span class="constant" style="color:purple">2</span>); }</code></pre> +<p class="p noindent para-continued">Both of these proofs follow the intuitive proofs given in Sections +<a href="#sec-example-least-solution" title="11.0.2.0. Example with Least Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.0</span></a> and <a href="#sec-example-greatest-solution" title="11.0.2.1. Example with Greatest Solution" class="localref" style="target-element:h4"><span class="heading-label">11.0.2.1</span></a>. Note that in these +simple examples, the user is never bothered with either prefix predicates nor +prefix lemmas—the proofs just look like “what you'd expect”. +</p> +<p class="p indent">Since Dafny automatically inserts calls to the induction hypothesis at the beginning of +each lemma, the bodies of the given extreme lemmas <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">EvenNat</code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Always</code> can be empty and Dafny still completes the proofs. +Folks, it doesn't get any simpler than that! +</p><h2 id="sec-class-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">12</span>. </span>Class Types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_classdecl" class="ntdef" style="color:olive">ClassDecl</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"class"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_classname" class="ntref localref" style="color:maroon">ClassName</a></span> [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + [<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"extends"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> {<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span>} ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { { <span class="code-escaped"><a href="#1_declmodifier" class="ntref localref" style="color:maroon">DeclModifier</a></span> } <span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span>(moduleLevelDecl: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_classmemberdecl" class="ntdef" style="color:olive">ClassMemberDecl</span></span>(moduleLevelDecl) = + ( <span class="code-escaped"><a href="#1_fielddecl" class="ntref localref" style="color:maroon">FieldDecl</a></span> | <span class="code-escaped"><a href="#1_functiondecl" class="ntref localref" style="color:maroon">FunctionDecl</a></span> | + <span class="code-escaped"><a href="#1_methoddecl" class="ntref localref" style="color:maroon">MethodDecl</a></span>(isGhost: (<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> <span class="code-escaped"><a href="#2_was" class="ntref localref" style="color:maroon">was</a></span> <span class="code-escaped"><a href="#2_present" class="ntref localref" style="color:maroon">present</a></span>), + <span class="code-escaped"><a href="#2_allowconstructor" class="ntref localref" style="color:maroon">allowConstructor</a></span>: !<span class="code-escaped"><a href="#2_moduleleveldecl" class="ntref localref" style="color:maroon">moduleLevelDecl</a></span>) + ) </code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span></code> parameter <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">moduleLevelDecl</code> will be true if +the member declaration is at the top level or directly within a +module declaration. It will be false for <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span></code>s +that are part of a class or trait declaration. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">moduleLevelDecl</code> is +false <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_fielddecl" class="ntref localref" style="color:maroon">FieldDecl</a></span></code>s are not allowed. +</p> +<p class="p indent">A <em class="em-low1">class</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> is a reference type declared as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> C<T> <span style="color:blue">extends</span> J1, ..., Jn +{ + <span class="code-escaped"><em class="em-low1">members</em></span> +}</code></pre> +<p class="p noindent para-continued">where the list of type parameters <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is optional and so is +“<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">extends</span> J1, ..., Jn</code>”, which says that the class extends traits <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J1</code> … <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Jn</code>. +The members of a class are <em class="em-low1">fields</em>, <em class="em-low1">functions</em>, and +<em class="em-low1">methods</em>. These are accessed or invoked by dereferencing a reference +to a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> instance. +</p> +<p class="p indent">A function or method is invoked on an <em class="em-low1">instance</em> +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>, unless the function or method is declared <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code>. +A function or method that is not <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code> is called an +<em class="em-low1">instance</em> function or method. +</p> +<p class="p indent">An instance function or method takes an implicit <em class="em-low1">receiver</em> +parameter, namely, the instance used to access the member. In the +specification and body of an instance function or method, the receiver +parameter can be referred to explicitly by the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code>. +However, in such places, members of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code> can also be mentioned +without any qualification. To illustrate, the qualified <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span>.f</code> and +the unqualified <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> refer to the same field of the same object in the +following example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> C { + <span style="color:blue">var</span> f: <span style="color:teal">int</span> + <span style="color:blue">method</span> Example() <span style="color:blue">returns</span> (b: <span style="color:teal">bool</span>) + { + b <span style="color:blue">:=</span> f == <span style="color:blue">this</span>.f; + } +}</code></pre> +<p class="p noindent para-continued">so the method body always assigns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> to the out-parameter <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b</code>. +There is no semantic difference between qualified and +unqualified accesses to the same receiver and member. +</p> +<p class="p indent">A <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> instance is created using <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code>, for example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>c <span style="color:blue">:=</span> <span style="color:blue">new</span> C;</code></pre> +<p class="p noindent para-continued">Note that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> simply allocates a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> object and returns a reference +to it; the initial values of its fields are arbitrary values of their +respective types. Therefore, it is common to invoke a method, known +as an <em class="em-low1">initialization method</em>, immediately after creation, for +example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>c <span style="color:blue">:=</span> <span style="color:blue">new</span> C; +c.InitFromList(xs, <span class="constant" style="color:purple">3</span>);</code></pre> +<p class="p noindent para-continued">When an initialization method has no out-parameters and modifies no +more than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code>, then the two statements above can be combined into +one: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>c <span style="color:blue">:=</span> <span style="color:blue">new</span> C.InitFromList(xs, <span class="constant" style="color:purple">3</span>);</code></pre> +<p class="p noindent para-continued">Note that a class can contain several initialization methods, that +these methods can be invoked at any time, not just as part of a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code>, +and that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> does not require that an initialization method be +invoked at creation. +</p> +<p class="p indent">A clas can declare special initializing methods called <em class="em-low1">constructor methods</em>. +See Section <a href="#sec-method-declarations" title="12.1. Method Declarations" class="localref" style="target-element:h2"><span class="heading-label">12.1</span></a>. +</p><h3 id="sec-field-declarations" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">12.0</span>. </span>Field Declarations</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_fielddecl" class="ntdef" style="color:olive">FieldDecl</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"var"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_fidenttype" class="ntref localref" style="color:maroon">FIdentType</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_fidenttype" class="ntref localref" style="color:maroon">FIdentType</a></span> }</code></pre> +<p class="p noindent para-continued">An <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_fidenttype" class="ntref localref" style="color:maroon">FIdentType</a></span></code> is used to declare a field. The field name is either an +identifier (that is not allowed to start with a leading underscore) or +some digits. Digits are used if you want to number your fields, e.g. “0”, +“1”, etc. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_fidenttype" class="ntdef" style="color:olive">FIdentType</span></span> = ( <span class="code-escaped"><a href="#1_fieldident" class="ntref localref" style="color:maroon">FieldIdent</a></span> | <span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> </code></pre> +<p class="p noindent para-continued">A field x of some type T is declared as: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> x: T</code></pre> +<p class="p noindent para-continued">A field declaration declares one or more fields of the enclosing class. +Each field is a named part of the state of an object of that class. A +field declaration is similar to but distinct from a variable declaration +statement. Unlike for local variables and bound variables, the type is +required and will not be inferred. +</p> +<p class="p indent">Unlike method and function declarations, a field declaration +cannot be given at the top level. Fields can be declared in either a +class or a trait. A class that inherits from multiple traits will +have all the fields declared in any of its parent traits. +</p> +<p class="p indent">Fields that are declared as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code> can only be used in specifications, +not in code that will be compiled into executable code. +</p> +<p class="p indent">Fields may not be declared static. +</p> +<p class="p indent"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">protected</span></code> is not allowed for fields. +</p><h3 id="sec-method-declarations" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">12.1</span>. </span>Method Declarations</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_methoddecl" class="ntdef" style="color:olive">MethodDecl</span></span>(isGhost, <span class="code-escaped"><a href="#2_allowconstructor" class="ntref localref" style="color:maroon">allowConstructor</a></span>) = + <span class="code-escaped"><a href="#1_methodkeyword" class="ntref localref" style="color:maroon">MethodKeyword</a></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } [ <span class="code-escaped"><a href="#1_methodname" class="ntref localref" style="color:maroon">MethodName</a></span> ] + ( <span class="code-escaped"><a href="#1_methodsignature" class="ntref localref" style="color:maroon">MethodSignature</a></span>(isGhost) | <span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span> ) + <span class="code-escaped"><a href="#1_methodspec" class="ntref localref" style="color:maroon">MethodSpec</a></span> [ <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> ]</code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">isGhost</code> parameter is true iff the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code> keyword +preceded the method declaration. +</p> +<p class="p indent">If the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowConstructor</code> parameter is false then +the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methoddecl" class="ntref localref" style="color:maroon">MethodDecl</a></span></code> must not be a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">constructor</span></code> +declaration. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_methodkeyword" class="ntdef" style="color:olive">MethodKeyword</span></span> = (<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"lemma"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"colemma"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"inductive"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"lemma"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"constructor"</span></span> )</code></pre> +<p class="p noindent para-continued">The method keyword is used to specify special kinds of methods +as explained below. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_methodsignature" class="ntdef" style="color:olive">MethodSignature</span></span>(isGhost) = + [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhost: !<span class="code-escaped"><a href="#2_isghost" class="ntref localref" style="color:maroon">isGhost</a></span>) + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"returns"</span></span> <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhost: !<span class="code-escaped"><a href="#2_isghost" class="ntref localref" style="color:maroon">isGhost</a></span>) ]</code></pre> +<p class="p noindent para-continued">A method signature specifies the method generic parameters, +input parameters and return parameters. +The formal parameters are not allowed to have <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code> specified +if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code> was already specified for the method. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_signatureellipsis_" class="ntdef" style="color:olive">SignatureEllipsis_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span></code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span></code> is used when a method or function is being redeclared +in module that refines another module. In that case the signature is +copied from the module that is being refined. This works because +Dafny does not support method or function overloading, so the +name of the class method uniquely identifies it without the +signature. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_formals" class="ntdef" style="color:olive">Formals</span></span>(allowGhostKeyword) = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_gidenttype" class="ntref localref" style="color:maroon">GIdentType</a></span>(allowGhostKeyword) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_gidenttype" class="ntref localref" style="color:maroon">GIdentType</a></span>(allowGhostKeyword) } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span></code> specifies the names and types of the method input or +output parameters. +</p> +<p class="p indent">See section <a href="#sec-method-specification" title="4.1. Method Specification" class="localref" style="target-element:h2"><span class="heading-label">4.1</span></a> for a description of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methodspec" class="ntref localref" style="color:maroon">MethodSpec</a></span></code>. +</p> +<p class="p indent">A method declaration adheres to the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methoddecl" class="ntref localref" style="color:maroon">MethodDecl</a></span></code> grammar above. +Here is an example of a method declaration. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> {<span style="color:purple">:att1</span>}{<span style="color:purple">:att2</span>} M<T1, T2>(a: A, b: B, c: C) <span style="color:blue">returns</span> (x: X, y: Y, z: Z) + <span style="color:purple">requires</span> Pre + <span style="color:purple">modifies</span> Frame + <span style="color:purple">ensures</span> Post + <span style="color:purple">decreases</span> Rank +{ + Body +}</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">:att1</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">:att2</code> are attributes of the method, +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T1</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T2</code> are type parameters of the method (if generic), +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a, b, c</code> are the method’s in-parameters, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x, y, z</code> are the +method’s out-parameters, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pre</code> is a boolean expression denoting the +method’s precondition, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Frame</code> denotes a set of objects whose fields may +be updated by the method, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Post</code> is a boolean expression denoting the +method’s postcondition, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Rank</code> is the method’s variant function, and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Body</code> is a statement that implements the method. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Frame</code> can be a list +of expressions, each of which is a set of objects or a single object, the +latter standing for the singleton set consisting of that one object. The +method’s frame is the union of these sets, plus the set of objects +allocated by the method body. For example, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code> are parameters +of a class type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>, then +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:purple">modifies</span> {c, d} + +<span style="color:purple">modifies</span> {c} + {d} + +<span style="color:purple">modifies</span> c, {d} + +<span style="color:purple">modifies</span> c, d</code></pre> +<p class="p noindent para-continued">all mean the same thing. +</p> +<p class="p indent">A method can be declared as ghost by preceding the declaration with the +keyword ghost. By default, a method has an implicit receiver parameter, +this. This parameter can be removed by preceding the method declaration +with the keyword static. A static method M in a class C can be invoked by +C.M(…). +</p> +<p class="p indent">In a class, a method can be declared to be a constructor method by +replacing the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">method</span></code> with the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">constructor</span></code>. A constructor +can only be called at the time an object is allocated (see +object-creation examples below), and for a class that contains one or +more constructors, object creation must be done in conjunction with a +call to a constructor. +</p> +<p class="p indent">An ordinary method is declared with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">method</span></code> keyword. +Section <a href="#sec-constructors" title="12.1.0. Constructors" class="localref" style="target-element:h3"><span class="heading-label">12.1.0</span></a> explains methods that instead use the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">constructor</span></code> keyword. Section <a href="#sec-lemmas" title="12.1.1. Lemmas" class="localref" style="target-element:h3"><span class="heading-label">12.1.1</span></a> discusses methods that are +declared with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">lemma</span></code> keyword. Methods declared with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">inductive</span></code> +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">lemma</span></code> keywords are discussed later in the context of inductive +predicates (see <a href="#sec-inductive-datatypes" title="18.0. Inductive datatypes" class="localref" style="target-element:h2"><span class="heading-label">18.0</span></a>). Methods declared with the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">colemma</span></code> keyword are discussed later in the context of co-inductive +types, in section <a href="#sec-colemmas" title="18.2.4.1. Colemmas" class="localref" style="target-element:h4"><span class="heading-label">18.2.4.1</span></a>. +</p> +<p class="p indent">A method without is body is <em class="em-low1">abstract</em>. A method is allowed to be +abstract under the following circumstances: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">It contains an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:axiom</span>}</code> attribute +</li> +<li class="li ul-li list-star-li compact-li">It contains an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:imported</span>}</code> attribute +</li> +<li class="li ul-li list-star-li compact-li">It contains a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:decl</span>}</code> attribute +</li> +<li class="li ul-li list-star-li compact-li">It is a declaration in an abstract module. +Note that when there is no body, Dafny assumes that the <em class="em-star1">ensures</em> +clauses are true without proof. +</li></ul> +<h4 id="sec-constructors" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">12.1.0</span>. </span>Constructors</h4> +<p class="p noindent">To write structured object-oriented programs, one often relies on that +objects are constructed only in certain ways. For this purpose, Dafny +provides <em class="em-low1">constructor (method)s</em>, which are a restricted form of +initialization methods. A constructor is declared with the keyword +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">constructor</span></code> instead of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">method</span></code>. When a class contains a +constructor, every call to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> for that class must be accompanied +with a call to one of the constructors. Moreover, a constructor +cannot be called at other times, only during object creation. Other +than these restrictions, there is no semantic difference between using +ordinary initialization methods and using constructors. +</p> +<p class="p indent">The Dafny design allows the constructors to be named, which promotes +using names like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">InitFromList</code> above. Still, many classes have just +one constructor or have a typical constructor. Therefore, Dafny +allows one <em class="em-low1">anonymous constructor</em>, that is, a constructor whose name +is essentially “”. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> Item { + <span style="color:blue">constructor</span> (x: <span style="color:teal">int</span>, y: <span style="color:teal">int</span>) + <span style="color:darkgreen">// ...</span> +}</code></pre> +<p class="p noindent para-continued">When invoking this constructor, the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.</code>” is dropped, as in: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>m <span style="color:blue">:=</span> <span style="color:blue">new</span> Item(<span class="constant" style="color:purple">45</span>, <span class="constant" style="color:purple">29</span>);</code></pre> +<p class="p noindent para-continued">Note that an anonymous constructor is just one way to name a +constructor; there can be other constructors as well. +</p><h4 id="sec-lemmas" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">12.1.1</span>. </span>Lemmas</h4> +<p class="p noindent">Sometimes there are steps of logic required to prove a program correct, +but they are too complex for Dafny to discover and use on its own. When +this happens, we can often give Dafny assistance by providing a lemma. +This is done by declaring a method with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">lemma</span></code> keyword. +Lemmas are implicitly ghost methods and the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code> keyword cannot +be applied to them. +</p> +<p class="p indent">For an example, see the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FibProperty</code> lemma in +Section <a href="#sec-proofs-in-dafny" title="11.1.1. Proofs in Dafny" class="localref" style="target-element:h3"><span class="heading-label">11.1.1</span></a>. +</p> +<p class="p indent">See <a href="http://rise4fun.com/Dafny/tutorial/Lemmas">the Dafny Lemmas tutorial</a> +for more examples and hints for using lemmas. +</p><h3 id="sec-function-declarations" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">12.2</span>. </span>Function Declarations</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_functiondecl" class="ntdef" style="color:olive">FunctionDecl</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"function"</span></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> ] { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_functionname" class="ntref localref" style="color:maroon">FunctionName</a></span> + <span class="code-escaped"><a href="#1_functionsignatureorellipsis_" class="ntref localref" style="color:maroon">FunctionSignatureOrEllipsis_</a></span>(allowGhostKeyword: (<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> <span class="code-escaped"><a href="#2_present" class="ntref localref" style="color:maroon">present</a></span>)) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"predicate"</span></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> ] { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_predicatename" class="ntref localref" style="color:maroon">PredicateName</a></span> + <span class="code-escaped"><a href="#1_predicatesignatureorellipsis_" class="ntref localref" style="color:maroon">PredicateSignatureOrEllipsis_</a></span>(allowGhostKeyword: (<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"method"</span></span> <span class="code-escaped"><a href="#2_present" class="ntref localref" style="color:maroon">present</a></span>)) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"inductive"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"predicate"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_predicatename" class="ntref localref" style="color:maroon">PredicateName</a></span> + <span class="code-escaped"><a href="#1_predicatesignatureorellipsis_" class="ntref localref" style="color:maroon">PredicateSignatureOrEllipsis_</a></span>(allowGhostKeyword: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"copredicate"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span class="code-escaped"><a href="#1_copredicatename" class="ntref localref" style="color:maroon">CopredicateName</a></span> + <span class="code-escaped"><a href="#1_predicatesignatureorellipsis_" class="ntref localref" style="color:maroon">PredicateSignatureOrEllipsis_</a></span>(allowGhostKeyword: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + ) + <span class="code-escaped"><a href="#1_functionspec" class="ntref localref" style="color:maroon">FunctionSpec</a></span> [ <span class="code-escaped"><a href="#1_functionbody" class="ntref localref" style="color:maroon">FunctionBody</a></span> ] + +<span class="code-escaped"><span id="1_functionsignatureorellipsis_" class="ntdef" style="color:olive">FunctionSignatureOrEllipsis_</span></span>(allowGhostKeyword) = + <span class="code-escaped"><a href="#1_functionsignature_" class="ntref localref" style="color:maroon">FunctionSignature_</a></span> | <span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span> +<span class="code-escaped"><span id="1_functionsignature_" class="ntdef" style="color:olive">FunctionSignature_</span></span>(allowGhostKeyword) = + [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhostKeyword) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> + +<span class="code-escaped"><span id="1_predicatesignatureorellipsis_" class="ntdef" style="color:olive">PredicateSignatureOrEllipsis_</span></span>(allowGhostKeyword) = + <span class="code-escaped"><a href="#1_predicatesignature_" class="ntref localref" style="color:maroon">PredicateSignature_</a></span>(allowGhostKeyword) | <span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span> +<span class="code-escaped"><span id="1_predicatesignature_" class="ntdef" style="color:olive">PredicateSignature_</span></span>(allowGhostKeyword) = + [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhostKeyword) + +<span class="code-escaped"><span id="1_functionbody" class="ntdef" style="color:olive">FunctionBody</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<p class="p noindent para-continued">In the above productions, allowGhostKeyword is true if the optional +“method” keyword was specified. This allows some of the +formal parameters of a function method to be specified as ghost. +</p> +<p class="p indent">See section <a href="#sec-function-specification" title="4.2. Function Specification" class="localref" style="target-element:h2"><span class="heading-label">4.2</span></a> for a description of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functionspec" class="ntref localref" style="color:maroon">FunctionSpec</a></span></code>. +</p> +<p class="p indent">A Dafny function is a pure mathematical function. It is allowed to +read memory that was specified in its <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code> expression but is not +allowed to have any side effects. +</p> +<p class="p indent">Here is an example function declaration: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> {<span style="color:purple">:att1</span>}{<span style="color:purple">:att2</span>} F<T1, T2>(a: A, b: B, c: C): T + <span style="color:purple">requires</span> Pre + <span style="color:purple">reads</span> Frame + <span style="color:purple">ensures</span> Post + <span style="color:purple">decreases</span> Rank +{ + Body +}</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">:att1</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">:att2</code> are attributes of the function, if any, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T1</code> +and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T2</code> are type parameters of the function (if generic), <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a, b, c</code> are +the functions’s parameters, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is the type of the function’s result, +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pre</code> is a boolean expression denoting the function’s precondition, +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Frame</code> denotes a set of objects whose fields the function body may +depend on, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Post</code> is a boolean expression denoting the function’s +postcondition, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Rank</code> is the function’s variant function, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Body</code> is +an expression that defines the function return value. The precondition +allows a function to be partial, that is, the precondition says when the +function is defined (and Dafny will verify that every use of the function +meets the precondition). The postcondition is usually not needed, since +the body of the function gives the full definition. However, the +postcondition can be a convenient place to declare properties of the +function that may require an inductive proof to establish. For example: +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="2_function" class="ntdef" style="color:olive">function</span></span> <span class="code-escaped"><a href="#1_factorial" class="ntref localref" style="color:maroon">Factorial</a></span>(n: <span class="code-escaped"><a href="#2_int" class="ntref localref" style="color:maroon">int</a></span>): <span class="code-escaped"><a href="#2_int" class="ntref localref" style="color:maroon">int</a></span> + <span class="code-escaped"><a href="#2_requires" class="ntref localref" style="color:maroon">requires</a></span> <span class="constant" style="color:purple">0</span> <= n + <span class="code-escaped"><a href="#2_ensures" class="ntref localref" style="color:maroon">ensures</a></span> <span class="constant" style="color:purple">1</span> <= <span class="code-escaped"><a href="#1_factorial" class="ntref localref" style="color:maroon">Factorial</a></span>(n) +{ + <span class="code-escaped"><a href="#2_if" class="ntref localref" style="color:maroon">if</a></span> n == <span class="constant" style="color:purple">0</span> <span class="code-escaped"><a href="#2_then" class="ntref localref" style="color:maroon">then</a></span> <span class="constant" style="color:purple">1</span> <span class="code-escaped"><a href="#2_else" class="ntref localref" style="color:maroon">else</a></span> <span class="code-escaped"><a href="#1_factorial" class="ntref localref" style="color:maroon">Factorial</a></span>(n-<span class="constant" style="color:purple">1</span>) * n +}</code></pre> +<p class="p noindent para-continued">says that the result of Factorial is always positive, which Dafny +verifies inductively from the function body. To refer to the function’s +result in the postcondition, use the function itself, as shown in the +example. +</p> +<p class="p indent">By default, a function is <em class="em-star1">ghost</em>, and cannot be called from non-ghost +code. To make it non-ghost, replace the keyword function with the two +keywords “function method”. +</p> +<p class="p indent">By default, a function has an implicit receiver parameter, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code>. This +parameter can be removed by preceding the function declaration with the +keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code>. A static function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> in a class <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> can be invoked +by <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C.F(…)</code>. This can give a convenient way to declare a number of helper +functions in a separate class. +</p> +<p class="p indent">As for methods, a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span></code> is used when declaring +a function in a module refinement. For example, if module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M0</code> declares +function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code>, a module <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M1</code> can be declared to refine <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M0</code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M1</code> can then refine <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code>. The refinement function, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M1.F</code> can have +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_signatureellipsis_" class="ntref localref" style="color:maroon">SignatureEllipsis_</a></span></code> which means to copy the signature form +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M0.F</code>. A refinement function can furnish a body for a function +(if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M0.F</code> does not provide one). It can also add <strong class="strong-star2">ensures</strong> +clauses. And if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> is a predicate, it can add conjuncts to +a previously given body. +</p><h4 id="sec-function-transparency" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">12.2.0</span>. </span>Function Transparency</h4> +<p class="p noindent">A function is said to be <em class="em-low1">transparent</em> in a location if the +contents of the body of the function is visible at that point. +A function is said to be <em class="em-low1">opaque</em> at a location if it is not +transparent. However the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functionspec" class="ntref localref" style="color:maroon">FunctionSpec</a></span></code> of a function +is always available. +</p> +<p class="p indent">A function is usually transparent up to some unrolling level (up to +1, or maybe 2 or 3). If its arguments are all literals it is +transparent all the way. +</p> +<p class="p indent">But the transparency of a function is affected by the following: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">whether the function was declared to be protected, and +</li> +<li class="li ul-li list-star-li compact-li">whether the function was given the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code> attribute (as explained +in Section <a href="#sec-opaque" title="24.1.12. opaque" class="localref" style="target-element:h3"><span class="heading-label">24.1.12</span></a>). +</li></ul> + +<p class="p noindent">The following table summarizes where the function is transparent. +The module referenced in the table is the module in which the +function is defined. +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:center"></th><th class="thead tr-even col cell-border-left cell-line col-even" data-row="0" data-col="2" style="text-align:center"></th><th class="thead tr-even col cell-border-left cell-line col-odd" data-row="0" data-col="3" style="text-align:center"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="4" style="text-align:center"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold;text-align:center"> Protected? </th><th class="col cell-border-left thead tr-odd tr-first col-even" data-row="1" data-col="2" style="font-weight:bold;text-align:center"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code>? </th><th class="col cell-border-left thead tr-odd tr-first col-odd" data-row="1" data-col="3" style="font-weight:bold;text-align:center"> Transparent </th><th class="col cell-border-left cell-border-right thead tr-odd tr-first col-even col-last" data-row="1" data-col="4" style="font-weight:bold;text-align:center"> Transparent </th></tr> +<tr><th class="col cell-border-left thead tr-even col-odd col-first" data-row="2" data-col="1" style="font-weight:bold;text-align:center"> </th><th class="col cell-border-left thead tr-even col-even" data-row="2" data-col="2" style="font-weight:bold;text-align:center"> </th><th class="col cell-border-left thead tr-even col-odd" data-row="2" data-col="3" style="font-weight:bold;text-align:center"> Inside </th><th class="col cell-border-left cell-border-right thead tr-even col-even col-last" data-row="2" data-col="4" style="font-weight:bold;text-align:center"> Outside </th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last col-odd col-first" data-row="3" data-col="1" style="font-weight:bold;text-align:center"> </th><th class="col cell-border-left thead tr-odd tr-last col-even" data-row="3" data-col="2" style="font-weight:bold;text-align:center"> </th><th class="col cell-border-left thead tr-odd tr-last col-odd" data-row="3" data-col="3" style="font-weight:bold;text-align:center"> Module </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last col-even col-last" data-row="3" data-col="4" style="font-weight:bold;text-align:center"> Module </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1" style="text-align:center"></td><td class="tbody tr-even col cell-border-left cell-line col-even" data-row="0" data-col="2" style="text-align:center"></td><td class="tbody tr-even col cell-border-left cell-line col-odd" data-row="0" data-col="3" style="text-align:center"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="4" style="text-align:center"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1" style="text-align:center"> N </td><td class="tbody tr-odd tr-first col cell-border-left col-even" data-row="1" data-col="2" style="text-align:center"> N </td><td class="tbody tr-odd tr-first col cell-border-left col-odd" data-row="1" data-col="3" style="text-align:center"> Y </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="4" style="text-align:center"> Y </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1" style="text-align:center"> Y </td><td class="tbody tr-even col cell-border-left col-even" data-row="2" data-col="2" style="text-align:center"> N </td><td class="tbody tr-even col cell-border-left col-odd" data-row="2" data-col="3" style="text-align:center"> Y </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="4" style="text-align:center"> N </td></tr> +<tr><td class="tbody tr-odd tr-last col cell-border-left col-odd col-first" data-row="3" data-col="1" style="text-align:center"> N </td><td class="tbody tr-odd tr-last col cell-border-left col-even" data-row="3" data-col="2" style="text-align:center"> Y </td><td class="tbody tr-odd tr-last col cell-border-left col-odd" data-row="3" data-col="3" style="text-align:center"> N </td><td class="tbody tr-odd tr-last col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="4" style="text-align:center"> N </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="3" data-col="1" style="text-align:center"></td><td class="tbody tr-odd col cell-border-left cell-line col-even" data-row="3" data-col="2" style="text-align:center"></td><td class="tbody tr-odd col cell-border-left cell-line col-odd" data-row="3" data-col="3" style="text-align:center"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="3" data-col="4" style="text-align:center"></td></tr></tbody></table> +<p class="p noindent">When <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code> is specified for function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g</code> is opaque, +however the lemma <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">reveal_g</code> is available to give the semantics +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">g</code> whether in the defining module or outside. +</p> +<p class="p indent">It currently is not allowed to have both <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">protected</span></code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code> specified for a function. +</p><h4 id="sec-predicates" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">12.2.1</span>. </span>Predicates</h4> +<p class="p noindent">A function that returns a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code> results is called a <em class="em-low1">predicate</em>. As an +alternative syntax, a predicate can be declared by replacing the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">function</span></code> +keyword with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">predicate</span></code> keyword and omitting a declaration of the +return type. +</p><h4 id="sec-inductive-predicates-and-lemmas" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">12.2.2</span>. </span>Inductive Predicates and Lemmas</h4> +<p class="p noindent">See section <a href="#sec-friendliness" title="11.1.2. Extreme Predicates in Dafny" class="localref" style="target-element:h3"><span class="heading-label">11.1.2</span></a> for descriptions +of inductive predicates and lemmas. +</p><h2 id="sec-trait-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">13</span>. </span>Trait Types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_traitdecl" class="ntdef" style="color:olive">TraitDecl</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"trait"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_traitname" class="ntref localref" style="color:maroon">TraitName</a></span> [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { { <span class="code-escaped"><a href="#1_declmodifier" class="ntref localref" style="color:maroon">DeclModifier</a></span> } <span class="code-escaped"><a href="#1_classmemberdecl" class="ntref localref" style="color:maroon">ClassMemberDecl</a></span>(moduleLevelDecl: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<p class="p noindent para-continued">A <em class="em-low1">trait</em> is an “abstract superclass”, or call it an “interface” or +“mixin”. Traits are new to Dafny and are likely to evolve for a +while. +</p> +<p class="p indent">The declaration of a trait is much like that of a class: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">trait</span> J +{ + <span class="code-escaped"><em class="em-low1">members</em></span> +}</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">members</em></span></code> can include fields, functions, and methods, but +no constructor methods. The functions and methods are allowed to be +declared <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code>. +</p> +<p class="p indent">A reference type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> that extends a trait <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code> is assignable to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code>, but +not the other way around. The members of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code> are available as members +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>. A member in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code> is not allowed to be redeclared in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>, +except if the member is a non-<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">static</span></code> function or method without a +body in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code>. By doing so, type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> can supply a stronger +specification and a body for the member. +</p> +<p class="p indent"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> is not allowed to be used with traits. Therefore, there is no +object whose allocated type is a trait. But there can of course be +objects of a class <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> that implements a trait <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code>, and a reference to +such a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> object can be used as a value of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">J</code>. +</p> +<p class="p indent">As an example, the following trait represents movable geometric shapes: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">trait</span> Shape +{ + <span style="color:blue">function</span> <span style="color:blue">method</span> Width(): <span style="color:teal">real</span> + <span style="color:purple">reads</span> <span style="color:blue">this</span> + <span style="color:blue">method</span> Move(dx: <span style="color:teal">real</span>, dy: <span style="color:teal">real</span>) + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + <span style="color:blue">method</span> MoveH(dx: <span style="color:teal">real</span>) + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + Move(dx, <span class="constant" style="color:purple">0.0</span>); + } +}</code></pre> +<p class="p noindent para-continued">Members <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Width</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Move</code> are <em class="em-low1">abstract</em> (that is, body less) and can +be implemented differently by different classes that extend the trait. +The implementation of method <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveH</code> is given in the trait and thus +gets used by all classes that extend <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Shape</code>. Here are two classes +that each extends <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Shape</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> UnitSquare <span style="color:blue">extends</span> Shape +{ + <span style="color:blue">var</span> x: <span style="color:teal">real</span>, y: <span style="color:teal">real</span> + <span style="color:blue">function</span> <span style="color:blue">method</span> Width(): <span style="color:teal">real</span> { <span style="color:darkgreen">// note the empty reads clause</span> + <span class="constant" style="color:purple">1.0</span> + } + <span style="color:blue">method</span> Move(dx: <span style="color:teal">real</span>, dy: <span style="color:teal">real</span>) + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + x, y <span style="color:blue">:=</span> x + dx, y + dy; + } +} +<span style="color:blue">class</span> LowerRightTriangle <span style="color:blue">extends</span> Shape +{ + <span style="color:blue">var</span> xNW: <span style="color:teal">real</span>, yNW: <span style="color:teal">real</span>, xSE: <span style="color:teal">real</span>, ySE: <span style="color:teal">real</span> + <span style="color:blue">function</span> <span style="color:blue">method</span> Width(): <span style="color:teal">real</span> + <span style="color:purple">reads</span> <span style="color:blue">this</span> + { + xSE - xNW + } + <span style="color:blue">method</span> Move(dx: <span style="color:teal">real</span>, dy: <span style="color:teal">real</span>) + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + xNW, yNW, xSE, ySE <span style="color:blue">:=</span> xNW + dx, yNW + dy, xSE + dx, ySE + dy; + } +}</code></pre> +<p class="p noindent para-continued">Note that the classes can declare additional members, that they supply +implementations for the abstract members of the trait, +that they repeat the member signatures, and that they are responsible +for providing their own member specifications that both strengthen the +corresponding specification in the trait and are satisfied by the +provided body. +Finally, here is some code that creates two class instances and uses +them together as shapes: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> myShapes: <span style="color:teal">seq</span><Shape>; +<span style="color:blue">var</span> A <span style="color:blue">:=</span> <span style="color:blue">new</span> UnitSquare; +myShapes <span style="color:blue">:=</span> [A]; +<span style="color:blue">var</span> tri <span style="color:blue">:=</span> <span style="color:blue">new</span> LowerRightTriangle; +<span style="color:darkgreen">// myShapes contains two Shape values, of different classes</span> +myShapes <span style="color:blue">:=</span> myShapes + [tri]; +<span style="color:darkgreen">// move shape 1 to the right by the width of shape 0</span> +myShapes[<span class="constant" style="color:purple">1</span>].MoveH(myShapes[<span class="constant" style="color:purple">0</span>].Width());</code></pre><h2 id="sec-array-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">14</span>. </span>Array Types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_arraytype_" class="ntdef" style="color:olive">ArrayType_</span></span> = <span class="code-escaped"><a href="#2_arraytoken" class="ntref localref" style="color:maroon">arrayToken</a></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] </code></pre> +<p class="p noindent para-continued">Dafny supports mutable fixed-length <em class="em-low1">array types</em> of any positive +dimension. Array types are reference types. +</p><h3 id="sec-one-dimensional-arrays" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">14.0</span>. </span>One-dimensional arrays</h3> +<p class="p noindent">A one-dimensional array of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> elements is created as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a <span style="color:blue">:=</span> <span style="color:blue">new</span> T[n];</code></pre> +<p class="p noindent para-continued">The initial values of the array elements are arbitrary values of type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>. +The length of an array is retrieved using the immutable <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length</code> +member. For example, the array allocated above satisfies: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a.Length == n</code></pre> +<p class="p noindent para-continued">For any integer-based numeric <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> in the range <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= i < a.Length</code>, +the <em class="em-low1">array selection</em> expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[i]</code> retrieves element <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> (that +is, the element preceded by <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> elements in the array). The +element stored at <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> can be changed to a value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> using the array +update statement: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a[i] <span style="color:blue">:=</span> t;</code></pre> +<p class="p noindent para-continued">Caveat: The type of the array created by <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span> T[n]</code> is +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>. A mistake that is simple to make and that can lead to +befuddlement is to write <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code> instead of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> after <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code>. +For example, consider the following: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> a <span style="color:blue">:=</span> <span style="color:blue">new</span> <span style="color:teal">array</span><T>; +<span style="color:blue">var</span> b <span style="color:blue">:=</span> <span style="color:blue">new</span> <span style="color:teal">array</span><T>[n]; +<span style="color:blue">var</span> c <span style="color:blue">:=</span> <span style="color:blue">new</span> <span style="color:teal">array</span><T>(n); <span style="color:darkgreen">// resolution error</span> +<span style="color:blue">var</span> d <span style="color:blue">:=</span> <span style="color:blue">new</span> <span style="color:teal">array</span>(n); <span style="color:darkgreen">// resolution error</span></code></pre> +<p class="p noindent para-continued">The first statement allocates an array of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>, but of +unknown length. The second allocates an array of type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><<span style="color:teal">array</span><T>></code> of length <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>, that is, an array that holds <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> +values of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>. The third statement allocates an +array of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code> and then attempts to invoke an anonymous +constructor on this array, passing argument <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>. Since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span></code> has no +constructors, let alone an anonymous constructor, this statement +gives rise to an error. If the type-parameter list is omitted for a +type that expects type parameters, Dafny will attempt to fill these +in, so as long as the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span></code> type parameter can be inferred, it is +okay to leave off the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><T></code>” in the fourth statement above. However, +as with the third statement, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span></code> has no anonymous constructor, so +an error message is generated. +</p> +<p class="p indent">One-dimensional arrays support operations that convert a stretch of +consecutive elements into a sequence. For any array <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> of type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>, integer-based numerics <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> satisfying +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= lo <= hi <= a.Length</code>, the following operations each yields a +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><T></code>: +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> expression </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[lo..hi]</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> subarray conversion to sequence </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[lo..]</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> drop </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[..hi]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> take </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[..]</code> </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> array conversion to sequence </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr></tbody></table> +<p class="p noindent">The expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[lo..hi]</code> takes the first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> elements of the array, +then drops the first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> elements thereof and returns what remains as +a sequence. The resulting sequence thus has length <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi - lo</code>. +The other operations are special instances of the first. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> is +omitted, it defaults to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span></code> and if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> is omitted, it defaults to +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a.Length</code>. +In the last operation, both <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> have been omitted, thus +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a[..]</code> returns the sequence consisting of all the array elements of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code>. +</p> +<p class="p indent">The subarray operations are especially useful in specifications. For +example, the loop invariant of a binary search algorithm that uses +variables <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> to delimit the subarray where the search <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">key</code> +may be still found can be expressed as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>key !<span style="color:blue">in</span> a[..lo] && key !<span style="color:blue">in</span> a[hi..]</code></pre> +<p class="p noindent para-continued">Another use is to say that a certain range of array elements have not +been changed since the beginning of a method: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>a[lo..hi] == <span style="color:blue">old</span>(a[lo..hi])</code></pre> +<p class="p noindent para-continued">or since the beginning of a loop: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">var</span> prevElements <span style="color:blue">:=</span> a[..]; +<span style="color:blue">while</span> <span style="color:darkgreen">// ...</span> + <span style="color:purple">invariant</span> a[lo..hi] == prevElements[lo..hi] +{ + <span style="color:darkgreen">// ...</span> +}</code></pre> +<p class="p noindent para-continued">Note that the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">prevElements</code> in this example is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">seq</span><T></code>, if +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>. +</p> +<p class="p indent">A final example of the subarray operation lies in expressing that an +array's elements are a permutation of the array's elements at the +beginning of a method, as would be done in most sorting algorithms. +Here, the subarray operation is combined with the sequence-to-multiset +conversion: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">multiset</span>(a[..]) == <span style="color:teal">multiset</span>(<span style="color:blue">old</span>(a[..]))</code></pre><h3 id="sec-multi-dimensional-arrays" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">14.1</span>. </span>Multi-dimensional arrays</h3> +<p class="p noindent">An array of 2 or more dimensions is mostly like a one-dimensional +array, except that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> takes more length arguments (one for each +dimension), and the array selection expression and the array update +statement take more indices. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>matrix <span style="color:blue">:=</span> <span style="color:blue">new</span> T[m, n]; +matrix[i, j], matrix[x, y] <span style="color:blue">:=</span> matrix[x, y], matrix[i, j];</code></pre> +<p class="p noindent para-continued">create a 2-dimensional array whose dimensions have lengths <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code>, respectively, and then swaps the elements at <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i,j</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x,y</code>. +The type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">matrix</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array2</span><T></code>, and similarly for +higher-dimensional arrays (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array3</span><T></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array4</span><T></code>, etc.). Note, +however, that there is no type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">array0<T></code>, and what could have been +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">array1<T></code> is actually named just <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">array</span><T></code>. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> operation above requires <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> to be non-negative +integer-based numerics. These lengths can be retrieved using the +immutable fields <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length0</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length1</code>. For example, the following +holds of the array created above: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>matrix.Length0 == m && matrix.Length1 == n</code></pre> +<p class="p noindent para-continued">Higher-dimensional arrays are similar (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length0</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length1</code>, +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Length2</code>, …). The array selection expression and array update +statement require that the indices are in bounds. For example, the +swap statement above is well-formed only if: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="constant" style="color:purple">0</span> <= i < matrix.Length0 && <span class="constant" style="color:purple">0</span> <= j < matrix.Length1 && +<span class="constant" style="color:purple">0</span> <= x < matrix.Length0 && <span class="constant" style="color:purple">0</span> <= y < matrix.Length1</code></pre> +<p class="p noindent para-continued">In contrast to one-dimensional arrays, there is no operation to +convert stretches of elements from a multi-dimensional array to a +sequence. +</p><h2 id="sec-type-object" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">15</span>. </span>Type object</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_objecttype_" class="ntdef" style="color:olive">ObjectType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"object"</span></span></code></pre> +<p class="p noindent para-continued">There is a built-in trait <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">object</span></code> that is like a supertype of all +reference types.<sup id="back-fn-fn-object-trait" ><a href="#fn-fn-object-trait" title="6.The current compiler restriction that object cannot +be used as a type parameter needs to be removed. +↩" class="footnote-ref localref" ><span class="footnote-label">6</span></a></sup> Every class automatically extends +object and so does every user-defined trait. The purpose of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">object</span></code> +is to enable a uniform treatment of <em class="em-low1">dynamic frames</em>. In particular, it +is useful to keep a ghost field (typically named <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Repr</code> for +“representation”) of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span><<span style="color:teal">object</span>></code>. +</p><h2 id="sec-iterator-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">16</span>. </span>Iterator types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_iteratordecl" class="ntdef" style="color:olive">IteratorDecl</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iterator"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_iteratorname" class="ntref localref" style="color:maroon">IteratorName</a></span> + ( [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhostKeyword: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yields"</span></span> <span class="code-escaped"><a href="#1_formals" class="ntref localref" style="color:maroon">Formals</a></span>(allowGhostKeyword: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ] + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + ) + <span class="code-escaped"><a href="#1_iteratorspec" class="ntref localref" style="color:maroon">IteratorSpec</a></span> [ <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> ] </code></pre> +<p class="p noindent para-continued">See section <a href="#sec-iterator-specification" title="4.4. Iterator Specification" class="localref" style="target-element:h2"><span class="heading-label">4.4</span></a> for a description of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_iteratorspec" class="ntref localref" style="color:maroon">IteratorSpec</a></span></code>. +</p> +<p class="p indent">An <em class="em-low1">iterator</em> provides a programming abstraction for writing code that +iteratively returns elements. These CLU-style iterators are +<em class="em-low1">co-routines</em> in the sense that they keep track of their own program +counter and control can be transferred into and out of the iterator +body. +</p> +<p class="p indent">An iterator is declared as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">iterator</span> Iter<T>(<span class="code-escaped"><em class="em-low1">in-params</em></span>) <span style="color:blue">yields</span> (<span class="code-escaped"><em class="em-low1">yield-params</em></span>) + <span class="code-escaped"><em class="em-low1">specification</em></span> +{ + <span class="code-escaped"><em class="em-low1">body</em></span> +}</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is a list of type parameters (as usual, if there are no type +parameters, “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><T></code>” is omitted). This declaration gives rise to a +reference type with the same name, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Iter<T></code>. In the signature, +in-parameters and yield-parameters are the iterator's analog of a +method's in-parameters and out-parameters. The difference is that the +out-parameters of a method are returned to a caller just once, whereas +the yield-parameters of an iterator are returned each time the iterator +body performs a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">yield</span></code>. The body consists of statements, like in a +method body, but with the availability also of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">yield</span></code> statements. +</p> +<p class="p indent">From the perspective of an iterator client, the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">iterator</span></code> declaration +can be understood as generating a class <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Iter<T></code> with various +members, a simplified version of which is described next. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Iter<T></code> class contains an anonymous constructor whose parameters +are the iterator's in-parameters: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">predicate</span> Valid() +<span style="color:blue">constructor</span> (<span class="code-escaped"><em class="em-low1">in-params</em></span>) + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + <span style="color:purple">ensures</span> Valid()</code></pre> +<p class="p noindent para-continued">An iterator is created using <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">new</span></code> and this anonymous constructor. +For example, an iterator willing to return ten consecutive integers +from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">start</code> can be declared as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">iterator</span> Gen(start: <span style="color:teal">int</span>) <span style="color:blue">yields</span> (x: <span style="color:teal">int</span>) +{ + <span style="color:blue">var</span> i <span style="color:blue">:=</span> <span class="constant" style="color:purple">0</span>; + <span style="color:blue">while</span> i < <span class="constant" style="color:purple">10</span> { + x <span style="color:blue">:=</span> start + i; + <span style="color:blue">yield</span>; + i <span style="color:blue">:=</span> i + <span class="constant" style="color:purple">1</span>; + } +}</code></pre> +<p class="p noindent para-continued">An instance of this iterator is created using: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>iter <span style="color:blue">:=</span> <span style="color:blue">new</span> Gen(<span class="constant" style="color:purple">30</span>);</code></pre> +<p class="p noindent para-continued">The predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Valid()</code> says when the iterator is in a state where one +can attempt to compute more elements. It is a postcondition of the +constructor and occurs in the specification of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> member: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">method</span> MoveNext() <span style="color:blue">returns</span> (more: <span style="color:teal">bool</span>) + <span style="color:purple">requires</span> Valid() + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + <span style="color:purple">ensures</span> more ==> Valid()</code></pre> +<p class="p noindent para-continued">Note that the iterator remains valid as long as <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> returns +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>. Once <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> returns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code>, the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> method can no +longer be called. Note, the client is under no obligation to keep +calling <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> until it returns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code>, and the body of the +iterator is allowed to keep returning elements forever. +</p> +<p class="p indent">The in-parameters of the iterator are stored in immutable fields of +the iterator class. To illustrate in terms of the example above, the +iterator class <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Gen</code> contains the following field: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> start: <span style="color:teal">int</span></code></pre> +<p class="p noindent para-continued">The yield-parameters also result in members of the iterator class: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> x: <span style="color:teal">int</span></code></pre> +<p class="p noindent para-continued">These fields are set by the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> method. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code> returns +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>, the latest yield values are available in these fields and the +client can read them from there. +</p> +<p class="p indent">To aid in writing specifications, the iterator class also contains +ghost members that keep the history of values returned by +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code>. The names of these ghost fields follow the names of the +yield-parameters with an “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>” appended to the name (to suggest +plural). Name checking rules make sure these names do not give rise +to ambiguities. The iterator class for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Gen</code> above thus contains: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">var</span> xs: <span style="color:teal">seq</span><<span style="color:teal">int</span>></code></pre> +<p class="p noindent para-continued">These history fields are changed automatically by <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">MoveNext</code>, but are +not assignable by user code. +</p> +<p class="p indent">Finally, the iterator class contains some special fields for use in +specifications. In particular, the iterator specification gets +recorded in the following immutable fields: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">var</span> _reads: <span style="color:teal">set</span><<span style="color:teal">object</span>> +<span style="color:blue">ghost</span> <span style="color:blue">var</span> _modifies: <span style="color:teal">set</span><<span style="color:teal">object</span>> +<span style="color:blue">ghost</span> <span style="color:blue">var</span> _decreases0: T0 +<span style="color:blue">ghost</span> <span style="color:blue">var</span> _decreases1: T1 +<span style="color:darkgreen">// ...</span></code></pre> +<p class="p noindent para-continued">where there is a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_decreases<span class="code-escaped"><em class="em-low1">i</em></span>: T<span class="code-escaped"><em class="em-low1">i</em></span></code> field for each +component of the iterator's <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> +clause.<sup id="back-fn-fn-iterator-field-names" ><a href="#fn-fn-iterator-field-names" title="7.It would make sense to rename the special +fields _reads and _modifies to have the same names as the +corresponding keywords, reads and modifies, as is done for +function values. Also, the various _decreasesi fields can +combined into one field named decreases whose type is a +n-tuple. Thse changes may be incorporated into a future version +of Dafny. + +…" class="footnote-ref localref" ><span class="footnote-label">7</span></a></sup> +In addition, there is a field: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">var</span> _new: <span style="color:teal">set</span><<span style="color:teal">object</span>>;</code></pre> +<p class="p noindent para-continued">to which any objects allocated on behalf of the iterator body get +added. The iterator body is allowed to remove elements from the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_new</code> set, but cannot by assignment to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_new</code> add any elements. +</p> +<p class="p indent">Note, in the precondition of the iterator, which is to hold upon +construction of the iterator, the in-parameters are indeed +in-parameters, not fields of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">this</span></code>. +</p> +<p class="p indent">It's regrettably tricky to use iterators. The language really +ought to have a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">foreach</code> statement to make this easier. +Here is an example showing definition and use of an iterator. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">iterator</span> Iter<T>(s: <span style="color:teal">set</span><T>) <span style="color:blue">yields</span> (x: T) + <span style="color:blue">yield</span> <span style="color:purple">ensures</span> x <span style="color:blue">in</span> s && x !<span style="color:blue">in</span> xs[..|xs|-<span class="constant" style="color:purple">1</span>]; + <span style="color:purple">ensures</span> s == <span style="color:teal">set</span> z | z <span style="color:blue">in</span> xs; +{ + <span style="color:blue">var</span> r <span style="color:blue">:=</span> s; + <span style="color:blue">while</span> (r != {}) + <span style="color:purple">invariant</span> <span style="color:blue">forall</span> z :: z <span style="color:blue">in</span> xs ==> x !<span style="color:blue">in</span> r; <span style="color:darkgreen">// r and xs are disjoint</span> + <span style="color:purple">invariant</span> s == r + <span style="color:teal">set</span> z | z <span style="color:blue">in</span> xs; + { + <span style="color:blue">var</span> y <span style="color:blue">:|</span> y <span style="color:blue">in</span> r; + r, x <span style="color:blue">:=</span> r - {y}, y; + <span style="color:blue">yield</span>; + <span style="color:blue">assert</span> y == xs[|xs|-<span class="constant" style="color:purple">1</span>]; <span style="color:darkgreen">// needed as a lemma to prove loop invariant</span> + } +} + +<span style="color:blue">method</span> UseIterToCopy<T>(s: <span style="color:teal">set</span><T>) <span style="color:blue">returns</span> (t: <span style="color:teal">set</span><T>) + <span style="color:purple">ensures</span> s == t; +{ + t <span style="color:blue">:=</span> {}; + <span style="color:blue">var</span> m <span style="color:blue">:=</span> <span style="color:blue">new</span> Iter(s); + <span style="color:blue">while</span> (<span style="color:blue">true</span>) + <span style="color:purple">invariant</span> m.Valid() && <span style="color:blue">fresh</span>(m._new); + <span style="color:purple">invariant</span> t == <span style="color:teal">set</span> z | z <span style="color:blue">in</span> m.xs; + <span style="color:purple">decreases</span> s - t; + { + <span style="color:blue">var</span> more <span style="color:blue">:=</span> m.MoveNext(); + <span style="color:blue">if</span> (!more) { <span style="color:blue">break</span>; } + t <span style="color:blue">:=</span> t + {m.x}; + } +}</code></pre><!-- +# Async-task types + +Another experimental feature in Dafny that is likely to undergo some +evolution is _asynchronous methods_. When an asynchronous method is +called, it does not return values for the out-parameters, but instead +returns an instance of an _async-task type_. An asynchronous method +declared in a class `C` with the following signature: +``` +async method AM<T>(\(_in-params_\)) returns (\(_out-params_\)) +``` +also gives rise to an async-task type `AM<T>` (outside the enclosing +class, the name of the type needs the qualification `C.AM<T>`). The +async-task type is a reference type and can be understood as a class +with various members, a simplified version of which is described next. + +Each in-parameter `x` of type `X` of the asynchronous method gives +rise to a immutable ghost field of the async-task type: +``` +ghost var x: X; +``` +Each out-parameter `y` of type `Y` gives rise to a field +``` +var y: Y; +``` +These fields are changed automatically by the time the asynchronous +method is successfully awaited, but are not assignable by user code. + +The async-task type also gets a number of special fields that are used +to keep track of dependencies, outstanding tasks, newly allocated +objects, etc. These fields will be described in more detail as the +design of asynchronous methods evolves. + +--> + + +<h2 id="sec-function-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">17</span>. </span>Function types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_type" class="ntdef" style="color:olive">Type</span></span> = <span class="code-escaped"><a href="#1_domaintype" class="ntref localref" style="color:maroon">DomainType</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"->"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> </code></pre> +<p class="p noindent para-continued">Functions are first-class values in Dafny. Function types have the form +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(T) -> U</code> where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is a comma-delimited list of types and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code> is a +type. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is called the function's <em class="em-low1">domain type(s)</em> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code> is its +<em class="em-low1">range type</em>. For example, the type of a function +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> F(x: <span style="color:teal">int</span>, b: <span style="color:teal">bool</span>): <span style="color:teal">real</span></code></pre> +<p class="p noindent para-continued">is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(<span style="color:teal">int</span>, <span style="color:teal">bool</span>) -> <span style="color:teal">real</span></code>. Parameters are not allowed to be ghost. +</p> +<p class="p indent">To simplify the appearance of the basic case where a function's +domain consist of a list of exactly one type, the parentheses around +the domain type can be dropped in this case, as in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T -> U</code>. +This innocent simplification requires additional explanation in the +case where that one type is a tuple type, since tuple types are also +written with enclosing parentheses. +If the function takes a single argument that is a tuple, an additional +set of parentheses is needed. For example, the function +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> G(pair: (<span style="color:teal">int</span>, <span style="color:teal">bool</span>)): <span style="color:teal">real</span></code></pre> +<p class="p noindent para-continued">has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">((<span style="color:teal">int</span>, <span style="color:teal">bool</span>)) -> <span style="color:teal">real</span></code>. Note the necessary double +parentheses. Similarly, a function that takes no arguments is +different from one that takes a 0-tuple as an argument. For instance, +the functions +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> NoArgs(): <span style="color:teal">real</span> +<span style="color:blue">function</span> Z(unit: ()): <span style="color:teal">real</span></code></pre> +<p class="p noindent para-continued">have types <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">() -> <span style="color:teal">real</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(()) -> <span style="color:teal">real</span></code>, respectively. +</p> +<p class="p indent">The function arrow, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-></code>, is right associative, so <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A -> B -> C</code> means +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">A -> (B -> C)</code>. The other association requires explicit parentheses: +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(A -> B) -> C</code>. +</p> +<p class="p indent">Note that the receiver parameter of a named function is not part of +the type. Rather, it is used when looking up the function and can +then be thought of as being captured into the function definition. +For example, suppose function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> above is declared in a class <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> and +that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code> references an object of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>; then, the following is type +correct: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> f: (<span style="color:teal">int</span>, <span style="color:teal">bool</span>) -> <span style="color:teal">real</span> <span style="color:blue">:=</span> c.F;</code></pre> +<p class="p noindent para-continued">whereas it would have been incorrect to have written something like: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> f': (C, <span style="color:teal">int</span>, <span style="color:teal">bool</span>) -> <span style="color:teal">real</span> <span style="color:blue">:=</span> F; <span style="color:darkgreen">// not correct</span></code></pre> +<p class="p noindent para-continued">Outside its type signature, each function value has three properties, +described next. +</p> +<p class="p indent">Every function implicitly takes the heap as an argument. No function +ever depends on the <em class="em-low1">entire</em> heap, however. A property of the +function is its declared upper bound on the set of heap locations it +depends on for a given input. This lets the verifier figure out that +certain heap modifications have no effect on the value returned by a +certain function. For a function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f: T -> U</code> and a value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> of type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, the dependency set is denoted <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">reads</span>(t)</code> and has type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">set</span><<span style="color:teal">object</span>></code>. +</p> +<p class="p indent">The second property of functions stems from the fact that every function +is potentially <em class="em-low1">partial</em>. In other words, a property of a function is its +<em class="em-low1">precondition</em>. For a function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f: T -> U</code>, the precondition of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> for a +parameter value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is denoted <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">requires</span>(t)</code> and has type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">bool</span></code>. +</p> +<p class="p indent">The third property of a function is more obvious—the function's +body. For a function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f: T -> U</code>, the value that the function yields +for an input <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> is denoted <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f(t)</code> and has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">U</code>. +</p> +<p class="p indent">Note that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">reads</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">requires</span></code> are themselves functions. +Suppose <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T -> U</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>. Then, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">reads</span></code> +is a function of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T -> <span style="color:teal">set</span><<span style="color:teal">object</span>></code> whose <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> +properties are: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>f.<span style="color:purple">reads</span>.<span style="color:purple">reads</span>(t) == f.<span style="color:purple">reads</span>(t) +f.<span style="color:purple">reads</span>.<span style="color:purple">requires</span>(t) == <span style="color:blue">true</span></code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f.<span style="color:purple">requires</span></code> is a function of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T -> <span style="color:teal">bool</span></code> whose <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> properties are: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>f.<span style="color:purple">requires</span>.<span style="color:purple">reads</span>(t) == f.<span style="color:purple">reads</span>(t) +f.<span style="color:purple">requires</span>.<span style="color:purple">requires</span>(t) == <span style="color:blue">true</span></code></pre> +<p class="p noindent para-continued">Dafny also support anonymous functions by means of +<em class="em-low1">lambda expressions</em>. See section <a href="#sec-lambda-expressions" title="22.9. Lambda expressions" class="localref" style="target-element:h2"><span class="heading-label">22.9</span></a>. +</p><h2 id="sec-algebraic-datatypes" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">18</span>. </span>Algebraic Datatypes</h2> +<p class="p noindent">Dafny offers two kinds of algebraic datatypes, those defined +inductively and those defined co-inductively. The salient property of +every datatype is that each value of the type uniquely identifies one +of the datatype's constructors and each constructor is injective in +its parameters. +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_datatypedecl" class="ntdef" style="color:olive">DatatypeDecl</span></span> = ( <span class="code-escaped"><a href="#1_inductivedatatypedecl" class="ntref localref" style="color:maroon">InductiveDatatypeDecl</a></span> | <span class="code-escaped"><a href="#1_coinductivedatatypedecl" class="ntref localref" style="color:maroon">CoinductiveDatatypeDecl</a></span> ) </code></pre><h3 id="sec-inductive-datatypes" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">18.0</span>. </span>Inductive datatypes</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_inductivedatatypedecl_" class="ntdef" style="color:olive">InductiveDatatypeDecl_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"datatype"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_datatypename" class="ntref localref" style="color:maroon">DatatypeName</a></span> [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"="</span></span> <span class="code-escaped"><a href="#1_datatypememberdecl" class="ntref localref" style="color:maroon">DatatypeMemberDecl</a></span> { <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_datatypememberdecl" class="ntref localref" style="color:maroon">DatatypeMemberDecl</a></span> } [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> ] +<span class="code-escaped"><span id="1_datatypememberdecl" class="ntdef" style="color:olive">DatatypeMemberDecl</span></span> = { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_datatypemembername" class="ntref localref" style="color:maroon">DatatypeMemberName</a></span> [ <span class="code-escaped"><a href="#1_formalsoptionalids" class="ntref localref" style="color:maroon">FormalsOptionalIds</a></span> ] </code></pre> +<p class="p noindent para-continued">The values of inductive datatypes can be seen as finite trees where +the leaves are values of basic types, numeric types, reference types, +co-inductive datatypes, or function types. Indeed, values of +inductive datatypes can be compared using Dafny's well-founded +<span class="monospace"><</span> ordering. +</p> +<p class="p indent">An inductive datatype is declared as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> D<T> = <span class="code-escaped"><em class="em-low1">Ctors</em></span></code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">Ctors</em></span></code> is a nonempty <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|</code>-separated list of +<em class="em-low1">(datatype) constructors</em> for the datatype. Each constructor has the +form: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>C(<span class="code-escaped"><em class="em-low1">params</em></span>)</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">params</em></span></code> is a comma-delimited list of types, optionally +preceded by a name for the parameter and a colon, and optionally +preceded by the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">ghost</span></code>. If a constructor has no parameters, +the parentheses after the constructor name can be omitted. If no +constructor takes a parameter, the type is usually called an +<em class="em-low1">enumeration</em>; for example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Friends = Agnes | Agatha | Jermaine | Jack</code></pre> +<p class="p noindent para-continued">For every constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>, Dafny defines a <em class="em-low1">discriminator</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C?</code>, which +is a member that returns <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> if and only if the datatype value has +been constructed using <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>. For every named parameter <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">p</code> of a +constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code>, Dafny defines a <em class="em-low1">destructor</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">p</code>, which is a member +that returns the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">p</code> parameter from the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> call used to construct the +datatype value; its use requires that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C?</code> holds. For example, for +the standard <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">List</code> type +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> List<T> = Nil | Cons(head: T, tail: List<T>)</code></pre> +<p class="p noindent para-continued">the following holds: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>Cons(<span class="constant" style="color:purple">5</span>, Nil).Cons? && Cons(<span class="constant" style="color:purple">5</span>, Nil).head == <span class="constant" style="color:purple">5</span></code></pre> +<p class="p noindent para-continued">Note that the expression +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>Cons(<span class="constant" style="color:purple">5</span>, Nil).tail.head</code></pre> +<p class="p noindent para-continued">is not well-formed, since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Cons(<span class="constant" style="color:purple">5</span>, Nil).tail</code> does not satisfy +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Cons?</code>. +</p> +<p class="p indent">The names of the destructors must be unique across all the +constructors of the datatype. A constructor can have the same name as +the enclosing datatype; this is especially useful for +single-constructor datatypes, which are often called +<em class="em-low1">record types</em>. For example, a record type for black-and-white pixels +might be represented as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Pixel = Pixel(x: <span style="color:teal">int</span>, y: <span style="color:teal">int</span>, on: <span style="color:teal">bool</span>)</code></pre> +<p class="p noindent para-continued">To call a constructor, it is usually necessary only to mention the +name of the constructor, but if this is ambiguous, it is always +possible to qualify the name of constructor by the name of the +datatype. For example, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Cons(<span class="constant" style="color:purple">5</span>, Nil)</code> above can be written +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>List.Cons(<span class="constant" style="color:purple">5</span>, List.Nil)</code></pre> +<p class="p noindent para-continued">As an alternative to calling a datatype constructor explicitly, a +datatype value can be constructed as a change in one parameter from a +given datatype value using the <em class="em-low1">datatype update</em> expression. For any +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code> whose type is a datatype that includes a constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> that has +a parameter (destructor) named <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, and any expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code> +of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code>, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>d[f <span style="color:blue">:=</span> t]</code></pre> +<p class="p noindent para-continued">constructs a value like <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code> but whose <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> parameter is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t</code>. The +operation requires that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">d</code> satisfies <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C?</code>. For example, the +following equality holds: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>Cons(<span class="constant" style="color:purple">4</span>, Nil)[tail <span style="color:blue">:=</span> Cons(<span class="constant" style="color:purple">3</span>, Nil)] == Cons(<span class="constant" style="color:purple">4</span>, Cons(<span class="constant" style="color:purple">3</span>, Nil))</code></pre> +<p class="p noindent para-continued">The datatype update expression also accepts multiple field +names, provided these are distinct. For example, a node of some +inductive datatype for trees may be updated as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>node[left <span style="color:blue">:=</span> L, right <span style="color:blue">:=</span> R]</code></pre><h3 id="sec-tuple-types" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">18.1</span>. </span>Tuple types</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_tupletype_" class="ntdef" style="color:olive">TupleType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">Dafny builds in record types that correspond to tuples and gives these +a convenient special syntax, namely parentheses. For example, what +might have been declared as: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Pair<T,U> = Pair(<span class="constant" style="color:purple">0</span>: T, <span class="constant" style="color:purple">1</span>: U)</code></pre> +<p class="p noindent para-continued">Dafny provides as the type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(T, U)</code> and the constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(t, u)</code>, as +if the datatype's name were “” and its type arguments are given in +round parentheses, and as if the constructor name were “”. Note that +the destructor names are <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">1</span></code>, which are legal identifier names +for members. For example, showing the use of a tuple destructor, here +is a property that holds of 2-tuples (that is, <em class="em-low1">pairs</em>): +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>(<span class="constant" style="color:purple">5</span>, <span style="color:blue">true</span>).<span class="constant" style="color:purple">1</span> == <span style="color:blue">true</span></code></pre> +<p class="p noindent para-continued">Dafny declares <em class="em-low1">n</em>-tuples where <em class="em-low1">n</em> is 0 or 2 or up. There are no +1-tuples, since parentheses around a single type or a single value have +no semantic meaning. The 0-tuple type, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">()</code>, is often known as the +<em class="em-low1">unit type</em> and its single value, also written <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">()</code>, is known as <em class="em-low1">unit</em>. +</p><h3 id="sec-co-inductive-datatypes" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">18.2</span>. </span>Co-inductive datatypes</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_coinductivedatatypedecl_" class="ntdef" style="color:olive">CoinductiveDatatypeDecl_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"codatatype"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_datatypename" class="ntref localref" style="color:maroon">DatatypeName</a></span> [ <span class="code-escaped"><a href="#1_genericparameters" class="ntref localref" style="color:maroon">GenericParameters</a></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"="</span></span> <span class="code-escaped"><a href="#1_datatypememberdecl" class="ntref localref" style="color:maroon">DatatypeMemberDecl</a></span> { <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_datatypememberdecl" class="ntref localref" style="color:maroon">DatatypeMemberDecl</a></span> } [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> ] </code></pre> +<p class="p noindent para-continued">Whereas Dafny insists that there is a way to construct every inductive +datatype value from the ground up, Dafny also supports +<em class="em-low1">co-inductive datatypes</em>, whose constructors are evaluated lazily and +hence allows infinite structures. A co-inductive datatype is declared +using the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">codatatype</span></code>; other than that, it is declared and +used like an inductive datatype. +</p> +<p class="p indent">For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">codatatype</span> IList<T> = Nil | Cons(head: T, tail: IList<T>) +<span style="color:blue">codatatype</span> Stream<T> = More(head: T, tail: Stream<T>) +<span style="color:blue">codatatype</span> Tree<T> = Node(left: Tree<T>, value: T, right: Tree<T>)</code></pre> +<p class="p noindent para-continued">declare possibly infinite lists (that is, lists that can be either +finite or infinite), infinite streams (that is, lists that are always +infinite), and infinite binary trees (that is, trees where every +branch goes on forever), respectively. +</p> +<p class="p indent">The paper <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf" title="Co-induction Simply: Automatic Co-inductive Proofs in a Program Verifier" data-linkid="co-induction simply">Co-induction Simply</a>, by Leino and +Moskal<span class="citations" style="target-element:bibitem">[<a href="#leino:dafny:coinduction" title="K. Rustan M. Leino and Michal Moskal. +Co-induction simply: Automatic co-inductive proofs in a program verifier. +Manuscript KRML 230, 2014a. +Available at http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf." class="bibref localref" style="target-element:bibitem"><span class="cite-number">20</span></a>]</span>, explains Dafny's implementation and +verification of co-inductive types. We capture the key features from that +paper in this section but the reader is referred to that paper for more +complete details and to supply bibliographic references that we have +omitted. +</p> +<p class="p indent">Mathematical induction is a cornerstone of programming and program +verification. It arises in data definitions (e.g., some algebraic data +structures can be described using induction), it underlies program +semantics (e.g., it explains how to reason about finite iteration and +recursion), and it gets used in proofs (e.g., supporting lemmas about +data structures use inductive proofs). Whereas induction deals with +finite things (data, behavior, etc.), its dual, co-induction, deals with +possibly infinite things. Co-induction, too, is important in programming +and program verification, where it arises in data definitions (e.g., lazy +data structures), semantics (e.g., concurrency), and proofs (e.g., +showing refinement in a co-inductive big-step semantics). It is thus +desirable to have good support for both induction and co-induction in a +system for constructing and reasoning about programs. +</p> +<p class="p indent">Co-datatypes and co-recursive functions make it possible to use lazily +evaluated data structures (like in Haskell or Agda). Co-predicates, +defined by greatest fix-points, let programs state properties of such +data structures (as can also be done in, for example, Coq). For the +purpose of writing co-inductive proofs in the language, we introduce +co-lemmas. Ostensibly, a co-lemma invokes the co-induction hypothesis +much like an inductive proof invokes the induction hypothesis. Underneath +the hood, our co-inductive proofs are actually approached via induction: +co-lemmas provide a syntactic veneer around this approach. +</p> +<p class="p indent">The following example gives a taste of how the co-inductive features in +Dafny come together to give straightforward definitions of infinite +matters. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:darkgreen">// infinite streams</span> +<span style="color:blue">codatatype</span> IStream<T> = ICons(head: T, tail: IStream) + +<span style="color:darkgreen">// pointwise product of streams</span> +<span style="color:blue">function</span> Mult(a: IStream<<span style="color:teal">int</span>>, b: IStream<<span style="color:teal">int</span>>): IStream<<span style="color:teal">int</span>> +{ ICons(a.head * b.head, Mult(a.tail, b.tail)) } + +<span style="color:darkgreen">// lexicographic order on streams</span> +<span style="color:blue">copredicate</span> Below(a: IStream<<span style="color:teal">int</span>>, b: IStream<<span style="color:teal">int</span>>) +{ a.head <= b.head && ((a.head == b.head) ==> Below(a.tail, b.tail)) } + +<span style="color:darkgreen">// a stream is Below its Square</span> +<span style="color:blue">colemma</span> Theorem_BelowSquare(a: IStream<<span style="color:teal">int</span>>) +<span style="color:purple">ensures</span> Below(a, Mult(a, a)) +{ <span style="color:blue">assert</span> a.head <= Mult(a, a).head; + <span style="color:blue">if</span> a.head == Mult(a, a).head { + Theorem_BelowSquare(a.tail); + } +} + +<span style="color:darkgreen">// an incorrect property and a bogus proof attempt</span> +<span style="color:blue">colemma</span> NotATheorem_SquareBelow(a: IStream<<span style="color:teal">int</span>>) + <span style="color:purple">ensures</span> Below(Mult(a, a), a); <span style="color:darkgreen">// ERROR</span> +{ + NotATheorem_SquareBelow(a); +}</code></pre> +<p class="p noindent para-continued">It defines a type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">IStream</code> of infinite streams, with constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">ICons</code> and +destructors <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">head</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">tail</code>. Function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mult</code> performs pointwise +multiplication on infinite streams of integers, defined using a +co-recursive call (which is evaluated lazily). Co-predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Below</code> is +defined as a greatest fix-point, which intuitively means that the +co-predicate will take on the value true if the recursion goes on forever +without determining a different value. The co-lemma states the theorem +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Below(a, Mult(a, a))</code>. Its body gives the proof, where the recursive +invocation of the co-lemma corresponds to an invocation of the +co-induction hypothesis. +</p> +<p class="p indent">The proof of the theorem stated by the first co-lemma lends +itself to the following intuitive reading: To prove that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">a</code> is below +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Mult(a, a)</code>, check that their heads are ordered and, if the heads are +equal, also prove that the tails are ordered. The second co-lemma states +a property that does not always hold; the verifier is not fooled by the +bogus proof attempt and instead reports the property as unproved. +</p> +<p class="p indent">We argue that these definitions in Dafny are simple enough to level the +playing field between induction (which is familiar) and co-induction +(which, despite being the dual of induction, is often perceived as eerily +mysterious). Moreover, the automation provided by our SMT-based verifier +reduces the tedium in writing co-inductive proofs. For example, it +verifies <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Theorem_BelowSquare</code> from the program text given above— no +additional lemmas or tactics are needed. In fact, as a consequence of the +automatic-induction heuristic in Dafny, the verifier will +automatically verify Theorem_BelowSquare even given an empty body. +</p> +<p class="p indent">Just like there are restrictions on when an <em class="em-low1">inductive hypothesis</em> can be +invoked, there are restriction on how a <em class="em-low1">co-inductive</em> hypothesis can be +<em class="em-low1">used</em>. These are, of course, taken into consideration by our verifier. +For example, as illustrated by the second co-lemma above, invoking the +co-inductive hypothesis in an attempt to obtain the entire proof goal is +futile. (We explain how this works in section <a href="#sec-colemmas" title="18.2.4.1. Colemmas" class="localref" style="target-element:h4"><span class="heading-label">18.2.4.1</span></a>) Our initial experience +with co-induction in Dafny shows it to provide an intuitive, low-overhead +user experience that compares favorably to even the best of today’s +interactive proof assistants for co-induction. In addition, the +co-inductive features and verification support in Dafny have other +potential benefits. The features are a stepping stone for verifying +functional lazy programs with Dafny. Co-inductive features have also +shown to be useful in defining language semantics, as needed to verify +the correctness of a compiler, so this opens the possibility that +such verifications can benefit from SMT automation. +</p><h4 id="sec-well-founded-functionmethod-definitions" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">18.2.0</span>. </span>Well-Founded Function/Method Definitions</h4> +<p class="p noindent">The Dafny programming language supports functions and methods. A <em class="em-low1">function</em> +in Dafny is a mathematical function (i.e., it is well-defined, +deterministic, and pure), whereas a <em class="em-low1">method</em> is a body of statements that +can mutate the state of the program. A function is defined by its given +body, which is an expression. To ensure that function definitions +are mathematically consistent, Dafny insists that recursive calls be well-founded, +enforced as follows: Dafny computes the call graph of functions. The strongly connected +components within it are <em class="em-low1">clusters</em> of mutually recursive definitions arranged in +a DAG. This stratifies the functions so that a call from one cluster in the DAG to a +lower cluster is allowed arbitrarily. For an intra-cluster call, Dafny prescribes a proof +obligation that gets taken through the program verifier’s reasoning engine. Semantically, +each function activation is labeled by a <em class="em-low1">rank</em>—a lexicographic tuple determined +by evaluating the function’s <strong class="strong-star2">decreases</strong> clause upon invocation of the function. The +proof obligation for an intra-cluster call is thus that the rank of the callee is strictly less +(in a language-defined well-founded relation) than the rank of the caller. Because +these well-founded checks correspond to proving termination of executable code, we +will often refer to them as “termination checksâ€. The same process applies to methods. +</p> +<p class="p indent">Lemmas in Dafny are commonly introduced by declaring a method, stating +the property of the lemma in the <em class="em-low1">postcondition</em> (keyword <strong class="strong-star2">ensures</strong>) of +the method, perhaps restricting the domain of the lemma by also giving a +<em class="em-low1">precondition</em> (keyword <strong class="strong-star2">requires</strong>), and using the lemma by invoking +the method. Lemmas are stated, used, and proved as methods, but +since they have no use at run time, such lemma methods are typically +declared as <em class="em-low1">ghost</em>, meaning that they are not compiled into code. The +keyword <strong class="strong-star2">lemma</strong> introduces such a method. Control flow statements +correspond to proof techniques—case splits are introduced with if +statements, recursion and loops are used for induction, and method calls +for structuring the proof. Additionally, the statement: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> x | P(x) { Lemma(x); }</code></pre> +<p class="p noindent para-continued">is used to invoke <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Lemma(x)</code> on all <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> for which <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(x)</code> holds. If +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Lemma(x)</code> ensures <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q(x)</code>, then the forall statement establishes +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> x :: P(x) ==> Q(x).</code></pre><h4 id="sec-defining-co-inductive-datatypes" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">18.2.1</span>. </span>Defining Co-inductive Datatypes</h4> +<p class="p noindent">Each value of an inductive datatype is finite, in the sense that it can +be constructed by a finite number of calls to datatype constructors. In +contrast, values of a co-inductive datatype, or co-datatype for short, +can be infinite. For example, a co-datatype can be used to represent +infinite trees. +</p> +<p class="p indent">Syntactically, the declaration of a co-datatype in Dafny looks like that +of a datatype, giving prominence to the constructors (following Coq). The +following example defines a co-datatype Stream of possibly +infinite lists. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">codatatype</span> Stream<T> = SNil | SCons(head: T, tail: Stream) +<span style="color:blue">function</span> Up(n: <span style="color:teal">int</span>): Stream<<span style="color:teal">int</span>> { SCons(n, Up(n+<span class="constant" style="color:purple">1</span>)) } +<span style="color:blue">function</span> FivesUp(n: <span style="color:teal">int</span>): Stream<<span style="color:teal">int</span>> + <span style="color:purple">decreases</span> <span class="constant" style="color:purple">4</span> - (n - <span class="constant" style="color:purple">1</span>) % <span class="constant" style="color:purple">5</span> +{ + <span style="color:blue">if</span> (n % <span class="constant" style="color:purple">5</span> == <span class="constant" style="color:purple">0</span>) <span style="color:blue">then</span> + SCons(n, FivesUp(n+<span class="constant" style="color:purple">1</span>)) + <span style="color:blue">else</span> + FivesUp(n+<span class="constant" style="color:purple">1</span>) +}</code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Stream</code> is a co-inductive datatype whose values are possibly infinite +lists. Function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up</code> returns a stream consisting of all integers upwards +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FivesUp</code> returns a stream consisting of all multiples of 5 +upwards of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> . The self-call in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up</code> and the first self-call in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FivesUp</code> +sit in productive positions and are therefore classified as co-recursive +calls, exempt from termination checks. The second self-call in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FivesUp</code> is +not in a productive position and is therefore subject to termination +checking; in particular, each recursive call must decrease the rank +defined by the <strong class="strong-star2">decreases</strong> clause. +</p> +<p class="p indent">Analogous to the common finite list datatype, Stream declares two +constructors, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">SNil</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">SCons</code>. Values can be destructed using match +expressions and statements. In addition, like for inductive datatypes, +each constructor <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C</code> automatically gives rise to a discriminator <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C?</code> and +each parameter of a constructor can be named in order to introduce a +corresponding destructor. For example, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">xs</code> is the stream +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">SCons(x, ys)</code>, then <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">xs.SCons?</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">xs.head == x</code> hold. In contrast +to datatype declarations, there is no grounding check for +co-datatypes—since a codatatype admits infinite values, the type is +nevertheless inhabited. +</p><h4 id="sec-creating-values-of-co-datatypes" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">18.2.2</span>. </span>Creating Values of Co-datatypes</h4> +<p class="p noindent">To define values of co-datatypes, one could imagine a “co-function†+language feature: the body of a “co-function†could include possibly +never-ending self-calls that are interpreted by a greatest fix-point +semantics (akin to a <strong class="strong-star2">CoFixpoint</strong> in Coq). Dafny uses a different design: +it offers only functions (not “co-functionsâ€), but it classifies each +intra-cluster call as either <em class="em-low1">recursive</em> or <em class="em-low1">co-recursive</em>. Recursive calls +are subject to termination checks. Co-recursive calls may be +never-ending, which is what is needed to define infinite values of a +co-datatype. For example, function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up(n )</code> in the preceding example is defined as the +stream of numbers from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> upward: it returns a stream that starts with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> +and continues as the co-recursive call <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up(n + <span class="constant" style="color:purple">1</span>)</code>. +</p> +<p class="p indent">To ensure that co-recursive calls give rise to mathematically consistent definitions, +they must occur only in productive positions. This says that it must be possible to determine +each successive piece of a co-datatype value after a finite amount of work. This +condition is satisfied if every co-recursive call is syntactically guarded by a constructor +of a co-datatype, which is the criterion Dafny uses to classify intra-cluster calls as being +either co-recursive or recursive. Calls that are classified as co-recursive are exempt from +termination checks. +</p> +<p class="p indent">A consequence of the productivity checks and termination checks is that, even in the +absence of talking about least or greatest fix-points of self-calling functions, all functions +in Dafny are deterministic. Since there is no issue of several possible fix-points, +the language allows one function to be involved in both recursive and co-recursive calls, +as we illustrate by the function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">FivesUp</code>. +</p><h4 id="sec-copredicates" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">18.2.3</span>. </span>Copredicates</h4> +<p class="p noindent">Determining properties of co-datatype values may require an infinite +number of observations. To that avail, Dafny provides <em class="em-low1">co-predicates</em> +which are function declarations that use the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">copredicate</span></code> keyword. +Self-calls to a co-predicate need not terminate. Instead, the value +defined is the greatest fix-point of the given recurrence equations. +Continuing the preceding example, the following code defines a +co-predicate that holds for exactly those streams whose payload consists +solely of positive integers. The co-predicate definition implicitly also +gives rise to a corresponding prefix predicate, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#</code>. The syntax for +calling a prefix predicate sets apart the argument that specifies the +prefix length, as shown in the last line; for this figure, we took the +liberty of making up a coordinating syntax for the signature of the +automatically generated prefix predicate (which is not part of +Dafny syntax). +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">copredicate</span> Pos(s: Stream<<span style="color:teal">int</span>>) +{ + <span style="color:blue">match</span> s + <span style="color:blue">case</span> SNil => <span style="color:blue">true</span> + <span style="color:blue">case</span> SCons(x, rest) => x > <span class="constant" style="color:purple">0</span> && Pos(rest) +} +<span style="color:darkgreen">// Automatically generated by the Dafny compiler:</span> +<span style="color:blue">predicate</span> Pos#[_k: <span style="color:teal">nat</span>](s: Stream<<span style="color:teal">int</span>>) + <span style="color:purple">decreases</span> _k +{ <span style="color:blue">if</span> _k = <span class="constant" style="color:purple">0</span> <span style="color:blue">then</span> <span style="color:blue">true</span> <span style="color:blue">else</span> + <span style="color:blue">match</span> s + <span style="color:blue">case</span> SNil => <span style="color:blue">true</span> + <span style="color:blue">case</span> SCons(x, rest) => x > <span class="constant" style="color:purple">0</span> && Pos#[_k-<span class="constant" style="color:purple">1</span>](rest) +}</code></pre> +<p class="p noindent para-continued">Some restrictions apply. To guarantee that the greatest fix-point always +exists, the (implicit functor defining the) co-predicate must be +monotonic. This is enforced by a syntactic restriction on the form of the +body of co-predicates: after conversion to negation normal form (i.e., +pushing negations down to the atoms), intra-cluster calls of +co-predicates must appear only in <em class="em-low1">positive</em> positions—that is, they must +appear as atoms and must not be negated. Additionally, to guarantee +soundness later on, we require that they appear in <em class="em-low1">co-friendly</em> +positions—that is, in negation normal form, when they appear under +existential quantification, the quantification needs to be limited to a +finite range<sup id="back-fn-fn-copredicate-restriction" ><a href="#fn-fn-copredicate-restriction" title="8.Higher-order function support in Dafny is +rather modest and typical reasoning patterns do not involve them, so this +restriction is not as limiting as it would have been in, e.g., Coq. +↩" class="footnote-ref localref" ><span class="footnote-label">8</span></a></sup>. Since the evaluation of a co-predicate might not +terminate, co-predicates are always ghost. There is also a restriction on +the call graph that a cluster containing a co-predicate must contain only +co-predicates, no other kinds of functions. +</p> +<p class="p indent">A <strong class="strong-star2">copredicate</strong> declaration of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code> defines not just a co-predicate, but +also a corresponding <em class="em-low1">prefix predicate</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P#</code>. A prefix predicate is a +finite unrolling of a co-predicate. The prefix predicate is constructed +from the co-predicate by +</p> +<ul class="ul list-star loose"> +<li class="li ul-li list-star-li loose-li"> +<p>adding a parameter _k of type nat to denote the prefix length, +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>adding the clause “<strong class="strong-star2">decreases</strong> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k;</code>” to the prefix predicate (the +co-predicate itself is not allowed to have a decreases clause), +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>replacing in the body of the co-predicate every intra-cluster +call <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q(args)</code> to a copredicate by a call <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q#[_k - <span class="constant" style="color:purple">1</span>](args)</code> +to the corresponding prefix predicate, and then +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>prepending the body with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span> _k = <span class="constant" style="color:purple">0</span> <span style="color:blue">then</span> <span style="color:blue">true</span> <span style="color:blue">else</span></code>. +</p></li></ul> + +<p class="p noindent">For example, for co-predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos</code>, the definition of the prefix +predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#</code> is as suggested above. Syntactically, the prefix-length +argument passed to a prefix predicate to indicate how many times to +unroll the definition is written in square brackets, as in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#[k](s)</code>. +In the Dafny grammar this is called a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code>. The definition of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#</code> is available only at clusters strictly higher than that of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos</code>; +that is, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#</code> must not be in the same cluster. In other +words, the definition of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos</code> cannot depend on <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#</code>. +</p><h5 id="sec-co-equality" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">18.2.3.0</span>. </span>Co-Equality</h5> +<p class="p noindent">Equality between two values of a co-datatype is a built-in co-predicate. +It has the usual equality syntax <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s == t</code>, and the corresponding prefix +equality is written <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s ==#[k] t</code>. And similarly for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s != t</code> +and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s !=#[k] t</code>. +</p><h4 id="sec-co-inductive-proofs" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">18.2.4</span>. </span>Co-inductive Proofs</h4> +<p class="p noindent">From what we have said so far, a program can make use of properties of +co-datatypes. For example, a method that declares <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos(s)</code> as a +precondition can rely on the stream <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> containing only positive integers. +In this section, we consider how such properties are established in the +first place. +</p><h5 id="sec-properties-about-prefix-predicates" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">18.2.4.0</span>. </span>Properties About Prefix Predicates</h5> +<p class="p noindent">Among other possible strategies for establishing co-inductive properties +we take the time-honored approach of reducing co-induction to +induction. More precisely, Dafny passes to the SMT solver an +assumption <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">D(P)</code> for every co-predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code>, where: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>D(P) = ? x • P(x) <==> ? k • P#[k](x)</code></pre> +<p class="p noindent para-continued">In other words, a co-predicate is true iff its corresponding prefix +predicate is true for all finite unrollings. +</p> +<p class="p indent">In Sec. 4 of the paper <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf" title="Co-induction Simply: Automatic Co-inductive Proofs in a Program Verifier" data-linkid="co-induction simply">Co-induction Simply</a> a soundness theorem of such +assumptions is given, provided the co-predicates meet the co-friendly +restrictions. An example proof of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos(Up(n))</code> for every <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n > <span class="constant" style="color:purple">0</span></code> is +here shown: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> UpPosLemma(n: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> n > <span class="constant" style="color:purple">0</span> + <span style="color:purple">ensures</span> Pos(Up(n)) +{ + <span style="color:blue">forall</span> k | <span class="constant" style="color:purple">0</span> <= k { UpPosLemmaK(k, n); } +} + +<span style="color:blue">lemma</span> UpPosLemmaK(k: <span style="color:teal">nat</span>, n: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> n > <span class="constant" style="color:purple">0</span> + <span style="color:purple">ensures</span> Pos#[k](Up(n)) + <span style="color:purple">decreases</span> k +{ + <span style="color:blue">if</span> k != <span class="constant" style="color:purple">0</span> { + <span style="color:darkgreen">// this establishes Pos#[k-1](Up(n).tail)</span> + UpPosLemmaK(k-<span class="constant" style="color:purple">1</span>, n+<span class="constant" style="color:purple">1</span>); + } +}</code></pre> +<p class="p noindent para-continued">The lemma <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma</code> proves <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos(Up(n))</code> for every <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n > <span class="constant" style="color:purple">0</span></code>. We first +show <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos#[k](Up(n ))</code>, for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n > <span class="constant" style="color:purple">0</span></code> and an arbitrary <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code>, and then use +the forall statement to show <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">? k • Pos#[k](Up(n))</code>. Finally, the axiom +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">D(Pos)</code> is used (automatically) to establish the co-predicate. +</p><h5 id="sec-colemmas" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">18.2.4.1</span>. </span>Colemmas</h5> +<p class="p noindent">As we just showed, with help of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">D</code> axiom we can now prove a +co-predicate by inductively proving that the corresponding prefix +predicate holds for all prefix lengths <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> . In this section, we introduce +<em class="em-low1">co-lemma</em> declarations, which bring about two benefits. The first benefit +is that co-lemmas are syntactic sugar and reduce the tedium of having to +write explicit quantifications over <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> . The second benefit is that, in +simple cases, the bodies of co-lemmas can be understood as co-inductive +proofs directly. As an example consider the following co-lemma. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">colemma</span> UpPosLemma(n: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> n > <span class="constant" style="color:purple">0</span> + <span style="color:purple">ensures</span> Pos(Up(n)) +{ + UpPosLemma(n+<span class="constant" style="color:purple">1</span>); +}</code></pre> +<p class="p noindent para-continued">This co-lemma can be understood as follows: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma</code> invokes itself +co-recursively to obtain the proof for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos(Up(n).tail)</code> (since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up(n).tail</code> +equals <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Up(n+<span class="constant" style="color:purple">1</span>)</code>). The proof glue needed to then conclude <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Pos(Up(n))</code> is +provided automatically, thanks to the power of the SMT-based verifier. +</p><h5 id="sec-prefix-lemmas" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">18.2.4.2</span>. </span>Prefix Lemmas</h5> +<p class="p noindent">To understand why the above <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma</code> co-lemma code is a sound proof, +let us now describe the details of the desugaring of co-lemmas. In +analogy to how a <strong class="strong-star2">copredicate</strong> declaration defines both a co-predicate and +a prefix predicate, a <strong class="strong-star2">colemma</strong> declaration defines both a co-lemma and +<em class="em-low1">prefix lemma</em>. In the call graph, the cluster containing a co-lemma must +contain only co-lemmas and prefix lemmas, no other methods or function. +By decree, a co-lemma and its corresponding prefix lemma are always +placed in the same cluster. Both co-lemmas and prefix lemmas are always +ghosts. +</p> +<p class="p indent">The prefix lemma is constructed from the co-lemma by +</p> +<ul class="ul list-star loose"> +<li class="li ul-li list-star-li loose-li"> +<p>adding a parameter <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code> to denote the prefix length, +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>replacing in the co-lemma’s postcondition the positive co-friendly +occurrences of co-predicates by corresponding prefix predicates, +passing in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k</code> as the prefix-length argument, +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>prepending <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k</code> to the (typically implicit) <strong class="strong-star2">decreases</strong> clause of the co-lemma, +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>replacing in the body of the co-lemma every intra-cluster call +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M(args)</code> to a colemma by a call <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M#[_k - <span class="constant" style="color:purple">1</span>](args)</code> to the +corresponding prefix lemma, and then +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>making the body’s execution conditional on <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k != <span class="constant" style="color:purple">0</span></code>. +</p></li></ul> + +<p class="p noindent">Note that this rewriting removes all co-recursive calls of co-lemmas, +replacing them with recursive calls to prefix lemmas. These recursive +call are, as usual, checked to be terminating. We allow the pre-declared +identifier <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k</code> to appear in the original body of the +co-lemma.<sup id="back-fn-fn-co-predicate-co-lemma-diffs" ><a href="#fn-fn-co-predicate-co-lemma-diffs" title="9.Note, two places where co-predicates +and co-lemmas are not analogous are: co-predicates must not make +recursive calls to their prefix predicates, and co-predicates cannot +mention _k. +↩" class="footnote-ref localref" ><span class="footnote-label">9</span></a></sup> +</p> +<p class="p indent">We can now think of the body of the co-lemma as being replaced by a +<strong class="strong-star2">forall</strong> call, for every <em class="em-low1">k</em> , to the prefix lemma. By construction, +this new body will establish the colemma’s declared postcondition (on +account of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">D</code> axiom, and remembering that only the positive +co-friendly occurrences of co-predicates in the co-lemma’s postcondition +are rewritten), so there is no reason for the program verifier to check +it. +</p> +<p class="p indent">The actual desugaring of our co-lemma <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma</code> is in fact the +previous code for the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma</code> lemma except that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemmaK</code> is +named <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">UpPosLemma#</code> and modulo a minor syntactic difference in how the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">k</code> argument is passed. +</p> +<p class="p indent">In the recursive call of the prefix lemma, there is a proof obligation +that the prefixlength argument <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k - <span class="constant" style="color:purple">1</span></code> is a natural number. +Conveniently, this follows from the fact that the body has been wrapped +in an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span> _k != <span class="constant" style="color:purple">0</span></code> statement. This also means that the postcondition must +hold trivially when <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k = <span class="constant" style="color:purple">0</span></code>, or else a postcondition violation will be +reported. This is an appropriate design for our desugaring, because +co-lemmas are expected to be used to establish co-predicates, whose +corresponding prefix predicates hold trivially when <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_k = <span class="constant" style="color:purple">0</span></code>. (To prove +other predicates, use an ordinary lemma, not a co-lemma.) +</p> +<p class="p indent">It is interesting to compare the intuitive understanding of the +co-inductive proof in using a co-lemma with the inductive proof in using +the lemma. Whereas the inductive proof is performing proofs for deeper +and deeper equalities, the co-lemma can be understood as producing the +infinite proof on demand. +</p><h2 id="sec-newtypes" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">19</span>. </span>Newtypes</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_newtypedecl" class="ntdef" style="color:olive">NewtypeDecl</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"newtype"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_newtypename" class="ntref localref" style="color:maroon">NewtypeName</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"="</span></span> + ( <span class="code-escaped"><a href="#1_numerictypename" class="ntref localref" style="color:maroon">NumericTypeName</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> ] <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> + ) </code></pre> +<p class="p noindent para-continued">A new numeric type can be declared with the <em class="em-low1">newtype</em> +declaration<sup id="back-fn-fn-newtype-name" ><a href="#fn-fn-newtype-name" title="10.Should newtype perhaps be renamed to numtype? +↩" class="footnote-ref localref" ><span class="footnote-label">10</span></a></sup>, for example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">newtype</span> N = x: M | Q</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> is a numeric type and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> is a boolean expression that can +use <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> as a free variable. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> is an integer-based numeric type, +then so is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code>; if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> is real-based, then so is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code>. If the type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> +can be inferred from <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code>, the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">: M</code>” can be omitted. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> is just +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>, then the declaration can be given simply as: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">newtype</span> N = M</code></pre> +<p class="p noindent para-continued">Type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code> is known as the <em class="em-low1">base type</em> of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code>. +</p> +<p class="p indent">A newtype is a numeric type that supports the same operations as its +base type. The newtype is distinct from and incompatible with other +numeric types; in particular, it is not assignable to its base type +without an explicit conversion. An important difference between the +operations on a newtype and the operations on its base type is that +the newtype operations are defined only if the result satisfies the +predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code>, and likewise for the literals of the +newtype.<sup id="back-fn-fn-newtype-design-question" ><a href="#fn-fn-newtype-design-question" title="11.Would it be useful to also +automatically define predicate N?(m: M) { Q }? +↩" class="footnote-ref localref" ><span class="footnote-label">11</span></a></sup> +</p> +<p class="p indent">For example, suppose <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> are integer-based numerics that +satisfy <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= lo <= hi</code> and consider the following code fragment: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> mid <span style="color:blue">:=</span> (lo + hi) / <span class="constant" style="color:purple">2</span>;</code></pre> +<p class="p noindent para-continued">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> have type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>, then the code fragment is legal; in +particular, it never overflows, since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> has no upper bound. In +contrast, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> are variables of a newtype <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code> declared +as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">newtype</span> int32 = x | -<span class="constant" style="color:purple">0x80000000</span> <= x < <span class="constant" style="color:purple">0x80000000</span></code></pre> +<p class="p noindent para-continued">then the code fragment is erroneous, since the result of the addition +may fail to satisfy the predicate in the definition of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>. The +code fragment can be rewritten as +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> mid <span style="color:blue">:=</span> lo + (hi - lo) / <span class="constant" style="color:purple">2</span>;</code></pre> +<p class="p noindent para-continued">in which case it is legal for both <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>. +</p> +<p class="p indent">Since a newtype is incompatible with its base type and since all +results of the newtype's operations are members of the newtype, a +compiler for Dafny is free to specialize the run-time representation +of the newtype. For example, by scrutinizing the definition of +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code> above, a compiler may decide to store <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code> values using +signed 32-bit integers in the target hardware. +</p> +<p class="p indent">Note that the bound variable <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> has type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">M</code>, not <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code>. +Consequently, it may not be possible to state <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> about the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code> +value. For example, consider the following type of 8-bit 2's +complement integers: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">newtype</span> int8 = x: <span style="color:teal">int</span> | -<span class="constant" style="color:purple">128</span> <= x < <span class="constant" style="color:purple">128</span></code></pre> +<p class="p noindent para-continued">and consider a variable <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code> of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int8</code>. The expression +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>-<span class="constant" style="color:purple">128</span> <= c < <span class="constant" style="color:purple">128</span></code></pre> +<p class="p noindent para-continued">is not well-defined, because the comparisons require each operand to +have type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int8</code>, which means the literal <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">128</span></code> is checked to be of +type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int8</code>, which it is not. A proper way to write this expression +would be to use a conversion operation, described next, on <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code> to +convert it to the base type: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>-<span class="constant" style="color:purple">128</span> <= <span style="color:teal">int</span>(c) < <span class="constant" style="color:purple">128</span></code></pre> +<p class="p noindent para-continued">If possible Dafny will represent values of the newtype using +a native data type for the sake of efficiency. This action can +be inhibited or a specific native data type selected by +using the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(:nativeType)</code> attribute, as explained in +section <a href="#sec-nativetype" title="24.1.11. nativeType" class="localref" style="target-element:h3"><span class="heading-label">24.1.11</span></a>. +</p> +<p class="p indent">There is a restriction that the value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span></code> must be part of every +newtype.<sup id="back-fn-fn-newtype-zero" ><a href="#fn-fn-newtype-zero" title="12.The restriction is due to a current limitation in +the compiler. This will change in the future and will also open +up the possibility for subset types and non-null reference +types. +↩" class="footnote-ref localref" ><span class="footnote-label">12</span></a></sup> +</p><h3 id="sec-numeric-conversion-operations" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">19.0</span>. </span>Numeric conversion operations</h3> +<p class="p noindent">For every numeric type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">N</code>, there is a conversion function with the +same name. It is a partial identity function. It is defined when the +given value, which can be of any numeric type, is a member of the type +converted to. When the conversion is from a real-based numeric type +to an integer-based numeric type, the operation requires that the +real-based argument has no fractional part. (To round a real-based +numeric value down to the nearest integer, use the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">.Trunc</code> member, +see Section <a href="#sec-numeric-types" title="6.1. Numeric types" class="localref" style="target-element:h2"><span class="heading-label">6.1</span></a>.) +</p> +<p class="p indent">To illustrate using the example from above, if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> have type +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>, then the code fragment can legally be written as follows: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> mid <span style="color:blue">:=</span> (<span style="color:teal">int</span>(lo) + <span style="color:teal">int</span>(hi)) / <span class="constant" style="color:purple">2</span>;</code></pre> +<p class="p noindent para-continued">where the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">mid</code> is inferred to be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>. Since the result +value of the division is a member of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>, one can introduce +yet another conversion operation to make the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">mid</code> be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> mid <span style="color:blue">:=</span> int32((<span style="color:teal">int</span>(lo) + <span style="color:teal">int</span>(hi)) / <span class="constant" style="color:purple">2</span>);</code></pre> +<p class="p noindent para-continued">If the compiler does specialize the run-time representation for +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">int32</code>, then these statements come at the expense of two, +respectively three, run-time conversions. +</p><h2 id="sec-subset-types" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">20</span>. </span>Subset types</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_nattype_" class="ntdef" style="color:olive">NatType_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"nat"</span></span> </code></pre> +<p class="p noindent para-continued">A <em class="em-low1">subset type</em> is a restricted use of an existing type, called +the <em class="em-low1">base type</em> of the subset type. A subset type is like a +combined use of the base type and a predicate on the base +type. +</p> +<p class="p indent">An assignment from a subset type to its base type is always +allowed. An assignment in the other direction, from the base type to +a subset type, is allowed provided the value assigned does indeed +satisfy the predicate of the subset type. +(Note, in contrast, assignments between a newtype and its base type +are never allowed, even if the value assigned is a value of the target +type. For such assignments, an explicit conversion must be used, see +Section <a href="#sec-numeric-conversion-operations" title="19.0. Numeric conversion operations" class="localref" style="target-element:h2"><span class="heading-label">19.0</span></a>.) +</p> +<p class="p indent">Dafny supports one subset type, namely the built-in type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code>, +whose base type is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>.<sup id="back-fn-fn-more-subset-types" ><a href="#fn-fn-more-subset-types" title="13.A future version of Dafny will support +user-defined subset types. +↩" class="footnote-ref localref" ><span class="footnote-label">13</span></a></sup> Type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code> +designates the non-negative subrange of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>. A simple example that +puts subset type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code> to good use is the standard Fibonacci +function: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> Fib(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> +{ + <span style="color:blue">if</span> n < <span class="constant" style="color:purple">2</span> <span style="color:blue">then</span> n <span style="color:blue">else</span> Fib(n-<span class="constant" style="color:purple">2</span>) + Fib(n-<span class="constant" style="color:purple">1</span>) +}</code></pre> +<p class="p noindent para-continued">An equivalent, but clumsy, formulation of this function (modulo the +wording of any error messages produced at call sites) would be to use +type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> and to write the restricting predicate in pre- and +postconditions: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> Fib(n: <span style="color:teal">int</span>): <span style="color:teal">int</span> + <span style="color:purple">requires</span> <span class="constant" style="color:purple">0</span> <= n; <span style="color:darkgreen">// the function argument must be non-negative</span> + <span style="color:purple">ensures</span> <span class="constant" style="color:purple">0</span> <= Fib(n); <span style="color:darkgreen">// the function result is non-negative</span> +{ + <span style="color:blue">if</span> n < <span class="constant" style="color:purple">2</span> <span style="color:blue">then</span> n <span style="color:blue">else</span> Fib(n-<span class="constant" style="color:purple">2</span>) + Fib(n-<span class="constant" style="color:purple">1</span>) +}</code></pre> +<p class="p noindent para-continued">Type inference will never infer the type of a variable to be a +subset type. It will instead infer the type to be the base type +of the subset type. For example, the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> in +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> x :: P(x)</code></pre> +<p class="p noindent para-continued">will be <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>, even if predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code> declares its argument to have +type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">nat</span></code>. +</p><h2 id="sec-statements" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">21</span>. </span>Statements</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_stmt" class="ntdef" style="color:olive">Stmt</span></span> = ( <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> | <span class="code-escaped"><a href="#1_assertstmt" class="ntref localref" style="color:maroon">AssertStmt</a></span> | <span class="code-escaped"><a href="#1_assumestmt" class="ntref localref" style="color:maroon">AssumeStmt</a></span> | <span class="code-escaped"><a href="#1_printstmt" class="ntref localref" style="color:maroon">PrintStmt</a></span> | <span class="code-escaped"><a href="#1_updatestmt" class="ntref localref" style="color:maroon">UpdateStmt</a></span> + | <span class="code-escaped"><a href="#1_vardeclstatement" class="ntref localref" style="color:maroon">VarDeclStatement</a></span> | <span class="code-escaped"><a href="#1_ifstmt" class="ntref localref" style="color:maroon">IfStmt</a></span> | <span class="code-escaped"><a href="#1_whilestmt" class="ntref localref" style="color:maroon">WhileStmt</a></span> | <span class="code-escaped"><a href="#1_matchstmt" class="ntref localref" style="color:maroon">MatchStmt</a></span> | <span class="code-escaped"><a href="#1_forallstmt" class="ntref localref" style="color:maroon">ForallStmt</a></span> + | <span class="code-escaped"><a href="#1_calcstmt" class="ntref localref" style="color:maroon">CalcStmt</a></span> | <span class="code-escaped"><a href="#1_modifystmt" class="ntref localref" style="color:maroon">ModifyStmt</a></span> | <span class="code-escaped"><a href="#1_labeledstmt_" class="ntref localref" style="color:maroon">LabeledStmt_</a></span> | <span class="code-escaped"><a href="#1_breakstmt_" class="ntref localref" style="color:maroon">BreakStmt_</a></span> | <span class="code-escaped"><a href="#1_returnstmt" class="ntref localref" style="color:maroon">ReturnStmt</a></span> + | <span class="code-escaped"><a href="#1_yieldstmt" class="ntref localref" style="color:maroon">YieldStmt</a></span> | <span class="code-escaped"><a href="#1_skeletonstmt" class="ntref localref" style="color:maroon">SkeletonStmt</a></span> + ) </code></pre> +<p class="p noindent para-continued">Many of Dafny's statements are similar to those in traditional +programming languages, but a number of them are significantly different. +This grammar production shows the different kinds of Dafny statements. +They are described in subsequent sections. +</p><h3 id="sec-labeled-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.0</span>. </span>Labeled Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_labeledstmt_" class="ntdef" style="color:olive">LabeledStmt_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"label"</span></span> <span class="code-escaped"><a href="#1_labelname" class="ntref localref" style="color:maroon">LabelName</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_stmt" class="ntref localref" style="color:maroon">Stmt</a></span> </code></pre> +<p class="p noindent para-continued">A labeled statement is just the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">label</span></code> followed by and +identifier which is the label followed by a colon and a +statement. The label may be referenced in a break statement +to transfer control to the location after that statement. +</p><h3 id="sec-break-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.1</span>. </span>Break Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_breakstmt_" class="ntdef" style="color:olive">BreakStmt_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"break"</span></span> ( <span class="code-escaped"><a href="#1_labelname" class="ntref localref" style="color:maroon">LabelName</a></span> | { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"break"</span></span> } ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued">A break statement breaks out of one or more loops (if the +statement consists solely of one or more <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">break</span></code> keywords), +or else transfers control to just past the statement +bearing the referenced label, if a label was used. +</p><h3 id="sec-block-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.2</span>. </span>Block Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_blockstmt" class="ntdef" style="color:olive">BlockStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><a href="#1_stmt" class="ntref localref" style="color:maroon">Stmt</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<p class="p noindent para-continued">A block statement is just a sequence of statements enclosed by curly braces. +</p><h3 id="sec-return-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.3</span>. </span>Return Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_returnstmt" class="ntdef" style="color:olive">ReturnStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"return"</span></span> [ <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued">A return statement can only be used in a method. It is used +to terminate the execution of the method. +To return a value from a method, the value is assigned to one +of the named return values sometime before a return statement. +In fact, the return values act very much like local variables, +and can be assigned to more than once. Return statements are +used when one wants to return before reaching the end of the +body block of the method. Return statements can be just the +return keyword (where the current value of the out parameters +are used), or they can take a list of values to return. +If a list is given the number of values given must be the +same as the number of named return values. +</p><h3 id="sec-yield-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.4</span>. </span>Yield Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_yieldstmt" class="ntdef" style="color:olive">YieldStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"yield"</span></span> [ <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued">A yield statement can only be used in an iterator. +See section <a href="#sec-iterator-types" class="localref">Iterator types</a> for more details +about iterators. +</p> +<p class="p indent">The body of an iterator is a <em class="em-low1">co-routine</em>. It is used +to yield control to its caller, signaling that a new +set of values for the iterator's yield parameters (if any) +are available. Values are assigned to the yield parameters +at or before a yield statement. +In fact, the yield parameters act very much like local variables, +and can be assigned to more than once. Yield statements are +used when one wants to return new yield parameter values +to the caller. Yield statements can be just the +<strong class="strong-star2">yield</strong> keyword (where the current value of the yield parameters +are used), or they can take a list of values to yield. +If a list is given the number of values given must be the +same as the number of named return yield parameters. +</p><h3 id="sec-update-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.5</span>. </span>Update Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_updatestmt" class="ntdef" style="color:olive">UpdateStmt</span></span> = <span class="code-escaped"><a href="#1_lhs" class="ntref localref" style="color:maroon">Lhs</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_lhs" class="ntref localref" style="color:maroon">Lhs</a></span> } + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> } + | <span style="color:maroon">"</span><span style="color:maroon">:|</span><span style="color:maroon">"</span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assume"</span></span> ] <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + ) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span><span style="color:red">"</span></code></pre> +<p class="p noindent para-continued">The update statement has two forms. The first more normal form +allows for parallel assignment of right-hand-side values to the +left-hand side. For example <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x,y <span style="color:blue">:=</span> y,x</code> to swap the values +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">y</code>. Of course the common case will have only one +rhs and one lhs. +</p> +<p class="p indent">The form that uses “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">:|</span></code>” assigns some values to the left-hand-side +variables such that the boolean expression on the right hand side +is satisfied. This can be used to make a choice as in the +following example where we choose an element in a set. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> PickOne<T>(s: <span style="color:teal">set</span><T>): T + <span style="color:purple">requires</span> s != {} +{ + <span style="color:blue">var</span> x <span style="color:blue">:|</span> x <span style="color:blue">in</span> s; x +}</code></pre> +<p class="p noindent para-continued">Dafny will report an error if it cannot prove that values +exist which satisfy the condition. +</p> +<p class="p indent">In addition, though the choice is arbitrary, given identical +circumstances the choice will be made consistently. +</p> +<p class="p indent">In the actual grammar two additional forms are recognized for +purposes of error detection. The form: +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_lhs" class="ntdef" style="color:olive">Lhs</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span>} ;</code></pre> +<p class="p noindent para-continued">is assumed to be a mal-formed call. +</p> +<p class="p indent">The form +</p> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_lhs" class="ntdef" style="color:olive">Lhs</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span></code></pre> +<p class="p noindent para-continued">is diagnosed as a label in which the user forgot the <strong class="strong-star2">label</strong> keyword. +</p><h3 id="sec-variable-declaration-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.6</span>. </span>Variable Declaration Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_vardeclstatement" class="ntdef" style="color:olive">VarDeclStatement</span></span> = [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"var"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + ( + <span class="code-escaped"><a href="#1_localidenttypeoptional" class="ntref localref" style="color:maroon">LocalIdentTypeOptional</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span class="code-escaped"><a href="#1_localidenttypeoptional" class="ntref localref" style="color:maroon">LocalIdentTypeOptional</a></span> } + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span> } + | { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span style="color:maroon">"</span><span style="color:maroon">:|</span><span style="color:maroon">"</span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assume"</span></span> ] <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + ] + | + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + ) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span></code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_vardeclstatement" class="ntref localref" style="color:maroon">VarDeclStatement</a></span></code> is used to declare one or more local variables in a method or function. +The type of each local variable must be given unless the variable is given an initial +value in which case the type will be inferred. If initial values are given, the number of +values must match the number of variables declared. +</p> +<p class="p indent">Note that the type of each variable must be given individually. The following code +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> x, y : <span style="color:teal">int</span>;</code></pre> +<p class="p noindent para-continued">does not declare both <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">y</code> to be of type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code>. Rather it will give an +error explaining that the type of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> is underspecified. +</p> +<p class="p indent">The lefthand side can also contain a tuple of patterns which will be +matched against the right-hand-side. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> returnsTuple() : (<span style="color:teal">int</span>, <span style="color:teal">int</span>) +{ + (<span class="constant" style="color:purple">5</span>, <span class="constant" style="color:purple">10</span>) +} + +<span style="color:blue">function</span> usesTuple() : <span style="color:teal">int</span> +{ + <span style="color:blue">var</span> (x, y) <span style="color:blue">:=</span> returnsTuple(); + x + y +}</code></pre><h3 id="sec-guards" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.7</span>. </span>Guards</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_guard" class="ntdef" style="color:olive">Guard</span></span> = ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> | <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ) </code></pre> +<p class="p noindent para-continued">Guards are used in <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">while</span></code> statements as boolean expressions. Guards +take two forms. +</p> +<p class="p indent">The first and most common form is just a boolean expression. +</p> +<p class="p indent">The second form is either <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(*)</code>. These have the same meaning. An +unspecified boolean value is returned. The value returned +may be different each time it is executed. +</p><h3 id="sec-binding-guards" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.8</span>. </span>Binding Guards</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_bindingguard" class="ntdef" style="color:olive">BindingGuard</span></span>(allowLambda) = + <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> } { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span style="color:maroon">"</span><span style="color:maroon">:|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>)</code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_bindingguard" class="ntref localref" style="color:maroon">BindingGuard</a></span></code> is used as a condition in an <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ifstmt" class="ntref localref" style="color:maroon">IfStmt</a></span></code>. +It binds the identifiers declared in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span></code>s. +If there exists one or more assignments of values to the bound identifiers +for which <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> is true, then the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_bindingguard" class="ntref localref" style="color:maroon">BindingGuard</a></span></code> +returns true and the identifiers are bound to values that make the +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> true. +</p> +<p class="p indent">The identifiers bound by <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_bindingguard" class="ntref localref" style="color:maroon">BindingGuard</a></span></code> are ghost variables +and cannot be assigned to non-ghost variables. They are only +used in specification contexts. +</p> +<p class="p indent">Here is an example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">predicate</span> P(n: <span style="color:teal">int</span>) +{ + n % <span class="constant" style="color:purple">2</span> == <span class="constant" style="color:purple">0</span> +} + +<span style="color:blue">method</span> M1() <span style="color:blue">returns</span> (<span style="color:blue">ghost</span> y: <span style="color:teal">int</span>) + <span style="color:purple">requires</span> <span class="code-escaped">∃<span style="font-family:serif"> </span></span>x :: P(x) + <span style="color:purple">ensures</span> P(y) +{ + <span style="color:blue">if</span> x : <span style="color:teal">int</span> <span style="color:blue">:|</span> P(x) { + y <span style="color:blue">:=</span> x; + } +}</code></pre><h3 id="sec-if-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.9</span>. </span>If Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_ifstmt" class="ntdef" style="color:olive">IfStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"if"</span></span> + ( <span class="code-escaped"><a href="#1_ifalternativeblock" class="ntref localref" style="color:maroon">IfAlternativeBlock</a></span> + | + ( <span class="code-escaped"><a href="#1_bindingguard" class="ntref localref" style="color:maroon">BindingGuard</a></span>(allowLambda: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><a href="#1_guard" class="ntref localref" style="color:maroon">Guard</a></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + ) + <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"else"</span></span> ( <span class="code-escaped"><a href="#1_ifstmt" class="ntref localref" style="color:maroon">IfStmt</a></span> | <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> ) ] + ) </code></pre> +<p class="p noindent para-continued">In the simplest form an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code> statement uses a guard that is a boolean +expression. It then has the same form as in C# and other common +programming languages. For example +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">if</span> x < <span class="constant" style="color:purple">0</span> { + x <span style="color:blue">:=</span> -x; + } </code></pre> +<p class="p noindent para-continued">If the guard is an asterisk then a non-deterministic choice is made: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">if</span> * { + <span style="color:blue">print</span> <span style="color:maroon">"</span><span style="color:maroon">True</span><span style="color:maroon">"</span>; + } <span style="color:blue">else</span> { + <span style="color:blue">print</span> <span style="color:maroon">"</span><span style="color:maroon">False</span><span style="color:maroon">"</span>; + }</code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_ifalternativeblock" class="ntdef" style="color:olive">IfAlternativeBlock</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"case"</span></span> + ( + <span class="code-escaped"><a href="#1_bindingguard" class="ntref localref" style="color:maroon">BindingGuard</a></span>(allowLambda:<span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + | <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) + ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=>"</span></span> { <span class="code-escaped"><a href="#1_stmt" class="ntref localref" style="color:maroon">Stmt</a></span> } } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> .</code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code> statement using the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">IfAlternativeBlock</code> form is similar to the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span> ... fi</code> construct used in the book “A Discipline of Programming” by +Edsger W. Dijkstra. It is used for a multi-branch <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code>. +</p> +<p class="p indent">For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">if</span> { + <span style="color:blue">case</span> x <= y => max <span style="color:blue">:=</span> y; + <span style="color:blue">case</span> y <= x => max <span style="color:blue">:=</span> y; + }</code></pre> +<p class="p noindent para-continued">In this form the expressions following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">case</span></code> keyword are called +<em class="em-low1">guards</em>. The statement is evaluated by evaluating the guards in an +undetermined order until one is found that is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> or else all have +evaluated to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code>. If none of them evaluate to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> then the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code> +statement does nothing. Otherwise the statements to the right of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">=></code> +for the guard that evaluated to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> are executed. +</p><h3 id="sec-while-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.10</span>. </span>While Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_whilestmt" class="ntdef" style="color:olive">WhileStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"while"</span></span> + ( <span class="code-escaped"><a href="#1_loopspecwhile" class="ntref localref" style="color:maroon">LoopSpecWhile</a></span> <span class="code-escaped"><a href="#1_whilealternativeblock" class="ntref localref" style="color:maroon">WhileAlternativeBlock</a></span> + | ( <span class="code-escaped"><a href="#1_guard" class="ntref localref" style="color:maroon">Guard</a></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> ) <span class="code-escaped"><a href="#1_loopspec" class="ntref localref" style="color:maroon">LoopSpec</a></span> + ( <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + | <span style="color:darkgreen">/*</span><span style="color:darkgreen"> go body-less </span><span style="color:darkgreen">*/</span> + ) + ) </code></pre> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_whilealternativeblock" class="ntdef" style="color:olive">WhileAlternativeBlock</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"case"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=>"</span></span> { <span class="code-escaped"><a href="#1_stmt" class="ntref localref" style="color:maroon">Stmt</a></span> } } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> .</code></pre> +<p class="p noindent para-continued">See section <a href="#sec-loop-specification" title="4.5. Loop Specification" class="localref" style="target-element:h2"><span class="heading-label">4.5</span></a> for a description of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_loopspec" class="ntref localref" style="color:maroon">LoopSpec</a></span></code>. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">while</span></code> statement is Dafny's only loop statement. It has two general +forms. +</p> +<p class="p indent">The first form is similar to a while loop in a C-like language. For +example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">var</span> i <span style="color:blue">:=</span> <span class="constant" style="color:purple">0</span>; + <span style="color:blue">while</span> i < <span class="constant" style="color:purple">5</span> { + i <span style="color:blue">:=</span> i + <span class="constant" style="color:purple">1</span>; + }</code></pre> +<p class="p noindent para-continued">In this form the condition following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">while</span></code> is one of these: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">A boolean expression. If true it means execute one more +iteration of the loop. If false then terminate the loop. +</li> +<li class="li ul-li list-star-li compact-li">An asterisk (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code>), meaning non-deterministically yield either +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code> as the value of the condition +</li> +<li class="li ul-li list-star-li compact-li">An ellipsis (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">...</code>), which makes the while statement a <em class="em-low1">skeleton</em> +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">while</span></code> statement. TODO: What does that mean? +</li></ul> + +<p class="p noindent">The <em class="em-low1">body</em> of the loop is usually a block statement, but it can also +be a <em class="em-low1">skeleton</em>, denoted by ellipsis, or missing altogether. +TODO: Wouldn't a missing body cause problems? Isn't it clearer to have +a block statement with no statements inside? +</p> +<p class="p indent">The second form uses the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">WhileAlternativeBlock</code>. It is similar to the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">do ... od</code> construct used in the book “A Discipline of Programming” by +Edsger W. Dijkstra. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">while</span> + <span style="color:purple">decreases</span> <span style="color:blue">if</span> <span class="constant" style="color:purple">0</span> <= r <span style="color:blue">then</span> r <span style="color:blue">else</span> -r; + { + <span style="color:blue">case</span> r < <span class="constant" style="color:purple">0</span> => + r <span style="color:blue">:=</span> r + <span class="constant" style="color:purple">1</span>; + <span style="color:blue">case</span> <span class="constant" style="color:purple">0</span> < r => + r <span style="color:blue">:=</span> r - <span class="constant" style="color:purple">1</span>; + }</code></pre> +<p class="p noindent para-continued">For this form the guards are evaluated in some undetermined order +until one is found that is true, in which case the corresponding statements +are executed. If none of the guards evaluates to true then the +loop execution is terminated. +</p><h4 id="sec-loop-specifications" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">21.10.0</span>. </span>Loop Specifications</h4> +<p class="p noindent">For some simple loops such as those mentioned previously Dafny can figure +out what the loop is doing without more help. However in general the user +must provide more information in order to help Dafny prove the effect of +the loop. This information is provided by a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_loopspec" class="ntref localref" style="color:maroon">LoopSpec</a></span></code>. A +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_loopspec" class="ntref localref" style="color:maroon">LoopSpec</a></span></code> provides information about invariants, termination, and +what the loop modifies. <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_loopspecs" class="ntref localref" style="color:maroon">LoopSpecs</a></span></code> are explained in +section <a href="#sec-loop-specification" title="4.5. Loop Specification" class="localref" style="target-element:h2"><span class="heading-label">4.5</span></a>. However the following sections +present additional rationale and tutorial on loop specifications. +</p><h5 id="sec-loop-invariants" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">21.10.0.0</span>. </span>Loop Invariants</h5> +<p class="p noindent"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">While</code> loops present a problem for Dafny. There is no way for Dafny to +know in advance how many times the code will go around the loop. But +Dafny needs to consider all paths through a program, which could include +going around the loop any number of times. To make it possible for Dafny +to work with loops, you need to provide loop invariants, another kind of +annotation. +</p> +<p class="p indent">A loop invariant is an expression that holds upon entering a loop, and +after every execution of the loop body. It captures something that is +invariant, i.e. does not change, about every step of the loop. Now, +obviously we are going to want to change variables, etc. each time around +the loop, or we wouldn't need the loop. Like pre- and postconditions, an +invariant is a property that is preserved for each execution of the loop, +expressed using the same boolean expressions we have seen. For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> i <span style="color:blue">:=</span> <span class="constant" style="color:purple">0</span>; +<span style="color:blue">while</span> i < n + <span style="color:purple">invariant</span> <span class="constant" style="color:purple">0</span> <= i +{ + i <span style="color:blue">:=</span> i + <span class="constant" style="color:purple">1</span>; +}</code></pre> +<p class="p noindent para-continued">When you specify an invariant, Dafny proves two things: the invariant +holds upon entering the loop, and it is preserved by the loop. By +preserved, we mean that assuming that the invariant holds at the +beginning of the loop, we must show that executing the loop body once +makes the invariant hold again. Dafny can only know upon analyzing the +loop body what the invariants say, in addition to the loop guard (the +loop condition). Just as Dafny will not discover properties of a method +on its own, it will not know any but the most basic properties of a loop +are preserved unless it is told via an invariant. +</p><h5 id="sec-loop-termination" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">21.10.0.1</span>. </span>Loop Termination</h5> +<p class="p noindent">Dafny proves that code terminates, i.e. does not loop forever, by using +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> annotations. For many things, Dafny is able to guess the right +annotations, but sometimes it needs to be made explicit. In fact, for all +of the code we have seen so far, Dafny has been able to do this proof on +its own, which is why we haven't seen the decreases annotation explicitly +yet. There are two places Dafny proves termination: loops and recursion. +Both of these situations require either an explicit annotation or a +correct guess by Dafny. +</p> +<p class="p indent">A <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> annotation, as its name suggests, gives Dafny an expression +that decreases with every loop iteration or recursive call. There are two +conditions that Dafny needs to verify when using a decreases expression: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">that the expression actually gets smaller, and +</li> +<li class="li ul-li list-star-li compact-li">that it is bounded. +</li></ul> + +<p class="p noindent">Many times, an integral value (natural or plain integer) is the quantity +that decreases, but other things that can be used as well. In the case of +integers, the bound is assumed to be zero. For example, the following is +a proper use of decreases on a loop (with its own keyword, of course): +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">while</span> <span class="constant" style="color:purple">0</span> < i + <span style="color:purple">invariant</span> <span class="constant" style="color:purple">0</span> <= i + <span style="color:purple">decreases</span> i + { + i <span style="color:blue">:=</span> i - <span class="constant" style="color:purple">1</span>; + }</code></pre> +<p class="p noindent para-continued">Here Dafny has all the ingredients it needs to prove termination. The +variable i gets smaller each loop iteration, and is bounded below by +zero. This is fine, except the loop is backwards from most loops, which +tend to count up instead of down. In this case, what decreases is not the +counter itself, but rather the distance between the counter and the upper +bound. A simple trick for dealing with this situation is given below: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">while</span> i < n + <span style="color:purple">invariant</span> <span class="constant" style="color:purple">0</span> <= i <= n + <span style="color:purple">decreases</span> n - i + { + i <span style="color:blue">:=</span> i + <span class="constant" style="color:purple">1</span>; + }</code></pre> +<p class="p noindent para-continued">This is actually Dafny's guess for this situation, as it sees <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i < n</code> and +assumes that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n - i</code> is the quantity that decreases. The upper bound of the +loop invariant implies that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= n – i</code>, and gives Dafny a lower bound on +the quantity. This also works when the bound <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">n</code> is not constant, such as +in the binary search algorithm, where two quantities approach each other, +and neither is fixed. +</p> +<p class="p indent">If the <strong class="strong-star2">decreases</strong> clause of a loop specified “*”, then no +termination check will be performed. Use of this feature is sound only with +respect to partial correctness. +</p><h5 id="sec-loop-framing" class="h4" data-heading-depth="4" style="display:block"><span class="heading-before"><span class="heading-label">21.10.0.2</span>. </span>Loop Framing</h5> +<p class="p noindent">In some cases we also must specify what memory locations the loop body +is allowed to modify. This is done using a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">modifies</span></code> clause. +See the discussion of framing in methods for a fuller discussion. +</p><h3 id="sec-match-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.11</span>. </span>Match Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_matchstmt" class="ntdef" style="color:olive">MatchStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"match"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><a href="#1_casestatement" class="ntref localref" style="color:maroon">CaseStatement</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> + | { <span class="code-escaped"><a href="#1_casestatement" class="ntref localref" style="color:maroon">CaseStatement</a></span> } + ) + +<span class="code-escaped"><span id="1_casestatement" class="ntdef" style="color:olive">CaseStatement</span></span> = <span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=>"</span></span> { <span class="code-escaped"><a href="#1_stmt" class="ntref localref" style="color:maroon">Stmt</a></span> } </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">match</span></code> statement is used to do case analysis on a value of inductive +or co-inductive type. The form with no leading <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span></code> is for matching +tuples. The expression after the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">match</span></code> keyword is the (co)inductive +value being matched. The expression is evaluated and then matched against +each of the case clauses. +</p> +<p class="p indent">There must be a case clause for each constructor of the data type. +The identifier after the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">case</span></code> keyword in a case clause, if present, +must be the name of one of the data type's constructors. +If the constructor takes parameters then a parenthesis-enclosed +list of identifiers (with optional type) must follow the +constructor. There must be as many identifiers as the constructor +has parameters. If the optional type is given it must be the same +as the type of the corresponding parameter of the constructor. +If no type is given then the type of the corresponding parameter +is the type assigned to the identifier. +</p> +<p class="p indent">When an inductive value that was created using constructor +expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C1(v1, v2)</code> is matched against a case clause +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C2(x1, x2</code>), there is a match provided that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C1</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">C2</code> are the +same constructor. In that case <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x1</code> is bound to value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">v1</code> and +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x2</code> is bound to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">v2</code>. The identifiers in the case pattern +are not mutable. Here is an example of the use of a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">match</span></code> statement. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Tree = Empty | Node(left: Tree, data: <span style="color:teal">int</span>, right: Tree) + +<span style="color:darkgreen">// Return the sum of the data in a tree.</span> +<span style="color:blue">method</span> Sum(x: Tree) <span style="color:blue">returns</span> (r: <span style="color:teal">int</span>) +{ + <span style="color:blue">match</span> x { + <span style="color:blue">case</span> Empty => r <span style="color:blue">:=</span> -<span class="constant" style="color:purple">1</span>; + <span style="color:blue">case</span> Node(t1 : Tree, d, t2) => { + <span style="color:blue">var</span> v1 <span style="color:blue">:=</span> Sum(t1); + <span style="color:blue">var</span> v2 <span style="color:blue">:=</span> Sum(t2); + r <span style="color:blue">:=</span> v1 + d + v2; + } + } +}</code></pre> +<p class="p noindent para-continued">Note that the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Sum</code> method is recursive yet has no <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> annotation. +In this case it is not needed because Dafny is able to deduce that +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t1</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">t2</code> are <em class="em-low1">smaller</em> (structurally) than <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code>. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Tree</code> had been +coinductive this would not have been possible since <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> might have been +infinite. +</p><h3 id="sec-assert-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.12</span>. </span>Assert Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_assertstmt" class="ntdef" style="color:olive">AssertStmt</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assert"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + ( <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Assert</code> statements are used to express logical proposition that are +expected to be true. Dafny will attempt to prove that the assertion +is true and give an error if not. Once it has proved the assertion +it can then use its truth to aid in following deductions. +Thus if Dafny is having a difficult time verifying a method +the user may help by inserting assertions that Dafny can prove, +and whose true may aid in the larger verification effort. +</p> +<p class="p indent">If the proposition is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">...</code> then (TODO: what does this mean?). +</p><h3 id="sec-assume-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.13</span>. </span>Assume Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_assumestmt" class="ntdef" style="color:olive">AssumeStmt</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"assume"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + ( <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Assume</code> statement lets the user specify a logical proposition +that Dafny may assume to be true without proof. If in fact the +proposition is not true this may lead to invalid conclusions. +</p> +<p class="p indent">An <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Assume</code> statement would ordinarily be used as part of a larger +verification effort where verification of some other part of +the program required the proposition. By using the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Assume</code> statement +the other verification can proceed. Then when that is completed the +user would come back and replace the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">assume</span></code> with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">assert</span></code>. +</p> +<p class="p indent">If the proposition is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">...</code> then (TODO: what does this mean?). +</p><h3 id="sec-print-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.14</span>. </span>Print Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_printstmt" class="ntdef" style="color:olive">PrintStmt</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"print"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">print</span></code> statement is used to print the values of a comma-separated +list of expressions to the console. The generated C# code uses +the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">System.Object.ToString()</code> method to convert the values to printable +strings. The expressions may of course include strings that are used +for captions. There is no implicit new line added, so to get a new +line you should include “\n” as part of one of the expressions. +Dafny automatically creates overrides for the ToString() method +for Dafny data types. For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Tree = Empty | Node(left: Tree, data: <span style="color:teal">int</span>, right: Tree) +<span style="color:blue">method</span> Main() +{ + <span style="color:blue">var</span> x : Tree <span style="color:blue">:=</span> Node(Node(Empty, <span class="constant" style="color:purple">1</span>, Empty), <span class="constant" style="color:purple">2</span>, Empty); + <span style="color:blue">print</span> <span style="color:maroon">"</span><span style="color:maroon">x=</span><span style="color:maroon">"</span>, x, <span style="color:maroon">"</span><span style="color:gray">\n</span><span style="color:maroon">"</span>; +}</code></pre> +<p class="p noindent para-continued">produces this output: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>x=Tree.Node(Tree.Node(Tree.Empty, <span class="constant" style="color:purple">1</span>, Tree.Empty), <span class="constant" style="color:purple">2</span>, Tree.Empty)</code></pre><h3 id="sec-forall-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.15</span>. </span>Forall Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_forallstmt" class="ntdef" style="color:olive">ForallStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"forall"</span></span> + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_quantifierdomain" class="ntref localref" style="color:maroon">QuantifierDomain</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + | [ <span class="code-escaped"><a href="#1_quantifierdomain" class="ntref localref" style="color:maroon">QuantifierDomain</a></span> ] + ) + { [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"free"</span></span> ] <span class="code-escaped"><a href="#1_forallensuresclause_" class="ntref localref" style="color:maroon">ForAllEnsuresClause_</a></span> } + [ <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> ] </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement executes ensures expressions or a body in +parallel for all quantified values in the specified range. +The use of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">parallel</code> keyword is deprecated. Use +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> instead. There are several variant uses of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> +statement. And there are a number of restrictions. +</p> +<p class="p indent">In particular a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement can be classified as one of the following: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><em class="em-low1">Assign</em> - the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement is used for simultaneous assignment. +The target must be an array element or an object field. +</li> +<li class="li ul-li list-star-li compact-li"><em class="em-low1">Call</em> - The body consists of a single call to a method without side effects +</li> +<li class="li ul-li list-star-li compact-li"><em class="em-low1">Proof</em> - The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> has <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">ensure</code> expressions which are effectively +quantified or proved by the body (if present). +</li></ul> + +<p class="p noindent">An <em class="em-low1">assign</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement is to perform simultaneous assignment. +The following is an excerpt of an example given by Leino in +<a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml233.pdf" data-linkid="leino233">Developing Verified Programs with Dafny</a>. +When the buffer holding the queue needs to be resized, +the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement is used to simultaneously copy the old contents +into the new buffer. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> {<span style="color:purple">:autocontracts</span>} SimpleQueue<Data> +{ + <span style="color:blue">ghost</span> <span style="color:blue">var</span> Contents: <span style="color:teal">seq</span><Data>; + <span style="color:blue">var</span> a: <span style="color:teal">array</span><Data>; <span style="color:darkgreen">// Buffer holding contents of queue.</span> + <span style="color:blue">var</span> m: <span style="color:teal">int</span> <span style="color:darkgreen">// Index head of queue.</span> + <span style="color:blue">var</span> n: <span style="color:teal">int</span>; <span style="color:darkgreen">// Index just past end of queue</span> + ... + <span style="color:blue">method</span> Enqueue(d: Data) + <span style="color:purple">ensures</span> Contents == <span style="color:blue">old</span>(Contents) + [d] + { + <span style="color:blue">if</span> n == a.Length { + <span style="color:blue">var</span> b <span style="color:blue">:=</span> a; + <span style="color:blue">if</span> m == <span class="constant" style="color:purple">0</span> { b <span style="color:blue">:=</span> <span style="color:blue">new</span> Data[<span class="constant" style="color:purple">2</span> * a.Length]; } + <span style="color:blue">forall</span> (i | <span class="constant" style="color:purple">0</span> <= i < n - m) { + b[i] <span style="color:blue">:=</span> a[m + i]; + } + a, m, n <span style="color:blue">:=</span> b, <span class="constant" style="color:purple">0</span>, n - m; + } + a[n], n, Contents <span style="color:blue">:=</span> d, n + <span class="constant" style="color:purple">1</span>, Contents + [d]; + } +}</code></pre> +<p class="p noindent para-continued">Here is an example of a <em class="em-low1">call</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement and the +callee. This is contained in the CloudMake-ConsistentBuilds.dfy +test in the Dafny repository. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> (cmd', deps', e' | Hash(Loc(cmd', deps', e')) == Hash(Loc(cmd, deps, e))) { + HashProperty(cmd', deps', e', cmd, deps, e); +} + +<span style="color:blue">ghost</span> <span style="color:blue">method</span> HashProperty(cmd: Expression, deps: Expression, ext: <span style="color:teal">string</span>, + cmd': Expression, deps': Expression, ext': <span style="color:teal">string</span>) + <span style="color:purple">requires</span> Hash(Loc(cmd, deps, ext)) == Hash(Loc(cmd', deps', ext')) + <span style="color:purple">ensures</span> cmd == cmd' && deps == deps' && ext == ext'</code></pre> +<p class="p noindent para-continued">From the same file here is an example of a <em class="em-low1">proof</em> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> (p | p <span style="color:blue">in</span> DomSt(stCombinedC.st) && p <span style="color:blue">in</span> DomSt(stExecC.st)) + <span style="color:purple">ensures</span> GetSt(p, stCombinedC.st) == GetSt(p, stExecC.st) +{ + <span style="color:blue">assert</span> DomSt(stCombinedC.st) <= DomSt(stExecC.st); + <span style="color:blue">assert</span> stCombinedC.st == Restrict(DomSt(stCombinedC.st), stExecC.st); +}</code></pre> +<p class="p noindent para-continued">More generally the statement +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> x | P(x) { Lemma(x); }</code></pre> +<p class="p noindent para-continued">is used to invoke <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Lemma(x)</code> on all <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> for which <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(x)</code> holds. If +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Lemma(x)</code> ensures <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q(x)</code>, then the forall statement establishes +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">forall</span> x :: P(x) ==> Q(x).</code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement is also used extensively in the desugared forms of +co-predicates and co-lemmas. See section <a href="#sec-co-inductive-datatypes" title="18.2. Co-inductive datatypes" class="localref" style="target-element:h2"><span class="heading-label">18.2</span></a>. +</p> +<p class="p indent">TODO: List all of the restrictions on the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">forall</span></code> statement. +</p><h3 id="sec-modify-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.16</span>. </span>Modify Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_modifystmt" class="ntdef" style="color:olive">ModifyStmt</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"modify"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + ( <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_frameexpression" class="ntref localref" style="color:maroon">FrameExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + ) + ( <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> ) </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement has two forms which have two different +purposes. +</p> +<p class="p indent">When the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement ends with a semi-colon rather than +a block statement its effect is to say that some undetermined +modifications have been made to any or all of the memory +locations specified by the <a href="#sec-frame-expressions" class="localref">frame expressions</a>. +In the following example, a value is assigned to field <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> +followed by a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement that may modify any field +in the object. After that we can no longer prove that the field +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> still has the value we assigned to it. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> MyClass { + <span style="color:blue">var</span> x: <span style="color:teal">int</span>; + <span style="color:blue">method</span> N() + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + x <span style="color:blue">:=</span> <span class="constant" style="color:purple">18</span>; + <span style="color:blue">modify</span> <span style="color:blue">this</span>; + <span style="color:blue">assert</span> x == <span class="constant" style="color:purple">18</span>; <span style="color:darkgreen">// error: cannot conclude this here</span> + } +}</code></pre> +<p class="p noindent para-continued">When the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement is followed by a block statement +we are instead specifying what can be modified in that +block statement. Namely, only memory locations specified +by the frame expressions of the block <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement +may be modified. Consider the following example. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">class</span> ModifyBody { + <span style="color:blue">var</span> x: <span style="color:teal">int</span>; + <span style="color:blue">var</span> y: <span style="color:teal">int</span>; + <span style="color:blue">method</span> M0() + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + <span style="color:blue">modify</span> {} { + x <span style="color:blue">:=</span> <span class="constant" style="color:purple">3</span>; <span style="color:darkgreen">// error: violates modifies clause of the modify statement</span> + } + } + <span style="color:blue">method</span> M1() + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + <span style="color:blue">modify</span> {} { + <span style="color:blue">var</span> o <span style="color:blue">:=</span> <span style="color:blue">new</span> ModifyBody; + o.x <span style="color:blue">:=</span> <span class="constant" style="color:purple">3</span>; <span style="color:darkgreen">// fine</span> + } + } + <span style="color:blue">method</span> M2() + <span style="color:purple">modifies</span> <span style="color:blue">this</span> + { + <span style="color:blue">modify</span> <span style="color:blue">this</span> { + x <span style="color:blue">:=</span> <span class="constant" style="color:purple">3</span>; + } + } +}</code></pre> +<p class="p noindent para-continued">The first <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement in the example has an empty +frame expression so it cannot modify any memory locations. +So an error is reported when it tries to modify field <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code>. +</p> +<p class="p indent">The second <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement also has an empty frame +expression. But it allocates a new object and modifies it. +Thus we see that the frame expressions on a block <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> +statement only limits what may be modified of existing +memory. It does not limit what may be modified in +new memory that is allocated. +</p> +<p class="p indent">The third <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">modify</span></code> statement has a frame expression that +allows it to modify any of the fields of the current object, +so the modification of field <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> is allowed. +</p><h3 id="sec-calc-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.17</span>. </span>Calc Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_calcstmt" class="ntdef" style="color:olive">CalcStmt</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"calc"</span></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } [ <span class="code-escaped"><a href="#1_calcop" class="ntref localref" style="color:maroon">CalcOp</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> <span class="code-escaped"><a href="#1_calcbody" class="ntref localref" style="color:maroon">CalcBody</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> +<span class="code-escaped"><span id="1_calcbody" class="ntdef" style="color:olive">CalcBody</span></span> = { <span class="code-escaped"><a href="#1_calcline" class="ntref localref" style="color:maroon">CalcLine</a></span> [ <span class="code-escaped"><a href="#1_calcop" class="ntref localref" style="color:maroon">CalcOp</a></span> ] <span class="code-escaped"><a href="#1_hints" class="ntref localref" style="color:maroon">Hints</a></span> } +<span class="code-escaped"><span id="1_calcline" class="ntdef" style="color:olive">CalcLine</span></span> = <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> +<span class="code-escaped"><span id="1_hints" class="ntdef" style="color:olive">Hints</span></span> = { ( <span class="code-escaped"><a href="#1_blockstmt" class="ntref localref" style="color:maroon">BlockStmt</a></span> | <span class="code-escaped"><a href="#1_calcstmt" class="ntref localref" style="color:maroon">CalcStmt</a></span> ) } +<span class="code-escaped"><span id="1_calcop" class="ntdef" style="color:olive">CalcOp</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=="</span></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"#"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> ] + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"!="</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<="</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">="</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<==>"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"==>"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<=="</span></span> + ) </code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statement supports <em class="em-low1">calculational proofs</em> using a language feature called <em class="em-low1">program-oriented calculations</em> (poC). This feature was introduced and explained in the <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf" data-linkid="verified calculations">Verified Calculations</a> paper by +Leino and Polikarpova<span class="citations" style="target-element:bibitem">[<a href="#leino:dafny:calc" title="K. Rustan M. Leino and Nadia Polikarpova. +Verified calculations." class="bibref localref" style="target-element:bibitem"><span class="cite-number">22</span></a>]</span>. Please see that paper for a more complete explanation +of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statement. We here mention only the highlights. +</p> +<p class="p noindent">Calculational proofs are proofs by stepwise formula manipulation +as is taught in elementary algebra. The typical example is to prove +an equality by starting with a left-hand-side, and through a series of +transformations morph it into the desired right-hand-side. +</p> +<p class="p indent">Non-syntactic rules further restrict hints to only ghost and side-effect +free statements, as well as impose a constraint that only +chain-compatible operators can be used together in a calculation. The +notion of chain-compatibility is quite intuitive for the operators +supported by poC; for example, it is clear that “<” and “>” cannot be used within +the same calculation, as there would be no relation to conclude between +the first and the last line. See the <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf" data-linkid="verified calculations">paper</a> for +a more formal treatment of chain-compatibility. +</p> +<p class="p indent">Note that we allow a single occurrence of the intransitive operator “!=” to +appear in a chain of equalities (that is, “!=” is chain-compatible with +equality but not with any other operator, including itself). Calculations +with fewer than two lines are allowed, but have no effect. If a step +operator is omitted, it defaults to the calculation-wide operator, +defined after the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> keyword. If that operator if omitted, it defaults +to equality. +</p> +<p class="p indent">Here is an example using <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statements to prove an elementary +algebraic identity. As it turns out Dafny is able to prove this without +the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statements, but it helps to illustrate the syntax. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">lemma</span> docalc(x : <span style="color:teal">int</span>, y: <span style="color:teal">int</span>) + <span style="color:purple">ensures</span> (x + y) * (x + y) == x * x + <span class="constant" style="color:purple">2</span> * x * y + y * y +{ + <span style="color:blue">calc</span> { + (x + y) * (x + y); == + <span style="color:darkgreen">// distributive law: (a + b) * c == a * c + b * c</span> + x * (x + y) + y * (x + y); == + <span style="color:darkgreen">// distributive law: a * (b + c) == a * b + a * c</span> + x * x + x * y + y * x + y * y; == + <span style="color:blue">calc</span> { + y * x; == + x * y; + } + x * x + x * y + x * y + y * y; == + <span style="color:blue">calc</span> { + x * y + x * y; == + <span style="color:darkgreen">// a = 1 * a</span> + <span class="constant" style="color:purple">1</span> * x * y + <span class="constant" style="color:purple">1</span> * x * y; == + <span style="color:darkgreen">// Distributive law</span> + (<span class="constant" style="color:purple">1</span> + <span class="constant" style="color:purple">1</span>) * x * y; == + <span class="constant" style="color:purple">2</span> * x * y; + } + x * x + <span class="constant" style="color:purple">2</span> * x * y + y * y; + } +}</code></pre> +<p class="p noindent para-continued">Here we started with <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(x + y) * (x + y)</code> as the left-hand-side +expressions and gradually transformed it using distributive, +commutative and other laws into the desired right-hand-side. +</p> +<p class="p indent">The justification for the steps are given as comments, or as +nested <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statements that prove equality of some sub-parts +of the expression. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code> to the right of the semicolons show the relation between +that expression and the next. Because of the transitivity of +equality we can then conclude that the original left-hand-side is +equal to the final expression. +</p> +<p class="p indent">We can avoid having to supply the relational operator between +every pair of expressions by giving a default operator between +the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> keyword and the opening brace as shown in this abbreviated +version of the above calc statement: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">calc</span> == { + (x + y) * (x + y); + x * (x + y) + y * (x + y); + x * x + x * y + y * x + y * y; + x * x + x * y + x * y + y * y; + x * x + <span class="constant" style="color:purple">2</span> * x * y + y * y; +}</code></pre> +<p class="p noindent para-continued">And since equality is the default operator we could have omitted +it after the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> keyword. +The purpose of the block statements or the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statements between +the expressions is to provide hints to aid Dafny in proving that +step. As shown in the example, comments can also be used to aid +the human reader in cases where Dafny can prove the step automatically. + +</p><h3 id="sec-skeleton-statement" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">21.18</span>. </span>Skeleton Statement</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_skeletonstmt" class="ntdef" style="color:olive">SkeletonStmt</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"…"</span></span> + [<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"where"</span></span> <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> {<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + {<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } + ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> </code></pre><h2 id="sec-expressions" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">22</span>. </span>Expressions</h2> +<p class="p noindent">The grammar of Dafny expressions follows a hierarchy that +reflects the precedence of Dafny operators. The following +table shows the Dafny operators and their precedence +in order of increasing binding power. +</p><table class="madoko block"> +<thead><tr><th class="thead tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></th><th class="thead tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></th></tr> +<tr><th class="col cell-border-left thead tr-odd tr-last tr-first col-odd col-first" data-row="1" data-col="1" style="font-weight:bold"> operator </th><th class="col cell-border-left cell-border-right thead tr-odd tr-last tr-first col-even col-last" data-row="1" data-col="2" style="font-weight:bold"> description </th></tr></thead> +<tbody><tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="0" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="0" data-col="2"></td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left col-odd col-first" data-row="1" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">;</code> </td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right col-even col-last" data-row="1" data-col="2"> In LemmaCall;Expression </td></tr> +<tr><td class="tbody tr-odd tr-first col cell-border-left cell-line col-odd col-first" data-row="1" data-col="1"></td><td class="tbody tr-odd tr-first col cell-border-left cell-border-right cell-line col-even col-last" data-row="1" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="2" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==></code>, ⇔ </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="2" data-col="2"> equivalence (if and only if) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="2" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="2" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="3" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==></code>, ⇒ </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="3" data-col="2"> implication (implies) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="4" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==</code>, ⇐ </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="4" data-col="2"> reverse implication (follows from) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="4" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="4" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="5" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">&&</code>, ∧ </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="5" data-col="2"> conjunction (and) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="6" data-col="1"> <span class="monospace">||</span>, ∨ </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="6" data-col="2"> disjunction (or) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="6" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="6" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="7" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!</code>, ¬ </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="7" data-col="2"> negation (not) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="7" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="7" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="8" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="8" data-col="2"> equality </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="9" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==#[k]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="9" data-col="2"> prefix equality (co-inductive) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="10" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="10" data-col="2"> disequality </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="11" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!=#[k]</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="11" data-col="2"> prefix disequality (co-inductive) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="12" data-col="1"> <span class="monospace"><</span> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="12" data-col="2"> less than </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="13" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="13" data-col="2"> at most </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="14" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="14" data-col="2"> at least </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="15" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="15" data-col="2"> greater than </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="16" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">in</span></code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="16" data-col="2"> collection membership </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="17" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!<span style="color:blue">in</span></code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="17" data-col="2"> collection non-membership </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="18" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!!</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="18" data-col="2"> disjointness </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="18" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="18" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="19" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">+</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="19" data-col="2"> addition (plus) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="20" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="20" data-col="2"> subtraction (minus) </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="20" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="20" data-col="2"></td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="21" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="21" data-col="2"> multiplication (times) </td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="22" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">/</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="22" data-col="2"> division (divided by) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="23" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">%</code> </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="23" data-col="2"> modulus (mod) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left cell-line col-odd col-first" data-row="23" data-col="1"></td><td class="tbody tr-odd col cell-border-left cell-border-right cell-line col-even col-last" data-row="23" data-col="2"></td></tr> +<tr><td class="tbody tr-even col cell-border-left col-odd col-first" data-row="24" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">-</code> </td><td class="tbody tr-even col cell-border-left cell-border-right col-even col-last" data-row="24" data-col="2"> arithmetic negation (unary minus) </td></tr> +<tr><td class="tbody tr-odd col cell-border-left col-odd col-first" data-row="25" data-col="1"> <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!</code>, ¬ </td><td class="tbody tr-odd col cell-border-left cell-border-right col-even col-last" data-row="25" data-col="2"> logical negation </td></tr> +<tr><td class="tbody tr-even tr-last col cell-border-left col-odd col-first" data-row="26" data-col="1"> Primary Expressions </td><td class="tbody tr-even tr-last col cell-border-left cell-border-right col-even col-last" data-row="26" data-col="2"> </td></tr> +<tr><td class="tbody tr-even col cell-border-left cell-line col-odd col-first" data-row="26" data-col="1"></td><td class="tbody tr-even col cell-border-left cell-border-right cell-line col-even col-last" data-row="26" data-col="2"></td></tr></tbody></table> +<p class="p noindent">We are calling the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span></code>s that are neither +arithmetic nor logical negation the <em class="em-low1">primary expressions</em>. +They are the most tightly bound. +</p> +<p class="p indent">In the grammar entries below we explain the meaning when the +operator for that precedence level is present. If the +operator is not present then we just descend to the +next precedence level. +</p><h3 id="sec-top-level-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.0</span>. </span>Top-level expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_expression" class="ntdef" style="color:olive">Expression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_equivexpression" class="ntref localref" style="color:maroon">EquivExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) ] </code></pre> +<p class="p noindent para-continued">The “allowLemma” argument says whether or not the expression +to be parsed is allowed to have the form S;E where S is a call to a lemma. +“allowLemma” should be passed in as “false” whenever the expression to +be parsed sits in a context that itself is terminated by a semi-colon. +</p> +<p class="p indent">The “allowLambda” says whether or not the expression to be parsed is +allowed to be a lambda expression. More precisely, an identifier or +parenthesized-enclosed comma-delimited list of identifiers is allowed to +continue as a lambda expression (that is, continue with a “reads”, “requires”, +or “=>”) only if “allowLambda” is true. This affects function/method/iterator +specifications, if/while statements with guarded alternatives, and expressions +in the specification of a lambda expression itself. +</p> +<p class="p indent">Sometimes an expression will fail unless some relevant fact is known. +In the following example the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F_Fails</code> function fails to verify +because the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Fact(n)</code> divisor may be zero. But preceding +the expression by a lemma that ensures that the denominator +is not zero allows function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F_Succeeds</code> to succeed. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> Fact(n: <span style="color:teal">nat</span>): <span style="color:teal">nat</span> +{ + <span style="color:blue">if</span> n == <span class="constant" style="color:purple">0</span> <span style="color:blue">then</span> <span class="constant" style="color:purple">1</span> <span style="color:blue">else</span> n * Fact(n-<span class="constant" style="color:purple">1</span>) +} + +<span style="color:blue">lemma</span> L(n: <span style="color:teal">nat</span>) + <span style="color:purple">ensures</span> <span class="constant" style="color:purple">1</span> <= Fact(n) +{ +} + +<span style="color:blue">function</span> F_Fails(n: <span style="color:teal">nat</span>): <span style="color:teal">int</span> +{ + <span class="constant" style="color:purple">50</span> / Fact(n) <span style="color:darkgreen">// error: possible division by zero</span> +} + +<span style="color:blue">function</span> F_Succeeds(n: <span style="color:teal">nat</span>): <span style="color:teal">int</span> +{ + L(n); + <span class="constant" style="color:purple">50</span> / Fact(n) +}</code></pre><h3 id="sec-equivalence-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.1</span>. </span>Equivalence Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_equivexpression" class="ntdef" style="color:olive">EquivExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_impliesexpliesexpression" class="ntref localref" style="color:maroon">ImpliesExpliesExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<==>"</span></span> <span class="code-escaped"><a href="#1_impliesexpliesexpression" class="ntref localref" style="color:maroon">ImpliesExpliesExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } </code></pre> +<p class="p noindent para-continued">An <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_equivexpression" class="ntref localref" style="color:maroon">EquivExpression</a></span></code> that contains one or more “<==>”s is +a boolean expression and all the contained <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_impliesexpliesexpression" class="ntref localref" style="color:maroon">ImpliesExpliesExpression</a></span></code> +must also be boolean expressions. In that case each “<==>” +operator tests for logical equality which is the same as +ordinary equality. +</p> +<p class="p indent">See section <a href="#sec-equivalence-operator" title="6.0.0. Equivalence Operator" class="localref" style="target-element:h3"><span class="heading-label">6.0.0</span></a> for an explanation of the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==></code> operator as compared with the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code> operator. +</p><h3 id="sec-implies-or-explies-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.2</span>. </span>Implies or Explies Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_impliesexpliesexpression" class="ntdef" style="color:olive">ImpliesExpliesExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_logicalexpression" class="ntref localref" style="color:maroon">LogicalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"==>"</span></span> <span class="code-escaped"><a href="#1_impliesexpression" class="ntref localref" style="color:maroon">ImpliesExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<=="</span></span> <span class="code-escaped"><a href="#1_logicalexpression" class="ntref localref" style="color:maroon">LogicalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<=="</span></span> <span class="code-escaped"><a href="#1_logicalexpression" class="ntref localref" style="color:maroon">LogicalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } + ) + ] + +<span class="code-escaped"><span id="1_impliesexpression" class="ntdef" style="color:olive">ImpliesExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_logicalexpression" class="ntref localref" style="color:maroon">LogicalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"==>"</span></span> <span class="code-escaped"><a href="#1_impliesexpression" class="ntref localref" style="color:maroon">ImpliesExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) ] </code></pre> +<p class="p noindent para-continued">See section <a href="#sec-implication-and-reverse-implication" title="6.0.2. Implication and Reverse Implication" class="localref" style="target-element:h3"><span class="heading-label">6.0.2</span></a> for an explanation +of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><==</code> operators. +</p><h3 id="sec-logical-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.3</span>. </span>Logical Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_logicalexpression" class="ntdef" style="color:olive">LogicalExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_relationalexpression" class="ntref localref" style="color:maroon">RelationalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"&&"</span></span> <span class="code-escaped"><a href="#1_relationalexpression" class="ntref localref" style="color:maroon">RelationalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"&&"</span></span> <span class="code-escaped"><a href="#1_relationalexpression" class="ntref localref" style="color:maroon">RelationalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } + | <span style="color:maroon">"</span><span style="color:maroon">||</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_relationalexpression" class="ntref localref" style="color:maroon">RelationalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span style="color:maroon">"</span><span style="color:maroon">||</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_relationalexpression" class="ntref localref" style="color:maroon">RelationalExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } + ) + ] </code></pre> +<p class="p noindent para-continued">See section <a href="#sec-conjunction-and-disjunction" title="6.0.1. Conjunction and Disjunction" class="localref" style="target-element:h3"><span class="heading-label">6.0.1</span></a> for an explanation +of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">&&</code> (or ∧) and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">||</code> (or ∨) operators. +</p><h3 id="sec-relational-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.4</span>. </span>Relational Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_relationalexpression" class="ntdef" style="color:olive">RelationalExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_term" class="ntref localref" style="color:maroon">Term</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ <span class="code-escaped"><a href="#1_relop" class="ntref localref" style="color:maroon">RelOp</a></span> <span class="code-escaped"><a href="#1_term" class="ntref localref" style="color:maroon">Term</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><a href="#1_relop" class="ntref localref" style="color:maroon">RelOp</a></span> <span class="code-escaped"><a href="#1_term" class="ntref localref" style="color:maroon">Term</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } ] + +<span class="code-escaped"><span id="1_relop" class="ntdef" style="color:olive">RelOp</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=="</span></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"#"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> ] + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"<="</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">">="</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"!="</span></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"#"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> ] + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"in"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"!in"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"!!"</span></span> + ) + </code></pre> +<p class="p noindent para-continued">The relation expressions that have a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_relop" class="ntref localref" style="color:maroon">RelOp</a></span></code> compare two or more terms. +As explained in section <a href="#sec-basic-types" title="6. Basic types" class="localref" style="target-element:h1"><span class="heading-label">6</span></a>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">==</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!=</code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">></code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><=</code>, and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">>=</code> +and their corresponding Unicode equivalents are <em class="em-low1">chaining</em>. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">in</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!<span style="color:blue">in</span></code> operators apply to collection types as explained in +section <a href="#sec-collection-types" title="9. Collection types" class="localref" style="target-element:h1"><span class="heading-label">9</span></a> and represent membership or non-membership +respectively. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!!</code> represents disjointness for sets and multisets as explained in +sections <a href="#sec-sets" title="9.0. Sets" class="localref" style="target-element:h2"><span class="heading-label">9.0</span></a> and <a href="#sec-multisets" title="9.1. Multisets" class="localref" style="target-element:h2"><span class="heading-label">9.1</span></a>. +</p> +<p class="p indent">Note that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x ==#[k] y</code> is the prefix equality operator that compares +co-inductive values for equality to a nesting level of k, as +explained in section <a href="#sec-co-equality" title="18.2.3.0. Co-Equality" class="localref" style="target-element:h4"><span class="heading-label">18.2.3.0</span></a>. +</p><h3 id="sec-terms" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.5</span>. </span>Terms</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_term" class="ntdef" style="color:olive">Term</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_factor" class="ntref localref" style="color:maroon">Factor</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><a href="#1_addop" class="ntref localref" style="color:maroon">AddOp</a></span> <span class="code-escaped"><a href="#1_factor" class="ntref localref" style="color:maroon">Factor</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } +<span class="code-escaped"><span id="1_addop" class="ntdef" style="color:olive">AddOp</span></span> = ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"+"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"-"</span></span> ) </code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Terms</code> combine <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Factors</code> by adding or subtracting. +Addition has these meanings for different types: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">Arithmetic addition for numeric types (section <a href="#sec-numeric-types" title="6.1. Numeric types" class="localref" style="target-element:h2"><span class="heading-label">6.1</span></a>). +</li> +<li class="li ul-li list-star-li compact-li">Union for sets and multisets (sections <a href="#sec-sets" title="9.0. Sets" class="localref" style="target-element:h2"><span class="heading-label">9.0</span></a> and <a href="#sec-multisets" title="9.1. Multisets" class="localref" style="target-element:h2"><span class="heading-label">9.1</span></a>) +</li> +<li class="li ul-li list-star-li compact-li">Concatenation for sequences (section <a href="#sec-sequences" title="9.2. Sequences" class="localref" style="target-element:h2"><span class="heading-label">9.2</span></a>) +</li></ul> + +<p class="p noindent">Subtraction is arithmetic subtraction for numeric types, and set or multiset +difference for sets and multisets. +</p><h3 id="sec-factors" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.6</span>. </span>Factors</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_factor" class="ntdef" style="color:olive">Factor</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + { <span class="code-escaped"><a href="#1_mulop" class="ntref localref" style="color:maroon">MulOp</a></span> <span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } +<span class="code-escaped"><span id="1_mulop" class="ntdef" style="color:olive">MulOp</span></span> = ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"/"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"%"</span></span> ) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_factor" class="ntref localref" style="color:maroon">Factor</a></span></code> combines <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span></code>s using multiplication, +division, or modulus. For numeric types these are explained in +section <a href="#sec-numeric-types" title="6.1. Numeric types" class="localref" style="target-element:h2"><span class="heading-label">6.1</span></a>. +</p> +<p class="p indent">Only <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">*</code> has a non-numeric application. It represents set or multiset +intersection as explained in sections <a href="#sec-sets" title="9.0. Sets" class="localref" style="target-element:h2"><span class="heading-label">9.0</span></a> and <a href="#sec-multisets" title="9.1. Multisets" class="localref" style="target-element:h2"><span class="heading-label">9.1</span></a>. +</p><h3 id="sec-unary-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.7</span>. </span>Unary Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_unaryexpression" class="ntdef" style="color:olive">UnaryExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"-"</span></span> <span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"!"</span></span> <span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_primaryexpression_" class="ntref localref" style="color:maroon">PrimaryExpression_</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + ) + </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_unaryexpression" class="ntref localref" style="color:maroon">UnaryExpression</a></span></code> applies either numeric (section <a href="#sec-numeric-types" title="6.1. Numeric types" class="localref" style="target-element:h2"><span class="heading-label">6.1</span></a>) +or logical (section <a href="#sec-booleans" title="6.0. Booleans" class="localref" style="target-element:h2"><span class="heading-label">6.0</span></a>) negation to its operand. +</p><h3 id="sec-primary-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.8</span>. </span>Primary Expressions</h3><!-- These are introduced for explanatory purposes as are not in the grammar. --> + + +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_primaryexpression_" class="ntdef" style="color:olive">PrimaryExpression_</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><a href="#1_mapdisplayexpr" class="ntref localref" style="color:maroon">MapDisplayExpr</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_lambdaexpression" class="ntref localref" style="color:maroon">LambdaExpression</a></span>(allowLemma) + | <span class="code-escaped"><a href="#1_endlessexpression" class="ntref localref" style="color:maroon">EndlessExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_seqdisplayexpr" class="ntref localref" style="color:maroon">SeqDisplayExpr</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_setdisplayexpr" class="ntref localref" style="color:maroon">SetDisplayExpr</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_multisetexpr" class="ntref localref" style="color:maroon">MultiSetExpr</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_constatomexpression" class="ntref localref" style="color:maroon">ConstAtomExpression</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + ) + </code></pre> +<p class="p noindent para-continued">After descending through all the binary and unary operators we arrive at +the primary expressions which are explained in subsequent sections. As +can be seen, a number of these can be followed by 0 or more <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code>es +to select a component of the value. +</p> +<p class="p indent">If the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">allowLambda</code> is false then <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_lambdaexpression" class="ntref localref" style="color:maroon">LambdaExpression</a></span></code>s are not +recognized in this context. +</p><h3 id="sec-lambda-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.9</span>. </span>Lambda expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_lambdaexpression" class="ntdef" style="color:olive">LambdaExpression</span></span>(allowLemma) = + ( <span class="code-escaped"><a href="#1_wildident" class="ntref localref" style="color:maroon">WildIdent</a></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + ) + <span class="code-escaped"><a href="#1_lambdaspec_" class="ntref localref" style="color:maroon">LambdaSpec_</a></span> + <span class="code-escaped"><a href="#1_lambdaarrow" class="ntref localref" style="color:maroon">LambdaArrow</a></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + +<span class="code-escaped"><span id="1_lambdaarrow" class="ntdef" style="color:olive">LambdaArrow</span></span> = ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=>"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"->"</span></span> ) </code></pre> +<p class="p noindent para-continued">See section <a href="#sec-lambda-specification" title="4.3. Lambda Specification" class="localref" style="target-element:h2"><span class="heading-label">4.3</span></a> for a description of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_lambdaspec" class="ntref localref" style="color:maroon">LambdaSpec</a></span></code>. +</p> +<p class="p indent">In addition to named functions, Dafny supports expressions that define +functions. These are called <em class="em-low1">lambda (expression)s</em> (some languages +know them as <em class="em-low1">anonymous functions</em>). A lambda expression has the +form: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>(<span class="code-escaped"><em class="em-low1">params</em></span>) <span class="code-escaped"><em class="em-low1">specification</em></span> => <span class="code-escaped"><em class="em-low1">body</em></span></code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">params</em></span></code> is a comma-delimited list of parameter +declarations, each of which has the form <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x: T</code>. The type <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">T</code> +of a parameter can be omitted when it can be inferred. If the +identifier <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> is not needed, it can be replaced by “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_</code>”. If +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">params</em></span></code> consists of a single parameter <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x</code> (or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_</code>) without an +explicit type, then the parentheses can be dropped; for example, the +function that returns the successor of a given integer can be written +as the following lambda expression: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>x => x + <span class="constant" style="color:purple">1</span></code></pre> +<p class="p noindent para-continued">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">specification</em></span></code> is a list of clauses <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span> E</code> or +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span> W</code>, where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">E</code> is a boolean expression and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">W</code> is a frame +expression. +</p> +<p class="p indent"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="code-escaped"><em class="em-low1">body</em></span></code> is an expression that defines the function's return +value. The body must be well-formed for all possible values of the +parameters that satisfy the precondition (just like the bodies of +named functions and methods). In some cases, this means it is +necessary to write explicit <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code> clauses. For +example, the lambda expression +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>x <span style="color:purple">requires</span> x != <span class="constant" style="color:purple">0</span> => <span class="constant" style="color:purple">100</span> / x</code></pre> +<p class="p noindent para-continued">would not be well-formed if the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> clause were omitted, +because of the possibility of division-by-zero. +</p> +<p class="p indent">In settings where functions cannot be partial and there are no +restrictions on reading the heap, the <em class="em-low1">eta expansion</em> of a function +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F: T -> U</code> (that is, the wrapping of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> inside a lambda expression +in such a way that the lambda expression is equivalent to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code>) would +be written <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x => F(x)</code>. In Dafny, eta expansion must also account for +the precondition and reads set of the function, so the eta expansion +of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">F</code> looks like: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>x <span style="color:purple">requires</span> F.<span style="color:purple">requires</span>(x) <span style="color:purple">reads</span> F.<span style="color:purple">reads</span>(x) => F(x)</code></pre><h3 id="sec-left-hand-side-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.10</span>. </span>Left-Hand-Side Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_lhs" class="ntdef" style="color:olive">Lhs</span></span> = + ( <span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + | <span class="code-escaped"><a href="#1_constatomexpression" class="ntref localref" style="color:maroon">ConstAtomExpression</a></span> <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> { <span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span> } + ) </code></pre> +<p class="p noindent para-continued">A left-hand-side expression is only used on the left hand +side of an <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_updatestmt" class="ntref localref" style="color:maroon">UpdateStmt</a></span></code>. +</p> +<p class="p indent">TODO: Try to give examples showing how these kinds of +left-hand-sides are possible. +</p><h3 id="sec-right-hand-side-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.11</span>. </span>Right-Hand-Side Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_rhs" class="ntdef" style="color:olive">Rhs</span></span> = + ( <span class="code-escaped"><a href="#1_arrayallocation_" class="ntref localref" style="color:maroon">ArrayAllocation_</a></span> + | <span class="code-escaped"><a href="#1_objectallocation_" class="ntref localref" style="color:maroon">ObjectAllocation_</a></span> + | <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + | <span class="code-escaped"><a href="#1_havocrhs_" class="ntref localref" style="color:maroon">HavocRhs_</a></span> + ) + { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } </code></pre> +<p class="p noindent para-continued">An <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_rhs" class="ntref localref" style="color:maroon">Rhs</a></span></code> is either array allocation, an object allocation, +an expression, or a havoc right-hand-side, optionally followed +by one or more <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span></code>s. +</p> +<p class="p indent">Right-hand-side expressions appear in the following constructs: +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_returnstmt" class="ntref localref" style="color:maroon">ReturnStmt</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_yieldstmt" class="ntref localref" style="color:maroon">YieldStmt</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_updatestmt" class="ntref localref" style="color:maroon">UpdateStmt</a></span></code>, or <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_vardeclstatement" class="ntref localref" style="color:maroon">VarDeclStatement</a></span></code>. +These are the only contexts in which arrays or objects may be +allocated, or in which havoc may be produced. +</p><h3 id="sec-array-allocation" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.12</span>. </span>Array Allocation</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_arrayallocation_" class="ntdef" style="color:olive">ArrayAllocation_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"new"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">This allocates a new single or multi-dimensional array as explained in +section <a href="#sec-array-types" title="14. Array Types" class="localref" style="target-element:h1"><span class="heading-label">14</span></a>. +</p><h3 id="sec-object-allocation" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.13</span>. </span>Object Allocation</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_objectallocation_" class="ntdef" style="color:olive">ObjectAllocation_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"new"</span></span> <span class="code-escaped"><a href="#1_type" class="ntref localref" style="color:maroon">Type</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> ] </code></pre> +<p class="p noindent para-continued">This allocated a new object of a class type as explained +in section <a href="#sec-class-types" title="12. Class Types" class="localref" style="target-element:h1"><span class="heading-label">12</span></a>. +</p><h3 id="sec-havoc-right-hand-side" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.14</span>. </span>Havoc Right-Hand-Side</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_havocrhs_" class="ntdef" style="color:olive">HavocRhs_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"*"</span></span></code></pre> +<p class="p noindent para-continued">A havoc right-hand-side produces an arbitrary value of its associated +type. To get a more constrained arbitrary value the “assign-such-that” +operator (<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">:|</span></code>) can be used. See section <a href="#sec-update-statement" title="21.5. Update Statement" class="localref" style="target-element:h2"><span class="heading-label">21.5</span></a>. +</p><h3 id="sec-constant-or-atomic-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.15</span>. </span>Constant Or Atomic Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_constatomexpression" class="ntdef" style="color:olive">ConstAtomExpression</span></span> = + ( <span class="code-escaped"><a href="#1_literalexpression_" class="ntref localref" style="color:maroon">LiteralExpression_</a></span> + | <span class="code-escaped"><a href="#1_freshexpression_" class="ntref localref" style="color:maroon">FreshExpression_</a></span> + | <span class="code-escaped"><a href="#1_oldexpression_" class="ntref localref" style="color:maroon">OldExpression_</a></span> + | <span class="code-escaped"><a href="#1_cardinalityexpression_" class="ntref localref" style="color:maroon">CardinalityExpression_</a></span> + | <span class="code-escaped"><a href="#1_numericconversionexpression_" class="ntref localref" style="color:maroon">NumericConversionExpression_</a></span> + | <span class="code-escaped"><a href="#1_parensexpression" class="ntref localref" style="color:maroon">ParensExpression</a></span> + ) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_constatomexpression" class="ntref localref" style="color:maroon">ConstAtomExpression</a></span></code> represent either a constant of some type, or an +atomic expression. A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_constatomexpression" class="ntref localref" style="color:maroon">ConstAtomExpression</a></span></code> is never an l-value. Also, a +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_constatomexpression" class="ntref localref" style="color:maroon">ConstAtomExpression</a></span></code> is never followed by an open parenthesis (but could +very well have a suffix that starts with a period or a square bracket). +(The “Also…” part may change if expressions in Dafny could yield +functions.) +</p><h3 id="sec-literal-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.16</span>. </span>Literal Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_literalexpression_" class="ntdef" style="color:olive">LiteralExpression_</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"false"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"true"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"null"</span></span> | <span class="code-escaped"><a href="#1_nat" class="ntref localref" style="color:maroon">Nat</a></span> | <span class="code-escaped"><a href="#1_dec" class="ntref localref" style="color:maroon">Dec</a></span> | + <span class="code-escaped"><a href="#2_chartoken" class="ntref localref" style="color:maroon">charToken</a></span> | <span class="code-escaped"><a href="#2_stringtoken" class="ntref localref" style="color:maroon">stringToken</a></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"this"</span></span>) </code></pre> +<p class="p noindent para-continued">A literal expression is a boolean literal, a null object reference, +an unsigned integer or real literal, a character or string literal, +or “this” which denote the current object in the context of +an instance method or function. +</p><h3 id="sec-fresh-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.17</span>. </span>Fresh Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_freshexpression_" class="ntdef" style="color:olive">FreshExpression_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"fresh"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">fresh</span>(e)</code> returns a boolean value that is true if +the objects referenced in expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> were all +freshly allocated in the current method invocation. +The argument of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">fresh</span></code> must be either an object reference +or a collection of object references. +</p><h3 id="sec-old-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.18</span>. </span>Old Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_oldexpression_" class="ntdef" style="color:olive">OldExpression_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"old"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">An <em class="em-low1">old expression</em> is used in postconditions. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">old</span>(e)</code> evaluates to +the value expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">e</code> had on entry to the current method. +</p><h3 id="sec-cardinality-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.19</span>. </span>Cardinality Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_cardinalityexpression_" class="ntdef" style="color:olive">CardinalityExpression_</span></span> = <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> </code></pre> +<p class="p noindent para-continued">For a collection expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">|c|</code> is the cardinality of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">c</code>. For a +set or sequence the cardinality is the number of elements. For +a multiset the cardinality is the sum of the multiplicities of the +elements. For a map the cardinality is the cardinality of the +domain of the map. Cardinality is not defined for infinite maps. +For more see section <a href="#sec-collection-types" title="9. Collection types" class="localref" style="target-element:h1"><span class="heading-label">9</span></a>. +</p><h3 id="sec-numeric-conversion-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.20</span>. </span>Numeric Conversion Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_numericconversionexpression_" class="ntdef" style="color:olive">NumericConversionExpression_</span></span> = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"int"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"real"</span></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">Numeric conversion expressions give the name of the target type +followed by the expression being converted in parentheses. +This production is for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">int</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">real</span></code> as the target types +but this also applies more generally to other numeric types, +e.g. <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">newtypes</code>. See section <a href="#sec-numeric-conversion-operations" title="19.0. Numeric conversion operations" class="localref" style="target-element:h2"><span class="heading-label">19.0</span></a>. +</p><h3 id="sec-parenthesized-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.21</span>. </span>Parenthesized Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_parensexpression" class="ntdef" style="color:olive">ParensExpression</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_parensexpression" class="ntref localref" style="color:maroon">ParensExpression</a></span></code> is a list of zero or more expressions +enclosed in parentheses. +</p> +<p class="p indent">If there is exactly one expression enclosed then the value is just +the value of that expression. +</p> +<p class="p indent">If there are zero or more than one the result is a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">tuple</code> value. +See section <a href="#sec-tuple-types" title="18.1. Tuple types" class="localref" style="target-element:h2"><span class="heading-label">18.1</span></a>. +</p><h3 id="sec-sequence-display-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.22</span>. </span>Sequence Display Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_seqdisplayexpr" class="ntdef" style="color:olive">SeqDisplayExpr</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">A sequence display expression provide a way to constructing +a sequence with given values. For example +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>[<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>]</code></pre> +<p class="p noindent para-continued">is a sequence with three elements in it. +See section <a href="#sec-sequences" title="9.2. Sequences" class="localref" style="target-element:h2"><span class="heading-label">9.2</span></a> for more information on +sequences. +</p><h3 id="sec-set-display-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.23</span>. </span>Set Display Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_setdisplayexpr" class="ntdef" style="color:olive">SetDisplayExpr</span></span> = [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iset"</span></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<p class="p noindent para-continued">A set display expression provide a way to constructing +a set with given elements. If the keyword <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">iset</span></code> is present +then a potentially infinite set is constructed. +</p> +<p class="p indent">For example +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>{<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>}</code></pre> +<p class="p noindent para-continued">is a set with three elements in it. +See section <a href="#sec-sets" title="9.0. Sets" class="localref" style="target-element:h2"><span class="heading-label">9.0</span></a> for more information on +sets. +</p><h3 id="sec-multiset-display-or-cast-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.24</span>. </span>Multiset Display or Cast Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_multisetexpr" class="ntdef" style="color:olive">MultiSetExpr</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"multiset"</span></span> + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + ) </code></pre> +<p class="p noindent para-continued">A multiset display expression provide a way to constructing +a multiset with given elements and multiplicity. For example +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">multiset</span>{<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>}</code></pre> +<p class="p noindent para-continued">is a multiset with three elements in it. The number 1 has a multiplicity of 2, +the others a multiplicity of 1. +</p> +<p class="p indent">On the other hand, a multiset cast expression converts a set or a sequence +into a multiset as shown here: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> s : <span style="color:teal">set</span><<span style="color:teal">int</span>> <span style="color:blue">:=</span> {<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>}; +<span style="color:blue">var</span> ms : <span style="color:teal">multiset</span><<span style="color:teal">int</span>> <span style="color:blue">:=</span> <span style="color:teal">multiset</span>(s); +ms <span style="color:blue">:=</span> ms + <span style="color:teal">multiset</span>{<span class="constant" style="color:purple">1</span>}; +<span style="color:blue">var</span> sq : <span style="color:teal">seq</span><<span style="color:teal">int</span>> <span style="color:blue">:=</span> [<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">2</span>, <span class="constant" style="color:purple">3</span>]; +<span style="color:blue">var</span> ms2 : <span style="color:teal">multiset</span><<span style="color:teal">int</span>> <span style="color:blue">:=</span> <span style="color:teal">multiset</span>(sq); +<span style="color:blue">assert</span> ms == ms2;</code></pre> +<p class="p noindent para-continued">See section <a href="#sec-multisets" title="9.1. Multisets" class="localref" style="target-element:h2"><span class="heading-label">9.1</span></a> for more information on +multisets. +</p><h3 id="sec-map-display-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.25</span>. </span>Map Display Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_mapdisplayexpr" class="ntdef" style="color:olive">MapDisplayExpr</span></span> = (<span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"map"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"imap"</span></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> [ <span class="code-escaped"><a href="#1_mapliteralexpressions" class="ntref localref" style="color:maroon">MapLiteralExpressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> +<span class="code-escaped"><span id="1_mapliteralexpressions" class="ntdef" style="color:olive">MapLiteralExpressions</span></span> = + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + }</code></pre> +<p class="p noindent para-continued">A map display expression builds a finite or potentially infinite +map from explicit <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_mapliteralexpressions" class="ntref localref" style="color:maroon">MapLiteralExpressions</a></span></code>. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> m <span style="color:blue">:=</span> <span style="color:teal">map</span>[<span class="constant" style="color:purple">1</span> <span style="color:blue">:=</span> <span style="color:maroon">"</span><span style="color:maroon">a</span><span style="color:maroon">"</span>, <span class="constant" style="color:purple">2</span> <span style="color:blue">:=</span> <span style="color:maroon">"</span><span style="color:maroon">b</span><span style="color:maroon">"</span>]; +<span style="color:blue">ghost</span> <span style="color:blue">var</span> im <span style="color:blue">:=</span> <span style="color:teal">imap</span>[<span class="constant" style="color:purple">1</span> <span style="color:blue">:=</span> <span style="color:maroon">"</span><span style="color:maroon">a</span><span style="color:maroon">"</span>, <span class="constant" style="color:purple">2</span> <span style="color:blue">:=</span> <span style="color:maroon">"</span><span style="color:maroon">b</span><span style="color:maroon">"</span>];</code></pre> +<p class="p noindent para-continued">Note that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">imap</span></code>s may only appear in ghost contexts. See +section <a href="#sec-finite-and-infinite-maps" title="9.3. Finite and Infinite Maps" class="localref" style="target-element:h2"><span class="heading-label">9.3</span></a> for more details on maps and imaps. +</p><h3 id="sec-endless-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.26</span>. </span>Endless Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_endlessexpression" class="ntdef" style="color:olive">EndlessExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><a href="#1_ifexpression_" class="ntref localref" style="color:maroon">IfExpression_</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_matchexpression" class="ntref localref" style="color:maroon">MatchExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_quantifierexpression" class="ntref localref" style="color:maroon">QuantifierExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_setcomprehensionexpr" class="ntref localref" style="color:maroon">SetComprehensionExpr</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_stmtinexpr" class="ntref localref" style="color:maroon">StmtInExpr</a></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_letexpr" class="ntref localref" style="color:maroon">LetExpr</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + | <span class="code-escaped"><a href="#1_mapcomprehensionexpr" class="ntref localref" style="color:maroon">MapComprehensionExpr</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + ) </code></pre><!-- Experimental - do not document. + | NamedExpr(allowLemma, allowLambda) +--> + + + +<p class="p noindent para-continued"><code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_endlessexpression" class="ntref localref" style="color:maroon">EndlessExpression</a></span></code> gets it name from the fact that all its alternate +productions have no terminating symbol to end them, but rather they +all end with an <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> at the end. The various +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_endlessexpression" class="ntref localref" style="color:maroon">EndlessExpression</a></span></code> alternatives are described below. +</p><h3 id="sec-if-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.27</span>. </span>If Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_ifexpression_" class="ntdef" style="color:olive">IfExpression_</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"if"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"then"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"else"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) </code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ifexpression" class="ntref localref" style="color:maroon">IfExpression</a></span></code> is a conditional expression. It first evaluates +the expression following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">if</span></code>. If it evaluates to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code> then +it evaluates the expression following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">then</span></code> and that is the +result of the expression. If it evaluates to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">false</span></code> then the +expression following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">else</span></code> is evaluated and that is the result +of the expression. It is important that only the selected expression +is evaluated as the following example shows. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> k <span style="color:blue">:=</span> <span class="constant" style="color:purple">10</span> / x; <span style="color:darkgreen">// error, may divide by 0.</span> +<span style="color:blue">var</span> m <span style="color:blue">:=</span> <span style="color:blue">if</span> x != <span class="constant" style="color:purple">0</span> <span style="color:blue">then</span> <span class="constant" style="color:purple">10</span> / x <span style="color:blue">else</span> <span class="constant" style="color:purple">1</span>; <span style="color:darkgreen">// ok, guarded</span></code></pre><h3 id="sec-case-bindings-and-patterns" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.28</span>. </span>Case Bindings and Patterns</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_casebinding_" class="ntdef" style="color:olive">CaseBinding_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"case"</span></span> + ( <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> ] + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + ) + +<span class="code-escaped"><span id="1_casepattern" class="ntdef" style="color:olive">CasePattern</span></span> = + ( <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">Casepattern</a></span> } ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + | <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> + ) </code></pre> +<p class="p noindent para-continued">Case bindings and patterns are used for (possibly nested) +pattern matching on inductive or coinductive values. +The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span></code> construct is used in +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casestatement" class="ntref localref" style="color:maroon">CaseStatement</a></span></code> and <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span></code>s. +Besides its use in <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span></code>, <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s are used +in <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_letexpr" class="ntref localref" style="color:maroon">LetExpr</a></span></code>s and <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_vardeclstatement" class="ntref localref" style="color:maroon">VarDeclStatement</a></span></code>s. +</p> +<p class="p indent">When matching an inductive or coinductive value in +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_matchstmt" class="ntref localref" style="color:maroon">MatchStmt</a></span></code> or <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_matchexpression" class="ntref localref" style="color:maroon">MatchExpression</a></span></code>, there must be +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span></code> for each constructor. A tuple is +considered to have a single constructor. +The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span></code> of the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span></code> must match the name +of a constructor (or in the case of a tuple the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span></code> is +absent and the second alternative is chosen). +The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s inside the parenthesis are then +matched against the argument that were given to the +constructor when the value was constructed. +The number of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s must match the number +of parameters to the constructor (or the arity of the +tuple). +</p> +<p class="p indent">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s may be nested. The set of non-constructor-name +identifiers contained in a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span></code> must be distinct. +They are bound to the corresponding values in the value being +matched. +</p><h3 id="sec-match-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.29</span>. </span>Match Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_matchexpression" class="ntdef" style="color:olive">MatchExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"match"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> { <span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> + | { <span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) } + ) + +<span class="code-escaped"><span id="1_caseexpression" class="ntdef" style="color:olive">CaseExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + <span class="code-escaped"><a href="#1_casebinding_" class="ntref localref" style="color:maroon">CaseBinding_</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"=>"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_matchexpression" class="ntref localref" style="color:maroon">MatchExpression</a></span></code> is used to conditionally evaluate and select an +expression depending on the value of an algebraic type, i.e. an inductive +type, or a co-inductive type. +</p> +<p class="p indent">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">match</span></code> keyword is called the +<em class="em-low1">selector</em>. There must be a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span></code> for each constructor of +the type of the selector. The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span></code> following the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">case</span></code> keyword in a +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span></code> is the name of a constructor of the selector's type. +It may be absent if the expression being matched is a tuple since these +have no constructor name. +</p> +<p class="p indent">If the constructor has parameters then in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span></code> the +constructor name must be followed by a parenthesized list of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s. +If the constructor has no parameters then the +<code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseexpression" class="ntref localref" style="color:maroon">CaseExpression</a></span></code> must not have a following <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code> list. +All of the identifiers in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code>s must be distinct. +If types for the identifiers are not given then types are inferred +from the types of the constructor's parameters. If types are +given then they must agree with the types of the +corresponding parameters. +</p> +<p class="p indent">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_matchexpression" class="ntref localref" style="color:maroon">MatchExpression</a></span></code> is evaluated by first evaluating the selector. +Then the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseclause" class="ntref localref" style="color:maroon">CaseClause</a></span></code> is selected for the constructor that was +used to construct the evaluated selector. If the constructor had +parameters then the actual values used to construct the selector +value are bound to the identifiers in the identifier list. +The expression to the right of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">=></code> in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseclause" class="ntref localref" style="color:maroon">CaseClause</a></span></code> is then +evaluated in the environment enriched by this binding. The result +of that evaluation is the result of the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_matchexpression" class="ntref localref" style="color:maroon">MatchExpression</a></span></code>. +</p> +<p class="p indent">Note that the braces enclosing the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_caseclause" class="ntref localref" style="color:maroon">CaseClause</a></span></code>s may be omitted. +</p><h3 id="sec-quantifier-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.30</span>. </span>Quantifier Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_quantifierexpression" class="ntdef" style="color:olive">QuantifierExpression</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"forall"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"exists"</span></span> ) <span class="code-escaped"><a href="#1_quantifierdomain" class="ntref localref" style="color:maroon">QuantifierDomain</a></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"::"</span></span> + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + +<span class="code-escaped"><span id="1_quantifierdomain" class="ntdef" style="color:olive">QuantifierDomain</span></span> = + <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> } { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + [ <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ]</code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_quantifierexpression" class="ntref localref" style="color:maroon">QuantifierExpression</a></span></code> is a boolean expression that specifies that a +given expression (the one following the “::”) is true for all (for +<strong class="strong-star2">forall</strong>) or some (for <strong class="strong-star2">exists</strong>) combination of values of the +quantified variables, namely those in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_quantifierdomain" class="ntref localref" style="color:maroon">QuantifierDomain</a></span></code>. +</p> +<p class="p indent">Here are some examples: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">assert</span> <span style="color:blue">forall</span> x : <span style="color:teal">nat</span> | x <= <span class="constant" style="color:purple">5</span> :: x * x <= <span class="constant" style="color:purple">25</span>; +(<span style="color:blue">forall</span> n :: <span class="constant" style="color:purple">2</span> <= n ==> (<span class="code-escaped">∃<span style="font-family:serif"> </span></span>d :: n < d && d < <span class="constant" style="color:purple">2</span>*n))</code></pre> +<p class="p noindent para-continued">or using the Unicode symbols: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">assert</span> <span class="code-escaped">∀</span> x : <span style="color:teal">nat</span> | x <= <span class="constant" style="color:purple">5</span> <span class="code-escaped">•</span> x * x <= <span class="constant" style="color:purple">25</span>; +(<span class="code-escaped">∀</span> n <span class="code-escaped">•</span> <span class="constant" style="color:purple">2</span> <= n ==> (<span class="code-escaped">∃</span> d <span class="code-escaped">•</span> n < d && d < <span class="constant" style="color:purple">2</span>*n))</code></pre> +<p class="p noindent para-continued">The quantifier identifiers are <em class="em-low1">bound</em> within the scope of the +expressions in the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_quantifierexpression" class="ntref localref" style="color:maroon">QuantifierExpression</a></span></code>. +</p> +<p class="p indent">It types are not given for the quantified identifiers then Dafny +attempts to infer their types from the context of the expressions. +It this is not possible the program is in error. +</p><h3 id="sec-set-comprehension-expressions" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.31</span>. </span>Set Comprehension Expressions</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_setcomprehensionexpr" class="ntdef" style="color:olive">SetComprehensionExpr</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"set"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"iset"</span></span> ] + <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> } { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"::"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) ] </code></pre> +<p class="p noindent para-continued">A set comprehension expression is an expressions that yields a set +(possibly infinite if <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">iset</span></code> is used) that +satisfies specified conditions. There are two basic forms. +</p> +<p class="p indent">If there is only one quantified variable the optional <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"::"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> +need not be supplied, in which case it is as if it had been supplied +and the expression consists solely of the quantified variable. +That is, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">set</span> x : T | P(x)</code></pre> +<p class="p noindent para-continued">is equivalent to +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">set</span> x : T | P(x) :: x</code></pre> +<p class="p noindent para-continued">For the full form +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> S <span style="color:blue">:=</span> <span style="color:teal">set</span> x1:T1, x2:T2 ... | P(x1, x2, ...) :: Q(x1, x2, ...)</code></pre> +<p class="p noindent para-continued">the elements of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">S</code> will be all values resulting from evaluation of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q(x1, x2, ...)</code> +for all combinations of quantified variables <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">x1, x2, ...</code> such that +predicate <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P(x1, x2, ...)</code> holds. For example, +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> S <span style="color:blue">:=</span> <span style="color:teal">set</span> x:<span style="color:teal">nat</span>, y:<span style="color:teal">nat</span> | x < <span class="constant" style="color:purple">2</span> && y < <span class="constant" style="color:purple">2</span> :: (x, y)</code></pre> +<p class="p noindent para-continued">would yield <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">S == {(<span class="constant" style="color:purple">0</span>, <span class="constant" style="color:purple">0</span>), (<span class="constant" style="color:purple">0</span>, <span class="constant" style="color:purple">1</span>), (<span class="constant" style="color:purple">1</span>, <span class="constant" style="color:purple">0</span>), (<span class="constant" style="color:purple">1</span>,<span class="constant" style="color:purple">1</span>) }</code> +</p> +<p class="p indent">The types on the quantified variables are optional and if not given Dafny +will attempt to infer them from the contexts in which they are used in the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">P</code> or <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Q</code> expressions. +</p> +<p class="p indent">If a finite set was specified (“set” keyword used), Dafny must be able to prove that the +result is finite otherwise the set comprehension expression will not be +accepted. +</p> +<p class="p indent">Set comprehensions involving reference types such as +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:teal">set</span> o: <span style="color:teal">object</span> | <span style="color:blue">true</span></code></pre> +<p class="p noindent para-continued">are allowed in ghost contexts. In particular, in ghost contexts, the +check that the result is finite should allow any set comprehension +where the bound variable is of a reference type. In non-ghost contexts, +it is not allowed, because–even though the resulting set would be +finite–it is not pleasant or practical to compute at run time. +</p><h3 id="sec-statements-in-an-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.32</span>. </span>Statements in an Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_stmtinexpr" class="ntdef" style="color:olive">StmtInExpr</span></span> = ( <span class="code-escaped"><a href="#1_assertstmt" class="ntref localref" style="color:maroon">AssertStmt</a></span> | <span class="code-escaped"><a href="#1_assumestmt" class="ntref localref" style="color:maroon">AssumeStmt</a></span> | <span class="code-escaped"><a href="#1_calcstmt" class="ntref localref" style="color:maroon">CalcStmt</a></span> ) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_stmtinexpr" class="ntref localref" style="color:maroon">StmtInExpr</a></span></code> is a kind of statement that is allowed to +precede an expression in order to ensure that the expression +can be evaluated without error. For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">assume</span> x != <span class="constant" style="color:purple">0</span>; <span class="constant" style="color:purple">10</span>/x</code></pre> +<p class="p noindent para-continued"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Assert</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">assume</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">calc</span></code> statements can be used in this way. +</p><h3 id="sec-let-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.33</span>. </span>Let Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_letexpr" class="ntdef" style="color:olive">LetExpr</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"ghost"</span></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"var"</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span> } + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> | { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } <span style="color:maroon">"</span><span style="color:maroon">:|</span><span style="color:maroon">"</span> ) + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_false" class="ntref localref" style="color:maroon">false</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">";"</span></span> + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) </code></pre> +<p class="p noindent para-continued">A <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">let</code> expression allows binding of intermediate values to identifiers +for use in an expression. The start of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">let</code> expression is +signaled by the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">var</span></code> keyword. They look much like a local variable +declaration except the scope of the variable only extends to the +enclosed expression. +</p> +<p class="p indent">For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">var</span> sum <span style="color:blue">:=</span> x + y; sum * sum</code></pre> +<p class="p noindent para-continued">In the simple case the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_casepattern" class="ntref localref" style="color:maroon">CasePattern</a></span></code> is just an identifier with optional +type (which if missing is inferred from the rhs). +</p> +<p class="p indent">The more complex case allows destructuring of constructor expressions. +For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">datatype</span> Stuff = SCons(x: <span style="color:teal">int</span>, y: <span style="color:teal">int</span>) | Other +<span style="color:blue">function</span> GhostF(z: Stuff): <span style="color:teal">int</span> + <span style="color:purple">requires</span> z.SCons? +{ + <span style="color:blue">var</span> SCons(u, v) <span style="color:blue">:=</span> z; <span style="color:blue">var</span> sum <span style="color:blue">:=</span> u + v; sum * sum +}</code></pre><h3 id="sec-map-comprehension-expression" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.34</span>. </span>Map Comprehension Expression</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_mapcomprehensionexpr" class="ntdef" style="color:olive">MapComprehensionExpr</span></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) = + ( <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"map"</span></span> | <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"imap"</span></span> ) <span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span> { <span class="code-escaped"><a href="#1_attribute" class="ntref localref" style="color:maroon">Attribute</a></span> } + [ <span style="color:maroon">"</span><span style="color:maroon">|</span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"::"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>) </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_mapcomprehensionexpr" class="ntref localref" style="color:maroon">MapComprehensionExpr</a></span></code> defines a finite or infinite map value +by defining a domain (using the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_identtypeoptional" class="ntref localref" style="color:maroon">IdentTypeOptional</a></span></code> and the optional +condition following the “|”) and for each value in the domain, +giving the mapped value using the expression following the “::”. +</p> +<p class="p indent">For example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> square(x : <span style="color:teal">int</span>) : <span style="color:teal">int</span> { x * x } +<span style="color:blue">method</span> test() +{ + <span style="color:blue">var</span> m <span style="color:blue">:=</span> <span style="color:teal">map</span> x : <span style="color:teal">int</span> | <span class="constant" style="color:purple">0</span> <= x <= <span class="constant" style="color:purple">10</span> :: x * x; + <span style="color:blue">ghost</span> <span style="color:blue">var</span> im <span style="color:blue">:=</span> <span style="color:teal">imap</span> x : <span style="color:teal">int</span> :: x * x; + <span style="color:blue">ghost</span> <span style="color:blue">var</span> im2 <span style="color:blue">:=</span> <span style="color:teal">imap</span> x : <span style="color:teal">int</span> :: square(x); +}</code></pre> +<p class="p noindent para-continued">Dafny maps must be finite, so the domain must be constrained to be finite. +But imaps may be infinite as the example shows. The last example shows +creation of an infinite map that gives the same results as a function. +</p><!-- Experimental - do not document. + +## Named Expression +```` +NamedExpr(allowLemma, allowLambda) = + "label" LabelName ":" Expression(allowLemma, allowLambda) +```` + +A ``NamedExpr`` is an expression that has been tagged with a name. +For example: +``` +label squareit: x * x +``` + +This is an experimental feature. +TODO: When is this useful. Is there any way to refer to the label? +Should we remove the description? +--> + + +<h3 id="sec-name-segment" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.35</span>. </span>Name Segment</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_namesegment" class="ntdef" style="color:olive">NameSegment</span></span> = <span class="code-escaped"><a href="#1_ident" class="ntref localref" style="color:maroon">Ident</a></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> | <span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span> ] </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_namesegment" class="ntref localref" style="color:maroon">NameSegment</a></span></code> names a Dafny entity by giving its declared +name optionally followed by information to +make the name more complete. For the simple case it is +just an identifier. +</p> +<p class="p indent">If the identifier is for a generic entity it is followed by +a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span></code> which provides actual types for +the type parameters. +</p> +<p class="p indent">To reference a prefix predicate (see section <a href="#sec-copredicates" title="18.2.3. Copredicates" class="localref" style="target-element:h3"><span class="heading-label">18.2.3</span></a>) or +prefix lemma (see section <a href="#sec-prefix-lemmas" title="18.2.4.2. Prefix Lemmas" class="localref" style="target-element:h4"><span class="heading-label">18.2.4.2</span></a>), the identifier +must be the name of the copredicate or colemma and it must be +followed by a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code>. +</p><h3 id="sec-hash-call" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.36</span>. </span>Hash Call</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_hashcall" class="ntdef" style="color:olive">HashCall</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"#"</span></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">A <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code> is used to call the prefix for a copredicate or colemma. +In the non-generic case it just insert <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">#[k]</span><span style="color:maroon">"</span></code> before the call argument +list where k is the number of recursion levels. +</p> +<p class="p indent">In the case where the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">colemma</span></code> is generic, the generic type +argument is given before. Here is an example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">codatatype</span> Stream<T> = Nil | Cons(head: <span style="color:teal">int</span>, stuff: T, tail: Stream) + +<span style="color:blue">function</span> append(M: Stream, N: Stream): Stream +{ + <span style="color:blue">match</span> M + <span style="color:blue">case</span> Nil => N + <span style="color:blue">case</span> Cons(t, s, M') => Cons(t, s, append(M', N)) +} + +<span style="color:blue">function</span> zeros<T>(s : T): Stream<T> +{ + Cons(<span class="constant" style="color:purple">0</span>, s, zeros(s)) +} + +<span style="color:blue">function</span> ones<T>(s: T): Stream<T> +{ + Cons(<span class="constant" style="color:purple">1</span>, s, ones(s)) +} + +<span style="color:blue">copredicate</span> atmost(a: Stream, b: Stream) +{ + <span style="color:blue">match</span> a + <span style="color:blue">case</span> Nil => <span style="color:blue">true</span> + <span style="color:blue">case</span> Cons(h,s,t) => b.Cons? && h <= b.head && atmost(t, b.tail) +} + +<span style="color:blue">colemma</span> {<span style="color:purple">:induction</span> <span style="color:blue">false</span>} Theorem0<T>(s: T) + <span style="color:purple">ensures</span> atmost(zeros(s), ones(s)) +{ + <span style="color:darkgreen">// the following shows two equivalent ways to getting essentially the</span> + <span style="color:darkgreen">// co-inductive hypothesis</span> + <span style="color:blue">if</span> (*) { + Theorem0#<T>[_k-<span class="constant" style="color:purple">1</span>](s); + } <span style="color:blue">else</span> { + Theorem0(s); + } +} +</code></pre> +<p class="p noindent para-continued">where the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:maroon">"</span><span style="color:maroon">Theorem0#<T>[_k-1](s);</span><span style="color:maroon">"</span></code>. +See sections <a href="#sec-copredicates" title="18.2.3. Copredicates" class="localref" style="target-element:h3"><span class="heading-label">18.2.3</span></a> and <a href="#sec-prefix-lemmas" title="18.2.4.2. Prefix Lemmas" class="localref" style="target-element:h4"><span class="heading-label">18.2.4.2</span></a>. +</p><h3 id="sec-suffix" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.37</span>. </span>Suffix</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_suffix" class="ntdef" style="color:olive">Suffix</span></span> = + ( <span class="code-escaped"><a href="#1_augmenteddotsuffix_" class="ntref localref" style="color:maroon">AugmentedDotSuffix_</a></span> + | <span class="code-escaped"><a href="#1_datatypeupdatesuffix_" class="ntref localref" style="color:maroon">DatatypeUpdateSuffix_</a></span> + | <span class="code-escaped"><a href="#1_subsequencesuffix_" class="ntref localref" style="color:maroon">SubsequenceSuffix_</a></span> + | <span class="code-escaped"><a href="#1_slicesbylengthsuffix_" class="ntref localref" style="color:maroon">SlicesByLengthSuffix_</a></span> + | <span class="code-escaped"><a href="#1_sequenceupdatesuffix_" class="ntref localref" style="color:maroon">SequenceUpdateSuffix_</a></span> + | <span class="code-escaped"><a href="#1_selectionsuffix_" class="ntref localref" style="color:maroon">SelectionSuffix_</a></span> + | <span class="code-escaped"><a href="#1_argumentlistsuffix_" class="ntref localref" style="color:maroon">ArgumentListSuffix_</a></span> + ) </code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_suffix" class="ntref localref" style="color:maroon">Suffix</a></span></code> non-terminal describes ways of deriving a new value from +the entity to which the suffix is appended. There are six kinds +of suffixes which are described below. +</p><h4 id="sec-augmented-dot-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.0</span>. </span>Augmented Dot Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_augmenteddotsuffix_" class="ntdef" style="color:olive">AugmentedDotSuffix_</span></span> = <span style="color:maroon">"</span><span style="color:maroon">. </span><span style="color:maroon">"</span> <span class="code-escaped"><a href="#1_dotsuffix" class="ntref localref" style="color:maroon">DotSuffix</a></span> [ <span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span> | <span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span> ] </code></pre> +<p class="p noindent para-continued">An augmented dot suffix consists of a simple <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dotsuffix" class="ntref localref" style="color:maroon">DotSuffix</a></span></code> optionally +followed by either +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_genericinstantiation" class="ntref localref" style="color:maroon">GenericInstantiation</a></span></code> (for the case where the item +selected by the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_dotsuffix" class="ntref localref" style="color:maroon">DotSuffix</a></span></code> is generic), or +</li> +<li class="li ul-li list-star-li compact-li">a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_hashcall" class="ntref localref" style="color:maroon">HashCall</a></span></code> for the case where we want to call a prefix copredicate +or colemma. The result is the result of calling the prefix copredicate +or colemma. +</li></ul> +<h4 id="sec-datatype-update-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.1</span>. </span>Datatype Update Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_datatypeupdatesuffix_" class="ntdef" style="color:olive">DatatypeUpdateSuffix_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"."</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> <span class="code-escaped"><a href="#1_memberbindingupdate" class="ntref localref" style="color:maroon">MemberBindingUpdate</a></span> { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_memberbindingupdate" class="ntref localref" style="color:maroon">MemberBindingUpdate</a></span> } <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> + +<span class="code-escaped"><span id="1_memberbindingupdate" class="ntdef" style="color:olive">MemberBindingUpdate</span></span> = + ( <span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span> | <span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span> ) <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>)</code></pre> +<p class="p noindent para-continued">A datatype update suffix is used to produce a new datatype value +that is the same as an old datatype value except that the +value corresponding to a given destructor has the specified value. +In a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_memberbindingupdate" class="ntref localref" style="color:maroon">MemberBindingUpdate</a></span></code>, the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_ident" class="ntref localref" style="color:maroon">ident</a></span></code> or <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#2_digits" class="ntref localref" style="color:maroon">digits</a></span></code> is the +name of a destructor (i.e. formal parameter name) for one of the +constructors of the datatype. The expression to the right of the +“:=” is the new value for that formal. +</p> +<p class="p indent">All of the destructors in a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_datatypeupdatesuffix_" class="ntref localref" style="color:maroon">DatatypeUpdateSuffix_</a></span></code> must be +for the same constructor, and if they do not cover all of the +destructors for that constructor then the datatype value being +updated must have a value derived from that same constructor. +</p> +<p class="p indent">Here is an example: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">module</span> NewSyntax { +<span style="color:blue">datatype</span> MyDataType = MyConstructor(myint:<span style="color:teal">int</span>, mybool:<span style="color:teal">bool</span>) + | MyOtherConstructor(otherbool:<span style="color:teal">bool</span>) + | MyNumericConstructor(<span class="constant" style="color:purple">42</span>:<span style="color:teal">int</span>) + +<span style="color:blue">method</span> test(datum:MyDataType, x:<span style="color:teal">int</span>) + <span style="color:blue">returns</span> (abc:MyDataType, def:MyDataType, ghi:MyDataType, jkl:MyDataType) + <span style="color:purple">requires</span> datum.MyConstructor?; + <span style="color:purple">ensures</span> abc == datum.(myint <span style="color:blue">:=</span> x + <span class="constant" style="color:purple">2</span>); + <span style="color:purple">ensures</span> def == datum.(otherbool <span style="color:blue">:=</span> !datum.mybool); + <span style="color:purple">ensures</span> ghi == datum.(myint <span style="color:blue">:=</span> <span class="constant" style="color:purple">2</span>).(mybool <span style="color:blue">:=</span> <span style="color:blue">false</span>); + <span style="color:darkgreen">// Resolution error: no non_destructor in MyDataType</span> + <span style="color:darkgreen">//ensures jkl == datum.(non_destructor := 5);</span> + <span style="color:purple">ensures</span> jkl == datum.(<span class="constant" style="color:purple">42</span> <span style="color:blue">:=</span> <span class="constant" style="color:purple">7</span>); +{ + abc <span style="color:blue">:=</span> MyConstructor(x + <span class="constant" style="color:purple">2</span>, datum.mybool); + abc <span style="color:blue">:=</span> datum.(myint <span style="color:blue">:=</span> x + <span class="constant" style="color:purple">2</span>); + def <span style="color:blue">:=</span> MyOtherConstructor(!datum.mybool); + ghi <span style="color:blue">:=</span> MyConstructor(<span class="constant" style="color:purple">2</span>, <span style="color:blue">false</span>); + jkl <span style="color:blue">:=</span> datum.(<span class="constant" style="color:purple">42</span> <span style="color:blue">:=</span> <span class="constant" style="color:purple">7</span>); + + <span style="color:blue">assert</span> abc.(myint <span style="color:blue">:=</span> abc.myint - <span class="constant" style="color:purple">2</span>) == datum.(myint <span style="color:blue">:=</span> x); +} +}</code></pre><h4 id="sec-subsequence-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.2</span>. </span>Subsequence Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_subsequencesuffix_" class="ntdef" style="color:olive">SubsequenceSuffix_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> [ <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">".."</span></span> [ <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">A subsequence suffix applied to a sequence produces a new sequence whose +elements are taken from a contiguous part of the original sequence. For +example, expression <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[lo..hi]</code> for sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code>, and integer-based +numerics <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">lo</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">hi</code> satisfying <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span class="constant" style="color:purple">0</span> <= lo <= hi <= |s|</code>. See +section <a href="#sec-other-sequence-expressions" title="9.2.3. Other Sequence Expressions" class="localref" style="target-element:h3"><span class="heading-label">9.2.3</span></a> for details. +</p><h4 id="sec-slices-by-length-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.3</span>. </span>Slices By Length Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_slicesbylengthsuffix_" class="ntdef" style="color:olive">SlicesByLengthSuffix_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } + [ <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> ] + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">Applying a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_slicesbylengthsuffix_" class="ntref localref" style="color:maroon">SlicesByLengthSuffix_</a></span></code> to a sequence produces a +sequence of subsequences of the original sequence. +See section <a href="#sec-other-sequence-expressions" title="9.2.3. Other Sequence Expressions" class="localref" style="target-element:h3"><span class="heading-label">9.2.3</span></a> for details. +</p><h4 id="sec-sequence-update-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.4</span>. </span>Sequence Update Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_sequenceupdatesuffix_" class="ntdef" style="color:olive">SequenceUpdateSuffix_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":="</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">For a sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> and expressions <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">v</code>, the expression +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s[i <span style="color:blue">:=</span> v]</code> is the same as the sequence <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">s</code> except that at +index <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">i</code> it has value <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">v</code>. +</p><h4 id="sec-selection-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.5</span>. </span>Selection Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_selectionsuffix_" class="ntdef" style="color:olive">SelectionSuffix_</span></span> = + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"["</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) } + <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"]"</span></span> </code></pre> +<p class="p noindent para-continued">If a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_selectionsuffix_" class="ntref localref" style="color:maroon">SelectionSuffix_</a></span></code> has only one expression in it, it is a +zero-based index that may be used to select a single element of a +sequence or from a single-dimensional array. +</p> +<p class="p indent">If a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_selectionsuffix_" class="ntref localref" style="color:maroon">SelectionSuffix_</a></span></code> has more than one expression in it, then +it is a list of indices to index into a multi-dimensional array. +The rank of the array must be the same as the number of indices. +</p><h4 id="sec-argument-list-suffix" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">22.37.6</span>. </span>Argument List Suffix</h4> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_argumentlistsuffix_" class="ntdef" style="color:olive">ArgumentListSuffix_</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"("</span></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">")"</span></span> </code></pre> +<p class="p noindent para-continued">An argument list suffix is a parenthesized list of expressions that +are the arguments to pass to a method or function that is being +called. Applying such a suffix caused the method or function +to be called and the result is the result of the call. +</p><h3 id="sec-expression-lists" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">22.38</span>. </span>Expression Lists</h3> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_expressions" class="ntdef" style="color:olive">Expressions</span></span> = + <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) + { <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">","</span></span> <span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span>(allowLemma: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>, <span class="code-escaped"><a href="#2_allowlambda" class="ntref localref" style="color:maroon">allowLambda</a></span>: <span class="code-escaped"><a href="#2_true" class="ntref localref" style="color:maroon">true</a></span>) }</code></pre> +<p class="p noindent para-continued">The <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span></code> non-terminal represents a list of +one or more expressions separated by a comma. +</p><h2 id="sec-module-refinement" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">23</span>. </span>Module Refinement</h2> +<p class="p noindent">TODO: Write this section. +</p><h2 id="sec-attributes" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">24</span>. </span>Attributes</h2> +<pre class="para-block grammar-def pre-fenced pre-fenced4 language-java lang-java java colorized" style="display:block;font-size:small;margin-left:1em"><code><span class="code-escaped"><span id="1_attribute" class="ntdef" style="color:olive">Attribute</span></span> = <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"{"</span></span> <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">":"</span></span> <span class="code-escaped"><a href="#1_attributename" class="ntref localref" style="color:maroon">AttributeName</a></span> [ <span class="code-escaped"><a href="#1_expressions" class="ntref localref" style="color:maroon">Expressions</a></span> ] <span class="code-escaped"><span class="terminal" style="font-weight:bold;color:black">"}"</span></span> </code></pre> +<p class="p noindent para-continued">Dafny allows many of its entities to be annotated with <em class="em-low1">Attributes</em>. +The grammar shows where the attribute annotations may appear. +</p> +<p class="p indent">Here is an example of an attribute from the Dafny test suite: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>{<span style="color:purple">:MyAttribute</span> <span style="color:maroon">"</span><span style="color:maroon">hello</span><span style="color:maroon">"</span>, <span style="color:maroon">"</span><span style="color:maroon">hi</span><span style="color:maroon">"</span> + <span style="color:maroon">"</span><span style="color:maroon">there</span><span style="color:maroon">"</span>, <span class="constant" style="color:purple">57</span>}</code></pre> +<p class="p noindent para-continued">In general an attribute may have any name the user chooses. It may be +followed by a comma separated list of expressions. These expressions will +be resolved and type-checked in the context where the attribute appears. +</p><h3 id="sec-dafny-attribute-implementation-details" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">24.0</span>. </span>Dafny Attribute Implementation Details</h3> +<p class="p noindent">In the Dafny implementation the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Attributes</code> type holds the name of +the attribute, a list of <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_expression" class="ntref localref" style="color:maroon">Expression</a></span></code> arguments and a link to the +previous Attributes object for that Dafny entity. So for each +Dafny entity that has attributes we have a list of them. +</p> +<p class="p indent">Dafny stores attributes on the following kinds of entities: +Declaration (base class), ModuleDefinition, Statement, +AssignmentRhs, LocalVariable, LetExpr, ComprehensionExpr, +MaybeFreeExpression, Specification. +</p> +<p class="p indent">TODO: Dafny internals information should go into a separate +document on Dafny internals. +</p><h3 id="sec-dafny-attributes" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">24.1</span>. </span>Dafny Attributes</h3> +<p class="p noindent">All entities that Dafny translates to Boogie have their attributes +passed on to Boogie except for the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:axiom</span>}</code> attribute (which +conflicts with Boogie usage) and the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:trigger</span>}</code> attribute which is +instead converted into a Boogie quantifier <em class="em-low1">trigger</em>. See Section 11 of +<span class="citations" style="target-element:bibitem">[<a href="#leino:boogie2-refman" title="K. Rustan M. Leino. +This is Boogie 2." class="bibref localref" style="target-element:bibitem"><span class="cite-number">16</span></a>]</span>. +</p> +<p class="p indent">Dafny has special processing for some attributes. For some attributes the +setting is only looked for on the entity of interest. For others we start +at the entity and if the attribute is not there, look up in the hierarchy +(enclosing class and enclosing modules). The latter case is checked by +the ContainsBoolAtAnyLevel method in the Dafny source. The attribute +declaration closest to the entity overrides those further away. +</p> +<p class="p indent">For attributes with a single boolean expression argument, the attribute +with no argument is interpreted as if it were true. +</p> +<p class="p indent">The attributes that are processed specially by Dafny are described in the +following sections. +</p><h4 id="sec-assumption" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.0</span>. </span>assumption</h4> +<p class="p noindent">This attribute can only be placed on a local ghost bool +variable of a method. Its declaration cannot have a rhs, but it is +allowed to participate as the lhs of exactly one assignment of the +form: <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">b <span style="color:blue">:=</span> b && expr;</code>. Such a variable declaration translates in the +Boogie output to a declaration followed by an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">assume</span> b</code> command. TODO: +What is the motivation for this? +</p><h4 id="sec-autoreq-boolexpr" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.1</span>. </span>autoReq boolExpr</h4> +<p class="p noindent">For a function declaration, if this attribute is set true at the nearest +level, then its <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> clause is strengthed sufficiently so that +it may call the functions that it calls. +</p> +<p class="p indent">For following example +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> f(x:<span style="color:teal">int</span>) : <span style="color:teal">bool</span> + <span style="color:purple">requires</span> x > <span class="constant" style="color:purple">3</span> +{ + x > <span class="constant" style="color:purple">7</span> +} + +<span style="color:darkgreen">// Should succeed thanks to auto_reqs</span> +<span style="color:blue">function</span> {<span style="color:purple">:autoReq</span>} g(y:<span style="color:teal">int</span>, b:<span style="color:teal">bool</span>) : <span style="color:teal">bool</span> +{ + <span style="color:blue">if</span> b <span style="color:blue">then</span> f(y + <span class="constant" style="color:purple">2</span>) <span style="color:blue">else</span> f(<span class="constant" style="color:purple">2</span>*y) +}</code></pre> +<p class="p noindent para-continued">the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:autoReq</span>}</code> attribute causes Dafny to +deduce a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">requires</span></code> clause for g as if it had been +declared +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">function</span> g(y:<span style="color:teal">int</span>, b:<span style="color:teal">bool</span>) : <span style="color:teal">bool</span> + <span style="color:purple">requires</span> <span style="color:blue">if</span> b <span style="color:blue">then</span> y + <span class="constant" style="color:purple">2</span> > <span class="constant" style="color:purple">3</span> <span style="color:blue">else</span> <span class="constant" style="color:purple">2</span> * y > <span class="constant" style="color:purple">3</span> +{ + <span style="color:blue">if</span> b <span style="color:blue">then</span> f(y + <span class="constant" style="color:purple">2</span>) <span style="color:blue">else</span> f(<span class="constant" style="color:purple">2</span>*y) +}</code></pre><h4 id="sec-autocontracts" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.2</span>. </span>autocontracts</h4> +<p class="p noindent">Dynamic frames <span class="citations" style="target-element:bibitem">[<a href="#kassios:fm2006" title="Ioannis T. Kassios. +Dynamic frames: Support for framing, dependencies and sharing without restrictions. +In Jayadev Misra, Tobias Nipkow, and Emil Sekerinski, editors, FM 2006: Formal Methods, 14th International Symposium on Formal Methods, volume 4085, pages 268–283. Springer, August 2006." class="bibref localref" style="target-element:bibitem"><span class="cite-number">9</span></a>, <a href="#leino:dafny:dynamicframes" title="K. Rustan M. Leino. +Dynamic-frame specifications in dafny." class="bibref localref" style="target-element:bibitem"><span class="cite-number">17</span></a>, <a href="#smansetal:vericool" title="Jan Smans, Bart Jacobs, Frank Piessens, and Wolfram Schulte. +Automatic verifier for Java-like programs based on dynamic frames." class="bibref localref" style="target-element:bibitem"><span class="cite-number">32</span></a>, <a href="#smansetal:implicitdynamicframes" title="Jan Smans, Bart Jacobs, and Frank Piessens. +Implicit dynamic frames: Combining dynamic frames and separation logic. +In Sophia Drossopoulou, editor, ECOOP 2009 — Object-Oriented Programming, 23rd European Conference, volume 5653, pages 148–172. Springer, July 2009." class="bibref localref" style="target-element:bibitem"><span class="cite-number">33</span></a>]</span> +are frame expressions that can vary dynamically during +program execution. AutoContracts is an experimental feature that will +fill much of the dynamic-frames boilerplate into a class. +</p> +<p class="p indent">From the user's perspective, what needs to be done is simply: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">mark the class with {:autocontracts} +</li> +<li class="li ul-li list-star-li compact-li">declare a function (or predicate) called Valid() +</li></ul> + +<p class="p noindent">AutoContracts will then: +</p> +<ul class="ul list-star loose"> +<li class="li ul-li list-star-li loose-li"> +<p>Declare: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">var</span> Repr: <span style="color:teal">set</span>(<span style="color:teal">object</span>);</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>For function/predicate Valid(), insert: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:purple">reads</span> <span style="color:blue">this</span>, Repr</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>Into body of Valid(), insert (at the beginning of the body): +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">this</span> <span style="color:blue">in</span> Repr && <span style="color:blue">null</span> !<span style="color:blue">in</span> Repr</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>and also insert, for every array-valued field A declared in the class: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> (A != <span style="color:blue">null</span> ==> A <span style="color:blue">in</span> Repr) &&</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>and for every field F of a class type T where T has a field called Repr, also insert: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> (F != <span style="color:blue">null</span> ==> F <span style="color:blue">in</span> Repr && F.Repr SUBSET Repr && <span style="color:blue">this</span> !<span style="color:blue">in</span> Repr)</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>Except, if A or F is declared with {:autocontracts false}, then the implication will not +be added. +</p></li> +<li class="li ul-li list-star-li loose-li"> +<p>For every constructor, add: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:purple">modifies</span> <span style="color:blue">this</span> + <span style="color:purple">ensures</span> Valid() && <span style="color:blue">fresh</span>(Repr - {<span style="color:blue">this</span>})</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>At the end of the body of the constructor, add: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> Repr <span style="color:blue">:=</span> {<span style="color:blue">this</span>}; + <span style="color:blue">if</span> (A != <span style="color:blue">null</span>) { Repr <span style="color:blue">:=</span> Repr + {A}; } + <span style="color:blue">if</span> (F != <span style="color:blue">null</span>) { Repr <span style="color:blue">:=</span> Repr + {F} + F.Repr; }</code></pre></li> +<li class="li ul-li list-star-li loose-li"> +<p>For every method, add: +</p></li></ul> + +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:purple">requires</span> Valid() + <span style="color:purple">modifies</span> Repr + <span style="color:purple">ensures</span> Valid() && <span style="color:blue">fresh</span>(Repr - <span style="color:blue">old</span>(Repr))</code></pre> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">At the end of the body of the method, add: + +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">if</span> (A != <span style="color:blue">null</span>) { Repr <span style="color:blue">:=</span> Repr + {A}; } + <span style="color:blue">if</span> (F != <span style="color:blue">null</span>) { Repr <span style="color:blue">:=</span> Repr + {F} + F.Repr; }</code></pre></li></ul> +<h4 id="sec-axiom" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.3</span>. </span>axiom</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:axiom</span>}</code> attribute may be placed on a function or method. +It means that the post-condition may be assumed to be true +without proof. In that case also the body of the function or +method may be omitted. +</p> +<p class="p indent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:axiom</span>}</code> attribute is also used for generated <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">reveal_*</code> +lemmas as shown in Section <a href="#sec-opaque" title="24.1.12. opaque" class="localref" style="target-element:h3"><span class="heading-label">24.1.12</span></a>. +</p><h4 id="sec-compile" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.4</span>. </span>compile</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:compile</span>}</code> attribute takes a boolean argument. It may be applied to +any top-level declaration. If that argument is false then that declaration +will not be compiled into .Net code. +</p><h4 id="sec-decl" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.5</span>. </span>decl</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:decl</span>}</code> attribute may be placed on a method declaration. It +inhibits the error message that has would be given when the method has a +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">ensures</span></code> clauses but no body. +</p> +<p class="p indent">TODO: There are no examples of this in the Dafny tests. What is the motivation +for this? +</p><h4 id="sec-fuel" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.6</span>. </span>fuel</h4> +<p class="p noindent">The fuel attributes is used to specify how much “fuel” a function should have, +i.e., how many times Z3 is permitted to unfold it's definition. The +new {:fuel} annotation can be added to the function itself, it which +case it will apply to all uses of that function, or it can overridden +within the scope of a module, function, method, iterator, calc, forall, +while, assert, or assume. The general format is: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>{<span style="color:purple">:fuel</span> functionName,lowFuel,highFuel}</code></pre> +<p class="p noindent para-continued">When applied as an annotation to the function itself, omit +functionName. If highFuel is omitted, it defaults to lowFuel + 1. +</p> +<p class="p indent">The default fuel setting for recursive functions is 1,2. Setting the +fuel higher, say, to 3,4, will give more unfoldings, which may make +some proofs go through with less programmer assistance (e.g., with +fewer assert statements), but it may also increase verification time, +so use it with care. Setting the fuel to 0,0 is similar to making the +definition opaque, except when used with all literal arguments. +</p><h4 id="sec-heapquantifier" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.7</span>. </span>heapQuantifier</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:heapQuantifier</span>}</code> attribute may be used on a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_quantifierexpression" class="ntref localref" style="color:maroon">QuantifierExpression</a></span></code>. +When it appears in a quantifier expression it is as if a new heap-valued +quantifier variable was added to the quantification. Consider this code +that is one of the invariants of a while loop. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:purple">invariant</span> <span style="color:blue">forall</span> u {<span style="color:purple">:heapQuantifier</span>} :: f(u) == u + r</code></pre> +<p class="p noindent para-continued">The quantifier is translated into the following Boogie: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>(<span style="color:blue">forall</span> q$heap#<span class="constant" style="color:purple">8</span>: Heap, u#<span class="constant" style="color:purple">5</span>: <span style="color:teal">int</span> :: + {<span style="color:purple">:heapQuantifier</span>} + $IsGoodHeap(q$heap#<span class="constant" style="color:purple">8</span>) && ($Heap == q$heap#<span class="constant" style="color:purple">8</span> || $HeapSucc($Heap, q$heap#<span class="constant" style="color:purple">8</span>)) + ==> $Unbox(Apply1(TInt, TInt, f#<span class="constant" style="color:purple">0</span>, q$heap#<span class="constant" style="color:purple">8</span>, $Box(u#<span class="constant" style="color:purple">5</span>))): <span style="color:teal">int</span> == u#<span class="constant" style="color:purple">5</span> + r#<span class="constant" style="color:purple">0</span>);</code></pre> +<p class="p noindent para-continued">What this is saying is that the quantified expression, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f(u) == u + r</code>, +which may depend on the heap, is also valid for any good heap that is either the +same as the current heap, or that is derived from it by heap update operations. +</p> +<p class="p indent">TODO: I think this means that the quantified expression is actually independent of the +heap. Is that true? +</p><h4 id="sec-imported" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.8</span>. </span>imported</h4> +<p class="p noindent">If a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_methoddecl" class="ntref localref" style="color:maroon">MethodDecl</a></span></code> or <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_functiondecl" class="ntref localref" style="color:maroon">FunctionDecl</a></span></code> has an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:imported</span>}</code> attribute, +then it is allowed to have a empty body even though it has an <strong class="strong-star2">ensures</strong> +clause. Ordinarily a body would be required in order to provide the +proof of the <strong class="strong-star2">ensures</strong> clause (but the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(:axiom)</code> attribute also +provides this facility, so the need for <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(:imported)</code> is not clear.) +A method or function declaration may be given the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(:imported)</code> attribute. This suppresses +the error message that would be given if a method or function with an <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">ensures</span></code> clause +does not have a body. +</p> +<p class="p indent">TODO: When would this be used? An example would be helpful. +</p> +<p class="p indent">TODO: When is this useful or valid? +</p><h4 id="sec-induction" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.9</span>. </span>induction</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span>}</code> attribute controls the application of +proof by induction to two contexts. Given a list of +variables on which induction might be applied, the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span>}</code> attribute selects a sub-list of those +variables (in the same order) to which to apply induction. +</p> +<p class="p indent">TODO: Would there be any advantage to taking the order +from the attribute, rather than preserving the original +order? That would seem to give the user more control. +</p> +<p class="p indent">The two contexts are: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">A method, in which case the bound variables are all the +in-parameters of the method. +</li> +<li class="li ul-li list-star-li compact-li">A quantifier expression, in which case the bound variables +are the bound variables of the quantifier expression. +</li></ul> + +<p class="p noindent">The form of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span>}</code> attribute is one of the following: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span>}</code> – apply induction to all bound variables +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span> <span style="color:blue">false</span>}</code> – suppress induction, that is, don't apply it to any bound variable +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span> L}</code> where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">L</code> is a list consisting entirely of bound variables +– apply induction to the specified bound variables +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:induction</span> X}</code> where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">X</code> is anything else – treat the same as +{:induction}, that is, apply induction to all bound variables. For this +usage conventionally <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">X</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">true</span></code>. +</li></ul> + +<p class="p noindent">Here is an example of using it on a quantifier expression: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:blue">ghost</span> <span style="color:blue">method</span> Fill_J(s: <span style="color:teal">seq</span><<span style="color:teal">int</span>>) + <span style="color:purple">requires</span> <span style="color:blue">forall</span> i :: <span class="constant" style="color:purple">1</span> <= i < |s| ==> s[i-<span class="constant" style="color:purple">1</span>] <= s[i] + <span style="color:purple">ensures</span> <span style="color:blue">forall</span> i,j {<span style="color:purple">:induction</span> j} :: <span class="constant" style="color:purple">0</span> <= i < j < |s| ==> s[i] <= s[j] +{ +}</code></pre><h4 id="sec-layerquantifier" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.10</span>. </span>layerQuantifier</h4> +<p class="p noindent">When Dafny is translating a quantified expression, if it has +a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:layerQuantifier</span>}</code> attribute an additional quantifier +variable is added to the quantifier bound variables. +This variable as the predefined <em class="em-low1">LayerType</em>. +A <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:layerQuantifier</span>}</code> attribute may be placed on a quantifier expression. +Translation of Dafny into Boogie defines a <em class="em-low1">LayerType</em> which has defined zero and +successor constructors. +</p> +<p class="p indent">The Dafny source has the comment that “if a function is recursive, +then make the reveal lemma quantifier a layerQuantifier.” +And in that case it adds the attribute to the quantifier. +</p> +<p class="p indent">There is no explicit user of the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:layerQuantifier</span>}</code> attribute +in the Dafny tests. So I believe this attribute is only used +internally by Dafny and not externally. +</p> +<p class="p indent">TODO: Need more complete explanation of this attribute. +</p><h4 id="sec-nativetype" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.11</span>. </span>nativeType</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:nativeType</span>}</code> attribute may only be used on a <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_newtypedecl" class="ntref localref" style="color:maroon">NewtypeDecl</a></span></code> +where the base type is an integral type. It can take one of the following +forms: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:nativeType</span>}</code> - With no parameters it has no effect and the <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_newtypedecl" class="ntref localref" style="color:maroon">NewtypeDecl</a></span></code> +have its default behavior which is to choose a native type that can hold any +value satisfying the constraints, if possible, otherwise BigInteger is used. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:nativeType</span> <span style="color:blue">true</span>}</code> - Also gives default <code class="grammar-ref code code2 language-java lang-java java colorized"><span class="code-escaped"><a href="#1_newtypedecl" class="ntref localref" style="color:maroon">NewtypeDecl</a></span></code> behavior, +but gives an error if base type is not integral. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:nativeType</span> <span style="color:blue">false</span>}</code> - Inhibits using a native type. BigInteger is used +for integral types and BitRational for real types. +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:nativeType</span> <span style="color:maroon">"</span><span style="color:maroon">typename</span><span style="color:maroon">"</span>}</code> - This form has an native integral +type name as a string literal. Acceptable values are: “byte”, +“sbyte”, “ushort”, “short”, “uint”, “int”, “ulong” and “long”. +An error is reported if the given data type cannot hold all the +values that satisfy the constraint. +</li></ul> +<h4 id="sec-opaque" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.12</span>. </span>opaque</h4> +<p class="p noindent">Ordinarily the body of a function is transparent to its users but +sometimes it is useful to hide it. If a function <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">f</code> is given the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code> attribute then Dafny hides the body of the function, +so that it can only be seen within its recursive clique (if any), +or if the programmer specifically asks to see it via the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">reveal_f()</code> lemma. +</p> +<p class="p indent">We create a lemma to allow the user to selectively reveal the function's body <br> +That is, given: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">function</span> {<span style="color:purple">:opaque</span>} foo(x:<span style="color:teal">int</span>, y:<span style="color:teal">int</span>) : <span style="color:teal">int</span> + <span style="color:purple">requires</span> <span class="constant" style="color:purple">0</span> <= x < <span class="constant" style="color:purple">5</span> + <span style="color:purple">requires</span> <span class="constant" style="color:purple">0</span> <= y < <span class="constant" style="color:purple">5</span> + <span style="color:purple">ensures</span> foo(x, y) < <span class="constant" style="color:purple">10</span> + { x + y }</code></pre> +<p class="p noindent para-continued">We produce: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> <span style="color:blue">lemma</span> {<span style="color:purple">:axiom</span>} reveal_foo() + <span style="color:purple">ensures</span> <span style="color:blue">forall</span> x:<span style="color:teal">int</span>, y:<span style="color:teal">int</span> {<span style="color:purple">:trigger</span> foo(x,y)} :: + <span class="constant" style="color:purple">0</span> <= x < <span class="constant" style="color:purple">5</span> && <span class="constant" style="color:purple">0</span> <= y < <span class="constant" style="color:purple">5</span> ==> foo(x,y) == foo_FULL(x,y)</code></pre> +<p class="p noindent para-continued">where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">foo_FULL</code> is a copy of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">foo</code> which does not have its body +hidden. In addition <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">foo_FULL</code> is given the +<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque_full</span>}</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:auto_generated</span>}</code> attributes in addition +to the <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque</span>}</code> attribute (which it got because it is a copy of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">foo</code>). +</p><h4 id="sec-opaque-full" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.13</span>. </span>opaque full</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:opaque_full</span>}</code> attribute is used to mark the <em class="em-low1">full</em> version +of an opaque function. See Section <a href="#sec-opaque" title="24.1.12. opaque" class="localref" style="target-element:h3"><span class="heading-label">24.1.12</span></a>. +</p><h4 id="sec-prependasserttoken" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.14</span>. </span>prependAssertToken</h4> +<p class="p noindent">This is used internally in Dafny as part of module refinement. +It is an attribute on an assert statement. +The Dafny code has the following comment: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code><span style="color:darkgreen">// Clone the expression, but among the new assert's attributes, indicate</span> +<span style="color:darkgreen">// that this assertion is supposed to be translated into a check. That is,</span> +<span style="color:darkgreen">// it is not allowed to be just assumed in the translation, despite the fact</span> +<span style="color:darkgreen">// that the condition is inherited.</span></code></pre> +<p class="p noindent para-continued">TODO: Decide if we want to describe this in more detail, or whether +the functionality is already adequately described where +refinement is described. +</p><h4 id="sec-tailrecursion" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.15</span>. </span>tailrecursion</h4> +<p class="p noindent">This attribute is used on a method declarations. It has a boolean argument. +</p> +<p class="p indent">If specified with a false value it means the user specifically +requested no tail recursion, so none is done. +</p> +<p class="p indent">If specified with a true value, or if not specified +then tail recursive optimization will be attempted subject to +the following conditions: +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li">It is an error if the method is a ghost method and tail +recursion was explicitly requested. +</li> +<li class="li ul-li list-star-li compact-li">Only direct recursion is supported, not mutually recursive methods. +</li> +<li class="li ul-li list-star-li compact-li">If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:tailrecursion</span> <span style="color:blue">true</span>}</code> was specified but the code does not allow it +an error message is given. +</li></ul> +<h4 id="sec-timelimitmultiplier" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.16</span>. </span>timeLimitMultiplier</h4> +<p class="p noindent">This attribute may be placed on a method or function declaration +and has an integer argument. If <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:timeLimitMultiplier</span> X}</code> was +specified a <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:timelimit</span> Y}</code> attributed is passed on to Boogie +where <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Y</code> is <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">X</code> times either the default verification time limit +for a function or method, or times the value specified by the +Boogie <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">timelimit</code> command-line option. +</p><h4 id="sec-trigger" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.17</span>. </span>trigger</h4> +<p class="p noindent">Trigger attributes are used on quantifiers and comprehensions. +They are translated into Boogie triggers. +</p><h4 id="sec-typequantifier" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">24.1.18</span>. </span>typeQuantifier</h4> +<p class="p noindent">The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:typeQuantifier</span>}</code> must be used on a quantifier if it +quantifies over types. +</p><h3 id="sec-boogie-attributes" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">24.2</span>. </span>Boogie Attributes</h3> +<p class="p noindent">Use the Boogie “/attrHelp” option to get the list of attributes +that Boogie recognizes and their meaning. Here is the output at +the time of this writing. Dafny passes attributes that have +been specified to the Boogie. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>Boogie: The following attributes are supported by <span style="color:blue">this</span> implementation. + + ---- On top-level declarations --------------------------------------------- + + {<span style="color:purple">:ignore</span>} + Ignore the declaration (after checking for duplicate names). + + {<span style="color:purple">:extern</span>} + If two top-level declarations introduce the same name (for example, two + constants with the same name or two procedures with the same name), <span style="color:blue">then</span> + Boogie usually produces an error message. However, <span style="color:blue">if</span> at least one of + the declarations is declared with :extern, one of the declarations is + ignored. If both declarations are :extern, Boogie arbitrarily chooses + one of them to keep; otherwise, Boogie ignore the :extern declaration + and keeps the other. + + {<span style="color:purple">:checksum</span> <<span style="color:teal">string</span>>} + Attach a checksum to be used for verification result caching. + + ---- On implementations and procedures ------------------------------------- + + {<span style="color:purple">:inline</span> N} + Inline given procedure (can be also used on implementation). + N should be a non-negative number and represents the inlining depth. + With /inline:<span style="color:blue">assume</span> call is replaced with <span style="color:maroon">"</span><span style="color:maroon">assume false</span><span style="color:maroon">"</span> once inlining depth is reached. + With /inline:<span style="color:blue">assert</span> call is replaced with <span style="color:maroon">"</span><span style="color:maroon">assert false</span><span style="color:maroon">"</span> once inlining depth is reached. + With /inline:spec call is left <span style="color:blue">as</span> is once inlining depth is reached. + With the above three options, methods with the attribute {<span style="color:purple">:inline</span> N} are not verified. + With /inline:none the entire attribute is ignored. + + {<span style="color:purple">:verify</span> <span style="color:blue">false</span>} + Skip verification of an implementation. + + {<span style="color:purple">:vcs_max_cost</span> N} + {<span style="color:purple">:vcs_max_splits</span> N} + {<span style="color:purple">:vcs_max_keep_going_splits</span> N} + Per-implementation versions of + /vcsMaxCost, /vcsMaxSplits and /vcsMaxKeepGoingSplits. + + {<span style="color:purple">:selective_checking</span> <span style="color:blue">true</span>} + Turn all asserts into assumes except for the ones reachable from + assumptions marked with the attribute {<span style="color:purple">:start_checking_here</span>}. + Thus, <span style="color:maroon">"</span><span style="color:maroon">assume {:start_checking_here} something;</span><span style="color:maroon">"</span> becomes an inverse + of <span style="color:maroon">"</span><span style="color:maroon">assume false;</span><span style="color:maroon">"</span>: the first one disables all verification before + it, and the second one disables all verification after. + + {<span style="color:purple">:priority</span> N} + Assign a positive priority <span style="color:maroon">'N'</span> to an implementation to control the order + <span style="color:blue">in</span> which implementations are verified (<span style="color:blue">default</span>: N = <span class="constant" style="color:purple">1</span>). + + {<span style="color:purple">:id</span> <<span style="color:teal">string</span>>} + Assign a unique ID to an implementation to be used for verification + result caching (<span style="color:blue">default</span>: <span style="color:maroon">"</span><span style="color:maroon"><impl. name>:0</span><span style="color:maroon">"</span>). + + {<span style="color:purple">:timeLimit</span> N} + Set the time limit for a given implementation. + + ---- On functions ---------------------------------------------------------- + + {<span style="color:purple">:builtin</span> <span style="color:maroon">"</span><span style="color:maroon">spec</span><span style="color:maroon">"</span>} + {<span style="color:purple">:bvbuiltin</span> <span style="color:maroon">"</span><span style="color:maroon">spec</span><span style="color:maroon">"</span>} + Rewrite the <span style="color:blue">function</span> to built-<span style="color:blue">in</span> prover <span style="color:blue">function</span> symbol 'fn'. + + {<span style="color:purple">:inline</span>} + {<span style="color:purple">:inline</span> <span style="color:blue">true</span>} + Expand <span style="color:blue">function</span> according to its definition before going to the prover. + + {<span style="color:purple">:never_pattern</span> <span style="color:blue">true</span>} + Terms starting with <span style="color:blue">this</span> <span style="color:blue">function</span> symbol will never be + automatically selected <span style="color:blue">as</span> patterns. It does not prevent them + from being used inside the triggers, and does not affect explicit + trigger annotations. Internally it works by adding {<span style="color:purple">:nopats</span> ...} + annotations to quantifiers. + + {<span style="color:purple">:identity</span>} + {<span style="color:purple">:identity</span> <span style="color:blue">true</span>} + If the <span style="color:blue">function</span> has <span class="constant" style="color:purple">1</span> argument and the use of it has <span style="color:blue">type</span> X->X for + some X, <span style="color:blue">then</span> the <span style="color:blue">abstract</span> interpreter will treat the <span style="color:blue">function</span> <span style="color:blue">as</span> an + identity <span style="color:blue">function</span>. Note, the <span style="color:blue">abstract</span> interpreter trusts the + attribute--it does not try to verify that the <span style="color:blue">function</span> really is an + identity <span style="color:blue">function</span>. + + ---- On variables ---------------------------------------------------------- + + {<span style="color:purple">:existential</span> <span style="color:blue">true</span>} + Marks a global Boolean variable <span style="color:blue">as</span> existentially quantified. If + used <span style="color:blue">in</span> combination with option /contractInfer Boogie will check + whether there <span class="code-escaped">∃<span style="font-family:serif"> </span></span>a Boolean assignment to the existentials + that makes all verification conditions valid. Without option + /contractInfer the attribute is ignored. + + ---- On <span style="color:blue">assert</span> statements -------------------------------------------------- + + {<span style="color:purple">:subsumption</span> n} + Overrides the /subsumption command-line setting for <span style="color:blue">this</span> assertion. + + {<span style="color:purple">:split_here</span>} + Verifies code leading to <span style="color:blue">this</span> point and code leading from <span style="color:blue">this</span> point + to the next split_here <span style="color:blue">as</span> separate pieces. May help with timeouts. + May also occasionally double-report errors. + + ---- The end --------------------------------------------------------------- +</code></pre> +<p class="p noindent para-continued">However a scan of Boogie's sources shows it checks for the +following attributes. +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{:$}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{:$renamed$}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:InlineAssume</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:PossiblyUnreachable</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:__dominator_enabled</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:__enabled</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:a</span>##post##}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:absdomain</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:ah</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:assumption</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:assumption_variable_initialization</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:atomic</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:aux</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:both</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:bvbuiltin</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:candidate</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:captureState</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:checksum</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:constructor</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:datatype</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:do_not_predicate</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:entrypoint</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:existential</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:exitAssert</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:expand</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:extern</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:hidden</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:ignore</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:inline</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:left</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:linear</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:linear_in</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:linear_out</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:msg</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:name</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:originated_from_invariant</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:partition</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:positive</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:post</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:pre</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:precondition_previous_snapshot</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:qid</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:right</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:selective_checking</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:si_fcall</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:si_unique_call</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:sourcefile</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:sourceline</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:split_here</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:stage_active</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:stage_complete</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:staged_houdini_tag</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:start_checking_here</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:subsumption</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:template</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:terminates</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:upper</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:verified_under</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:weight</span>}</code> +</li> +<li class="li ul-li list-star-li compact-li"><code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">{<span style="color:purple">:yields</span>}</code> +</li></ul> +<h2 id="sec-dafny-users-guide" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">25</span>. </span>Dafny User's Guide</h2><h3 id="sec-installing-dafny-from-binaries" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">25.0</span>. </span>Installing Dafny From Binaries</h3><h3 id="sec-building-dafny-from-source" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">25.1</span>. </span>Building Dafny from Source</h3> +<p class="p noindent">The current version of Dafny only works with Visual Studio 2012, +so if you intend to run Dafny from withing Visual Studio you must +install Visual Studio 2012. +</p> +<p class="p indent">Dafny performs its verification by translating the Dafny source into +the Boogie intermediate verification language. So Dafny references +data structures defined in the Boogie project. So the first step +is to clone and build Boogie from sources. See +<a href="https://github.com/boogie-org/boogie">https://github.com/boogie-org/boogie</a>. +</p> +<p class="p indent">Follow these steps. +</p> +<p class="p indent">Let <em class="em-low1">work</em> be a working directory. +</p> +<p class="p indent">Clone Boogie using +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>cd work +git clone https:<span style="color:darkgreen">//github.com/boogie-org/boogie.git</span></code></pre> +<p class="p noindent para-continued">Build Boogie using the directions from the Boogie web site, +which for Windows currently are: +</p> +<ol class="ol compact"> +<li class="li ol-li compact-li">Open Source\Boogie.sln in Visual Studio +</li> +<li class="li ol-li compact-li">Right click the Boogie solution in the Solution Explorer and click Enable NuGet Package Restore. You will probably get a prompt asking to confirm this. Choose Yes. +</li> +<li class="li ol-li compact-li">Click BUILD > Build Solution. +</li></ol> + +<p class="p noindent">Clone Dafny using Mercurial. The Dafny directory must be a sibling +of the Boogie directory in order for it to find the Boogie files it needs. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>cd work +hg clone https:<span style="color:darkgreen">//hg.codeplex.com/dafny </span></code></pre> +<p class="p noindent para-continued">Download and install the Visual Studio 2012 SDK from +</p> +<ul class="ul list-star compact"> +<li class="li ul-li list-star-li compact-li"><a href="https://www.microsoft.com/en-us/download/details.aspx?id=30668">https://www.microsoft.com/en-us/download/details.aspx?id=30668</a>. +</li></ul> + +<p class="p noindent">This is needed to build the Visual Studio Extension that +runs Dafny from within Visual Studio 2012. +</p> +<p class="p indent">Build the command-line Dafny executables. +1. Open dafny\Source\Dafny.sln in Visual Studio +2. Click BUILD > Build Solution. +</p> +<p class="p indent">Build and install the Dafny Visual Studio extensions +</p> +<ol class="ol compact"> +<li class="li ol-li compact-li">Open dafny/Source/DafnyExtension.sln in Visual Studio +</li> +<li class="li ol-li compact-li">Click BUILD > Build Solution. +</li> +<li class="li ol-li compact-li">This builds DafnyLanguageService.vsix and DafnyMenu.vsix +in the dafny/Binaries directory. +</li> +<li class="li ol-li compact-li">Install these by clicking on them from Windows Explorer. When +prompted, only check installing into Visual Studio 2012. +</li></ol> +<h3 id="sec-using-dafny-from-visual-studio" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">25.2</span>. </span>Using Dafny From Visual Studio</h3> +<p class="p noindent">To test your installation, you can open Dafny test files +from the dafny/Test subdirectory in Visual Studio 2012. +You will want to use “VIEW/Error List” to ensure that +you see any errors that Dafny detects, and +“VIEW/Output” to see the result of any compilation. +</p> +<p class="p indent">An example of a valid Dafny test is +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>dafny\Test\vstte2012\Tree.dfy</code></pre> +<p class="p noindent para-continued">You can choose “Dafny/Compile” to compile the Dafny +program to C#. Doing that for the above test +produces <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Tree.cs</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Tree.dll</code> (since this test does +not have a main program). +</p> +<p class="p indent">The following file: +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code>D:\gh\dafny\Test\dafny0\Array.dfy</code></pre> +<p class="p noindent para-continued">is an example of a Dafny file with verification errors. +The source will show red squiggles or dots where there +are errors, and the Error List window will describe the +errors. +</p><h3 id="sec-using-dafny-from-the-command-line" class="h2" data-heading-depth="2" style="display:block"><span class="heading-before"><span class="heading-label">25.3</span>. </span>Using Dafny From the Command Line</h3><h4 id="sec-dafny-command-line-options" class="h3" data-heading-depth="3" style="display:block"><span class="heading-before"><span class="heading-label">25.3.0</span>. </span>Dafny Command Line Options</h4> +<p class="p noindent">The command <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">Dafny.exe /?</code> gives the following description of +options that can be passed to Dafny. +</p> +<pre class="para-block pre-fenced pre-fenced3 language-dafnyx lang-dafnyx dafnyx colorized" style="display:block;font-size:small;margin-left:1em"><code> ---- Dafny options --------------------------------------------------------- + + Multiple .dfy files supplied on the command line are concatenated into one + Dafny program. + + /dprelude:<file> + choose Dafny prelude file + /dprint:<file> + <span style="color:blue">print</span> Dafny program after parsing it + (use - <span style="color:blue">as</span> <file> to <span style="color:blue">print</span> to console) + /printMode:<Everything|NoIncludes|NoGhost> + NoIncludes disables printing of {<span style="color:purple">:verify</span> <span style="color:blue">false</span>} methods incorporated via the + <span style="color:blue">include</span> mechanism, <span style="color:blue">as</span> well <span style="color:blue">as</span> datatypes and fields included from other files. + NoGhost disables printing of functions, <span style="color:blue">ghost</span> methods, and proof statements + <span style="color:blue">in</span> implementation methods. It also disables anything NoIncludes disables. + /rprint:<file> + <span style="color:blue">print</span> Dafny program after resolving it + (use - <span style="color:blue">as</span> <file> to <span style="color:blue">print</span> to console) + /dafnyVerify:<n> + <span class="constant" style="color:purple">0</span> - stop after typechecking + <span class="constant" style="color:purple">1</span> - continue on to translation, verification, and compilation + /compile:<n> <span class="constant" style="color:purple">0</span> - do not compile Dafny program + <span class="constant" style="color:purple">1</span> (<span style="color:blue">default</span>) - upon successful verification of the Dafny + program, compile Dafny program to .NET assembly + Program.exe (<span style="color:blue">if</span> the program has a Main <span style="color:blue">method</span>) or + Program.dll (othewise), <span style="color:blue">where</span> Program.dfy is the name + of the last .dfy file on the command line + <span class="constant" style="color:purple">2</span> - always attempt to compile Dafny program to C# program + out.cs, regardless of verification outcome + <span class="constant" style="color:purple">3</span> - <span style="color:blue">if</span> there is a Main <span style="color:blue">method</span> and there are no verification + errors, compiles program <span style="color:blue">in</span> memory (i.e., does not write + an output file) and runs it + /spillTargetCode:<n> + <span class="constant" style="color:purple">0</span> (<span style="color:blue">default</span>) - don't write the compiled Dafny program (but + still compile it, <span style="color:blue">if</span> /compile indicates to do so) + <span class="constant" style="color:purple">1</span> - write the compiled Dafny program <span style="color:blue">as</span> a .cs file + /dafnycc Disable features not supported by DafnyCC + /noCheating:<n> + <span class="constant" style="color:purple">0</span> (<span style="color:blue">default</span>) - allow <span style="color:blue">assume</span> statements and <span style="color:purple">free</span> invariants + <span class="constant" style="color:purple">1</span> - treat all assumptions <span style="color:blue">as</span> asserts, and drop <span style="color:purple">free</span>. + /induction:<n> + <span class="constant" style="color:purple">0</span> - never do induction, not even when attributes request it + <span class="constant" style="color:purple">1</span> - only apply induction when attributes request it + <span class="constant" style="color:purple">2</span> - apply induction <span style="color:blue">as</span> requested (by attributes) and also + for heuristically chosen quantifiers + <span class="constant" style="color:purple">3</span> (<span style="color:blue">default</span>) - apply induction <span style="color:blue">as</span> requested, and for + heuristically chosen quantifiers and <span style="color:blue">ghost</span> methods + /inductionHeuristic:<n> + <span class="constant" style="color:purple">0</span> - least discriminating induction heuristic (that is, lean + toward applying induction more often) + <span class="constant" style="color:purple">1</span>,<span class="constant" style="color:purple">2</span>,<span class="constant" style="color:purple">3</span>,<span class="constant" style="color:purple">4</span>,<span class="constant" style="color:purple">5</span> - levels <span style="color:blue">in</span> between, ordered <span style="color:blue">as</span> follows <span style="color:blue">as</span> far <span style="color:blue">as</span> + how discriminating they are: <span class="constant" style="color:purple">0</span> < <span class="constant" style="color:purple">1</span> < <span class="constant" style="color:purple">2</span> < (<span class="constant" style="color:purple">3</span>,<span class="constant" style="color:purple">4</span>) < <span class="constant" style="color:purple">5</span> < <span class="constant" style="color:purple">6</span> + <span class="constant" style="color:purple">6</span> (<span style="color:blue">default</span>) - most discriminating + /noIncludes Ignore <span style="color:blue">include</span> directives + /noNLarith Reduce Z3's knowledge of non-linear arithmetic (*,/,%). + Results <span style="color:blue">in</span> more manual work, but also produces more predictable behavior. + /autoReqPrint:<file> + Print out requirements that were automatically generated by autoReq. + /noAutoReq Ignore autoReq attributes + /allowGlobals Allow the implicit <span style="color:blue">class</span> '_default' to contain fields, instance functions, + and instance methods. These <span style="color:blue">class</span> members are declared at the <span style="color:blue">module</span> scope, + outside of explicit classes. This command-line option is provided to simply + a transition from the behavior <span style="color:blue">in</span> the language prior to version <span class="constant" style="color:purple">1.9</span>.<span class="constant" style="color:purple">3</span>, from + which point onward all functions and methods declared at the <span style="color:blue">module</span> scope are + implicitly <span style="color:blue">static</span> and fields declarations are not allowed at the <span style="color:blue">module</span> scope. + The reference manual is written assuming <span style="color:blue">this</span> option is not given. + + + /nologo suppress printing of version number, copyright message + /env:<n> <span style="color:blue">print</span> command line arguments + <span class="constant" style="color:purple">0</span> - never, <span class="constant" style="color:purple">1</span> (<span style="color:blue">default</span>) - during BPL <span style="color:blue">print</span> and prover log, + <span class="constant" style="color:purple">2</span> - like <span class="constant" style="color:purple">1</span> and also to standard output + /wait <span style="color:blue">await</span> Enter from keyboard before terminating program + /xml:<file> also produce output <span style="color:blue">in</span> XML format to <file> + + ---- Boogie options -------------------------------------------------------- + + Multiple .bpl files supplied on the command line are concatenated into one + Boogie program. + + /proc:<p> : limits which procedures to check + /noResolve : parse only + /noTypecheck : parse and resolve only + + /<span style="color:blue">print</span>:<file> : <span style="color:blue">print</span> Boogie program after parsing it + (use - <span style="color:blue">as</span> <file> to <span style="color:blue">print</span> to console) + /pretty:<n> + <span class="constant" style="color:purple">0</span> - <span style="color:blue">print</span> each Boogie statement on one line (faster). + <span class="constant" style="color:purple">1</span> (<span style="color:blue">default</span>) - pretty-<span style="color:blue">print</span> with some line breaks. + /printWithUniqueIds : <span style="color:blue">print</span> augmented information that uniquely + identifies variables + /printUnstructured : with /<span style="color:blue">print</span> option, desugars all structured statements + /printDesugared : with /<span style="color:blue">print</span> option, desugars calls + + /overlookTypeErrors : skip any implementation with resolution or <span style="color:blue">type</span> + checking errors + + /loopUnroll:<n> + unroll loops, following up to n back edges (and <span style="color:blue">then</span> some) + /soundLoopUnrolling + sound loop unrolling + /printModel:<n> + <span class="constant" style="color:purple">0</span> (<span style="color:blue">default</span>) - do not <span style="color:blue">print</span> Z3's error model + <span class="constant" style="color:purple">1</span> - <span style="color:blue">print</span> Z3's error model + <span class="constant" style="color:purple">2</span> - <span style="color:blue">print</span> Z3's error model plus reverse mappings + <span class="constant" style="color:purple">4</span> - <span style="color:blue">print</span> Z3's error model <span style="color:blue">in</span> a more human readable way + /printModelToFile:<file> + <span style="color:blue">print</span> model to <file> instead of console + /mv:<file> Specify file <span style="color:blue">where</span> to save the model <span style="color:blue">in</span> BVD format + /enhancedErrorMessages:<n> + <span class="constant" style="color:purple">0</span> (<span style="color:blue">default</span>) - no enhanced error messages + <span class="constant" style="color:purple">1</span> - Z3 error model enhanced error messages + + /printCFG:<prefix> : <span style="color:blue">print</span> control flow graph of each implementation <span style="color:blue">in</span> + Graphviz format to files named: + <prefix>.<procedure name>.dot + + /useBaseNameForFileName : When parsing use basename of file for tokens instead + of the path supplied on the command line + + ---- Inference options ----------------------------------------------------- + + /infer:<flags> + use <span style="color:blue">abstract</span> interpretation to infer invariants + The <span style="color:blue">default</span> is /infer:i + <flags> are <span style="color:blue">as</span> follows (missing <flags> means all) + i = intervals + c = constant propagation + d = dynamic <span style="color:blue">type</span> + n = nullness + p = polyhedra for linear inequalities + t = trivial bottom/top lattice (cannot be combined with + other domains) + j = stronger intervals (cannot be combined with other + domains) + or the following (which denote options, not domains): + s = debug statistics + <span class="constant" style="color:purple">0</span>..<span class="constant" style="color:purple">9</span> = number of iterations before applying a widen (<span style="color:blue">default</span>=<span class="constant" style="color:purple">0</span>) + /noinfer turn off the <span style="color:blue">default</span> inference, and overrides the /infer + switch on its left + /checkInfer instrument inferred invariants <span style="color:blue">as</span> asserts to be checked by + theorem prover + /interprocInfer + perform interprocedural inference (deprecated, not supported) + /contractInfer + perform procedure contract inference + /instrumentInfer + h - instrument inferred invariants only at beginning of + loop headers (<span style="color:blue">default</span>) + e - instrument inferred invariants at beginning and end + of every block (<span style="color:blue">this</span> mode is intended for use <span style="color:blue">in</span> + debugging of <span style="color:blue">abstract</span> domains) + /printInstrumented + <span style="color:blue">print</span> Boogie program after it has been instrumented with + invariants + + ---- Debugging and general tracing options --------------------------------- + + /trace blurt out various debug trace information + /traceTimes output timing information at certain points <span style="color:blue">in</span> the pipeline + /tracePOs output information about the number of proof obligations + (also included <span style="color:blue">in</span> the /trace output) + /log[:<span style="color:blue">method</span>] Print debug output during translation + + /<span style="color:blue">break</span> launch and <span style="color:blue">break</span> into debugger + + ---- Verification-condition generation options ----------------------------- + + /liveVariableAnalysis:<c> + <span class="constant" style="color:purple">0</span> = do not perform live variable analysis + <span class="constant" style="color:purple">1</span> = perform live variable analysis (<span style="color:blue">default</span>) + <span class="constant" style="color:purple">2</span> = perform interprocedural live variable analysis + /noVerify skip VC generation and invocation of the theorem prover + /verifySnapshots:<n> + verify several program snapshots (named <filename>.v0.bpl + to <filename>.vN.bpl) using verification result caching: + <span class="constant" style="color:purple">0</span> - do not use any verification result caching (<span style="color:blue">default</span>) + <span class="constant" style="color:purple">1</span> - use the basic verification result caching + <span class="constant" style="color:purple">2</span> - use the more advanced verification result caching + /verifySeparately + verify each input program separately + /removeEmptyBlocks:<c> + <span class="constant" style="color:purple">0</span> - do not remove empty blocks during VC generation + <span class="constant" style="color:purple">1</span> - remove empty blocks (<span style="color:blue">default</span>) + /coalesceBlocks:<c> + <span class="constant" style="color:purple">0</span> = do not coalesce blocks + <span class="constant" style="color:purple">1</span> = coalesce blocks (<span style="color:blue">default</span>) + /vc:<variety> n = nested block (<span style="color:blue">default</span> for /prover:Simplify), + m = nested block reach, + b = flat block, r = flat block reach, + s = structured, l = local, + d = dag (<span style="color:blue">default</span>, except with /prover:Simplify) + doomed = doomed + /traceverify <span style="color:blue">print</span> debug output during verification condition generation + /subsumption:<c> + apply subsumption to asserted conditions: + <span class="constant" style="color:purple">0</span> - never, <span class="constant" style="color:purple">1</span> - not for quantifiers, <span class="constant" style="color:purple">2</span> (<span style="color:blue">default</span>) - always + /alwaysAssumeFreeLoopInvariants + usually, a <span style="color:purple">free</span> loop <span style="color:purple">invariant</span> (or <span style="color:blue">assume</span> + statement <span style="color:blue">in</span> that position) is ignored <span style="color:blue">in</span> checking contexts + (like other <span style="color:purple">free</span> things); <span style="color:blue">this</span> option includes these <span style="color:purple">free</span> + loop invariants <span style="color:blue">as</span> assumes <span style="color:blue">in</span> both contexts + /inline:<i> use inlining strategy <i> for procedures with the :inline + attribute, see /attrHelp for details: + none + <span style="color:blue">assume</span> (<span style="color:blue">default</span>) + <span style="color:blue">assert</span> + spec + /printInlined + <span style="color:blue">print</span> the implementation after inlining calls to + procedures with the :inline attribute (works with /inline) + /lazyInline:<span class="constant" style="color:purple">1</span> + Use the lazy inlining algorithm + /stratifiedInline:<span class="constant" style="color:purple">1</span> + Use the stratified inlining algorithm + /fixedPointEngine:<engine> + Use the specified fixed point engine for inference + /recursionBound:<n> + Set the recursion bound for stratified inlining to + be n (<span style="color:blue">default</span> <span class="constant" style="color:purple">500</span>) + /inferLeastForUnsat:<str> + Infer the least number of constants (whose names + are prefixed by <str>) that need to be <span style="color:teal">set</span> to + <span style="color:blue">true</span> for the program to be correct. This turns + on stratified inlining. + /smoke Soundness Smoke Test: try to stick <span style="color:blue">assert</span> <span style="color:blue">false</span>; <span style="color:blue">in</span> some + places <span style="color:blue">in</span> the BPL and see <span style="color:blue">if</span> we can still prove it + /smokeTimeout:<n> + Timeout, <span style="color:blue">in</span> seconds, for a single theorem prover + invocation during smoke test, defaults to <span class="constant" style="color:purple">10</span>. + /causalImplies + Translate Boogie's A ==> B into prover's A ==> A && B. + /typeEncoding:<m> + how to encode types when sending VC to theorem prover + n = none (unsound) + p = predicates (<span style="color:blue">default</span>) + a = arguments + m = monomorphic + /monomorphize + Do not <span style="color:blue">abstract</span> <span style="color:teal">map</span> types <span style="color:blue">in</span> the encoding (<span style="color:blue">this</span> is an + experimental feature that will not do the right thing <span style="color:blue">if</span> + the program uses polymorphism) + /reflectAdd In the VC, generate an auxiliary symbol, elsewhere defined + to be +, instead of +. + + ---- Verification-condition splitting -------------------------------------- + + /vcsMaxCost:<f> + VC will not be split unless the cost of a VC exceeds <span style="color:blue">this</span> + number, defaults to <span class="constant" style="color:purple">2000.0</span>. This does NOT apply <span style="color:blue">in</span> the + keep-going mode after first round of splitting. + /vcsMaxSplits:<n> + Maximal number of VC generated per <span style="color:blue">method</span>. In keep + going mode only applies to the first round. + Defaults to <span class="constant" style="color:purple">1</span>. + /vcsMaxKeepGoingSplits:<n> + If <span style="color:teal">set</span> to more than <span class="constant" style="color:purple">1</span>, activates the keep + going mode, <span style="color:blue">where</span> after the first round of splitting, + VCs that timed out are split into <n> pieces and retried + until we succeed proving them, or there is only one + assertion on a single path and it timeouts (<span style="color:blue">in</span> which + <span style="color:blue">case</span> error is reported for that assertion). + Defaults to <span class="constant" style="color:purple">1</span>. + /vcsKeepGoingTimeout:<n> + Timeout <span style="color:blue">in</span> seconds for a single theorem prover + invocation <span style="color:blue">in</span> keep going mode, except for the final + single-assertion <span style="color:blue">case</span>. Defaults to <span class="constant" style="color:purple">1</span>s. + /vcsFinalAssertTimeout:<n> + Timeout <span style="color:blue">in</span> seconds for the single last + assertion <span style="color:blue">in</span> the keep going mode. Defaults to <span class="constant" style="color:purple">30</span>s. + /vcsPathJoinMult:<f> + If more than one path join at a block, by how much + multiply the number of paths <span style="color:blue">in</span> that block, to accomodate + for the fact that the prover will learn something on one + paths, before proceeding to another. Defaults to <span class="constant" style="color:purple">0.8</span>. + /vcsPathCostMult:<f1> + /vcsAssumeMult:<f2> + The cost of a block is + (<<span style="color:blue">assert</span>-cost> + <f2>*<<span style="color:blue">assume</span>-cost>) * + (<span class="constant" style="color:purple">1.0</span> + <f1>*<entering-paths>) + <f1> defaults to <span class="constant" style="color:purple">1.0</span>, <f2> defaults to <span class="constant" style="color:purple">0.01</span>. + The cost of a single assertion or assumption is + currently always <span class="constant" style="color:purple">1.0</span>. + /vcsPathSplitMult:<f> + If the best path split of a VC of cost A is into + VCs of cost B and C, <span style="color:blue">then</span> the split is applied <span style="color:blue">if</span> + A >= <f>*(B+C), otherwise assertion splitting will be + applied. Defaults to <span class="constant" style="color:purple">0.5</span> (always do path splitting <span style="color:blue">if</span> + possible), <span style="color:teal">set</span> to more to do less path splitting + and more assertion splitting. + /vcsDumpSplits + For split #n dump split.n.dot and split.n.bpl. + Warning: Affects error reporting. + /vcsCores:<n> + Try to verify <n> VCs at once. Defaults to <span class="constant" style="color:purple">1</span>. + /vcsLoad:<f> Sets vcsCores to the machine's ProcessorCount * f, + rounded to the nearest integer (<span style="color:blue">where</span> <span class="constant" style="color:purple">0.0</span> <= f <= <span class="constant" style="color:purple">3.0</span>), + but never to less than <span class="constant" style="color:purple">1</span>. + + ---- Prover options -------------------------------------------------------- + + /errorLimit:<num> + Limit the number of errors produced for each procedure + (<span style="color:blue">default</span> is <span class="constant" style="color:purple">5</span>, some provers may support only <span class="constant" style="color:purple">1</span>) + /timeLimit:<num> + Limit the number of seconds spent trying to verify + each procedure + /errorTrace:<n> + <span class="constant" style="color:purple">0</span> - no Trace labels <span style="color:blue">in</span> the error output, + <span class="constant" style="color:purple">1</span> (<span style="color:blue">default</span>) - <span style="color:blue">include</span> useful Trace labels <span style="color:blue">in</span> error output, + <span class="constant" style="color:purple">2</span> - <span style="color:blue">include</span> all Trace labels <span style="color:blue">in</span> the error output + /vcBrackets:<b> + bracket odd-charactered identifier names with |'s. <b> is: + <span class="constant" style="color:purple">0</span> - no (<span style="color:blue">default</span> with non-/prover:Simplify), + <span class="constant" style="color:purple">1</span> - yes (<span style="color:blue">default</span> with /prover:Simplify) + /prover:<tp> use theorem prover <tp>, <span style="color:blue">where</span> <tp> is either the name of + a DLL containing the prover interface located <span style="color:blue">in</span> the + Boogie directory, or a full path to a DLL containing such + an interface. The standard interfaces shipped <span style="color:blue">include</span>: + SMTLib (<span style="color:blue">default</span>, uses the SMTLib2 format and calls Z3) + Z3 (uses Z3 with the Simplify format) + Simplify + ContractInference (uses Z3) + Z3api (Z3 using Managed .NET API) + /proverOpt:KEY[=VALUE] + Provide a prover-specific option (short form /p). + /proverLog:<file> + Log input for the theorem prover. Like filenames + supplied <span style="color:blue">as</span> arguments to other options, <file> can use the + following macros: + @TIME@ expands to the current time + @PREFIX@ expands to the concatenation of strings given + by /logPrefix options + @FILE@ expands to the last filename specified on the + command line + In addition, /proverLog can also use the macro '@PROC@', + which causes there to be one prover log file per + verification condition, and the macro <span style="color:blue">then</span> expands to the + name of the procedure that the verification condition is for. + /logPrefix:<str> + Defines the expansion of the macro '@PREFIX@', which can + be used <span style="color:blue">in</span> various filenames specified by other options. + /proverLogAppend + Append (not overwrite) the specified prover log file + /proverWarnings + <span class="constant" style="color:purple">0</span> (<span style="color:blue">default</span>) - don't <span style="color:blue">print</span>, <span class="constant" style="color:purple">1</span> - <span style="color:blue">print</span> to stdout, + <span class="constant" style="color:purple">2</span> - <span style="color:blue">print</span> to stderr + /proverMemoryLimit:<num> + Limit on the virtual memory for prover before + restart <span style="color:blue">in</span> MB (<span style="color:blue">default</span>:<span class="constant" style="color:purple">100</span>MB) + /restartProver + Restart the prover after each query + /proverShutdownLimit<num> + Time between closing the stream to the prover and + killing the prover process (<span style="color:blue">default</span>: <span class="constant" style="color:purple">0</span>s) + /platform:<ptype>,<location> + ptype = v11,v2,cli1 + location = platform libraries directory + + Simplify specific options: + /simplifyMatchDepth:<num> + Set Simplify prover's matching depth limit + + Z3 specific options: + /z3opt:<arg> specify additional Z3 options + /z3multipleErrors + report multiple counterexamples for each error + /useArrayTheory + use Z3's native theory (<span style="color:blue">as</span> opposed to axioms). Currently + implies /monomorphize. + /useSmtOutputFormat + Z3 outputs a model <span style="color:blue">in</span> the SMTLIB2 format. + /z3types generate multi-sorted VC that make use of Z3 types + /z3lets:<n> <span class="constant" style="color:purple">0</span> - no LETs, <span class="constant" style="color:purple">1</span> - only LET TERM, <span class="constant" style="color:purple">2</span> - only LET FORMULA, + <span class="constant" style="color:purple">3</span> - (<span style="color:blue">default</span>) any + /z3exe:<path> + path to Z3 executable + + CVC4 specific options: + /cvc4exe:<path> + path to CVC4 executable +</code></pre><h2 id="sec-references" class="h1" data-heading-depth="1" style="display:block"><span class="heading-before"><span class="heading-label">26</span>. </span>References</h2> +<div class="bibl" style="bbl-file:out/DafnyRef-bib.bbl.mdk"> +<div class="bibliography bib-numeric" data-style="plainnat" style="bibstyle:madoko-numeric"><h2 id="sec-references" class="clearnum h1 heading-references" data-heading-depth="1" style="display:block">References</h2> +<div id="boogie:architecture" class="bibitem" data-cite-label="0" data-cite-year="2006" data-cite-authors="Barnett et\ al." data-cite-authors-long="Barnett, Chang, DeLine, Jacobs, and + Leino" style="searchterm:Mike+Barnett+Evan+Chang+Robert+DeLine+Bart+Jacobs+Rustan+Leino+Boogie+modular+reusable+verifier+object+oriented+programs+Frank+Boer+Marcello+Bonsangue+Susanne+Graf+Willem+Paul+Roever+editors+_Formal+Methods+Components+Objects+International+Symposium+FMCO+volume+pages+Springer+September++"><span class="bibitem-before">[0]  </span>Mike Barnett, Bor-Yuh Evan Chang, Robert DeLine, Bart Jacobs, and K. Rustan M. + Leino. +<span class="newblock"></span> Boogie: A modular reusable verifier for object-oriented programs. +<span class="newblock"></span> In Frank S. de Boer, Marcello M. Bonsangue, Susanne Graf, and + Willem-Paul de Roever, editors, <em class="em-low1">Formal Methods for Components and + Objects: 4th International Symposium, FMCO 2005</em>, volume 4111, pages + 364–387. Springer, September 2006. <a href="http://www.bing.com/search?q=Mike+Barnett+Evan+Chang+Robert+DeLine+Bart+Jacobs+Rustan+Leino+Boogie+modular+reusable+verifier+object+oriented+programs+Frank+Boer+Marcello+Bonsangue+Susanne+Graf+Willem+Paul+Roever+editors+_Formal+Methods+Components+Objects+International+Symposium+FMCO+volume+pages+Springer+September++" class="bibsearch">🔎</a></div> +<div id="coq:book" class="bibitem" data-cite-label="1" data-cite-year="2004" data-cite-authors="Bertot and Castéran" style="searchterm:Yves+Bertot+Pierre+Cast+_Interactive+Theorem+Proving+Program+Development+Calculus+Inductive+Constructions_+Texts+Theoretical+Computer+Science+Springer++"><span class="bibitem-before">[1]  </span>Yves Bertot and Pierre Castéran. +<span class="newblock"></span> <em class="em-low1">Interactive Theorem Proving and Program Development — + Coq'Art: The Calculus of Inductive Constructions</em>. +<span class="newblock"></span> Texts in Theoretical Computer Science. Springer, 2004. <a href="http://www.bing.com/search?q=Yves+Bertot+Pierre+Cast+_Interactive+Theorem+Proving+Program+Development+Calculus+Inductive+Constructions_+Texts+Theoretical+Computer+Science+Springer++" class="bibsearch">🔎</a></div> +<div id="bovedybjernorell:briefagda" class="bibitem" data-cite-label="2" data-cite-year="2009" data-cite-authors="Bove et\ al." data-cite-authors-long="Bove, Dybjer, and Norell" style="searchterm:+Bove+Peter+Dybjer+Norell+brief+overview+Agda+functional+language+with+dependent+types+Stefan+Berghofer+Tobias+Nipkow+Christian+Urban+Makarius+Wenzel+editors+_Theorem+Proving+Higher+Order+Logics+International+Conference+TPHOLs+volume+_Lecture+Notes+Computer+Science_+pages+Springer+August++"><span class="bibitem-before">[2]  </span>Ana Bove, Peter Dybjer, and Ulf Norell. +<span class="newblock"></span> A brief overview of Agda — a functional language with dependent + types. +<span class="newblock"></span> In Stefan Berghofer, Tobias Nipkow, Christian Urban, and Makarius + Wenzel, editors, <em class="em-low1">Theorem Proving in Higher Order Logics, 22nd + International Conference, TPHOLs 2009</em>, volume 5674 of <em class="em-low1">Lecture Notes in + Computer Science</em>, pages 73–78. Springer, August 2009. <a href="http://www.bing.com/search?q=+Bove+Peter+Dybjer+Norell+brief+overview+Agda+functional+language+with+dependent+types+Stefan+Berghofer+Tobias+Nipkow+Christian+Urban+Makarius+Wenzel+editors+_Theorem+Proving+Higher+Order+Logics+International+Conference+TPHOLs+volume+_Lecture+Notes+Computer+Science_+pages+Springer+August++" class="bibsearch">🔎</a></div> +<div id="camillerimelham:inductiverelations" class="bibitem" data-cite-label="3" data-cite-year="1992" data-cite-authors="Camilleri and Melham" style="searchterm:Juanito+Camilleri+Melham+Reasoning+with+inductively+defined+relations+theorem+prover+Technical+Report+University+Cambridge+Computer+Laboratory++"><span class="bibitem-before">[3]  </span>Juanito Camilleri and Tom Melham. +<span class="newblock"></span> Reasoning with inductively defined relations in the HOL theorem + prover. +<span class="newblock"></span> Technical Report 265, University of Cambridge Computer Laboratory, + 1992. <a href="http://www.bing.com/search?q=Juanito+Camilleri+Melham+Reasoning+with+inductively+defined+relations+theorem+prover+Technical+Report+University+Cambridge+Computer+Laboratory++" class="bibsearch">🔎</a></div> +<div id="demourabjorner:z3:overview" class="bibitem" data-cite-label="4" data-cite-year="2008" data-cite-authors="de\ Moura and Bjørner" style="searchterm:+efficient+solver++Leonardo+Moura+Nikolaj+rner+"><span class="bibitem-before">[4]  </span>Leonardo de Moura and Nikolaj Bjørner. +<span class="newblock"></span> Z3: An efficient SMT solver. +<span class="newblock"></span> In C. R. Ramakrishnan and Jakob Rehof, editors, <em class="em-low1">Tools and + Algorithms for the Construction and Analysis of Systems, 14th International + Conference, TACAS 2008</em>, volume 4963, pages 337–340. Springer, March–April + 2008. <a href="http://www.bing.com/search?q=+efficient+solver++Leonardo+Moura+Nikolaj+rner+" class="bibsearch">🔎</a></div> +<div id="msr:dafny:source" class="bibitem" data-cite-label="5" data-cite-authors="et\ al" style="searchterm:Dafny+source+code+++Rustan+Leino+"><span class="bibitem-before">[5]  </span>K. Rustan M. Leino et al. +<span class="newblock"></span> Dafny source code. +<span class="newblock"></span> Available at <a href="http://dafny.codeplex.com">http://dafny.codeplex.com</a>. <a href="http://www.bing.com/search?q=Dafny+source+code+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="harrison:inductivedefs" class="bibitem" data-cite-label="6" data-cite-year="1995" data-cite-authors="Harrison" style="searchterm:Inductive+definitions+Automation+application++John+Harrison+"><span class="bibitem-before">[6]  </span>John Harrison. +<span class="newblock"></span> Inductive definitions: Automation and application. +<span class="newblock"></span> In E. Thomas Schubert, Phillip J. Windley, and Jim Alves-Foss, + editors, <em class="em-low1">TPHOLs 1995</em>, volume 971 of <em class="em-low1">LNCS</em>, pages 200–213. + Springer, 1995. <a href="http://www.bing.com/search?q=Inductive+definitions+Automation+application++John+Harrison+" class="bibsearch">🔎</a></div> +<div id="hoare:axiomaticbasis" class="bibitem" data-cite-label="7" data-cite-year="1969" data-cite-authors="Hoare" style="searchterm:+axiomatic+basis+computer+programming+++Hoare+"><span class="bibitem-before">[7]  </span>C. A. R. Hoare. +<span class="newblock"></span> An axiomatic basis for computer programming. +<span class="newblock"></span> <em class="em-low1">Communications of the ACM</em>, 12<span style="penalty:0"></span> (10):<span style="penalty:0"></span> + 576–580,583, October 1969. <a href="http://www.bing.com/search?q=+axiomatic+basis+computer+programming+++Hoare+" class="bibsearch">🔎</a></div> +<div id="jacobsrutten:introductioncoalgebra" class="bibitem" data-cite-label="8" data-cite-year="2011" data-cite-authors="Jacobs and Rutten" style="searchterm:+introduction+algebra+induction++Bart+Jacobs+Rutten+"><span class="bibitem-before">[8]  </span>Bart Jacobs and Jan Rutten. +<span class="newblock"></span> An introduction to (co)algebra and (co)induction. +<span class="newblock"></span> In Davide Sangiorgi and Jan Rutten, editors, <em class="em-low1">Advanced Topics in + Bisimulation and Coinduction</em>, number 52 in Cambridge Tracts in Theoretical + Computer Science, pages 38–99. Cambridge University Press, October 2011. <a href="http://www.bing.com/search?q=+introduction+algebra+induction++Bart+Jacobs+Rutten+" class="bibsearch">🔎</a></div> +<div id="kassios:fm2006" class="bibitem" data-cite-label="9" data-cite-year="2006" data-cite-authors="Kassios" style="searchterm:Ioannis+Kassios+Dynamic+frames+Support+framing+dependencies+sharing+without+restrictions+Jayadev+Misra+Tobias+Nipkow+Emil+Sekerinski+editors+Formal+Methods+International+Symposium+Formal+Methods_+volume+pages+Springer+August++"><span class="bibitem-before">[9]  </span>Ioannis T. Kassios. +<span class="newblock"></span> Dynamic frames: Support for framing, dependencies and sharing without + restrictions. +<span class="newblock"></span> In Jayadev Misra, Tobias Nipkow, and Emil Sekerinski, editors, + <em class="em-low1">FM 2006: Formal Methods, 14th International Symposium on Formal + Methods</em>, volume 4085, pages 268–283. Springer, August 2006. <a href="http://www.bing.com/search?q=Ioannis+Kassios+Dynamic+frames+Support+framing+dependencies+sharing+without+restrictions+Jayadev+Misra+Tobias+Nipkow+Emil+Sekerinski+editors+Formal+Methods+International+Symposium+Formal+Methods_+volume+pages+Springer+August++" class="bibsearch">🔎</a></div> +<div id="acl2:book" class="bibitem" data-cite-label="10" data-cite-year="2000" data-cite-authors="Kaufmann et\ al." data-cite-authors-long="Kaufmann, Manolios, and Moore" style="searchterm:_Computer+Aided+Reasoning+Approach_++Matt+Kaufmann+Panagiotis+Manolios+Strother+Moore+"><span class="bibitem-before">[10]  </span>Matt Kaufmann, Panagiotis Manolios, and J Strother Moore. +<span class="newblock"></span> <em class="em-low1">Computer-Aided Reasoning: An Approach</em>. +<span class="newblock"></span> Kluwer Academic Publishers, 2000. <a href="http://www.bing.com/search?q=_Computer+Aided+Reasoning+Approach_++Matt+Kaufmann+Panagiotis+Manolios+Strother+Moore+" class="bibsearch">🔎</a></div> +<div id="kozensilva:coinduction" class="bibitem" data-cite-label="11" data-cite-year="2012" data-cite-authors="Kozen and Silva" style="searchterm:Practical+coinduction++Dexter+Kozen+Alexandra+Silva+"><span class="bibitem-before">[11]  </span>Dexter Kozen and Alexandra Silva. +<span class="newblock"></span> Practical coinduction. +<span class="newblock"></span> Technical Report <a href="http://hdl.handle.net/1813/30510">http://hdl.handle.net/1813/30510</a>, Comp. and + Inf. Science, Cornell Univ., 2012. <a href="http://www.bing.com/search?q=Practical+coinduction++Dexter+Kozen+Alexandra+Silva+" class="bibsearch">🔎</a></div> +<div id="krauss:phd" class="bibitem" data-cite-label="12" data-cite-year="2009" data-cite-authors="Krauss" style="searchterm:Alexander+Krauss+_Automating+Recursive+Definitions+Termination+Proofs+Higher+Order+Logic_+thesis+Technische+Universit+nchen++"><span class="bibitem-before">[12]  </span>Alexander Krauss. +<span class="newblock"></span> <em class="em-low1">Automating Recursive Definitions and Termination Proofs in + Higher-Order Logic</em>. +<span class="newblock"></span> PhD thesis, Technische Universität München, 2009. <a href="http://www.bing.com/search?q=Alexander+Krauss+_Automating+Recursive+Definitions+Termination+Proofs+Higher+Order+Logic_+thesis+Technische+Universit+nchen++" class="bibsearch">🔎</a></div> +<div id="msr:dafny:main" class="bibitem" data-cite-label="13" data-cite-authors="Leino" data-cite-authors-long="a)" style="searchterm:Main+microsoft+research+dafny+page+++Rustan+Leino+"><span class="bibitem-before">[13]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Main microsoft research dafny web page, a. +<span class="newblock"></span> Available at + <a href="http://research.microsoft.com/en-us/projects/dafny">http://research.microsoft.com/en-us/projects/dafny</a>. <a href="http://www.bing.com/search?q=Main+microsoft+research+dafny+page+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="msr:dafny:quickref" class="bibitem" data-cite-label="14" data-cite-authors="Leino" data-cite-authors-long="b)" style="searchterm:Dafny+quick+reference+++Rustan+Leino+"><span class="bibitem-before">[14]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Dafny quick reference, b. +<span class="newblock"></span> Available at + <a href="http://research.microsoft.com/en-us/projects/dafny/reference.aspx">http://research.microsoft.com/en-us/projects/dafny/reference.aspx</a>. <a href="http://www.bing.com/search?q=Dafny+quick+reference+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="rise4fun:dafny" class="bibitem" data-cite-label="15" data-cite-authors="Leino" data-cite-authors-long="c)" style="searchterm:+dafny+your+browser+++Rustan+Leino+"><span class="bibitem-before">[15]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Try dafny in your browser, c. +<span class="newblock"></span> Available at <a href="http://rise4fun.com/Dafny">http://rise4fun.com/Dafny</a>. <a href="http://www.bing.com/search?q=+dafny+your+browser+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="leino:boogie2-refman" class="bibitem" data-cite-label="16" data-cite-year="2008" data-cite-authors="Leino" style="searchterm:This+Boogie+++Rustan+Leino+"><span class="bibitem-before">[16]  </span>K. Rustan M. Leino. +<span class="newblock"></span> This is Boogie 2. +<span class="newblock"></span> Manuscript KRML 178, 2008. +<span class="newblock"></span> Available at <a href="http://research.microsoft.com/~leino/papers.html">http://research.microsoft.com/~leino/papers.html</a>. <a href="http://www.bing.com/search?q=This+Boogie+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="leino:dafny:dynamicframes" class="bibitem" data-cite-label="17" data-cite-year="2009" data-cite-authors="Leino" style="searchterm:Dynamic+frame+specifications+dafny+++Rustan+Leino+"><span class="bibitem-before">[17]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Dynamic-frame specifications in dafny. +<span class="newblock"></span> JML seminar, Dagstuhl, Germany, 2009. +<span class="newblock"></span> Available at + <a href="http://research.microsoft.com/en-us/um/people/leino/papers/dafny-jml-dagstuhl-2009.pptx">http://research.microsoft.com/en-us/um/people/leino/papers/dafny-jml-dagstuhl-2009.pptx</a>. <a href="http://www.bing.com/search?q=Dynamic+frame+specifications+dafny+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="leino:dafny:lpar16" class="bibitem" data-cite-label="18" data-cite-year="2010" data-cite-authors="Leino" style="searchterm:Dafny+automatic+program+verifier+functional+correctness+++Rustan+Leino+"><span class="bibitem-before">[18]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Dafny: An automatic program verifier for functional correctness. +<span class="newblock"></span> In Edmund M. Clarke and Andrei Voronkov, editors, <em class="em-low1">LPAR-16</em>, + volume 6355, pages 348–370. Springer, April 2010. <a href="http://www.bing.com/search?q=Dafny+automatic+program+verifier+functional+correctness+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="leino:induction" class="bibitem" data-cite-label="19" data-cite-year="2012" data-cite-authors="Leino" style="searchterm:Automating+induction+with+solver+++Rustan+Leino+"><span class="bibitem-before">[19]  </span>K. Rustan M. Leino. +<span class="newblock"></span> Automating induction with an SMT solver. +<span class="newblock"></span> In Viktor Kuncak and Andrey Rybalchenko, editors, <em class="em-low1">Verification, + Model Checking, and Abstract Interpretation — 13th International + Conference, VMCAI 2012</em>, volume 7148, pages 315–331. Springer, January 2012. <a href="http://www.bing.com/search?q=Automating+induction+with+solver+++Rustan+Leino+" class="bibsearch">🔎</a></div> +<div id="leino:dafny:coinduction" class="bibitem" data-cite-label="20" data-cite-year="2014a" data-cite-authors="Leino and Moskal" style="searchterm:+Rustan+Leino+Michal+Moskal+induction+simply+Automatic+inductive+proofs+program+verifier+Manuscript+KRML+Available+http+research+microsoft+people+leino+papers+krml230++"><span class="bibitem-before">[20]  </span>K. Rustan M. Leino and Michal Moskal. +<span class="newblock"></span> Co-induction simply: Automatic co-inductive proofs in a program + verifier. +<span class="newblock"></span> Manuscript KRML 230, 2014a. +<span class="newblock"></span> Available at + <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf">http://research.microsoft.com/en-us/um/people/leino/papers/krml230.pdf</a>. <a href="http://www.bing.com/search?q=+Rustan+Leino+Michal+Moskal+induction+simply+Automatic+inductive+proofs+program+verifier+Manuscript+KRML+Available+http+research+microsoft+people+leino+papers+krml230++" class="bibsearch">🔎</a></div> +<div id="leinomoskal:coinduction" class="bibitem" data-cite-label="21" data-cite-year="2014b" data-cite-authors="Leino and Moskal" style="searchterm:+Rustan+Leino+Micha+Moskal+induction+simply+automatic+inductive+proofs+program+verifier+volume+_LNCS_+pages+Springer++"><span class="bibitem-before">[21]  </span>K. Rustan M. Leino and Michał Moskal. +<span class="newblock"></span> Co-induction simply — automatic co-inductive proofs in a program + verifier. +<span class="newblock"></span> In <em class="em-low1">FM 2014</em>, volume 8442 of <em class="em-low1">LNCS</em>, pages 382–398. + Springer, May 2014b. <a href="http://www.bing.com/search?q=+Rustan+Leino+Micha+Moskal+induction+simply+automatic+inductive+proofs+program+verifier+volume+_LNCS_+pages+Springer++" class="bibsearch">🔎</a></div> +<div id="leino:dafny:calc" class="bibitem" data-cite-label="22" data-cite-year="2013" data-cite-authors="Leino and Polikarpova" style="searchterm:Verified+calculations+++Rustan+Leino+Nadia+Polikarpova+"><span class="bibitem-before">[22]  </span>K. Rustan M. Leino and Nadia Polikarpova. +<span class="newblock"></span> Verified calculations. +<span class="newblock"></span> Manuscript KRML 231, 2013. +<span class="newblock"></span> Available at + <a href="http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf">http://research.microsoft.com/en-us/um/people/leino/papers/krml231.pdf</a>. <a href="http://www.bing.com/search?q=Verified+calculations+++Rustan+Leino+Nadia+Polikarpova+" class="bibsearch">🔎</a></div> +<div id="leinoruemmer:boogie2" class="bibitem" data-cite-label="23" data-cite-year="2010" data-cite-authors="Leino and Rümmer" style="searchterm:+Rustan+Leino+Philipp+mmer+polymorphic+intermediate+verification+language+Design+logical+encoding+Javier+Esparza+Rupak+Majumdar+editors+_Tools+Algorithms+Construction+Analysis+Systems+International+Conference+TACAS+volume+pages+Springer+March++"><span class="bibitem-before">[23]  </span>K. Rustan M. Leino and Philipp Rümmer. +<span class="newblock"></span> A polymorphic intermediate verification language: Design and logical + encoding. +<span class="newblock"></span> In Javier Esparza and Rupak Majumdar, editors, <em class="em-low1">Tools and + Algorithms for the Construction and Analysis of Systems, 16th International + Conference, TACAS 2010</em>, volume 6015, pages 312–327. Springer, March 2010. <a href="http://www.bing.com/search?q=+Rustan+Leino+Philipp+mmer+polymorphic+intermediate+verification+language+Design+logical+encoding+Javier+Esparza+Rupak+Majumdar+editors+_Tools+Algorithms+Construction+Analysis+Systems+International+Conference+TACAS+volume+pages+Springer+March++" class="bibsearch">🔎</a></div> +<div id="leroygrall:coinductivebigstep" class="bibitem" data-cite-label="24" data-cite-year="2009" data-cite-authors="Leroy and Grall" style="searchterm:Coinductive+step+operational+semantics++Xavier+Leroy+Herv+Grall+"><span class="bibitem-before">[24]  </span>Xavier Leroy and Hervé Grall. +<span class="newblock"></span> Coinductive big-step operational semantics. +<span class="newblock"></span> <em class="em-low1">Information and Computation</em>, 207<span style="penalty:0"></span> (2):<span style="penalty:0"></span> + 284–304, February 2009. <a href="http://www.bing.com/search?q=Coinductive+step+operational+semantics++Xavier+Leroy+Herv+Grall+" class="bibsearch">🔎</a></div> +<div id="manoliosmoore:partialfunctions" class="bibitem" data-cite-label="25" data-cite-year="2003" data-cite-authors="Manolios and Moore" style="searchterm:Partial+functions+ACL2++Panagiotis+Manolios+Strother+Moore+"><span class="bibitem-before">[25]  </span>Panagiotis Manolios and J Strother Moore. +<span class="newblock"></span> Partial functions in ACL2. +<span class="newblock"></span> <em class="em-low1">Journal of Automated Reasoning</em>, 31<span style="penalty:0"></span> (2):<span style="penalty:0"></span> + 107–127, 2003. <a href="http://www.bing.com/search?q=Partial+functions+ACL2++Panagiotis+Manolios+Strother+Moore+" class="bibsearch">🔎</a></div> +<div id="milner:ccs" class="bibitem" data-cite-label="26" data-cite-year="1982" data-cite-authors="Milner" style="searchterm:+Calculus+Communicating+Systems_++Robin+Milner+"><span class="bibitem-before">[26]  </span>Robin Milner. +<span class="newblock"></span> <em class="em-low1">A Calculus of Communicating Systems</em>. +<span class="newblock"></span> Springer-Verlag New York, Inc., 1982. +<span class="newblock"></span> ISBN 0387102353. <a href="http://www.bing.com/search?q=+Calculus+Communicating+Systems_++Robin+Milner+" class="bibsearch">🔎</a></div> +<div id="linz:coco" class="bibitem" data-cite-label="27" data-cite-year="2013" data-cite-authors="Mössenböck et\ al." data-cite-authors-long="Mössenböck, + Löberbauer, and Wöß" style="searchterm:Hanspeter+ssenb+Markus+berbauer+Albrecht+compiler+generator+coco+Open+source+from+University+Linz+Available+http+linz+Research+Projects+Coco++"><span class="bibitem-before">[27]  </span>Hanspeter Mössenböck, Markus Löberbauer, and Albrecht + Wöß. +<span class="newblock"></span> The compiler generator coco/r. +<span class="newblock"></span> Open source from University of Linz, 2013. +<span class="newblock"></span> Available at + <a href="http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/">http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/</a>. <a href="http://www.bing.com/search?q=Hanspeter+ssenb+Markus+berbauer+Albrecht+compiler+generator+coco+Open+source+from+University+Linz+Available+http+linz+Research+Projects+Coco++" class="bibsearch">🔎</a></div> +<div id="nipkowklein:concretesemantics" class="bibitem" data-cite-label="28" data-cite-year="2014" data-cite-authors="Nipkow and Klein" style="searchterm:_Concrete+Semantics+with+Isabelle+HOL_++Tobias+Nipkow+Gerwin+Klein+"><span class="bibitem-before">[28]  </span>Tobias Nipkow and Gerwin Klein. +<span class="newblock"></span> <em class="em-low1">Concrete Semantics with Isabelle/HOL</em>. +<span class="newblock"></span> Springer, 2014. <a href="http://www.bing.com/search?q=_Concrete+Semantics+with+Isabelle+HOL_++Tobias+Nipkow+Gerwin+Klein+" class="bibsearch">🔎</a></div> +<div id="paulinmohring:inductivecoq" class="bibitem" data-cite-label="29" data-cite-year="1993" data-cite-authors="Paulin-Mohring" style="searchterm:Inductive+definitions+system+rules+properties++Christine+Paulin+Mohring+"><span class="bibitem-before">[29]  </span>Christine Paulin-Mohring. +<span class="newblock"></span> Inductive definitions in the system Coq — rules and properties. +<span class="newblock"></span> In <em class="em-low1">TLCA '93</em>, volume 664 of <em class="em-low1">LNCS</em>, pages 328–345. + Springer, 1993. <a href="http://www.bing.com/search?q=Inductive+definitions+system+rules+properties++Christine+Paulin+Mohring+" class="bibsearch">🔎</a></div> +<div id="paulson:cade1994" class="bibitem" data-cite-label="30" data-cite-year="1994" data-cite-authors="Paulson" style="searchterm:+fixedpoint+approach+implementing+inductive+definitions++Lawrence+Paulson+"><span class="bibitem-before">[30]  </span>Lawrence C. Paulson. +<span class="newblock"></span> A fixedpoint approach to implementing (co)inductive definitions. +<span class="newblock"></span> In Alan Bundy, editor, <em class="em-low1">CADE-12</em>, volume 814 of <em class="em-low1">LNCS</em>, + pages 148–161. Springer, 1994. <a href="http://www.bing.com/search?q=+fixedpoint+approach+implementing+inductive+definitions++Lawrence+Paulson+" class="bibsearch">🔎</a></div> +<div id="pierce:softwarefoundations" class="bibitem" data-cite-label="31" data-cite-year="2015" data-cite-authors="Pierce et\ al." data-cite-authors-long="Pierce, Casinghino, Gaboardi, Greenberg, + Hriţcu, Sjöberg, and Yorgey" style="searchterm:Benjamin+Pierce+Chris+Casinghino+Marco+Gaboardi+Michael+Greenberg+Catalin+Vilhelm+berg+Brent+Yorgey+_Software+Foundations_+http+upenn+bcpierce+version+edition+January++"><span class="bibitem-before">[31]  </span>Benjamin C. Pierce, Chris Casinghino, Marco Gaboardi, Michael Greenberg, + Catalin Hriţcu, Vilhelm Sjöberg, and Brent Yorgey. +<span class="newblock"></span> <em class="em-low1">Software Foundations</em>. +<span class="newblock"></span> <a href="http://www.cis.upenn.edu/~bcpierce/sf">http://www.cis.upenn.edu/~bcpierce/sf</a>, version 3.2 edition, + January 2015. <a href="http://www.bing.com/search?q=Benjamin+Pierce+Chris+Casinghino+Marco+Gaboardi+Michael+Greenberg+Catalin+Vilhelm+berg+Brent+Yorgey+_Software+Foundations_+http+upenn+bcpierce+version+edition+January++" class="bibsearch">🔎</a></div> +<div id="smansetal:vericool" class="bibitem" data-cite-label="32" data-cite-year="2008" data-cite-authors="Smans et\ al." data-cite-authors-long="Smans, Jacobs, Piessens, and + Schulte" style="searchterm:Automatic+verifier+Java+like+programs+based+dynamic+frames+++Smans+Bart+Jacobs+Frank+Piessens+Wolfram+Schulte+"><span class="bibitem-before">[32]  </span>Jan Smans, Bart Jacobs, Frank Piessens, and Wolfram Schulte. +<span class="newblock"></span> Automatic verifier for Java-like programs based on dynamic frames. +<span class="newblock"></span> In José Luiz Fiadeiro and Paola Inverardi, editors, + <em class="em-low1">Fundamental Approaches to Software Engineering, 11th International + Conference, FASE 2008</em>, volume 4961, pages 261–275. Springer, March–April + 2008. <a href="http://www.bing.com/search?q=Automatic+verifier+Java+like+programs+based+dynamic+frames+++Smans+Bart+Jacobs+Frank+Piessens+Wolfram+Schulte+" class="bibsearch">🔎</a></div> +<div id="smansetal:implicitdynamicframes" class="bibitem" data-cite-label="33" data-cite-year="2009" data-cite-authors="Smans et\ al." data-cite-authors-long="Smans, Jacobs, and + Piessens" style="searchterm:+Smans+Bart+Jacobs+Frank+Piessens+Implicit+dynamic+frames+Combining+dynamic+frames+separation+logic+Sophia+Drossopoulou+editor+_ECOOP+Object+Oriented+Programming+European+Conference_+volume+pages+Springer+July++"><span class="bibitem-before">[33]  </span>Jan Smans, Bart Jacobs, and Frank Piessens. +<span class="newblock"></span> Implicit dynamic frames: Combining dynamic frames and separation + logic. +<span class="newblock"></span> In Sophia Drossopoulou, editor, <em class="em-low1">ECOOP 2009 — Object-Oriented + Programming, 23rd European Conference</em>, volume 5653, pages 148–172. + Springer, July 2009. <a href="http://www.bing.com/search?q=+Smans+Bart+Jacobs+Frank+Piessens+Implicit+dynamic+frames+Combining+dynamic+frames+separation+logic+Sophia+Drossopoulou+editor+_ECOOP+Object+Oriented+Programming+European+Conference_+volume+pages+Springer+July++" class="bibsearch">🔎</a></div> +<div id="swamyetal:fstar2011" class="bibitem" data-cite-label="34" data-cite-year="2011" data-cite-authors="Swamy et\ al." data-cite-authors-long="Swamy, Chen, Fournet, Strub, Bhargavan, and + Yang" style="searchterm:Nikhil+Swamy+Juan+Chen+dric+Fournet+Pierre+Yves+Strub+Karthikeyan+Bhargavan+Jean+Yang+Secure+distributed+programming+with+value+dependent+types+_ICFP+pages+September++"><span class="bibitem-before">[34]  </span>Nikhil Swamy, Juan Chen, Cédric Fournet, Pierre-Yves Strub, Karthikeyan + Bhargavan, and Jean Yang. +<span class="newblock"></span> Secure distributed programming with value-dependent types. +<span class="newblock"></span> In <em class="em-low1">ICFP 2011</em>, pages 266–278. ACM, September 2011. <a href="http://www.bing.com/search?q=Nikhil+Swamy+Juan+Chen+dric+Fournet+Pierre+Yves+Strub+Karthikeyan+Bhargavan+Jean+Yang+Secure+distributed+programming+with+value+dependent+types+_ICFP+pages+September++" class="bibsearch">🔎</a></div> +<div id="tarski:theorem" class="bibitem" data-cite-label="35" data-cite-year="1955" data-cite-authors="Tarski" style="searchterm:+lattice+theoretical+fixpoint+theorem+applications++Alfred+Tarski+"><span class="bibitem-before">[35]  </span>Alfred Tarski. +<span class="newblock"></span> A lattice-theoretical fixpoint theorem and its applications. +<span class="newblock"></span> <em class="em-low1">Pacific Journal of Mathematics</em>, 5:<span style="penalty:0"></span> 285–309, 1955. <a href="http://www.bing.com/search?q=+lattice+theoretical+fixpoint+theorem+applications++Alfred+Tarski+" class="bibsearch">🔎</a></div> +<div id="winskel:formalsemantics" class="bibitem" data-cite-label="36" data-cite-year="1993" data-cite-authors="Winskel" style="searchterm:Glynn+Winskel+_The+Formal+Semantics+Programming+Languages+Introduction_+Press++"><span class="bibitem-before">[36]  </span>Glynn Winskel. +<span class="newblock"></span> <em class="em-low1">The Formal Semantics of Programming Languages: An + Introduction</em>. +<span class="newblock"></span> MIT Press, 1993. <a href="http://www.bing.com/search?q=Glynn+Winskel+_The+Formal+Semantics+Programming+Languages+Introduction_+Press++" class="bibsearch">🔎</a></div></div></div><span data-line=""></span> +<div class="footnotes madoko"> +<hr > + +<div id="fn-fn-nullable" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">0</span>.</sup></span>This will change in a future version of Dafny that +will support both nullable and (by default) non-null reference +types. +<a href="#back-fn-fn-nullable" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-type-mode" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">1</span>.</sup></span>Being equality-supporting is just one of many +<em class="em-low1">modes</em> that one can imagine types in a rich type system to have. +For example, other modes could include having a total order, +being zero-initializable, and possibly being uninhabited. If +Dafny were to support more modes in the future, the “<code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">(<span class="code-escaped"> </span>)</code>”-suffix +syntax may be extended. For now, the suffix can only indicate the +equality-supporting mode. +<a href="#back-fn-fn-type-mode" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-slice-into-tuple" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">2</span>.</sup></span>Now that Dafny supports built-in tuples, the +plan is to change the sequence slice operation to return not a +sequence of subsequences, but a tuple of subsequences. +<a href="#back-fn-fn-slice-into-tuple" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-map-display" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">3</span>.</sup></span>This is likely to change in the future to disallow +multiple occurrences of the same key. +<a href="#back-fn-fn-map-display" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-map-membership" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">4</span>.</sup></span>This is likely to change in the future as +follows: The <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">in</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">!<span style="color:blue">in</span></code> operations will no longer be +supported on maps. Instead, for any map <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code>, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m.Domain</code> will +return its domain as a set and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m.Range</code> will return, also as a +set, the image of <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">m</code> under its domain. +<a href="#back-fn-fn-map-membership" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-on-da-web" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">5</span>.</sup></span>Dafny is open source at <a href="http://dafny.codeplex.com">dafny.codeplex.com</a> and can also be used online at <a href="http://rise4fun.com/dafny">rise4fun.com/dafny</a>. +<a href="#back-fn-fn-on-da-web" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-object-trait" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">6</span>.</sup></span>The current compiler restriction that <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:teal">object</span></code> cannot +be used as a type parameter needs to be removed. +<a href="#back-fn-fn-object-trait" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-iterator-field-names" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">7</span>.</sup></span>It would make sense to rename the special +fields <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_reads</code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_modifies</code> to have the same names as the +corresponding keywords, <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">reads</span></code> and <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">modifies</span></code>, as is done for +function values. Also, the various <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">_decreases<span class="code-escaped"><em class="em-low1">i</em></span></code> fields can +combined into one field named <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:purple">decreases</span></code> whose type is a +<em class="em-low1">n</em>-tuple. Thse changes may be incorporated into a future version +of Dafny. +</p> +<p class="p indent"><a href="#back-fn-fn-iterator-field-names" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-copredicate-restriction" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">8</span>.</sup></span>Higher-order function support in Dafny is +rather modest and typical reasoning patterns do not involve them, so this +restriction is not as limiting as it would have been in, e.g., Coq. +<a href="#back-fn-fn-copredicate-restriction" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-co-predicate-co-lemma-diffs" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">9</span>.</sup></span>Note, two places where co-predicates +and co-lemmas are not analogous are: co-predicates must not make +recursive calls to their prefix predicates, and co-predicates cannot +mention _k. +<a href="#back-fn-fn-co-predicate-co-lemma-diffs" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-newtype-name" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">10</span>.</sup></span>Should <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">newtype</span></code> perhaps be renamed to <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small">numtype</code>? +<a href="#back-fn-fn-newtype-name" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-newtype-design-question" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">11</span>.</sup></span>Would it be useful to also +automatically define <code class="code code1 language-dafnyx lang-dafnyx dafnyx colorized" style="font-size:small"><span style="color:blue">predicate</span> N?(m: M) { Q }</code>? +<a href="#back-fn-fn-newtype-design-question" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-newtype-zero" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">12</span>.</sup></span>The restriction is due to a current limitation in +the compiler. This will change in the future and will also open +up the possibility for subset types and non-null reference +types. +<a href="#back-fn-fn-newtype-zero" class="footnote-backref localref">↩</a></p></div> +<div id="fn-fn-more-subset-types" class="footnote" style="line-adjust:0"> +<p class="p noindent"><span class="footnote-before"><sup><span class="footnote-label">13</span>.</sup></span>A future version of Dafny will support +user-defined subset types. +<a href="#back-fn-fn-more-subset-types" class="footnote-backref localref">↩</a></p></div></div></div> +<svg id='math-svg-paths' style='display:none' version='1.1' viewBox='0 0 0 0' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<path d='M1.913 -3.766C1.913 -4.055 1.674 -4.294 1.385 -4.294S0.857 -4.055 0.857 -3.766S1.096 -3.238 1.385 -3.238S1.913 -3.477 1.913 -3.766ZM1.913 -0.528C1.913 -0.817 1.674 -1.056 1.385 -1.056S0.857 -0.817 0.857 -0.528S1.096 0 1.385 0S1.913 -0.239 1.913 -0.528Z' id='g5-58'/> +<path d='M8.309 -2.291C7.761 -1.873 7.492 -1.465 7.412 -1.335C6.964 -0.648 6.884 -0.02 6.884 -0.01C6.884 0.11 7.004 0.11 7.083 0.11C7.253 0.11 7.263 0.09 7.303 -0.09C7.532 -1.066 8.12 -1.903 9.245 -2.361C9.365 -2.401 9.395 -2.421 9.395 -2.491S9.335 -2.59 9.315 -2.6C8.877 -2.77 7.671 -3.268 7.293 -4.941C7.263 -5.061 7.253 -5.091 7.083 -5.091C7.004 -5.091 6.884 -5.091 6.884 -4.971C6.884 -4.951 6.974 -4.324 7.392 -3.656C7.592 -3.357 7.88 -3.009 8.309 -2.69H0.907C0.727 -2.69 0.548 -2.69 0.548 -2.491S0.727 -2.291 0.907 -2.291H8.309Z' id='g1-33'/> +<path d='M4.832 -4.095L3.995 -6.077C3.965 -6.157 3.945 -6.197 3.945 -6.207C3.945 -6.267 4.115 -6.456 4.533 -6.496C4.633 -6.506 4.732 -6.516 4.732 -6.685C4.732 -6.804 4.613 -6.804 4.583 -6.804C4.174 -6.804 3.746 -6.775 3.328 -6.775C3.078 -6.775 2.461 -6.804 2.212 -6.804C2.152 -6.804 2.032 -6.804 2.032 -6.605C2.032 -6.496 2.132 -6.496 2.262 -6.496C2.859 -6.496 2.919 -6.396 3.009 -6.177L4.184 -3.397L2.082 -1.136L1.953 -1.026C1.465 -0.498 0.996 -0.339 0.488 -0.309C0.359 -0.299 0.269 -0.299 0.269 -0.11C0.269 -0.1 0.269 0 0.399 0C0.697 0 1.026 -0.03 1.335 -0.03C1.704 -0.03 2.092 0 2.451 0C2.511 0 2.63 0 2.63 -0.199C2.63 -0.299 2.531 -0.309 2.511 -0.309C2.421 -0.319 2.112 -0.339 2.112 -0.618C2.112 -0.777 2.262 -0.936 2.381 -1.066L3.397 -2.142L4.294 -3.118L5.3 -0.737C5.34 -0.628 5.35 -0.618 5.35 -0.598C5.35 -0.518 5.161 -0.349 4.772 -0.309C4.663 -0.299 4.573 -0.289 4.573 -0.12C4.573 0 4.682 0 4.722 0C5.001 0 5.699 -0.03 5.978 -0.03C6.227 -0.03 6.834 0 7.083 0C7.153 0 7.273 0 7.273 -0.189C7.273 -0.309 7.173 -0.309 7.093 -0.309C6.426 -0.319 6.406 -0.349 6.237 -0.747C5.848 -1.674 5.181 -3.228 4.951 -3.826C5.629 -4.523 6.675 -5.709 6.994 -5.988C7.283 -6.227 7.661 -6.466 8.259 -6.496C8.389 -6.506 8.478 -6.506 8.478 -6.695C8.478 -6.705 8.478 -6.804 8.349 -6.804C8.05 -6.804 7.721 -6.775 7.412 -6.775C7.044 -6.775 6.665 -6.804 6.306 -6.804C6.247 -6.804 6.117 -6.804 6.117 -6.605C6.117 -6.535 6.167 -6.506 6.237 -6.496C6.326 -6.486 6.635 -6.466 6.635 -6.187C6.635 -6.047 6.526 -5.918 6.446 -5.828L4.832 -4.095Z' id='g3-88'/> +<path d='M5.948 -5.669L6.087 -5.808C6.386 -6.107 6.715 -6.446 7.392 -6.496C7.502 -6.506 7.592 -6.506 7.592 -6.685C7.592 -6.765 7.542 -6.804 7.462 -6.804C7.203 -6.804 6.914 -6.775 6.645 -6.775C6.316 -6.775 5.968 -6.804 5.649 -6.804C5.589 -6.804 5.46 -6.804 5.46 -6.615C5.46 -6.506 5.559 -6.496 5.609 -6.496C5.679 -6.496 5.968 -6.476 5.968 -6.267C5.968 -6.097 5.738 -5.838 5.699 -5.788L3.387 -3.128L2.291 -6.087C2.232 -6.227 2.232 -6.247 2.232 -6.257C2.232 -6.496 2.72 -6.496 2.819 -6.496C2.959 -6.496 3.059 -6.496 3.059 -6.695C3.059 -6.804 2.939 -6.804 2.909 -6.804C2.63 -6.804 1.933 -6.775 1.654 -6.775C1.405 -6.775 0.787 -6.804 0.538 -6.804C0.478 -6.804 0.349 -6.804 0.349 -6.605C0.349 -6.496 0.448 -6.496 0.578 -6.496C1.176 -6.496 1.215 -6.406 1.305 -6.157L2.531 -2.879C2.54 -2.849 2.57 -2.74 2.57 -2.71S2.172 -1.076 2.122 -0.897C1.993 -0.349 1.983 -0.319 1.186 -0.309C0.996 -0.309 0.917 -0.309 0.917 -0.11C0.917 0 1.036 0 1.056 0C1.335 0 2.032 -0.03 2.311 -0.03S3.308 0 3.587 0C3.656 0 3.776 0 3.776 -0.199C3.776 -0.309 3.686 -0.309 3.497 -0.309C3.477 -0.309 3.288 -0.309 3.118 -0.329C2.909 -0.349 2.849 -0.369 2.849 -0.488C2.849 -0.558 2.939 -0.907 2.989 -1.116L3.337 -2.521C3.387 -2.71 3.397 -2.74 3.477 -2.829L5.948 -5.669Z' id='g3-89'/> +<path d='M3.656 -3.985H4.513C4.712 -3.985 4.812 -3.985 4.812 -4.184C4.812 -4.294 4.712 -4.294 4.543 -4.294H3.716L3.925 -5.43C3.965 -5.639 4.105 -6.346 4.164 -6.466C4.254 -6.655 4.423 -6.804 4.633 -6.804C4.672 -6.804 4.932 -6.804 5.121 -6.625C4.682 -6.585 4.583 -6.237 4.583 -6.087C4.583 -5.858 4.762 -5.738 4.951 -5.738C5.21 -5.738 5.499 -5.958 5.499 -6.336C5.499 -6.795 5.041 -7.024 4.633 -7.024C4.294 -7.024 3.666 -6.844 3.367 -5.858C3.308 -5.649 3.278 -5.549 3.039 -4.294H2.351C2.162 -4.294 2.052 -4.294 2.052 -4.105C2.052 -3.985 2.142 -3.985 2.331 -3.985H2.989L2.242 -0.05C2.062 0.917 1.893 1.823 1.375 1.823C1.335 1.823 1.086 1.823 0.897 1.644C1.355 1.614 1.445 1.255 1.445 1.106C1.445 0.877 1.265 0.757 1.076 0.757C0.817 0.757 0.528 0.976 0.528 1.355C0.528 1.803 0.966 2.042 1.375 2.042C1.923 2.042 2.321 1.455 2.501 1.076C2.819 0.448 3.049 -0.757 3.059 -0.827L3.656 -3.985Z' id='g3-102'/> +<path d='M3.298 2.391C3.298 2.361 3.298 2.341 3.128 2.172C1.883 0.917 1.564 -0.966 1.564 -2.491C1.564 -4.224 1.943 -5.958 3.168 -7.203C3.298 -7.323 3.298 -7.342 3.298 -7.372C3.298 -7.442 3.258 -7.472 3.198 -7.472C3.098 -7.472 2.202 -6.795 1.614 -5.529C1.106 -4.433 0.986 -3.328 0.986 -2.491C0.986 -1.714 1.096 -0.508 1.644 0.618C2.242 1.843 3.098 2.491 3.198 2.491C3.258 2.491 3.298 2.461 3.298 2.391Z' id='g5-40'/> +<path d='M2.879 -2.491C2.879 -3.268 2.77 -4.473 2.222 -5.599C1.624 -6.824 0.767 -7.472 0.667 -7.472C0.608 -7.472 0.568 -7.432 0.568 -7.372C0.568 -7.342 0.568 -7.323 0.757 -7.143C1.733 -6.157 2.301 -4.573 2.301 -2.491C2.301 -0.787 1.933 0.966 0.697 2.222C0.568 2.341 0.568 2.361 0.568 2.391C0.568 2.451 0.608 2.491 0.667 2.491C0.767 2.491 1.664 1.813 2.252 0.548C2.76 -0.548 2.879 -1.654 2.879 -2.491Z' id='g5-41'/> +<path d='M6.844 -3.258C6.994 -3.258 7.183 -3.258 7.183 -3.457S6.994 -3.656 6.854 -3.656H0.887C0.747 -3.656 0.558 -3.656 0.558 -3.457S0.747 -3.258 0.897 -3.258H6.844ZM6.854 -1.325C6.994 -1.325 7.183 -1.325 7.183 -1.524S6.994 -1.724 6.844 -1.724H0.897C0.747 -1.724 0.558 -1.724 0.558 -1.524S0.747 -1.325 0.887 -1.325H6.854Z' id='g5-61'/> +<path d='M8.269 -6.426C8.269 -6.884 7.502 -6.814 7.193 -6.814H3.437C2.939 -6.814 2.052 -6.526 1.893 -5.988C1.913 -5.928 1.933 -5.918 1.993 -5.918C2.212 -5.918 2.511 -6.097 2.65 -6.247C2.959 -6.247 3.258 -6.267 3.567 -6.267H4.184C4.184 -6.267 4.144 -6.087 4.144 -6.077C3.756 -4.254 3.168 -2.71 2.73 -1.733C2.67 -1.604 2.132 -0.359 1.993 -0.239C1.554 -0.239 1.225 -0.478 1.046 -0.867C1.016 -0.927 1.016 -0.966 0.946 -0.966C0.717 -0.966 0.169 -0.648 0.169 -0.478C0.169 -0.458 0.179 -0.438 0.189 -0.418C0.369 0.05 0.817 0.319 1.305 0.319C1.813 0.319 2.401 -0.05 2.72 -0.418C3.049 -0.797 3.706 -2.431 3.965 -3.029H5.888C5.878 -3.019 5.868 -3.009 5.868 -2.999C5.868 -2.959 5.928 -2.929 5.968 -2.929C6.187 -2.929 6.755 -3.208 6.755 -3.517C6.755 -3.587 6.685 -3.577 6.565 -3.577H4.174C4.433 -4.473 4.772 -5.35 4.951 -6.267H6.267C6.516 -6.267 7.213 -6.316 7.392 -6.097C7.412 -6.037 7.382 -5.938 7.412 -5.888C7.432 -5.868 7.462 -5.858 7.492 -5.858C7.731 -5.858 8.269 -6.157 8.269 -6.426Z' id='g1-70'/> +<path d='M2.75 -3.985H4.742L4.025 -1.126C4.015 -1.086 3.975 -0.927 3.975 -0.787C3.975 -0.259 4.334 0.11 4.812 0.11C5.181 0.11 5.39 -0.139 5.539 -0.448C5.719 -0.827 5.838 -1.405 5.838 -1.425C5.838 -1.524 5.758 -1.524 5.689 -1.524C5.569 -1.524 5.559 -1.514 5.499 -1.295C5.36 -0.737 5.171 -0.11 4.832 -0.11C4.573 -0.11 4.573 -0.379 4.573 -0.518C4.573 -0.588 4.573 -0.747 4.643 -1.026L5.4 -4.055C5.41 -4.115 5.43 -4.164 5.43 -4.184C5.43 -4.294 5.36 -4.294 5.191 -4.294H2.809L2.989 -5.22C3.188 -6.177 3.318 -6.804 4.533 -6.804C4.812 -6.804 5.28 -6.775 5.529 -6.526C5.091 -6.436 5.091 -6.047 5.091 -6.037C5.091 -5.908 5.181 -5.719 5.44 -5.719C5.659 -5.719 5.938 -5.898 5.938 -6.276C5.938 -7.024 4.762 -7.024 4.513 -7.024C3.357 -7.024 2.62 -6.635 2.351 -5.23L2.172 -4.294H1.524C1.355 -4.294 1.245 -4.294 1.245 -4.105C1.245 -3.985 1.335 -3.985 1.494 -3.985H2.112L1.425 -0.428C1.325 0.06 1.215 0.548 1.096 1.036C1.026 1.295 0.897 1.823 0.538 1.823C0.518 1.823 0.279 1.823 0.149 1.644C0.448 1.594 0.588 1.355 0.588 1.156C0.588 0.936 0.408 0.837 0.249 0.837C0 0.837 -0.249 1.036 -0.249 1.385C-0.249 1.853 0.189 2.042 0.538 2.042C1.435 2.042 1.873 0.588 2.152 -0.857L2.75 -3.985Z' id='g0-12'/> +<path d='M3.019 -6.665C3.029 -6.695 3.049 -6.775 3.049 -6.795C3.049 -6.884 2.989 -6.914 2.909 -6.914C2.879 -6.914 2.78 -6.904 2.75 -6.894L1.763 -6.814C1.644 -6.804 1.534 -6.795 1.534 -6.605C1.534 -6.496 1.634 -6.496 1.773 -6.496C2.252 -6.496 2.271 -6.426 2.271 -6.326C2.271 -6.296 2.242 -6.167 2.242 -6.157L1.255 -2.222C1.245 -2.192 1.146 -1.783 1.146 -1.405C1.146 -0.568 1.564 0.11 2.291 0.11C3.407 0.11 4.573 -1.385 4.573 -2.849C4.573 -3.915 3.975 -4.403 3.377 -4.403C2.999 -4.403 2.66 -4.194 2.321 -3.875L3.019 -6.665ZM2.291 -0.11C2.042 -0.11 1.714 -0.319 1.714 -1.066C1.714 -1.504 1.803 -1.853 2.092 -2.989C2.162 -3.228 2.162 -3.248 2.311 -3.447C2.6 -3.846 2.979 -4.184 3.357 -4.184C3.806 -4.184 3.905 -3.616 3.905 -3.298C3.905 -2.879 3.636 -1.694 3.347 -1.056C3.228 -0.807 2.8 -0.11 2.291 -0.11Z' id='g0-98'/> +<path d='M4.075 -2.291H6.854C6.994 -2.291 7.183 -2.291 7.183 -2.491S6.994 -2.69 6.854 -2.69H4.075V-5.479C4.075 -5.619 4.075 -5.808 3.875 -5.808S3.676 -5.619 3.676 -5.479V-2.69H0.887C0.747 -2.69 0.558 -2.69 0.558 -2.491S0.747 -2.291 0.887 -2.291H3.676V0.498C3.676 0.638 3.676 0.827 3.875 0.827S4.075 0.638 4.075 0.498V-2.291Z' id='g5-43'/> +<path d='M2.929 -6.376C2.929 -6.615 2.929 -6.635 2.7 -6.635C2.082 -5.998 1.205 -5.998 0.887 -5.998V-5.689C1.086 -5.689 1.674 -5.689 2.192 -5.948V-0.787C2.192 -0.428 2.162 -0.309 1.265 -0.309H0.946V0C1.295 -0.03 2.162 -0.03 2.56 -0.03S3.826 -0.03 4.174 0V-0.309H3.856C2.959 -0.309 2.929 -0.418 2.929 -0.787V-6.376Z' id='g5-49'/> +<path d='M1.265 -0.767L2.321 -1.793C3.875 -3.168 4.473 -3.706 4.473 -4.702C4.473 -5.838 3.577 -6.635 2.361 -6.635C1.235 -6.635 0.498 -5.719 0.498 -4.832C0.498 -4.274 0.996 -4.274 1.026 -4.274C1.196 -4.274 1.544 -4.394 1.544 -4.802C1.544 -5.061 1.365 -5.32 1.016 -5.32C0.936 -5.32 0.917 -5.32 0.887 -5.31C1.116 -5.958 1.654 -6.326 2.232 -6.326C3.138 -6.326 3.567 -5.519 3.567 -4.702C3.567 -3.905 3.068 -3.118 2.521 -2.501L0.608 -0.369C0.498 -0.259 0.498 -0.239 0.498 0H4.194L4.473 -1.733H4.224C4.174 -1.435 4.105 -0.996 4.005 -0.847C3.935 -0.767 3.278 -0.767 3.059 -0.767H1.265Z' id='g5-50'/> +<path d='M1.116 -2.511C1.176 -3.995 2.012 -4.244 2.351 -4.244C3.377 -4.244 3.477 -2.899 3.477 -2.511H1.116ZM1.106 -2.301H3.885C4.105 -2.301 4.134 -2.301 4.134 -2.511C4.134 -3.497 3.597 -4.463 2.351 -4.463C1.196 -4.463 0.279 -3.437 0.279 -2.192C0.279 -0.857 1.325 0.11 2.471 0.11C3.686 0.11 4.134 -0.996 4.134 -1.186C4.134 -1.285 4.055 -1.305 4.005 -1.305C3.915 -1.305 3.895 -1.245 3.875 -1.166C3.527 -0.139 2.63 -0.139 2.531 -0.139C2.032 -0.139 1.634 -0.438 1.405 -0.807C1.106 -1.285 1.106 -1.943 1.106 -2.301Z' id='g5-101'/> +<path d='M1.743 -4.294V-5.45C1.743 -6.326 2.222 -6.804 2.66 -6.804C2.69 -6.804 2.839 -6.804 2.989 -6.735C2.869 -6.695 2.69 -6.565 2.69 -6.316C2.69 -6.087 2.849 -5.888 3.118 -5.888C3.407 -5.888 3.557 -6.087 3.557 -6.326C3.557 -6.695 3.188 -7.024 2.66 -7.024C1.963 -7.024 1.116 -6.496 1.116 -5.44V-4.294H0.329V-3.985H1.116V-0.757C1.116 -0.309 1.006 -0.309 0.339 -0.309V0C0.727 -0.01 1.196 -0.03 1.474 -0.03C1.873 -0.03 2.341 -0.03 2.74 0V-0.309H2.531C1.793 -0.309 1.773 -0.418 1.773 -0.777V-3.985H2.909V-4.294H1.743Z' id='g5-102'/> +<path d='M1.096 -0.757C1.096 -0.309 0.986 -0.309 0.319 -0.309V0C0.667 -0.01 1.176 -0.03 1.445 -0.03C1.704 -0.03 2.222 -0.01 2.56 0V-0.309C1.893 -0.309 1.783 -0.309 1.783 -0.757V-2.59C1.783 -3.626 2.491 -4.184 3.128 -4.184C3.756 -4.184 3.866 -3.646 3.866 -3.078V-0.757C3.866 -0.309 3.756 -0.309 3.088 -0.309V0C3.437 -0.01 3.945 -0.03 4.214 -0.03C4.473 -0.03 4.991 -0.01 5.33 0V-0.309C4.812 -0.309 4.563 -0.309 4.553 -0.608V-2.511C4.553 -3.367 4.553 -3.676 4.244 -4.035C4.105 -4.204 3.776 -4.403 3.198 -4.403C2.361 -4.403 1.923 -3.806 1.753 -3.427V-6.914L0.319 -6.804V-6.496C1.016 -6.496 1.096 -6.426 1.096 -5.938V-0.757Z' id='g5-104'/> +<path d='M1.763 -4.403L0.369 -4.294V-3.985C1.016 -3.985 1.106 -3.925 1.106 -3.437V-0.757C1.106 -0.309 0.996 -0.309 0.329 -0.309V0C0.648 -0.01 1.186 -0.03 1.425 -0.03C1.773 -0.03 2.122 -0.01 2.461 0V-0.309C1.803 -0.309 1.763 -0.359 1.763 -0.747V-4.403ZM1.803 -6.137C1.803 -6.456 1.554 -6.665 1.275 -6.665C0.966 -6.665 0.747 -6.396 0.747 -6.137C0.747 -5.868 0.966 -5.609 1.275 -5.609C1.554 -5.609 1.803 -5.818 1.803 -6.137Z' id='g5-105'/> +<path d='M1.763 -6.914L0.329 -6.804V-6.496C1.026 -6.496 1.106 -6.426 1.106 -5.938V-0.757C1.106 -0.309 0.996 -0.309 0.329 -0.309V0C0.658 -0.01 1.186 -0.03 1.435 -0.03S2.172 -0.01 2.54 0V-0.309C1.873 -0.309 1.763 -0.309 1.763 -0.757V-6.914Z' id='g5-108'/> +<path d='M1.096 -3.427V-0.757C1.096 -0.309 0.986 -0.309 0.319 -0.309V0C0.667 -0.01 1.176 -0.03 1.445 -0.03C1.704 -0.03 2.222 -0.01 2.56 0V-0.309C1.893 -0.309 1.783 -0.309 1.783 -0.757V-2.59C1.783 -3.626 2.491 -4.184 3.128 -4.184C3.756 -4.184 3.866 -3.646 3.866 -3.078V-0.757C3.866 -0.309 3.756 -0.309 3.088 -0.309V0C3.437 -0.01 3.945 -0.03 4.214 -0.03C4.473 -0.03 4.991 -0.01 5.33 0V-0.309C4.812 -0.309 4.563 -0.309 4.553 -0.608V-2.511C4.553 -3.367 4.553 -3.676 4.244 -4.035C4.105 -4.204 3.776 -4.403 3.198 -4.403C2.471 -4.403 2.002 -3.975 1.724 -3.357V-4.403L0.319 -4.294V-3.985C1.016 -3.985 1.096 -3.915 1.096 -3.427Z' id='g5-110'/> +<path d='M2.072 -1.933C2.291 -1.893 3.108 -1.733 3.108 -1.016C3.108 -0.508 2.76 -0.11 1.983 -0.11C1.146 -0.11 0.787 -0.677 0.598 -1.524C0.568 -1.654 0.558 -1.694 0.458 -1.694C0.329 -1.694 0.329 -1.624 0.329 -1.445V-0.13C0.329 0.04 0.329 0.11 0.438 0.11C0.488 0.11 0.498 0.1 0.687 -0.09C0.707 -0.11 0.707 -0.13 0.887 -0.319C1.325 0.1 1.773 0.11 1.983 0.11C3.128 0.11 3.587 -0.558 3.587 -1.275C3.587 -1.803 3.288 -2.102 3.168 -2.222C2.839 -2.54 2.451 -2.62 2.032 -2.7C1.474 -2.809 0.807 -2.939 0.807 -3.517C0.807 -3.866 1.066 -4.274 1.923 -4.274C3.019 -4.274 3.068 -3.377 3.088 -3.068C3.098 -2.979 3.188 -2.979 3.208 -2.979C3.337 -2.979 3.337 -3.029 3.337 -3.218V-4.224C3.337 -4.394 3.337 -4.463 3.228 -4.463C3.178 -4.463 3.158 -4.463 3.029 -4.344C2.999 -4.304 2.899 -4.214 2.859 -4.184C2.481 -4.463 2.072 -4.463 1.923 -4.463C0.707 -4.463 0.329 -3.796 0.329 -3.238C0.329 -2.889 0.488 -2.61 0.757 -2.391C1.076 -2.132 1.355 -2.072 2.072 -1.933Z' id='g5-115'/> +<path d='M1.724 -3.985H3.148V-4.294H1.724V-6.127H1.474C1.465 -5.31 1.166 -4.244 0.189 -4.204V-3.985H1.036V-1.235C1.036 -0.01 1.963 0.11 2.321 0.11C3.029 0.11 3.308 -0.598 3.308 -1.235V-1.803H3.059V-1.255C3.059 -0.518 2.76 -0.139 2.391 -0.139C1.724 -0.139 1.724 -1.046 1.724 -1.215V-3.985Z' id='g5-116'/> +<path d='M6.565 -2.291C6.735 -2.291 6.914 -2.291 6.914 -2.491S6.735 -2.69 6.565 -2.69H1.176C1.006 -2.69 0.827 -2.69 0.827 -2.491S1.006 -2.291 1.176 -2.291H6.565Z' id='g1-0'/> +<path d='M4.423 -2.491C4.423 -3.557 3.537 -4.423 2.491 -4.423C1.415 -4.423 0.548 -3.537 0.548 -2.491C0.548 -1.435 1.415 -0.558 2.491 -0.558C3.537 -0.558 4.423 -1.425 4.423 -2.491Z' id='g1-15'/> +<path d='M3.557 -2.909C3.965 -1.863 4.443 -0.339 4.603 -0.11C4.762 0.11 4.862 0.11 5.131 0.11H5.35C5.45 0.1 5.46 0.04 5.46 0.01S5.44 -0.04 5.41 -0.08C5.31 -0.189 5.25 -0.339 5.181 -0.538L3.148 -6.207C2.939 -6.785 2.401 -6.914 1.933 -6.914C1.883 -6.914 1.753 -6.914 1.753 -6.804C1.753 -6.725 1.833 -6.705 1.843 -6.705C2.172 -6.645 2.242 -6.585 2.491 -5.908L3.457 -3.198L0.707 -0.468C0.588 -0.349 0.528 -0.289 0.528 -0.159C0.528 0.01 0.667 0.13 0.827 0.13S1.076 0.02 1.156 -0.08L3.557 -2.909Z' id='g3-21'/> +<path d='M6.725 -4.961C6.844 -5.021 6.914 -5.071 6.914 -5.181S6.824 -5.38 6.715 -5.38C6.685 -5.38 6.665 -5.38 6.535 -5.31L1.016 -2.71C0.907 -2.66 0.827 -2.61 0.827 -2.491S0.907 -2.321 1.016 -2.271L6.535 0.329C6.665 0.399 6.685 0.399 6.715 0.399C6.824 0.399 6.914 0.309 6.914 0.199S6.844 0.04 6.725 -0.02L1.494 -2.491L6.725 -4.961Z' id='g3-60'/> +<path d='M0.877 -0.588C0.847 -0.438 0.787 -0.209 0.787 -0.159C0.787 0.02 0.927 0.11 1.076 0.11C1.196 0.11 1.375 0.03 1.445 -0.169C1.455 -0.189 1.574 -0.658 1.634 -0.907L1.853 -1.803C1.913 -2.022 1.973 -2.242 2.022 -2.471C2.062 -2.64 2.142 -2.929 2.152 -2.969C2.301 -3.278 2.829 -4.184 3.776 -4.184C4.224 -4.184 4.314 -3.816 4.314 -3.487C4.314 -2.869 3.826 -1.594 3.666 -1.166C3.577 -0.936 3.567 -0.817 3.567 -0.707C3.567 -0.239 3.915 0.11 4.384 0.11C5.32 0.11 5.689 -1.345 5.689 -1.425C5.689 -1.524 5.599 -1.524 5.569 -1.524C5.469 -1.524 5.469 -1.494 5.42 -1.345C5.22 -0.667 4.892 -0.11 4.403 -0.11C4.234 -0.11 4.164 -0.209 4.164 -0.438C4.164 -0.687 4.254 -0.927 4.344 -1.146C4.533 -1.674 4.951 -2.77 4.951 -3.337C4.951 -4.005 4.523 -4.403 3.806 -4.403C2.909 -4.403 2.421 -3.766 2.252 -3.537C2.202 -4.095 1.793 -4.403 1.335 -4.403S0.687 -4.015 0.588 -3.836C0.428 -3.497 0.289 -2.909 0.289 -2.869C0.289 -2.77 0.389 -2.77 0.408 -2.77C0.508 -2.77 0.518 -2.78 0.578 -2.999C0.747 -3.706 0.946 -4.184 1.305 -4.184C1.504 -4.184 1.614 -4.055 1.614 -3.726C1.614 -3.517 1.584 -3.407 1.455 -2.889L0.877 -0.588Z' id='g3-110'/> +<path d='M6.167 -5.22C6.286 -5.29 6.366 -5.33 6.366 -5.44C6.366 -5.579 6.257 -5.639 6.167 -5.639C6.097 -5.639 6.027 -5.599 5.988 -5.579L0.737 -2.71C0.618 -2.64 0.548 -2.61 0.548 -2.491S0.618 -2.341 0.737 -2.271L5.978 0.588C6.097 0.658 6.127 0.658 6.167 0.658C6.296 0.658 6.366 0.558 6.366 0.458C6.366 0.349 6.286 0.309 6.167 0.239L1.166 -2.491L6.167 -5.22ZM9.205 -5.22C9.325 -5.29 9.405 -5.33 9.405 -5.44C9.405 -5.579 9.295 -5.639 9.205 -5.639C9.136 -5.639 9.066 -5.599 9.026 -5.579L3.776 -2.71C3.656 -2.64 3.587 -2.61 3.587 -2.491S3.656 -2.341 3.776 -2.271L9.016 0.588C9.136 0.658 9.166 0.658 9.205 0.658C9.335 0.658 9.405 0.558 9.405 0.458C9.405 0.349 9.325 0.309 9.205 0.239L4.204 -2.491L9.205 -5.22Z' id='g1-28'/> +<path d='M2.022 -3.292C2.078 -3.41 2.085 -3.466 2.085 -3.515C2.085 -3.731 1.89 -3.898 1.674 -3.898C1.409 -3.898 1.325 -3.682 1.29 -3.571L0.37 -0.551C0.363 -0.537 0.335 -0.446 0.335 -0.439C0.335 -0.356 0.551 -0.286 0.607 -0.286C0.656 -0.286 0.663 -0.3 0.711 -0.404L2.022 -3.292Z' id='g2-48'/> +<path d='M3.328 -3.009C3.387 -3.268 3.616 -4.184 4.314 -4.184C4.364 -4.184 4.603 -4.184 4.812 -4.055C4.533 -4.005 4.334 -3.756 4.334 -3.517C4.334 -3.357 4.443 -3.168 4.712 -3.168C4.932 -3.168 5.25 -3.347 5.25 -3.746C5.25 -4.264 4.663 -4.403 4.324 -4.403C3.746 -4.403 3.397 -3.875 3.278 -3.646C3.029 -4.304 2.491 -4.403 2.202 -4.403C1.166 -4.403 0.598 -3.118 0.598 -2.869C0.598 -2.77 0.697 -2.77 0.717 -2.77C0.797 -2.77 0.827 -2.79 0.847 -2.879C1.186 -3.935 1.843 -4.184 2.182 -4.184C2.371 -4.184 2.72 -4.095 2.72 -3.517C2.72 -3.208 2.55 -2.54 2.182 -1.146C2.022 -0.528 1.674 -0.11 1.235 -0.11C1.176 -0.11 0.946 -0.11 0.737 -0.239C0.986 -0.289 1.205 -0.498 1.205 -0.777C1.205 -1.046 0.986 -1.126 0.837 -1.126C0.538 -1.126 0.289 -0.867 0.289 -0.548C0.289 -0.09 0.787 0.11 1.225 0.11C1.883 0.11 2.242 -0.588 2.271 -0.648C2.391 -0.279 2.75 0.11 3.347 0.11C4.374 0.11 4.941 -1.176 4.941 -1.425C4.941 -1.524 4.852 -1.524 4.822 -1.524C4.732 -1.524 4.712 -1.484 4.692 -1.415C4.364 -0.349 3.686 -0.11 3.367 -0.11C2.979 -0.11 2.819 -0.428 2.819 -0.767C2.819 -0.986 2.879 -1.205 2.989 -1.644L3.328 -3.009Z' id='g3-120'/> +<path d='M7.054 -2.321C7.073 -2.371 7.103 -2.441 7.103 -2.461C7.103 -2.471 7.103 -2.57 6.984 -2.57C6.894 -2.57 6.874 -2.511 6.854 -2.451C6.207 -0.976 5.838 -0.309 4.134 -0.309H2.68C2.54 -0.309 2.521 -0.309 2.461 -0.319C2.361 -0.329 2.331 -0.339 2.331 -0.418C2.331 -0.448 2.331 -0.468 2.381 -0.648L3.059 -3.367H4.045C4.892 -3.367 4.892 -3.158 4.892 -2.909C4.892 -2.839 4.892 -2.72 4.822 -2.421C4.802 -2.371 4.792 -2.341 4.792 -2.311C4.792 -2.262 4.832 -2.202 4.922 -2.202C5.001 -2.202 5.031 -2.252 5.071 -2.401L5.639 -4.732C5.639 -4.792 5.589 -4.842 5.519 -4.842C5.43 -4.842 5.41 -4.782 5.38 -4.663C5.171 -3.905 4.991 -3.676 4.075 -3.676H3.138L3.736 -6.077C3.826 -6.426 3.836 -6.466 4.274 -6.466H5.679C6.894 -6.466 7.193 -6.177 7.193 -5.36C7.193 -5.121 7.193 -5.101 7.153 -4.832C7.153 -4.772 7.143 -4.702 7.143 -4.653S7.173 -4.533 7.263 -4.533C7.372 -4.533 7.382 -4.593 7.402 -4.782L7.601 -6.506C7.631 -6.775 7.582 -6.775 7.333 -6.775H2.301C2.102 -6.775 2.002 -6.775 2.002 -6.575C2.002 -6.466 2.092 -6.466 2.281 -6.466C2.65 -6.466 2.929 -6.466 2.929 -6.286C2.929 -6.247 2.929 -6.227 2.879 -6.047L1.564 -0.777C1.465 -0.389 1.445 -0.309 0.658 -0.309C0.488 -0.309 0.379 -0.309 0.379 -0.12C0.379 0 0.468 0 0.658 0H5.828C6.057 0 6.067 -0.01 6.137 -0.169L7.054 -2.321Z' id='g3-69'/> +<path d='M6.725 -5.918C6.834 -5.968 6.914 -6.017 6.914 -6.137C6.914 -6.247 6.834 -6.336 6.715 -6.336C6.665 -6.336 6.575 -6.296 6.535 -6.276L1.026 -3.676C0.857 -3.597 0.827 -3.527 0.827 -3.447C0.827 -3.357 0.887 -3.288 1.026 -3.228L6.535 -0.638C6.665 -0.568 6.685 -0.568 6.715 -0.568C6.824 -0.568 6.914 -0.658 6.914 -0.767C6.914 -0.857 6.874 -0.917 6.705 -0.996L1.494 -3.447L6.725 -5.918ZM6.565 1.365C6.735 1.365 6.914 1.365 6.914 1.166S6.705 0.966 6.555 0.966H1.186C1.036 0.966 0.827 0.966 0.827 1.166S1.006 1.365 1.176 1.365H6.565Z' id='g1-20'/> +<path d='M7.233 -3.258C7.651 -2.899 8.159 -2.64 8.488 -2.491C8.13 -2.331 7.641 -2.072 7.233 -1.724H0.907C0.737 -1.724 0.548 -1.724 0.548 -1.524S0.727 -1.325 0.897 -1.325H6.785C6.306 -0.867 5.788 0.01 5.788 0.139C5.788 0.249 5.918 0.249 5.978 0.249C6.057 0.249 6.127 0.249 6.167 0.169C6.376 -0.209 6.655 -0.737 7.303 -1.315C7.99 -1.923 8.658 -2.192 9.176 -2.341C9.345 -2.401 9.355 -2.411 9.375 -2.431C9.395 -2.441 9.395 -2.471 9.395 -2.491S9.395 -2.531 9.385 -2.55L9.355 -2.57C9.335 -2.58 9.325 -2.59 9.136 -2.65C7.791 -3.049 6.795 -3.955 6.237 -5.021C6.127 -5.22 6.117 -5.23 5.978 -5.23C5.918 -5.23 5.788 -5.23 5.788 -5.121C5.788 -4.991 6.296 -4.125 6.785 -3.656H0.897C0.727 -3.656 0.548 -3.656 0.548 -3.457S0.737 -3.258 0.907 -3.258H7.233Z' id='g1-41'/> +<path d='M3.547 -5.748C3.467 -5.918 3.407 -5.958 3.318 -5.958C3.188 -5.958 3.158 -5.888 3.098 -5.748L0.618 -0.179C0.558 -0.05 0.548 -0.03 0.548 0.02C0.548 0.13 0.638 0.219 0.747 0.219C0.817 0.219 0.897 0.199 0.976 0.01L3.318 -5.27L5.659 0.01C5.748 0.219 5.848 0.219 5.888 0.219C5.998 0.219 6.087 0.13 6.087 0.02C6.087 0 6.087 -0.02 6.027 -0.139L3.547 -5.748Z' id='g1-94'/> +<path d='M3.019 -3.148H4.712C6.127 -3.148 7.512 -4.184 7.512 -5.3C7.512 -6.067 6.854 -6.804 5.549 -6.804H2.321C2.132 -6.804 2.022 -6.804 2.022 -6.615C2.022 -6.496 2.112 -6.496 2.311 -6.496C2.441 -6.496 2.62 -6.486 2.74 -6.476C2.899 -6.456 2.959 -6.426 2.959 -6.316C2.959 -6.276 2.949 -6.247 2.919 -6.127L1.584 -0.777C1.484 -0.389 1.465 -0.309 0.677 -0.309C0.508 -0.309 0.399 -0.309 0.399 -0.12C0.399 0 0.518 0 0.548 0C0.827 0 1.534 -0.03 1.813 -0.03C2.022 -0.03 2.242 -0.02 2.451 -0.02C2.67 -0.02 2.889 0 3.098 0C3.168 0 3.298 0 3.298 -0.199C3.298 -0.309 3.208 -0.309 3.019 -0.309C2.65 -0.309 2.371 -0.309 2.371 -0.488C2.371 -0.548 2.391 -0.598 2.401 -0.658L3.019 -3.148ZM3.736 -6.117C3.826 -6.466 3.846 -6.496 4.274 -6.496H5.23C6.057 -6.496 6.585 -6.227 6.585 -5.539C6.585 -5.151 6.386 -4.294 5.998 -3.935C5.499 -3.487 4.902 -3.407 4.463 -3.407H3.059L3.736 -6.117Z' id='g3-80'/> +<path d='M1.714 -0.727C1.634 -0.389 1.574 -0.309 0.897 -0.309C0.737 -0.309 0.628 -0.309 0.628 -0.12C0.628 0 0.717 0 0.877 0H3.935C5.818 0 7.721 -2.122 7.721 -4.364C7.721 -5.788 6.914 -6.804 5.629 -6.804H2.521C2.361 -6.804 2.252 -6.804 2.252 -6.615C2.252 -6.496 2.331 -6.496 2.521 -6.496C2.829 -6.496 3.098 -6.496 3.098 -6.326C3.098 -6.296 3.098 -6.276 3.059 -6.137L1.714 -0.727ZM3.846 -6.137C3.935 -6.486 4.005 -6.496 4.334 -6.496H5.3C6.107 -6.496 6.894 -6.047 6.894 -4.742C6.894 -4.154 6.605 -2.291 5.758 -1.295C5.27 -0.727 4.563 -0.309 3.766 -0.309H2.74C2.431 -0.309 2.431 -0.339 2.431 -0.408C2.431 -0.468 2.461 -0.568 2.471 -0.628L3.846 -6.137Z' id='g0-68'/> +<path d='M3.128 -3.148H4.672C5.928 -3.148 7.273 -4.164 7.273 -5.33C7.273 -6.167 6.595 -6.804 5.509 -6.804H2.521C2.361 -6.804 2.252 -6.804 2.252 -6.615C2.252 -6.496 2.331 -6.496 2.521 -6.496C2.829 -6.496 3.098 -6.496 3.098 -6.326C3.098 -6.296 3.098 -6.276 3.059 -6.137L1.714 -0.727C1.634 -0.389 1.574 -0.309 0.897 -0.309C0.737 -0.309 0.628 -0.309 0.628 -0.12C0.628 0 0.737 0 0.767 0C1.146 0 1.554 -0.03 1.943 -0.03C2.341 -0.03 2.75 0 3.138 0C3.208 0 3.328 0 3.328 -0.179C3.328 -0.309 3.258 -0.309 3.059 -0.309C2.481 -0.309 2.481 -0.389 2.481 -0.478C2.481 -0.518 2.481 -0.538 2.521 -0.677L3.128 -3.148ZM3.846 -6.137C3.935 -6.496 4.005 -6.496 4.334 -6.496H5.191C5.888 -6.496 6.396 -6.237 6.396 -5.599C6.396 -5.4 6.247 -4.423 5.868 -3.985C5.519 -3.597 5.021 -3.407 4.423 -3.407H3.168L3.846 -6.137Z' id='g0-80'/> +<path d='M3.477 -0.588C3.587 -0.1 3.955 0.11 4.304 0.11C4.672 0.11 4.882 -0.139 5.031 -0.448C5.21 -0.827 5.33 -1.405 5.33 -1.425C5.33 -1.524 5.25 -1.524 5.181 -1.524C5.061 -1.524 5.051 -1.514 4.991 -1.295C4.852 -0.737 4.663 -0.11 4.324 -0.11C4.065 -0.11 4.065 -0.379 4.065 -0.518C4.065 -0.588 4.065 -0.747 4.134 -1.026L4.812 -3.736C4.852 -3.875 4.852 -3.895 4.852 -3.945C4.852 -4.154 4.682 -4.204 4.583 -4.204C4.264 -4.204 4.194 -3.866 4.184 -3.816C3.995 -4.244 3.676 -4.403 3.357 -4.403C2.252 -4.403 1.076 -2.889 1.076 -1.435C1.076 -0.588 1.534 0.11 2.281 0.11C2.64 0.11 3.078 -0.1 3.477 -0.588ZM4.015 -3.118L3.547 -1.235C3.467 -0.917 2.849 -0.11 2.301 -0.11C1.833 -0.11 1.753 -0.697 1.753 -0.996C1.753 -1.494 2.062 -2.66 2.242 -3.078C2.491 -3.686 2.949 -4.184 3.357 -4.184C3.796 -4.184 4.045 -3.666 4.045 -3.248C4.045 -3.228 4.035 -3.178 4.015 -3.118Z' id='g0-97'/> +<path d='M5.549 -6.665C5.559 -6.695 5.579 -6.775 5.579 -6.795C5.579 -6.884 5.519 -6.914 5.44 -6.914C5.41 -6.914 5.31 -6.904 5.28 -6.894L4.294 -6.814C4.174 -6.804 4.065 -6.795 4.065 -6.605C4.065 -6.496 4.164 -6.496 4.304 -6.496C4.782 -6.496 4.802 -6.426 4.802 -6.326C4.802 -6.296 4.772 -6.167 4.772 -6.157L4.194 -3.826C4.045 -4.134 3.776 -4.403 3.357 -4.403C2.252 -4.403 1.076 -2.889 1.076 -1.435C1.076 -0.588 1.534 0.11 2.281 0.11C2.64 0.11 3.078 -0.1 3.477 -0.588C3.587 -0.1 3.955 0.11 4.304 0.11C4.672 0.11 4.882 -0.139 5.031 -0.448C5.21 -0.827 5.33 -1.405 5.33 -1.425C5.33 -1.524 5.25 -1.524 5.181 -1.524C5.061 -1.524 5.051 -1.514 4.991 -1.295C4.852 -0.737 4.663 -0.11 4.324 -0.11C4.065 -0.11 4.065 -0.379 4.065 -0.518C4.065 -0.588 4.065 -0.737 4.125 -0.976L5.549 -6.665ZM3.537 -1.215C3.457 -0.907 2.849 -0.11 2.301 -0.11C1.833 -0.11 1.753 -0.697 1.753 -0.996C1.753 -1.494 2.062 -2.66 2.242 -3.078C2.491 -3.686 2.949 -4.184 3.357 -4.184C3.437 -4.184 3.666 -4.174 3.846 -3.895C3.945 -3.736 4.045 -3.447 4.045 -3.258C4.045 -3.228 4.035 -3.188 4.015 -3.128L3.537 -1.215Z' id='g0-100'/> +<path d='M2.291 -1.743C2.341 -1.963 2.401 -2.172 2.451 -2.391C2.58 -2.899 2.58 -2.909 2.75 -3.198C2.889 -3.437 3.337 -4.184 4.095 -4.184C4.533 -4.184 4.553 -3.736 4.553 -3.527C4.553 -2.909 4.115 -1.724 3.975 -1.325C3.846 -0.986 3.816 -0.897 3.816 -0.687C3.816 -0.249 4.095 0.11 4.573 0.11C5.499 0.11 5.838 -1.375 5.838 -1.425C5.838 -1.524 5.758 -1.524 5.689 -1.524C5.559 -1.524 5.559 -1.504 5.519 -1.355C5.44 -1.086 5.171 -0.11 4.593 -0.11C4.384 -0.11 4.374 -0.259 4.374 -0.399C4.374 -0.648 4.473 -0.907 4.553 -1.146C4.752 -1.674 5.161 -2.79 5.161 -3.367C5.161 -4.184 4.613 -4.403 4.125 -4.403C3.308 -4.403 2.829 -3.806 2.7 -3.616C2.63 -4.105 2.291 -4.403 1.863 -4.403C1.504 -4.403 1.305 -4.174 1.146 -3.875C0.956 -3.477 0.827 -2.889 0.827 -2.869C0.827 -2.77 0.927 -2.77 0.976 -2.77C1.106 -2.77 1.116 -2.78 1.166 -2.999C1.345 -3.696 1.534 -4.184 1.843 -4.184C2.102 -4.184 2.102 -3.895 2.102 -3.786C2.102 -3.626 2.072 -3.437 2.032 -3.278L1.285 -0.289C1.265 -0.229 1.255 -0.179 1.255 -0.149C1.255 -0.04 1.335 0.11 1.534 0.11C1.654 0.11 1.823 0.04 1.893 -0.149L2.291 -1.743Z' id='g0-110'/> +<path d='M5.071 -2.77C5.071 -3.716 4.483 -4.403 3.616 -4.403C2.381 -4.403 1.096 -2.989 1.096 -1.534C1.096 -0.508 1.724 0.11 2.55 0.11C3.786 0.11 5.071 -1.305 5.071 -2.77ZM2.55 -0.11C2.162 -0.11 1.793 -0.418 1.793 -1.136C1.793 -1.634 2.052 -2.74 2.371 -3.278C2.74 -3.885 3.218 -4.184 3.606 -4.184C4.095 -4.184 4.374 -3.746 4.374 -3.158C4.374 -2.73 4.154 -1.704 3.836 -1.106C3.547 -0.558 3.039 -0.11 2.55 -0.11Z' id='g0-111'/> +<path d='M2.57 -2.869C2.58 -2.899 3.029 -4.184 3.885 -4.184C3.935 -4.184 4.214 -4.184 4.413 -4.045C4.065 -3.935 4.035 -3.616 4.035 -3.567C4.035 -3.437 4.125 -3.248 4.384 -3.248C4.563 -3.248 4.872 -3.387 4.872 -3.776C4.872 -4.294 4.224 -4.403 3.895 -4.403C3.208 -4.403 2.849 -3.905 2.69 -3.686C2.58 -4.214 2.192 -4.403 1.863 -4.403C1.504 -4.403 1.305 -4.174 1.146 -3.875C0.956 -3.477 0.827 -2.889 0.827 -2.869C0.827 -2.77 0.927 -2.77 0.976 -2.77C1.106 -2.77 1.116 -2.78 1.166 -2.999C1.345 -3.696 1.534 -4.184 1.843 -4.184C2.102 -4.184 2.102 -3.895 2.102 -3.786C2.102 -3.626 2.072 -3.437 2.032 -3.278L1.285 -0.289C1.265 -0.229 1.255 -0.179 1.255 -0.149C1.255 -0.04 1.335 0.11 1.534 0.11C1.833 0.11 1.903 -0.179 1.923 -0.259L2.57 -2.869Z' id='g0-114'/> +<path d='M3.786 -1.674C3.716 -1.395 3.706 -1.186 3.706 -1.046C3.706 -0.936 3.397 -0.11 2.869 -0.11C2.172 -0.11 2.172 -0.847 2.172 -0.976C2.172 -1.514 2.431 -2.252 2.74 -3.068C2.809 -3.258 2.859 -3.407 2.859 -3.597C2.859 -4.095 2.531 -4.403 2.102 -4.403C1.176 -4.403 0.827 -2.929 0.827 -2.869C0.827 -2.77 0.927 -2.77 0.976 -2.77C1.106 -2.77 1.116 -2.79 1.156 -2.929C1.235 -3.238 1.504 -4.184 2.082 -4.184C2.192 -4.184 2.301 -4.154 2.301 -3.895C2.301 -3.656 2.202 -3.387 2.062 -2.999C1.564 -1.644 1.564 -1.385 1.564 -1.116C1.564 -0.777 1.644 -0.438 1.903 -0.199C2.222 0.08 2.67 0.11 2.839 0.11C3.158 0.11 3.507 -0.02 3.806 -0.528C3.955 -0.159 4.354 0.11 4.941 0.11C5.539 0.11 5.958 -0.299 6.257 -1.006C6.555 -1.684 6.944 -3.218 6.944 -3.746C6.944 -4.095 6.824 -4.403 6.535 -4.403C6.306 -4.403 6.057 -4.174 6.057 -3.945C6.057 -3.816 6.127 -3.746 6.187 -3.676C6.426 -3.417 6.456 -3.098 6.456 -2.889C6.456 -2.491 6.137 -1.445 5.968 -1.036C5.748 -0.518 5.43 -0.11 4.971 -0.11C4.473 -0.11 4.314 -0.518 4.314 -0.936C4.314 -1.026 4.324 -1.265 4.433 -1.704L4.852 -3.377C4.912 -3.597 5.011 -3.995 5.011 -4.035C5.011 -4.144 4.932 -4.294 4.732 -4.294C4.443 -4.294 4.374 -4.025 4.354 -3.945L3.786 -1.674Z' id='g0-119'/> +<path d='M5.489 -6.535C5.539 -6.645 5.539 -6.665 5.539 -6.715C5.539 -6.814 5.46 -6.914 5.34 -6.914C5.21 -6.914 5.151 -6.795 5.111 -6.685L4.284 -4.493H1.255L0.428 -6.685C0.379 -6.824 0.329 -6.914 0.199 -6.914C0.1 -6.914 0 -6.814 0 -6.715C0 -6.695 0 -6.675 0.06 -6.535L2.54 -0.01C2.59 0.13 2.64 0.219 2.77 0.219C2.909 0.219 2.949 0.11 2.989 0.01L5.489 -6.535ZM1.415 -4.095H4.125L2.77 -0.548L1.415 -4.095Z' id='g1-56'/> +<path d='M4.672 -2.72C4.672 -3.756 3.975 -4.403 3.078 -4.403C1.743 -4.403 0.408 -2.989 0.408 -1.574C0.408 -0.588 1.076 0.11 2.002 0.11C3.328 0.11 4.672 -1.265 4.672 -2.72ZM2.012 -0.11C1.584 -0.11 1.146 -0.418 1.146 -1.196C1.146 -1.684 1.405 -2.76 1.724 -3.268C2.222 -4.035 2.79 -4.184 3.068 -4.184C3.646 -4.184 3.945 -3.706 3.945 -3.108C3.945 -2.72 3.746 -1.674 3.367 -1.026C3.019 -0.448 2.471 -0.11 2.012 -0.11Z' id='g3-111'/> +<path d='M0.448 1.215C0.369 1.554 0.349 1.624 -0.09 1.624C-0.209 1.624 -0.319 1.624 -0.319 1.813C-0.319 1.893 -0.269 1.933 -0.189 1.933C0.08 1.933 0.369 1.903 0.648 1.903C0.976 1.903 1.315 1.933 1.634 1.933C1.684 1.933 1.813 1.933 1.813 1.733C1.813 1.624 1.714 1.624 1.574 1.624C1.076 1.624 1.076 1.554 1.076 1.465C1.076 1.345 1.494 -0.279 1.564 -0.528C1.694 -0.239 1.973 0.11 2.481 0.11C3.636 0.11 4.882 -1.345 4.882 -2.809C4.882 -3.746 4.314 -4.403 3.557 -4.403C3.059 -4.403 2.58 -4.045 2.252 -3.656C2.152 -4.194 1.724 -4.403 1.355 -4.403C0.897 -4.403 0.707 -4.015 0.618 -3.836C0.438 -3.497 0.309 -2.899 0.309 -2.869C0.309 -2.77 0.408 -2.77 0.428 -2.77C0.528 -2.77 0.538 -2.78 0.598 -2.999C0.767 -3.706 0.966 -4.184 1.325 -4.184C1.494 -4.184 1.634 -4.105 1.634 -3.726C1.634 -3.497 1.604 -3.387 1.564 -3.218L0.448 1.215ZM2.202 -3.108C2.271 -3.377 2.54 -3.656 2.72 -3.806C3.068 -4.115 3.357 -4.184 3.527 -4.184C3.925 -4.184 4.164 -3.836 4.164 -3.248S3.836 -1.514 3.656 -1.136C3.318 -0.438 2.839 -0.11 2.471 -0.11C1.813 -0.11 1.684 -0.936 1.684 -0.996C1.684 -1.016 1.684 -1.036 1.714 -1.156L2.202 -3.108Z' id='g3-112'/> +<path d='M6.027 -3.706C6.027 -4.154 5.848 -4.403 5.629 -4.403C5.37 -4.403 5.101 -4.164 5.101 -3.935C5.101 -3.836 5.151 -3.726 5.25 -3.636C5.42 -3.487 5.599 -3.218 5.599 -2.8C5.599 -2.401 5.41 -1.833 5.101 -1.375C4.802 -0.946 4.433 -0.608 3.965 -0.608C3.397 -0.608 3.088 -0.966 2.999 -1.504C3.108 -1.763 3.337 -2.401 3.337 -2.68C3.337 -2.8 3.288 -2.899 3.158 -2.899C3.078 -2.899 2.969 -2.879 2.889 -2.73C2.78 -2.531 2.66 -1.883 2.66 -1.524C2.331 -1.056 1.933 -0.608 1.305 -0.608C0.648 -0.608 0.438 -1.196 0.438 -1.753C0.438 -2.999 1.455 -4.045 1.455 -4.174C1.455 -4.284 1.375 -4.364 1.265 -4.364C1.136 -4.364 1.066 -4.234 1.006 -4.144C0.498 -3.407 0.12 -2.222 0.12 -1.315C0.12 -0.628 0.349 0.11 1.166 0.11C1.873 0.11 2.341 -0.389 2.7 -0.936C2.79 -0.359 3.178 0.11 3.796 0.11C4.573 0.11 5.051 -0.498 5.41 -1.245C5.649 -1.733 6.027 -3.088 6.027 -3.706Z' id='g3-33'/> +<path d='M2.889 -3.507C3.706 -3.776 4.284 -4.473 4.284 -5.26C4.284 -6.077 3.407 -6.635 2.451 -6.635C1.445 -6.635 0.687 -6.037 0.687 -5.28C0.687 -4.951 0.907 -4.762 1.196 -4.762C1.504 -4.762 1.704 -4.981 1.704 -5.27C1.704 -5.768 1.235 -5.768 1.086 -5.768C1.395 -6.257 2.052 -6.386 2.411 -6.386C2.819 -6.386 3.367 -6.167 3.367 -5.27C3.367 -5.151 3.347 -4.573 3.088 -4.134C2.79 -3.656 2.451 -3.626 2.202 -3.616C2.122 -3.606 1.883 -3.587 1.813 -3.587C1.733 -3.577 1.664 -3.567 1.664 -3.467C1.664 -3.357 1.733 -3.357 1.903 -3.357H2.341C3.158 -3.357 3.527 -2.68 3.527 -1.704C3.527 -0.349 2.839 -0.06 2.401 -0.06C1.973 -0.06 1.225 -0.229 0.877 -0.817C1.225 -0.767 1.534 -0.986 1.534 -1.365C1.534 -1.724 1.265 -1.923 0.976 -1.923C0.737 -1.923 0.418 -1.783 0.418 -1.345C0.418 -0.438 1.345 0.219 2.431 0.219C3.646 0.219 4.553 -0.687 4.553 -1.704C4.553 -2.521 3.925 -3.298 2.889 -3.507Z' id='g5-51'/> +<path d='M2.022 -0.01C2.022 -0.667 1.773 -1.056 1.385 -1.056C1.056 -1.056 0.857 -0.807 0.857 -0.528C0.857 -0.259 1.056 0 1.385 0C1.504 0 1.634 -0.04 1.733 -0.13C1.763 -0.149 1.773 -0.159 1.783 -0.159S1.803 -0.149 1.803 -0.01C1.803 0.727 1.455 1.325 1.126 1.654C1.016 1.763 1.016 1.783 1.016 1.813C1.016 1.883 1.066 1.923 1.116 1.923C1.225 1.923 2.022 1.156 2.022 -0.01Z' id='g3-59'/> +<path d='M1.913 -6.137C1.913 -6.406 1.684 -6.665 1.385 -6.665C1.046 -6.665 0.847 -6.386 0.847 -6.137C0.847 -5.868 1.076 -5.609 1.375 -5.609C1.714 -5.609 1.913 -5.888 1.913 -6.137Z' id='g5-95'/> +<path d='M4.692 -3.756C4.702 -3.816 4.722 -3.866 4.722 -3.935C4.722 -4.105 4.603 -4.204 4.433 -4.204C4.334 -4.204 4.065 -4.134 4.025 -3.776C3.846 -4.144 3.497 -4.403 3.098 -4.403C1.963 -4.403 0.727 -3.009 0.727 -1.574C0.727 -0.588 1.335 0 2.052 0C2.64 0 3.108 -0.468 3.208 -0.578L3.218 -0.568C3.009 0.319 2.889 0.727 2.889 0.747C2.849 0.837 2.511 1.823 1.455 1.823C1.265 1.823 0.936 1.813 0.658 1.724C0.956 1.634 1.066 1.375 1.066 1.205C1.066 1.046 0.956 0.857 0.687 0.857C0.468 0.857 0.149 1.036 0.149 1.435C0.149 1.843 0.518 2.042 1.474 2.042C2.72 2.042 3.437 1.265 3.587 0.667L4.692 -3.756ZM3.397 -1.275C3.337 -1.016 3.108 -0.767 2.889 -0.578C2.68 -0.399 2.371 -0.219 2.082 -0.219C1.584 -0.219 1.435 -0.737 1.435 -1.136C1.435 -1.614 1.724 -2.79 1.993 -3.298C2.262 -3.786 2.69 -4.184 3.108 -4.184C3.766 -4.184 3.905 -3.377 3.905 -3.328S3.885 -3.218 3.875 -3.178L3.397 -1.275Z' id='g3-103'/> +<path d='M6.834 -4.224C7.004 -4.224 7.193 -4.224 7.193 -4.423S7.014 -4.623 6.844 -4.623H0.897C0.727 -4.623 0.548 -4.623 0.548 -4.423S0.747 -4.224 0.907 -4.224H6.834ZM6.844 -0.359C7.014 -0.359 7.193 -0.359 7.193 -0.558S7.004 -0.757 6.834 -0.757H0.907C0.747 -0.757 0.548 -0.757 0.548 -0.558S0.727 -0.359 0.897 -0.359H6.844ZM6.844 -2.291C7.014 -2.291 7.193 -2.291 7.193 -2.491S7.014 -2.69 6.844 -2.69H0.897C0.727 -2.69 0.548 -2.69 0.548 -2.491S0.727 -2.291 0.897 -2.291H6.844Z' id='g1-17'/> +<path d='M4.503 -4.294C4.503 -4.334 4.473 -4.394 4.403 -4.394C4.294 -4.394 3.895 -3.995 3.726 -3.706C3.507 -4.244 3.118 -4.403 2.8 -4.403C1.624 -4.403 0.399 -2.929 0.399 -1.484C0.399 -0.508 0.986 0.11 1.714 0.11C2.142 0.11 2.531 -0.13 2.889 -0.488C2.8 -0.139 2.471 1.205 2.441 1.295C2.361 1.574 2.281 1.614 1.724 1.624C1.594 1.624 1.494 1.624 1.494 1.823C1.494 1.833 1.494 1.933 1.624 1.933C1.943 1.933 2.291 1.903 2.62 1.903C2.959 1.903 3.318 1.933 3.646 1.933C3.696 1.933 3.826 1.933 3.826 1.733C3.826 1.624 3.726 1.624 3.567 1.624C3.088 1.624 3.088 1.554 3.088 1.465C3.088 1.395 3.108 1.335 3.128 1.245L4.503 -4.294ZM1.743 -0.11C1.146 -0.11 1.106 -0.877 1.106 -1.046C1.106 -1.524 1.395 -2.61 1.564 -3.029C1.873 -3.766 2.391 -4.184 2.8 -4.184C3.447 -4.184 3.587 -3.377 3.587 -3.308C3.587 -3.248 3.039 -1.066 3.009 -1.026C2.859 -0.747 2.301 -0.11 1.743 -0.11Z' id='g3-113'/> +<path d='M2.381 -2.301C2.68 -2.301 3.347 -2.331 3.826 -2.521C4.613 -2.839 4.613 -3.487 4.613 -3.557C4.613 -4.015 4.244 -4.403 3.606 -4.403C2.56 -4.403 1.136 -3.397 1.136 -1.634C1.136 -0.737 1.614 0.11 2.56 0.11C3.836 0.11 4.663 -0.887 4.663 -1.036C4.663 -1.086 4.583 -1.196 4.503 -1.196C4.463 -1.196 4.453 -1.186 4.374 -1.086C3.636 -0.149 2.75 -0.11 2.58 -0.11C1.933 -0.11 1.823 -0.817 1.823 -1.205C1.823 -1.584 1.923 -2.032 1.993 -2.301H2.381ZM2.052 -2.521C2.481 -4.154 3.507 -4.184 3.606 -4.184C4.005 -4.184 4.234 -3.915 4.234 -3.577C4.234 -2.521 2.59 -2.521 2.262 -2.521H2.052Z' id='g0-101'/> +<path d='M2.76 -3.985H3.577C3.746 -3.985 3.846 -3.985 3.846 -4.164C3.846 -4.294 3.766 -4.294 3.597 -4.294H2.819C2.959 -5.031 2.989 -5.21 3.138 -5.908C3.218 -6.276 3.328 -6.804 3.686 -6.804C3.766 -6.804 3.975 -6.785 4.105 -6.625C3.806 -6.575 3.666 -6.336 3.666 -6.137C3.666 -5.918 3.846 -5.818 4.005 -5.818C4.254 -5.818 4.503 -6.017 4.503 -6.366C4.503 -6.795 4.095 -7.024 3.686 -7.024C2.71 -7.024 2.461 -5.729 2.391 -5.39L2.182 -4.294H1.524C1.365 -4.294 1.255 -4.294 1.255 -4.095C1.255 -3.985 1.355 -3.985 1.504 -3.985H2.122L1.395 -0.269C1.275 0.349 1.176 0.757 1.116 0.966C1.036 1.305 0.907 1.823 0.548 1.823C0.448 1.823 0.259 1.793 0.149 1.644C0.448 1.594 0.588 1.355 0.588 1.156C0.588 0.936 0.408 0.837 0.249 0.837C0 0.837 -0.249 1.036 -0.249 1.385C-0.249 1.833 0.179 2.042 0.548 2.042C1.584 2.042 1.993 -0.05 2.062 -0.408L2.76 -3.985Z' id='g0-102'/> +<path d='M3.019 -6.665C3.029 -6.695 3.049 -6.775 3.049 -6.795C3.049 -6.884 2.989 -6.914 2.909 -6.914C2.879 -6.914 2.78 -6.904 2.75 -6.894L1.763 -6.814C1.644 -6.804 1.534 -6.795 1.534 -6.605C1.534 -6.496 1.634 -6.496 1.773 -6.496C2.252 -6.496 2.271 -6.426 2.271 -6.326C2.271 -6.296 2.242 -6.167 2.242 -6.157L0.996 -1.176C0.986 -1.136 0.936 -0.936 0.936 -0.787C0.936 -0.259 1.295 0.11 1.773 0.11C2.152 0.11 2.351 -0.159 2.481 -0.408C2.65 -0.757 2.79 -1.395 2.79 -1.425C2.79 -1.524 2.71 -1.524 2.64 -1.524C2.59 -1.524 2.531 -1.524 2.501 -1.474L2.431 -1.225C2.262 -0.528 2.072 -0.11 1.793 -0.11C1.534 -0.11 1.534 -0.379 1.534 -0.518C1.534 -0.588 1.534 -0.737 1.594 -0.976L3.019 -6.665Z' id='g0-108'/> +<path d='M2.461 -1.963C2.899 -1.863 3.347 -1.763 3.347 -1.225C3.347 -0.907 3.078 -0.11 2.052 -0.11C1.833 -0.11 1.255 -0.159 1.096 -0.667C1.604 -0.717 1.604 -1.136 1.604 -1.156C1.604 -1.345 1.474 -1.474 1.265 -1.474C1.036 -1.474 0.757 -1.305 0.757 -0.857C0.757 -0.249 1.335 0.11 2.042 0.11C3.537 0.11 3.915 -1.106 3.915 -1.564C3.915 -2.431 3.138 -2.61 2.73 -2.7C2.451 -2.76 2.092 -2.839 2.092 -3.268C2.092 -3.507 2.301 -4.184 3.098 -4.184C3.367 -4.184 3.736 -4.085 3.846 -3.696C3.527 -3.656 3.447 -3.387 3.447 -3.288C3.447 -3.178 3.507 -3.009 3.746 -3.009C3.915 -3.009 4.174 -3.128 4.174 -3.557C4.174 -4.015 3.766 -4.403 3.108 -4.403C1.943 -4.403 1.534 -3.447 1.534 -2.929C1.534 -2.162 2.182 -2.022 2.461 -1.963Z' id='g0-115'/> +<path d='M2.59 -3.985H3.437C3.606 -3.985 3.716 -3.985 3.716 -4.174C3.716 -4.294 3.626 -4.294 3.467 -4.294H2.67L3.039 -5.768C3.078 -5.908 3.078 -5.928 3.078 -5.978C3.078 -6.187 2.909 -6.237 2.809 -6.237C2.56 -6.237 2.461 -6.027 2.421 -5.878L2.032 -4.294H1.186C1.016 -4.294 0.907 -4.294 0.907 -4.105C0.907 -3.985 0.996 -3.985 1.156 -3.985H1.953L1.235 -1.126C1.225 -1.086 1.186 -0.927 1.186 -0.787C1.186 -0.289 1.514 0.11 2.032 0.11C3.039 0.11 3.547 -1.375 3.547 -1.425C3.547 -1.524 3.467 -1.524 3.397 -1.524C3.278 -1.524 3.278 -1.514 3.198 -1.335C3.019 -0.857 2.62 -0.11 2.052 -0.11C1.783 -0.11 1.783 -0.359 1.783 -0.518C1.783 -0.588 1.783 -0.747 1.853 -1.026L2.59 -3.985Z' id='g0-116'/> +<path d='M5.111 -3.895C5.131 -3.955 5.141 -4.005 5.141 -4.035C5.141 -4.144 5.061 -4.294 4.862 -4.294C4.563 -4.294 4.493 -4.005 4.473 -3.925L3.746 -1.016C3.696 -0.837 3.696 -0.817 3.606 -0.687C3.417 -0.408 3.128 -0.11 2.69 -0.11C2.242 -0.11 2.152 -0.548 2.152 -0.877C2.152 -1.484 2.481 -2.381 2.73 -3.059C2.809 -3.268 2.859 -3.407 2.859 -3.597C2.859 -4.095 2.531 -4.403 2.102 -4.403C1.176 -4.403 0.827 -2.929 0.827 -2.869C0.827 -2.77 0.927 -2.77 0.976 -2.77C1.106 -2.77 1.116 -2.79 1.156 -2.929C1.235 -3.238 1.504 -4.184 2.082 -4.184C2.192 -4.184 2.301 -4.154 2.301 -3.895C2.301 -3.656 2.202 -3.387 2.062 -2.999C1.803 -2.301 1.544 -1.564 1.544 -1.046C1.544 -0.179 2.122 0.11 2.66 0.11C3.188 0.11 3.527 -0.189 3.766 -0.488C3.945 0.05 4.374 0.11 4.563 0.11C4.932 0.11 5.141 -0.139 5.29 -0.448C5.469 -0.827 5.589 -1.405 5.589 -1.425C5.589 -1.524 5.509 -1.524 5.44 -1.524C5.32 -1.524 5.31 -1.514 5.25 -1.295C5.111 -0.737 4.922 -0.11 4.583 -0.11C4.324 -0.11 4.324 -0.379 4.324 -0.518C4.324 -0.588 4.324 -0.747 4.394 -1.026L5.111 -3.895Z' id='g0-117'/> +<path d='M4.583 -3.188C4.583 -3.985 4.533 -4.782 4.184 -5.519C3.726 -6.476 2.909 -6.635 2.491 -6.635C1.893 -6.635 1.166 -6.376 0.757 -5.45C0.438 -4.762 0.389 -3.985 0.389 -3.188C0.389 -2.441 0.428 -1.544 0.837 -0.787C1.265 0.02 1.993 0.219 2.481 0.219C3.019 0.219 3.776 0.01 4.214 -0.936C4.533 -1.624 4.583 -2.401 4.583 -3.188ZM2.481 0C2.092 0 1.504 -0.249 1.325 -1.205C1.215 -1.803 1.215 -2.72 1.215 -3.308C1.215 -3.945 1.215 -4.603 1.295 -5.141C1.484 -6.326 2.232 -6.416 2.481 -6.416C2.809 -6.416 3.467 -6.237 3.656 -5.25C3.756 -4.692 3.756 -3.935 3.756 -3.308C3.756 -2.56 3.756 -1.883 3.646 -1.245C3.497 -0.299 2.929 0 2.481 0Z' id='g5-48'/> +<path d='M6.017 -5.559C6.077 -5.689 6.087 -5.709 6.087 -5.758C6.087 -5.868 5.998 -5.958 5.888 -5.958C5.788 -5.958 5.729 -5.888 5.659 -5.738L3.318 -0.468L0.976 -5.748C0.897 -5.938 0.817 -5.958 0.747 -5.958C0.638 -5.958 0.548 -5.868 0.548 -5.758C0.548 -5.738 0.548 -5.719 0.608 -5.599L3.088 0.01C3.168 0.179 3.228 0.219 3.318 0.219C3.447 0.219 3.477 0.149 3.537 0.01L6.017 -5.559Z' id='g1-95'/> +<path d='M4.603 -3.377C4.653 -3.597 4.752 -3.965 4.752 -4.025C4.752 -4.204 4.613 -4.294 4.463 -4.294C4.344 -4.294 4.164 -4.214 4.095 -4.015C4.065 -3.945 3.597 -2.042 3.527 -1.783C3.457 -1.484 3.437 -1.305 3.437 -1.126C3.437 -1.016 3.437 -0.996 3.447 -0.946C3.218 -0.418 2.919 -0.11 2.531 -0.11C1.733 -0.11 1.733 -0.847 1.733 -1.016C1.733 -1.335 1.783 -1.724 2.252 -2.949C2.361 -3.248 2.421 -3.387 2.421 -3.587C2.421 -4.035 2.092 -4.403 1.604 -4.403C0.658 -4.403 0.289 -2.959 0.289 -2.869C0.289 -2.77 0.389 -2.77 0.408 -2.77C0.508 -2.77 0.518 -2.79 0.568 -2.949C0.837 -3.875 1.225 -4.184 1.574 -4.184C1.664 -4.184 1.823 -4.174 1.823 -3.856C1.823 -3.606 1.714 -3.328 1.644 -3.158C1.205 -1.983 1.086 -1.524 1.086 -1.146C1.086 -0.239 1.753 0.11 2.501 0.11C2.67 0.11 3.138 0.11 3.537 -0.588C3.796 0.05 4.483 0.11 4.782 0.11C5.529 0.11 5.968 -0.518 6.227 -1.116C6.565 -1.893 6.884 -3.228 6.884 -3.706C6.884 -4.254 6.615 -4.403 6.446 -4.403C6.197 -4.403 5.948 -4.144 5.948 -3.925C5.948 -3.796 6.007 -3.736 6.097 -3.656C6.207 -3.547 6.456 -3.288 6.456 -2.809C6.456 -2.471 6.167 -1.494 5.908 -0.986C5.649 -0.458 5.3 -0.11 4.812 -0.11C4.344 -0.11 4.075 -0.408 4.075 -0.976C4.075 -1.255 4.144 -1.564 4.184 -1.704L4.603 -3.377Z' id='g3-119'/> +<path d='M3.786 -0.548V0.11L5.25 0V-0.309C4.553 -0.309 4.473 -0.379 4.473 -0.867V-6.914L3.039 -6.804V-6.496C3.736 -6.496 3.816 -6.426 3.816 -5.938V-3.786C3.527 -4.144 3.098 -4.403 2.56 -4.403C1.385 -4.403 0.339 -3.427 0.339 -2.142C0.339 -0.877 1.315 0.11 2.451 0.11C3.088 0.11 3.537 -0.229 3.786 -0.548ZM3.786 -3.218V-1.176C3.786 -0.996 3.786 -0.976 3.676 -0.807C3.377 -0.329 2.929 -0.11 2.501 -0.11C2.052 -0.11 1.694 -0.369 1.455 -0.747C1.196 -1.156 1.166 -1.724 1.166 -2.132C1.166 -2.501 1.186 -3.098 1.474 -3.547C1.684 -3.856 2.062 -4.184 2.6 -4.184C2.949 -4.184 3.367 -4.035 3.676 -3.587C3.786 -3.417 3.786 -3.397 3.786 -3.218Z' id='g5-100'/> +<path d='M4.692 -2.132C4.692 -3.407 3.696 -4.463 2.491 -4.463C1.245 -4.463 0.279 -3.377 0.279 -2.132C0.279 -0.847 1.315 0.11 2.481 0.11C3.686 0.11 4.692 -0.867 4.692 -2.132ZM2.491 -0.139C2.062 -0.139 1.624 -0.349 1.355 -0.807C1.106 -1.245 1.106 -1.853 1.106 -2.212C1.106 -2.6 1.106 -3.138 1.345 -3.577C1.614 -4.035 2.082 -4.244 2.481 -4.244C2.919 -4.244 3.347 -4.025 3.606 -3.597S3.866 -2.59 3.866 -2.212C3.866 -1.853 3.866 -1.315 3.646 -0.877C3.427 -0.428 2.989 -0.139 2.491 -0.139Z' id='g5-111'/> +<path d='M4.144 -3.318C4.234 -3.547 4.403 -3.975 5.061 -3.985V-4.294C4.832 -4.274 4.543 -4.264 4.314 -4.264C4.075 -4.264 3.616 -4.284 3.447 -4.294V-3.985C3.816 -3.975 3.925 -3.746 3.925 -3.557C3.925 -3.467 3.905 -3.427 3.866 -3.318L2.849 -0.777L1.733 -3.557C1.674 -3.686 1.674 -3.706 1.674 -3.726C1.674 -3.985 2.062 -3.985 2.242 -3.985V-4.294C1.943 -4.284 1.385 -4.264 1.156 -4.264C0.887 -4.264 0.488 -4.274 0.189 -4.294V-3.985C0.817 -3.985 0.857 -3.925 0.986 -3.616L2.421 -0.08C2.481 0.06 2.501 0.11 2.63 0.11S2.8 0.02 2.839 -0.08L4.144 -3.318Z' id='g5-118'/> +<path d='M5.46 -2.291C5.629 -2.291 5.808 -2.291 5.808 -2.491S5.629 -2.69 5.46 -2.69H1.235C1.355 -4.025 2.501 -4.981 3.905 -4.981H5.46C5.629 -4.981 5.808 -4.981 5.808 -5.181S5.629 -5.38 5.46 -5.38H3.885C2.182 -5.38 0.827 -4.085 0.827 -2.491S2.182 0.399 3.885 0.399H5.46C5.629 0.399 5.808 0.399 5.808 0.199S5.629 0 5.46 0H3.905C2.501 0 1.355 -0.956 1.235 -2.291H5.46Z' id='g1-50'/> +<path d='M2.819 -6.147C2.819 -6.545 3.078 -7.183 4.164 -7.253C4.214 -7.263 4.254 -7.303 4.254 -7.362C4.254 -7.472 4.174 -7.472 4.065 -7.472C3.068 -7.472 2.162 -6.964 2.152 -6.227V-3.955C2.152 -3.567 2.152 -3.248 1.753 -2.919C1.405 -2.63 1.026 -2.61 0.807 -2.6C0.757 -2.59 0.717 -2.55 0.717 -2.491C0.717 -2.391 0.777 -2.391 0.877 -2.381C1.534 -2.341 2.012 -1.983 2.122 -1.494C2.152 -1.385 2.152 -1.365 2.152 -1.006V0.966C2.152 1.385 2.152 1.704 2.63 2.082C3.019 2.381 3.676 2.491 4.065 2.491C4.174 2.491 4.254 2.491 4.254 2.381C4.254 2.281 4.194 2.281 4.095 2.271C3.467 2.232 2.979 1.913 2.849 1.405C2.819 1.315 2.819 1.295 2.819 0.936V-1.156C2.819 -1.614 2.74 -1.783 2.421 -2.102C2.212 -2.311 1.923 -2.411 1.644 -2.491C2.461 -2.72 2.819 -3.178 2.819 -3.756V-6.147Z' id='g1-102'/> +<path d='M2.152 1.166C2.152 1.564 1.893 2.202 0.807 2.271C0.757 2.281 0.717 2.321 0.717 2.381C0.717 2.491 0.827 2.491 0.917 2.491C1.883 2.491 2.809 2.002 2.819 1.245V-1.026C2.819 -1.415 2.819 -1.733 3.218 -2.062C3.567 -2.351 3.945 -2.371 4.164 -2.381C4.214 -2.391 4.254 -2.431 4.254 -2.491C4.254 -2.59 4.194 -2.59 4.095 -2.6C3.437 -2.64 2.959 -2.999 2.849 -3.487C2.819 -3.597 2.819 -3.616 2.819 -3.975V-5.948C2.819 -6.366 2.819 -6.685 2.341 -7.064C1.943 -7.372 1.255 -7.472 0.917 -7.472C0.827 -7.472 0.717 -7.472 0.717 -7.362C0.717 -7.263 0.777 -7.263 0.877 -7.253C1.504 -7.213 1.993 -6.894 2.122 -6.386C2.152 -6.296 2.152 -6.276 2.152 -5.918V-3.826C2.152 -3.367 2.232 -3.198 2.55 -2.879C2.76 -2.67 3.049 -2.57 3.328 -2.491C2.511 -2.262 2.152 -1.803 2.152 -1.225V1.166Z' id='g1-103'/> +<path d='M1.584 -7.113C1.584 -7.293 1.584 -7.472 1.385 -7.472S1.186 -7.293 1.186 -7.113V2.132C1.186 2.311 1.186 2.491 1.385 2.491S1.584 2.311 1.584 2.132V-7.113Z' id='g1-106'/> +<path d='M1.315 -3.268V-3.507C1.315 -6.027 2.55 -6.386 3.059 -6.386C3.298 -6.386 3.716 -6.326 3.935 -5.988C3.786 -5.988 3.387 -5.988 3.387 -5.539C3.387 -5.23 3.626 -5.081 3.846 -5.081C4.005 -5.081 4.304 -5.171 4.304 -5.559C4.304 -6.157 3.866 -6.635 3.039 -6.635C1.763 -6.635 0.418 -5.35 0.418 -3.148C0.418 -0.488 1.574 0.219 2.501 0.219C3.606 0.219 4.553 -0.717 4.553 -2.032C4.553 -3.298 3.666 -4.254 2.56 -4.254C1.883 -4.254 1.514 -3.746 1.315 -3.268ZM2.501 -0.06C1.873 -0.06 1.574 -0.658 1.514 -0.807C1.335 -1.275 1.335 -2.072 1.335 -2.252C1.335 -3.029 1.654 -4.025 2.55 -4.025C2.71 -4.025 3.168 -4.025 3.477 -3.407C3.656 -3.039 3.656 -2.531 3.656 -2.042C3.656 -1.564 3.656 -1.066 3.487 -0.707C3.188 -0.11 2.73 -0.06 2.501 -0.06Z' id='g5-54'/> +<path d='M2.929 -1.644V-0.777C2.929 -0.418 2.909 -0.309 2.172 -0.309H1.963V0C2.371 -0.03 2.889 -0.03 3.308 -0.03S4.254 -0.03 4.663 0V-0.309H4.453C3.716 -0.309 3.696 -0.418 3.696 -0.777V-1.644H4.692V-1.953H3.696V-6.486C3.696 -6.685 3.696 -6.745 3.537 -6.745C3.447 -6.745 3.417 -6.745 3.337 -6.625L0.279 -1.953V-1.644H2.929ZM2.989 -1.953H0.558L2.989 -5.669V-1.953Z' id='g5-52'/> +<path d='M1.913 -0.528C1.913 -0.817 1.674 -1.056 1.385 -1.056S0.857 -0.817 0.857 -0.528S1.096 0 1.385 0S1.913 -0.239 1.913 -0.528Z' id='g5-46'/> +<path d='M4.473 -2.002C4.473 -3.188 3.656 -4.184 2.58 -4.184C2.102 -4.184 1.674 -4.025 1.315 -3.676V-5.619C1.514 -5.559 1.843 -5.489 2.162 -5.489C3.387 -5.489 4.085 -6.396 4.085 -6.526C4.085 -6.585 4.055 -6.635 3.985 -6.635C3.975 -6.635 3.955 -6.635 3.905 -6.605C3.706 -6.516 3.218 -6.316 2.55 -6.316C2.152 -6.316 1.694 -6.386 1.225 -6.595C1.146 -6.625 1.126 -6.625 1.106 -6.625C1.006 -6.625 1.006 -6.545 1.006 -6.386V-3.437C1.006 -3.258 1.006 -3.178 1.146 -3.178C1.215 -3.178 1.235 -3.208 1.275 -3.268C1.385 -3.427 1.753 -3.965 2.56 -3.965C3.078 -3.965 3.328 -3.507 3.407 -3.328C3.567 -2.959 3.587 -2.57 3.587 -2.072C3.587 -1.724 3.587 -1.126 3.347 -0.707C3.108 -0.319 2.74 -0.06 2.281 -0.06C1.554 -0.06 0.986 -0.588 0.817 -1.176C0.847 -1.166 0.877 -1.156 0.986 -1.156C1.315 -1.156 1.484 -1.405 1.484 -1.644S1.315 -2.132 0.986 -2.132C0.847 -2.132 0.498 -2.062 0.498 -1.604C0.498 -0.747 1.186 0.219 2.301 0.219C3.457 0.219 4.473 -0.737 4.473 -2.002Z' id='g5-53'/> +<path d='M4.742 -6.067C4.832 -6.187 4.832 -6.207 4.832 -6.416H2.411C1.196 -6.416 1.176 -6.545 1.136 -6.735H0.887L0.558 -4.682H0.807C0.837 -4.842 0.927 -5.469 1.056 -5.589C1.126 -5.649 1.903 -5.649 2.032 -5.649H4.095C3.985 -5.489 3.198 -4.403 2.979 -4.075C2.082 -2.73 1.753 -1.345 1.753 -0.329C1.753 -0.229 1.753 0.219 2.212 0.219S2.67 -0.229 2.67 -0.329V-0.837C2.67 -1.385 2.7 -1.933 2.78 -2.471C2.819 -2.7 2.959 -3.557 3.397 -4.174L4.742 -6.067Z' id='g5-55'/> +<path d='M0.774 -5.021C0.774 -5.161 0.774 -5.23 0.656 -5.23S0.537 -5.161 0.537 -5.014V-0.07C0.537 0.07 0.537 0.139 0.656 0.139C0.76 0.139 1.22 -0.181 1.36 -0.279C1.897 -0.656 2.678 -1.297 2.678 -2.239C2.678 -2.838 2.148 -3.208 1.632 -3.208C1.59 -3.208 1.102 -3.208 0.774 -2.943V-5.021ZM0.774 -2.357C0.774 -2.518 0.774 -2.65 0.983 -2.769C1.081 -2.817 1.269 -2.887 1.534 -2.887C2.029 -2.887 2.057 -2.35 2.057 -2.239C2.057 -1.381 1.381 -0.663 0.774 -0.195V-2.357Z' id='g4-91'/> +<path d='M2.183 -4.631C2.19 -4.645 2.211 -4.735 2.211 -4.742C2.211 -4.777 2.183 -4.84 2.099 -4.84C1.96 -4.84 1.381 -4.784 1.206 -4.77C1.151 -4.763 1.053 -4.756 1.053 -4.61C1.053 -4.512 1.151 -4.512 1.234 -4.512C1.569 -4.512 1.569 -4.463 1.569 -4.407C1.569 -4.359 1.555 -4.317 1.541 -4.254L0.558 -0.307C0.523 -0.181 0.523 -0.167 0.523 -0.153C0.523 -0.049 0.607 0.07 0.76 0.07C0.948 0.07 1.039 -0.07 1.081 -0.223C1.095 -0.251 1.395 -1.478 1.423 -1.576C1.918 -1.527 2.315 -1.367 2.315 -1.004C2.315 -0.969 2.315 -0.934 2.301 -0.865C2.273 -0.76 2.273 -0.725 2.273 -0.649C2.273 -0.153 2.678 0.07 3.013 0.07C3.689 0.07 3.898 -0.99 3.898 -0.997C3.898 -1.088 3.808 -1.088 3.787 -1.088C3.689 -1.088 3.682 -1.053 3.647 -0.921C3.564 -0.621 3.375 -0.126 3.034 -0.126C2.845 -0.126 2.79 -0.3 2.79 -0.488C2.79 -0.607 2.79 -0.621 2.831 -0.802C2.838 -0.823 2.866 -0.941 2.866 -1.018C2.866 -1.639 2.029 -1.736 1.736 -1.757C1.939 -1.883 2.197 -2.113 2.315 -2.218C2.671 -2.552 3.02 -2.88 3.41 -2.88C3.494 -2.88 3.585 -2.859 3.64 -2.79C3.34 -2.741 3.278 -2.504 3.278 -2.399C3.278 -2.246 3.396 -2.141 3.557 -2.141C3.745 -2.141 3.954 -2.294 3.954 -2.587C3.954 -2.817 3.787 -3.075 3.417 -3.075C3.02 -3.075 2.657 -2.79 2.301 -2.462C2.008 -2.183 1.778 -1.967 1.492 -1.848L2.183 -4.631Z' id='g4-107'/> +<path d='M2.127 0.146V0.886C2.127 1.011 2.127 1.095 2.225 1.095C2.364 1.095 2.364 0.997 2.364 0.872V0.07L2.587 0C2.678 -0.028 2.678 -0.063 2.678 -0.209V-0.411C2.678 -0.53 2.678 -0.621 2.58 -0.621C2.532 -0.621 2.406 -0.572 2.364 -0.558V-2.936L2.587 -3.006C2.678 -3.034 2.678 -3.068 2.678 -3.215V-3.417C2.678 -3.536 2.678 -3.626 2.58 -3.626C2.532 -3.626 2.406 -3.578 2.364 -3.564V-4.777C2.364 -4.903 2.364 -4.993 2.267 -4.993C2.127 -4.993 2.127 -4.896 2.127 -4.77V-3.487L1.088 -3.152V-4.373C1.088 -4.498 1.088 -4.582 0.99 -4.582C0.851 -4.582 0.851 -4.484 0.851 -4.359V-3.075C0.746 -3.048 0.711 -3.034 0.628 -3.006C0.537 -2.971 0.537 -2.95 0.537 -2.79V-2.594C0.537 -2.476 0.537 -2.385 0.635 -2.385C0.683 -2.385 0.809 -2.434 0.851 -2.448V-0.07C0.746 -0.042 0.711 -0.028 0.628 0C0.537 0.035 0.537 0.056 0.537 0.216V0.411C0.537 0.53 0.537 0.621 0.635 0.621C0.683 0.621 0.809 0.572 0.851 0.558V1.29C0.851 1.416 0.851 1.506 0.948 1.506C1.088 1.506 1.088 1.409 1.088 1.283V0.481L2.127 0.146ZM2.127 -2.859V-0.481L1.088 -0.146V-2.525L2.127 -2.859Z' id='g4-93'/> +<path d='M2.859 -6.804C2.859 -6.814 2.859 -6.914 2.73 -6.914C2.501 -6.914 1.773 -6.834 1.514 -6.814C1.435 -6.804 1.325 -6.795 1.325 -6.615C1.325 -6.496 1.415 -6.496 1.564 -6.496C2.042 -6.496 2.062 -6.426 2.062 -6.326L2.032 -6.127L0.588 -0.389C0.548 -0.249 0.548 -0.229 0.548 -0.169C0.548 0.06 0.747 0.11 0.837 0.11C0.966 0.11 1.116 0.02 1.176 -0.1C1.225 -0.189 1.674 -2.032 1.733 -2.281C2.072 -2.252 2.889 -2.092 2.889 -1.435C2.889 -1.365 2.889 -1.325 2.859 -1.225C2.839 -1.106 2.819 -0.986 2.819 -0.877C2.819 -0.289 3.218 0.11 3.736 0.11C4.035 0.11 4.304 -0.05 4.523 -0.418C4.772 -0.857 4.882 -1.405 4.882 -1.425C4.882 -1.524 4.792 -1.524 4.762 -1.524C4.663 -1.524 4.653 -1.484 4.623 -1.345C4.423 -0.618 4.194 -0.11 3.756 -0.11C3.567 -0.11 3.437 -0.219 3.437 -0.578C3.437 -0.747 3.477 -0.976 3.517 -1.136C3.557 -1.305 3.557 -1.345 3.557 -1.445C3.557 -2.092 2.929 -2.381 2.082 -2.491C2.391 -2.67 2.71 -2.989 2.939 -3.228C3.417 -3.756 3.875 -4.184 4.364 -4.184C4.423 -4.184 4.433 -4.184 4.453 -4.174C4.573 -4.154 4.583 -4.154 4.663 -4.095C4.682 -4.085 4.682 -4.075 4.702 -4.055C4.224 -4.025 4.134 -3.636 4.134 -3.517C4.134 -3.357 4.244 -3.168 4.513 -3.168C4.772 -3.168 5.061 -3.387 5.061 -3.776C5.061 -4.075 4.832 -4.403 4.384 -4.403C4.105 -4.403 3.646 -4.324 2.929 -3.527C2.59 -3.148 2.202 -2.75 1.823 -2.6L2.859 -6.804Z' id='g3-107'/> +<path d='M4.144 14.834C4.144 14.366 4.144 13.629 3.517 12.822C3.128 12.324 2.56 11.866 1.873 11.557C3.816 10.62 4.144 9.186 4.144 8.618V2.879C4.144 2.262 4.144 0.986 6.077 0.03C6.157 -0.01 6.157 -0.03 6.157 -0.179C6.157 -0.389 6.157 -0.399 5.938 -0.399C5.798 -0.399 5.778 -0.399 5.519 -0.279C4.533 0.209 3.557 0.996 3.347 2.212C3.318 2.411 3.318 2.501 3.318 3.168V7.771C3.318 8.08 3.318 8.598 3.308 8.707C3.218 9.753 2.61 10.66 1.474 11.288C1.315 11.377 1.305 11.387 1.305 11.547C1.305 11.716 1.315 11.726 1.455 11.806C2.122 12.174 3.078 12.892 3.278 14.137C3.318 14.366 3.318 14.386 3.318 14.496V20.413C3.318 21.858 4.314 22.804 5.549 23.392C5.768 23.502 5.788 23.502 5.938 23.502C6.147 23.502 6.157 23.502 6.157 23.283C6.157 23.123 6.147 23.113 6.067 23.064C5.659 22.864 4.374 22.217 4.164 20.782C4.144 20.643 4.144 20.533 4.144 19.935V14.834Z' id='g7-26'/> +<path d='M5.189 -1.576C5.3 -1.576 5.467 -1.576 5.467 -1.743C5.467 -1.918 5.307 -1.918 5.189 -1.918H1.032C0.921 -1.918 0.753 -1.918 0.753 -1.75C0.753 -1.576 0.914 -1.576 1.032 -1.576H5.189Z' id='g2-0'/> +<path d='M2.336 -4.435C2.336 -4.624 2.322 -4.631 2.127 -4.631C1.681 -4.191 1.046 -4.184 0.76 -4.184V-3.933C0.928 -3.933 1.388 -3.933 1.771 -4.129V-0.572C1.771 -0.342 1.771 -0.251 1.074 -0.251H0.809V0C0.934 -0.007 1.792 -0.028 2.05 -0.028C2.267 -0.028 3.145 -0.007 3.299 0V-0.251H3.034C2.336 -0.251 2.336 -0.342 2.336 -0.572V-4.435Z' id='g6-49'/> +<path d='M6.725 -2.271C6.834 -2.321 6.914 -2.371 6.914 -2.491S6.834 -2.66 6.725 -2.71L1.205 -5.31C1.076 -5.38 1.056 -5.38 1.026 -5.38C0.917 -5.38 0.827 -5.29 0.827 -5.181C0.827 -5.091 0.877 -5.031 1.016 -4.961L6.247 -2.491L1.016 -0.02C0.877 0.05 0.827 0.11 0.827 0.199C0.827 0.309 0.917 0.399 1.026 0.399C1.056 0.399 1.076 0.399 1.205 0.329L6.725 -2.271Z' id='g3-62'/> +<path d='M4.075 -6.296C4.075 -6.476 4.075 -6.655 3.875 -6.655S3.676 -6.446 3.676 -6.296V-0.399H0.907C0.757 -0.399 0.548 -0.399 0.548 -0.199S0.757 0 0.907 0H6.854C7.024 0 7.203 0 7.203 -0.199S7.024 -0.399 6.854 -0.399H4.075V-6.296Z' id='g1-63'/> +<path d='M4.075 -6.257H6.854C7.024 -6.257 7.203 -6.257 7.203 -6.456S7.024 -6.655 6.854 -6.655H0.907C0.757 -6.655 0.548 -6.655 0.548 -6.456S0.757 -6.257 0.907 -6.257H3.676V-0.359C3.676 -0.209 3.676 0 3.875 0S4.075 -0.179 4.075 -0.359V-6.257Z' id='g1-62'/> +<path d='M3.599 -2.225C3.599 -2.992 3.508 -3.543 3.187 -4.031C2.971 -4.352 2.538 -4.631 1.981 -4.631C0.363 -4.631 0.363 -2.727 0.363 -2.225S0.363 0.139 1.981 0.139S3.599 -1.723 3.599 -2.225ZM1.981 -0.056C1.66 -0.056 1.234 -0.244 1.095 -0.816C0.997 -1.227 0.997 -1.799 0.997 -2.315C0.997 -2.824 0.997 -3.354 1.102 -3.738C1.248 -4.289 1.695 -4.435 1.981 -4.435C2.357 -4.435 2.72 -4.205 2.845 -3.801C2.957 -3.424 2.964 -2.922 2.964 -2.315C2.964 -1.799 2.964 -1.283 2.873 -0.844C2.734 -0.209 2.26 -0.056 1.981 -0.056Z' id='g6-48'/> +<path d='M3.522 -1.269H3.285C3.264 -1.116 3.194 -0.704 3.103 -0.635C3.048 -0.593 2.511 -0.593 2.413 -0.593H1.13C1.862 -1.241 2.106 -1.437 2.525 -1.764C3.041 -2.176 3.522 -2.608 3.522 -3.271C3.522 -4.115 2.783 -4.631 1.89 -4.631C1.025 -4.631 0.439 -4.024 0.439 -3.382C0.439 -3.027 0.739 -2.992 0.809 -2.992C0.976 -2.992 1.179 -3.11 1.179 -3.361C1.179 -3.487 1.13 -3.731 0.767 -3.731C0.983 -4.226 1.458 -4.38 1.785 -4.38C2.483 -4.38 2.845 -3.836 2.845 -3.271C2.845 -2.664 2.413 -2.183 2.19 -1.932L0.509 -0.272C0.439 -0.209 0.439 -0.195 0.439 0H3.313L3.522 -1.269Z' id='g6-50'/> +<path d='M0.159 -0.986C0.139 -0.956 0.11 -0.927 0.11 -0.887C0.11 -0.837 0.169 -0.757 0.229 -0.757C0.279 -0.757 0.309 -0.787 0.588 -1.066C0.667 -1.136 0.867 -1.325 0.946 -1.405C1.046 -0.618 1.335 0.12 2.062 0.12C2.461 0.12 2.809 -0.11 3.019 -0.259C3.158 -0.359 3.626 -0.747 3.626 -0.847C3.626 -0.877 3.597 -0.966 3.507 -0.966C3.477 -0.966 3.467 -0.956 3.377 -0.877C2.74 -0.249 2.371 -0.1 2.082 -0.1C1.634 -0.1 1.474 -0.618 1.474 -1.395C1.474 -1.455 1.494 -1.913 1.524 -1.963C1.544 -1.993 1.544 -2.012 1.743 -2.212C2.55 -3.019 3.965 -4.702 3.965 -6.247C3.965 -6.416 3.965 -7.024 3.377 -7.024C2.55 -7.024 1.813 -5.38 1.714 -5.151C1.235 -4.065 0.927 -2.899 0.927 -1.714L0.159 -0.986ZM1.574 -2.381C1.594 -2.491 2.022 -4.702 2.59 -5.868C2.859 -6.406 3.068 -6.804 3.387 -6.804C3.726 -6.804 3.726 -6.446 3.726 -6.286C3.726 -4.623 2.052 -2.879 1.574 -2.381Z' id='g3-96'/> +<path d='M0.83 -0.955C0.9 -0.502 1.13 0.084 1.723 0.084C1.946 0.084 2.197 -0.007 2.448 -0.167C2.566 -0.237 2.929 -0.495 2.929 -0.579C2.929 -0.621 2.88 -0.711 2.817 -0.711C2.783 -0.711 2.769 -0.711 2.664 -0.607C2.364 -0.342 2.043 -0.112 1.73 -0.112C1.255 -0.112 1.255 -0.928 1.255 -1.06C1.255 -1.151 1.255 -1.165 1.269 -1.297C1.276 -1.367 1.276 -1.381 1.36 -1.458C1.743 -1.82 3.062 -3.089 3.062 -4.303C3.062 -4.407 3.062 -4.91 2.601 -4.91C2.022 -4.91 1.555 -4.01 1.444 -3.801C1.137 -3.208 0.976 -2.636 0.9 -2.287C0.795 -1.82 0.795 -1.576 0.795 -1.234C0.746 -1.186 0.349 -0.83 0.279 -0.774C0.167 -0.676 0.16 -0.669 0.16 -0.628C0.16 -0.579 0.223 -0.502 0.279 -0.502C0.328 -0.502 0.516 -0.676 0.565 -0.725L0.83 -0.955ZM1.332 -1.75C1.458 -2.462 2.008 -4.714 2.594 -4.714C2.755 -4.714 2.838 -4.603 2.838 -4.352C2.838 -4.268 2.838 -3.647 2.239 -2.79C1.883 -2.287 1.499 -1.911 1.332 -1.75Z' id='g4-96'/> +<path d='M2.211 -4.561C2.211 -4.672 2.211 -4.84 2.043 -4.84C1.869 -4.84 1.869 -4.679 1.869 -4.561V0.335C1.262 -0.516 0.37 -0.656 0.335 -0.656C0.23 -0.656 0.23 -0.558 0.23 -0.488C0.23 -0.411 0.23 -0.342 0.321 -0.321C0.544 -0.258 0.969 -0.146 1.36 0.23C1.764 0.628 1.876 1.032 1.932 1.206C1.953 1.297 1.967 1.353 2.043 1.353C2.113 1.353 2.12 1.311 2.162 1.172C2.343 0.551 2.817 -0.07 3.689 -0.3C3.829 -0.335 3.85 -0.342 3.85 -0.488C3.85 -0.558 3.85 -0.656 3.745 -0.656C3.71 -0.656 2.817 -0.516 2.211 0.335V-4.561Z' id='g2-35'/> +<path d='M2.211 -3.822C2.817 -2.971 3.71 -2.831 3.745 -2.831C3.85 -2.831 3.85 -2.929 3.85 -2.999C3.85 -3.075 3.85 -3.145 3.759 -3.166C3.473 -3.243 2.497 -3.494 2.155 -4.693C2.12 -4.798 2.113 -4.84 2.043 -4.84C1.988 -4.84 1.96 -4.798 1.946 -4.756C1.862 -4.463 1.59 -3.501 0.391 -3.187C0.251 -3.152 0.23 -3.145 0.23 -2.999C0.23 -2.929 0.23 -2.831 0.335 -2.831C0.37 -2.831 1.262 -2.971 1.869 -3.822V1.074C1.869 1.186 1.869 1.353 2.036 1.353C2.211 1.353 2.211 1.193 2.211 1.074V-3.822Z' id='g2-34'/> +<path d='M4.981 -6.555C4.981 -6.884 4.951 -6.914 4.633 -6.914H0.897C0.727 -6.914 0.548 -6.914 0.548 -6.715S0.727 -6.516 0.897 -6.516H4.583V-3.656H1.036C0.867 -3.656 0.687 -3.656 0.687 -3.457S0.867 -3.258 1.036 -3.258H4.583V-0.399H0.897C0.727 -0.399 0.548 -0.399 0.548 -0.199S0.727 0 0.897 0H4.633C4.951 0 4.981 -0.03 4.981 -0.359V-6.555Z' id='g1-57'/> +<path d='M4.364 -0.06C5.908 -0.648 7.372 -2.421 7.372 -4.344C7.372 -5.948 6.316 -7.024 4.832 -7.024C2.68 -7.024 0.488 -4.762 0.488 -2.441C0.488 -0.787 1.604 0.219 3.039 0.219C3.288 0.219 3.626 0.179 4.015 0.07C3.975 0.687 3.975 0.707 3.975 0.837C3.975 1.156 3.975 1.933 4.802 1.933C5.988 1.933 6.466 0.11 6.466 0C6.466 -0.07 6.396 -0.1 6.356 -0.1C6.276 -0.1 6.257 -0.05 6.237 0.01C5.998 0.717 5.42 0.966 5.071 0.966C4.613 0.966 4.463 0.697 4.364 -0.06ZM2.481 -0.139C1.704 -0.448 1.365 -1.225 1.365 -2.122C1.365 -2.809 1.624 -4.224 2.381 -5.3C3.108 -6.316 4.045 -6.775 4.772 -6.775C5.768 -6.775 6.496 -5.998 6.496 -4.663C6.496 -3.666 5.988 -1.335 4.314 -0.399C4.264 -0.747 4.164 -1.474 3.437 -1.474C2.909 -1.474 2.421 -0.976 2.421 -0.458C2.421 -0.259 2.481 -0.149 2.481 -0.139ZM3.098 -0.03C2.959 -0.03 2.64 -0.03 2.64 -0.458C2.64 -0.857 3.019 -1.255 3.437 -1.255S4.045 -1.016 4.045 -0.408C4.045 -0.259 4.035 -0.249 3.935 -0.209C3.676 -0.1 3.377 -0.03 3.098 -0.03Z' id='g3-81'/> +<path d='M3.736 -6.117C3.796 -6.356 3.826 -6.456 4.015 -6.486C4.105 -6.496 4.423 -6.496 4.623 -6.496C5.33 -6.496 6.436 -6.496 6.436 -5.509C6.436 -5.171 6.276 -4.483 5.888 -4.095C5.629 -3.836 5.101 -3.517 4.204 -3.517H3.088L3.736 -6.117ZM5.171 -3.387C6.177 -3.606 7.362 -4.304 7.362 -5.31C7.362 -6.167 6.466 -6.804 5.161 -6.804H2.321C2.122 -6.804 2.032 -6.804 2.032 -6.605C2.032 -6.496 2.122 -6.496 2.311 -6.496C2.331 -6.496 2.521 -6.496 2.69 -6.476C2.869 -6.456 2.959 -6.446 2.959 -6.316C2.959 -6.276 2.949 -6.247 2.919 -6.127L1.584 -0.777C1.484 -0.389 1.465 -0.309 0.677 -0.309C0.498 -0.309 0.408 -0.309 0.408 -0.11C0.408 0 0.528 0 0.548 0C0.827 0 1.524 -0.03 1.803 -0.03S2.79 0 3.068 0C3.148 0 3.268 0 3.268 -0.199C3.268 -0.309 3.178 -0.309 2.989 -0.309C2.62 -0.309 2.341 -0.309 2.341 -0.488C2.341 -0.548 2.361 -0.598 2.371 -0.658L3.029 -3.298H4.214C5.121 -3.298 5.3 -2.74 5.3 -2.391C5.3 -2.242 5.22 -1.933 5.161 -1.704C5.091 -1.425 5.001 -1.056 5.001 -0.857C5.001 0.219 6.197 0.219 6.326 0.219C7.173 0.219 7.522 -0.787 7.522 -0.927C7.522 -1.046 7.412 -1.046 7.402 -1.046C7.313 -1.046 7.293 -0.976 7.273 -0.907C7.024 -0.169 6.595 0 6.366 0C6.037 0 5.968 -0.219 5.968 -0.608C5.968 -0.917 6.027 -1.425 6.067 -1.743C6.087 -1.883 6.107 -2.072 6.107 -2.212C6.107 -2.979 5.44 -3.288 5.171 -3.387Z' id='g3-82'/> +<path d='M4.842 -3.796C4.882 -3.935 4.882 -3.955 4.882 -4.025C4.882 -4.204 4.742 -4.294 4.593 -4.294C4.493 -4.294 4.334 -4.234 4.244 -4.085C4.224 -4.035 4.144 -3.726 4.105 -3.547C4.035 -3.288 3.965 -3.019 3.905 -2.75L3.457 -0.956C3.417 -0.807 2.989 -0.11 2.331 -0.11C1.823 -0.11 1.714 -0.548 1.714 -0.917C1.714 -1.375 1.883 -1.993 2.222 -2.869C2.381 -3.278 2.421 -3.387 2.421 -3.587C2.421 -4.035 2.102 -4.403 1.604 -4.403C0.658 -4.403 0.289 -2.959 0.289 -2.869C0.289 -2.77 0.389 -2.77 0.408 -2.77C0.508 -2.77 0.518 -2.79 0.568 -2.949C0.837 -3.885 1.235 -4.184 1.574 -4.184C1.654 -4.184 1.823 -4.184 1.823 -3.866C1.823 -3.616 1.724 -3.357 1.654 -3.168C1.255 -2.112 1.076 -1.544 1.076 -1.076C1.076 -0.189 1.704 0.11 2.291 0.11C2.68 0.11 3.019 -0.06 3.298 -0.339C3.168 0.179 3.049 0.667 2.65 1.196C2.391 1.534 2.012 1.823 1.554 1.823C1.415 1.823 0.966 1.793 0.797 1.405C0.956 1.405 1.086 1.405 1.225 1.285C1.325 1.196 1.425 1.066 1.425 0.877C1.425 0.568 1.156 0.528 1.056 0.528C0.827 0.528 0.498 0.687 0.498 1.176C0.498 1.674 0.936 2.042 1.554 2.042C2.58 2.042 3.606 1.136 3.885 0.01L4.842 -3.796Z' id='g3-121'/> +<path d='M1.913 -0.528C1.913 -0.817 1.674 -1.056 1.385 -1.056S0.857 -0.817 0.857 -0.528S1.096 0 1.385 0S1.913 -0.239 1.913 -0.528Z' id='g3-58'/> +</defs> +</svg> + +</body> + +</html> diff --git a/Docs/DafnyRef/out/DafnyRef.pdf b/Docs/DafnyRef/out/DafnyRef.pdf Binary files differnew file mode 100644 index 00000000..b4e94885 --- /dev/null +++ b/Docs/DafnyRef/out/DafnyRef.pdf diff --git a/Docs/DafnyRef/paper-full.bib b/Docs/DafnyRef/paper-full.bib new file mode 100644 index 00000000..c382df3b --- /dev/null +++ b/Docs/DafnyRef/paper-full.bib @@ -0,0 +1,577 @@ +@string{lncs = "Lecture Notes in Computer Science"}
+@string{lnai = "Lecture Notes in Artificial Intelligence"}
+
+@InProceedings{Dafny:LPAR16,
+ author = {K. Rustan M. Leino},
+ title = {Dafny: An Automatic Program Verifier for Functional Correctness},
+ booktitle = {LPAR-16},
+ year = {2010},
+ volume = {6355},
+ series = lncs,
+ publisher = {Springer},
+ month = apr,
+ editor = {Edmund M. Clarke and Andrei Voronkov},
+ pages = {348-370},
+}
+
+@InCollection{LeinoMoskal:UsableProgramVerification,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Usable Auto-Active Verification},
+ booktitle = {UV10 (Usable Verification) workshop},
+ year = {2010},
+ editor = {Tom Ball and Lenore Zuck and N. Shankar},
+ month = nov,
+ publisher = {\url{http://fm.csl.sri.com/UV10/}},
+}
+
+@InProceedings{Leino:VMCAI2012,
+ author = {K. Rustan M. Leino},
+ title = {Automating Induction with an {SMT} Solver},
+ booktitle = {Verification, Model Checking, and Abstract Interpretation --- 13th International Conference, VMCAI 2012},
+ pages = {315-331},
+ year = {2012},
+ editor = {Viktor Kuncak and Andrey Rybalchenko},
+ volume = {7148},
+ series = lncs,
+ month = jan,
+ publisher = {Springer},
+}
+
+@InProceedings{LeinoMonahan:Comprehensions,
+ author = {K. Rustan M. Leino and Rosemary Monahan},
+ title = {Reasoning about Comprehensions with First-Order {SMT} Solvers},
+ booktitle = {Proceedings of the 2009 ACM Symposium on Applied Computing (SAC)},
+ editor = {Sung Y. Shin and Sascha Ossowski},
+ publisher = {ACM},
+ month = mar,
+ year = 2009,
+ pages = {615-622},
+}
+
+@TechReport{VeriFast:TR,
+ author = {Bart Jacobs and Frank Piessens},
+ title = {The {VeriFast} program verifier},
+ institution = {Department of Computer Science, Katholieke Universiteit Leuven},
+ year = {2008},
+ number = {CW-520},
+ month = aug,
+}
+
+@InProceedings{LGLM:BVD,
+ author = {Le Goues, Claire and K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {The {B}oogie {V}erification {D}ebugger (Tool Paper)},
+ booktitle = {Software Engineering and Formal Methods --- 9th International Conference, SEFM 2011},
+ pages = {407-414},
+ year = {2011},
+ editor = {Gilles Barthe and Alberto Pardo and Gerardo Schneider},
+ volume = {7041},
+ series = lncs,
+ month = nov,
+ publisher = {Springer},
+}
+
+@inproceedings{Paulson:coinduction2000,
+ author = {Lawrence C. Paulson},
+ title = {A fixedpoint approach to (co)inductive and (co)datatype
+ definitions},
+ booktitle = {Proof, Language, and Interaction},
+ year = {2000},
+ pages = {187-212},
+ crossref = {DBLP:conf/birthday/1999milner},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+@proceedings{DBLP:conf/birthday/1999milner,
+ editor = {Gordon D. Plotkin and
+ Colin Stirling and
+ Mads Tofte},
+ title = {Proof, Language, and Interaction, Essays in Honour of Robin
+ Milner},
+ booktitle = {Proof, Language, and Interaction},
+ publisher = {The MIT Press},
+ year = {2000},
+ isbn = {978-0-262-16188-6},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@inproceedings{Paulson:coinduction1994,
+ author = {Lawrence C. Paulson},
+ title = {A Fixedpoint Approach to Implementing (Co)Inductive Definitions},
+ booktitle = {CADE},
+ year = {1994},
+ pages = {148-161},
+ ee = {http://dx.doi.org/10.1007/3-540-58156-1_11},
+ crossref = {DBLP:conf/cade/1994},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+@proceedings{DBLP:conf/cade/1994,
+ editor = {Alan Bundy},
+ title = {Automated Deduction - CADE-12, 12th International Conference
+ on Automated Deduction, Nancy, France, June 26 - July 1,
+ 1994, Proceedings},
+ booktitle = {CADE},
+ publisher = {Springer},
+ series = lncs,
+ volume = {814},
+ year = {1994},
+ isbn = {3-540-58156-1},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@inproceedings{Hausmann:CoCasl,
+ author = {Daniel Hausmann and
+ Till Mossakowski and
+ Lutz Schr{\"o}der},
+ title = {Iterative Circular Coinduction for {CoCasl} in {I}sabelle/{HOL}},
+ booktitle = {Fundamental Approaches to Software Engineering, 8th International
+ Conference, FASE 2005},
+ editor = {Maura Cerioli},
+ series = lncs,
+ volume = {3442},
+ publisher = {Springer},
+ year = {2005},
+ pages = {341-356},
+}
+
+@inproceedings{Rosu:CIRC,
+ author = {Dorel Lucanu and
+ Grigore Rosu},
+ title = {{CIRC}: A Circular Coinductive Prover},
+ booktitle = {CALCO},
+ year = {2007},
+ pages = {372-378},
+ ee = {http://dx.doi.org/10.1007/978-3-540-73859-6_25},
+ crossref = {DBLP:conf/calco/2007},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+@proceedings{DBLP:conf/calco/2007,
+ editor = {Till Mossakowski and
+ Ugo Montanari and
+ Magne Haveraaen},
+ title = {Algebra and Coalgebra in Computer Science, Second International
+ Conference, CALCO 2007, Bergen, Norway, August 20-24, 2007,
+ Proceedings},
+ booktitle = {CALCO},
+ publisher = {Springer},
+ series = lncs,
+ volume = {4624},
+ year = {2007},
+ isbn = {978-3-540-73857-2},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@inproceedings{Rosu:circRule,
+ author = {Grigore Rosu and
+ Dorel Lucanu},
+ title = {Circular Coinduction: A Proof Theoretical Foundation},
+ booktitle = {CALCO},
+ year = {2009},
+ pages = {127-144},
+ ee = {http://dx.doi.org/10.1007/978-3-642-03741-2_10},
+ crossref = {DBLP:conf/calco/2009},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+@proceedings{DBLP:conf/calco/2009,
+ editor = {Alexander Kurz and
+ Marina Lenisa and
+ Andrzej Tarlecki},
+ title = {Algebra and Coalgebra in Computer Science, Third International
+ Conference, CALCO 2009, Udine, Italy, September 7-10, 2009.
+ Proceedings},
+ booktitle = {CALCO},
+ publisher = {Springer},
+ series = lncs,
+ volume = {5728},
+ year = {2009},
+ isbn = {978-3-642-03740-5},
+ ee = {http://dx.doi.org/10.1007/978-3-642-03741-2},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{VCC,
+ author = {Ernie Cohen and
+ Markus Dahlweid and
+ Mark A. Hillebrand and
+ Dirk Leinenbach and
+ Micha{\l} Moskal and
+ Thomas Santen and
+ Wolfram Schulte and
+ Stephan Tobies},
+ title = {{VCC}: A Practical System for Verifying Concurrent {C}},
+ booktitle = {TPHOLs 2009},
+ series = LNCS,
+ publisher = {Springer},
+ volume = {5674},
+ year = {2009},
+ pages = {23-42},
+}
+
+@InProceedings{VeriFast:ProgramsAsProofs,
+ author = {Bart Jacobs and Jan Smans and Frank Piessens},
+ title = {{VeriFast}: Imperative Programs as Proofs},
+ booktitle = {VS-Tools workshop at VSTTE 2010},
+ year = {2010},
+ month = aug,
+}
+
+@book{DijkstraScholten:book,
+ author = "Edsger W. Dijkstra and Carel S. Scholten",
+ title = "Predicate Calculus and Program Semantics",
+ publisher = "Springer-Verlag",
+ series = "Texts and Monographs in Computer Science",
+ year = 1990
+}
+
+@Book{BirdWadler:IntroFunctionalProgramming,
+ author = {Richard Bird and Philip Wadler},
+ title = {Introduction to Functional Programming},
+ publisher = {Prentice Hall},
+ series = {International Series in Computing Science},
+ year = {1992},
+}
+
+@inproceedings{Z3,
+ author = "de Moura, Leonardo and Nikolaj Bj{\o}rner",
+ title = {{Z3}: An efficient {SMT} solver},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 14th International Conference,
+ TACAS 2008},
+ editor = {C. R. Ramakrishnan and Jakob Rehof},
+ series = lncs,
+ volume = 4963,
+ publisher = {Springer},
+ year = 2008,
+ pages = {337-340},
+}
+
+@phdthesis{moy09phd,
+ author = {Yannick Moy},
+ title = {Automatic Modular Static Safety Checking for C Programs},
+ school = {Universit{\'e} Paris-Sud},
+ year = 2009,
+ month = jan,
+ topics = {team},
+ x-equipes = {demons PROVAL},
+ x-type = {these},
+ x-support = {rapport},
+ url = {http://www.lri.fr/~marche/moy09phd.pdf}
+}
+@Book{PeytonJones:Haskell,
+ author = {Peyton Jones, Simon},
+ title = {Haskell 98 language and libraries: the Revised Report},
+ publisher = {Cambridge University Press},
+ year = {2003},
+}
+
+@InProceedings{Park:InfSeq,
+ author = {David Park},
+ title = {Concurrency and automata on infinite sequences},
+ booktitle = {Theoretical Computer Science, 5th GI-Conference},
+ editor = {Peter Deussen},
+ volume = {104},
+ series = lncs,
+ publisher = {Springer},
+ year = {1981},
+ pages = {167-183},
+}
+
+@Article{Leroy:CompCert:CACM,
+ author = {Xavier Leroy},
+ title = {Formal verification of a realistic compiler},
+ journal = cacm,
+ volume = {52},
+ number = {7},
+ month = jul,
+ year = {2009},
+ pages = {107-115},
+}
+
+@Book{KeY:book,
+ author = {Bernhard Beckert and Reiner H{\"a}hnle and Peter H. Schmitt},
+ title = {Verification of Object-Oriented Software: The {KeY} Approach},
+ volume = 4334,
+ series = lnai,
+ publisher = {Springer},
+ year = 2007,
+}
+
+@Book{Nipkow-Paulson-Menzel02,
+ author = {Tobias Nipkow and Lawrence Paulson and Markus Menzel},
+ title = {{Isabelle/HOL} --- A Proof Assistant for Higher-Order Logic},
+ publisher = {Springer},
+ year = 2002,
+ volume = 2283,
+ series = LNCS,
+}
+
+@Book{Coq:book,
+ author = {Yves Bertot and Pierre Cast{\'e}ran},
+ title = {Interactive Theorem Proving and Program Development --- {C}oq'{A}rt: The Calculus of Inductive Constructions},
+ publisher = {Springer},
+ year = {2004},
+ series = {Texts in Theoretical Computer Science},
+}
+
+@Book{ACL2:book,
+ author = {Matt Kaufmann and Panagiotis Manolios and J Strother Moore},
+ title = {Computer-Aided Reasoning: An Approach},
+ publisher = {Kluwer Academic Publishers},
+ year = {2000},
+}
+
+@Book{BoyerMoore:book,
+ author = {Robert S. Boyer and J Strother Moore},
+ title = {A Computational Logic},
+ publisher = {Academic Press},
+ series = {ACM Monograph Series},
+ year = {1979},
+}
+
+@article{Bertot:CoinductionInCoq,
+ location = {http://www.scientificcommons.org/8157029},
+ title = {CoInduction in {C}oq},
+ author = {Bertot, Yves},
+ year = {2005},
+ publisher = {HAL - CCSd - CNRS},
+ url = {http://hal.inria.fr/inria-00001174/en/},
+ institution = {CCSd/HAL : e-articles server (based on gBUS) [http://hal.ccsd.cnrs.fr/oai/oai.php] (France)},
+}
+
+@InProceedings{Coq:Coinduction,
+ author = {Eduardo Gim{\'e}nez},
+ title = {An Application of Co-inductive Types in {Coq}: Verification of the Alternating Bit Protocol},
+ booktitle = {Types for Proofs and Programs, International Workshop TYPES'95},
+ pages = {135-152},
+ year = {1996},
+ editor = {Stefano Berardi and Mario Coppo},
+ volume = 1158,
+ series = lncs,
+ publisher = {Springer},
+}
+
+@InProceedings{Boogie:Architecture,
+ author = "Mike Barnett and Bor-Yuh Evan Chang and Robert DeLine and
+ Bart Jacobs and K. Rustan M. Leino",
+ title = "{B}oogie: A Modular Reusable Verifier for Object-Oriented Programs",
+ booktitle = "Formal Methods for Components and Objects: 4th
+ International Symposium, FMCO 2005",
+ editor = "de Boer, Frank S. and Marcello M. Bonsangue and
+ Susanne Graf and de Roever, Willem-Paul",
+ series = lncs,
+ volume = 4111,
+ publisher = "Springer",
+ month = sep,
+ year = 2006,
+ pages = "364-387"
+}
+
+@InCollection{JacobsRutten:IntroductionCoalgebra,
+ author = {Bart Jacobs and Jan Rutten},
+ title = {An Introduction to (Co)Algebra and (Co)Induction},
+ booktitle = {Advanced Topics in Bisimulation and Coinduction},
+ editor = {Davide Sangiorgi and Jan Rutten},
+ series = {Cambridge Tracts in Theoretical Computer Science},
+ number = {52},
+ publisher = {Cambridge University Press},
+ month = oct,
+ year = {2011},
+ pages = {38-99},
+}
+
+@Book{Chlipala,
+ author = {Adam Chlipala},
+ title = {Certified Programming with Dependent Types},
+ publisher = {MIT Press},
+ year = {To appear},
+ note = {http://adam.chlipala.net/cpdt/}
+}
+
+@Misc{Charity,
+ author = {Robin Cockett},
+ title = {The {CHARITY} home page},
+ howpublished = {\url{http://pll.cpsc.ucalgary.ca/charity1/www/home.html}},
+ year = {1996},
+}
+
+@Article{Tarski:theorem,
+ author = "Alfred Tarski",
+ title = "A lattice-theoretical fixpoint theorem and its applications",
+ journal = "Pacific Journal of Mathematics",
+ year = 1955,
+ volume = 5,
+ pages = "285-309"
+}
+
+@InProceedings{PVS,
+ author = "Sam Owre and S. Rajan and John M. Rushby and Natarajan
+ Shankar and Mandayam K. Srivas",
+ title = "{PVS}: Combining Specification, Proof Checking, and Model
+ Checking",
+ editor = "Rajeev Alur and Thomas A. Henzinger",
+ booktitle = "Computer Aided Verification, 8th International
+ Conference, CAV '96",
+ volume = 1102,
+ series = lncs,
+ publisher = "Springer",
+ year = 1996,
+ pages = "411-414"
+}
+
+@InProceedings{SonnexEtAl:Zeno,
+ author = {William Sonnex and Sophia Drossopoulou and Susan Eisenbach},
+ title = {Zeno: An Automated Prover for Properties of Recursive
+ Data Structures},
+ booktitle = {Tools and Algorithms for the Construction and Analysis of
+ Systems --- 18th International Conference, TACAS 2012},
+ editor = {Cormac Flanagan and Barbara K{\"o}nig},
+ volume = {7214},
+ series = lncs,
+ year = {2012},
+ month = mar # "--" # apr,
+ publisher = {Springer},
+ pages = {407-421},
+}
+
+@InProceedings{JohanssonEtAl:IPT2010,
+ author = {Moa Johansson and Lucas Dixon and Alan Bundy},
+ title = {Case-Analysis for {R}ippling and Inductive Proof},
+ booktitle = {Interactive Theorem Proving, First International Conference, ITP 2010},
+ editor = {Matt Kaufmann and Lawrence C. Paulson},
+ volume = {6172},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2010},
+ pages = {291-306},
+}
+
+@book{Milner:CCS,
+ author = "Robin Milner",
+ title = {A Calculus of Communicating Systems},
+ year = {1982},
+ isbn = {0387102353},
+ publisher = {Springer-Verlag New York, Inc.},
+}
+
+@InProceedings{BoehmeNipkow:Sledgehammer,
+ author = {Sascha B{\"o}hme and Tobias Nipkow},
+ title = {Sledgehammer: {J}udgement {D}ay},
+ booktitle = {Automated Reasoning, 5th International Joint Conference, IJCAR 2010},
+ editor = {J{\"u}rgen Giesl and Reiner H{\"a}hnle},
+ year = {2010},
+ pages = {107-121},
+ volume = {6173},
+ series = lncs,
+ month = jul,
+ publisher = {Springer},
+}
+
+@PhdThesis{Norell:PhD,
+ author = {Ulf Norell},
+ title = {Towards a practical programming language based on dependent type theory},
+ school = {Department of Computer Science and Engineering, Chalmers
+ University of Technology},
+ year = {2007},
+ month = sep,
+}
+
+@Article{Paulson:MechanizingCoRecursion,
+ author = {Lawrence C. Paulson},
+ title = {Mechanizing Coinduction and Corecursion in Higher-order Logic},
+ journal = {Journal of Logic and Computation},
+ year = {1997},
+ volume = {7},
+}
+
+@InProceedings{Bertot:sieve,
+ author = {Yves Bertot},
+ title = {Filters on CoInductive Streams, an Application to {E}ratosthenes' Sieve},
+ booktitle = {Typed Lambda Calculi and Applications, 7th International Conference,
+ TLCA 2005},
+ editor = {Pawel Urzyczyn},
+ series = lncs,
+ volume = {3461},
+ month = apr,
+ year = {2005},
+ pages = {102-115},
+ publisher = {Springer},
+}
+
+@Misc{AltenkirchDanielsson:QuantifierInversion,
+ author = {Thorsten Altenkirch and Nils Anders Danielsson},
+ title = {Termination Checking in the Presence of Nested Inductive and Coinductive Types},
+ howpublished = {Short note supporting a talk given at PAR 2010, Workshop on Partiality and Recursion in Interactive Theorem Provers},
+ year = {2010},
+ note = {Available from \url{http://www.cse.chalmers.se/~nad/publications/}.},
+}
+
+@InProceedings{HurEtAl:Paco,
+ author = {Hur, Chung-Kil and Neis, Georg and Dreyer, Derek and Vafeiadis, Viktor},
+ title = {The power of parameterization in coinductive proof},
+ booktitle = {Proceedings of the 40th Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL '13},
+ editor = {Roberto Giacobazzi and Radhia Cousot},
+ pages = {193--206},
+ month = jan,
+ year = {2013},
+ publisher = {ACM},
+}
+
+@InProceedings{BoveDybjerNorell:BriefAgda,
+ author = {Ana Bove and Peter Dybjer and Ulf Norell},
+ title = {A Brief Overview of {A}gda --- A Functional Language with Dependent Types},
+ booktitle = {Theorem Proving in Higher Order Logics, 22nd International Conference, TPHOLs 2009},
+ editor = {Stefan Berghofer and Tobias Nipkow and Christian Urban and Makarius Wenzel},
+ series = lncs,
+ volume = {5674},
+ publisher = {Springer},
+ month = aug,
+ year = {2009},
+ pages = {73-78},
+}
+
+@Article{Moore:Piton,
+ author = {J Strother Moore},
+ title = {A Mechanically Verified Language Implementation},
+ journal = {Journal of Automated Reasoning},
+ year = {1989},
+ volume = {5},
+ number = {4},
+ pages = {461-492},
+}
+
+@InProceedings{Leroy:ESOP2006,
+ author = {Xavier Leroy},
+ title = {Coinductive Big-Step Operational Semantics},
+ booktitle = {Programming Languages and Systems, 15th European Symposium on Programming, ESOP 2006},
+ pages = {54-68},
+ year = {2006},
+ editor = {Peter Sestoft},
+ volume = {3924},
+ series = lncs,
+ month = mar,
+ publisher = {Springer},
+}
+
+@InProceedings{Leino:ITP2013,
+ author = {K. Rustan M. Leino},
+ title = {Automating Theorem Proving with {SMT}},
+ booktitle = {Interactive Theorem Proving --- 4th International Conference, ITP 2013},
+ year = {2013},
+ editor = {Sandrine Blazy and Christine Paulin-Mohring and David Pichardie},
+ volume = {7998},
+ series = lncs,
+ pages = {2-16},
+ month = jul,
+ publisher = {Springer},
+}
+
+@TechReport{TR-version,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Co-induction Simply: Automatic Co-inductive Proofs in a Program Verifier},
+ institution = {Microsoft Research},
+ year = {2013},
+ number = {MSR-TR-2013-49},
+ month = may,
+}
diff --git a/Docs/DafnyRef/poc.bib b/Docs/DafnyRef/poc.bib new file mode 100644 index 00000000..a0f1ed79 --- /dev/null +++ b/Docs/DafnyRef/poc.bib @@ -0,0 +1,523 @@ +@string{lncs = "LNCS"}
+@string{lnai = "LNAI"}
+
+@InCollection{LeinoMoskal:UsableProgramVerification,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Usable Auto-Active Verification},
+ booktitle = {Usable Verification workshop},
+ year = {2010},
+ editor = {Tom Ball and Lenore Zuck and N. Shankar},
+ publisher = {\url{http://fm.csl.sri.com/UV10/}},
+}
+ booktitle = {UV10 (Usable Verification) workshop},
+ month = nov,
+
+@Book{Coq:book,
+ author = {Yves Bertot and Pierre Cast{\'e}ran},
+ title = {Interactive Theorem Proving and Program Development --- {C}oq'{A}rt: The Calculus of Inductive Constructions},
+ publisher = {Springer},
+ year = {2004},
+}
+ series = {Texts in Theoretical Computer Science},
+
+@Manual{Isabelle:Guide,
+ title = {Programming and Proving in {I}sabelle/{HOL}},
+ author = {Tobias Nipkow},
+ organization = {\url{http://isabelle.informatik.tu-muenchen.de/}},
+ year = {2012},
+}
+ month = may,
+
+@InProceedings{Leino:Dafny:LPAR16,
+ author = {K. Rustan M. Leino},
+ title = {Dafny: An Automatic Program Verifier for Functional Correctness},
+ booktitle = {LPAR-16},
+ year = {2010},
+ volume = {6355},
+ series = lncs,
+ publisher = {Springer},
+ pages = {348-370},
+}
+ editor = {Edmund M. Clarke and Andrei Voronkov},
+ month = apr,
+
+@InProceedings{VCC:TPHOLs,
+ author = {Ernie Cohen and Markus Dahlweid and Mark
+ A. Hillebrand and Dirk Leinenbach and Micha{\l}
+ Moskal and Thomas Santen and Wolfram Schulte and
+ Stephan Tobies},
+ title = {{VCC}: A Practical System for Verifying Concurrent {C}},
+ booktitle = {TPHOLs 2009},
+ volume = {5674},
+ series = lncs,
+ publisher = {Springer},
+ year = {2009},
+ pages = {23-42},
+}
+ booktitle = {Theorem Proving in Higher Order Logics, 22nd International Conference, TPHOLs 2009},
+ editor = {Stefan Berghofer and Tobias Nipkow and Christian
+ Urban and Makarius Wenzel},
+ month = aug,
+
+@TechReport{VeriFast:TR,
+ author = {Bart Jacobs and Frank Piessens},
+ title = {The {VeriFast} program verifier},
+ institution = {Department of Computer Science, Katholieke Universiteit Leuven},
+ year = {2008},
+ number = {CW-520},
+}
+ month = aug,
+
+@InProceedings{VeriFast:ProgramsAsProofs,
+ author = {Bart Jacobs and Jan Smans and Frank Piessens},
+ title = {{VeriFast}: Imperative Programs as Proofs},
+ booktitle = {VS-Tools workshop at VSTTE 2010},
+ year = {2010},
+}
+ month = aug,
+
+@Article{IPL:vol53:3,
+ author = {Roland Backhouse},
+ title = {Special issue on The Calculational Method},
+ journal = {Information Processing Letters},
+ year = {1995},
+ volume = {53},
+ number = {3},
+ pages = {121-172},
+}
+ month = feb,
+
+@InProceedings{VonWright:ExtendingWindowInference,
+ author = {von Wright, Joakim},
+ title = {Extending Window Inference},
+ booktitle = {TPHOLs'98},
+ pages = {17-32},
+ year = {1998},
+ volume = {1479},
+ series = lncs,
+ publisher = {Springer},
+}
+ booktitle = {Theorem Proving in Higher Order Logics, 11th International Conference, TPHOLs'98},
+ editor = {Jim Grundy and Malcolm C. Newey},
+
+@PhdThesis{Wenzel:PhD,
+ author = {Markus Wenzel},
+ title = {{I}sabelle/{I}sar --- a versatile environment for human-readable formal proof documents},
+ school = {Institut f{\"u}r Informatik, Technische Universit{\"a}t M{\"u}nchen},
+ year = {2002},
+}
+
+@InProceedings{BauerWenzel:IsarExperience,
+ author = {Gertrud Bauer and Markus Wenzel},
+ title = {Calculational reasoning revisited: an {I}sabelle/{I}sar experience},
+ booktitle = {TPHOLs 2001},
+ pages = {75-90},
+ year = {2001},
+ volume = {2152},
+ series = lncs,
+ publisher = {Springer},
+}
+ booktitle = {Theorem Proving in Higher Order Logics, 14th International Conference, TPHOLs 2001},
+ editor = {Richard J. Boulton and Paul B. Jackson},
+ month = sep,
+
+@InCollection{KoenigLeino:MOD2011,
+ author = {Jason Koenig and K. Rustan M. Leino},
+ title = {Getting Started with {D}afny: A Guide},
+ booktitle = {Software Safety and Security: Tools for Analysis and Verification},
+ pages = {152-181},
+ publisher = {IOS Press},
+ year = {2012},
+}
+ volume = {33},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ editor = {Tobias Nipkow and Orna Grumberg and Benedikt Hauptmann},
+ note = {Summer School Marktoberdorf 2011 lecture notes},
+
+@InProceedings{Leino:induction,
+ author = {K. Rustan M. Leino},
+ title = {Automating Induction with an {SMT} Solver},
+ booktitle = {VMCAI 2012},
+ pages = {315-331},
+ year = {2012},
+ volume = {7148},
+ series = lncs,
+ publisher = {Springer},
+}
+ booktitle = {Verification, Model Checking, and Abstract Interpretation - 13th International Conference, VMCAI 2012},
+ editor = {Viktor Kuncak and Andrey Rybalchenko},
+ month = jan,
+
+@article{Hoare:AxiomaticBasis,
+ author = "C. A. R. Hoare",
+ title = "An axiomatic basis for computer programming",
+ journal = cacm,
+ volume = 12,
+ number = 10,
+ year = 1969,
+ pages = "576--580,583"
+}
+ month = oct,
+
+@Article{Simplify:tome,
+ author = "David Detlefs and Greg Nelson and James B. Saxe",
+ title = "Simplify: a theorem prover for program checking",
+ journal = JACM,
+ volume = 52,
+ number = 3,
+ year = 2005,
+ pages = "365-473",
+}
+ month = may,
+
+@techreport{Nelson:thesis,
+ author = "Charles Gregory Nelson",
+ title = "Techniques for Program Verification",
+ institution = "Xerox PARC",
+ year = 1981,
+ number = "CSL-81-10",
+ note = "PhD thesis, Stanford University"
+}
+ month = jun,
+
+@inproceedings{deMouraBjorner:Z3:overview,
+ author = "de Moura, Leonardo and Nikolaj Bj{\o}rner",
+ title = {{Z3}: An efficient {SMT} solver},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 14th International Conference,
+ TACAS 2008},
+ series = lncs,
+ volume = 4963,
+ publisher = {Springer},
+ year = 2008,
+ pages = {337-340},
+}
+ editor = {C. R. Ramakrishnan and Jakob Rehof},
+ month = mar # "--" # apr,
+
+@InProceedings{LGLM:BVD,
+ author = {Le Goues, Claire and K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {The {B}oogie {V}erification {D}ebugger (Tool Paper)},
+ booktitle = {Software Engineering and Formal Methods - 9th International Conference, SEFM 2011},
+ pages = {407-414},
+ year = {2011},
+ volume = {7041},
+ series = lncs,
+ publisher = {Springer},
+}
+ editor = {Gilles Barthe and Alberto Pardo and Gerardo Schneider},
+ month = nov,
+
+@InProceedings{HipSpec:WING,
+ author = {Koen Claessen and Moa Johansson and Dan Ros{\'e}n and Nicholas Smallbone},
+ title = {{HipSpec}: Automating Inductive Proofs of Program Properties},
+ booktitle = {Workshop on {A}utomated {T}heory e{X}ploration: {ATX} 2012},
+ year = {2012},
+}
+ month = jul,
+
+@InProceedings{HipSpec:CADE,
+ author = {Koen Claessen and Moa Johansson and Dan Ros{\'e}n and Nicholas Smallbone},
+ title = {Automating Inductive Proofs Using Theory Exploration},
+ booktitle = {CADE-24},
+ pages = {392-406},
+ year = {2013},
+ volume = {7898},
+ series = lncs,
+ publisher = {Springer},
+}
+ booktitle = {Automated Deduction --- CADE-24 --- 24th International Conference on Automated Deduction},
+ editor = {Maria Paola Bonacina},
+ month = jun,
+
+@article{ManoliosMoore:Calc,
+ author = {Panagiotis Manolios and J. Strother Moore},
+ title = {On the desirability of mechanizing calculational proofs},
+ journal = {Inf. Process. Lett.},
+ volume = {77},
+ number = {2-4},
+ year = {2001},
+ pages = {173-179},
+ ee = {http://dx.doi.org/10.1016/S0020-0190(00)00200-3},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{Lifschitz:DS,
+ title={On Calculational Proofs},
+ author={Vladimir Lifschitz},
+ volume={113},
+ journal={Annals of Pure and Applied Logic},
+ pages={207-224},
+ url="http://www.cs.utexas.edu/users/ai-lab/pub-view.php?PubID=26805",
+ year={2002}
+}
+
+@article{BackGrundyWright:SCP,
+ author = {Ralph Back and Jim Grundy and Joakim von Wright},
+ title = {Structured Calculational Proof},
+ journal = {Formal Aspects of Computing},
+ year = {1997},
+ volume = {9},
+ number = {5--6},
+ pages = {469--483}
+}
+
+@article{Back:SD,
+ author = {Back, Ralph-Johan},
+ title = {Structured derivations: a unified proof style for teaching mathematics},
+ journal = {Formal Aspects of Computing},
+ issue_date = {September 2010},
+ volume = {22},
+ number = {5},
+ year = {2010},
+ issn = {0934-5043},
+ pages = {629--661},
+ numpages = {33},
+ url = {http://dx.doi.org/10.1007/s00165-009-0136-5},
+ doi = {10.1007/s00165-009-0136-5},
+ acmid = {1858559},
+ publisher = {Springer},
+}
+ month = sep,
+
+@article{Dijkstra:EWD1300,
+ author = {Edsger W. Dijkstra},
+ title = {{EWD1300}: The Notational Conventions {I} Adopted, and Why},
+ journal = {Formal Asp. Comput.},
+ volume = {14},
+ number = {2},
+ year = {2002},
+ pages = {99-107},
+ ee = {http://dx.doi.org/10.1007/s001650200030},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{BCDJL05:Boogie,
+ author = {Michael Barnett and
+ Bor-Yuh Evan Chang and
+ Robert DeLine and
+ Bart Jacobs and
+ K. Rustan M. Leino},
+ title = {Boogie: A Modular Reusable Verifier for Object-Oriented
+ Programs},
+ booktitle = {FMCO 2005},
+ series = lncs,
+ volume = 4111,
+ publisher = "Springer",
+ year = {2006},
+ pages = {364-387},
+}
+ month = sep,
+
+@article{BVW:Mathpad,
+ author = {Roland Backhouse and
+ Richard Verhoeven and
+ Olaf Weber},
+ title = {Math{$\!\!\int\!\!$}pad: A System for On-Line Preparation of Mathematical
+ Documents},
+ journal = {Software --- Concepts and Tools},
+ volume = {18},
+ number = {2},
+ year = {1997},
+ pages = {80-},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{VB:MathpadPVS,
+ author = {Richard Verhoeven and
+ Roland Backhouse},
+ title = {Interfacing Program Construction and Verification},
+ booktitle = {World Congress on Formal Methods},
+ year = {1999},
+ pages = {1128-1146},
+ ee = {http://dx.doi.org/10.1007/3-540-48118-4_10},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{Corbineau:CoqDecl,
+ author = {Pierre Corbineau},
+ title = {A Declarative Language for the {Coq} Proof Assistant},
+ booktitle = {TYPES},
+ year = {2007},
+ pages = {69-84},
+ ee = {http://dx.doi.org/10.1007/978-3-540-68103-8_5},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{Wiedijk:Sketches,
+ author = {Freek Wiedijk},
+ title = {Formal Proof Sketches},
+ booktitle = {TYPES},
+ year = {2003},
+ pages = {378-393},
+ ee = {http://dx.doi.org/10.1007/978-3-540-24849-1_24},
+ crossref = {DBLP:conf/types/2003},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@book{DijkstraScholten:Book,
+ author = {Edsger W. Dijkstra and
+ Carel S. Scholten},
+ title = {Predicate calculus and program semantics},
+ publisher = {Springer},
+ series = {Texts and monographs in computer science},
+ year = {1990},
+ isbn = {978-3-540-96957-0},
+ pages = {I-X, 1-220},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{Rudnicki:Mizar,
+ author = {Piotr Rudnicki},
+ title = {An Overview of the {MIZAR} Project},
+ booktitle = {University of Technology, Bastad},
+ year = {1992},
+ pages = {311--332},
+ publisher = {}
+}
+
+@inproceedings{ORS:PVS,
+ AUTHOR = {S. Owre and J. M. Rushby and N. Shankar},
+ TITLE = {{PVS:} {A} Prototype Verification System},
+ BOOKTITLE = {CADE-11},
+ YEAR = {1992},
+ SERIES = lnai,
+ VOLUME = {607},
+ PAGES = {748--752},
+ PUBLISHER = {Springer},
+ URL = {http://www.csl.sri.com/papers/cade92-pvs/}
+}
+ BOOKTITLE = {11th International Conference on Automated Deduction (CADE)},
+ EDITOR = {Deepak Kapur},
+
+@article{Robinson:Window,
+ author = {Peter J. Robinson and
+ John Staples},
+ title = {Formalizing a Hierarchical Structure of Practical Mathematical
+ Reasoning},
+ journal = {J. Log. Comput.},
+ volume = {3},
+ number = {1},
+ year = {1993},
+ pages = {47-61},
+ ee = {http://dx.doi.org/10.1093/logcom/3.1.47},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{Grundy:WindowHOL,
+ author = {Jim Grundy},
+ title = {Transformational Hierarchical Reasoning},
+ journal = {Comput. J.},
+ volume = {39},
+ number = {4},
+ year = {1996},
+ pages = {291-302},
+ ee = {http://dx.doi.org/10.1093/comjnl/39.4.291},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{BN:Sledgehammer,
+ author = {Sascha B{\"o}hme and
+ Tobias Nipkow},
+ title = {Sledgehammer: Judgement Day},
+ booktitle = {IJCAR},
+ year = {2010},
+ pages = {107-121},
+ ee = {http://dx.doi.org/10.1007/978-3-642-14203-1_9},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{Armand:CoqSMT,
+ author = {Micha{\"e}l Armand and
+ Germain Faure and
+ Benjamin Gr{\'e}goire and
+ Chantal Keller and
+ Laurent Th{\'e}ry and
+ Benjamin Werner},
+ title = {A Modular Integration of {SAT}/{SMT} Solvers to {Coq} through
+ Proof Witnesses},
+ booktitle = {CPP},
+ year = {2011},
+ pages = {135-150},
+ ee = {http://dx.doi.org/10.1007/978-3-642-25379-9_12},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{Besson:CoqSMTReflexive,
+ author = {Fr{\'e}d{\'e}ric Besson and
+ Pierre-Emmanuel Cornilleau and
+ David Pichardie},
+ title = {Modular SMT Proofs for Fast Reflexive Checking Inside Coq},
+ booktitle = {CPP},
+ year = {2011},
+ pages = {151-166},
+ ee = {http://dx.doi.org/10.1007/978-3-642-25379-9_13},
+ crossref = {DBLP:conf/cpp/2011},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@Book{ACL2:book,
+ author = {Matt Kaufmann and Panagiotis Manolios and J Strother Moore},
+ title = {Computer-Aided Reasoning: An Approach},
+ publisher = {Kluwer Academic Publishers},
+ year = {2000},
+}
+
+@inproceedings{boogie11why3,
+ author = {Fran\c{c}ois Bobot and Jean-Christophe Filli\^atre and Claude March\'e and Andrei Paskevich},
+ title = {{Why3}: Shepherd Your Herd of Provers},
+ booktitle = {BOOGIE 2011: Workshop on Intermediate Verification Languages},
+ year = 2011,
+ pages = {53--64},
+ url = {http://proval.lri.fr/publications/boogie11final.pdf},
+}
+ booktitle = {BOOGIE 2011: First International Workshop on Intermediate Verification Languages},
+ month = aug,
+
+@InProceedings{zeno,
+ author = {William Sonnex and Sophia Drossopoulou and Susan Eisenbach},
+ title = {Zeno: An Automated Prover for Properties of Recursive
+ Data Structures},
+ booktitle = {TACAS},
+ volume = {7214},
+ series = lncs,
+ year = {2012},
+ publisher = {Springer},
+ pages = {407-421},
+}
+ booktitle = {Tools and Algorithms for the Construction and Analysis of
+ Systems --- 18th International Conference, TACAS 2012},
+ editor = {Cormac Flanagan and Barbara K{\"o}nig},
+ month = mar # "--" # apr,
+
+@InProceedings{Chisholm:CalculationByComputer,
+ author = {P. Chisholm},
+ title = {Calculation by computer},
+ booktitle = {Third International Workshop on Software Engineering and its Applications},
+ address = {Toulouse, France},
+ year = {1990},
+ month = dec,
+ pages = {713-728},
+}
+
+@TechReport{VanDeSnepscheut:Proxac,
+ author = {van de Snepscheut, Jan L. A.},
+ title = {Proxac: an editor for program transformation},
+ institution = {Caltech},
+ year = {1993},
+ number = {CS-TR-93-33},
+}
+
+@InProceedings{VanGasterenBijlsma:CalcExtension,
+ author = {A. J. M. van Gasteren and A. Bijlsma},
+ title = {An extension of the program derivation format},
+ booktitle = {PROCOMET '98},
+ pages = {167-185},
+ year = {1998},
+ publisher = {IFIP Conference Proceedings},
+}
+ booktitle = {Programming Concepts and Methods, IFIP TC2/WG2.2,2.3 International Conference on
+ Programming Concepts and Methods (PROCOMET '98)},
+ editor = {David Gries and Willem P. de Roever},
+ month = jun,
+
diff --git a/Docs/DafnyRef/references.bib b/Docs/DafnyRef/references.bib new file mode 100644 index 00000000..880d8446 --- /dev/null +++ b/Docs/DafnyRef/references.bib @@ -0,0 +1,1446 @@ +@InCollection{Leino:Dafny:MOD2008,
+ author = {K. Rustan M. Leino},
+ title = {Specification and verification of object-oriented software},
+ booktitle = {Engineering Methods and Tools for Software Safety and Security},
+ pages = {231-266},
+ publisher = {IOS Press},
+ year = {2009},
+ editor = {Manfred Broy and Wassiou Sitou and Tony Hoare},
+ volume = {22},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ note = {Summer School Marktoberdorf 2008 lecture notes},
+}
+
+@InCollection{LeinoSchulte:MOD2006,
+ author = {K. Rustan M. Leino and Wolfram Schulte},
+ title = {A verifying compiler for a multi-threaded object-oriented language},
+ booktitle = {Software Safety and Security},
+ pages = {351-416},
+ publisher = {IOS Press},
+ year = {2007},
+ editor = {Manfred Broy and Johannes Gr{\"u}nbauer and Tony Hoare},
+ volume = {9},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ note = {Summer School Marktoberdorf 2006 lecture notes},
+}
+
+@techreport{ESC:rr,
+ author = "David L. Detlefs and K. Rustan M. Leino and Greg Nelson
+ and James B. Saxe",
+ title = "Extended static checking",
+ institution = "Compaq Systems Research Center",
+ month = dec,
+ year = 1998,
+ type = "Research Report",
+ number = 159
+}
+
+@Article{Simplify:tome,
+ author = "David Detlefs and Greg Nelson and James B. Saxe",
+ title = "Simplify: a theorem prover for program checking",
+ journal = JACM,
+ volume = 52,
+ number = 3,
+ month = may,
+ year = 2005,
+ pages = "365-473",
+}
+
+@InProceedings{Doomed:FM2009,
+ author = {Jochen Hoenicke and K. Rustan M. Leino and Andreas
+ Podelski and Martin Sch{\"a}f and Thomas Wies},
+ title = {It's Doomed; We Can Prove It},
+ booktitle = {FM 2009: Formal Methods, Second World Congress},
+ editor = {Ana Cavalcanti and Dennis Dams},
+ volume = 5850,
+ series = lncs,
+ publisher = {Springer},
+ month = nov,
+ year = 2009,
+ pages = {338-353},
+}
+
+@InProceedings{Regis-Gianas:Pottier:MPC2008,
+ author = {Yann R{\'e}gis-Gianas and Fran{\c{c}}ois Pottier},
+ title = {A {Hoare} Logic for Call-by-Value Functional Programs},
+ booktitle = {Mathematics of Program Construction, 9th International Conference},
+ editor = {Philippe Audebaud and Christine Paulin-Mohring},
+ volume = {5133},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2008},
+ pages = {305-335},
+}
+
+@InProceedings{ZeeKuncakRinard:PLDI2008,
+ author = {Karen Zee and Viktor Kuncak and Martin C. Rinard},
+ title = {Full functional verification of linked data structures},
+ booktitle = {Proceedings of the ACM SIGPLAN 2008 Conference on
+ Programming Language Design and Implementation},
+ editor = {Rajiv Gupta and Saman P. Amarasinghe},
+ year = {2008},
+ month = jun,
+ publisher = {ACM},
+ pages = {349-361},
+}
+
+@InProceedings{VCC:TPHOLs,
+ author = {Ernie Cohen and Markus Dahlweid and Mark
+ A. Hillebrand and Dirk Leinenbach and Micha{\l}
+ Moskal and Thomas Santen and Wolfram Schulte and
+ Stephan Tobies},
+ title = {{VCC}: A Practical System for Verifying Concurrent {C}},
+ booktitle = {Theorem Proving in Higher Order Logics, 22nd
+ International Conference, TPHOLs 2009},
+ editor = {Stefan Berghofer and Tobias Nipkow and Christian
+ Urban and Makarius Wenzel},
+ volume = {5674},
+ series = lncs,
+ publisher = {Springer},
+ year = {2009},
+ month = aug,
+ pages = {23-42},
+}
+
+@InProceedings{seL4:SOSP2009,
+ author = {Gerwin Klein and Kevin Elphinstone and Gernot Heiser
+ and June Andronick and David Cock and Philip Derrin
+ and Dhammika Elkaduwe and Kai Engelhardt and Rafal
+ Kolanski and Michael Norrish and Thomas Sewell and
+ Harvey Tuch and Simon Winwood},
+ title = {{seL4}: formal verification of an {OS} kernel},
+ booktitle = {Proceedings of the 22nd ACM Symposium on Operating
+ Systems Principles 2009, SOSP 2009},
+ editor = {Jeanna Neefe Matthews and Thomas E. Anderson},
+ publisher = {ACM},
+ month = oct,
+ year = {2009},
+ pages = {207-220},
+}
+
+@book{Meyer:OOP,
+ author = "Bertrand Meyer",
+ title = "Object-oriented Software Construction",
+ publisher = "Prentice-Hall International",
+ series = "Series in Computer Science",
+ year = 1988
+}
+
+@InProceedings{SpecSharp:Overview,
+ author = {Mike Barnett and K. Rustan M. Leino and Wolfram Schulte},
+ title = {The {Spec\#} Programming System: An Overview},
+ booktitle = {{CASSIS 2004}, Construction and Analysis of Safe,
+ Secure and Interoperable Smart devices},
+ editor = "Gilles Barthe and Lilian Burdy and Marieke Huisman and
+ Jean-Louis Lanet and Traian Muntean",
+ series = lncs,
+ volume = 3362,
+ publisher = "Springer",
+ year = 2005,
+ pages = "49-69"
+}
+
+@InProceedings{Kassios:FM2006,
+ author = "Ioannis T. Kassios",
+ title = "Dynamic Frames: Support for Framing, Dependencies and Sharing Without Restrictions",
+ booktitle = "FM 2006: Formal Methods, 14th International Symposium on Formal Methods",
+ editor = "Jayadev Misra and Tobias Nipkow and Emil Sekerinski",
+ series = lncs,
+ volume = 4085,
+ publisher = "Springer",
+ month = aug,
+ year = 2006,
+ pages = "268-283",
+}
+
+@InProceedings{Boogie:Architecture,
+ author = "Mike Barnett and Bor-Yuh Evan Chang and Robert DeLine and
+ Bart Jacobs and K. Rustan M. Leino",
+ title = "{B}oogie: A Modular Reusable Verifier for Object-Oriented Programs",
+ booktitle = "Formal Methods for Components and Objects: 4th
+ International Symposium, FMCO 2005",
+ editor = "de Boer, Frank S. and Marcello M. Bonsangue and
+ Susanne Graf and de Roever, Willem-Paul",
+ series = lncs,
+ volume = 4111,
+ publisher = "Springer",
+ month = sep,
+ year = 2006,
+ pages = "364-387"
+}
+
+@Misc{Leino:Boogie2-RefMan,
+ author = {K. Rustan M. Leino},
+ title = {This is {B}oogie 2},
+ howpublished = {Manuscript KRML 178},
+ year = 2008,
+ note = "Available at \url{http://research.microsoft.com/~leino/papers.html}",
+}
+
+@inproceedings{deMouraBjorner:Z3:overview,
+ author = "de Moura, Leonardo and Nikolaj Bj{\o}rner",
+ title = {{Z3}: An efficient {SMT} solver},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 14th International Conference,
+ TACAS 2008},
+ editor = {C. R. Ramakrishnan and Jakob Rehof},
+ series = lncs,
+ volume = 4963,
+ publisher = {Springer},
+ month = mar # "--" # apr,
+ year = 2008,
+ pages = {337-340},
+}
+
+@InProceedings{Gonthier:CAV2006,
+ author = {Georges Gonthier},
+ title = {Verifying the safety of a practical concurrent
+ garbage collector},
+ booktitle = {Computer Aided Verification, 8th International Conference, CAV '96},
+ editor = {Rajeev Alur and Thomas A. Henzinger},
+ volume = {1102},
+ series = lncs,
+ publisher = {Springer},
+ month = jul # "--" # aug,
+ year = {1996},
+ pages = {462-465},
+}
+
+@Article{CLIncStack,
+ author = {William R. Bevier and Hunt, Jr., Warren A. and
+ J Strother Moore and William D. Young},
+ title = {Special issue on system verification},
+ journal = {Journal of Automated Reasoning},
+ volume = {5},
+ number = {4},
+ month = dec,
+ year = {1989},
+ pages = {409-530},
+}
+
+@InProceedings{ParkinsonBierman:POPL2005,
+ author = {Matthew J. Parkinson and Gavin M. Bierman},
+ title = {Separation logic and abstraction},
+ booktitle = {Proceedings of the 32nd ACM SIGPLAN-SIGACT Symposium
+ on Principles of Programming Languages, POPL 2005},
+ publisher = {ACM},
+ month = jan,
+ year = {2005},
+ pages = {247-258},
+}
+
+@InProceedings{Weide:VSTTE2008,
+ author = {Bruce W. Weide and Murali Sitaraman and Heather
+ K. Harton and Bruce Adcock and Paolo Bucci and
+ Derek Bronish and Wayne D. Heym and Jason
+ Kirschenbaum and David Frazier},
+ title = {Incremental Benchmarks for Software Verification Tools and Techniques},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ Second International Conference, VSTTE 2008},
+ editor = {Natarajan Shankar and Jim Woodcock},
+ volume = {5295},
+ series = lncs,
+ publisher = {Springer},
+ month = oct,
+ year = {2008},
+ pages = {84-98},
+}
+
+@Article{SchorrWaite:CACM1967,
+ author = {H. Schorr and W. M. Waite},
+ title = {An Efficient Machine-Independent Procedure for
+ Garbage Collection in Various List Structures},
+ journal = cacm,
+ volume = {10},
+ number = {8},
+ month = aug,
+ year = {1967},
+ pages = {501-506},
+}
+
+@phdthesis{Leino:thesis,
+ author = "K. Rustan M. Leino",
+ title = "Toward Reliable Modular Programs",
+ school = {California Institute of Technology},
+ year = 1995,
+ note = "Technical Report Caltech-CS-TR-95-03."
+}
+
+@inproceedings{Boyland:SAS2003,
+ author = {John Boyland},
+ title = {Checking Interference with Fractional Permissions},
+ booktitle = "Static Analysis, 10th International Symposium, SAS 2003",
+ editor = {Radhia Cousot},
+ series = lncs,
+ volume = 2694,
+ publisher = "Springer",
+ year = 2003,
+ pages = {55-72}
+}
+
+@InProceedings{Reynolds:SepLogic,
+ author = {John C. Reynolds},
+ title = {Separation Logic: A Logic for Shared Mutable Data Structures},
+ booktitle = {17th IEEE Symposium on Logic in Computer Science (LICS 2002)},
+ publisher = {IEEE Computer Society},
+ year = {2002},
+ month = jul,
+ pages = {55-74},
+}
+
+@InProceedings{Clarke-Drossopoulou02,
+ author = {Dave Clarke and Sophia Drossopoulou},
+ title = {Ownership, encapsulation and the disjointness of
+ type and effect},
+ booktitle = {Proceedings of the 2002 ACM SIGPLAN Conference on
+ Object-Oriented Programming Systems, Languages and
+ Applications, OOPSLA 2002},
+ publisher = {ACM},
+ Month = nov,
+ Year = 2002,
+ pages = {292--310},
+}
+
+@InProceedings{FAP:OOPSLA1998,
+ author = {Dave Clarke and John Potter and James Noble},
+ title = {Ownership Types for Flexible Alias Protection},
+ booktitle = {Proceedings of the 1998 ACM SIGPLAN Conference on
+ Object-Oriented Programming Systems, Languages \&
+ Applications (OOPSLA '98)},
+ publisher = {ACM},
+ month = oct,
+ year = {1998},
+ pages = {48-64},
+}
+
+@Article{LeinoNelson:tome,
+ author = "K. Rustan M. Leino and Greg Nelson",
+ title = "Data abstraction and information hiding",
+ journal = toplas,
+ month = sep,
+ year = 2002,
+ volume = 24,
+ number = 5,
+ pages = "491-553"
+}
+
+@PhdThesis{Darvas:thesis,
+ author = {{\'A}d{\'a}m P{\'e}ter Darvas},
+ title = {Reasoning About Data Abstraction in Contract Languages},
+ school = {ETH Zurich},
+ year = {2009},
+ note = {Diss. ETH No. 18622},
+}
+
+@InProceedings{SmansEtAl:VeriCool,
+ author = {Jan Smans and Bart Jacobs and Frank Piessens and Wolfram Schulte},
+ title = {Automatic Verifier for {J}ava-Like Programs Based on Dynamic Frames},
+ booktitle = {Fundamental Approaches to Software Engineering, 11th
+ International Conference, FASE 2008},
+ editor = {Jos{\'e} Luiz Fiadeiro and Paola Inverardi},
+ volume = {4961},
+ series = lncs,
+ publisher = {Springer},
+ month = mar # "--" # apr,
+ year = {2008},
+ pages = {261-275},
+}
+
+@inproceedings{Why:Platform,
+ author = {Jean-Christophe Filli{\^a}tre and Claude March{\'e}},
+ title = {The {Why}/{Krakatoa}/{Caduceus} Platform for Deductive Program Verification},
+ booktitle = {Computer Aided Verification, 19th International Conference, CAV 2007},
+ editor = {Werner Damm and Holger Hermanns},
+ volume = {4590},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2007},
+ pages = {173--177}
+}
+
+@InProceedings{BarrettTinelli:CVC3,
+ author = {Clark Barrett and Cesare Tinelli},
+ title = {{CVC3}},
+ booktitle = {Computer Aided Verification, 19th International Conference, CAV 2007},
+ editor = {Werner Damm and Holger Hermanns},
+ volume = {4590},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2007},
+ pages = {298-302},
+}
+
+@InProceedings{HubertMarche:SchorrWaite,
+ author = {Thierry Hubert and Claude March{\'e}},
+ title = {A case study of {C} source code verification: the
+ {S}chorr-{W}aite algorithm},
+ booktitle = {Third IEEE International Conference on Software
+ Engineering and Formal Methods (SEFM 2005)},
+ editor = {Bernhard K. Aichernig and Bernhard Beckert},
+ publisher = {IEEE Computer Society },
+ month = sep,
+ year = {2005},
+ pages = {190-199},
+}
+
+@Article{BroyPepper:SchorrWaite,
+ author = {Manfred Broy and Peter Pepper},
+ title = {Combining Algebraic and Algorithmic Reasoning: An
+ Approach to the {S}chorr-{W}aite Algorithm},
+ journal = toplas,
+ volume = {4},
+ number = {3},
+ month = jul,
+ year = {1982},
+ pages = {362-381},
+}
+
+@Article{MehtaNipkow:SchorrWaite,
+ author = {Farhad Mehta and Tobias Nipkow},
+ title = {Proving pointer programs in higher-order logic},
+ journal = {Information and Computation},
+ year = {2005},
+ volume = {199},
+ number = {1--2},
+ pages = {200-227},
+ month = may # "--" # jun,
+}
+
+@InProceedings{Abrial:SchorrWaite,
+ author = {Jean-Raymond Abrial},
+ title = {Event Based Sequential Program Development:
+ Application to Constructing a Pointer Program},
+ booktitle = {FME 2003: Formal Methods, International Symposium of
+ Formal Methods Europe},
+ editor = {Keijiro Araki and Stefania Gnesi and Dino Mandrioli},
+ volume = {2805},
+ series = lncs,
+ publisher = {Springer},
+ month = sep,
+ year = {2003},
+ pages = {51-74},
+}
+
+@InCollection{Bubel:SchorrWaite,
+ author = {Richard Bubel},
+ title = {The Schorr-Waite-Algorithm},
+ booktitle = {Verification of Object-Oriented Software: The {KeY} Approach},
+ crossref = {KeY:book},
+ chapter = {15},
+}
+
+@InProceedings{BanerjeeEtAl:RegionLogic,
+ author = {Anindya Banerjee and David A. Naumann and Stan Rosenberg},
+ title = {Regional Logic for Local Reasoning about Global Invariants},
+ booktitle = {ECOOP 2008 --- Object-Oriented Programming, 22nd European Conference},
+ editor = {Jan Vitek},
+ series = lncs,
+ volume = 5142,
+ publisher = {Springer},
+ month = jul,
+ year = 2008,
+ pages = {387-411},
+}
+
+@Book{Abrial:BBook,
+ author = "J.-R. Abrial",
+ title = "The {B}-Book: Assigning Programs to Meanings",
+ publisher = "Cambridge University Press",
+ year = 1996
+}
+
+@Book{Abrial:EventB:book,
+ author = {Jean-Raymond Abrial},
+ title = {Modeling in {Event-B}: System and Software Engineering},
+ publisher = {Cambridge University Press},
+ year = {2010},
+}
+
+@Article{MisraCook:Orc,
+ author = {Jayadev Misra and William R. Cook},
+ title = {Computation Orchestration: A Basis for Wide-Area Computing},
+ journal = {Software and Systems Modeling},
+ year = {2007},
+ volume = 6,
+ number = 1,
+ pages = {83-110},
+ month = mar,
+}
+
+@Book{Jackson:Alloy:book,
+ author = {Daniel Jackson},
+ title = {Software Abstractions: Logic, Language, and Analysis},
+ publisher = {MIT Press},
+ year = {2006},
+}
+
+@InProceedings{JacksonEtAl:Formula,
+ author = {Ethan K. Jackson and Dirk Seifert and Markus
+ Dahlweid and Thomas Santen and Nikolaj Bj{\o}rner
+ and Wolfram Schulte},
+ title = {Specifying and Composing Non-functional Requirements
+ in Model-Based Development},
+ booktitle = {Proceedings of the 8th International Conference on
+ Software Composition},
+ pages = {72-89},
+ year = {2009},
+ editor = {Alexandre Bergel and Johan Fabry},
+ series = lncs,
+ volume = {5634},
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{HarelEtAl:PlayInPlayOut,
+ author = {David Harel and Hillel Kugler and Rami Marelly and
+ Amir Pnueli},
+ title = {Smart {P}lay-out of Behavioral Requirements},
+ booktitle = {Formal Methods in Computer-Aided Design, 4th
+ International Conference, FMCAD 2002},
+ pages = {378-398},
+ year = {2002},
+ editor = {Mark Aagaard and John W. O'Leary},
+ volume = {2517},
+ series = lncs,
+ month = nov,
+ publisher = {Springer},
+}
+
+@Article{Smith:KIDS-overview,
+ author = "Douglas R. Smith",
+ title = "{KIDS}: A Semi-Automatic Program Development System",
+ journal = {IEEE Transactions on Software Engineering },
+ volume = 16,
+ number = 9,
+ month = sep,
+ year = 1990,
+ pages = "1024-1043",
+}
+
+@article{Hoare:DataRepresentations,
+ author = "C. A. R. Hoare",
+ title = "Proof of correctness of data representations",
+ journal = acta,
+ volume = 1,
+ number = 4,
+ year = 1972,
+ pages = "271-281"
+}
+
+@InProceedings{Abrial:FM-in-practice,
+ author = {Jean-Raymond Abrial},
+ title = {Formal methods in industry: achievements, problems, future},
+ booktitle = {28th International Conference on Software Engineering (ICSE 2006)},
+ editor = {Leon J. Osterweil and H. Dieter Rombach and Mary Lou Soffa},
+ month = may,
+ year = {2006},
+ publisher = {ACM},
+ pages = {761-768},
+}
+
+@InProceedings{MartinEtAl:AsynchMIPS,
+ author = {Alain J. Martin and Andrew Lines and Rajit Manohar
+ and Mika Nystr{\"o}m and Paul I. P{\'e}nzes and
+ Robert Southworth and Uri Cummings},
+ title = {The Design of an Asynchronous MIPS R3000 Microprocessor},
+ booktitle = {17th Conference on Advanced Research in VLSI (ARVLSI '97}},
+ month = sep,
+ year = {1997},
+ publisher = {IEEE Computer Society},
+ pages = {164-181},
+}
+
+@InProceedings{BallEtAll:ScalableChecking,
+ author = {Thomas Ball and Brian Hackett and Shuvendu K. Lahiri
+ and Shaz Qadeer and Julien Vanegue},
+ title = {Towards Scalable Modular Checking of User-Defined Properties},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ (VSTTE 2010)},
+ editor = {Gary T. Leavens and Peter O'Hearn and Sriram K. Rajamani},
+ volume = {6217},
+ series = lncs,
+ publisher = {Springer},
+ month = aug,
+ year = {2010},
+ pages = {1-24},
+}
+
+@InProceedings{RegisGianasPottier:FunctionalHoare,
+ author = {Yann R{\'e}gis-Gianas and Fran{\,c}ois Pottier},
+ title = {A {H}oare Logic for Call-by-Value Functional Programs},
+ booktitle = {Mathematics of Program Construction, 9th International Conference, MPC 2008},
+ pages = {305-335},
+ year = {2008},
+ editor = {Philippe Audebaud and Christine Paulin-Mohring},
+ volume = {5133},
+ series = lncs,
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{VeanesEtAl:SpecExplorer,
+ author = {Margus Veanes and Colin Campbell and Wolfgang
+ Grieskamp and Wolfram Schulte and Nikolai Tillmann
+ and Lev Nachmanson},
+ title = {Model-Based Testing of Object-Oriented Reactive
+ Systems with {Spec} {Explorer}},
+ booktitle = {Formal Methods and Testing},
+ pages = {39-76},
+ year = {2008},
+ editor = {Robert M. Hierons and Jonathan P. Bowen and Mark Harman},
+ volume = {4949},
+ series = lncs,
+ publisher = {Springer},
+}
+
+@book{Dijkstra:Discipline,
+ author = "Edsger W. Dijkstra",
+ title = "A Discipline of Programming",
+ publisher = "Prentice Hall",
+ address = "Englewood Cliffs, NJ",
+ year = 1976
+}
+
+@InProceedings{LeinoMueller:ESOP2009,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller},
+ title = {A Basis for Verifying Multi-threaded Programs},
+ booktitle = {Programming Languages and Systems, 18th European
+ Symposium on Programming, ESOP 2009},
+ editor = {Giuseppe Castagna},
+ volume = {5502},
+ series = lncs,
+ publisher = {Springer},
+ month = mar,
+ year = 2009,
+ pages = {378-393},
+}
+
+@InProceedings{LeinoRuemmer:Boogie2,
+ author = {K. Rustan M. Leino and Philipp R{\"u}mmer},
+ title = {A Polymorphic Intermediate Verification Language:
+ Design and Logical Encoding},
+ booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, 16th International Conference,
+ TACAS 2010},
+ editor = {Javier Esparza and Rupak Majumdar},
+ series = lncs,
+ volume = 6015,
+ publisher = {Springer},
+ month = mar,
+ year = 2010,
+ pages = {312-327},
+}
+
+@book{LiskovGuttag:book,
+ author = "Barbara Liskov and John Guttag",
+ title = "Abstraction and Specification in Program Development",
+ publisher = "MIT Press",
+ series = "MIT Electrical Engineering and Computer Science Series",
+ year = 1986
+}
+
+@TechReport{DahlEtAl:Simula67,
+ author = {Ole-Johan Dahl and Bj{\o}rn Myhrhaug and Kristen Nygaard},
+ title = {Common Base Language},
+ institution = {Norwegian Computing Center},
+ type = {Publication},
+ number = {S-22},
+ month = oct,
+ year = 1970,
+}
+
+@inproceedings{LeinoMueller:ModelFields,
+ author = {K. Rustan M. Leino and
+ Peter M{\"u}ller},
+ title = {A Verification Methodology for Model Fields},
+ booktitle = "Programming Languages and Systems, 15th European Symposium on Programming, ESOP 2006",
+ editor = "Peter Sestoft",
+ series = lncs,
+ volume = 3924,
+ publisher = "Springer",
+ month = mar,
+ year = 2006,
+ pages = {115-130},
+}
+
+@InProceedings{CarterEtAl:UsingPerfectDeveloper,
+ author = {Gareth Carter and Rosemary Monahan and Joseph M. Morris},
+ title = {Software Refinement with {P}erfect {D}eveloper},
+ booktitle = {Third IEEE International Conference on Software
+ Engineering and Formal Methods (SEFM 2005)},
+ pages = {363-373},
+ editor = {Bernhard K. Aichernig and Bernhard Beckert},
+ month = sep,
+ year = {2005},
+ publisher = {IEEE Computer Society},
+}
+
+@InProceedings{Abrial:SchorrWaite,
+ author = {Jean-Raymond Abrial},
+ title = {Event Based Sequential Program Development:
+ Application to Constructing a Pointer Program},
+ booktitle = {FME 2003: Formal Methods, International Symposium of
+ Formal Methods Europe},
+ editor = {Keijiro Araki and Stefania Gnesi and Dino Mandrioli},
+ volume = {2805},
+ series = lncs,
+ publisher = {Springer},
+ month = sep,
+ year = {2003},
+ pages = {51-74},
+}
+
+@article{Barnett-etal04,
+ author = {Mike Barnett and Robert DeLine and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Wolfram Schulte},
+ title = {Verification of Object-Oriented Programs with Invariants},
+ journal = {Journal of Object Technology},
+ volume = 3,
+ number = 6,
+ year = 2004,
+ pages = {27-56},
+}
+
+@InProceedings{SmansEtAl:ImplicitDynamicFrames,
+ author = {Jan Smans and Bart Jacobs and Frank Piessens},
+ title = {Implicit Dynamic Frames: Combining Dynamic Frames
+ and Separation Logic},
+ booktitle = {ECOOP 2009 --- Object-Oriented Programming, 23rd
+ European Conference},
+ editor = {Sophia Drossopoulou},
+ volume = {5653},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2009},
+ pages = {148-172},
+}
+
+@inproceedings{GriesPrins:Encapsulation,
+ author = "David Gries and Jan Prins",
+ title = "A New Notion of Encapsulation",
+ booktitle = "Proceedings of the {ACM} {SIGPLAN} 85
+ Symposium on Language Issues in Programming Environments",
+ publisher = "ACM",
+ series = "SIGPLAN Notices 20",
+ number = 7,
+ month = jul,
+ year = 1985,
+ pages = "131-139"
+}
+
+@InProceedings{YangHawblitzel:Verve,
+ author = {Jean Yang and Chris Hawblitzel},
+ title = {Safe to the last instruction: automated verification of a type-safe operating system},
+ booktitle = {Proceedings of the 2010 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2010},
+ editor = {Benjamin G. Zorn and Alexander Aiken},
+ month = jun,
+ year = {2010},
+ publisher = {ACM},
+ pages = {99-110},
+}
+
+@Book{BoyerMoore:book,
+ author = {Robert S. Boyer and J Strother Moore},
+ title = {A Computational Logic},
+ publisher = {Academic Press},
+ series = {ACM Monograph Series},
+ year = {1979},
+}
+
+@article{HoareWirth:Pascal,
+ author = "C. A. R. Hoare and N. Wirth",
+ title = "An axiomatic definition of the programming language {PASCAL}",
+ journal = acta,
+ volume = 2,
+ number = 4,
+ year = 1973,
+ pages = "335-355"
+}
+
+@article{Hoare:AxiomaticBasis,
+ author = "C. A. R. Hoare",
+ title = "An axiomatic basis for computer programming",
+ journal = cacm,
+ volume = 12,
+ number = 10,
+ year = 1969,
+ month = oct,
+ pages = "576--580,583"
+}
+
+@InProceedings{LeinoMoskal:vacid0-notYetConfirmed,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {{VACID-0}: {V}erification of {A}mple {C}orrectness
+ of {I}nvariants of {D}ata-structures, Edition 0},
+ booktitle = {VS-Tools & Experiments},
+ year = 2010,
+ editor = {Rajeev Joshi and Tiziana Margaria and Peter
+ M{\"u}ller and David Naumann and Hongseok Yang},
+ series = {VSTTE 2010 Workshop Proceedings},
+ publisher = {ETH Zurich Technical Report 676},
+ month = aug,
+}
+
+@InCollection{Chalice:tutorial,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller and Jan Smans},
+ title = {Verification of Concurrent Programs with {C}halice},
+ booktitle = {Foundations of Security Analysis and Design {V}: {FOSAD} 2007/2008/2009 Tutorial Lectures},
+ editor = {Alessandro Aldini and Gilles Barthe and Roberto Gorrieri},
+ volume = {5705},
+ series = lncs,
+ publisher = {Springer},
+ year = {2009},
+ pages = {195-222}
+}
+
+@inproceedings{LeinoMuellerSmans10,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller and Jan Smans},
+ title = {Deadlock-Free Channels and Locks},
+ booktitle = {Programming Languages and Systems, 19th European Symposium on Programming, ESOP 2010},
+ editor = {Andrew D. Gordon},
+ volume = {6012},
+ series = lncs,
+ publisher = {Springer},
+ month = mar,
+ year = {2010},
+ pages = {407-426}
+}
+
+@Book{BundyEtAl:Rippling,
+ author = {Alan Bundy and David Basin and Dieter Hutter and Andrew Ireland},
+ title = {Rippling: Meta-level Guidance for Mathematical Reasoning},
+ publisher = {Cambridge University Press},
+ volume = {56},
+ series = {Cambridge Tracts in Theoretical Computer Science},
+ year = {2005},
+}
+
+@book{Gries:Science,
+ author = "David Gries",
+ title = "The Science of Programming",
+ publisher = "Springer-Verlag",
+ series = "Texts and Monographs in Computer Science",
+ year = 1981
+}
+
+@Book{DijkstraFeijen:Book,
+ author = "Edsger W. Dijkstra and W. H. J. Feijen",
+ title = "A Method of Programming",
+ publisher = "Addison-Wesley",
+ month = jul,
+ year = 1988,
+}
+
+@book{Kaldewaij:Programming,
+ author = "Anne Kaldewaij",
+ title = "Programming: The Derivation of Algorithms",
+ publisher = "Prentice-Hall International",
+ year = 1990,
+ series = "Series in Computer Science",
+}
+
+@InProceedings{LeinoMonahan:VSTTE2010,
+ author = {K. Rustan M. Leino and Rosemary Monahan},
+ title = {Dafny Meets the Verification Benchmarks Challenge},
+ booktitle = {Verified Software: Theories, Tools, Experiments,
+ Third International Conference, VSTTE 2010},
+ pages = {112-126},
+ year = {2010},
+ editor = {Gary T. Leavens and Peter W. O'Hearn and Sriram K. Rajamani},
+ volume = {6217},
+ series = lncs,
+ month = aug,
+ publisher = {Springer},
+}
+
+@InProceedings{VSComp2010:report,
+ author = {Vladimir Klebanov and Peter M{\"u}ller and Natarajan Shankar and
+ Gary T. Leavens and Valentin W{\"u}stholz and Eyad Alkassar and
+ Rob Arthan and Derek Bronish and Rod Chapman and Ernie Cohen and
+ Mark Hillebrand and Bart Jacobs and K. Rustan M. Leino and
+ Rosemary Monahan and Frank Piessens and Nadia Polikarpova and
+ Tom Ridge and Jan Smans and Stephan Tobies and Thomas Tuerk and
+ Mattias Ulbrich and Benjamin Wei{\ss}},
+ title = {The 1st Verified Software Competition: Experience Report},
+ booktitle = {FM 2011: Formal Methods --- 17th International
+ Symposium on Formal Methods},
+ pages = {154-168},
+ year = {2011},
+ editor = {Michael Butler and Wolfram Schulte},
+ volume = {6664},
+ series = lncs,
+ month = jun,
+ publisher = {Springer},
+}
+
+@InProceedings{Leino:Dafny:LPAR16,
+ author = {K. Rustan M. Leino},
+ title = {Dafny: An Automatic Program Verifier for Functional Correctness},
+ booktitle = {LPAR-16},
+ year = {2010},
+ volume = {6355},
+ series = lncs,
+ publisher = {Springer},
+ month = apr,
+ editor = {Edmund M. Clarke and Andrei Voronkov},
+ pages = {348-370},
+}
+
+@book{BackVonWright:Book,
+ author = "Ralph-Johan Back and von Wright, Joakim",
+ title = "Refinement Calculus: A Systematic Introduction",
+ series = "Graduate Texts in Computer Science",
+ publisher = "Springer-Verlag",
+ year = 1998
+}
+
+@Article{BalzerCheathamGreen:1990s,
+ author = {Robert Balzer and {Cheatham, Jr.}, Thomas E. and Cordell Green},
+ title = {Software Technology in the 1990's: Using a New Paradigm},
+ journal = {IEEE Computer},
+ year = {1983},
+ volume = {16},
+ number = {11},
+ pages = {39-45 },
+ month = nov,
+}
+
+@InProceedings{Zloof:QBE,
+ author = {Mosh{\'e} M. Zloof},
+ title = {Query by Example},
+ booktitle = {American Federation of Information Processing
+ Societies: 1975 National Computer Conference},
+ pages = {431-438},
+ year = {1975},
+ month = may,
+ publisher = {AFIPS Press },
+}
+
+@InProceedings{HarrisGulwani:PLDI2011,
+ author = {William R. Harris and Sumit Gulwani},
+ title = {Spreadsheet table transformations from examples},
+ booktitle = {Proceedings of the 32nd ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2011},
+ pages = {317-328},
+ year = {2011},
+ editor = {Mary W. Hall and David A. Padua},
+ month = jun,
+ publisher = {ACM},
+}
+
+@Article{Smith:KIDS-overview,
+ author = "Douglas R. Smith",
+ title = "{KIDS}: A Semi-Automatic Program Development System",
+ journal = {IEEE Transactions on Software Engineering },
+ volume = 16,
+ number = 9,
+ month = sep,
+ year = 1990,
+ pages = "1024-1043",
+}
+
+@Article{RodinToolset,
+ author = {Jean-Raymond Abrial and Michael Butler and Stefan
+ Hallerstede and Thai Son Hoang and Farhad Mehta and
+ Laurent Voisin},
+ title = {Rodin: An Open Toolset for Modelling and Reasoning in {Event-B}},
+ journal = {International Journal on Software Tools for Technology Transfer},
+ year = {2010},
+ month = apr,
+}
+
+@Article{Summers:LISP-from-examples,
+ author = {Phillip D. Summers},
+ title = {A Methodology for {LISP} Program Construction from Examples},
+ journal = jacm,
+ year = {1977},
+ volume = {24},
+ number = {1},
+ pages = {161-175},
+ month = jan,
+}
+
+@InProceedings{Pex:overview,
+ author = {Nikolai Tillmann and de Halleux, Jonathan},
+ title = {Pex---White Box Test Generation for {.NET}},
+ booktitle = {Tests and Proofs, Second International Conference, TAP 2008},
+ pages = {134-153},
+ year = {2008},
+ editor = {Bernhard Beckert and Reiner H{\"a}hnle},
+ series = lncs,
+ volume = {4966},
+ month = apr,
+ publisher = {Springer},
+}
+
+@InProceedings{GodefroidKlarlundSen:DART,
+ author = {Patrice Godefroid and Nils Klarlund and Koushik Sen},
+ title = {{DART}: directed automated random testing},
+ booktitle = {Proceedings of the ACM SIGPLAN 2005 Conference on
+ Programming Language Design and Implementation},
+ pages = {213-223},
+ year = {2005},
+ editor = {Vivek Sarkar and Mary W. Hall},
+ month = jun,
+ publisher = {ACM},
+}
+
+@PhdThesis{Monahan:thesis,
+ author = {Rosemary Monahan},
+ title = {Data Refinement in Object-Oriented Verification},
+ school = {Dublin City University},
+ year = {2010},
+}
+
+@InProceedings{Denali:pldi2002,
+ author = {Rajeev Joshi and Greg Nelson and Keith H. Randall},
+ title = {Denali: A Goal-directed Superoptimizer},
+ booktitle = {Proceedings of the 2002 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation
+ (PLDI)},
+ pages = {304-314},
+ year = {2002},
+ month = jun,
+ publisher = {ACM},
+}
+@Book{SETL,
+ author = {J. T. Schwartz and R. B. K. Dewar and E. Dubinsky and E. Schonberg},
+ title = {Programming with Sets: An Introduction to {SETL}},
+ series = {Texts and Monographs in Computer Science},
+ publisher = {Springer},
+ year = {1986},
+}
+
+@InProceedings{KuncakEtAl:PLDI2010,
+ author = {Viktor Kuncak and Mika{\"e}l Mayer and Ruzica Piskac
+ and Philippe Suter},
+ title = {Complete functional synthesis},
+ booktitle = {Proceedings of the 2010 ACM SIGPLAN Conference on
+ Programming Language Design and Implementation, PLDI
+ 2010},
+ pages = {316-329},
+ year = {2010},
+ editor = {Benjamin G. Zorn and Alexander Aiken},
+ month = jun,
+ publisher = {ACM},
+}
+
+@Article{JML:ToolSuite:STTT,
+ author = {Lilian Burdy and Yoonsik Cheon and David R. Cok and
+ Michael D. Ernst and Joeseph R. Kiniry and Gary T. Leavens and
+ K. Rustan M. Leino and Erik Poll},
+ title = {An overview of {JML} tools and applications},
+ journal = {International Journal on Software Tools
+ for Technology Transfer},
+ volume = 7,
+ number = 3,
+ publisher = {Springer},
+ month = jun,
+ year = 2005,
+ pages = {212-232},
+}
+
+@InProceedings{Green:ProblemSolving,
+ author = {Cordell Green},
+ title = {Application of Theorem Proving to Problem Solving},
+ booktitle = {Proceedings of the 1st International Joint Conference on Artificial Intelligence},
+ editor = {Donald E. Walker and Lewis M. Norton},
+ pages = {219-240},
+ year = {1969},
+ month = may,
+ publisher = {William Kaufmann},
+}
+
+@Article{MannaWaldinger:CACM1971,
+ author = {Zohar Manna and Richard J. Waldinger},
+ title = {Towards automatic program synthesis},
+ journal = cacm,
+ year = {1971},
+ volume = {14},
+ number = {3},
+ pages = {151-165},
+ month = mar,
+}
+
+@Article{RichWaters:ProgAppren,
+ author = {Charles Rich and Richard C. Waters},
+ title = {The {P}rogrammer's {A}pprentice: A Research Overview},
+ journal = {IEEE Computer},
+ year = {1988},
+ volume = {21},
+ number = {11},
+ pages = {10-25},
+ month = nov,
+}
+
+@InProceedings{Green:PSI,
+ author = {Cordell Green},
+ title = {The Design of the {PSI} Program Synthesis System},
+ booktitle = {Proceedings of the 2nd International Conference on Software Engineering},
+ pages = {4-18},
+ year = {1976},
+ month = oct,
+ publisher = {IEEE Computer Society},
+}
+
+@Article{SpecSharp:Retrospective:CACM,
+ author = {Mike Barnett and Manuel F{\"a}hndrich and
+ K. Rustan M. Leino and Peter M{\"u}ller and
+ Wolfram Schulte and Herman Venter},
+ title = {Specification and Verification: The {Spec\#} Experience},
+ journal = cacm,
+ volume = {54},
+ number = {6},
+ pages = {81-91},
+ month = jun,
+ year = 2011,
+}
+
+@article{Filipovic:SepLogicRefinement,
+ author = {Ivana Filipovi{\'c} and Peter O'Hearn and
+ Noah Torp-Smith and Hongseok Yang},
+ title = {Blaming the client: on data refinement in the presence of pointers},
+ journal = {Formal Aspects of Computing},
+ volume = {22},
+ number = {5},
+ month = sep,
+ year = {2010},
+ pages = {547-583},
+}
+
+@inproceedings{Grandy:JavaRefinement,
+ author = {Grandy, Holger and Stenzel, Kurt and Reif, Wolfgang},
+ title = {A refinement method for {J}ava programs},
+ booktitle = {Formal Methods for Open Object-Based Distributed Systems, 9th IFIP WG 6.1 International Conference, FMOODS 2007},
+ editor = {Marcello M. Bonsangue and Einar Broch Johnsen},
+ series = lncs,
+ number = {4468},
+ month = jun,
+ year = {2007},
+ publisher = {Springer},
+ pages = {221--235},
+}
+
+@InCollection{KoenigLeino:MOD2011,
+ author = {Jason Koenig and K. Rustan M. Leino},
+ title = {Getting Started with {D}afny: A Guide},
+ booktitle = {Software Safety and Security: Tools for Analysis and Verification},
+ pages = {152-181},
+ publisher = {IOS Press},
+ year = {2012},
+ editor = {Tobias Nipkow and Orna Grumberg and Benedikt Hauptmann},
+ volume = {33},
+ series = {NATO Science for Peace and Security Series D: Information and Communication Security},
+ note = {Summer School Marktoberdorf 2011 lecture notes},
+}
+
+@InProceedings{VonWright:ExtendingWindowInference,
+ author = {von Wright, Joakim},
+ title = {Extending Window Inference},
+ booktitle = {Theorem Proving in Higher Order Logics, 11th International Conference, TPHOLs'98},
+ pages = {17-32},
+ year = {1998},
+ editor = {Jim Grundy and Malcolm C. Newey},
+ volume = {1479},
+ series = lncs,
+ publisher = {Springer},
+}
+
+@InProceedings{BauerWenzel:IsarExperience,
+ author = {Gertrud Bauer and Markus Wenzel},
+ title = {Calculational reasoning revisited: an {I}sabelle/{I}sar experience},
+ booktitle = {Theorem Proving in Higher Order Logics, 14th International Conference, TPHOLs 2001},
+ pages = {75-90},
+ year = {2001},
+ editor = {Richard J. Boulton and Paul B. Jackson},
+ volume = {2152},
+ series = lncs,
+ month = sep,
+ publisher = {Springer},
+}
+
+@InProceedings{Leino:induction,
+ author = {K. Rustan M. Leino},
+ title = {Automating Induction with an {SMT} Solver},
+ booktitle = {Verification, Model Checking, and Abstract Interpretation --- 13th International Conference, VMCAI 2012},
+ pages = {315-331},
+ year = {2012},
+ editor = {Viktor Kuncak and Andrey Rybalchenko},
+ volume = {7148},
+ series = lncs,
+ month = jan,
+ publisher = {Springer},
+}
+
+@InProceedings{LGLM:BVD,
+ author = {Le Goues, Claire and K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {The {B}oogie {V}erification {D}ebugger (Tool Paper)},
+ booktitle = {Software Engineering and Formal Methods --- 9th International Conference, SEFM 2011},
+ pages = {407-414},
+ year = {2011},
+ editor = {Gilles Barthe and Alberto Pardo and Gerardo Schneider},
+ volume = {7041},
+ series = lncs,
+ month = nov,
+ publisher = {Springer},
+}
+
+@InProceedings{Filliatre:2lines,
+ author = {Jean-Christophe Filli{\^a}tre},
+ title = {Verifying two lines of {C} with {Why3}: an exercise in
+ program verification},
+ booktitle = {Verified Software: Theories, Tools, Experiments ---
+ 4th International Conference, VSTTE 2012},
+ pages = {83-97},
+ year = {2012},
+ editor = {Rajeev Joshi and Peter M{\"u}ller and Andreas Podelski},
+ volume = {7152},
+ series = lncs,
+ month = jan,
+ publisher = {Springer},
+}
+
+@InCollection{LeinoMoskal:UsableProgramVerification,
+ author = {K. Rustan M. Leino and Micha{\l} Moskal},
+ title = {Usable Auto-Active Verification},
+ booktitle = {UV10 (Usable Verification) workshop},
+ year = {2010},
+ editor = {Tom Ball and Lenore Zuck and N. Shankar},
+ month = nov,
+ publisher = {\url{http://fm.csl.sri.com/UV10/}},
+}
+
+@InProceedings{LeinoMonahan:Comprehensions,
+ author = {K. Rustan M. Leino and Rosemary Monahan},
+ title = {Reasoning about Comprehensions with First-Order {SMT} Solvers},
+ booktitle = {Proceedings of the 2009 ACM Symposium on Applied Computing (SAC)},
+ editor = {Sung Y. Shin and Sascha Ossowski},
+ publisher = {ACM},
+ month = mar,
+ year = 2009,
+ pages = {615-622},
+}
+
+@TechReport{VeriFast:TR,
+ author = {Bart Jacobs and Frank Piessens},
+ title = {The {VeriFast} program verifier},
+ institution = {Department of Computer Science, Katholieke Universiteit Leuven},
+ year = {2008},
+ number = {CW-520},
+ month = aug,
+}
+
+@book{DijkstraScholten:book,
+ author = "Edsger W. Dijkstra and Carel S. Scholten",
+ title = "Predicate Calculus and Program Semantics",
+ publisher = "Springer-Verlag",
+ series = "Texts and Monographs in Computer Science",
+ year = 1990
+}
+
+@Book{KeY:book,
+ author = {Bernhard Beckert and Reiner H{\"a}hnle and Peter H. Schmitt},
+ title = {Verification of Object-Oriented Software: The {KeY} Approach},
+ volume = 4334,
+ series = lnai,
+ publisher = {Springer},
+ year = 2007,
+}
+
+@Book{Coq:book,
+ author = {Yves Bertot and Pierre Cast{\'e}ran},
+ title = {Interactive Theorem Proving and Program Development --- {C}oq'{A}rt: The Calculus of Inductive Constructions},
+ publisher = {Springer},
+ year = {2004},
+ series = {Texts in Theoretical Computer Science},
+}
+
+@Book{ACL2:book,
+ author = {Matt Kaufmann and Panagiotis Manolios and J Strother Moore},
+ title = {Computer-Aided Reasoning: An Approach},
+ publisher = {Kluwer Academic Publishers},
+ year = {2000},
+}
+
+@InProceedings{Coq:Coinduction,
+ author = {Eduardo Gim{\'e}nez},
+ title = {An Application of Co-inductive Types in {Coq}: Verification of the Alternating Bit Protocol},
+ booktitle = {Types for Proofs and Programs, International Workshop TYPES'95},
+ pages = {135-152},
+ year = {1996},
+ editor = {Stefano Berardi and Mario Coppo},
+ volume = 1158,
+ series = lncs,
+ publisher = {Springer},
+}
+
+@InCollection{JacobsRutten:IntroductionCoalgebra,
+ author = {Bart Jacobs and Jan Rutten},
+ title = {An Introduction to (Co)Algebra and (Co)Induction},
+ booktitle = {Advanced Topics in Bisimulation and Coinduction},
+ editor = {Davide Sangiorgi and Jan Rutten},
+ series = {Cambridge Tracts in Theoretical Computer Science},
+ number = {52},
+ publisher = {Cambridge University Press},
+ month = oct,
+ year = {2011},
+ pages = {38-99},
+}
+
+@InProceedings{SonnexEtAl:Zeno,
+ author = {William Sonnex and Sophia Drossopoulou and Susan Eisenbach},
+ title = {Zeno: An Automated Prover for Properties of Recursive
+ Data Structures},
+ booktitle = {Tools and Algorithms for the Construction and Analysis of
+ Systems --- 18th International Conference, TACAS 2012},
+ editor = {Cormac Flanagan and Barbara K{\"o}nig},
+ volume = {7214},
+ series = lncs,
+ year = {2012},
+ month = mar # "--" # apr,
+ publisher = {Springer},
+ pages = {407-421},
+}
+
+@InProceedings{JohanssonEtAl:IPT2010,
+ author = {Moa Johansson and Lucas Dixon and Alan Bundy},
+ title = {Case-Analysis for {R}ippling and Inductive Proof},
+ booktitle = {Interactive Theorem Proving, First International Conference, ITP 2010},
+ editor = {Matt Kaufmann and Lawrence C. Paulson},
+ volume = {6172},
+ series = lncs,
+ publisher = {Springer},
+ month = jul,
+ year = {2010},
+ pages = {291-306},
+}
+
+@Article{HatcliffEtAl:BISL,
+ author = {John Hatcliff and Gary T. Leavens and
+ K. Rustan M. Leino and Peter M{\"u}ller and Matthew Parkinson},
+ title = {Behavioral interface specification languages},
+ journal = {ACM Computing Surveys},
+ volume = {44},
+ number = {3},
+ note = {Article 16},
+ month = jun,
+ year = {2012},
+}
+
+@InProceedings{BoehmeNipkow:Sledgehammer,
+ author = {Sascha B{\"o}hme and Tobias Nipkow},
+ title = {Sledgehammer: {J}udgement {D}ay},
+ booktitle = {Automated Reasoning, 5th International Joint Conference, IJCAR 2010},
+ editor = {J{\"u}rgen Giesl and Reiner H{\"a}hnle},
+ year = {2010},
+ pages = {107-121},
+ volume = {6173},
+ series = lncs,
+ month = jul,
+ publisher = {Springer},
+}
+
+@InProceedings{Dafny:LASER2011,
+ author = {Luke Herbert and K. Rustan M. Leino and Jose Quaresma},
+ title = {Using {Dafny}, an Automatic Program Verifier},
+ booktitle = {Tools for Practical Software Verification, {LASER}, International Summer School 2011},
+ editor = {Bertrand Meyer and Martin Nordio},
+ volume = {7682},
+ series = lncs,
+ year = {2012},
+ pages = {156-181},
+ publisher = {Springer},
+}
+
+@Article{Leroy:CompCert:CACM,
+ author = {Xavier Leroy},
+ title = {Formal verification of a realistic compiler},
+ journal = cacm,
+ volume = {52},
+ number = {7},
+ year = {2009},
+ pages = {107-115},
+}
+
+@InProceedings{Leino:ITP2013,
+ author = {K. Rustan M. Leino},
+ title = {Automating Theorem Proving with {SMT}},
+ booktitle = {Interactive Theorem Proving --- 4th International Conference, ITP 2013},
+ year = {2013},
+ editor = {Sandrine Blazy and Christine Paulin-Mohring and David Pichardie},
+ volume = {7998},
+ series = lncs,
+ pages = {2-16},
+ month = jul,
+ publisher = {Springer},
+}
+
+@techreport{Nelson:thesis,
+ author = "Charles Gregory Nelson",
+ title = "Techniques for Program Verification",
+ institution = "Xerox PARC",
+ month = jun,
+ year = 1981,
+ number = "CSL-81-10",
+ note = "The author's PhD thesis"
+}
+
+@InProceedings{LernerMillsteinChambers:VerifiedOptimizations,
+ author = {Sorin Lerner and Todd Millstein and Craig Chambers},
+ title = {Automatically proving the correctness of compiler optimizations},
+ booktitle = {Proceedings of the ACM SIGPLAN 2003 Conference on
+ Programming Language Design and Implementation 2003},
+ year = {2003},
+ editor = {Ron Cytron and Rajiv Gupta},
+ pages = {220-231},
+ month = jun,
+ publisher = {ACM},
+}
+
+@InProceedings{BoyerHunt:ACL2,
+ author = {Robert S. Boyer and Hunt, Jr., Warren A.},
+ title = {Function Memoization and Unique Object Representation for {ACL2} Functions},
+ booktitle = {Proceedings of the Sixth International Workshop on
+ the ACL2 Theorem Prover and its Applications, ACL2 2006},
+ editor = {Panagiotis Manolios and Matthew Wilding},
+ month = aug,
+ year = {2006},
+ pages = {81--89},
+ publisher = {ACM},
+}
+
+@inproceedings{LeinoWuestholz:DafnyIDE,
+ author = {K. Rustan M. Leino and
+ Valentin W{\"{u}}stholz},
+ title = {The {D}afny Integrated Development Environment},
+ booktitle = {Proceedings 1st Workshop on Formal Integrated Development Environment,
+ {F-IDE} 2014},
+ month = apr,
+ year = {2014},
+ pages = {3--15},
+ editor = {Catherine Dubois and
+ Dimitra Giannakopoulou and
+ Dominique M{\'{e}}ry},
+ series = {{EPTCS}},
+ volume = {149},
+}
+
+@inproceedings{BarnettLeino:Weakest,
+ author = {Mike Barnett and K. Rustan M. Leino},
+ title = {Weakest-precondition of unstructured programs},
+ booktitle = {Proceedings of the 2005 ACM SIGPLAN-SIGSOFT Workshop on
+ Program Analysis For Software Tools and Engineering,
+ PASTE'05},
+ editor = {Michael D. Ernst and Thomas P. Jensen},
+ month = sep,
+ year = {2005},
+ pages = {82-87},
+ publisher = {ACM},
+}
|