void tarjanVisit_aux(Graph g, int from, int to) { if (low[to] == INT_MAX || stack_contains(to)) { if(low[to] == INT_MAX) { tarjanVisit(g, to); } low[from]=min(low[from],low[to]); } }
// Tarjan's Algorithm from wikipedia static uint32_t strongly_connected(struct stack* stack, remodel_node_t* node, uint32_t* index) { node->index = *index; node->low_index = *index; (*index)++; stack_push(stack, node); ht_entry_t* entry; ht_iterator_t iter = HT_ITERATOR_INITIALIZER; while (ht_next(node->children, &iter, &entry)) { remodel_edge_t* edge = entry->value; assert(edge->from == node); if (edge->to->index == 0) { strongly_connected(stack, edge->to, index); node->low_index = min(node->low_index, edge->to->low_index); } else if(stack_contains(stack, edge->to)) { node->low_index = min(node->low_index, edge->to->index); } } if (node->low_index == node->index) { array_t* component = array_new(); remodel_node_t* w; do { assert(!stack_is_empty(stack)); w = stack_pop(stack); array_append(component, w); } while (w != node); if (component->len > 1) { fprintf(stderr, "error: dependency graph contains cycle:\n"); fprintf(stderr, " ["); for (uint32_t i = 0; i < component->len; i++) { remodel_node_t* n = array_get(component, i); fprintf(stderr, "%s", n->name); if (i != component->len - 1) { fprintf(stderr, ", "); } } fprintf(stderr, "]\n"); array_free(component); return true; } else { array_free(component); return false; } } else { return false; } }
_Bool stack_push_unique(stack * root, void * pointer, char value_type) { assert(root != NULL); return stack_contains(root, pointer, value_type) ? 1 : stack_push(root, pointer, value_type); }