package agg.parser;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import agg.xt_basis.Arc;
import agg.xt_basis.BaseFactory;
import agg.xt_basis.ConcurrentRule;
import agg.xt_basis.GraGra;
import agg.xt_basis.Graph;
import agg.xt_basis.GraphObject;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.Rule;
import agg.xt_basis.Node;
import agg.util.XMLHelper;
import agg.util.Pair;
// ****************************************************************************+
/**
* This Container contains only conflict free and dependency relations.
*
* @author $Author: olga $
*/
public class DependencyPairContainer extends ExcludePairContainer {
protected boolean switchDependency;
protected boolean makeConcurrentRules;
protected boolean completeConcurrency = true;
protected List<ConcurrentRule> concurrentRules;
/**
* Creates a new container for critical pairs.
*
* @param gragra
* The graph grammar.
*/
public DependencyPairContainer(GraGra gragra) {
super(gragra);
this.conflictKind = CriticalPair.TRIGGER_DEPENDENCY;
this.completeConcurrency = true;
}
public Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>>
getDependencyContainer() {
return super.getExcludeContainer();
}
public Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
getCriticalPair(Rule r1, Rule r2, int kind, boolean local)
throws InvalidAlgorithmException {
if (local) {
Entry e = this.getEntry(r1, r2);
if (e.isProgressIndexSet()) {
return this.continueComputeCriticalPair(r1, r2, getContainer(kind, r1, r2));
}
return getCriticalPair(r1, r2, getContainer(kind, r1, r2));
}
return getCriticalPair(r1, r2, getContainer(kind));
}
public void enableSwitchDependency(boolean b) {
this.switchDependency = b;
if (this.conflictKind == CriticalPair.TRIGGER_DEPENDENCY && this.switchDependency)
this.conflictKind = CriticalPair.TRIGGER_SWITCH_DEPENDENCY;
else if (this.conflictKind == CriticalPair.TRIGGER_SWITCH_DEPENDENCY && !this.switchDependency)
this.conflictKind = CriticalPair.TRIGGER_DEPENDENCY;
}
public void enableProduceConcurrentRule(boolean b) {
this.makeConcurrentRules = b;
}
public void setCompleteConcurrency(boolean b) {
this.completeConcurrency = b;
}
public List<ConcurrentRule> getConcurrentRules() {
return this.concurrentRules;
}
public DependencyPair getCurrentDependencyPair() {
return (DependencyPair) this.excludePair;
}
/**
* Computes if the second rule depends of the first rule. The result is
* added to the container.
*
* @param r1
* The first rule.
* @param r2
* The second rule.
*/
protected synchronized void computeCritical(Rule r1, Rule r2) {
Report.trace("ExcludePairContainer: starte computeCritical"
+ this.getEntry(r1, r2).state + " " + r1.getName() + " "
+ r2.getName(), 2);
// System.out.println("ExcludePairContainer: starte computeCritical,
// state: "+this.getEntry(r1, r2).state+", "+r1.getName()+"
// "+r2.getName());
// mark Entry
Entry e = this.getEntry(r1, r2);
if (!r1.isEnabled() || !r2.isEnabled()) { // test disabled rule
e.state = Entry.DISABLED;
addEntry(r1, r2, false, null);
addQuadruple(this.excludeContainer, r1, r2, false, null);
addQuadruple(this.conflictFreeContainer, r1, r2, false, null);
firePairEvent(new CriticalPairEvent(this, r1, r2, "<"
+ r1.getName() + "> and <" + r2.getName()
+ "> should not be computed."));
return;
}
if ((e.state == Entry.SCHEDULED_FOR_COMPUTING)
|| (e.state == Entry.NOT_SET)) {
e.state = Entry.COMPUTING_IS_RUNNING;
firePairEvent(new CriticalPairEvent(this, r1, r2,
"Computing critical rule pair [ " + r1.getName()
+ " , " + r2.getName() + " ]"));
if (!this.complete)
this.excludePair = new SimpleDependencyPair();
else {
this.excludePair = new DependencyPair();
this.excludePair.setGraGra(this.grammar);
}
// this.excludePair.setProgressIndx(e);
setOptionsOfExcludePair();
((DependencyPair) this.excludePair).enableSwitchDependency(this.switchDependency);
((DependencyPair) this.excludePair).enableProduceConcurrentRule(this.makeConcurrentRules);
((DependencyPair) this.excludePair).setCompleteConcurrency(this.completeConcurrency);
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapping = null;
try {
overlapping = this.excludePair.isCritical(CriticalPair.EXCLUDE, r1, r2);
e = this.getEntry(r1, r2, true);
e.setProgressIndx(this.excludePair);
if (!this.excludePair.computable) {
e.setStatus(Entry.NOT_COMPUTABLE);
} else if (overlapping != null) {
this.concurrentRules = ((DependencyPair) this.excludePair).getConcurrentRules();
}
} catch (InvalidAlgorithmException iae) {
// System.out.println(iae.getLocalizedMessage());
// if (iae.getKindOfInvalidAlgorithm() == CriticalPairEvent.NOT_COMPUTABLE) {
// e(r1, r2).status = Entry.NOT_COMPUTABLE;
// }
}
boolean critic = (overlapping != null);
// add to container
addEntry(r1, r2, critic, overlapping);
if (critic) {
if (!this.excludePair.dependencyCond1 && this.excludePair.dependencyCond2)
e.setState(Entry.COMPUTED2);
else if (this.excludePair.dependencyCond1 && this.excludePair.dependencyCond2)
e.setState(Entry.COMPUTED12);
else
e.setState(Entry.COMPUTED);
}
this.usedM = this.usedM + this.excludePair.usedM;
this.excludePair.dispose();
this.excludePair = null;
/*
* Wenn overlapping Elemente enthaelt sind r1/r2 kritisch critic
* wird daher true. Alle wichtigen Informationen werden eingetragen.
* Enthaelt r1/r2 keine Elementen, so wird critic auf false gesetzt.
* Wenn excludeContainer nach r1/r2 gefragt wird, liefert die
* Antwort auch false. overlapping kann daher null sein.
*/
addQuadruple(this.excludeContainer, r1, r2, critic, overlapping);
addQuadruple(this.conflictFreeContainer, r1, r2, !critic, null);
if (overlapping != null) {
firePairEvent(new CriticalPairEvent(this, r1, r2,
CriticalPairEvent.CRITICAL, "<" + r1.getName()
+ "> and <" + r2.getName()
+ "> have critical pairs"));
//TEST CriticalPairData
// CriticalPairData cpd = this.getCriticalPairData(r1, r2);
// System.out.println("rule1 has name: " + cpd.getRule1().getName());
// System.out.println("rule2 has name: " + cpd.getRule2().getName());
// System.out.println("morph1 has name: " + cpd.getMorph1().getName());
// System.out.println("morph2 has name: " + cpd.getMorph2().getName());
}
else {
firePairEvent(new CriticalPairEvent(this, r1, r2,
CriticalPairEvent.UNCRITICAL, "<" + r1.getName()
+ "> and <" + r2.getName()
+ "> have not any critical pairs"));
}
}
}
protected synchronized Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
continueComputeCriticalPair(
Rule r1,
Rule r2,
final Hashtable<Rule, Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>>
container) {
// get Entry
Entry e = this.getEntry(r1, r2, true);
if (!e.isProgressIndexSet()) {
return null;
}
e.state = Entry.COMPUTING_IS_RUNNING;
firePairEvent(new CriticalPairEvent(this, r1, r2,
"Computing critical rule pair [ " + r1.getName()
+ " , " + r2.getName() + " ]"));
if (!this.complete)
this.excludePair = new SimpleDependencyPair();
else
this.excludePair = new DependencyPair();
this.excludePair.setProgressIndx(e);
setOptionsOfExcludePair();
((DependencyPair) this.excludePair).enableSwitchDependency(this.switchDependency);
((DependencyPair) this.excludePair).enableProduceConcurrentRule(this.makeConcurrentRules);
((DependencyPair) this.excludePair).setCompleteConcurrency(this.completeConcurrency);
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
overlapping = null;
try {
overlapping = this.excludePair.isCritical(CriticalPair.EXCLUDE, r1, r2);
e = this.getEntry(r1, r2, true);
e.setProgressIndx(this.excludePair);
if (!this.excludePair.computable) {
e.setStatus(Entry.NOT_COMPUTABLE);
} else if (overlapping != null) {
this.concurrentRules = ((DependencyPair) this.excludePair).getConcurrentRules();
}
} catch (InvalidAlgorithmException iae) {}
boolean critic = (overlapping != null);
// add to container
Entry entry = addEntry(r1, r2, critic, overlapping);
if (critic) {
if (!this.excludePair.dependencyCond1 && this.excludePair.dependencyCond2)
entry.setState(Entry.COMPUTED2);
else if (this.excludePair.dependencyCond1 && this.excludePair.dependencyCond2)
entry.setState(Entry.COMPUTED12);
else
entry.setState(Entry.COMPUTED);
}
this.excludePair.dispose();
this.excludePair = null;
addQuadruple(this.excludeContainer, r1, r2, critic, overlapping);
addQuadruple(this.conflictFreeContainer, r1, r2, !critic, null);
if (overlapping != null) {
firePairEvent(new CriticalPairEvent(this, r1, r2,
CriticalPairEvent.CRITICAL, "<" + r1.getName()
+ "> and <" + r2.getName()
+ "> have critical pairs"));
}
else {
firePairEvent(new CriticalPairEvent(this, r1, r2,
CriticalPairEvent.UNCRITICAL, "<" + r1.getName()
+ "> and <" + r2.getName()
+ "> have not any critical pairs"));
}
firePairEvent(new CriticalPairEvent(this, r1, r2, "rule pair [ "
+ r1.getName() + " , " + r2.getName() + " ] done"));
return getCriticalPair(r1, r2, container);
}
protected Pair<OrdinaryMorphism, OrdinaryMorphism>
readOldOverlappingMorphisms(
XMLHelper h,
Rule r1,
Rule r2,
String firstName,
Graph overlapGraph) {
OrdinaryMorphism first = BaseFactory.theFactory().createMorphism(
r1.getRight(), overlapGraph);
OrdinaryMorphism second = BaseFactory.theFactory().createMorphism(
r2.getLeft(), overlapGraph);
first.setName(firstName.replaceAll(" ", ""));
while (h.readSubTag("Mapping")) {
GraphObject o = (GraphObject) h.getObject("orig", null, false);
GraphObject i = (GraphObject) h.getObject("image", null, false);
if (o != null && i != null) {
first.addMapping(o, i);
}
h.close();
}
h.close();
if (h.readSubTag("Morphism")) {
String name = h.readAttr("name");
second.setName(name.replaceAll(" ", ""));
while (h.readSubTag("Mapping")) {
GraphObject o = (GraphObject) h.getObject("orig", null, false);
GraphObject i = (GraphObject) h.getObject("image", null, false);
if (o != null && i != null) {
second.addMapping(o, i);
}
h.close();
}
h.close();
}
return new Pair<OrdinaryMorphism, OrdinaryMorphism>(first, second);
}
/**
* Writes the contents of this object to a file in a xml format.
*
* @param h
* A helper object for storing.
*/
public void XwriteObject(XMLHelper h) {
h.openNewElem("CriticalPairs", this);
h.addObject("GraGra", getGrammar(), true);
h.openSubTag("dependenciesContainer");
String kind = "trigger_dependency";
if (this.switchDependency)
kind = "trigger_switch_dependency";
h.addAttr("kind", kind);
// Inhalt von excludeContainer schreiben (save)
for (Enumeration<Rule> keys = this.excludeContainer.keys(); keys.hasMoreElements();) {
Rule r1 = keys.nextElement();
h.openSubTag("Rule");
h.addObject("R1", r1, false);
Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>
secondPart = this.excludeContainer.get(r1);
for (Enumeration<Rule> k2 = secondPart.keys(); k2.hasMoreElements();) {
Rule r2 = k2.nextElement();
h.openSubTag("Rule");
h.addObject("R2", r2, false);
Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>
p = secondPart.get(r2);
Boolean b = p.first;
h.addAttr("bool", b.toString());
if (b.booleanValue()) {
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>
v = p.second;
for (int i = 0; i < v.size(); i++) {
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
p2i = v.elementAt(i);
Pair<OrdinaryMorphism, OrdinaryMorphism> p2 = p2i.first;
h.openSubTag("Overlapping_Pair");
OrdinaryMorphism first = p2.first;
Graph overlapping = first.getImage();
/*
* durch das true macht der String am Anfang keinen Sinn
*/
h.addObject("", overlapping, true);
for (Iterator<Node> e = overlapping.getNodesSet().iterator();
e.hasNext();) {
GraphObject o = e.next();
if (o.isCritical()) {
h.openSubTag("Critical");
h.addObject("object", o, false);
h.close();
}
}
for (Iterator<Arc> e = overlapping.getArcsSet().iterator();
e.hasNext();) {
GraphObject o = e.next();
if (o.isCritical()) {
h.openSubTag("Critical");
h.addObject("object", o, false);
h.close();
}
}
/*
* first.writeMorphism(h); ((OrdinaryMorphism)
* p2.second).writeMorphism(h);
*/
writeOverlapMorphisms(h, r1, r2, p2i);
h.close();
}
}
h.close();
}
h.close();
}
h.close();
if (this.conflictFreeContainer != null) {
h.openSubTag("conflictFreeContainer");
for (Enumeration<Rule> keys = this.excludeContainer.keys(); keys.hasMoreElements();) {
Rule r1 = keys.nextElement();
h.openSubTag("Rule");
h.addObject("R1", r1, false);
Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>
secondPart = this.conflictFreeContainer.get(r1);
for (Enumeration<Rule> k2 = secondPart.keys(); k2.hasMoreElements();) {
Rule r2 = k2.nextElement();
h.openSubTag("Rule");
h.addObject("R2", r2, false);
Boolean b = secondPart.get(r2).first;
h.addAttr("bool", b.toString());
h.close();
}
h.close();
}
h.close();
}
h.close();
}
/**
* Reads the contents of a xml file to restore this object.
*
* @param h
* A helper object for loading.
*/
public void XreadObject(XMLHelper h) {
if (h.isTag("CriticalPairs", this)) {
Rule r1 = null;
Rule r2 = null;
boolean b = false;
Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> allOverlappings = null;
Vector<String> tagnames = new Vector<String>(1);
Vector<String> tagnames2 = new Vector<String>(1);
this.grammar = BaseFactory.theFactory().createGraGra();
// loads the data in the predefined object
h.getObject("", this.grammar, true);
tagnames.add("conflictContainer");
tagnames.add("conflictsContainer");
tagnames.add("excludeContainer");
tagnames2.add("dependencyContainer");
tagnames2.add("dependenciesContainer");
this.switchDependency = false;
if (h.readSubTag(tagnames2)) {
this.conflictKind = CriticalPair.TRIGGER_DEPENDENCY;
if (h.readAttr("kind").equals("trigger_switch_dependency")) {
this.switchDependency = true;
this.conflictKind = CriticalPair.TRIGGER_SWITCH_DEPENDENCY;
}
}
else if (h.readSubTag(tagnames)) {
this.conflictKind = CriticalPair.CONFLICT;
}
if (this.conflictKind == CriticalPair.TRIGGER_DEPENDENCY
|| this.conflictKind == CriticalPair.TRIGGER_SWITCH_DEPENDENCY
|| this.conflictKind == CriticalPair.CONFLICT) {
// System.out.println("conflictKind : "+conflictKind);
Enumeration<?> r1s = h.getEnumeration("", null, true, "Rule");
if (!r1s.hasMoreElements())
r1s = h.getEnumeration("", null, true, "Regel");
while (r1s.hasMoreElements()) {
h.peekElement(r1s.nextElement());
/*
* da ein referenziertes object geholt werden soll. muss nur
* angegeben werden wie der Membername heisst.
*/
r1 = (Rule) h.getObject("R1", null, false);
Enumeration<?> r2s = h.getEnumeration("", null, true, "Rule");
if (!r2s.hasMoreElements())
r2s = h.getEnumeration("", null, true, "Regel");
while (r2s.hasMoreElements()) {
h.peekElement(r2s.nextElement());
r2 = (Rule) h.getObject("R2", null, false);
String bool = h.readAttr("bool");
b = false;
allOverlappings = null;
if (bool.equals("true")) {
b = true;
allOverlappings = new Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>();
Enumeration<?> overlappings = h.getEnumeration("",
null, true, "Overlapping_Pair");
while (overlappings.hasMoreElements()) {
h.peekElement(overlappings.nextElement());
Graph g = (Graph) h.getObject("", BaseFactory.theFactory().createGraph(
this.grammar.getTypeSet()), true);
while (h.readSubTag("Critical")) {
GraphObject o = (GraphObject) h.getObject(
"object", null, false);
if (o != null)
o.setCritical(true);
h.close();
}
/*
* OrdinaryMorphism first =
* BaseFactory.theFactory().createMorphism(r1.getRight(),
* g); first.readMorphism(h);
* //System.out.println("DependPairCont.Xread::
* "+first.getSize()); OrdinaryMorphism second =
* BaseFactory.theFactory().createMorphism(r2.getLeft(),
* g); second.readMorphism(h);
* allOverlappings.addElement(new Pair(first,
* second));
*/
Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>
p = readOverlappingMorphisms(h, r1, r2, g);
allOverlappings.addElement(p);
h.close();
}
}
addQuadruple(this.excludeContainer, r1, r2, b,
allOverlappings);
h.close();
}
h.close();
}
h.close();
}
if (h.readSubTag("conflictFreeContainer")) {
Enumeration<?> r1s = h.getEnumeration("", null, true, "Rule");
if (!r1s.hasMoreElements())
r1s = h.getEnumeration("", null, true, "Regel");
while (r1s.hasMoreElements()) {
h.peekElement(r1s.nextElement());
/*
* da ein referenziertes object geholt werden soll. muss nur
* angegeben werden wie der Membername heisst.
*/
r1 = (Rule) h.getObject("R1", null, false);
Enumeration<?> r2s = h.getEnumeration("", null, true, "Rule");
if (!r2s.hasMoreElements())
r2s = h.getEnumeration("", null, true, "Regel");
while (r2s.hasMoreElements()) {
h.peekElement(r2s.nextElement());
r2 = (Rule) h.getObject("R2", null, false);
String bool = h.readAttr("bool");
b = false;
if (bool.equals("true"))
b = true;
addQuadruple(this.conflictFreeContainer, r1, r2, b, null);
if (!r1.isEnabled()) // test disabled rule
this.getEntry(r1, r2).state = Entry.DISABLED;
h.close();
}
h.close();
}
h.close();
// System.out.println("conflictFreeContainer
// "+conflictFreeContainer+"\n");
}
}
// //isComputed = true;
h.close();
}
/**
* Provides a human readable text of the critical pairs.
*
* @return The text.
*/
public String toString() {
String result = super.toString() + "\n" + getGrammar().toString()
+ "\n";
result += "dependenciesContainer " + this.excludeContainer + "\n\n";
result += "conflictFreeContainer " + this.conflictFreeContainer + "\n";
return result;
}
}