From d3634d02540349b6764d5d2059a247f87af72ec5 Mon Sep 17 00:00:00 2001 From: Jerry James Date: Tue, 2 Jun 2020 08:48:24 -0600 Subject: [PATCH] Version 2.7.1. --- nauty-autotoolization.patch | 200 +- nauty-fix-gt_numorbits.patch | 8 +- nauty-fix-include-extern.patch | 18 - nauty-help2man.patch | 257 ++- nauty-popcnt.patch | 648 +++++-- nauty-tool-prefix.patch | 65 +- nauty-unbundle-cliquer.patch | 3325 ++++++++++++++++++++++++++++++++ nauty.spec | 67 +- sources | 2 +- 9 files changed, 4199 insertions(+), 391 deletions(-) delete mode 100644 nauty-fix-include-extern.patch create mode 100644 nauty-unbundle-cliquer.patch diff --git a/nauty-autotoolization.patch b/nauty-autotoolization.patch index a887ee0..955eafc 100644 --- a/nauty-autotoolization.patch +++ b/nauty-autotoolization.patch @@ -2,12 +2,12 @@ Description: upstream autotoolization Attempt to autotoolize nauty source. Origin: debian Author: Jerome Benoit -Last-Update: 2016-03-19 +Last-Update: 2017-11-24 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,22 @@ - dnl Process this file with autoconf to produce a configure script. + # Process this file with autoconf to produce a configure script. -AC_INIT(nauty-h.in) +AC_INIT([nauty],[@INJECTVER@],[bdm@cs.anu.edu.au],[nauty],[http://pallini.di.uniroma1.it/]) +AC_CONFIG_MACRO_DIR([m4]) @@ -28,51 +28,81 @@ Last-Update: 2016-03-19 +AC_SUBST(LIBNAUTY_VERSION_MICRO) +AC_SUBST(LIBNAUTY_LT_VERSION) - AC_DEFUN([AX_TLS], [ - AC_MSG_CHECKING(for thread local storage (TLS) class) -@@ -48,7 +65,7 @@ - - dnl CVT_YESNO([YES-NO VARIABLE],[0-1 VARIABLE]) - dnl Make a 0-1 output variable from a yes/no shell variable --AC_DEFUN(CVT_YESNO,[if test x"$$1" = x"yes"; then -+AC_DEFUN([CVT_YESNO],[if test x"$$1" = x"yes"; then - $2=1 - else - $2=0 -@@ -77,10 +94,15 @@ - *) - gccver=0.0.0 ;; + # ====================================================================== + # First we define some functions +@@ -124,30 +141,37 @@ + is_cygwin=0 ;; esac -+AC_PATH_PROG([HELP2MAN],[help2man]) - dnl Checks for C compiler and sets CFLAGS if not set by user - user_cflags="$CFLAGS" +-dnl Checks for C compiler and sets CFLAGS if not set by user +-user_cflags="$CFLAGS" ++AC_PATH_PROG([HELP2MAN],[help2man]) AC_PROG_CC +-CFLAGS=$user_cflags +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +LT_INIT - CFLAGS=$user_cflags ++ ++dnl dnl Checks for C compiler and sets CFLAGS if not set by user ++dnl user_cflags="$CFLAGS" ++dnl AC_PROG_CC ++dnl CFLAGS=$user_cflags MORECFLAGS="" dnl we need AC_SYS_LARGEFILE and AC_FUNC_FSEEKO -@@ -400,6 +422,26 @@ - echo CFLAGS=$CFLAGS - echo MORECFLAGS=$MORECFLAGS + AC_SYS_LARGEFILE + AS_IF([test "x$ac_cv_sys_file_offset_bits" = xno],[ac_cv_sys_file_offset_bits=0]) + AC_SUBST(ac_cv_sys_file_offset_bits) + +-AS_IF([test "x$user_cflags" = x || test "x$user_cflags" = x-m32], +-[ +- AS_IF([test "$CC" = "icc"], +- [AC_TRY_CFLAGS([-O3],[CFLAGS="$CFLAGS -O3"]); +- AS_IF([test "x$ac_cv_try_cflags_ok" = xno], +- [AC_TRY_CFLAGS([-O2],[CFLAGS="$CFLAGS -O2"],[CFLAGS="$CFLAGS -O"])])], +- [AC_TRY_CFLAGS([-O4 -Werror],[CFLAGS="$CFLAGS -O4"]); +- AS_IF([test "x$ac_cv_try_cflags_ok" = xno], +- [AC_TRY_CFLAGS([-O3],[CFLAGS="$CFLAGS -O3"]) +- AS_IF([test "x$ac_cv_try_cflags_ok" = xno], +- [AC_TRY_CFLAGS([-O2],[CFLAGS="$CFLAGS -O2"],[CFLAGS="$CFLAGS -O"])]) +- ]) +- ]) +-]) ++dnl AS_IF([test "x$user_cflags" = x || test "x$user_cflags" = x-m32], ++dnl [ ++dnl AS_IF([test "$CC" = "icc"], ++dnl [AC_TRY_CFLAGS([-O3],[CFLAGS="$CFLAGS -O3"]); ++dnl AS_IF([test "x$ac_cv_try_cflags_ok" = xno], ++dnl [AC_TRY_CFLAGS([-O2],[CFLAGS="$CFLAGS -O2"],[CFLAGS="$CFLAGS -O"])])], ++dnl [AC_TRY_CFLAGS([-O4 -Werror],[CFLAGS="$CFLAGS -O4"]); ++dnl AS_IF([test "x$ac_cv_try_cflags_ok" = xno], ++dnl [AC_TRY_CFLAGS([-O3],[CFLAGS="$CFLAGS -O3"]) ++dnl AS_IF([test "x$ac_cv_try_cflags_ok" = xno], ++dnl [AC_TRY_CFLAGS([-O2],[CFLAGS="$CFLAGS -O2"],[CFLAGS="$CFLAGS -O"])]) ++dnl ]) ++dnl ]) ++dnl ]) + + case "$CC" in + gcc*) +@@ -448,5 +472,26 @@ + edit_msg="++++++ This file is automatically generated, don't edit it by hand! ++++++" + AC_SUBST(edit_msg) -AC_OUTPUT(makefile:makefile.in nauty.h:nauty-h.in - naututil.h:naututil-h.in gtools.h:gtools-h.in) +dnl Checks for linker script support +gl_LD_VERSION_SCRIPT - ++ +dnl Checks for libraries +## pkg-config +PKG_PROG_PKG_CONFIG +## math library +LT_LIB_M +## zlib Library (zlib) -+AM_PATH_ZLIB(1.2.7,[],[AC_MSG_WARN([could not find required version of zlib])]) ++AM_PATH_ZLIB(1.2.8,[],[AC_MSG_WARN([could not find required version of zlib])]) +## GNU MultiPrecision arithmetic library (GMP) -+AM_PATH_GMP(5.1.2,[],[AC_MSG_WARN([could not find required version of GMP])]) ++AM_PATH_GMP(6.1.2,[],[AC_MSG_WARN([could not find required version of GMP])]) + +AC_CONFIG_FILES([ + nauty.pc @@ -86,7 +116,7 @@ Last-Update: 2016-03-19 +AC_OUTPUT --- /dev/null +++ b/Makefile.am -@@ -0,0 +1,483 @@ +@@ -0,0 +1,519 @@ +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 + @@ -99,6 +129,10 @@ Last-Update: 2016-03-19 + nausparse.h \ + naututil.h \ + naugroup.h \ ++ naugstrings.h \ ++ nautaux.h \ ++ nautycliquer.h \ ++ planarity.h \ + schreier.h \ + traces.h \ + gtools.h \ @@ -112,6 +146,7 @@ Last-Update: 2016-03-19 + \ + addedgeg \ + amtog \ ++ assembleg \ + biplabg \ + catg \ + complg \ @@ -124,6 +159,7 @@ Last-Update: 2016-03-19 + directg \ + dretodot \ + dretog \ ++ edgetransg \ + genbg \ + genbgL \ + geng \ @@ -146,6 +182,7 @@ Last-Update: 2016-03-19 + showg \ + subdivideg \ + twohamg \ ++ underlyingg \ + vcolg \ + watercluster2 \ + \ @@ -158,6 +195,7 @@ Last-Update: 2016-03-19 + \ + addedgeg.1 \ + amtog.1 \ ++ assembleg.1 \ + biplabg.1 \ + catg.1 \ + complg.1 \ @@ -170,6 +208,7 @@ Last-Update: 2016-03-19 + directg.1 \ + dretodot.1 \ + dretog.1 \ ++ edgetransg.1 \ + genbg.1 \ + genbgL.1 \ + geng.1 \ @@ -192,6 +231,7 @@ Last-Update: 2016-03-19 + showg.1 \ + subdivideg.1 \ + twohamg.1 \ ++ underlyingg.1 \ + vcolg.1 \ + watercluster2.1 \ + \ @@ -219,6 +259,9 @@ Last-Update: 2016-03-19 + dreadtestW1 \ + dreadtestL1 \ + dreadtest4K \ ++ nautestS \ ++ nautestW \ ++ nautestL \ + naucompare + +TESTS = runalltests @@ -239,7 +282,7 @@ Last-Update: 2016-03-19 + --no-info + +%.1: % -+ $(HELP2MAN) \ ++ LD_LIBRARY_PATH=$(top_builddir)/.libs $(HELP2MAN) \ + -s 1 \ + $(AM_H2MFLAGS) \ + -I $(top_srcdir)/man/$*.h2m \ @@ -266,6 +309,7 @@ Last-Update: 2016-03-19 +dreadnaut_DESCRIPTION = "command line interface to nauty graph isomorphism library" +addedgeg_DESCRIPTION = "add an edge in each possible way" +amtog_DESCRIPTION = "read graphs in matrix format" ++assembleg_DESCRIPTION = "assemble input graphs as components of output graphs" +biplabg_DESCRIPTION = "label bipartite graphs so the colour classes are contiguous" +catg_DESCRIPTION = "concatenate files of graphs" +complg_DESCRIPTION = "complement graphs" @@ -278,6 +322,7 @@ Last-Update: 2016-03-19 +directg_DESCRIPTION = "generate small digraphs with given underlying graph" +dretodot_DESCRIPTION = "read graphs and initial coloring in dreadnaut format and write in dot format" +dretog_DESCRIPTION = "read graphs in dreadnaut format" ++edgetransg_DESCRIPTION = "select undirected graphs according to group action on vertices, edges and arcs" +genbg_DESCRIPTION = "generate small bicoloured graphs" +genbgL_DESCRIPTION = "$(shell printf "%s %s" $(genbg_DESCRIPTION) "(L1 flavour)")" +geng_DESCRIPTION = "generate small graphs" @@ -300,6 +345,7 @@ Last-Update: 2016-03-19 +showg_DESCRIPTION = "$(shell printf "%s %s" $(listg_DESCRIPTION) "(stand-alone subset of listg)")" +subdivideg_DESCRIPTION = "compute the subdivision graphs of a file of graphs" +twohamg_DESCRIPTION = "split quartic graphs into two hamiltonian cycles" ++underlyingg_DESCRIPTION = "take the underlying undirected graphs of a file of graphs" +vcolg_DESCRIPTION = "colour the vertices of graphs in all distinct ways" +watercluster2_DESCRIPTION = "$(shell printf "%s %s" $(directg_DESCRIPTION) "(faster alternative to directg)")" +blisstog_DESCRIPTION = "convert files of graphs in bliss format to stdout in sparse6 format" @@ -309,6 +355,7 @@ Last-Update: 2016-03-19 +dreadnaut_CPPFLAGS = +addedgeg_CPPFLAGS = +amtog_CPPFLAGS = ++assembleg_CPPFLAGS = +biplabg_CPPFLAGS = +catg_CPPFLAGS = +complg_CPPFLAGS = @@ -321,6 +368,7 @@ Last-Update: 2016-03-19 +directg_CPPFLAGS = +dretodot_CPPFLAGS = +dretog_CPPFLAGS = ++edgetransg_CPPFLAGS = +genbg_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) +genbgL_CPPFLAGS = $(nautyL1_flavour_CPPFLAGS) -DMAXN1=30 +geng_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) @@ -343,6 +391,7 @@ Last-Update: 2016-03-19 +showg_CPPFLAGS = +subdivideg_CPPFLAGS = +twohamg_CPPFLAGS = ++underlyingg_CPPFLAGS = +vcolg_CPPFLAGS = +watercluster2_CPPFLAGS = -DMAXN=32 +blisstog_CPPFLAGS = $(ZLIB_CFLAGS) @@ -352,6 +401,7 @@ Last-Update: 2016-03-19 +dreadnaut_SOURCES = dreadnaut.c +addedgeg_SOURCES = addedgeg.c +amtog_SOURCES = amtog.c ++assembleg_SOURCES = assembleg.c +biplabg_SOURCES = biplabg.c +catg_SOURCES = catg.c +complg_SOURCES = complg.c @@ -364,6 +414,7 @@ Last-Update: 2016-03-19 +directg_SOURCES = directg.c +dretodot_SOURCES = dretodot.c +dretog_SOURCES = dretog.c ++edgetransg_SOURCES = edgetransg.c +genbg_SOURCES = genbg.c +genbgL_SOURCES = genbg.c +geng_SOURCES = geng.c @@ -386,6 +437,7 @@ Last-Update: 2016-03-19 +showg_SOURCES = showg.c +subdivideg_SOURCES = subdivideg.c +twohamg_SOURCES = twohamg.c ++underlyingg_SOURCES = underlyingg.c +vcolg_SOURCES = vcolg.c +watercluster2_SOURCES = watercluster2.c +blisstog_SOURCES = blisstog.c @@ -395,6 +447,7 @@ Last-Update: 2016-03-19 +dreadnaut_LDADD = $(NAUTY_LDADD) +addedgeg_LDADD = $(NAUTY_LDADD) +amtog_LDADD = $(NAUTY_LDADD) ++assembleg_LDADD = $(NAUTY_LDADD) +biplabg_LDADD = $(NAUTY_LDADD) +catg_LDADD = $(NAUTY_LDADD) +complg_LDADD = $(NAUTY_LDADD) @@ -407,6 +460,7 @@ Last-Update: 2016-03-19 +directg_LDADD = $(NAUTY_LDADD) +dretodot_LDADD = $(NAUTY_LDADD) $(LIBM) +dretog_LDADD = $(NAUTY_LDADD) ++edgetransg_LDADD = $(NAUTY_LDADD) +genbg_LDADD = $(NAUTYW1_LDADD) +genbgL_LDADD = $(NAUTYL1_LDADD) +geng_LDADD = $(NAUTYW1_LDADD) @@ -429,6 +483,7 @@ Last-Update: 2016-03-19 +showg_LDADD = +subdivideg_LDADD = $(NAUTY_LDADD) +twohamg_LDADD = $(NAUTY_LDADD) ++underlyingg_LDADD = $(NAUTY_LDADD) +vcolg_LDADD = $(NAUTY_LDADD) +watercluster2_LDADD = $(NAUTY_LDADD) +blisstog_LDADD = $(NAUTY_LDADD) $(ZLIB_LIBS) @@ -482,6 +537,8 @@ Last-Update: 2016-03-19 + gtools.c \ + naututil.c \ + nautinv.c \ ++ nautycliquer.c \ ++ planarity.c \ + gutil1.c \ + gutil2.c \ + gtnauty.c \ @@ -538,6 +595,9 @@ Last-Update: 2016-03-19 +dreadtestL_CPPFLAGS = $(dreadtest_CPPFLAGS) $(nautyL0_flavour_CPPFLAGS) +dreadtestL1_CPPFLAGS = $(dreadtest_CPPFLAGS) $(nautyL1_flavour_CPPFLAGS) +dreadtest4K_CPPFLAGS = $(dreadtest_CPPFLAGS) -DMAXN=4096 ++nautestS_CPPFLAGS = $(dreadtest_CPPFLAGS) $(nautyS0_flavour_CPPFLAGS) ++nautestW_CPPFLAGS = $(dreadtest_CPPFLAGS) $(nautyW0_flavour_CPPFLAGS) ++nautestL_CPPFLAGS = $(dreadtest_CPPFLAGS) $(nautyL0_flavour_CPPFLAGS) + +dreadtest_SOURCES = $(dreadnaut_SOURCES) +dreadtest1_SOURCES = $(dreadnaut_SOURCES) @@ -548,6 +608,9 @@ Last-Update: 2016-03-19 +dreadtestL_SOURCES = $(dreadnaut_SOURCES) +dreadtestL1_SOURCES = $(dreadnaut_SOURCES) +dreadtest4K_SOURCES = $(dreadnaut_SOURCES) $(libnauty_la_SOURCES) ++nautestS_SOURCES = nauty.h naututil.h nautest.c ++nautestW_SOURCES = nauty.h naututil.h nautest.c ++nautestL_SOURCES = nauty.h naututil.h nautest.c + +dreadtest_LDADD = $(NAUTY_LDADD) +dreadtest1_LDADD = $(top_builddir)/libnautyA1.la $(threadlib) @@ -558,6 +621,9 @@ Last-Update: 2016-03-19 +dreadtestL_LDADD = $(top_builddir)/libnautyL0.la $(threadlib) +dreadtestL1_LDADD = $(top_builddir)/libnautyL1.la $(threadlib) +dreadtest4K_LDADD = $(threadlib) ++nautestS_LDADD = $(top_builddir)/libnautyS0.la $(threadlib) ++nautestW_LDADD = $(top_builddir)/libnautyW0.la $(threadlib) ++nautestL_LDADD = $(top_builddir)/libnautyL0.la $(threadlib) + +CLEANFILES = \ + $(man_MANS) \ @@ -628,7 +694,7 @@ Last-Update: 2016-03-19 +]) --- a/runalltests +++ b/runalltests -@@ -1,12 +1,16 @@ +@@ -1,13 +1,17 @@ #!/bin/sh # Run all nauty checks @@ -636,6 +702,7 @@ Last-Update: 2016-03-19 + +tdx=0 + + # runonetest command input output runonetest() { cmd="$1" in="$2" @@ -646,7 +713,7 @@ Last-Update: 2016-03-19 if [ "X$in" = "X" ] ; then in=/dev/null elif [ ! -r "$in" ] ; then -@@ -19,10 +23,16 @@ +@@ -20,10 +24,16 @@ exit 1 fi @@ -662,12 +729,12 @@ Last-Update: 2016-03-19 + sed -i 's@'$top_workingdir'/.libs/lt-@./@' $out2 +fi + - LC_COLLATE=C sort $out2 >>$out1 + LC_LANG=C sort $out2 >>$out1 if ./naucompare "$out1" "$ok" ; then rm $out1 $out2 --- /dev/null +++ b/nauty.map -@@ -0,0 +1,279 @@ +@@ -0,0 +1,291 @@ +LIBNAUTY_2.5 { +global: +## nauty.h @@ -947,6 +1014,18 @@ Last-Update: 2016-03-19 + +local: *; +}; ++ ++LIBNAUTY_2.7 { ++## gtools.h ++arg_sequence_min; ++## gutils.h ++degstats3; ++maxcliquesize; ++maxindsetsize; ++## nautycliquer.h ++find_clique; ++find_indset; ++}; --- /dev/null +++ b/m4/gmp.m4 @@ -0,0 +1,168 @@ @@ -1133,24 +1212,17 @@ Last-Update: 2016-03-19 #include --- a/naugroup.h +++ b/naugroup.h -@@ -3,7 +3,10 @@ +@@ -3,7 +3,9 @@ Procedures for handling groups found by nauty. */ -#include "nauty.h" -+#ifndef _NAUGROUP_H_ /* only process this file once */ -+#define _NAUGROUP_H_ ++#pragma once + +#include typedef struct perm_struct { -@@ -53,3 +56,5 @@ - #ifdef __cplusplus - } - #endif -+ -+#endif /* _NAUGROUP_H_ */ --- a/naurng.h +++ b/naurng.h @@ -11,8 +11,10 @@ @@ -1184,7 +1256,7 @@ Last-Update: 2016-03-19 #ifndef SG_WEIGHT #define SG_WEIGHT int -@@ -125,4 +125,4 @@ +@@ -127,4 +127,4 @@ } #endif @@ -1192,35 +1264,27 @@ Last-Update: 2016-03-19 +#endif /* _NAUSPARSE_H_ */ --- a/nautinv.h +++ b/nautinv.h -@@ -10,7 +10,10 @@ +@@ -10,7 +10,9 @@ * * *****************************************************************************/ -#include "nauty.h" /* which includes stdio.h */ -+#ifndef _NAUTINV_H_ /* only process this file once */ -+#define _NAUTINV_H_ ++#pragma once + +#include /* which includes stdio.h */ #ifdef __cplusplus extern "C" { -@@ -40,3 +43,5 @@ - #ifdef __cplusplus - } - #endif -+ -+#endif /* _NAUTINV_H_ */ --- a/naututil-h.in +++ b/naututil-h.in -@@ -115,9 +115,13 @@ +@@ -116,9 +116,12 @@ * * *****************************************************************************/ -#include "nauty.h" /* which includes stdio.h */ -#include "nausparse.h" -#include "naurng.h" -+#ifndef _NAUTUTIL_H_ /* only process this file once */ -+#define _NAUTUTIL_H_ ++#pragma once + +#include /* which includes stdio.h */ +#include @@ -1229,12 +1293,6 @@ Last-Update: 2016-03-19 /* At this point we can assume that , , , , or and if necessary have been included if they exist. */ -@@ -287,3 +291,5 @@ - #endif /*NAUTY_SEED_DEFINED*/ - - /* @edit_msg@ */ -+ -+#endif /* _NAUTUTIL_H_ */ --- a/schreier.h +++ b/schreier.h @@ -3,8 +3,8 @@ @@ -1328,36 +1386,22 @@ Last-Update: 2016-03-19 +]) --- a/traces.h +++ b/traces.h -@@ -23,6 +23,9 @@ +@@ -23,6 +23,8 @@ * 12-Jul-16 : bug correction (reaching degree 2 vertices) * *****************************************************************************/ -+#ifndef _TRACES_H_ /* only process this file once */ -+#define _TRACES_H_ ++#pragma once + #include "gtools.h" #include "schreier.h" -@@ -62,3 +65,5 @@ extern void Traces(sparsegraph*,int*,int - TracesStats*,sparsegraph*); - extern void refine_tr(sparsegraph*,int*,int*,int*,int*,TracesOptions*); - extern void traces_freedyn(void); -+ -+#endif /* _TRACES_H_ */ --- a/gutils.h +++ b/gutils.h -@@ -1,5 +1,8 @@ +@@ -1,5 +1,7 @@ /* gutils.h - procedure declarations for gutil1.c and gutil2.c */ -+#ifndef _GUTILS_H_ /* only process this file once */ -+#define _GUTILS_H_ ++#pragma once + #ifdef __cplusplus extern "C" { #endif -@@ -44,3 +47,5 @@ - #ifdef __cplusplus - } - #endif -+ -+#endif /* _GUTILS_H_ */ diff --git a/nauty-fix-gt_numorbits.patch b/nauty-fix-gt_numorbits.patch index 128095f..bc2a821 100644 --- a/nauty-fix-gt_numorbits.patch +++ b/nauty-fix-gt_numorbits.patch @@ -1,11 +1,11 @@ Description: explicit extern declaration for gt_numorbits Origin: debian Author: Jerome Benoit -Last-Update: 2013-11-22 +Last-Update: 2017-11-24 --- a/labelg.c +++ b/labelg.c -@@ -88,7 +88,6 @@ +@@ -89,7 +89,6 @@ static nauty_counter orbtotal; static double unorbtotal; @@ -15,7 +15,7 @@ Last-Update: 2013-11-22 --- a/gtools-h.in +++ b/gtools-h.in -@@ -283,6 +283,7 @@ +@@ -296,6 +296,7 @@ extern TLS_ATTR char *readg_line; extern TLS_ATTR size_t ogf_linelen; extern TLS_ATTR boolean is_pipe; @@ -25,7 +25,7 @@ Last-Update: 2013-11-22 } --- a/gtnauty.c +++ b/gtnauty.c -@@ -18,7 +18,7 @@ +@@ -19,7 +19,7 @@ static int fuzz2[] = {006532,070236,035523,062437}; #define FUZZ2(x) ((x) ^ fuzz2[(x)&3]) diff --git a/nauty-fix-include-extern.patch b/nauty-fix-include-extern.patch deleted file mode 100644 index 8a53ad3..0000000 --- a/nauty-fix-include-extern.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: explicit extern declaration in naurng.h -Origin: debian -Author: Jerome Benoit -Last-Update: 2013-11-22 - ---- a/naurng.h -+++ b/naurng.h -@@ -18,8 +18,8 @@ - extern "C" { - #endif - --void ran_init(long seed); --long ran_nextran(void); -+extern void ran_init(long seed); -+extern long ran_nextran(void); - - #ifdef __cplusplus - } diff --git a/nauty-help2man.patch b/nauty-help2man.patch index 22de855..7deed2e 100644 --- a/nauty-help2man.patch +++ b/nauty-help2man.patch @@ -7,7 +7,7 @@ Last-Update: 2016-03-19 --- a/watercluster2.c +++ b/watercluster2.c -@@ -1,54 +1,58 @@ +@@ -1,53 +1,65 @@ // cc -O4 -o water2 -DWORDSIZE=32 -DMAXN=WORDSIZE nauty.c naugraph.c nautil.c gtools.c schreier.c naurng.c watercluster2.c -/* @@ -35,6 +35,8 @@ Last-Update: 2016-03-19 - ended by a 0. Then the list of outgoing neighbours of 2 follows -- again ended with a 0, etc. - The code is complete with the 0 ending the list of outgoing neighbours of nv. - +- Z means: Output the directed graphs in digraph6 code. See formats.txt for a complete definition. +- - C means: Do really construct all the directed graphs in memory, but don't output them. This is not - a big difference in case of restricted in- and outdegrees, because all that is done extra is that - edges are directed instead of just keeping track of in- and out-degrees. This option is intended only @@ -52,68 +54,72 @@ Last-Update: 2016-03-19 - m read multicode - -This program uses different labelling routines -- all based on the ideas of -- --G. Brinkmann, Generating water clusters and other directed graphs, --Journal of Mathematical Chemistry 46, 1112--1121 (2009) +#define GTOOL_USAGEHELP_COMPATIBILITY --October 10, 2011: corrected error caused by overflow of 32bit int used as hashvalue. -+#define USAGE "watercluster2 [ix] [oy] [S] [T] [B] [C] [m]" +-G. Brinkmann, Generating water clusters and other directed graphs, +-Journal of Mathematical Chemistry 46, 1112--1121 (2009) ++#define USAGE "watercluster2 [ix] [oy] [S] [T] [B] [Z] [C] [m]" --Sep, 2012: PROCESS feature added by BDM. +#define HELPTEXT \ +" Reads graphs in g6 code or multicode (optional) from stdin and directs them\n\ +\n\ -+ ix : the indegree of every vertex may be at most x.\n\ -+ The default maximum indegree is unlimited.\n\ ++ ix: the indegree of every vertex may be at most x.\n\ ++ The default maximum indegree is unlimited.\n\ +\n\ -+ oy : the outdegree of every vertex may be at most y.\n\ -+ The default maximum outdegree is unlimited.\n\ ++ oy: the outdegree of every vertex may be at most y.\n\ ++ The default maximum outdegree is unlimited.\n\ +\n\ -+ S : allow that for every pair of vertices x,y at most one of the edges x-->y\n\ -+ and y-->x may be present. By default both of them may be present in the same graph.\n\ ++ S : allow that for every pair of vertices x,y at most one of the edges x-->y\n\ ++ and y-->x may be present. By default both of them may be present in the\n\ ++ same graph.\n\ +\n\ ++ T : Output directed graphs in T-code. This is a simple ASCII output format.\n\ ++ Every line contains one graph. First the number of vertices, then the\n\ ++ number of directed edges and then the list of directed edges with the\n\ ++ start first and the end then. E.g.: 3 2 0 1 2 1 means 3 vertices, 2\n\ ++ directed edges:\n\ ++ 0-->1 and 2-->1\n\ +\n\ -+ T : Output directed graphs in T-code. This is a simple ASCII output format. Every line\n\ -+ contains one graph. First the number of vertices, then the number of\n\ -+ directed edges and then the list of directed edges with the start first\n\ -+ and the end then. E.g.: 3 2 0 1 2 1 means 3 vertices, 2 directed edges:\n\ -+ 0-->1 and 2-->1\n\ ++ B : Output the directed graphs in a binary code. Every item of the code is an\n\ ++ unsigned char. The first unsigned char is the number nv of vertices. The\n\ ++ vertices are numbered 1..nv. Then the list of vertices x for which there\n\ ++ is a directed edge 1->x follow. This list is ended by a 0. Then the list\n\ ++ of outgoing neighbours of 2 follows -- again ended with a 0, etc.\n\ ++ The code is complete with the 0 ending the list of outgoing neighbours of\n\ ++ nv.\n\ +\n\ -+ B : Output the directed graphs in a binary code. Every item of the code is an unsigned\n\ -+ char. The first unsigned char is the number nv of vertices. The vertices are numbered 1..nv\n\ -+ Then the list of vertices x for which there is a directed edge 1->x follow. This list is\n\ -+ ended by a 0. Then the list of outgoing neighbours of 2 follows -- again ended with a 0, etc.\n\ -+ The code is complete with the 0 ending the list of outgoing neighbours of nv.\n\ ++ Z : Output the directed graphs in digraph6 code. See formats.txt for a\n\ ++ complete definition.\n\ +\n\ -+ C : Do really construct all the directed graphs in memory, but don't output them. This is not\n\ -+ a big difference in case of restricted in- and outdegrees, because all that is done extra is that\n\ -+ edges are directed instead of just keeping track of in- and out-degrees. This option is intended only\n\ -+ for testing purposes to test also routines that are normally not used when counting. Things that would\n\ -+ speed up the counting also in some cases of restricted in- and out-degrees -- like multiplying the\n\ -+ possibilities of assigning directions to edges that can be assigned directions independent\n\ -+ of each other (depending on the degrees of the endvertices and overlaps) -- are not included.\n\ -+ In case of not restrictive bounds on the in- and out-degree it not really constructing the graphs\n\ -+ can be considerably faster. In cases of restricted in- and out-degrees the only difference is that\n\ -+ the graph isn't modified...\n\ -+ The fact that in case of no output the graph is not modified is mainly to save time for the one\n\ -+ case of waterclusters, where large numbers were determined. If large numbers (without output)\n\ -+ for other cases shall be determined, one should think about adding the multiplication routines.\n\ ++ C : Do really construct all the directed graphs in memory, but don't output\n\ ++ them. This is not a big difference in case of restricted in- and\n\ ++ outdegrees, because all that is done extra is that edges are directed\n\ ++ instead of just keeping track of in- and out-degrees. This option is\n\ ++ intended only for testing purposes to test also routines that are normally\n\ ++ not used when counting. Things that would speed up the counting also in\n\ ++ some cases of restricted in- and out-degrees -- like multiplying the\n\ ++ possibilities of assigning directions to edges that can be assigned\n\ ++ directions independent of each other (depending on the degrees of the\n\ ++ endvertices and overlaps) -- are not included.\n\ ++ In case of not restrictive bounds on the in- and out-degree it not really\n\ ++ constructing the graphs can be considerably faster. In cases of restricted\n\ ++ in- and out-degrees the only difference is that the graph isn't modified.\n\ ++ The fact that in case of no output the graph is not modified is mainly to\n\ ++ save time for the one case of waterclusters, where large numbers were\n\ ++ determined. If large numbers (without output) for other cases shall be\n\ ++ determined, one should think about adding the multiplication routines.\n\ +\n\ -+ m : read multicode instead of g6 code\n\ ++ m : read multicode instead of g6 code\n\ +\n\ +This program uses different labelling routines -- all based on the ideas of\n\ +\n\ -+G. Brinkmann, Generating water clusters and other directed graphs,\n\ ++G. Brinkmann, Generating water clusters and other directed graphs,\m\ +Journal of Mathematical Chemistry 46, 1112--1121 (2009)\n" +/* -+ * October 10, 2011: corrected error caused by overflow of 32bit int used as hashvalue. -+ * -+ * Sep, 2012: PROCESS feature added by BDM. - */ + October 10, 2011: corrected error caused by overflow of 32bit int used as hashvalue. - /* PROCESS feature -@@ -67,7 +71,7 @@ + Sep, 2012: PROCESS feature added by BDM. +@@ -71,7 +83,7 @@ Oct, 2017: digraph6 output added by BDM. * * If SUMMARY is defined, it must expand as the name of a procedure * with prototype void SUMMARY(void). It is called at the end after @@ -122,7 +128,7 @@ Last-Update: 2016-03-19 */ //#include -@@ -500,7 +504,7 @@ +@@ -526,7 +538,7 @@ while (nullerE long long too short; This may cause problems with the hashing function for large degree -- exit().\n"); +@@ -4059,7 +4081,15 @@ int main(int argc, char *argv[]) + else if (argv[i][0]=='Z') direct_output=4; /* BDM */ + else if (argv[i][0]=='S') double_allowed=0; + else if (argv[i][0]=='m') { g6code=0; multicode=1; } - else usage(argv[0]); + else { +#ifdef GTOOL_USAGEHELP_COMPATIBILITY -+ fprintf(stderr,">E Usage: %s\n",USAGE); -+ fprintf(stderr,"Use watercluster2 -help to see a list of the options.\n"); -+ exit(1); ++ fprintf(stderr, ">E Usage: %s\n", USAGE); ++ fprintf(stderr, "Use watercluster2 -help to see a list of the options.\n"); ++ exit(1); +#else -+ usage(argv[0]); ++ usage(argv[0]); +#endif -+ } ++ } } #ifdef PROCESS @@ -187,7 +193,7 @@ Last-Update: 2016-03-19 --- a/geng.c +++ b/geng.c @@ -6,8 +6,7 @@ - /* geng.c version 2.9; B D McKay, Jan 2016. */ + /* geng.c version 3.1; B D McKay, Jan 2019. */ #define USAGE \ -"geng [-cCmtfbd#D#] [-uygsnh] [-lvq] \n\ @@ -208,30 +214,18 @@ Last-Update: 2016-03-19 #define HELPTEXT \ " Generate random graphs.\n\ ---- a/vcolg.c -+++ b/vcolg.c -@@ -1,8 +1,7 @@ - /* vcolg.c version 1.0; B D McKay, Aug 31, 2013 */ - - #define USAGE \ --"vcolg [-q] [-u|-T|-G|-A|-B] [-e#|-e#:#] \n" \ --" [-m#] [-f#] [-D#|-r#|-l#] [infile [outfile]]" -+"vcolg [-q] [-u|-T|-G|-A|-B] [-e#|-e#:#] [-m#] [-f#] [-D#|-r#|-l#] [infile [outfile]]" - - #define HELPTEXT \ - " Read undirected loop-free graphs and colour their vertices in\n\ --- a/genspecialg.c +++ b/genspecialg.c -@@ -1,20 +1,22 @@ - /* genspecialg.c version 1.1; B D McKay, Feb 12, 2016 */ +@@ -1,13 +1,12 @@ + /* genspecialg.c version 1.3; B D McKay, Mar 19, 2018 */ --#define USAGE "genspecialg \n\ --[-s|-g|-z|-d] [-q] \ --[-p#|-c#|-e#|-k#|-b#,#|-Q#|-f#|-J#,#|-P#,#|C#,#...|G#,#...|T#,#...] [outfile]" -+#define USAGE "genspecialg [-s|-g|-z|-d] [-q] [-p#|-c#|-e#|-k#|-b#,#|-Q#|-f#|-J#,#|-P#,#|C#[,#]|G#[,#]|T#[,#]] [outfile]" +-#define USAGE "genspecialg [-s|-g|-z|-d|-v] [-q]\n\ +- [-p#|-c#|-e#|-k#|-b#,#[,#]|-Q#|-f#|-J#,#\n\ +- |-P#,#|C#,#...|G#,#...|T#,#...]* [outfile]" ++#define USAGE "genspecialg [-s|-g|-z|-d|-v] [-q] [-p#|-c#|-e#|-k#|-b#,#[,#]|-Q#|-f#|-J#,#|-P#,#|C#,#...|G#,#...|T#,#...]* [outfile]" #define HELPTEXT \ - " Generate one particular graph.\n\ + " Generate special graphs.\n\ - # : size parameter called n in the descriptions\n\ \n\ +Options:\n\ @@ -239,7 +233,8 @@ Last-Update: 2016-03-19 -s : Write in sparse6 format (default)\n\ -g : Write in graph6 format\n\ -z : Make digraph versions and write in digraph6 format\n\ - -d : Write in dreadnaut format (can be used with -z)\n\ +@@ -15,7 +14,10 @@ + -v : For each graph, report the size to stderr\n\ -q : Suppress summary\n\ \n\ - If defined, the digraph version is shown in parentheses:\n\ @@ -250,32 +245,73 @@ Last-Update: 2016-03-19 -p# : path (directed path) on n vertices.\n\ -c# : cycle (directed cycle) on n vertices.\n\ -e# : empty graph (digraph with loops only) on n vertices.\n\ -@@ -24,9 +26,9 @@ +@@ -26,9 +28,9 @@ -P#,# : generalized Petersen graph; usual one is -P5,2\n\ -Q# : hypercube on 2^n vertices and degree n.\n\ -J#,# : Johnson graph J(n,k), args are n and k.\n\ - -C#,#... : circulant (di)graph.\n\ - -T#,#... : theta (di)graph Theta(#,#,...), give path lengths.\n\ -- -G#,#... : (directed) grid, use negative values for open directions\n" +- -G#,#... : (directed) grid, use negative values for open directions\n\ + -C#[,#] : circulant (di)graph.\n\ -+ -T#[,#] : theta (di)graph Theta(#[,#]), give path lengths.\n\ -+ -G#[,#] : (directed) grid, use negative values for open directions\n" - - /* Ideas: multipartite, knesser, full trees */ ++ -T#[,#] : theta (di)graph Theta(#,#,...), give path lengths.\n\ ++ -G#[,#] : (directed) grid, use negative values for open directions\n\ + \n\ + Any number of graphs can be generated at once.\n" --- a/cubhamg.c +++ b/cubhamg.c @@ -1,54 +1,53 @@ -/* cubhamg.c : pick those inputs that are nonhamiltonian and - have max degree <= 3. -+/* cubhamg.c : pick those inputs that are nonhamiltonian and have max degree <= 3. */ - +- - Usage: -cubhamg [-#] [-v|-V] [-n#-#|-y#-#|-i|-I|-o|-x|-e|-E] [-b|-t] [infile [outfile]] -+#define USAGE "cubhamg [-#] [-v|-V] [-n#-#|-y#-#|-i|-I|-o|-x|-e|-E] [-b|-t] [infile [outfile]]" - +- - infile is the name of the input file in graph6/sparse6 format - outfile is the name of the output file in the same format +- +- stdin and stdout are the defaults for infile and outfile +- +- The output file will have a header >>graph6<< or >>sparse6<< +- if and only if the input file does. +- +- Optional switches: ++/* cubhamg.c : pick those inputs that are nonhamiltonian and have max degree <= 3. */ + +- -# A parameter useful for tuning (default 100) +- -v Report nonhamiltonian graphs and noncubic graphs +- -V .. in addition give a cycle for the hamiltonian ones +- -n#-# If the two numbers are v and i, then the i-th edge +- out of vertex v is required to be not in the cycle. +- It must be that i=1..3 and v=0..n-1. +- -y#-# If the two numbers are v and i, then the i-th edge +- out of vertex v is required to be in the cycle. +- It must be that i=1..3 and v=0..n-1. +- You can use any number of -n/-y switches to force +- edges. Out of range first arguments are ignored. +- If -y and -n give same edge, -y wins. +- -i Test + property: for each edge e, there is a hamiltonian +- cycle using e. +- -I Test ++ property: for each pair of edges e,e', there is +- a hamiltonian cycle which uses both e and e'. +- -o Test - property: for each edge e, there is a hamiltonian +- cycle avoiding e. +- -x Test +- property: for each pair of edges e,e', there is +- a hamiltonian cycle which uses e but avoids e'. +- -e Test 3/4 property: for each edge e, at least 3 of the 4 +- paths of length 3 passing through e lie on hamiltonian cycles. +- -E Test 3/4+ property: for each edge e failing the 3/4 property, +- all three ways of joining e to the rest of the graph are +- hamiltonian avoiding e. +- -T# Specify a timeout, being a limit on how many search tree +- nodes are made. If the timeout occurs, the graph is +- written to the output as if it is nonhamiltonian. +- -R# Specify the number of repeat attempts for each stage. +- -F Analyze covering paths from 2 or 4 vertices of degree 2. ++#define USAGE "cubhamg [-#] [-v|-V] [-n#-#|-y#-#|-i|-I|-o|-x|-e|-E] [-b|-t] [infile [outfile]]" + +- -b Require biconnectivity +- -t Require triconnectivity (note: quadratic algorithm) +#define HELPTEXT \ +" Pick those inputs that are nonhamiltonian and have max degree <= 3.\n\ +\n\ @@ -321,53 +357,12 @@ Last-Update: 2016-03-19 +Comments:\n\ + -y, -n, -#, -R and -T are ignored for -i, -I, -x, -o, -e, -E, -F\n" -- stdin and stdout are the defaults for infile and outfile -- -- The output file will have a header >>graph6<< or >>sparse6<< -- if and only if the input file does. -- -- Optional switches: -- -- -# A parameter useful for tuning (default 100) -- -v Report nonhamiltonian graphs and noncubic graphs -- -V .. in addition give a cycle for the hamiltonian ones -- -n#-# If the two numbers are v and i, then the i-th edge -- out of vertex v is required to be not in the cycle. -- It must be that i=1..3 and v=0..n-1. -- -y#-# If the two numbers are v and i, then the i-th edge -- out of vertex v is required to be in the cycle. -- It must be that i=1..3 and v=0..n-1. -- You can use any number of -n/-y switches to force -- edges. Out of range first arguments are ignored. -- If -y and -n give same edge, -y wins. -- -i Test + property: for each edge e, there is a hamiltonian -- cycle using e. -- -I Test ++ property: for each pair of edges e,e', there is -- a hamiltonian cycle which uses both e and e'. -- -o Test - property: for each edge e, there is a hamiltonian -- cycle avoiding e. -- -x Test +- property: for each pair of edges e,e', there is -- a hamiltonian cycle which uses e but avoids e'. -- -e Test 3/4 property: for each edge e, at least 3 of the 4 -- paths of length 3 passing through e lie on hamiltonian cycles. -- -E Test 3/4+ property: for each edge e failing the 3/4 property, -- all three ways of joining e to the rest of the graph are -- hamiltonian avoiding e. -- -T# Specify a timeout, being a limit on how many search tree -- nodes are made. If the timeout occurs, the graph is -- written to the output as if it is nonhamiltonian. -- -R# Specify the number of repeat attempts for each stage. -- -F Analyze covering paths from 2 or 4 vertices of degree 2. -- -- -b Require biconnectivity -- -t Require triconnectivity (note: quadratic algorithm) -- - -y, -n, -#, -R and -T are ignored for -i, -I, -x, -o, -e, -E, -F +/************************************************************************** B. D. McKay, Nov 1995 + Aug 1996 + Feb 2002 + Jul 2008 + Nov 2015 -@@ -1611,6 +1610,8 @@ +@@ -1611,6 +1610,8 @@ main(int argc, char *argv[]) char *arg; int codetype; @@ -376,7 +371,7 @@ Last-Update: 2016-03-19 infilename = outfilename = NULL; badargs = FALSE; e34plus = e34 = in = out = inin = inout = FALSE; -@@ -1729,8 +1730,8 @@ +@@ -1729,8 +1730,8 @@ main(int argc, char *argv[]) if (badargs) { diff --git a/nauty-popcnt.patch b/nauty-popcnt.patch index 308e44f..b158d2d 100644 --- a/nauty-popcnt.patch +++ b/nauty-popcnt.patch @@ -1,7 +1,7 @@ Description: enable runtime detection of popcnt-enabled CPU Origin: fedora Author: Jerry James -Last-Update: 2016-04-20 +Last-Update: 2020-05-21 --- a/addedgeg.c +++ b/addedgeg.c @@ -58,7 +58,7 @@ Last-Update: 2016-04-20 okdist[0] = okdist[1] = FALSE; --- a/complg.c +++ b/complg.c -@@ -50,6 +50,17 @@ compl(graph *g, int m, int n, graph *h, +@@ -51,6 +51,17 @@ compl(graph *g, int m, int n, graph *h, } } @@ -76,7 +76,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ int -@@ -172,10 +183,10 @@ main(int argc, char *argv[]) +@@ -175,10 +186,10 @@ main(int argc, char *argv[]) if (restricted || Restricted) { @@ -91,32 +91,33 @@ Last-Update: 2016-04-20 { --- a/configure.ac +++ b/configure.ac -@@ -263,6 +263,9 @@ dnl --disable-popcnt disables the use of - AC_MSG_CHECKING(if popcnt instruction is available and requested) - AC_ARG_ENABLE([popcnt], - AS_HELP_STRING([--disable-popcnt], [Disable popcnt extensions]), [popcntarg=given], [popcntarg=notgiven]) +@@ -83,6 +83,9 @@ + AS_HELP_STRING([--disable-popcnt], [Disable popcnt extensions]), + [enablearg=given], [enablearg=notgiven]) + AS_IF([test $enablearg = notgiven || test "x$enable_popcnt" = xyes],[allow_popcnt=1],[allow_popcnt=0]) +AC_ARG_ENABLE([runtime-popcnt], + AS_HELP_STRING([--enable-runtime-popcnt], [Detect popcnt extensions at runtime]), + [runtime_popcnt=1;enable_popcnt=yes], [runtime_popcnt=0]) - AS_IF([test "x$popcntarg" = "xnotgiven" -o "x$enable_popcnt" = "xyes"], [ - have_hwpopcnt=0 - test -e /proc/cpuinfo && grep -i popcnt /proc/cpuinfo >/dev/null && have_hwpopcnt=1 -@@ -293,7 +296,6 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([#include - main(){unsigned int x; x = _mm_popcnt_u64(x);}])], [have_mmpop64=1], [have_mmpop64=0]) - AC_MSG_RESULT($have_mmpop64) - ], [ --CFLAGS="$CFLAGS -mpopcnt" - AC_MSG_CHECKING(if __builtin_popcount() is supported) - AC_LINK_IFELSE([AC_LANG_SOURCE([main(){unsigned int x; x = __builtin_popcount(x);}])], [have_popcnt=1], [have_popcnt=0]) - AC_MSG_RESULT($have_popcnt) -@@ -312,6 +314,7 @@ AC_SUBST(have_popcntl) + + dnl --disable-clz disallows clz instructions, otherwise they are tested for + AC_ARG_ENABLE([clz], +@@ -317,7 +320,7 @@ + have_mmpop32=0 + have_mmpop64=0 + +-AS_IF([test $have_hwpopcnt -eq 1], ++AS_IF([test $have_hwpopcnt -eq 1 -a $runtime_popcnt -eq 0], + [AS_IF([test "$CC" = "icc"], + [AC_MSG_CHECKING(if _mm_popcnt_u32() is supported) + AC_LINK_IFELSE([AC_LANG_SOURCE([#include +@@ -351,6 +354,7 @@ AC_SUBST(have_popcntll) AC_SUBST(have_mmpop32) AC_SUBST(have_mmpop64) +AC_SUBST(runtime_popcnt) - AC_SUBST(MORECFLAGS) - dnl --disable-clz disables the use of gcc extensions __builtin_clz*() + # Unless --enable-generic is given to configure, we try to use the -march=native compiler + # switch. However, it breaks some versions of gcc on MacOSX due to a compiler bug, so --- a/deledgeg.c +++ b/deledgeg.c @@ -16,6 +16,23 @@ @@ -265,7 +266,7 @@ Last-Update: 2016-04-20 lab[++j0] = i; --- a/genbg.c +++ b/genbg.c -@@ -465,8 +465,7 @@ isconnected(graph *g, int n) +@@ -475,8 +475,7 @@ isconnected(graph *g, int n) /**************************************************************************/ @@ -275,7 +276,7 @@ Last-Update: 2016-04-20 /* make distance invariant/ exit immediately FALSE if n-1 not maximal else exit TRUE Note: only invar[n1..n1+n2-1] set */ -@@ -498,7 +497,7 @@ distinvar(graph *g, int *invar, int n1, +@@ -508,7 +507,7 @@ distinvar(graph *g, int *invar, int n1, if (v < n-1 && inv > invar[n-1]) return FALSE; } return TRUE; @@ -284,7 +285,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -654,10 +653,10 @@ userautomproc(int count, int *p, int *or +@@ -664,10 +663,10 @@ userautomproc(int count, int *p, int *or * * *****************************************************************************/ @@ -298,7 +299,7 @@ Last-Update: 2016-04-20 { int i,c1,c2,labc1; setword x; -@@ -790,7 +789,7 @@ refinex(graph *g, int *lab, int *ptn, in +@@ -800,7 +799,7 @@ refinex(graph *g, int *lab, int *ptn, in } } } @@ -307,7 +308,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -938,9 +937,28 @@ accept1(graph *g, int n2, int x, graph * +@@ -948,9 +947,28 @@ accept1(graph *g, int n2, int x, graph * } /**************************************************************************/ @@ -338,7 +339,7 @@ Last-Update: 2016-04-20 /* decide if n in theta(g+x) -- version for n+1 == maxn */ { int i,n; -@@ -957,10 +975,8 @@ accept2(graph *g, int n2, int x, graph * +@@ -967,10 +985,8 @@ accept2(graph *g, int n2, int x, graph * static DEFAULTOPTIONS_GRAPH(options); setword workspace[50]; @@ -351,7 +352,7 @@ Last-Update: 2016-04-20 n = n1 + n2; nx = n + 1; for (i = 0; i < n; ++i) -@@ -980,18 +996,12 @@ accept2(graph *g, int n2, int x, graph * +@@ -990,18 +1006,12 @@ accept2(graph *g, int n2, int x, graph * gx[n] |= bit[i]; ++degx[i]; } @@ -373,7 +374,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,n1,n2+1); return TRUE; } -@@ -1040,12 +1050,8 @@ accept2(graph *g, int n2, int x, graph * +@@ -1050,12 +1060,8 @@ accept2(graph *g, int n2, int x, graph * { if (j0 == n) { @@ -388,7 +389,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,n1,n2+1); return TRUE; } -@@ -1096,12 +1102,8 @@ accept2(graph *g, int n2, int x, graph * +@@ -1106,12 +1112,8 @@ accept2(graph *g, int n2, int x, graph * { if (j0 == n) { @@ -403,7 +404,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,n1,n2+1); return TRUE; } -@@ -1117,12 +1119,8 @@ accept2(graph *g, int n2, int x, graph * +@@ -1127,12 +1129,8 @@ accept2(graph *g, int n2, int x, graph * return FALSE; else if (code > 0 || numcells >= nx-4) { @@ -418,7 +419,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,n1,n2+1); return TRUE; } -@@ -1133,25 +1131,19 @@ accept2(graph *g, int n2, int x, graph * +@@ -1143,25 +1141,19 @@ accept2(graph *g, int n2, int x, graph * options.defaultptn = FALSE; active[0] = 0; @@ -450,7 +451,7 @@ Last-Update: 2016-04-20 --- a/geng.c +++ b/geng.c -@@ -703,8 +703,7 @@ gcomplement(graph *g, graph *gc, int n) +@@ -698,8 +698,7 @@ gcomplement(graph *g, graph *gc, int n) /**********************************************************************/ @@ -460,7 +461,7 @@ Last-Update: 2016-04-20 /* make distance invariant return FALSE if n-1 not maximal else return TRUE */ { -@@ -734,7 +733,7 @@ distinvar(graph *g, int *invar, int n) +@@ -729,7 +728,7 @@ distinvar(graph *g, int *invar, int n) if (v < n-1 && inv > invar[n-1]) return FALSE; } return TRUE; @@ -469,7 +470,48 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -1174,9 +1173,9 @@ userautomprocb(int count, int *p, int *o +@@ -943,8 +942,7 @@ arith(xword a, xword b, xword c) + + /**************************************************************************/ + +-static void +-makeleveldata(boolean restricted) ++STATIC_POPCNTFUNC(void,makeleveldata,(boolean restricted), + /* make the level data for each level */ + { + long h; +@@ -1050,7 +1048,7 @@ makeleveldata(boolean restricted) + if (xcard[i] > xcard[i-1]) d->xstart[xcard[i]] = i; + d->xstart[xcard[nxsets-1]+1] = nxsets; + } +-} ++}) + + /**************************************************************************/ + +@@ -1101,9 +1099,9 @@ userautomproc(int count, int *p, int *or + + /**************************************************************************/ + +-static void +-userautomprocb(int count, int *p, int *orbits, +- int numorbits, int stabvertex, int n) ++STATIC_POPCNTFUNC(void, ++userautomprocb,(int count, int *p, int *orbits, ++ int numorbits, int stabvertex, int n), + /* form orbits on powerset of VG + called by nauty; operates on data[n] */ + { +@@ -1167,7 +1165,7 @@ userautomprocb(int count, int *p, int *o + if (j1 < j2) xorb[j2] = xorb[i] = xorb[pi] = j1; + else if (j1 > j2) xorb[j1] = xorb[i] = xorb[pi] = j2; + } +-} ++}) + + /***************************************************************************** + * * +@@ -1180,9 +1178,9 @@ userautomprocb(int count, int *p, int *o * * *****************************************************************************/ @@ -482,7 +524,7 @@ Last-Update: 2016-04-20 { int i,c1,c2,labc1; setword x,lact; -@@ -1307,7 +1306,7 @@ refinex(graph *g, int *lab, int *ptn, in +@@ -1313,7 +1311,7 @@ refinex(graph *g, int *lab, int *ptn, in } } } @@ -491,32 +533,179 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -1540,9 +1539,22 @@ accept1b(graph *g, int n, xword x, graph +@@ -1332,9 +1330,35 @@ makecanon(graph *g, graph *gcan, int n) } /**************************************************************************/ +#ifdef INSTRUMENT ++#define INSTRUMENTED_VAR(var) boolean var = FALSE ++#define INSTRUMENT_TRUE(var) var = TRUE +#define INSTRUMENT_VAR(var) ++var -+#define INSTRUMENT_UNIQ(var) if (nuniq) ++var ++#define INSTRUMENT_VAR_IF(var1,var2) if (var1) ++var2 +#else ++#define INSTRUMENTED_VAR(var) ++#define INSTRUMENT_TRUE(var) +#define INSTRUMENT_VAR(var) -+#define INSTRUMENT_UNIQ(var) ++#define INSTRUMENT_VAR_IF(var1,var2) +#endif -static boolean --accept2(graph *g, int n, xword x, graph *gx, int *deg, boolean nuniq) +-accept1(graph *g, int n, xword x, graph *gx, int *deg, boolean *rigid) +#ifdef PREPRUNE +#define DO_PREPRUNE(a,b,c) if (PREPRUNE(a,b,c)) return FALSE +#else +#define DO_PREPRUNE(a,b,c) +#endif + ++#ifdef PRUNE ++#define DO_PRUNE(a,b,c) if (PRUNE(a,b,c)) return ++#define PRUNE_NOT(a,b,c) if (!PRUNE(a,b,c)) ++#else ++#define DO_PRUNE(a,b,c) ++#define PRUNE_NOT(a,b,c) ++#endif ++ ++ ++STATIC_POPCNTFUNC(boolean,accept1, ++ (graph *g, int n, xword x, graph *gx, int *deg, boolean *rigid), + /* decide if n in theta(g+x) - version for n+1 < maxn */ + { + int i; +@@ -1349,9 +1373,7 @@ accept1(graph *g, int n, xword x, graph + static DEFAULTOPTIONS_GRAPH(options); + setword workspace[50]; + +-#ifdef INSTRUMENT +- ++a1calls; +-#endif ++ INSTRUMENT_VAR(a1calls); + + nx = n + 1; + for (i = 0; i < n; ++i) gx[i] = g[i]; +@@ -1368,9 +1390,7 @@ accept1(graph *g, int n, xword x, graph + ++deg[i]; + } + +-#ifdef PREPRUNE +- if (PREPRUNE(gx,n+1,maxn)) return FALSE; +-#endif ++ DO_PREPRUNE(gx,n+1,maxn); + + i0 = 0; + i1 = n; +@@ -1399,9 +1419,7 @@ accept1(graph *g, int n, xword x, graph + if (numcells == nx) + { + *rigid = TRUE; +-#ifdef INSTRUMENT +- ++a1succs; +-#endif ++ INSTRUMENT_VAR(a1succs); + return TRUE; + } + +@@ -1410,28 +1428,24 @@ accept1(graph *g, int n, xword x, graph + options.userautomproc = userautomproc; + + active[0] = 0; +-#ifdef INSTRUMENT +- ++a1nauty; +-#endif ++ INSTRUMENT_VAR(a1nauty); + nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,h); + + if (orbits[lab[n]] == orbits[n]) + { + *rigid = stats.numorbits == nx; +-#ifdef INSTRUMENT +- ++a1succs; +-#endif ++ INSTRUMENT_VAR(a1succs); + return TRUE; + } + else + return FALSE; +-} ++}) + + /**************************************************************************/ + +-static boolean +-accept1b(graph *g, int n, xword x, graph *gx, int *deg, boolean *rigid, +- void (*makeh)(graph*,xword*,int)) ++STATIC_POPCNTFUNC(boolean,accept1b, ++ (graph *g, int n, xword x, graph *gx, int *deg, boolean *rigid, ++ void (*makeh)(graph*,xword*,int)), + /* decide if n in theta(g+x) -- version for n+1 < maxn */ + { + int i,v; +@@ -1447,9 +1461,7 @@ accept1b(graph *g, int n, xword x, graph + static DEFAULTOPTIONS_GRAPH(options); + setword workspace[50]; + +-#ifdef INSTRUMENT +- ++a1calls; +-#endif ++ INSTRUMENT_VAR(a1calls); + + nx = n + 1; + for (i = 0; i < n; ++i) gx[i] = g[i]; +@@ -1466,9 +1478,7 @@ accept1b(graph *g, int n, xword x, graph + ++deg[i]; + } + +-#ifdef PREPRUNE +- if (PREPRUNE(gx,n+1,maxn)) return FALSE; +-#endif ++ DO_PREPRUNE(gx,n+1,maxn); + + i0 = 0; + i1 = n; +@@ -1517,9 +1527,7 @@ accept1b(graph *g, int n, xword x, graph + if (numcells == nx) + { + *rigid = TRUE; +-#ifdef INSTRUMENT +- ++a1succs; +-#endif ++ INSTRUMENT_VAR(a1succs); + return TRUE; + } + +@@ -1528,27 +1536,23 @@ accept1b(graph *g, int n, xword x, graph + options.userautomproc = userautomprocb; + + active[0] = 0; +-#ifdef INSTRUMENT +- ++a1nauty; +-#endif ++ INSTRUMENT_VAR(a1nauty); + nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,gc); + + if (orbits[lab[n]] == orbits[n]) + { + *rigid = stats.numorbits == nx; +-#ifdef INSTRUMENT +- ++a1succs; +-#endif ++ INSTRUMENT_VAR(a1succs); + return TRUE; + } + else + return FALSE; +-} ++}) + + /**************************************************************************/ + +-static boolean +-accept2(graph *g, int n, xword x, graph *gx, int *deg, boolean nuniq) +STATIC_POPCNTFUNC(boolean,accept2, + (graph *g, int n, xword x, graph *gx, int *deg, boolean nuniq), /* decide if n in theta(g+x) -- version for n+1 == maxn */ { int i; -@@ -1560,10 +1572,8 @@ accept2(graph *g, int n, xword x, graph +@@ -1566,10 +1570,8 @@ accept2(graph *g, int n, xword x, graph setword workspace[50]; boolean cheapacc; @@ -525,11 +714,11 @@ Last-Update: 2016-04-20 - if (nuniq) ++a2uniq; -#endif + INSTRUMENT_VAR(a2calls); -+ INSTRUMENT_UNIQ(a2uniq); ++ INSTRUMENT_VAR_IF(nuniq,a2uniq); nx = n + 1; for (i = 0; i < n; ++i) { -@@ -1583,15 +1593,11 @@ accept2(graph *g, int n, xword x, graph +@@ -1589,15 +1591,11 @@ accept2(graph *g, int n, xword x, graph ++degx[i]; } @@ -547,7 +736,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,nx); return TRUE; } -@@ -1631,9 +1637,7 @@ accept2(graph *g, int n, xword x, graph +@@ -1637,9 +1635,7 @@ accept2(graph *g, int n, xword x, graph { if (j0 == n) { @@ -558,7 +747,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,nx); return TRUE; } -@@ -1676,9 +1680,7 @@ accept2(graph *g, int n, xword x, graph +@@ -1682,9 +1678,7 @@ accept2(graph *g, int n, xword x, graph { if (j0 == n) { @@ -569,7 +758,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,nx); return TRUE; } -@@ -1718,9 +1720,7 @@ accept2(graph *g, int n, xword x, graph +@@ -1724,9 +1718,7 @@ accept2(graph *g, int n, xword x, graph if (cheapacc) { @@ -580,7 +769,7 @@ Last-Update: 2016-04-20 if (canonise) makecanon(gx,gcan,nx); return TRUE; } -@@ -1729,22 +1729,18 @@ accept2(graph *g, int n, xword x, graph +@@ -1735,22 +1727,18 @@ accept2(graph *g, int n, xword x, graph options.defaultptn = FALSE; active[0] = 0; @@ -606,9 +795,161 @@ Last-Update: 2016-04-20 /**************************************************************************/ +@@ -1795,9 +1783,9 @@ xbnds(int n, int ne, int dmax) + + /**************************************************************************/ + +-static void +-spaextend(graph *g, int n, int *deg, int ne, boolean rigid, +- int xlb, int xub, void (*makeh)(graph*,xword*,int)) ++STATIC_POPCNTFUNC(void,spaextend, ++ (graph *g, int n, int *deg, int ne, boolean rigid, ++ int xlb, int xub, void (*makeh)(graph*,xword*,int)), + /* extend from n to n+1 -- version for restricted graphs */ + { + xword x,d,dlow; +@@ -1808,12 +1796,8 @@ spaextend(graph *g, int n, int *deg, int + int degx[MAXN]; + boolean rigidx; + +-#ifdef INSTRUMENT +- boolean haschild; +- +- haschild = FALSE; +- if (rigid) ++rigidnodes[n]; +-#endif ++ INSTRUMENTED_VAR(haschild); ++ INSTRUMENT_VAR_IF(rigid,rigidnodes[n]); + ++nodes[n]; + + nx = n + 1; +@@ -1830,9 +1814,7 @@ spaextend(graph *g, int n, int *deg, int + if (nx == maxn && xlb < mindeg) xlb = mindeg; + if (xlb > xub) return; + +-#ifdef PRUNE +- if (PRUNE(g,n,maxn)) return; +-#endif ++ DO_PRUNE(g,n,maxn); + + xorb = data[n].xorb; + xx = data[n].xx; +@@ -1855,13 +1837,9 @@ spaextend(graph *g, int n, int *deg, int + (connec==1 && isconnected(gx,nx)) || + (connec>1 && isbiconnected(gx,nx)))) + { +-#ifdef PRUNE +- if (!PRUNE(gx,nx,maxn)) +-#endif ++ PRUNE_NOT(gx,nx,maxn) + { +-#ifdef INSTRUMENT +- haschild = TRUE; +-#endif ++ INSTRUMENT_TRUE(haschild); + ++ecount[ne+xc]; + (*outproc)(outfile,canonise ? gcan : gx,nx); + } +@@ -1894,9 +1872,7 @@ spaextend(graph *g, int n, int *deg, int + if (xlbx <= xubx + && accept1b(g,n,x,gx,degx,&rigidx,makeh)) + { +-#ifdef INSTRUMENT +- haschild = TRUE; +-#endif ++ INSTRUMENT_TRUE(haschild); + spaextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx,makeh); + } + } +@@ -1905,15 +1881,13 @@ spaextend(graph *g, int n, int *deg, int + && nodes[n] >= multiplicity) + --splitlevel; + } +-#ifdef INSTRUMENT +- if (haschild) ++fertilenodes[n]; +-#endif +-} ++ INSTRUMENT_VAR_IF(haschild, fertilenodes[n]); ++}) + + /**************************************************************************/ + +-static void +-genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub) ++STATIC_POPCNTFUNC(void,genextend, ++ (graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub), + /* extend from n to n+1 -- version for general graphs */ + { + xword x,d,dlow; +@@ -1925,12 +1899,8 @@ genextend(graph *g, int n, int *deg, int + int degx[MAXN]; + boolean rigidx; + +-#ifdef INSTRUMENT +- boolean haschild; +- +- haschild = FALSE; +- if (rigid) ++rigidnodes[n]; +-#endif ++ INSTRUMENTED_VAR(haschild); ++ INSTRUMENT_VAR_IF(rigid,rigidnodes[n]); + ++nodes[n]; + + nx = n + 1; +@@ -1947,9 +1917,7 @@ genextend(graph *g, int n, int *deg, int + if (nx == maxn && xlb < mindeg) xlb = mindeg; + if (xlb > xub) return; + +-#ifdef PRUNE +- if (PRUNE(g,n,maxn)) return; +-#endif ++ DO_PRUNE(g,n,maxn); + + imin = data[n].xstart[xlb]; + imax = data[n].xstart[xub+1]; +@@ -1971,13 +1939,9 @@ genextend(graph *g, int n, int *deg, int + if (!connec || (connec==1 && isconnected(gx,nx)) + || (connec>1 && isbiconnected(gx,nx))) + { +-#ifdef PRUNE +- if (!PRUNE(gx,nx,maxn)) +-#endif ++ PRUNE_NOT(gx,nx,maxn) + { +-#ifdef INSTRUMENT +- haschild = TRUE; +-#endif ++ INSTRUMENT_TRUE(haschild); + ++ecount[ne+xc]; + (*outproc)(outfile,canonise ? gcan : gx,nx); + } +@@ -2008,9 +1972,7 @@ genextend(graph *g, int n, int *deg, int + data[nx].hi = data[nx].xstart[xubx+1]; + if (accept1(g,n,x,gx,degx,&rigidx)) + { +-#ifdef INSTRUMENT +- haschild = TRUE; +-#endif ++ INSTRUMENT_TRUE(haschild); + genextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx); + } + } +@@ -2018,10 +1980,8 @@ genextend(graph *g, int n, int *deg, int + if (n == splitlevel-1 && n >= min_splitlevel + && nodes[n] >= multiplicity) + --splitlevel; +-#ifdef INSTRUMENT +- if (haschild) ++fertilenodes[n]; +-#endif +-} ++ INSTRUMENT_VAR_IF(haschild, fertilenodes[n]); ++}) + + /**************************************************************************/ + /**************************************************************************/ --- a/genquarticg.c +++ b/genquarticg.c -@@ -228,9 +228,9 @@ isbiconnected(graph *g, int n) +@@ -227,9 +227,9 @@ isbiconnected(graph *g, int n) * of the graph reaches nmax after which it is written to outputfile * ****************************************************************************/ @@ -619,9 +960,9 @@ Last-Update: 2016-04-20 + (int n, graph *g, edgestruct *edge, pairstruct *epair, int numpair, + int *epairorbit, int *multar, setword *zar, int *col00w, boolean connectflag), { - int vm1, vm2, vm3, vm4, vt1, vt2, vt3, vt4, c, b, mcol1, mcol, - tcol, got_one, i, j, k, numpair1, numdovi, maxdovi, i1, j1, i2, j2, -@@ -916,7 +916,7 @@ extend(int n, graph *g, edgestruct *edge + int vm1, vm2, vm3, vm4, vt1, vt2, vt3, vt4, c, b, mcol1, + tcol, got_one, i, j, numpair1, numdovi, maxdovi, i1, j1, i2, j2, +@@ -913,7 +913,7 @@ extend(int n, graph *g, edgestruct *edge } //end for c.. @@ -630,7 +971,7 @@ Last-Update: 2016-04-20 /***************************************************************************** * * -@@ -1160,9 +1160,9 @@ init_refinex( int *clr, int *lb, int *p, +@@ -1157,9 +1157,9 @@ init_refinex( int *clr, int *lb, int *p, * code := -1 for n-1 not max, 0 for maybe, 1 for definite * * * *****************************************************************************/ @@ -643,7 +984,7 @@ Last-Update: 2016-04-20 { int i, c1, c2, labc1, split1, split2, cell1, cell2, cnt, bmin, bmax; int workperm[MAXN], bucket[MAXN+2]; -@@ -1290,7 +1290,7 @@ refinex(graph *g, int *lab, int *ptn, in +@@ -1287,7 +1287,7 @@ refinex(graph *g, int *lab, int *ptn, in } } } @@ -821,7 +1162,7 @@ Last-Update: 2016-04-20 /* Compute degree-related graph properties. *edges = number of edges *mindeg, *mincount = minimum degree and how many there are -@@ -60,16 +60,16 @@ degstats(graph *g, int m, int n, unsigne +@@ -60,13 +60,13 @@ degstats(graph *g, int m, int n, unsigne *maxcount = maxdc; *edges = ned / 2; *eulerian = (dor & 1) == 0; @@ -830,6 +1171,24 @@ Last-Update: 2016-04-20 /**************************************************************************/ +-void +-degstats3(graph *g, int m, int n, unsigned long *edges, int *mindeg, +- int *mincount, int *maxdeg, int *maxcount, int *odddeg) ++POPCNTFUNC(void,degstats3, ++ (graph *g, int m, int n, unsigned long *edges, int *mindeg, ++ int *mincount, int *maxdeg, int *maxcount, int *odddeg), + /* Compute degree-related graph properties. + *edges = number of edges + *mindeg, *mincount = minimum degree and how many there are +@@ -119,16 +119,16 @@ degstats3(graph *g, int m, int n, unsign + *maxcount = maxdc; + *edges = ned / 2; + *odddeg = dodd; +-} ++}) + + /**************************************************************************/ + -void -degstats2(graph *g, boolean digraph, int m, int n, +POPCNTFUNC(void,degstats2, @@ -842,7 +1201,7 @@ Last-Update: 2016-04-20 /* Compute degree-related graph properties. *edges = number of edges (including loops), directed edges for digraphs *loops = number of loops -@@ -232,12 +232,11 @@ degstats2(graph *g, boolean digraph, int +@@ -300,12 +300,11 @@ degstats2(graph *g, boolean digraph, int if (indeg[i] != outdeg[i]) break; *eulerian = (i == n); } @@ -857,7 +1216,7 @@ Last-Update: 2016-04-20 /* test if g is connected (m=1) */ { setword seen,expanded,toexpand; -@@ -254,7 +253,7 @@ isconnected1(graph *g, int n) +@@ -324,7 +323,7 @@ isconnected1(graph *g, int n) } return POPCOUNT(seen) == n; @@ -866,7 +1225,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -304,24 +303,18 @@ isconnected(graph *g, int m, int n) +@@ -375,25 +374,19 @@ isconnected(graph *g, int m, int n) /**************************************************************************/ @@ -874,6 +1233,7 @@ Last-Update: 2016-04-20 -issubconnected(graph *g, set *sub, int m, int n) +POPCNTFUNC(boolean,issubconnected,(graph *g, set *sub, int m, int n), /* Test if the subset of g induced by sub is connected. Empty is connected. */ + /* Note that the value for empty subgraphs disagrees with isconnected() */ { int i,head,tail,w,subsize; set *gw; @@ -898,7 +1258,7 @@ Last-Update: 2016-04-20 subsize = 0; for (i = 0; i < m; ++i) subsize += (sub[i] ? POPCOUNT(sub[i]) : 0); -@@ -353,7 +346,7 @@ issubconnected(graph *g, set *sub, int m +@@ -425,7 +418,7 @@ issubconnected(graph *g, set *sub, int m } return tail == subsize; @@ -907,6 +1267,26 @@ Last-Update: 2016-04-20 /**********************************************************************/ +@@ -1007,8 +1000,8 @@ maxcliques(graph *g, int m, int n) + + /**************************************************************************/ + +-static void +-maxcsnode1(int *best, graph *g, setword cliq, setword cov, int maxv) ++STATIC_POPCNTFUNC(void, ++maxcsnode1,(int *best, graph *g, setword cliq, setword cov, int maxv), + /* Internal search node. cov has all the vertices outside cliq that + * cover all of cliq. maxv is the last vertex of cliq. + * *best is the largest clique known so far. +@@ -1032,7 +1025,7 @@ maxcsnode1(int *best, graph *g, setword + maxcsnode1(best,g,cliq|bit[i],cov&g[i]&~bit[i],i); + } + } +-} ++}) + + int + maxcliquesize(graph *g, int m, int n) --- a/gutil2.c +++ b/gutil2.c @@ -21,8 +21,7 @@ loopcount(graph *g, int m, int n) @@ -928,7 +1308,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -86,8 +85,7 @@ cyclecount(graph *g, int m, int n) +@@ -87,8 +86,7 @@ cyclecount(graph *g, int m, int n) /**************************************************************************/ @@ -938,7 +1318,7 @@ Last-Update: 2016-04-20 /* Number of induced paths in g starting at start, extravertices within * body and ending in last. * {start}, body and last should be disjoint. */ -@@ -108,7 +106,7 @@ indpathcount1(graph *g, int start, setwo +@@ -109,7 +107,7 @@ indpathcount1(graph *g, int start, setwo } return count; @@ -947,7 +1327,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -153,8 +151,7 @@ indcyclecount(graph *g, int m, int n) +@@ -155,8 +153,7 @@ indcyclecount(graph *g, int m, int n) /**************************************************************************/ @@ -957,7 +1337,7 @@ Last-Update: 2016-04-20 /* The number of triangles in g */ { int i,j; -@@ -174,12 +171,11 @@ numtriangles1(graph *g, int n) +@@ -176,12 +173,11 @@ numtriangles1(graph *g, int n) } return total; @@ -972,7 +1352,7 @@ Last-Update: 2016-04-20 /* The number of triangles in g */ { int i,j,k,kw; -@@ -204,7 +200,7 @@ numtriangles(graph *g, int m, int n) +@@ -206,7 +202,7 @@ numtriangles(graph *g, int m, int n) } return total; @@ -981,7 +1361,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -230,9 +226,8 @@ numdirtriangles(graph *g, int m, int n) +@@ -232,9 +228,8 @@ numdirtriangles(graph *g, int m, int n) /**************************************************************************/ @@ -993,7 +1373,7 @@ Last-Update: 2016-04-20 /* Count the common neighbours of pairs of vertices, and give the minimum and maximum for adjacent and non-adjacent vertices. Undirected only. Null minimums are n+1 and null maximums are -1. -@@ -273,7 +268,7 @@ commonnbrs(graph *g, int *minadj, int *m +@@ -281,7 +276,7 @@ commonnbrs(graph *g, int *minadj, int *m *maxadj = maxa; *minnon = minn; *maxnon = maxn; @@ -1002,7 +1382,7 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -342,8 +337,7 @@ contract1(graph *g, graph *h, int v, int +@@ -350,8 +345,7 @@ contract1(graph *g, graph *h, int v, int static TLS_ATTR int knm[18][16]; /* knm[n,m] = conncontent(K_n - m*K_2) */ static TLS_ATTR boolean knm_computed = FALSE; @@ -1012,7 +1392,7 @@ Last-Update: 2016-04-20 /* number of connected spanning subgraphs with an even number of edges minus the number with an odd number of edges */ { -@@ -403,14 +397,6 @@ conncontent(graph *g, int m, int n) +@@ -411,14 +405,6 @@ conncontent(graph *g, int m, int n) if (mindeg == 0) return 0; @@ -1027,7 +1407,7 @@ Last-Update: 2016-04-20 /* Cases of clique and near-clique */ if (mindeg == n-1) -@@ -494,7 +480,7 @@ conncontent(graph *g, int m, int n) +@@ -502,7 +488,7 @@ conncontent(graph *g, int m, int n) v2 = conncontent(h,m,n-1); return v1 - v2; @@ -1058,18 +1438,18 @@ Last-Update: 2016-04-20 /**************************************************************************/ -@@ -326,8 +326,8 @@ putdotty(FILE *f, graph *g, unsigned lon +@@ -325,8 +325,8 @@ putdotty(FILE *f, graph *g, unsigned lon /**************************************************************************/ -static void --putbliss(FILE *f, unsigned long id, graph *g, int m, int n) +-putbliss(FILE *f, unsigned long id, boolean qswitch, graph *g, int m, int n) +STATIC_POPCNTFUNC(void,putbliss, -+ (FILE *f, unsigned long id, graph *g, int m, int n), ++ (FILE *f, unsigned long id, boolean qswitch, graph *g, int m, int n), /* Write the graph in Bliss format, according to * http://www.tcs.hut.fi/Software/bliss/fileformat.shtml */ { -@@ -346,7 +346,7 @@ putbliss(FILE *f, unsigned long id, grap +@@ -346,7 +346,7 @@ putbliss(FILE *f, unsigned long id, bool for (i = 0, pg = g; i < n; ++i, pg += m) for (j = nextelement(pg,m,i); j >= 0; j = nextelement(pg,m,j)) fprintf(f,"e %d %d\n",i+1,j+1); @@ -1078,9 +1458,47 @@ Last-Update: 2016-04-20 /**************************************************************************/ +@@ -436,9 +436,8 @@ putMaple(FILE *outfile, graph *g, int li + + /**************************************************************************/ + +-static void +-putLaplacianMagma(FILE *outfile, graph *g, int linelength, +- int m, int n, long index) ++STATIC_POPCNTFUNC(void,putLaplacianMagma, ++ (FILE *outfile, graph *g, int linelength, int m, int n, long index), + { + int i,j,j0,d; + set *gi; +@@ -463,13 +462,12 @@ putLaplacianMagma(FILE *outfile, graph * + if (i < n-1) fprintf(outfile,",\n"); + else fprintf(outfile,"]);\n"); + } +-} ++}) + + /**************************************************************************/ + +-static void +-putLaplacianMaple(FILE *outfile, graph *g, int linelength, +- int m, int n, long index) ++STATIC_POPCNTFUNC(void,putLaplacianMaple, ++ (FILE *outfile, graph *g, int linelength, int m, int n, long index), + { + int i,j,d; + set *gi; +@@ -503,7 +501,7 @@ putLaplacianMaple(FILE *outfile, graph * + if (i != n-1) fprintf(outfile,",\n"); + } + fprintf(outfile,"]);\n"); +-} ++}) + + /**************************************************************************/ + /**************************************************************************/ --- a/multig.c +++ b/multig.c -@@ -442,6 +442,18 @@ scan_reg(int level, int ne, long minedge +@@ -450,6 +450,18 @@ scan_reg(int level, int ne, long minedge /**************************************************************************/ @@ -1099,7 +1517,7 @@ Last-Update: 2016-04-20 static void multi(graph *g, int nfixed, long minedges, long maxedges, long maxmult, int maxdeg, boolean lswitch, int m, int n) -@@ -469,8 +481,7 @@ multi(graph *g, int nfixed, long minedge +@@ -477,8 +489,7 @@ multi(graph *g, int nfixed, long minedge maxd = 0; for (i = 0, gi = g; i < n; ++i, gi += m) { @@ -1192,7 +1610,7 @@ Last-Update: 2016-04-20 * * --- a/nausparse.c +++ b/nausparse.c -@@ -1473,8 +1473,7 @@ copy_sg(sparsegraph *sg1, sparsegraph *s +@@ -1476,8 +1476,7 @@ copy_sg(sparsegraph *sg1, sparsegraph *s * * *****************************************************************************/ @@ -1202,7 +1620,7 @@ Last-Update: 2016-04-20 { int *d,*e; int i,k; -@@ -1512,7 +1511,7 @@ nauty_to_sg(graph *g, sparsegraph *sg, i +@@ -1515,7 +1514,7 @@ nauty_to_sg(graph *g, sparsegraph *sg, i } return sg; @@ -1604,7 +2022,7 @@ Last-Update: 2016-04-20 * * --- a/nauty-h.in +++ b/nauty-h.in -@@ -66,6 +66,7 @@ it is necessary to check they are correc +@@ -68,6 +68,7 @@ it is necessary to check they are correc #define HAVE_POPCNTLL @have_popcntll@ #define HAVE_MMPOP32 @have_mmpop32@ #define HAVE_MMPOP64 @have_mmpop64@ @@ -1612,18 +2030,9 @@ Last-Update: 2016-04-20 /*==================================================================*/ -@@ -763,7 +764,7 @@ typedef unsigned long nauty_counter; - /* Note that, unlike icc, gcc will not use the POPCNT instruction without - permission, in which case it defines __POPCNT__ . - */ --#ifdef __POPCNT__ -+#if defined(__POPCNT__) || RUNTIME_POPCNT - #if defined(SETWORD_LONGLONG) && HAVE_POPCNTLL - #undef POPCOUNT - #define POPCOUNT(x) __builtin_popcountll(x) -@@ -779,6 +780,47 @@ typedef unsigned long nauty_counter; - #endif - #endif +@@ -804,6 +805,46 @@ typedef unsigned long nauty_counter; + + #ifndef FIRSTBITNZ /* Can be defined outside */ +/* Determine popcount support at runtime */ +#if RUNTIME_POPCNT @@ -1646,20 +2055,19 @@ Last-Update: 2016-04-20 +#define POPCNTHDR(type,name,params,...) \ + SLOWPOPCNT(type,name,params,__VA_ARGS__) \ + FASTPOPCNT(type,name,params,__VA_ARGS__) \ -+ static void __attribute__((optimize ("O0"))) \ -+ (*resolve_##name (void))(void) { \ ++ static type (*resolve_##name (void)) params { \ + unsigned int eax, ebx, ecx, edx; \ + return (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && \ + (ecx & bit_POPCNT) != 0) \ -+ ? (void (*)(void))&fast_##name \ -+ : (void (*)(void))&slow_##name; \ ++ ? &fast_##name \ ++ : &slow_##name; \ + } +#define POPCNTFUNC(type,name,params,...) \ -+ POPCNTHDR(type,name,params,__VA_ARGS__) \ -+ type __attribute__((ifunc ("resolve_" #name))) name params; ++ type __attribute__((ifunc ("resolve_" #name))) name params; \ ++ POPCNTHDR(type,name,params,__VA_ARGS__) +#define STATIC_POPCNTFUNC(type,name,params,...) \ -+ POPCNTHDR(type,name,params,__VA_ARGS__) \ -+ static type __attribute__((ifunc ("resolve_" #name))) name params; ++ static type __attribute__((ifunc ("resolve_" #name))) name params; \ ++ POPCNTHDR(type,name,params,__VA_ARGS__) +#else +#define POPCNTFUNC(type,name,params,...) type name params __VA_ARGS__ +#define STATIC_POPCNTFUNC(type,name,params,...) \ @@ -1667,9 +2075,18 @@ Last-Update: 2016-04-20 +#endif + #ifdef NAUTY_IN_MAGMA - #undef POPCOUNT - #undef FIRSTBIT -@@ -1035,6 +1077,18 @@ extern void free(void*); + #define FIRSTBITNZ(x) bs_firstbit(x) + +@@ -915,7 +956,7 @@ static int msc_bsr_16(setword x) \ + + /* Note that, unlike icc, gcc will not use the POPCNT instruction + without permission, in which case it defines __POPCNT__ . */ +-#elif defined(__POPCNT__) ++#elif defined(__POPCNT__) || RUNTIME_POPCNT + #if defined(SETWORD_LONGLONG) && HAVE_POPCNTLL + #define POPCOUNT(x) __builtin_popcountll(x) + #elif defined(SETWORD_LONG) && HAVE_POPCNTL +@@ -1176,6 +1217,18 @@ extern void free(void*); #define CONDYNFREE(name,name_sz,minsz) \ if (name_sz > (size_t)(minsz)) {DYNFREE(name,name_sz);} @@ -1704,30 +2121,29 @@ Last-Update: 2016-04-20 + ne = 0; + for (gi = g + m*(size_t)n; --gi >= g; ) + ne += POPCOUNT(*gi); -+ return ne / 2; ++ return ne; +}) +#endif + +/**************************************************************************/ + static int - trythisone(grouprec *group, graph *g, int m, int n) + trythisone(grouprec *group, graph *g, boolean digraph, int m, int n) /* Try one solution, accept if maximal. */ -@@ -174,10 +190,7 @@ trythisone(grouprec *group, graph *g, in +@@ -174,9 +190,7 @@ trythisone(grouprec *group, graph *g, bo #ifdef OUTPROC OUTPROC(outfile,g,col,m,n); #else - ne = 0; - for (gi = g + m*(size_t)n; --gi >= g; ) - ne += POPCOUNT(*gi); -- ne /= 2; -+ ne = compute_degree(g,m,n); - fprintf(outfile,"%d %lu",n,(unsigned long)ne); - - for (i = 0; i < n; ++i) fprintf(outfile," %d",col[i]); ++ ne = compute_degree(g,m,n); + if (!digraph) + { + for (i = 0, gi = g; i < n; ++i, gi += m) --- a/watercluster2.c +++ b/watercluster2.c -@@ -557,7 +557,7 @@ void decode_to_nauty(unsigned char *code +@@ -593,7 +593,7 @@ void decode_to_nauty(unsigned char *code /****************************************INIT_FOR_G6*****************************/ @@ -1736,7 +2152,7 @@ Last-Update: 2016-04-20 { int i; -@@ -569,7 +569,7 @@ void init_for_g6(graph g[],int aantal_to +@@ -605,7 +605,7 @@ void init_for_g6(graph g[],int aantal_to aantal_gerichte_bogen=0; return; @@ -1745,7 +2161,7 @@ Last-Update: 2016-04-20 /***************************FILL_EDGELIST**************************/ -@@ -1202,7 +1202,8 @@ void construct_operations_in(int list[], +@@ -1238,7 +1238,8 @@ void construct_operations_in(int list[], /**********************************CONSTRUCT_EXTENSIONS**************************/ @@ -1755,7 +2171,7 @@ Last-Update: 2016-04-20 { int top, top2, j, end, list[MAXN], decided[MAXN], error, lowerlimit_outdeg, readylist[MAXN], *readyrun, dummy; int minout, do_double=0, i, mindouble; -@@ -1362,7 +1363,7 @@ for (number_operations=0; (top=(*still_o +@@ -1398,7 +1399,7 @@ for (number_operations=0; (top=(*still_o } } return; @@ -1764,7 +2180,7 @@ Last-Update: 2016-04-20 int compare_op(unsigned char *op1, unsigned char *op2) // returns 0 if operations are the same, something negative if op1 -@@ -1489,7 +1490,8 @@ void compute_edgeorbits(int edgelist[][2 +@@ -1525,7 +1526,8 @@ void compute_edgeorbits(int edgelist[][2 /******************************CANONICAL****************************/ @@ -1774,7 +2190,7 @@ Last-Update: 2016-04-20 // checks whether the operation is canonical in vertexorbit. Returns 1 if yes, 0 otherwise. // In newgroup it is stored whether a new group has been computed for this (*newgroup=1) or not -@@ -1786,7 +1788,7 @@ int canonical(unsigned char operation[], +@@ -1822,7 +1824,7 @@ int canonical(unsigned char operation[], else { return 0; } @@ -1783,7 +2199,7 @@ Last-Update: 2016-04-20 int all_diff_colours(graph testset, int orbitid) // returns 1 if all elements have some different vertex invariant and 0 otherwise -@@ -3728,7 +3730,7 @@ int test_possible(graph globalg[],int gl +@@ -3764,7 +3766,7 @@ int test_possible(graph globalg[],int gl @@ -1792,7 +2208,7 @@ Last-Update: 2016-04-20 { int i, j, k, orbitsize, start, end, fixed_edge, dummy, maxgraphdeg, biggest_orbit; BOOG kleinste_orbit[MAX_BOGEN+1]; /* het is mogelijk dat er maar 1 orbit is */ -@@ -3891,7 +3893,7 @@ void waterclusters (graph g[], int n) +@@ -3927,7 +3929,7 @@ void waterclusters (graph g[], int n) return; diff --git a/nauty-tool-prefix.patch b/nauty-tool-prefix.patch index 27b7524..5c9f2f7 100644 --- a/nauty-tool-prefix.patch +++ b/nauty-tool-prefix.patch @@ -1,16 +1,17 @@ Description: debianization: nauty tools suite prefix Prepend nauty- to the names of the nauty tools, named gtools. Author: Jerome Benoit -Last-Update: 2016-03-19 +Last-Update: 2017-11-24 --- a/Makefile.am +++ b/Makefile.am -@@ -21,94 +21,94 @@ +@@ -25,100 +25,100 @@ bin_PROGRAMS = \ dreadnaut \ \ - addedgeg \ - amtog \ +- assembleg \ - biplabg \ - catg \ - complg \ @@ -23,6 +24,7 @@ Last-Update: 2016-03-19 - directg \ - dretodot \ - dretog \ +- edgetransg \ - genbg \ - genbgL \ - geng \ @@ -45,10 +47,12 @@ Last-Update: 2016-03-19 - showg \ - subdivideg \ - twohamg \ +- underlyingg \ - vcolg \ - watercluster2 \ + nauty-addedgeg \ + nauty-amtog \ ++ nauty-assembleg \ + nauty-biplabg \ + nauty-catg \ + nauty-complg \ @@ -61,6 +65,7 @@ Last-Update: 2016-03-19 + nauty-directg \ + nauty-dretodot \ + nauty-dretog \ ++ nauty-edgetransg \ + nauty-genbg \ + nauty-genbgL \ + nauty-geng \ @@ -83,6 +88,7 @@ Last-Update: 2016-03-19 + nauty-showg \ + nauty-subdivideg \ + nauty-twohamg \ ++ nauty-underlyingg \ + nauty-vcolg \ + nauty-watercluster2 \ \ @@ -98,6 +104,7 @@ Last-Update: 2016-03-19 \ - addedgeg.1 \ - amtog.1 \ +- assembleg.1 \ - biplabg.1 \ - catg.1 \ - complg.1 \ @@ -110,6 +117,7 @@ Last-Update: 2016-03-19 - directg.1 \ - dretodot.1 \ - dretog.1 \ +- edgetransg.1 \ - genbg.1 \ - genbgL.1 \ - geng.1 \ @@ -132,10 +140,12 @@ Last-Update: 2016-03-19 - showg.1 \ - subdivideg.1 \ - twohamg.1 \ +- underlyingg.1 \ - vcolg.1 \ - watercluster2.1 \ + nauty-addedgeg.1 \ + nauty-amtog.1 \ ++ nauty-assembleg.1 \ + nauty-biplabg.1 \ + nauty-catg.1 \ + nauty-complg.1 \ @@ -148,6 +158,7 @@ Last-Update: 2016-03-19 + nauty-directg.1 \ + nauty-dretodot.1 \ + nauty-dretog.1 \ ++ nauty-edgetransg.1 \ + nauty-genbg.1 \ + nauty-genbgL.1 \ + nauty-geng.1 \ @@ -170,6 +181,7 @@ Last-Update: 2016-03-19 + nauty-showg.1 \ + nauty-subdivideg.1 \ + nauty-twohamg.1 \ ++ nauty-underlyingg.1 \ + nauty-vcolg.1 \ + nauty-watercluster2.1 \ \ @@ -182,8 +194,8 @@ Last-Update: 2016-03-19 lib_LTLIBRARIES = \ libnauty.la \ -@@ -153,8 +153,8 @@ - $(HELP2MAN) \ +@@ -166,8 +166,8 @@ + LD_LIBRARY_PATH=$(top_builddir)/.libs $(HELP2MAN) \ -s 1 \ $(AM_H2MFLAGS) \ - -I $(top_srcdir)/man/$*.h2m \ @@ -193,12 +205,14 @@ Last-Update: 2016-03-19 -o $@ \ $(top_builddir)/$< -@@ -175,176 +175,176 @@ +@@ -187,189 +187,189 @@ + ## short descriptions inspired from the basic functions of the programs as described ## in section `Utilities' (15) of the `Nauty and Traces User's Guide' (version 2.6) - dreadnaut_DESCRIPTION = "command line interface to nauty graph isomorphism library" +-dreadnaut_DESCRIPTION = "command line interface to nauty graph isomorphism library" -addedgeg_DESCRIPTION = "add an edge in each possible way" -amtog_DESCRIPTION = "read graphs in matrix format" +-assembleg_DESCRIPTION = "assemble input graphs as components of output graphs" -biplabg_DESCRIPTION = "label bipartite graphs so the colour classes are contiguous" -catg_DESCRIPTION = "concatenate files of graphs" -complg_DESCRIPTION = "complement graphs" @@ -211,6 +225,7 @@ Last-Update: 2016-03-19 -directg_DESCRIPTION = "generate small digraphs with given underlying graph" -dretodot_DESCRIPTION = "read graphs and initial coloring in dreadnaut format and write in dot format" -dretog_DESCRIPTION = "read graphs in dreadnaut format" +-edgetransg_DESCRIPTION = "select undirected graphs according to group action on vertices, edges and arcs" -genbg_DESCRIPTION = "generate small bicoloured graphs" -genbgL_DESCRIPTION = "$(shell printf "%s %s" $(genbg_DESCRIPTION) "(L1 flavour)")" -geng_DESCRIPTION = "generate small graphs" @@ -233,13 +248,16 @@ Last-Update: 2016-03-19 -showg_DESCRIPTION = "$(shell printf "%s %s" $(listg_DESCRIPTION) "(stand-alone subset of listg)")" -subdivideg_DESCRIPTION = "compute the subdivision graphs of a file of graphs" -twohamg_DESCRIPTION = "split quartic graphs into two hamiltonian cycles" +-underlyingg_DESCRIPTION = "take the underlying undirected graphs of a file of graphs" -vcolg_DESCRIPTION = "colour the vertices of graphs in all distinct ways" -watercluster2_DESCRIPTION = "$(shell printf "%s %s" $(directg_DESCRIPTION) "(faster alternative to directg)")" -blisstog_DESCRIPTION = "convert files of graphs in bliss format to stdout in sparse6 format" -checks6_DESCRIPTION = "check a file of graphs and optionally perform corrections" -sumlines_DESCRIPTION = "sum lines matching specified graph formats" ++dreadnaut_DESCRIPTION = "command line interface to nauty graph isomorphism library" +nauty_addedgeg_DESCRIPTION = "add an edge in each possible way" +nauty_amtog_DESCRIPTION = "read graphs in matrix format" ++nauty_assembleg_DESCRIPTION = "assemble input graphs as components of output graphs" +nauty_biplabg_DESCRIPTION = "label bipartite graphs so the colour classes are contiguous" +nauty_catg_DESCRIPTION = "concatenate files of graphs" +nauty_complg_DESCRIPTION = "complement graphs" @@ -252,8 +270,9 @@ Last-Update: 2016-03-19 +nauty_directg_DESCRIPTION = "generate small digraphs with given underlying graph" +nauty_dretodot_DESCRIPTION = "read graphs and initial coloring in dreadnaut format and write in dot format" +nauty_dretog_DESCRIPTION = "read graphs in dreadnaut format" ++nauty_edgetransg_DESCRIPTION = "select undirected graphs according to group action on vertices, edges and arcs" +nauty_genbg_DESCRIPTION = "generate small bicoloured graphs" -+nauty_genbgL_DESCRIPTION = "$(shell printf "%s %s" $(nauty_genbg_DESCRIPTION) "(L1 flavour)")" ++nauty_genbgL_DESCRIPTION = "$(shell printf "%s %s" $(genbg_DESCRIPTION) "(L1 flavour)")" +nauty_geng_DESCRIPTION = "generate small graphs" +nauty_genquarticg_DESCRIPTION = "generate quartic graphs" +nauty_genrang_DESCRIPTION = "generate random graphs" @@ -271,11 +290,12 @@ Last-Update: 2016-03-19 +nauty_planarg_DESCRIPTION = "test graphs for planarity and find embeddings or obstructions" +nauty_ranlabg_DESCRIPTION = "randomly relabel graphs" +nauty_shortg_DESCRIPTION = "remove isomorphs from a file of graphs" -+nauty_showg_DESCRIPTION = "$(shell printf "%s %s" $(nauty_listg_DESCRIPTION) "(stand-alone subset of listg)")" ++nauty_showg_DESCRIPTION = "$(shell printf "%s %s" $(listg_DESCRIPTION) "(stand-alone subset of listg)")" +nauty_subdivideg_DESCRIPTION = "compute the subdivision graphs of a file of graphs" +nauty_twohamg_DESCRIPTION = "split quartic graphs into two hamiltonian cycles" ++nauty_underlyingg_DESCRIPTION = "take the underlying undirected graphs of a file of graphs" +nauty_vcolg_DESCRIPTION = "colour the vertices of graphs in all distinct ways" -+nauty_watercluster2_DESCRIPTION = "$(shell printf "%s %s" $(nauty_directg_DESCRIPTION) "(faster alternative to directg)")" ++nauty_watercluster2_DESCRIPTION = "$(shell printf "%s %s" $(directg_DESCRIPTION) "(faster alternative to directg)")" +nauty_blisstog_DESCRIPTION = "convert files of graphs in bliss format to stdout in sparse6 format" +nauty_checks6_DESCRIPTION = "check a file of graphs and optionally perform corrections" +nauty_sumlines_DESCRIPTION = "sum lines matching specified graph formats" @@ -283,6 +303,7 @@ Last-Update: 2016-03-19 dreadnaut_CPPFLAGS = -addedgeg_CPPFLAGS = -amtog_CPPFLAGS = +-assembleg_CPPFLAGS = -biplabg_CPPFLAGS = -catg_CPPFLAGS = -complg_CPPFLAGS = @@ -295,6 +316,7 @@ Last-Update: 2016-03-19 -directg_CPPFLAGS = -dretodot_CPPFLAGS = -dretog_CPPFLAGS = +-edgetransg_CPPFLAGS = -genbg_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) -genbgL_CPPFLAGS = $(nautyL1_flavour_CPPFLAGS) -DMAXN1=30 -geng_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) @@ -317,6 +339,7 @@ Last-Update: 2016-03-19 -showg_CPPFLAGS = -subdivideg_CPPFLAGS = -twohamg_CPPFLAGS = +-underlyingg_CPPFLAGS = -vcolg_CPPFLAGS = -watercluster2_CPPFLAGS = -DMAXN=32 -blisstog_CPPFLAGS = $(ZLIB_CFLAGS) @@ -324,6 +347,7 @@ Last-Update: 2016-03-19 -sumlines_CPPFLAGS = $(GMP_CFLAGS) +nauty_addedgeg_CPPFLAGS = +nauty_amtog_CPPFLAGS = ++nauty_assembleg_CPPFLAGS = +nauty_biplabg_CPPFLAGS = +nauty_catg_CPPFLAGS = +nauty_complg_CPPFLAGS = @@ -336,6 +360,7 @@ Last-Update: 2016-03-19 +nauty_directg_CPPFLAGS = +nauty_dretodot_CPPFLAGS = +nauty_dretog_CPPFLAGS = ++nauty_edgetransg_CPPFLAGS = +nauty_genbg_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) +nauty_genbgL_CPPFLAGS = $(nautyL1_flavour_CPPFLAGS) -DMAXN1=30 +nauty_geng_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) @@ -358,6 +383,7 @@ Last-Update: 2016-03-19 +nauty_showg_CPPFLAGS = +nauty_subdivideg_CPPFLAGS = +nauty_twohamg_CPPFLAGS = ++nauty_underlyingg_CPPFLAGS = +nauty_vcolg_CPPFLAGS = +nauty_watercluster2_CPPFLAGS = -DMAXN=32 +nauty_blisstog_CPPFLAGS = $(ZLIB_CFLAGS) @@ -367,6 +393,7 @@ Last-Update: 2016-03-19 dreadnaut_SOURCES = dreadnaut.c -addedgeg_SOURCES = addedgeg.c -amtog_SOURCES = amtog.c +-assembleg_SOURCES = assembleg.c -biplabg_SOURCES = biplabg.c -catg_SOURCES = catg.c -complg_SOURCES = complg.c @@ -379,6 +406,7 @@ Last-Update: 2016-03-19 -directg_SOURCES = directg.c -dretodot_SOURCES = dretodot.c -dretog_SOURCES = dretog.c +-edgetransg_SOURCES = edgetransg.c -genbg_SOURCES = genbg.c -genbgL_SOURCES = genbg.c -geng_SOURCES = geng.c @@ -401,6 +429,7 @@ Last-Update: 2016-03-19 -showg_SOURCES = showg.c -subdivideg_SOURCES = subdivideg.c -twohamg_SOURCES = twohamg.c +-underlyingg_SOURCES = underlyingg.c -vcolg_SOURCES = vcolg.c -watercluster2_SOURCES = watercluster2.c -blisstog_SOURCES = blisstog.c @@ -408,6 +437,7 @@ Last-Update: 2016-03-19 -sumlines_SOURCES = sumlines.c +nauty_addedgeg_SOURCES = addedgeg.c +nauty_amtog_SOURCES = amtog.c ++nauty_assembleg_SOURCES = assembleg.c +nauty_biplabg_SOURCES = biplabg.c +nauty_catg_SOURCES = catg.c +nauty_complg_SOURCES = complg.c @@ -420,6 +450,7 @@ Last-Update: 2016-03-19 +nauty_directg_SOURCES = directg.c +nauty_dretodot_SOURCES = dretodot.c +nauty_dretog_SOURCES = dretog.c ++nauty_edgetransg_SOURCES = edgetransg.c +nauty_genbg_SOURCES = genbg.c +nauty_genbgL_SOURCES = genbg.c +nauty_geng_SOURCES = geng.c @@ -442,15 +473,17 @@ Last-Update: 2016-03-19 +nauty_showg_SOURCES = showg.c +nauty_subdivideg_SOURCES = subdivideg.c +nauty_twohamg_SOURCES = twohamg.c ++nauty_underlyingg_SOURCES = underlyingg.c +nauty_vcolg_SOURCES = vcolg.c +nauty_watercluster2_SOURCES = watercluster2.c +nauty_blisstog_SOURCES = blisstog.c +nauty_checks6_SOURCES = checks6.c +nauty_sumlines_SOURCES = sumlines.c - dreadnaut_LDADD = $(NAUTY_LDADD) +-dreadnaut_LDADD = $(NAUTY_LDADD) -addedgeg_LDADD = $(NAUTY_LDADD) -amtog_LDADD = $(NAUTY_LDADD) +-assembleg_LDADD = $(NAUTY_LDADD) -biplabg_LDADD = $(NAUTY_LDADD) -catg_LDADD = $(NAUTY_LDADD) -complg_LDADD = $(NAUTY_LDADD) @@ -463,6 +496,7 @@ Last-Update: 2016-03-19 -directg_LDADD = $(NAUTY_LDADD) -dretodot_LDADD = $(NAUTY_LDADD) $(LIBM) -dretog_LDADD = $(NAUTY_LDADD) +-edgetransg_LDADD = $(NAUTY_LDADD) -genbg_LDADD = $(NAUTYW1_LDADD) -genbgL_LDADD = $(NAUTYL1_LDADD) -geng_LDADD = $(NAUTYW1_LDADD) @@ -485,13 +519,16 @@ Last-Update: 2016-03-19 -showg_LDADD = -subdivideg_LDADD = $(NAUTY_LDADD) -twohamg_LDADD = $(NAUTY_LDADD) +-underlyingg_LDADD = $(NAUTY_LDADD) -vcolg_LDADD = $(NAUTY_LDADD) -watercluster2_LDADD = $(NAUTY_LDADD) -blisstog_LDADD = $(NAUTY_LDADD) $(ZLIB_LIBS) -checks6_LDADD = $(NAUTY_LDADD) -sumlines_LDADD = $(GMP_LIBS) ++dreadnaut_LDADD = $(NAUTY_LDADD) +nauty_addedgeg_LDADD = $(NAUTY_LDADD) +nauty_amtog_LDADD = $(NAUTY_LDADD) ++nauty_assembleg_LDADD = $(NAUTY_LDADD) +nauty_biplabg_LDADD = $(NAUTY_LDADD) +nauty_catg_LDADD = $(NAUTY_LDADD) +nauty_complg_LDADD = $(NAUTY_LDADD) @@ -504,6 +541,7 @@ Last-Update: 2016-03-19 +nauty_directg_LDADD = $(NAUTY_LDADD) +nauty_dretodot_LDADD = $(NAUTY_LDADD) $(LIBM) +nauty_dretog_LDADD = $(NAUTY_LDADD) ++nauty_edgetransg_LDADD = $(NAUTY_LDADD) +nauty_genbg_LDADD = $(NAUTYW1_LDADD) +nauty_genbgL_LDADD = $(NAUTYL1_LDADD) +nauty_geng_LDADD = $(NAUTYW1_LDADD) @@ -526,6 +564,7 @@ Last-Update: 2016-03-19 +nauty_showg_LDADD = +nauty_subdivideg_LDADD = $(NAUTY_LDADD) +nauty_twohamg_LDADD = $(NAUTY_LDADD) ++nauty_underlyingg_LDADD = $(NAUTY_LDADD) +nauty_vcolg_LDADD = $(NAUTY_LDADD) +nauty_watercluster2_LDADD = $(NAUTY_LDADD) +nauty_blisstog_LDADD = $(NAUTY_LDADD) $(ZLIB_LIBS) @@ -536,7 +575,7 @@ Last-Update: 2016-03-19 libnautyA1_la_MAP = --- a/runalltests +++ b/runalltests -@@ -30,7 +30,7 @@ +@@ -31,7 +31,7 @@ eval $cmd <"$in" 2>$out2 >$out1 if [ -d $top_workingdir/.libs ]; then @@ -544,8 +583,8 @@ Last-Update: 2016-03-19 + sed -i 's@'$top_workingdir'/.libs/lt-nauty-@./@' $out2 fi - LC_COLLATE=C sort $out2 >>$out1 -@@ -82,13 +82,13 @@ + LC_LANG=C sort $out2 >>$out1 +@@ -100,13 +100,13 @@ runonetest ./dreadtest4K nautest2.dre nautest2a.ans runonetest "./dreadtest4K -o As" nautest2.dre nautest2b.ans diff --git a/nauty-unbundle-cliquer.patch b/nauty-unbundle-cliquer.patch new file mode 100644 index 0000000..9b9a655 --- /dev/null +++ b/nauty-unbundle-cliquer.patch @@ -0,0 +1,3325 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -152,9 +152,9 @@ + AM_LDFLAGS = + LDADD = + +-NAUTY_LDADD = $(top_builddir)/libnauty.la $(threadlib) +-NAUTYW1_LDADD = $(top_builddir)/libnautyW1.la $(threadlib) +-NAUTYL1_LDADD = $(top_builddir)/libnautyL1.la $(threadlib) ++NAUTY_LDADD = $(top_builddir)/libnauty.la -lcliquer $(threadlib) ++NAUTYW1_LDADD = $(top_builddir)/libnautyW1.la -lcliquer $(threadlib) ++NAUTYL1_LDADD = $(top_builddir)/libnautyL1.la -lcliquer $(threadlib) + + AM_H2MFLAGS = \ + --manual="Nauty Manual" \ +@@ -404,7 +404,7 @@ + libnautyL1_la_LD_VERSION_SCRIPT += -Wl,--version-script=$(top_builddir)/$(libnautyL1_la_MAP) + endif + +-libnauty_la_LIBADD = $(threadlib) ++libnauty_la_LIBADD = -lcliquer $(threadlib) + libnauty_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnauty_la_LD_VERSION_SCRIPT) + + libnauty_la_SOURCES = \ +@@ -427,43 +427,43 @@ + + libnautyA1_la_DEPENDENCIES = $(libnautyA1_la_MAP) + libnautyA1_la_CPPFLAGS = $(nautyA1_flavour_CPPFLAGS) +-libnautyA1_la_LIBADD = $(threadlib) ++libnautyA1_la_LIBADD = -lcliquer $(threadlib) + libnautyA1_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyA1_la_LD_VERSION_SCRIPT) + libnautyA1_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyS0_la_DEPENDENCIES = $(libnautyS0_la_MAP) + libnautyS0_la_CPPFLAGS = $(nautyS0_flavour_CPPFLAGS) +-libnautyS0_la_LIBADD = $(threadlib) ++libnautyS0_la_LIBADD = -lcliquer $(threadlib) + libnautyS0_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyS0_la_LD_VERSION_SCRIPT) + libnautyS0_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyS1_la_DEPENDENCIES = $(libnautyS1_la_MAP) + libnautyS1_la_CPPFLAGS = $(nautyS1_flavour_CPPFLAGS) +-libnautyS1_la_LIBADD = $(threadlib) ++libnautyS1_la_LIBADD = -lcliquer $(threadlib) + libnautyS1_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyS1_la_LD_VERSION_SCRIPT) + libnautyS1_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyW0_la_DEPENDENCIES = $(libnautyW0_la_MAP) + libnautyW0_la_CPPFLAGS = $(nautyW0_flavour_CPPFLAGS) +-libnautyW0_la_LIBADD = $(threadlib) ++libnautyW0_la_LIBADD = -lcliquer $(threadlib) + libnautyW0_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyW0_la_LD_VERSION_SCRIPT) + libnautyW0_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyW1_la_DEPENDENCIES = $(libnautyW1_la_MAP) + libnautyW1_la_CPPFLAGS = $(nautyW1_flavour_CPPFLAGS) +-libnautyW1_la_LIBADD = $(threadlib) ++libnautyW1_la_LIBADD = -lcliquer $(threadlib) + libnautyW1_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyW1_la_LD_VERSION_SCRIPT) + libnautyW1_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyL0_la_DEPENDENCIES = $(libnautyL0_la_MAP) + libnautyL0_la_CPPFLAGS = $(nautyL0_flavour_CPPFLAGS) +-libnautyL0_la_LIBADD = $(threadlib) ++libnautyL0_la_LIBADD = -lcliquer $(threadlib) + libnautyL0_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyL0_la_LD_VERSION_SCRIPT) + libnautyL0_la_SOURCES =$(libnauty_la_SOURCES) + + libnautyL1_la_DEPENDENCIES = $(libnautyL1_la_MAP) + libnautyL1_la_CPPFLAGS = $(nautyL1_flavour_CPPFLAGS) +-libnautyL1_la_LIBADD = $(threadlib) ++libnautyL1_la_LIBADD = -lcliquer $(threadlib) + libnautyL1_la_LDFLAGS = -version-info $(LIBNAUTY_LT_VERSION) $(libnautyL1_la_LD_VERSION_SCRIPT) + libnautyL1_la_SOURCES =$(libnauty_la_SOURCES) + +@@ -494,17 +494,17 @@ + nautestL_SOURCES = nauty.h naututil.h nautest.c + + dreadtest_LDADD = $(NAUTY_LDADD) +-dreadtest1_LDADD = $(top_builddir)/libnautyA1.la $(threadlib) +-dreadtestS_LDADD = $(top_builddir)/libnautyS0.la $(threadlib) +-dreadtestS1_LDADD = $(top_builddir)/libnautyS1.la $(threadlib) +-dreadtestW_LDADD = $(top_builddir)/libnautyW0.la $(threadlib) +-dreadtestW1_LDADD = $(top_builddir)/libnautyW1.la $(threadlib) +-dreadtestL_LDADD = $(top_builddir)/libnautyL0.la $(threadlib) +-dreadtestL1_LDADD = $(top_builddir)/libnautyL1.la $(threadlib) +-dreadtest4K_LDADD = $(threadlib) +-nautestS_LDADD = $(top_builddir)/libnautyS0.la $(threadlib) +-nautestW_LDADD = $(top_builddir)/libnautyW0.la $(threadlib) +-nautestL_LDADD = $(top_builddir)/libnautyL0.la $(threadlib) ++dreadtest1_LDADD = $(top_builddir)/libnautyA1.la -lcliquer $(threadlib) ++dreadtestS_LDADD = $(top_builddir)/libnautyS0.la -lcliquer $(threadlib) ++dreadtestS1_LDADD = $(top_builddir)/libnautyS1.la -lcliquer $(threadlib) ++dreadtestW_LDADD = $(top_builddir)/libnautyW0.la -lcliquer $(threadlib) ++dreadtestW1_LDADD = $(top_builddir)/libnautyW1.la -lcliquer $(threadlib) ++dreadtestL_LDADD = $(top_builddir)/libnautyL0.la -lcliquer $(threadlib) ++dreadtestL1_LDADD = $(top_builddir)/libnautyL1.la -lcliquer $(threadlib) ++dreadtest4K_LDADD = -lcliquer $(threadlib) ++nautestS_LDADD = $(top_builddir)/libnautyS0.la -lcliquer $(threadlib) ++nautestW_LDADD = $(top_builddir)/libnautyW0.la -lcliquer $(threadlib) ++nautestL_LDADD = $(top_builddir)/libnautyL0.la -lcliquer $(threadlib) + + CLEANFILES = \ + $(man_MANS) \ +--- a/nautycliquer.c ++++ b/nautycliquer.c +@@ -18,2577 +18,6 @@ + + #include "nautycliquer.h" + +-/* +- * This file contains the clique searching routines. +- * +- * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. +- * Licensed under the GNU GPL, read the file LICENSE for details. +- * This version covered by nauty&Traces licence, see file COPYRIGHT. +- */ +- +-/* +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "cliquer.h" +-*/ +- +- +-/* Default cliquer options */ +-static clique_options clique_default_options_struct = { +- reorder_by_default, NULL, clique_print_time, NULL, NULL, NULL, NULL, 0 +-}; +-clique_options *clique_default_options=&clique_default_options_struct; +- +- +-/* Calculate d/q, rounding result upwards/downwards. */ +-#define DIV_UP(d,q) (((d)+(q)-1)/(q)) +-#define DIV_DOWN(d,q) ((int)((d)/(q))) +- +- +-/* Global variables used: */ +-/* These must be saved and restored in re-entrance. */ +-static int *clique_size; /* c[i] == max. clique size in {0,1,...,i-1} */ +-static set_t current_clique; /* Current clique being searched. */ +-static set_t best_clique; /* Largest/heaviest clique found so far. */ +-#if 0 +-static struct tms cputimer; /* Timer for opts->time_function() */ +-static struct timeval realtimer; /* Timer for opts->time_function() */ +-#endif +-static int clique_list_count=0; /* No. of cliques in opts->clique_list[] */ +-static int weight_multiplier=1; /* Weights multiplied by this when passing +- * to time_function(). */ +- +-/* List cache (contains memory blocks of size g->n * sizeof(int)) */ +-static int **temp_list=NULL; +-static int temp_count=0; +- +- +-/* +- * Macros for re-entrance. ENTRANCE_SAVE() must be called immediately +- * after variable definitions, ENTRANCE_RESTORE() restores global +- * variables to original values. entrance_level should be increased +- * and decreased accordingly. +- */ +-static int entrance_level=0; /* How many levels for entrance have occurred? */ +- +-#define ENTRANCE_SAVE() \ +-int *old_clique_size = clique_size; \ +-set_t old_current_clique = current_clique; \ +-set_t old_best_clique = best_clique; \ +-int old_clique_list_count = clique_list_count; \ +-int old_weight_multiplier = weight_multiplier; \ +-int **old_temp_list = temp_list; \ +-int old_temp_count = temp_count; +-/* +-struct tms old_cputimer; \ +-struct timeval old_realtimer; \ +-memcpy(&old_cputimer,&cputimer,sizeof(struct tms)); \ +-memcpy(&old_realtimer,&realtimer,sizeof(struct timeval)) +-*/ +- +-#define ENTRANCE_RESTORE() \ +-clique_size = old_clique_size; \ +-current_clique = old_current_clique; \ +-best_clique = old_best_clique; \ +-clique_list_count = old_clique_list_count; \ +-weight_multiplier = old_weight_multiplier; \ +-temp_list = old_temp_list; +-/* +-temp_count = old_temp_count; \ +-memcpy(&cputimer,&old_cputimer,sizeof(struct tms)); \ +-memcpy(&realtimer,&old_realtimer,sizeof(struct timeval)); +-temp_count = old_temp_count; +-*/ +- +- +-/* Number of clock ticks per second (as returned by sysconf(_SC_CLK_TCK)) */ +-static int clocks_per_sec=0; +- +- +- +-/* Recursion and helper functions */ +-static boolean sub_unweighted_single(int *table, int size, int min_size, +- graph_t *g); +-static int sub_unweighted_all(int *table, int size, int min_size, int max_size, +- boolean maximal, graph_t *g, +- clique_options *opts); +-static int sub_weighted_all(int *table, int size, int weight, +- int current_weight, int prune_low, int prune_high, +- int min_weight, int max_weight, boolean maximal, +- graph_t *g, clique_options *opts); +- +- +-static boolean store_clique(set_t clique, graph_t *g, clique_options *opts); +-static boolean is_maximal(set_t clique, graph_t *g); +-static boolean false_function(set_t clique,graph_t *g,clique_options *opts); +- +- +- +- +- +-/***** Unweighted searches *****/ +-/* +- * Unweighted searches are done separately from weighted searches because +- * some effective pruning methods can be used when the vertex weights +- * are all 1. Single and all clique finding routines are separated, +- * because the single clique finding routine can store the found clique +- * while it is returning from the recursion, thus requiring no implicit +- * storing of the current clique. When searching for all cliques the +- * current clique must be stored. +- */ +- +- +-/* +- * unweighted_clique_search_single() +- * +- * Searches for a single clique of size min_size. Stores maximum clique +- * sizes into clique_size[]. +- * +- * table - the order of the vertices in g to use +- * min_size - minimum size of clique to search for. If min_size==0, +- * searches for a maximum clique. +- * g - the graph +- * opts - time printing options +- * +- * opts->time_function is called after each base-level recursion, if +- * non-NULL. (NOT IN THIS VERSION) +- * +- * Returns the size of the clique found, or 0 if min_size>0 and a clique +- * of that size was not found (or if time_function aborted the search). +- * The largest clique found is stored in current_clique. +- * +- * Note: Does NOT use opts->user_function of opts->clique_list. +- */ +-static int unweighted_clique_search_single(int *table, int min_size, +- graph_t *g, clique_options *opts) { +-#if 0 +- struct tms tms; +- struct timeval timeval; +-#endif +- int i,j; +- int v,w; +- int *newtable; +- int newsize; +- +- v=table[0]; +- clique_size[v]=1; +- set_empty(current_clique); +- SET_ADD_ELEMENT(current_clique,v); +- if (min_size==1) +- return 1; +- +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- for (i=1; i < g->n; i++) { +- w=v; +- v=table[i]; +- +- newsize=0; +- for (j=0; jtime_function) { +- gettimeofday(&timeval,NULL); +- times(&tms); +- if (!opts->time_function(entrance_level, +- i+1,g->n,clique_size[v] * +- weight_multiplier, +- (double)(tms.tms_utime- +- cputimer.tms_utime)/ +- clocks_per_sec, +- timeval.tv_sec- +- realtimer.tv_sec+ +- (double)(timeval.tv_usec- +- realtimer.tv_usec)/ +- 1000000,opts)) { +- temp_list[temp_count++]=newtable; +- return 0; +- } +- } +-#endif +- +- if (min_size) { +- if (clique_size[v]>=min_size) { +- temp_list[temp_count++]=newtable; +- return clique_size[v]; +- } +- if (clique_size[v]+g->n-i-1 < min_size) { +- temp_list[temp_count++]=newtable; +- return 0; +- } +- } +- } +- +- temp_list[temp_count++]=newtable; +- +- if (min_size) +- return 0; +- return clique_size[v]; +-} +- +-/* +- * sub_unweighted_single() +- * +- * Recursion function for searching for a single clique of size min_size. +- * +- * table - subset of the vertices in graph +- * size - size of table +- * min_size - size of clique to look for within the subgraph +- * (decreased with every recursion) +- * g - the graph +- * +- * Returns TRUE if a clique of size min_size is found, FALSE otherwise. +- * If a clique of size min_size is found, it is stored in current_clique. +- * +- * clique_size[] for all values in table must be defined and correct, +- * otherwise inaccurate results may occur. +- */ +-static boolean sub_unweighted_single(int *table, int size, int min_size, +- graph_t *g) { +- int i; +- int v; +- int *newtable; +- int *p1, *p2; +- +- /* Zero or one vertices needed anymore. */ +- if (min_size <= 1) { +- if (size>0 && min_size==1) { +- set_empty(current_clique); +- SET_ADD_ELEMENT(current_clique,table[0]); +- return TRUE; +- } +- if (min_size==0) { +- set_empty(current_clique); +- return TRUE; +- } +- return FALSE; +- } +- if (size < min_size) +- return FALSE; +- +- /* Dynamic memory allocation with cache */ +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- for (i = size-1; i >= 0; i--) { +- v = table[i]; +- +- if (clique_size[v] < min_size) +- break; +- /* This is faster when compiling with gcc than placing +- * this in the for-loop condition. */ +- if (i+1 < min_size) +- break; +- +- /* Very ugly code, but works faster than "for (i=...)" */ +- p1 = newtable; +- for (p2=table; p2 < table+i; p2++) { +- int w = *p2; +- if (GRAPH_IS_EDGE(g, v, w)) { +- *p1 = w; +- p1++; +- } +- } +- +- /* Avoid unneccessary loops (next size == p1-newtable) */ +- if (p1-newtable < min_size-1) +- continue; +- /* Now p1-newtable >= min_size-1 >= 2-1 == 1, so we can use +- * p1-newtable-1 safely. */ +- if (clique_size[newtable[p1-newtable-1]] < min_size-1) +- continue; +- +- if (sub_unweighted_single(newtable,p1-newtable, +- min_size-1,g)) { +- /* Clique found. */ +- SET_ADD_ELEMENT(current_clique,v); +- temp_list[temp_count++]=newtable; +- return TRUE; +- } +- } +- temp_list[temp_count++]=newtable; +- return FALSE; +-} +- +- +-/* +- * unweighted_clique_search_all() +- * +- * Searches for all cliques with size at least min_size and at most +- * max_size. Stores the cliques as opts declares. +- * +- * table - the order of the vertices in g to search +- * start - first index where the subgraph table[0], ..., table[start] +- * might include a requested kind of clique +- * min_size - minimum size of clique to search for. min_size > 0 ! +- * max_size - maximum size of clique to search for. If no upper limit +- * is desired, use eg. INT_MAX +- * maximal - requires cliques to be maximal +- * g - the graph +- * opts - time printing and clique storage options +- * +- * Cliques found are stored as defined by opts->user_function and +- * opts->clique_list. opts->time_function is called after each +- * base-level recursion, if non-NULL. +- * +- * clique_size[] must be defined and correct for all values of +- * table[0], ..., table[start-1]. +- * +- * Returns the number of cliques stored (not neccessarily number of cliques +- * in graph, if user/time_function aborts). +- */ +-static int unweighted_clique_search_all(int *table, int start, +- int min_size, int max_size, +- boolean maximal, graph_t *g, +- clique_options *opts) { +-#if 0 +- struct timeval timeval; +- struct tms tms; +-#endif +- int i,j; +- int v; +- int *newtable; +- int newsize; +- int count=0; +- +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- clique_list_count=0; +- set_empty(current_clique); +- for (i=start; i < g->n; i++) { +- v=table[i]; +- clique_size[v]=min_size; /* Do not prune here. */ +- +- newsize=0; +- for (j=0; jtime_function) { +- gettimeofday(&timeval,NULL); +- times(&tms); +- if (!opts->time_function(entrance_level, +- i+1,g->n,min_size * +- weight_multiplier, +- (double)(tms.tms_utime- +- cputimer.tms_utime)/ +- clocks_per_sec, +- timeval.tv_sec- +- realtimer.tv_sec+ +- (double)(timeval.tv_usec- +- realtimer.tv_usec)/ +- 1000000,opts)) { +- /* Abort. */ +- break; +- } +- } +-#endif +- } +- temp_list[temp_count++]=newtable; +- return count; +-} +- +-/* +- * sub_unweighted_all() +- * +- * Recursion function for searching for all cliques of given size. +- * +- * table - subset of vertices of graph g +- * size - size of table +- * min_size - minimum size of cliques to search for (decreased with +- * every recursion) +- * max_size - maximum size of cliques to search for (decreased with +- * every recursion). If no upper limit is desired, use +- * eg. INT_MAX +- * maximal - require cliques to be maximal (passed through) +- * g - the graph +- * opts - storage options +- * +- * All cliques of suitable size found are stored according to opts. +- * +- * Returns the number of cliques found. If user_function returns FALSE, +- * then the number of cliques is returned negative. +- * +- * Uses current_clique to store the currently-being-searched clique. +- * clique_size[] for all values in table must be defined and correct, +- * otherwise inaccurate results may occur. +- */ +-static int sub_unweighted_all(int *table, int size, int min_size, int max_size, +- boolean maximal, graph_t *g, +- clique_options *opts) { +- int i; +- int v; +- int n; +- int *newtable; +- int *p1, *p2; +- int count=0; /* Amount of cliques found */ +- +- if (min_size <= 0) { +- if ((!maximal) || is_maximal(current_clique,g)) { +- /* We've found one. Store it. */ +- count++; +- if (!store_clique(current_clique,g,opts)) { +- return -count; +- } +- } +- if (max_size <= 0) { +- /* If we add another element, size will be too big. */ +- return count; +- } +- } +- +- if (size < min_size) { +- return count; +- } +- +- /* Dynamic memory allocation with cache */ +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- for (i=size-1; i>=0; i--) { +- v = table[i]; +- if (clique_size[v] < min_size) { +- break; +- } +- if (i+1 < min_size) { +- break; +- } +- +- /* Very ugly code, but works faster than "for (i=...)" */ +- p1 = newtable; +- for (p2=table; p2 < table+i; p2++) { +- int w = *p2; +- if (GRAPH_IS_EDGE(g, v, w)) { +- *p1 = w; +- p1++; +- } +- } +- +- /* Avoid unneccessary loops (next size == p1-newtable) */ +- if (p1-newtable < min_size-1) { +- continue; +- } +- +- SET_ADD_ELEMENT(current_clique,v); +- n=sub_unweighted_all(newtable,p1-newtable, +- min_size-1,max_size-1,maximal,g,opts); +- SET_DEL_ELEMENT(current_clique,v); +- if (n < 0) { +- /* Abort. */ +- count -= n; +- count = -count; +- break; +- } +- count+=n; +- } +- temp_list[temp_count++]=newtable; +- return count; +-} +- +- +- +- +-/***** Weighted clique searches *****/ +-/* +- * Weighted clique searches can use the same recursive routine, because +- * in both cases (single/all) they have to search through all potential +- * permutations searching for heavier cliques. +- */ +- +- +-/* +- * weighted_clique_search_single() +- * +- * Searches for a single clique of weight at least min_weight, and at +- * most max_weight. Stores maximum clique sizes into clique_size[] +- * (or min_weight-1, whichever is smaller). +- * +- * table - the order of the vertices in g to use +- * min_weight - minimum weight of clique to search for. If min_weight==0, +- * then searches for a maximum weight clique +- * max_weight - maximum weight of clique to search for. If no upper limit +- * is desired, use eg. INT_MAX +- * g - the graph +- * opts - time printing options +- * +- * opts->time_function is called after each base-level recursion, if +- * non-NULL. +- * +- * Returns 0 if a clique of requested weight was not found (also if +- * time_function requested an abort), otherwise returns >= 1. +- * If min_weight==0 (search for maximum-weight clique), then the return +- * value is the weight of the clique found. The found clique is stored +- * in best_clique. +- * +- * Note: Does NOT use opts->user_function of opts->clique_list. +- */ +-static int weighted_clique_search_single(int *table, int min_weight, +- int max_weight, graph_t *g, +- clique_options *opts) { +-#if 0 +- struct timeval timeval; +- struct tms tms; +-#endif +- int i,j; +- int v; +- int *newtable; +- int newsize; +- int newweight; +- int search_weight; +- int min_w; +- clique_options localopts; +- +- if (min_weight==0) +- min_w=INT_MAX; +- else +- min_w=min_weight; +- +- +- if (min_weight==1) { +- /* min_weight==1 may cause trouble in the routine, and +- * it's trivial to check as it's own case. +- * We write nothing to clique_size[]. */ +- for (i=0; i < g->n; i++) { +- if (g->weights[table[i]] <= max_weight) { +- set_empty(best_clique); +- SET_ADD_ELEMENT(best_clique,table[i]); +- return g->weights[table[i]]; +- } +- } +- return 0; +- } +- +- localopts.time_function=NULL; +- localopts.reorder_function=NULL; +- localopts.reorder_map=NULL; +- localopts.user_function=false_function; +- localopts.user_data=NULL; +- localopts.clique_list=&best_clique; +- localopts.clique_list_length=1; +- clique_list_count=0; +- +- v=table[0]; +- set_empty(best_clique); +- SET_ADD_ELEMENT(best_clique,v); +- search_weight=g->weights[v]; +- if (min_weight && (search_weight >= min_weight)) { +- if (search_weight <= max_weight) { +- /* Found suitable clique. */ +- return search_weight; +- } +- search_weight=min_weight-1; +- } +- clique_size[v]=search_weight; +- set_empty(current_clique); +- +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- for (i = 1; i < g->n; i++) { +- v=table[i]; +- +- newsize=0; +- newweight=0; +- for (j=0; jweights[table[j]]; +- newtable[newsize]=table[j]; +- newsize++; +- } +- } +- +- +- SET_ADD_ELEMENT(current_clique,v); +- search_weight=sub_weighted_all(newtable,newsize,newweight, +- g->weights[v],search_weight, +- clique_size[table[i-1]] + +- g->weights[v], +- min_w,max_weight,FALSE, +- g,&localopts); +- SET_DEL_ELEMENT(current_clique,v); +- if (search_weight < 0) { +- break; +- } +- +- clique_size[v]=search_weight; +- +-#if 0 +- if (opts->time_function) { +- gettimeofday(&timeval,NULL); +- times(&tms); +- if (!opts->time_function(entrance_level, +- i+1,g->n,clique_size[v] * +- weight_multiplier, +- (double)(tms.tms_utime- +- cputimer.tms_utime)/ +- clocks_per_sec, +- timeval.tv_sec- +- realtimer.tv_sec+ +- (double)(timeval.tv_usec- +- realtimer.tv_usec)/ +- 1000000,opts)) { +- set_free(current_clique); +- current_clique=NULL; +- break; +- } +- } +-#endif +- } +- temp_list[temp_count++]=newtable; +- if (min_weight && (search_weight > 0)) { +- /* Requested clique has not been found. */ +- return 0; +- } +- return clique_size[table[i-1]]; +-} +- +- +-/* +- * weighted_clique_search_all() +- * +- * Searches for all cliques with weight at least min_weight and at most +- * max_weight. Stores the cliques as opts declares. +- * +- * table - the order of the vertices in g to search +- * start - first index where the subgraph table[0], ..., table[start] +- * might include a requested kind of clique +- * min_weight - minimum weight of clique to search for. min_weight > 0 ! +- * max_weight - maximum weight of clique to search for. If no upper limit +- * is desired, use eg. INT_MAX +- * maximal - search only for maximal cliques +- * g - the graph +- * opts - time printing and clique storage options +- * +- * Cliques found are stored as defined by opts->user_function and +- * opts->clique_list. opts->time_function is called after each +- * base-level recursion, if non-NULL. +- * +- * clique_size[] must be defined and correct for all values of +- * table[0], ..., table[start-1]. +- * +- * Returns the number of cliques stored (not neccessarily number of cliques +- * in graph, if user/time_function aborts). +- */ +-static int weighted_clique_search_all(int *table, int start, +- int min_weight, int max_weight, +- boolean maximal, graph_t *g, +- clique_options *opts) { +-#if 0 +- struct timeval timeval; +- struct tms tms; +-#endif +- int i,j; +- int v; +- int *newtable; +- int newsize; +- int newweight; +- +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- clique_list_count=0; +- set_empty(current_clique); +- for (i=start; i < g->n; i++) { +- v=table[i]; +- clique_size[v]=min_weight; /* Do not prune here. */ +- +- newsize=0; +- newweight=0; +- for (j=0; jweights[table[j]]; +- newsize++; +- } +- } +- +- SET_ADD_ELEMENT(current_clique,v); +- j=sub_weighted_all(newtable,newsize,newweight, +- g->weights[v],min_weight-1,INT_MAX, +- min_weight,max_weight,maximal,g,opts); +- SET_DEL_ELEMENT(current_clique,v); +- +- if (j<0) { +- /* Abort. */ +- break; +- } +- +-#if 0 +- if (opts->time_function) { +- gettimeofday(&timeval,NULL); +- times(&tms); +- if (!opts->time_function(entrance_level, +- i+1,g->n,clique_size[v] * +- weight_multiplier, +- (double)(tms.tms_utime- +- cputimer.tms_utime)/ +- clocks_per_sec, +- timeval.tv_sec- +- realtimer.tv_sec+ +- (double)(timeval.tv_usec- +- realtimer.tv_usec)/ +- 1000000,opts)) { +- set_free(current_clique); +- current_clique=NULL; +- break; +- } +- } +-#endif +- } +- temp_list[temp_count++]=newtable; +- +- return clique_list_count; +-} +- +-/* +- * sub_weighted_all() +- * +- * Recursion function for searching for all cliques of given weight. +- * +- * table - subset of vertices of graph g +- * size - size of table +- * weight - total weight of vertices in table +- * current_weight - weight of clique found so far +- * prune_low - ignore all cliques with weight less or equal to this value +- * (often heaviest clique found so far) (passed through) +- * prune_high - maximum weight possible for clique in this subgraph +- * (passed through) +- * min_size - minimum weight of cliques to search for (passed through) +- * Must be greater than 0. +- * max_size - maximum weight of cliques to search for (passed through) +- * If no upper limit is desired, use eg. INT_MAX +- * maximal - search only for maximal cliques +- * g - the graph +- * opts - storage options +- * +- * All cliques of suitable weight found are stored according to opts. +- * +- * Returns weight of heaviest clique found (prune_low if a heavier clique +- * hasn't been found); if a clique with weight at least min_size is found +- * then min_size-1 is returned. If clique storage failed, -1 is returned. +- * +- * The largest clique found smaller than max_weight is stored in +- * best_clique, if non-NULL. +- * +- * Uses current_clique to store the currently-being-searched clique. +- * clique_size[] for all values in table must be defined and correct, +- * otherwise inaccurate results may occur. +- * +- * To search for a single maximum clique, use min_weight==max_weight==INT_MAX, +- * with best_clique non-NULL. To search for a single given-weight clique, +- * use opts->clique_list and opts->user_function=false_function. When +- * searching for all cliques, min_weight should be given the minimum weight +- * desired. +- */ +-static int sub_weighted_all(int *table, int size, int weight, +- int current_weight, int prune_low, int prune_high, +- int min_weight, int max_weight, boolean maximal, +- graph_t *g, clique_options *opts) { +- int i; +- int v,w; +- int *newtable; +- int *p1, *p2; +- int newweight; +- +- if (current_weight >= min_weight) { +- if ((current_weight <= max_weight) && +- ((!maximal) || is_maximal(current_clique,g))) { +- /* We've found one. Store it. */ +- if (!store_clique(current_clique,g,opts)) { +- return -1; +- } +- } +- if (current_weight >= max_weight) { +- /* Clique too heavy. */ +- return min_weight-1; +- } +- } +- if (size <= 0) { +- /* current_weight < min_weight, prune_low < min_weight, +- * so return value is always < min_weight. */ +- if (current_weight>prune_low) { +- if (best_clique) +- set_copy(best_clique,current_clique); +- if (current_weight < min_weight) +- return current_weight; +- else +- return min_weight-1; +- } else { +- return prune_low; +- } +- } +- +- /* Dynamic memory allocation with cache */ +- if (temp_count) { +- temp_count--; +- newtable=temp_list[temp_count]; +- } else { +- newtable=malloc(g->n * sizeof(int)); +- } +- +- for (i = size-1; i >= 0; i--) { +- v = table[i]; +- if (current_weight+clique_size[v] <= prune_low) { +- /* Dealing with subset without heavy enough clique. */ +- break; +- } +- if (current_weight+weight <= prune_low) { +- /* Even if all elements are added, won't do. */ +- break; +- } +- +- /* Very ugly code, but works faster than "for (i=...)" */ +- p1 = newtable; +- newweight = 0; +- for (p2=table; p2 < table+i; p2++) { +- w = *p2; +- if (GRAPH_IS_EDGE(g, v, w)) { +- *p1 = w; +- newweight += g->weights[w]; +- p1++; +- } +- } +- +- w=g->weights[v]; +- weight-=w; +- /* Avoid a few unneccessary loops */ +- if (current_weight+w+newweight <= prune_low) { +- continue; +- } +- +- SET_ADD_ELEMENT(current_clique,v); +- prune_low=sub_weighted_all(newtable,p1-newtable, +- newweight, +- current_weight+w, +- prune_low,prune_high, +- min_weight,max_weight,maximal, +- g,opts); +- SET_DEL_ELEMENT(current_clique,v); +- if ((prune_low<0) || (prune_low>=prune_high)) { +- /* Impossible to find larger clique. */ +- break; +- } +- } +- temp_list[temp_count++]=newtable; +- return prune_low; +-} +- +- +- +- +-/***** Helper functions *****/ +- +- +-/* +- * store_clique() +- * +- * Stores a clique according to given user options. +- * +- * clique - the clique to store +- * opts - storage options +- * +- * Returns FALSE if opts->user_function() returned FALSE; otherwise +- * returns TRUE. +- */ +-static boolean store_clique(set_t clique, graph_t *g, clique_options *opts) { +- +- clique_list_count++; +- +- /* clique_list[] */ +- if (opts->clique_list) { +- /* +- * This has been a major source of bugs: +- * Has clique_list_count been set to 0 before calling +- * the recursions? +- */ +- if (clique_list_count <= 0) { +- fprintf(stderr,"CLIQUER INTERNAL ERROR: " +- "clique_list_count has negative value!\n"); +- fprintf(stderr,"Please report as a bug.\n"); +- abort(); +- } +- if (clique_list_count <= opts->clique_list_length) +- opts->clique_list[clique_list_count-1] = +- set_duplicate(clique); +- } +- +- /* user_function() */ +- if (opts->user_function) { +- if (!opts->user_function(clique,g,opts)) { +- /* User function requested abort. */ +- return FALSE; +- } +- } +- +- return TRUE; +-} +- +-/* +- * maximalize_clique() +- * +- * Adds greedily all possible vertices in g to set s to make it a maximal +- * clique. +- * +- * s - clique of vertices to make maximal +- * g - graph +- * +- * Note: Not very optimized (uses a simple O(n^2) routine), but is called +- * at maximum once per clique_xxx() call, so it shouldn't matter. +- */ +-static void maximalize_clique(set_t s,graph_t *g) { +- int i,j; +- boolean add; +- +- for (i=0; i < g->n; i++) { +- add=TRUE; +- for (j=0; j < g->n; j++) { +- if (SET_CONTAINS_FAST(s,j) && !GRAPH_IS_EDGE(g,i,j)) { +- add=FALSE; +- break; +- } +- } +- if (add) { +- SET_ADD_ELEMENT(s,i); +- } +- } +- return; +-} +- +- +-/* +- * is_maximal() +- * +- * Check whether a clique is maximal or not. +- * +- * clique - set of vertices in clique +- * g - graph +- * +- * Returns TRUE is clique is a maximal clique of g, otherwise FALSE. +- */ +-static boolean is_maximal(set_t clique, graph_t *g) { +- int i,j; +- int *table; +- int len; +- boolean addable; +- +- if (temp_count) { +- temp_count--; +- table=temp_list[temp_count]; +- } else { +- table=malloc(g->n * sizeof(int)); +- } +- +- len=0; +- for (i=0; i < g->n; i++) +- if (SET_CONTAINS_FAST(clique,i)) +- table[len++]=i; +- +- for (i=0; i < g->n; i++) { +- addable=TRUE; +- for (j=0; jtime_function() requests abort). +- * +- * The returned clique is newly allocated and can be freed by set_free(). +- * +- * Note: Does NOT use opts->user_function() or opts->clique_list[]. +- */ +-set_t clique_unweighted_find_single(graph_t *g,int min_size,int max_size, +- boolean maximal, clique_options *opts) { +- int i; +- int *table; +- set_t s; +- +- ENTRANCE_SAVE(); +- entrance_level++; +- +- if (opts==NULL) +- opts=clique_default_options; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(g!=NULL); +- ASSERT(min_size>=0); +- ASSERT(max_size>=0); +- ASSERT((max_size==0) || (min_size <= max_size)); +- ASSERT(!((min_size==0) && (max_size>0))); +- ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); +- +- if ((max_size>0) && (min_size>max_size)) { +- /* state was not changed */ +- entrance_level--; +- return NULL; +- } +- +-#if 0 +- if (clocks_per_sec==0) +- clocks_per_sec=sysconf(_SC_CLK_TCK); +- ASSERT(clocks_per_sec>0); +-#endif +- +- /* Dynamic allocation */ +- current_clique=set_new(g->n); +- clique_size=malloc(g->n * sizeof(int)); +- /* table allocated later */ +- temp_list=malloc((g->n+2)*sizeof(int *)); +- temp_count=0; +- +-#if 0 +- /* "start clock" */ +- gettimeofday(&realtimer,NULL); +- times(&cputimer); +-#endif +- +- /* reorder */ +- if (opts->reorder_function) { +- table=opts->reorder_function(g,FALSE); +- } else if (opts->reorder_map) { +- table=reorder_duplicate(opts->reorder_map,g->n); +- } else { +- table=reorder_ident(g->n); +- } +- ASSERT(reorder_is_bijection(table,g->n)); +- +- +- if (unweighted_clique_search_single(table,min_size,g,opts)==0) { +- set_free(current_clique); +- current_clique=NULL; +- goto cleanreturn; +- } +- if (maximal && (min_size>0)) { +- maximalize_clique(current_clique,g); +- +- if ((max_size > 0) && (set_size(current_clique) > max_size)) { +- clique_options localopts; +- +- s = set_new(g->n); +- localopts.time_function = opts->time_function; +- localopts.output = opts->output; +- localopts.user_function = false_function; +- localopts.clique_list = &s; +- localopts.clique_list_length = 1; +- +- for (i=0; i < g->n-1; i++) +- if (clique_size[table[i]]>=min_size) +- break; +- if (unweighted_clique_search_all(table,i,min_size, +- max_size,maximal, +- g,&localopts)) { +- set_free(current_clique); +- current_clique=s; +- } else { +- set_free(current_clique); +- current_clique=NULL; +- } +- } +- } +- +- cleanreturn: +- s=current_clique; +- +- /* Free resources */ +- for (i=0; i < temp_count; i++) +- free(temp_list[i]); +- free(temp_list); +- free(table); +- free(clique_size); +- +- ENTRANCE_RESTORE(); +- entrance_level--; +- +- return s; +-} +- +- +-/* +- * clique_unweighted_find_all() +- * +- * Find all cliques with size at least min_size and at most max_size. +- * +- * g - the graph +- * min_size - minimum size of cliques to search for. If min_size==0, +- * searches for maximum cliques. +- * max_size - maximum size of cliques to search for. If max_size==0, no +- * upper limit is used. If min_size==0, this must also be 0. +- * maximal - require cliques to be maximal cliques +- * opts - time printing and clique storage options +- * +- * Returns the number of cliques found. This can be less than the number +- * of cliques in the graph iff opts->time_function() or opts->user_function() +- * returns FALSE (request abort). +- * +- * The cliques found are stored in opts->clique_list[] and +- * opts->user_function() is called with them (if non-NULL). The cliques +- * stored in opts->clique_list[] are newly allocated, and can be freed +- * by set_free(). +- */ +-int clique_unweighted_find_all(graph_t *g, int min_size, int max_size, +- boolean maximal, clique_options *opts) { +- int i; +- int *table; +- int count; +- +- ENTRANCE_SAVE(); +- entrance_level++; +- +- if (opts==NULL) +- opts=clique_default_options; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(g!=NULL); +- ASSERT(min_size>=0); +- ASSERT(max_size>=0); +- ASSERT((max_size==0) || (min_size <= max_size)); +- ASSERT(!((min_size==0) && (max_size>0))); +- ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); +- +- if ((max_size>0) && (min_size>max_size)) { +- /* state was not changed */ +- entrance_level--; +- return 0; +- } +- +-#if 0 +- if (clocks_per_sec==0) +- clocks_per_sec=sysconf(_SC_CLK_TCK); +- ASSERT(clocks_per_sec>0); +-#endif +- +- /* Dynamic allocation */ +- current_clique=set_new(g->n); +- clique_size=malloc(g->n * sizeof(int)); +- /* table allocated later */ +- temp_list=malloc((g->n+2)*sizeof(int *)); +- temp_count=0; +- +- clique_list_count=0; +- memset(clique_size,0,g->n * sizeof(int)); +- +-#if 0 +- /* "start clock" */ +- gettimeofday(&realtimer,NULL); +- times(&cputimer); +-#endif +- +- /* reorder */ +- if (opts->reorder_function) { +- table=opts->reorder_function(g,FALSE); +- } else if (opts->reorder_map) { +- table=reorder_duplicate(opts->reorder_map,g->n); +- } else { +- table=reorder_ident(g->n); +- } +- ASSERT(reorder_is_bijection(table,g->n)); +- +- +- /* Search as normal until there is a chance to find a suitable +- * clique. */ +- if (unweighted_clique_search_single(table,min_size,g,opts)==0) { +- count=0; +- goto cleanreturn; +- } +- +- if (min_size==0 && max_size==0) { +- min_size=max_size=clique_size[table[g->n-1]]; +- maximal=FALSE; /* No need to test, since we're searching +- * for maximum cliques. */ +- } +- if (max_size==0) { +- max_size=INT_MAX; +- } +- +- for (i=0; i < g->n-1; i++) +- if (clique_size[table[i]] >= min_size) +- break; +- count=unweighted_clique_search_all(table,i,min_size,max_size, +- maximal,g,opts); +- +- cleanreturn: +- /* Free resources */ +- for (i=0; itime_function() requests abort). +- * +- * The returned clique is newly allocated and can be freed by set_free(). +- * +- * Note: Does NOT use opts->user_function() or opts->clique_list[]. +- * Note: Automatically uses clique_unweighted_find_single if all vertex +- * weights are the same. +- */ +-set_t clique_find_single(graph_t *g,int min_weight,int max_weight, +- boolean maximal, clique_options *opts) { +- int i; +- int *table; +- set_t s; +- +- ENTRANCE_SAVE(); +- entrance_level++; +- +- if (opts==NULL) +- opts=clique_default_options; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(g!=NULL); +- ASSERT(min_weight>=0); +- ASSERT(max_weight>=0); +- ASSERT((max_weight==0) || (min_weight <= max_weight)); +- ASSERT(!((min_weight==0) && (max_weight>0))); +- ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); +- +- if ((max_weight>0) && (min_weight>max_weight)) { +- /* state was not changed */ +- entrance_level--; +- return NULL; +- } +- +-#if 0 +- if (clocks_per_sec==0) +- clocks_per_sec=sysconf(_SC_CLK_TCK); +- ASSERT(clocks_per_sec>0); +-#endif +- +- /* Check whether we can use unweighted routines. */ +- if (!graph_weighted(g)) { +- min_weight=DIV_UP(min_weight,g->weights[0]); +- if (max_weight) { +- max_weight=DIV_DOWN(max_weight,g->weights[0]); +- if (max_weight < min_weight) { +- /* state was not changed */ +- entrance_level--; +- return NULL; +- } +- } +- +- weight_multiplier = g->weights[0]; +- entrance_level--; +- s=clique_unweighted_find_single(g,min_weight,max_weight, +- maximal,opts); +- ENTRANCE_RESTORE(); +- return s; +- } +- +- /* Dynamic allocation */ +- current_clique=set_new(g->n); +- best_clique=set_new(g->n); +- clique_size=malloc(g->n * sizeof(int)); +- memset(clique_size, 0, g->n * sizeof(int)); +- /* table allocated later */ +- temp_list=malloc((g->n+2)*sizeof(int *)); +- temp_count=0; +- +- clique_list_count=0; +- +-#if 0 +- /* "start clock" */ +- gettimeofday(&realtimer,NULL); +- times(&cputimer); +-#endif +- +- /* reorder */ +- if (opts->reorder_function) { +- table=opts->reorder_function(g,TRUE); +- } else if (opts->reorder_map) { +- table=reorder_duplicate(opts->reorder_map,g->n); +- } else { +- table=reorder_ident(g->n); +- } +- ASSERT(reorder_is_bijection(table,g->n)); +- +- if (max_weight==0) +- max_weight=INT_MAX; +- +- if (weighted_clique_search_single(table,min_weight,max_weight, +- g,opts)==0) { +- /* Requested clique has not been found. */ +- set_free(best_clique); +- best_clique=NULL; +- goto cleanreturn; +- } +- if (maximal && (min_weight>0)) { +- maximalize_clique(best_clique,g); +- if (graph_subgraph_weight(g,best_clique) > max_weight) { +- clique_options localopts; +- +- localopts.time_function = opts->time_function; +- localopts.output = opts->output; +- localopts.user_function = false_function; +- localopts.clique_list = &best_clique; +- localopts.clique_list_length = 1; +- +- for (i=0; i < g->n-1; i++) +- if ((clique_size[table[i]] >= min_weight) || +- (clique_size[table[i]] == 0)) +- break; +- if (!weighted_clique_search_all(table,i,min_weight, +- max_weight,maximal, +- g,&localopts)) { +- set_free(best_clique); +- best_clique=NULL; +- } +- } +- } +- +- cleanreturn: +- s=best_clique; +- +- /* Free resources */ +- for (i=0; i < temp_count; i++) +- free(temp_list[i]); +- free(temp_list); +- temp_list=NULL; +- temp_count=0; +- free(table); +- set_free(current_clique); +- current_clique=NULL; +- free(clique_size); +- clique_size=NULL; +- +- ENTRANCE_RESTORE(); +- entrance_level--; +- +- return s; +-} +- +- +- +- +- +-/* +- * clique_find_all() +- * +- * Find all cliques with weight at least min_weight and at most max_weight. +- * +- * g - the graph +- * min_weight - minimum weight of cliques to search for. If min_weight==0, +- * searches for maximum weight cliques. +- * max_weight - maximum weight of cliques to search for. If max_weight==0, +- * no upper limit is used. If min_weight==0, max_weight must +- * also be 0. +- * maximal - require cliques to be maximal cliques +- * opts - time printing and clique storage options +- * +- * Returns the number of cliques found. This can be less than the number +- * of cliques in the graph iff opts->time_function() or opts->user_function() +- * returns FALSE (request abort). +- * +- * The cliques found are stored in opts->clique_list[] and +- * opts->user_function() is called with them (if non-NULL). The cliques +- * stored in opts->clique_list[] are newly allocated, and can be freed +- * by set_free(). +- * +- * Note: Automatically uses clique_unweighted_find_all if all vertex +- * weights are the same. +- */ +-int clique_find_all(graph_t *g, int min_weight, int max_weight, +- boolean maximal, clique_options *opts) { +- int i,n; +- int *table; +- +- ENTRANCE_SAVE(); +- entrance_level++; +- +- if (opts==NULL) +- opts=clique_default_options; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(g!=NULL); +- ASSERT(min_weight>=0); +- ASSERT(max_weight>=0); +- ASSERT((max_weight==0) || (min_weight <= max_weight)); +- ASSERT(!((min_weight==0) && (max_weight>0))); +- ASSERT((opts->reorder_function==NULL) || (opts->reorder_map==NULL)); +- +- if ((max_weight>0) && (min_weight>max_weight)) { +- /* state was not changed */ +- entrance_level--; +- return 0; +- } +- +-#if 0 +- if (clocks_per_sec==0) +- clocks_per_sec=sysconf(_SC_CLK_TCK); +- ASSERT(clocks_per_sec>0); +-#endif +- +- if (!graph_weighted(g)) { +- min_weight=DIV_UP(min_weight,g->weights[0]); +- if (max_weight) { +- max_weight=DIV_DOWN(max_weight,g->weights[0]); +- if (max_weight < min_weight) { +- /* state was not changed */ +- entrance_level--; +- return 0; +- } +- } +- +- weight_multiplier = g->weights[0]; +- entrance_level--; +- i=clique_unweighted_find_all(g,min_weight,max_weight,maximal, +- opts); +- ENTRANCE_RESTORE(); +- return i; +- } +- +- /* Dynamic allocation */ +- current_clique=set_new(g->n); +- best_clique=set_new(g->n); +- clique_size=malloc(g->n * sizeof(int)); +- memset(clique_size, 0, g->n * sizeof(int)); +- /* table allocated later */ +- temp_list=malloc((g->n+2)*sizeof(int *)); +- temp_count=0; +- +-#if 0 +- /* "start clock" */ +- gettimeofday(&realtimer,NULL); +- times(&cputimer); +-#endif +- +- /* reorder */ +- if (opts->reorder_function) { +- table=opts->reorder_function(g,TRUE); +- } else if (opts->reorder_map) { +- table=reorder_duplicate(opts->reorder_map,g->n); +- } else { +- table=reorder_ident(g->n); +- } +- ASSERT(reorder_is_bijection(table,g->n)); +- +- /* First phase */ +- n=weighted_clique_search_single(table,min_weight,INT_MAX,g,opts); +- if (n==0) { +- /* Requested clique has not been found. */ +- goto cleanreturn; +- } +- +- if (min_weight==0) { +- min_weight=n; +- max_weight=n; +- maximal=FALSE; /* They're maximum cliques already. */ +- } +- if (max_weight==0) +- max_weight=INT_MAX; +- +- for (i=0; i < g->n; i++) +- if ((clique_size[table[i]] >= min_weight) || +- (clique_size[table[i]] == 0)) +- break; +- +- /* Second phase */ +- n=weighted_clique_search_all(table,i,min_weight,max_weight,maximal, +- g,opts); +- +- cleanreturn: +- /* Free resources */ +- for (i=0; i < temp_count; i++) +- free(temp_list[i]); +- free(temp_list); +- free(table); +- set_free(current_clique); +- set_free(best_clique); +- free(clique_size); +- +- ENTRANCE_RESTORE(); +- entrance_level--; +- +- return n; +-} +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-/* +- * clique_print_time() +- * +- * Reports current running information every 0.1 seconds or when values +- * change. +- * +- * level - re-entrance level +- * i - current recursion level +- * n - maximum recursion level +- * max - weight of heaviest clique found +- * cputime - CPU time used in algorithm so far +- * realtime - real time used in algorithm so far +- * opts - prints information to (FILE *)opts->output (or stdout if NULL) +- * +- * Returns always TRUE (ie. never requests abort). +- */ +-boolean clique_print_time(int level, int i, int n, int max, +- double cputime, double realtime, +- clique_options *opts) { +- static float prev_time=100; +- static int prev_i=100; +- static int prev_max=100; +- static int prev_level=0; +- FILE *fp=opts->output; +- int j; +- +- if (fp==NULL) +- fp=stdout; +- +- if (ABS(prev_time-realtime)>0.1 || i==n || ioutput (or stdout if NULL) +- * +- * Returns always TRUE (ie. never requests abort). +- */ +-boolean clique_print_time_always(int level, int i, int n, int max, +- double cputime, double realtime, +- clique_options *opts) { +- static float prev_time=100; +- static int prev_i=100; +- FILE *fp=opts->output; +- int j; +- +- if (fp==NULL) +- fp=stdout; +- +- for (j=1; j +-#include +-#include +-#include "graph.h" +-*/ +- +- +-/* +- * graph_new() +- * +- * Returns a newly allocated graph with n vertices all with weight 1, +- * and no edges. +- */ +-graph_t *graph_new(int n) { +- graph_t *g; +- int i; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(n>0); +- +- g=malloc(sizeof(graph_t)); +- g->n=n; +- g->edges=malloc(g->n * sizeof(set_t)); +- g->weights=malloc(g->n * sizeof(int)); +- for (i=0; i < g->n; i++) { +- g->edges[i]=set_new(n); +- g->weights[i]=1; +- } +- return g; +-} +- +-/* +- * graph_free() +- * +- * Frees the memory associated with the graph g. +- */ +-void graph_free(graph_t *g) { +- int i; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- ASSERT(g!=NULL); +- ASSERT(g->n > 0); +- +- for (i=0; i < g->n; i++) { +- set_free(g->edges[i]); +- } +- free(g->weights); +- free(g->edges); +- free(g); +- return; +-} +- +- +-/* +- * graph_resize() +- * +- * Resizes graph g to given size. If size > g->n, the new vertices are +- * not connected to any others and their weights are set to 1. +- * If size < g->n, the last g->n - size vertices are removed. +- */ +-void graph_resize(graph_t *g, int size) { +- int i; +- +- ASSERT(g!=NULL); +- ASSERT(g->n > 0); +- ASSERT(size > 0); +- +- if (g->n == size) +- return; +- +- /* Free/alloc extra edge-sets */ +- for (i=size; i < g->n; i++) +- set_free(g->edges[i]); +- g->edges=realloc(g->edges, size * sizeof(set_t)); +- for (i=g->n; i < size; i++) +- g->edges[i]=set_new(size); +- +- /* Resize original sets */ +- for (i=0; i < MIN(g->n,size); i++) { +- g->edges[i]=set_resize(g->edges[i],size); +- } +- +- /* Weights */ +- g->weights=realloc(g->weights,size * sizeof(int)); +- for (i=g->n; iweights[i]=1; +- +- g->n=size; +- return; +-} +- +-/* +- * graph_crop() +- * +- * Resizes the graph so as to remove all highest-valued isolated vertices. +- */ +-void graph_crop(graph_t *g) { +- int i; +- +- for (i=g->n-1; i>=1; i--) +- if (set_size(g->edges[i])>0) +- break; +- graph_resize(g,i+1); +- return; +-} +- +- +-/* +- * graph_weighted() +- * +- * Returns TRUE if all vertex weights of graph g are all the same. +- * +- * Note: Does NOT require weights to be 1. +- */ +-boolean graph_weighted(graph_t *g) { +- int i,w; +- +- w=g->weights[0]; +- for (i=1; i < g->n; i++) +- if (g->weights[i] != w) +- return TRUE; +- return FALSE; +-} +- +-/* +- * graph_edge_count() +- * +- * Returns the number of edges in graph g. +- */ +-int graph_edge_count(graph_t *g) { +- int i; +- int count=0; +- +- for (i=0; i < g->n; i++) { +- count += set_size(g->edges[i]); +- } +- return count/2; +-} +- +-/* +- * graph_print() +- * +- * Prints a representation of the graph g to stdout (along with any errors +- * noticed). Mainly useful for debugging purposes and trivial output. +- * +- * The output consists of a first line describing the dimensions and then +- * one line per vertex containing the vertex number (numbered 0,...,n-1), +- * the vertex weight (if the graph is weighted), "->" and then a list +- * of all vertices it is adjacent to. +- */ +-void graph_print(graph_t *g) { +- int i,j; +- int asymm=0; +- int refl=0; +- int nonpos=0; +- int extra=0; +- unsigned int weight=0; +- boolean weighted; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- +- if (g==NULL) { +- printf(" WARNING: Graph pointer is NULL!\n"); +- return; +- } +- if (g->n <= 0) { +- printf(" WARNING: Graph has %d vertices " +- "(should be positive)!\n",g->n); +- return; +- } +- +- weighted=graph_weighted(g); +- +- printf("%s graph has %d vertices, %d edges (density %.2f).\n", +- weighted?"Weighted":((g->weights[0]==1)? +- "Unweighted":"Semi-weighted"), +- g->n,graph_edge_count(g), +- (float)graph_edge_count(g)/((float)(g->n - 1)*(g->n)/2)); +- +- for (i=0; i < g->n; i++) { +- printf("%2d",i); +- if (weighted) { +- printf(" w=%d",g->weights[i]); +- if (g->weights[i] <= 0) { +- printf("*NON-POSITIVE*"); +- nonpos++; +- } +- } +- if (weight < INT_MAX) +- weight+=g->weights[i]; +- printf(" ->"); +- for (j=0; j < g->n; j++) { +- if (SET_CONTAINS_FAST(g->edges[i],j)) { +- printf(" %d",j); +- if (i==j) { +- printf("*REFLEXIVE*"); +- refl++; +- } +- if (!SET_CONTAINS_FAST(g->edges[j],i)) { +- printf("*ASYMMERTIC*"); +- asymm++; +- } +- } +- } +- for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE; +- j++) { +- if (SET_CONTAINS_FAST(g->edges[i],j)) { +- printf(" %d*NON-EXISTENT*",j); +- extra++; +- } +- } +- printf("\n"); +- } +- +- if (asymm) +- printf(" WARNING: Graph contained %d asymmetric edges!\n", +- asymm); +- if (refl) +- printf(" WARNING: Graph contained %d reflexive edges!\n", +- refl); +- if (nonpos) +- printf(" WARNING: Graph contained %d non-positive vertex " +- "weights!\n",nonpos); +- if (extra) +- printf(" WARNING: Graph contained %d edges to " +- "non-existent vertices!\n",extra); +- if (weight>=INT_MAX) +- printf(" WARNING: Total graph weight >= INT_MAX!\n"); +- return; +-} +- +- +-/* +- * graph_test() +- * +- * Tests graph g to be valid. Checks that g is non-NULL, the edges are +- * symmetric and anti-reflexive, and that all vertex weights are positive. +- * If output is non-NULL, prints a few lines telling the status of the graph +- * to file descriptor output. +- * +- * Returns TRUE if the graph is valid, FALSE otherwise. +- */ +-boolean graph_test(graph_t *g,FILE *output) { +- int i,j; +- int edges=0; +- int asymm=0; +- int nonpos=0; +- int refl=0; +- int extra=0; +- unsigned int weight=0; +- boolean weighted; +- +- ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); +- +- if (g==NULL) { +- if (output) +- fprintf(output," WARNING: Graph pointer is NULL!\n"); +- return FALSE; +- } +- +- weighted=graph_weighted(g); +- +- for (i=0; i < g->n; i++) { +- if (g->edges[i]==NULL) { +- if (output) +- fprintf(output," WARNING: Graph edge set " +- "NULL!\n" +- " (further warning suppressed)\n"); +- return FALSE; +- } +- if (SET_MAX_SIZE(g->edges[i]) < g->n) { +- if (output) +- fprintf(output," WARNING: Graph edge set " +- "too small!\n" +- " (further warnings suppressed)\n"); +- return FALSE; +- } +- for (j=0; j < g->n; j++) { +- if (SET_CONTAINS_FAST(g->edges[i],j)) { +- edges++; +- if (i==j) { +- refl++; +- } +- if (!SET_CONTAINS_FAST(g->edges[j],i)) { +- asymm++; +- } +- } +- } +- for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE; +- j++) { +- if (SET_CONTAINS_FAST(g->edges[i],j)) +- extra++; +- } +- if (g->weights[i] <= 0) +- nonpos++; +- if (weightweights[i]; +- } +- +- edges/=2; /* Each is counted twice. */ +- +- if (output) { +- /* Semi-weighted means all weights are equal, but not 1. */ +- fprintf(output,"%s graph has %d vertices, %d edges " +- "(density %.2f).\n", +- weighted?"Weighted": +- ((g->weights[0]==1)?"Unweighted":"Semi-weighted"), +- g->n,edges,(float)edges/((float)(g->n - 1)*(g->n)/2)); +- +- if (asymm) +- fprintf(output," WARNING: Graph contained %d " +- "asymmetric edges!\n",asymm); +- if (refl) +- fprintf(output," WARNING: Graph contained %d " +- "reflexive edges!\n",refl); +- if (nonpos) +- fprintf(output," WARNING: Graph contained %d " +- "non-positive vertex weights!\n",nonpos); +- if (extra) +- fprintf(output," WARNING: Graph contained %d edges " +- "to non-existent vertices!\n",extra); +- if (weight>=INT_MAX) +- fprintf(output," WARNING: Total graph weight >= " +- "INT_MAX!\n"); +- if (asymm==0 && refl==0 && nonpos==0 && extra==0 && +- weight=INT_MAX) +- return FALSE; +- +- return TRUE; +-} +- +- +-/* +- * graph_test_regular() +- * +- * Returns the vertex degree for regular graphs, or -1 if the graph is +- * not regular. +- */ +-int graph_test_regular(graph_t *g) { +- int i,n; +- +- n=set_size(g->edges[0]); +- +- for (i=1; i < g->n; i++) { +- if (set_size(g->edges[i]) != n) +- return -1; +- } +- return n; +-} +- +- +- +-/* +- * This file contains the vertex reordering routines. +- * +- * Copyright (C) 2002 Sampo Niskanen, Patric Östergård. +- * Licensed under the GNU GPL, read the file LICENSE for details. +- */ +- +-/* +-#include "reorder.h" +- +-#include +-#include +-#include +- +-#include +-*/ +- +- +-/* +- * reorder_set() +- * +- * Reorders the set s with a function i -> order[i]. +- * +- * Note: Assumes that order is the same size as SET_MAX_SIZE(s). +- */ +-void reorder_set(set_t s,int *order) { +- set_t tmp; +- int i,j; +- setelement e; +- +- ASSERT(reorder_is_bijection(order,SET_MAX_SIZE(s))); +- +- tmp=set_new(SET_MAX_SIZE(s)); +- +- for (i=0; i<(SET_MAX_SIZE(s)/ELEMENTSIZE); i++) { +- e=s[i]; +- if (e==0) +- continue; +- for (j=0; j>1; +- } +- } +- if (SET_MAX_SIZE(s)%ELEMENTSIZE) { +- e=s[i]; +- for (j=0; j<(SET_MAX_SIZE(s)%ELEMENTSIZE); j++) { +- if (e&1) { +- SET_ADD_ELEMENT(tmp,order[i*ELEMENTSIZE+j]); +- } +- e = e>>1; +- } +- } +- set_copy(s,tmp); +- set_free(tmp); +- return; +-} +- +- +-/* +- * reorder_graph() +- * +- * Reorders the vertices in the graph with function i -> order[i]. +- * +- * Note: Assumes that order is of size g->n. +- */ +-void reorder_graph(graph_t *g, int *order) { +- int i; +- set_t *tmp_e; +- int *tmp_w; +- +- ASSERT(reorder_is_bijection(order,g->n)); +- +- tmp_e=malloc(g->n * sizeof(set_t)); +- tmp_w=malloc(g->n * sizeof(int)); +- for (i=0; in; i++) { +- reorder_set(g->edges[i],order); +- tmp_e[order[i]]=g->edges[i]; +- tmp_w[order[i]]=g->weights[i]; +- } +- for (i=0; in; i++) { +- g->edges[i]=tmp_e[i]; +- g->weights[i]=tmp_w[i]; +- } +- free(tmp_e); +- free(tmp_w); +- return; +-} +- +- +- +-/* +- * reorder_duplicate() +- * +- * Returns a newly allocated duplicate of the given ordering. +- */ +-int *reorder_duplicate(int *order,int n) { +- int *new; +- +- new=malloc(n*sizeof(int)); +- memcpy(new,order,n*sizeof(int)); +- return new; +-} +- +-/* +- * reorder_invert() +- * +- * Inverts the given ordering so that new[old[i]]==i. +- * +- * Note: Asserts that order is a bijection. +- */ +-void reorder_invert(int *order,int n) { +- int *new; +- int i; +- +- ASSERT(reorder_is_bijection(order,n)); +- +- new=malloc(n*sizeof(int)); +- for (i=0; i {0,...,n-1}. +- * +- * Returns TRUE if it is a bijection, FALSE otherwise. +- */ +-boolean reorder_is_bijection(int *order,int n) { +- boolean *used; +- int i; +- +- used=calloc(n,sizeof(boolean)); +- for (i=0; i=n) { +- free(used); +- return FALSE; +- } +- if (used[order[i]]) { +- free(used); +- return FALSE; +- } +- used[order[i]]=TRUE; +- } +- for (i=0; in); +-} +- +-/* +- * reorder_by_reverse() +- * +- * Returns a reverse identity ordering. +- */ +-int *reorder_by_reverse(graph_t *g,boolean weighted) { +- int i; +- int *order; +- +- order=malloc(g->n * sizeof(int)); +- for (i=0; i < g->n; i++) +- order[i]=g->n-i-1; +- return order; +-} +- +-/* +- * reorder_by_greedy_coloring() +- * +- * Equivalent to reorder_by_weighted_greedy_coloring or +- * reorder_by_unweighted_greedy_coloring according to the value of weighted. +- */ +-int *reorder_by_greedy_coloring(graph_t *g,boolean weighted) { +- if (weighted) +- return reorder_by_weighted_greedy_coloring(g,weighted); +- else +- return reorder_by_unweighted_greedy_coloring(g,weighted); +-} +- +- +-/* +- * reorder_by_unweighted_greedy_coloring() +- * +- * Returns an ordering for the graph g by coloring the clique one +- * color at a time, always adding the vertex of largest degree within +- * the uncolored graph, and numbering these vertices 0, 1, ... +- * +- * Experimentally efficient for use with unweighted graphs. +- */ +-int *reorder_by_unweighted_greedy_coloring(graph_t *g,boolean weighted) { +- int i,j,v; +- boolean *tmp_used; +- int *degree; /* -1 for used vertices */ +- int *order; +- int maxdegree,maxvertex=0; +- boolean samecolor; +- +- tmp_used=calloc(g->n,sizeof(boolean)); +- degree=calloc(g->n,sizeof(int)); +- order=calloc(g->n,sizeof(int)); +- +- for (i=0; i < g->n; i++) { +- for (j=0; j < g->n; j++) { +- ASSERT(!((i==j) && GRAPH_IS_EDGE(g,i,j))); +- if (GRAPH_IS_EDGE(g,i,j)) +- degree[i]++; +- } +- } +- +- v=0; +- while (v < g->n) { +- /* Reset tmp_used. */ +- memset(tmp_used,0,g->n * sizeof(boolean)); +- +- do { +- /* Find vertex to be colored. */ +- maxdegree=0; +- samecolor=FALSE; +- for (i=0; i < g->n; i++) { +- if (!tmp_used[i] && degree[i] >= maxdegree) { +- maxvertex=i; +- maxdegree=degree[i]; +- samecolor=TRUE; +- } +- } +- if (samecolor) { +- order[v]=maxvertex; +- degree[maxvertex]=-1; +- v++; +- +- /* Mark neighbors not to color with same +- * color and update neighbor degrees. */ +- for (i=0; i < g->n; i++) { +- if (GRAPH_IS_EDGE(g,maxvertex,i)) { +- tmp_used[i]=TRUE; +- degree[i]--; +- } +- } +- } +- } while (samecolor); +- } +- +- free(tmp_used); +- free(degree); +- return order; +-} +- +-/* +- * reorder_by_weighted_greedy_coloring() +- * +- * Returns an ordering for the graph g by coloring the clique one +- * color at a time, always adding the vertex that (in order of importance): +- * 1. has the minimum weight in the remaining graph +- * 2. has the largest sum of weights surrounding the vertex +- * +- * Experimentally efficient for use with weighted graphs. +- */ +-int *reorder_by_weighted_greedy_coloring(graph_t *g, boolean weighted) { +- int i,j,p=0; +- int cnt; +- int *nwt; /* Sum of surrounding vertices' weights */ +- int min_wt,max_nwt; +- boolean *used; +- int *order; +- +- nwt=malloc(g->n * sizeof(int)); +- order=malloc(g->n * sizeof(int)); +- used=calloc(g->n,sizeof(boolean)); +- +- for (i=0; i < g->n; i++) { +- nwt[i]=0; +- for (j=0; j < g->n; j++) +- if (GRAPH_IS_EDGE(g, i, j)) +- nwt[i] += g->weights[j]; +- } +- +- for (cnt=0; cnt < g->n; cnt++) { +- min_wt=INT_MAX; +- max_nwt=-1; +- for (i=g->n-1; i>=0; i--) +- if ((!used[i]) && (g->weights[i] < min_wt)) +- min_wt=g->weights[i]; +- for (i=g->n-1; i>=0; i--) { +- if (used[i] || (g->weights[i] > min_wt)) +- continue; +- if (nwt[i] > max_nwt) { +- max_nwt=nwt[i]; +- p=i; +- } +- } +- order[cnt]=p; +- used[p]=TRUE; +- for (j=0; j < g->n; j++) +- if ((!used[j]) && (GRAPH_IS_EDGE(g, p, j))) +- nwt[j] -= g->weights[p]; +- } +- +- free(nwt); +- free(used); +- +- ASSERT(reorder_is_bijection(order,g->n)); +- +- return order; +-} +- +-/* +- * reorder_by_degree() +- * +- * Returns a reordering of the graph g so that the vertices with largest +- * degrees (most neighbors) are first. +- */ +-int *reorder_by_degree(graph_t *g, boolean weighted) { +- int i,j,v; +- int *degree; +- int *order; +- int maxdegree,maxvertex=0; +- +- degree=calloc(g->n,sizeof(int)); +- order=calloc(g->n,sizeof(int)); +- +- for (i=0; i < g->n; i++) { +- for (j=0; j < g->n; j++) { +- ASSERT(!((i==j) && GRAPH_IS_EDGE(g,i,j))); +- if (GRAPH_IS_EDGE(g,i,j)) +- degree[i]++; +- } +- } +- +- for (v=0; v < g->n; v++) { +- maxdegree=0; +- for (i=0; i < g->n; i++) { +- if (degree[i] >= maxdegree) { +- maxvertex=i; +- maxdegree=degree[i]; +- } +- } +- order[v]=maxvertex; +- degree[maxvertex]=-1; /* used */ +-/*** Max. degree withing unselected graph: +- for (i=0; i < g->n; i++) { +- if (GRAPH_IS_EDGE(g,maxvertex,i)) +- degree[i]--; +- } +-***/ +- } +- +- free(degree); +- return order; +-} +- +-/* +- * reorder_by_random() +- * +- * Returns a random reordering for graph g. +- * Note: Used the functions rand() and srand() to generate the random +- * numbers. srand() is re-initialized every time reorder_by_random() +- * is called using the system time. +- */ +-int *reorder_by_random(graph_t *g, boolean weighted) { +- /* struct tms t; */ +- int i,r; +- int *new; +- boolean *used; +- +-/* +- srand(times(&t)+time(NULL)); +-*/ +- INITRANBYTIME; +- +- new=calloc(g->n, sizeof(int)); +- used=calloc(g->n, sizeof(boolean)); +- for (i=0; i < g->n; i++) { +- do { +- r=NEXTRAN % g->n; +- } while (used[r]); +- new[i]=r; +- used[r]=TRUE; +- } +- free(used); +- return new; +-} +- + /************************************************************************/ + + /* This is an interface between nauty and cliquer for finding +--- a/nautycliquer.h ++++ b/nautycliquer.h +@@ -6,637 +6,7 @@ + + #include "nauty.h" + #include "gtools.h" +-#include +- +-/********************************************************************** +-#include "cliquerconf.h" +-*/ +- +-/* +- * setelement is the basic memory type used in sets. It is often fastest +- * to be as large as can fit into the CPU registers. +- * +- * ELEMENTSIZE is the size of one setelement, measured in bits. It must +- * be either 16, 32 or 64 (otherwise additional changes must be made to +- * the source). +- * +- * The default is to use "unsigned long int" and attempt to guess the +- * size using , which should work pretty well. Check functioning +- * with "make test". +- */ +- +-/* typedef unsigned long int setelement; */ +-/* #define ELEMENTSIZE 64 */ +- +-/* +- * INLINE is a command prepended to function declarations to instruct the +- * compiler to inline the function. If inlining is not desired, define blank. +- * +- * The default is to use "inline", which is recognized by most compilers. +- */ +- +-/* #define INLINE */ +-/* #define INLINE __inline__ */ +- +- +-/* +- * Set handling functions are defined as static functions in set.h for +- * performance reasons. This may cause unnecessary warnings from the +- * compiler. Some compilers (such as GCC) have the possibility to turn +- * off the warnings on a per-function basis using a flag prepended to +- * the function declaration. +- * +- * The default is to use the correct attribute when compiling with GCC, +- * or no flag otherwise. +- */ +- +-/* #define UNUSED_FUNCTION __attribute__((unused)) */ +-/* #define UNUSED_FUNCTION */ +- +-/* +- * Uncommenting the following will disable all assertions (checks that +- * function arguments and other variables are correct). This is highly +- * discouraged, as it allows bugs to go unnoticed easier. The assertions +- * are set so that they do not slow down programs notably. +- */ +- +-/* #define ASSERT(x) */ +- +-/********************************************************************** +-#include "misc.h" +-*/ +- +-/* +- * We #define boolean instead of using a typedef because nauty.h uses it +- * also. AFAIK, there is no way to check for an existing typedef, and +- * re-typedefing is illegal (even when using exactly the same datatype!). +-#ifndef boolean +-#define boolean int +-#endif +- +-BDM: In nauty's version we will use nauty's boolean (which is int anyway). +- */ +- +-/* +- * Default value for UNUSED_FUNCTION: use "__attribute__((unused))" for +- * GCC versions that support it, otherwise leave blank. +- */ +-#ifndef UNUSED_FUNCTION +-# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +-# define UNUSED_FUNCTION __attribute__((unused)) +-# else +-# define UNUSED_FUNCTION +-# endif +-#endif /* !UNUSED_FUNCTION */ +- +-/* +- * Default inlining directive: "inline" +- */ +-#ifndef INLINE +-#define INLINE inline +-#endif +- +-#ifndef ASSERT +-#define ASSERT(expr) \ +- if (!(expr)) { \ +- fprintf(stderr,"cliquer file %s: line %d: assertion failed: " \ +- "(%s)\n",__FILE__,__LINE__,#expr); \ +- abort(); \ +- } +-#endif /* !ASSERT */ +- +- +-#ifndef FALSE +-#define FALSE (0) +-#endif +-#ifndef TRUE +-#define TRUE (!FALSE) +-#endif +- +- +-#ifndef MIN +-#define MIN(a,b) (((a)<(b))?(a):(b)) +-#endif +-#ifndef MAX +-#define MAX(a,b) (((a)>(b))?(a):(b)) +-#endif +-#ifndef ABS +-#define ABS(v) (((v)<0)?(-(v)):(v)) +-#endif +- +-/********************************************************************** +-#include "set.h" +-*/ +- +-/* +- * This file contains the set handling routines. +- * +- * Copyright (C) 2002 Sampo Niskanen, Patric ÖstergÃ¥rd. +- * Licensed under the GNU GPL, read the file LICENSE for details. +- */ +- +-/* +- * Sets are arrays of setelement's (typically unsigned long int's) with +- * representative bits for each value they can contain. The values +- * are numbered 0,...,n-1. +- */ +- +- +-/*** Variable types and constants. ***/ +- +- +-/* +- * If setelement hasn't been declared: +- * - use "unsigned long int" as setelement +- * - try to deduce size from ULONG_MAX +- */ +- +-#ifndef ELEMENTSIZE +-typedef unsigned long int setelement; +-# if (ULONG_MAX == 65535) +-# define ELEMENTSIZE 16 +-# elif (ULONG_MAX == 4294967295) +-# define ELEMENTSIZE 32 +-# else +-# define ELEMENTSIZE 64 +-# endif +-#endif /* !ELEMENTSIZE */ +- +-typedef setelement * set_t; +- +- +-/*** Counting amount of 1 bits in a setelement ***/ +- +-/* Array for amount of 1 bits in a byte. */ +-static int set_bit_count[256] = { +- 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, +- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +- 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 }; +- +-/* The following macros assume that all higher bits are 0. +- * They may in some cases be useful also on with other ELEMENTSIZE's, +- * so we define them all. */ +-#define SET_ELEMENT_BIT_COUNT_8(a) (set_bit_count[(a)]) +-#define SET_ELEMENT_BIT_COUNT_16(a) (set_bit_count[(a)>>8] + \ +- set_bit_count[(a)&0xFF]) +-#define SET_ELEMENT_BIT_COUNT_32(a) (set_bit_count[(a)>>24] + \ +- set_bit_count[((a)>>16)&0xFF] + \ +- set_bit_count[((a)>>8)&0xFF] + \ +- set_bit_count[(a)&0xFF]) +-#define SET_ELEMENT_BIT_COUNT_64(a) (set_bit_count[(a)>>56] + \ +- set_bit_count[((a)>>48)&0xFF] + \ +- set_bit_count[((a)>>40)&0xFF] + \ +- set_bit_count[((a)>>32)&0xFF] + \ +- set_bit_count[((a)>>24)&0xFF] + \ +- set_bit_count[((a)>>16)&0xFF] + \ +- set_bit_count[((a)>>8)&0xFF] + \ +- set_bit_count[(a)&0xFF]) +-#if (ELEMENTSIZE==64) +-# define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_64(a) +-# define FULL_ELEMENT ((setelement)0xFFFFFFFFFFFFFFFF) +-#elif (ELEMENTSIZE==32) +-# define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_32(a) +-# define FULL_ELEMENT ((setelement)0xFFFFFFFF) +-#elif (ELEMENTSIZE==16) +-# define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_16(a) +-# define FULL_ELEMENT ((setelement)0xFFFF) +-#else +-# error "SET_ELEMENT_BIT_COUNT(a) not defined for current ELEMENTSIZE" +-#endif +- +-/*** Macros and functions ***/ +- +-/* +- * Gives a value with bit x (counting from lsb up) set. +- * +- * Making this as a table might speed up things on some machines +- * (though on most modern machines it's faster to shift instead of +- * using memory). Making it a macro makes it easy to change. +- */ +-#define SET_BIT_MASK(x) ((setelement)1<<(x)) +- +-/* Set element handling macros */ +- +-#define SET_ELEMENT_INTERSECT(a,b) ((a)&(b)) +-#define SET_ELEMENT_UNION(a,b) ((a)|(b)) +-#define SET_ELEMENT_DIFFERENCE(a,b) ((a)&(~(b))) +-#define SET_ELEMENT_CONTAINS(e,v) ((e)&SET_BIT_MASK(v)) +- +-/* Set handling macros */ +- +-#define SET_ADD_ELEMENT(s,a) \ +- ((s)[(a)/ELEMENTSIZE] |= SET_BIT_MASK((a)%ELEMENTSIZE)) +-#define SET_DEL_ELEMENT(s,a) \ +- ((s)[(a)/ELEMENTSIZE] &= ~SET_BIT_MASK((a)%ELEMENTSIZE)) +-#define SET_CONTAINS_FAST(s,a) (SET_ELEMENT_CONTAINS((s)[(a)/ELEMENTSIZE], \ +- (a)%ELEMENTSIZE)) +-#define SET_CONTAINS(s,a) (((a)0); +- +- n=(size/ELEMENTSIZE+1)+1; +- s=calloc(n,sizeof(setelement)); +- s[0]=size; +- +- return &(s[1]); +-} +- +-/* +- * set_free() +- * +- * Free the memory associated with set s. +- */ +-UNUSED_FUNCTION INLINE +-static void set_free(set_t s) { +- ASSERT(s!=NULL); +- free(&(s[-1])); +-} +- +-/* +- * set_resize() +- * +- * Resizes set s to given size. If the size is less than SET_MAX_SIZE(s), +- * the last elements are dropped. +- * +- * Returns a pointer to the new set. +- */ +-UNUSED_FUNCTION INLINE +-static set_t set_resize(set_t s, int size) { +- int n; +- +- ASSERT(size>0); +- +- n=(size/ELEMENTSIZE+1); +- s=((setelement *)realloc(s-1,(n+1)*sizeof(setelement)))+1; +- +- if (n>SET_ARRAY_LENGTH(s)) +- memset(s+SET_ARRAY_LENGTH(s),0, +- (n-SET_ARRAY_LENGTH(s))*sizeof(setelement)); +- if (size < SET_MAX_SIZE(s)) +- s[(size-1)/ELEMENTSIZE] &= (FULL_ELEMENT >> +- (ELEMENTSIZE-size%ELEMENTSIZE)); +- s[-1]=size; +- +- return s; +-} +- +-/* +- * set_size() +- * +- * Returns the number of elements in set s. +- */ +-UNUSED_FUNCTION INLINE +-static int set_size(set_t s) { +- int count=0; +- setelement *c; +- +- for (c=s; c < s+SET_ARRAY_LENGTH(s); c++) +- count+=SET_ELEMENT_BIT_COUNT(*c); +- return count; +-} +- +-/* +- * set_duplicate() +- * +- * Returns a newly allocated duplicate of set s. +- */ +-UNUSED_FUNCTION INLINE +-static set_t set_duplicate(set_t s) { +- set_t new; +- +- new=set_new(SET_MAX_SIZE(s)); +- memcpy(new,s,SET_ARRAY_LENGTH(s)*sizeof(setelement)); +- return new; +-} +- +-/* +- * set_copy() +- * +- * Copies set src to dest. If dest is NULL, is equal to set_duplicate. +- * If dest smaller than src, it is freed and a new set of the same size as +- * src is returned. +- */ +-UNUSED_FUNCTION INLINE +-static set_t set_copy(set_t dest,set_t src) { +- if (dest==NULL) +- return set_duplicate(src); +- if (SET_MAX_SIZE(dest)=0) { +- * // i is in set s +- * } +- */ +-UNUSED_FUNCTION INLINE +-static int set_return_next(set_t s, int n) { +- if (n<0) +- n=0; +- else +- n++; +- if (n >= SET_MAX_SIZE(s)) +- return -1; +- +- while (n%ELEMENTSIZE) { +- if (SET_CONTAINS(s,n)) +- return n; +- n++; +- if (n >= SET_MAX_SIZE(s)) +- return -1; +- } +- +- while (s[n/ELEMENTSIZE]==0) { +- n+=ELEMENTSIZE; +- if (n >= SET_MAX_SIZE(s)) +- return -1; +- } +- while (!SET_CONTAINS(s,n)) { +- n++; +- if (n >= SET_MAX_SIZE(s)) +- return -1; +- } +- return n; +-} +- +- +-/* +- * set_print() +- * +- * Prints the size and contents of set s to stdout. +- * Mainly useful for debugging purposes and trivial output. +- */ +-UNUSED_FUNCTION +-static void set_print(set_t s) { +- int i; +- printf("size=%d(max %d)",set_size(s),(int)SET_MAX_SIZE(s)); +- for (i=0; iedges[(i)],(j))) +-#define GRAPH_IS_EDGE(g,i,j) (((i)<((g)->n))?SET_CONTAINS((g)->edges[(i)], \ +- (j)):FALSE) +-#define GRAPH_ADD_EDGE(g,i,j) do { \ +- SET_ADD_ELEMENT((g)->edges[(i)],(j)); \ +- SET_ADD_ELEMENT((g)->edges[(j)],(i)); \ +-} while (FALSE) +-#define GRAPH_DEL_EDGE(g,i,j) do { \ +- SET_DEL_ELEMENT((g)->edges[(i)],(j)); \ +- SET_DEL_ELEMENT((g)->edges[(j)],(i)); \ +-} while (FALSE) +- +- +-extern graph_t *graph_new(int n); +-extern void graph_free(graph_t *g); +-extern void graph_resize(graph_t *g, int size); +-extern void graph_crop(graph_t *g); +- +-extern boolean graph_weighted(graph_t *g); +-extern int graph_edge_count(graph_t *g); +- +-extern graph_t *graph_read_dimacs(FILE *fp); +-extern graph_t *graph_read_dimacs_file(char *file); +-extern boolean graph_write_dimacs_ascii(graph_t *g, char *comment,FILE *fp); +-extern boolean graph_write_dimacs_ascii_file(graph_t *g,char *comment, +- char *file); +-extern boolean graph_write_dimacs_binary(graph_t *g, char *comment,FILE *fp); +-extern boolean graph_write_dimacs_binary_file(graph_t *g, char *comment, +- char *file); +- +-extern void graph_print(graph_t *g); +-extern boolean graph_test(graph_t *g, FILE *output); +-extern int graph_test_regular(graph_t *g); +- +-UNUSED_FUNCTION INLINE +-static int graph_subgraph_weight(graph_t *g,set_t s) { +- int i,j; +- int count=0; +- setelement e; +- +- for (i=0; iweights[i*ELEMENTSIZE+j]; +- e = e>>1; +- } +- } +- } +- return count; +-} +- +-UNUSED_FUNCTION INLINE +-static int graph_vertex_degree(graph_t *g, int v) { +- return set_size(g->edges[v]); +-} +- +-/******************************************************************** +-#include "reorder.h" +-*/ +- +-extern void reorder_set(set_t s,int *order); +-extern void reorder_graph(graph_t *g, int *order); +-extern int *reorder_duplicate(int *order,int n); +-extern void reorder_invert(int *order,int n); +-extern void reorder_reverse(int *order,int n); +-extern int *reorder_ident(int n); +-extern boolean reorder_is_bijection(int *order,int n); +- +- +-#define reorder_by_default reorder_by_greedy_coloring +-extern int *reorder_by_greedy_coloring(graph_t *g, boolean weighted); +-extern int *reorder_by_weighted_greedy_coloring(graph_t *g, boolean weighted); +-extern int *reorder_by_unweighted_greedy_coloring(graph_t *g,boolean weighted); +-extern int *reorder_by_degree(graph_t *g, boolean weighted); +-extern int *reorder_by_random(graph_t *g, boolean weighted); +-extern int *reorder_by_ident(graph_t *g, boolean weighted); +-extern int *reorder_by_reverse(graph_t *g, boolean weighted); +- +- +-typedef struct _clique_options clique_options; +-struct _clique_options { +- int *(*reorder_function)(graph_t *, boolean); +- int *reorder_map; +- +- /* arguments: level, n, max, user_time, system_time, opts */ +- boolean (*time_function)(int,int,int,int,double,double, +- clique_options *); +- FILE *output; +- +- boolean (*user_function)(set_t,graph_t *,clique_options *); +- void *user_data; +- set_t *clique_list; +- int clique_list_length; +-}; +- +-extern clique_options *clique_default_options; +- +-/* Weighted clique functions */ +-extern int clique_max_weight(graph_t *g,clique_options *opts); +-extern set_t clique_find_single(graph_t *g,int min_weight,int max_weight, +- boolean maximal, clique_options *opts); +-extern int clique_find_all(graph_t *g, int req_weight, boolean exact, +- boolean maximal, clique_options *opts); +- +-/* Unweighted clique functions */ +-#define clique_unweighted_max_size clique_unweighted_max_weight +-extern int clique_unweighted_max_weight(graph_t *g, clique_options *opts); +-extern set_t clique_unweighted_find_single(graph_t *g,int min_size, +- int max_size,boolean maximal, +- clique_options *opts); +-extern int clique_unweighted_find_all(graph_t *g, int min_size, int max_size, +- boolean maximal, clique_options *opts); +- +-/* Time printing functions */ +-extern boolean clique_print_time(int level, int i, int n, int max, +- double cputime, double realtime, +- clique_options *opts); +-extern boolean clique_print_time_always(int level, int i, int n, int max, +- double cputime, double realtime, +- clique_options *opts); +- +- +-/* Alternate spelling (let's be a little forgiving): */ +-#define cliquer_options clique_options +-#define cliquer_default_options clique_default_options ++#include + + /* Procedures defined in nautycliquer.c */ + extern int find_clique(graph *g, int m, int n, diff --git a/nauty.spec b/nauty.spec index 86db627..89d496e 100644 --- a/nauty.spec +++ b/nauty.spec @@ -1,9 +1,9 @@ -%global nautybasever 2.6r12 +%global nautybasever 2.7r1 %global nautytarver %(tr -d . <<< %{nautybasever}) Name: nauty Version: %(tr r . <<< %{nautybasever}) -Release: 2%{?dist} +Release: 1%{?dist} Summary: Graph canonical labeling and automorphism group computation License: ASL 2.0 @@ -12,26 +12,32 @@ Source0: http://pallini.di.uniroma1.it/%{name}%{nautytarver}.tar.gz # Debian patch to fix the gt_numorbits declaration Patch0: %{name}-fix-gt_numorbits.patch -# Debian patch to add explicit extern declarations where needed -Patch1: %{name}-fix-include-extern.patch # Debian patch to use zlib instead of invoking zcat through a pipe -Patch2: %{name}-zlib-blisstog.patch +Patch1: %{name}-zlib-blisstog.patch # Debian patch to improve usage and help information -Patch3: %{name}-help2man.patch +Patch2: %{name}-help2man.patch # Debian patch to add libtool support for building a shared library -Patch4: %{name}-autotoolization.patch +Patch3: %{name}-autotoolization.patch # Debian patch to canonicalize header file usage -Patch5: %{name}-includes.patch +Patch4: %{name}-includes.patch # Debian patch to prefix "nauty-" to the names of the generic tools -Patch6: %{name}-tool-prefix.patch +Patch5: %{name}-tool-prefix.patch # Detect availability of the popcnt instruction at runtime -Patch7: %{name}-popcnt.patch +Patch6: %{name}-popcnt.patch +# Unbundle cliquer +Patch7: %{name}-unbundle-cliquer.patch +BuildRequires: cliquer-devel BuildRequires: gcc BuildRequires: gmp-devel BuildRequires: help2man BuildRequires: libtool -BuildRequires: zlib-devel +BuildRequires: pkgconfig(zlib) + +# Some version of planarity is bundled. I do not know which version it is, +# but the interface is completely different from the one provided by Fedora's +# planarity package. +Provides: bundled(planarity) # The shortg program invokes sort. Requires: coreutils @@ -65,15 +71,7 @@ Requires: lib%{name}%{?_isa} = %{version}-%{release} This package contains files needed to develop programs that use libnauty. %prep -%setup -q -n %{name}%{nautytarver} -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 +%autosetup -p1 -n %{name}%{nautytarver} # Remove the pregenerated makefile rm -f makefile @@ -85,36 +83,42 @@ sed -i 's/@INJECTVER@/%{version}/' configure.ac autoreconf -fi %build -export CFLAGS="%{optflags} -fwrapv" -%configure --disable-static \ +export CFLAGS="%{optflags} -fwrapv -I%{_includedir}/cliquer" +%configure --disable-static --enable-generic \ %ifarch %ix86 x86_64 --enable-runtime-popcnt \ %endif --enable-tls -make %{?_smp_mflags} + +# Get rid of undesirable hardcoded rpaths; workaround libtool reordering +# -Wl,--as-needed after all the libraries. +sed -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' \ + -e 's|CC="\(.*g..\)"|CC="\1 -Wl,--as-needed"|' \ + -i libtool + +%make_build %install -make install DESTDIR=%{buildroot} +%make_install # We do not want the libtool archives rm %{buildroot}%{_libdir}/*.la %check -make check - -%ldconfig_scriptlets -n libnauty +LD_LIBRARY_PATH=$PWD/.libs make check %files -%doc README nug26.pdf +%doc README nug27.pdf %{_bindir}/dreadnaut %{_bindir}/nauty-* %{_mandir}/man1/dreadnaut.1* %{_mandir}/man1/nauty-*.1* %files -n libnauty -%doc changes24-26.txt formats.txt +%doc changes24-27.txt formats.txt %license COPYRIGHT -%{_libdir}/libnauty*.so.* +%{_libdir}/libnauty*.so.2* %files -n libnauty-devel %doc schreier.txt @@ -123,6 +127,9 @@ make check %{_libdir}/pkgconfig/%{name}.pc %changelog +* Tue Jun 2 2020 Jerry James - 2.7.1-1 +- Version 2.7.1 + * Wed Jan 29 2020 Fedora Release Engineering - 2.6.12-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/sources b/sources index d1c35fe..1cba5c5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (nauty26r12.tar.gz) = ac71af163bd2490171adea31bb3dec12a900c495365c069a5a7bbb42ca20d668bb4f319e9f9a43d85d6bd8b1842ff1a60dda5d2dc4cd89a902d78c40bfd6beb6 +SHA512 (nauty27r1.tar.gz) = f3a228b2967553f0096f9f70eaa1c25b0a929c315b4a6c6948903d197aa6431b7068ca19b1f7902c41597e1abfa81fb709fc7c4a8d193a187491239df8507b33