/** * */ package agg.ruleappl; 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.attribute.impl.CondTuple; import agg.attribute.impl.ContextView; import agg.attribute.impl.ValueMember; import agg.attribute.impl.ValueTuple; import agg.attribute.impl.VarTuple; import agg.parser.CriticalPair; import agg.parser.CriticalPairOption; import agg.parser.DependencyPairContainer; import agg.parser.ExcludePair; import agg.parser.ExcludePairContainer; import agg.parser.ExcludePairHelper; import agg.parser.PairContainer; import agg.parser.ParserFactory; import agg.parser.SimpleExcludePair; import agg.util.Pair; import agg.xt_basis.Arc; import agg.xt_basis.BadMappingException; import agg.xt_basis.BaseFactory; import agg.xt_basis.Completion_InjCSP; import agg.xt_basis.ConcurrentRule; import agg.xt_basis.GraGra; import agg.xt_basis.Graph; import agg.xt_basis.GraphObject; import agg.xt_basis.Match; import agg.xt_basis.MorphCompletionStrategy; //import agg.xt_basis.Node; import agg.xt_basis.OrdinaryMorphism; import agg.xt_basis.Rule; import agg.xt_basis.Type; import agg.xt_basis.csp.CompletionPropertyBits; /** * @author olga * */ public class ApplicabilityChecker implements Runnable { private GraGra gragra; private final Completion_InjCSP strategy = new Completion_InjCSP(); private MorphCompletionStrategy gragraStrategy; private CriticalPairOption cpOption; private RuleSequence ruleSequence; private final List<Rule> nonApplicableRules = new Vector<Rule>(); private final List<ConcurrentRule> concurrentRules = new Vector<ConcurrentRule>(); private final List<ConcurrentRule> applicableConcurrentRules = new Vector<ConcurrentRule>(); // private boolean checked, // applicabilityChecked, // nonApplicabilityChecked; private String info = ""; private int depth = -1; private boolean completeConcurrency; private boolean completeCPA; private boolean consistentConcurrency; private boolean completeConcurRuleBackward = true; private boolean ignoreDanglingEdgeOfDelNode; private boolean mainResult; public ApplicabilityChecker( final RuleSequence sequence, final GraGra grammar) { this.ruleSequence = sequence; this.gragra = grammar; this.cpOption = sequence.getCriticalPairOption(); if (this.cpOption == null) this.cpOption = new CriticalPairOption(); this.completeConcurRuleBackward = true; if (this.gragra != null) this.gragraStrategy = this.gragra.getMorphismCompletionStrategy(); } public ApplicabilityChecker( final RuleSequence sequence, final GraGra grammar, final CriticalPairOption option) { this.ruleSequence = sequence; this.gragra = grammar; this.cpOption = option; this.completeConcurRuleBackward = true; this.gragraStrategy = this.gragra.getMorphismCompletionStrategy(); } // public ApplicabilityChecker( // final RuleSequence sequence, // MorphCompletionStrategy strat) { // // this.ruleSequence = sequence; // this.cpOption = new CriticalPairOption(); // this.completeConcurRuleBackward = false; // if (strat != null) // this.gragraStrategy = strat; // } public void setCriticalPairOption(final CriticalPairOption option) { this.cpOption = option; } public void run() { this.check(); } public boolean getResult() { return this.mainResult; } public void setDepthOfConcurrentRule(final int d) { this.depth = d; } public int getDepthOfConcurrentRule() { return this.depth; } /** * If the specified parameter is false, * only maximal intersection of rhs and lhs of base rules * is taken into account for building a concurrent rule, * otherwise all possible intersections are used. */ public void setCompleteConcurrency(boolean b) { this.completeConcurrency = b; } public boolean getCompleteConcurrency() { return this.completeConcurrency; } /** * Set the value of the local variable for checking concurrent rules. * If the specified parameter is true, * created concurrent rules will be checked by critical * pair analysis (CPA), otherwise only its building rules. */ public void setCompleteCPAOfConcurrency(boolean b) { this.completeCPA = b; } /** * Returns the value of the local variable for checking concurrent rules. */ public boolean getCompleteCPAOfConcurrency() { return this.completeCPA; } public void setConsistentConcurrency(boolean b) { this.consistentConcurrency = b; } public boolean getConsistentConcurrency() { return this.consistentConcurrency; } // private void setCompletionConcurrentRuleBackward(boolean b) { // this.completeConcurrentRuleBackward = b; // } public boolean isCompletionConcurrentRuleForward() { return !this.completeConcurRuleBackward; } public boolean isCompletionConcurrentRuleBackward() { return this.completeConcurRuleBackward; } /** * Set the value of the local variable for checking * the dangling edge condition when a rule is node-deleting. */ public void setIgnoreDanglingEdgeOfDelNode(boolean b) { this.ignoreDanglingEdgeOfDelNode = b; } /** * Returns the value of the local variable for checking * the dangling edge condition when a rule is node-deleting. */ public boolean getIgnoreDanglingEdgeOfDelNode() { return this.ignoreDanglingEdgeOfDelNode; } public void dispose() { clear(); this.gragra = null; this.cpOption = null; this.gragraStrategy = null; this.ruleSequence = null; } public void clear() { this.nonApplicableRules.clear(); this.applicableConcurrentRules.clear(); this.concurrentRules.clear(); } // private void clearHelpContainerOfSequence() { // this.nonApplicableRules.clear(); // this.applicableConcurrentRules.clear(); // this.concurrentRules.clear(); // } public RuleSequence getRuleSequence() { return this.ruleSequence; } public boolean check() { this.mainResult = false; if (this.ruleSequence != null) { if (this.ruleSequence.getGraph() == null) { this.mainResult = checkWithoutGraph(); } else { this.mainResult = checkAtGraph(); } this.ruleSequence.checked = true; // save created concurrent rules // this.ruleSequence.saveConcurrentRules(); } return this.mainResult; } private boolean checkAtGraph() { System.out.println("\n*** ApplicabilityChecker.checkAtGraph " +this.ruleSequence.getGraph().getName() +" start at: "+this.ruleSequence.getStartIndexOfCheck()+" "+this.ruleSequence.getStartRule().getName()); this.clear(); if (this.ruleSequence.checked) { this.ruleSequence.reinit(); } if (this.ruleSequence.getStartIndexOfCheck() > 0) { int preIndx = this.ruleSequence.getStartIndexOfCheck()-1; Rule preRule = this.ruleSequence.getRule(preIndx); boolean applicabilityOfPreRuleTrue = this.ruleSequence.getRuleApplicabilityResult(preIndx, preRule.getName()); if (!applicabilityOfPreRuleTrue) { setApplicabilityResult(false, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); return false; } } boolean result1 = this.initializationRule(this.ruleSequence.getRules(), this.ruleSequence.getGraph()); if (!result1) { // this.checked = true; // this.applicabilityChecked = true; return result1; } boolean result2 = this.noNodeDeletingRules(this.ruleSequence.getRules()); if (!result2 && !this.ruleSequence.getIgnoreDanglingEdgeOfDelNode()) { // this.checked = true; // this.applicabilityChecked = true; return result2; } boolean result3 = this.noImpedingPredecessors(this.ruleSequence.getRules()); boolean result4 = true; if (this.completeConcurrency) { // all dependency overlapping will be consider result4 = this.enablingPredecessorApplicablePureConcurrent( this.ruleSequence.getStartIndexOfCheck(), this.ruleSequence.getRules(), this.ruleSequence.getGraph()); } else { // only dependences with max overlapping will be considered result4 = this.enablingPredecessorPureConcurrentApplicable( this.ruleSequence.getStartIndexOfCheck(), this.ruleSequence.getRules(), this.ruleSequence.getGraph()); } // this.checked = true; // this.applicabilityChecked = true; return result1 && result2 && result3 && result4; } public boolean checkWithoutGraph() { this.clear(); if (this.ruleSequence.checked) { this.ruleSequence.reinit(); } if (this.ruleSequence.getStartIndexOfCheck() > 0) { int preIndx = this.ruleSequence.getStartIndexOfCheck()-1; Rule preRule = this.ruleSequence.getRule(preIndx); boolean applicabilityOfPreRuleTrue = this.ruleSequence.getRuleApplicabilityResult(preIndx, preRule.getName()); if (!applicabilityOfPreRuleTrue) { setApplicabilityResult(false, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); return false; } } boolean result1 = this.initializationRule(this.ruleSequence.getRules(), null); if (!result1) { // this.checked = true; // this.applicabilityChecked = true; return result1; } boolean result2 = this.noNodeDeletingRules(this.ruleSequence.getRules()); if (!result2) { // this.checked = true; // this.applicabilityChecked = true; return result2; } boolean result3 = this.noImpedingPredecessors(this.ruleSequence.getRules()); boolean result4 = true; if (this.completeConcurrency) { // all dependency overlapping will be consider result4 = this.enablingPredecessorApplicablePureConcurrent( this.ruleSequence.getStartIndexOfCheck(), this.ruleSequence.getRules()); } else { // only dependences with max overlapping will be considered result4 = this.enablingPredecessorPureConcurrentApplicable( this.ruleSequence.getStartIndexOfCheck(), this.ruleSequence.getRules()); } // this.checked = true; // this.applicabilityChecked = true; return result1 && result2 && result3 && result4; } public List<ConcurrentRule> getConcurrentRules() { return this.concurrentRules; } public List<ConcurrentRule> getApplicableConcurrentRules() { return this.applicableConcurrentRules; } /* * Check 1. criterion of applicability : * first rule is applicable on graph g via injective match * (initialization) */ private boolean initializationRule( final List<Rule> sequence, final Graph g) { boolean result = sequence.isEmpty(); if (result) { setApplicabilityResult(true, ApplicabilityConstants.INITIALIZATION); } else { final Rule r = sequence.get(0); final Pair<Boolean, List<String>> ruleRes = this.ruleSequence.getRuleResult(0, r.getName(), ApplicabilityConstants.INITIALIZATION); if (ruleRes != null) { result = ruleRes.first.booleanValue(); } else { if (g != null) { result = initializationCheck(0, r, g); } else { result = true; // TODO: implementation } } if (result) { System.out.println("=== >>> ApplicabilityChecker.initialization: rule: "+r.getName()+" applicable"); setApplicabilityResult(true, ApplicabilityConstants.INITIALIZATION); setNonApplicabilityResult(false, ApplicabilityConstants.INITIALIZATION_ERROR); setRuleResult(0, r.getName(), true, ApplicabilityConstants.INITIALIZATION, ""); setRuleResult(0, r.getName(), false, ApplicabilityConstants.INITIALIZATION_ERROR, ""); } else { setApplicabilityResult(false, ApplicabilityConstants.INITIALIZATION); setNonApplicabilityResult(true, ApplicabilityConstants.INITIALIZATION_ERROR); setRuleResult(0, r.getName(), false, ApplicabilityConstants.INITIALIZATION, ""); setRuleResult(0, r.getName(), true, ApplicabilityConstants.INITIALIZATION_ERROR, ""); } } return result; } /* * Check 1. criterion of non-applicability: * first rule is not applicable on graph g via injective match * (initialization error) */ /* private boolean initializationError( final List<Rule> sequence, final Graph g) { boolean result = sequence.isEmpty(); if (!result) { final Rule r = sequence.get(0); result = initializationCheck(0, r, g); List<String> v = null; if (result) { setNonApplicabilityResult(false, ApplicabilityConstants.INITIALIZATION_ERROR); setRuleResult(0, r.getName(), false, ApplicabilityConstants.INITIALIZATION_ERROR, ""); } else { setRuleResult(0, r.getName(), true, ApplicabilityConstants.INITIALIZATION_ERROR, ""); } } return result; } */ private boolean isNonApplicableRule(final Rule r, final Graph g) { boolean result = true; Match m = BaseFactory.theFactory().createMatch(r, g); if (m != null) { setMatchCompletionStrategy(m, this.gragraStrategy, true); m.enableInputParameter(false); while (m.nextCompletion()) { m.clearErrorMsg(); if (m.isValid()) { result = false; break; } } m.dispose(); } return result; } private Hashtable<GraphObject, GraphObject> makeMatchMapByObjectFlow( int indx, final Rule r, final Graph g) { int sizeOfObjectFlow = this.ruleSequence.getSizeOfObjFlowForRule(r, indx); if (sizeOfObjectFlow == 0) return null; final List<ObjectFlow> objFlowList = this.ruleSequence.getObjFlowForRule(r, indx); Hashtable<GraphObject, GraphObject> matchmap = this.ruleSequence.getMatchSequence().makeMatchMapByObjectFlow(r, objFlowList); boolean result = (matchmap.size() == sizeOfObjectFlow); if (!result) { Rule ri = r; int i = indx; final Hashtable<GraphObject, GraphObject> inputToPostInput = new Hashtable<GraphObject, GraphObject>(); while (ri != null) { matchmap.putAll(this.ruleSequence.getInput2outputMapIntoGraphAbovePreRule( r, indx, objFlowList, ri, i, inputToPostInput, g)); result = (matchmap.size() == sizeOfObjectFlow); if (!result) { i--; ri = this.ruleSequence.getRule(i); } else break; } } return matchmap; } private boolean initializationCheck(int indx, final Rule r, final Graph g) { if (g == null) { return true; } boolean result = false; Match m = BaseFactory.theFactory().createMatch(r, g); if (m != null) { setMatchCompletionStrategy(m, this.gragraStrategy, true); m.enableInputParameter(false); // try to use object flow if (!r.getLeft().isEmpty() && this.ruleSequence.isObjFlowActive()) { Hashtable<GraphObject, GraphObject> matchmap = makeMatchMapByObjectFlow(indx, r, g); if (matchmap != null && !matchmap.isEmpty()) { try { m.addMapping(matchmap); m.setPartialMorphismCompletion(true); } catch (BadMappingException ex) { // break when OF does not usable m.dispose(); return false; } if (m.isTotal()) { m.clearErrorMsg(); if (m.isAttrConditionSatisfied() && m.areNACsSatisfied() && m.arePACsSatisfied() && m.isValid()) { result = true; } } } } while (!result && m.nextCompletion()) { m.clearErrorMsg(); if (m.isValid()) { result = true; break; } } if (result) { // add match to matchSequence this.ruleSequence.getMatchSequence().addDirectMatch(r, m); } m.dispose(); } return result; } private boolean isRuleApplicable(int indx, final Rule r, final Graph g, boolean checkIfRuleReadyToTransform) { if (checkIfRuleReadyToTransform && r.isReadyToTransform() || !checkIfRuleReadyToTransform) return this.initializationCheck(indx, r, g); return false; } private Hashtable<GraphObject, GraphObject> makeMatchMapByObjectFlow( final ConcurrentRule cr, int indx, final Graph g) { int sizeOfObjectFlow = cr.getSizeOfReflectedInputObjectFlow(); if (sizeOfObjectFlow == 0) return null; Hashtable<GraphObject, GraphObject> matchmap = cr.applyReflectedObjectFlowToMatchMap(g); boolean result = (matchmap.size() == sizeOfObjectFlow); if (!result) { final List<ObjectFlow> objFlowList = this.ruleSequence.getObjFlowForRule(cr.getLastSecondSourceRule(), indx+cr.getDepth()); Rule ri = cr.getLastSecondSourceRule(); int i = indx+cr.getDepth(); final Hashtable<GraphObject, GraphObject> inputToPostInput = new Hashtable<GraphObject, GraphObject>(); while (ri != null) { matchmap.putAll(this.ruleSequence.getReflectedObjectFlowOfGraphAndPreRule( cr, objFlowList, ri, i, inputToPostInput, g)); result = (matchmap.size() == sizeOfObjectFlow); if (!result) { i--; ri = this.ruleSequence.getRule(i); } else break; } } return matchmap; } private boolean isRuleApplicable( final Rule r, final ConcurrentRule cr, final Graph g, boolean checkIfRuleReadyToTransform) { if (cr.getRule().isNotApplicable()) return false; // boolean failed = false; boolean result = false; boolean crReady = cr.isReadyToTransform(); // ((VarTuple)cr.getRule().getAttrContext().getVariables()).showVariables(); if (checkIfRuleReadyToTransform && crReady || !checkIfRuleReadyToTransform) { Match m = cr.getRule().getMatch(); if (m == null) m = BaseFactory.theFactory().createMatch(cr.getRule(), g); if (m != null) { // System.out.println("########## "+m.getRule().getName()); setMatchCompletionStrategy(m, this.gragraStrategy, true); // injective // m.getCompletionStrategy().showProperties(); m.enableInputParameter(false); boolean withOF = false; // LHS of CR is empty if (cr.getRule().getLeft().isEmpty()) { if (m.areNACsSatisfied() && m.arePACsSatisfied()) { result = true; } else { m.dispose(); return false; } } // does ObjectFlow of CR exist else if (this.ruleSequence.isObjFlowActive()) { withOF = true; if (cr.getSizeOfReflectedInputObjectFlow() > 0) { Hashtable<GraphObject, GraphObject> matchmap = makeMatchMapByObjectFlow( cr, this.ruleSequence.getIndexOf(cr.getFirstSourceRule()), this.ruleSequence.getGraph()); if ((matchmap == null) // || (cr.getSizeOfReflectedInputObjectFlow() != matchmap.size()) ) { // break because usage of object flow failed m.dispose(); return false; } try { m.addMapping(matchmap); m.setPartialMorphismCompletion(true); } catch(BadMappingException ex) { // break because usage of object flow failed m.dispose(); return false; } } if (m.isTotal()) { m.clearErrorMsg(); if (m.isAttrConditionSatisfied() && m.areNACsSatisfied() && m.arePACsSatisfied() && m.isValid()) { result = true; } else { m.dispose(); return false; } } else { if (this.completeConcurRuleBackward) m.getCompletionStrategy().getProperties().clear(CompletionPropertyBits.INJECTIVE); m.getCompletionStrategy().initialize(m); while (m.nextCompletion()) { if (m.isAttrConditionSatisfied() && m.areNACsSatisfied() && m.arePACsSatisfied() && m.isValid()) { result = true; cr.setInjectiveMatchProperty(false); // add concurrent match to matchSequence this.ruleSequence.getMatchSequence().addConcurrentSourceMatch(r, cr, m); System.out.println("=== >>> ApplicabilityChecker.isRuleApplicable concurrent rule: "+cr.getRule().getName()+" match found "); } } if (!result) { m.dispose(); cr.getRule().setApplicable(false); return false; } } } // do more if needed if (!result || !withOF) { // do injective match completion while (!result && m.nextCompletion()) { if (!m.isAttrConditionSatisfied()) { if (this.usingAttrConditionAndInputParameter(m.getRule(), m)) { result = true; } else { m.dispose(); return false; } } if (m.isValid()) { result = true; cr.setInjectiveMatchProperty(true); // add concurrent match to matchSequence this.ruleSequence.getMatchSequence().addConcurrentSourceMatch(r, cr, m); System.out.println("=== >>> ApplicabilityChecker.isRuleApplicable concurrent rule: "+cr.getRule().getName()+" INJECTIVE match found "); break; } } if (!result) { // try non-injective match m.getCompletionStrategy().getProperties().clear(CompletionPropertyBits.INJECTIVE); // m.getCompletionStrategy().showProperties(); m.getCompletionStrategy().initialize(m); while (m.nextCompletion()) { if (!m.isAttrConditionSatisfied()) { if (this.usingAttrConditionAndInputParameter(m.getRule(), m)) { result = true; } else { m.dispose(); return false; } } if (m.isValid()) { result = true; cr.setInjectiveMatchProperty(false); // add concurrent match to matchSequence this.ruleSequence.getMatchSequence().addConcurrentSourceMatch(r, cr, m); System.out.println("=== >>> ApplicabilityChecker.isRuleApplicable concurrent rule: "+cr.getRule().getName()+" NON-INJECTIVE match found "); break; } } } m.dispose(); } } } return result; } private void setMatchCompletionStrategy( final Match m, final MorphCompletionStrategy strat, boolean injective) { m.setCompletionStrategy(strat, true); if (injective) m.getCompletionStrategy().getProperties().set(CompletionPropertyBits.INJECTIVE); else m.getCompletionStrategy().getProperties().clear(CompletionPropertyBits.INJECTIVE); // m.getCompletionStrategy().showProperties(); } /* * Check 2. criterion of applicability : * each rule occurring in sequence is non-deleting on nodes * (no node-deleting rules) */ private boolean noNodeDeletingRules(final List<Rule> sequence) { boolean result = true; for (int i=0; i<sequence.size(); i++) { Rule r = sequence.get(i); // System.out.println(r.getName()); final Pair<Boolean, List<String>> ruleRes = this.ruleSequence.getRuleResult(i, r.getName(), ApplicabilityConstants.NO_NODE_DELETING); if (ruleRes != null) { if (!ruleRes.first.booleanValue()) result = false; } else { if (//r.isNodeDeleting() //&& r.mayCauseDanglingEdge() ) { result = false; setRuleResult(i, r.getName(), false, ApplicabilityConstants.NO_NODE_DELETING, ""); System.out.println("=== >>> ApplicabilityChecker.noNodeDeletingRules:: FAILED! rule: "+r.getName()+" may cause dangling edge."); } else { setRuleResult(i, r.getName(), true, ApplicabilityConstants.NO_NODE_DELETING, ""); } } } if (!result && !this.ruleSequence.getIgnoreDanglingEdgeOfDelNode()) { setApplicabilityResult(false, ApplicabilityConstants.NO_NODE_DELETING); } return result; } /* * Check 3. criterion of applicability : * for all (r_i,r_j) in sequence with 1<=j<i<=n, r_i is asymmetrically parallel * independent on r_j * (no impeding predecessors) */ private boolean noImpedingPredecessors( final List<Rule> sequence) { boolean result = true; for (int i=1; i<sequence.size(); i++) { Rule ri = sequence.get(i); boolean localResult = true; final Pair<Boolean, List<String>> ruleRes = this.ruleSequence.getRuleResult(i, ri.getName(), ApplicabilityConstants.NO_IMPEDING_PREDECESSORS); if (ruleRes != null) { localResult = ruleRes.first.booleanValue(); } else { for (int j=0; j<i; j++) { Rule rj = sequence.get(j); final SimpleExcludePair excludePair = makeExcludePair(); if(!asymParallelIndependentByCPA(excludePair, rj, j, ri, i)) { localResult = false; setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_IMPEDING_PREDECESSORS, rj.getName()); break; // evntl. weiter machen! } excludePair.dispose(); } if (localResult) { setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_IMPEDING_PREDECESSORS, ""); } } // rewrite result only if localResult is FALSE if (!localResult) { result = false; } } if (!result) { setApplicabilityResult(false, ApplicabilityConstants.NO_IMPEDING_PREDECESSORS); } return result; } /* private ExcludePairContainer makeExcludePairContainer() { PairContainer pc = ParserFactory.createEmptyCriticalPairs(gragra, CriticalPairOption.EXCLUDEONLY, false); ((ExcludePairContainer) pc).enableComplete( cpOption.completeEnabled()); ((ExcludePairContainer) pc).enableNACs( cpOption.nacsEnabled()); ((ExcludePairContainer) pc).enablePACs( cpOption.pacsEnabled()); ((ExcludePairContainer) pc).enableReduce( cpOption.reduceEnabled()); ((ExcludePairContainer) pc).enableConsistent( cpOption.consistentEnabled()); ((ExcludePairContainer) pc).enableStrongAttrCheck( cpOption.strongAttrCheckEnabled()); ((ExcludePairContainer) pc).enableIgnoreIdenticalRules( cpOption.ignoreIdenticalRulesEnabled()); ((ExcludePairContainer) pc).enableReduceSameMatch( cpOption.reduceSameMatchEnabled()); return (ExcludePairContainer) pc; } */ @SuppressWarnings("deprecation") private DependencyPairContainer makeDependencyPairContainer() { PairContainer pc = ParserFactory.createEmptyCriticalPairs(this.gragra, CriticalPair.TRIGGER_DEPENDENCY, false); ((DependencyPairContainer) pc).enableComplete( this.cpOption.completeEnabled()); ((DependencyPairContainer) pc).enableNACs( this.cpOption.nacsEnabled()); ((DependencyPairContainer) pc).enablePACs( this.cpOption.pacsEnabled()); ((DependencyPairContainer) pc).enableReduce( this.cpOption.reduceEnabled()); ((DependencyPairContainer) pc).enableConsistent( this.cpOption.consistentEnabled()); ((DependencyPairContainer) pc).enableStrongAttrCheck( this.cpOption.strongAttrCheckEnabled()); ((DependencyPairContainer) pc).enableEqualVariableNameOfAttrMapping( this.cpOption.equalVariableNameOfAttrMappingEnabled()); ((DependencyPairContainer) pc).enableIgnoreIdenticalRules( this.cpOption.ignoreIdenticalRulesEnabled()); ((DependencyPairContainer) pc).enableReduceSameMatch( this.cpOption.reduceSameMatchEnabled()); ((DependencyPairContainer) pc).enableDirectlyStrictConfluent( this.cpOption.directlyStrictConflEnabled()); ((DependencyPairContainer) pc).enableDirectlyStrictConfluentUpToIso( this.cpOption.directlyStrictConflUpToIsoEnabled()); ((DependencyPairContainer) pc).enableNamedObjectOnly( this.cpOption.namedObjectEnabled()); ((DependencyPairContainer) pc).enableMaxBoundOfCriticCause( this.cpOption.getMaxBoundOfCriticCause()); return (DependencyPairContainer) pc; } @SuppressWarnings("deprecation") private SimpleExcludePair makeExcludePair() { final SimpleExcludePair pc = new SimpleExcludePair(); pc.enableNACs(this.cpOption.nacsEnabled()); pc.enablePACs(this.cpOption.pacsEnabled()); pc.enableReduce(this.cpOption.reduceEnabled()); pc.enableConsistent( this.cpOption.consistentEnabled(), this.gragra); pc.enableStrongAttrCheck(true); // cpOption.strongAttrCheckEnabled()); pc.enableEqualVariableNameOfAttrMapping( this.cpOption.equalVariableNameOfAttrMappingEnabled()); pc.enableIgnoreIdenticalRules( this.cpOption.ignoreIdenticalRulesEnabled()); pc.enableReduceSameMatch( this.cpOption.reduceSameMatchEnabled()); pc.enableDirectlyStrictConfluent(false); pc.enableDirectlyStrictConfluentUpToIso(false); pc.enableNamedObjectOnly(this.cpOption.namedObjectEnabled()); pc.setMaxBoundOfCriticCause(this.cpOption.getMaxBoundOfCriticCause()); return pc; } /* private boolean asymParallelIndependentByCPA( final ExcludePairContainer excludeContainer, final Rule r1, int indx_r1, final Rule r2, int indx_r2) { boolean result = false; try { if (!this.gragra.isLayered() || r1.getLayer() == r2.getLayer()) { // result = (excludeContainer.getCriticalPair(r1, r2, CriticalPair.CONFLICT, true) == null) ? true : false; final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> conflicts = excludeContainer.getCriticalPair(r1, r2, CriticalPair.CONFLICT, true); if (conflicts != null && !conflicts.isEmpty()) { result = false; for (int i=0; i<conflicts.size(); i++) { final Pair<OrdinaryMorphism, OrdinaryMorphism> pair = conflicts.get(i).first; if (this.ruleSequence.isObjectFlowActive()) { ObjectFlow objFlow = this.ruleSequence.getObjectFlowForRules(r1, indx_r1, r2, indx_r2); if (objFlow != null && !objFlow.isEmpty()) { boolean inside = false; final List<Object> inputs = objFlow.getInputs(); final Enumeration<GraphObject> objs = pair.second.getDomain(); while (objs.hasMoreElements() && !inside) { final GraphObject obj = objs.nextElement(); if (pair.first.getInverseImage(pair.second.getImage(obj)).hasMoreElements() && inputs.contains(obj)) { inside = true; } } if (!inside) { conflicts.remove(i); i--; // System.out.println("Conflict overlapping removed, because Object Flow outside of it."); } } } } } else { result = true; } } else { return true; } } catch (Exception ex) {} return result; } */ private boolean asymParallelIndependentByCPA( final ExcludePair excludePair, final Rule r1, int indx_r1, final Rule r2, int indx_r2) { boolean result = false; try { if (!this.gragra.isLayered() || r1.getLayer() == r2.getLayer()) { final Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> conflicts = excludePair.isCritical(CriticalPair.CONFLICT, r1, r2); if (conflicts != null && !conflicts.isEmpty()) { result = false; if (indx_r1 >=0 && indx_r1 >= 0) { for (int i=0; i<conflicts.size(); i++) { final Pair<OrdinaryMorphism, OrdinaryMorphism> pair = conflicts.get(i).first; if (this.ruleSequence.isObjFlowActive()) { ObjectFlow objFlow = this.ruleSequence.getObjFlowForRules(r1, indx_r1, r2, indx_r2); if (objFlow != null && !objFlow.isEmpty()) { boolean inside = false; final List<Object> inputs = objFlow.getInputs(); final Enumeration<GraphObject> objs = pair.second.getDomain(); while (objs.hasMoreElements() && !inside) { final GraphObject obj = objs.nextElement(); if (pair.first.getInverseImage(pair.second.getImage(obj)).hasMoreElements() && inputs.contains(obj)) { inside = true; } } if (!inside) { conflicts.remove(i); i--; // System.out.println("Conflict overlapping removed, because Object Flow outside of it."); } } } } } } else { result = true; } } else { result = true; } } catch (Exception ex) {} return result; } /* private boolean asymParallelIndependentByCPA(final Rule r1, final Rule r2, final Graph graph) { final CriticalRulePairAtGraph crp = new CriticalRulePairAtGraph(r1, r2, graph); // final Vector<Pair<Hashtable<GraphObject, GraphObject>, Hashtable<GraphObject, GraphObject>>> // crpResult = crp.isCriticalAtGraph(); return (crp.isCriticalAtGraph() == null); } */ /** * Check 4a. criterion of applicability : * for all r_i without NACs in sequence with 1<i<=n which are no applicable on graph g * via an injective match there exists a rule r_j in sequence with 1<=j<i<=n * and r_i is purely sequential dependent on r_j * (pure enabling predecessor) */ private boolean pureEnablingPredecessor( final Rule ri, final int i, final List<Rule> sequence, final Graph g) { boolean result = false; for (int j=0; j<i; j++) { final Rule rj = sequence.get(j); if ( (g != null && !checkForbiddenObjects(ri.getNACs(), rj, g)) || (g == null && !checkForbiddenObjects(ri.getNACs(), rj)) ) { if (purelySequentialDependent(rj, j, ri, i, g)) { result = true; System.out.println("=== >>> ApplicabilityChecker.pureEnablingPredecessor of rule: "+ri.getName() +" is rule: "+rj.getName()); // setRuleResult( i, ri.getName(), true, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, rj.getName()); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "pure"); break; } } } return result; } private boolean pureEnablingPredecessor( final Rule ri, final int i, final List<Rule> sequence) { boolean result = false; for (int j=0; j<i; j++) { final Rule rj = sequence.get(j); if (!checkForbiddenObjects(ri.getNACs(), rj)) { if (purelySequentialDependent(rj, j, ri, i, null)) { result = true; System.out.println("=== >>> ApplicabilityChecker.pureEnablingPredecessor of rule: "+ri.getName() +" is rule: "+rj.getName()); setRuleResult( i, ri.getName(), true, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, rj.getName()); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "pure"); break; } } } return result; } @SuppressWarnings("unused") private boolean enablingPredecessorApplicablePureConcurrent( int startIndx, final List<Rule> sequence, final Graph graph) { System.out.println("=== >>> ApplicabilityChecker.enablingPredecessorApplicablePureConcurrent" ); DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); String criterion = ""; boolean result = true; boolean noEnablingPredecessor = false; int start = (startIndx > 1) ? startIndx : 1; for (int i=start; i<sequence.size(); i++) { Rule ri = sequence.get(i); Rule ri_1 = sequence.get(i-1); criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, graph); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); noEnablingPredecessor = noEnablingPredecessor(sequence, i, ri, dependencyContainer); if (!noEnablingPredecessor) { criterion = ApplicabilityConstants.PURE_ENABLING_PREDECESSOR; result = this.pureEnablingPredecessor(ri, i, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR; result = this.partialEnablingPredecessor(ri, i, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; result = this.directEnablingPredecessor(i, ri, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); } } } } } setApplicabilityResult(result, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); } dependencyContainer.clear(); return result; } @SuppressWarnings("unused") private boolean enablingPredecessorApplicablePureConcurrent( int startIndx, final List<Rule> sequence) { System.out.println("=== >>> ApplicabilityChecker.enablingPredecessorApplicablePureConcurrent" ); DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); String criterion = ""; boolean result = true; boolean noEnablingPredecessor = false; int start = (startIndx > 1) ? startIndx : 1; for (int i=start; i<sequence.size(); i++) { Rule ri = sequence.get(i); Rule ri_1 = sequence.get(i-1); criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, null); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); noEnablingPredecessor = noEnablingPredecessor(sequence, i, ri, dependencyContainer); if (!noEnablingPredecessor) { criterion = ApplicabilityConstants.PURE_ENABLING_PREDECESSOR; result = this.pureEnablingPredecessor(ri, i, sequence); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR; result = this.partialEnablingPredecessor(ri, i, sequence, null); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; result = this.directEnablingPredecessor(i, ri, sequence, null); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); } } } } } setApplicabilityResult(result, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); } dependencyContainer.clear(); return result; } private boolean isRuleWithEmptyLHSApplicableAtGraph( final Rule r, int indx, final Graph g) { boolean result = false; if (r.getLeft().isEmpty()) { // String criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; if (this.isRuleApplicable(indx, r, g, true)) { result = true; System.out.println("=== >>> ApplicabilityChecker.isRuleWithEmptyLHSApplicableAtGraph: rule: "+r.getName()+" applicable"); setRuleResult(indx, r.getName(), true, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, "(applicable)"); setRuleResult(indx, r.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "(applicable)"); } else { result = false; this.nonApplicableRules.add(r); setRuleResult(indx, r.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); } } return result; } private boolean isPredecessorNotNeeded( final Rule r, int indx, final Graph g) { boolean result = false; result = this.isRuleApplicable(indx, r, g, true); if (result) { setRuleResult(indx, r.getName(), true, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, "(applicable)"); setRuleResult(indx, r.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "(applicable)"); } return result; } @SuppressWarnings("unused") private boolean enablingPredecessorPureConcurrentApplicable( int startIndx, final List<Rule> sequence, final Graph graph) { DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); boolean result = true; String criterion = ""; boolean noEnablingPredecessor = false; int start = (startIndx > 1) ? startIndx : 1; for (int i=start; i<sequence.size(); i++) { Rule ri = sequence.get(i); Rule ri_1 = sequence.get(i-1); System.out.println("=== >>>ApplicabilityChecker.enablingPredecessorPureConcurrentApplicable: check rule: "+ri.getName()); // extra case when LHS of the rule is empty criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = isRuleWithEmptyLHSApplicableAtGraph(ri, i, graph); if (!result) { // check is ri applicable in general (do not respect ObjectFlow) if (this.isNonApplicableRule(ri, graph)) { noEnablingPredecessor = noEnablingPredecessor(sequence, i, ri, dependencyContainer); } if (!noEnablingPredecessor) { criterion = ApplicabilityConstants.PURE_ENABLING_PREDECESSOR; result = this.pureEnablingPredecessor(ri, i, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR; result = this.partialEnablingPredecessor(ri, i, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; result = this.directEnablingPredecessor(i, ri, sequence, graph); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, graph); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); // rule ri is not applicable // and there are no enabling predecessors - // - this implies that sequence is not applicable! noEnablingPredecessor = true; setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); // setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); } } } } else { Pair<Boolean, List<String>> resPair = this.ruleSequence.getRuleResult(i, ri.getName(), ApplicabilityConstants.PURE_ENABLING_PREDECESSOR); if (resPair != null && !resPair.first.booleanValue()) { result = false; setRuleResult(i, ri.getName(), true, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ri_1.getName()); } } } else { criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, graph); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); // rule ri is not applicable // and there are no enabling predecessors - // - this implies that sequence is not applicable! noEnablingPredecessor = true; setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); } } } setApplicabilityResult(result, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); if (noEnablingPredecessor) { if (this.ruleSequence.getNonApplicabilityResult().first.booleanValue()) { break; } } } dependencyContainer.clear(); return result; } @SuppressWarnings("unused") private boolean enablingPredecessorPureConcurrentApplicable( int startIndx, final List<Rule> sequence) { DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); boolean result = true; String criterion = ""; boolean noEnablingPredecessor = false; int start = (startIndx > 1) ? startIndx : 1; for (int i=start; i<sequence.size(); i++) { Rule ri = sequence.get(i); Rule ri_1 = sequence.get(i-1); System.out.println("=== >>>ApplicabilityChecker.enablingPredecessorPureConcurrentApplicable: check rule: "+ri.getName()); // extra case when LHS of the rule is empty criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = isRuleWithEmptyLHSApplicableAtGraph(ri, i, null); if (!result) { noEnablingPredecessor = noEnablingPredecessor(sequence, i, ri, dependencyContainer); if (!noEnablingPredecessor) { criterion = ApplicabilityConstants.PURE_ENABLING_PREDECESSOR; result = this.pureEnablingPredecessor(ri, i, sequence, null); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR; result = this.partialEnablingPredecessor(ri, i, sequence, null); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; result = this.directEnablingPredecessor(i, ri, sequence, null); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, null); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); // rule ri is not applicable // and there are no enabling predecessors - // - this implies that sequence is not applicable! noEnablingPredecessor = true; setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); // setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); } } } } } else { criterion = ApplicabilityConstants.PREDECESSOR_NOT_NEEDED; result = this.isPredecessorNotNeeded(ri, i, null); if (!result) { this.nonApplicableRules.add(ri); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PREDECESSOR_NOT_NEEDED, ""); // rule ri is not applicable // and there are no enabling predecessors - // - this implies that sequence is not applicable! noEnablingPredecessor = true; setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); } } } setApplicabilityResult(result, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); if (noEnablingPredecessor) { if (this.ruleSequence.getNonApplicabilityResult().first.booleanValue()) { break; } } } dependencyContainer.clear(); return result; } public List<ConcurrentRule> buildPlainConcurrentRule(final List<Rule> seq, final Graph g) { if (seq.size()<=1 || BaseFactory.theFactory().checkApplCondsOfRules(seq) != null) { return null; } List<ConcurrentRule> crs = new Vector<ConcurrentRule>(1); for (int i=1; i<seq.size(); i++) { Rule ri = seq.get(i); int preI = i-1; Rule preR = seq.get(preI); List<List<ConcurrentRule>> concurRuleListsOfRule = this.getListsOfConcurrentRulesOfRule(ri, i); if (concurRuleListsOfRule == null) { concurRuleListsOfRule = new Vector<List<ConcurrentRule>> (); this.ruleSequence.putListsOfConcurrentRules(ri, i, concurRuleListsOfRule); } List<ConcurrentRule> list = null; if (i==1) { list = this.makeConcurrentRulesDuetoDependency(preR, preI, ri, i, null); concurRuleListsOfRule.add(list); } else { if (this.getListsOfConcurrentRulesOfRule(preR, preI) != null) { List<ConcurrentRule> listOfPreRule = this.getListsOfConcurrentRulesOfRule(preR, preI).get(0); list = new Vector<ConcurrentRule>(); for (int c=0; c<listOfPreRule.size(); c++) { ConcurrentRule cr = listOfPreRule.get(c); list.addAll(this.makeConcurrentRulesDuetoDependency(cr, ri, null)); } concurRuleListsOfRule.add(list); } } if (list != null && !list.isEmpty()) { crs.clear(); crs.addAll(list); System.out.println( "=== >>> ApplicabilityChecker.buildPlainConcurrentRule:: "+list.get(0).getRule().getName()); } } return crs; } /* private boolean enablingPredecessor( int startIndx, final List<Rule> sequence) { Graph graph = null; DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); String criterion = ""; boolean result = true; boolean noEnablingPredecessor = false; int start = (startIndx > 1) ? startIndx : 1; for (int i=start; i<sequence.size(); i++) { Rule ri = sequence.get(i); Rule ri_1 = sequence.get(i-1); // System.out.println("=== >>> ApplicabilityChecker.enablingPredecessor of "+ri.getName()); criterion = ApplicabilityConstants.PURE_ENABLING_PREDECESSOR; result = this.pureEnablingPredecessor(ri, i, sequence); if (!result) { setRuleResult(i, ri.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, ""); criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; result = this.directEnablingPredecessor(i, ri, sequence, graph); if (!result) { criterion = ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); } noEnablingPredecessor = noEnablingPredecessor(sequence, i, ri, dependencyContainer); } setApplicabilityResult(result, ApplicabilityConstants.ENABLING_PREDECESSOR); setNonApplicabilityResult(noEnablingPredecessor, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); } dependencyContainer.clear(); return result; } private List<Rule> getPotentialEnablingPredecessor( final List<Rule> sequence, final int i, final Rule ri, final DependencyPairContainer dependencyContainer) { final List<Rule> list = new Vector<Rule>(); dependencyContainer.enableProduceConcurrentRule(false); dependencyContainer.enableComplete(false); Rule r = null; for (int j=0; j<i; j++) { Rule rj = sequence.get(j); try { if (dependencyContainer.getCriticalPair(rj, ri, CriticalPair.EXCLUDE, true) != null) { r = rj; break; } } catch (Exception ex) {} } dependencyContainer.enableComplete(true); return list; } private boolean anyEnablingPredecessor( final List<Rule> sequence, final int i, final Rule ri, final DependencyPairContainer dependencyContainer) { dependencyContainer.enableProduceConcurrentRule(false); dependencyContainer.enableComplete(false); boolean result = false; for (int j=0; j<i; j++) { Rule rj = sequence.get(j); try { if (dependencyContainer.getCriticalPair(rj, ri, CriticalPair.EXCLUDE, true) != null) { result = true; break; } } catch (Exception ex) {} } dependencyContainer.enableComplete(true); return result; } */ private Rule getFirstEnablingPredecessor( final List<Rule> sequence, final int i, final Rule ri, final DependencyPairContainer dependencyContainer) { dependencyContainer.enableProduceConcurrentRule(false); dependencyContainer.enableComplete(false); Rule r = null; for (int j=0; j<i; j++) { Rule rj = sequence.get(j); try { if (dependencyContainer.getCriticalPair(rj, ri, CriticalPair.EXCLUDE, true) != null) { r = rj; break; } } catch (Exception ex) {} } dependencyContainer.enableComplete(true); return r; } /* private boolean noEnablingPredecessor( final List<Rule> sequence, final int i, final Rule ri, final Rule enablingRule) { boolean result = false; info = ""; if (enablingRule != null) { info = enablingRule.getName(); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, info); } else { result = true; setNonApplicabilityResult(true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); } return result; } */ private boolean noEnablingPredecessor( final List<Rule> sequence, final int i, final Rule ri, final DependencyPairContainer dependencyContainer) { boolean result = false; this.info = ""; Rule enablingRule = this.getFirstEnablingPredecessor(sequence, i, ri, dependencyContainer); if (enablingRule != null) { // info = enablingRule.getName(); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, this.info); } else { result = true; setNonApplicabilityResult(true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR); setRuleResult(i, ri.getName(), true, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, ""); } return result; } private boolean purelySequentialDependent( final Rule r1, int indx_r1, final Rule r2, int indx_r2, Graph g) { // r1.getRight().setNotificationRequired(false); // zu testen!!! final Match embedding = BaseFactory.theFactory().createMatch(r2, r1.getRight()); embedding.setCompletionStrategy(this.strategy, true); boolean result = false; while (embedding.nextCompletionWithConstantsChecking() && !result) { Enumeration<GraphObject> codom = embedding.getCodomain(); // exist l21 : L2 -> R1 while (codom.hasMoreElements()) { GraphObject obj = codom.nextElement(); // rule r1 produce at least one object which is used in LHS of r2 if (!r1.getInverseImage(obj).hasMoreElements()) { result = true; if (this.ruleSequence.isObjFlowActive()) { final ObjectFlow objFlow = this.ruleSequence.getObjFlowForRules(r1, indx_r1, r2, indx_r2); if (objFlow != null && !objFlow.isEmpty()) result = pureEnablingAlongObjectFlow(embedding, objFlow); } // add match to matchSequence if (result) this.ruleSequence.getMatchSequence().addTotalPureEnablingSourceMatch(r2, r1, embedding, indx_r2, indx_r1); break; } } if (result) { boolean attrCondUsesIP = attrConditionUsesInputParameterRight(r2, r1, embedding); if (attrCondUsesIP) { setRuleResult(indx_r2, r2.getName(), false, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, r1.getName()); } else { setRuleResult(indx_r2, r2.getName(), true, ApplicabilityConstants.PURE_ENABLING_PREDECESSOR, r1.getName()); } } // TODO: apply r1, then r2 along the comatch of r2 to check NACs of r2 // result = isPurelyEnabledRuleApplicable(r1, r2, embedding, g); // if (result) { // // to test : add match to matchSequence // this.ruleSequence.getMatchSequence().addTotalPureEnablingSourceOfMatch(r2, r1, embedding, indx_r2, indx_r1); // } } embedding.dispose(); BaseFactory.theFactory().unsetAllTransientAttrValuesOfRule(r1); // r1.getRight().setNotificationRequired(true); return result; } private boolean attrConditionUsesInputParameterRight( final Rule ruleAC, final Rule preRuleIP, final Match ruleLHS2preRuleRHS) { if (ruleAC.getAttrContext().getConditions().getNumberOfEntries() > 0 && ((VarTuple)preRuleIP.getAttrContext().getVariables()).hasInputParameter()) { List<String> inputParams = preRuleIP.getInputParameterNames(); // find object with IP in the RHS of preRuleWithInputParam List<GraphObject> goIP = preRuleIP.getInputParameterObjectsRight(inputParams); // collect objects with variable of the conditions of ruleAC Vector<String> varsAC = ((CondTuple) ruleAC.getAttrContext().getConditions()).getAllVariables(); List<GraphObject> goAC = new Vector<GraphObject>(); // find LHS object with variable of the conditions of ruleAC addObjsWithVarOfCond(ruleAC.getLeft(), varsAC, null, goAC); // find PAC object with variable in the conditions of ruleAC Enumeration<OrdinaryMorphism> morphs = ruleAC.getPACs(); while (morphs.hasMoreElements()) { OrdinaryMorphism morph = morphs.nextElement(); addObjsWithVarOfCond(morph.getTarget(), varsAC, morph, goAC); } // find NAC object with variable in the conditions of ruleAC morphs = ruleAC.getNACs(); while (morphs.hasMoreElements()) { OrdinaryMorphism morph = morphs.nextElement(); addObjsWithVarOfCond(morph.getTarget(), varsAC, morph, goAC); } Enumeration<GraphObject> dom = ruleLHS2preRuleRHS.getDomain(); while (dom.hasMoreElements()) { GraphObject go_ac = dom.nextElement(); GraphObject go_ip = ruleLHS2preRuleRHS.getImage(go_ac); if (goAC.contains(go_ac) && goIP.contains(go_ip)) { return true; } } } return false; } /* private boolean attrConditionUsesInputParameter(final Rule rule, final Match m) { if (rule.getAttrContext().getConditions().getNumberOfEntries() > 0 && ((VarTuple)rule.getAttrContext().getVariables()).hasInputParameter()) { List<String> inputParams = rule.getInputParameterNames(); // find object with IP List<GraphObject> goIPleft = rule.getInputParameterObjectsLeft(inputParams); List<GraphObject> goIPright = rule.getInputParameterObjectsRight(inputParams); // collect objects with variable of the conditions of rule Vector<String> varsAC = ((CondTuple) rule.getAttrContext().getConditions()).getAllVariables(); List<GraphObject> goAC = new Vector<GraphObject>(); // find LHS object with variable of conditions of rule addObjsWithVarOfCond(rule.getLeft(), varsAC, null, goAC); // find PAC object with variable in conditions of rule Enumeration<OrdinaryMorphism> morphs = rule.getPACs(); while (morphs.hasMoreElements()) { OrdinaryMorphism morph = morphs.nextElement(); addObjsWithVarOfCond(morph.getTarget(), varsAC, morph, goAC); } // find NAC object with variable in the conditions of ruleAC morphs = rule.getNACs(); while (morphs.hasMoreElements()) { OrdinaryMorphism morph = morphs.nextElement(); addObjsWithVarOfCond(morph.getTarget(), varsAC, morph, goAC); } Enumeration<GraphObject> dom = m.getDomain(); while (dom.hasMoreElements()) { GraphObject go = dom.nextElement(); if (goAC.contains(go) && goIPleft.contains(go)) { return true; } } Iterator<?> iter = rule.getRight().getNodesSet().iterator(); while (iter.hasNext()) { GraphObject go = (GraphObject) iter.next(); if (goAC.contains(go) && goIPright.contains(go)) { return true; } } iter = rule.getRight().getArcsSet().iterator(); while (iter.hasNext()) { GraphObject go = (GraphObject) iter.next(); if (goAC.contains(go) && goIPright.contains(go)) { return true; } } } return false; } */ private boolean usingAttrConditionAndInputParameter(final Rule rule, final Match m) { if (rule.getAttrContext().getConditions().getNumberOfEntries() > 0 && ((VarTuple)rule.getAttrContext().getVariables()).hasInputParameter()) return true; return false; } private void addObjsWithVarOfCond(final Graph g, final List<String> vars, final OrdinaryMorphism morph, final List<GraphObject> list) { addGOsWithVarOfCond(g.getNodesSet().iterator(), vars, morph, list); addGOsWithVarOfCond(g.getArcsSet().iterator(), vars, morph, list); } private void addGOsWithVarOfCond(final Iterator<?> iter, final List<String> vars, final OrdinaryMorphism morph, final List<GraphObject> list) { while (iter.hasNext()) { GraphObject go = (GraphObject)iter.next(); if (go.getAttribute() != null) { ValueTuple val = (ValueTuple)go.getAttribute(); for (int i=0; i<val.getNumberOfEntries(); i++) { ValueMember mem = val.getEntryAt(i); if (mem.isSet() && mem.getExpr().isVariable()) { if (vars.contains(mem.getExprAsText())) { if (morph == null) { if (!list.contains(go)) list.add(go); } else if (morph.getInverseImage(go).hasMoreElements()) { GraphObject go1 = morph.getInverseImage(go).nextElement(); if (!list.contains(go1)) list.add(go1); } } } } } } } private boolean pureEnablingAlongObjectFlow( final OrdinaryMorphism morph, final ObjectFlow objFlow) { Enumeration<Object> outs = objFlow.getMapping().keys(); while (outs.hasMoreElements()) { Object out = outs.nextElement(); Object in = objFlow.getMapping().get(out); GraphObject img = morph.getImage((GraphObject)in); if (img != null && img != out) { return false; } } return true; } /* private boolean checkForbiddenObjects( final Rule rule, final List<Rule> predecessors, final Graph g) { boolean noObj = true; List<GraphObject> toCreate = null; for (int r=0; r<predecessors.size(); r++) { final Rule prerule = predecessors.get(r); toCreate = prerule.getElementsToCreate(); noObj = !toCreate.isEmpty(); Enumeration<OrdinaryMorphism> nacs = rule.getNACs(); while (nacs.hasMoreElements() && noObj) { OrdinaryMorphism nac = nacs.nextElement(); noObj = doCheckForbiddenObjs(nac, toCreate, nac.getTarget().getNodesSet().iterator()) || doCheckForbiddenObjs(nac, toCreate, nac.getTarget().getArcsSet().iterator()); } } if (noObj) { // check graph Enumeration<OrdinaryMorphism> nacs = rule.getNACs(); while (nacs.hasMoreElements() && noObj) { OrdinaryMorphism nac = nacs.nextElement(); noObj = doCheckForbiddenObjsAtGraph(nac.getTarget().getNodesSet().iterator(), g) || doCheckForbiddenObjsAtGraph(nac.getTarget().getArcsSet().iterator(), g); } } return !noObj; } private boolean doCheckForbiddenObjsAtGraph( final Iterator<?> elems, final Graph g) { boolean noObj = true; while (elems.hasNext() && noObj) { GraphObject elem = (GraphObject) elems.next(); if (elem.isNode()) { String key = ((Node) elem).convertToKey(); if (g.getTypeObjectsMap().get(key) != null && !g.getTypeObjectsMap().get(key).isEmpty()) { noObj = false; // System.out.println(" Graph: "+g.getName()+" contains forbidden object of type: "+t.getName()); } } else { String key = ((Arc) elem).convertToKey(); if (g.getTypeObjectsMap().get(key) != null && !g.getTypeObjectsMap().get(key).isEmpty()) { noObj = false; // System.out.println(" Graph: "+g.getName()+" contains forbidden object of type: "+t.getName()); } } } return noObj; } */ /** * Returns true if the specified rule r produces an object * which is forbidden from the specified Negative Application Conditions nacs * of an other rule * or it is already preserved in the specified graph g. * Otherwise false. */ private boolean checkForbiddenObjects( final Enumeration<OrdinaryMorphism> nacs, final Rule r, final Graph g) { final List<GraphObject> toCreate = r.getElementsToCreate(); boolean found = false; while (nacs.hasMoreElements() && !found) { OrdinaryMorphism nac = nacs.nextElement(); found = checkForbiddenObjs(nac, g, nac.getTarget().getNodesSet().iterator(), toCreate) || checkForbiddenObjs( nac, g, nac.getTarget().getArcsSet().iterator(), toCreate); } return found; } /** * Returns true if the specified graph object to create * which is forbidden from the specified Negative Application Condition nac * of an other rule * or it is already preserved in the specified graph g. * Otherwise false. */ private boolean checkForbiddenObjs( final OrdinaryMorphism nac, final Graph g, final Iterator<?> iter, final List<GraphObject> toCreate) { boolean found = false; while (iter.hasNext()) { GraphObject elem = (GraphObject) iter.next(); if (!nac.getInverseImage(elem).hasMoreElements()) { Type t = elem.getType(); // check RHS of rule for (int i=0; i<toCreate.size(); i++) { GraphObject newgo = toCreate.get(i); if (elem.isNode()) { if (t.isParentOf(newgo.getType())) { found = true; break; } } else { if (t == newgo.getType() && ((Arc)elem).getSource().getType().isParentOf(((Arc)newgo).getSource().getType()) && ((Arc)elem).getTarget().getType().isParentOf(((Arc)newgo).getTarget().getType())) { found = true; break; } } } if (!found) { // check graph Hashtable<String, HashSet<GraphObject>> type2objects = g.getTypeObjectsMap(); if (elem.isNode()) { String key = elem.convertToKey(); if (type2objects.get(key) != null && !type2objects.get(key).isEmpty()) { found = true; } } else { String key = ((Arc) elem).convertToKey(); if (type2objects.get(key) != null && !type2objects.get(key).isEmpty()) { found = true; } } } } } return found; } /** * Returns true if the specified rule r produces an object * which is forbidden from the specified Negative Application Conditions nacs * of an other rule. * Otherwise false. */ private boolean checkForbiddenObjects( final Enumeration<OrdinaryMorphism> nacs, final Rule r) { final List<GraphObject> toCreate = r.getElementsToCreate(); boolean found = false; while (nacs.hasMoreElements() && !found) { OrdinaryMorphism nac = nacs.nextElement(); found = doCheckForbiddenObjs(nac, toCreate, nac.getTarget().getNodesSet().iterator()) || doCheckForbiddenObjs(nac, toCreate, nac.getTarget().getArcsSet().iterator()); } return found; } private boolean doCheckForbiddenObjs( final OrdinaryMorphism nac, final List<GraphObject> toCreate, final Iterator<?> elems) { boolean noObj = !toCreate.isEmpty(); while (elems.hasNext()) { GraphObject elem = (GraphObject) elems.next(); if (!nac.getInverseImage(elem).hasMoreElements()) { Type t = elem.getType(); // check new objects of rule for (int i=0; i<toCreate.size(); i++) { if (t.isParentOf(toCreate.get(i).getType())) { noObj = false; // System.out.println(" Rule: "+r.getName()+" produces forbidden object of type: "+t.getName()); break; } } } } return !noObj; } /* private boolean doCheckNACGraphContextOnGraph( final Enumeration<OrdinaryMorphism> nacs, final Graph g) { // System.out.println("doCheckNACGraphContextOnGraph.... "); boolean nacResult = true; while (nacs.hasMoreElements() && nacResult) { OrdinaryMorphism nac = nacs.nextElement(); OrdinaryMorphism nacIso = nac.getTarget().isomorphicCopy(); Graph contextGraph = nacIso.getTarget(); // remove mapped edge/node from context Enumeration<GraphObject> codom = nac.getCodomain(); while (codom.hasMoreElements()) { GraphObject obj = codom.nextElement(); if (obj.isArc()) { try { contextGraph.destroyArc((Arc)nacIso.getImage(obj), false, true); } catch (Exception ex) { // System.out.println(ex.getStackTrace()); } } } codom = nac.getCodomain(); while (codom.hasMoreElements()) { GraphObject obj = codom.nextElement(); if (obj.isNode() && ((Node) obj).isIsolated()) { try { contextGraph.destroyNode((Node)nacIso.getImage(obj), false, true); } catch (Exception ex) { // System.out.println(ex.getStackTrace()); } } } // make embedding emb: context -> g OrdinaryMorphism emb = BaseFactory.theFactory().createMorphism(contextGraph, g); emb.addToAttrContext((CondTuple) nac.getAttrContext().getConditions()); emb.setCompletionStrategy(this.strategy, true); nacResult = false; while (emb.nextCompletionWithConstantsChecking()) { nacResult = true; // check attr conditions CondTuple conds = (CondTuple) emb.getAttrContext().getConditions(); for (int i=0; i<conds.getSize(); i++) { CondMember cond = conds.getCondMemberAt(i); // System.out.println(cond.toString()+" "+cond.getMark()); } if (conds.isDefinite() && !conds.isTrue()) { nacResult = false; } else { // System.out.println("---> NAC: "+nac.getName() +" found in graph"); break; } } emb.dispose(); nacIso.dispose(false, true); } return !nacResult; } */ /** * Check 4c. (direct enabling predecessor) criterion of applicability : * there exists a concurrent rule r_c of r_i-1 and r_i such that r_c is applicable * via an injective match on graph g and r_c is asymmetrically parallel independent * on r_j for all j<(i-1) and r_j is asymmetrically parallel independent * on r_c for all i<j<=n. */ private boolean directEnablingPredecessor( final int i, final Rule ri, final List<Rule> sequence, final Graph g) { boolean result = false; Rule ri_1 = sequence.get(i-1); if (ri_1 != null) { this.info = ri_1.getName(); // get already existing or new list of concurrent rules of the current rule ri // OLD part, TODO: refactoring List<List<ConcurrentRule>> concurRuleLists = this.ruleSequence.getListsOfConcurrentRules(ri, i); if (concurRuleLists == null) { concurRuleLists = new Vector<List<ConcurrentRule>> (); this.ruleSequence.putListsOfConcurrentRules(ri, i, concurRuleLists); } //test this.completeConcurRuleBackward = this.ruleSequence.isObjFlowActive(); // System.out.println(ri.getName()+" completeConcurRuleBackward: "+completeConcurRuleBackward); if (this.completeConcurRuleBackward) { result = this.buildConcurrentRulesBackward(ri_1, i-1, ri, i, g); } else { result = this.buildConcurrentRulesForward(ri_1, i-1, ri, i, g); // if (!result) { // result = this.buildPlainConcurrentRule(sequence, g); // } } } if (result) { System.out.println("=== >>> ApplicabilityChecker.directEnablingPredecessor: of rule: "+ri.getName()+" is rule: "+this.info); setRuleResult(i, ri.getName(), true, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, this.info); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "(direct)"); } return result; } /** * Check 4b. (partial enabling predecessor) criterion of applicability : * there exists a concurrent rule r_c of a not necessarily direct predecessor rule r * and r_i such that r_c is applicable to graph g * and all predecessors of r_c do not cause a conflict with r_c. * Moreover, r is self-enabled such that its match can be forwarded * to the match of r_c. */ private boolean partialEnablingPredecessor( final Rule ri, final int i, final List<Rule> sequence, final Graph g) { // System.out.println("\n=== >>> ApplicabilityChecker.partialEnablingPredecessor ... of "+ri.getName()); boolean result = false; for (int j=i-1; j>=0; j--) { Rule rj = sequence.get(j); this.info = rj.getName(); Pair<Boolean, List<String>> pair = this.ruleSequence.getRuleResult(j, rj.getName(), ApplicabilityConstants.PREDECESSOR_NOT_NEEDED); if (pair == null) pair = this.ruleSequence.getRuleResult(j, rj.getName(), ApplicabilityConstants.INITIALIZATION); if (pair != null && pair.first.booleanValue()) { // System.out.println("=== >>> ApplicabilityChecker.partialEnablingPredecessor :: applicable: "+rj.getName()); // rule rj is applicable to graph g // get new list of concurrent rules of the current rule ri List<List<ConcurrentRule>> concurRuleLists = this.ruleSequence.getListsOfConcurrentRules(ri, i); if (concurRuleLists == null) { concurRuleLists = new Vector<List<ConcurrentRule>> (); this.ruleSequence.putListsOfConcurrentRules(ri, i, concurRuleLists); } // make concurrent rule(s) due to dependency pair overlapping List<ConcurrentRule> list = this.makeJointlyConcurrentRule(rj, j, ri, i); if (list != null && !list.isEmpty()) { concurRuleLists.add(list); int d = 1; // set match of concurrent rule, (check due to ObjectFlow?) final Hashtable<GraphObject, GraphObject> rjMatch = this.ruleSequence.getMatchSequence().getDirectMatch(j, rj); if (rjMatch != null) { for (int c=0; c<list.size(); c++) { final ConcurrentRule cr = list.get(c); if (!rjMatch.isEmpty() && !cr.forwardMatchMappingOfFirstSourceRule(rjMatch, this.ruleSequence.getGraph())) { list.remove(c); c--; } } for (int k = 0; k<list.size(); k++) { ConcurrentRule cr = list.get(k); if (isConcurrentRuleApplicable(i, ri, this.ruleSequence.getRules(), g, cr, d, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR)) { result = true; System.out.println("=== >>> ApplicabilityChecker.partialEnablingPredecessor: of rule: "+ri.getName()+" is rule: "+rj.getName()); break; } } if (result) break; } } } } if (result) { setRuleResult(i, ri.getName(), true, ApplicabilityConstants.PARTIAL_ENABLING_PREDECESSOR, this.info); // setRuleResult(i, ri.getName(), true, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, "(partial)"); } return result; } // private boolean isConcurrentRuleApplicableWithoutConflicts( // final int i, // final Rule ri, // final List<Rule> sequence, // final Graph g, // final List<Rule> concurRules) { // System.out.println("---> ApplicabilityChecker.isConcurrentRuleApplicableWithoutConflicts... :: of "+ri.getName()); // ExcludePair excludePair = null; // boolean result = false; // for (int k = 0; k<concurRules.size() && !result; k++) { // Rule cr = concurRules.get(k); // System.out.println("---> applicability of Concurrent rule: "+cr.getName()); // result = true; // // if (cr.isApplicable(g, this.gragraStrategy, false)) { // // Vector<Rule> tmp = new Vector<Rule>(); // tmp.addAll(sequence); // tmp.remove(i); // tmp.remove(i-1); // tmp.add(i-1, cr); // int c = tmp.indexOf(cr); // // // find conflicts of concurrent rule with rules before // for (int j=0; j<c; j++) { // Rule rj = tmp.get(j); // excludePair = this.makeExcludePair(); // if(!asymParallelIndependentByCPA(excludePair, rj, cr)) { // result = false; //// info = cr.getName(); // System.out.println("---> Concurrent rule: "+cr.getName()+" has conflicts!"); // break; // } // excludePair.dispose(); // } // if (result) { // // find conflicts of concurrent rule with rules after // for (int l=c+1; l<tmp.size(); l++) { // Rule rj = tmp.get(l); // excludePair = this.makeExcludePair(); // if (!asymParallelIndependentByCPA(excludePair, cr, rj)) { // result = false; //// info = cr.getName(); // System.out.println("---> Concurrent rule: "+cr.getName()+" has conflicts!"); // break; // } // excludePair.dispose(); // } // if (result) { // info = cr.getName(); // setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, info); // setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, info); // System.out.println("---> Concurrent rule: "+cr.getName()+" is applicable without conflicts!"); // applicableConcurrentRules.add(cr); // break; // } // // } // tmp.clear(); // } else { // result = false; // System.out.println("---> Concurrent rule: "+cr.getName()+" is not applicable!"); // } // } // // return result; // } /** * Checks applicability of an concurrent rule at given Graph g. * Additionaly, for an applicable concurrent rule check * whether it produces conflicts with other rules or not. * * @return true, if at least one concurrent rule is applicable, otherwise false */ private boolean isConcurrentRuleApplicable( final int i, final Rule ri, final List<Rule> sequence, final Graph g, final ConcurrentRule cr, final int concurdepth, String criterion) { boolean result = false; if (g == null || this.isRuleApplicable(ri, cr, g, false)) { this.applicableConcurrentRules.add(cr); result = true; System.out.println("=== >>> Concurrent rule: "+cr.getRule().getName()+" applicable"); // check whether an applicable concurrent rule produces conflicts with other rules if (this.completeCPA) { // result = concurrentRuleAsymParallelIndependentByCPA(i, ri, cr, sequence, concurdepth, criterion); } else { // result = concurrentRuleAsymParallelIndependent(i, ri, cr, sequence, concurdepth, criterion); } } return result; } private boolean concurrentRuleAsymParallelIndependent( final int i, final Rule ri, final ConcurrentRule cr, final List<Rule> sequence, final int concurdepth, String criterion) { // System.out.println("\n=== >>> concurrentRuleAsymParallelIndependent: check conflicts of its base rules... cr.depth: "+ // cr.getRule().getName()+" depth: "+cr.getDepth()); boolean result = true; int concurrrentRuleDepth = cr.getDepth(); Vector<Rule> remainList = new Vector<Rule>(); for (int l=i+1; l<sequence.size(); l++) { remainList.add(sequence.get(l)); } Vector<Rule> crSourceList = new Vector<Rule>(); int start = i-concurrrentRuleDepth; for (int l=start; l<=i; l++) { crSourceList.add(sequence.get(l)); } // find conflicts of concurrent rule with rules before for (int l = 0; l<crSourceList.size(); l++) { Rule r = crSourceList.get(l); int indx = start + l; Pair<Boolean, List<String>> ruleRes = this.ruleSequence.getRuleResult(indx, r.getName(), ApplicabilityConstants.NO_IMPEDING_PREDECESSORS); if (ruleRes != null && !ruleRes.first.booleanValue()) { result = false; // String otherRule = ruleRes.second.isEmpty()? "": ruleRes.second.get(0); // System.out.println("---> Concurrent rule: "+cr.getRule().getName()+": its base rule: "+r.getName()+" has conflict with " +otherRule); break; } } if (result) { // find conflicts of concurrent rule with successor rules for (int l = 0; l<crSourceList.size(); l++) { Rule r1 = crSourceList.get(l); for (int k=0; k<remainList.size(); k++) { Rule r2 = remainList.get(k); SimpleExcludePair excludePair = this.makeExcludePair(); if (!asymParallelIndependentByCPA(excludePair, r1, -1, r2, -1)) { result = false; // System.out.println("---> Concurrent rule: "+cr.getRule().getName()+": its base rule: "+r1.getName()+" has conflict with " +r2.getName()); break; } excludePair.dispose(); } if (!result) { break; } } } this.info = this.getConcurrentRuleNameInfo(cr.getRule(), ri); setRuleResult(i, ri.getName(), result, criterion, this.info); remainList.clear(); crSourceList.clear(); return result; } private boolean concurrentRuleAsymParallelIndependentByCPA( final int i, final Rule ri, final ConcurrentRule cr, final List<Rule> sequence, final int concurdepth, String criterion) { // System.out.println("=== >>> concurrentRuleAsymParallelIndependentByCPA: check conflicts of concurrent rule..."); boolean result = true; Vector<Rule> tmp = new Vector<Rule>(); tmp.addAll(sequence); int n = 0; while (concurdepth-n >= 0) { tmp.remove(i-n); n++; } if ((i-n) < 0) { tmp.add(0, cr.getRule()); } else { tmp.add(i-n, cr.getRule()); } int c = tmp.indexOf(cr.getRule()); // find conflicts of concurrent rule with rules before for (int j=0; j<c; j++) { final Rule rj = tmp.get(j); final SimpleExcludePair excludePair = this.makeExcludePair(); if(!asymParallelIndependentByCPA(excludePair, rj, -1, cr.getRule(), -1)) { result = false; // System.out.println("---> Concurrent rule: "+cr.getRule().getName()+" has conflict with " +rj.getName()); break; } excludePair.dispose(); } if (result) { // find conflicts of concurrent rule with successor rules for (int l=c+1; l<tmp.size(); l++) { final Rule rj = tmp.get(l); final SimpleExcludePair excludePair = this.makeExcludePair(); if (!asymParallelIndependentByCPA(excludePair, cr.getRule(), -1, rj, -1)) { result = false; // System.out.println("---> Concurrent rule: "+cr.getRule().getName()+" has conflict with " +rj.getName()); break; } excludePair.dispose(); } } this.info = this.getConcurrentRuleNameInfo(cr.getRule(), ri); setRuleResult(i, ri.getName(), result, criterion, this.info); // System.out.println("=== >>> Concurrent rule: "+cr.getRule().getName()+" is applicable without conflicts!"); tmp.clear(); return result; } /* private boolean directEnablingPredecessor( final Rule ri, final Rule concurrentRule, final List<Rule> sequence, final Graph g) { System.out.println("---> ApplicabilityChecker.directEnablingPredecessor ... of "+concurrentRule.getName()); ExcludePair excludePair = null; boolean result = true; int i = sequence.indexOf(ri); if (i-1 < 0) { result = false; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); return result; } Rule ri_1 = sequence.get(i-1); String info = ri_1.getName(); List<Rule> cRules = makeConcurrentRules(ri_1, concurrentRule); if (cRules != null) { this.concurrentRules.addAll(cRules); for (int k = 0; k<cRules.size(); k++) { Rule cr = cRules.get(k); System.out.println("---> Concurrent rule: "+cr.getName()); if (cr.isApplicable(g, strategy, false)) { Vector<Rule> tmp = new Vector<Rule>(); tmp.addAll(sequence); tmp.add(i, cr); tmp.remove(i-1); tmp.remove(i); int c = tmp.indexOf(cr); // find conflicts of concurrent rule with rules before for (int j=0; j<c; j++) { Rule rj = tmp.get(j); excludePair = this.makeExcludePair(); if(!asymParallelIndependentByCPA(excludePair, rj, cr)) { result = false; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, rj.getName()); System.out.println("---> Concurrent rule: "+cr.getName()+" has conflicts!"); break; } excludePair.dispose(); } if (result) { // find conflicts of concurrent rule with rules after for (int l=c+1; l<tmp.size(); l++) { Rule rj = tmp.get(l); excludePair = this.makeExcludePair(); if (!asymParallelIndependentByCPA(excludePair, cr, rj)) { result = false; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, rj.getName()); System.out.println("---> Concurrent rule: "+cr.getName()+" has conflicts!"); break; } excludePair.dispose(); } if (result) { setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, info); setRuleResult(i, ri.getName(), false, ApplicabilityConstants.NO_ENABLING_PREDECESSOR, info); applicableConcurrentRules.add(cr); break; } } tmp.clear(); } else { result = false; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); System.out.println("---> Concurrent rule: "+cr.getName()+" is not applicable!"); } } } else { result = false; setRuleResult(i, ri.getName(), result, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR, ""); } return result; } private boolean checkConcurrentRuleAsPredecessor( final int i, final Rule ri, List<Rule> applicableConcurRules, final Graph graph) { List<Rule> concurRules = new Vector<Rule>(applicableConcurRules); boolean result = this.pureEnablingPredecessorAsConcurrentRule(i, ri, concurRules, graph); return result; } */ private String getConcurrentRuleNameInfo(final Rule concurRule, final Rule rule) { String name = concurRule.getName(); int pos = name.indexOf(rule.getName()); if (pos > 0) { name = name.substring(0, pos-1); } return name; } private List<List<ConcurrentRule>> getListsOfConcurrentRulesOfRule( final Rule r, final int indx) { return this.ruleSequence.getListsOfConcurrentRules(r, indx); } private List<ConcurrentRule> getConcurrentRulesOfRule( final Rule r, final int indx, final int listIndx) { List<List<ConcurrentRule>> lists = this.ruleSequence.getListsOfConcurrentRules(r, indx); if (lists == null) { lists = new Vector<List<ConcurrentRule>>(); this.ruleSequence.putListsOfConcurrentRules(r, indx, lists); return null; } else if (listIndx < lists.size()) { return lists.get(listIndx); } else { return null; } } private boolean completeConcurrentRules( final Rule r, final int rIndx, final List<List<ConcurrentRule>> crsOfRule, final int listIndx, final Hashtable<?, ?> matchmap) { // System.out.println("=== >>> ApplicabilityChecker.completeConcurrentRules: of "+r.getName()); boolean res = false; if (listIndx >= crsOfRule.size()) { int x = listIndx; int preIndx = rIndx-1; Rule preRule = this.ruleSequence.getRule(preIndx); if (x == 0) { List<ConcurrentRule> list = this.makeConcurrentRulesDuetoDependency(preRule, preIndx, r, rIndx, matchmap); crsOfRule.add(list); res = true; } else { List<ConcurrentRule> crListOfPreRule = this.getConcurrentRulesOfRule(preRule, preIndx, x-1); if (crListOfPreRule == null || crListOfPreRule.isEmpty()) { // create a new list of lists to fill final List<List<ConcurrentRule>> conRuleListsOfPreRule = this.getListsOfConcurrentRulesOfRule(preRule, preIndx); // put this list to fill this.completeConcurrentRules(preRule, rIndx-1, conRuleListsOfPreRule, x-1, matchmap); // get the (x-1) list crListOfPreRule = this.getConcurrentRulesOfRule(preRule, preIndx, x-1); } if (crListOfPreRule != null) { final List<ConcurrentRule> list = new Vector<ConcurrentRule>(); for (int c=0; c<crListOfPreRule.size(); c++) { final ConcurrentRule cr = crListOfPreRule.get(c); list.addAll(this.makeConcurrentRulesDuetoDependency(cr, r, matchmap)); } while (crsOfRule.size() < x) { crsOfRule.add(new Vector<ConcurrentRule>()); } crsOfRule.add(list); res = true; } } } return res; } /* * Creates concurrent rule forwards: * Exmpl.: CR(r1,r2,r3) * 1) CR(r1,r2) = r1 *E r2; * 2) CR(r1,r2,r3) = CR(r1,r2) *E r3; * * @param ri_1 the direct predecessor rule * @param i_1 index of the direct predecessor rule * @param ri the current rule * @param i index of the current rule * @param g a graph to apply the rule * * @return true, when at least one rule of created concurrent rules is applicable, * otherwise false */ private boolean buildConcurrentRulesForward( final Rule ri_1, final int i_1, final Rule ri, final int i, final Graph g) { System.out.println("=== >>> ApplicabilityChecker.buildConcurrentRulesForwards:: "+ri_1.getName()+" & "+ri.getName()); boolean result = false; final List<List<ConcurrentRule>> crListsOfRuleI = this.getListsOfConcurrentRulesOfRule(ri, i); final List<List<ConcurrentRule>> crListsOfRuleI_1 = this.getListsOfConcurrentRulesOfRule(ri_1, i_1); if (crListsOfRuleI_1 != null && !crListsOfRuleI_1.isEmpty()) { for (int l=0; l<crListsOfRuleI_1.size() && !result; l++) { List<ConcurrentRule> listAll = new Vector<ConcurrentRule>(); crListsOfRuleI.add(listAll); List<ConcurrentRule> crList = crListsOfRuleI_1.get(l); for (int c=0; c<crList.size() && !result; c++) { ConcurrentRule cr = crList.get(c); List<ConcurrentRule> list = this.makeConcurrentRulesDuetoDependency(cr, ri, null); listAll.addAll(list); if (!list.isEmpty()) { int d = crListsOfRuleI.size(); for (int j = 0; j<list.size(); j++) { ConcurrentRule crj = list.get(j); if (isConcurrentRuleApplicable(i, ri, this.ruleSequence.getRules(), g, crj, d, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR)) { result = true; } else { list.remove(j); j--; } } } } } } if (!result) { for (int k=0; k<i; k++) { Rule r = this.ruleSequence.getRule(k); int k1 = k+1; Rule r1 = this.ruleSequence.getRule(k1); List<ConcurrentRule> list = null; if (k==0) { list = this.makeConcurrentRulesDuetoDependency(r, k, r1, k1, null); crListsOfRuleI.add(list); } else //if (this.depth == -1 || k < this.depth) { List<ConcurrentRule> listOfPreRule = this.getConcurrentRulesOfRule(r, k, k-1); if (listOfPreRule == null || listOfPreRule.isEmpty()) { final List<List<ConcurrentRule>> crListsOfPreRule = this.getListsOfConcurrentRulesOfRule(r, k); this.completeConcurrentRules(r, k, crListsOfPreRule, k-1, null); listOfPreRule = this.getConcurrentRulesOfRule(r, k, k-1); if (listOfPreRule == null || listOfPreRule.isEmpty()) { result = false; break; } } list = new Vector<ConcurrentRule>(); for (int c=0; c<listOfPreRule.size(); c++) { final ConcurrentRule cr = listOfPreRule.get(c); list.addAll(this.makeConcurrentRulesDuetoDependency(cr, r1, null)); } crListsOfRuleI.add(list); } if (!list.isEmpty()) { int d = crListsOfRuleI.size(); for (int c = 0; c<list.size(); c++) { ConcurrentRule cr = list.get(c); if (isConcurrentRuleApplicable(i, ri, this.ruleSequence.getRules(), g, cr, d, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR)) { result = true; } // else { // list.remove(c); // c--; // } } if (result) break; } } } // System.out.println("---> ApplicabilityChecker.buildConcurrentRulesForward:: result: "+result); return result; } // private void showObjectFlow() { // Enumeration<String> keys = this.ruleSequence.getObjectFlow().keys(); // while (keys.hasMoreElements()) { // String key = keys.nextElement(); // ObjectFlow of = this.ruleSequence.getObjectFlow().get(key); // System.out.println(key+":: "+of.getNameOfOutput()+" -> "+of.getNameOfInput() // +" :: "+of.getMapping().size()); // } // } /** * Creates concurrent rule backwards: * Exmpl.: CR(1,2,3) * 1) CR(2,3) = r2 + r3; * 2) CR(1,2,3) = r1 + CR(2,3); * * @param ri_1 the direct predecessor rule * @param i_1 index of the direct predecessor rule * @param ri the current rule * @param i index of the current rule * @param g a graph to apply the rule * * @return true, when at least one rule of created concurrent rules is applicable, * otherwise false */ private boolean buildConcurrentRulesBackward( final Rule ri_1, final int i_1, final Rule ri, final int i, final Graph g) { System.out.println("=== >>> ApplicabilityChecker.buildConcurrentRulesBackwards:: "+ri_1.getName()+" & "+ri.getName()); boolean result = false; int size = i; final List<List<ConcurrentRule>> concurrentRuleListsOfRule = this.getListsOfConcurrentRulesOfRule(ri, i); // showObjectFlow(); List<ConcurrentRule> list = null; for (int m=size-1; m>=0; m--) { if (m==size-1) { // try to use object flow if (this.ruleSequence.isObjFlowActive()) { final ObjectFlow objFlow = this.ruleSequence.getObjFlowForRules(ri_1, i_1, ri, i); if (objFlow != null && !objFlow.isEmpty()) { // test:: reset depth when using ObjectFlow // this.depth = 1; final Hashtable<Object, Object> objFlowMap = objFlow.getMapping(); System.out.println("=== >>> ApplicabilityChecker.buildConcurrentRulesBackwards:: USE ObjectFlow "); list = this.makeConcurrentRules(ri_1, i_1, ri, i, objFlowMap); } else { list = this.makeConcurrentRules(ri_1, i_1, ri, i); } // list = this.makeConcurrentRulesDuetoDependency(ri_1, i_1, ri, i, matchmap); } else { System.out.println("=== >>> ApplicabilityChecker.buildConcurrentRulesBackwards:: WITHOUT ObjectFlow "); list = this.makeConcurrentRules(ri_1, i_1, ri, i); } concurrentRuleListsOfRule.add(list); } else if (this.depth == -1 || m < this.depth) { // System.out.println("=== >>> ApplicabilityChecker.buildConcurrentRulesBackwards:: CR = (r, cr)"); Rule r = this.ruleSequence.getRule(m); list = this.makeConcurrentRules(r, m, list, m+1); // list = this.makeConcurrentRulesDuetoDependency(r, m, list, m+1, null); concurrentRuleListsOfRule.add(list); } // check applicability of concurrent rules if (list != null && !list.isEmpty()) { int d = concurrentRuleListsOfRule.size(); for (int k = 0; k<list.size(); k++) { ConcurrentRule cr = list.get(k); if (isConcurrentRuleApplicable(i, ri, this.ruleSequence.getRules(), g, cr, d, ApplicabilityConstants.DIRECT_ENABLING_PREDECESSOR)) { result = true; break; } } if (result) break; } } return result; } private List<ConcurrentRule> makeJointlyConcurrentRule( final Rule r1, int indx_r1, final Rule r2, int indx_r2) { final DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); dependencyContainer.enableProduceConcurrentRule(true); // here all overlappings will be considered dependencyContainer.setCompleteConcurrency(true); //this.completeConcurrency); List<ConcurrentRule> list = null; try { Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPairs = dependencyContainer.getCriticalPair(r1, r2, CriticalPair.EXCLUDE, true); if (criticalPairs != null) { list = dependencyContainer.getConcurrentRules(); // check overlappings against ObjectFlow reduceConcurrentRulesDuetoObjectFlow(r1, indx_r1, r2, indx_r2, list); extendRuleNameByIndex(list); } } catch (Exception ex) {} return list; } /* private List<ConcurrentRule> makeConcurrentRulesDuetoDependency( final Rule r1, int indx_r1, final List<ConcurrentRule> crules, int indx_cr, final Hashtable<?, ?> matchmap) { final List<ConcurrentRule> reslist = new Vector<ConcurrentRule>(); for (int i=0; i<crules.size(); i++) { final ConcurrentRule cr = crules.get(i); final List<ConcurrentRule> list = makeConcurrentRulesDuetoDependency(r1, indx_r1, cr.getRule(), indx_cr, matchmap); if (list != null && !list.isEmpty()) { reslist.addAll(list); } } return reslist; } */ private List<ConcurrentRule> makeConcurrentRulesDuetoDependency( final Rule r1, int indx_r1, final Rule r2, int indx_r2, final Hashtable<?, ?> matchmap) { final DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); dependencyContainer.enableProduceConcurrentRule(true); // if this.completeConcurrency Is false, only max overlapping above nodes will be considered // otherwise use all overlappings to create concurrent rules dependencyContainer.setCompleteConcurrency(this.completeConcurrency); List<ConcurrentRule> list = null; try { Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPairs = dependencyContainer.getCriticalPair(r1, r2, CriticalPair.EXCLUDE, true); if (criticalPairs != null) { list = dependencyContainer.getConcurrentRules(); } } catch (Exception ex) {} if (list == null) list = new Vector<ConcurrentRule>(1); else { for (int i=0; i<list.size(); i++) { list.get(i).setIndexOfFirstSourceRule(indx_r1); list.get(i).setIndexOfSecondSourceRule(indx_r2); } } if (this.completeConcurrency) { // make concurrent rule with disjoint (RHS1+LHS2) of (r1, r2) final ConcurrentRule cr = new ConcurrentRule(r1, r2); if (cr.getRule() != null) { cr.setIndexOfFirstSourceRule(indx_r1); cr.setIndexOfSecondSourceRule(indx_r2); list.add(cr); } } // try to use object flow if (!list.isEmpty()) reduceConcurrentRulesDuetoObjectFlow(r1, indx_r1, r2, indx_r2, list); extendRuleNameByIndex(list); // System.out.println("---> ApplicabilityChecker.makeConcurrentRulesDuetoDependency: count: "+list.size()); return list; } private List<ConcurrentRule> makeConcurrentRulesDuetoDependency( final ConcurrentRule cr1, final Rule r2, final Hashtable<?, ?> matchmap) { // System.out.println("---> ApplicabilityChecker.makeConcurrentRulesDuetoDependency(ConcurrentRule r1, final Rule r2 "); final DependencyPairContainer dependencyContainer = this.makeDependencyPairContainer(); dependencyContainer.enableProduceConcurrentRule(true); // if this.completeConcurrency Is false, only max overlapping above nodes will be considered // otherwise use all overlappings to create concurrent rules dependencyContainer.setCompleteConcurrency(this.completeConcurrency); List<ConcurrentRule> list = null; try { Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPairs = dependencyContainer.getCriticalPair(cr1.getRule(), r2, CriticalPair.EXCLUDE, true); if (criticalPairs != null) { list = dependencyContainer.getConcurrentRules(); } } catch (Exception ex) {} if (list == null) list = new Vector<ConcurrentRule>(1); if (this.completeConcurrency) { // make concurrent rule with disjoint (RHS1+LHS2) of (r1, r2) final ConcurrentRule cr = new ConcurrentRule(cr1, r2); if (cr.getRule() != null) { list.add(cr); } } for (int c=0; c<list.size(); c++) { if (this.completeConcurRuleBackward) list.get(c).setSecondSourceConcurrentRule(cr1); else list.get(c).setFirstSourceConcurrentRule(cr1); } extendRuleNameByIndex(list); // System.out.println("---> ApplicabilityChecker.makeConcurrentRulessDuetoDependency: count: "+list.size()); return list; } private Hashtable<Object, Object> getObjectFlowForRules( final Rule r1, int indx_r1, final ConcurrentRule cr, int indx_cr) { Hashtable<Object, Object> map = new Hashtable<Object, Object>(); // Rule r2 = cr.getFirstSourceRule(); map.putAll(cr.getReflectedInputObjectFlowFromRule( r1, this.ruleSequence.getObjFlowFromRule(r1, indx_r1))); return map; } private List<ConcurrentRule> makeConcurrentRules( final Rule r1, int indx_r1, final List<ConcurrentRule> crules, int indx_cr) { final List<ConcurrentRule> reslist = new Vector<ConcurrentRule>(); if (this.completeConcurRuleBackward) { for (int i=0; i<crules.size(); i++) { final ConcurrentRule cr = crules.get(i); if (this.ruleSequence.isObjFlowActive()) { // Rule r2 = cr.getFirstSourceRule(); // get object flow of (r1.RHS -> r2.LHS) to use it for overlapping (Graph E) // ObjectFlow objFlow = this.ruleSequence.getObjectFlowForRules(r1, indx_r1, r2, indx_cr); // if (objFlow != null && !objFlow.isEmpty()) { // System.out.println("=== >>> try to forward the object flow to concurrent rule along embedding"); // final Hashtable<Object, Object> matchmap12 = objFlow.getMapping(); // output --> input final Hashtable<Object, Object> matchmap = getObjectFlowForRules(r1, indx_r1, cr, indx_cr); if (!matchmap.isEmpty()) { // make shifting object flow along embedding // final Hashtable<Object, Object> matchmap = new Hashtable<Object, Object>(); // fill matchmap from matchmapOI along embedding of cr.r1.LHS -> cr.LHS // boolean ok = true; // Enumeration<Object> outputs = matchmapOI.keys(); // while (outputs.hasMoreElements() && ok) { // Object output = outputs.nextElement(); // Object input_cr = matchmapOI.get(output); // if (input_cr != null) { // matchmap.put(output, input_cr); // } // ok = ok && (input_cr != null); // } // if (ok) { final List<ConcurrentRule> list = makeConcurrentRules(r1, indx_r1, cr.getRule(), indx_cr, matchmap); if (list != null) { for (int j=0; j<list.size(); j++) { ConcurrentRule concrule = list.get(j); concrule.setSecondSourceConcurrentRule(cr); reflectObjectFlows(concrule, indx_r1, (indx_r1+concrule.getDepth())); // if (cr.reflectObjectFlow(this.ruleSequence.getObjectFlowForRule(r1, indx_r1)) // && cr.reflectObjectFlow(this.ruleSequence.getObjectFlowForRule(r2, cr.getIndexOfSecondSourceRule()))) { // } reslist.add(concrule); } } } } else { System.out.println("=== >>> "+r1.getName()+" & "+cr.getRule().getName()+" :: ObjectFlow is EMPTY. "); final List<ConcurrentRule> list = makeConcurrentRules(r1, indx_r1, cr.getRule(), indx_cr); if (list != null) { for (int j=0; j<list.size(); j++) { list.get(j).setSecondSourceConcurrentRule(cr); reslist.add(list.get(j)); } } } } else { final List<ConcurrentRule> list = makeConcurrentRules(r1, indx_r1, cr.getRule(), indx_cr); if (list != null) { for (int j=0; j<list.size(); j++) { list.get(j).setSecondSourceConcurrentRule(cr); reslist.add(list.get(j)); } } } } } return reslist; } private void reflectObjectFlows(final ConcurrentRule cr, int fromRuleIndx, int toRuleIndx) { for (int i=fromRuleIndx; i<=toRuleIndx; i++) { Rule r = this.ruleSequence.getRule(i); if (r != null) { cr.reflectObjectFlow(this.ruleSequence.getObjFlowForRule(r, i)); } } } private List<ConcurrentRule> makeConcurrentRules( final Rule r1, int indx_r1, final Rule r2, int indx_r2, final Hashtable<?, ?> objFlowMap) { if (objFlowMap == null || objFlowMap.isEmpty()) { return makeConcurrentRules(r1, indx_r1, r2, indx_r2); } System.out.println("=== >>> ApplicabilityChecker.makeConcurrentRules:: "+r1.getName()+" "+r2.getName()+" by Object Flow: "); // rename similar variables of rule1 final Hashtable<String, String> storeNewName2OldName = new Hashtable<String, String>(); if (r1 != r2) { BaseFactory.theFactory().renameSimilarVariable(r2, r1, "r1_", storeNewName2OldName); // ((VarTuple) r1.getAttrContext().getVariables()).showVariables(); // ((CondTuple) r1.getAttrContext().getConditions()).showConditions(); } final List<ConcurrentRule> list = new Vector<ConcurrentRule>(); Pair<Pair<Rule,Boolean>, Pair<OrdinaryMorphism, OrdinaryMorphism>> inverseRulePair = BaseFactory.theFactory().reverseRule(r1); Rule inverseRule1 = inverseRulePair.first.first; int maxsize = objFlowMap.size(); if (maxsize > 0) { // matchmap inverse:: keys to values, values to keys, because of inverse r1 final Hashtable<Object, Object> inversematchmap = new Hashtable<Object, Object>(); Enumeration<?> keys = objFlowMap.keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); inversematchmap.put(objFlowMap.get(key), inverseRulePair.second.second.getImage((GraphObject)key)); } Enumeration<Pair<OrdinaryMorphism, OrdinaryMorphism>> enums = BaseFactory.theFactory().getOverlappingByPredefinedIntersection( r2.getLeft(), inverseRule1.getLeft(), inversematchmap); if (enums != null && enums.hasMoreElements()) { while (enums.hasMoreElements()) { final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping = enums.nextElement(); if (this.checkIntersectionDuetoObjectFlow(overlapping, objFlowMap)) { ConcurrentRule cr = new ConcurrentRule(r1, inverseRulePair.first.first, r2, inverseRulePair.second.first, inverseRulePair.second.second, overlapping.second, overlapping.first); if (cr.getRule() != null) { cr.setIndexOfFirstSourceRule(indx_r1); cr.setIndexOfSecondSourceRule(indx_r2); cr.reflectObjectFlow(this.ruleSequence.getObjFlowForRule(r1, indx_r1)); cr.reflectObjectFlow(this.ruleSequence.getObjFlowForRule(r2, indx_r2)); list.add(0, cr); System.out.println("=== >>> Concurrent rule: " +cr.getRule().getName() +" has NACs: "+cr.getRule().getNACs().hasMoreElements() +", has PACs: "+cr.getRule().getPACs().hasMoreElements()); // ((VarTuple) cr.getRule().getAttrContext().getVariables()).showVariables(); } } } } } extendRuleNameByIndex(list); System.out.println("=== >>> ApplicabilityChecker.makeConcurrentRules:: count: "+list.size()); if (!storeNewName2OldName.isEmpty()) { BaseFactory.theFactory().restoreVariableNameOfRule(r1, storeNewName2OldName); } return list; } private List<ConcurrentRule> makeConcurrentRules( final Rule r1, int indx_r1, final Rule r2, int indx_r2) { System.out.println("=== >>> ApplicabilityChecker.makeConcurrentRules:: of "+r1.getName()+" "+r2.getName()); // rename similar variables of rule1 final Hashtable<String, String> storeNewName2OldName = new Hashtable<String, String>(); if (r1 != r2) { BaseFactory.theFactory().renameSimilarVariable(r2, r1, "r1_", storeNewName2OldName); // ((VarTuple) rule1.getAttrContext().getVariables()).showVariables(); } final List<ConcurrentRule> list = new Vector<ConcurrentRule>(); // final Pair<Rule, Pair<OrdinaryMorphism, OrdinaryMorphism>> // inverseRulePair = BaseFactory.theFactory().makeInverseRule(r1); // Rule inverseRule1 = inverseRulePair.first; // if (list.isEmpty()) { // make disjoint concurrent rule ConcurrentRule cr = new ConcurrentRule(r1, r2); if (cr.getRule() != null) { if (this.isOverlappingGraphValid(r1, null, r2, cr.getFirstLeftEmbedding(), cr.getSecondLeftEmbedding())) { cr.setIndexOfFirstSourceRule(indx_r1); cr.setIndexOfSecondSourceRule(indx_r2); cr.reflectObjectFlow(this.ruleSequence.getObjFlowForRule(r1, indx_r1)); cr.reflectObjectFlow(this.ruleSequence.getObjFlowForRule(r2, indx_r2)); System.out.println("=== >>> ApplicabilityChecker.makeConcurrentRules:: DISJOINT CR: " +cr.getRule().getName() +" has NACs: "+cr.getRule().getNACs().hasMoreElements() +", has PACs: "+cr.getRule().getPACs().hasMoreElements()); list.add(cr); } } // } extendRuleNameByIndex(list); System.out.println("=== >>> ApplicabilityChecker.makeConcurrentRules:: count: "+list.size()); if (!storeNewName2OldName.isEmpty()) { BaseFactory.theFactory().restoreVariableNameOfRule(r1, storeNewName2OldName); } return list; } private boolean isOverlappingGraphValid( final Rule r1, final Rule inverse_r1, final Rule r2, final OrdinaryMorphism morph1, final OrdinaryMorphism morph2) { boolean valid = true; // make match of r1 ((ContextView) morph1.getAttrContext()).setVariableContext(true); if (inverse_r1 != null) { // Match m1 = BaseFactory.theFactory().makeMatch(inverse_r1, morph1); // if (m1 != null && inverse_r1.hasNACs()) { // valid = ExcludePairHelper.isMatchValid(inverse_r1, m1, null, true, null); // } // if (!valid) { // System.out.println("=== >>> Match of rule: "+inverse_r1.getName()+" FAILED (NAC) "); // return false; // } } else { Match m1 = BaseFactory.theFactory().makeMatch(r1, morph1); if (m1 != null) { if (r1.hasNACs()) { valid = ExcludePairHelper.isMatchValid(r1, m1, null, true, null); } if (!valid) { return false; } } else { return false; } } // make match of r2 ((ContextView) morph2.getAttrContext()).setVariableContext(true); Match m2 = BaseFactory.theFactory().makeMatch(r2, morph2); if (m2 != null) { if (valid) { valid = ExcludePairHelper.isMatchValid(r2, m2, null, false, null); } if (!valid) { return false; } } else { return false; } return valid; } /* private boolean checkIntersectionOfConcurrentRuleDuetoObjectFlow( final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping, final Hashtable<?, ?> objFlow) { boolean ok = true; if (objFlow != null) { List<GraphObject> r2LHSobjs = getOverlappingObjectsOfSecondMorphism(overlapping); Iterator<?> r2_objFlow = objFlow.values().iterator(); while (r2_objFlow.hasNext() && ok) { ok = ok && r2LHSobjs.contains(r2_objFlow.next()); } } return ok; } private List<GraphObject> getOverlappingObjectsOfSecondMorphism( final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping) { List<GraphObject> list = new Vector<GraphObject>(); Iterator<?> elems = overlapping.first.getTarget().getNodesSet().iterator(); while (elems.hasNext()) { GraphObject go = (GraphObject) elems.next(); if (overlapping.first.getInverseImage(go).hasMoreElements() && overlapping.second.getInverseImage(go).hasMoreElements()) { list.add(overlapping.second.getInverseImage(go).nextElement()); } } elems = overlapping.first.getTarget().getArcsSet().iterator(); while (elems.hasNext()) { GraphObject go = (GraphObject) elems.next(); if (overlapping.first.getInverseImage(go).hasMoreElements() && overlapping.second.getInverseImage(go).hasMoreElements()) { list.add(overlapping.second.getInverseImage(go).nextElement()); } } return list; } */ private boolean checkIntersectionDuetoObjectFlow( final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping, final Hashtable<?, ?> objFlow) { boolean ok = true; if (objFlow != null) { List<GraphObject> r2LHSobjs = getOverlappingObjectsOfFirstMorphism(overlapping); Iterator<?> r2_objFlow = objFlow.values().iterator(); while (r2_objFlow.hasNext() && ok) { ok = ok && r2LHSobjs.contains(r2_objFlow.next()); } } return ok; } private List<GraphObject> getOverlappingObjectsOfFirstMorphism( final Pair<OrdinaryMorphism, OrdinaryMorphism> overlapping) { List<GraphObject> list = new Vector<GraphObject>(); Iterator<?> elems = overlapping.first.getTarget().getNodesSet().iterator(); while (elems.hasNext()) { GraphObject go = (GraphObject) elems.next(); if (overlapping.second.getInverseImage(go).hasMoreElements() && overlapping.first.getInverseImage(go).hasMoreElements()) { list.add(overlapping.first.getInverseImage(go).nextElement()); } } elems = overlapping.first.getTarget().getArcsSet().iterator(); while (elems.hasNext()) { GraphObject go = (GraphObject) elems.next(); if (overlapping.second.getInverseImage(go).hasMoreElements() && overlapping.first.getInverseImage(go).hasMoreElements()) { list.add(overlapping.first.getInverseImage(go).nextElement()); } } return list; } private boolean checkConcurrentRuleDuetoObjectFlow( final ConcurrentRule cr, final Hashtable<?, ?> objFlow) { if (objFlow == null || objFlow.isEmpty() || cr.getOverlappingObjectsOfSecondRule() == null) { return true; } boolean ok = true; boolean inside = false; // List<GraphObject> r2LHSobjs = cr.getOverlappingObjectsOfSecondRule(); // Iterator<?> r2_objFlow = objFlow.values().iterator(); // while (r2_objFlow.hasNext() && ok) { // ok = ok && r2LHSobjs.contains(r2_objFlow.next()); // } Enumeration<?> outs = objFlow.keys(); while (outs.hasMoreElements()) { GraphObject out = (GraphObject)outs.nextElement(); Hashtable<GraphObject,GraphObject> map = cr.getOverlappingObjects(); Enumeration<GraphObject> objs = map.keys(); while (objs.hasMoreElements()) { GraphObject obj_rhs1 = objs.nextElement();// == output object GraphObject obj_lhs2 = map.get(obj_rhs1); // == input object GraphObject input = (GraphObject) objFlow.get(out); if (input != obj_lhs2) { ok = false; // return false; } else { inside = true; } } } if (!inside) return true; return ok; } private void reduceConcurrentRulesDuetoObjectFlow( final Rule r1, int indx_r1, final Rule r2, int indx_r2, final List<ConcurrentRule> list) { // try to use object flow if (this.ruleSequence.isObjFlowActive()) { final ObjectFlow objFlow = this.ruleSequence.getObjFlowForRules(r1, indx_r1, r2, indx_r2); if (objFlow != null && !objFlow.isEmpty()) { Hashtable<Object, Object> map = objFlow.getMapping(); // remove overlappings without object flow for (int c=0; c<list.size(); c++) { ConcurrentRule cr = list.get(c); if (!checkConcurrentRuleDuetoObjectFlow(cr, map)) { list.remove(c); c--; } } } } } /* private boolean hasConflictsWithSuccessors(final Rule r, final List<Rule> successors) { boolean result = false; for (int i=0; i<successors.size(); i++) { Rule ri = successors.get(i); final SimpleExcludePair excludePair = makeExcludePair(); if(!asymParallelIndependentByCPA(excludePair, r, -1, ri, -1)) { result = true; break; } excludePair.dispose(); } // System.out.println("=== >>> ApplicabilityChecker.hasConflictsWithSuccessors: r2: "+r.getName()+" "+result); return result; } */ private void extendRuleNameByIndex(final List<ConcurrentRule> list) { for (int i=1; i<list.size(); i++) { final Rule r = list.get(i).getRule(); r.setName(r.getName().concat("_").concat(String.valueOf(i))); } } /* private boolean doesDependencyExist( final DependencyPairContainer dependencyContainer, final Rule r1, final Rule r2) { try { Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>> criticalPairs = dependencyContainer.getCriticalPair(r1, r2, CriticalPair.EXCLUDE, true); if (criticalPairs == null) { // System.out.println("=== >>> "+r1.getName()+" & "+r2.getName()+" : dependency does not exist! "); return false; } } catch (Exception ex) { // System.out.println("---> "+r1.getName()+" & "+r2.getName()+" : dependency does not exist! "); return false; } return true; } private String makeRuleKey(final int indx, final String rName, final String criterion) { String ruleKey = String.valueOf(indx); ruleKey = ruleKey.concat(rName); ruleKey = ruleKey.concat(criterion); return ruleKey; } */ private void setRuleResult( final int indx, final String ruleName, final boolean result, final String criterion, final String otherRuleName) { this.ruleSequence.setRuleResult(indx, ruleName, result, criterion, otherRuleName); } private void setApplicabilityResult( final boolean result, final String criterion) { this.ruleSequence.setApplicabilityResult(result, criterion); } private void setNonApplicabilityResult( final boolean result, final String criterion) { this.ruleSequence.setNonApplicabilityResult(result, criterion); } }