合金:意外实例,Sig’ = Sig和Sig.field’之间的差异= Sig.field

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

Alloy: unexpected instance, difference between Sig'=Sig & Sig.field' = Sig.field

问题

  1. 在这里,在State 1中,我们的“raised”比State 0中少了一些。然而,我只指定了如何增加更多的提醒,从未指定如何删除它们。这是如何可能的?

  2. “State' = State”和“State.raised' = State.raised”之间有什么区别?用第二个替换第一个会导致“找不到实例”,我不明白为什么?

编辑后:

  • 添加了一些规则和一些可观察的事实。
  • 将liveness从事实更改为谓词。
  • 不再出现意外的实例,但仍然有些谓词只会卡住,没有任何有用的操作。
  • 我必须从谓词中删除“always”才能真正有用的东西。
  • “特别是,它们可以通过阻止任何跟踪的存在或仅允许有限的跟踪来进行交互。但Alloy只将无限跟踪视为实例”:我不知道你在说什么。感觉像是从秘密地方出来的一些魔法规则。我可以在哪里了解更多信息?我认为这不在“软件抽象”书中...
英文:

I am trying to model the following properties:

  • Given a computation rule, and an Observable (~asset) we may raise an alert for this pair of (rule, observable).
  • User can disable some rules, and we won't raise alerts for them.

I have modelled it like so:

var sig Rule {}
var sig Disabled in Rule {}
sig Observable {}

var one sig State {
	var raised: Rule -> lone Observable
}

pred stutter {
	State' = State
}

pred raiseAlert[r: Rule, p: Observable] {
	// rule must not be disabled
	r not in Disabled
	(r -> p) not in State.raised
	State.raised' = State.raised + (r -> p)
	Rule' = Rule
}

pred muteRule[r: Rule] {
    // not yet in Disabled
	r not in Disabled
	Disabled' = Disabled + r
	// State.raised' = State.raised // this results in "No instance found" ?
	State' = State
}

pred liveness {
	 (some r: Rule, p: Observable | raiseAlert[r, p])
	or (some r: Rule | muteRule[r])
}

fact next {
	always (liveness)
}

run liveness

Two questions:

  1. Here, in State 1 somehow we end up we less "raised" than in State 0. However, I only ever specified how to add more raised alerts, never how to remove them. How is this possible?
    合金:意外实例,Sig’ = Sig和Sig.field’之间的差异= Sig.field
  1. What's the difference between "State' = State" and State.raised' = State.raised? Replacing the first with the second, results in No Instance found, and I don't understand why?

EDIT:

var sig Rule {}
var sig Disabled in Rule {}
sig Observable {}

var one sig State {
	var raised: Rule -> lone Observable
}
fact {
	some Rule
	some Observable
}
pred stutter {
	State' = State
	State.raised' = State.raised
	Disabled' = Disabled
	Rule' = Rule
}

pred raiseAlert[r: Rule, p: Observable] {
	r not in Disabled
	(r -> p) not in State.raised
	State.raised' = State.raised + (r -> p)
	Rule' = Rule
	State' = State
	Disabled' = Disabled
}

pred muteRule[r: Rule] {
	r not in Disabled
	Disabled' = Disabled + r
	State' = State
	// remove those elements from raised which start with rule "r"
	State.raised' = State.raised - (r <: State.raised)
}

pred liveness_only_stutter {
	always ((some r: Rule, p: Observable | raiseAlert[r, p])
		or (some r: Rule | muteRule[r]) or stutter)
}

pred liveness_no_instances {
	always ((some r: Rule, p: Observable | raiseAlert[r, p])
		or (some r: Rule | muteRule[r]))
}

pred liveness_actually_interesting {
	// this one actually generates interesting instances
	(some r: Rule, p: Observable | raiseAlert[r, p])
		or (some r: Rule | muteRule[r])
}


run liveness_actually_interesting

After this edit:

  • added a fact for some Rule, some Observable
  • changed liveness from fact to predicate
  • No more unexpected instances, but still, some predicates only ever stutter, and do anything useful.
  • I had to remove always from my predicate to actually get useful stuff done
  • In particular, they may interact by preventing the existence of any trace or by only allowing finite traces. But Alloy only considers infinite traces as instances: I have no idea what you are talking about. Feels like some magic rules coming out of secret places. Where I can read more about it? I don't think it's in the "Software Abstractions" book ...

答案1

得分: 1

以下是您要翻译的内容:

许多评论都是有序的。首先,我不会将liveness称为表示可能跟踪的谓词。通常,我们将liveness保留用于我们想要检查的活性属性,而不是我们要将其视为事实的属性。

有了next作为事实,似乎没有必要运行run livenessrun {}就足够了。

然后,您有一个stutter谓词,但您没有说明这可能会作为next事实中的事件发生。

还要注意,但也许这对您来说很明显,State可以在由范围定义的有限数量的值之间取不同的值。one属性只表示它在每个瞬时具有确切的一个值。

next中,您允许muteRule发生,并且此事件不会限制raised。因此,正如之前解释的那样,raised可能会任意变化,这就是您的问题1中发生的情况。

关于问题2,如果您没有run的实例,那是因为您对模型进行了过度约束。因此,您必须再次查看所有约束,并考虑它们如何相互作用。特别是,它们可能通过阻止任何跟踪的存在或仅允许有限跟踪来相互作用。但Alloy只考虑无限跟踪作为实例(这是在next事实中系统性地添加stutter事件的一个原因)。

现在,评估您的模型中事件如何相互作用有点困难,因为如上所述,您没有说明每个事件中的每个变量会发生什么(缺少一些帧条件)。例如,在raiseAlert中,DisabledStateraisedState以外的值上可能发生任何事情。因此,例如,raiseAlert可能会增加State.raised的值,但同时减小其他状态的值。类似的情况也适用于muteRule

请首先通过明确说明每个变量会发生什么来修复您的模型。

编辑:现在您的模型已经编辑,以下是一些评论。

关于“liveness”,我只是指出名称选择得不好。但您仍然可以(通常应该)在一个事实中定义谓词内容,说明可能的跟踪,如下所示:

always ((some r: Rule, p: Observable | raiseAlert[r, p])
        or (some r: Rule | muteRule[r]) or stutter)
}

其次,请注意,在您的事件中,您仅修改State上的raised。这意味着您允许raised对每个其他状态值进行更改。我认为这通常不是您的意思。一种表达raised仅在State上更改的方式是:

raised' = raised - State -> r -> univ

通过这种方式,您有效地指定了raised中每个元组的发生情况。

此外,您忘记在muteRule中说明Rule的情况。

关于您不总是获得有趣实例的事实,这是正常的。现在您的系统允许执行stutter,这通常是有益的,但其结果可能是您可能获得“不感兴趣”的实例。但这些都是正确的实例!要查看其他实例,您可以在可视化工具中使用“New ...”按钮;您还可以发出特定的run命令;最后,您还可以(但需要更多经验)添加所谓的“弱公平性”属性(在可能时迫使进展)。

最后,关于跟踪的问题。我假设您知道这一点,因为您使用了var关键字,这也不是Daniel Jackson的书中的内容。这是Alloy 6特有的:请参考使用Alloy 6进行形式化软件设计,这是一本教程式的进行性书籍。

英文:

Many comments are in order. First, I wouldn't call liveness the predicate representing possible traces. Usually we keep liveness for liveness properties we want to check, not properties we want to take as a fact.

With next as a fact, it doesn't seem really useful to run liveness, run {} will do.

Then, you have a stutter predicate but you don't say that this may happen as an event in the next fact.

Also notice, but maybe that was clear to you, that State may take various values among a finite number of values defined by the scope. The one attribute only says that it has exactly one value in every instant.

In next you allow muteRule to happen, and this event doesn't constrain raised. So, as explained just before, raised may change arbitrarily, which is what happens in your question 1.

Re question 2, if you have no instance for a run, it's because you have over-constrained your model. So you must look again at all constraints and think about how they may interact. In particular, they may interact by preventing the existence of any trace or by only allowing finite traces. But Alloy only considers infinite traces as instances (this is one reason to systematically add a stutter event in the next fact).

Now, assessing how events interact in your model is a bit hard because, as explained above, you haven't said what happens to every variable in every event (some frame conditions are missing). In raiseAlert for instance, anything may happen to Disabled, to State, and to raised on values other than State. So for instance, raiseAlert may increase the value of State.raised but decrease it for other states at the same time. Similarly for muteRule.

Please fix your model first, by stating explicitly what happens to every variable.

EDIT: Now that your model is edited, some comments.

Regarding "liveness", I was just pointing out that the name was badly chosen. But you can (and usually should) still define the predicate contents in a fact stating what are the possible traces, like this:

fact possible_traces {
always ((some r: Rule, p: Observable | raiseAlert[r, p])
        or (some r: Rule | muteRule[r]) or stutter)
}

Second, note that in your events, you only modify raised on State. Which means you allow raised to change for every other state value. I don't think this is what you mean in general. One way to say that raised changes only on State is rather to write:

raised' = raised - State -> r -> univ

This way, you effectively specify what happens to every tuple in raised.

Also you forgot to say what happens to Rule in muteRule.

Re the fact that you don't always get interesting instances, that's normal. Your system is now allowed to stutter, which is good in general, but a consequence is that you may also get "uninteresting" instances. But these are correct instances! To see other instances, you may use the New ... buttons in the Visualizer; you could also issue specific run commands; and you could finally (but that will need a bit more experience) add so-called "weak fairness" properties (which somehow force progress when it's possible).

Finally, regarding the question on traces. I was supposing you knew about that as you're using the var keyword which isn't Daniel Jackson's book either. This is specific to Alloy 6: please refer to Formal Software Design with Alloy 6 for a tutorial-style on-going book.

huangapple
  • 本文由 发表于 2023年6月12日 00:29:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451442.html
匿名

发表评论

匿名网友

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

确定