bool gt_type_graph_is_partof(GtTypeGraph *type_graph, const char *parent_type, const char *child_type) { const char *parent_id, *child_id; GtTypeNode *parent_node, *child_node; gt_assert(type_graph && parent_type && child_type); /* make sure graph is built */ if (!type_graph->ready) { create_vertices(type_graph); type_graph->ready = true; } /* get parent ID, if the type is not mappable to an ID, assume it is the ID */ if (!(parent_id = gt_hashmap_get(type_graph->name2id, parent_type))) parent_id = parent_type; /* get child ID, if the type is not mappable to an ID, assmue it is the ID */ if (!(child_id = gt_hashmap_get(type_graph->name2id, child_type))) child_id = child_type; /* get parent node */ parent_node = gt_hashmap_get(type_graph->nodemap, parent_id); gt_assert(parent_node); /* get child node */ child_node = gt_hashmap_get(type_graph->nodemap, child_id); gt_assert(child_node); /* check for parent */ return gt_type_node_has_parent(child_node, parent_node, type_graph->part_of_out_edges, type_graph->part_of_in_edges, type_graph->nodes, type_graph->id2name, 0); }
bool gt_type_node_has_parent(GtTypeNode *node, const char *id, GtBoolMatrix *part_of_out_edges, GtBoolMatrix *part_of_in_edges, GtArray *node_list) { GtArray *node_stack; GtTypeNode *parent; unsigned long i; bool *result; gt_assert(node && id); gt_log_log("check if node %s has parent %s", node->id, id); /* try cache */ if (node->cache) { if ((result = gt_hashmap_get(node->cache, id))) return *result; } else node->cache = gt_hashmap_new(GT_HASH_DIRECT, NULL, gt_free_func); result = gt_malloc(sizeof (bool)); /* no cache hit found */ if (node->id == id) { *result = true; gt_hashmap_add(node->cache, (char*) id, result); gt_log_log("return true"); return true; } /* create transitive part_of edges */ node_stack = gt_array_new(sizeof (GtTypeNode*)); create_transitive_part_of_edges(node, part_of_out_edges, part_of_in_edges, node_stack); gt_assert(!gt_array_size(node_stack)); gt_array_delete(node_stack); /* traversal of part_of out edges */ for (i = gt_bool_matrix_get_first_column(part_of_out_edges, node->num); i != gt_bool_matrix_get_last_column(part_of_out_edges, node->num); i = gt_bool_matrix_get_next_column(part_of_out_edges, node->num, i)) { parent = *(GtTypeNode**) gt_array_get(node_list, i); if (gt_type_node_has_parent(parent, id, part_of_out_edges, part_of_in_edges, node_list)) { *result = true; gt_hashmap_add(node->cache, (char*) id, result); gt_log_log("return true"); return true; } } /* traversal of is_a out edges */ for (i = 0; i < gt_array_size(node->is_a_out_edges); i++) { parent = *(GtTypeNode**) gt_array_get(node->is_a_out_edges, i); if (gt_type_node_has_parent(parent, id, part_of_out_edges, part_of_in_edges, node_list)) { *result = true; gt_hashmap_add(node->cache, (char*) id, result); gt_log_log("return true"); return true; } } /* no result found */ *result = false; gt_hashmap_add(node->cache, (char*) id, result); return false; }