【问题标题】:Modeling an HTTP transition system in Alloy在 Alloy 中建模 HTTP 转换系统
【发布时间】:2014-08-29 15:46:36
【问题描述】:

我想对 HTTP 交互进行建模,即 HTTPRequest/HTTPResponse 序列,并且我试图将其建模为转换系统。 我使用以下方法在类 State 上定义了一个排序:

open util/ordering[State]

State 只是一组消息:

sig State { 
    msgSet: set Message
}

每对 (HTTPRequest->HTTPResponse) 和 (HTTPResponse->HTTPRequest) 在我的转换系统中都表示为一条规则。 这些规则在 Alloy 中表示为谓词,可以让一个状态从一种状态转移到另一种状态。

例如,这是在收到特定 HTTPRequest 后生成 HTTPResponse 的规则:

pred rsp1 [s, s': State] {
    one msg: Request, msg':Response | (

       // Preconditions (previous Request)
    msg.method=get &&
    msg.address.url=sample_com &&

       // Postconditions (next Response)
    msg'.status=OK_200 &&

       // previous Request has to be in previous state
    msg in s.msgSet &&
       // Response generated is added to next state
    s'.msgSet = s.msgSet + msg' 
}

不幸的是,创建的模型似乎太复杂了:我们有十几个规则(比上面的更复杂,但遵循相同的模式)并且执行速度很慢。

编辑:特别是,CNF 生成非常慢,而求解需要相当长的时间。

您对如何建模类似的过渡系统有什么建议吗?

非常感谢!

【问题讨论】:

  • 原则上,您似乎没有做任何明显错误的事情。但是,如果您正在创建一系列状态,那么您的模型是否不需要服务器(或整个系统)永远不会两次处于相同状态?这似乎需要比您原本需要的更多的状态(以及让读者说“等等,HTTP 不是无状态协议吗?!”);如果您允许重用状态,您可能会获得更好的性能。许多事情可以影响性能;您尝试过许多不同的 SAT 求解器吗?
  • 感谢您的回复!今天早上,我尝试了几个 SAT 求解器,但没有得到更好的表现。特别是,事实证明,大部分分析时间都与 CNF 子句的生成有关。你说得对,我们从来没有两次处于同一状态,但这不应该成为我正在建模的案例研究中的问题。关于如何改进 CNF 生成阶段的任何建议?
  • 如果没有更多细节,我无法提出任何建议(我怀疑其他人也可能)。您可能需要提供minimum complete example 来说明问题:展示性能问题的最短可能示例。生成这样一个最小示例所需的工作量可能很大,但它也可以帮助您找到解决方案。
  • 关于状态重用问题——您可能是对的,您对状态的处理不会使模型无效。然而,这里的相关点是,任何需要模型拥有更多个体的东西都会减慢分析速度。允许状态重用是否可以解决您的性能问题?
  • 我无法复制问题;使用您在 pastebin 中提供的模型,Alloy 报告在大约 400 毫秒内找不到模型。 (顺便说一下,许多 Stack Overflow 版主不鼓励使用 pastebin,因为如果粘贴的材料消失了,它会使问题变得不那么有用。)我非常普遍的建议是:从简单的开始,大纲有三个或五个签名,并逐步建立;不要等到有 17 个抽象签名和 60 多个具体签名才尝试实例化模型。

标签: http transitions alloy model-checking transition-systems


【解决方案1】:

这是一个细节水平令人印象深刻的模型;谢谢分享!

honestAction 的各种形式本身都不需要超过两三分钟才能找到一个实例(或者在某些情况下找不到任何实例),除了rsp8,这需要相当长的一段时间本身(在我停止之前它运行了大约十五分钟)。

因此,您观察到的长 CNF 准备时间显然是由(a)只是谓词 rsp8 导致您的时间问题,或(b)honestAction 谓词中析取的大小,或(c ) 两者。

我怀疑但尚未证明时间问题是由填充模型所需的个体数量和模型中的约束数量的组合爆炸引起的。

我的第一直觉(仅此而已)是减少模型中的详细程度,尤其是实例化抽象签名的大量单例签名。这些似乎(我可能是错的)存在于簿记目的(因此您可以确定哪些规则许可从一个状态到另一个状态的转换),或者因为建模者不信任 Alloy 生成签名的具体实例,如用户名,密码、代码等

就像现在的模型一样,看起来您需要做很多工作来定义特定示例中涉及的所有个人,而不是定义约束并让 Alloy 来完成查找示例的工作。 (使用 Alloy 来检查特定的具体示例的属性可能很有用,但还有其他方法可以做到这一点。)

由于模型中的许多具体签名都受限于单例基数,我实际上并不知道定义它们会使查找模型的任务变得更加复杂;据我所知,它使它更简单。但我的直觉是认为,无论涉及哪些主机、用户和 URI,知道状态转换通常具有特定属性(并且可能更容易让 Alloy 建立)比知道更有用该属性rsp1 适用于主机名为examplecom 并且地址URI 为example_url_https 等等的所有情况。

推测减少其存在和属性被规定的个体数量,以及对哪些个体可以参与哪些状态转换的约束,将减少 CNF 生成时间。

如果您的长期目标是测试长序列的状态转换,以测试从给定起点是否可能或不可能到达特定状态(或某种状态),您可能需要重新考虑使更短的状态转换序列来完成这项工作的方法。

第二个猜想将涉及较少的模型重组。由于我认为我不完全理解的原因,有时使用one 进行量化似乎会伤害而不是帮助性能,例如this example,其中使用some 而不是one 明确量化一些变量结果证明是问题易于处理而不是难以处理。

该问题涉及谓词中的量化,而不是整个模型中的量化,并且one 的量化最初并不是有意的,因此在这里可能不相关。但是我们可以用一种简单的方式测试one 关键字对这个模型的影响:我注释掉了honestAction 中除了rsp8 之外的所有内容,并在8 的范围内运行谓词first != last,一次与大部分one 的出现被注释掉,并且这些关键字完好无损。注释掉one 关键字后,Analyzer 在 24 秒左右运行问题;使用 one 关键字,到目前为止,它运行了 500 秒,然后我决定提出并终止它。

所以我会尝试从具有特定实例的个人的所有签名中删除关键字one,仅将其保留在 get、post、OK_200 等和 appData 上。我也会尝试不使用 Key、SessionID、URL、Host、UserName 和 Password 的各种子类型,或者至少在 run 命令中限制它们的基数。

【讨论】:

  • 非常感谢您提供详细的 cmets。我们调查了您的一些建议,并得到了一些稍微好一点的结果。特别是,我们将签名状态中的消息集替换为单个消息(这对于我们的示例来说已经足够了),这显着提高了性能。
猜你喜欢
  • 1970-01-01
  • 2012-11-16
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多