Using Alloy functions in a recursive way through transitive closures

眉间皱痕 提交于 2019-12-11 20:19:35

问题


I am doing a model in Alloy to represent a subset of Java language. Below we have some elements of this model:

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
}

The problem is that Block has to be a sequence of StatementExpression at the same time that recursive calls to the same method should be avoided. Thus, I thought in the solution above.

When i try to generate the corresponding instances i get the following error type:

.
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.

Still regarding this question, i also tried changing the definition for the predicate noRecursiveMethodInvocationCall (thus eliminating the mentioned function):

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

However, a new type error occurs:

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

Any clue? I just want to avoid recursive calls to the same method. Thanks in advance,


回答1:


You are misusing the transitive closure operator ^. This latter applies on binary relations solely, not on functions.

I would thus declare MethodInvokedInsideBody as a field of the Method and use transitive closure on it the way you did.

Hope it helps :)

EDIT:

Here is an example of how the transitive closure operator can be used in order to achieve what you want to achieve:

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
}


来源:https://stackoverflow.com/questions/29905830/using-alloy-functions-in-a-recursive-way-through-transitive-closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!