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 }