简体   繁体   English

如何将此信号添加到合金中的关系中?

[英]how is this sig being added to a relation in Alloy?

I am modeling a Google Docs-like inline commenting system in Alloy.我在 Alloy 中为类似 Google Docs 的内联评论系统建模。 Specifically, I'm modeling the UI interactions that the user can do.具体来说,我正在对用户可以执行的 UI 交互进行建模。 The constraints, in English, are that:用英语表示的限制是:

  • users can have any number of comments用户可以有任意数量的评论
  • users can have any number of comments composing at once用户可以同时撰写任意数量的评论
  • comments can be either composing or editing, not both评论可以是撰写或编辑,而不是两者
  • (eventually) users can expand one comment at a time to view it—text is truncated otherwise. (最终)用户可以一次展开一条评论来查看它——否则文本会被截断。

so far I have only modeled adding a new comment—or so I think, When I run the model below, I expect to see that Alloy cannot find any counterexamples, but it finds one where a comment is in both the composed and composing relations at a single time.到目前为止,我只模拟了添加一个新评论——或者我认为,当我运行下面的 model 时,我希望看到 Alloy 找不到任何反例,但它会找到一个评论在composed关系和composing关系中都有的一次。

I think there may be something off in my mental model of how Alloy works in this case.我认为合金在这种情况下是如何工作的,我的心理 model 可能有些问题。 I can't see how a comment would possibly be added to the composed relation here: I think init would set all the drafts to have empty relations there, and that the actions in Traces would preclude a comment ever being added to composed .我看不到如何将评论添加到这里的composed关系中:我认为init会将所有草稿设置为在那里具有空关系,并且Traces中的操作会阻止评论被添加到composed中。 BUT, I'm clearly wrong, since Alloy finds an example where composed is non-empty.但是,我显然错了,因为合金找到了一个composed非空的例子。 Does anyone know what's actually happening here?有谁知道这里实际发生了什么?

module inlineComments

open util/ordering [Time] as TimeOrdering

sig Time {}

sig Draft {
  composing: set Comment -> Time,
  composed: set Comment -> Time,
  -- expanded: lone Comment -> Time,
}

sig Comment {}

-- What can we do with these?

pred newComment (t, t': Time, c: Comment, d: Draft) {
  -- comment is not already known to us
  c not in d.composing.t
  c not in d.composed.t

  -- start composing the comment
  d.composing.t' = d.composing.t + c
}

pred init (t: Time) {
  all d: Draft, c: Comment | c not in d.composing.t
  all d: Draft, c: Comment | c not in d.composed.t
}

fact Traces {
  init[TimeOrdering/first]

  all t: Time - TimeOrdering/last |
    let t' = TimeOrdering/next[t] |
      some d: Draft, c: Comment |
        newComment [t, t', c, d]
}

-- Is the world how we expect it to be?

assert validState {
  -- comments cannot be composing and composed at the same time
  all t: Time, d: Draft | d.composing.t & d.composed.t = none
}

check validState for 3 but 1 Draft

This is known as the "frame problem": you've specified that new comments can be put into composing , but not that nothing else happens!这被称为“框架问题”:您已指定可以将新评论放入composing中,但并非没有其他任何事情发生! You have to make it explicit that the only way the system may change is via newComment .您必须明确表明系统可能更改的唯一方法是通过newComment Here's one way you could do that:这是您可以做到的一种方法:

fact Traces {
  init[TimeOrdering/first]

  all t: Time - TimeOrdering/last |
    let t' = TimeOrdering/next[t] |
      some d: Draft, c: Comment {
        newComment [t, t', c, d]
        d.composed.t = d.composed.t' -- d.composed doesn't change
      }
}

Note this only works because you've exlicitly scoped to a maximum of 1 draft.请注意,这仅适用于您已明确将范围限定为最多 1 个草稿。 If you test with two drafts, you also have to show that none of the drafts change in any way.如果您使用两个草稿进行测试,您还必须证明草稿没有任何变化。 If that will always be the case that there's only one Draft, you can write one sig Draft to enforce that.如果这种情况总是只有一个草稿,您可以编写one sig Draft来强制执行。

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

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