ConstraintGroup.java
001 /*
002  *  ConstraintGroup.java - transducer class
003  *
004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Hamish Cunningham, 24/07/98
013  *
014  *  $Id: ConstraintGroup.java 12006 2009-12-01 17:24:28Z thomas_heitz $
015  */
016 
017 
018 package gate.jape;
019 
020 import java.util.ArrayList;
021 import java.util.Iterator;
022 import java.util.HashSet;
023 
024 import gate.AnnotationSet;
025 import gate.Document;
026 import gate.annotation.AnnotationSetImpl;
027 import gate.util.Strings;
028 
029 
030 /**
031   * A sequence of conjunctions of PatternElements that form a
032   * disjunction.
033   */
034 public class ConstraintGroup
035 extends PatternElement implements JapeConstants, java.io.Serializable
036 {
037   /** Debug flag */
038   private static final boolean DEBUG = false;
039 
040   /** Anonymous constructor. */
041   public ConstraintGroup() {
042     patternElementDisjunction1 = new ArrayList();
043     currentConjunction = new ArrayList();
044     patternElementDisjunction1.add(currentConjunction);
045   // Anonymous constructor
046 
047   /** Need cloning for processing of macro references. See comments on
048     <CODE>PatternElement.clone()</CODE>
049     */
050   public Object clone() {
051     ConstraintGroup newPE = (ConstraintGroupsuper.clone();
052 
053     // created by createDisjunction
054     newPE.currentConjunction = null;
055 
056     newPE.patternElementDisjunction1 = new ArrayList();
057     // for each (conjunction) member of the pattern element discjunction
058     for(
059       Iterator disjunction = patternElementDisjunction1.iterator();
060       disjunction.hasNext();
061 
062     ) {
063 
064       newPE.createDisjunction();
065       // for each pattern element making up this conjunction
066       for(
067         Iterator conjunction = ((ArrayListdisjunction.next()).iterator();
068         conjunction.hasNext();
069 
070       ) {
071         PatternElement pat = (PatternElementconjunction.next();
072 
073         newPE.addPatternElement((PatternElementpat.clone());
074       // for each element of the conjunction
075     // for each conjunction (element of the disjunction)
076 
077     return newPE;
078   // clone
079 
080   /** An array of arrays that represent PatternElement conjunctions
081     * during parsing of the .jape. Each conjunction is
082     * considered as being disjunct with the next. (I.e. they are
083     * or'd, in the same way as expressions around "||" in C and
084     * Java.) Set during parsing; replaced by finish().
085     */
086   private ArrayList patternElementDisjunction1;
087 
088   /** The pattern element disjunction for transduction - Java arrays. */
089   private PatternElement[][] patternElementDisjunction2;
090 
091   /** An array of PatternElements making up a conjunction. It is a member of
092     * patternElementDisjunction. This is the one we're adding to
093     * at present. Used during parsing, not matching.
094     */
095   private ArrayList currentConjunction;
096 
097   /** Make a new disjunction at this point. */
098   public void createDisjunction() {
099     currentConjunction = new ArrayList();
100     patternElementDisjunction1.add(currentConjunction);
101   // createDisjunction
102 
103   /** Add an element to the current conjunction. */
104   public void addPatternElement(PatternElement pe) {
105     currentConjunction.add(pe);
106   // addPatternElement
107 
108   /** Get an list of CPEs that we contain. */
109   protected Iterator getCPEs() {
110     ArrayList cpes = new ArrayList();
111 
112     // for each (conjunction) member of the pattern element discjunction
113     for(
114       Iterator disjunction = patternElementDisjunction1.iterator();
115       disjunction.hasNext();
116     ) {
117       // for each pattern element making up this conjunction
118       for(
119         Iterator conjunction = ((ArrayListdisjunction.next()).iterator();
120         conjunction.hasNext();
121       ) {
122         PatternElement pat = (PatternElementconjunction.next();
123 
124         Iterator i = null;
125         if(pat instanceof ComplexPatternElement) {
126           cpes.add(pat);
127           i = ((ComplexPatternElementpat).getCPEs();
128         }
129         else if(pat instanceof ConstraintGroup)
130           i = ((ConstraintGrouppat).getCPEs();
131 
132         if(i != null)
133           for; i.hasNext())
134             cpes.add(i.next());
135       // for each element of the conjunction
136     // for each conjunction (element of the disjunction)
137 
138     return cpes.iterator();
139   // getCPEs
140 
141   /**
142    * Populate the HashSet passed as a parameter with all the annotation
143    * types that occur in this and recursively contained pattern elements.
144    */
145   public void getContainedAnnotationTypes(HashSet<String> set) {
146     // for each (conjunction) member of the pattern element discjunction
147     for(
148       Iterator disjunction = patternElementDisjunction1.iterator();
149       disjunction.hasNext();
150       ) {
151       // for each pattern element making up this conjunction
152       for(
153         Iterator conjunction = ((ArrayListdisjunction.next()).iterator();
154         conjunction.hasNext();
155       ) {
156         PatternElement pat = (PatternElementconjunction.next();
157         if(pat instanceof BasicPatternElement) {
158           ArrayList<Constraint> constraints = 
159             ((BasicPatternElement)pat).getUnfinishedConstraints();
160           for (Constraint c : constraints) {
161             set.add(c.getAnnotType());
162           }
163         else if(pat instanceof ComplexPatternElement) {
164           ((ComplexPatternElement)pat)
165             .getConstraintGroup().getContainedAnnotationTypes(set);
166         else if(pat instanceof ConstraintGroup) {
167           ((ConstraintGroup)pat)
168             .getContainedAnnotationTypes(set);
169         }
170       // for each pattern element making up this conjunction
171     // for each (conjunction) member of the pattern element discjunction
172   // method getContainedAnnotationTypes(String<String>)
173   
174   /** Finish: replace dynamic data structures with Java arrays; called
175     * after parsing.
176     */
177   public void finish() {
178 
179     // index into patternElementDisjunction2
180     int i = 0;
181 
182     // index into the conjunctions (second dimension of pED2)
183     int j = 0;
184 
185     patternElementDisjunction2 =
186       new PatternElement[patternElementDisjunction1.size()][];
187 
188     // for each (conjunction) member of the pattern element discjunction
189     for(
190       Iterator disjuncIter = patternElementDisjunction1.iterator();
191       disjuncIter.hasNext();
192       i++
193     ) {
194       ArrayList conjunction = (ArrayListdisjuncIter.next();
195       patternElementDisjunction2[inew PatternElement[conjunction.size()];
196       j = 0;
197 
198       // for each pattern element making up this conjunction
199       for(
200         Iterator conjIter = conjunction.iterator();
201         conjIter.hasNext();
202         j++
203       ) {
204         patternElementDisjunction2[i][j(PatternElementconjIter.next();
205         patternElementDisjunction2[i][j].finish();
206       // loop on conjunction
207 
208     // loop on patternElementDisjunction1
209 
210     patternElementDisjunction1 = null;
211   // finish
212 
213 
214 
215   /** Create a string representation of the object. */
216   public String toString() { return toString("")}
217 
218   /** Create a string representation of the object. */
219   public String toString(String pad) {
220     String newline = Strings.getNl();
221 
222     StringBuffer buf =
223       new StringBuffer(pad + "CG: disjunction(" + newline);
224     String newPad = Strings.addPadding(pad, INDENT_PADDING);
225 
226     boolean firstTime = true;
227 
228     if(patternElementDisjunction1 != null) { // before finish()
229       // for each (conjunction) member of the pattern element discjunction
230       for(
231         Iterator disjunction = patternElementDisjunction1.iterator();
232         disjunction.hasNext();
233       ) {
234         if(firstTimefirstTime = false;
235         else buf.append(newline + pad + "|" + newline);
236 
237         // for each pattern element making up this conjunction
238         for(
239           Iterator conjunction = ((ArrayListdisjunction.next()).iterator();
240           conjunction.hasNext();
241         ) {
242           buf.append(
243             ((PatternElementconjunction.next()).toString(newPad+ newline
244           );
245         // for each element of the conjunction
246       // for each conjunction (element of the disjunction)
247 
248     else // after finish
249       int pEDLen = patternElementDisjunction2.length;
250       if(firstTimefirstTime = false;
251       else buf.append(newline + pad + "|" + newline);
252 
253       for(int i = 0; i < pEDLen; i++) {
254         int conjLen = patternElementDisjunction2[i].length;
255         // for each pattern element making up this conjunction
256         for(int j = 0; j < conjLen; j++)
257           buf.append(
258             patternElementDisjunction2[i][j].toString(newPad+ newline
259           );
260       }
261     }
262 
263     buf.append(pad + ") CG." + newline);
264 
265     return buf.toString();
266   // toString
267 
268 
269   //needed by FSM
270   public PatternElement[][] getPatternElementDisjunction(){
271     return patternElementDisjunction2;
272   }
273 
274 // class ConstraintGroup
275 
276 
277 // $Log$
278 // Revision 1.11  2005/01/11 13:51:36  ian
279 // Updating copyrights to 1998-2005 in preparation for v3.0
280 //
281 // Revision 1.10  2004/07/21 17:10:07  akshay
282 // Changed copyright from 1998-2001 to 1998-2004
283 //
284 // Revision 1.9  2004/03/25 13:01:15  valyt
285 // Imports optimisation throughout the Java sources
286 // (to get rid of annoying warnings in Eclipse)
287 //
288 // Revision 1.8  2001/09/13 12:09:50  kalina
289 // Removed completely the use of jgl.objectspace.Array and such.
290 // Instead all sources now use the new Collections, typically ArrayList.
291 // I ran the tests and I ran some documents and compared with keys.
292 // JAPE seems to work well (that's where it all was). If there are problems
293 // maybe look at those new structures first.
294 //
295 // Revision 1.7  2001/09/12 11:59:33  kalina
296 // Changed the old JAPE stuff to use the new Collections API,
297 // instead of com.objectspace stuff. Will eliminate that library
298 // completely very soon! Just one class left to re-implement,
299 //
300 // ParseCPSL.jj changed accordingly. All tested and no smoke.
301 //
302 // Revision 1.6  2000/11/08 16:35:02  hamish
303 // formatting
304 //
305 // Revision 1.5  2000/10/26 10:45:30  oana
306 // Modified in the code style
307 //
308 // Revision 1.4  2000/10/16 16:44:33  oana
309 // Changed the comment of DEBUG variable
310 //
311 // Revision 1.3  2000/10/10 15:36:35  oana
312 // Changed System.out in Out and System.err in Err;
313 // Added the DEBUG variable seted on false;
314 // Added in the header the licence;
315 //
316 // Revision 1.2  2000/04/14 18:02:46  valyt
317 // Added some gate.fsm classes
318 // added some accessor function in old jape classes
319 //
320 // Revision 1.1  2000/02/23 13:46:06  hamish
321 // added
322 //
323 // Revision 1.1.1.1  1999/02/03 16:23:01  hamish
324 // added gate2
325 //
326 // Revision 1.17  1998/11/24 16:18:29  hamish
327 // fixed toString for calls after finish
328 //
329 // Revision 1.16  1998/11/01 21:21:36  hamish
330 // use Java arrays in transduction where possible
331 //
332 // Revision 1.15  1998/11/01 14:55:54  hamish
333 // fixed lFP setting in matches
334 //
335 // Revision 1.14  1998/10/30 14:06:45  hamish
336 // added getTransducer
337 //
338 // Revision 1.13  1998/10/29 12:07:49  hamish
339 // toString change
340 //
341 // Revision 1.12  1998/10/06 16:16:10  hamish
342 // negation percolation during constrain add; position advance when none at end
343 //
344 // Revision 1.11  1998/10/01 16:06:30  hamish
345 // new appelt transduction style, replacing buggy version
346 //
347 // Revision 1.10  1998/09/26 09:19:16  hamish
348 // added cloning of PE macros
349 //
350 // Revision 1.9  1998/09/17 16:48:31  hamish
351 // added macro defs and macro refs on LHS
352 //
353 // Revision 1.8  1998/08/12 19:05:43  hamish
354 // fixed multi-part CG bug; set reset to real reset and fixed multi-doc bug
355 //
356 // Revision 1.7  1998/08/12 15:39:35  hamish
357 // added padding toString methods
358 //
359 // Revision 1.6  1998/08/05 21:58:06  hamish
360 // backend works on simple test
361 //
362 // Revision 1.5  1998/08/03 19:51:20  hamish
363 // rollback added
364 //
365 // Revision 1.4  1998/07/31 13:12:16  hamish
366 // done RHS stuff, not tested
367 //
368 // Revision 1.3  1998/07/30 11:05:16  hamish
369 // more jape
370 //
371 // Revision 1.2  1998/07/29 11:06:56  hamish
372 // first compiling version
373 //
374 // Revision 1.1.1.1  1998/07/28 16:37:46  hamish
375 // gate2 lives