理解。和&操作者

时间:2016-03-26 00:16:37

标签: alloy

我无法理解这些运算符的工作原理。问题如下:我基本上写了这个

abstract sig Statement {
    predecessor: lone Statement
    --...
}
sig Assignment extends Statement{
    --...
}
--Statements have unique prdecessors
fact { all disj s, t: Statement | s.predecessor & t.predecessor = none }

但是当我运行它时,我得到了这个: this / Statement<:predecessor = {作业$ 0->作业$ 1,作业$ 1->作业$ 1,...}

现在我理解的是,s.predecessor和t.predecessor应该采用前任关系并预测第一个元素(分别为s和t),这意味着赋值$ 0.predecessor应该产生{Assignment $ 1}和Assignment $ 1。前任也应该产生{Assignment $ 1}。然后取这些 union 的交集(&)肯定不是没有,所以它与事实相矛盾,不应该出现。

你能解释我哪里出错吗?

由于

编辑:

这是所有代码。它很长,还有一些其他问题,但有问题的部分在那里。我看不出有什么可能影响事实。运行它时可以在第一个例子中看到这个问题(无论如何都在我的机器上)。

//Signatures

//specification

--Expressions
abstract sig Expr{
    type: one Type,
    subExprs: set Expr
}

--Literals
sig Literal extends Expr{}
{ no subExprs }

--Variables
sig Variable{
    type: Type
}

--Functions
sig Function{
    statements: set Statement,
    returnType: one Type,
    params: set FormalParameter
}

--Statements
abstract sig Statement {
    exprs: set Expr,
    predecessor: lone Statement
}

--Variable Declarations
sig VarDecl extends Statement{
    var: Variable
}
{ no exprs }

--Types
sig Type{
    super: lone Type
}

--Formal Parameters
sig FormalParameter{
    type: Type,
    var: Variable
}

//more

--Call Expressions
sig CallExpr extends Expr{
    funct: Function,
    mapping: subExprs -> FormalParameter
}
//not modeled: order of parameters is the same as order of exprs

--Varaible References
sig Reference extends Expr{
    var: Variable
}
{ no subExprs }

--Return Statement
sig Return extends Statement{}
{ one exprs }

--Variable Assignment
sig Assignment extends Statement{
    var: Variable
}
{ one exprs }

--Main Function
one sig Main extends Function{}  




//==========================================================================
//Functions

//specification

--number of function calls in the program
fun p_numFunctionsCalls[]: Int{
    #CallExpr
}

--returns the types of all expressions
fun p_literalTypes[]: set Type{
    Expr.type // not sure if multiples allowed
}

--Returns all statements directly contained in the body of a function
fun p_statementsInFunction[f: Function]: set Statement{
    f.statements
}

--Returns all statements contained after s in the same function
fun p_statementsAfter[s: Statement]: set Statement{
    { fs: Statement | s in fs.^predecessor } 
}

--Returns the formal parameters of function f
fun p_parameters[f: Function]: FormalParameter{
    {ps: f.params}
}

--Returns the direct subexpressions of e
fun p_subExprs[e: Expr]: set Expr{
    e.subExprs
}

//more

--Returns all Expression in a function
fun p_funExprs[f: Function]: set Expr{
     p_statementExprs[f.statements]
}

--Returns all callExpressions in a function
fun p_funCallExprs[f: Function]: set CallExpr{
    { ce: CallExpr | ce in  p_funExprs[f]}
}

--Returns all exprs in s
fun p_statementExprs[s: Statement]: set Expr{
    s.exprs.*subExprs
}

--Returns all references in statements
fun p_statementReferences[s: Statement]: set Reference{
    { r: Reference | r in s.p_statementExprs }
}

--Returns all variable Declarations in f
fun p_funVarDecls[f: Function]: set VarDecl{
    { vd: VarDecl | vd in f.statements }
}

--Returns all variables declared in f
fun p_funVars[f: Function]: set Variable{
    { v: Variable | v in f.p_funVarDecls.var }
}

--return all subTypes of t and t itself
fun p_subTypes[t: Type]: set Type{
    { st: Type | t in st.*super }
}


//==========================================================================
//Predicates

//specification

--true iff f contains a function call directly in its body
pred p_containsCall[f: Function]{
    { some ce: CallExpr | ce in f.statements.exprs.*subExprs }
}

--true iff v appears on the left side of an assignment anywhere the program
pred p_isAssigned[v: Variable]{
    v in Assignment.var
}

--true iff v appears in an expression anywhere the program
pred p_isRead[v: Variable]{
    v in Reference.var
}

--true iff v is declared exactly once
pred p_isDeclared[v: Variable]{
    { all disj a, b: VarDecl | v = a.var implies v != b.var }
}

--true iff v is declared as a parameter
pred p_isParameter[v: Variable]{
    { all vd: VarDecl | v not in vd.var }//FIXME: variable might not be declared at all
}

--true iff t1 is a subtype of t2
pred p_subtypeOf[t1: Type, t2: Type]{
    t1 in t2.super
}

--true iff s assigns to the variable declared by vd
pred p_assignsTo[s: Statement, vd: VarDecl]{
    { all a: Assignment | s in a implies vd.var = a.var }
}

//more

//==========================================================================
//Facts

--All statements are in functions
fact { all s: Statement | s in Function.statements }

--Statements unique to functions
fact { all s: Statement, disj f, g: Function |  s in f.statements implies s not in g.statements }

--Statement predecessors are in same function
fact { all s: Statement, f: Function | s in f.statements implies s.p_statementsAfter in f.statements }

--Statements have unique prdecessors
fact { all disj s, t: Statement | s.predecessor & t.predecessor = none }


--return is always last
fact { all r: Return, f: Function | r in f.statements implies r.^predecessor = f.statements - r} 

--return has the same type as function its in
fact { all r: Return, f: Function | r in f.statements implies r.exprs.type in f.returnType.p_subTypes }



--assignments are only used after vars are declared
fact { all a: Assignment, vd: VarDecl | a.var in vd.var implies a in vd.p_statementsAfter }

--assignment and variable type match
fact { all a: Assignment | a.subExprs.type = a.var.type.p_subTypes }


--references only reference variables of the same function
fact { all r: Reference, f: Function | r in f.p_funExprs implies (r.var in f.params.var  or  r.var in f.p_funVars) }

--references only reference declared variables, all variables are referenced
fact { all f: Function | p_statementReferences[f.statements].var = f.p_funVars }

--type of the reference is type of the variable
fact { all r: Reference | r.type in r.var.type.p_subTypes }



--all functions have a return
fact { all f: Function | Return & f.statements != none }

--all functions but main are called
fact { all f: Function | f not in Main implies f in CallExpr.funct }

--recursion is not allowed
fact { all f: Function | f not in f.p_funCallExprs.*funct }


--each expression only in one statement
fact { all disj s, t: Statement | s.p_statementExprs & t.p_statementExprs = none }

--all expressions in statements
fact { all e: Expr | e in p_statementExprs[Statement] }

--expression not in its subExprs
fact { all e: Expr | e not in e.^subExprs }

--subExpressions unique
fact { all disj c, d, e: Expr | c in d.subExprs implies c not in e.subExprs }


--main never called
fact { Main not in CallExpr.funct }

--main has no params
fact { Main.params = none }


--types not supertytes of themselves
fact { all t: Type | t not in t.^super }


--variables always declared in either callExprs or varDecls
fact { all v: Variable | (v in VarDecl.var iff v not in FormalParameter.var) and (v in FormalParameter.var iff v not in VarDecl.var) }

--variables only declared once in varDecls
fact { all disj u, v: VarDecl | u.var != v.var }

--variables only declared once as parameters / parameters map to unique variable
fact { all disj fp1, fp2: FormalParameter | fp1.var != fp2.var }

--variables have the same type as corresponding param
fact { all fp: FormalParameter | fp.type = fp.var.type }

--declared variables are used always after the declaration and never before
fact { all vd: VarDecl | vd.var in vd.p_statementsAfter.p_statementReferences.var and  vd.var not in vd.^predecessor.p_statementReferences.var }


--parameters are never assigned to
fact { all fp: FormalParameter | fp.var not in Assignment.var }

--all parameters are in functions
fact { all fp: FormalParameter | fp in Function.params }

--params are unique to functions
fact { all fp: FormalParameter, disj f, g: Function | fp in f.params implies fp not in g.params }


--only params of function are mapped to
fact { all ce: CallExpr, expr: ce.subExprs | ce.mapping[expr] in ce.funct.params }

--callExprs have correct type
fact { all ce: CallExpr | ce.type = ce.funct.returnType }

--types of mapping are correct
fact { all ce: CallExpr, expr: ce.subExprs, p: ce.funct.params | ce.mapping[expr] = p implies expr.type = p.type }

--callExpr mapping is unique
fact { all ce: CallExpr, disj expr1, expr2: ce.subExprs | ce.mapping[expr1] != ce.mapping[expr2] }

--all subExprs are being mapped
fact { all ce: CallExpr | #ce.subExprs = #ce.funct.params } 


/*
--references have the same type as their variable
fact { all r: Reference | r.type = r.var.type }


*/


//==========================================================================
//Assertions



//==========================================================================
//Run

pred show{ all ce: CallExpr | #ce.subExprs >= 2}
pred show2{#Literal >= 3}
run {show2} 

1 个答案:

答案 0 :(得分:2)

当我在Alloy 4.2上运行你的模型时,我没有看到任何错误。也许你可能想在这里分享完整的模型。

关于接受联合,您需要使用正确的运算符+&用于交叉。

您可以参考alloy language reference获取基本语法:

  

·e1 + e2:e1和e2的联合;
  ·e1-e2:e1和e2的差异;
  ·e1& e2:e1和e2的交集;