合约(contract)
在进行Check的时候,会执行contract内的验证内容,验证代码逻辑是否有效
格式说明
-
contract格式:
node 结点名 ( 输入变量 ) returns ( 输出变量 ) ;
(*@contract
\quad 验证结点方法的方法
*)
let
\quad 结点方法
tel -
验证结点方法的方法:可以定义var、const、assum、guarantee、mode或者import一个外部的contract
-
mode 格式:
mode 名称 (
\quad require 约束条件;
\quad ensure 验证结果;
);不同的mode内的约束条件互不影响
-
var 格式:
var 变量名 -
const 格式:
const 常量名 -
assume 格式
assume 约束条件(可以是一个布尔值true/false,也可也是一个结果为布尔值的公式,如 2 < 3 )
-
guarantee 的格式:
guarantee 验证结果(可以是一个布尔值true/false,也可也是一个结果为布尔值的公式,如 a < b )
对于real类型的变量,在和数值比较大小或赋值的时候,数值一定要带小数,比如a < 0.0,如果写作a < 0则会报错无法执行
范例一
问题描述:验证两个数相乘的代码,如果两个数均为零,则结果一定也为零
代码:
node times (lhs, rhs: real) returns (res: real) ;
(*@contract
mode absorbing (
require lhs = 0.0 or rhs = 0.0 ;
ensure res = 0.0 ;
) ;
*)
let
res = lhs * rhs ;
tel
Check结果:
._one_mode_active为什么Answer结果为falsifiable我暂时不太理解,对目前的验证不是很重要,所以没仔细研究,等我明白了再回来补充
范例二
问题描述:不使用mode,验证两个数相乘的代码,如果两个数均不为零,则结果一定也不为零
代码:
node times (lhs, rhs: real) returns (res: real) ;
(*@contract
assume lhs <> 0.0 and rhs <> 0.0;
guarantee res <> 0.0 ;
*)
let
res = lhs * rhs ;
tel
Check结果:
- assume后面写上假设的前提条件
- guarantee后面写上,当上述的前提条件满足时,要验证的式子是否有效
- a <> b表示a不等于b
范例三
问题描述:验证两个数相乘的代码,如果两个数均为零,则结果一定也为零;如果两个数都大于零或都小于零,则结果一定大于零;如果两个数一个大于零,一个小于零,则结果一定小于零。
代码:
node times (lhs, rhs: real) returns (res: real) ;
(*@contract
const zero = 0.0;
mode absorbing (
require lhs = zero or rhs = zero ;
ensure res = zero ;
) ;
mode positive (
require (
rhs > zero and lhs > zero
) or (
rhs < zero and lhs < zero
) ;
ensure res > zero ;
) ;
mode pos_neg (
require (
rhs > zero and lhs < zero
) or (
rhs < zero and lhs > zero ) ; ensure res < zero ; ) ;
*)
let
res = lhs * rhs ;
tel
Check结果:
import一个contract的方法
问题描述:验证两个数相乘的代码,如果两个数均为零,则结果一定也为零
代码:
contract test (lhs, rhs: real) returns (res: real) ;
let
mode absorbing (
require lhs = 0.0 or rhs = 0.0 ;
ensure res = 0.0 ;
) ;
tel
node times (lhs, rhs: real) returns (res: real) ;
(*@contract
import test (lhs, rhs) returns (res) ;
*)
let
res = lhs * rhs ;
tel
Check结果: