dafny Как проверить значение члена в другом классе

Я пытаюсь изучить дафни и столкнулся с проблемой, которую не понимаю. Мне нужно проверить, существует ли пользователь в массиве, и я хочу использовать для этого предикат. У меня есть массив пользователей, и у каждого пользователя есть идентификатор. Итак, я хочу проверить идентификатор, принадлежащий классу User.

Я получаю эту ошибку Test.dfy(57,24): Error: member id does not exist in array type array

Все остальное работает нормально (я так думаю).

Итак, как мне прочитать/получить доступ к члену другого класса в предикате, когда у меня есть массив объектов (пользователь)?

Спасибо за помощь. `

class Test {

    var users : array<User>;
    var size : int;
    var index : int;

    method Init(c : int)
    modifies this;   
    requires c > 0;
    ensures fresh(users);   
    ensures size == c; 
    ensures Check();
    ensures Empty();

{
    users := new User[c];   
    size := c;    
    index := -1;        
}

predicate Empty()
reads this`index;
{
    index == -1
}

predicate Full()
reads this`index, this`size;
{
    index == (size - 1)
}

predicate Check()
reads this;
{
    users != null && 
    size > 0 && 
    size == users.Length && 
    index >= -1 && 
    index < size 
}

method AddUser(u : User)
modifies this.users, this`index;
requires Check();
requires !Full();

ensures Check();
ensures index == old(index) + 1;
ensures users[index] == u;
{
    index := index + 1;   
    users[index] := u; 
}

predicate FindUserById(n : int)
reads this.users, this.users`id;
requires Check();
{
    exists i :: 0 <= i < users.Length ==> users[i].id == n
}

method Main()
{
    var t := new Test;
    t.Init(3);
    var u1 := new User.Init(1,23);
    var u2 := new User.Init(2,24);
    var u3 := new User.Init(3,25);
    t.AddUser(u1);
    t.AddUser(u2);
    t.AddUser(u3);
}
}

class User {

   var id : int;
   var phone : int;

   method Init(i : int, p : int)
   modifies this`id, this`phone;
   requires 0 < i < 99999;
   requires 0 < p < 99999;
   ensures id == i;
   ensures phone == p;
   {
        id := i;
        phone := p;
   }
}

person rolf-ralf    schedule 01.12.2017    source источник


Ответы (1)


Проблема заключается в части предложения reads this.users`id, поскольку users является массивом, а массивы не имеют поля id.

Вам вообще не нужна эта часть предложения reads; просто удалите его. Затем вам нужно будет исправить несколько других проблем, прежде чем программа проверит.

person James Wilcox    schedule 01.12.2017
comment
Спасибо, но если я удалю this.users`id, я получу эту ошибку Error: insufficient reads clause to invoke function в строке, где находится Check(). И если я уберу Check(), я получу Error: insufficient reads clause to read field. Если я удаляю весь предикат, код компилируется без ошибок. Не могли бы вы подсказать, как это решить? - person rolf-ralf; 02.12.2017
comment
@rolf-ralf да, вам все равно нужно исправить предложение reads, чтобы включить весь массив. как насчет такого? reads this, this.users, set i | 0 <= i < users.Length :: users[i]; - person James Wilcox; 04.12.2017