OO第三单元总结--根据JML写代码
一. JML语言
1. 理论基础
首先,JML不是JAVA的一部分,它是一群研究者为JAVA设计的扩展部分,但还没有得到官方的支持。因此,JAVA编译器并不支持JML,所以要想JML起作用,只能采用类似openJML这样的第三方来编译,将JML 规格编译为运行时检查的语句,即RAC code(runtime assertion checking)。如果代码实现与其JML规格不一致,将引发运行时JML exception。
JML遵从契约式设计范式(DBC),Design by contract是软件开发的一种方法,核心是类与其客户之间达成契约。JML是一种形式化的、 面向 JAVA的行为接口规格语言。
推荐一篇step by step以一个比较复杂的例子来讲解JML语法和设计的教程:https://www.ibm.com/developerworks/library/j-jml/
2. 应用工具链
- jmlrac: test for violations of assertions during execution
- ESC/Java2: static verification; compile-time proving that contracts are never violated
- jmldoc: javadoc-style documentation
- jmlc: assertion-checking compiler
- jml4c: a new JML compiler built upon the Eclipse JDT open-source platform
上述工具很多都已经不再维护(跟不上java的升级,大多支持到java 1.5), 看大家抱怨openJML坑,就想找找有没有更好用的JML工具,结果发现openJML竟然是最好用的。
- openJML:目前对JML支持最好,维护最积极的JML编译器了
- jmlunit/jmlunitNG: unit testing tool
二. 部署SMT Solver
maven+openJML+Eclipse试了一下午还是报错,命令行没试过,不知道怎么样,这一部分只好放弃了。
二. JMLUnitNG
下述过程可复现,代码和运行结果是一致的,如果有兴趣,可以参照我的步骤在本地试一试。
配置过程参见讨论区https://course.buaaoo.top/assignment/71/discussion/199 ,为了保证配置成功,我也是在Linux下配置。
Graph接口方法的规格几乎全部含有 \exists 或 \old,根本搞不了,于是只能退而求其次,去验证Path类。Path类里面的\sum等语法也不支持,于是我就模仿MyPath,写了个比减法稍复杂的demo。
// yifan/MyPath.java
package yifan; public class MyPath {
private/*@ spec_public @*/ int[] nodes; public MyPath(int[] nodeList) {
nodes = new int[nodeList.length];
for (int i = 0; i < nodeList.length; i++) {
nodes[i]=nodeList[i];
}
} //@ ensures \result == nodes.length;
public /*@pure@*/ int size() {
return nodes.length;
} /*@ requires index >= 0 && index < size();
@ assignable \nothing;
@ ensures \result == nodes[index];
@*/
public /*@pure@*/ int getNode(int index) {
return nodes[index];
} //@ ensures \result == (nodes.length >= 2);
public /*@pure@*/ boolean isValid() {
return nodes.length >= 2;
} public static void main(String args[]) {
return;
}
}
运行过程 step-by-step:
./jmlunitng yifan/MyPath.java
javac -cp jmlunitng.jar yifan/**/*.java
./openjml -rac yifan/MyPath.java
javac -cp jmlunitng.jar yifan/MyPath_InstanceStrategy.java
java -cp jmlunitng.jar yifan.MyPath_JML_Test
运行前目录
运行后目录
运行结果
结果讨论
- MyPath(null),MyPath.java中会调用length,错误,意料之中;
- 明明已经requires index>=0了,为什么生成的测试例子里还会有负数?就算刚开始nodes=new int[10],避免nodes为null的情况还是这种结果;
- 似乎JmlUnitNG只会生成int的边界值和0,不管requires? 这只是我的猜想。
有个问题需要讨论一下:
- 为什么不写成
//@ public instance model non_null int[] nodes;
private ArrayList<Integer> nodes;
openJML会把规格和实现里的nodes当成一个nodes,会报错。
那这么写不就行了吗?
//@ public instance model non_null int[] nodes;
private ArrayList<Integer> myNodes;
非也,会报下述错误
yifan/MyPath.java:6: 警告: JML model field is not implemented: nodes
//@ public model int[] nodes;
^
nodes没实现?对的。要想解决这个问题,就得写抽象函数,可以看看这篇论文https://digitalcommons.utep.edu/cgi/viewcontent.cgi?referer=https://www.google.com.hk/&httpsredir=1&article=2073&context=cs_techrep ,我大概写了个抽象函数,没bug,但也没起作用,还是报nodes没实现的错误,所以这里就不贴我的抽象函数了。
从上图可以看到如果不实现nodes,大多数方法都被skip掉了。
三. 架构设计
1. 第一次作业
直接继承接口,简单地实现了两个类。
2. 第二次作业
为了更改方便,直接ctrl+v把MyPathContiner的代码复制到MyGraph。
3. 第三次作业
由于第二次作业比较复杂,再去动很可能出bug,于是在写第三次作业的时候对于第二次作业已有的代码我一行都没动,只是在MyGraph类里加了求连通块个数的Public的函数。这样一来bug少了,但新加的架构和已有的架构看起来很不协调。
看了std码之后,惊呼:我之前竟将所有代码都直接放在src文件夹下。好的分层设计应该像标程一样,起码得有多个文件夹吧,比如base,core,util,grpha等。
四. bug和修复情况
三次作业均无bug。
五. 心得体会
撰写:规格的撰写用到了很多离散数学的知识,掌握常见的几种模式后,就能够比较容易地写出一些简单函数的规格。以我目前的水平看,写代码还是要比写规格来得容易。
理解:实操中,我实际上是先看的指导书,对于含混的地方,(比如起点和终点相同的情况下,算不算换乘,最小费用算多少?同一路径中如果有环该怎么算?)我会去详细阅读规格,因为规格严谨的描述了某一个方法该干什么。(但这次直觉上的理解实际上更靠谱,比如同一路径中有环的情况,直觉上的理解是不用非得绕着环走一圈多余的路,但死扣规格,确实得绕,事后证明是老师或助教的规格写错了)。
JML和JmlunitNG:JML设计期望太高,其目的是写出规格后,就可以自动生成测试用例,还可直接检查代码是否准确实现了规格;但相关工具链及其难用,功能及其有限,目前我只能写个简单的demo探索一下它的性质,体验一下整个流程。
OO第三单元总结--根据JML写代码的更多相关文章
- OO第三单元(地铁,JML)单元总结
OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...
- OO第三单元作业总结
OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...
- OO第三单元个人总结
OO第三单元个人总结 JML理论与基础与应用工具链 JML是什么? Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约设计方法 和Larch ...
- oo第三单元学习总结
OO第三单元小结 一.JML语言理论基础及工具链梳理 在本单元我们学习了JML语言的一些基础知识,能够让我们看懂简单的JML规格并写出对应代码, 主要用到的知识点有: 1.requires 该子句 ...
- OO第三单元——基于JML的社交网络总结
OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...
- 2020 OO 第三单元总结 JML语言
title: 2020 OO 第三单元总结 date: 2020-05-21 10:10:06 tags: OO categories: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...
- OO第三单元作业(JML)总结
OO第三单元作业(JML)总结 目录 OO第三单元作业(JML)总结 JML语言知识梳理 使用jml的目的 jml注释结构 jml表达式 方法规格 类型规格 SMT Solver 部署JMLUnitN ...
- OO第三单元——JML规格化设计
OO第三单元--JML规格化设计 JML语言的理论基础以及应用工具链情况 理论基础 JML是对JAVA程序进行规格化设计的一种表示语言,是一种行为接口规格语言.JML整合了Java和JAVAdoc,并 ...
- 【OO学习】OO第三单元作业总结
[OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...
随机推荐
- SAP CRM和Cloud for Customer中的Event handler(事件处理器)
SAP CRM可以在开发工具中用右键直接创建一个新的事件处理器: 这些事件处理器实际上就是UI控制器(Controller)上具有特定接口类型的方法. C4C UI的event handler 在C4 ...
- forward reference extends over definition of value
在scala代码中定义了一个方法,,刚开始直接代码中报错,,后来编译是一直报错,最后只是在sc.stop后边加了一个中括号解决,方法体不能放在main主函数中
- Jquery中children与find之间的区别
<table id="tb"> <tr> <td>0</td> <td>1</td> <td>2 ...
- OPENCV3 命名空间等变化
CV_VERSION 表示的opencv的版本号 命名空间变化: 可以通过增加 #include <cv.h> 解决 1 直接去掉CV_ 前缀 1) nameWindow 函数 C ...
- Word转html并移植到web项目
1.打开对应word文件 建议使用web视图查看文档 这样可以提前预览转转成html样式 2.如果有图片修改图片大小及格式 在web视图下,把图片调制适当大小,不然导出的html可能图片较小 3.点击 ...
- 任务五:零基础HTML及CSS编码(二)
面向人群: 零基础或初学者 难度: 简单 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合理性,但即使如此,真正决定课 ...
- POJ-2442-Sequence(二叉堆)
POJ-2442 Description Given m sequences, each contains n non-negative integer. Now we may select one ...
- catalina配置参数
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.por ...
- 嵩天老师的零基础Python笔记:https://www.bilibili.com/video/av15123607/?from=search&seid=10211084839195730432#page=25 中的42-45讲 {字典}
#coding=gbk#嵩天老师的零基础Python笔记:https://www.bilibili.com/video/av15123607/?from=search&seid=1021108 ...
- Spring核心技术(十)——JSR-330标准注解
从Spring 3.0开始,Spring开始支持JSR-330标准的注解(依赖注入).这些注解和Spring注解扫描的方式是一直的,开发者只需要在classpath中配置相关的jar包即可. 如果开发 ...