Function 通过传递闭包递归使用合金函数

Function 通过传递闭包递归使用合金函数,function,recursion,closures,alloy,Function,Recursion,Closures,Alloy,我正在用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 Express

我正在用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
}
问题是块必须是语句表达式序列,同时避免对同一方法的递归调用。因此,我在上面的解决方案中思考

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

.
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的定义(从而消除了提到的函数):

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

^ can be used only with a binary relation.
Instead, its possible type(s) are:
{genericLawsMetaModel/javametamodel_withfield_final/Method}
有线索吗?我只是想避免对同一方法的递归调用。
提前感谢,

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

因此,我将MethodInvokedInsideBody声明为该方法的一个字段,并像您那样对其使用传递闭包

希望有帮助:)

编辑:

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

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
}

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

因此,我将MethodInvokedInsideBody声明为该方法的一个字段,并像您那样对其使用传递闭包

希望有帮助:)

编辑:

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

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
}

嗨,洛奇·甘麦托尼,谢谢你的回复。但是,你能说得更清楚些吗?(见我的问题版,我试着按照你的建议去做,但没有用=/)我编辑了我的答案。在第二次尝试中,您尝试将传递闭包运算符应用于singleton类型的方法。正如错误消息所强调的,这不是一个二元关系,因此出现了错误。嗨,Loïc Gammaitoni,谢谢你的回复。但是,你能说得更清楚些吗?(见我的问题版,我试着按照你的建议去做,但没有用=/)我编辑了我的答案。在第二次尝试中,您尝试将传递闭包运算符应用于singleton类型的方法。正如错误消息所强调的,这不是一个二进制关系,因此出现了错误。