简体   繁体   English

在Alloy中更改系统内对象的服务代码

[英]Changing service code for object inside a system in Alloy

I want to change the service code of an object whenever there has been any service operated upon it. 我希望在对象上运行任何服务时更改对象的服务代码。 Suppose, I have a operation whenever that applies to an object, the service code of that object will be 1 and again when another operation executes then the service code will be 2. I want to save the latest service code to each object. 假设,每当适用于对象时,我都有一个操作,该对象的服务代码将为1,当另一个操作执行时,服务代码将为2.我想将最新的服务代码保存到每个对象。 Unfortunately, I am not able design my predicate well, that's why getting predicate inconsistent message from alloy. 不幸的是,我无法很好地设计我的谓词,这就是为什么从合金获得谓词不一致的消息。

I have tried some code for assigning service code to each object. 我已经尝试了一些代码来为每个对象分配服务代码。 The complete code shown below- 完整的代码如下所示 -

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

The above code works fine when I have only one operation link to one object. 当我只有一个操作链接到一个对象时,上面的代码工作正常。 I have attached the diagram for it here . 在这里附上了图表。 Whenever there is more than one operation, then alloy fails to find an instance. 只要有多个操作,合金就找不到实例。 Need help on designing alloy code for achieving my goal. 需要帮助设计合金代码以实现我的目标。

Another possible approach might be- instead of one service code, we may have a list of service code. 另一种可能的方法可能是 - 而不是一个服务代码,我们可能有一个服务代码列表。 Considering timestamp along with each service code. 考虑时间戳以及每个服务代码。 Then when need to find out the latest service code. 然后在需要时找出最新的服务代码。 We can take the service code of max timestamp. 我们可以采用最大时间戳的服务代码。 But I am not sure how to design this in alloy. 但我不知道如何用合金设计它。

I think you should take a look at Daniel Jackson's book. 我想你应该看看Daniel Jackson的书。 Alloy is not a programming language with mutable assignments. Alloy不是具有可变赋值的编程语言。 It is basically a rule engine over relations that can generate an instance , a set of relations matching those rules. 它基本上是关系的规则引擎,可以生成一个实例 ,一组匹配这些规则的关系。 This means that if you need mutable assignments then you need a way to represent the mutable state over time in a relation. 这意味着如果您需要可变分配,那么您需要一种方法来表示关系中随时间变化的可变状态。 There are two ways: 有两种方法:

  • Time – Make each field have a column with Time , where Time is ordered. Time - 使每个字段都有一个带有Time的列,其中Time是有序的。 I find this quite cumbersome. 我发现这非常麻烦。 The Electrum project made this easier by providing a var keyword that then maintains the Time column for you. Electrum项目通过提供var关键字使您更容易,然后为您维护Time列。
  • Trace – Instead of associating each field with a Time , you can also place the associations in a state sig that is ordered. Trace - 您可以将关联放置在已排序的状态 sig ,而不是将每个字段与Time相关联。 That relation then shows how the values change over time. 然后,该关系显示了价值随时间的变化情况。

The key problem is that your problem description is almost completely disconnected from the specification. 关键问题是您的问题描述几乎与规范完全脱节。 You talk about Service and then later Operation , are they the same? 你谈论服务然后再操作 ,它们是一样的吗? Where do Event and Connector come in? EventConnector在哪里? They are never mentioned in your problem description? 在您的问题描述中从未提及过它们?

Let's take it one by one: 让我们一个接一个:

I want to change the service code of an object 我想更改对象服务代码

   open util/ordering[Environment]

   sig Object {}
   enum ServiceCode { _1, _2 }

   sig Environment {
      object    : Object -> ServiceCode
   }

In general, you do not want to use Ints for things like Service Code since they tend to blow up the state space. 一般而言,您不希望将Int用于Service Code之类的东西,因为它们往往会炸毁状态空间。

The Environment is our state . Environment是我们的国家 We want to execute one Service per Environment atom. 我们想要为每个环境原子执行一个服务

... whenever there has been any service operated upon it. ......每当有任何服务在其上运作时。

   sig Service {
    serviceCode : ServiceCode
   }

   pred execute[ e, e' : Environment, o : Object, s : Service ] {
    e'.object = e.object ++ o -> s.serviceCode       
   }

Suppose, I have an Operation whenever that applies to an Object , 假设,只要适用于Object ,我就有一个Operation

It is not clear what you mean with Operation , I assume this is the earlier Service ? 目前尚不清楚您对Operation的意思,我认为这是早期的服务

... the Service Code of that Object will be 1 and again when another Operation executes then the ServiceCode will be 2. I want to save the latest service code to each object. ...该对象服务代码将为1,当另一个操作执行时, ServiceCode将为2.我想将最新的服务代码保存到每个对象。 Unfortunately, 不幸,

  pred trace {
    no first.object
    all t : Environment-last, t':t.next {
           some o: Object, s : Service {
           execute[t,t', o, s]
        }
    }
  }

  run trace

In the table view this gives you: 在表格视图中,这为您提供:

┌────────────────┐
│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⁰│
└────────────────┴───────┴───┘

When you use Alloy the first thing you should do is define the problem you want to specify in plain English. 当你使用Alloy时,你应该做的第一件事是用简单的英语定义你想要指定的问题。 You then translate the concepts in this text to Alloy constructs. 然后,您将本文中的概念转换为Alloy构造。 The goal of an Alloy spec is to make it read like prose. Alloy规范的目标是让它像散文一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM