KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > jrexx > set > AutomatonSet_String


1 /*
2 * 01/07/2003 - 15:19:32
3 *
4 * AutomatonSet_String.java -
5 * Copyright (C) 2003 Buero fuer Softwarearchitektur GbR
6 * ralf.meyer@karneim.com
7 * http://jrexx.sf.net
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */

23 package com.tc.jrexx.set;
24
25 import com.tc.jrexx.automaton.*;
26
27 import java.util.*;
28
29 public class AutomatonSet_String extends Automaton {
30   protected static final ISet_char FULLSET = new com.tc.jrexx.set.CharSet();
31   static {
32     AutomatonSet_String.FULLSET.complement();
33   }
34
35   protected static class SProperties extends HashSet implements IProperties {
36
37     public SProperties() {
38     }
39
40     public boolean containsAll(IProperties p) {
41       //performance leak
42
if ((p instanceof SProperties)==false) throw new IllegalArgumentException JavaDoc("(p instanceof SProperties)==false");
43       return super.containsAll((SProperties)p);
44     }
45
46     public void addAll(IProperties p) {
47       //performance leak
48
if ((p instanceof SProperties)==false) throw new IllegalArgumentException JavaDoc("(p instanceof SProperties)==false");
49       super.addAll((SProperties)p);
50     }
51
52     public void retainAll(IProperties p) {
53       //performance leak
54
if ((p instanceof SProperties)==false) throw new IllegalArgumentException JavaDoc("(p instanceof SProperties)==false");
55       super.retainAll((SProperties)p);
56     }
57
58     public void removeAll(IProperties p) {
59       //performance leak
60
if ((p instanceof SProperties)==false) throw new IllegalArgumentException JavaDoc("(p instanceof SProperties)==false");
61       super.removeAll((SProperties)p);
62     }
63
64     public Object JavaDoc clone() {
65       return super.clone();
66     }
67
68   }
69
70   public interface ISStateChangedListener extends IStateChangedListener {
71     public void isFinalChanged(SState state,boolean isFinal);
72   }
73
74
75   public interface ISState extends Automaton.IState {
76     public boolean isFinal();
77   }
78
79   public class SState extends Automaton.State implements ISState {
80
81     public boolean isFinal;
82
83     public SState(boolean isFinal) {
84       this.isFinal = isFinal;
85     }
86
87     protected Automaton parent() {
88       return AutomatonSet_String.this;
89     }
90
91     protected void setDeterministic(Boolean JavaDoc isDeterministic) {
92       super.setDeterministic(isDeterministic);
93     }
94
95     public boolean isFinal() {
96       return this.isFinal;
97     }
98
99     protected void setFinal(boolean isFinal) {
100       if (this.isFinal==isFinal) return;
101       this.isFinal = isFinal;
102       //inform listener
103
if (this.changedListeners!=null) {
104         final Iterator it = this.changedListeners.iterator();
105         for (int i=this.changedListeners.size(); i>0; --i) {
106           ((ISStateChangedListener)it.next()).isFinalChanged(this,isFinal);
107         }
108       }
109     }
110
111 /*
112     protected void addTransition(State.Transition trans) {
113       super.addTransition(trans);
114     }
115 */

116     protected Transition addTransition(IProperties properties,ISet_char charSet,State toState) {
117       // performance leak
118
if (properties!=null && (properties instanceof SProperties)==false) throw new IllegalArgumentException JavaDoc("(properties instanceof SProperties)==false");
119       if ((toState instanceof SState)==false) throw new IllegalArgumentException JavaDoc("(toState("+toState+") instanceof SState)==false");
120
121       return super.addTransition(properties,charSet,toState);
122     }
123
124     protected boolean removeTransition(State.Transition trans) {
125       return super.removeTransition(trans);
126       /*
127       if(super.removeTransition(trans)) {
128         return true;
129       }
130       return false;
131       */

132     }
133
134     protected void removeAllTransitions() {
135       super.removeAllTransitions();
136     }
137
138     protected IState getEClosure() {
139       return super.getEClosure();
140     }
141
142     public String JavaDoc toString() {
143       if (this.isFinal) return AutomatonSet_String.this.automatonNr+".["+String.valueOf(this.stateNr)+']';
144       else return super.toString();
145     }
146
147   }
148
149   protected class LinkedSet_SState extends Automaton.LinkedSet_State implements ISState {
150
151     protected LinkedSet_SState() {
152       super();
153     }
154
155     protected LinkedSet_SState(SState state) {
156       super(state);
157     }
158
159     public boolean isFinal() {
160       for (Wrapper_State w=this.elements; w!=null; w=w.next) {
161         if ( ((SState)w.state).isFinal ) return true;
162       }
163       return false;
164     }
165
166     public String JavaDoc toString() {
167       final StringBuffer JavaDoc result = new StringBuffer JavaDoc();
168       result.append( this.isFinal() ? '[' : '(' );
169       for (Wrapper_State wrapper=this.elements; wrapper!=null; wrapper=wrapper.next) {
170         if (wrapper!=this.elements) result.append(", ");
171         result.append(wrapper.state.toString());
172       }
173       result.append( this.isFinal() ? ']' : ')' );
174       return result.toString();
175     }
176
177   }
178
179
180   protected final ISet_char fullSet;
181 // protected boolean isMinimized = true;
182

183   protected AutomatonSet_String(ISet_char fullSet) {
184     super();
185     this.fullSet = fullSet;
186   }
187
188   protected void addChangedListener(Automaton.IChangedListener listener) {
189     super.addChangedListener(listener);
190   }
191
192   protected boolean removeChangedListener(Automaton.IChangedListener listener) {
193     return super.removeChangedListener(listener);
194   }
195
196   protected boolean isDeterministic() {
197     return super.isDeterministic();
198   }
199
200   protected Automaton.State getStartState() {
201     return this.startState;
202   }
203
204
205   protected AutomatonSet_String() {
206     super();
207     this.fullSet = AutomatonSet_String.FULLSET;
208   }
209
210   protected LinkedSet_State newLinkedSet_State() {
211     return new LinkedSet_SState();
212   }
213
214   protected LinkedSet_State newLinkedSet_State(State state) {
215     return new LinkedSet_SState((SState)state);
216   }
217
218   protected State createState() {
219     return new SState(false);
220   }
221
222   protected SState createState(boolean isFinal) {
223     return new SState(isFinal);
224   }
225
226   protected SState addState(boolean isFinal) {
227     final SState result = this.createState(isFinal);
228     this.addState(result);
229     return result;
230   }
231
232   protected SState addState(boolean isFinal,int stateNr) {
233     this.currentStateNr = stateNr;
234     return this.addState(isFinal);
235   }
236
237   protected boolean removeState(State removeState) {
238     return super.removeState(removeState);
239   }
240
241   protected void clear() {
242     super.clear();
243   }
244
245   protected void setDeterministic(Boolean JavaDoc isDeterministic) {
246     super.setDeterminstic(isDeterministic);
247   }
248
249   protected void setStartState(State startState) {
250     super.setStartState(startState);
251   }
252
253   protected LinkedSet_State getStates() {
254     return this.aStates;
255   }
256
257
258   protected SState complement(SState state) {
259     if (state==null) {
260       SState totalFinalState = this.addState(true);
261       totalFinalState.addTransition(null,(ISet_char)this.fullSet.clone(),totalFinalState);
262       return totalFinalState;
263     }
264
265     if (this.isDeterministic(state)==false) {
266       // remove all properties
267
LinkedSet_State states = new LinkedSet_State(state);
268       for (Wrapper_State w=states.elements; w!=null; w=w.next) {
269         for (State.Transition trans=w.state.eTransitions; trans!=null; trans=trans.next) {
270           states.add(trans.toState);
271           trans.properties = null;
272         }
273         for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
274           states.add(trans.toState);
275           trans.properties = null;
276         }
277       }
278
279       state = this.makeDeterministic(state);
280     }
281
282
283     SState totalFinalState = null;
284
285     LinkedSet_State reachableStates = new LinkedSet_State(state);
286     for (Wrapper_State w=reachableStates.elements; w!=null; w=w.next) {
287       ISet_char charSet = (ISet_char)this.fullSet.clone();
288       for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
289         reachableStates.add(trans.toState);
290         charSet.removeAll(trans.charSet);
291       }
292
293       SState sstate = (SState)w.state;
294       if (charSet.isEmpty()==false) {
295         if (totalFinalState==null) {
296           totalFinalState = this.addState(true);
297           totalFinalState.addTransition(null,(ISet_char)this.fullSet.clone(),totalFinalState);
298         }
299
300         sstate.addTransition(null,charSet,totalFinalState);
301       }
302       sstate.setFinal(!sstate.isFinal);
303     }
304
305     return state;
306   }
307
308   protected SState optional(SState state) {
309     if (state.isFinal) return state;
310     final SState newState = this.addState(true);
311     newState.addTransition(null,null,state);
312     return newState;
313   }
314
315   protected SState concat(SState state_A,SState state_B) {
316     final LinkedSet_State states = new LinkedSet_State(state_A);
317     for (Wrapper_State w = states.elements; w!=null; w=w.next) {
318       for (State.Transition trans = w.state.eTransitions; trans!=null; trans=trans.next)
319         states.add(trans.toState);
320
321       for (State.Transition trans = w.state.transitions; trans!=null; trans=trans.next)
322         states.add(trans.toState);
323
324       SState sState = (SState)w.state;
325       if (sState.isFinal) {
326         sState.setFinal(false);
327         sState.addTransition(null,null,state_B);
328       }
329     }
330     return state_A;
331   }
332
333   protected SState repeat(SState element,int minTimes,int maxTimes) {
334     SState startState = element;
335
336     if (minTimes==0) {
337       startState = this.optional(element);
338       minTimes = 1;
339     } else {
340       for (int i=minTimes-1; i>0; --i) {
341         SState newState = (SState)element.clone();
342         startState = (SState)this.concat(newState,startState);
343       }
344     }
345
346     if (maxTimes==0) {
347       final LinkedSet_State states = new LinkedSet_State(element);
348
349       for (Wrapper_State w=states.elements; w!=null; w=w.next) {
350         for (Automaton.State.Transition trans=w.state.eTransitions; trans!=null; trans=trans.next)
351           states.add(trans.toState);
352
353         for (Automaton.State.Transition trans=w.state.transitions; trans!=null; trans=trans.next)
354           states.add(trans.toState);
355
356         if ( ((SState)w.state).isFinal) ((SState)w.state).addTransition(null,null,element);
357       }
358     } else {
359       for (int i=maxTimes-minTimes; i>0; --i) {
360         SState newState = (SState)element.clone();
361
362         LinkedSet_State states = element.getAllReachableStates();
363         states.add(element);
364
365         for (Wrapper_State w=states.elements; w!=null; w=w.next) {
366           if ( ((SState)w.state).isFinal )
367             ((SState)w.state).addTransition(null,null,newState);
368         }
369
370         element = newState;
371       }
372     }
373
374     return startState;
375   }
376
377   protected SState union(SState state_A,SState state_B) {
378     final SState newState = this.addState(false);
379     newState.addTransition(null,null,state_A);
380     newState.addTransition(null,null,state_B);
381     return newState;
382   }
383
384   protected SState intersect(SState state_A,SState state_B) {
385     // A & B = !(!A + !B)
386
return
387       this.complement(
388         this.union(
389           this.complement(state_A),
390           this.complement(state_B)
391         )
392       );
393   }
394
395   protected SState minus(SState state_A,SState state_B) {
396     // A \ B = A & !B = !(!A + !!B) = !(!A + B)
397
return
398       this.complement(
399         this.union(
400           this.complement(state_A),
401           state_B
402         )
403       );
404   }
405
406
407   protected void addAll(SState state) {
408     if (this.startState==null) this.setStartState(state);
409     else this.setStartState(this.union((SState)this.startState,state));
410   }
411
412   protected void retainAll(SState state) {
413     if (this.startState==null) return;
414     this.setStartState(this.intersect((SState)this.startState,state));
415   }
416
417   protected void removeAll(SState state) {
418     if (this.startState==null) return;
419     this.setStartState(this.minus((SState)this.startState,state));
420   }
421
422   protected void concatAll(SState state) {
423     if (this.startState==null) return;
424     this.setStartState(this.concat((SState)this.startState,state));
425   }
426
427
428   protected void removeUselessStates() {
429     if (5==6) {
430       this.removeUnreachableStates();
431       return;
432     }
433     final LinkedSet_State usefullStates = new LinkedSet_State();
434     if (this.startState!=null) {
435       final LinkedSet_State uselessStates = this.startState.getAllReachableStates();
436       uselessStates.add(this.startState);
437       for (Wrapper_State w=uselessStates.elements; w!=null; w=w.next) {
438         if (((SState)w.state).isFinal) {
439           if (uselessStates.remove(w.state)==false) throw new Error JavaDoc();
440 /*
441           if (prev==null) uselessStates.elements = w.next;
442           else prev.next = w.next;
443 */

444           if (usefullStates.add(w.state)==false) throw new Error JavaDoc();
445         }
446       }
447 //System.out.println(uselessStates);
448
for(boolean flag=true; flag;) {
449         flag = false;
450         loop: for (Wrapper_State w=uselessStates.elements; w!=null; w=w.next) {
451           for (State.Transition trans=w.state.eTransitions; trans!=null; trans=trans.next) {
452             if (usefullStates.contains(trans.toState)) {
453               if (uselessStates.remove(w.state)==false) throw new Error JavaDoc();
454               if (usefullStates.add(w.state)==false) throw new Error JavaDoc();
455               flag = true;
456               continue loop;
457             }
458           }
459           for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
460             if (trans.charSet.isEmpty()==false && usefullStates.contains(trans.toState)) {
461               if (uselessStates.remove(w.state)==false) throw new Error JavaDoc();
462               if (usefullStates.add(w.state)==false) throw new Error JavaDoc();
463               flag = true;
464               continue loop;
465             }
466           }
467         }
468       }
469     }
470
471     for (Wrapper_State w=this.aStates.elements; w!=null; w=w.next) {
472       if (usefullStates.contains(w.state)==false) {
473         if (this.removeState(w.state)==false) throw new Error JavaDoc();
474 // System.out.println("####"+w.state.stateNr+"####");
475
}
476     }
477   }
478
479   protected void complement() {
480     this.setStartState( this.complement( (SState)this.startState) );
481     this.removeUselessStates();
482   }
483
484   protected void addAll(AutomatonSet_String automaton) {
485     if (automaton.startState==null) return;
486
487 // final LinkedSet_State reachableStates = automaton.startState.getAllReachableStates();
488
// reachableStates.addAll(automaton.startState);
489
// java.util.Map map = this.cloneStates(reachableStates);
490
java.util.Map JavaDoc map = this.cloneState(automaton.startState);
491     this.addAll((SState)map.get(automaton.startState));
492   }
493
494   protected void retainAll(AutomatonSet_String automaton) {
495     if (automaton.startState==null) return;
496
497 // final LinkedSet_State reachableStates = automaton.startState.getAllReachableStates();
498
// reachableStates.addAll(automaton.startState);
499
// java.util.Map map = this.cloneStates(reachableStates);
500
java.util.Map JavaDoc map = this.cloneState(automaton.startState);
501     this.retainAll((SState)map.get(automaton.startState));
502     this.removeUselessStates();
503   }
504
505   protected void removeAll(AutomatonSet_String automaton) {
506     if (automaton.startState==null) return;
507
508 // final LinkedSet_State reachableStates = automaton.startState.getAllReachableStates();
509
// reachableStates.addAll(automaton.startState);
510
// java.util.Map map = this.cloneStates(reachableStates);
511
java.util.Map JavaDoc map = this.cloneState(automaton.startState);
512     this.removeAll((SState)map.get(automaton.startState));
513     this.removeUselessStates();
514   }
515
516   protected void concatAll(AutomatonSet_String automaton) {
517     if (automaton.startState==null) return;
518
519 // java.util.Map map = this.cloneStates(automaton.startState.getAllReachableStates());
520
java.util.Map JavaDoc map = this.cloneState(automaton.startState);
521     this.concatAll((SState)map.get(automaton.startState));
522   }
523
524   protected Map cloneState(State state) {
525     final Map map = super.cloneState(state);
526     final Set keys = map.keySet();
527     final Iterator it = keys.iterator();
528     for (int i=keys.size(); i>0; --i) {
529       SState oldState = (SState)it.next();
530       SState newState = (SState)map.get(oldState);
531       newState.setFinal(oldState.isFinal);
532     }
533     return map;
534   }
535
536   protected Map cloneStates(LinkedSet_State states) {
537     final Map map = super.cloneStates(states);
538     final Set keys = map.keySet();
539     final Iterator it = keys.iterator();
540     for (int i=keys.size(); i>0; --i) {
541       SState oldState = (SState)it.next();
542       SState newState = (SState)map.get(oldState);
543       newState.setFinal(oldState.isFinal);
544     }
545     return map;
546   }
547
548   protected Object JavaDoc clone() {
549     return super.clone();
550   }
551
552
553   private static class Transition {
554     final ISet_char charSet;
555     final EClosure toEClosure;
556     IProperties properties = null;
557     Transition next = null;
558
559     Transition(IProperties properties,ISet_char charSet,EClosure toEClosure) {
560       this.properties = properties;
561       this.charSet = charSet;
562       this.toEClosure = toEClosure;
563     }
564   }
565
566
567   class EClosure {
568     final LinkedSet_SState states;
569     Transition eTransitions = null;
570     Transition transitions = null;
571
572
573     SState state = null;
574
575     EClosure(LinkedSet_SState eStates) {
576       this.states = eStates;
577     }
578 /*
579     EClosure(SState state) {
580       this.state = state;
581     }
582 */

583     Transition addTransition(IProperties properties,ISet_char charSet,EClosure toEClosure) {
584       Transition newTrans = new Transition(properties,charSet,toEClosure);
585       newTrans.next = this.transitions;
586       this.transitions = newTrans;
587       return newTrans;
588     }
589
590     boolean removeTransition(Transition transition) {
591       for (Transition prevTrans=null, trans=this.transitions; trans!=null; prevTrans=trans, trans=trans.next) {
592         if (trans==transition) {
593           if (prevTrans==null) this.transitions = trans.next;
594           else prevTrans.next = trans.next;
595
596           return true;
597         }
598       }
599       return false;
600     }
601
602     public boolean equals(Object JavaDoc obj) {
603       return this.states.equals( ((EClosure)obj).states );
604     }
605     public int hashCode() {
606       return this.states.hashCode();
607     }
608
609   }
610
611   class EClosureSet {
612     final EClosure eClosure;
613     EClosureSet next = null;
614
615     EClosureSet(EClosure eClosure) {
616       this.eClosure = eClosure;
617     }
618
619     boolean add(EClosure eClosure) {
620       EClosureSet prev = null;
621
622       for (EClosureSet eCS=this; eCS!=null; prev=eCS,eCS=eCS.next) {
623         if (eCS.eClosure==eClosure) return false;
624       }
625
626       prev.next = new EClosureSet(eClosure);
627       return true;
628     }
629   }
630
631   protected SState makeDeterministic(SState state) {
632     //performance leak
633
if ((state instanceof SState)==false) throw new IllegalArgumentException JavaDoc("state instanceof SState)==false");
634     if (AutomatonSet_String.this.isDeterministic(state)) return state;
635
636     final HashMap eStates2EClosure = new HashMap();
637
638
639     IState istate = state.getEClosure();
640     LinkedSet_SState startEStates = (istate instanceof SState)
641                                     ? (LinkedSet_SState)this.newLinkedSet_State((SState)istate)
642                                     : (LinkedSet_SState)istate;
643
644     EClosure startEClosure = new EClosure(startEStates);
645     eStates2EClosure.put(startEStates,startEClosure);
646
647     final EClosureSet eClosureSet = new EClosureSet(startEClosure);
648     for (EClosureSet eCS=eClosureSet; eCS!=null; eCS=eCS.next) {
649       final EClosure eClosure = eCS.eClosure;
650
651       for (Wrapper_State w=eClosure.states.elements; w!=null; w=w.next) {
652         loop: for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
653           ISet_char trans_charSet = trans.charSet;
654           istate = ((SState)trans.toState).getEClosure();
655           LinkedSet_SState trans_toEStates = (istate instanceof SState)
656                                              ? (LinkedSet_SState)this.newLinkedSet_State(trans.toState)
657                                              : (LinkedSet_SState)istate;
658
659           inner: for (Transition newTrans=eClosure.transitions; newTrans!=null; newTrans=newTrans.next) {
660             ISet_char intersection = (ISet_char)newTrans.charSet.clone();
661             intersection.retainAll(trans_charSet);
662
663             if (intersection.isEmpty()==false) {
664
665                 if (trans_toEStates.equals(newTrans.toEClosure.states)==false) {
666                   if (newTrans.charSet.size()==intersection.size())
667                     eClosure.removeTransition(newTrans);
668                   else
669                     newTrans.charSet.removeAll(intersection);
670
671                   /////////////////////////
672

673                   LinkedSet_SState tmpEStates = ((LinkedSet_SState)trans_toEStates.clone());
674                   tmpEStates.addAll(newTrans.toEClosure.states);
675
676                   EClosure newToEClosure = (EClosure)eStates2EClosure.get(tmpEStates);
677                   if (newToEClosure==null) {
678                     newToEClosure = new EClosure(tmpEStates);
679                     eStates2EClosure.put(tmpEStates,newToEClosure);
680                   }
681
682                   if (trans.properties==null) eClosure.addTransition(null,intersection,newToEClosure);
683                   else eClosure.addTransition( (IProperties)trans.properties.clone(),intersection,newToEClosure);
684                 }
685
686                 if (trans_charSet.size()==intersection.size()) continue loop;
687
688                 if (trans_charSet==trans.charSet) trans_charSet = (ISet_char)trans.charSet.clone();
689                 trans_charSet.removeAll(intersection);
690             }
691           }
692
693           if (trans_charSet.isEmpty()==false) {
694             EClosure toEClosure = (EClosure)eStates2EClosure.get(trans_toEStates);
695             if (toEClosure!=null) {
696               for (Transition newTrans=eClosure.transitions; newTrans!=null; newTrans=newTrans.next) {
697                 if (newTrans.toEClosure==toEClosure) {
698                   if (newTrans.properties==null && trans.properties==null
699                       || newTrans.properties!=null && newTrans.properties.equals(trans.properties)) {
700                     newTrans.charSet.addAll(trans.charSet);
701                     continue loop;
702                   }
703                 }
704               }
705             } else {
706               toEClosure = new EClosure(trans_toEStates);
707               eStates2EClosure.put(trans_toEStates,toEClosure);
708             }
709
710             if (trans_charSet==trans.charSet) trans_charSet = (ISet_char)trans.charSet.clone();
711             if (trans.properties==null) eClosure.addTransition(null,trans_charSet,toEClosure);
712             else {
713               eClosure.addTransition((IProperties)trans.properties.clone(),trans_charSet,toEClosure);
714             }
715           }
716         }
717       }
718
719       if (eClosure.state==null) eClosure.state = this.addState(eClosure.states.isFinal());
720       for (Transition trans=eClosure.transitions; trans!=null; trans=trans.next) {
721         if (trans.toEClosure.state==null)
722           trans.toEClosure.state = this.addState(trans.toEClosure.states.isFinal());
723
724         State.Transition newTrans = eClosure.state.addTransition(trans.properties,trans.charSet,trans.toEClosure.state);
725
726         eClosureSet.add(trans.toEClosure);
727       }
728
729     }
730
731     this.isDeterministic = Automaton.UNKNOWN;
732     return startEClosure.state;
733   }
734
735
736   protected void minimize() {
737     if (this.startState==null) return;
738     SState state = (SState)this.startState;
739
740     int states = this.aStates.size();
741     this.setStartState(this.minimize(state));
742 // this.setStartState(this.makeDeterministic(state));
743

744     this.removeUnreachableStates();
745     if (this.aStates.size()>states)
746       throw new Error JavaDoc("more states("+this.aStates.size()+") after minimzing than before ("+states+")");
747   }
748
749
750   private static class Tupel {
751     final SState a;
752     final SState b;
753     final int hashCode;
754
755     Tupel next = null;
756
757     Tupel(SState a,SState b) {
758       if (a==b) throw new Error JavaDoc("a==b");
759       this.a = a;
760       this.b = b;
761
762       this.hashCode = (int)((((long)a.hashCode()) + ((long)b.hashCode())) % 4294967291L);
763     }
764
765     public boolean equals(Object JavaDoc obj) {
766       if (this==obj) return true;
767
768       final Tupel tupel = (Tupel)obj;
769       if (this.a!=tupel.a && this.a!=tupel.b) return false;
770       if (this.b!=tupel.a && this.b!=tupel.b) return false;
771       return true;
772     }
773
774     public int hashCode() {
775       return this.hashCode;
776     }
777   }
778
779   protected SState minimize(SState state) {
780
781
782 //System.out.println("states before makeDeterministic: "+state.getAllReachableStates().size());
783
SState newStartState = this.makeDeterministic(state);
784 //System.out.println("states after makeDeterministic: "+newStartState.getAllReachableStates().size());
785
if (this.aStates.contains(newStartState)==false) throw new Error JavaDoc("this.states.contains(newStartState)==false");
786
787     LinkedSet_State states = newStartState.getAllReachableStates();
788     states.add(newStartState);
789
790     final SState totalState = this.addState(false);
791     states.add(totalState);
792 //System.out.println("totalState: "+totalState);
793

794     HashSet tupelList_ne = new HashSet();
795     Tupel tupelList = null;
796     for (Wrapper_State w1=states.elements; w1!=null; w1=w1.next) {
797       ISet_char rest = (ISet_char)this.fullSet.clone();
798       for (State.Transition trans=w1.state.transitions; trans!=null; trans=trans.next) {
799         rest.removeAll(trans.charSet);
800       }
801       if (rest.isEmpty()==false) ((SState)w1.state).addTransition(null,rest,totalState);
802
803       for (Wrapper_State w2=w1.next; w2!=null; w2=w2.next) {
804         Tupel tupel = new Tupel((SState)w1.state,(SState)w2.state);
805         if (tupel.a.isFinal ^ tupel.b.isFinal) tupelList_ne.add(tupel);
806         else {
807           tupel.next = tupelList;
808           tupelList = tupel;
809         }
810       }
811     }
812
813 //System.out.println("++++++++++++++++++++++++++++++++++++++");
814
//for (Tupel tupel=tupelList; tupel!=null; tupel=tupel.next) {
815
// System.out.println(tupel.a +"=="+tupel.b );
816
//}
817
//Iterator _it = tupelList_ne.iterator();
818
//while (_it.hasNext() ) {
819
// Tupel t = (Tupel)_it.next();
820
// System.out.println( t.a+"!="+t.b );
821
//}
822

823     boolean flag = true;
824     while(flag) {
825       flag = false;
826       loop: for (Tupel tupel=tupelList,prev=null; tupel!=null; tupel=tupel.next) {
827         for (State.Transition trans_a=tupel.a.transitions; trans_a!=null; trans_a=trans_a.next) {
828           for (State.Transition trans_b=tupel.b.transitions; trans_b!=null; trans_b=trans_b.next) {
829             if (trans_a.toState!=trans_b.toState) {
830               Tupel newTupel = new Tupel( (SState)trans_a.toState,(SState)trans_b.toState);
831               if (tupelList_ne.contains(newTupel)) {
832                 ISet_char intersection = (ISet_char)trans_a.charSet.clone();
833                 intersection.retainAll(trans_b.charSet);
834                 if (intersection.isEmpty()==false) {
835                   if (prev==null) tupelList = tupel.next;
836                   else prev.next = tupel.next;
837
838                   tupelList_ne.add(tupel);
839
840                   flag = true;
841                   continue loop;
842                 }
843               }
844             }
845           }
846         }
847         prev = tupel;
848       }
849     }
850
851 //System.out.println("#############################");
852
//for (Tupel tupel=tupelList; tupel!=null; tupel=tupel.next) {
853
// System.out.println(tupel.a.stateNr +"=="+tupel.b.stateNr );
854
//}
855
// _it = tupelList_ne.iterator();
856
//while (_it.hasNext() ) {
857
// Tupel t = (Tupel)_it.next();
858
// System.out.println( t.a.stateNr+"!="+t.b.stateNr );
859
//}
860

861     //should be IdentityMap
862
final HashMap map = new HashMap();
863     for(Tupel tupel=tupelList; tupel!=null; tupel=tupel.next) {
864       SState eqState = (SState)map.get(tupel.a);
865       if (eqState!=null) map.put(tupel.b,eqState);
866       else {
867         eqState = (SState)map.get(tupel.b);
868         if (eqState!=null) map.put(tupel.a,eqState);
869         else if (tupel.b!=totalState) map.put(tupel.a,tupel.b);
870         else map.put(tupel.b,tupel.a);
871       }
872     }
873
874 //System.out.println("***********************************");
875
//Iterator it_ = map.keySet().iterator();
876
//while (it_.hasNext()) {
877
// State key = (State)it_.next();
878
// System.out.println(key.stateNr+"="+((State)map.get(key)).stateNr);
879
//}
880

881     this.removeState(totalState);
882
883     for (Wrapper_State w=states.elements; w!=null; w=w.next) {
884       SState newState = (SState)map.get(w.state);
885       if (newState==null) {
886         for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
887           SState newToState = (SState)map.get(trans.toState);
888           if (newToState!=null) {
889             ((SState)w.state).removeTransition(trans);
890
891             for (State.Transition tmp=w.state.transitions; tmp!=null; tmp=tmp.next) {
892               if (tmp.toState==newToState) {
893                 if (tmp.properties==null && trans.properties==null
894                     || tmp.properties!=null && tmp.properties.equals(trans.properties)) {
895                   ((SState)w.state).removeTransition(tmp);
896                   trans.charSet.addAll(tmp.charSet);
897                   break;
898                 }
899               }
900             }
901
902             ((SState)w.state).addTransition(trans.properties,trans.charSet,newToState);
903           }
904         }
905       } else {
906         loop: for (State.Transition trans=w.state.transitions; trans!=null; trans=trans.next) {
907           SState newToState = (SState)map.get(trans.toState);
908           if (newToState==null) newToState = (SState)trans.toState;
909
910           ((SState)w.state).removeTransition(trans);
911
912           for (State.Transition tmp=newState.transitions; tmp!=null; tmp=tmp.next) {
913             if (tmp.toState==newToState) {
914               if (tmp.properties==null && trans.properties==null
915                   || tmp.properties!=null && tmp.properties.equals(trans.properties)) {
916                 continue loop;
917               }
918             }
919           }
920
921           newState.addTransition(trans.properties,trans.charSet,newToState);
922         }
923       }
924     }
925
926     Iterator it = map.keySet().iterator();
927     for (int i=map.size(); i>0; --i) this.removeState( (SState)it.next() );
928
929     SState newNewStartState = (SState)map.get(newStartState);
930     if (newNewStartState!=null) return newNewStartState;
931     return newStartState;
932   }
933
934 }
Popular Tags