如何在Alloy6中指定“全局”框架条件?

huangapple go评论50阅读模式
英文:

How to specify "global" frame condition in Alloy6?

问题

链接: 形式化软件设计与Alloy 6 - 协议设计章节

玩具示例:

假设我有一个"员工"的概念,他可以登录到"机器",并可以出现在"机器"或"测量室"。"机器"可以处于多个状态之一:未登录工作测量。"机器"当前有一个活跃的工具和其他工具,这些工具在模型的不同部分改变活动(只是为了有更大的框架条件而包含在示例中)。

然后我指定了初始状态,在此状态下"员工"处于"未在工作"状态。

fact init {
  Employee.location = NotAtWork

  no Machine.login
  Machine.state = NoLogin

  Machine.tools = Tool
  no Machine.activeTool
}

最后,不同状态之间的转换(例如,登录开始测量结束测量):

pred login {
  Machine.state = NoLogin // 保护条件。

  // 影响:
  Machine.state' = Work
  Machine.login' = Employee
  Employee.location' = Machine
}

pred measuring_begin {
  Machine.state = Work // 保护条件。

  // 影响:
  Machine.state' = Measuring
  Employee.location' = MeasureRoom
  
  // 框架条件 - **如何使这些更简洁?**:
  Machine.login' = Machine.login
  Machine.tools' = Machine.tools
  Machine.activeTool' = Machine.activeTool
}

pred measuring_end {
  Machine.state = Measuring // 保护条件。

  // 影响:
  Machine.state' = Work
  Employee.location' = Machine

  // 框架条件 - **如何使这些更简洁?**:
  Machine.login' = Machine.login
  Machine.tools' = Machine.tools
  Machine.activeTool' = Machine.activeTool
}


fact transition {
    always (
        login or measuring_begin or measuring_end
    )
}

run example {
	eventually measuring_end
}

更具体地说,是否可能编写简洁的框架条件,以确保新状态与先前状态相同,除了影响之外?我理解可能不可能,因为谓词(如果我理解正确)不会改变状态,而只是指定可能未来状态的搜索条件。

英文:

I am trying to model temporal process using for reference Formal Software Design with Alloy 6 - Protocol design chapter. I would like to know how to make frame conditions in predicates less verbose.

Toy example:

Let's say that I have concept of Employee who can be logged into Machine and can be present at Machine or in MeasureRoom. Machine can be in one of multiple states: NoLogin, Work and Measuring. Machine has currently active Tool and other Tools, which change activity in different part of model (included in example just to have bigger frame conditions).

enum MachineState { NoLogin, Work, Measuring }

abstract sig Location {}

some sig Tool {}

one sig Machine extends Location {
  var login: lone Employee,
  var state: one MachineState,
  var tools: some Tool,
  var activeTool: lone Tool
}

one sig NotAtWork extends Location {}

one sig MeasureRoom extends Location {}

one sig Employee {
  var location: one Location
}

Then I specify initial state, in which Employee is NotAtWork.

fact init {
  Employee.location = NotAtWork

  no Machine.login
  Machine.state = NoLogin

  Machine.tools = Tool
  no Machine.activeTool
}

Finally transitions between different states (for example, login, measuring_begin and measuring_end):

pred login {
  Machine.state = NoLogin // Guard condition.

  // Effects:
  Machine.state' = Work
  Machine.login' = Employee
  Employee.location' = Machine
}

pred measuring_begin {
  Machine.state = Work // Guard condition.

  // Effects:
  Machine.state' = Measuring
  Employee.location' = MeasureRoom
  
  // Frame conditions - **how to make these less verbose?**:
  Machine.login' = Machine.login
  Machine.tools' = Machine.tools
  Machine.activeTool' = Machine.activeTool
}

pred measuring_end {
  Machine.state = Measuring // Guard condition.

  // Effects:
  Machine.state' = Work
  Employee.location' = Machine

  // Frame conditions - **how to make these less verbose?**:
  Machine.login' = Machine.login
  Machine.tools' = Machine.tools
  Machine.activeTool' = Machine.activeTool
}


fact transition {
    always (
        login or measuring_begin or measuring_end
    )
}

run example {
	eventually measuring_end
}

So more concretely, is it possible to write concise frame condition, that would ensure that new state is identical to previous one except for effects? I understand it may not be possible, since predicates (if I understand correctly), do not mutate state, but just specify search criteria for possible future states.

答案1

得分: 2

你说得对,谓词(对事件进行编码)只是约束了未来的状态。由于约束可以是任意公式,因此似乎不可能从效果中推断出帧条件。一个解决方案,目前在Alloy中尚未实现,并且会大幅改变语言,是以某种方式限制效果的语法,使所述推断成为可能。

与此同时,有一些简化帧条件的方法。例如,你可以依赖于来定义一个unchanged关键字(宏是一种脆弱的、无类型的、带参数的表达式或约束)。例如:

let unchanged[r] { ((r) = (r)') } // 注意括号

pred measuring_begin {
  ...
  // 帧条件
  unchanged[Machine.login]
  unchanged[Machine.tools]
  unchanged[Machine.activeTool]
}

在你的情况下,因为只有一个Machine,你甚至可以摆脱Machine.部分,直接写成unchanged

此处为隐藏的内容
注册登录后,方可查看

另一种方法是依赖于Reiter风格的帧条件(参见例如Daniel Jackson的这些幻灯片(在Alloy 4中))。在这种方法中,你可以在全局事实中编写帧条件,说明如果关系r发生变化,那只能是因为这个或那个事件。例如对于login

fact {
  always {
    (unchanged[Machine.login] or login)
    (unchanged[state] or login or measuring_begin or measuring_end)
    ...
  }
}

根据事件是否改变了许多状态变量,局部帧条件与全局Reiter风格帧条件中的一个将比另一个更短。

最后,如果你的模型中有非one签名,通常可以在单个约束中表达对字段的效果和帧条件。参见这里的"指定全局效果"部分2

编辑:修复了一个拼写错误。

英文:

You're right that predicates (encoding events) just constrain future states. And because constraints can be arbitrary formulas, it seems impossible to infer frame conditions out of effects. One solution, not currently implemented in Alloy and which would change the language a lot, would be to restrict the syntax of effects in such a way that the said inference would be possible.

Meanwhile, there are a few approaches to simplify your frame conditions. For instance, you can rely on a macro to define an unchanged keyword (macros are a fragile, untyped, parametrized expressions or constraints). E.g.:

let unchanged[r] { ((r) = (r)') } // mind the parentheses

pred measuring_begin {
  ...
  // Frame conditions 
  unchanged[Machine.login]
  unchanged[Machine.tools]
  unchanged[Machine.activeTool]
}

In your case, as there's only one Machine, you may even get rid of the Machine. part and write unchanged

此处为隐藏的内容
注册登录后,方可查看
.

Another approach is to rely on Reiter-style frame conditions (see e.g. these slides by Daniel Jackson (in Alloy 4)). In this approach, you write frame conditions, in a global fact, saying that if relation r changes, it's only because of this or that event. E.g. for login:

fact {
  always {
    (unchanged[Machine.login] or login)
    (unchanged[state] or login or measuring_begin or measuring_end)
    ...
  }
}

Depending on whether events change a lot of state variables or not, one out of local frame conditions vs. global Reiter-style frame conditions will be shorter than the other.

Finally, if you have non-one sigs in your model, you can often express an effect and a frame condition on a field in a single constraint. See the box "Specifying global effects" here.

EDIT: fixed a typo.

huangapple
  • 本文由 发表于 2023年2月24日 17:04:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554537.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定