Package kodkod.instance

Examples of kodkod.instance.TupleSet


    /** Computes the upperbound from top-down, then allocate a relation for it.
     * Precondition: sig is not a builtin sig
     */
    private void computeUpperBound(PrimSig sig) throws Err {
        // Sig's upperbound is fully computed. We recursively compute the upperbound for children...
        TupleSet x = ub.get(sig).clone();
        // We remove atoms that MUST be in a subsig
        for(PrimSig c: sig.children()) x.removeAll(lb.get(c));
        // So now X is the set of atoms that MIGHT be in this sig, but MIGHT NOT be in any particular subsig.
        // For each subsig that may need more atom, we say it could potentionally get any of the atom from X.
        for(PrimSig c: sig.children()) {
           if (sc.sig2scope(c) > lb.get(c).size()) ub.get(c).addAll(x);
           computeUpperBound(c);
View Full Code Here


           if (sum==null) { sum=childexpr; continue; }
           // subsigs are disjoint
           sol.addFormula(sum.intersection(childexpr).no(), child.isSubsig);
           sum = sum.union(childexpr);
        }
        TupleSet lower = lb.get(sig).clone(), upper = ub.get(sig).clone();
        if (sum == null) {
           // If sig doesn't have children, then sig should make a fresh relation for itself
           sum = sol.addRel(sig.label, lower, upper);
        } else if (sig.isAbstract == null) {
           // If sig has children, and sig is not abstract, then create a new relation to act as the remainder.
           for(PrimSig child:sig.children()) {
              // Remove atoms that are KNOWN to be in a subsig;
              // it's okay to mistakenly leave some atoms in, since we will never solve for the "remainder" relation directly;
              // instead, we union the remainder with the children, then solve for the combined solution.
              // (Thus, the more we can remove, the more efficient it gets, but it is not crucial for correctness)
              TupleSet childTS = sol.query(false, sol.a2k(child), false);
              lower.removeAll(childTS);
              upper.removeAll(childTS);
           }
           sum = sum.union(sol.addRel(sig.label+" remainder", lower, upper));
        }
View Full Code Here

    private Expression allocateSubsetSig(SubsetSig sig) throws Err {
        // We must not visit the same SubsetSig more than once, so if we've been here already, then return the old value right away
        Expression sum = sol.a2k(sig);
        if (sum!=null && sum!=Expression.NONE) return sum;
        // Recursively form the union of all parent expressions
        TupleSet ts = factory.noneOf(1);
        for(Sig parent:sig.parents) {
           Expression p = (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig)parent);
           ts.addAll(sol.query(true, p, false));
           if (sum==null) sum=p; else sum=sum.union(p);
        }
        // If subset is exact, then just use the "sum" as is
        if (sig.exact) { sol.addSig(sig, sum); return sum; }
        // Allocate a relation for this subset sig, then bound it
View Full Code Here

              if (!(b1 instanceof PrimSig) || b1!=b2 || b1!=b3) break;
              PrimSig sub = (PrimSig)b1;
              Field f1 = s.getFields().get(0), f2 = s.getFields().get(1);
              if (sub.isEnum==null || !list.args.get(0).isSame(sub) || !list.args.get(1).isSame(s.join(f1)) || !list.args.get(2).isSame(s.join(f2))) break;
              // Now, we've confirmed it is a total ordering on an enum. Let's pre-bind the relations
              TupleSet me = sol.query(true, sol.a2k(s), false), firstTS = factory.noneOf(2), lastTS = null, nextTS = factory.noneOf(3);
              if (me.size()!=1 || me.arity()!=1) break;
              int n = sub.children().size();
              for(PrimSig c: sub.children()) {
                 TupleSet TS = sol.query(true, sol.a2k(c), false);
                 if (TS.size()!=1 || TS.arity()!=1) { firstTS=factory.noneOf(2); nextTS=factory.noneOf(3); break; }
                 if (lastTS==null) { firstTS=me.product(TS); lastTS=TS; continue; }
                 nextTS.addAll(me.product(lastTS).product(TS));
                 lastTS=TS;
              }
              if (firstTS.size()!=(n>0 ? 1 : 0) || nextTS.size() != n-1) break;
              sol.addField(f1, sol.addRel(s.label+"."+f1.label, firstTS, firstTS));
              sol.addField(f2, sol.addRel(s.label+"."+f2.label, nextTS, nextTS));
              rep.bound("Field "+s.label+"."+f1.label+" == "+firstTS+"\n");
              rep.bound("Field "+s.label+"."+f2.label+" == "+nextTS+"\n");
              continue again;
           }
           for(Field f:s.getFields()) {
              boolean isOne = s.isOne!=null;
              if (isOne && f.decl().expr.mult()==ExprUnary.Op.EXACTLYOF) {
                 Expression sim = sim(f.decl().expr);
                 if (sim!=null) {
                    rep.bound("Field "+s.label+"."+f.label+" defined to be "+sim+"\n");
                    sol.addField(f, sol.a2k(s).product(sim));
                    continue;
                 }
              }
              Type t = isOne ? Sig.UNIV.type().join(f.type()) : f.type();
              TupleSet ub = factory.noneOf(t.arity());
              for(List<PrimSig> p:t.fold()) {
                 TupleSet upper=null;
                 for(PrimSig b:p) {
                    TupleSet tmp = sol.query(true, sol.a2k(b), false);
                    if (upper==null) upper=tmp; else upper=upper.product(tmp);
                 }
                 ub.addAll(upper);
              }
              Relation r = sol.addRel(s.label+"."+f.label, null, ub);
              sol.addField(f, isOne ? sol.a2k(s).product(r) : r);
           }
        }
        // Add any additional SIZE constraints
        for(Sig s:sigs) if (!s.builtin) {
            Expression exp = sol.a2k(s);
            TupleSet upper = sol.query(true,exp,false), lower=sol.query(false,exp,false);
            final int n = sc.sig2scope(s);
            if (s.isOne!=null && (lower.size()!=1 || upper.size()!=1)) {
                rep.bound("Sig "+s+" in "+upper+" with size==1\n");
                sol.addFormula(exp.one(), s.isOne);
                continue;
            }
            if (s.isSome!=null && lower.size()<1) sol.addFormula(exp.some(), s.isSome);
            if (s.isLone!=null && upper.size()>1) sol.addFormula(exp.lone(), s.isLone);
            if (n<0) continue; // This means no scope was specified
            if (lower.size()==n && upper.size()==n && sc.isExact(s)) {
                rep.bound("Sig "+s+" == "+upper+"\n");
            }
            else if (sc.isExact(s)) {
                rep.bound("Sig "+s+" in "+upper+" with size=="+n+"\n");
                sol.addFormula(size(s,n,true), Pos.UNKNOWN);
            }
            else if (upper.size()<=n){
                rep.bound("Sig "+s+" in "+upper+"\n");
            }
            else {
                rep.bound("Sig "+s+" in "+upper+" with size<="+n+"\n");
                sol.addFormula(size(s,n,false), Pos.UNKNOWN);
View Full Code Here

        private Iterable<Sig> allSigs = null;
        private ConstList<Sig> growableSigs = null;
        private A4Solution partial = null;
        public GreedySimulator() { }
        private TupleSet convert(TupleFactory factory, Expr f) throws Err {
            TupleSet old = ((A4TupleSet) (partial.eval(f))).debugGetKodkodTupleset();
            TupleSet ans = factory.noneOf(old.arity());
            for(Tuple oldT: old) {
                Tuple newT = null;
                for(int i=0; i<oldT.arity(); i++) {
                    if (newT==null) newT=factory.tuple(oldT.atom(i)); else newT=newT.product(factory.tuple(oldT.atom(i)));
                }
                ans.add(newT);
            }
            return ans;
        }
View Full Code Here

            }
            return ans;
        }
        @Override public boolean simplify(A4Reporter rep, A4Solution sol, List<Formula> unused) throws Err {
            TupleFactory factory = sol.getFactory();
            TupleSet oldUniv = convert(factory, Sig.UNIV);
            Set<Object> oldAtoms = new HashSet<Object>(); for(Tuple t: oldUniv) oldAtoms.add(t.atom(0));
            for(Sig s: allSigs) {
                // The case below is STRICTLY an optimization; the entire statement can be removed without affecting correctness
                if (s.isOne!=null && s.getFields().size()==2)
                  for(int i=0; i+3<totalOrderPredicates.size(); i=i+4)
                      if (totalOrderPredicates.get(i+1)==right(sol.a2k(s.getFields().get(0))) && totalOrderPredicates.get(i+3)==right(sol.a2k(s.getFields().get(1)))) {
                          TupleSet allelem = sol.query(true, totalOrderPredicates.get(i), true);
                          if (allelem.size()==0) continue;
                          Tuple first=null, prev=null; TupleSet next=factory.noneOf(2);
                          for(Tuple t:allelem) {
                              if (prev==null) first=t; else next.add(prev.product(t));
                              prev=t;
                          }
                          try {
                              sol.shrink(totalOrderPredicates.get(i+1), factory.range(first,first), factory.range(first,first));
                              sol.shrink(totalOrderPredicates.get(i+2), factory.range(prev,prev), factory.range(prev,prev));
                              sol.shrink(totalOrderPredicates.get(i+3), next, next);
                          } catch(Throwable ex) {
                              // Error here is not fatal
                          }
                      }
                // The case above is STRICTLY an optimization; the entire statement can be removed without affecting correctness
                for(Field f: s.getFields()) {
                    Expression rel = sol.a2k(f);
                    if (s.isOne!=null) {
                        rel = right(rel);
                        if (!(rel instanceof Relation)) continue;
                        // Retrieve the old value from the previous solution, and convert it to the new unverse.
                        // This should always work since the new universe is not yet solved, and so it should have all possible atoms.
                        TupleSet newLower = convert(factory, s.join(f)), newUpper = newLower.clone();
                        // Bind the partial instance
                        for(Tuple t: sol.query(false, rel, false)) for(int i=0; i<t.arity(); i++) if (!oldAtoms.contains(t.atom(i))) { newLower.add(t); break; }
                        for(Tuple t: sol.query(true, rel, false)) for(int i=0; i<t.arity(); i++) if (!oldAtoms.contains(t.atom(i))) { newUpper.add(t); break; }
                        sol.shrink((Relation)rel, newLower, newUpper);
                    } else {
                        if (!(rel instanceof Relation)) continue;
                        // Retrieve the old value from the previous solution, and convert it to the new unverse.
                        // This should always work since the new universe is not yet solved, and so it should have all possible atoms.
                        TupleSet newLower = convert(factory, f), newUpper = newLower.clone();
                        // Bind the partial instance
                        for(Tuple t: sol.query(false, rel, false)) for(int i=0; i<t.arity(); i++) if (!oldAtoms.contains(t.atom(i))) { newLower.add(t); break; }
                        for(Tuple t: sol.query(true, rel, false)) for(int i=0; i<t.arity(); i++) if (!oldAtoms.contains(t.atom(i))) { newUpper.add(t); break; }
                        sol.shrink((Relation)rel, newLower, newUpper);
                    }
                }
            }
View Full Code Here

    public A4TupleSet plus(A4TupleSet that) throws ErrorAPI {
        if (that==null) return this;
        if (sol != that.sol) throw new ErrorAPI("A4TupleSet.plus() requires 2 tuplesets from the same A4Solution.");
        if (arity() != that.arity()) throw new ErrorAPI("A4TupleSet.plus() requires 2 tuplesets with the same arity.");
        if (this==that || tuples.size()==0) return that; else if (that.tuples.size()==0) return this; // special short cut
        TupleSet ts = tuples.clone();
        ts.addAll(that.tuples);
        if (tuples.size()==ts.size()) return this;
        if (that.tuples.size()==ts.size()) return that;
        return new A4TupleSet(ts, sol);
    }
View Full Code Here

    public A4TupleSet minus(A4TupleSet that) throws ErrorAPI {
        if (that==null) return this;
        if (sol != that.sol) throw new ErrorAPI("A4TupleSet.minus() requires 2 tuplesets from the same A4Solution.");
        if (arity() != that.arity()) throw new ErrorAPI("A4TupleSet.minus() requires 2 tuplesets with the same arity.");
        if (tuples.size()==0 || that.tuples.size()==0) return this; // special short cut
        TupleSet ts = tuples.clone();
        ts.removeAll(that.tuples);
        if (tuples.size()!=ts.size()) return new A4TupleSet(ts, sol); else return this;
    }
View Full Code Here

    public A4TupleSet intersect(A4TupleSet that) throws ErrorAPI {
        if (sol != that.sol) throw new ErrorAPI("A4TupleSet.intersect() requires 2 tuplesets from the same A4Solution.");
        if (arity() != that.arity()) throw new ErrorAPI("A4TupleSet.intersect() requires 2 tuplesets with the same arity.");
        if (this.tuples.size()==0) return this; // special short cut
        if (that.tuples.size()==0) return that; // special short cut
        TupleSet ts = tuples.clone();
        ts.retainAll(that.tuples);
        if (tuples.size()!=ts.size()) return new A4TupleSet(ts, sol); else return this;
    }
View Full Code Here

    /** This tries a particular solution against the formula. */
    private static Solution trial (A4Reporter rep, TupleFactory fac, Solver solver, Iterable<Sig> sigs, Formula f, A4Solution frame, Object[] t) {
       try {
          frame.kr2typeCLEAR();
          Bounds b = null;
          TupleSet ts = null;
          for(int i=1; i<t.length; i++) {
             Object x=t[i];
             if (x==null) return null;
             if (x instanceof String && ((String)x).length()>0) { // This means it's a unary Tuple containing the given atom
                Tuple xx = fac.tuple((String)x);
                if (ts==null) ts=fac.noneOf(1);
                ts.add(xx);
                continue;
             }
             if (x instanceof Tuple) { // This means it's a Tuple
                Tuple xx=(Tuple)x;
                if (ts==null) ts=fac.noneOf(xx.arity());
                ts.add(xx);
                continue;
             }
             if (x instanceof String) { // The empty string means the sig name follows here
                i++;
                if (i>=t.length-1 || !(t[i] instanceof String) || !(t[i+1] instanceof String)) return null;
                String sigName = (String)(t[i]);
                i++;
                String fieldName = (String)(t[i]);
                Sig first = hasSig(sigs,sigName);
                if (first==null) return null;
                Expression expr = null;
                if (fieldName.length()==0) {
                    expr=frame.a2k(first);
                } else {
                    for(Field field:first.getFields()) if (field.label.equals(fieldName)) {
                        expr=frame.a2k(field);
                        while(expr instanceof BinaryExpression) expr=((BinaryExpression)expr).right();
                        break;
                    }
                }
                if (!(expr instanceof Relation)) return null;
                if (b==null) b = frame.getBounds(); // We delay the expansive Bounds.clone() until we really find a possible match
                if (ts==null) ts = fac.noneOf(expr.arity());
                if (!ts.containsAll(b.lowerBound((Relation)expr))) return null; // Sanity check
                if (!b.upperBound((Relation)expr).containsAll(ts)) return null; // Sanity check
                b.boundExactly((Relation)expr, ts);
                ts=null;
                continue;
             }
View Full Code Here

TOP

Related Classes of kodkod.instance.TupleSet

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.