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