Cygwin PROCELA SPIN在proctype错误中未实现

Cygwin PROCELA SPIN在proctype错误中未实现,cygwin,mutual-exclusion,model-checking,spin,promela,Cygwin,Mutual Exclusion,Model Checking,Spin,Promela,我对SPIN和Promela非常陌生,我在尝试验证模型中的liveness属性时遇到了这个错误 错误代码: unreached in proctype P (0 of 29 states) unreached in proctype monitor mutex_assert.pml:39, state 1, "assert(!((mutex>1)))" mutex_assert.pml:42, state 2, "-end-"

我对SPIN和Promela非常陌生,我在尝试验证模型中的liveness属性时遇到了这个错误

错误代码:

unreached in proctype P
        (0 of 29 states)
unreached in proctype monitor
        mutex_assert.pml:39, state 1, "assert(!((mutex>1)))"
        mutex_assert.pml:42, state 2, "-end-"
        (2 of 2 states)
unreached in init
        (0 of 3 states)
unreached in claim ltl_0
        _spin_nvr.tmp:10, state 13, "-end-"
        (1 of 13 states)

pan: elapsed time 0 seconds
代码基本上是彼得森算法的实现,我检查了安全性,它似乎是有效的。但是每当我尝试使用ltl{[](wait->(cs))}验证liveness属性时,就会出现上述错误。我不知道他们的意思,所以我不知道如何继续

我的代码如下:

#define N 3
#define wait   (P[1]@WAIT)
#define cs     (P[1]@CRITICAL)

int pos[N]; 
int step[N]; 
int enter;
byte mutex;
ltl {[]((wait -> <> (cs)))}

proctype P(int i) {
  int t;
  int k;
  WAIT:
  for (t : 1 .. (N-1)){
  pos[i] = t
  step[t] = i
  k = 0;
  do
  ::  atomic {(k != i && k < N && (pos[k] < t|| step[t] != i)) -> k++}
  ::  atomic {k == i -> k++}
  ::  atomic {k == N -> break}
  od;
  }

CRITICAL:
  atomic {mutex++;
  printf("MSC: P(%d) HAS ENTERED THE CRITICAL SECTION.\n", i);
  mutex--;}
  pos[i] = 0;
}

init {
  atomic { run P(0); }
}
#定义N 3
#定义等待(P[1]@wait)
#定义cs(P[1]@临界)
int pos[N];
整数步[N];
输入;
字节互斥;
ltl{[](等待->(cs))}
程序类型P(int i){
int t;
int k;
等待:
对于(t:1..(N-1)){
pos[i]=t
步骤[t]=i
k=0;
做
::原子{(k!=i&&kk++
::原子{k==i->k++}
::原子{k==N->break}
od;
}
关键:
原子{mutex++;
printf(“MSC:P(%d)已进入临界段。\n”,i);
互斥--;}
pos[i]=0;
}
初始化{
原子{runp(0);}
}

一般答案

这是一个警告告诉您,由于从未进行转换,某些状态无法访问

一般来说,这不是一个错误,但仔细查看您所建模的每个例程的不可到达状态,并检查您是否期望它们都不可到达,这是一个良好的实践。i、 e.如果模型不正确,则wrt。预期的行为

注意。您可以在特定代码行前面使用标签end:来标记有效的终止状态,以消除这些警告,例如当您的过程未终止时。更多信息


具体答案

我无法复制你的输出。特别是通过跑步

~$ spin -a file.pml
~$ gcc pan.c
~$ ./a.out -a
我得到了与您不同的以下输出:

(Spin Version 6.4.3 -- 16 December 2014)
    + Partial Order Reduction

Full statespace search for:
    never claim             + (ltl_0)
    assertion violations    + (if within scope of claim)
    acceptance   cycles     + (fairness disabled)
    invalid end states  - (disabled by never claim)

State-vector 64 byte, depth reached 47, errors: 0
       41 states, stored (58 visited)
       18 states, matched
       76 transitions (= visited+matched)
        0 atomic steps
hash conflicts:         0 (resolved)

Stats on memory usage (in Megabytes):
    0.004   equivalent memory usage for states (stored*(State-vector + overhead))
    0.288   actual memory usage for states
  128.000   memory used for hash table (-w24)
    0.534   memory used for DFS stack (-m10000)
  128.730   total actual memory usage


unreached in proctype P
    (0 of 29 states)
unreached in init
    (0 of 3 states)
unreached in claim ltl_0
    _spin_nvr.tmp:10, state 13, "-end-"
    (1 of 13 states)

pan: elapsed time 0 seconds
特别是,我缺少有关监视器进程中未实现状态的警告。就我而言,从源代码来看,我得到的警告都没有问题

您使用的是与我不同的Spin版本,或者您的问题中没有包含完整的源代码。在后一种情况下,您能否编辑您的问题并添加代码?之后我会更新我的答案


编辑:在评论中,您询问以下消息是什么意思:“索赔ltl\u 0\u spin\u nvr.tmp:10,状态13中未实现,”-end-”

如果打开文件\u spin\u nvr.tmp,您可以看到下面的Promela代码,它对应于一个Büchi自动机,该自动机只接受所有违反ltl属性[]((等待->(cs))的执行

never ltl_0{/*!([](!((P[1]@WAIT)))|(((P[1]@CRITICALщщ)))*/
T0_init:
做
:(!(!((P[1]@WAIT))&((P[1]@CRITICAL))->转到接受
::(1)->转到T0_init
od;
接受_S4:
做
:(!((P[1]@CRITICAL))->转到接受
od;
}

该消息只是警告您,此代码的执行永远不会到达最后一个结束括号}(state“-end-”),这意味着该过程永远不会终止。

非常感谢!是的,我在把代码发布到这里之前最后一次编辑了我的代码,这似乎已经修复了它。下面的代码是什么意思?我以为这是错误的一部分?索赔ltl_0 _spin_nvr.tmp:10,状态13,“-end-”@firearian我更新了我的帖子以回答您的问题。再一次,请务必理解这里没有错误。非常感谢!这回答了我的问题!不过,如果可以的话,我会再做一点跟进。我是否理解,这意味着ltl属性得到了成功验证,因为该过程从未进入“从不ltl_0”@firearian以验证模型M是否满足ltl公式F,Spin生成一个与F的求反相对应的Buchi自动机,并计算其与自动机M的同步积[我简化了一点]。如果后一个产品包含一个验收周期,那么您的属性F有一个反例。否则,您的系统是安全的。一般来说,严格来说,执行Buchi自动机的某些转换并不相关,而是在接受路径上是否有执行。因此,关注您的示例,这意味着M+never ltl_0模型的同步乘积的执行永远不会进入标记为accept_S4的状态。但是,执行仍然通过以下代码进入状态::(1)->goto T0_init(它在其上循环)。
never ltl_0 {    /* !([] ((! ((P[1]@WAIT))) || (<> ((P[1]@CRITICAL))))) */
T0_init:
    do
    :: (! ((! ((P[1]@WAIT)))) && ! (((P[1]@CRITICAL)))) -> goto accept_S4
    :: (1) -> goto T0_init
    od;
accept_S4:
    do
    :: (! (((P[1]@CRITICAL)))) -> goto accept_S4
    od;
}