AsmL实例研究(一)

原创 2003年05月09日 20:01:00

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

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 

Dijkstra的饭桌上的哲学家

FSE

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

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />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:可执行的软件规格》。

企业信息门户平台整体解决方案研究(概述与案例分享)

前言:企业信息门户平台就是指在Internet的环境下,把各种应用系统、数据资源和互联网资源统一集成到企业信息门户之下,根据每个用户使用特点和角色的不同,形成个性化的应用界面,并通过对事件和消息的处理...
  • faifanuiop
  • faifanuiop
  • 2015年06月15日 09:49
  • 334

Bimap实例化研究

一说到Bitmap,所以人都会想到回收,内存溢出等问题,我一直对Bitmap存在的实例化方法不太懂,现在就来看看。 大家都知道有个BitmapFactory类,该类有好多静态方法可以实例化一个Bitm...
  • p892848153
  • p892848153
  • 2014年08月27日 14:06
  • 413

一文纵览无监督学习研究现状:从自编码器到生成对抗网络

这篇文章确实写的不错,总结无监督学习的方法如下: 1)自编码器 2)聚类学习 3)生成对抗网络 4)设计不需要标签的无监督学习任务,直接从无标签的数据中学习模型 视觉表征:通过解决拼图问题来...
  • mmc2015
  • mmc2015
  • 2017年05月08日 22:27
  • 854

计算机网络研究方向和网络安全问题

1)密码理论:研究高强度的密码理论,高速加解密算法,密码分析与攻击算法等     2)安全协议:研究安全协议的形式化方法,如BAN逻辑,串空间,SPI演算等;研究安全多方计算的基础理论  ...
  • moqingxinai2008
  • moqingxinai2008
  • 2016年12月28日 15:33
  • 600

数据建模讲解和案例分析

第一部分:数据建模理论和逻辑 一、从数据分析的定义开始 维基百科对数据分析的定义如下: Analysis of data is a process of inspecting, cleaning...
  • z_xiaozhuT
  • z_xiaozhuT
  • 2017年04月18日 13:34
  • 2855

前瞻性队列、回顾性队列、病例对照研究

一、前瞻性队列研究 研究对象的确定与分组根据研究开始时的实际情况,研究的结局需随访观察一段时间才能得到,这种研究可信度高、偏倚少,但费时、费人力、物力、财力。 二、回顾性队列研究 回顾性队列研究...
  • u012344939
  • u012344939
  • 2017年02月24日 18:31
  • 1047

研究linux内核的目的

一.研究内核的目的  欲举其事,先正其道。要谈论内核的研读以及交流心得,前提必须得有一个恰当准确的目的,方能收获良多。 很多人都有这样一个疑惑,为什么要研究内核呢?我们又不是内核开发者(或...
  • SunboyJohn690905084
  • SunboyJohn690905084
  • 2013年11月08日 18:14
  • 1418

做课题与科研项目常用的研究方法

研究方法不出“硬伤” 1、常用的研究方法有文献研究法、教育观察法、经验总结法、个案研究法、行动研究法、实验研究法、历史研究法、调查研究法、比较研究法、叙事研究法等。 2、研究类型或途径、或...
  • neilol
  • neilol
  • 2015年06月18日 15:28
  • 3080

图解PE文件实例研究

一 使用Win32汇编的PE信息查看小工具查看和研究PE文件     PE信息查看工具有多种。下面先使用在《Windows PE权威指南》中所附带的用Win32汇编编写的PE信息查看小工具来查看PE...
  • bcbobo21cn
  • bcbobo21cn
  • 2015年04月19日 13:21
  • 638

C++ ~ Time类实例研究

Time类的定义:     类中的定义包含成员函数Time、setTime、printUniversal、printStandard的函数原型,以及private unsigned int成员hou...
  • m0_37925202
  • m0_37925202
  • 2017年11月04日 22:43
  • 40
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AsmL实例研究(一)
举报原因:
原因补充:

(最多只允许输入30个字)