bool Graph<Vertex, Edge_value>::Check_node_for_cycle(const Vertex& start_vertex, set< Vertex, less<Vertex> >& processed, set< Vertex, less<Vertex> >& visited) { if (processed.find(start_vertex) == processed.end()) { // We've not already processed this node in an earlier pass. // We now insert the vertex into the visited set. The insert // method on sets returns a pair, the first of which is an // iterator pointing to the inserted item, and the second // of which is a boolean telling us whether the item was indeed // inserted, or whether it was already in the set. We'll use // this boolean value to determine whether we'd already visited // this node, implying that we have a cycle. pair<set< Vertex, less<Vertex> >::iterator, bool> insert_result(visited.insert(start_vertex)); if (!insert_result.second) { // We've already visited this vertex on this pass, i.e., // we have a cycle. return(true); } else { // We've not seen this node already. // Loop through the vertices that start_vertex has // edges going to, and make recursive calls for each of them. bool has_cycle = false; // A multimap can contain multiple pairs for the same key // (in our case, multiple edges leaving the same vertex). The // multimap class has a member function equal_range that // returns a pair of iterators. The first points to the // first item in the multiset with the given key (in our // case start_vertex), and the second points to the first // item _after_ the _last_ item with our given key. Thus // one can loop starting at the first iterator and ending // at the second iterator, and get all the pairs that match // our key. pair<edge_set::iterator, edge_set::iterator> vertex_edge_bounds; vertex_edge_bounds = edges.equal_range(start_vertex); // Go through each edge from start_vertex, and recursively call // Check_node_for_cycle. edge_set::const_iterator i = vertex_edge_bounds.first; while (!has_cycle && i != vertex_edge_bounds.second) { has_cycle = has_cycle || Check_node_for_cycle((*i).second, processed, visited); ++i; } // We've now chased down every edge from start_vertex, so // we'll add start_vertex to the set of processed vertices. processed.insert(start_vertex); // Remove start_vertex from the list of visited vertices. visited.erase(insert_result.first); return(has_cycle); } } else { // We've already been here, and there were no cycles from this // point. return(false); } }
void reduce_core(goal_ref const& g, goal_ref_buffer& result) { init(g); m_context.push(); assert_clauses(g); m_context.push(); // internalize assertions. prune_clauses(); goal_ref r(g); insert_result(r); r->elim_true(); result.push_back(r.get()); m_context.pop(2); TRACE("unit_subsumption_tactic", g->display(tout); r->display(tout););
/** * 強度を計算する再帰関数 * @param ARRARY *first 最初の単語が格納された要素 * @param TREE *conb 2つの単語の要素 * @param int threshold 計算に用いる出現頻度の最小値 * @param double *get_indicator(ARRAY *, ARRAY *, TREE *) 強度を返す関数 */ void calc_indicator_in_tree(ARRAY *first, TREE *conb, int threshold, double (*get_indicator)(ARRAY *, ARRAY *, TREE *)) { double indicator; // 要素が登録されていない if (conb->left == conb || conb->right == conb) return ; if (conb->left != NULL) // 右へ calc_indicator_in_tree(first, conb->left, threshold, get_indicator); if (conb->right != NULL) // 右へ calc_indicator_in_tree(first, conb->right, threshold, get_indicator); // 閾値よりも低い時は計算しない if (words[conb->id]->freq >= threshold) { // 強度の計算 indicator = get_indicator(first, words[conb->id], conb); insert_result(first->word, words[conb->id]->word, indicator); // 登録 } }