📄 msystemstate.java
字号:
GFlaggedInvariant flaggedInv = (GFlaggedInvariant) it.next(); MClassInvariant inv = flaggedInv.classInvariant(); Expression expr = inv.expandedExpression(); //sanity check if (! expr.type().isBoolean() ) throw new RuntimeException("Expression " + expr + "has type " + expr.type() + ", expected boolean type"); if (flaggedInv.negated() ){ try { Expression [] args = { expr }; Expression expr1 = ExpStdOp.create("not", args); expr = expr1; } catch (ExpInvalidException e) { // TODO: Should this be ignored or is this a fatal error? } negatedList.add(Boolean.TRUE ); } else { negatedList.add(Boolean.FALSE ); } invList.add(inv); exprList.add(expr); System.out.println("GeneratorInvariants: "+inv); } } else if (invNames.isEmpty() ) { // get all invariants Iterator it = model.classInvariants().iterator(); while (it.hasNext() ) { MClassInvariant inv = (MClassInvariant) it.next(); Expression expr = inv.expandedExpression(); // sanity check if (! expr.type().isBoolean() ) throw new RuntimeException("Expression " + expr + "has type " + expr.type() + ", expected boolean type"); invList.add(inv); negatedList.add(Boolean.FALSE ); exprList.add(expr); } } else { // get only specified invariants Iterator it = invNames.iterator(); while (it.hasNext() ) { String invName = (String) it.next(); MClassInvariant inv = model.getClassInvariant(invName); if (inv != null ) { Expression expr = inv.expandedExpression(); // sanity check if (! expr.type().isBoolean() ) throw new RuntimeException("Expression " + expr + "has type " + expr.type() + ", expected boolean type"); invList.add(inv); negatedList.add(Boolean.FALSE ); exprList.add(expr); } else { GFlaggedInvariant flaggedInv = fSystem.generator().flaggedInvariant(invName); inv = flaggedInv.classInvariant(); if (inv != null ) { Expression expr = inv.expandedExpression(); //sanity check if (! expr.type().isBoolean() ) throw new RuntimeException("Expression " + expr + "has type " + expr.type() + ", expected boolean type"); if (flaggedInv.negated() ){ try { Expression [] args = { expr }; Expression expr1 = ExpStdOp.create("not", args); expr = expr1; } catch (ExpInvalidException e) { // TODO: Should this be ignored or is this a fatal error? } negatedList.add(Boolean.TRUE ); } else { negatedList.add(Boolean.FALSE ); } invList.add(inv); exprList.add(expr); } } } /////////////////////////////////////////// // it's the same as above /////////////////////////////////////////// // } else { // // get only specified invariants // Iterator it = invNames.iterator(); // while ( it.hasNext() ) { // String invName = (String) it.next(); // MClassInvariant inv = model.getClassInvariant(invName); // if ( inv != null ) { // Expression expr = inv.expandedExpression(); // // sanity check // if ( ! expr.type().isBoolean() ) // throw new RuntimeException("Expression " + expr + // "has type " + expr.type() + // ", expected boolean type"); // invList.add(inv); // exprList.add(expr); // } // } } // start (possibly concurrent) evaluation Queue resultValues = evaluator.evalList(Options.EVAL_NUMTHREADS, exprList, this); // receive results for (int i = 0; i < exprList.size(); i++) { MClassInvariant inv = (MClassInvariant) invList.get(i); numChecked++; String negated = ((Boolean) negatedList.get(i)).booleanValue() ? " negated" : ""; String msg = "checking invariant (" + numChecked + ") `" + inv.cls().name() + "::" + inv.name() + "': "; out.print(msg); // + inv.bodyExpression()); out.flush(); try { Value v = (Value) resultValues.get(); // if value 'v' is null, the invariant can not be evaluated, therefor // it is N/A (not available). if (v == null ){ out.println("N/A"); // if there is a value, the invariant can allways be evaluated and the // result can be printed. } else { boolean ok = v.isDefined() && ((BooleanValue) v).isTrue(); if (ok ) out.println("OK."); // (" + timeStr +")."); else { out.println("FAILED."); // (" + timeStr +")."); out.println(" -> " + v.toStringWithType()); // repeat evaluation with output of all subexpression results if (traceEvaluation ) { out.println("Results of subexpressions:"); Expression expr = (Expression) exprList.get(i); evaluator.eval(expr, this, new VarBindings(), out); } // show instances violating the invariant by using // the OCL expression C.allInstances->reject(self | <inv>) if (showDetails ) { out.println("Instances of " + inv.cls().name() + " violating the invariant:"); Expression expr = inv.getExpressionForViolatingInstances(); Value v1 = evaluator.eval(expr, this, new VarBindings()); out.println(" -> " + v1.toStringWithType()); } valid = false; numFailed++; } } } catch (InterruptedException ex) { Log.error("InterruptedException: " + ex.getMessage()); } } long t = System.currentTimeMillis() - tAll; String timeStr = t % 1000 + "s"; timeStr = (t / 1000) + "." + StringUtil.leftPad(timeStr, 4, '0'); out.println("checked " + numChecked + " invariant" + ((numChecked == 1 ) ? "" : "s") + " in " + timeStr + ", " + numFailed + " failure" + ((numFailed == 1 ) ? "" : "s") + '.'); out.flush(); return valid; } /** * Checks model inherent constraints, i.e., checks whether * cardinalities of association links match their declaration of * multiplicities. */ public boolean checkStructure(PrintWriter out) { boolean res = true; out.println("checking structure..."); out.flush(); // check all associations Iterator it = fSystem.model().associations().iterator(); while (it.hasNext() ) { MAssociation assoc = (MAssociation) it.next(); if (assoc.associationEnds().size() != 2 ) { // check for n-ary links if (! naryAssociationsAreValid(out, assoc) ) res = false; } else { // check both association ends Iterator it2 = assoc.associationEnds().iterator(); MAssociationEnd aend1 = (MAssociationEnd) it2.next(); MAssociationEnd aend2 = (MAssociationEnd) it2.next(); if (! binaryAssociationsAreValid(out, assoc, aend1, aend2) || ! binaryAssociationsAreValid(out, assoc, aend2, aend1) ) res = false; } } //out.println("checking link cardinalities, done."); out.flush(); return res; } private boolean naryAssociationsAreValid(PrintWriter out, MAssociation assoc) { boolean valid = true; Set links = linksOfAssociation(assoc).links(); Iterator aendIter1 = assoc.associationEnds().iterator(); while (aendIter1.hasNext() ) { MAssociationEnd selEnd = (MAssociationEnd) aendIter1.next(); List otherEnds = selEnd.getAllOtherAssociationEnds(); List classes = new ArrayList(); for (Iterator it = otherEnds.iterator(); it.hasNext();) { MAssociationEnd end = (MAssociationEnd) it.next(); classes.add(end.cls()); } Bag crossProduct = getCrossProductOfInstanceSets(classes); for (Iterator itTuples=crossProduct.iterator(); itTuples.hasNext();) { MObject[] tuple = (MObject[])itTuples.next(); int count = 0; for( Iterator itLinks=links.iterator();itLinks.hasNext();) { MLink link = (MLink)itLinks.next(); boolean ok=true; int index = 0; for (Iterator itEnds=otherEnds.iterator();itEnds.hasNext();) { MAssociationEnd end = (MAssociationEnd)itEnds.next(); if (link.linkEnd(end).object()!=tuple[index]) { ok=false; } ++index; } if (ok) ++count; } if (!selEnd.multiplicity().contains(count)) { out.println("Multiplicity constraint violation in association `" + assoc.name() + "':"); out.println(" Objects `" + StringUtil.fmtSeq(tuple, ", ") + "' are connected to " + count + " object" + ((count == 1 ) ? "" : "s") + " of class `" + selEnd.cls().name() + "'"); out.println(" but the multiplicity is specified as `" + selEnd.multiplicity() + "'."); valid = false; } } } return valid; } /** * Returns a bag containing the cross product of the instances of * <code>classes</code> * @param classes * @return a bag of object arrays (<code>Bag(MObject[])</code>) */ Bag getCrossProductOfInstanceSets(List classes) { Bag bag = new HashBag(); insertAllNMinusOneTuples(bag, (MClass[])classes.toArray(new MClass[classes.size()]), 0, new MObject[0]); return bag; } // Helper method for getCrossProductOfInstanceSets. private void insertAllNMinusOneTuples(Bag allNMinusOneTuples, MClass[] classes, int index, MObject[] objects) { if (index < classes.length) { MClass next = classes[index]; MObject[] objects1 = new MObject[objects.length + 1]; for (int i=0;i<objects.length;++i) objects1[i] = objects[i]; for (Iterator it=objectsOfClassAndSubClasses(next).iterator();it.hasNext();) { MObject obj = (MObject)it.next(); objects1[objects.length] = obj; insertAllNMinusOneTuples(allNMinusOneTuples, classes, index+1, objects1); } } else { allNMinusOneTuples.add(objects.clone()); } } private boolean binaryAssociationsAreValid(PrintWriter out, MAssociation assoc, MAssociationEnd aend1, MAssociationEnd aend2) { boolean valid = true; // for each object of the association end's type get // the number of links in which the object participates MClass cls = aend1.cls(); Set objects = objectsOfClassAndSubClasses(cls); Iterator it = objects.iterator(); while (it.hasNext() ) { MObject obj = (MObject) it.next(); List objList = getLinkedObjects(obj, aend1, aend2); int n = objList.size(); if (! aend2.multiplicity().contains(n) ) { out.println("Multiplicity constraint violation in association `" + assoc.name() + "':"); out.println(" Object `" + obj.name() + "' of class `" + obj.cls().name() + "' is connected to " + n + " object" + ((n == 1 ) ? "" : "s") + " of class `" + aend2.cls().name() + "'"); out.println(" but the multiplicity is specified as `" + aend2.multiplicity() + "'."); valid = false; } } return valid; } /** * Returns a unique name that can be used for a new object of the * given class. Checks whether the name is used in this state. * BigFix for USE 2.0.0. * This operation is only used by the Snapshot Generator. */ public String uniqueObjectNameForClass(String clsName) { String name; do name = system().uniqueObjectNameForClass(clsName); while (objectByName(name)!=null ); return name; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -