/** * computes matrices for all actions which show whether two pattern nodes are allowed to be * identified by the matcher */ protected void collectPotHomInfo() { // tells whether two pattern nodes of a given action are pot hom or not // e.g. : potHomMatrices[act_id][node_1][node_2] // protected int potHomMatrices[][][]; potHomNodeMatrices = new int[n_graph_actions][max_n_pattern_nodes][max_n_pattern_nodes]; for (int i = 0; i < n_graph_actions; i++) for (int j = 0; j < max_n_pattern_nodes; j++) for (int k = 0; k < max_n_pattern_nodes; k++) potHomNodeMatrices[i][j][k] = 0; // got through that m,atrices and set cells to '1' if two nodes // are potentialy homomorphic for (Rule action : actionRuleMap.keySet()) { PatternGraph pattern = action.getPattern(); for (Node node_1 : pattern.getNodes()) { Collection<Node> hom_of_node_1 = new HashSet<Node>(); hom_of_node_1 = pattern.getHomomorphic(node_1); for (Node node_2 : pattern.getNodes()) { // check whether these to nodes are potentially homomorphic // the pattern graph of the currrent action if (hom_of_node_1.contains(node_2)) { int act_id = actionRuleMap.get(action).intValue(); int node_1_num = pattern_node_num.get(act_id).get(node_1).intValue(); int node_2_num = pattern_node_num.get(act_id).get(node_2).intValue(); potHomNodeMatrices[act_id][node_1_num][node_2_num] = 1; } } } } }
/** 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()); } } }
/* * 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(); }