/** * Initializes the variable lists and generates the respective Alloy declarations. * * @throws EchoError * @todo Support fom <code>CollectionTemplateExp</code> */ private void initVariableLists() throws EchoError { Map<EVariable, String> whenvar2model = new HashMap<EVariable, String>(); Map<EVariable, String> sourcevar2model = new HashMap<EVariable, String>(); Map<EVariable, String> targetvar2model = new HashMap<EVariable, String>(); for (EModelDomain dom : relation.getDomains()) { rootvariables.put(dom.getRootVariable(), dom.getModel().getName()); if (dependency.target.equals(dom)) targetdomain = dom; else sourcedomains.add(dom); } ECondition preCondition = relation.getPre(); if (preCondition != null) whenvar2model = preCondition.getVariables(null); for (EModelDomain dom : sourcedomains) { ECondition cond = dom.getCondition(); sourcevar2model.putAll(cond.getVariables(dom.getModel().getName())); } for (EVariable x : whenvar2model.keySet()) { whenvar2model.put(x, sourcevar2model.get(x)); sourcevar2model.remove(x); } ECondition temp = targetdomain.getCondition(); targetvar2model = temp.getVariables(targetdomain.getModel().getName()); ECondition postCondition = relation.getPost(); if (postCondition != null) for (EVariable x : postCondition.getVariables(null).keySet()) if (targetvar2model.get(x) == null) targetvar2model.put(x, null); for (EVariable x : sourcevar2model.keySet()) { if (sourcevar2model.get(x) == null) sourcevar2model.put(x, targetvar2model.get(x)); targetvar2model.remove(x); } for (EVariable x : whenvar2model.keySet()) { if (whenvar2model.get(x) == null) whenvar2model.put(x, targetvar2model.get(x)); targetvar2model.remove(x); } if (!top) for (EVariable x : rootvariables.keySet()) { whenvar2model.remove(x); targetvar2model.remove(x); sourcevar2model.remove(x); } for (EVariable s : sourcevar2model.keySet()) var2model.put(s.getName(), sourcevar2model.get(s)); for (EVariable s : targetvar2model.keySet()) var2model.put(s.getName(), targetvar2model.get(s)); for (EVariable s : whenvar2model.keySet()) var2model.put(s.getName(), whenvar2model.get(s)); if (!top) for (EVariable s : rootvariables.keySet()) var2model.put(s.getName(), rootvariables.get(s)); sourcevar2alloydecl = AlloyUtil.variableListToExpr(sourcevar2model.keySet(), var2varmodel(), modelparam2var); for (String s : sourcevar2alloydecl.keySet()) var2var.put(s, sourcevar2alloydecl.get(s).get()); targetvar2alloydecl = AlloyUtil.variableListToExpr(targetvar2model.keySet(), var2varmodel(), modelparam2var); for (String s : targetvar2alloydecl.keySet()) var2var.put(s, targetvar2alloydecl.get(s).get()); whenvar2alloydecl = AlloyUtil.variableListToExpr(whenvar2model.keySet(), var2varmodel(), modelparam2var); for (String s : whenvar2alloydecl.keySet()) var2var.put(s, whenvar2alloydecl.get(s).get()); rootvar2alloydecl = AlloyUtil.variableListToExpr(rootvariables.keySet(), var2varmodel(), modelparam2var); if (!top) for (String s : rootvar2alloydecl.keySet()) var2var.put(s, rootvar2alloydecl.get(s).get()); }
/** * Calculates the Alloy constraint denoting the relation top test. Takes the shape "forall * whenvars : when => (forall sourcevars : sourcedomain => (exists targetvars+wherevars : * targetdomain && where))" Must be run after relation field is created (otherwise recursive calls * will fail) * * @return the Alloy constraint representing the relation * @throws EchoError */ private Expr calculateFact() throws EchoError { Expr fact = Sig.NONE.no(), sourceexpr = Sig.NONE.no(), postexpr = Sig.NONE.no(), whenexpr = Sig.NONE.no(); Decl[] arraydecl; ECondition postCondition = relation.getPost(); ECondition targetCondition = targetdomain.getCondition(); try { if (postCondition != null) { postCondition.initTranslation(parent_translator, var2varmodel(), modelparam2var, null); postexpr = (Expr) postCondition.translate(); } targetCondition.initTranslation(parent_translator, var2varmodel(), modelparam2var, null); Expr targetexpr = (Expr) targetCondition.translate(); targetexpr = targetexpr.and(postexpr); if (targetvar2alloydecl.size() == 1) targetexpr = targetexpr.forSome(targetvar2alloydecl.values().iterator().next()); else if (targetvar2alloydecl.size() > 1) { arraydecl = targetvar2alloydecl.values().toArray(new Decl[targetvar2alloydecl.size()]); targetexpr = targetexpr.forSome(arraydecl[0], Arrays.copyOfRange(arraydecl, 1, arraydecl.length)); } for (EModelDomain dom : sourcedomains) { ECondition sourceCondition = dom.getCondition(); sourceCondition.initTranslation(parent_translator, var2varmodel(), modelparam2var, null); sourceexpr = sourceexpr.and((Expr) sourceCondition.translate()); } fact = (sourceexpr.implies(targetexpr)); // for (Decl d : sourcevar2alloydecl.values()) // EchoReporter.getInstance().debug("Source var decl: "+d.names+"::"+d.expr); // for (Decl d : targetvar2alloydecl.values()) // EchoReporter.getInstance().debug("Target var decl: "+d.names+"::"+d.expr); if (sourcevar2alloydecl.size() == 1) { fact = fact.forAll(sourcevar2alloydecl.values().iterator().next()); } else if (sourcevar2alloydecl.size() > 1) { arraydecl = sourcevar2alloydecl.values().toArray(new Decl[sourcevar2alloydecl.size()]); fact = fact.forAll(arraydecl[0], Arrays.copyOfRange(arraydecl, 1, arraydecl.length)); } ECondition preCondition = relation.getPre(); if (preCondition != null) { preCondition.initTranslation(parent_translator, var2varmodel(), modelparam2var, null); whenexpr = (Expr) preCondition.translate(); fact = (whenexpr.implies(fact)); for (Decl d : whenvar2alloydecl.values()) fact = fact.forAll(d); } } catch (Err a) { throw new ErrorAlloy( ErrorAlloy.FAIL_CREATE_VAR, "Failed to create relation constraint variables: " + relation.getName(), a, Task.TRANSLATE_TRANSFORMATION); } return fact; }