/** Method coolectPatternNodesToBeKeptInfo */ private void collectPatternNodesToBeKeptInfo() { patternNodeIsToBeKept = new int[n_graph_actions][max_n_pattern_nodes]; // init the arrays with -1 for (int i = 0; i < n_graph_actions; i++) for (int j = 0; j < max_n_pattern_nodes; j++) patternNodeIsToBeKept[i][j] = -1; // for all nodes to be kept set the corresponding array entry to the // appropriate replacement node number for (Rule action : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(action).intValue(); // compute the set of pattern nodes to be kept for this action Collection<Node> pattern_nodes_to_keep = new HashSet<Node>(); pattern_nodes_to_keep.addAll(action.getPattern().getNodes()); if (action.getRight() != null) { Graph replacement = action.getRight(); pattern_nodes_to_keep.retainAll(replacement.getNodes()); // iterate over the pattern nodes to be kept and store their // corresponding replacement node number for (Node node : pattern_nodes_to_keep) { int node_num = pattern_node_num.get(act_id).get(node).intValue(); patternNodeIsToBeKept[act_id][node_num] = replacement_node_num.get(act_id).get(node).intValue(); } } } }
/** Method collectReplacementNodeIsPreservedNodeInfo */ private void collectReplacementNodeIsPreservedNodeInfo() { replacementNodeIsPreservedNode = new int[n_graph_actions][max_n_replacement_nodes]; // init the array with -1 for (int i = 0; i < n_graph_actions; i++) for (int j = 0; j < max_n_replacement_nodes; j++) replacementNodeIsPreservedNode[i][j] = -1; // for all nodes preserved set the corresponding array entry to the // appropriate pattern node number for (Rule action : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(action).intValue(); if (action.getRight() != null) { // compute the set of replacement nodes preserved by this action Collection<Node> replacement_nodes_preserved = new HashSet<Node>(); replacement_nodes_preserved.addAll(action.getRight().getNodes()); replacement_nodes_preserved.retainAll(action.getPattern().getNodes()); // for all those preserved replacement nodes store the // corresponding pattern node for (Node node : replacement_nodes_preserved) { int node_num = replacement_node_num.get(act_id).get(node).intValue(); replacementNodeIsPreservedNode[act_id][node_num] = pattern_node_num.get(act_id).get(node).intValue(); } } } }
/** Method collectReplacementNodeChangesTypeToInfo */ private void collectReplacementNodeChangesTypeToInfo() { replacementNodeChangesTypeTo = new int[n_graph_actions][max_n_replacement_nodes]; // init the array with -1 for (int i = 0; i < n_graph_actions; i++) for (int j = 0; j < max_n_replacement_nodes; j++) replacementNodeChangesTypeTo[i][j] = -1; // for all nodes preserved set the corresponding array entry to the // appropriate node type id for (Rule action : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(action).intValue(); if (action.getRight() != null) { for (Node node : action.getRight().getNodes()) { if (!node.changesType(action.getRight())) continue; int node_num = replacement_node_num.get(act_id).get(node).intValue(); NodeType old_type = node.getNodeType(); NodeType new_type = node.getRetypedNode(action.getRight()).getNodeType(); if (!nodeTypeMap.get(old_type).equals(nodeTypeMap.get(new_type))) replacementNodeChangesTypeTo[act_id][node_num] = nodeTypeMap.get(new_type).intValue(); } } } }
/** Method collectNewInsertEdgesInfo */ private void collectNewInsertEdgesInfo() { // Collection[] new_edges_of_action; newEdgesOfAction = new Vector<Collection<Edge>>(n_graph_actions); // init the array with empty HashSets for (int i = 0; i < n_graph_actions; i++) newEdgesOfAction.set(i, new HashSet<Edge>()); // for all actions collect the edges to be newly inserted for (Rule action : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(action).intValue(); if (action.getRight() != null) { Graph replacement = action.getRight(); // compute the set of newly inserted edges newEdgesOfAction.get(act_id).addAll(replacement.getEdges()); newEdgesOfAction.get(act_id).removeAll(action.getPattern().getEdges()); } } }
/** * La methode principale qui renvoie l'arbre remplace si il y a matching et null sinon * * @param rule la rule qui va nous permettre de tester notre arbre. * @param arbre l'arbre a tester * @return le return qui vaut null si ça ne match pas, et qui vaut l'arbre remplacé sinon */ public Expression check(Rule rule, Expression arbre) { boolean check; // ici on recupere le pattern de la rule et l'arbre Expression pattern = rule.getLeft(); // Maintenant on homogeneise les noms de variable Hashtable<Character, Expression> ht = new Hashtable<Character, Expression>(); check = this.compareExpressions(pattern, arbre, ht); if (check == false) return null; return replace(rule.getRight(), ht); }
public boolean apply(Rule r) { // System.out.println("ApplRuleSequencesGraTraImpl.apply(Rule) : "+r.getName()+" // "+updateTypeObjectsMapAfterStep); // long time0 = System.currentTimeMillis(); this.stoppingRule = false; boolean result = false; boolean valid = false; this.currentMatch = r.getMatch(); if (this.currentMatch == null) { this.currentMatch = this.grammar.createMatch(r); this.currentMatch.setCompletionStrategy( (MorphCompletionStrategy) this.strategy.clone(), true); // strategy.showProperties(); } else if (this.updateTypeObjectsMapAfterStep) { this.currentMatch.setTypeObjectsMapChanged(true); } boolean parallelApply = true; boolean is_applied = false; // int matchCompletions = 0; // time0 = System.currentTimeMillis(); while (parallelApply) { if (!isInputParameterSet(r.getLeft(), true, this.currentMatch)) { fireGraTra(new GraTraEvent(this, GraTraEvent.INPUT_PARAMETER_NOT_SET, this.currentMatch)); } if (this.stopping || this.stoppingRule) { this.currentMatch.clear(); return false; } if (this.pauseRule) return false; valid = false; while (!valid) { if (this.currentMatch.isTotal() || this.currentMatch.nextCompletion()) { if (this.currentMatch.isValid()) { valid = true; // matchCompletions++; if (r.isParallelApplyEnabled() && this.currentMatch.typeObjectsMapChanged) { this.currentMatch.typeObjectsMapChanged = false; // das hat Auswirkung auf den naechsten Aufruf // von nextCompletion(): // die Graphaenderungen nach dem Step werden // NICHT BEACHTET!!! } } else { this.errorMsg = this.currentMatch.getErrorMsg(); this.currentMatch.clear(); } } else { this.errorMsg = this.currentMatch.getErrorMsg(); break; } } if (valid) { fireGraTra(new GraTraEvent(this, GraTraEvent.MATCH_VALID, this.currentMatch)); if (!isInputParameterSet(r.getRight(), false, this.currentMatch)) { fireGraTra(new GraTraEvent(this, GraTraEvent.INPUT_PARAMETER_NOT_SET, this.currentMatch)); } if (this.stopping || this.stoppingRule) { if (this.currentMatch != null) { this.currentMatch.clear(); } return false; } if (this.pauseRule) return false; try { // check attr context: variables only boolean checkVarsOnly = true; this.currentMatch .getAttrContext() .getVariables() .getAttrManager() .checkIfReadyToTransform(this.currentMatch.getAttrContext(), checkVarsOnly); } catch (AttrException ex) { fireGraTra(new GraTraEvent(this, GraTraEvent.NOT_READY_TO_TRANSFORM, r.getName())); // destroyMatch(currentMatch); return false; } Morphism coMatch = apply(this.currentMatch); if (coMatch != null) { this.errorMsg = ""; is_applied = true; this.currentMatch.clear(); // destroyMatch(currentMatch); coMatch.dispose(); coMatch = null; result = true; } else { valid = false; fireGraTra( new GraTraEvent(this, GraTraEvent.NO_COMPLETION, this.currentMatch, this.errorMsg)); this.currentMatch.clear(); // destroyMatch(currentMatch); result = false; } } else { fireGraTra( new GraTraEvent( this, GraTraEvent.NO_COMPLETION, this.currentMatch, this.currentMatch.getErrorMsg())); this.currentMatch.clear(); // destroyMatch(currentMatch); result = false; } // if (r.isParallelApplyEnabled()) { if (!valid) { parallelApply = false; this.currentMatch.typeObjectsMapChanged = true; } if (is_applied) { result = true; } } else { parallelApply = false; break; } // } return result; }
/* * collect some information needed for code gen process of the data * structures representing the graph actions * */ protected void collectActionInfo() { /* get the overall number of graph actions */ n_graph_actions = actionRuleMap.keySet().size(); /* get the overall maximum numbers of nodes and edges of all pattern and replacement graphs respectively */ max_n_pattern_nodes = 0; max_n_pattern_edges = 0; max_n_replacement_nodes = 0; max_n_replacement_edges = 0; for (Rule act : actionRuleMap.keySet()) { // check whether its graphs node and edge set sizes are greater int size; size = act.getPattern().getNodes().size(); if (size > max_n_pattern_nodes) max_n_pattern_nodes = size; size = act.getPattern().getEdges().size(); if (size > max_n_pattern_edges) max_n_pattern_edges = size; if (act.getRight() != null) { size = act.getRight().getNodes().size(); if (size > max_n_replacement_nodes) max_n_replacement_nodes = size; size = act.getRight().getEdges().size(); if (size > max_n_replacement_edges) max_n_replacement_edges = size; } } /* compute the numbers of nodes/edges of all pattern/replacement-graphs */ pattern_node_num = new Vector<Map<Node, Integer>>(n_graph_actions); pattern_edge_num = new Vector<Map<Edge, Integer>>(n_graph_actions); replacement_node_num = new Vector<Map<Node, Integer>>(n_graph_actions); replacement_edge_num = new Vector<Map<Edge, Integer>>(n_graph_actions); for (Rule act : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(act).intValue(); assert act_id < n_graph_actions : "action id found which was greater than the number of graph actions"; // compute node/edge numbers pattern_node_num.set(act_id, new HashMap<Node, Integer>()); pattern_edge_num.set(act_id, new HashMap<Edge, Integer>()); // fill the map with pairs (node, node_num) int node_num = 0; for (Node node : act.getPattern().getNodes()) { pattern_node_num.get(act_id).put(node, new Integer(node_num++)); } assert node_num == act.getPattern().getNodes().size() : "Wrong number of node_nums was created"; // fill the map with pairs (edge, edge_num) int edge_num = 0; for (Edge edge : act.getPattern().getEdges()) { pattern_edge_num.get(act_id).put(edge, new Integer(edge_num++)); } assert edge_num == act.getPattern().getEdges().size() : "Wrong number of edge_nums was created"; // if action has a replacement graph, compute node/edge numbers if (act.getRight() != null) { replacement_node_num.set(act_id, new HashMap<Node, Integer>()); replacement_edge_num.set(act_id, new HashMap<Edge, Integer>()); // fill the map with pairs (node, node_num) node_num = 0; for (Node node : act.getRight().getNodes()) { replacement_node_num.get(act_id).put(node, new Integer(node_num++)); } assert node_num == act.getRight().getNodes().size() : "Wrong number of node_nums was created"; // fill the map with pairs (edge, edge_num) edge_num = 0; for (Edge edge : act.getRight().getEdges()) { replacement_edge_num.get(act_id).put(edge, new Integer(edge_num++)); } assert edge_num == act.getRight().getEdges().size() : "Wrong number of edge_nums was created"; } else { replacement_node_num.set(act_id, null); replacement_edge_num.set(act_id, null); } } /* for all actions decompose the conditions into conjunctive parts, give all these subexpessions a number, and setup some maps keeping information about them */ // init a subexpression counter int subConditionCounter = 0; // setup the array for conditions conditions = new HashMap<Integer, Collection<Expression>>(); // iterate over all actions for (Rule act : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(act).intValue(); conditions.put(act_id, new TreeSet<Expression>(conditionsComparator)); // iterate over all conditions of the current action for (Expression condition : act.getPattern().getConditions()) { // divide the expression to all AND-connected parts, which do // not have an AND-Operator as root themselves Collection<Expression> subConditions = decomposeAndParts(condition); // for all the subconditions just computed... for (Expression sub_condition : subConditions) { // ...create condition numbers conditionNumbers.put(sub_condition, new Integer(subConditionCounter++)); // ...extract the pattern nodes and edges involved in the condition Collection<Node> involvedNodes = collectInvolvedNodes(sub_condition); Collection<Edge> involvedEdges = collectInvolvedEdges(sub_condition); // and at these Collections to prepared Maps conditionsInvolvedNodes.put(sub_condition, involvedNodes); conditionsInvolvedEdges.put(sub_condition, involvedEdges); // store the subcondition in an ordered Collection conditions.get(act_id).add(sub_condition); } } } // store the overall number of (sub)conditions n_conditions = subConditionCounter; /* collect the type constraints of the node of all actions pattern graphs */ int typeConditionCounter = n_conditions; typeConditions = new Vector<Collection<Collection<InheritanceType>>>(n_graph_actions); for (Rule act : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(act).intValue(); typeConditions.set( act_id, new TreeSet<Collection<InheritanceType>>(typeConditionsComparator)); /* for all nodes of the current MatchingActions pattern graph extract that nodes type constraints */ PatternGraph pattern = act.getPattern(); for (Node node : pattern.getNodes()) { // if node has type constraints, register the as conditions if (!node.getConstraints().isEmpty()) { // note that a type condition is the set of all types, // the corresponding node/edge is not allowed to be of Collection<InheritanceType> type_condition = node.getConstraints(); // ...create condition numbers typeConditionNumbers.put(type_condition, new Integer(typeConditionCounter++)); // ...extract the pattern nodes and edges involved in the condition Collection<Node> involvedNodes = new HashSet<Node>(); involvedNodes.add(node); // and at these Collections to prepared Maps typeConditionsInvolvedNodes.put(type_condition, involvedNodes); Collection<Edge> empty = Collections.emptySet(); typeConditionsInvolvedEdges.put(type_condition, empty); // store the subcondition in an ordered Collection typeConditions.get(act_id).add(type_condition); } } // do the same thing for all edges of the current pattern for (Edge edge : pattern.getEdges()) { // if node has type constraints, register the as conditions if (!edge.getConstraints().isEmpty()) { // note that a type condition is the set of all types, // the corresponding edge is not allowed to be of Collection<InheritanceType> type_condition = edge.getConstraints(); // ...create condition numbers typeConditionNumbers.put(type_condition, new Integer(typeConditionCounter++)); // ...extract the pattern edges and edges involved in the condition Collection<Edge> involvedEdges = new HashSet<Edge>(); involvedEdges.add(edge); // and at these Collections to prepared Maps Collection<Node> empty = Collections.emptySet(); typeConditionsInvolvedNodes.put(type_condition, empty); typeConditionsInvolvedEdges.put(type_condition, involvedEdges); // store the subcondition in an ordered Collection typeConditions.get(act_id).add(type_condition); } } } // update the overall number of conditions, such that type // conditions are also included n_conditions = typeConditionCounter; /* for all conditions (not type conditions!) the pairs (pattern_node_num, attr_id), which occur in qualifications at the leaves of the condition, are needed. To obtain that compute a map condition_num -> pattern_node_num_ -> { attr_ids } implemented by an Array of Maps; usage is: involvedPatternNodeAttrIds[cond_num].get(pattern_node_num) which yields a Collection of attr-ids. */ involvedPatternNodeAttrIds = new HashMap<Expression, Map<Node, Collection<Integer>>>(); involvedPatternEdgeAttrIds = new HashMap<Expression, Map<Edge, Collection<Integer>>>(); for (Rule act : actionRuleMap.keySet()) { int act_id = actionRuleMap.get(act).intValue(); // collect the attr ids in dependency of condition and the pattern node for (Expression cond : conditions.get(act_id)) { // TODO use or remove it // int cond_num = conditionNumbers.get(cond).intValue(); // descent to the conditions leaves and look for qualifications Map<Node, Collection<Integer>> node_map = new HashMap<Node, Collection<Integer>>(); Map<Edge, Collection<Integer>> edge_map = new HashMap<Edge, Collection<Integer>>(); __recursive_qual_collect(act_id, node_map, edge_map, cond); involvedPatternNodeAttrIds.put(cond, node_map); involvedPatternEdgeAttrIds.put(cond, edge_map); } } /* for each action compute the start node used in the matching process */ // init the array of start nodes start_node = new Node[n_graph_actions]; // for all actions gen matcher programs for (Rule action : actionRuleMap.keySet()) { Graph pattern = action.getPattern(); // pick out the node with the highest priority as start node int max_prio = 0; // get any node as initial node Node max_prio_node = null; if (pattern.getNodes().iterator().hasNext()) { max_prio_node = pattern.getNodes().iterator().next(); } for (Node node : pattern.getNodes()) { // get the nodes priority int prio = 0; Annotations a = node.getAnnotations(); if (a != null) if (a.containsKey("prio") && a.isInteger("prio")) prio = ((Integer) a.get("prio")).intValue(); // if the current priority is greater, update the maximum priority node if (prio > max_prio) { max_prio = prio; max_prio_node = node; } } start_node[actionRuleMap.get(action).intValue()] = max_prio_node; } // collect information about potential homomorphic pattern graph nodes, // i.e. nodes that are allowed to be identified by the matcher during the // matching process collectPotHomInfo(); collectPatternNodesToBeKeptInfo(); collectReplacementNodeIsPreservedNodeInfo(); collectReplacementNodeChangesTypeToInfo(); collectNewInsertEdgesInfo(); }