【问题标题】:Alloy Array Model合金阵列模型
【发布时间】:2026-02-11 21:30:01
【问题描述】:

我刚开始学习合金模型语言,并试图在合金中编写自己的数组模型。但是,我无法从关系中提取索引。这是我的信号和事实:

sig Element {}

one sig Array {
  // Map index to element
  IdxEle: Int -> Element,
  // Length of the array.
  length: Int
}

fact Index {
    all r : IdxEle | r.Int >= 0 and r.Int < length
}

我得到的错误是

This must be an integer expression.
Instead, it has the following possible type(s):
{none->none}

我查看了参考指南,但找不到提取关系的 idx 字段的方法。有人可以帮帮我吗? 谢谢

【问题讨论】:

    标签: testing modeling alloy


    【解决方案1】:

    首先,您的模型中的 rArray-&gt;Int-&gt;Element 类型,因此无法计算 (Array-&gt;Int-&gt;Element).Int,因为元组中的最后一列是 Element 类型,而不是您似乎期望的 Int 类型。 (加入Alloy时,左侧最后一列必须与右侧第一列类型相同。)

    其次,有更简单、更灵活、更易读的方式来表达你想要的:

    sig Element {}
    
    let range[start,end] = {  i : Int | i >= start and i < end }
    
    one sig Array { index : Int -> Element } {
        index.Element = range[ 0, len[this] ]
    }
    
    fun len[ array : Array ] : Int { # array.index }
    

    第三...有一个内置类型为你称为seq。它拥有您想要的一切,甚至更多。

    【讨论】:

    • 非常感谢,您的回答确实帮助我掌握了合金的数据类型和概念。这也让我开始思考是否可以在一行代码中实现它(尽管这会牺牲灵活性和可读性)所以我做了以下事情:fact Index { all a : Array | a.IdxEle.Element &gt;= 0 and a.IdxEle.Element &lt; a.length } 但是,当我执行它并显示它时,我得到了负索引.这可能是什么原因?再次感谢。
    • 这是因为 a.IdxEle.Element 返回了一组整数。我不确定&gt;= 运算符在比较集合时的行为如何,但从你得到的结果看来,并不是所有组成集合的整数都进行了比较。
    • 一种修复方法是检查整数集是否分别包含在0Array.length 之后的整数中。将以下合金公式放入您的 Index Fact 将解决您的问题。 Array.IdxEle.Element in nexts[0] and Array.IdxEle.Element in prevs[Array.length](我冒昧地摆脱了量化,因为您的 Array 签名具有多重性)。
    • 感谢 Loic,我继续研究了 nexts 和 prevs,这些操作真的很有用。
    • 如何在 seq.对我来说 s.add["sample string"] 不起作用