在 dafny 中创建 class 类型的数组

Creating an array of a class type in dafny

我在创建我在 dafny 中创建的 class 类型的对象数组时遇到问题。问题是在初始化该类型的新数组时,我在 vscode:

中收到此错误

unless an initializer is provided for the array elements, a new array of 'Cup' must have empty size

这是代码(实际上是一个仍然能说明问题的精简版):

datatype Drink = WATER | LEMONADE | COFFEE | TEA

class Cup {
  var volume: int
  var drink_type: Drink
  var dirty: bool

  predicate Valid()
  reads this;
  {
    volume >= 0 
  }

  constructor (v: int, dt: Drink, d: bool)
  requires v >= 0;
  ensures Valid();
  {
    volume := v;
    drink_type := dt;
    dirty := d;
  }
}

method FilterCupDrinkType(a: array<Cup>, dt: Drink) returns (b: array<Cup>, n: int)
{
  var temp := new Cup[a.Length]; 
}

我查看了手册和在线,但找不到真正的答案,所以我希望这里有人知道该怎么做。如果无法在 dafny 中执行此操作(dafny 非常新),我将不胜感激有关验证此类内容的任何建议。谢谢!

您可以创建一个默认值 Cup,然后用它初始化数组,如下所示

method FilterCupDrinkType(a: array<Cup>, dt: Drink) returns (b: array<Cup>, n: int)
{
  var default := new Cup(0, WATER, false);
  var temp := new Cup[a.Length](_ => default); 
}

或者您可以允许 temp 成为可空 Cup 的数组(即 Cup?

method FilterCupDrinkType(a: array<Cup>, dt: Drink) returns (b: array<Cup>, n: int)
{
  var temp := new Cup?[a.Length]; 
}

或者您可以复制a如下

method FilterCupDrinkType(a: array<Cup>, dt: Drink) returns (b: array<Cup>, n: int)
{
  var temp := new Cup[a.Length](i requires 0 <= i < a.Length reads a => a[i]); 
}

如果您不想在这里等待答案,通常寻找此类问题解决方案的好方法是在 https://github.com/dafny-lang/dafny/tree/master/Test 搜索 Dafny 的广泛测试套件。当然,如果能针对主题,教程是更好的选择。