public static void main(String[] args) throws Err { // Chooses the Alloy4 options A4Options opt = new A4Options(); opt.solver = A4Options.SatSolver.SAT4J; // abstract sig A {} PrimSig A = new PrimSig("A", Attr.ABSTRACT); // sig B {} PrimSig B = new PrimSig("B"); // one sig A1 extends A {} PrimSig A1 = new PrimSig("A1", A, Attr.ONE); // one sig A2 extends A {} PrimSig A2 = new PrimSig("A2", A, Attr.ONE); // A { f: B lone->lone B } Expr f = A.addField("f", B.lone_arrow_lone(B)); // Since (B lone->lone B) is not unary, the default is "setOf", meaning "f:set (B lone->lone // B)" // A { g: B } Expr g = A.addField("g", B); // The line above is the same as: A.addField(null, "g", B.oneOf()) since B is unary. // If you want "setOf", you need: A.addField(null, "g", B.setOf()) // pred someG { some g } Func someG = new Func(null, "SomeG", null, null, g.some()); // pred atMostThree[x:univ, y:univ] { #(x+y) >= 3 } Decl x = UNIV.oneOf("x"); Decl y = UNIV.oneOf("y"); Expr body = x.get().plus(y.get()).cardinality().lte(ExprConstant.makeNUMBER(3)); Func atMost3 = new Func(null, "atMost3", Util.asList(x, y), null, body); List<Sig> sigs = Arrays.asList(new Sig[] {A, B, A1, A2}); // run { some A && atMostThree[B,B] } for 3 but 3 int, 3 seq Expr expr1 = A.some().and(atMost3.call(B, B)); Command cmd1 = new Command(false, 3, 3, 3, expr1); A4Solution sol1 = TranslateAlloyToKodkod.execute_command(NOP, sigs, cmd1, opt); System.out.println("[Solution1]:"); System.out.println(sol1.toString()); // run { some f && SomeG[] } for 3 but 2 int, 1 seq, 5 A, exactly 6 B Expr expr2 = f.some().and(someG.call()); Command cmd2 = new Command(false, 3, 2, 1, expr2); cmd2 = cmd2.change(A, false, 5); cmd2 = cmd2.change(B, true, 6); A4Solution sol2 = TranslateAlloyToKodkod.execute_command(NOP, sigs, cmd2, opt); System.out.println("[Solution2]:"); System.out.println(sol2.toString()); }
/** * adds to the transformation translator the constraint defining the field of this sub relation * * @param fact the constraint defining this relation * @param field the field representing this sub relation * @throws EchoError */ private void addRelationDef(Expr fact, Field field) throws EchoError { Decl fst = rootvar2alloydecl.get(relation.getDomains().get(0).getRootVariable().getName()); Decl snd = rootvar2alloydecl.get(relation.getDomains().get(1).getRootVariable().getName()); Func f; try { Expr e = field.equal(fact.comprehensionOver(fst, snd)); f = new Func(null, field.label + "def", model_params_decls, null, e); transformation_translator.addSubRelationDef(f); } catch (Err a) { throw new ErrorAlloy( ErrorAlloy.FAIL_CREATE_FUNC, "Failed to create sub relation field constraint: " + relation.getName(), a, Task.TRANSLATE_TRANSFORMATION); } }
/** * 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; }