Тип не совпадает с набором в Дафни. Вы хотите express квантификаторы в своих леммах следующим образом:
lemma algebra()
ensures exists x: Alg :: eval(x) == {}
ensures forall x: Alg :: eval(x) <= S
ensures forall x: Alg :: exists y: Alg :: eval(y) == S - eval(x)
ensures forall b: Alg, c: Alg :: exists d: Alg :: eval(d) == eval(b) + eval(c)
Таким же образом вы можете объявить переменную x
для типа int
, но вы не пишете x in int
.
Из-за вывода типа вам не нужно явно писать : Alg
. Вы можете просто написать:
lemma algebra()
ensures exists x :: eval(x) == {}
ensures forall x :: eval(x) <= S
ensures forall x :: exists y :: eval(y) == S - eval(x)
ensures forall b, c :: exists d :: eval(d) == eval(b) + eval(c)
Еще один комментарий к примеру: здесь вы определяете математику. Когда вы это делаете, обычно неплохо держаться подальше от императивных функций, таких как классы, методы и изменяемые поля. Вам не нужны такие функции, и они просто усложняют математику. Вместо этого я предлагаю удалить класс, изменив объявление S
на const
и удалив предложение reads
. Это дает вам:
datatype Alg = Empty | Complement(a: Alg) | Union(b: Alg, c: Alg) | Set(s: set<int>)
const S: set<int>
function eval(X: Alg): set<int> // evaluates an algebra
decreases X
{
match X
case Empty => {}
case Complement(a) => S - eval(X.a)
case Union(b,c) => eval(X.b) + eval(X.c)
case Set(s) => X.s
}
lemma algebra()
ensures exists x :: eval(x) == {}
ensures forall x :: eval(x) <= S
ensures forall x :: exists y :: eval(y) == S - eval(x)
ensures forall b, c :: exists d :: eval(d) == eval(b) + eval(c)
Растан