View Javadoc

1   // Relation.java, created Mar 16, 2004 12:39:48 PM 2004 by jwhaley
2   // Copyright (C) 2004 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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/*<Attribute>*/ attributes;
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      * (non-Javadoc)
252      * 
253      * @see java.lang.Object#toString()
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         // TODO.
364         return null;
365     }
366     
367     public Element toXMLElement() {
368         // TODO.
369         return null;
370     }
371 }