package agg.xt_basis; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; import java.util.Date; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.File; import agg.cons.AtomConstraint; import agg.util.IntComparator; import agg.util.OrderedSet; import agg.util.Pair; import agg.xt_basis.agt.RuleScheme; public class PriorityGraTraImpl extends GraTra { Random ran = new Random(); private boolean appliedOnce; // private boolean allRulesEnabled = false; private boolean priorityGraTra = false; private Vector<Pair<Integer, HashSet<Rule>>> sortedRules; private File f; private FileOutputStream os; private String protocolFileName = ""; private boolean grammarChecked; // private long time0; public PriorityGraTraImpl() { this.sortedRules = new Vector<Pair<Integer, HashSet<Rule>>>(); } public void dispose() { if (this.sortedRules != null) this.sortedRules.clear(); super.dispose(); } /** not implemented yet! * */ public Pair<Morphism, Morphism> derivation(Match m){ return (null); } public boolean atLeastOneRuleHasPriority() { for (int i = 0; i < this.currentRuleSet.size(); i++) { Rule r = this.currentRuleSet.get(i); if (r.getPriority() > 0) return true; } return false; } private void sortByPriority(Vector<Rule> rules) { RulePriority priority = new RulePriority(rules); Integer startPriority = priority.getStartPriority(); Hashtable<Integer, HashSet<Rule>> invertedRulePriority = priority.invertPriority(); OrderedSet<Integer> rulePrioritySet = new OrderedSet<Integer>(new IntComparator<Integer>()); for (Enumeration<Integer> en = invertedRulePriority.keys(); en .hasMoreElements();) { rulePrioritySet.add(en.nextElement()); } int i = 0; Integer maxPriorityInt = null; HashSet<Rule> priority0Set = null; Integer currentPriority = startPriority; boolean nextPriorityExists = true; while (nextPriorityExists && (currentPriority != null)) { HashSet<Rule> rulesForPriority = invertedRulePriority.get(currentPriority); Pair<Integer, HashSet<Rule>> p = new Pair<Integer, HashSet<Rule>>( currentPriority, rulesForPriority); if (currentPriority.intValue() > 0) this.sortedRules.add(p); else { priority0Set = rulesForPriority; } maxPriorityInt = currentPriority; // set next Layer i++; if (i < rulePrioritySet.size()) { currentPriority = rulePrioritySet.get(i); } else { nextPriorityExists = false; } } if (priority0Set != null && maxPriorityInt != null) { int maxPriority = maxPriorityInt.intValue() + 1; Pair<Integer, HashSet<Rule>> p0 = new Pair<Integer, HashSet<Rule>>(new Integer( maxPriority), priority0Set); this.sortedRules.add(p0); } } public boolean apply() { boolean applied = false; if (atLeastOneRuleHasPriority()) { this.priorityGraTra = true; sortByPriority(this.currentRuleSet); applied = applyPriorityGraTra(); return applied; } return false; } @SuppressWarnings("rawtypes") private boolean applyPriorityGraTra() { boolean result = false; Pair<Integer, HashSet<Rule>> pFirst = this.sortedRules.get(0); // int firstpriority = pFirst.first.intValue(); HashSet ruleSetFirst = pFirst.second; boolean asLongAsPossible = true; boolean applied = true; while (!this.stopping && applied) { if (!this.stopping) { // apply rule with highest priority non-deterministically. // as long as possible asLongAsPossible = true; applied = applyRandomly(ruleSetFirst, asLongAsPossible); // if (applied && options.hasOption(GraTraOptions.CONSISTENCY_CHECK_AFTER_GRAPH_TRAFO)) { // this.checkGraphConsistencyForLayer(firstpriority); // } } asLongAsPossible = false; Pair<Integer, HashSet<Rule>> p = null; HashSet<Rule> ruleSet = null; for (int i = 1; !this.stopping && i < this.sortedRules.size(); i++) { p = this.sortedRules.get(i); // int priority = p.first.intValue(); ruleSet = p.second; if (applyRandomly(ruleSet, asLongAsPossible)) { applied = true; // if (options.hasOption(GraTraOptions.CONSISTENCY_CHECK_AFTER_GRAPH_TRAFO)) { // this.checkGraphConsistencyForLayer(priority); // } break; } } if (applied) result = true; } return result; } @SuppressWarnings("rawtypes") private boolean applyRandomly(Vector<Rule> rules, boolean asLongAsPossible) { boolean result = false; boolean applied = true; while (applied) { applied = false; Vector<?> v = (Vector) rules.clone(); while (!v.isEmpty()) { int j = this.ran.nextInt(v.size()); this.currentRule = (Rule) v.get(j); if (this.currentRule instanceof RuleScheme) { applied = apply((RuleScheme) this.currentRule); } else { applied = this.currentRule.canMatch(this.hostgraph, this.strategy) && applyRule(this.currentRule); } if (applied) { result = true; if (asLongAsPossible) break; return result; } v.remove(this.currentRule); } } return result; } @SuppressWarnings("rawtypes") private boolean applyRandomly(HashSet rules, boolean asLongAsPossible) { Vector<Rule> rulesVec = new Vector<Rule>(rules.size()); Iterator<?> en = rules.iterator(); while (en.hasNext()) { Rule r = (Rule) en.next(); rulesVec.add(r); } return applyRandomly(rulesVec, asLongAsPossible); } private boolean applyRule(Rule r) { boolean applied = false; while (apply(r)) { applied = true; break; } String s0 = r.getName() + " \t applied: " + applied; System.out.println(s0); writeTransformProtocol(s0); String s1 = ""; if (!applied) { s1 = s1 + getErrorMsg(); writeTransformProtocol(s1); } return applied; } /* private boolean applyDefaultGraTra() { boolean applied = false; while (!this.stopping && (currentRuleSet.size() > 0) && !applied) { int i = ran.nextInt(currentRuleSet.size()); // System.out.println("random i: "+i); this.currentRule = currentRuleSet.elementAt(i); if (this.currentRule instanceof RuleScheme) { applied = apply((RuleScheme) this.currentRule); } else { applied = this.currentRule.canMatch(hostgraph, this.strategy) && apply(this.currentRule); } String s0 = this.currentRule.getName() + " \t applied: " + applied; writeTransformProtocol(s0); String s1 = ""; if (!applied) { s1 = s1 + getErrorMsg(); writeTransformProtocol(s1); currentRuleSet.removeElementAt(i); String ss1 = getRuleNames(currentRuleSet); writeTransformProtocol(ss1); } else { appliedOnce = true; if (!isGraphConsistent()) this.stopping = true; } } return applied; } */ public void transform(List<Rule> ruleSet) { // allRulesEnabled = true; this.currentRuleSet.clear(); this.currentRuleSet.addAll(ruleSet); boolean result = apply(); if (!result && !this.priorityGraTra) writeTransformProtocol("Graph transformation failed. No rule priority used."); } public void transform() { this.stopping = false; if(!this.grammar.getListOfRules().isEmpty() && this.currentRuleSet.isEmpty()) setRuleSet(); if (this.writeLogFile) { String dirName = this.grammar.getDirName(); String fileName = this.grammar.getFileName(); if ((fileName == null) || fileName.equals("")) fileName = this.grammar.getName(); openTransformProtocol(dirName, fileName); String version = "Version: AGG " + Version.getID() + "\n"; writeTransformProtocol(version); String s0 = "Graph transformation by rule priority of : " + this.grammar.getName(); String s1 = "at graph : " + this.grammar.getGraph().getName(); String s2 = getRuleNames(this.currentRuleSet); writeTransformProtocol(s0); writeTransformProtocol(s1); writeTransformProtocol(s2); writeTransformProtocol("\n"); } // first check the rules, the graph if (!this.grammarChecked) { Pair<Object, String> pair = this.grammar.isReadyToTransform(true); if (pair != null) { Object test = pair.first; if (test != null) { String s0 = pair.second + "\nTransformation is stopped."; if (test instanceof Type) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.ATTR_TYPE_FAILED, s0)); else if (test instanceof Rule) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.RULE_FAILED, s0)); else if (test instanceof AtomConstraint) ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.ATOMIC_GC_FAILED, s0)); transformFailed(s0); return; } } else if (!this.grammar.isGraphReadyForTransform()) { String s0 = "Graph of the grammar is not fine." + "\nPlease check attribute settings of the objects. \nTransformation is stopped."; ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.GRAPH_FAILED, s0)); transformFailed(s0); return; } else if (!this.checkGraphConsistency()) { String s = "Graph consistency failed." + "\nPlease check the host graph against the graph constraints." + "\nTransformation is stopped."; ((GraTra) this).fireGraTra(new GraTraEvent(this, GraTraEvent.GRAPH_FAILED, s)); transformFailed(s); return; } this.grammarChecked = true; } // stop start time long startTime = System.currentTimeMillis(); // time0 = startTime; Vector<Rule> ruleSet = getEnabledRules(this.currentRuleSet); transform(ruleSet); if (this.options.hasOption(GraTraOptions.CONSISTENCY_CHECK_AFTER_GRAPH_TRAFO)) { this.checkGraphConsistency(); } // stop time System.out.println("Used time for graph transformation: " + (System.currentTimeMillis() - startTime) + "ms"); if (this.writeLogFile) { writeUsedTimeToProtocol("Used time for graph transformation: ", startTime); writeTransformProtocol("\nGraph transformation finished"); closeTransformProtocol(); } fireGraTra(new GraTraEvent(this, GraTraEvent.TRANSFORM_FINISHED, this.errorMsg)); } private void writeUsedTimeToProtocol(String text, long beginTime) { writeTransformProtocol(text+ + (System.currentTimeMillis()-beginTime) + "ms"); // time0 = System.currentTimeMillis(); } private Vector<Rule> getEnabledRules(Vector<Rule> ruleSet) { Vector<Rule> vec = new Vector<Rule>(ruleSet.size()); for (int j = 0; j < ruleSet.size(); j++) { if (ruleSet.elementAt(j).isEnabled()) vec.add(ruleSet.elementAt(j)); } return vec; } private void transformFailed(String text) { System.out.println(text); writeTransformProtocol(text); writeTransformProtocol("\nGraph transformation failed"); // fireGraTra(new GraTraEvent(this,GraTraEvent.TRANSFORM_FAILED, // this.errorMsg)); fireGraTra(new GraTraEvent(this, GraTraEvent.TRANSFORM_FINISHED, this.errorMsg)); closeTransformProtocol(); } public boolean transformationDone() { return this.appliedOnce; } public String getProtocolName() { return this.protocolFileName; } private String getRuleNames(Vector<Rule> rules) { String names = "[ "; for (int j = 0; j < rules.size(); j++) { Rule r = rules.elementAt(j); names = names + r.getName() + " "; } names = names + "]"; return names; } private void openTransformProtocol(String dirName, String fileName) { String dName = dirName; String fName = "PriorityGraTra.log"; // System.out.println("PriorityGraTraImpl.openTransformProtocol: // dirName: "+dirName); // System.out.println("PriorityGraTraImpl.openTransformProtocol: // fileName: "+fileName); if ((fileName != null) && !fileName.equals("")) { if (fileName.endsWith(".ggx")) fName = fileName.substring(0, fileName.length() - 4) + "_GraTra.log"; else fName = fileName + "_GraTra.log"; } // System.out.println(fName); if ((dName != null) && !dName.equals("")) { this.f = new File(dirName); if (this.f.exists()) { if (this.f.isFile()) { if (this.f.getParent() != null) dName = this.f.getParent() + File.separator; else dName = "." + File.separator; } else if (this.f.isDirectory()) { // System.out.println(dirName); dName = this.f.getPath() + File.separator; } else dName = "." + File.separator; } else dName = "." + File.separator; this.f = new File(dirName + fName); } else this.f = new File(fName); try { this.os = new FileOutputStream(this.f); this.protocolFileName = this.f.getName(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } writeTransformProtocol((new Date()).toString()); } private void writeTransformProtocol(String s) { if (this.os == null) return; try { if (!s.equals("\n")) this.os.write(s.getBytes()); this.os.write('\n'); } catch (IOException ex) { ex.printStackTrace(); } } private void closeTransformProtocol() { if (this.os == null) return; try { this.os.close(); } catch (IOException ex) { ex.printStackTrace(); } } }