[英]Changing service code for object inside a system in Alloy
我希望在對象上運行任何服務時更改對象的服務代碼。 假設,每當適用於對象時,我都有一個操作,該對象的服務代碼將為1,當另一個操作執行時,服務代碼將為2.我想將最新的服務代碼保存到每個對象。 不幸的是,我無法很好地設計我的謂詞,這就是為什么從合金獲得謂詞不一致的消息。
我已經嘗試了一些代碼來為每個對象分配服務代碼。 完整的代碼如下所示 -
open util/ordering[Environment]
abstract sig Object{
name: String,
serviceCode: Int,
}{
serviceCode >= 0 and serviceCode <= 3
}
// Events
enum Event {Event1, Event2, Event3}
abstract sig Condition{
name: Event,
object: Object
}
abstract sig BaseOperation{
name: Event,
object: Object
// it will have more attributes than Condition later
}
abstract sig Connector{
condition: Condition,
baseOperation: BaseOperation,
}
sig Environment{
ev : set Event
}
pred execute [u:Environment, u':Environment, r:Connector] {
some e: u.ev | {
e = r.condition.name =>
u'.ev = u.ev + r.baseOperation.name
else
u'.ev = u.ev
}
}
fact {
all u:Environment-last, u':u.next, r:Connector {
execute [u, u', r]
}
}
sig Object1 extends Object{
}{
name = "Object1 Object"
}
sig Object2 extends Object{
}{
name = "Object2 Object"
}
sig Condition1 extends Condition{
}{
name = Event1
object = Object2
object.serviceCode = 1
}
sig Operation1 extends BaseOperation{
}{
name = Event2
object = Object1
object.serviceCode = 1
}
sig Operation2 extends BaseOperation{
}{
name = Event3
object = Object1
object.serviceCode = 0
}
one sig Connector1 extends Connector{
}{
condition = Condition1
baseOperation = Operation1
}
one sig Connector2 extends Connector{
}{
condition = Condition1
baseOperation = Operation2
}
fact {
Event3 !in first.ev &&
Event2 !in first.ev
}
run {Event1 in last.ev} for 10
當我只有一個操作鏈接到一個對象時,上面的代碼工作正常。 我在這里附上了圖表。 只要有多個操作,合金就找不到實例。 需要幫助設計合金代碼以實現我的目標。
另一種可能的方法可能是 - 而不是一個服務代碼,我們可能有一個服務代碼列表。 考慮時間戳以及每個服務代碼。 然后在需要時找出最新的服務代碼。 我們可以采用最大時間戳的服務代碼。 但我不知道如何用合金設計它。
我想你應該看看Daniel Jackson的書。 Alloy不是具有可變賦值的編程語言。 它基本上是關系的規則引擎,可以生成一個實例 ,一組匹配這些規則的關系。 這意味着如果您需要可變分配,那么您需要一種方法來表示關系中隨時間變化的可變狀態。 有兩種方法:
Time
- 使每個字段都有一個帶有Time
的列,其中Time
是有序的。 我發現這非常麻煩。 Electrum項目通過提供var
關鍵字使您更容易,然后為您維護Time
列。 Trace
- 您可以將關聯放置在已排序的狀態 sig
,而不是將每個字段與Time
相關聯。 然后,該關系顯示了價值隨時間的變化情況。 關鍵問題是您的問題描述幾乎與規范完全脫節。 你談論服務然后再操作 ,它們是一樣的嗎? Event
和Connector
在哪里? 在您的問題描述中從未提及過它們?
讓我們一個接一個:
我想更改對象的服務代碼
open util/ordering[Environment]
sig Object {}
enum ServiceCode { _1, _2 }
sig Environment {
object : Object -> ServiceCode
}
一般而言,您不希望將Int用於Service Code之類的東西,因為它們往往會炸毀狀態空間。
Environment
是我們的國家 。 我們想要為每個環境原子執行一個服務 。
......每當有任何服務在其上運作時。
sig Service {
serviceCode : ServiceCode
}
pred execute[ e, e' : Environment, o : Object, s : Service ] {
e'.object = e.object ++ o -> s.serviceCode
}
假設,只要適用於Object ,我就有一個Operation ,
目前尚不清楚您對Operation的意思,我認為這是早期的服務 ?
...該對象的服務代碼將為1,當另一個操作執行時, ServiceCode將為2.我想將最新的服務代碼保存到每個對象。 不幸,
pred trace {
no first.object
all t : Environment-last, t':t.next {
some o: Object, s : Service {
execute[t,t', o, s]
}
}
}
run trace
在表格視圖中,這為您提供:
┌────────────────┐
│this/ServiceCode│
├────────────────┤
│_1⁰ │
├────────────────┤
│_2⁰ │
└────────────────┘
┌───────────┐
│this/Object│
├───────────┤
│Object⁰ │
├───────────┤
│Object¹ │
└───────────┘
┌────────────┬───────────┐
│this/Service│serviceCode│
├────────────┼───────────┤
│Service⁰ │_2⁰ │
├────────────┼───────────┤
│Service¹ │_2⁰ │
├────────────┼───────────┤
│Service² │_1⁰ │
└────────────┴───────────┘
┌────────────────┬───────────┐
│this/Environment│object │
├────────────────┼───────────┤
│Environment⁰ │ │
├────────────────┼───────┬───┤
│Environment¹ │Object¹│_2⁰│
├────────────────┼───────┼───┤
│Environment² │Object⁰│_1⁰│
│ ├───────┼───┤
│ │Object¹│_2⁰│
└────────────────┴───────┴───┘
當你使用Alloy時,你應該做的第一件事是用簡單的英語定義你想要指定的問題。 然后,您將本文中的概念轉換為Alloy構造。 Alloy規范的目標是讓它像散文一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.