1
2
3
4 package net.sf.bddbddb;
5
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.LinkedList;
9 import java.util.List;
10 import java.util.Map;
11 import java.io.IOException;
12 import java.math.BigInteger;
13 import net.sf.bddbddb.dataflow.PartialOrder.Constraints;
14 import org.jdom.Element;
15
16 /***
17 * Represents a relation in bddbddb.
18 *
19 * @author jwhaley
20 * @version $Id: Relation.java 607 2005-07-15 00:04:10Z joewhaley $
21 */
22 public abstract class Relation {
23
24 /***
25 * Static relation id factory.
26 */
27 private static int relationCounter;
28
29 /***
30 * Name of this relation.
31 */
32 protected String name;
33
34 /***
35 * Attributes of this relation.
36 */
37 protected List
38
39 /***
40 * Negated form of this relation, or null if it doesn't exist.
41 */
42 protected Relation negated;
43
44 /***
45 * Priority of this relation, used in determining iteration order.
46 */
47 int priority = 2;
48
49 /***
50 * Unique id number for this relation.
51 */
52 public final int id;
53
54 /***
55 * Ordering constraints for this relation.
56 */
57 Constraints constraints;
58
59 /***
60 * Code fragments to be executed whenever this relation is updated.
61 */
62 List onUpdate;
63
64 /***
65 * Flag saying whether or not this relation is initialized.
66 */
67 boolean isInitialized;
68
69 /***
70 * Create a new Relation.
71 *
72 * @param solver solver
73 * @param name name of relation
74 * @param attributes attributes for relation
75 */
76 protected Relation(Solver solver, String name, List attributes) {
77 this.name = name;
78 this.attributes = attributes;
79 this.id = relationCounter++;
80 solver.registerRelation(this);
81 for (Iterator i = attributes.iterator(); i.hasNext();) {
82 Attribute a = (Attribute) i.next();
83 if (a.relation == null) a.relation = this;
84 }
85 constraints = new Constraints();
86 onUpdate = new LinkedList();
87 }
88
89 /***
90 * Initialize this relation.
91 */
92 public abstract void initialize();
93
94 /***
95 * Load this relation from disk in its native format.
96 *
97 * @throws IOException
98 */
99 public abstract void load() throws IOException;
100
101 /***
102 * Load the tuple form of this relation from disk.
103 *
104 * @throws IOException
105 */
106 public abstract void loadTuples() throws IOException;
107
108 /***
109 * Load this relation in tuple form from the given file.
110 *
111 * @param filename the file to load
112 * @throws IOException
113 */
114 public abstract void loadTuples(String filename) throws IOException;
115
116 /***
117 * Save the current value of this relation to disk in its native format.
118 *
119 * @throws IOException
120 */
121 public abstract void save() throws IOException;
122
123 /***
124 * Save the current value of this relation to disk in tuple form.
125 *
126 * @throws IOException
127 */
128 public abstract void saveTuples() throws IOException;
129
130 /***
131 * Save the value of this relation in tuple form to the given file.
132 *
133 * @param filename name of file to save
134 * @throws IOException
135 */
136 public abstract void saveTuples(String filename) throws IOException;
137
138 /***
139 * Make a copy of this relation. The new relation will have the same attributes
140 * and a derived name.
141 *
142 * @return the new relation
143 */
144 public abstract Relation copy();
145
146 /***
147 * Free the memory associated with this relation. After calling this, the relation can
148 * no longer be used.
149 */
150 public abstract void free();
151
152 /***
153 * Return the number of tuples in this relation.
154 *
155 * @return number of tuples in relation
156 */
157 public long size() {
158 return (long) dsize();
159 }
160
161 /***
162 * Return the number of tuples in this relation, in double format.
163 *
164 * @return number of tuples in relation
165 */
166 public abstract double dsize();
167
168 /***
169 * Return an iterator over the tuples of this relation.
170 *
171 * @return iterator of BigInteger[]
172 */
173 public abstract TupleIterator iterator();
174
175 /***
176 * Return an iterator over the values in the kth field of the relation. k is
177 * zero-based.
178 *
179 * @param k
180 * zero-based field number
181 * @return iterator of BigInteger[]
182 */
183 public abstract TupleIterator iterator(int k);
184
185 /***
186 * Return an iterator over the tuples where the kth field has value j. k is
187 * zero-based.
188 *
189 * @param k
190 * zero-based field number
191 * @param j
192 * value
193 * @return iterator of BigInteger[]
194 */
195 public abstract TupleIterator iterator(int k, BigInteger j);
196
197 /***
198 * Return an iterator over the tuples where the fields match the values in
199 * the given array. A -1 value in the array matches any value.
200 *
201 * @param j
202 * values
203 * @return iterator of BigInteger[]
204 */
205 public abstract TupleIterator iterator(BigInteger[] j);
206
207 /***
208 * Returns true iff this relation contains a tuple where the kth field is
209 * value j. k is zero-based.
210 *
211 * @param k
212 * zero-based field number
213 * @param j
214 * value
215 * @return whether the given value appears in the given field
216 */
217 public abstract boolean contains(int k, BigInteger j);
218
219 /***
220 * Adds the given tuple to this relation. Returns true if the relation changed.
221 *
222 * @param tuple new tuple
223 * @return true iff relation changed
224 */
225 public abstract boolean add(BigInteger[] tuple);
226
227 /***
228 * Return the negated form of this relation, or null if it does not exist.
229 *
230 * @return negated version of this relation, or null
231 */
232 public Relation getNegated() {
233 return negated;
234 }
235
236 /***
237 * Get or create the negated form of this relation.
238 *
239 * @param solver
240 * solver
241 * @return negated version of this relation
242 */
243 public Relation makeNegated(Solver solver) {
244 if (negated != null) return negated;
245 negated = solver.createRelation("!" + name, attributes);
246 negated.negated = this;
247 return negated;
248 }
249
250
251
252
253
254
255 public String toString() {
256 return name;
257 }
258
259 /***
260 * Returns a verbose representation of the relation
261 */
262 public abstract String verboseToString();
263
264 public String elementsToString() {
265 TupleIterator i = this.iterator();
266 StringBuffer sb = new StringBuffer("[");
267 while (i.hasNext()) {
268 BigInteger t[] = i.nextTuple();
269 sb.append('<');
270 for (int k = 0; k < t.length; ++k) {
271 if (k > 0) sb.append(',');
272 sb.append(this.getAttribute(k).getDomain().toString(t[k]));
273 }
274 sb.append('>');
275 if (i.hasNext()) sb.append(",\n");
276 }
277 sb.append(']');
278 return sb.toString();
279 }
280
281 /***
282 * Returns the list of attributes of this relation.
283 *
284 * @return attributes
285 */
286 public List getAttributes() {
287 return attributes;
288 }
289
290 /***
291 * Get the attribute at the given index.
292 *
293 * @param x index
294 * @return attribute
295 */
296 public Attribute getAttribute(int x) {
297 return (Attribute) attributes.get(x);
298 }
299
300 /***
301 * Get the attribute with the given name.
302 *
303 * @param x name
304 * @return attribute
305 */
306 public Attribute getAttribute(String x) {
307 for (Iterator i = attributes.iterator(); i.hasNext();) {
308 Attribute a = (Attribute) i.next();
309 if (x.equals(a.attributeName)) return a;
310 }
311 return null;
312 }
313
314 /***
315 * Returns the number of attributes.
316 *
317 * @return number of attributes
318 */
319 public int numberOfAttributes() {
320 return attributes.size();
321 }
322
323 /***
324 * Returns the constraints.
325 *
326 * @return constraints
327 */
328 public Constraints getConstraints() {
329 return constraints;
330 }
331
332 /***
333 * Set the constraints for this relation.
334 *
335 * @param constraints The constraints to set.
336 */
337 public void setConstraints(Constraints constraints) {
338 this.constraints = constraints;
339 }
340
341 /***
342 * The hashCode for relations is deterministic. (We use the unique id number.)
343 *
344 * @see java.lang.Object#hashCode()
345 */
346 public int hashCode() {
347 return id;
348 }
349
350 /***
351 * @return map from names to variables
352 */
353 public Map getAttribNameMap() {
354 HashMap nameToAttrib = new HashMap();
355 for (Iterator i = attributes.iterator(); i.hasNext(); ) {
356 Attribute a = (Attribute) i.next();
357 nameToAttrib.put(a.attributeName, a);
358 }
359 return nameToAttrib;
360 }
361
362 public static Relation fromXMLElement(Element e, XMLFactory f) {
363
364 return null;
365 }
366
367 public Element toXMLElement() {
368
369 return null;
370 }
371 }