Меня смущает оператор forall Дафни, если оператор внутри forall предназначен для обновления переменной, такой как c.arr[i].d, которая смешивается с доступом к полю и элементу массива. Например, следующий пример не может быть скомпилирован.
Я думаю, что явное указание модифицирующего предложения очень утомительно, мне нужно указать: модифицирует top, модифицирует top.Cache[i]
datatype CACHE_STATE = I| S| E
datatype MSG_CMD = Empty| ReqS| ReqE| Inv| InvAck| GntS| GntE
type NODE=nat
type DATA=nat
type boolean=bool
class class_0 {
var
Data : DATA,
Cmd : MSG_CMD
}
class class_1 {
var
Data : DATA,
State : CACHE_STATE
}
class TopC{
var
AuxData : DATA,
MemData : DATA,
CurPtr : NODE,
CurCmd : MSG_CMD,
ExGntd : boolean,
ShrSet : array<boolean>,
InvSet : array<boolean>,
Chan3 : array<class_0 > ,
Chan2 : array<class_0 > ,
Chan1 : array<class_0 > ,
Cache : array<class_1 > }
method n_RecvReqS(top:TopC,i:nat, N0:nat )
requires 0<= i<N0
requires top.Chan1.Length ==N0
requires N0>0
requires top.InvSet.Length ==N0
requires N0>0
requires top.ShrSet.Length ==N0
requires N0>0
requires top.Cache.Length ==N0
requires ((top.Chan1[i].Cmd == ReqS) && (top.CurCmd == Empty))
modifies top.Chan1[i]
modifies top.InvSet
modifies top.ShrSet
modifies top
modifies top.Cache
{
top.CurCmd := ReqS;
top.CurPtr := i;
top.Chan1[i].Cmd := Empty;
forall j | 0<= j< N0 {
top.InvSet[j] := top.ShrSet[j];
}
forall j | 0<= j< N0 {
top.Cache[j].State:= I;
}
}