FSP考试代码参考

索引变量上支持通常的算术运算: 

const N = 1
range T = 0..N
range R = 0..2*N
 
SUM        = (in[a:T][b:T]->TOTAL[a+b]),
TOTAL[s:R] = (out[s]->SUM).

forall的用法: 

||SWITCHES(N=3) =(forall[i:1..N] s[i]:SWITCH).


||SWITCHES(N=3) =(s[i:1..N]:SWITCH).

用这种方法去表示N个客户端加一个服务器的系统模型: 

||N_CLIENT_SERVER(N=2)
  = (forall[i:1..N] c[i]:CLIENT )||{c[i:1..N]}::(SERVER/{call/request , wait/reply})).

 通过这个语法,我们就可以将我们可以将行人中的行为 wander 重新标记为行为 idle,如下所示:

TRAFFIC_LIGHT = (button -> YELLOW | idle -> GREEN),
GREEN = (green -> TRAFFIC_LIGHT),
YELLOW = (yellow -> RED),
RED = (red -> TRAFFIC_LIGHT).
 
PEDESTRIAN = ( button -> PEDESTRIAN
             | wander -> PEDESTRIAN
             ).
 
||LIGHT_PEDESTRIAN = (TRAFFIC_LIGHT || PEDESTRIAN/{idle/wander}).

const N = 4
range T = 0..N
 
VAR = VAR[0],
VAR[u:T] = ( read[u]->VAR[u]
           | write[v:T]->VAR[v]).
 
LOCK = (acquire->release->LOCK).
 
INCREMENT = (acquire->read[x:T]
             -> (when (x<N) write[x+1]
                 ->release->increment->INCREMENT
                )
             )+{read[T],write[T]}.
 
||COUNTER = (INCREMENT||LOCK||VAR)@{increment}.

信号量:

SEMAPHORE(N=0) = SEMA[N],
SEMA[v:Int]    = (up->SEMA[v+1]
                 |when(v>0) down->SEMA[v-1]
                 ).

 信号量和Buffer:

const Max = 5
range Int = 0..Max
 
SEMAPHORE(I=0) = SEMA[I],
SEMA[v:Int]    = (up->SEMA[v+1]
                 |when(v>0) down->SEMA[v-1]
                 ).
 
BUFFER = (put -> BUFFER
         |get -> BUFFER
         ).
 
PRODUCER = (empty.down->put ->full.up ->PRODUCER).
CONSUMER = (full.down ->get ->empty.up->CONSUMER).
 
||BOUNDEDBUFFER = (PRODUCER|| BUFFER || CONSUMER
                  ||empty:SEMAPHORE(5)
                  ||full:SEMAPHORE(0))@{put,get}.

如何使用FSP描述有界缓冲区呢:

BUFFER(N=5) = COUNT[0],
COUNT[i:0..N]
    = ( when (i<N) put -> COUNT[i+1]
      | when (i>0) get -> COUNT[i-1]
      ).
 
PRODUCER = (put -> PRODUCER).
CONSUMER = (get -> CONSUMER).
 
||BOUNDEDBUFFER = (PRODUCER || BUFFER(5) || CONSUMER).

wait-for cycle 是由于所有哲学家都在同一时间需要右边的刀叉造成的,要解决这个问题,一种方法就是让他们有不同的行为。比如,让奇数的哲学家先拿起他们的右叉,偶数的哲学家先拿起他们的左叉: 

PHIL(I=0)
    = ( when (I%2 == 0)
            sitdown -> left.get -> right.get
            -> eat -> left.put -> right.put
            -> arise -> PHIL
      | when (I%2 == 1)
            sitdown -> right.get -> left.get
            -> eat -> left.put -> right.put
            -> arise -> PHIL
      ).

一个简单的资源分配器控制对固定数量的资源的访问(构造函数的参数定义了资源的数量)。线程可以通过参与get[n]的动作向控制器请求n个资源,他们必须在稍后的某个时间点通过调用put[n]来释放这些资源。对get[n]的调用应该暂停,直到有足够的资源可用。你可以假设在调用get时请求的资源数量总是大于0,但永远不会大于资源的总数N。

const N = 10 // number of resources
range T = 1..N // resources requested
const U = 5 // number of users

RESOURCE_USER =
    ( get[n:T] -> use[n] -> put[n] -> RESOURCE_USER ).

RESOURCE_ALLOC = RESOURCE_ALLOC[N],
RESOURCE_ALLOC[r:0..N] =
    // note: index can be zero!
    ( when (r > 0) get[n:1..r] -> RESOURCE_ALLOC[r-n]
    | put[n:T] -> RESOURCE_ALLOC[r+n]
    ). 

在描述整个系统组成之前,我们需要指定一个安全属性与系统组成,以验证汽车在桥上不发生碰撞。下面列出了所需的属性。它规定,当红色汽车在桥上时,只有红色汽车可以进入,当蓝色汽车在桥上时,只有蓝色汽车可以进入。当桥是空的时候,红车或蓝车都可以进入。索引i用来计算目前在桥上的红(或蓝)车。

property ONEWAY =(red[ID].enter   -> RED[1]
                 |blue[ID].enter -> BLUE[1]
                 ),
RED[i:ID] = (red[ID].enter -> RED[i+1]
            |when(i==1)red[ID].exit -> ONEWAY
            |when(i>1) red[ID].exit -> RED[i-1]
            ),
BLUE[i:ID]= (blue[ID].enter -> BLUE[i+1]
            |when(i==1)blue[ID].exit -> ONEWAY
            |when(i>1) blue[ID].exit -> BLUE[i-1]
            ).

抛硬币的有活性要求现在可以表示为: 

progress HEADS = {heads}
progress TAILS = {tails}
progress HEADSorTAILS = {heads,tails}

Action Priority 

 

桥梁模型现在可以计算在两端等待的汽车数量。当汽车请求进入时,这个计数被递增,当汽车进入桥时被递减。我们对修改后的BRIDGE过程的第一次尝试,使用了这种对等待车辆的计数,具体如下。只有当桥上没有蓝色汽车,也没有蓝色汽车在等待时,红色汽车才被允许进入桥上。只有当桥上没有红色汽车,也没有红色汽车在等待进入桥上时,才允许蓝色汽车进入桥上。修订后的BRIDGE流程如下:

/* nr - number of red cars on the bridge
   nb - number of blue cars on the bridge
   wr - number of red cars waiting to enter
   wb - number of blue cars waiting to enter
*/
BRIDGE = BRIDGE[0][0][0][0],
BRIDGE[nr:T][nb:T][wr:T][wb:T] =
  (red[ID].request  -> BRIDGE[nr][nb][wr+1][wb]
  |when (nb==0 && wb==0)
    red[ID].enter   -> BRIDGE[nr+1][nb][wr-1][wb]
  |red[ID].exit     -> BRIDGE[nr-1][nb][wr][wb]
  |blue[ID].request -> BRIDGE[nr][nb][wr][wb+1]
  |when (nr==0 && wr==0)
    blue[ID].enter  -> BRIDGE[nr][nb+1][wr][wb-1]
  |blue[ID].exit    -> BRIDGE[nr][nb-1][wr][wb]
  ).

Readers–Writers Problem

set Actions = {acquireRead,releaseRead,
               acquireWrite,releaseWrite}
READER =
  (acquireRead->examine->releaseRead->READER)
  +Actions
  \ {examine}.
 
WRITER =
  (acquireWrite->modify->releaseWrite->WRITER)
  +Actions
  \ {modify}.
const False = 0   const True = 1
range Bool  = False..True
const Nread = 2           // Maximum readers
const Nwrite= 2           // Maximum writers
 
RW_LOCK = RW[0][False],
RW[readers:0..Nread][writing:Bool] =
      (when (!writing)
         acquireRead ->RW[readers+1][writing]
      |releaseRead   ->RW[readers-1][writing]
      |when (readers==0 && !writing)
         acquireWrite->RW[readers][True]
      |releaseWrite  ->RW[readers][False]
      ).
property SAFE_RW
  = (acquireRead->READING[1]
    |acquireWrite->WRITING
    ),
READING[i:1..Nread]
  = (acquireRead->READING[i+1]
    |when(i>1) releaseRead ->READING[i-1]
    |when(i==1)releaseRead ->SAFE_RW
    ),
WRITING = (releaseWrite->SAFE_RW).
||READWRITELOCK = (RW_LOCK || SAFE_RW).
progress WRITE = {writer[1..Nwrite].acquireWrite}
progress READ  = {reader[1..Nread].acquireRead}
||RW_PROGRESS = READERS_WRITERS
                >>{reader[1..Nread].releaseRead,
                   writer[1..Nread].releaseWrite}.

FSP—流动性

fluent GREEN[i:1..2]
    = <{green[i]}, {yellow[i],red[i]}> initially 1

时间逻辑—“always”

assert ALWAYS_A_COLOUR = [](GREEN || YELLOW || RED)

时间逻辑—“eventually”

assert EVENTUALLY_RED = <>RED

时间逻辑—“next”操作符

assert BUTTON_TO_YELLOW = (button -> X YELLOW)
assert MUST_EXIT
    = forall[i:1..N]
        [](p[i].enter -> <>p[i].exit)

 下面的断言说,进程a和b最终都将获得该资源:

assert EVENTUALLY_ACQUIRE
= (<>a.acquire && <>b.acquire)

下面的断言说,获取资源的进程最终将释放资源的情况永远是这样的:

assert USE_BEFORE_RELEASE
= []((a.acquire -> <>a.release) && (b.acquire -> <>b.release))

 下面的断言说,每当一个进程获得资源时,它会一直持有它,直到另一个进程获得它:

fluent A_HOLDS
= <a.acquire, a.release>
fluent B_HOLDS
= <b.acquire, b.release>
assert HOLDS_UNTIL
= []((A_HOLDS U B_HOLDS) && (B_HOLDS U A_HOLDS))

HMAS Emafor是一艘航空母舰,飞机从它出发执行任务,然后再次降落。为了安全,任何时候跑道上只能有一架飞机。为了确保这一点,飞机加入到达队列(enterArrQ)或离开队列(enterDepQ),等待降落或起飞的机会。两个队列的最大长度都是两个平面。飞机只有在得到空中交通管制员(ATC)的允许后才能起飞或降落。下面的FSP模型描述了这个系统: 

const MaxID = 2
range ID = 0..MaxID - 1

ARRIVE = ARRIVE[0],
ARRIVE[n:ID] = (enterArrQ[n] -> ARRIVE[n+1 % MaxID]).

ARRIVAL_Q = (enterArrQ[n: ID] -> ARRIVAL_Q[n]),
//one plane in queue
ARRIVAL_Q[n0: ID] = 
	(enterArrQ[n: ID] -> ARRIVAL_Q[n0][n]
	| permitLand[n0] ->land[n0] -> ARRIVAL_Q
	),
//two planes in queue
ARRIVAL_Q[n0: ID][n1: ID] = 
	(permitLand[n0] -> land[n0] -> ARRIVAL_Q[n1]).

DEPART = DEPART[0],
DEPART[n: ID] = (enterDepQ[n] -> DEPART[(n+1) % MaxID]).
DEPARTURE_Q = (enterDepQ[n: ID] -> DEPARTURE_Q[n]),
//one plane in queue
DEPARTURE_Q[n0: ID] = 
	(enterDepQ[n: ID] -> DEPARTURE_Q[n0][n]
	| permitTakeoff[n0] -> takeoff[n0] -> DEPARTURE_Q
	),
//two planes in queue
DEOARTURE_Q[n0: ID][n1: ID] = 
	(permitTakeoff[n0] -> takeoff[n0] -> DEPARTURE_Q[n1]).

ACT = 
	(permitLand[n: ID] -> land[n] -> ACT
	| permitTakeoff[n: ID] -> takeoff[n] -> ACT
	).

|| CARRIER = (ARRIVE || ARRIVAL_Q || DEPART || DEPARTURE_Q || ACT) >>{permitLand[ID]}.

property  ARRIVAL_MAX = MAX[MaxID-1],
MAX[m:ID] = 
	(when (m < 1) enterArrQ[n:ID] -> MAX[m+1]
	|when (m > 0) takeoff[n:ID] -> MAX[m-1]
	). 

||SAFE_CARRIER = (CARRIER||ARRIVAL_MAX).


assert TAKEOFF = <>takeoff

墨尔本一家商店有一台卫生纸自动售货机,一次最多可以装5卷卫生纸。三名顾客(C=3)从自动售货机购买卫生纸,每次一卷,除非自动售货机是空的,否则他们会等待重新装满。供应商定期给机器加满油,但只有当机器是空的时候才加。这台机器最初装满了R卷卫生纸。墨尔本会定期封锁,下一个使用机器的顾客会感到恐慌(这是一种行动!),然后买下所有剩下的卫生纸卷。在锁定结束之前,供应商无法重新填充机器,所有其他客户必须等待。写下FSP流程CUSTOMER, SUPPLIER, MACHINE和locked,以及一个复合流程系统来建模这个系统。

const R = 5
const C = 3
const True = 0
const False = 1
range T = 0..R
range Bool = True..False

MACHINE = MACHINE[5],
MACHINE[i:T] = 
	(when (i>0)  opened -> buy[1] -> MACHINE[i-1]
	|when (i==0) opened -> fill -> MACHINE[5]
	|when (i>0)  locked -> buy[i] -> MACHINE[0]
	).

SUPPLIER = (opened -> fill -> SUPPLIER).

CUSTOMER = 
	(opened -> buy[1] -> CUSTOMER
	|locked -> panice -> buy[n:T]-> CUSTOMER
	). 

LOCKED = LOCKED[False],
LOCKED[m:Bool] =
	(when (m == False) locked -> LOCKED[True]
	|when (m == True) opened -> LOCKED[False]
	).

||SYSTEM = (LOCKED||SUPPLIER||c[i:1..C]:CUSTOMER||{c[i:1..C]}::MACHINE)
/{locked/{[c:1..C].locked} , opened/{[c:1..C].opened}}.

以下是FSP对水位传感器的描述:

/*
* FSP code for a sensor that monitors a tank volume and checks
* whether the level is low, high, or ok.
*/
// The readings of the level are assumed to be provided by an
// external process; the action reading[v] means a reading of
// ‘v’ is received. There are 7 different levels:
range T = 0..6
SENSOR
= (read[v:T] -> MEASURE[v]),
MEASURE[v:T]
= ( when (v < 2) low -> SENSOR
| when (v > 4) high -> SENSOR
| when (v > 1 && v < 5) ok -> SENSOR
).

The drinks dispensing machine:

/*
* FSP code for a drinks dispensing machine.
* Assumption: Once there is 15 cents to buy the drink,
* the user cannot add more coins.
*/
DRINKS
= CREDIT[0],
// Inserting money is modelled using an indexed process,
// where the index represents the amount entered so far
CREDIT[i:0..30]
= ( when (i <= 10) insert[5] -> CREDIT[i+5]
| when (i <= 10) insert[10] -> CREDIT[i+10]
| when (i <= 10) insert[20] -> CREDIT[i+20]
// When credit is sufficient, give i-15 in change
// (since the cost is 15 cents):
| when (i >= 15) press_button -> CHANGE[i-15]
),
// 20c change is not possible: the maximal input is 10+20,
// so the maximal change is 15. The index represents the
// amount of change owing:
CHANGE[i:0..15]
= ( when (i > 10) return[10] -> CHANGE[i-10]
| when (i >= 5 && i < 20) return[5] -> CHANGE[i-5]
| when (i < 5) dummy -> END
)\{dummy}.

Moving around on the 4 × 4 board:

/*
* FSP code for a pebble moving around on an NxN board.
*/
const N = 4
range T = 1..N
P = STATE[1][1], // The pebble starts in row 1, column 1
STATE[row:T][col:T]
= ( when (row > 1) down -> STATE[row-1][col]
| when (row < N) up -> STATE[row+1][col]
| when (col > 1) left -> STATE[row][col-1]
| when (col < N) right -> STATE[row][col+1]
).

RESOURCE SHAREv3: 

RESOURCE = (acquire -> release -> RESOURCE).
USER = (acquire -> use -> release -> USER).
||RESOURCE_SHAREv3(N=5) = (u[1..N]:USER || {u[1..N]}::RESOURCE).

Here are the five dining philosophers, assisted by a butler:

const PHIL_NUMBER = 5
PHIL = (sitdown -> right.get -> left.get -> eat
-> left.put -> right.put -> arise -> PHIL).
FORK = (get -> put -> FORK).
BUTLER = BUTLER[0],
BUTLER[i:0..PHIL_NUMBER-1]
= ( when (i < PHIL_NUMBER-1) sitdown -> BUTLER[i+1]
| when (i > 0) arise -> BUTLER[i-1]
).
||DINERS(N=PHIL_NUMBER)
= forall [i:0..N-1]
( phil[i]:PHIL
|| {phil[i].left,phil[((i-1)+N)%N].right}::FORK
).
||DINERS_WITH_BUTLER
= (DINERS || {phil[i:0..PHIL_NUMBER-1]}::BUTLER).

const N = 10
range T = 0..N
// The safety property that ensures the number of
// passengers in the lift never exceeds 10
// (or, incidentally, falls below 0!)
property FULL = FULL[0],
FULL[i:T] = (when (i<N) enter -> FULL[i+1]
|when (i>0) exit -> FULL[i-1]
).
// The following implementation of a lift (v1) will cause a property
// violation when composed with the safety property.
LIFTv1 = LIFTv1[0],
LIFTv1[i:T] =
( enter -> LIFTv1[i+1]
| exit -> LIFTv1[i-1]
).
// The following implementation of a lift (v2) uses guards to prevent
// the safety property being violated, and hence will not cause a
// property violation when composed with the safety property.
LIFTv2 = LIFTv1[0],
LIFTv1[i:T] =
( when (i<N) enter -> LIFTv1[i+1]
| when (i>0) exit -> LIFTv1[i-1]
).
||SAFE_LIFTv1 = (LIFTv1 || FULL).
||SAFE_LIFTv2 = (LIFTv2 || FULL).

const False = 0
const True = 1
range Bool = False..True
const Nuser = 2
const Nsystem = 2
// As with the reader-writer model, we need to add the full set
// of acquire/release actions to the alphabets of both user and
// system processes
set Actions = {systemAcquire, systemRelease,
userAcquire, userRelease}
// The console acts as a binary semaphore that only allows one
// process access at a time
CONSOLE(N=1) = CONSOLE[0],
CONSOLE[v:0..N] =
( when (v<1) systemAcquire -> CONSOLE[v+1]
| when (v>0) systemRelease -> CONSOLE[v-1]
| when (v<1) userAcquire -> CONSOLE[v+1]
| when (v>0) userRelease -> CONSOLE[v-1]
).
USER = (userAcquire -> userConsole -> userRelease -> USER)
+ Actions.
SYSTEM = (systemAcquire -> systemConsole -> systemRelease -> SYSTEM)
+ Actions.
||OS = (user[1..Nuser]:USER
||system[1..Nsystem]:SYSTEM
||{user[1..Nuser],
system[1..Nsystem]}::CONSOLE(1)).
// Under fair scheduling assumptions the OS process will provide
// equal access to both user and system processes. However, user
// processes may be denied access to the console if system processes
// have a higher priority when attempting to acquire access,
// as denoted by the action priority operator below.
||OS_PROGRESS = OS <<{system[1..Nsystem].systemAcquire}.
progress USER_PROG = {user[1..Nuser].userAcquire}
progress SYS_PROG = {system[1..Nsystem].systemAcquire}

const True = 1
const False = 0
range Bool = False..True
set BoolActions = {setTrue, setFalse, check[False], check[True]}
BOOLVAR = VAL[False],
VAL[v:Bool] = ( setTrue -> VAL[True]
| setFalse -> VAL[False]
| check[v] -> VAL[v]
).
||FLAGS = (flag1:BOOLVAR || flag2:BOOLVAR).
FIELD = (enter -> exit -> FIELD).
N1 = (flag1.setTrue -> flag2.check[t:Bool] ->
(when (t == True) flag1.setFalse -> N1
|when (t == False) n1.enter -> n1.pickBerries -> n1.exit ->
flag1.setFalse -> N1)
).
N2 = (flag2.setTrue -> flag1.check[t:Bool] ->
(when (t == True) flag2.setFalse -> N2
|when (t == False) n2.enter -> n2.pickBerries -> n2.exit ->
flag2.setFalse -> N2)
).
||WAR = (FLAGS || N1 || N2 || {n1,n2}::FIELD).
// Safety property to ensure mutual exclusion (one neighbour leaves the
// field before the other enters).
property MUTEX = ( n1.enter -> n1.exit -> MUTEX
| n2.enter -> n2.exit -> MUTEX).
||CHECK = (WAR || MUTEX).
// Progress property to ensure that both neighbours are able to pick berries
progress PICK = {{n1,n2}.pickBerries}
// A version of the warring neighbours model with greedy neighbours who refuse
// to lower their flags when trying to access the field.
||WAR_PROGRESS = WAR >>{{flag1,flag2}.setFalse}.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值