JML理论基础

jml是基于一阶谓词逻辑来对类进行形式化描述的语言,jml语言通过表达式、方法规格、类规格三个部分来进行描述。其中表达式是在java语言的基础上扩展了非修改类型的表达式;方法规格中包括了前置条件、后置条件、副作用作用范围三个部分;类规格包含不变式和状态变化约束两个部分。jml相较于自然语言而言,可以消除歧义,同时配合相关工具进行形式化验证。

jml方法规格写法举例

 /*@ public normal_behavior  //正常行为规格
@ requires (\exists int i; 0 <= i && i < acquaintance.length; //前置条件
@ acquaintance[i].getId() == person.getId());
@ assignable \nothing; //副作用范围
@ ensures (\exists int i; 0 <= i && i < acquaintance.length; //后置条件
@ acquaintance[i].getId() == person.getId() && \result == value[i]);
@ also
@ public normal_behavior
@ requires (\forall int i; 0 <= i && i < acquaintance.length;
@ acquaintance[i].getId() != person.getId());
@ ensures \result == 0;
@*/

JML工具链

目前能用的jml工具链不多,我在本单元使用了openjml和jmlunitng两种工具

openjml使用

openjml使用过程中槽点相当之多,包括jdk版本、大量报错,静态检查巨慢等...

除了用官网的简单代码的测试外,我是用魔改了的MyPerson类来进行了静态测试,结果如下:

可以看到有很多奇怪的报错,后面我用原版的MyPerson执行

java -jar $opjml/openjml.jar  -cp ../../explaintion/package/offical.jar -esc MyPerson.java

结果如下

可以看到时间相当长,而且报了7个奇怪的错误,怀疑可能是opjml支持性的问题

为了证明opjml的效果,我改了一下MyPerson的getId()方法

结果如下

可以看到静态检查确实发现了问题,但是有价值的错误信息混在大量无意义的信息中无疑加大了阅读难度

openjml总结

虽然opjml能够发现问题,但是时间长、报错多的问题使得它并不是特别实用

jmlunitng使用

jmluniting的使用由于Group一直报错,我就自己写了一个MainClass来测试。

MainClass代码如下:

public class MainClass{
private /*@spec_public@*/ int id;
private /*@spec_public@*/ String s;
/*@ assignable id;
@ ensures id == \old(id)+1;
@*/
public void addid(){
id++;
} /*@ requires num>=0;
@ assignable id;
@ ensures id == \old(id)+num;
@*/
public void main(int num){
if(num<0||num>150) return;
for(int i=1;i<=num;i++){
addid();
} } /*@ requires ins!= null;
@ assignable s;
@ ensures !s.equals(ins);
@*/
public void setString(String ins){
this.s = ins;
} /*@ requires ss != null;
@ assignable \everything;
@ ensures id == 0 && s==ss;
@*/
public MainClass(String ss){
s=ss;
id=0;
} }

使用如下的指令来进行测试:

java -jar %opjml%/jmlunitng.jar MainClass.java
javac -cp %opjml%/jmlunitng.jar *.java
java -jar %opjml%/openjml.jar -rac MainClass.java //生成openjml的断言
java -cp .;%opjml%/jmlunitng.jar MainClass_JML_Test
pause

运行结果

可以看到主要对于边界数据进行了一些测试,其实按照官方文档的说法是可以在生成的代码里面添加自己想要测试的数据的,但是这样的化其实会比写junit好一点,自己写junit的话如果理解错误就凉凉了。

代码分析

第一次作业

非常简单,自己写了一个并查集,其余的就是一步步按照jml来,这也为后来的错误埋下了伏笔

第二次作业

同样非常简单,就是把理按照jml一步步来,把某些事件复杂度大的方法稍加修改,结果由于第一次的getPerson采用遍历的方式,导致强测直接原地爆炸,强测0分。

第三次作业

这次作业复杂一些,我先理解完了jml后然后再按照自己的方法来写,其中把queryAgeSum、queryMiPath、queryStrongLink三个方法的实现封装在了Work里面。

测试&bug分析

在这个单元中可以说吃了测试不全的大亏,导致三次作业分数都非常不理想。

黑盒测试

黑盒测试是我这次在互测中采用的主要方法,我的测试主要由两部分构成,一部分是数据生成器,一部分是对拍器。对排器比较简单,主要讲讲数据生成生成。我本来是随机生成的,后来第一次作业观摩了房内某个基本道道全中的dalao的数据,发现采用不同权重的随机数,对于权重高的数据每次生成一小批,例如

A
A
A
B
C
C
C
B

这种,同时尽可能多的把图变得稠密,这样也能增加数据的强度。

在本单元的测试中,前两次我都是用黑盒测试来互相测试,第三次我利用黑盒和同学的代码进行对拍。比较血亏的是我以为queryAgeSum的缩写是qas结果导致本地一个数组开小的错误没有测出,互测中数据强度也不太够,只刀了4个人。

白盒测试(Junit)

本单元,我觉得Junit测试有一定风险,如果对jml理解错误就会导致一些比较尴尬的情况。我觉得junit测试方面有两个心得,一个是要尽可能多的覆盖掉所有代码路径,这样能够比较大限度地判断已经完成代码逻辑与没有问题。另外一个方面是尽可能多地覆盖数据的情况,对数据进行分类,比如采用判断表法或者数据等价类划分能够很好地解决黑盒测试中难以生存的某些边界数据问题。

总结

在本单元的学习中,我对于形式化验证的方法有了一定了解,但也认识到形式化验证还存在效率不高等问题。同时本单元的连续多次踩坑,也让我更加注重测试的重要性,对测试代码的迭代也让我了解了许多测试的方法。当然本单元学习还是有一些遗留问题,比如为什么jml的是如此设计的,为什么通过前置和后置条件副作用就能完美地描述一个方法,这其实有赖于对于公理逻辑系统的理解,希望以后有空能去看看相关论文深入了解下。

OO第三单元小结的更多相关文章

  1. oo第三单元学习总结

    OO第三单元小结 一.JML语言理论基础及工具链梳理 在本单元我们学习了JML语言的一些基础知识,能够让我们看懂简单的JML规格并写出对应代码, 主要用到的知识点有:   1.requires 该子句 ...

  2. OO第三单元作业总结

    OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...

  3. 规格化设计——OO第三单元总结

    规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 ​ JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.J ...

  4. 【OO学习】OO第三单元作业总结

    [OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...

  5. OO第三单元(地铁,JML)单元总结

    OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...

  6. OO第三单元——基于JML的社交网络总结

    OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...

  7. OO第三单元作业——魔教规格

    OO第三单元作业--魔教规格 JML的理论基础和相关工具   JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...

  8. OO第三单元个人总结

    OO第三单元个人总结 JML理论与基础与应用工具链 JML是什么? Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约设计方法 和Larch ...

  9. 2020 OO 第三单元总结 JML语言

    title: 2020 OO 第三单元总结 date: 2020-05-21 10:10:06 tags: OO categories: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...

随机推荐

  1. 比特币市场活跃,VAST发行在即!

    截至1月25日13:30,BTC合约多空持仓人数比为1.44,市场做多人数占据优势:季度合约基差保持在1255美元上方,永续合约资金费率为正,交割及永续合约持仓总量为19.5亿美元,总体上多军占优:B ...

  2. 算法型稳定币USDN有什么价值和用途?

    USDN的标签是"数字美元",与大多数稳定资产一样,USDN是一种金融服务产品.基于NGK公链发行的算法型稳定币USDN,USDN是和美元1:1锚定的加密数字货币,1USDN等于1 ...

  3. Unity 定点投射固定高度抛物线

    假设同一平面中有AB两点,A点向B点水平射击,很容易想象子弹会沿由A指向B的向量方向前进,经过时间t后到达B点,若此时A点不再水平射击,改为以抛物线的方式向B点投射,同样需要在时间t后击中B点,那么如 ...

  4. iOS 兼容性处理

    1. scroll滑动层,在iOS中滑动不流畅的处理 -webkit-overflow-scrolling:touch; //在滑动层标签添加这个样式 2. iOS 系统中input标签,去掉圆角效果 ...

  5. oracle 查看 FK constraint referenced_table及columns

    select uc.table_name, uc.r_constraint_name, ucc.table_name, listagg(ucc.column_name, ',') within gro ...

  6. nacos服务注册之服务器端Raft

    Raft是持久化,数据存储在\nacos\data\naming\data目录 nacos启动后首先从数据存储目录加载数据 Raft协议中节点只有一个LEADER,只有LEADER节点负责数据写入,F ...

  7. Python3.x 基础练习题100例(11-20)

    练习11: 题目: 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 分析: 兔子的规律为数列1,1,2, ...

  8. 一文读懂clickhouse集群监控

    更多精彩内容,请关注微信公众号:后端技术小屋 一文读懂clickhouse集群监控 常言道,兵马未至,粮草先行,在clickhouse上生产环境之前,我们就得制定好相关的监控方案,包括metric采集 ...

  9. TorchVision Faster R-CNN 微调,实战 Kaggle 小麦检测

    本文将利用 TorchVision Faster R-CNN 预训练模型,于 Kaggle: 全球小麦检测 上实践迁移学习中的一种常用技术:微调(fine tuning). 本文相关的 Kaggle ...

  10. Java安全初学之反射

    前言: 复现fastjson的时候深深意识到了需要好好学习一下Java和Java安全,激情的学习了一番java安全中重要的几部分:反序列化.反射.rmi.动态代理,从反射开始做个总结. 反射:java ...