Model 如何将这些更改为NuSMV模型中的CTL规范?

Model 如何将这些更改为NuSMV模型中的CTL规范?,model,logic,model-checking,ctl,nusmv,Model,Logic,Model Checking,Ctl,Nusmv,我需要帮助写这些CTL。我还不知道如何用NuSMV格式写,希望我的代码对你有意义,因为它是不完整的 2) 如果一个进程正在等待,它最终将到达其关键部分 CTLSPEC AG (proc1.waiting -> AF proc1.critical); CTLSPEC AG ((proc1.critical -> AX A[!proc1.critical U proc2.critical]) & (proc2.critical -> AX A[!pr

我需要帮助写这些CTL。我还不知道如何用NuSMV格式写,希望我的代码对你有意义,因为它是不完整的

2) 如果一个进程正在等待,它最终将到达其关键部分

CTLSPEC AG (proc1.waiting -> AF proc1.critical);
CTLSPEC AG ((proc1.critical -> AX A[!proc1.critical U proc2.critical]) &
           (proc2.critical -> AX A[!proc2.critical U proc1.critical]));
3) 这两个过程必须“轮流”进入临界段

CTLSPEC AG (proc1.waiting -> AF proc1.critical);
CTLSPEC AG ((proc1.critical -> AX A[!proc1.critical U proc2.critical]) &
           (proc2.critical -> AX A[!proc2.critical U proc1.critical]));
4) 一个过程有可能连续两次进入临界段(在另一个过程进入临界段之前)

5) 过程1进入临界段的连续入口将被至少n个循环隔开,其中n是某个常数。您应该为n选择一个合适的值,并且应该验证这个值(即,不反证)

6) 2更多您选择的非平凡属性

MODULE thread1(flag2,turn)
VAR
   state : {W0,F1,W1,T1,F2,Wait,F3,C1,T2,F4};
   flag1 : boolean;

ASSIGN
   init(state) := W0;
   next(state) :=
case
   state = W0                 : F1;  
   state = F1                 : W1;  
   state = W1 & flag2         : T1; 
   (state = W1) & !flag2      : C1;  
   (state = T1)&(turn = 2)    : F2;  
   (state = T1)&(turn != 2)   : W1;  
   (state = F2)               : Wait; 
   (state = Wait)&(turn = 1)  : F3;   
   (state = Wait)&(turn != 1) : Wait; 
   (state = F3)               : W1; 
   (state = C1)               : T2; 
   (state = T2)               : F4; 
   (state = F4)               : W0;
    TRUE : state;
esac;

init(flag1) := FALSE;
next(flag1) := 
case
   state = F1 | state = F3 : TRUE;  
   state = F2 | state = F4 : FALSE; 
   TRUE                    : flag1;
esac;

DEFINE
  critical := (state = C1);
  trying := (state = F1 | state = W1 | state = T1 | state = F2 |     state = Wait | state = F3);  

MODULE thread2(flag1,turn)
VAR
   state1 : {N0,N1,N2,N3,N4,Wait1,N5,Critical1,N7,N8};
   flag2 : boolean;

ASSIGN
   init(state1) := N0;
   next(state1) :=
case
   (state1 = N0)               : N1;  
   (state1 = N1)               : N2;  
   (state1 = N2) & flag1       : N3;  
   (state1 = N2) & !flag1      : Critical1;
   (state1 = N3) & (turn = 1)  : N4;  
   (state1 = N3) & (turn != 2) : N2;  
   (state1 = F4)               : Wait1; 
   (state1 = Wait1)&(turn = 2) : N5;   
   (state1 = Wait1)&(turn != 2): Wait1; 
   (state1 = N5)               : N2; 
   (state1 = Critical1)        : N7; 
   (state1 = N7)               : N8;
   (state1 = N8)               : N0;
    TRUE : state1;
esac;

init(flag2) := FALSE;
next(flag2) := 
case
   state1 = N1 | state1 = N5 : TRUE;  
   state1 = N4 | state1 = N8 : FALSE;
   TRUE                    : flag2;
esac;

DEFINE
  critical := (state1 = Critical1);
  trying := (state1 = N1 | state1 = N2 | state1 = N3 | state1 = N4 |     state1 = Wait1 | state1 = N5);  

MODULE main

VAR

turn: {1, 2};
proc1: process thread1(proc2.flag2,turn);
proc2: process thread2(proc1.flag1,turn);

ASSIGN

init(turn) := 1;
next(turn) := 
case
   proc1.state = T2 : 2;
   proc2.state1 = N7 : 1;
   TRUE : turn;
esac;

SPEC 

AG !(proc1.critical & proc2.critical); 
--two processes are never in the critical section at the same time

SPEC 
AG (proc1.trying -> AF proc1.critical);

注意:在回答中全面介绍CTL是不现实的。除了关于NuSMV/nuXmv的快速而肮脏的课程之外,您还可以从以下内容中受益:提供CTL模型检查的理论背景


CTL操作员

为简单起见,假设您的程序具有唯一的初始状态

CTL运算符的语义如下:

  • AF P在所有可能的执行路径中,迟早会出现
  • AGP在所有可能的执行路径中,P始终为
  • axp在所有可能的执行路径中,在下一个状态中P为真
  • A[puq]在所有可能的执行路径中,p为真*,直到Q为真(至少一次)

  • EF p在至少一个执行路径中,迟早会是真的

  • 例如P在至少一个执行路径中,P始终为
  • EX P在至少一个执行路径中,在下一个状态中P为真
  • E[P U Q]在至少一个执行路径中,P为真*,直到Q为真(至少一次)
*:直到为真也是在p永远不为真的路径上,前提是Q立即得到验证。[另见:

如果有多个
初始状态,CTL属性在每个初始状态都为true时保持不变


属性:

请注意,由于您的NuSMV模型目前已损坏,这似乎是一个家庭作业,因此我将为您提供属性的伪代码版本,并将其保留在您自己的代码中

  • 如果一个进程正在等待,那么它最终将到达其关键部分

    CTLSPEC AG (proc1.waiting -> AF proc1.critical);
    
    CTLSPEC AG ((proc1.critical -> AX A[!proc1.critical U proc2.critical]) &
               (proc2.critical -> AX A[!proc2.critical U proc1.critical]));
    
    解释:括号的内容与您阅读的句子完全相同。我添加了AG,因为该属性必须明确适用于模型中的每个可能状态。如果忽略它,则模型检查器将简单地测试
    proc1.waiting->AF proc1.critical
    在initi中是否为真艾尔州

  • 这两个过程必须“轮流”进入临界段

    CTLSPEC AG (proc1.waiting -> AF proc1.critical);
    
    CTLSPEC AG ((proc1.critical -> AX A[!proc1.critical U proc2.critical]) &
               (proc2.critical -> AX A[!proc2.critical U proc1.critical]));
    
    解释:让我假设这种编码是有效的,因为proc1和proc2仅在一种状态下处于临界区。
    proc1.critical->AX A[!proc1.critical U proc2.critical]
    的思想如下:“如果过程1处于临界段,则从下一状态开始,过程1将永远不会(再次)处于临界段,直到过程2处于临界段”

  • 一个过程有可能连续两次进入临界段(在另一个过程进入临界段之前)

    解释:与前一个类似。在这里我使用EF,因为它满足属性只保留一次的要求

  • 过程1进入临界段的连续条目将被至少n个循环隔开,其中n是某个常数。您应该为n选择一个合适的值,并且应该对该值进行验证(即,不反证)

    编辑:我删除了此编码,因为我再次认为我编写的公式比要求的强得多。但是,我认为不可能使用E运算符来削弱它,因为它将变得比要求的弱得多。目前我想不出除了修改您的模式之外的其他可能的替代方法我要数一数循环的次数,不管那意味着什么


代码不起作用。我建议您在考虑编写CTL公式之前先修复代码,因为您需要一个统一的模型。嗯,是的,每当我运行它时,它都会告诉我第88行“proc1.state”"是未定义的,因为thread1hmmm中没有名为state的变量好的,所以如果我将其更改为proc1.state1,则会出现错误proc2.state1,但我将其定义为proc2.state。您可以命名这两个状态,变量是它们所在模块范围的局部变量。我看不到您在电话中提到的错误,在哪一行?顺便说一下Hen即使我尝试CTLSPEC,它也会给我一个错误,所以我只是用spec编写它有区别吗?@Darkflame你会得到什么错误,你使用什么命令来检查属性?--注意,我更新了我的答案。另外一个问题是,“等待”是与“临界”一样正确的状态之一也是另一个状态…在信号量示例中,它有一些