package de.psi.alloy4smt.ast; import de.psi.alloy4smt.smt.SExpr; import edu.mit.csail.sdg.alloy4.ConstList; import edu.mit.csail.sdg.alloy4.Pair; import edu.mit.csail.sdg.alloy4compiler.ast.Command; import edu.mit.csail.sdg.alloy4compiler.ast.Sig; import kodkod.instance.TupleFactory; import kodkod.instance.TupleSet; import java.util.List; import java.util.Vector; /** * Created by psi on 08.05.14. */ public class PreparedCommand { public final Command command; public final ConstList<String> hysatExprs; public final ConstList<SExpr> smtExprs; public final ConstList<IntrefSigRecord> intrefRecords; public final ConstList<Sig> sigs; public final Sig.PrimSig intref; public PreparedCommand(Command command, ConstList<String> hysatExprs, ConstList<IntrefSigRecord> intrefRecords, ConstList<Sig> sigs, Sig.PrimSig intref) { this.command = command; this.hysatExprs = hysatExprs; this.intrefRecords = intrefRecords; this.sigs = sigs; this.intref = intref; this.smtExprs = null; } public PreparedCommand(Command command, ConstList<Sig> sigs, Sig.PrimSig intref, ConstList<SExpr> smtExprs) { this.command = command; this.hysatExprs = null; this.intrefRecords = null; this.sigs = sigs; this.intref = intref; this.smtExprs = smtExprs; } public ConstList<String> getIntrefAtoms() { ConstList.TempList<String> result = new ConstList.TempList<String>(); for (IntrefSigRecord record : intrefRecords) { result.addAll(record.getAtoms()); } return result.makeConst(); } public TupleSet getIntRefEqualsTupleSet(TupleFactory factory) { final List<String> atoms = getIntrefAtoms(); final int numatoms = atoms.size(); TupleSet result = factory.noneOf(2); for (int i = 0; i < numatoms; ++i) { for (int j = i + 1; j < numatoms; ++j) { result.add(factory.tuple(atoms.get(i), atoms.get(j))); } } return result; } public TupleSet getEqualsTupleSet(TupleFactory factory) { return null; } public static class IntrefSigRecord { public final Sig.PrimSig sig; public final Sig.Field mapfield; public final ConstList<Sig> dependencies; public final int instances; public IntrefSigRecord(Sig.PrimSig intexpr, Sig.Field mapfield, ConstList<Sig> dependencies, int instances) { this.sig = intexpr; this.mapfield = mapfield; this.dependencies = dependencies; this.instances = instances; } public List<String> getAtoms() { List<String> result = new Vector<String>(); for (int i = 0; i < instances; ++i) { result.add(IntRefPreprocessor.atomize(sig, i)); } return result; } private ConstList<Pair<Sig, Integer>> getDependencyScopes(Command command) { ConstList.TempList<Pair<Sig, Integer>> result = new ConstList.TempList<Pair<Sig, Integer>>(); for (Sig sig : dependencies) { result.add(new Pair<Sig, Integer>(sig, Helpers.getScope(command, sig))); } return result.makeConst(); } public TupleSet getMapBounds(Command command, TupleFactory factory) { TupleSet result = null; if (mapfield != null) { final ConstList<Pair<Sig, Integer>> depscopes = getDependencyScopes(command); final int depsize = depscopes.size(); int[] sigids = new int[depsize + 1]; result = factory.noneOf(depsize + 1); addMapBoundsTuples(factory, result, depscopes, 0, sigids); } return result; } private void addMapBoundsTuples(TupleFactory factory, TupleSet result, ConstList<Pair<Sig, Integer>> depscopes, int depthlvl, int[] sigids) { if (depthlvl < depscopes.size()) { final int scope = depscopes.get(depthlvl).b; for (int i = 0; i < scope; ++i) { sigids[depthlvl + 1] = i; addMapBoundsTuples(factory, result, depscopes, depthlvl + 1, sigids); } } else { List<String> tuple = new Vector<String>(); tuple.add(IntRefPreprocessor.atomize(sig, sigids[0]++)); for (int d = depscopes.size() - 1; d >= 0; --d) { tuple.add(IntRefPreprocessor.atomize(depscopes.get(d).a, sigids[d + 1])); } result.add(factory.tuple(tuple)); } } } }