【问题标题】:Generation of apparently inconsistent alloy instances生成明显不一致的合金实例
【发布时间】:2013-09-25 14:01:49
【问题描述】:

我正在为 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_)

因此,alloy 中的 ConstructorMethodInvocation 签名试图表示 java 中的构造,例如 new A().x()。另外,方法 x() 只能在它不是类 A 的私有方法时才能被调用。所以,为了避免调用类 id_Class 的私有方法,我设置了以下限制(在 ConstructorMethodInvocation 签名中):

(this.@cmethodInvoked in (this.@id_Class).methods || this.@cmethodInvoked in ((this.@id_Class).^extend).methods && (this.@cmethodInvoked).acc != private_)

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

有人看到我做错了吗?

【问题讨论】:

    标签: java instances alloy


    【解决方案1】:

    这是因为您在ConstructorMethodInvocation sig 的附加事实中放错了括号:现在的方式是,您有一个顶级析取,它允许(cmethodInvokedid_Class.methods 中)或(它是在id_Class.^extend.methods 而不是私人的)。如果您将附加的事实块更改为

    {
       this.@cmethodInvoked in this.@id_Class.*extend.methods 
       this.@cmethodInvoked.acc != private_
    }
    

    您将获得预期的行为(星号运算符 (*) 是反射传递闭包,它的含义基本上与您打算编写的原始析取相同;您仍然可以使用旧约束并修复括号)。

    为了检查不存在任何 ConstructorMethodInvocation 方法是私有的实例,我执行了

    check {
      no c: ConstructorMethodInvocation {
        c.cmethodInvoked.acc = private_
      }
    }
    

    没有找到反例。

    【讨论】:

    • 嗨,Aleksandar,我知道您的代码生成的实例是正确的,因为您阻止它通过“c.cmethodInvoked.acc != private_”调用私有方法。出于这个原因,我不明白你的论点。我的意图几乎相同,但我还必须将此方法与 id_class 引用的类链接。我想我会阻止从这个类调用私有方法:“this.@cmethodInvoked in (this.@id_Class).methods) || (this.@cmethodInvoked in ((this.@id_Class).^extend ).methods && (this.@cmethodInvoked).acc != private_"
    • 继续:我会阻止从此类调用私有方法,除非该方法本身在类中,允许调用并且它由事实:this.@cmethodInvoked in (this.@id_Class).methods)。为了更好地说明,下面是一个生成实例的示例:[由于字符限制,请在下一条评论中继续]
    • 公共类 Teste { public static void main( String[] args){ new ClassId_6().methodid_0(); System.out.println(new ClassId_6().methodid_0()); } } 这应该是不可能的,因为 methodid_0 是一个私有方法并且 ConstructorMethodInvocation 签名阻止了这一生成。
    • 我在第一部分“this.@cmethodInvoked in (this.@id_Class).methods)”中犯了一个错误。但即使我在签名中加入了限制:“(this.@cmethodInvoked in (this.@id_Class).methods || this.@cmethodInvoked in ((this.@id_Class).^extend).methods && this.@ cmethodInvoked.acc != private_)",结果是一样的。
    • 我想我没有(而且我仍然不)明白你的问题是什么。我以为您在问为什么所有生成的实例都碰巧只调用私有方法。我对此的回应是,您的模型的所有有效实例总是调用私有方法是不正确的。您能否编辑您的问题并尝试更好地解释您发现模型的具体问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    相关资源
    最近更新 更多