// This class belongs to the following package:
package agg.parser;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import agg.xt_basis.BaseFactory;
import agg.xt_basis.GraGra;
import agg.xt_basis.Graph;
import agg.xt_basis.Match;
import agg.xt_basis.MorphCompletionStrategy;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.Rule;
import agg.util.Pair;
//****************************************************************************+
/**
* This class provides a parser which needs critical pairs. The critical pair
* must be <code>ExcludePair</code>. So objects has to be instanciated with
* <code>ExcludePairContainer</code>. To be independent of a grammar it is
* necessary to instanciate an object with a host graph and stop graph
* seperately.
*
* @author $Author: olga $
* @version $Id: SimpleExcludeParser.java,v 1.11 2010/08/18 09:26:52 olga Exp $
*/
public class SimpleExcludeParser extends ExcludeParser {
/**
* Creates a new parser that is a little bit simpler than a <CODE>ExcludeParser</CODE>.
*
* @param grammar
* The graph grammar.
* @param hostGraph
* The host graph.
* @param stopGraph
* The stop graph.
* @param excludeContainer
* The critical pairs.
*/
public SimpleExcludeParser(GraGra grammar, Graph hostGraph,
Graph stopGraph, ExcludePairContainer excludeContainer) {
super(grammar, hostGraph, stopGraph, excludeContainer);
}
// ****************************************************************************+
/**
* Starts the parser.
*
* @return true if the graph can be parsed.
*/
@SuppressWarnings("rawtypes")
public boolean parse() {
// System.out.println("Starting simple exclude parser ...");
this.correct = true;
fireParserEvent(new ParserMessageEvent(this,
"Starting simple exclude parser ..."));
Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>> conflictFree = null;
if (this.stop)
return false;
try {
conflictFree = this.pairContainer
.getContainer(CriticalPair.CONFLICTFREE);
} catch (InvalidAlgorithmException iae) {
fireParserEvent(new ParserErrorEvent(iae, "ERROR: "
+ iae.getMessage()));
return false;
}
Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>> exclude = null;
if (this.stop)
return false;
try {
exclude = this.pairContainer.getContainer(CriticalPair.EXCLUDE);
} catch (InvalidAlgorithmException iae) {
fireParserEvent(new ParserErrorEvent(iae, "ERROR: "
+ iae.getMessage()));
return false;
}
if (this.stop)
return false;
Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>> conflictFreeLight = null;
Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>> excludeLight = null;
excludeLight = new Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>>();
conflictFreeLight = new Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>>();
if (this.stop)
return false;
makeLightContainer(exclude, excludeLight);
if (this.stop)
return false;
makeLightContainer(conflictFree, conflictFreeLight);
if (this.stop)
return false;
for (Enumeration<Rule> keys = conflictFreeLight.keys(); keys
.hasMoreElements();) {
Object key = keys.nextElement();
if (excludeLight.containsKey(key)) {
conflictFreeLight.remove(key);
}
}
/*
* haelt alle Matche, die kritisch sind, damit nicht an einer Stelle
* immer wieder angesetzt wird
*/
RuleInstances eri = new RuleInstances();
fireParserEvent(new ParserMessageEvent(this, "Parser initialized"));
if (this.stop)
return false;
boolean ruleApplied = false;
while (!this.stop && !this.graph.isIsomorphicTo(this.stopGraph) && this.correct) {
ruleApplied = false;
/* zuerst sollen alle konfliktfreien Regeln probiert werden. */
for (Enumeration<Rule> keys = conflictFreeLight.keys(); keys
.hasMoreElements()
&& !ruleApplied;) {
Rule r = keys.nextElement();
// Report.println("versuche konfliktfreie Regel " + r.getName(),
// Report.PARSER);
fireParserEvent(new ParserMessageEvent(this,
"Searching for easy match"));
Match m = BaseFactory.theFactory().createMatch(r,
getHostGraph());
m.setCompletionStrategy((MorphCompletionStrategy) this.grammar
.getMorphismCompletionStrategy().clone(), true);
// m.getCompletionStrategy().showProperties();
while (!this.stop && !ruleApplied && m.nextCompletion()) {
// TODO ATTRIBUTE CHECKEN machen hier Inputparameter Sinn??
if (m.isValid()) {
if (applyRule(m)) {
ruleApplied = true;
try {
Thread.sleep(this.delay);
} catch (InterruptedException ex1) {
}
}
}
}
}
/* Die konfliktfreien Regeln sind abgearbeitet */
/* Die Excluderegeln muessen ueberprueft werden */
if (!this.stop && !ruleApplied) {
/*
* Zuerst wird ein beliebiger Ansatz einer Regel gesucht.
*/
for (Enumeration<Rule> keys = excludeLight.keys(); keys
.hasMoreElements()
&& !ruleApplied;) {
Rule r = keys.nextElement();
fireParserEvent(new ParserMessageEvent(this,
"Searching for difficult match"));
Match m = BaseFactory.theFactory().createMatch(r,
getHostGraph());
m.setCompletionStrategy((MorphCompletionStrategy) this.grammar
.getMorphismCompletionStrategy().clone(), true);
boolean found = false;
while (!found && m.nextCompletion()) {
if (!eri.isIn(m) && m.isValid())
found = true;
}
if (!this.stop && found) {
OrdinaryMorphism copyMorph = getHostGraph().isomorphicCopy();
if (copyMorph != null) {
fireParserEvent(new ParserMessageEvent(copyMorph,
"IsoCopy"));
eri.add(m);
/*
* ERI muss nicht kopiert werden, da nur an
* Entscheidungsstellen der Match/die Matches gemerkt
* werden mssen, die uns m�licherweise auf einen Holzweg
* fhren. Der Match in ERI ist eine Stufe tiefer (also
* nach Regelanwendung, denn wir löschen) nicht
* mehr verfgbar. Dadurch kann ein neues ERI erzeugt
* werden. Auf dem Stack liegen dann nur die
* Ableitungen, die uns in eine Sackgasse gefhrt haben.
*/
Pair<Graph, RuleInstances> tmpPair = new Pair<Graph, RuleInstances>(
getHostGraph(), eri);
this.stack.push(tmpPair);
eri = new RuleInstances();
/*
* Die Regel muss auf den kopierten Graphen mit
* DEMSELBEN kopierten Match angewendet werden.
*/
setHostGraph(copyMorph.getImage());
OrdinaryMorphism tmpMorph = m.compose(copyMorph);
Match n = tmpMorph.makeMatch(m.getRule());
n.setCompletionStrategy(
(MorphCompletionStrategy) this.grammar
.getMorphismCompletionStrategy()
.clone(), true);
boolean notFound = false;
while (!this.stop && !n.isValid() && !notFound) {
if (!n.nextCompletion())
notFound = true;
}
if (!this.stop && !notFound) {
if (applyRule(n)) {
ruleApplied = true;
try {
Thread.sleep(this.delay);
} catch (InterruptedException ex1) {
}
}
}
}
} else {
BaseFactory.theFactory().destroyMatch(m);
m = null;
}
}
if (!this.stop && !ruleApplied) {
try {
Pair<?,?> tmpPair = (Pair) this.stack.pop();
/* backtrack */
setHostGraph((Graph)tmpPair.first);
eri = (RuleInstances)tmpPair.second;
} catch (Exception ioe) {
/* Stack ist leer */
fireParserEvent(new ParserErrorEvent(this,
"ERROR: This graph is not part of the language"));
this.correct = false;
}
}
}
}
/* Fertig mit den Excluderegeln */
while (!this.stack.empty()) {
try {
fireParserEvent(new ParserMessageEvent(this, "Cleaning stack."));
Pair<?,?> tmpPair = (Pair) this.stack.pop();
Graph g = (Graph)tmpPair.first;
BaseFactory.theFactory().destroyGraph(g);
tmpPair.second = null;
} catch (Exception ioe) {
}
}
fireParserEvent(new ParserMessageEvent(this,
"Stopping parser. Result is " + this.correct + "."));
return this.correct;
}
}
// End of ExcludeParser.java
/*
* $Log: SimpleExcludeParser.java,v $
* Revision 1.11 2010/08/18 09:26:52 olga
* tuning
*
* Revision 1.10 2010/06/09 10:56:07 olga
* tuning
*
* Revision 1.9 2008/04/07 09:36:51 olga
* Code tuning: refactoring + profiling
* Extension: CPA - two new options added
*
* Revision 1.8 2007/11/01 09:58:18 olga
* Code refactoring: generic types- done
*
* Revision 1.7 2007/09/10 13:05:41 olga
* In this update:
* - package xerces2.5.0 is not used anymore;
* - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair;
* - bugs fixed in: usage of PACs in rules; match completion;
* usage of static method calls in attr. conditions
* - graph editing: added some new features
* Revision 1.6 2007/07/02 08:27:33 olga Help
* docu update, Source tuning
*
* Revision 1.5 2007/06/13 08:32:58 olga Update: V161
*
* Revision 1.4 2007/04/11 10:03:36 olga Undo, Redo tuning, Simple Parser- bug
* fixed
*
* Revision 1.3 2007/03/28 10:00:57 olga - extensive changes of Node/Edge Type
* Editor, - first Undo implementation for graphs and Node/edge Type editing and
* transformation, - new / reimplemented options for layered transformation, for
* graph layouter - enable / disable for NACs, attr conditions, formula - GUI
* tuning
*
* Revision 1.2 2006/11/09 10:31:05 olga Matching error fixed
*
* Revision 1.1 2005/08/25 11:56:57 enrico *** empty log message ***
*
* Revision 1.1 2005/05/30 12:58:03 olga Version with Eclipse
*
* Revision 1.3 2004/12/20 14:53:48 olga Changes because of matching
* optimisation.
*
* Revision 1.2 2003/03/05 18:24:08 komm sorted/optimized import statements
*
* Revision 1.1.1.1 2002/07/11 12:17:24 olga Imported sources
*
* Revision 1.5 2001/06/13 16:49:36 olga Parser Classen Optimierung.
*
* Revision 1.4 2001/05/31 11:57:57 olga Zusaetzliche Parser Meldungen fuer GUI
* eingefuegt.
*
* Revision 1.3 2001/05/14 12:03:02 olga Zusaetzliche Parser Events Aufrufe
* eingebaut, um bessere Kommunikation mit GUI Status Anzeige zu ermoeglichen.
*
* Revision 1.2 2001/03/08 10:44:57 olga Neue Files aus parser branch in Head
* eingefuegt.
*
* Revision 1.1.2.5 2001/01/28 13:14:58 shultzke API fertig
*
* Revision 1.1.2.4 2001/01/03 09:45:01 shultzke TODO's bis auf laden und
* speichern erledigt. Wann meldet sich endlich Michael?
*
* Revision 1.1.2.3 2001/01/02 12:29:01 shultzke Alle Optionen angebunden
*
* Revision 1.1.2.2 2000/12/26 10:00:06 shultzke Layered Parser hinzugefuegt
*
* Revision 1.1.2.1 2000/12/04 12:26:48 shultzke drei parser stehen zur
* verfuegung
*
*/