package agg.termination;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import agg.xt_basis.csp.Completion_InheritCSP;
import agg.xt_basis.Completion_InjCSP;
import agg.xt_basis.GraGra;
import agg.xt_basis.Graph;
import agg.xt_basis.GraphObject;
import agg.xt_basis.Node;
import agg.xt_basis.Rule;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.BaseFactory;
import agg.xt_basis.RulePriority;
import agg.xt_basis.Type;
import agg.xt_basis.RuleLayer;
import agg.xt_basis.Arc;
import agg.xt_basis.TypeGraph;
import agg.util.IntComparator;
import agg.util.OrderedSet;
import agg.util.Pair;
/**
* This class implements termination conditions of Layered Graph Grammar
* which is typed by a type graph.
*
* @author $Author: olga $
* @version $Id: TerminationLGTSTypedByTypeGraph.java,v 1.13 2010/09/23 08:26:15 olga Exp $
*/
public class TerminationLGTSTypedByTypeGraph implements TerminationLGTSInterface {
/** The graph grammar */
private GraGra grammar;
private TypeGraph typeGraph;
private List<Rule> listOfRules;
private boolean layered, priority;
private Vector<Rule> deletionRule;
private Vector<Rule> nondeletionRule;
private Vector<Rule> creationRule;
private Hashtable<Rule, Integer> ruleLayer;
private Hashtable<GraphObject, Integer> creationLayer;
private Hashtable<GraphObject, Integer> deletionLayer;
private boolean generateRuleLayer;
private Hashtable<Rule, Integer> oldRuleLayer;
private int maxl;
private Hashtable<Integer, HashSet<Rule>> invertedRuleLayer;
private OrderedSet<Integer> orderedRuleLayerSet;
private Hashtable<Integer, HashSet<Object>> invertedTypeDeletionLayer;
private OrderedSet<Integer> orderedTypeDeletionLayerSet;
private Hashtable<Integer, HashSet<Object>> invertedTypeCreationLayer;
private OrderedSet<Integer> orderedTypeCreationLayerSet;
private Integer startLayer, startRuleLayer;
private Vector<Integer> orderedRuleLayer;
// private Vector<Integer> orderedTypeDeletionLayer;
// private Vector<Integer> orderedTypeCreationLayer;
private Hashtable<Integer, Pair<Boolean, Vector<Rule>>> resultTypeDeletion;
private Hashtable<Integer, Pair<Boolean, Vector<Rule>>> resultDeletion;
private Hashtable<Integer, Pair<Boolean, Vector<Rule>>> resultNonDeletion;
private Hashtable<Integer, List<String>> errorMsg;
private Hashtable<Integer, List<String>> errorMsgDeletion1;
private Hashtable<Integer, List<String>> errorMsgDeletion2;
private Hashtable<Integer, List<String>> errorMsgNonDeletion;
private Hashtable<Integer, Vector<GraphObject>> deletionType;
private boolean needCorrection = false;
/** The error message if termination conditions are not valid */
private String errMsg;
/** true if termination conditions are valid */
private boolean valid;
public TerminationLGTSTypedByTypeGraph() {}
public void dispose() {
if (this.grammar != null)
unsetLayer();
this.grammar = null;
}
private void setKind() {
this.priority = this.grammar.trafoByPriority();
this.layered = this.grammar.isLayered() || !this.priority;
this.oldRuleLayer.clear();
this.saveRuleLayerInto(this.oldRuleLayer);
}
/**
* Initialize a termination layers of the grammar. Initially the termination
* conditions are invalid.
*
* @param gra
* The graph grammar.
*/
public void setGrammar(GraGra gra) {
if (gra == null) {
unsetLayer();
this.grammar = null;
} else {
this.grammar = gra;
this.typeGraph = (TypeGraph) gra.getTypeGraph();
this.listOfRules = this.getListOfEnabledRules();
this.errMsg = "";
this.valid = false;
this.oldRuleLayer = new Hashtable<Rule, Integer>();
setKind();
initRuleLayer(this.grammar);
initCreationLayer(this.grammar);
initDeletionLayer(this.grammar);
initOrderedRuleLayer(this.grammar);
this.deletionType = new Hashtable<Integer, Vector<GraphObject>>();
initResults();
}
}
public void resetGrammar() {
if (this.grammar != null) {
this.typeGraph = (TypeGraph) this.grammar.getTypeGraph();
this.listOfRules = this.getListOfEnabledRules();
this.errMsg = "";
this.valid = false;
setKind();
reinitRuleLayer();
reinitCreationLayer();
reinitDeletionLayer();
reinitOrderedRuleLayer();
this.deletionType.clear();
reinitResults();
}
}
public GraGra getGrammar() {
return this.grammar;
}
public List<Rule> getListOfEnabledRules() {
List<Rule> list = new Vector<Rule>();
for (int i=0; i<this.grammar.getListOfRules().size(); i++) {
Rule r = this.grammar.getListOfRules().get(i);
if (r.isEnabled()) {
list.add(r);
}
}
return list;
}
public boolean hasGrammarChanged() {
if (this.grammar != null) {
boolean changed = false;
if (this.grammar.hasRuleChangedEvailability()
|| (this.layered && this.grammar.trafoByPriority())
|| (this.priority && this.grammar.isLayered())
|| (this.layered && this.grammar.hasRuleChangedLayer())
|| (this.priority && this.grammar.hasRuleChangedPriority())
|| (this.layered && !this.grammar.isLayered()) ) {
changed = true;
this.setGrammar(this.grammar);
}
return changed;
}
return false;
}
public List<Rule> getListOfRules() {
return this.listOfRules;
}
public Hashtable<Integer, HashSet<Rule>> getInvertedRuleLayer() {
return this.invertedRuleLayer;
}
public Vector<Integer> getOrderedRuleLayer() {
return this.orderedRuleLayer;
}
public Hashtable<Integer, HashSet<Object>> getInvertedTypeDeletionLayer() {
return this.invertedTypeDeletionLayer;
}
// public Vector getOrderedTypeDeletionLayer()
// { return orderedTypeDeletionLayer; }
public Hashtable<Integer, HashSet<Object>> getInvertedTypeCreationLayer() {
return this.invertedTypeCreationLayer;
}
// public Vector getOrderedTypeCreationLayer()
// { return orderedTypeCreationLayer; }
public Hashtable<Integer, Vector<Type>> getDeletionType() {
final Hashtable<Integer, Vector<Type>> delLayerType = new Hashtable<Integer, Vector<Type>>();
Enumeration<Integer> keys = this.deletionType.keys();
while (keys.hasMoreElements()) {
Integer key = keys.nextElement();
final Vector<GraphObject> typeGOs = this.deletionType.get(key);
final Vector<Type> typeObjs = new Vector<Type>();
for (int i=0; i<typeGOs.size(); i++) {
typeObjs.add(typeGOs.get(i).getType());
}
delLayerType.put(key, typeObjs);
}
return delLayerType;
}
public Hashtable<Integer, Vector<GraphObject>> getDeletionTypeObject() {
return this.deletionType;
}
public Hashtable<Integer, Pair<Boolean, Vector<Rule>>> getResultTypeDeletion() {
return this.resultTypeDeletion;
}
public Hashtable<Integer, Pair<Boolean, Vector<Rule>>> getResultDeletion() {
return this.resultDeletion;
}
public Hashtable<Integer, Pair<Boolean, Vector<Rule>>> getResultNondeletion() {
return this.resultNonDeletion;
}
public void resetLayer() {
this.maxl = 0;
setKind();
initRuleLayer(this.oldRuleLayer);
initCreationLayer(this.grammar);
initDeletionLayer(this.grammar);
initOrderedRuleLayer(this.grammar);
this.deletionType = new Hashtable<Integer, Vector<GraphObject>>();
initResults();
}
private void unsetLayer() {
this.creationLayer.clear();
this.deletionLayer.clear();
this.deletionType.clear();
this.deletionRule.clear();
this.creationRule.clear();
this.nondeletionRule.clear();
this.invertedRuleLayer.clear();
// this.invertedTypeDeletionLayer.clear();
this.ruleLayer.clear();
this.oldRuleLayer.clear();
this.orderedRuleLayerSet.clear();
// this.orderedTypeDeletionLayerSet.clear();
// this.invertedTypeCreationLayer.clear();
// this.orderedTypeCreationLayerSet.clear();
this.resultDeletion.clear();
this.resultDeletion.clear();
this.resultNonDeletion.clear();
clearErrors();
}
private void initRuleLayer(GraGra gragra) {
this.ruleLayer = new Hashtable<Rule, Integer>();
this.deletionRule = new Vector<Rule>();
this.nondeletionRule = new Vector<Rule>();
this.creationRule = new Vector<Rule>();
Iterator<Rule> rules = this.listOfRules.iterator();
while (rules.hasNext()) {
Rule rule = rules.next();
if (this.priority)
this.ruleLayer.put(rule, Integer.valueOf(rule.getPriority()));
else
this.ruleLayer.put(rule, Integer.valueOf(rule.getLayer()));
if (isDeleting(rule)) {
this.deletionRule.add(rule);
// System.out.println("Deleting rule: "+rule.getName());
// if (isCreating(rule)) {
// creationRule.add(rule);
// System.out.println("Deleting and Creating rule: "+rule.getName());
// }
} else {
if (isCreating(rule)) {
this.creationRule.add(rule);
// System.out.println("Creating rule: "+rule.getName());
}
this.nondeletionRule.add(rule);
}
}
}
private void reinitRuleLayer() {
this.ruleLayer.clear();
this.deletionRule.clear();
this.nondeletionRule.clear();
this.creationRule.clear();
Iterator<Rule> rules = this.listOfRules.iterator();
while (rules.hasNext()) {
Rule rule = rules.next();
if (this.priority)
this.ruleLayer.put(rule, Integer.valueOf(rule.getPriority()));
else if (this.layered)
this.ruleLayer.put(rule, Integer.valueOf(rule.getLayer()));
if (isDeleting(rule)) {
this.deletionRule.add(rule);
// System.out.println("Deleting rule: "+rule.getName());
} else {
if (isCreating(rule)) {
this.creationRule.add(rule);
// System.out.println("Creating rule: "+rule.getName());
}
this.nondeletionRule.add(rule);
}
}
}
/*
private void initRuleLayer(int init) {
for (Enumeration<Rule> keys = ruleLayer.keys(); keys.hasMoreElements();) {
Rule rule = keys.nextElement();
if (rule.isEnabled()) {
ruleLayer.put(rule, Integer.valueOf(init));
}
}
}
*/
public void initRuleLayer(Hashtable<?, Integer> init) {
for (Enumeration<?> keys = init.keys(); keys.hasMoreElements();) {
Rule rule = (Rule) keys.nextElement();
if (rule.isEnabled()) {
Integer rl = init.get(rule);
this.ruleLayer.put(rule, Integer.valueOf(rl.intValue()));
}
}
}
private void initCreationLayer(GraGra gragra) {
this.creationLayer = new Hashtable<GraphObject, Integer>();
Iterator<Node> typeNodes = this.typeGraph.getNodesSet().iterator();
while (typeNodes.hasNext()) {
Node t = typeNodes.next();
if (this.startLayer != null)
this.creationLayer.put(t, Integer.valueOf(this.startLayer.intValue())); //+1));
else
this.creationLayer.put(t, Integer.valueOf(0));
}
Iterator<Arc> typeArcs = this.typeGraph.getArcsSet().iterator();
while (typeArcs.hasNext()) {
Arc t = typeArcs.next();
if (this.startLayer != null)
this.creationLayer.put(t, Integer.valueOf(this.startLayer.intValue())); //+1));
else
this.creationLayer.put(t, Integer.valueOf(0));
}
}
private void reinitCreationLayer() {
this.creationLayer.clear();
Iterator<Node> typeNodes = this.typeGraph.getNodesSet().iterator();
while (typeNodes.hasNext()) {
Node t = typeNodes.next();
this.creationLayer.put(t, Integer.valueOf(0));
}
Iterator<Arc> typeArcs = this.typeGraph.getArcsSet().iterator();
while (typeArcs.hasNext()) {
Arc t = typeArcs.next();
this.creationLayer.put(t, Integer.valueOf(0));
}
}
private void initCreationLayer(int init) {
for (Enumeration<GraphObject> keys = this.creationLayer.keys(); keys.hasMoreElements();) {
GraphObject t = keys.nextElement();
this.creationLayer.put(t, Integer.valueOf(init));
}
}
private void initDeletionLayer(GraGra gragra) {
this.deletionLayer = new Hashtable<GraphObject, Integer>();
Iterator<Node> typeNodes = this.typeGraph.getNodesSet().iterator();
while (typeNodes.hasNext()) {
Node t = typeNodes.next();
this.deletionLayer.put(t, Integer.valueOf(0));
}
Iterator<Arc> typeArcs = this.typeGraph.getArcsSet().iterator();
while (typeArcs.hasNext()) {
Arc t = typeArcs.next();
this.deletionLayer.put(t, Integer.valueOf(0));
}
}
private void reinitDeletionLayer() {
this.deletionLayer.clear();
Iterator<Node> typeNodes = this.typeGraph.getNodesSet().iterator();
while (typeNodes.hasNext()) {
Node t = typeNodes.next();
this.deletionLayer.put(t, Integer.valueOf(0));
}
Iterator<Arc> typeArcs = this.typeGraph.getArcsSet().iterator();
while (typeArcs.hasNext()) {
Arc t = typeArcs.next();
this.deletionLayer.put(t, Integer.valueOf(0));
}
}
private void initDeletionLayer(int init) {
for (Enumeration<GraphObject> keys = this.deletionLayer.keys(); keys.hasMoreElements();) {
GraphObject t = keys.nextElement();
this.deletionLayer.put(t, Integer.valueOf(init));
}
}
private void initOrderedRuleLayer(GraGra gragra) {
if (this.priority) {
RulePriority layer = new RulePriority(this.listOfRules);
this.invertedRuleLayer = layer.invertPriority();
this.startRuleLayer = layer.getStartPriority();
this.orderedRuleLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>());
for (Enumeration<Integer> en = this.invertedRuleLayer.keys(); en.hasMoreElements();)
this.orderedRuleLayerSet.add(en.nextElement());
}
else {
RuleLayer layer = new RuleLayer(this.listOfRules);
this.invertedRuleLayer = layer.invertLayer();
this.startRuleLayer = layer.getStartLayer();
this.orderedRuleLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>());
for (Enumeration<Integer> en = this.invertedRuleLayer.keys(); en.hasMoreElements();)
this.orderedRuleLayerSet.add(en.nextElement());
}
}
private void reinitOrderedRuleLayer() {
if (this.priority) {
RulePriority layer = new RulePriority(this.listOfRules);
this.invertedRuleLayer = layer.invertPriority();
this.startRuleLayer = layer.getStartPriority();
this.orderedRuleLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>());
for (Enumeration<Integer> en = this.invertedRuleLayer.keys(); en.hasMoreElements();)
this.orderedRuleLayerSet.add(en.nextElement());
}
else {
RuleLayer layer = new RuleLayer(this.listOfRules);
this.invertedRuleLayer = layer.invertLayer();
this.startRuleLayer = layer.getStartLayer();
this.orderedRuleLayerSet.clear();
for (Enumeration<Integer> en = this.invertedRuleLayer.keys(); en.hasMoreElements();)
this.orderedRuleLayerSet.add(en.nextElement());
}
}
private void initOrderedTypeDeletionLayer() {
TypeLayerOfTypeGraph layer = new TypeLayerOfTypeGraph(this.deletionLayer);
this.invertedTypeDeletionLayer = layer.invertLayer();
this.startLayer = layer.getStartLayer();
this.invertedTypeDeletionLayer = layer.invertLayer();
this.orderedTypeDeletionLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>());
for (Enumeration<Integer> en = this.invertedTypeDeletionLayer.keys(); en
.hasMoreElements();)
this.orderedTypeDeletionLayerSet.add(en.nextElement());
}
private void initOrderedTypeCreationLayer() {
TypeLayerOfTypeGraph layer = new TypeLayerOfTypeGraph(this.creationLayer);
this.invertedTypeCreationLayer = layer.invertLayer();
this.startLayer = layer.getStartLayer();
this.invertedTypeCreationLayer = layer.invertLayer();
this.orderedTypeCreationLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>());
for (Enumeration<Integer> en = this.invertedTypeCreationLayer.keys();
en.hasMoreElements();) {
this.orderedTypeCreationLayerSet.add(en.nextElement());
}
}
private void initResults() {
this.orderedRuleLayer = new Vector<Integer>();
this.resultTypeDeletion = new Hashtable<Integer, Pair<Boolean, Vector<Rule>>>();
this.resultDeletion = new Hashtable<Integer, Pair<Boolean, Vector<Rule>>>();
this.resultNonDeletion = new Hashtable<Integer, Pair<Boolean, Vector<Rule>>>();
this.errorMsg = new Hashtable<Integer, List<String>>();
this.errorMsgDeletion1 = new Hashtable<Integer, List<String>>();
this.errorMsgDeletion2 = new Hashtable<Integer, List<String>>();
this.errorMsgNonDeletion = new Hashtable<Integer, List<String>>();
}
private void reinitResults() {
this.orderedRuleLayer.clear();
this.resultTypeDeletion.clear();
this.resultDeletion.clear();
this.resultNonDeletion.clear();
clearErrors();
}
public void initAll(boolean generate) {
if (generate) {
// initRuleLayer(0);
initRuleLayer(this.oldRuleLayer);
if (this.startLayer != null)
initCreationLayer(this.startLayer.intValue()); //+1);
else
initCreationLayer(0);
initDeletionLayer(0);
initResults();
this.maxl = 0;
} else
resetLayer();
}
private boolean isDeleting(Rule r) {
return r.isDeleting();
}
private boolean isCreating(Rule r) {
return r.isCreating();
}
private GraphObject getTypeGraphObject(GraphObject go) {
GraphObject t = null;
if (go.isNode())
t = this.typeGraph.getTypeSet().getTypeGraphNode(go.getType());
else
t = this.typeGraph.getTypeSet().getTypeGraphArc(
go.getType(), ((Arc) go).getSourceType(), ((Arc) go).getTargetType());
return t;
}
public Vector<Object> getCreatedTypesOnDeletionLayer(Integer layer) {
Vector<Object> types = new Vector<Object>();
for (Enumeration<Rule> en = this.deletionRule.elements(); en.hasMoreElements();) {
Rule r = en.nextElement();
for (Enumeration<GraphObject> elems = r.getRight().getElements(); elems
.hasMoreElements();) {
GraphObject go = elems.nextElement();
if (!r.getInverseImage(go).hasMoreElements()) {
GraphObject t = getTypeGraphObject(go);
Integer tLayer = this.creationLayer.get(t);
if ((tLayer.intValue() == layer.intValue())
&& !types.contains(t))
types.add(t);
}
}
}
return types;
}
private void generateCreationLayer() {
for (Enumeration<Rule> en = this.nondeletionRule.elements(); en.hasMoreElements();) {
Rule r = en.nextElement();
for (Enumeration<GraphObject> types = this.creationLayer.keys(); types
.hasMoreElements();) {
GraphObject t = types.nextElement();
setCreationLayer(r, t);
}
}
}
private boolean ofSameNodeType(GraphObject t, GraphObject go) {
if (go.isNode() && t.isNode()) {
// return t.getType().isRelatedTo(go.getType());
return t.getType().isParentOf(go.getType());
}
return false;
}
private boolean ofSameArcType(GraphObject t, GraphObject go) {
if (go.isArc() && t.isArc()) {
return t.getType().compareTo(go.getType())
&& ((Arc)t).getSourceType().isRelatedTo(((Arc)go).getSourceType())
&& ((Arc)t).getTargetType().isRelatedTo(((Arc)go).getTargetType());
}
return false;
}
private void setCreationLayer(Rule r, GraphObject t) {
for (Enumeration<GraphObject> en = r.getRight().getElements(); en.hasMoreElements();) {
GraphObject go = en.nextElement();
if (!r.getInverseImage(go).hasMoreElements()) {
if (ofSameNodeType(t, go) || ofSameArcType(t, go)) {
Integer rl = this.ruleLayer.get(r);
Integer cl = this.creationLayer.get(t);
if (cl.intValue() <= rl.intValue()) {
int l = rl.intValue() + 1;
this.creationLayer.put(t, Integer.valueOf(l));
if (l > this.maxl)
this.maxl = l;
}
}
}
}
// now for preserved graph objects
for (Enumeration<GraphObject> en = r.getLeft().getElements(); en.hasMoreElements();) {
GraphObject go = en.nextElement();
if (r.getImage(go) != null) {
if (ofSameNodeType(t, go) || ofSameArcType(t, go)) {
Integer rl = this.ruleLayer.get(r);
Integer cl = this.creationLayer.get(t);
if (cl.intValue() > rl.intValue()) {
if (this.generateRuleLayer) {
this.ruleLayer.put(r, Integer.valueOf(cl.intValue()));
rl = this.ruleLayer.get(r);
this.needCorrection = true;
}
else {
this.creationLayer.put(t, Integer.valueOf(rl.intValue()));
}
}
}
}
}
}
/*
private boolean increaseRuleLayer(Enumeration<Rule> rules, GraphObject t,
Rule excludedRule) {
boolean increased = false;
while (rules.hasMoreElements()) {
Rule r = rules.nextElement();
if (!r.equals(excludedRule)) {
if (usedType(t, r)) {
if (layered)
r.setLayer(r.getLayer() + 1);
else if (priority)
r.setPriority(r.getPriority() + 1);
else
r.setLayer(r.getLayer() + 1);
increased = true;
}
}
}
return increased;
}
*/
/*
private boolean usedType(GraphObject t, Rule r) {
for (Enumeration<GraphObject> elems = r.getLeft().getElements(); elems
.hasMoreElements();) {
GraphObject go = elems.nextElement();
if (r.getImage(go) != null) {
if (ofSameType(t, go))
return true;
}
}
return false;
}
private void passCreationLayer() {
for (Enumeration<Rule> en = creationRule.elements(); en.hasMoreElements();) {
Rule r = en.nextElement();
for (Enumeration<GraphObject> types = this.creationLayer.keys(); types
.hasMoreElements();) {
GraphObject t = types.nextElement();
// System.out.print("creation type: <"+t+">");
Integer rl = ruleLayer.get(r);
Integer cl = this.creationLayer.get(t);
if (cl.intValue() <= rl.intValue()) {
int l = rl.intValue() + 1;
this.creationLayer.put(t, Integer.valueOf(l));
cl = this.creationLayer.get(t);
if (l > maxl)
maxl = l;
}
}
}
}
*/
private void generateDeletionLayer() {
if (this.generateRuleLayer) {
// set rule layer of deletion rules to maxl first
for (Enumeration<Rule> en = this.deletionRule.elements(); en.hasMoreElements();) {
Rule r = en.nextElement();
Integer rl = getRuleLayer().get(r);
if (rl.intValue() < this.maxl)
this.ruleLayer.put(r, Integer.valueOf(this.maxl));
}
}
for (Enumeration<Rule> en = this.deletionRule.elements(); en.hasMoreElements();) {
Rule r = en.nextElement();
for (Enumeration<GraphObject> types = this.deletionLayer.keys(); types
.hasMoreElements();) {
GraphObject t = types.nextElement();
setDeletionLayer(r, t);
}
}
// set deletion layer of unused types to maxl
for (Enumeration<Object> en = getDeletionLayer().keys(); en.hasMoreElements();) {
GraphObject key = (GraphObject) en.nextElement();
Integer dl = getDeletionLayer().get(key);
Integer cl = this.creationLayer.get(key);
if (dl.intValue() < cl.intValue())
this.deletionLayer.put(key, Integer.valueOf(cl.intValue()));
}
}
private void setDeletionLayer(Rule r, GraphObject t) {
for (Enumeration<GraphObject> en = r.getLeft().getElements(); en.hasMoreElements();) {
// first graph objects to delete
GraphObject go = en.nextElement();
if (r.getImage(go) == null) {
if (ofSameNodeType(t, go) || ofSameArcType(t, go)) {
Integer rl = this.ruleLayer.get(r);
Integer cl = this.creationLayer.get(t);
Integer dl = this.deletionLayer.get(t);
int l = cl.intValue(); // + 1;
if (l > this.maxl)
this.maxl = l;
if (this.generateRuleLayer && (rl.intValue() < this.maxl)) {
this.ruleLayer.put(r, Integer.valueOf(this.maxl));
rl = this.ruleLayer.get(r);
}
if (dl.intValue() < cl.intValue()) {
this.deletionLayer.put(t, Integer.valueOf(this.maxl));
dl = this.deletionLayer.get(t);
}
if ((dl.intValue() > rl.intValue()) && this.generateRuleLayer) {
this.ruleLayer.put(r, Integer.valueOf(dl.intValue()));
rl = this.ruleLayer.get(r);
}
if (dl.intValue() == 0) {
this.deletionLayer.put(t, Integer.valueOf(rl.intValue()));
dl = this.deletionLayer.get(t);
// System.out.println("setDeletionLayer:: "+r.getName()+" <"+t.getType().getName()+"> cl: "+cl+" dl: "+dl);
}
}
}
}
// now for new graph objects: update type creation layer
for (Enumeration<GraphObject> en = r.getRight().getElements(); en.hasMoreElements();) {
GraphObject go = en.nextElement();
if (!r.getInverseImage(go).hasMoreElements()) {
if (ofSameNodeType(t, go) || ofSameArcType(t, go)) {
Integer rl = this.ruleLayer.get(r);
Integer cl = this.creationLayer.get(t);
if (cl.intValue() <= rl.intValue()) {
this.creationLayer.put(t, Integer.valueOf(rl.intValue() + 1));
cl = this.creationLayer.get(t);
}
}
}
}
}
private void clearErrors() {
this.errorMsg.clear();
this.errorMsgDeletion1.clear();
this.errorMsgDeletion2.clear();
this.errorMsgNonDeletion.clear();
}
/**
* Checks layer conditions .
*
* @return true if conditions are valid.
*/
public boolean checkTermination() {
clearErrors();
if (this.generateRuleLayer) {
initAll(this.generateRuleLayer);
}
generateCreationLayer();
generateDeletionLayer();
int n = this.listOfRules.size();
while (this.needCorrection && n >= 0) {
this.needCorrection = false;
generateCreationLayer();
generateDeletionLayer();
n--;
}
this.valid = false;
// check totality of rule layer function
for (Iterator<Rule> en = this.listOfRules.iterator(); en.hasNext();) {
Rule r = en.next();
Integer rl = this.ruleLayer.get(r);
/* layer function must be total*/
if (rl == null) {
this.errMsg = "Rule <"+ r.getName() + "> "
+ "does not satisfy totality of rule layer function.";
addErrorMessage(this.errorMsg, rl, this.errMsg);
return false;
}
}
// check totality of deletion/creation layer functions
for (Enumeration<GraphObject> en = this.grammar.getTypeGraph().getElements(); en.hasMoreElements();) {
GraphObject t = en.nextElement();
Integer dl = this.deletionLayer.get(t);
Integer cl = this.creationLayer.get(t);
/* layer function must be total */
if (cl == null) {
this.errMsg = "Type <"+ t.getType().getStringRepr() + "> "
+ "does not satisfy totality of creation layer function.";
addErrorMessage(this.errorMsg, dl, this.errMsg);
return false;
} else if (dl == null) {
this.errMsg = "Type <"+ t.getType().getStringRepr() + "> "
+ "does not satisfy totality of deletion layer function.";
addErrorMessage(this.errorMsg, cl, this.errMsg);
return false;
}
}
boolean result = checkTerminationConditions();
initOrderedTypeDeletionLayer();
initOrderedTypeCreationLayer();
this.valid = this.setValidResult();
return result;
}
private void addErrorMessage(
final Hashtable<Integer, List<String>> msgContainer,
final Integer key,
final String msg) {
List<String> errList = msgContainer.get(key);
if (errList == null) {
errList = new Vector<String>();
msgContainer.put(key, errList);
}
errList.add(this.errMsg);
}
private boolean checkTerminationConditions() {
Integer currentLayer = this.startRuleLayer;
int i=0;
boolean nextLayerExists = true;
while (nextLayerExists && (currentLayer != null)) {
// get rules for layer
HashSet<Rule> rulesForLayer = this.invertedRuleLayer.get(currentLayer);
if (rulesForLayer != null) {
this.orderedRuleLayer.addElement(currentLayer);
Vector<Rule> currentRules = new Vector<Rule>();
Iterator<?> en = rulesForLayer.iterator();
while (en.hasNext()) {
Rule rule = (Rule) en.next();
if (rule.isEnabled())
currentRules.addElement(rule);
}
boolean checkOK = checkTypeDeletion(currentLayer, currentRules);
Pair<Boolean, Vector<Rule>> value1 = new Pair<Boolean, Vector<Rule>>(
Boolean.valueOf(checkOK), currentRules);
this.resultTypeDeletion.put(currentLayer, value1);
checkOK = checkNonDeletionLayer(currentRules);
Pair<Boolean, Vector<Rule>> value2 = new Pair<Boolean, Vector<Rule>>(
Boolean.valueOf(checkOK), currentRules);
this.resultNonDeletion.put(currentLayer, value2);
checkOK = checkDeletionLayer(currentRules);
Pair<Boolean, Vector<Rule>> value3 = new Pair<Boolean, Vector<Rule>>(
Boolean.valueOf(checkOK), currentRules);
this.resultDeletion.put(currentLayer, value3);
}
// OrderedSetIterator osi = this.orderedRuleLayerSet.find(currentLayer);
// if ((osi == null) || osi.atEnd())
// nextLayerExists = false;
// else {
// osi.advance();
// currentLayer = (Integer) osi.get();
// }
i++;
if (i < orderedRuleLayerSet.size()) {
currentLayer = orderedRuleLayerSet.get(i);
}
else {
nextLayerExists = false;
}
}
return true;
}
/**
* Checks first (type) deletion condition of rules on a certain layer .
* These rules must to delete at least one node or edge of a certain type.
*
* @param rules
* belong to the same rule layer
* @return true if condition is satisfied.
*/
private boolean checkTypeDeletion(Integer layer, Vector<Rule> rules) {
// Deletion Layer Conditions (1)
boolean checkOK = true;
// 1) check: each rule decreases the number of graph items
for (int j = 0; j < rules.size(); j++) {
Rule r = rules.elementAt(j);
// each rule has to delete
if (this.deletionRule.contains(r)) {
if (r.getLeft().getSize() < r.getRight().getSize()) {
// the rule is deleting, but creating, too
checkOK = false;
String test = "Rule <" + r.getName()+ "> does not decrease";
if (this.errMsg.indexOf(test) < 0) {
this.errMsg = "Rule <" + r.getName()
+ "> does not decrease the number of graph items of one special type.";
addErrorMessage(this.errorMsgDeletion1, layer, this.errMsg);
}
break;
}
}
else if (/*r.isEmptyRule() && */r.isTriggerOfLayer()) {
// an special case: a trigger rule is applied once only
}
else {
// the rule is not deleting
this.errMsg = "Rule <" + r.getName()
+ "> does not decrease the number of graph items.";
addErrorMessage(this.errorMsgDeletion1, layer, this.errMsg);
return false;
}
}
if (checkOK) {
return true;
}
// or
// 2) check: each rule decreases the number of graph items of one
// special type
Hashtable<Pair<GraphObject, Object>, Vector<Rule>> deletedType = new Hashtable<Pair<GraphObject, Object>, Vector<Rule>>();
for (int j = 0; j < rules.size(); j++) {
Rule r = rules.elementAt(j);
// each rule has to delete is already checked
// check one special type
for (Enumeration<GraphObject> en = r.getLeft().getElements(); en
.hasMoreElements();) {
GraphObject o = en.nextElement();
if (r.getImage(o) == null) {
boolean containsKey = false;
GraphObject t = null;
if (o.isNode())
t = r.getTypeSet().getTypeGraphNode(o.getType());
else
t = r.getTypeSet().getTypeGraphArc(o.getType(),
((Arc)o).getSourceType(),
((Arc)o).getTargetType());
Pair<GraphObject, Object> delt = new Pair<GraphObject, Object>(t, null);
if (o.isArc())
delt.second = new Pair<GraphObject, GraphObject>(
r.getTypeSet().getTypeGraphNode(((Arc) o).getSource().getType()),
r.getTypeSet().getTypeGraphNode(((Arc) o).getTarget().getType()));
Pair<GraphObject, Object> t1 = null;
Enumeration<Pair<GraphObject, Object>> e = deletedType.keys();
while (e.hasMoreElements()) {
t1 = e.nextElement();
if (t.getType().isRelatedTo(t1.first.getType())) {
if (t1.second == null && delt.second == null) {
containsKey = true;
break;
}
if (t1.second != null && delt.second != null) {
Pair<?,?> t1sec = (Pair<?,?>) t1.second;
Pair<?,?> deltsec = (Pair<?,?>) delt.second;
if (((GraphObject)deltsec.first).getType()
.isRelatedTo(((GraphObject)t1sec.first).getType())
&& (((GraphObject)deltsec.second).getType())
.isRelatedTo(((GraphObject)t1sec.second).getType())) {
containsKey = true;
break;
}
}
}
}
if (containsKey) {
if (!deletedType.get(t1).contains(r))
deletedType.get(t1).add(r);
} else {
Vector<Rule> v = new Vector<Rule>(rules.size());
v.add(r);
deletedType.put(delt, v);
}
}
}
}
Vector<GraphObject> ltypes = new Vector<GraphObject>();
for (Enumeration<Pair<GraphObject, Object>> en = deletedType.keys(); en.hasMoreElements();) {
Pair<GraphObject, Object> key = en.nextElement();
GraphObject t = key.first;
Vector<Rule> v = deletedType.get(key);
if (v.size() == rules.size()) {
for (int j = 0; j < rules.size(); j++) {
Rule r = rules.elementAt(j);
if (key.second == null) { // node type
if (r.getLeft().getElementsOfTypeAsVector(t.getType()).size() <= r
.getRight().getElementsOfTypeAsVector(t.getType()).size()) {
String test = "Rule <" + r.getName()+ "> does not decrease";
if (this.errMsg.indexOf(test) < 0) {
this.errMsg = "Rule <" + r.getName()
+ "> does not decrease the number of graph items of one special node type <"
+t.getType().getName()+">";
addErrorMessage(this.errorMsgDeletion1, layer, this.errMsg);
}
return false;
}
} else { // arc type
if (r.getLeft().getElementsOfTypeAsVector(t.getType(),
((GraphObject) ((Pair<?,?>) key.second).first).getType(),
((GraphObject) ((Pair<?,?>) key.second).second).getType())
.size() <= r.getRight().getElementsOfTypeAsVector(t.getType(),
((GraphObject) ((Pair<?,?>) key.second).first).getType(),
((GraphObject) ((Pair<?,?>) key.second).second).getType())
.size()) {
String test = "Rule <" + r.getName()+ "> does not decrease";
if (this.errMsg.indexOf(test) < 0) {
this.errMsg = "Rule <" + r.getName()
+ "> does not decrease the number of graph items of one special edge type <"
+t.getType().getName()+">";
addErrorMessage(this.errorMsgDeletion1, layer, this.errMsg);
}
return false;
}
}
}
ltypes.add(t);
}
}
if (ltypes.size() != 0) {
this.deletionType.put(layer, ltypes);
return true;
}
this.errMsg = "Rules do not decrease the number of graph items.";
addErrorMessage(this.errorMsgDeletion1, layer, this.errMsg);
return false;
}
/**
* Checks deletion cond. of rules on a certain layer.
*
* @return true if condition is satisfied.
*/
private boolean checkDeletionLayer(Vector<Rule> rules) {
// Deletion Layer Conditions (2)
boolean result = true;
HashSet<Object> deletionSet = new HashSet<Object>();
HashSet<Object> creationSet = new HashSet<Object>();
for (int j = 0; j < rules.size(); j++) {
deletionSet.clear();
creationSet.clear();
Rule rule = rules.elementAt(j);
if (this.deletionRule.contains(rule)) {
Integer rl = this.ruleLayer.get(rule);
Graph leftGraph = rule.getLeft();
Graph rightGraph = rule.getRight();
/* find all objects to delete */
for (Enumeration<GraphObject> en = leftGraph.getElements();
en.hasMoreElements();) {
GraphObject go = en.nextElement();
if (rule.getImage(go) == null)
deletionSet.add(go);
}
/* 1. is deleting at least one item */
if (deletionSet.isEmpty()) {
result = false;
this.errMsg = "Rule <"+ rule.getName() + ">"
+" does not delete at least one graph item.";
addErrorMessage(this.errorMsgDeletion2, rl, this.errMsg);
break;
}
/* 2. 0<= cl(l)<=dl(l)<=n */
for (Enumeration<Object> en = getDeletionLayer().keys(); en
.hasMoreElements()
&& result;) {
GraphObject key = (GraphObject) en.nextElement();
Integer dl = getDeletionLayer().get(key);
Integer cl = getCreationLayer().get(key);
if (!(0 <= cl.intValue())
|| !(cl.intValue() <= dl.intValue())) {
result = false;
this.errMsg = "Type <"
+ key.getType().getStringRepr()+ ">"
+ ", rl = "+rl.intValue()
+ ", cl = "+cl.intValue()
+ ", dl = "+ dl.intValue()
+ " do not satisfy condition:"
+ " 0 <= cl <= dl <= rl";
addErrorMessage(this.errorMsgDeletion2, dl, this.errMsg);
break;
}
}
/* 3. dl(l) <= rl(r) */
for (Iterator<?> en = deletionSet.iterator(); en.hasNext()
&& result;) {
GraphObject go = (GraphObject) en.next();
GraphObject t = getTypeGraphObject(go);
Integer dl = getDeletionLayer().get(t);
if (dl.intValue() > rl.intValue()) {
result = false;
this.errMsg = "Rule <"+ rule.getName()+ ">, "
+ "Type <"+ t.getType().getStringRepr()+ ">"
+ ", dl = "+ dl.intValue()
+ ", rl = "+rl.intValue()
+ " do not satisfy condition"
+ " dl <= rl.";
addErrorMessage(this.errorMsgDeletion2, rl, this.errMsg);
break;
}
}
if (!result)
break;
/* alle erzeugten Objekte suchen */
for (Enumeration<GraphObject> en = rightGraph.getElements(); en
.hasMoreElements();) {
GraphObject go = en.nextElement();
if (!rule.getInverseImage(go).hasMoreElements())
creationSet.add(go);
}
/* 4. cl(l) > rl(r) */
for (Iterator<?> en = creationSet.iterator(); en.hasNext()
&& result;) {
GraphObject go = (GraphObject) en.next();
GraphObject t = getTypeGraphObject(go);
Integer cl = getCreationLayer().get(t);
if (cl.intValue() <= rl.intValue()) {
result = false;
this.errMsg = "Rule <"+ rule.getName()+ ">, "
+ "Type <"+ t.getType().getStringRepr()+ ">"
+ ", cl = "+ cl.intValue()
+ ", rl = "+rl.intValue()
+ " do not satisfy condition"
+ " cl > rl.";
addErrorMessage(this.errorMsgDeletion2, rl, this.errMsg);
break;
}
}
} else {
result = false;
break;
}
}
return result;
}
/**
* Checks non-deletion cond. of rules on a certain layer.
*
* @return true if condition is satisfied.
*/
private boolean checkNonDeletionLayer(Vector<Rule> rules) {
// Creation Layer Conditions (3)
boolean result = true;
HashSet<Object> preservedSet = new HashSet<Object>();
HashSet<Object> creationSet = new HashSet<Object>();
for (int j = 0; j < rules.size(); j++) {
Rule rule = rules.elementAt(j);
int errKey = rule.getLayer();
if (this.priority)
errKey = rule.getPriority();
if (this.nondeletionRule.contains(rule)) {
/* rule is total */
if (!rule.isTotal()) {
this.errMsg = "Rule <" + rule.getName()
+ "> is not total.";
addErrorMessage(this.errorMsgNonDeletion, new Integer(errKey), this.errMsg);
return false;
}
/* 1. rule is injective */
if (!rule.isInjective()) {
this.errMsg = "Rule <" + rule.getName()
+ "> is not injective.";
addErrorMessage(this.errorMsgNonDeletion, new Integer(errKey), this.errMsg);
return false;
}
/* 2. rule has a NAC */
else if (rule.isCreating()
&& rule.getNACsList().isEmpty()) {
this.errMsg = "Rule <" + rule.getName()
+ "> does not have any NAC.";
addErrorMessage(this.errorMsgNonDeletion, new Integer(errKey), this.errMsg);
return false;
}
/* 2. NAC : L -> N with N -> R injective */
else if (!this.ruleWithRightInjNAC(errKey, rule)) {
return false;
}
Integer rl = this.ruleLayer.get(rule);
creationSet.clear();
preservedSet.clear();
Graph leftGraph = rule.getLeft();
Graph rightGraph = rule.getRight();
/* alle erhaltende Objekte suchen */
for (Enumeration<GraphObject> en = leftGraph.getElements(); en
.hasMoreElements();) {
GraphObject grob = en.nextElement();
if (rule.getImage(grob) != null)
preservedSet.add(grob);
}
/* alle erzeugten Objekte suchen */
for (Enumeration<GraphObject> en = rightGraph.getElements(); en
.hasMoreElements();) {
GraphObject grob = en.nextElement();
if (!rule.getInverseImage(grob).hasMoreElements())
creationSet.add(grob);
}
/* 3. for preserved objects: cl(l) <= rl(r) */
for (Iterator<?> en = preservedSet.iterator(); en.hasNext()
&& result;) {
GraphObject grob = (GraphObject) en.next();
GraphObject t = getTypeGraphObject(grob);
Integer cl = getCreationLayer().get(t);
if (cl.intValue() > rl.intValue()) {
result = false;
this.errMsg = "Rule <"+ rule.getName()+ ">, "
+ "Type <"+ t.getType().getStringRepr()+ ">, "
+ " rl = "+ rl.intValue()
+ ", cl = "+ cl.intValue()
+ " does not preserve graph items "
+ " such that cl <= rl.";
addErrorMessage(this.errorMsgNonDeletion, rl, this.errMsg);
break;
}
}
/* 4. for created objects: cl(l) > rl(r) */
for (Iterator<?> en = creationSet.iterator(); en.hasNext()
&& result;) {
GraphObject grob = (GraphObject) en.next();
GraphObject t = getTypeGraphObject(grob);
Integer cl = getCreationLayer().get(t);
if (cl.intValue() <= rl.intValue()) {
result = false;
this.errMsg = "Rule <"+ rule.getName()+ ">, "
+ "Type <"+ t.getType().getStringRepr()+ ">, "
+ "rl = "+ rl.intValue()
+ ", cl = "+ cl.intValue()
+ " does not create graph items"
+ " such that cl > rl.";
addErrorMessage(this.errorMsgNonDeletion, rl, this.errMsg);
break;
}
}
} else {
result = false;
break;
}
}
return result;
}
/** exists a NAC : L -> N with N -> R injective
*/
private boolean ruleWithRightInjNAC(int errKey, final Rule rule) {
/* 2. NAC : L -> N with N -> R injective */
final List<OrdinaryMorphism> nacs = rule.getNACsList();
if (nacs.isEmpty()) {
return false;
}
List<Pair<OrdinaryMorphism,OrdinaryMorphism>> childNacs = null;
boolean result = false;
for (int l=0; l<nacs.size() && !result; l++) {
final OrdinaryMorphism nac = nacs.get(l);
if (nac.isEnabled()) {
boolean isChildNac = false;
boolean failed = false;
OrdinaryMorphism nprime = BaseFactory.theFactory()
.createMorphism(nac.getTarget(),
rule.getRight());
nprime.setCompletionStrategy(new Completion_InjCSP());
Enumeration<GraphObject> dom = rule.getDomain();
while (dom.hasMoreElements()) {
GraphObject grob = dom.nextElement();
GraphObject nacob = nac.getImage(grob);
if (nacob != null) {
try {
if (nacob.getType().isChildOf(rule.getImage(grob).getType())) {
isChildNac = true;
if (childNacs == null)
childNacs = new Vector<Pair<OrdinaryMorphism,OrdinaryMorphism>>(1);
childNacs.add(new Pair<OrdinaryMorphism,OrdinaryMorphism>(nac, nprime));
break;
}
else
nprime.addMapping(nacob, rule.getImage(grob));
} catch (agg.xt_basis.BadMappingException ex) {
failed = true;
break;
}
}
}
// at least one NAC exists so that n':N->R injective
if (isChildNac) {
result = false;
continue;
}
else if (!failed)
result = nprime.nextCompletionWithConstantsChecking();
}
}
if (!result && childNacs != null && !childNacs.isEmpty()) {
for (int i=0; i<childNacs.size() && !result; i++) {
result = ruleWithRightInjChildNAC(rule, childNacs.get(i));
}
}
if (!result) {
this.errMsg = "Rule <"+ rule.getName()+ "> "
+ "does not have any right injective NACs.";
addErrorMessage(this.errorMsgNonDeletion, new Integer(errKey), this.errMsg);
}
return result;
}
private boolean ruleWithRightInjChildNAC(final Rule rule, Pair<OrdinaryMorphism,OrdinaryMorphism> p) {
/* 2. NAC : L -> N with N -> R injective */
boolean result = false;
boolean oneChildOnly = false;
boolean failed = false;
OrdinaryMorphism nac = p.first;
OrdinaryMorphism nprime = p.second;
nprime.setCompletionStrategy(new Completion_InheritCSP());
Enumeration<GraphObject> dom = rule.getDomain();
while (dom.hasMoreElements()) {
GraphObject grob = dom.nextElement();
GraphObject nacob = nac.getImage(grob);
if (nacob != null) {
try {
if (nacob.getType().isChildOf(rule.getImage(grob).getType())) {
nprime.addChild2ParentMapping(nacob, rule.getImage(grob));
if (grob.getType().getChildren().size() == 1)
oneChildOnly = true;
}
else
nprime.addMapping(nacob, rule.getImage(grob));
} catch (agg.xt_basis.BadMappingException ex) {
// this.errMsg = "Rule <"+ rule.getName()+ "> : "
// + "Mapping of N': N->R across N<-L->R failed.";
// addErrorMessage(this.errorMsgNonDeletion, new Integer(errKey), this.errMsg);
failed = true;
break;
}
}
}
// at least one NAC exists so that n':N->R injective
if (!failed && oneChildOnly)
result = nprime.nextCompletionWithConstantsChecking();
return result;
}
/**
* A fast check on validity.
*
* @return true if the layer function is valid.
*/
public boolean isValid() {
return this.valid;
}
private boolean setValidResult() {
boolean result = true;
for (int i = 0; i < this.orderedRuleLayer.size(); i++) {
Integer currentLayer = this.orderedRuleLayer.elementAt(i);
// System.out.println("Layer: "+currentLayer.intValue());
boolean localresult = true; //false;
Pair<Boolean, Vector<Rule>> p = this.resultTypeDeletion.get(currentLayer);
if (p != null && !p.second.isEmpty()) {
localresult = p.first.booleanValue();
}
if (!localresult) {
p = this.resultNonDeletion.get(currentLayer);
localresult = p.first.booleanValue();
if (!localresult) {
p = this.resultDeletion.get(currentLayer);
localresult = p.first.booleanValue();
if (localresult) {
// System.out.println("Layer: "+currentLayer.intValue()+" Deletion_2: "+localresult);
this.errorMsgDeletion1.remove(currentLayer);
this.errorMsgDeletion2.remove(currentLayer);
this.errorMsgNonDeletion.remove(currentLayer);
}
} else {
// System.out.println("Layer: "+currentLayer.intValue()+" NonDeletion: "+localresult);
this.errorMsgDeletion1.remove(currentLayer);
this.errorMsgDeletion2.remove(currentLayer);
this.errorMsgNonDeletion.remove(currentLayer);
}
} else {
// System.out.println("Layer: "+currentLayer.intValue()+" Deletion_1: "+localresult);
this.errorMsgDeletion1.remove(currentLayer);
this.errorMsgDeletion2.remove(currentLayer);
this.errorMsgNonDeletion.remove(currentLayer);
}
result = result && localresult;
}
return result;
}
/**
* Returns an error message if the layer function is not valid.
*
* @return The error message.
*/
public String getErrorMessage() {
String str = getErrorOfTypeDeletion(10);
String str1 = getErrorOfDeletion(10);
String str2 = getErrorOfNonDeletion(10);
if (!str1.equals("")) {
str = str.concat("\n\n");
str = str.concat(str1);
}
if (!str2.equals("")) {
str = str.concat("\n\n");
str = str.concat(str2);
}
return str;
}
private String getErrorOfTypeDeletion(int maxErrors) {
int n = 0;
String str0 = "*** (Type) Deletion Layer Condition ( Deletion_1 ) ***";
String str = "";
Enumeration<Integer> keys = this.errorMsgDeletion1.keys();
while (keys.hasMoreElements() && n<=maxErrors) {
final List<String> list = this.errorMsgDeletion1.get(keys.nextElement());
for (int i=0; i<list.size(); i++) {
str = str.concat("\n");
str = str.concat(list.get(i));
n++;
if (n>maxErrors) {
str = str.concat("\n ... ");
break;
}
}
}
if (!str.equals(""))
str = str0.concat(str);
return str;
}
private String getErrorOfDeletion(int maxErrors) {
int n = 0;
String str0 = "*** Deletion Layer Condition ( Deletion_2 ) ***";
String str = "";
Enumeration<Integer> keys = this.errorMsgDeletion2.keys();
while (keys.hasMoreElements() && n<=maxErrors) {
final List<String> list = this.errorMsgDeletion2.get(keys.nextElement());
for (int i=0; i<list.size(); i++) {
str = str.concat("\n");
str = str.concat(list.get(i));
n++;
if (n>maxErrors) {
str = str.concat("\n ... ");
break;
}
}
}
if (!str.equals(""))
str = str0.concat(str);
return str;
}
private String getErrorOfNonDeletion(int maxErrors) {
int n = 0;
String str0 = "*** Nondeletion Layer Condition ( Nondeletion ) ***";
String str = "";
Enumeration<Integer> keys = this.errorMsgNonDeletion.keys();
while (keys.hasMoreElements() && n<=maxErrors) {
final List<String> list = this.errorMsgNonDeletion.get(keys.nextElement());
for (int i=0; i<list.size(); i++) {
str = str.concat("\n");
str = str.concat(list.get(i));
if (n>maxErrors) {
str = str.concat("\n ... ");
break;
}
}
}
if (!str.equals(""))
str = str0.concat(str);
return str;
}
/**
* Returns the rule layer of the layer function.
*
* @return The rule layer.
*/
public Hashtable<Rule, Integer> getRuleLayer() {
int size = this.listOfRules.size();
if (size != this.ruleLayer.size()) {
initRuleLayer(this.grammar);
return this.ruleLayer;
}
Iterator<Rule> en = this.listOfRules.iterator();
while (en.hasNext()) {
Object key = en.next();
if (!this.ruleLayer.containsKey(key)) {
initRuleLayer(this.grammar);
return this.ruleLayer;
}
}
return this.ruleLayer;
}
public int getRuleLayer(Rule r) {
if (this.ruleLayer.containsKey(r))
return this.ruleLayer.get(r).intValue();
return 0;
}
/**
* Returns the creation layer of the layer function.
*
* @return The creation layer.
*/
public Hashtable<Object, Integer> getCreationLayer() {
int size = this.typeGraph.getSize();
if (size != this.creationLayer.size()) {
initCreationLayer(this.grammar);
return new Hashtable<Object, Integer>(this.creationLayer);
}
Enumeration<GraphObject> en = this.typeGraph.getElements();
while (en.hasMoreElements()) {
Object key = en.nextElement();
if (!this.creationLayer.containsKey(key)) {
initCreationLayer(this.grammar);
return new Hashtable<Object, Integer>(this.creationLayer);
}
}
return new Hashtable<Object, Integer>(this.creationLayer);
}
public int getCreationLayer(GraphObject t) {
if (this.creationLayer.containsKey(t))
return this.creationLayer.get(t).intValue();
return 0;
}
/**
* Returns the deletion layer of the layer function.
*
* @return The deletion layer.
*/
public Hashtable<Object, Integer> getDeletionLayer() {
int size = this.typeGraph.getSize();
if (size != this.deletionLayer.size()) {
initDeletionLayer(this.grammar);
return new Hashtable<Object, Integer>(this.deletionLayer);
}
Enumeration<GraphObject> en = this.typeGraph.getElements();
while (en.hasMoreElements()) {
Object key = en.nextElement();
if (!this.deletionLayer.containsKey(key)) {
initDeletionLayer(this.grammar);
return new Hashtable<Object, Integer>(this.deletionLayer);
}
}
return new Hashtable<Object, Integer>(this.deletionLayer);
}
public int getDeletionLayer(GraphObject t) {
if (this.deletionLayer.containsKey(t))
return this.deletionLayer.get(t).intValue();
return 0;
}
/**
* Returns the smallest layer of the rule layer.
*
* @return The smallest layer.
*/
public Integer getStartLayer() {
int startL = Integer.MAX_VALUE;
Integer result = null;
for (Enumeration<Rule> keys = this.ruleLayer.keys(); keys.hasMoreElements();) {
Object key = keys.nextElement();
Integer layer = this.ruleLayer.get(key);
if (layer.intValue() < startL) {
startL = layer.intValue();
result = layer;
}
}
return result;
}
/**
* Inverts a layer function so that the layer is the key and the value is a
* set.
*
* @param layer
* The layer function will be inverted.
* @return The inverted layer function.
*/
public Hashtable<Integer, HashSet<Rule>> invertLayer(
Hashtable<Rule, Integer> layer) {
Hashtable<Integer, HashSet<Rule>> inverted = new Hashtable<Integer, HashSet<Rule>>();
for (Enumeration<Rule> keys = layer.keys(); keys.hasMoreElements();) {
Rule key = keys.nextElement();
Integer value = layer.get(key);
HashSet<Rule> invertedValue = inverted.get(value);
if (invertedValue == null) {
invertedValue = new HashSet<Rule>();
invertedValue.add(key);
inverted.put(value, invertedValue);
} else {
invertedValue.add(key);
}
}
return inverted;
}
public void saveRuleLayer() {
for (Enumeration<Rule> keys = this.ruleLayer.keys(); keys.hasMoreElements();) {
Rule r = keys.nextElement();
Integer layer = this.ruleLayer.get(r);
if (this.layered)
r.setLayer(layer.intValue());
else if (this.priority)
r.setPriority(layer.intValue());
else
r.setLayer(layer.intValue());
}
saveRuleLayerInto(this.oldRuleLayer);
}
private void saveRuleLayerInto(Hashtable<Rule, Integer> table) {
for (Iterator<Rule> e = this.listOfRules.iterator(); e.hasNext();) {
Rule r = e.next();
if (this.layered)
table.put(r, Integer.valueOf(r.getLayer()));
else if (this.priority)
table.put(r, Integer.valueOf(r.getPriority()));
else
table.put(r, Integer.valueOf(r.getLayer()));
}
}
public void setGenerateRuleLayer(boolean b) {
this.generateRuleLayer = b;
}
public void showLayer() {
System.out.println(" RULE LAYER");
for (Enumeration<Rule> keys = this.ruleLayer.keys(); keys.hasMoreElements();) {
Rule r = keys.nextElement();
Integer layer = this.ruleLayer.get(r);
System.out.println(layer.intValue()+" "+r.getName());
}
System.out.println(" CREATION LAYER");
for (Enumeration<GraphObject> keys = this.creationLayer.keys(); keys.hasMoreElements();) {
GraphObject t = keys.nextElement();
Integer layer = this.creationLayer.get(t);
System.out.println(layer.intValue()+" "+t.getType().getStringRepr());
}
System.out.println(" DELETION LAYER");
for (Enumeration<GraphObject> keys = this.deletionLayer.keys(); keys.hasMoreElements();) {
GraphObject t = keys.nextElement();
Integer layer = this.deletionLayer.get(t);
System.out.println(layer.intValue()+" "+t.getType().getStringRepr());
}
}
/**
* Returns the layer function in a human readable way.
*
* @return The text.
*/
public String toString() {
String resultString = super.toString() + " LayerFunction:\n";
resultString += "\tRuleLayer:\n";
resultString += getRuleLayer().toString() + "\n";
resultString += "\tCreationLayer:\n";
resultString += getCreationLayer().toString() + "\n";
resultString += "\tDeletionLayer:\n";
resultString += getDeletionLayer().toString() + "\n";
return resultString;
}
public int getCreationLayer(Type t) {
return 0;
}
public int getDeletionLayer(Type t) {
return 0;
}
}