Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Dafny无法证明函数方法的等价性,即高阶多态递归与线性迭代_Algorithm_Polymorphism_Verification_Dafny_Formal Verification - Fatal编程技术网

Algorithm Dafny无法证明函数方法的等价性,即高阶多态递归与线性迭代

Algorithm Dafny无法证明函数方法的等价性,即高阶多态递归与线性迭代,algorithm,polymorphism,verification,dafny,formal-verification,Algorithm,Polymorphism,Verification,Dafny,Formal Verification,这个消息会有点长,但那是因为我想尽可能地解释它 在Dafny中,我遇到了下一个问题:给定一个数组,计算发生这种情况的长度为k的段数;段左半部分的正片数大于或等于右半部分 例如(假设片段只能是偶数,因此不讨论什么是半): 我以两种方式实现了这一点:一种是使用函数,使用高阶和多态性(但它不是线性的),另一种是使用迭代实现,它是线性的 该函数的工作方式如下: 我们定义了一个计数函数,它对数组中的属性进行计数 我们定义了一种方法,在给定数组的情况下,生成给定长度的所有段 我们使用Count定义一个谓词,

这个消息会有点长,但那是因为我想尽可能地解释它

在Dafny中,我遇到了下一个问题:给定一个数组,计算发生这种情况的长度为k的段数;段左半部分的正片数大于或等于右半部分

例如(假设片段只能是偶数,因此不讨论什么是半):

我以两种方式实现了这一点:一种是使用函数,使用高阶和多态性(但它不是线性的),另一种是使用迭代实现,它是线性的

该函数的工作方式如下:

  • 我们定义了一个计数函数,它对数组中的属性进行计数
  • 我们定义了一种方法,在给定数组的情况下,生成给定长度的所有段
  • 我们使用Count定义一个谓词,它告诉我们属性是否满足
  • 现在,关键是
    确保num_segmts==Count(segment_leftmore segmentright,product_segments(sequ,seg_length))不进行验证。显然,我必须用引理证明一些关于
    Count
    Count\u linear
    的性质,但不知道从哪里开始这个问题


    有什么帮助吗?我希望我已经尽可能最好地解释了这个问题。

    我正在回答这个问题,只是为了得到好的代码格式

    您的
    Count\u linear
    有一个bug

      var aseq := [1,2,3,4,5,6,7,8,9,10];
      var slow := Count(segment_LeftMoreSegmentRight, produce_segments(aseq,4)); //high order and polymorphic
      var fast := Count_linear(aseq, 4);
      print slow, "\n";
      print fast, "\n";
    
    印刷品

    7
    5
    

    我正在为您做一个完整的证明,但现在只需要一些简短的评论:(1)您的代码有错误:),您可以尝试运行添加一些打印语句,并在尝试证明之前先进行测试;(2) 确保在方法体中包含循环的子句始终需要循环不变量。首先,非常感谢。(1) 你完全正确,我用var bseq:=[1,2,3,4,5,6,7,8,9,10]证明了这一点
    over
    var seg\u leftRight:=Count(段\u Leftmore段右,bseq)
    并且确实有效(即,将计数应用于一个具体段)。我知道我没有用你说的那个来证明,但我想我已经证明了。现在,更为合理的是,这一政策确实正在失败。(2) 我认为Dafny的当前版本并不总是需要不变量,至少对于简单的算法是如此,所以在再次提出此类问题之前,我将对此进行研究。抱歉耽误了时间,没问题!这不是浪费时间。我会在几个小时内回到一个完整的证明。要回答您关于循环不变量的问题,不,Dafny可以自动推断的唯一循环不变量是
    之类的东西,我非常感谢!我会接受你的建议,并记住不变量总是需要的。我在达夫尼呆了一段时间,但我几乎忘记了编程的迭代方式:(我一直在测试函数,没有发现任何问题。例如,我测试了var aseq:=[1,2,-1,4,5,6,7,-1,9,10];var bseq:=[1,2,3,4,5,6,7,8,9,10];var seg_leftRight:=Count(segment_LeftMoreSegmentRight,bseq)var seg2_leftRight:=Count(segment_leftmore segmentright,product_segments(aseq,5));
    具有不同的
    aseq
    bseq
    s,并且具有不同的段长度。我可能错了:哪些是失败的案例?我怎么没有看到这一个……我会看到的。非常感谢!(现在还不打算结束帖子)
    //returns if the number of positives left is higher than the right or not
    function method segmentL_isMore_right (pos_left:int,pos_right:int) : bool
      {
        if pos_left>=pos_right then true
        else false
      }
     
     method initialize(sequ:seq<int>, seg_length:int) returns (sequ_new:seq<int>,pos_left: int,pos_right:int)
      requires |sequ| >= seg_length >= 0
    {
      var length := |sequ|;
      var pos_left_local := 0;
      var pos_right_local :=0;
      var i:=0;
      while i<(length/2) 
      {
        if sequ[i]>=1 {pos_left_local:=pos_left_local+1;}
        i:=i+1;
      }
      while i<(length) 
      {
        if sequ[i]>=1 {pos_right_local:=pos_right_local+1;}
        i:=i+1;
      }
      
      return sequ[0..],pos_left_local,pos_right_local;
    }
    
    //Linear implementation
    
    method Count_linear(sequ:seq<int>, seg_length:int) returns (num_segmts: int)
      requires |sequ| >= seg_length >= 0
      ensures num_segmts == Count(segment_LeftMoreSegmentRight, produce_segments(sequ,seg_length));
    {
      var num_segmts_local := 0;
      var new_seq, pos_left_local, pos_right_local := initialize(sequ,seg_length);
      var i:=seg_length+1;
      while i<|sequ| 
        decreases |sequ|-i
      {
        if (sequ[i] >=0) {pos_right_local:=pos_right_local+1;}
        if (sequ[i-seg_length]>=0) {pos_left_local:=pos_left_local+1;}
        if (sequ[i-seg_length]/2>=0) 
            {
            pos_right_local:=pos_right_local-1;
            pos_left_local:=pos_left_local+1;
            }
        i:=i+1;
        if segmentL_isMore_right (pos_left_local,pos_right_local) 
          {
            num_segmts_local:=num_segmts_local+1;
          }
      }
      return num_segmts_local;
    }
    
    
    \\if want to prove it:
    method Main()
    {
      var aseq := [1,2,3,4,5,6,7,8,9,10];
      var seg2_leftRight := Count(segment_LeftMoreSegmentRight, produce_segments(aseq,4)); //high order and polymorphic
    }
    
    
      var aseq := [1,2,3,4,5,6,7,8,9,10];
      var slow := Count(segment_LeftMoreSegmentRight, produce_segments(aseq,4)); //high order and polymorphic
      var fast := Count_linear(aseq, 4);
      print slow, "\n";
      print fast, "\n";
    
    7
    5