Beispiel #1
0
/**
 * Returns true if the linkage is connected when ignoring the links
 * whose names are in the given list of link names.
 * Actually, what it does is this: it returns false if the connectivity
 * of the subgraph reachable from word 0 changes as a result of deleting
 * these links.
 */
static bool
apply_must_form_a_cycle(PP_data *pp_data, Linkage sublinkage, pp_rule *rule)
{
	List_o_links *lol;
	size_t w;

	for (w = 0; w < pp_data->num_words; w++)
	{
		for (lol = pp_data->word_links[w]; lol != NULL; lol = lol->next)
		{
			if (w > lol->word) continue; /* only consider each edge once */
			if (!pp_linkset_match(rule->link_set, sublinkage->link_array[lol->link].link_name)) continue;

			clear_visited(pp_data);
			reachable_without_dfs(pp_data, sublinkage, w, lol->word, w);
			if (!pp_data->visited[lol->word]) return false;
		}
	}

	for (lol = pp_data->links_to_ignore; lol != NULL; lol = lol->next)
	{
		w = sublinkage->link_array[lol->link].lw;
		/* (w, lol->word) are the left and right ends of the edge we're considering */
		if (!pp_linkset_match(rule->link_set, sublinkage->link_array[lol->link].link_name)) continue;

		clear_visited(pp_data);
		reachable_without_dfs(pp_data, sublinkage, w, lol->word, w);

		assert(lol->word < pp_data->num_words, "Bad word index");
		if (!pp_data->visited[lol->word]) return false;
	}

	return true;
}
Beispiel #2
0
/**
 * Takes a linkage and returns:
 *  . for each link, the domain structure of that link
 *  . a list of the violation strings
 * NB: linkage->link[i]->l=-1 means that this connector is to be ignored.
 */
PP_node *do_post_process(Postprocessor *pp, Linkage sublinkage, bool is_long)
{
	const char *msg;

	if (pp == NULL) return NULL;

	// XXX wtf .. why is this not leaking memory ?
	pp->pp_data.links_to_ignore = NULL;

	pp->pp_data.num_words = sublinkage->num_words;

	/* Grab more memory if needed */
	if (pp->vlength <= pp->pp_data.num_words)
	{
		size_t newsz;
		pp->vlength += pp->pp_data.num_words;
		newsz = pp->vlength * sizeof(bool);
		pp->visited = (bool *) realloc(pp->visited, newsz);
	}
	clear_visited(pp);

	/* In the name of responsible memory management, we retain a copy of the
	 * returned data structure pp_node as a field in pp, so that we can clear
	 * it out after every call, without relying on the user to do so. */
	clear_pp_node(pp);

	/* For long sentences, we can save some time by pruning the rules
	 * which can't possibly be used during postprocessing the linkages
	 * of this sentence. For short sentences, this is pointless. */
	if (is_long && pp->q_pruned_rules == false)
	{
		prune_irrelevant_rules(pp);
	}
	pp->q_pruned_rules = true;

	switch (internal_process(pp, sublinkage, &msg))
	{
		case -1:
			/* some global test failed even before we had to build the domains */
			pp->n_global_rules_firing++;
			pp->pp_node->violation = msg;
			report_pp_stats(pp);
			return pp->pp_node;
			break;
		case 1:
			/* one of the "normal" post processing tests failed */
			pp->n_local_rules_firing++;
			pp->pp_node->violation = msg;
			break;
		case 0:
			/* This linkage is legal according to the post processing rules */
			pp->pp_node->violation = NULL;
			break;
	}

	report_pp_stats(pp);
	build_type_array(pp);

	return pp->pp_node;
}
Beispiel #3
0
void MemoryDump::clear_visited(Node &node)
{
    if (node.visited < 0) return;
    node.visited = -1;
    for (auto c : node.children) {
        clear_visited(*c.node);
    }
}
Beispiel #4
0
double MemoryDump::update_subtree_size()
{
    total_size = 0;
    for (auto node : top_nodes) {
        std::set<uintptr_t> path;
        pre_update_subtree_size(*node.node, path);
        clear_visited(*node.node);
    }

    for (auto node : top_nodes) {
        std::set<uintptr_t> path;
        total_size += update_subtree_size(*node.node, path);
    }
    clear_visited();

    set_critical(top_nodes);
    clear_visited();
    return total_size;
}
Beispiel #5
0
int main() {
    // add edges
    add_edge(0, 1);
    add_edge(0, 2);
    add_edge(1, 3);
    add_edge(2, 4);
    add_edge(4, 5);
    add_edge(3, 5);
    add_edge(3, 2);
    add_edge(5, 6);
    add_edge(5, 7);

    printf(solve_maze(ENTRY) ? "There's a solution.\n" : "No solution :(\n");

    // now let's make it fail
    remove_edge(5, 7);
    clear_visited();

    printf(solve_maze(ENTRY) ? "There's a solution.\n" : "No solution :(\n");
    return 0;
}
Beispiel #6
0
static void build_domains(Postprocessor *pp, Linkage sublinkage)
{
	size_t link, i, d;
	const char *s;
	PP_data *pp_data = &pp->pp_data;

	pp_data->N_domains = 0;

	for (link = 0; link<sublinkage->num_links; link++)
	{
		assert (sublinkage->link_array[link].lw != SIZE_MAX);
		if (NULL == sublinkage->link_array[link].link_name) continue;
		s = sublinkage->link_array[link].link_name;

		if (pp_linkset_match(pp->knowledge->ignore_these_links, s)) continue;
		if (pp_linkset_match(pp->knowledge->domain_starter_links, s))
		{
			setup_domain_array(pp, s, link);
			if (pp_linkset_match(pp->knowledge->domain_contains_links, s))
				add_link_to_domain(pp_data, link);

			clear_visited(pp_data);
			depth_first_search(pp, sublinkage, sublinkage->link_array[link].rw,
			                   sublinkage->link_array[link].lw, link);
		}
		else
		if (pp_linkset_match(pp->knowledge->urfl_domain_starter_links, s))
		{
			setup_domain_array(pp, s, link);
			/* always add the starter link to its urfl domain */
			add_link_to_domain(pp_data, link);

			clear_visited(pp_data);
			bad_depth_first_search(pp, sublinkage,sublinkage->link_array[link].rw,
			                       sublinkage->link_array[link].lw, link);
		}
		else
		if (pp_linkset_match(pp->knowledge->urfl_only_domain_starter_links, s))
		{
			setup_domain_array(pp, s, link);
			/* do not add the starter link to its urfl_only domain */
			clear_visited(pp_data);
			d_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw,
			                     sublinkage->link_array[link].lw,
			                     sublinkage->link_array[link].rw, link);
		}
		else
		if (pp_linkset_match(pp->knowledge->left_domain_starter_links, s))
		{
			setup_domain_array(pp, s, link);
			/* do not add the starter link to a left domain */
			clear_visited(pp_data);
			left_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw,
			                        sublinkage->link_array[link].rw, link);
		}
	}

	/* sort the domains by size */
	qsort((void *) pp_data->domain_array,
		pp_data->N_domains,
		sizeof(Domain),
		(int (*)(const void *, const void *)) domain_compare);

	/* sanity check: all links in all domains have a legal domain name */
	for (d = 0; d < pp_data->N_domains; d++)
	{
		i = find_domain_name(pp, pp_data->domain_array[d].string);
		if (i == SIZE_MAX)
			prt_error("Error: post_process(): Need an entry for %s in LINK_TYPE_TABLE",
			          pp_data->domain_array[d].string);
		pp_data->domain_array[d].type = i;
	}
}
Beispiel #7
0
bool MemoryDump::write_output(const cmd_opt &opt)
{
    try {
        std::ofstream ofile(opt.ofile, std::ofstream::trunc);
        min_size = total_size * opt.threshold;
        if (exporter == nullptr
            || export_type != opt.export_type) {
            delete exporter;
            export_type = opt.export_type;
            switch (export_type) {
            case EXPORT_DOT:
                exporter = new ExporterDot(total_size);
                break;
            case EXPORT_GML:
                exporter = new ExporterGML(total_size);
                break;
            case EXPORT_GRAPHML:
                exporter = new ExporterGraphML();
                break;
            default:
                exporter = new ExporterDot(total_size);
                export_type = EXPORT_DOT;
            }
        }
        else {
            switch (export_type) {
            case EXPORT_DOT:
            case EXPORT_GML:
                exporter->set_total_size(total_size);
                break;
            default:
                break;
            }
        }
        exporter->write_preamble(ofile);
        std::vector<Node*> selected_nodes;
        if (opt.nodes.empty() && opt.labels.empty()) {
            for (const auto &c : top_nodes) {
                selected_nodes.push_back(c.node);
            }
        }
        else {
            /* find the node pointed by opt.node */
            for (const auto &path : opt.nodes) {
                auto node = find_node(path.node);
                if (node == nullptr) {
                    std::cout << "No node found for path " << path.literal << std::endl;
                    continue;
                }
                selected_nodes.push_back(node);
            }

            for (const auto &label : opt.labels) {
                auto node = nodes.find(label);
                if (node != nodes.end()) {
                    std::cout << "Found node by label " << std::hex << label << std::dec << std::endl;
                    selected_nodes.push_back(&node->second);
                }
                else {
                    std::cout << "Label " << std::hex << label << std::dec << " was not found\n";
                }
            }
        }
        std::set<uintptr_t> declared_nodes;
        for (auto & node : selected_nodes) {
            write_node(*node, ofile, opt);
            declared_nodes.insert(node->label);
            draw_tree(*node, ofile, opt, declared_nodes);
        }
        for (auto & node : selected_nodes) {
            clear_visited(*node);
        }

        exporter->write_appendix(ofile);

    }
    catch (...) {
        std::cout << "Unexpected error hanppend while writing output" << std::endl;
    }

    return true;
}
Beispiel #8
0
void MemoryDump::clear_visited()
{
    for (const auto &node : top_nodes) {
        clear_visited(*node.node);
    }
}
Beispiel #9
0
    ACTION unmark( Object **opp )
    {
        clear_visited( *opp );

        return CONTINUE;
    }