peterson算法的verilog实现详见另一篇博客
peterson算法转换为NuSMV语法表示,代码如下:
#主模块
MODULE main
VAR
#标签定义
VAR turn : boolean; #礼让标志turn
interested : array 0..1 of boolean; #期望标志interested
P0 : process user(FALSE,self); #利用子模块user实例化P0、P1;self将当前模块作为参数传递
P1 : process user(TRUE,self);
ASSIGN
#变量初始化
init(turn) := FALSE;
init(interested[0]) := FALSE;
init(interested[1]) := FALSE;
#规范
CTLSPEC AF (interested[0] & turn & P0.state = L4)
CTLSPEC AG !(P0.state = L4 & P1.state = L4)
CTLSPEC AG (interested[0] -> AF (P0.state = L4))
CTLSPEC AG (interested[1] -> AF (P1.state = L4))
LTLSPEC G !(P0.state = L4 & P1.state = L4)
LTLSPEC G (interested[0] -> F (P0.state = L4))
LTLSPEC G (interested[1] -> F (P1.state = L4))
INVARSPEC !(P0.state = L4 & P1.state = L4)
#公平性
FAIRNESS !(P0.state = L4)
FAIRNESS !(P0.state = L0)
FAIRNESS !(P1.state = L4)
FAIRNESS !(P1.state = L0)
MODULE user(select,sup) #子模块user;select识别进程,sup传入主模块
VAR
state : {L0,L1,L2,L3,L4,L5};#状态语句组
ASSIGN
init(state) := L0;
#状态变迁
next(state) :=
case
state = L0 :{L0,L1};#非关键区域
state = L1 :L2;
state = L2 :L3;
state = L3 & (!sup.interested[!select ? 1 : 0] | !(select xor sup.turn)):L4;
state = L4 :{L4,L5};#关键区域
state = L5 :L0;
TRUE :state;
esac;
#主模块标签变迁
next(sup.interested[0]) :=
case
state = L1 & !select :TRUE;
state = L5 & !select :FALSE;
TRUE :sup.interested[0];
esac;
next(sup.interested[1]) :=
case
state = L1 & select :TRUE;
state = L5 & select :FALSE;
TRUE :sup.interested[1];
esac;
next(sup.turn) :=
case
state = L2 :!select;
TRUE :sup.turn;
esac;
FAIRNESS running
代码中公平约束限制了P0、P1不能无限的停留在非关键区域或非关键区域。
- CTL公式的第一条规范表示未来总会有P0的期望标志和礼让标志为true,且处于关键区域。
- 第二条表明P0、P1不会同时进入关键区域。
- 第三、四条表明一旦进程期望进入关键区域,那么未来它一定会进入关键区域。
- 其余规范类似。
这里选择了批处理模式进行检测,将规范写入了NuSMV代码块中,也可以采用NuSMV的交互模式对规范逐一进行检测,检测结果如下:
由运行结果可知,除第一个规范外其余规范都为true,结果同样给出了规范一的反例。