00001
00005 package edu.mit.csail.sdg.squander.absstate;
00006
00007 import java.util.Collections;
00008 import java.util.HashSet;
00009 import java.util.Iterator;
00010 import java.util.Set;
00011
00012
00013 import edu.mit.csail.sdg.squander.engine.ForgeConverter;
00014 import forge.solve.ForgeAtom;
00015 import forge.solve.ForgeConstant;
00016 import forge.solve.ForgeConstant.Tuple;
00017
00023 public class ObjTupleSet implements Iterable<ObjTuple> {
00024
00025 private final int arity;
00026 private final Set<ObjTuple> tuples = new HashSet<ObjTuple>();
00027
00028 public ObjTupleSet(int arity) {
00029 this.arity = arity;
00030 }
00031
00032 public ObjTupleSet(ObjTuple val) {
00033 this(val.arity());
00034 tuples.add(val);
00035 }
00036
00037 public int arity() { return arity; }
00038 public boolean isEmpty() { return tuples.isEmpty(); }
00039 public boolean isTuple() { return tuples.size() == 1; }
00040 public boolean isUnary() { return arity == 1; }
00041
00042 public boolean add(ObjTuple e) {
00043 assert arity == e.arity();
00044 return tuples.add(e);
00045 }
00046
00047 public boolean contains(Object o) { return tuples.contains(o); }
00048 public boolean remove(Object o) { return tuples.remove(o); }
00049 public int size() { return tuples.size(); }
00050 public Set<ObjTuple> tuples() { return Collections.unmodifiableSet(tuples); }
00051
00052 @Override public Iterator<ObjTuple> iterator() { return tuples.iterator(); }
00053 @Override public String toString() { return tuples.toString(); }
00054
00056 public ObjTupleSet join(ObjTupleSet ots) { return join(this, ots); }
00058 public ObjTupleSet product(ObjTupleSet ots) { return product(this, ots); }
00060 public ObjTupleSet union(ObjTupleSet ots) { return union(this, ots); }
00062 public ObjTupleSet union(ObjTuple val) { return union(new ObjTupleSet(val)); }
00064 public ObjTupleSet diff(ObjTupleSet ots) { return diff(this, ots); }
00066 public boolean subsetOf(ObjTupleSet rhs) { return rhs.tuples.containsAll(tuples); }
00068 public ObjTupleSet intersection(ObjTupleSet ots) { return intersection(this, ots); }
00069
00070 @Override
00071 public int hashCode() {
00072 final int prime = 31;
00073 int result = 1;
00074 result = prime * result + arity;
00075 result = prime * result + ((tuples == null) ? 0 : tuples.hashCode());
00076 return result;
00077 }
00078
00079 @Override
00080 public boolean equals(Object obj) {
00081 if (this == obj)
00082 return true;
00083 if (obj == null)
00084 return false;
00085 if (getClass() != obj.getClass())
00086 return false;
00087 ObjTupleSet other = (ObjTupleSet) obj;
00088 if (arity != other.arity)
00089 return false;
00090 if (tuples == null) {
00091 if (other.tuples != null)
00092 return false;
00093 } else if (!tuples.equals(other.tuples))
00094 return false;
00095 return true;
00096 }
00097
00101 public static ObjTupleSet singleTuple(Object... tuple) {
00102 ObjTupleSet ots = new ObjTupleSet(tuple.length);
00103 ots.add(new ObjTuple(tuple));
00104 return ots;
00105 }
00106
00111 public static ObjTupleSet filter(ObjTupleSet otset, int i, Object obj) {
00112 ObjTupleSet result = new ObjTupleSet(otset.arity);
00113 for (ObjTuple ot : otset) {
00114 if (ot.get(i) == obj)
00115 result.add(ot);
00116 }
00117 return result;
00118 }
00119
00124 public static ObjTupleSet join(ObjTupleSet lhs, ObjTupleSet rhs) {
00125 assert lhs.arity > 0;
00126 assert rhs.arity > 0;
00127 assert lhs.arity + rhs.arity > 2;
00128 ObjTupleSet result = new ObjTupleSet(lhs.arity + rhs.arity - 2);
00129 for (ObjTuple l : lhs) {
00130 for (ObjTuple r : rhs) {
00131 if (l.get(l.arity() - 1) == r.get(0)) {
00132 Object[] atoms = new Object[result.arity];
00133 System.arraycopy(l.tuple(), 0, atoms, 0, l.arity() - 1);
00134 System.arraycopy(r.tuple(), 1, atoms, l.arity() - 1, r.arity() - 1);
00135 result.add(new ObjTuple(atoms));
00136 }
00137 }
00138 }
00139 return result;
00140 }
00141
00146 public static ObjTupleSet product(ObjTupleSet lhs, ObjTupleSet rhs) {
00147 int arity = lhs.arity + rhs.arity;
00148 ObjTupleSet result = new ObjTupleSet(arity);
00149 for (ObjTuple t1 : lhs.tuples)
00150 for (ObjTuple t2 : rhs.tuples)
00151 result.add(t1.product(t2));
00152 return result;
00153 }
00154
00158 public static ObjTupleSet convertFrom(ForgeConstant val, ForgeConverter fconv) {
00159 ObjTupleSet result = new ObjTupleSet(val.arity());
00160 for (Tuple t : val.tuples()) {
00161 ObjTuple ot = convertToObjTuple(t, fconv);
00162 result.add(ot);
00163 }
00164 return result;
00165 }
00166
00170 private static ObjTuple convertToObjTuple(Tuple t, ForgeConverter fconv) {
00171 Object[] res = new Object[t.arity()];
00172 int idx = 0;
00173 for (ForgeAtom a : t.atoms()) {
00174 res[idx++] = fconv.atom2obj(a);
00175 }
00176 return new ObjTuple(res);
00177 }
00178
00182 public static ObjTupleSet union(ObjTupleSet lhs, ObjTupleSet rhs) {
00183 assert (lhs.arity == rhs.arity);
00184 ObjTupleSet result = new ObjTupleSet(lhs.arity);
00185 result.tuples.addAll(lhs.tuples);
00186 result.tuples.addAll(rhs.tuples);
00187 return result;
00188 }
00189
00193 public static ObjTupleSet diff(ObjTupleSet lhs, ObjTupleSet rhs) {
00194 assert (lhs.arity == rhs.arity);
00195 ObjTupleSet result = new ObjTupleSet(lhs.arity);
00196 result.tuples.addAll(lhs.tuples);
00197 result.tuples.removeAll(rhs.tuples);
00198 return result;
00199 }
00200
00204 public static ObjTupleSet intersection(ObjTupleSet lhs, ObjTupleSet rhs) {
00205 assert (lhs.arity == rhs.arity);
00206 ObjTupleSet result = new ObjTupleSet(lhs.arity);
00207 for (ObjTuple t : lhs)
00208 if (rhs.tuples.contains(t))
00209 result.add(t);
00210 return result;
00211 }
00212
00213 }