Dafny includes features which further support its use as a
proof assistant. Although proofs of simple properties within a function or method (as shown above) are not unusual for tools of this nature, Dafny also allows the proof of properties between one function and another. As is common for a
proof assistant, such proofs are often
inductive in nature. Dafny may be unusual in employing method invocation as a mechanism for applying the inductive hypothesis. The following illustrates: datatype List = Nil | Link(data: int, next: List) function sum(l: List): int { match l case Nil => 0 case Link(d, n) => d + sum(n) } predicate isNatList(l: List) { match l case Nil => true case Link(d, n) => d >= 0 && isNatList(n) } lemma NatSumLemma(l: List, n: int) requires isNatList(l) && n == sum(l) ensures n >= 0 { match l case Nil => // Discharged Automatically case Link(data, next) => { // Apply Inductive Hypothesis NatSumLemma(next, sum(next)); // Check what known by Dafny assert data >= 0; } } Here, NatSumLemma proves a useful property
between sum() and isNatList() (i.e. that isNatList(l) ==> (sum(l) >= 0)). The use of a ghost method for encoding
lemmas and theorems is standard in Dafny with recursion employed for induction (typically,
structural induction).
Case analysis is performed using match statements and non-inductive cases are often discharged automatically. The verifier must also have complete access to the contents of a function or predicate to unroll them as necessary. This has implications when used in conjunction with
access modifiers. Specifically, hiding the contents of a function using the protected modifier can limit what properties can be established about it. ==See also==