【问题标题】:Using Alloy functions in a recursive way through transitive closures通过传递闭包以递归方式使用 Alloy 函数
【发布时间】:2015-04-27 20:58:59
【问题描述】:

我正在用 Alloy 做一个模型来表示 Java 语言的一个子集。下面我们有这个模型的一些元素:

sig Method {
    id : one MethodId,
    param: lone Type,
    return: one Type,
    acc: lone Accessibility,    
    b: one Block
}

abstract sig Expression {}
abstract sig StatementExpression extends Expression {}

sig MethodInvocation extends StatementExpression{
    pExp: lone PrimaryExpression, 
    id_methodInvoked: one Method,
    param: lone Type
}

sig Block {
    statements: seq StatementExpression
}

pred noRecursiveMethodInvocationCall [] {
    no m:Method | m in ^getMethodInvokedInsideBody[m]
}

fun getMethodInvokedInsideBody [m: Method] : Method {
      (univ.(m.b.statements)).id_methodInvoked
}

问题是 Block 必须是 StatementExpression 的序列,同时应该避免对同一方法的递归调用。因此,我想到了上面的解决方案。

当我尝试生成相应的实例时,我得到以下错误类型:

.
Name cannot be resolved; possible incorrect
function/predicate call; perhaps you used ( ) when you
should have used [ ]

This cannot be a correct call to fun
genericLawsMetaModel/javametamodel_withfield_final/getMethodInvokedInsideBody.
The parameters are
m:
{genericLawsMetaModel/javametamodel_withfield_final/Method}
so the arguments cannot be empty.

关于这个问题,我还尝试更改谓词 noRecursiveMethodInvocationCall 的定义(从而消除上述函数):

pred noRecursiveMethodInvocationCall [] {
    no m:Method | m in ^( (univ.(m.b.statements)).id_methodInvoked )
}

但是,出现新的类型错误:

^ can be used only with a binary relation.
Instead, its possible type(s) are:
{genericLawsMetaModel/javametamodel_withfield_final/Method}

有什么线索吗?我只是想避免对同一方法的递归调用。 提前致谢,

【问题讨论】:

    标签: function recursion closures alloy


    【解决方案1】:

    您误用了传递闭包运算符 ^。 后者仅适用于二元关系,不适用于函数。

    因此,我会将 MethodInvokedInsideBody 声明为 Method 的一个字段,并按照您的方式对其使用传递闭包。

    希望对你有帮助:)

    编辑:

    这是一个如何使用传递闭包运算符来实现您想要实现的目标的示例:

    sig Method {
        id : one MethodId,
        param: lone Type,
        return: one Type,
        acc: lone Accessibility,    
        b: one Block
        methodsInvokedInsideBody: set Method
    }
    
    pred noRecursiveMethodInvocationCall{
        no m:Method | m in m.^methodsInvokedInsideBody
    }
    

    【讨论】:

    • 嗨,Loïc Gammaitoni,感谢您的回复。但是,你能更清楚一点吗? (请参阅我的问题版,我尝试按照您的建议进行操作,但它不起作用=/)
    • 我编辑了我的答案。在您的第二次尝试中,您尝试将传递闭包运算符应用于 Method 类型的单例。这不是二元关系,因为错误消息突出显示,因此错误。
    猜你喜欢
    • 2018-06-09
    • 2020-10-02
    • 2018-03-07
    • 2023-03-15
    • 2011-05-02
    • 2012-10-10
    • 2017-03-24
    • 2020-11-06
    • 1970-01-01
    相关资源
    最近更新 更多