Algorithm 在Dafny中保存属性的最长序列

Algorithm 在Dafny中保存属性的最长序列,algorithm,polymorphism,verification,dafny,formal-verification,Algorithm,Polymorphism,Verification,Dafny,Formal Verification,在Dafny中,我试图创建一个Max多态高阶函数,给定一个序列和一个谓词,该函数返回保存它的最长子序列。例如,最长递增子序列,或所有元素均为零的最长子序列 为此,我设计了一个慢速算法(给定p谓词和S序列): 1。在左侧开始一个i轴,在同一位置开始一个j轴。 2.开始max_序列=[]和max_序列长度=0。 3.当i bool时,sequ:seq)返回(max_seq:seq) { 变量i:=0; var j:=0; var最长:=0; var_sgmt:=sequ; var fresh_seg

在Dafny中,我试图创建一个
Max
多态高阶函数,给定一个序列和一个谓词,该函数返回保存它的最长子序列。例如,最长递增子序列,或所有元素均为零的最长子序列

为此,我设计了一个慢速算法(给定
p
谓词和
S
序列):

1。在左侧开始一个i轴,在同一位置开始一个j轴。
2.开始max_序列=[]和max_序列长度=0。
3.当i bool时,sequ:seq)返回(max_seq:seq)
{
变量i:=0;
var j:=0;
var最长:=0;
var_sgmt:=sequ;
var fresh_segmnt:=sequ;
变量计数器:=最长;
当我{
最长:=计数器;
_sgmt:=新鲜的_segmnt;
}
而P(新鲜的)和{
最长:=计数器;
_sgmt:=新鲜的_segmnt;
}
}
}
i:=i+1;
}
返回_sgmt;
}
我的问题是:如何验证
Max
函数的行为是否符合预期?更具体地说:我必须添加哪些

我的想法是:对于原始序列的所有子序列,没有一个子序列包含
p
,并且比
sgmt
长。但我不知道如何有效地表达它


谢谢

我编写了从给定整数数组中查找(最左边)最长的零子序列的代码。因为可以使用谓词映射
sequ
,所以这两个问题几乎是相同的

// For a given integer array, let's find the longest subesquence of 0s.
// sz: size, pos: position.   a[pos..(pos+sz)] will be all zeros
method longestZero(a: array<int>) returns (sz:int, pos:int)   
    requires 1 <= a.Length
    ensures 0 <= sz <= a.Length
    ensures 0 <= pos < a.Length
    ensures pos + sz <= a.Length
    ensures forall i:int  :: pos <= i < pos + sz ==> a[i] == 0
    ensures forall i,j :: (0 <= i < j < a.Length && getSize(i, j) > sz) ==> exists k :: i <= k <= j && a[k] != 0
{
    var b := new int[a.Length];   // if b[i] == n, then a[i], a[i-1], ... a[i-n+1] will be all zeros and (i-n ==0 or a[i-n] !=0)
    if a[0] == 0
        {b[0] := 1;}
    else
        {b[0] := 0;}

    var idx:int := 0;
    while idx < a.Length - 1    // idx <- 0 to a.Length - 2
        invariant 0 <= idx <= a.Length - 1
        invariant forall i:int :: 0 <= i <= idx ==>  0 <= b[i] <= a.Length
        invariant forall i:int :: 0 <= i <= idx ==> -1 <= i - b[i]
        invariant forall i:int :: 0 <= i <= idx ==> (forall j:int :: i-b[i] < j <= i ==> a[j] == 0) 
        invariant forall i:int :: 0 <= i <= idx ==> ( 0 <= i - b[i] ==> a[i - b[i]] != 0 )
    {
        if a[idx + 1] == 0
            { b[idx + 1] := b[idx] + 1; }
        else
            { b[idx + 1] := 0;}

        idx := idx + 1;
    }


    idx := 1;
    sz := b[0];
    pos := 0;
    // Let's find maximum of array b. That is the desired sz.
    while idx < a.Length
        invariant 1 <= idx <= b.Length

        invariant 0 <= sz <= a.Length
        invariant 0 <= pos < a.Length
        invariant pos + sz <= a.Length

        invariant forall i:int :: 0 <= i < idx  ==> b[i] <= sz
        invariant forall i:int  :: pos <= i < pos + sz ==> a[i] == 0
        invariant forall i, j:int  :: (0 <= i < j < idx && getSize(i,j) > sz) ==>  a[j-b[j]] != 0
    {
        // find max
        if b[idx] > sz 
        { 
            sz := b[idx]; 
            pos := idx - b[idx] + 1;
        }
        idx := idx + 1;
    }
}


function getSize(i: int, j:int) : int
{
    j - i + 1    
}
//对于给定的整数数组,让我们查找0的最长子序列。
//sz:尺寸,位置:位置。a[pos..(pos+sz)]将全部为零
方法longestZero(a:array)返回(sz:int,pos:int)

需要1个完全有帮助的人!!
method maxPropertySequence<T>(P: seq<T> -> bool, sequ: seq<T>) returns (max_seq: seq<T>)

  {
    var i := 0;
    var j := 0;
    var longest := 0;
    var the_sgmt := sequ;
    var fresh_segmnt := sequ;
    var counter := longest;
    while i<(|sequ|) 
      decreases |sequ|-i
    {
      j := i;
      counter := 0;
      fresh_segmnt := [sequ[i]];
      if P(fresh_segmnt) 
      {
          j := j+1;
          counter:=counter+1;
          if counter>longest {
            longest:=counter;
            the_sgmt := fresh_segmnt;
          }
          while P(fresh_segmnt) && j<|sequ|
            decreases |sequ|-j
          {
            fresh_segmnt := fresh_segmnt + [sequ[j]];
            j := j+1;
            counter:=counter+1;
            if counter>longest {
              longest:=counter;
              the_sgmt := fresh_segmnt;
            }
          }
      }
      i := i+1;
    }
    return the_sgmt;
      
  }


// For a given integer array, let's find the longest subesquence of 0s.
// sz: size, pos: position.   a[pos..(pos+sz)] will be all zeros
method longestZero(a: array<int>) returns (sz:int, pos:int)   
    requires 1 <= a.Length
    ensures 0 <= sz <= a.Length
    ensures 0 <= pos < a.Length
    ensures pos + sz <= a.Length
    ensures forall i:int  :: pos <= i < pos + sz ==> a[i] == 0
    ensures forall i,j :: (0 <= i < j < a.Length && getSize(i, j) > sz) ==> exists k :: i <= k <= j && a[k] != 0
{
    var b := new int[a.Length];   // if b[i] == n, then a[i], a[i-1], ... a[i-n+1] will be all zeros and (i-n ==0 or a[i-n] !=0)
    if a[0] == 0
        {b[0] := 1;}
    else
        {b[0] := 0;}

    var idx:int := 0;
    while idx < a.Length - 1    // idx <- 0 to a.Length - 2
        invariant 0 <= idx <= a.Length - 1
        invariant forall i:int :: 0 <= i <= idx ==>  0 <= b[i] <= a.Length
        invariant forall i:int :: 0 <= i <= idx ==> -1 <= i - b[i]
        invariant forall i:int :: 0 <= i <= idx ==> (forall j:int :: i-b[i] < j <= i ==> a[j] == 0) 
        invariant forall i:int :: 0 <= i <= idx ==> ( 0 <= i - b[i] ==> a[i - b[i]] != 0 )
    {
        if a[idx + 1] == 0
            { b[idx + 1] := b[idx] + 1; }
        else
            { b[idx + 1] := 0;}

        idx := idx + 1;
    }


    idx := 1;
    sz := b[0];
    pos := 0;
    // Let's find maximum of array b. That is the desired sz.
    while idx < a.Length
        invariant 1 <= idx <= b.Length

        invariant 0 <= sz <= a.Length
        invariant 0 <= pos < a.Length
        invariant pos + sz <= a.Length

        invariant forall i:int :: 0 <= i < idx  ==> b[i] <= sz
        invariant forall i:int  :: pos <= i < pos + sz ==> a[i] == 0
        invariant forall i, j:int  :: (0 <= i < j < idx && getSize(i,j) > sz) ==>  a[j-b[j]] != 0
    {
        // find max
        if b[idx] > sz 
        { 
            sz := b[idx]; 
            pos := idx - b[idx] + 1;
        }
        idx := idx + 1;
    }
}


function getSize(i: int, j:int) : int
{
    j - i + 1    
}