产生明显不一致的合金实例

时间:2013-09-25 14:01:49

标签: java instances alloy

我正在使用合金的元模型来获取Java的一个子集。

下面我们有一些签名:

abstract sig Id {}
sig Package{}
sig ClassId, MethodId,FieldId extends Id {}
abstract sig Accessibility {}
one sig public, private_, protected extends Accessibility {}
abstract sig Type {}
abstract sig PrimitiveType extends Type {}
one sig Int_, Long_ extends PrimitiveType {}

sig Class extends Type {
    package: one Package,
    id: one ClassId,
    extend: lone Class,
    methods: set Method,
    fields: set Field
}
sig Field {
    id : one FieldId,
    type: one Type,
    acc : lone Accessibility
}
sig Method {
    id : one MethodId,
    param: lone Type,
    acc: lone Accessibility,
    return: one Type,
    b: one Body
}
abstract sig Body {}
sig LiteralValue extends Body {} // returns a random value
abstract sig Qualifier {}
one sig this_, super_ extends Qualifier {}
sig MethodInvocation extends Body {
    id_methodInvoked : one Method, 
    q: lone Qualifier
}
//        return new A().k();
sig ConstructorMethodInvocation extends Body {
    id_Class : one Class, 
    cmethodInvoked: one Method
}{
    (this.@cmethodInvoked in (this.@id_Class).methods) || (this.@cmethodInvoked in ((this.@id_Class).^extend).methods && (this.@cmethodInvoked).acc != private_)
}
//        return x;
//        return this.x;
//        return super.x;
sig FieldInvocation extends Body {
    id_fieldInvoked : one Field, 
    qField: lone Qualifier
}
//        return new A().x;
sig ConstructorFieldInvocation extends Body {
    id_cf : one Class, 
    cfieldInvoked: one Field
}{
    (this.@cfieldInvoked in (this.@id_cf).fields) || ( this.@cfieldInvoked in ((this.@id_cf).^extend).fields && (this.@cfieldInvoked).acc != private_)
}

在Java语言中,如果此方法不是私有方法,我们只能调用类中的方法(通过此类的实例化)。我试图通过以下签名在我的合金模型中表示这种限制:

sig ConstructorMethodInvocation extends Body {

    id_Class : one Class, 
    cmethodInvoked: one Method
}{
    (this.@cmethodInvoked in (this.@id_Class).methods || this.@cmethodInvoked in ((this.@id_Class).^extend).methods && (this.@cmethodInvoked).acc != private_)

因此,合金中的ConstructorMethodInvocation签名试图表示java中的结构,如new A()。x()。另外,方法x()只有在它不是类A的私有方法时才能被调用。因此,我将以下限制(在ConstructorMethodInvocation签名中)以避免调用类id_Class的私有方法:

(这个。@ cmethodInvoked in(this。@ id_Class).methods || this。@ cmethodInvoked in((this。@ id_Class)。^ extend).methods&&(this。@ cmethodInvoked).acc! =私人_)

但是,尽管存在此限制,解算器仍然坚持生成实例(对于ConstructorMethodInvocation),其中cmethodInvoked是id_Class的私有方法。使用ConstructorFieldInvocation也是如此。

有人看到我做错了吗?

1 个答案:

答案 0 :(得分:1)

这是因为你在ConstructorMethodInvocation sig的附加事实中错误地放置了括号:现在的方式,你有一个顶级析取,允许其中任何一个(cmethodInvoked在{{1}中的实例或者(它在id_Class.methods而不是私有)。如果您将附加的事实块更改为

id_Class.^extend.methods

你会得到预期的行为(星号运算符({ this.@cmethodInvoked in this.@id_Class.*extend.methods this.@cmethodInvoked.acc != private_ } )是反射传递闭包,它基本上与你想要写的原始析取相同;你仍然可以使用你的旧约束而只是修复括号)。

要检查是否存在方法为私有的任何*个实例,我执行了

ConstructorMethodInvocation

没有找到反例。