Я смотрел на использование лемм в Дафни, но мне трудно понять, и, очевидно, приведенный ниже пример не проверяет, вполне возможно, потому что Дафни не видит индукции или что-то вроде лемма для доказательства некоторого свойства счетчика? В принципе, я не знаю, как или что мне нужно определить, чтобы помочь убедить Дафни в том, что подсчет является индуктивным, и т. Д. Некоторые из спецификаций обеспечения и инвариантов не нужны, но это не главное. Кстати, это было проще в SpeC#.Dafny и подсчет событий
function count(items: seq<int>, item: int): nat
decreases |items|
{
if |items| == 0 then 0 else
(if items[|items| - 1] == item then 1 else 0)
+ count(items[..(|items| - 1)], item)
}
method occurences(items: array<int>, item: int) returns (r: nat)
requires items != null
ensures r <= items.Length
// some number of occurences of item
ensures r > 0 ==> exists k: nat :: k < items.Length
&& items[k] == item
// no occurences of item
ensures r == 0 ==> forall k: nat :: k < items.Length
==> items[k] != item
ensures r == count(items[..], item)
{
var i: nat := 0;
var num: nat := 0;
while i < items.Length
// i is increasing and there could be elements that match
invariant num <= i <= items.Length
invariant num > 0 ==> exists k: nat :: k < i
&& items[k] == item
invariant num == 0 ==> forall k: nat :: k < i
==> items[k] != item
invariant num == old(num) + 1 || num == old(num)
invariant num == count(items[..i], item)
{
if items[i] == item
{ num := num + 1; }
i := i + 1;
}
return num;
}