分享
 
 
 

AsmL实例研究(一)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

为了能够对AsmL有一个更加感性的认识,同时也为了了解如何使用AsmL建模,我们不妨来研究一个AsmL的实例。下面这个例子是一个用AsmL写成的设计规格的Word版本,它来自于AsmL2.1.5.8所带的一个例子——DiningPhilosophers。为了便于理解,我将它翻译成了中文。更多的AsmL例子可以在AsmL的Sample folder中找到。

Dijkstra的饭桌上的哲学家

FSE

Copyright (C) Microsoft Corporation. All rights reserved.

1 Embedding

这个例子是下面这个名字空间的一部分:

namespace DiningPhilosophers

2 Model

一群哲学家坐在桌边。每人的左边和右边各有一个餐叉。我们用下面这个只有一个域index的结构来定义餐叉:

structure Fork

index as Integer

哲学家被定义成具有唯一的索引,能够反映他们当前所处的状态,以及具有如下两种能力:报告他们是否能够改变状态(canMove),以及能够执行状态的改变(move)。因为status 可以改变,所以哲学家是class而不是structure。

abstract class Philosopher

var status as State = Thinking

index as Integer

abstract canMove(table as Table) as Boolean

abstract move(table as Table)

为了简单起见,我们假定哲学家具有固定的数量(5个)。

numPhilosophers as Integer = 5

同样,我们有五把餐叉。

numForks as Integer = numPhilosophers

forks as Set of Fork = {Fork(i) | i in {1..numForks}}

哲学家左边的餐叉与哲学家具有相同的索引。哲学家右边的餐叉的索引比哲学家的索引大(是哲学家总数的模)。

left(p as Philosopher) as Fork

return Fork(p.index)

right(p as Philosopher) as Fork

return Fork(p.index mod numPhilosophers + 1)

思考中的哲学家没有餐叉。(谁需要一把餐叉来思考?)思考中的哲学家可能变得饥饿。饥饿的哲学家试图得到他左边的餐叉从而变成“左手拿餐叉的饥饿的哲学家”。但是只拿到一把餐叉是不够的,只有得到两把餐叉哲学家才开始吃东西。 而右边的餐叉只有在没有人用时才能被得到。吃完东西之后,哲学家只有一件事可以做,那就是放下两把餐叉继续思考。所以,一个成功的哲学家吃一次东西的过程是这样的: Thinking -> Hungry -> HungryWithLeftFork -> Eating -> Thinking

enum State

Thinking

Hungry

HungryWithLeftFork

Eating

我们现在为这五位哲学家定义一张桌子:

class Table

philosophers as Set of Philosopher

用一个变量来描述哪把餐叉正被哪个哲学家使用。另一个变量定义了一个正在吃东西的哲学家的集合:

class Table

var holder as Map of Fork to Philosopher = { -> }

var fed as Set of Philosopher = {}

下面的方法描述了哲学家的动作。能够动作的哲学家是随机选取的。如果没有哲学家能够动作,那么一个死锁发生了。

class Table

var stepNo as Integer = 0

[EntryPoint]

Move()

choose phil in philosophers where phil.canMove(me)

phil.move(me)

stepNo := stepNo + 1

EntryPoint使得被标记的方法能够被外部世界调用,例如可以被C#调用。

2.1 Greedy Philosophers

贪婪的哲学家在吃完东西并开始思考之前绝不会放下餐叉,这会导致死锁。

class GreedyPhilosopher extends Philosopher

override move(table as Table)

match status

Thinking : status := Hungry

Hungry : if not (left(me) in table.holder)

table.holder(left(me)) :=

me as Philosopher

status := HungryWithLeftFork

HungryWithLeftFork

: if not (right(me) in table.holder)

table.holder(right(me)) :=

me as Philosopher

status := Eating

add me to table.fed

Eating : remove table.holder(left(me))

remove table.holder(right(me))

status := Thinking

canMove方法指出哲学家是否能够改变状态:

class GreedyPhilosopher

override canMove(table as Table) as Boolean

return status = Thinking

or (status = Hungry and

left(me) notin table.holder)

or (status = HungryWithLeftFork and

right(me) notin table.holder)

or status = Eating

2.2 Generous Philosophers

慷慨的哲学家并不坚持一定要有一个成功的哲学家的生活。在拿到左手的叉子之后,如果发现无法得到右手的餐叉,慷慨的哲学家就会放下左手的餐叉,继续思考一会。因此,如果所有人都是慷慨的哲学家,那么不会有死锁,但是有可能有人饿死。:)

class GenerousPhilosopher extends Philosopher

override move(table as Table)

match status

Thinking : status := Hungry

Hungry : if not (left(me) in table.holder)

table.holder(left(me)) :=

me as Philosopher

status := HungryWithLeftFork

HungryWithLeftFork

: if not (right(me) in table.holder)

table.holder(right(me)) :=

me as Philosopher

status := Eating

add me to table.fed

else

// someone else is holding the

// right fork

// put the left one down and

// try again another time

remove table.holder(left(me))

status := Thinking

Eating : remove table.holder(left(me))

remove table.holder(right(me))

status := Thinking

注意,决定慷慨的哲学家的状态能否改变的条件要比贪婪的哲学家宽松。

class GenerousPhilosopher

override canMove(table as Table) as Boolean

return status = Thinking

or (status = Hungry and

left(me) notin table.holder)

or status = HungryWithLeftFork

or status = Eating

3 Providing the View

我们提供两个方法来初始化,一个初始化贪婪的哲学家,另一个初始化慷慨的哲学家。

class Table

[EntryPoint]

shared InitGreedy() as Table

philosophers = { new GreedyPhilosopher(i) as Philosopher |

i in [1..numPhilosophers] }

return new Table(philosophers)

[EntryPoint]

shared InitGenerous() as Table

philosophers = { new GenerousPhilosopher(i) as Philosopher |

i in [1..numPhilosophers] }

return new Table(philosophers)

给出哲学家的索引,下面的方法将指出该哲学家拿有餐叉,以及是否正在吃东西。

class Table

HoldsLeft(pIndex as Integer) as Boolean

return exists (i,p) in holder where p.index = pIndex and

left(p) = i

HoldsRight(pIndex as Integer) as Boolean

return exists (i,p) in holder where p.index = pIndex and

right(p) = i

IsFeeded(pIndex as Integer) as Boolean

return exists p in fed where p.index = pIndex

IsDeadlock() as Boolean

return forall p in philosophers holds not p.canMove(me)

IsGreedy() as Boolean

return exists p in philosophers where p is GreedyPhilosopher

StepNo() as Integer

return stepNo

本文旨在引介AsmL。由于作者也刚刚接触AsmL不久,文中的错误与疏漏之处在所难免。如遇不明之处,相信能够从微软研究院的相关网站上找到答案。如果您还不清楚AsmL是什么,您可以参考作者之前的一篇文章《AsmL:可执行的软件规格》。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有