精华内容
下载资源
问答
  • PROMELA
    千次阅读
    2019-08-07 13:42:05

    并发系统的Promela语言建模与SPIN model checker

    promela: https://blog.csdn.net/xlrtx/article/details/39971051

    spin: https://blog.csdn.net/ganggexiongqi/article/details/5794293

    更多相关内容
  • 三分之一共识阿尔戈特姆的验证。 由Hassan S. Matar和Suha Orhun Mutluergil(c)2013开发 算法伪代码 初始化: Xp := Vp 回合r: 建议零售价: send <Xp> to all processes ... if | HO (p,r)| > 2n / 3 then ...
  • spin和promela简介

    热门讨论 2011-04-08 23:00:43
    对spin和promela做了个简单总结,还有些简单例子
  • 在以下项目中使用:Python,Java,Matlab,Alloy,Promela Java项目: 电路(单个) 重新创建类以构建电路板: 电路 容器 器具 开发面板模拟器以实现电路系统 毕业(个人) 创建了一个使用以下课程保存课程的程序: ...
  • Traffic-Lights-Promela

    2021-06-09 18:26:57
    交通灯-Promela SVVT 项目-2。 在 Promela 中模拟交通灯。
  • 一个关于SPIN和Promela的简要介绍
  • 并发系统的Promela语言建模与SPIN模型检测
  • SPIN’s Promela to Java Compiler, with help from Stratego
  • 并发系统Promela语法规则,并发系统建模和SPIN的使用
  • Promela轻松入门教程

    千次阅读 2014-10-10 22:47:20
    最近在学并发开发, 里面需要用到Promela语言来检测代码的逻辑 Promela用起来很麻烦, 不过网上有个GUI

    最近在学并发开发, 里面需要用到Promela语言来检测代码的逻辑


    Promela用起来很麻烦, 不过网上有个Windows GUI程序, 里面还带了很多例子代码, 稍微看看就可以懂了


    工具名称叫JSpin, 在这里下载

    https://code.google.com/p/jspin/


    安装起来很简单, 安装好之后, 打开安装目录下的config文件, 吧Mingw路径配置好就可以了.


    打开程序运行, 随便找个示例代码跑下, 如果编译不成功, 那么就在他的Run.bat前面加上这行


    SET PATH=%path%;c:/path_of_mingw/bin


    你可以在安装目录下找到用户手册jspin-user.pdf


    一般检测并发代码需要检测下面三项

    1.互斥(Mutual exclusion)

    2.无死锁(Free from Deadlock)

    3.无饥饿(Free from starvation)


    在这个工具里面, 你可以用assert()来进行检测, 也可以自己写LTL(线性时间逻辑)来检测,

    你可以打开里面的 dekker.pml 学习下如何使用它们来检测

    pml语言的语法略奇葩,不过看看就会, active proctype 就是声明一个线程

    /* Dekker's algorithm */
    bool    wantp = false, wantq = false;
    byte    turn = 1;
    bool csp = false, csq = false;
    
    ltl { []<>csp && []<>csq }
    
    active proctype p() {
        do
        ::  wantp = true;
            do
            :: !wantq -> break;
            :: else ->
                if
                :: (turn == 1)
                :: (turn == 2) ->
                    wantp = false;
                    (turn == 1);
                    wantp = true
                fi
            od;
            csp = true;
            assert (!(csp && csq));
            csp = false;
            wantp = false;
            turn = 2
        od
    }
    
    active proctype q() {
        do
        ::  wantq = true;
            do
            :: !wantp -> break;
            :: else ->
                if
                :: (turn == 2)
                :: (turn == 1) ->
                    wantq = false;
                    (turn == 2);
                    wantq = true
                fi
            od;
            csq = true;
            assert (!(csp && csq));
            csq = false;
            wantq = false;
            turn = 1
        od
    }
    


    线性时间逻辑就是在逻辑的基础上加上了时间的概念, []表示永远是1, <>表示在未来终究会出现1 等等

    http://web.iitd.ac.in/~sumeet/slide3.pdf

    https://www.youtube.com/watch?v=KVQdTjvtyUw


    dekker.pml中的
    ltl { []<>csp && []<>csq }
    表示的意思就是
    永远会反反复复的进入p的critical section && 永远会反反复复的进入q的critical section
    这句话就是用来检测starvation的, 如果程序有能力反复执行p而不执行q(无论几率多么小), jspin都会报错


    检测ltl的时候请选择acceptance模式.


    测试starvation的时候去掉weak fairness
    意思就是:允许一个能够反复执行的进程无限反复执行,每次都是他执行, 而不让其他的进程执行(在现实的计算机cpu中是不现实的)
    如果你的程序有了starvation freedom的话, 那么就会保证上述的情况永远不会出现


    展开全文
  • 本文档包含停止等待协议以及AB协议的PROMELA语言描述,帮助我们理解上述两个协议有很大的帮助。
  • Promela BCL-6 A Protocol

    2007-07-26 19:05:00
    /**PROMELAValidationModel*协议层验证**验证BCL可靠性协议Aversion5.0**Yuhuang*2007-7-26*//**本版本特点:采用集合点来通信,允许ACK、DATA丢包,实现了队列自动重发。*加入了对传输介质的模拟。...
    /*
    *PROMELAValidationModel
    *协议层验证
    *
    *验证BCL可靠性协议Aversion5.0
    *
    *Yuhuang
    *2007-7-26
    */

    /*
    *本版本特点:采用集合点来通信,允许ACK、DATA丢包,实现了队列自动重发。
    *加入了对传输介质的模拟。介质可以丢包,导致包失序。
    *
    *未完全模拟的问题:ACK、DATA失序问题
    */


    /* *************数据结构定义************ */

    /* 序号范围定义 */
    # defineWIN9
    /*
    发送队列大小定义 */
    # defineQSIZE4


    /* 消息类型定义 */
    mtype
    = {ACK , DATA}


    /*
    *{ACK,s_seqno}
    */
    chansevts
    = [ 0 ]of{mtype , byte};
    chanrevts
    = [ 0 ]of{mtype , byte};


    /*
    *{DATA,r_seqno}
    *数据队列
    */
    chansdata
    = [ 0 ]of{mtype , byte};
    chanrdata
    = [ 0 ]of{mtype , byte};


    /* 发送记录队列 */
    /* 当ACK发生的时候,ACK(含)之前的内容都被清除 */
    bytehead_seq;
    bytetail_seq;
    bytecur_seq;
    /*
    #defineinc(x)(x=(x+1)%WIN)
    */



    proctypesender2media()
    {
    byteseq;

    do
    :: sdata ? DATA , seq ->
    if
    :: rdata ! DATA , seq
    :: skip
    fi
    od
    }


    proctypereceiver2media()
    {
    byteseq;
    do
    :: revts ? ACK , seq ->
    if
    :: sevts ! ACK , seq
    :: skip
    fi
    od
    }







    proctypesender(byteid)
    {

    bytes;

    head_seq
    = 0 ;
    tail_seq
    = 0 ;
    cur_seq
    = 0 ;

    do
    :: (tail_seq + WIN - head_seq + 1 ) % WIN != QSIZE -> /* 队列不为满,允许发送 */
    if
    :: sdata ! DATA , cur_seq /* normalsendaction */
    fi;

    progress_2
    : cur_seq = (cur_seq + 1 ) % WIN;
    tail_seq
    = (tail_seq + 1 ) % WIN;; /* 更新tail,head保持不变 */

    :: sevts ? ACK , s ->
    /* 进行ACK失序处理 */
    /* 若s不在当前的head_seq~tail_seq范围内,则简单忽略之 */
    if
    :: (head_seq < tail_seq) -> /* 顺序递增情景 */
    if
    :: (s > tail_seq || s < head_seq) ->
    gotoendofack
    :: else
    fi
    :: (head_seq > tail_seq) -> /* 非递增情景 */
    if
    :: (s < head_seq && s > tail_seq) ->
    gotoendofack
    :: else
    fi
    :: else
    fi;

    assert (s < WIN);
    head_seq
    = (s + 1 ) % WIN; /* 根据ACK更新head_seq,暗含了累积更新 */
    cur_seq
    = head_seq;
    endofack
    : skip



    :: ((cur_seq != tail_seq) && (tail_seq - head_seq) != 0 ) ->
    /* 队列不为空,允许发送.此情景配合timeout时重发使用 */
    /* 第一个判断是为了防止发送不存在内容 */

    if
    :: sdata ! DATA , cur_seq /* normalsendaction */
    fi;
    cur_seq
    = (cur_seq + 1 ) % WIN;

    :: timeout -> /* 超时 */
    /* 更新指针,准备重发队列 */
    cur_seq
    = head_seq;
    /* 尝试重发队列 */
    if
    :: sdata ! DATA , cur_seq /* normalsendaction */
    fi;
    cur_seq
    = (cur_seq + 1 ) % WIN; /* 发送了一个包,更新cur_seq */
    /* 这里不用更新tail_seq,因为这个值只在有新的包加入到队列的时候才更新 */
    od
    }


    proctypereceiver(byteid)
    {
    byteexpected_seqno;
    bytes;

    expected_seqno
    = 0 ;

    do
    :: rdata ? DATA , s ->
    if
    :: (s != expected_seqno) -> /* 非期望数据包 */
    if
    :: revts ! ACK , (expected_seqno + WIN - 1 ) % WIN /* someackswaslost,ackagain! */
    fi
    :: (s == expected_seqno) -> /* 期望数据包 */
    if
    :: revts ! ACK , expected_seqno -> /* ack */
    expected_seqno
    = (expected_seqno + 1 ) % WIN
    fi
    fi

    od

    }


    init
    {
    atomic{
    runsender(
    0 );
    runsender2media();
    runreceiver(
    1 );
    runreceiver2media();
    }

    }
    展开全文
  • Promela BCL-6 B4.0 Protocol [Incomplete]

    千次阅读 2007-07-27 19:56:00
    /** PROMELA Validation Model* 协议层验证** 验证BCL可靠性协议B version4.0** Yuhuang* 2007-7-27*//** 本版本特点:采用集合点来通信,允许CHK、RTT、ACK、DATA丢包,实现了队列自动重发。* 加入了对...
    /*
    * PROMELA Validation Model
    * 协议层验证
    *
    * 验证BCL可靠性协议B version4.0
    *
    * Yuhuang
    * 2007-7-27
    */





    /*
    * 本版本特点:采用集合点来通信,允许CHK、RTT、ACK、DATA丢包,实现了队列自动重发。
    *    加入了对传输介质的模拟。介质可以丢包,导致包失序。
    *    加入了对传输介质中存在延迟阻塞的模拟。包可以失序。
    *    
    *    加入对CHK的语义实现、接收方向发送方的失序模拟。 
    */






    /*
    * 测试记录: 
    * WIN=5 QSIZE=2 跑了大约_秒钟
    * WIN=7 QSIZE=3 跑了大约_分钟
    * WIN=9 QSIZE=4 ???
    */





    /* ************* 数据结构定义 ************ */


    /*  序号范围定义  */
    # define WIN 7
    /*
     发送队列大小定义  */
    # define QSIZE 3
    /*
    Note:上面是比较保险的做法: WIN = QSIZE * 2 + 1 */

    /*  消息类型定义  */
    mtype 
    =  { ACK , DATA , RRT , CHK }


    /*  
     * { ACK|RRT,res|version, seqno }
     
    */
    chan sevts 
    =  [ 0 ] of { mtype , byte , byte };
    chan revts 
    =  [ 0 ] of { mtype , byte , byte };


    /*
     * { DATA|CHK, res|version, seqno} 
     * 数据队列 
     
    */
    chan sdata 
    =  [ 0 ] of { mtype , byte , byte };
    chan rdata 
    =  [ 0 ] of { mtype , byte , byte };

    /*
     * 为实现阻塞模拟,需要定义复合类型数组
     
    */
    typedef Msg{
        mtype type;
        byte version;
        byte seqno;
    };


    /*  发送记录队列  */
    /*  当ACK发生的时候,ACK(含)之前的内容都被清除  */
    byte head_seq;
    byte tail_seq;
    byte cur_seq;
    /*
    #define inc(x) (x=(x+1)%WIN)
    */

    /*  接收方期望系列号  */
    byte expected_seqno;




    /*  进程说明:
     * 1. sender2media    发送方到接收方的介质模拟进程
     * 2. receiver2media     接收方到发送方的介质模拟进程
     * 3. sender        发送方进程
     * 4. receiver        接收方进程
     
    */

    proctype sender2media()
    {
        byte seq;
        byte v;
        mtype type;
        
        
    /*  阻塞队列  */
        Msg msg[QSIZE];
        
    /*  flag语义:
         *     flag[i] = 0的时候,表示msg[i] 为空
         *     flag[i]  = m (m>0) 的时候,表示从msg[i]被阻塞以来,没有被阻塞的包的个数为m
         * flag用法:
         *     (1)每次收到一个消息,将不为零的flag[i]逐个加一
         *    (2)发现某个flag[i] 的值大于等于QSIZE时必须将其从阻塞队列中取出,进行发送或丢弃,转4
         *    (3)随机选择一个不为空的阻塞Msg,将其从阻塞队列中取出,进行发送或丢弃
         *    (4)flag子序列结束
        
    */
        byte flag[QSIZE];    
        byte i;    
    /*  记录随机数下标用  */
        byte j;    
    /*  产生随机数用  */
        
        
        
    do
        
    :: sdata ? type , v , seq  ->

            
    /*  不为空者逐个加一  */
            i 
    =   0 ;
            j 
    =   0 ;    
            
    do
            
    ::  i  <  QSIZE  ->
                
    if
                
    :: flag[i]  !=   0   ->
                    flag[i] 
    =  flag[i]  +   1
                
    :: else   ->  skip
                fi;
                i 
    =  i  +   1
            
    ::   else   break
            od;
            
    /* 寻找需要立即处理的Msg  */
            i 
    =   0 ;
            j 
    =   0 ;
            
    do
            
    ::  i  <  QSIZE  ->
                
    if
                
    :: (flag[i]  ==  QSIZE - 1 ->
                    
    if
                    
    :: rdata ! msg[i] . type , msg[i] . version , msg[i] . seqno ->
                        flag[i] 
    =   0
                    fi                
                
    :: else   ->  skip
                fi;
                i 
    =  i  +   1 ;
            
    ::   else   break
            od;    
            
    /*  随机选择一个不为空的阻塞Msg,将其从阻塞队列中取出,进行发送或丢弃 */
            i 
    =   0 ;
            j 
    =   0 ;
            
    do
            
    ::  i  <  QSIZE  ->
                
    if
                
    :: flag[i]  !=   0   ->
                    
    if
                    
    :: rdata ! msg[i] . type , msg[i] . version , msg[i] . seqno  ->
                        flag[i] 
    =   0 ;
                    
    :: skip
                    fi            
                
    :: skip
                fi;
                i 
    =  i  +   1
            
    ::   else   break
            od;        
            
            
    /*  阻塞或传递当前的数据包  */
            i
    = 0 ;
            j
    = 0 ;
            
    if
            
    :: skip  ->      /*  阻塞这个数据包 */
                
    /*  随机选择一个空位  */
                
    do
                
    :: j >= 0   ->
                    j 
    =  (j  +   1 %  QSIZE
                
    :: skip  ->
                    i 
    =  j;         /* 获得随机数  */
                    
    break     
                od;

                
    if
                
    :: flag[i] == 0   ->      /* Msg[i]为空,可以放下一条阻塞消息 */
                    msg[i]
    . type  =  type;
                    msg[i]
    . version  =  v;
                    msg[i]
    . seqno  =  seq;
                    flag[i] 
    =   1 ;     /* 标记Msg[i] 中已经存有消息 */
                    goto endofsend    
    /*  信息已经阻塞,无须发送  */
                    
                
    :: else ->      /*  Msg[i]中已有一条消息,且不阻塞这条消息了  */
                    
    if
                    
    :: rdata ! type , v , seq
                    
    :: skip
                    fi
                fi;
    endofsend
    :         skip
            
    :: skip  ->      /*  直接传递或丢弃数据包  */         
                
    if
                
    :: rdata ! type , v , seq
                
    :: skip
                fi
            fi
        od
    }


    proctype receiver2media()
    {
        byte seq;
        byte v;
        mtype type;
        
        
    do
        
    :: revts ? type , v , seq  ->
            
    if
            
    :: sevts ! type , v , seq
            
    :: skip
            fi
        od
    }



    /*
    * 发送方
    * 发送两类消息: DATA(数据) 、CHK( 缓冲区可用性检查) 

    * 接受两类消息: ACK( 确认) 、RRT(请求重传) 
    */
    proctype sender()
    {

        byte s;
        byte version;
        byte rrt_version;
        
        head_seq 
    =   0 ;
        tail_seq 
    =   0 ;
        cur_seq 
    =   0 ;
        
        rrt_version 
    =   0 /*  init rrt version number  */
        
        
    do
        
    :: (tail_seq + WIN - head_seq + 1 ) % WIN  !=  QSIZE  ->      /*  队列不为满,允许发送 */
            
    if
            
    :: sdata ! DATA , 0 , cur_seq     /*  normal send action  */
            fi;
            
    progress_2
    :     cur_seq = (cur_seq + 1 ) % WIN;
            tail_seq
    = (tail_seq + 1 ) % WIN;;     /*  更新tail,  head保持不变  */
        


        
    :: sevts ? ACK , version , ->
            
    /*  进行ACK失序处理  */
            
    /*  若s不在当前的head_seq~tail_seq范围内,则简单忽略之  */
            
    if
            
    :: (head_seq  <  tail_seq)  ->      /* 顺序递增情景  */
                
    if
                
    :: (s  >  tail_seq  ||  s  <  head_seq )  ->
                    goto endofack
                
    :: else
                fi
            
    :: (head_seq  >  tail_seq)  ->      /*  非递增情景  */
                
    if
                
    :: ( s  <  head_seq  &&  s  >  tail_seq )  ->
                    goto endofack
                
    :: else
                fi
            
    :: else   ->      /*  队列为空   */
                goto endofack    
    /*  此ACK是在介质中被延迟了的ACK, 简单丢弃之  */
            fi;
            
            
    assert (s < WIN);
            head_seq 
    =  (s  +   1 ) % WIN;     /*  根据ACK更新head_seq,暗含了累积更新  */
            cur_seq 
    =  head_seq;
            
    endofack
    :     skip
            
        
    :: sevts ? RRT , version , ->
            
    if
            
    :: (version  ==  rrt_version)  ->      /*  预期rrt */
                
    /*  将发送链上s(eqno)之前的数据都摘除  */
                
    /* 发送链上 s之后的所有数据都重发,rrt_version加1   */
                
                head_seq 
    =  s;     /*  注意:  由于是响应 RRT消息,不要写成了head_seq =(s + 1)%WIN  */
                cur_seq 
    =  head_seq;     /*  调整发送指针,准备重发  */
                
                rrt_version 
    =  (rrt_version  +   1 %  WIN     /*  inc(rrt_version);  */
                
            
    ::   else   ->      /*  接受到非预期rrt  */
                skip    
    /*  简单丢弃之  */
            fi
        
        
    :: ((cur_seq  !=  tail_seq)  &&  (tail_seq  -  head_seq)  !=   0  )  ->     
        
    /*  队列不为空,允许发送. 此情景配合timeout时重发使用  */                                     
        
    /*  第一个判断是为了防止发送不存在内容  */
            
    if
            
    :: sdata ! DATA , 0 , cur_seq     /*  normal send action  */
            fi;        
            cur_seq
    = (cur_seq + 1 ) % WIN;    
            
            
        
    :: timeout  ->      /*  超时  */
            sdata
    ! CHK , rrt_version , head_seq;  /*  超时,发CHK消息,查询是否需要重发  */
        od
    }



    /*
    * 接收方
    * 发送两类消息: ACK( 确认) 、RRT(请求重传) 

    * 接受两类消息: DATA(数据) 、CHK( 缓冲区可用性检查) 
    */
    proctype receiver()
    {

        byte s;
        byte v;
        
        
    do
        
    :: rdata ? CHK , v , ->      /* 收到CHK消息 */
            
    if
            
    :: (s  ==  expected_seqno)  ->      /*  chk检查的数据包即为接收方期望的数据包  */
                revts
    ! RRT , v , s     /*  直接返回RRT消息  */


            
    :: ( ( s  <  expected_seqno  &&  expected_seqno - <  WIN / 2  )  ||
                (  s 
    >  expected_seqno  &&  s - expected_seqno  >  WIN / 2 ) )  ->      /*  小于期望包号,ACK之  */
                revts
    ! ACK , 0 , (expected_seqno + WIN - 1 ) % WIN

                
            
    :: else   ->      /*  CHK检查消息错,系统出错  */
                
    printf ( " s=%d exp=%d " , s , expected_seqno);
                
    assert ( false )
            fi


        
    :: rdata ? DATA , v , ->      /*  收到DATA消息,s为消息序列号  */
            
    /*  s 与expected_seqno在队列中前后关系的判断: 
            
            1. if  ( s > expected_seqno && s-expected_seqno < WIN/2 )  or    *normal
                     (  s < expected_seqno && expected_seqno-s > WIN/2) then 
                s'>'expected_seqno            -- 收到的消息(s)排在期待数(expected_seqno)的后面
                
            2. if  ( s < expected_seqno && expected_seqno-s < WIN/2 )  or    *normal
                     (  s > expected_seqno && s-expected_seqno > WIN/2) then 
                s'<'expected_seqno            -- 收到的消息排在期待数的前面 

            3. if( s==expected_seqno ) then
                s'=='expected_seqno            -- 收到的消息等于期待的数 
            
    */
            
    if
            
    :: ( ( s  >  expected_seqno  &&  s - expected_seqno  <  WIN / 2  )  ||
                (  s 
    <  expected_seqno  &&  expected_seqno - >  WIN / 2 ) )  ->          /* 大于 */
                
    /*  在存在丢包的流水环境下,这种情况是完全会出现的,不应该看作系统严重错误 */
                
    /* assert(false)     *//*  非预期消息,系统严重错误  */
                
                
    /*  Yuhuang的方案(2007-7-27):
                简单忽略之
                
    */
                skip
            
    :: ( s  ==  expected_seqno)  ->                          /* 等于 */
                revts
    ! ACK , 0 , expected_seqno;
                expected_seqno 
    =  (expected_seqno + 1 ) % WIN
                        
            
    ::   else   ->                                  /* 小于 */
                revts
    ! ACK , 0 , (expected_seqno + WIN - 1 ) % WIN
                
            fi
                
        od
                

        
    }


    /*  Promela入口程序  */
    init
    {
        atomic{
        run sender();
        run sender2media();
        run receiver();
        run receiver2media();
        }

    }
    展开全文
  • 网络协议簇中,传输控制协议TCP是最重要的协议之一,提供面向连接的可靠传输服务。采用Promela 描述 TCP建立连接和可靠数据传输,并用模型检测工具 Spin,验证 TCP三次握手协议的安全性与可靠数据传 输协议活性的属性。
  • 为了有效地提高网络认证协议建模和验证的效率,基于模型检测方法提出一个通用的网络认证协议模型描述方法,结合模型检测工具SPIN可以方便地进行性质验证。通过一些模型的简化策略,不仅可以对不同协议进行高效建模,...
  • 网络协议分析实验

    2012-05-20 21:34:54
    网络协议分析实验 西南交大
  • 在Eclipse平台上设计并实现了一个基于SPIN的易扩展的模型检测环境ESpin,通过一个优化了的代码分区算法和可迅速支持SPIN升级的文法分析器,构造了一个高效、易扩充的Promela编辑器。编辑器除了支持Promela的全部语法...
  • 协议的验证

    千次阅读 2018-12-18 20:14:30
    对于给定的一个使用PROMELA描述的协议系统,SPIN可以对其执行任意的模拟,也可以生成一个C代码程序,然后对该系统的正确性进行有效检验,并报告系统中出现的死锁,无效的循环,未定义的接受和标记不完全等情况。...
  • 随着嵌入式系统在能源、交通等安全关键领域的广泛应用,针对嵌入式软件的安全...最后使用Promela对故障扩展SysML活动图进行建模,并使用模型检测工具SPIN对其进行分析验证。通过一个燃气灶控制系统验证了此方法的有效性。
  • Promise语法

    2021-05-18 11:31:26
    Promise语法一、回调地狱二、Promise 一、回调地狱 当回调函数嵌套过多的时候出现的问题 没有可维护性和可读性 == 代码没有问题,不是错误的,只是不好进行后期维护 二、Promise 1、Promise的作用 ...
  • 文章目录一、概述二、核心类简介2.1 QuorumCnxManager三、源码解析3.1 选举入口分析3.2 选举初始化3.3 选举流程四、内容总结 一、概述   本篇博文会从 Zookeeper 中 FLE(Fast Leader Election) 算法的代码实现...
  • promela目录包含 Promela 源代码和输出。 src ├── barber │  ├── fifo │  │  ├── monitor │  │  │  ├── Barber.java │  │  │  ├── BarberShop.java │  │  │  └── ...
  • 哲学家进餐问题解决方法

    千次阅读 2020-11-25 19:50:23
    哲学家进餐问题(The Dinning Philosophers Problem)是由荷兰学者Dijkstra提出的经典的同步问题之一。 问题:有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子...
  • windows10 基于Spin的模型检测

    千次阅读 2019-03-13 14:39:46
    本博客主要讲述基于SPIN的模型检测的内容,转载请声明出处! 目录 ...二、Promela语言 2.1 Promela简介 2.2变量和数据类型 2.3进程 2.4通道与消息传递 2.5线性时序逻辑 LTL 及其到自动机的...
  • 课程作业03实验报告

    2017-10-13 22:42:00
    1.程序设计思路 先提示输出字符串,然后定义huiwen函数,先判断0和length-1位的字符是否相等,first=0,length-1=last,然后递推first+1,last-1,直到first=last。 2.程序流程图 3.源程序 ...
  • 在Eclipse平台上设计并实现了一个基于SPIN的易扩展的模型检测环境ESpin,通过一个优化了的代码分区算法和可迅速支持SPIN升级的文法分析器,构造了一个高效、易扩充的Promela编辑器。编辑器除了支持Promela的全部语法...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 174
精华内容 69
关键字:

PROMELA