511 lines
14 KiB
Diff
511 lines
14 KiB
Diff
--- ./graph.cc.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./graph.cc 2011-10-28 21:22:57.464203395 -0600
|
|
@@ -34,7 +34,10 @@
|
|
namespace bliss {
|
|
|
|
#define _INTERNAL_ERROR() fatal_error("%s:%d: internal error",__FILE__,__LINE__)
|
|
-#define _OUT_OF_MEMORY() fatal_error("%s:%d: out of memory",__FILE__,__LINE__)
|
|
+#define _OUT_OF_MEMORY(label) do { \
|
|
+ fatal_error("%s:%d: out of memory",__FILE__,__LINE__); \
|
|
+ goto label; \
|
|
+ } while (0)
|
|
|
|
/*-------------------------------------------------------------------------
|
|
*
|
|
@@ -279,20 +282,6 @@
|
|
*perm = i;
|
|
}
|
|
|
|
-bool
|
|
-AbstractGraph::is_automorphism(unsigned int* const perm)
|
|
-{
|
|
- _INTERNAL_ERROR();
|
|
- return false;
|
|
-}
|
|
-
|
|
-bool
|
|
-AbstractGraph::is_automorphism(const std::vector<unsigned int>& perm) const
|
|
-{
|
|
- _INTERNAL_ERROR();
|
|
- return false;
|
|
-}
|
|
-
|
|
|
|
|
|
|
|
@@ -618,7 +607,7 @@
|
|
} PathInfo;
|
|
|
|
|
|
-void
|
|
+bool
|
|
AbstractGraph::search(const bool canonical, Stats& stats)
|
|
{
|
|
const unsigned int N = get_nof_vertices();
|
|
@@ -658,7 +647,7 @@
|
|
if(N == 0)
|
|
{
|
|
/* Nothing to do, return... */
|
|
- return;
|
|
+ return true;
|
|
}
|
|
|
|
/* Initialize the partition ... */
|
|
@@ -696,10 +685,10 @@
|
|
*/
|
|
if(first_path_labeling) free(first_path_labeling);
|
|
first_path_labeling = (unsigned int*)calloc(N, sizeof(unsigned int));
|
|
- if(!first_path_labeling) _OUT_OF_MEMORY();
|
|
+ if(!first_path_labeling) _OUT_OF_MEMORY(oom1);
|
|
if(best_path_labeling) free(best_path_labeling);
|
|
best_path_labeling = (unsigned int*)calloc(N, sizeof(unsigned int));
|
|
- if(!best_path_labeling) _OUT_OF_MEMORY();
|
|
+ if(!best_path_labeling) _OUT_OF_MEMORY(oom2);
|
|
|
|
/*
|
|
* Is the initial partition discrete?
|
|
@@ -710,7 +699,7 @@
|
|
update_labeling(best_path_labeling);
|
|
/* Update statistics */
|
|
stats.nof_leaf_nodes = 1;
|
|
- return;
|
|
+ return true;
|
|
}
|
|
|
|
/*
|
|
@@ -718,20 +707,39 @@
|
|
*/
|
|
if(first_path_labeling_inv) free(first_path_labeling_inv);
|
|
first_path_labeling_inv = (unsigned int*)calloc(N, sizeof(unsigned int));
|
|
- if(!first_path_labeling_inv) _OUT_OF_MEMORY();
|
|
+ if(!first_path_labeling_inv) _OUT_OF_MEMORY(oom3);
|
|
if(best_path_labeling_inv) free(best_path_labeling_inv);
|
|
best_path_labeling_inv = (unsigned int*)calloc(N, sizeof(unsigned int));
|
|
- if(!best_path_labeling_inv) _OUT_OF_MEMORY();
|
|
+ if(!best_path_labeling_inv) _OUT_OF_MEMORY(oom4);
|
|
|
|
/*
|
|
* Allocate space for the automorphisms
|
|
*/
|
|
if(first_path_automorphism) free(first_path_automorphism);
|
|
first_path_automorphism = (unsigned int*)malloc(N * sizeof(unsigned int));
|
|
- if(!first_path_automorphism) _OUT_OF_MEMORY();
|
|
+ if(!first_path_automorphism) _OUT_OF_MEMORY(oom5);
|
|
if(best_path_automorphism) free(best_path_automorphism);
|
|
best_path_automorphism = (unsigned int*)malloc(N * sizeof(unsigned int));
|
|
- if(!best_path_automorphism) _OUT_OF_MEMORY();
|
|
+ if(!best_path_automorphism) {
|
|
+ _OUT_OF_MEMORY(oom6);
|
|
+ oom6:
|
|
+ free(first_path_automorphism);
|
|
+ first_path_automorphism = NULL;
|
|
+ oom5:
|
|
+ free(best_path_labeling_inv);
|
|
+ best_path_labeling_inv = NULL;
|
|
+ oom4:
|
|
+ free(first_path_labeling_inv);
|
|
+ first_path_labeling_inv = NULL;
|
|
+ oom3:
|
|
+ free(best_path_labeling);
|
|
+ best_path_labeling = NULL;
|
|
+ oom2:
|
|
+ free(first_path_labeling);
|
|
+ first_path_labeling = NULL;
|
|
+ oom1:
|
|
+ return false;
|
|
+ }
|
|
|
|
/*
|
|
* Initialize orbit information so that all vertices are in their own orbits
|
|
@@ -974,7 +982,6 @@
|
|
*/
|
|
{
|
|
unsigned int next_split_element = UINT_MAX;
|
|
- unsigned int* next_split_element_pos = 0;
|
|
unsigned int* ep = p.elements + cell->first;
|
|
if(current_node.fp_on)
|
|
{
|
|
@@ -985,7 +992,6 @@
|
|
*ep < next_split_element and
|
|
first_path_orbits.is_minimal_representative(*ep)) {
|
|
next_split_element = *ep;
|
|
- next_split_element_pos = ep;
|
|
}
|
|
}
|
|
}
|
|
@@ -1001,7 +1007,6 @@
|
|
current_node.long_prune_redundant.find(*ep) ==
|
|
current_node.long_prune_redundant.end())) {
|
|
next_split_element = *ep;
|
|
- next_split_element_pos = ep;
|
|
}
|
|
}
|
|
}
|
|
@@ -1015,7 +1020,6 @@
|
|
current_node.long_prune_redundant.find(*ep) ==
|
|
current_node.long_prune_redundant.end())) {
|
|
next_split_element = *ep;
|
|
- next_split_element_pos = ep;
|
|
}
|
|
}
|
|
}
|
|
@@ -1203,8 +1207,10 @@
|
|
|
|
#if defined(BLISS_VERIFY_EQUITABLEDNESS)
|
|
/* The new partition should be equitable */
|
|
- if(!is_equitable())
|
|
+ if(!is_equitable()) {
|
|
fatal_error("consistency check failed - partition after refinement is not equitable");
|
|
+ return false;
|
|
+ }
|
|
#endif
|
|
|
|
/*
|
|
@@ -1366,6 +1372,7 @@
|
|
goto handle_first_path_automorphism;
|
|
/* Should never get here because of CR:FP */
|
|
_INTERNAL_ERROR();
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
@@ -1598,8 +1605,10 @@
|
|
|
|
#if defined(BLISS_VERIFY_AUTOMORPHISMS)
|
|
/* Verify that it really is an automorphism */
|
|
- if(!is_automorphism(best_path_automorphism))
|
|
+ if(!is_automorphism(best_path_automorphism)) {
|
|
fatal_error("Best path automorhism validation check failed");
|
|
+ return false;
|
|
+ }
|
|
#endif
|
|
|
|
unsigned int gca_level_with_first = 0;
|
|
@@ -1666,6 +1675,7 @@
|
|
|
|
|
|
_INTERNAL_ERROR();
|
|
+ return false;
|
|
|
|
|
|
handle_first_path_automorphism:
|
|
@@ -1701,8 +1711,10 @@
|
|
|
|
#if defined(BLISS_VERIFY_AUTOMORPHISMS)
|
|
/* Verify that it really is an automorphism */
|
|
- if(!is_automorphism(first_path_automorphism))
|
|
+ if(!is_automorphism(first_path_automorphism)) {
|
|
fatal_error("First path automorphism validation check failed");
|
|
+ return false;
|
|
+ }
|
|
#endif
|
|
|
|
if(opt_use_long_prune)
|
|
@@ -1749,12 +1761,13 @@
|
|
/* Release component recursion data in partition */
|
|
if(opt_use_comprec)
|
|
p.cr_free();
|
|
+ return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
-void
|
|
+bool
|
|
AbstractGraph::find_automorphisms(Stats& stats,
|
|
void (*hook)(void *user_param,
|
|
unsigned int n,
|
|
@@ -1764,7 +1777,8 @@
|
|
report_hook = hook;
|
|
report_user_param = user_param;
|
|
|
|
- search(false, stats);
|
|
+ if (!search(false, stats))
|
|
+ return false;
|
|
|
|
if(first_path_labeling)
|
|
{
|
|
@@ -1776,6 +1790,7 @@
|
|
free(best_path_labeling);
|
|
best_path_labeling = 0;
|
|
}
|
|
+ return true;
|
|
}
|
|
|
|
|
|
@@ -1790,7 +1805,8 @@
|
|
report_hook = hook;
|
|
report_user_param = user_param;
|
|
|
|
- search(true, stats);
|
|
+ if (!search(true, stats))
|
|
+ return NULL;
|
|
|
|
return best_path_labeling;
|
|
}
|
|
@@ -3480,15 +3496,17 @@
|
|
* Check whether perm is an automorphism.
|
|
* Slow, mainly for debugging and validation purposes.
|
|
*/
|
|
-bool
|
|
+int
|
|
Digraph::is_automorphism(unsigned int* const perm)
|
|
{
|
|
std::set<unsigned int, std::less<unsigned int> > edges1;
|
|
std::set<unsigned int, std::less<unsigned int> > edges2;
|
|
|
|
#if defined(BLISS_CONSISTENCY_CHECKS)
|
|
- if(!is_permutation(get_nof_vertices(), perm))
|
|
+ if(!is_permutation(get_nof_vertices(), perm)) {
|
|
_INTERNAL_ERROR();
|
|
+ return -1;
|
|
+ }
|
|
#endif
|
|
|
|
for(unsigned int i = 0; i < get_nof_vertices(); i++)
|
|
@@ -3507,7 +3525,7 @@
|
|
ei++)
|
|
edges2.insert(*ei);
|
|
if(!(edges1 == edges2))
|
|
- return false;
|
|
+ return 0;
|
|
|
|
edges1.clear();
|
|
for(std::vector<unsigned int>::iterator ei = v1.edges_out.begin();
|
|
@@ -3520,10 +3538,10 @@
|
|
ei++)
|
|
edges2.insert(*ei);
|
|
if(!(edges1 == edges2))
|
|
- return false;
|
|
+ return 0;
|
|
}
|
|
|
|
- return true;
|
|
+ return 1;
|
|
}
|
|
|
|
bool
|
|
@@ -4330,8 +4348,10 @@
|
|
Graph::permute(const unsigned int* perm) const
|
|
{
|
|
#if defined(BLISS_CONSISTENCY_CHECKS)
|
|
- if(!is_permutation(get_nof_vertices(), perm))
|
|
+ if(!is_permutation(get_nof_vertices(), perm)) {
|
|
_INTERNAL_ERROR();
|
|
+ return NULL;
|
|
+ }
|
|
#endif
|
|
|
|
Graph* const g = new Graph(get_nof_vertices());
|
|
@@ -5270,15 +5290,17 @@
|
|
*
|
|
*-------------------------------------------------------------------------*/
|
|
|
|
-bool
|
|
+int
|
|
Graph::is_automorphism(unsigned int* const perm)
|
|
{
|
|
std::set<unsigned int, std::less<unsigned int> > edges1;
|
|
std::set<unsigned int, std::less<unsigned int> > edges2;
|
|
|
|
#if defined(BLISS_CONSISTENCY_CHECKS)
|
|
- if(!is_permutation(get_nof_vertices(), perm))
|
|
+ if(!is_permutation(get_nof_vertices(), perm)) {
|
|
_INTERNAL_ERROR();
|
|
+ return -1;
|
|
+ }
|
|
#endif
|
|
|
|
for(unsigned int i = 0; i < get_nof_vertices(); i++)
|
|
@@ -5298,10 +5320,10 @@
|
|
edges2.insert(*ei);
|
|
|
|
if(!(edges1 == edges2))
|
|
- return false;
|
|
+ return 0;
|
|
}
|
|
|
|
- return true;
|
|
+ return 1;
|
|
}
|
|
|
|
|
|
--- ./bliss_C.cc.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./bliss_C.cc 2011-10-28 21:22:39.428577545 -0600
|
|
@@ -131,7 +131,7 @@
|
|
}
|
|
|
|
extern "C"
|
|
-void
|
|
+int
|
|
bliss_find_automorphisms(BlissGraph *graph,
|
|
void (*hook)(void *user_param,
|
|
unsigned int n,
|
|
@@ -142,7 +142,8 @@
|
|
bliss::Stats s;
|
|
assert(graph);
|
|
assert(graph->g);
|
|
- graph->g->find_automorphisms(s, hook, hook_user_param);
|
|
+ if (!graph->g->find_automorphisms(s, hook, hook_user_param))
|
|
+ return 0;
|
|
|
|
if(stats)
|
|
{
|
|
@@ -154,6 +155,7 @@
|
|
stats->nof_generators = s.get_nof_generators();
|
|
stats->max_level = s.get_max_level();
|
|
}
|
|
+ return 1;
|
|
}
|
|
|
|
|
|
@@ -173,7 +175,7 @@
|
|
|
|
canonical_labeling = graph->g->canonical_form(s, hook, hook_user_param);
|
|
|
|
- if(stats)
|
|
+ if(canonical_labeling && stats)
|
|
{
|
|
stats->group_size_approx = s.get_group_size_approx();
|
|
stats->nof_nodes = s.get_nof_nodes();
|
|
--- ./bliss.cc.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./bliss.cc 2011-10-28 21:22:39.429577524 -0600
|
|
@@ -276,13 +276,16 @@
|
|
if(opt_canonize == false)
|
|
{
|
|
/* No canonical labeling, only automorphism group */
|
|
- g->find_automorphisms(stats, &report_aut, stdout);
|
|
+ if (!g->find_automorphisms(stats, &report_aut, stdout))
|
|
+ exit(1);
|
|
}
|
|
else
|
|
{
|
|
/* Canonical labeling and automorphism group */
|
|
const unsigned int* cl = g->canonical_form(stats, &report_aut, stdout);
|
|
|
|
+ if (!cl)
|
|
+ exit(1);
|
|
fprintf(stdout, "Canonical labeling: ");
|
|
bliss::print_permutation(stdout, g->get_nof_vertices(), cl, 1);
|
|
fprintf(stdout, "\n");
|
|
@@ -290,6 +293,8 @@
|
|
if(opt_output_can_file)
|
|
{
|
|
bliss::AbstractGraph* cf = g->permute(cl);
|
|
+ if (!cf)
|
|
+ exit(1);
|
|
FILE* const fp = fopen(opt_output_can_file, "w");
|
|
if(!fp)
|
|
_fatal("Cannot open '%s' for outputting the canonical form, aborting", opt_output_can_file);
|
|
--- ./defs.cc.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./defs.cc 2011-10-28 21:22:39.429577524 -0600
|
|
@@ -33,7 +33,6 @@
|
|
vfprintf(stderr, fmt, ap);
|
|
fprintf(stderr, "\nAborting!\n");
|
|
va_end(ap);
|
|
- exit(1);
|
|
}
|
|
|
|
}
|
|
--- ./bliss_C.h.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./bliss_C.h 2011-10-28 21:22:39.430577503 -0600
|
|
@@ -156,6 +156,7 @@
|
|
* The argument \a perm should be an array of
|
|
* N=bliss::bliss_get_nof_vertices(\a graph) elements describing
|
|
* a bijection on {0,...,N-1}.
|
|
+ * Returns NULL if insufficient memory or internal error.
|
|
*/
|
|
BlissGraph *bliss_permute(BlissGraph *graph, const unsigned int *perm);
|
|
|
|
@@ -174,8 +175,9 @@
|
|
* if you want to use the automorphism later, you have to take a copy of it.
|
|
* Do not call bliss_* functions in the hook.
|
|
* If \a stats is non-null, then some search statistics are copied there.
|
|
+ * \return nonzero if successful, zero if insufficient memory or internal error
|
|
*/
|
|
-void
|
|
+int
|
|
bliss_find_automorphisms(BlissGraph *graph,
|
|
void (*hook)(void *user_param,
|
|
unsigned int N,
|
|
@@ -194,6 +196,7 @@
|
|
* then bliss_permute() with the returned canonical labeling.
|
|
* Note that the computed canonical version may depend on the applied version
|
|
* of bliss.
|
|
+ * Returns NULL if insufficient memory or internal error.
|
|
*/
|
|
const unsigned int *
|
|
bliss_find_canonical_labeling(BlissGraph *graph,
|
|
--- ./graph.hh.orig 2011-05-12 06:29:46.000000000 -0600
|
|
+++ ./graph.hh 2011-10-28 21:27:16.463811606 -0600
|
|
@@ -270,7 +270,7 @@
|
|
void reset_permutation(unsigned int *perm);
|
|
|
|
/* Mainly for debugging purposes */
|
|
- virtual bool is_automorphism(unsigned int* const perm);
|
|
+ virtual int is_automorphism(unsigned int* const perm) = 0;
|
|
|
|
std::vector<unsigned int> certificate_current_path;
|
|
std::vector<unsigned int> certificate_first_path;
|
|
@@ -284,7 +284,11 @@
|
|
virtual Partition::Cell* find_next_cell_to_be_splitted(Partition::Cell *cell) = 0;
|
|
|
|
|
|
- void search(const bool canonical, Stats &stats);
|
|
+ /**
|
|
+ * \return true if successful, false if insufficient memory to complete or
|
|
+ * other internal error
|
|
+ */
|
|
+ bool search(const bool canonical, Stats &stats);
|
|
|
|
|
|
void (*report_hook)(void *user_param,
|
|
@@ -362,7 +366,7 @@
|
|
* Check whether \a perm is an automorphism of this graph.
|
|
* Unoptimized, mainly for debugging purposes.
|
|
*/
|
|
- virtual bool is_automorphism(const std::vector<unsigned int>& perm) const;
|
|
+ virtual bool is_automorphism(const std::vector<unsigned int>& perm) const = 0;
|
|
|
|
|
|
|
|
@@ -427,8 +431,10 @@
|
|
* if you want to use the automorphism later, you have to take a copy of it.
|
|
* Do not call any member functions in the hook.
|
|
* The search statistics are copied in \a stats.
|
|
+ * \return true if successful, false if insufficient memory to search or
|
|
+ * other internal error.
|
|
*/
|
|
- void find_automorphisms(Stats& stats,
|
|
+ bool find_automorphisms(Stats& stats,
|
|
void (*hook)(void* user_param,
|
|
unsigned int n,
|
|
const unsigned int* aut),
|
|
@@ -448,6 +454,8 @@
|
|
* Note that the computed canonical version may depend on the applied version
|
|
* of bliss as well as on some other options (for instance, the splitting
|
|
* heuristic selected with bliss::Graph::set_splitting_heuristic()).
|
|
+ * This function returns NULL if there is insufficient memory, or another
|
|
+ * internal error occurs.
|
|
*/
|
|
const unsigned int* canonical_form(Stats& stats,
|
|
void (*hook)(void* user_param,
|
|
@@ -615,7 +623,7 @@
|
|
|
|
void initialize_certificate();
|
|
|
|
- bool is_automorphism(unsigned int* const perm);
|
|
+ int is_automorphism(unsigned int* const perm);
|
|
|
|
|
|
bool nucr_find_first_component(const unsigned int level);
|
|
@@ -856,7 +864,7 @@
|
|
|
|
void initialize_certificate();
|
|
|
|
- bool is_automorphism(unsigned int* const perm);
|
|
+ int is_automorphism(unsigned int* const perm);
|
|
|
|
void sort_edges();
|
|
|