How to implement repeat untill (condition) loop in promela?

时光怂恿深爱的人放手 提交于 2019-12-24 07:58:49

问题


Which would be right approach to do :

repeat{
...
} until(<condition>)

in Promela ?

I have tried :

do::
 //..
(condition) -> break;
od

and

do ::
  //..
  if::(condition) -> break;
  else
  fi;
od

回答1:


Your first attempt is incorrect, because if <condition> is not true the process will simply block forever.

Your second attempt is functionally correct. Personally, I would prefer a minor variant to your solution which does not drop the true entry condition for executing the bulk code.


Given

repeat{
    // bulk code
} until(<condition>)

you have the following options:

  • do:

    do
        :: true ->
            // bulk code
            if
                :: <condition> ->
                    break;
                :: else;
            fi;
    od;
    

    or

    do
        :: true ->
            // bulk code
            if
                :: ! <condition>;
                :: else ->
                    break;
            fi;
    od;
    
  • goto:

    L1:
        // bulk code
        if
            :: <condition>;
            :: else
                -> goto L1;
        fi;
    

    or

    L1:
        // bulk code
        if
            :: ! <condition>
                -> goto L1;
            :: else;
        fi;
    
  • unless (do not use!):

    do
        :: true ->
            d_step {
                // bulk code
            }
    od unless { <condition> };
    

    Note that there are two catches with this approach:

    • it assumes that the value of <condition> is altered within // bulk code and not anywhere else in the code (e.g. by some other process)

    • depending on the content of // bulk code, it might not possible to use d_step at all.

    Only in the case in which the instruction altering the evaluation of <condition> is precisely the last one inside // bulk code then one is allowed to drop d_step without affecting the semantics.

    To see why this is the case, observe the behaviour of Spin on the following code example:

    active proctype example()
    {
        int cc = 0;
        do
            :: true ->
                printf("before %d\n", cc);
                cc++;
                printf("after  %d\n", cc);
        od unless { cc == 3 };
    }
    

    which has the following output:

    ~$ spin test.pml 
          before 0
          after  1
          before 1
          after  2
          before 2
    1 process created
    

    since cc++ alters the evaluation of cc == 3 but is not the last instruction of the code sequence, the statement after 3 is never printed on screen.


EDIT:

Of course one could also try another variant of code with the unless statement, e.g.

bool flag;
do
    :: true ->
        // bulk code
        flag = true;
        flag = false;
od unless { flag && <condition> };

This is obviously always correct, even in the general case, but it clogs the source code with additional variables that are not part of the original problem, so I would still discourage the use of unless to replace do/until.

Here is an example of how to use it:

active proctype example()
{
    int cc = 0;
    bool flag = false;
    do
        :: true ->
            printf("before %d\n", cc);
            cc++;
            printf("after  %d\n", cc);
            flag = true;
            flag = false;
    od unless { flag && (cc == 3) };
}

and indeed it yields the correct output:

~$ spin test.pml 
      before 0
      after  1
      before 1
      after  2
      before 2
      after  3
1 process created


来源:https://stackoverflow.com/questions/46581311/how-to-implement-repeat-untill-condition-loop-in-promela

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!