Java 调用函数后JML删除警告

Java 调用函数后JML删除警告,java,jml,openjml,Java,Jml,Openjml,我有一个任务,我必须删除JML产生的所有警告 如果我在构造函数中调用方法,我的需要,并且确保不再验证,尽管为被调用的函数添加了相同的约束 我被要求只使用要求,确保,不变和循环不变 代码如下: /*@ non_null @*/ int[] elements; int n; //@ invariant n >= 0; //@ requires input != null; //@ requires input.length >= 0; //@ ensures

我有一个任务,我必须删除JML产生的所有警告
如果我在构造函数中调用方法,我的
需要
,并且
确保不再验证
,尽管为被调用的函数添加了相同的约束
我被要求只使用
要求
确保
不变
循环不变

代码如下:

  /*@ non_null @*/ int[] elements;
  int n;
  //@ invariant n >= 0;
  
  //@ requires input != null;
  //@ requires input.length >= 0;
  //@ ensures elements != null;
  Class(int[] input) {
    n = input.length;
    elements = new int[n];
    arraycopy(input, 0, elements, 0, n);
    //@ assert n >= 0;
  }
  
  //@ requires srcOff >= 0;
  //@ requires destOff >= 0;
  //@ requires length >= 0;
  //@ requires dest.length >= destOff + length;
  //@ requires src.length >= srcOff + length;
  //@ ensures dest.length == \old(dest.length);
  //@ ensures length == \old(length) ==> length >= 0;
  //@ ensures dest != null;
  private static void arraycopy(/*@ non_null @*/ int[] src,
                                int   srcOff,
                                /*@ non_null @*/ int[] dest,
                                int   destOff,
                                int   length) {
     
     //@ loop_invariant destOff+i >= 0;
     //@ loop_invariant srcOff+i >= 0;
     //@ loop_invariant length >= 0;
     for(int i=0 ; i<length; i=i+1) {
        dest[destOff+i] = src[srcOff+i];
    }
  }

一种解决方案是使函数
arraycopy
非静态,但我不明白为什么。

验证程序无法确定类变量是否随着函数对
n
元素的可见性而改变。因此,它应该需要一个类似

//@ ensures n == \old(n)
//@ ensures elements == \old(elements)
这是一个问题,原因有两个:

  • 在Java中,静态方法无法访问非静态变量的值,因此JML无法证明以下规范(显示工具限制)
  • 第二个
    确保
    可能会导致将
    元素作为
    src
    参数提供给
    arraycopy
    时出现一些问题
  • 为了避免修改函数签名,您需要在每次
    arraycopy
    函数调用之后添加
    asure
    规范

    //@ ensures n == \old(n)
    //@ ensures elements == \old(elements)
    
    // ...
    //@ ensures n == \old(n)
    //@ ensures elements == \old(elements)
    private static void arraycopy( /* ... */ ) {