OO_JML_单元总结

OO_JML_单元总结

概述

  本单元作业主要学习的是规格化设计,即契约式编程,主要工作是根据所给出的JML规格描述,实现相应接口来满足功能需求。而本次作业在实现接口的同时要注意对数据结构的把控,并对功能实现算法进行优化,减少云心那个时间,避免出现TLE。

 

一、梳理JML语言的理论基础、应用工具链情况

理论基础

  JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。JML是一种行为接口规格语言 (Behavior Interface Specification Language,BISL),基于Larch方法构建。BISL提供了对方法和类型的规格定义 手段。所谓接口即一个方法或类型外部可见的内容。JML主要由Leavens教授在Larch上的工作,并融入了Betrand Meyer, John Guttag等人关于Design by Contract的研究成果。近年来,JML持续受到关注,为严格的程序设计提供 了一套行之有效的方法。通过JML及其支持工具,不仅可以基于规格自动构造测试用例,并整合了SMT Solver等工具 以静态方式来检查代码实现对规格的满足情况。

  我的理解其意义是采用统一规范的模块功能描述语言,避免采用自然语言而产生二义性,从而导致问题产生。

JML语法

1.注释结构

  JML以javadoc注释的方式来表示规格,每行都以@起头。有两种注释方式,行注释和块注释。其中行注释的表示方式为 //@annotation ,块注释的方式为 /* @ annotation @*/ 。

2.JML表达式
  • 原子表达式
    • \result表达式:表示一个非 void 类型的方法执行所获得的结果,即方法执行后的返回值。

    • \old( expr )表达式:用来表示一个表达式 expr 在相应方法执行前的取值。

    • ... ...

  • 量化表达式
    • \forall表达式:全称量词修饰的表达式,表示对于给定范围内的元素,每个元素都满足相应的约束。

    • \exists表达式:存在量词修饰的表达式,表示对于给定范围内的元素,存在某个元素满足相应的约束。

    • ... ...

  • 操作符
    • 子类型关系操作符

    • 等价关系操作符

    • 推理操作符

    • ... ...

3.方法规格
  • 前置条件(pre-condition):前置条件通过requires子句来表示: requires P。

  • 后置条件(post-condition):后置条件通过ensures子句来表示: ensures P。

4.类型规格
  • 不变式(invariant)是要求在所有可见状态下都必须满足的特性,语法上定义 invariant P ,其中 invariant 为关键词, P 为谓词。对于类型规格而言,可见状态(visible state)是一个特别重要的概念。

  • 状态变化约束(constraint)对象的状态在变化时往往也许满足一些约束,这种约束本质上也是一种不变式。

具体语法在此

应用工具链

  • openJML:可以根据JML对实现进行语法检查和静态检查。

  • JMLUnitNG:可以根据JML自动生成对应的测试样例,用于进行单元化测试。

 

二.部署SMTSolver,至少选择3个主要方法来尝试进行验证,报告结果

测试程序如下:

  1 public class MyPath1 implements Path {
  2     // Iterable<Integer>和Comparable<Path>接口的规格请参阅JDK
  3     //@ public instance model non_null int[] nodes;
  4     private ArrayList<Integer>
  5             nodes = new ArrayList<>();
  6     //@ ensures \result == nodes.length;
  7     public /*@pure@*/int size(){
  8         return nodes.size();
  9     }
 10  11     /*@ requires index >= 0 && index < size();
 12       @ assignable \nothing;
 13       @ ensures \result == nodes[index];
 14       @*/
 15     public /*@pure@*/ int getNode(int index){
 16         return nodes.get(index);
 17     }
 18  19     //@ ensures \result == (\exists int i; 0 <= i && i < nodes.length; nodes[i] == node);
 20     public /*@pure@*/ boolean containsNode(int node){
 21         return nodes.contains(node);
 22     }
 23  24  25     /*@ ensures (\exists int[] arr; (\forall int i, j; 0 <= i && i < j && j < arr.length; arr[i] != arr[j]);
 26       @             (\forall int i; 0 <= i && i < arr.length;this.containsNode(arr[i]))
 27       @           && (\forall int node; this.containsNode(node); (\exists int j; 0 <= j && j < arr.length; arr[j] == node))
 28       @           && (\result == arr.length));
 29       @*/
 30     public /*pure*/ int getDistinctNodeCount(){
 31         ArrayList<Integer> tempList = new ArrayList<>();
 32         Iterator<Integer> it = this.iterator();
 33         while (it.hasNext()) {
 34             int temp = it.next();
 35             if (!tempList.contains(temp)) {
 36                 tempList.add(temp);
 37             }
 38         }
 39         return tempList.size();
 40     }
 41  42     /*@ also
 43       @ public normal_behavior
 44       @ requires obj != null && obj instanceof Path;
 45       @ assignable \nothing;
 46       @ ensures \result == (((Path) obj).nodes.length == nodes.length) &&
 47       @                      (\forall int i; 0 <= i && i < nodes.length; nodes[i] == ((Path) obj).nodes[i]);
 48       @ also
 49       @ public normal_behavior
 50       @ requires obj == null || !(obj instanceof Path);
 51       @ assignable \nothing;
 52       @ ensures \result == false;
 53       @*/
 54     public boolean equals(Object obj){
 55         if (!(obj instanceof Path)) {
 56             return false;
 57         }
 58         if (this.size() != ((Path) obj).size()) {
 59             return false;
 60         }
 61         for (int i = 0; i < this.size(); i++) {
 62             if (this.getNode(i) != ((Path) obj).getNode(i)) {
 63                 return false;
 64             }
 65         }
 66         return true;
 67     }
 68  69     //@ ensures \result == (nodes.length >= 2);
 70     public /*@pure@*/ boolean isValid(){
 71         if (this.size() >= 2) {
 72             return true;
 73         } else {
 74             return false;
 75         }
 76     }
 77     
 78     public MyPath1(int[] nodeList) {
 79         for (int i = 0; i < nodeList.length; i++) {
 80             nodes.add(nodeList[i]);
 81         }
 82     }
 83  84     @Override
 85     public Iterator<Integer> iterator() {
 86         return nodes.iterator();
 87     }
 88  89     @Override
 90     public int compareTo(Path o) {
 91         for (int i = 0; i < o.size() && i < this.size(); i++) {
 92             if (o.getNode(i) > this.getNode(i)) {
 93                 return -1;
 94             } else if (o.getNode(i) < this.getNode(i)) {
 95                 return 1;
 96             }
 97         }
 98         if (o.size() == this.size()) {
 99             return 0;
100         } else if (o.size() > this.size()) {
101             return -1;
102         } else {
103             return 1;
104         }
105         /*
106         Iterator<Integer> itThis = this.iterator();
107         Iterator<Integer> itOo = o.iterator();
108         int temp1, temp2;
109         while (itThis.hasNext()) {
110             temp1 = itThis.next();
111             temp2 = itOo.next();
112             if (temp1 > temp2) {
113                 return 1;
114             } else if (temp1 < temp2) {
115                 return -1;
116             }
117         }
118          */
119     }
120 121     @Override
122     public int hashCode() {
123         return this.nodes.hashCode();
124     }
125 126     //@ ensures containsNode(nodeId) ==> \result == Math.pow(4, (nodeId % 5 + 5) % 5);
127     //@ ensures !containsNode(nodeId) ==> \result == 0;
128     public /*@pure@*/ int getUnpleasantValue(int nodeId){
129         if(containsNode(nodeId)) {
130             return (int)Math.pow(4, (nodeId % 5 + 5) % 5);
131         }
132         else {
133             return 0;
134         }
135     }
136 }

 

转载于:https://www.cnblogs.com/Sraey7-blog/p/10908257.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值