├── .gitignore ├── Makefile ├── README ├── algebra ├── Q.h ├── Z.h ├── Z2.h ├── Zp.h ├── algebra.cpp ├── algebra.h ├── fields.cpp ├── fraction_field.h ├── grading.cpp ├── grading.h ├── linear_combination.h ├── module.h ├── multivariate_laurentpoly.h ├── multivariate_polynomial.h ├── polynomial.cpp └── polynomial.h ├── alternating ├── cobordism.cpp ├── cobordism.h ├── cube.cpp ├── cube.h ├── cube_impl.h ├── dt_code.cpp ├── dt_code.h ├── kk.cpp ├── knot_diagram.cpp ├── knot_diagram.h ├── knot_parser ├── knot_parser.cc ├── knot_parser.hh ├── knot_parser.yy ├── knot_parser_driver.cpp ├── knot_parser_driver.h ├── knot_scanner.cc ├── knot_scanner.ll ├── location.hh ├── position.hh └── stack.hh ├── knot_tables.cpp ├── knotkit.h ├── lib ├── bitset.cpp ├── bitset.h ├── directed_multigraph.cpp ├── directed_multigraph.h ├── hashmap.h ├── hashset.h ├── io.cpp ├── io.h ├── lib.cpp ├── lib.h ├── map.h ├── map_wrapper.h ├── mapcommon.h ├── maybe.h ├── pair.h ├── priority_queue.h ├── refcount.cpp ├── refcount.h ├── set.h ├── set_wrapper.h ├── setcommon.cpp ├── setcommon.h ├── show.h ├── smallbitset.cpp ├── smallbitset.h ├── ullmanmap.h ├── ullmanset.h ├── unionfind.h └── vector.h ├── main.cpp ├── mpi_aux.cpp ├── mpi_aux.h ├── mpimain.cpp ├── mtlinks ├── hyperbolic_data_04a ├── hyperbolic_data_05a ├── hyperbolic_data_06a ├── hyperbolic_data_06n ├── hyperbolic_data_07a ├── hyperbolic_data_07n ├── hyperbolic_data_08a ├── hyperbolic_data_08n ├── hyperbolic_data_09a ├── hyperbolic_data_09n ├── hyperbolic_data_10a ├── hyperbolic_data_10n ├── hyperbolic_data_11a ├── hyperbolic_data_11n ├── hyperbolic_data_12a ├── hyperbolic_data_12n ├── hyperbolic_data_13a ├── hyperbolic_data_13n ├── hyperbolic_data_14a └── hyperbolic_data_14n ├── mutant_knot_groups ├── dat11 ├── dat12 ├── dat13 ├── dat14 └── dat15 ├── nonalternating ├── parallel.cmd ├── planar_diagram.cpp ├── planar_diagram.h ├── rd_parser ├── location.hh ├── position.hh ├── rd_parser.cc ├── rd_parser.hh ├── rd_parser.yy ├── rd_scanner.cc ├── rd_scanner.ll └── stack.hh ├── serial.cmd ├── simplify_chain_complex.h ├── smoothing.cpp ├── smoothing.h ├── spanning_tree_complex.cpp ├── spanning_tree_complex.h ├── sseq.cpp ├── sseq.h ├── steenrod_square.cpp ├── steenrod_square.h ├── testlib.cpp └── todo.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | /kk 4 | /main 5 | /testsurfaces 6 | /serial.cmd.[eo]* 7 | /parallel.cmd.[eo]* 8 | /save 9 | */save 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | devel = 1 3 | 4 | BISON = bison 5 | FLEX = flex 6 | 7 | # CXX = g++ 8 | # CXX = OMPI_CXX=clang++ mpic++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -I/u/cseed/llvm-3.1/lib/c++/v1 9 | CXX = clang++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 10 | 11 | INCLUDES = -I. -I/opt/local/include 12 | 13 | # OPTFLAGS = -g 14 | OPTFLAGS = -O2 -g 15 | # OPTFLAGS = -O2 -DNDEBUG 16 | 17 | LDFLAGS = -L/opt/local/lib 18 | 19 | CXXFLAGS = $(OPTFLAGS) -DHOME="\"`pwd`\"" -Wall -Wno-unused $(INCLUDES) 20 | 21 | LIB_OBJS = lib/refcount.o \ 22 | lib/lib.o lib/smallbitset.o lib/bitset.o lib/setcommon.o lib/io.o lib/directed_multigraph.o 23 | ALGEBRA_OBJS = algebra/algebra.o algebra/grading.o algebra/polynomial.o 24 | KNOTKIT_OBJS = planar_diagram.o dt_code.o knot_diagram.o cube.o steenrod_square.o \ 25 | spanning_tree_complex.o \ 26 | smoothing.o cobordism.o knot_tables.o sseq.o \ 27 | knot_parser/knot_parser.o knot_parser/knot_scanner.o \ 28 | rd_parser/rd_parser.o rd_parser/rd_scanner.o 29 | 30 | COMMON_OBJS = $(KNOTKIT_OBJS) $(ALGEBRA_OBJS) $(LIB_OBJS) 31 | 32 | LIB_HEADERS = lib/lib.h lib/show.h lib/refcount.h lib/pair.h lib/maybe.h lib/vector.h \ 33 | lib/set_wrapper.h lib/set.h lib/hashset.h \ 34 | lib/ullmanset.h lib/bitset.h lib/smallbitset.h lib/setcommon.h \ 35 | lib/map_wrapper.h lib/map.h lib/hashmap.h lib/ullmanmap.h lib/mapcommon.h \ 36 | lib/unionfind.h lib/priority_queue.h lib/io.h \ 37 | lib/directed_multigraph.h 38 | ALGEBRA_HEADERS = algebra/algebra.h algebra/grading.h algebra/module.h \ 39 | algebra/Z2.h algebra/linear_combination.h \ 40 | algebra/Z.h algebra/Zp.h algebra/Q.h \ 41 | algebra/polynomial.h algebra/multivariate_polynomial.h \ 42 | algebra/multivariate_laurentpoly.h algebra/fraction_field.h 43 | KNOTKIT_HEADERS = knotkit.h planar_diagram.h dt_code.h knot_diagram.h \ 44 | smoothing.h cobordism.h cube.h steenrod_square.h \ 45 | spanning_tree_complex.h cube_impl.h sseq.h simplify_chain_complex.h 46 | 47 | LIBS = -lgmp -lz 48 | 49 | all: kk 50 | 51 | %.o : %.cc 52 | $(CXX) -c $(CXXFLAGS) $< -o $@ 53 | 54 | %.o : %.cpp 55 | $(CXX) -c $(CXXFLAGS) $< -o $@ 56 | 57 | kk: kk.o $(COMMON_OBJS) 58 | $(CXX) $(LDFLAGS) -o kk $^ $(LIBS) 59 | 60 | main: main.o $(COMMON_OBJS) 61 | $(CXX) $(LDFLAGS) -o main $^ $(LIBS) 62 | 63 | mpimain: mpimain.o mpi_aux.o $(COMMON_OBJS) 64 | $(CXX) $(LDFLAGS) -o mpimain $^ $(LIBS) 65 | 66 | testlib: testlib.o $(COMMON_OBJS) 67 | $(CXX) $(LDFLAGS) -o testlib $^ 68 | 69 | ifeq ($(devel),1) 70 | knot_parser/knot_parser.cc knot_parser/knot_parser.hh: knot_parser/knot_parser.yy 71 | $(BISON) knot_parser/knot_parser.yy -o knot_parser/knot_parser.cc 72 | 73 | knot_parser/knot_scanner.cc: knot_parser/knot_scanner.ll 74 | $(FLEX) -o knot_parser/knot_scanner.cc knot_parser/knot_scanner.ll 75 | 76 | javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh: javakh_parser/javakh_parser.yy 77 | $(BISON) javakh_parser/javakh_parser.yy -o javakh_parser/javakh_parser.cc 78 | 79 | javakh_parser/javakh_scanner.cc: javakh_parser/javakh_scanner.ll 80 | $(FLEX) -o javakh_parser/javakh_scanner.cc javakh_parser/javakh_scanner.ll 81 | 82 | rd_parser/rd_parser.cc rd_parser/rd_parser.hh: rd_parser/rd_parser.yy 83 | $(BISON) rd_parser/rd_parser.yy -o rd_parser/rd_parser.cc 84 | 85 | rd_parser/rd_scanner.cc: rd_parser/rd_scanner.ll 86 | $(FLEX) -o rd_parser/rd_scanner.cc rd_parser/rd_scanner.ll 87 | endif 88 | 89 | .PHONY: parser_files 90 | parser_files: \ 91 | knot_parser/knot_parser.cc knot_parser/knot_parser.hh \ 92 | knot_parser/knot_scanner.cc \ 93 | javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh \ 94 | javakh_parser/javakh_scanner.cc \ 95 | rd_parser/rd_parser.cc rd_parser/rd_parser.hh \ 96 | rd_parser/rd_scanner.cc 97 | 98 | .PHONY: clean 99 | clean: 100 | rm -f *.o lib/*.o algebra/*.o knot_parser/*.o rd_parser/*.o 101 | rm -f main kk mpimain 102 | rm -f gmon.out 103 | 104 | .PHONY: realclean 105 | realclean: clean 106 | rm -f knot_parser/knot_parser.cc knot_parser/knot_parser.hh 107 | rm -f knot_parser/knot_scanner.cc 108 | rm -f knot_parser/location.hh knot_parser/position.hh knot_parser/stack.hh 109 | rm -f javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh 110 | rm -f javakh_parser/javakh_scanner.cc 111 | rm -f javakh_parser/location.hh javakh_parser/position.hh javakh_parser/stack.hh 112 | rm -f rd_parser/rd_parser.cc rd_parser/rd_parser.hh 113 | rm -f rd_parser/rd_scanner.cc 114 | rm -f rd_parser/location.hh rd_parser/position.hh rd_parser/stack.hh 115 | 116 | $(LIB_OBJS): $(LIB_HEADERS) 117 | $(ALGEBRA_OBJS): $(ALGEBRA_HEADERS) $(LIB_HEADERS) 118 | $(KNOTKIT_OBJS) main.o mpimain.o kk.o: $(KNOTKIT_HEADERS) $(ALGEBRA_HEADERS) $(LIB_HEADERS) 119 | 120 | mpimain.o mpi_aux.o: mpi_aux.h 121 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | knotkit is a C++ software package written by Cotton Seed 2 | (cseed@math.princeton.edu) for computing some knot and manifold 3 | invariants appearing in low-dimensional topology. Other contributors 4 | include Josh Batson. 5 | 6 | TABLE OF CONTENTS 7 | 8 | 1. INTRO 9 | 2. BUILDING 10 | 3. USAGE 11 | 4. UPCOMING CHANGES 12 | 5. FOR DEVELOPERS 13 | 14 | 1. INTRO 15 | 16 | In addition to accepting knot presentations in a variety of formats 17 | (see usage below), knotkit contains the following tables of knot data: 18 | 19 | * The Rolfsen knot tables through 10 crossings, extracted from 20 | Bar-Natan's Mathematica package, KnotTheory`, 21 | * The Hoste-Weeks-Thistlewaite knot tables through 16 crossings taken 22 | from knotscape, and 23 | * and the Morwen Thistlewaite hyperbolic link tables taken from 24 | SnapPy. 25 | 26 | This version of knotkit has support to compute the following 27 | invariants: 28 | 29 | * Khovanov homology 30 | See: 31 | M. Khovanov, A Categorification of the Jones Polynomial, Duke 32 | Math. J. 101 (2000), 359--426, arXiv:math/9908171. 33 | D. Bar-Natan, On Khovanov's Categorification of the Jones Polynomial, 34 | Algebraic and Geometric Topology 2 (2002), 337--370. 35 | 36 | * Szabo's geometric spectral sequence 37 | Computing gss was the original motivation for writing knotkit. For 38 | more information on gss, see: 39 | Z. Szabo, A geometric spectral sequence in Khovanov homology, 40 | arXiv:1010.4252, and 41 | C. Seed, Computations of Szabo's Geometric Spectral Sequence in Khovanov 42 | Homology, arXiv:1110.0735. 43 | 44 | * The Batson-Seed link splitting spectral sequence 45 | See: 46 | J. Batson, C. Seed, A Link Splitting Spectral Sequence in Khovanov 47 | Homology. 48 | 49 | * The Lipshitz-Sarkar Steenrod square on Khovanov homology 50 | See: 51 | R. Lipshitz, S. Sarkar, A Khovanov Homotopy Type, arXiv:1112.3932. 52 | R. Lipshitz, S. Sarkar, A Steenrod Square on Khovanov Homology, 53 | arXiv:1204.5776. 54 | 55 | * Bar-Natan's analogue of Lee homology 56 | See: 57 | E. S. Lee, An endomorphism of the Khovanov invariant, Adv. Math. 197 58 | (2005), 2, 554–586, arXiv:math/0210213. 59 | D. Bar-Natan, Khovanov’s homology for tangles and cobordisms, 60 | Geom. Topol. 9 (2005), 1443–1499, arXiv:math/0410495. 61 | R. Lipshitz, S. Sarkar, A refinement of Rasmussen's s-invariant, 62 | arXiv:1206.3532. 63 | 64 | * The s-invariant coming from Bar-Natan's analogue of Lee homology 65 | In addition to the above references, see: 66 | J. Rasmussen, Khovanov homology and the slice genus, Invent. 67 | Math. 182 2 (2010), 419--447, arXiv:math/0402131. 68 | R. Lipshitz, S. Sarkar, A refinement of Rasmussen's s-invariant, 69 | arXiv:1206.3532. 70 | 71 | 2. BUILDING 72 | 73 | To build knotkit on OS X, you will need the latest version of XCode 74 | (available for free in the App Store) and the GNU multiple precision 75 | arithmetic library (GMP). You can get GMP here: 76 | 77 | http://gmplib.org/ 78 | 79 | knotkit also builds under Linux. In addition to GMP, you will need a 80 | C++ compiler which supports C++11. I use LLVM clang, but knotkit 81 | should build with a recent version of GCC. 82 | 83 | knotkit doesn't have a sophisticated build system. To build knotkit, 84 | just run: 85 | 86 | make 87 | 88 | from the knotkit source directory. This should build the executable 89 | "kk". For instructions on invoking kk, see usage below. If you run 90 | into a problem, please contact me: Cotton Seed 91 | (cotton@math.princeton.edu). 92 | 93 | 3. USAGE 94 | 95 | The usage message for kk is given below. This can also be obtained by 96 | running "kk -h". 97 | 98 | A note about output. The output for commands kh, gss, ls and lee is a 99 | .tex file which renders the bigraded homology group or spectral 100 | sequence. The output for the command sq2 matches the output for the 101 | program written by Lipshitz-Sarkar and is suitable for loading into 102 | Sage. The command s outputs a single line of text. 103 | 104 | usage: kk [options...] 105 | compute for knot or link 106 | can be one of: 107 | kh: Khovanov homology 108 | gss: Szabo's geometric spectral sequence 109 | lsss: Batson-Seed link splitting spectral sequence 110 | component weights are 0, 1, ..., m 111 | sq2: Lipshitz-Sarkar Steenrod square on Z/2 Kh 112 | output suitable for Sage 113 | leess: spectral sequence coming from Bar-Natan analogue of Lee's 114 | deformation of Khovanov's complex (whew!) 115 | s: Rasmussen's s-invariant coming from lee 116 | output: 117 | kh, gss, lsss, leess: .tex file 118 | sq2: text in Sage format 119 | s: text 120 | options: 121 | -r : compute reduced theory 122 | -h : print this message 123 | -o : write output to 124 | (stdout is the default) 125 | -f : ground field (if applicable) 126 | (Z2 is the default) 127 | -v : verbose: report progress as the computation proceeds 128 | can be one of: 129 | Z2, Z3, Q 130 | can be one of: 131 | - the unknot, e.g. U or unknot 132 | - a torus knot, e.g. T(2,3) 133 | - a Rolfsen table knot, e.g. 10_124 134 | - a Hoste-Thistlethwaite-Weeks knot, e.g. 11a12 or 12n214 135 | - a Morwen Thistlethwaite link, e.g. L8n9 or L13n8862 136 | - a planar diagram, e.g. 137 | PD[X[1, 4, 2, 5], X[3, 6, 4, 1], X[5, 2, 6, 3]] or 138 | PD[[1, 4, 2, 5], [3, 6, 4, 1], [5, 2, 6, 3]] 139 | - a Dowker-Thistlethwaite code, e.g. 140 | DTCode[6,8,2,4], 141 | DT[dadbcda] or 142 | DT[{6, -8}, {-10, 12, -14, 2, -4}] 143 | - a braid, e.g. BR[2, {-1, -1, -1}] 144 | - disjoint union (juxtaposition), e.g. T(2,3) U 145 | 146 | 4. UPCOMING CHANGES 147 | 148 | The following changes are currently planned: 149 | 150 | * support for Z/p, p arbitrary prime and F(x) field of rational functions 151 | * Roberts' totally twisted Khovanov homology 152 | * the E^3 page of the twisted spectral sequence Kh(L) => \widehat{HF}(\Sigma_L) 153 | * spectral sequences of PIDs: lsss over F[x], gss over Z 154 | * maps induced by cobordisms 155 | 156 | 5. FOR DEVELOPERS 157 | 158 | If you are interested in contributing to knotkit or using it for a new 159 | application, please contact me: Cotton Seed 160 | (cotton@math.princeton.edu). I am interested in developing knotkit to 161 | be an open platform for performing computations arising in 162 | low-dimensional topology. 163 | -------------------------------------------------------------------------------- /algebra/Q.h: -------------------------------------------------------------------------------- 1 | 2 | class Q 3 | { 4 | public: 5 | typedef ::linear_combination linear_combination; 6 | typedef ::linear_combination_const_iter linear_combination_const_iter; 7 | 8 | private: 9 | enum steal { STEAL }; 10 | 11 | class Q_impl : public refcounted 12 | { 13 | public: 14 | mpq_t x; 15 | 16 | public: 17 | Q_impl () { mpq_init (x); } 18 | Q_impl (int init) 19 | { 20 | mpq_init (x); 21 | mpq_set_si (x, init, 1); 22 | } 23 | 24 | Q_impl (copy, mpq_srcptr init) 25 | { 26 | mpq_init (x); 27 | mpq_set (x, init); 28 | } 29 | 30 | Q_impl (steal, mpq_srcptr init) { x[0] = *init; } 31 | Q_impl (reader &r) 32 | { 33 | mpq_init (x); 34 | r.read_mpz (mpq_numref (x)); 35 | r.read_mpz (mpq_denref (x)); 36 | } 37 | 38 | ~Q_impl () { mpq_clear (x); } 39 | 40 | void write_self (writer &w) const 41 | { 42 | w.write_mpz (mpq_numref (x)); 43 | w.write_mpz (mpq_denref (x)); 44 | } 45 | }; 46 | 47 | ptr impl; 48 | 49 | Q (steal, mpq_srcptr init) : impl(new Q_impl (STEAL, init)) { } 50 | 51 | public: 52 | Q () : impl(new Q_impl) { } 53 | Q (int init) : impl(new Q_impl (init)) { } 54 | Q (const Q &q) : impl(q.impl) { } 55 | Q (copy, const Q &q) : impl(new Q_impl (COPY, q.impl->x)) { } 56 | Q (reader &r) : impl(new Q_impl (r)) { } 57 | ~Q () { } 58 | 59 | Q &operator = (const Q &q) { impl = q.impl; return *this; } 60 | Q &operator = (int x) { impl = new Q_impl (x); return *this; } 61 | 62 | bool operator == (const Q &q) const { return mpq_cmp (impl->x,q.impl->x) == 0; } 63 | 64 | bool operator == (int r) const { return mpq_cmp_si (impl->x, r, 1) == 0; } 65 | bool operator != (int r) const { return !operator == (r); } 66 | 67 | bool operator < (const Q &q) const { return mpq_cmp (impl->x, q.impl->x) < 0; } 68 | 69 | bool is_unit () const 70 | { 71 | return *this != 0; 72 | } 73 | 74 | Q operator - () const 75 | { 76 | mpq_t x; 77 | mpq_init (x); 78 | mpq_neg (x, impl->x); 79 | return Q (STEAL, x); 80 | } 81 | 82 | Q recip () const 83 | { 84 | mpq_t x; 85 | mpq_init (x); 86 | mpq_inv (x, impl->x); 87 | return Q (STEAL, x); 88 | } 89 | 90 | Q operator + (const Q &q) const 91 | { 92 | mpq_t x; 93 | mpq_init (x); 94 | mpq_add (x, impl->x, q.impl->x); 95 | return Q (STEAL, x); 96 | } 97 | 98 | Q operator - (const Q &q) const 99 | { 100 | mpq_t x; 101 | mpq_init (x); 102 | mpq_sub (x, impl->x, q.impl->x); 103 | return Q (STEAL, x); 104 | } 105 | 106 | Q operator * (const Q &q) const 107 | { 108 | mpq_t x; 109 | mpq_init (x); 110 | mpq_mul (x, impl->x, q.impl->x); 111 | return Q (STEAL, x); 112 | } 113 | 114 | Q operator / (const Q &q) const 115 | { 116 | assert (q != 0); 117 | 118 | mpq_t x; 119 | mpq_init (x); 120 | mpq_div (x, impl->x, q.impl->x); 121 | return Q (STEAL, x); 122 | } 123 | 124 | Q &muladdeq (const Q &q1, const Q &q2) 125 | { 126 | // ??? do inline saves refcount overhead 127 | return operator += (q1 * q2); 128 | } 129 | 130 | Q &operator += (const Q &q) 131 | { 132 | mpq_add (impl->x, impl->x, q.impl->x); 133 | return *this; 134 | } 135 | 136 | Q &operator -= (const Q &q) 137 | { 138 | mpq_sub (impl->x, impl->x, q.impl->x); 139 | return *this; 140 | } 141 | 142 | Q &operator *= (const Q &q) 143 | { 144 | mpq_mul (impl->x, impl->x, q.impl->x); 145 | return *this; 146 | } 147 | 148 | Q &operator /= (const Q &q) 149 | { 150 | assert (q != 0); 151 | 152 | mpq_div (impl->x, impl->x, q.impl->x); 153 | return *this; 154 | } 155 | 156 | // d | n, d.divides (n) 157 | bool divides (const Q &num) const 158 | { 159 | return *this != 0 || num == 0; 160 | } 161 | 162 | bool operator | (const Q &num) const { return divides (num); } 163 | 164 | Q div (const Q &d) const { return operator / (d); } 165 | 166 | tuple extended_gcd (const Q &q) const 167 | { 168 | if (*this != 0) 169 | return tuple (*this, 1, 0); 170 | else 171 | return tuple (q, 0, 1); 172 | } 173 | 174 | Q gcd (const Q &q) const 175 | { 176 | assert (*this != 0 || q != 0); 177 | return 1; 178 | } 179 | 180 | static void show_ring () { printf ("Q"); } 181 | void show_self () const { mpq_out_str (stdout, 10, impl->x); } 182 | void display_self () const { show_self (); newline (); } 183 | void write_self (writer &w) const { write (w, *impl); } 184 | }; 185 | -------------------------------------------------------------------------------- /algebra/Z.h: -------------------------------------------------------------------------------- 1 | 2 | class Z 3 | { 4 | public: 5 | typedef ::linear_combination linear_combination; 6 | typedef ::linear_combination_const_iter linear_combination_const_iter; 7 | 8 | private: 9 | enum steal { STEAL }; 10 | 11 | class Z_impl : public refcounted 12 | { 13 | public: 14 | mpz_t x; 15 | 16 | public: 17 | Z_impl () { mpz_init (x); } 18 | Z_impl (int init) { mpz_init_set_si (x, init); } 19 | Z_impl (copy, mpz_srcptr init) { mpz_init_set (x, init); } 20 | Z_impl (steal, mpz_srcptr init) { x[0] = *init; } 21 | Z_impl (reader &r) 22 | { 23 | mpz_init (x); 24 | r.read_mpz (x); 25 | } 26 | 27 | ~Z_impl () { mpz_clear (x); } 28 | 29 | void write_self (writer &w) const 30 | { 31 | w.write_mpz (x); 32 | } 33 | }; 34 | 35 | ptr impl; 36 | 37 | Z (steal, mpz_srcptr init) : impl(new Z_impl (STEAL, init)) { } 38 | 39 | public: 40 | Z () : impl(new Z_impl) { } 41 | Z (int init) : impl(new Z_impl (init)) { } 42 | Z (const Z &z) : impl(z.impl) { } 43 | Z (copy, const Z &z) : impl(new Z_impl (COPY, z.impl->x)) { } 44 | Z (reader &r) : impl(new Z_impl (r)) { } 45 | ~Z () { } 46 | 47 | Z &operator = (const Z &z) { impl = z.impl; return *this; } 48 | Z &operator = (int x) { impl = new Z_impl (x); return *this; } 49 | 50 | bool operator == (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) == 0; } 51 | bool operator != (const Z &z) const { return !operator == (z); } 52 | 53 | bool operator == (int y) const { return mpz_cmp_si (impl->x, y) == 0; } 54 | bool operator != (int y) const { return !operator == (y); } 55 | 56 | bool operator < (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) < 0; } 57 | 58 | bool is_unit () const 59 | { 60 | return *this == 1 || *this == -1; 61 | } 62 | 63 | Z operator + (const Z &z) const 64 | { 65 | mpz_t x; 66 | mpz_init (x); 67 | mpz_add (x, impl->x, z.impl->x); 68 | return Z (STEAL, x); 69 | } 70 | 71 | Z operator - () const 72 | { 73 | mpz_t x; 74 | mpz_init (x); 75 | mpz_neg (x, impl->x); 76 | return Z (STEAL, x); 77 | } 78 | 79 | Z operator - (const Z &z) const 80 | { 81 | mpz_t x; 82 | mpz_init (x); 83 | mpz_sub (x, impl->x, z.impl->x); 84 | return Z (STEAL, x); 85 | } 86 | 87 | Z operator * (const Z &z) const 88 | { 89 | mpz_t x; 90 | mpz_init (x); 91 | mpz_mul (x, impl->x, z.impl->x); 92 | return Z (STEAL, x); 93 | } 94 | 95 | Z operator / (const Z &denom) const 96 | { 97 | if (mpz_cmp_si (denom.impl->x, 1) == 0) 98 | return *this; 99 | else 100 | { 101 | assert (mpz_cmp_si (denom.impl->x, -1) == 0); 102 | 103 | mpz_t x; 104 | mpz_init (x); 105 | mpz_neg (x, impl->x); 106 | return Z (STEAL, x); 107 | } 108 | } 109 | 110 | Z recip () const 111 | { 112 | assert (is_unit ()); 113 | return Z (COPY, *this); 114 | } 115 | 116 | // *this += z1*z2 117 | Z &muladdeq (const Z &z1, const Z &z2) 118 | { 119 | mpz_addmul (impl->x, z1.impl->x, z2.impl->x); 120 | return *this; 121 | } 122 | 123 | Z &operator += (const Z &z) 124 | { 125 | mpz_add (impl->x, impl->x, z.impl->x); 126 | return *this; 127 | } 128 | 129 | Z &operator -= (const Z &z) 130 | { 131 | mpz_sub (impl->x, impl->x, z.impl->x); 132 | return *this; 133 | } 134 | 135 | Z &operator *= (const Z &z) 136 | { 137 | mpz_mul (impl->x, impl->x, z.impl->x); 138 | return *this; 139 | } 140 | 141 | Z &operator /= (const Z &z) 142 | { 143 | if (mpz_cmp_si (z.impl->x, 1) == 0) 144 | ; 145 | else 146 | { 147 | assert (mpz_cmp_si (z.impl->x, -1) == 0); 148 | mpz_neg (impl->x, impl->x); 149 | } 150 | return *this; 151 | } 152 | 153 | bool divides (const Z &num) const 154 | { 155 | return mpz_divisible_p (num.impl->x, impl->x); 156 | } 157 | bool operator | (const Z &num) const { return divides (num); } 158 | 159 | Z divide_exact (const Z &denom) const 160 | { 161 | // num = *this 162 | mpz_t q; 163 | mpz_init (q); 164 | mpz_divexact (q, impl->x, denom.impl->x); 165 | return Z (STEAL, q); 166 | } 167 | 168 | tuple divide_with_remainder (const Z &denom) const 169 | { 170 | // *this = num 171 | mpz_t q, r; 172 | mpz_init (q); 173 | mpz_init (r); 174 | mpz_tdiv_qr (q, r, impl->x, denom.impl->x); 175 | return make_tuple (Z (STEAL, q), 176 | Z (STEAL, r)); 177 | } 178 | 179 | Z gcd (const Z &z) const 180 | { 181 | mpz_t d; 182 | mpz_gcd (d, impl->x, z.impl->x); 183 | return Z (STEAL, d); 184 | } 185 | 186 | Z lcm (const Z &z) const 187 | { 188 | mpz_t m; 189 | mpz_lcm (m, impl->x, z.impl->x); 190 | return Z (STEAL, m); 191 | } 192 | 193 | tuple extended_gcd (const Z &z) const 194 | { 195 | mpz_t d, s, t; 196 | mpz_init (d); 197 | mpz_init (s); 198 | mpz_init (t); 199 | mpz_gcdext (d, s, t, impl->x, z.impl->x); 200 | return make_tuple (Z (STEAL, d), 201 | Z (STEAL, s), 202 | Z (STEAL, t)); 203 | } 204 | 205 | static void show_ring () { printf ("Z"); } 206 | void show_self () const { mpz_out_str (stdout, 10, impl->x); } 207 | void display_self () const { show_self (); newline (); } 208 | void write_self (writer &w) const { write (w, *impl); } 209 | }; 210 | -------------------------------------------------------------------------------- /algebra/Z2.h: -------------------------------------------------------------------------------- 1 | class Z2 2 | { 3 | public: 4 | typedef ::linear_combination linear_combination; 5 | // typedef linear_combination_iter linear_combination_iter; 6 | typedef ::linear_combination_const_iter linear_combination_const_iter; 7 | 8 | private: 9 | bool v; 10 | 11 | public: 12 | Z2 () : v(0) { } 13 | Z2 (int x) : v((bool)(x & 1)) { } 14 | Z2 (unsigned x) : v((bool)(x & 1)) { } 15 | Z2 (bool v_) : v(v_) { } 16 | Z2 (const Z2 &x) : v(x.v) { } 17 | Z2 (copy, const Z2 &x) : v(x.v) { } 18 | Z2 (reader &r) { v = r.read_bool (); } 19 | ~Z2 () { } 20 | 21 | Z2 &operator = (const Z2 &x) { v = x.v; return *this; } 22 | Z2 &operator = (int x) { v = (bool)(x & 1); return *this; } 23 | 24 | bool operator == (const Z2 &x) const { return v == x.v; } 25 | bool operator != (const Z2 &x) const { return v != x.v; } 26 | 27 | bool operator == (int x) const { return v == (bool)(x & 1); } 28 | bool operator != (int x) const { return !operator == (x); } 29 | 30 | bool is_unit () const { return v; } 31 | 32 | Z2 operator + (const Z2 &x) const { return Z2 (v ^ x.v); } 33 | Z2 operator - (const Z2 &x) const { return Z2 (v ^ x.v); } 34 | Z2 operator - () const { return *this; } 35 | Z2 operator * (const Z2 &x) const { return Z2 (v & x.v); } 36 | Z2 operator / (const Z2 &x) const { assert (x.v); return *this; } 37 | 38 | Z2 recip () const { assert (v); return *this; } 39 | 40 | Z2 &operator += (const Z2 &x) { v ^= x.v; return *this; } 41 | Z2 &operator -= (const Z2 &x) { v ^= x.v; return *this; } 42 | Z2 &operator *= (const Z2 &x) { v &= x.v; return *this; } 43 | Z2 &operator /= (const Z2 &x) { assert (x.v); return *this; } 44 | 45 | // *this += z1*z2 46 | Z2 &muladdeq (const Z2 &z1, const Z2 &z2) 47 | { 48 | return operator += (z1 * z2); 49 | } 50 | 51 | bool divides (Z2 x) const { return v || !x.v; } 52 | bool operator | (const Z2 x) const { return divides (x); } 53 | 54 | Z2 div (Z2 x) const 55 | { 56 | assert (x.divides (*this)); 57 | return *this; 58 | } 59 | 60 | Z2 gcd (Z2 x) const 61 | { 62 | assert (v && x.v); 63 | return Z2 (1); 64 | } 65 | 66 | tuple extended_gcd (Z2 x) const 67 | { 68 | if (v) 69 | return make_tuple (Z2 (1), Z2 (1), Z2 (0)); 70 | else 71 | return make_tuple (Z2 (1), Z2 (0), Z2 (1)); 72 | } 73 | 74 | static void show_ring () { printf ("Z2"); } 75 | void write_self (writer &w) const { w.write_bool (v); } 76 | void show_self () const { printf ("%d", (int)v); } 77 | void display_self () const { printf ("%d\n", (int)v); } 78 | }; 79 | -------------------------------------------------------------------------------- /algebra/Zp.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | class Zp 4 | { 5 | public: 6 | typedef ::linear_combination > linear_combination; 7 | typedef ::linear_combination_const_iter > linear_combination_const_iter; 8 | 9 | private: 10 | unsigned v; 11 | 12 | public: 13 | Zp () : v(0) { } 14 | Zp (unsigned init) : v(init % p) { } 15 | Zp (int init) 16 | { 17 | int i = init % (int)p; 18 | if (i < 0) 19 | i += p; 20 | assert (i >= 0 && i < (int)p); 21 | v = i; 22 | } 23 | 24 | Zp (const Zp &x) : v(x.v) { } 25 | Zp (copy, const Zp &x) : v(x.v) { } 26 | ~Zp () { } 27 | 28 | Zp &operator = (const Zp &x) { v = x.v; return *this; } 29 | Zp &operator = (int x) 30 | { 31 | return operator = (Zp (x)); 32 | } 33 | 34 | bool operator == (const Zp &x) const { return v == x.v; } 35 | bool operator != (const Zp &x) const { return !operator == (x); } 36 | 37 | bool operator == (int x) const { return operator == (Zp (x)); } 38 | bool operator != (int x) const { return !operator == (x); } 39 | 40 | bool operator < (const Zp &x) const { return v < x.v; } 41 | 42 | bool is_unit () const 43 | { 44 | return v != 0; 45 | } 46 | 47 | Zp operator + (const Zp &x) const { return Zp (v + x.v); } 48 | Zp operator - (const Zp &x) const { return Zp ((int)v - (int)x.v); } 49 | Zp operator - () const { return Zp (- (int)v); } 50 | 51 | Zp operator * (const Zp &x) const { return Zp (v * x.v); } 52 | 53 | Zp operator / (const Zp &x) const 54 | { 55 | return operator * (x.recip ()); 56 | } 57 | 58 | Zp recip () const 59 | { 60 | tuple t = unsigned_extended_gcd (v, p); 61 | assert (get<0> (t) == 1); 62 | assert ((int)get<0> (t) == get<1> (t)*(int)v + get<2> (t)*(int)p); 63 | 64 | return Zp (get<1> (t)); 65 | } 66 | 67 | Zp &operator += (const Zp &x) 68 | { 69 | v = (v + x.v) % p; 70 | return *this; 71 | } 72 | 73 | Zp &operator -= (const Zp &x) { return operator = (Zp ((int)v - (int)x.v)); } 74 | 75 | Zp &operator *= (const Zp &x) 76 | { 77 | v = (v * x.v) % p; 78 | return *this; 79 | } 80 | 81 | Zp &operator /= (const Zp &x) 82 | { 83 | return operator *= (x.recip ()); 84 | } 85 | 86 | // d | n, d.divides (n) 87 | bool divides (const Zp &n) const 88 | { 89 | return v || !n.v; 90 | } 91 | 92 | bool operator | (const Zp &n) const { return divides (n); } 93 | 94 | Zp div (const Zp &d) const { return operator / (d); } 95 | 96 | tuple extended_gcd (const Zp &x) const 97 | { 98 | if (v) 99 | return make_tuple (v, Zp (1), Zp (0)); 100 | else 101 | return make_tuple (x, Zp (0), Zp (1)); 102 | } 103 | 104 | Zp gcd (const Zp &x) const 105 | { 106 | assert (v || x.v); 107 | return 1; 108 | } 109 | 110 | static void show_ring () { printf ("Z%d", p); } 111 | void show_self () const { printf ("%d (%d)", v, p); } 112 | void display_self () const { show_self (); newline (); } 113 | }; 114 | -------------------------------------------------------------------------------- /algebra/algebra.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | unsigned 5 | unsigned_gcd (unsigned a, unsigned b) 6 | { 7 | while (b != 0) 8 | { 9 | unsigned t = a % b; 10 | a = b; 11 | b = t; 12 | } 13 | return a; 14 | } 15 | 16 | unsigned 17 | int_gcd (int a, int b) 18 | { 19 | return unsigned_gcd ((unsigned)abs (a), 20 | (unsigned)abs (b)); 21 | } 22 | 23 | uint64 24 | uint64_gcd (uint64 a, uint64 b) 25 | { 26 | while (b != 0) 27 | { 28 | uint64 t = a % b; 29 | a = b; 30 | b = t; 31 | } 32 | return a; 33 | } 34 | 35 | uint64 36 | int64_gcd (int64 a, int64 b) 37 | { 38 | return uint64_gcd ((uint64)abs64 (a), 39 | (uint64)abs64 (b)); 40 | } 41 | 42 | static tuple 43 | extended_gcd_1 (int a, int b) 44 | { 45 | if (b == 0) 46 | return tuple (a, 1, 0); 47 | 48 | unsigned t = a % b; 49 | if (!t) 50 | return make_tuple (b, 0, 1); 51 | else 52 | { 53 | tuple s = unsigned_extended_gcd (b, t); 54 | 55 | unsigned d = get<0> (s); 56 | int x = get<2> (s), 57 | y = get<1> (s) - get<2> (s) * (a / b); 58 | 59 | assert ((int)d == a*x + b*y); 60 | 61 | return make_tuple (d, x, y); 62 | } 63 | } 64 | 65 | tuple 66 | unsigned_extended_gcd (unsigned a, unsigned b) 67 | { 68 | return extended_gcd_1 ((int)a, (int)b); 69 | } 70 | 71 | tuple 72 | extended_gcd (int a, int b) 73 | { 74 | tuple t = extended_gcd_1 (abs (a), 75 | abs (b)); 76 | unsigned d = get<0> (t); 77 | int x = get<1> (t), 78 | y = get<2> (t); 79 | if (a < 0) 80 | x *= -1; 81 | if (b < 0) 82 | y *= -1; 83 | 84 | assert ((int)d == a*x + b*y); 85 | 86 | return make_tuple (d, x, y); 87 | } 88 | 89 | unsigned 90 | unsigned_lcm (unsigned a, unsigned b) 91 | { 92 | return (a / unsigned_gcd (a, b)) * b; 93 | } 94 | 95 | uint64 96 | uint64_lcm (uint64 a, uint64 b) 97 | { 98 | return (a / uint64_gcd (a, b)) * b; 99 | } 100 | 101 | unsigned int_lcm (int a, int b) 102 | { 103 | return unsigned_lcm ((unsigned)abs (a), 104 | (unsigned)abs (b)); 105 | } 106 | 107 | uint64 int64_lcm (int64 a, int64 b) 108 | { 109 | return uint64_lcm ((uint64)abs64 (a), 110 | (uint64)abs64 (b)); 111 | } 112 | -------------------------------------------------------------------------------- /algebra/algebra.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | inline int recip (int x) 5 | { 6 | assert (x == 1 || x == -1); 7 | return x; 8 | } 9 | 10 | template inline T recip (const T &x) { return x.recip (); } 11 | 12 | template inline T 13 | pow (const T &x, int d) 14 | { 15 | if (d == 0) 16 | return 1; 17 | else if (d == 1) 18 | return x; 19 | else if (d < 0) 20 | return pow (recip (x), -d); 21 | else 22 | { 23 | T x2 = x * x; 24 | if (d & 1) 25 | return x * pow (x2, (d - 1) / 2); 26 | else 27 | return pow (x2, d / 2); 28 | } 29 | } 30 | 31 | unsigned unsigned_gcd (unsigned a, unsigned b); 32 | uint64 uint64_gcd (uint64 a, uint64 b); 33 | 34 | unsigned int_gcd (int a, int b); 35 | uint64 int64_gcd (int64 a, int64 b); 36 | 37 | unsigned unsigned_lcm (unsigned a, unsigned b); 38 | uint64 uint64_lcm (uint64 a, uint64 b); 39 | unsigned int_lcm (int a, int b); 40 | uint64 int64_lcm (int64 a, int64 b); 41 | 42 | // (d, x, y) = gcd (a, b) where x*a + y*b = d 43 | tuple extended_gcd (int a, int b); 44 | 45 | tuple unsigned_extended_gcd (unsigned a, unsigned b); 46 | 47 | template class linear_combination; 48 | template class linear_combination_const_iter; 49 | 50 | template class module; 51 | 52 | /* constructor tag for multivariate_polynomial, 53 | multivariate_laurentpoly. */ 54 | enum variable { VARIABLE }; 55 | 56 | #include 57 | 58 | #include 59 | 60 | #include 61 | #include 62 | 63 | #include 64 | #include 65 | #include 66 | #include 67 | 68 | #include 69 | 70 | #include 71 | #include 72 | -------------------------------------------------------------------------------- /algebra/fields.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | -------------------------------------------------------------------------------- /algebra/fraction_field.h: -------------------------------------------------------------------------------- 1 | 2 | template class fraction_field 3 | { 4 | public: 5 | typedef ::linear_combination linear_combination; 6 | typedef ::linear_combination_const_iter linear_combination_const_iter; 7 | 8 | private: 9 | T num; 10 | T denom; 11 | 12 | enum reduced { REDUCED }; 13 | 14 | void reduce (); 15 | void check (); 16 | 17 | public: 18 | fraction_field () : num(0), denom(1) { } 19 | fraction_field (int x) : num(x), denom(1) { } 20 | fraction_field (T num_) : num(num_), denom(1) { } 21 | fraction_field (T num_, T denom_) : num(num_), denom(denom_) { assert (denom != 0); reduce (); } 22 | fraction_field (reduced, T num_, T denom_) 23 | : num(num_), denom(denom_) 24 | { 25 | assert (denom != 0); 26 | #ifndef NDEBUG 27 | check (); 28 | #endif 29 | } 30 | 31 | fraction_field (const fraction_field &q) : num(q.num), denom(q.denom) { } 32 | fraction_field (copy, const fraction_field &q) : num(COPY, q.num), denom(COPY, q.denom) { } 33 | ~fraction_field () { } 34 | 35 | fraction_field &operator = (const fraction_field &q) { num = q.num; denom = q.denom; return *this; } 36 | fraction_field &operator = (int x) { num = x; denom = 1; return *this; } 37 | 38 | bool operator == (const fraction_field &q) const { return num * q.denom == q.num * denom; } 39 | bool operator != (const fraction_field &q) const { return !operator == (q); } 40 | 41 | bool operator == (int x) const { return num == denom * T (x); } 42 | bool operator != (int x) const { return !operator == (x); } 43 | 44 | bool is_unit () const { return num != 0; } 45 | 46 | fraction_field operator + (const fraction_field &x) const 47 | { 48 | T d = denom.gcd (x.denom); 49 | T e = denom.divide_exact (d), 50 | xe = x.denom.divide_exact (d); 51 | 52 | T new_num = num * xe; 53 | new_num += x.num * e; 54 | 55 | return fraction_field (new_num, denom*xe); 56 | } 57 | 58 | fraction_field operator - (const fraction_field &x) const 59 | { 60 | T d = denom.gcd (x.denom); 61 | T e = denom.divide_exact (d), 62 | xe = x.denom.divide_exact (d); 63 | 64 | T new_num = num * xe; 65 | new_num -= x.num * e; 66 | 67 | return fraction_field (new_num, denom*xe); 68 | } 69 | 70 | fraction_field operator - () const 71 | { 72 | return fraction_field (-num, denom); 73 | } 74 | 75 | fraction_field operator * (const fraction_field &x) const 76 | { 77 | T d1 = num.gcd (x.denom); 78 | T d2 = denom.gcd (x.num); 79 | return fraction_field (REDUCED, 80 | num.divide_exact (d1) * x.num.divide_exact (d2), 81 | denom.divide_exact (d2) * x.denom.divide_exact (d1)); 82 | } 83 | 84 | fraction_field operator / (const fraction_field &x) const 85 | { 86 | assert (x.num != 0); 87 | 88 | T d1 = num.gcd (x.num); 89 | T d2 = denom.gcd (x.denom); 90 | return fraction_field (REDUCED, 91 | num.divide_exact (d1) * x.denom.divide_exact (d2), 92 | denom.divide_exact (d2) * x.num.divide_exact (d1)); 93 | } 94 | 95 | fraction_field &invert () 96 | { 97 | assert (num != 0); 98 | T t = num; 99 | num = denom; 100 | denom = t; 101 | return *this; 102 | } 103 | 104 | fraction_field recip () const 105 | { 106 | assert (num != 0); 107 | return fraction_field (T (COPY, denom), 108 | T (COPY, num)); 109 | } 110 | 111 | fraction_field &operator += (const fraction_field &x) 112 | { 113 | T d = denom.gcd (x.denom); 114 | T e = denom.divide_exact (d), 115 | xe = x.denom.divide_exact (d); 116 | 117 | num *= xe; 118 | num += x.num * e; 119 | denom *= xe; 120 | 121 | reduce (); 122 | 123 | return *this; 124 | } 125 | 126 | fraction_field &operator -= (const fraction_field &x) 127 | { 128 | T d = denom.gcd (x.denom); 129 | T e = denom.divide_exact (d), 130 | xe = x.denom.divide_exact (d); 131 | 132 | num *= xe; 133 | num -= x.num * e; 134 | denom *= xe; 135 | 136 | reduce (); 137 | 138 | return *this; 139 | } 140 | 141 | fraction_field &operator *= (const fraction_field &x) 142 | { 143 | T d1 = num.gcd (x.denom); 144 | num = num.divide_exact (d1); 145 | 146 | T d2 = denom.gcd (x.num); 147 | denom = denom.divide_exact (d2); 148 | 149 | num *= x.num.divide_exact (d2); 150 | denom *= x.denom.divide_exact (d1); 151 | 152 | #ifndef NDEBUG 153 | check (); 154 | #endif 155 | 156 | return *this; 157 | } 158 | 159 | fraction_field &operator /= (const fraction_field &x) 160 | { 161 | assert (x.num != 0); 162 | 163 | T d1 = num.gcd (x.num); 164 | num = num.divide_exact (d1); 165 | 166 | T d2 = denom.gcd (x.denom); 167 | denom = denom.divide_exact (d2); 168 | 169 | num *= x.denom.divide_exact (d2); 170 | denom *= x.num.divide_exact (d1); 171 | 172 | #ifndef NDEBUG 173 | check (); 174 | #endif 175 | 176 | return *this; 177 | } 178 | 179 | // d | n, d.divides (n) 180 | bool divides (const fraction_field &n) const 181 | { 182 | // d = *this 183 | return (num != 0) || (n.num == 0); 184 | } 185 | 186 | bool operator | (const fraction_field &q) const { return divides (q); } 187 | 188 | fraction_field div (const fraction_field &d) const { return operator / (d); } 189 | 190 | fraction_field gcd (const fraction_field &q) const 191 | { 192 | assert (num != 0 && q.num != 0); 193 | return fraction_field (1); 194 | } 195 | 196 | tuple extended_gcd (const fraction_field &x) const 197 | { 198 | if (*this != 0) 199 | return make_tuple (*this, fraction_field (1), fraction_field (0)); 200 | else 201 | return make_tuple (x, fraction_field (0), fraction_field (1)); 202 | } 203 | 204 | static void show_ring () { printf ("fraction_field("); T::show_ring (); printf (")"); } 205 | void show_self () const; 206 | void display_self () const { show_self (); newline (); } 207 | }; 208 | 209 | template void 210 | fraction_field::reduce () 211 | { 212 | if (num == 0) 213 | { 214 | denom = 1; 215 | return; 216 | } 217 | 218 | T d = num.gcd (denom); 219 | num = num.divide_exact (d); 220 | denom = denom.divide_exact (d); 221 | } 222 | 223 | template void 224 | fraction_field::check () 225 | { 226 | if (num == 0) 227 | return; 228 | 229 | // assert (num.gcd (denom) == 1); 230 | } 231 | 232 | template void 233 | fraction_field::show_self () const 234 | { 235 | if (denom == 1) 236 | show (num); 237 | else 238 | { 239 | printf ("("); 240 | show (num); 241 | printf (")/("); 242 | show (denom); 243 | printf (")"); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /algebra/grading.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | grading 5 | grading::mirror_grading (unsigned nplus, unsigned nminus, bool torsion) const 6 | { 7 | return grading (torsion ? (1-h) : -h, 8 | -q); 9 | } 10 | 11 | void 12 | grading::show_self () const 13 | { 14 | printf ("(%d, %d)", h, q); 15 | } 16 | 17 | void 18 | grading::display_self () const 19 | { 20 | printf ("(%d, %d)\n", h, q); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /algebra/grading.h: -------------------------------------------------------------------------------- 1 | 2 | class grading 3 | { 4 | public: 5 | int h, q; 6 | 7 | public: 8 | grading () : h(0), q(0) { } 9 | grading (int h_, int q_) : h(h_), q(q_) { } 10 | grading (const grading &gr) : h(gr.h), q(gr.q) { } 11 | grading (reader &r) 12 | { 13 | h = r.read_int (); 14 | q = r.read_int (); 15 | } 16 | 17 | ~grading () { } 18 | 19 | grading &operator = (const grading &gr) { h = gr.h; q = gr.q; return *this; } 20 | 21 | grading operator + (const grading &gr) const 22 | { 23 | return grading (h + gr.h, q + gr.q); 24 | } 25 | grading operator - (const grading &gr) const 26 | { 27 | return grading (h - gr.h, q - gr.q); 28 | } 29 | 30 | grading &operator += (const grading &gr) 31 | { 32 | h += gr.h; 33 | q += gr.q; 34 | return *this; 35 | } 36 | 37 | grading &operator -= (const grading &gr) 38 | { 39 | h -= gr.h; 40 | q -= gr.q; 41 | return *this; 42 | } 43 | 44 | bool operator == (const grading &gr) const { return h == gr.h && q == gr.q; } 45 | bool operator != (const grading &gr) const { return !operator == (gr); } 46 | 47 | bool operator < (const grading &gr) const 48 | { 49 | return h < gr.h 50 | || (h == gr.h && q < gr.q); 51 | } 52 | 53 | grading mirror_grading (unsigned nplus, unsigned nminus, bool torsion) const; 54 | 55 | void write_self (writer &w) const 56 | { 57 | w.write_int (h); 58 | w.write_int (q); 59 | } 60 | 61 | void show_self () const; 62 | void display_self () const; 63 | }; 64 | -------------------------------------------------------------------------------- /algebra/polynomial.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | polynomial 5 | polynomial::operator * (polynomial p) const 6 | { 7 | set r_coeffs; 8 | 9 | for (set_const_iter i = coeffs; i; i ++) 10 | for (set_const_iter j = p.coeffs; j; j ++) 11 | r_coeffs.toggle (i.val () + j.val ()); 12 | 13 | return polynomial (r_coeffs); 14 | } 15 | 16 | pair, polynomial > 17 | polynomial::divide_with_remainder (polynomial d) const 18 | { 19 | assert (d != 0); 20 | 21 | polynomial r (COPY, *this); 22 | polynomial q; 23 | 24 | unsigned d_leading_exponent = d.coeffs.tail (); 25 | for (;;) 26 | { 27 | if (r == 0) 28 | break; 29 | 30 | unsigned r_leading_exponent = r.coeffs.tail (); 31 | if (r_leading_exponent < d_leading_exponent) 32 | break; 33 | 34 | for (set_const_iter i = d.coeffs; i; i ++) 35 | r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ()); 36 | q.coeffs.toggle (r_leading_exponent - d_leading_exponent); 37 | } 38 | 39 | assert (r == 0 || r.degree () < d.degree ()); 40 | // assert (*this == q*d + r); 41 | 42 | return pair, polynomial > (q, r); 43 | } 44 | 45 | polynomial 46 | polynomial::mod (polynomial d) const 47 | { 48 | assert (d != 0); 49 | 50 | polynomial r (COPY, *this); 51 | 52 | unsigned d_leading_exponent = d.coeffs.tail (); 53 | for (;;) 54 | { 55 | if (r == 0) 56 | break; 57 | 58 | unsigned r_leading_exponent = r.coeffs.tail (); 59 | if (r_leading_exponent < d_leading_exponent) 60 | break; 61 | 62 | for (set_const_iter i = d.coeffs; i; i ++) 63 | r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ()); 64 | } 65 | 66 | assert (r == 0 || r.degree () < d.degree ()); 67 | 68 | return r; 69 | } 70 | 71 | bool 72 | polynomial::divides (polynomial d) const 73 | { 74 | return mod (d) == 0; 75 | } 76 | 77 | polynomial 78 | polynomial::divide_exact (polynomial d) const 79 | { 80 | pair, polynomial > qr = divide_with_remainder (d); 81 | assert (qr.second == 0); 82 | return qr.first; 83 | } 84 | 85 | polynomial 86 | polynomial::gcd (polynomial b) const 87 | { 88 | // ??? can return *this 89 | polynomial a = *this; 90 | 91 | while (b != 0) 92 | { 93 | pair, polynomial > a_qr = a.divide_with_remainder (b); 94 | a = b; 95 | b = a_qr.second; 96 | } 97 | return a; 98 | } 99 | 100 | void 101 | polynomial::show_self () const 102 | { 103 | unsigned first = 1; 104 | for (set_const_iter i = coeffs; i; i ++) 105 | { 106 | unsigned e = i.val (); 107 | 108 | if (first) 109 | first = 0; 110 | else 111 | printf (" + "); 112 | 113 | if (e == 0) 114 | printf ("1"); 115 | else 116 | { 117 | if (e == 1) 118 | printf ("x"); 119 | else 120 | printf ("x^%d", e); 121 | } 122 | } 123 | if (first) 124 | printf ("0"); 125 | } 126 | -------------------------------------------------------------------------------- /alternating: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cseed/knotkit/4fdd08f1d1db7b2e64dd8f186d32c8381db79b0f/alternating -------------------------------------------------------------------------------- /cobordism.h: -------------------------------------------------------------------------------- 1 | 2 | static const unsigned max_cpts = max_crossings * 2; 3 | 4 | enum reverse_crossing_t { REVERSE_CROSSING }; 5 | enum reverse_orientation_t { REVERSE_ORIENTATION }; 6 | 7 | class resolution_diagram 8 | { 9 | public: 10 | unsigned n_crossings; 11 | smallbitset resolved; 12 | smallbitset to_resolve; 13 | unsigned n_starting_circles; 14 | unsigned n_ending_circles; 15 | 16 | unsigned marked_edge; // edge from cpt 17 | unsigned marked_edge2; 18 | 19 | smallbitset cpt_inside; 20 | /* prev, next cpt on circle in some orientation */ 21 | basedvector prev, next; 22 | basedvector cpt_starting_circle; 23 | basedvector cpt_ending_circle; 24 | 25 | unsigned num_cpts () const { return n_crossings * 2; } 26 | unsigned crossing_from_cpt (unsigned c) const 27 | { 28 | assert (between (1, c, n_crossings)); 29 | return c * 2 - 1; 30 | } 31 | unsigned crossing_to_cpt (unsigned c) const 32 | { 33 | assert (between (1, c, n_crossings)); 34 | return c * 2; 35 | } 36 | unsigned is_from_cpt (unsigned pt) const 37 | { 38 | assert (between (1, pt, num_cpts ())); 39 | return is_odd (pt); 40 | } 41 | unsigned is_to_cpt (unsigned pt) const 42 | { 43 | assert (between (1, pt, num_cpts ())); 44 | return is_even (pt); 45 | } 46 | unsigned cpt_crossing (unsigned pt) const 47 | { 48 | assert (between (1, pt, num_cpts ())); 49 | return (pt + 1) / 2; 50 | } 51 | unsigned other_cpt (unsigned pt) const 52 | { 53 | assert (between (1, pt, num_cpts ())); 54 | if (is_odd (pt)) 55 | return pt + 1; 56 | else 57 | return pt - 1; 58 | } 59 | unsigned marked_starting_circle () const 60 | { 61 | assert (marked_edge); 62 | return cpt_starting_circle[marked_edge]; 63 | } 64 | unsigned marked_ending_circle () const 65 | { 66 | assert (marked_edge); 67 | unsigned c = cpt_crossing (marked_edge); 68 | 69 | if (to_resolve(c)) 70 | { 71 | if (is_to_cpt (marked_edge) != cpt_inside(marked_edge)) 72 | return cpt_ending_circle[crossing_from_cpt (c)]; 73 | else 74 | return cpt_ending_circle[crossing_to_cpt (c)]; 75 | } 76 | else 77 | { 78 | if (is_from_cpt (marked_edge)) 79 | return cpt_ending_circle[crossing_from_cpt (c)]; 80 | else 81 | return cpt_ending_circle[crossing_to_cpt (c)]; 82 | } 83 | } 84 | 85 | unsigned crossing_from (unsigned c) const 86 | { 87 | assert (between (1, c, n_crossings)); 88 | return cpt_starting_circle[crossing_from_cpt (c)]; 89 | } 90 | unsigned crossing_to (unsigned c) const 91 | { 92 | assert (between (1, c, n_crossings)); 93 | return cpt_starting_circle[crossing_to_cpt (c)]; 94 | } 95 | unsigned crossing_ending_from (unsigned c) const 96 | { 97 | assert (between (1, c, n_crossings)); 98 | return cpt_ending_circle[crossing_from_cpt (c)]; 99 | } 100 | unsigned crossing_ending_right (unsigned c) const { return crossing_ending_from (c); } 101 | unsigned crossing_ending_to (unsigned c) const 102 | { 103 | assert (between (1, c, n_crossings)); 104 | return cpt_ending_circle[crossing_to_cpt (c)]; 105 | } 106 | unsigned crossing_ending_left (unsigned c) const { return crossing_ending_to (c); } 107 | bool crossing_from_inside (unsigned c) const 108 | { 109 | assert (between (1, c, n_crossings)); 110 | return cpt_inside % crossing_from_cpt (c); 111 | } 112 | bool crossing_from_outside (unsigned c) const { return !crossing_from_inside (c); } 113 | bool crossing_to_inside (unsigned c) const 114 | { 115 | assert (between (1, c, n_crossings)); 116 | return cpt_inside % crossing_to_cpt (c); 117 | } 118 | bool crossing_to_outside (unsigned c) const { return !crossing_to_inside (c); } 119 | 120 | unsigned left_cpt (unsigned pt) const 121 | { 122 | if (cpt_inside % pt) 123 | return next[pt]; 124 | else 125 | return prev[pt]; 126 | } 127 | unsigned right_cpt (unsigned pt) const 128 | { 129 | if (cpt_inside % pt) 130 | return prev[pt]; 131 | else 132 | return next[pt]; 133 | } 134 | 135 | bool crossing_orientation (unsigned common, unsigned i) const; 136 | bool crossing_is_split (unsigned c) const { return crossing_from (c) == crossing_to (c); } 137 | bool crossing_is_join (unsigned c) const { return crossing_from (c) != crossing_to (c); } 138 | bool marked_edge_left (unsigned p) const; 139 | 140 | void compute_prev (); 141 | void check (); 142 | 143 | public: 144 | resolution_diagram (); 145 | 146 | resolution_diagram (unsigned n_crossings_, 147 | unsigned n_starting_circles_, 148 | unsigned n_ending_circles_); 149 | resolution_diagram (reverse_crossing_t, 150 | const resolution_diagram &rd, 151 | smallbitset to_reverse); 152 | resolution_diagram (reverse_orientation_t, 153 | const resolution_diagram &rd); 154 | 155 | resolution_diagram (const resolution_diagram &rd); // copies 156 | resolution_diagram (copy, const resolution_diagram &rd); 157 | resolution_diagram (reader &r); 158 | ~resolution_diagram () { } 159 | 160 | resolution_diagram &operator = (const resolution_diagram &rd); 161 | 162 | bool operator == (const resolution_diagram &rd) const; 163 | bool operator != (const resolution_diagram &rd) const { return !operator == (rd); } 164 | 165 | /* reverse, reverse_orientation leave starting/ending circle numbers 166 | unchanged. */ 167 | void reverse (); 168 | void reverse_orientation (); 169 | 170 | knot_diagram as_knot_diagram () const; 171 | 172 | void d (basedvector, 1> &out) const; 173 | void twisted_barE (basedvector >, 1> &out) const; 174 | void twin_arrows_P (basedvector, 1> &out) const; 175 | 176 | void write_self (writer &w) const; 177 | hash_t hash_self () const; 178 | void show_self () const; 179 | void display_self () const { show_self (); newline (); } 180 | }; 181 | 182 | class resolution_diagram_builder 183 | { 184 | public: 185 | ullmanset<1> gl_crossings; 186 | ullmanset<1> gl_starting_circles, gl_ending_circles; 187 | 188 | basedvector, 1> lg_edges; 189 | 190 | resolution_diagram rd; 191 | 192 | public: 193 | resolution_diagram_builder (); 194 | resolution_diagram_builder (const resolution_diagram_builder &) = delete; 195 | ~resolution_diagram_builder () { } 196 | 197 | resolution_diagram_builder &operator = (const resolution_diagram_builder &) = delete; 198 | 199 | void init (const knot_diagram &d, 200 | smallbitset from_state, const smoothing &from_s, 201 | smallbitset to_state, const smoothing &to_s, 202 | smallbitset crossings); 203 | 204 | void mirror (); 205 | void reverse_orientation (); 206 | void reverse_crossing (const knot_diagram &d, 207 | const smoothing &from_s, const smoothing &to_s, 208 | unsigned c); 209 | }; 210 | -------------------------------------------------------------------------------- /cube.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | sseq 5 | compute_szabo_sseq (const cube &c) 6 | { 7 | mod_map d = c.compute_d (0, 0, 0, 0, 0); 8 | 9 | sseq_builder builder (c.khC, d); 10 | return builder.build_sseq (); 11 | } 12 | -------------------------------------------------------------------------------- /cube.h: -------------------------------------------------------------------------------- 1 | 2 | class map_rules 3 | { 4 | public: 5 | map_rules () { } 6 | map_rules (const map_rules &) = delete; 7 | virtual ~map_rules () { } 8 | 9 | map_rules &operator = (const map_rules &) = delete; 10 | 11 | virtual void map (basedvector, 1> &out, 12 | resolution_diagram_builder &rdb) const = 0; 13 | }; 14 | 15 | template 16 | class cube /* of resolutions */ 17 | { 18 | public: 19 | typedef ::linear_combination linear_combination; 20 | typedef ::linear_combination_const_iter linear_combination_const_iter; 21 | 22 | public: 23 | bool markedp_only; 24 | 25 | knot_diagram &kd; 26 | unsigned n_crossings; 27 | unsigned n_resolutions; 28 | 29 | unsigned n_generators; 30 | vector resolution_circles; 31 | vector resolution_generator1; 32 | 33 | ptr > khC; 34 | 35 | mod_map compute_map (unsigned dh, unsigned max_n, 36 | bool mirror, 37 | bool reverse_orientation, 38 | unsigned to_reverse, 39 | const map_rules &rules) const; 40 | 41 | mod_map compute_d (unsigned dh, unsigned max_n, 42 | bool mirror, 43 | bool reverse_orientation, 44 | unsigned to_reverse) const; 45 | 46 | mod_map compute_twin_arrows_P (bool mirror, 47 | bool reverse_orientation, 48 | unsigned to_reverse) const; 49 | 50 | mod_map compute_dinv (unsigned c); 51 | mod_map H_i (unsigned c); 52 | 53 | mod_map compute_nu () const; 54 | mod_map compute_X (unsigned p) const; 55 | 56 | void check_reverse_crossings (); 57 | void check_reverse_orientation (); 58 | 59 | public: 60 | cube (knot_diagram &d_, bool markedp_only_ = 0); 61 | ~cube () { } 62 | 63 | grading compute_generator_grading (unsigned g) const; 64 | grading compute_state_monomial_grading (unsigned state, unsigned monomial) const; 65 | 66 | unsigned generator (unsigned i, unsigned j) const; 67 | pair generator_state_monomial (unsigned g) const; 68 | 69 | ptr > compute_kh () const; 70 | 71 | void show_state (unsigned state) const; 72 | void show_state_monomial (unsigned state, unsigned monomial) const; 73 | void show_self () const { printf ("cube"); } 74 | void display_self () const; 75 | }; 76 | 77 | class twisted_map_rules 78 | { 79 | public: 80 | twisted_map_rules () { } 81 | twisted_map_rules (const twisted_map_rules &) = delete; 82 | virtual ~twisted_map_rules () { } 83 | 84 | map_rules &operator = (const twisted_map_rules &) = delete; 85 | 86 | virtual void map (basedvector >, 1> &out, 87 | resolution_diagram_builder &rdb) const = 0; 88 | }; 89 | 90 | template 91 | class twisted_cube 92 | { 93 | public: 94 | typedef fraction_field > R; 95 | 96 | public: 97 | const cube &c; 98 | 99 | public: 100 | twisted_cube (const cube &c_) 101 | : c(c_) 102 | { } 103 | 104 | twisted_cube (const twisted_cube &) = delete; 105 | ~twisted_cube () { } 106 | 107 | twisted_cube &operator = (const twisted_cube &) = delete; 108 | 109 | mod_map compute_twisted_map (basedvector edge_weight, 110 | unsigned dh, 111 | unsigned to_reverse, 112 | const twisted_map_rules &rules) const; 113 | 114 | mod_map compute_twisted_barE (basedvector edge_weight, 115 | unsigned dh, unsigned to_reverse) const; 116 | mod_map twisted_d0 (basedvector edge_weight) const; 117 | }; 118 | 119 | extern sseq compute_szabo_sseq (const cube &c); 120 | 121 | #include 122 | -------------------------------------------------------------------------------- /dt_code.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | dt_code::dt_code (const std::string &name_, const char *p) 5 | : name(name_) 6 | { 7 | unsigned n_crossings = alpha_to_int (*p++); 8 | 9 | unsigned n_components = alpha_to_int (*p++); 10 | even_labels = basedvector, 1> (n_components); 11 | 12 | for (unsigned i = 1; i <= n_components; i ++) 13 | even_labels[i] = basedvector (alpha_to_int (*p++)); 14 | 15 | for (unsigned i = 1; i <= n_components; i ++) 16 | { 17 | for (unsigned j = 1; j <= even_labels[i].size (); j ++) 18 | even_labels[i][j] = alpha_to_int (*p++) * 2; 19 | } 20 | if (*p == '\n') 21 | p++; 22 | assert (*p == 0); 23 | 24 | assert (num_crossings () == n_crossings); 25 | } 26 | 27 | unsigned 28 | dt_code::num_crossings () const 29 | { 30 | unsigned n = 0; 31 | for (unsigned i = 1; i <= even_labels.size (); i ++) 32 | n += even_labels[i].size (); 33 | return n; 34 | } 35 | 36 | void 37 | dt_code::display_self () const 38 | { 39 | printf ("dt_code %s [", name.c_str ()); 40 | for (unsigned i = 1; i <= even_labels.size (); i ++) 41 | { 42 | if (i > 1) 43 | printf (", "); 44 | printf ("["); 45 | for (unsigned j = 1; j <= even_labels[i].size (); j ++) 46 | { 47 | if (j > 1) 48 | printf (", "); 49 | printf ("%d", even_labels[i][j]); 50 | } 51 | printf ("]"); 52 | } 53 | printf ("]\n"); 54 | } 55 | -------------------------------------------------------------------------------- /dt_code.h: -------------------------------------------------------------------------------- 1 | 2 | /* Dowker and Thistlethwaite codes */ 3 | 4 | /* minus = over */ 5 | 6 | class dt_code 7 | { 8 | public: 9 | std::string name; 10 | basedvector, 1> even_labels; 11 | 12 | public: 13 | dt_code (); 14 | dt_code (const std::string &name_, unsigned n_crossings, int even_labels_ar[]) 15 | : name(name_), even_labels(1) 16 | { 17 | even_labels[1] = basedvector (n_crossings); 18 | for (unsigned i = 0; i < n_crossings; i ++) 19 | even_labels[1][i + 1] = even_labels_ar[i]; 20 | } 21 | dt_code (const std::string &name_, const basedvector &even_labels_) 22 | : name(name_), even_labels(1) 23 | { 24 | even_labels[1] = even_labels_; 25 | } 26 | dt_code (const std::string &name_, const basedvector, 1> &even_labels_) 27 | : name(name_), even_labels(even_labels_) 28 | { 29 | } 30 | dt_code (const std::string &name_, const char *p); 31 | 32 | dt_code (const dt_code &dt) 33 | : name(dt.name), even_labels(dt.even_labels) 34 | { } 35 | ~dt_code () { } 36 | 37 | dt_code &operator = (const dt_code &dt) 38 | { 39 | name = dt.name; 40 | even_labels = dt.even_labels; 41 | return *this; 42 | } 43 | 44 | unsigned num_crossings () const; 45 | unsigned num_components () const { return even_labels.size (); } 46 | 47 | void show_self () const { printf ("dt_code %s", name.c_str ()); } 48 | void display_self () const; 49 | }; 50 | -------------------------------------------------------------------------------- /knot_diagram.h: -------------------------------------------------------------------------------- 1 | 2 | // for building knot_diagram 3 | inline unsigned edge_from_ept (unsigned e) 4 | { 5 | return e * 2 - 1; 6 | } 7 | inline unsigned edge_to_ept (unsigned e) 8 | { 9 | return e * 2; 10 | } 11 | 12 | static inline unsigned 13 | add_base1_mod4 (unsigned x, unsigned y) 14 | { 15 | assert (between (1, x, 4)); 16 | assert (between (0, y, 4)); 17 | 18 | return ((x - 1 + y) % 4) + 1; 19 | } 20 | 21 | enum mirror { MIRROR }; 22 | enum connect_sum { CONNECT_SUM }; 23 | enum sublink { SUBLINK }; 24 | enum disjoint_union { DISJOINT_UNION }; 25 | 26 | class knot_diagram 27 | { 28 | public: 29 | std::string name; 30 | 31 | unsigned n_crossings; 32 | unsigned marked_edge; 33 | 34 | basedvector, 1> crossings; 35 | basedvector ept_crossing; 36 | basedvector ept_index; 37 | 38 | /* true if the smoothing orientation for an edge matches the link 39 | orientation */ 40 | set edge_smoothing_oriented; 41 | 42 | unsigned nminus, nplus; 43 | 44 | unsigned num_edges () const { return n_crossings * 2; } 45 | unsigned num_epts () const { return n_crossings * 4; } 46 | unsigned ept_edge (unsigned p) const 47 | { 48 | assert (between (1, p, num_epts ())); 49 | return (p + 1) / 2; 50 | } 51 | unsigned edge_other_ept (unsigned p) const 52 | { 53 | assert (between (1, p, num_epts ())); 54 | if (is_odd (p)) 55 | return p + 1; 56 | else 57 | return p - 1; 58 | } 59 | 60 | unsigned edge_from_ept (unsigned e) const 61 | { 62 | assert (between (1, e, num_edges ())); 63 | return e * 2 - 1; 64 | } 65 | unsigned edge_to_ept (unsigned e) const 66 | { 67 | assert (between (1, e, num_edges ())); 68 | return e * 2; 69 | } 70 | unsigned is_from_ept (unsigned p) const 71 | { 72 | assert (between (1, p, num_epts ())); 73 | return is_odd (p); 74 | } 75 | unsigned is_to_ept (unsigned p) const { return !is_from_ept (p); } 76 | 77 | unsigned is_under_ept (unsigned p) const 78 | { 79 | assert (between (1, p, num_epts ())); 80 | return ept_index[p] == 1 || ept_index[p] == 3; 81 | } 82 | unsigned is_over_ept (unsigned p) const { return !is_under_ept (p); } 83 | 84 | bool is_crossing_from_ept (unsigned p) const 85 | { 86 | assert (is_under_ept (p)); 87 | return ept_index[p] == 1; 88 | } 89 | bool is_crossing_to_ept (unsigned p) const { return !is_crossing_from_ept (p); } 90 | 91 | /* wrt smoothing orientation */ 92 | unsigned edge_smoothing_from_ept (unsigned e) const 93 | { 94 | return edge_smoothing_oriented % e 95 | ? edge_from_ept (e) 96 | : edge_to_ept (e); 97 | } 98 | unsigned edge_smoothing_to_ept (unsigned e) const 99 | { 100 | return edge_smoothing_oriented % e 101 | ? edge_to_ept (e) 102 | : edge_from_ept (e); 103 | } 104 | bool is_smoothing_from_ept (unsigned p) const 105 | { 106 | unsigned e = ept_edge (p); 107 | return p == edge_smoothing_from_ept (e); 108 | } 109 | bool is_smoothing_to_ept (unsigned p) const { return !is_smoothing_from_ept (p); } 110 | 111 | unsigned num_components () const; 112 | 113 | void orient (); 114 | void calculate_nminus_nplus (); 115 | void calculate_smoothing_orientation (); 116 | 117 | void check_crossings (); 118 | void rotate_crossing (unsigned c); 119 | 120 | public: 121 | knot_diagram () 122 | : n_crossings(0), 123 | marked_edge(0), 124 | nminus(0), 125 | nplus(0) 126 | { } 127 | explicit knot_diagram (const planar_diagram &pd); 128 | explicit knot_diagram (const dt_code &dt); 129 | knot_diagram (mirror, const knot_diagram &kd); 130 | knot_diagram (connect_sum, 131 | const knot_diagram &d1, 132 | const knot_diagram &d2); 133 | knot_diagram (sublink, 134 | smallbitset c, 135 | const knot_diagram &kd); 136 | knot_diagram (disjoint_union, 137 | const knot_diagram &kd1, 138 | const knot_diagram &kd2); 139 | 140 | knot_diagram (const std::string &name_, unsigned n_crossings_, unsigned crossings_ar[][4]); 141 | knot_diagram (const std::string &name_, const basedvector, 1> &crossings_); 142 | knot_diagram (const knot_diagram &kd) 143 | : name(kd.name), 144 | n_crossings(kd.n_crossings), 145 | marked_edge(kd.marked_edge), 146 | crossings(kd.crossings), 147 | ept_crossing(kd.ept_crossing), 148 | ept_index(kd.ept_index), 149 | edge_smoothing_oriented(kd.edge_smoothing_oriented), 150 | nminus(kd.nminus), nplus(kd.nplus) 151 | { } 152 | ~knot_diagram () { } 153 | 154 | knot_diagram &operator = (const knot_diagram &kd) 155 | { 156 | name = kd.name; 157 | n_crossings = kd.n_crossings; 158 | marked_edge = kd.marked_edge; 159 | crossings = kd.crossings; 160 | ept_crossing = kd.ept_crossing; 161 | ept_index = kd.ept_index; 162 | edge_smoothing_oriented = kd.edge_smoothing_oriented; 163 | nminus = kd.nminus; 164 | nplus = kd.nplus; 165 | return *this; 166 | } 167 | 168 | directed_multigraph black_graph (basedvector &bg_edge_height) const; 169 | 170 | unsigned resolve_next_ept (unsigned p, bool resolution) const; 171 | 172 | int writhe () const { return (int)nplus - (int)nminus; } 173 | 174 | unsigned total_linking_number () const; 175 | 176 | basedvector, 1> planar_diagram_crossings () const; 177 | 178 | basedvector, 1> as_gauss_code () const; 179 | 180 | hash_t hash_self () const; 181 | 182 | void show_ept (unsigned p) const; 183 | void show_self () const; 184 | void display_self () const; 185 | }; 186 | -------------------------------------------------------------------------------- /knot_parser/knot_parser.yy: -------------------------------------------------------------------------------- 1 | 2 | %skeleton "lalr1.cc" 3 | %require "2.4.3" 4 | %defines 5 | %define parser_class_name "knot_parser" 6 | 7 | %parse-param { knot_diagram &parsed_knot } 8 | 9 | // %no-lines 10 | 11 | %code requires { 12 | #include 13 | } 14 | 15 | %code{ 16 | #define YY_DECL \ 17 | yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval) 18 | YY_DECL; 19 | } 20 | 21 | %union { 22 | int integer; 23 | bool alternating; 24 | basedvector *int_vec; 25 | basedvector, 1> *int_vec2; 26 | const char *string; 27 | knot_diagram *kd; 28 | } 29 | 30 | %code { 31 | #define yylex knot_yylex 32 | } 33 | 34 | %token INT 35 | 36 | %token END 0 "end of file" 37 | 38 | %token PD DT BR LINK X T 39 | %token U UNKNOT 40 | 41 | %token ALT NONALT 42 | %token STRING 43 | 44 | %type knot knot_1 45 | %type rolfsen_knot htw_knot mt_link planar_diagram dt torus_link unknot braid 46 | %type alt_spec 47 | 48 | %type int_vec int_vec_1 49 | %type int_vec2 50 | 51 | %type crossing 52 | %type crossing_vec 53 | 54 | %% 55 | 56 | %start entry; 57 | 58 | entry: 59 | knot 60 | { 61 | parsed_knot = *$1; 62 | delete $1; 63 | } 64 | ; 65 | 66 | knot: 67 | knot_1 68 | | knot knot 69 | { 70 | $$ = new knot_diagram (DISJOINT_UNION, *$1, *$2); 71 | delete $1; 72 | delete $2; 73 | } 74 | ; 75 | 76 | knot_1: 77 | rolfsen_knot 78 | | htw_knot 79 | | mt_link 80 | | planar_diagram 81 | | dt 82 | | torus_link 83 | | unknot 84 | | braid 85 | ; 86 | 87 | rolfsen_knot: 88 | INT '_' INT 89 | { 90 | unsigned n = $1, 91 | k = $3; 92 | 93 | if (n >= 1 && n <= 10 94 | && k >= 1 && k <= rolfsen_crossing_knots (n)) 95 | $$ = new knot_diagram (rolfsen_knot (n, k)); 96 | else 97 | { 98 | fprintf (stderr, "knot_parser: no such Rolfsen knot `%d_%d'\n", 99 | n, k); 100 | exit (EXIT_FAILURE); 101 | } 102 | } 103 | ; 104 | 105 | htw_knot: 106 | INT alt_spec INT 107 | { 108 | unsigned n = $1, 109 | k = $3; 110 | bool alt = $2; 111 | 112 | if (n >= 1 && n <= 16 113 | && k >= 1 && k <= htw_knots (n, alt)) 114 | $$ = new knot_diagram (htw_knot (n, alt, k)); 115 | else 116 | { 117 | fprintf (stderr, "knot_parser: no such HTW knot `%d%c%d'\n", 118 | n, alt ? 'a' : 'n', k); 119 | exit (EXIT_FAILURE); 120 | } 121 | } 122 | ; 123 | 124 | mt_link: 125 | LINK INT alt_spec INT 126 | { 127 | unsigned n = $2, 128 | k = $4; 129 | bool alt = $3; 130 | 131 | if (n >= 1 && n <= 14 132 | && k >= 1 && k <= mt_links (n, alt)) 133 | $$ = new knot_diagram (mt_link (n, alt, k)); 134 | else 135 | { 136 | fprintf (stderr, "knot_parser: no such MT link `%d%c%d'\n", 137 | n, alt ? 'a' : 'n', k); 138 | exit (EXIT_FAILURE); 139 | } 140 | } 141 | ; 142 | 143 | planar_diagram: 144 | PD '[' int_vec2 ']' 145 | { $$ = new knot_diagram (planar_diagram ("", *$3)); } 146 | | PD '[' crossing_vec ']' 147 | { $$ = new knot_diagram (planar_diagram ("", *$3)); } 148 | ; 149 | 150 | dt: 151 | DT '[' int_vec_1 ']' 152 | { 153 | basedvector, 1> even_labels (1); 154 | even_labels[1] = *$3; 155 | $$ = new knot_diagram (dt_code ("", even_labels)); 156 | } 157 | | DT '[' int_vec2 ']' 158 | { $$ = new knot_diagram (dt_code ("", *$3)); } 159 | | DT '[' STRING ']' 160 | { $$ = new knot_diagram (dt_code ("", $3)); } 161 | ; 162 | 163 | torus_link: 164 | T '(' INT ',' INT ')' 165 | { $$ = new knot_diagram (torus_knot ($3, $5)); } 166 | ; 167 | 168 | braid: 169 | BR '[' INT ',' int_vec ']' 170 | { $$ = new knot_diagram (braid ($3, *$5)); } 171 | ; 172 | 173 | unknot: 174 | UNKNOT 175 | { 176 | unsigned unknot_ar[1][4] = { 177 | { 2, 1, 3, 4, }, 178 | }; 179 | $$ = new knot_diagram ("U", 1, unknot_ar); 180 | } 181 | ; 182 | 183 | alt_spec: 184 | ALT 185 | | NONALT 186 | ; 187 | 188 | int_vec2: 189 | int_vec 190 | { 191 | basedvector, 1> *v 192 | = new basedvector, 1> (); 193 | v->append (*$1); 194 | $$ = v; 195 | } 196 | | int_vec2 ',' int_vec 197 | { 198 | basedvector, 1> *v = $1; 199 | v->append (*$3); 200 | $$ = v; 201 | } 202 | ; 203 | 204 | int_vec: 205 | '{' int_vec_1 '}' 206 | { $$ = $2; } 207 | | '[' int_vec_1 ']' 208 | { $$ = $2; } 209 | ; 210 | 211 | int_vec_1: 212 | INT 213 | { 214 | basedvector *v = 215 | new basedvector (); 216 | v->append ($1); 217 | $$ = v; 218 | } 219 | | int_vec_1 ',' INT 220 | { 221 | basedvector *v = $1; 222 | v->append ($3); 223 | $$ = v; 224 | } 225 | ; 226 | 227 | crossing_vec: 228 | crossing 229 | { 230 | basedvector, 1> *v 231 | = new basedvector, 1> (); 232 | v->append (*$1); 233 | $$ = v; 234 | } 235 | | crossing_vec ',' crossing 236 | { 237 | basedvector, 1> *v = $1; 238 | v->append (*$3); 239 | $$ = v; 240 | } 241 | ; 242 | 243 | crossing: 244 | X '[' INT ',' INT ',' INT ',' INT ']' 245 | { 246 | basedvector *v 247 | = new basedvector (); 248 | v->append ($3); 249 | v->append ($5); 250 | v->append ($7); 251 | v->append ($9); 252 | $$ = v; 253 | } 254 | 255 | %% 256 | 257 | void 258 | yy::knot_parser::error (const yy::knot_parser::location_type &l, 259 | const std::string &m) 260 | { 261 | fprintf (stderr, "knot_parser: parse error.\n"); 262 | exit (EXIT_FAILURE); 263 | } 264 | 265 | void knot_scan_string (const char *s); 266 | 267 | knot_diagram 268 | parse_knot (const char *s) 269 | { 270 | knot_scan_string (s); 271 | 272 | knot_diagram d; 273 | yy::knot_parser parser (d); 274 | parser.parse (); 275 | 276 | return d; 277 | } 278 | -------------------------------------------------------------------------------- /knot_parser/knot_parser_driver.cpp: -------------------------------------------------------------------------------- 1 | 2 | // includes knotkit 3 | #include "knot_parser.hh" 4 | 5 | void knot_scan_string (const char *s); 6 | 7 | knot_diagram 8 | parse_knot (const char *s) 9 | { 10 | knot_scan_string (s); 11 | 12 | knot_diagram d; 13 | yy::knot_parser parser (d); 14 | parser.parse (); 15 | 16 | return d; 17 | } 18 | -------------------------------------------------------------------------------- /knot_parser/knot_parser_driver.h: -------------------------------------------------------------------------------- 1 | 2 | knot_diagram parse_knot (const char *s); 3 | -------------------------------------------------------------------------------- /knot_parser/knot_scanner.ll: -------------------------------------------------------------------------------- 1 | 2 | %{ 3 | #include "knot_parser.hh" 4 | 5 | #define YY_DECL \ 6 | yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval) 7 | 8 | #define yyterminate() return token::END 9 | 10 | typedef yy::knot_parser::token token; 11 | typedef yy::knot_parser::token_type token_type; 12 | %} 13 | 14 | %option noyywrap nounput batch prefix="knot_yy" 15 | 16 | %% 17 | 18 | -?[0-9]+ { 19 | yylval->integer = atoi (yytext); 20 | return token::INT; 21 | } 22 | 23 | [a-zA-Z]+ { 24 | if (!strcmp (yytext, "a")) 25 | { 26 | yylval->alternating = 1; 27 | return token::ALT; 28 | } 29 | else if (!strcmp (yytext, "L")) 30 | return token::LINK; 31 | else if (!strcmp (yytext, "n")) 32 | { 33 | yylval->alternating = 0; 34 | return token::NONALT; 35 | } 36 | else if (!strcmp (yytext, "T")) 37 | return token::T; 38 | else if (!strcmp (yytext, "U") 39 | || !strcmp (yytext, "unknot")) 40 | return token::UNKNOT; 41 | else if (!strcmp (yytext, "X")) 42 | return token::X; 43 | else if (!strcmp (yytext, "BR")) 44 | return token::BR; 45 | else if (!strcmp (yytext, "PD")) 46 | return token::PD; 47 | else if (!strcmp (yytext, "DT") 48 | || !strcmp (yytext, "DTCode")) 49 | return token::DT; 50 | else if (!strcmp (yytext, "BR")) 51 | return token::BR; 52 | else 53 | { 54 | yylval->string = strdup (yytext); 55 | return token::STRING; 56 | } 57 | } 58 | 59 | [\t\r\n ] /* ignore */ 60 | 61 | . { return token_type (yytext[0]); } 62 | 63 | %% 64 | 65 | void 66 | knot_scan_string (const char *s) 67 | { 68 | knot_yy_scan_string (s); 69 | } 70 | -------------------------------------------------------------------------------- /knot_parser/location.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Locations for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file knot_parser/location.hh 35 | ** Define the yy::location class. 36 | */ 37 | 38 | #ifndef YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED 39 | # define YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED 40 | 41 | # include "position.hh" 42 | 43 | 44 | namespace yy { 45 | /* Line 166 of location.cc */ 46 | #line 47 "knot_parser/location.hh" 47 | 48 | /// Abstract a location. 49 | class location 50 | { 51 | public: 52 | 53 | /// Construct a location from \a b to \a e. 54 | location (const position& b, const position& e) 55 | : begin (b) 56 | , end (e) 57 | { 58 | } 59 | 60 | /// Construct a 0-width location in \a p. 61 | explicit location (const position& p = position ()) 62 | : begin (p) 63 | , end (p) 64 | { 65 | } 66 | 67 | /// Construct a 0-width location in \a f, \a l, \a c. 68 | explicit location (std::string* f, 69 | unsigned int l = 1u, 70 | unsigned int c = 1u) 71 | : begin (f, l, c) 72 | , end (f, l, c) 73 | { 74 | } 75 | 76 | 77 | /// Initialization. 78 | void initialize (std::string* f = YY_NULL, 79 | unsigned int l = 1u, 80 | unsigned int c = 1u) 81 | { 82 | begin.initialize (f, l, c); 83 | end = begin; 84 | } 85 | 86 | /** \name Line and Column related manipulators 87 | ** \{ */ 88 | public: 89 | /// Reset initial location to final location. 90 | void step () 91 | { 92 | begin = end; 93 | } 94 | 95 | /// Extend the current location to the COUNT next columns. 96 | void columns (unsigned int count = 1) 97 | { 98 | end += count; 99 | } 100 | 101 | /// Extend the current location to the COUNT next lines. 102 | void lines (unsigned int count = 1) 103 | { 104 | end.lines (count); 105 | } 106 | /** \} */ 107 | 108 | 109 | public: 110 | /// Beginning of the located region. 111 | position begin; 112 | /// End of the located region. 113 | position end; 114 | }; 115 | 116 | /// Join two location objects to create a location. 117 | inline const location operator+ (const location& begin, const location& end) 118 | { 119 | location res = begin; 120 | res.end = end.end; 121 | return res; 122 | } 123 | 124 | /// Add two location objects. 125 | inline const location operator+ (const location& begin, unsigned int width) 126 | { 127 | location res = begin; 128 | res.columns (width); 129 | return res; 130 | } 131 | 132 | /// Add and assign a location. 133 | inline location& operator+= (location& res, unsigned int width) 134 | { 135 | res.columns (width); 136 | return res; 137 | } 138 | 139 | /// Compare two location objects. 140 | inline bool 141 | operator== (const location& loc1, const location& loc2) 142 | { 143 | return loc1.begin == loc2.begin && loc1.end == loc2.end; 144 | } 145 | 146 | /// Compare two location objects. 147 | inline bool 148 | operator!= (const location& loc1, const location& loc2) 149 | { 150 | return !(loc1 == loc2); 151 | } 152 | 153 | /** \brief Intercept output stream redirection. 154 | ** \param ostr the destination output stream 155 | ** \param loc a reference to the location to redirect 156 | ** 157 | ** Avoid duplicate information. 158 | */ 159 | template 160 | inline std::basic_ostream& 161 | operator<< (std::basic_ostream& ostr, const location& loc) 162 | { 163 | position last = loc.end - 1; 164 | ostr << loc.begin; 165 | if (last.filename 166 | && (!loc.begin.filename 167 | || *loc.begin.filename != *last.filename)) 168 | ostr << '-' << last; 169 | else if (loc.begin.line != last.line) 170 | ostr << '-' << last.line << '.' << last.column; 171 | else if (loc.begin.column != last.column) 172 | ostr << '-' << last.column; 173 | return ostr; 174 | } 175 | 176 | 177 | } // yy 178 | /* Line 296 of location.cc */ 179 | #line 180 "knot_parser/location.hh" 180 | 181 | #endif /* !YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED */ 182 | -------------------------------------------------------------------------------- /knot_parser/position.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Positions for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file knot_parser/position.hh 35 | ** Define the yy::position class. 36 | */ 37 | 38 | #ifndef YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED 39 | # define YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED 40 | 41 | # include // std::max 42 | # include 43 | # include 44 | 45 | # ifndef YY_NULL 46 | # if defined __cplusplus && 201103L <= __cplusplus 47 | # define YY_NULL nullptr 48 | # else 49 | # define YY_NULL 0 50 | # endif 51 | # endif 52 | 53 | 54 | namespace yy { 55 | /* Line 36 of location.cc */ 56 | #line 57 "knot_parser/position.hh" 57 | /// Abstract a position. 58 | class position 59 | { 60 | public: 61 | 62 | /// Construct a position. 63 | explicit position (std::string* f = YY_NULL, 64 | unsigned int l = 1u, 65 | unsigned int c = 1u) 66 | : filename (f) 67 | , line (l) 68 | , column (c) 69 | { 70 | } 71 | 72 | 73 | /// Initialization. 74 | void initialize (std::string* fn = YY_NULL, 75 | unsigned int l = 1u, 76 | unsigned int c = 1u) 77 | { 78 | filename = fn; 79 | line = l; 80 | column = c; 81 | } 82 | 83 | /** \name Line and Column related manipulators 84 | ** \{ */ 85 | /// (line related) Advance to the COUNT next lines. 86 | void lines (int count = 1) 87 | { 88 | column = 1u; 89 | line += count; 90 | } 91 | 92 | /// (column related) Advance to the COUNT next columns. 93 | void columns (int count = 1) 94 | { 95 | column = std::max (1u, column + count); 96 | } 97 | /** \} */ 98 | 99 | /// File name to which this position refers. 100 | std::string* filename; 101 | /// Current line number. 102 | unsigned int line; 103 | /// Current column number. 104 | unsigned int column; 105 | }; 106 | 107 | /// Add and assign a position. 108 | inline position& 109 | operator+= (position& res, const int width) 110 | { 111 | res.columns (width); 112 | return res; 113 | } 114 | 115 | /// Add two position objects. 116 | inline const position 117 | operator+ (const position& begin, const int width) 118 | { 119 | position res = begin; 120 | return res += width; 121 | } 122 | 123 | /// Add and assign a position. 124 | inline position& 125 | operator-= (position& res, const int width) 126 | { 127 | return res += -width; 128 | } 129 | 130 | /// Add two position objects. 131 | inline const position 132 | operator- (const position& begin, const int width) 133 | { 134 | return begin + -width; 135 | } 136 | 137 | /// Compare two position objects. 138 | inline bool 139 | operator== (const position& pos1, const position& pos2) 140 | { 141 | return (pos1.line == pos2.line 142 | && pos1.column == pos2.column 143 | && (pos1.filename == pos2.filename 144 | || (pos1.filename && pos2.filename 145 | && *pos1.filename == *pos2.filename))); 146 | } 147 | 148 | /// Compare two position objects. 149 | inline bool 150 | operator!= (const position& pos1, const position& pos2) 151 | { 152 | return !(pos1 == pos2); 153 | } 154 | 155 | /** \brief Intercept output stream redirection. 156 | ** \param ostr the destination output stream 157 | ** \param pos a reference to the position to redirect 158 | */ 159 | template 160 | inline std::basic_ostream& 161 | operator<< (std::basic_ostream& ostr, const position& pos) 162 | { 163 | if (pos.filename) 164 | ostr << *pos.filename << ':'; 165 | return ostr << pos.line << '.' << pos.column; 166 | } 167 | 168 | 169 | } // yy 170 | /* Line 148 of location.cc */ 171 | #line 172 "knot_parser/position.hh" 172 | #endif /* !YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED */ 173 | -------------------------------------------------------------------------------- /knot_parser/stack.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Stack handling for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file knot_parser/stack.hh 35 | ** Define the yy::stack class. 36 | */ 37 | 38 | #ifndef YY_YY_KNOT_PARSER_STACK_HH_INCLUDED 39 | # define YY_YY_KNOT_PARSER_STACK_HH_INCLUDED 40 | 41 | # include 42 | 43 | 44 | namespace yy { 45 | /* Line 34 of stack.hh */ 46 | #line 47 "knot_parser/stack.hh" 47 | template > 48 | class stack 49 | { 50 | public: 51 | // Hide our reversed order. 52 | typedef typename S::reverse_iterator iterator; 53 | typedef typename S::const_reverse_iterator const_iterator; 54 | 55 | stack () : seq_ () 56 | { 57 | } 58 | 59 | stack (unsigned int n) : seq_ (n) 60 | { 61 | } 62 | 63 | inline 64 | T& 65 | operator [] (unsigned int i) 66 | { 67 | return seq_[i]; 68 | } 69 | 70 | inline 71 | const T& 72 | operator [] (unsigned int i) const 73 | { 74 | return seq_[i]; 75 | } 76 | 77 | inline 78 | void 79 | push (const T& t) 80 | { 81 | seq_.push_front (t); 82 | } 83 | 84 | inline 85 | void 86 | pop (unsigned int n = 1) 87 | { 88 | for (; n; --n) 89 | seq_.pop_front (); 90 | } 91 | 92 | inline 93 | unsigned int 94 | height () const 95 | { 96 | return seq_.size (); 97 | } 98 | 99 | inline const_iterator begin () const { return seq_.rbegin (); } 100 | inline const_iterator end () const { return seq_.rend (); } 101 | 102 | private: 103 | S seq_; 104 | }; 105 | 106 | /// Present a slice of the top of a stack. 107 | template > 108 | class slice 109 | { 110 | public: 111 | slice (const S& stack, unsigned int range) 112 | : stack_ (stack) 113 | , range_ (range) 114 | { 115 | } 116 | 117 | inline 118 | const T& 119 | operator [] (unsigned int i) const 120 | { 121 | return stack_[range_ - i]; 122 | } 123 | 124 | private: 125 | const S& stack_; 126 | unsigned int range_; 127 | }; 128 | 129 | } // yy 130 | /* Line 116 of stack.hh */ 131 | #line 132 "knot_parser/stack.hh" 132 | 133 | #endif /* !YY_YY_KNOT_PARSER_STACK_HH_INCLUDED */ 134 | -------------------------------------------------------------------------------- /knotkit.h: -------------------------------------------------------------------------------- 1 | 2 | // includes lib.h 3 | #include 4 | 5 | extern bool verbose; 6 | 7 | static const unsigned max_edges = 58; 8 | static const unsigned max_crossings = 29; 9 | static const unsigned max_circles = 58; 10 | 11 | class knot_diagram; 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | class knot_desc 27 | { 28 | public: 29 | enum table 30 | { 31 | NONE, 32 | ROLFSEN, 33 | HTW, 34 | HTW_ALT, 35 | HTW_NONALT, 36 | MT, 37 | MT_ALT, 38 | MT_NONALT, 39 | TORUS, 40 | }; 41 | 42 | table t; 43 | unsigned i; 44 | unsigned j; 45 | 46 | public: 47 | knot_desc () : t(NONE) { } 48 | knot_desc (table t_, unsigned i_, unsigned j_) 49 | : t(t_), i(i_), j(j_) 50 | { } 51 | knot_desc (const knot_desc &desc) 52 | : t(desc.t), i(desc.i), j(desc.j) 53 | { } 54 | knot_desc (reader &r); 55 | ~knot_desc () { } 56 | 57 | knot_desc &operator = (const knot_desc &desc) 58 | { 59 | t = desc.t; 60 | i = desc.i; 61 | j = desc.j; 62 | return *this; 63 | } 64 | 65 | bool operator == (const knot_desc &desc) const 66 | { 67 | return t == desc.t && i == desc.i && j == desc.j; 68 | } 69 | bool operator < (const knot_desc &desc) const 70 | { 71 | if ((int)t < (int)desc.t) 72 | return 1; 73 | else if ((int)t > (int)desc.t) 74 | return 0; 75 | 76 | if (i < desc.i) 77 | return 1; 78 | else if (i > desc.i) 79 | return 0; 80 | 81 | return j < desc.j; 82 | } 83 | 84 | knot_diagram diagram () const; 85 | 86 | std::string name () const; 87 | unsigned table_crossing_knots () const; 88 | 89 | hash_t hash_self () const 90 | { 91 | return hash_combine (hash ((int)t), 92 | hash_combine (hash (i), 93 | hash (j))); 94 | } 95 | 96 | void write_self (writer &w) const; 97 | void show_self () const { printf ("%s", name ().c_str ()); } 98 | void display_self () const { show_self (); newline (); } 99 | }; 100 | 101 | unsigned rolfsen_crossing_knots (unsigned n); 102 | planar_diagram rolfsen_knot (unsigned n, unsigned k); 103 | 104 | unsigned htw_knots (unsigned n, bool alternating); 105 | unsigned htw_knots (unsigned n); 106 | 107 | dt_code htw_knot (unsigned n, bool alternating, unsigned k); 108 | dt_code htw_knot (unsigned n, unsigned k); 109 | 110 | unsigned mt_links (unsigned n, bool alternating); 111 | unsigned mt_links (unsigned n); 112 | 113 | dt_code mt_link (unsigned n, bool alternating, unsigned k); 114 | dt_code mt_link (unsigned n, unsigned k); 115 | 116 | planar_diagram torus_knot (unsigned n_strands, unsigned n_shifts); 117 | 118 | knot_diagram braid (unsigned n_strands, const basedvector &twists); 119 | knot_diagram braid (unsigned n_strands, unsigned n_twists, int twists_ar[]); 120 | 121 | knot_diagram parse_knot (const char *s); 122 | resolution_diagram parse_resolution_diagram (const char *s); 123 | 124 | // 11 <= n <= 15 125 | basedvector, 1> mutant_knot_groups (unsigned n); 126 | -------------------------------------------------------------------------------- /lib/bitset.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | bool 5 | bitset::is_empty () const 6 | { 7 | unsigned nw = v.size (); 8 | for (unsigned i = 0; i < nw; i ++) 9 | { 10 | if (v[i] != 0) 11 | return 0; 12 | } 13 | return 1; 14 | } 15 | 16 | unsigned 17 | bitset::card () const 18 | { 19 | unsigned c = 0; 20 | unsigned nw = v.size (); 21 | for (unsigned i = 0; i < nw; i ++) 22 | c += word_bitcount (v[i]); 23 | 24 | assert (c <= n); 25 | 26 | return c; 27 | } 28 | 29 | unsigned 30 | bitset::head () const 31 | { 32 | bitset_const_iter i = *this; 33 | assert (i); 34 | return i.val (); 35 | } 36 | 37 | unsigned 38 | bitset::pop () 39 | { 40 | unsigned i = head (); 41 | operator -= (i); 42 | return i; 43 | } 44 | 45 | bitset & 46 | bitset::operator |= (const bitset &bs) 47 | { 48 | assert (n == bs.n); 49 | assert (v.size () == bs.v.size ()); 50 | int nw = v.size (); 51 | for (int i = 0; i < nw; i ++) 52 | v[i] |= bs.v[i]; 53 | return *this; 54 | } 55 | 56 | bitset & 57 | bitset::operator &= (const bitset &bs) 58 | { 59 | assert (n == bs.n); 60 | assert (v.size () == bs.v.size ()); 61 | int nw = v.size (); 62 | for (int i = 0; i < nw; i ++) 63 | v[i] &= bs.v[i]; 64 | return *this; 65 | } 66 | 67 | bitset & 68 | bitset::operator ^= (const bitset &bs) 69 | { 70 | assert (n == bs.n); 71 | assert (v.size () == bs.v.size ()); 72 | int nw = v.size (); 73 | for (int i = 0; i < nw; i ++) 74 | v[i] ^= bs.v[i]; 75 | return *this; 76 | } 77 | 78 | bool 79 | bitset::operator == (const bitset &bs) const 80 | { 81 | assert (n == bs.n); 82 | assert (v.size () == bs.v.size ()); 83 | int nw = v.size (); 84 | for (int i = 0; i < nw; i ++) 85 | { 86 | if (v[i] != bs.v[i]) 87 | return 0; 88 | } 89 | return 1; 90 | } 91 | 92 | void 93 | bitset_const_iter::find_next () 94 | { 95 | unsigned wn = v.size (); 96 | 97 | while (!w) 98 | { 99 | wi ++; 100 | if (wi < wn) 101 | w = v[wi]; 102 | else 103 | break; 104 | } 105 | if (wi < wn) 106 | b = word_ffs (w); 107 | } 108 | -------------------------------------------------------------------------------- /lib/bitset.h: -------------------------------------------------------------------------------- 1 | 2 | typedef uint64 word_t; 3 | 4 | static const unsigned word_bits = uint64_bits; 5 | static const unsigned word_bit_mask = uint64_bit_mask; 6 | 7 | inline unsigned word_bitcount (word_t x) { return uint64_bitcount (x); } 8 | inline unsigned word_ffs (word_t x) { return uint64_ffs (x); } 9 | 10 | inline word_t word_bitset (word_t x, unsigned i) { return uint64_bitset (x, i); } 11 | inline word_t word_bitclear (word_t x, unsigned i) { return uint64_bitclear (x, i); } 12 | inline bool word_bittest (word_t x, unsigned i) { return uint64_bittest (x, i); } 13 | 14 | class bitset_iter; 15 | class bitset_const_iter; 16 | 17 | class bitset 18 | { 19 | private: 20 | friend class bitset_iter; 21 | friend class bitset_const_iter; 22 | 23 | friend class smallbitset; 24 | 25 | unsigned n; 26 | vector v; 27 | 28 | public: 29 | typedef bitset_iter iter; 30 | typedef bitset_const_iter const_iter; 31 | 32 | public: 33 | bitset () : n(0) { } 34 | inline bitset (unsigned n_); 35 | bitset (const bitset &bs) : n(bs.n), v(bs.v) { } 36 | 37 | bitset (copy, const bitset &bs) : n(bs.n), v(COPY, bs.v) { } 38 | // explicit bitset (const unsignedset &t); 39 | explicit bitset (const ullmanset<1> &t); 40 | 41 | ~bitset () { } 42 | 43 | bitset &operator = (const bitset &bs) { n = bs.n; v = bs.v; return *this; } 44 | // bitset &operator = (const unsignedset &t); 45 | bitset &operator = (const ullmanset<1> &t); 46 | 47 | bool is_empty () const; 48 | unsigned card () const; 49 | unsigned size () const { return n; } 50 | unsigned head () const; 51 | unsigned pop (); 52 | 53 | void push (unsigned i) { assert (! (*this % i)); operator += (i); } 54 | void yank (unsigned i) { assert (*this % i); operator -= (i); } 55 | inline void operator += (unsigned i); 56 | inline void operator -= (unsigned i); 57 | 58 | bitset &operator |= (const bitset &bs); 59 | bitset &operator &= (const bitset &bs); 60 | bitset &operator ^= (const bitset &bs); 61 | 62 | bool operator == (const bitset &bs) const; 63 | bool operator != (const bitset &bs) const { return !operator == (bs); } 64 | 65 | inline bool operator % (unsigned i) const; 66 | inline bool operator () (unsigned i) const { return operator % (i); } 67 | }; 68 | 69 | class bitset_const_iter 70 | { 71 | private: 72 | const vector &v; 73 | 74 | unsigned wi; 75 | word_t w; 76 | unsigned b; 77 | 78 | void find_next (); 79 | void advance () 80 | { 81 | assert (wi < v.size ()); 82 | assert (word_bittest (w, b)); 83 | 84 | w = word_bitclear (w, b); 85 | find_next (); 86 | } 87 | 88 | public: 89 | bitset_const_iter (const bitset &bs) : v(bs.v), wi(0), w(v[0]) { find_next (); } 90 | ~bitset_const_iter () { } 91 | 92 | int val () const { assert (wi < v.size ()); return wi * word_bits + b; } 93 | bitset_const_iter &operator ++ () { advance (); return *this; } 94 | void operator ++ (int) { advance (); } 95 | operator bool () const { return wi < v.size (); } 96 | }; 97 | 98 | bitset::bitset (unsigned n_) 99 | : n(n_), 100 | v((n_ + word_bits - 1) / word_bits) 101 | { 102 | unsigned wn = v.size (); 103 | for (unsigned i = 0; i < wn; i ++) 104 | v[i] = 0; 105 | } 106 | 107 | void 108 | bitset::operator += (unsigned i) 109 | { 110 | assert (i >= 1); 111 | assert (i <= n); 112 | 113 | unsigned w = (i - 1) / word_bits; 114 | unsigned b = (i - 1) & word_bit_mask; 115 | v[w] = word_bitset (v[w], b + 1); 116 | } 117 | 118 | void 119 | bitset::operator -= (unsigned i) 120 | { 121 | assert (i >= 1); 122 | assert (i <= n); 123 | 124 | unsigned w = (i - 1) / word_bits; 125 | unsigned b = (i - 1) & word_bit_mask; 126 | v[w] = word_bitclear (v[w], b + 1); 127 | } 128 | 129 | bool 130 | bitset::operator % (unsigned i) const 131 | { 132 | assert (i >= 1); 133 | assert (i <= n); 134 | 135 | unsigned w = (i - 1) / word_bits; 136 | unsigned b = (i - 1) & word_bit_mask; 137 | return word_bittest (v[w], b + 1); 138 | } 139 | -------------------------------------------------------------------------------- /lib/directed_multigraph.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | unsigned 5 | directed_multigraph::num_components () const 6 | { 7 | unionfind<1> u (n_vertices); 8 | 9 | unsigned n_edges = num_edges (); 10 | for (unsigned i = 1; i <= n_edges; i ++) 11 | u.join (edge_from[i], edge_to[i]); 12 | return u.num_sets (); 13 | } 14 | 15 | directed_multigraph 16 | directed_multigraph::component (unsigned v, 17 | basedvector &edge_inj, 18 | basedvector &virtex_inj) const 19 | { 20 | unionfind<1> u (n_vertices); 21 | 22 | unsigned n_edges = num_edges (); 23 | for (unsigned i = 1; i <= n_edges; i ++) 24 | u.join (edge_from[i], edge_to[i]); 25 | 26 | ullmanset<1> comp_vertices (n_vertices); 27 | for (unsigned i = 1; i <= n_vertices; i ++) 28 | { 29 | if (u.find (v) == u.find (i)) 30 | comp_vertices.push (i); 31 | } 32 | 33 | unsigned comp_n_vertices = comp_vertices.card (); 34 | virtex_inj = basedvector (comp_n_vertices); 35 | for (unsigned i = 1; i <= comp_n_vertices; i ++) 36 | virtex_inj[i] = comp_vertices.nth (i - 1); 37 | 38 | basedvector comp_edge_from, 39 | comp_edge_to; 40 | for (unsigned i = 1; i <= n_edges; i ++) 41 | { 42 | if (comp_vertices % edge_from[i]) 43 | { 44 | comp_edge_from.append (comp_vertices.position (edge_from[i]) + 1); 45 | comp_edge_to.append (comp_vertices.position (edge_to[i]) + 1); 46 | edge_inj.append (i); 47 | } 48 | } 49 | 50 | return directed_multigraph (comp_n_vertices, 51 | comp_edge_from, 52 | comp_edge_to); 53 | } 54 | 55 | class spanning_tree_builder 56 | { 57 | public: 58 | const directed_multigraph &g; 59 | basedvector, 1> vertex_edges; 60 | 61 | ullmanset<1> tree; 62 | ullmanset<1> visited_edges; 63 | ullmanset<1> visited_vertices; 64 | 65 | ullmanset<1> edges_to_visit; 66 | 67 | basedvector, 1> trees; 68 | 69 | void enumerate (unsigned i); 70 | 71 | public: 72 | spanning_tree_builder (const directed_multigraph &g_); 73 | }; 74 | 75 | spanning_tree_builder::spanning_tree_builder (const directed_multigraph &g_) 76 | : g(g_), 77 | vertex_edges(g.n_vertices), 78 | tree(g.num_edges ()), 79 | visited_edges(g.num_edges ()), 80 | visited_vertices(g.n_vertices), 81 | edges_to_visit(g.num_edges ()) 82 | { 83 | for (unsigned i = 1; i <= g.num_edges (); i ++) 84 | { 85 | vertex_edges[g.edge_from[i]] += i; 86 | vertex_edges[g.edge_to[i]] += i; 87 | } 88 | 89 | for (set_const_iter i = vertex_edges[1]; i; i ++) 90 | edges_to_visit += i.val (); 91 | enumerate (1); 92 | } 93 | 94 | void 95 | spanning_tree_builder::enumerate (unsigned i) 96 | { 97 | assert (i >= 1); 98 | 99 | if (visited_vertices.card () == g.n_vertices) 100 | { 101 | set s; 102 | setassign (s, tree.size (), tree); 103 | trees.append (s); 104 | 105 | return; 106 | } 107 | 108 | if (i > g.num_edges () 109 | || i > edges_to_visit.card ()) 110 | return; 111 | 112 | unsigned e = edges_to_visit.nth (i - 1); 113 | 114 | unsigned visited_edges_card = visited_edges.card (); 115 | visited_edges.push (e); 116 | 117 | unsigned from = g.edge_from[e], 118 | to = g.edge_to[e]; 119 | if (! ((visited_vertices % from) && (visited_vertices % to))) 120 | { 121 | unsigned edges_to_visit_card = edges_to_visit.card (); 122 | unsigned visited_vertices_card = visited_vertices.card (); 123 | unsigned tree_card = tree.card (); 124 | 125 | tree.push (e); 126 | if (! (visited_vertices % from)) 127 | { 128 | visited_vertices += from; 129 | 130 | for (set_const_iter j = vertex_edges[from]; j; j ++) 131 | { 132 | if (! (visited_edges % j.val ())) 133 | edges_to_visit += j.val (); 134 | } 135 | } 136 | if (! (visited_vertices % to)) 137 | { 138 | visited_vertices += to; 139 | 140 | for (set_const_iter j = vertex_edges[to]; j; j ++) 141 | { 142 | if (! (visited_edges % j.val ())) 143 | edges_to_visit += j.val (); 144 | } 145 | } 146 | 147 | // with e 148 | enumerate (i + 1); 149 | 150 | tree.restore (tree_card); 151 | visited_vertices.restore (visited_vertices_card); 152 | edges_to_visit.restore (edges_to_visit_card); 153 | } 154 | 155 | // without e 156 | enumerate (i + 1); 157 | 158 | visited_edges.restore (visited_edges_card); 159 | } 160 | 161 | basedvector, 1> 162 | directed_multigraph::spanning_trees () const 163 | { 164 | spanning_tree_builder builder (*this); 165 | return builder.trees; 166 | } 167 | 168 | void 169 | directed_multigraph::display_self () const 170 | { 171 | printf ("directed_multigraph\n"); 172 | printf (" n_vertices %d\n", n_vertices); 173 | printf (" n_edges %d\n", num_edges ()); 174 | printf (" edges:\n"); 175 | for (unsigned i = 1; i <= num_edges (); i ++) 176 | { 177 | printf (" % 4d: %d -> %d\n", 178 | i, 179 | edge_from[i], 180 | edge_to[i]); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /lib/directed_multigraph.h: -------------------------------------------------------------------------------- 1 | 2 | class directed_multigraph 3 | { 4 | public: 5 | unsigned n_vertices; 6 | basedvector edge_from, 7 | edge_to; 8 | 9 | public: 10 | directed_multigraph () : n_vertices(0) { } 11 | directed_multigraph (unsigned n_vertices_, 12 | basedvector edge_from_, 13 | basedvector edge_to_) 14 | : n_vertices(n_vertices_), 15 | edge_from(edge_from_), 16 | edge_to(edge_to_) 17 | { 18 | } 19 | 20 | directed_multigraph (const directed_multigraph &g) 21 | : n_vertices(g.n_vertices), 22 | edge_from(g.edge_from), 23 | edge_to(g.edge_to) 24 | { } 25 | 26 | directed_multigraph (copy, const directed_multigraph &g) 27 | : n_vertices(g.n_vertices), 28 | edge_from(COPY, g.edge_from), 29 | edge_to(COPY, g.edge_to) 30 | { 31 | } 32 | 33 | directed_multigraph &operator = (const directed_multigraph &g) 34 | { 35 | n_vertices = g.n_vertices; 36 | edge_from = g.edge_from; 37 | edge_to = g.edge_to; 38 | return *this; 39 | } 40 | 41 | unsigned num_edges () const { return edge_from.size (); } 42 | unsigned num_components () const; 43 | 44 | // the component containing the vertex v 45 | directed_multigraph component (unsigned v, 46 | basedvector &edge_inj, 47 | basedvector &virtex_inj) const; 48 | 49 | basedvector, 1> spanning_trees () const; 50 | 51 | void display_self () const; 52 | }; 53 | -------------------------------------------------------------------------------- /lib/hashmap.h: -------------------------------------------------------------------------------- 1 | 2 | /* wrapper for std::unordered_map */ 3 | 4 | template 5 | class hashmap : public map_wrapper >, K, V> 6 | { 7 | typedef map_wrapper >, K, V> base; 8 | 9 | public: 10 | hashmap () { } 11 | hashmap (const hashmap &m) : base(m) { } 12 | hashmap (copy, const hashmap &m) : base(COPY, m) { } 13 | hashmap (initializer_list > il) : base(il) { } 14 | hashmap (reader &r) : base(r) { } 15 | ~hashmap () { } 16 | 17 | hashmap &operator = (const hashmap &m) { base::operator = (m); return *this; } 18 | hashmap &operator = (initializer_list > il) 19 | { 20 | base::operator = (il); 21 | return *this; 22 | } 23 | }; 24 | 25 | template 26 | using hashmap_iter = map_wrapper_iter, K, V>; 27 | 28 | template 29 | using hashmap_const_iter = map_wrapper_const_iter, K, V>; 30 | -------------------------------------------------------------------------------- /lib/hashset.h: -------------------------------------------------------------------------------- 1 | 2 | /* wrapper for std::unordered_set */ 3 | 4 | template 5 | class hashset : public set_wrapper >, T> 6 | { 7 | typedef set_wrapper >, T> base; 8 | 9 | public: 10 | hashset () { } 11 | hashset (const hashset &m) : base(m) { } 12 | hashset (copy, const hashset &m) : base(COPY, m) { } 13 | hashset (initializer_list il) : base(il) { } 14 | hashset (reader &r) : base(r) { } 15 | ~hashset () { } 16 | 17 | hashset &operator = (const hashset &m) { base::operator = (m); return *this; } 18 | hashset &operator = (initializer_list il) { base::operator = (il); return *this; } 19 | }; 20 | 21 | template 22 | using hashset_iter = set_wrapper_iter >, T>; 23 | 24 | template 25 | using hashset_const_iter = set_wrapper_const_iter >, T>; 26 | -------------------------------------------------------------------------------- /lib/io.cpp: -------------------------------------------------------------------------------- 1 | 2 | // #include 3 | #include 4 | 5 | writer::writer (bool raw_) 6 | : raw(raw_), 7 | aw(new algebra_writer) 8 | { 9 | } 10 | 11 | writer::~writer () 12 | { 13 | delete aw; 14 | } 15 | 16 | void 17 | writer::write_int (int x) 18 | { 19 | if (raw) 20 | write_raw (&x, sizeof x, 1); 21 | else 22 | { 23 | uint8 buf[5]; 24 | unsigned n = 0; 25 | 26 | bool more = 1; 27 | while (more) 28 | { 29 | uint8 b = (uint8)(x & 0x7f); 30 | x >>= 7; 31 | 32 | if ((x == 0 33 | && ! (b & 0x40)) 34 | || (x == -1 35 | && (b & 0x40) == 0x40)) 36 | more = 0; 37 | else 38 | b |= 0x80; 39 | 40 | assert (n < 5); 41 | buf[n] = b; 42 | n ++; 43 | } 44 | 45 | write_raw (buf, sizeof buf[0], n); 46 | } 47 | } 48 | 49 | void 50 | writer::write_unsigned (unsigned x) 51 | { 52 | if (raw) 53 | write_raw (&x, sizeof x, 1); 54 | else 55 | { 56 | uint8 buf[5]; 57 | unsigned n = 0; 58 | 59 | bool more = 1; 60 | while (more) 61 | { 62 | uint8 b = (uint8)(x & 0x7f); 63 | x >>= 7; 64 | 65 | if ((x == 0 66 | && ! (b & 0x40))) 67 | more = 0; 68 | else 69 | b |= 0x80; 70 | 71 | assert (n < 5); 72 | buf[n] = b; 73 | n ++; 74 | } 75 | 76 | write_raw (buf, sizeof buf[0], n); 77 | } 78 | } 79 | 80 | void 81 | writer::write_uint64 (uint64 x) 82 | { 83 | if (raw) 84 | write_raw (&x, sizeof x, 1); 85 | else 86 | { 87 | uint8 buf[10]; 88 | unsigned n = 0; 89 | 90 | bool more = 1; 91 | while (more) 92 | { 93 | uint8 b = (uint8)(x & 0x7f); 94 | x >>= 7; 95 | 96 | if ((x == 0 97 | && ! (b & 0x40))) 98 | more = 0; 99 | else 100 | b |= 0x80; 101 | 102 | assert (n < 10); 103 | buf[n] = b; 104 | n ++; 105 | } 106 | 107 | write_raw (buf, sizeof buf[0], n); 108 | } 109 | } 110 | 111 | void 112 | writer::write_mpz (const mpz_t x) 113 | { 114 | assert (!raw); 115 | 116 | size_t count; 117 | void *buf = mpz_export (nullptr, &count, -1, 1, -1, 0, x); 118 | 119 | write_unsigned ((unsigned)count); 120 | write_raw (buf, 1, count); 121 | 122 | free (buf); 123 | } 124 | 125 | reader::reader (bool raw_) 126 | : raw(raw_), 127 | ar(new algebra_reader) 128 | { 129 | } 130 | 131 | reader::~reader () 132 | { 133 | delete ar; 134 | } 135 | 136 | int 137 | reader::read_int () 138 | { 139 | int x = 0; 140 | 141 | if (raw) 142 | read_raw (&x, sizeof x, 1); 143 | else 144 | { 145 | int shift = 0; 146 | for (;;) 147 | { 148 | uint8 b = read_uint8 (); 149 | x |= ((int)(b & 0x7f) << shift); 150 | shift += 7; 151 | if (! (b & 0x80)) 152 | { 153 | if (shift < int_bits 154 | && (b & 0x40)) 155 | x = (x << (int_bits - shift)) >> (int_bits - shift); 156 | break; 157 | } 158 | } 159 | } 160 | 161 | return x; 162 | } 163 | 164 | unsigned 165 | reader::read_unsigned () 166 | { 167 | unsigned x = 0; 168 | 169 | if (raw) 170 | read_raw (&x, sizeof x, 1); 171 | else 172 | { 173 | unsigned shift = 0; 174 | for (;;) 175 | { 176 | uint8 b = read_uint8 (); 177 | x |= ((unsigned)(b & 0x7f) << shift); 178 | shift += 7; 179 | if (! (b & 0x80)) 180 | break; 181 | } 182 | } 183 | 184 | return x; 185 | } 186 | 187 | uint64 188 | reader::read_uint64 () 189 | { 190 | uint64 x = 0; 191 | 192 | if (raw) 193 | read_raw (&x, sizeof x, 1); 194 | else 195 | { 196 | uint64 shift = 0; 197 | for (;;) 198 | { 199 | uint8 b = read_uint8 (); 200 | x |= ((uint64)(b & 0x7f) << shift); 201 | shift += 7; 202 | if (! (b & 0x80)) 203 | break; 204 | } 205 | } 206 | 207 | return x; 208 | } 209 | 210 | void 211 | reader::read_mpz (mpz_t x) 212 | { 213 | assert (!raw); 214 | 215 | unsigned count = read_unsigned (); 216 | void *p = malloc (count); 217 | if (!p) 218 | { 219 | stderror ("malloc"); 220 | exit (EXIT_FAILURE); 221 | } 222 | 223 | read_raw (p, 1, count); 224 | 225 | mpz_import (x, count, -1, 1, -1, 0, p); 226 | 227 | free (p); 228 | } 229 | 230 | FILE *open_file (const std::string &file, const char *mode) 231 | { 232 | FILE *fp = fopen (file.c_str (), mode); 233 | if (!fp) 234 | { 235 | stderror ("fopen: %s", file.c_str ()); 236 | exit (EXIT_FAILURE); 237 | } 238 | return fp; 239 | } 240 | 241 | void close_file (FILE *fp) 242 | { 243 | fclose (fp); 244 | } 245 | 246 | gzFile 247 | open_gzfile (const std::string &file, const char *mode) 248 | { 249 | gzFile gzfp = gzopen (file.c_str (), mode); 250 | if (!gzfp) 251 | { 252 | stderror ("gzopen: %s", file.c_str ()); 253 | exit (EXIT_FAILURE); 254 | } 255 | return gzfp; 256 | } 257 | 258 | extern void close_gzfile (gzFile gzfp) 259 | { 260 | int r = gzclose (gzfp); 261 | if (r != Z_OK) 262 | { 263 | stderror ("gzclose"); 264 | exit (EXIT_FAILURE); 265 | } 266 | } 267 | 268 | void 269 | file_writer::write_raw (const void *p, size_t itemsize, size_t nitems) 270 | { 271 | if (fwrite (p, itemsize, nitems, fp) != nitems) 272 | { 273 | stderror ("fwrite"); 274 | exit (EXIT_FAILURE); 275 | } 276 | } 277 | 278 | void 279 | file_writer::write_mpz (const mpz_t x) 280 | { 281 | mpz_out_raw (fp, x); 282 | } 283 | 284 | void 285 | file_reader::read_raw (void *p, size_t itemsize, size_t nitems) 286 | { 287 | if (fread (p, itemsize, nitems, fp) != nitems) 288 | { 289 | stderror ("fread"); 290 | exit (EXIT_FAILURE); 291 | } 292 | } 293 | 294 | void 295 | file_reader::read_mpz (mpz_t x) 296 | { 297 | mpz_inp_raw (x, fp); 298 | } 299 | 300 | void 301 | gzfile_writer::write_raw (const void *p, size_t itemsize, size_t nitems) 302 | { 303 | unsigned nbytes = itemsize*nitems; 304 | if (gzwrite (gzfp, p, nbytes) != nbytes) 305 | { 306 | stderror ("gzwrite"); 307 | exit (EXIT_FAILURE); 308 | } 309 | } 310 | 311 | void 312 | gzfile_reader::read_raw (void *p, size_t itemsize, size_t nitems) 313 | { 314 | unsigned nbytes = itemsize*nitems; 315 | if (gzread (gzfp, p, nbytes) != nitems) 316 | { 317 | stderror ("fread"); 318 | exit (EXIT_FAILURE); 319 | } 320 | } 321 | 322 | void 323 | read (reader &r, std::string &s) 324 | { 325 | unsigned n = r.read_unsigned (); 326 | 327 | char buf[n + 1]; 328 | r.read_raw (buf, sizeof (char), n + 1); 329 | assert (buf[n] == 0); 330 | 331 | s = std::string (buf); 332 | } 333 | 334 | void 335 | write (writer &w, const std::string &s) 336 | { 337 | unsigned n = s.length (); 338 | w.write_unsigned (n); 339 | 340 | w.write_raw (s.c_str (), sizeof (char), n + 1); 341 | } 342 | -------------------------------------------------------------------------------- /lib/io.h: -------------------------------------------------------------------------------- 1 | 2 | template class module; 3 | 4 | class algebra_writer; 5 | class algebra_reader; 6 | 7 | class writer 8 | { 9 | public: 10 | bool raw; 11 | algebra_writer *aw; 12 | 13 | public: 14 | writer (const writer &) = delete; 15 | writer (bool raw_); 16 | virtual ~writer (); 17 | 18 | writer &operator = (const writer &) = delete; 19 | 20 | virtual void write_raw (const void *p, size_t itemsize, size_t nitems) = 0; 21 | 22 | void write_bool (bool x) { write_raw (&x, sizeof x, 1); } 23 | void write_char (char x) { write_raw (&x, sizeof x, 1); } 24 | void write_uint8 (uint8 x) { write_raw (&x, sizeof x, 1); } 25 | void write_int (int x); 26 | void write_unsigned (unsigned x); 27 | void write_uint64 (uint64 x); 28 | 29 | virtual void write_mpz (const mpz_t x); 30 | 31 | template void write_mod (ptr > m); 32 | }; 33 | 34 | class reader 35 | { 36 | bool raw; 37 | algebra_reader *ar; 38 | 39 | public: 40 | reader (const reader &) = delete; 41 | reader (bool raw_); 42 | virtual ~reader (); 43 | 44 | reader &operator = (const reader &) = delete; 45 | 46 | virtual void read_raw (void *p, size_t itemsize, size_t nitems) = 0; 47 | 48 | bool read_bool () 49 | { 50 | bool x; 51 | read_raw (&x, sizeof x, 1); 52 | return x; 53 | } 54 | 55 | char read_char () 56 | { 57 | char x; 58 | read_raw (&x, sizeof x, 1); 59 | return x; 60 | } 61 | 62 | uint8 read_uint8 () 63 | { 64 | uint8 x; 65 | read_raw (&x, sizeof x, 1); 66 | return x; 67 | } 68 | 69 | int read_int (); 70 | unsigned read_unsigned (); 71 | uint64 read_uint64 (); 72 | 73 | virtual void read_mpz (mpz_t x); 74 | 75 | template ptr > read_mod (); 76 | }; 77 | 78 | extern FILE *open_file (const std::string &file, const char *mode); 79 | extern void close_file (FILE *fp); 80 | 81 | extern gzFile open_gzfile (const std::string &file, const char *mode); 82 | extern void close_gzfile (gzFile fp); 83 | 84 | class file_writer : public writer 85 | { 86 | public: 87 | FILE *fp; 88 | 89 | public: 90 | file_writer (const std::string &file, bool raw = false) 91 | : writer(raw), 92 | fp(open_file (file, "w")) 93 | { 94 | } 95 | file_writer (const file_writer &) = delete; 96 | ~file_writer () { close_file (fp); } 97 | 98 | file_writer &operator = (const file_writer &) = delete; 99 | 100 | void write_raw (const void *p, size_t itemsize, size_t nitems); 101 | void write_mpz (const mpz_t x); 102 | }; 103 | 104 | class file_reader : public reader 105 | { 106 | public: 107 | FILE *fp; 108 | 109 | public: 110 | file_reader (const std::string &file, bool raw = false) 111 | : reader(raw), 112 | fp(open_file (file, "r")) 113 | { 114 | } 115 | file_reader (const file_reader &) = delete; 116 | ~file_reader () { close_file (fp); } 117 | 118 | file_reader &operator = (const file_reader &) = delete; 119 | 120 | void read_raw (void *p, size_t itemsize, size_t nitems); 121 | void read_mpz (mpz_t x); 122 | }; 123 | 124 | class gzfile_writer : public writer 125 | { 126 | public: 127 | gzFile gzfp; 128 | 129 | public: 130 | gzfile_writer (const std::string &file) 131 | : writer(false), 132 | gzfp(open_gzfile (file, "w9")) 133 | { 134 | } 135 | gzfile_writer (const gzfile_writer &) = delete; 136 | ~gzfile_writer () { close_gzfile (gzfp); } 137 | 138 | gzfile_writer &operator = (const gzfile_writer &) = delete; 139 | 140 | void write_raw (const void *p, size_t itemsize, size_t nitems); 141 | }; 142 | 143 | class gzfile_reader : public reader 144 | { 145 | public: 146 | gzFile gzfp; 147 | 148 | public: 149 | gzfile_reader (const std::string &file) 150 | : reader(false), 151 | gzfp(open_gzfile (file, "r")) 152 | { 153 | } 154 | gzfile_reader (const gzfile_reader &) = delete; 155 | ~gzfile_reader () { close_gzfile (gzfp); } 156 | 157 | gzfile_reader &operator = (const gzfile_reader &) = delete; 158 | 159 | void read_raw (void *p, size_t itemsize, size_t nitems); 160 | }; 161 | 162 | inline void read (reader &r, bool &x) { x = r.read_bool (); } 163 | inline void read (reader &r, char &x) { x = r.read_char (); } 164 | inline void read (reader &r, int &x) { x = r.read_int (); } 165 | inline void read (reader &r, unsigned &x) { x = r.read_unsigned (); } 166 | inline void read (reader &r, uint64 &x) { x = r.read_uint64 (); } 167 | extern void read (reader &r, std::string &s); 168 | template inline void read (reader &r, T &x) { x = T(r); } 169 | 170 | inline void ctor_read (reader &r, bool *p) { *p = r.read_bool (); } 171 | inline void ctor_read (reader &r, char *p) { *p = r.read_char (); } 172 | inline void ctor_read (reader &r, int *p) { *p = r.read_int (); } 173 | inline void ctor_read (reader &r, unsigned *p) { *p = r.read_unsigned (); } 174 | inline void ctor_read (reader &r, uint64 *p) { *p = r.read_uint64 (); } 175 | template inline void ctor_read (reader &r, T *p) { new (p) T (r); } 176 | 177 | inline void write (writer &w, bool x) { w.write_bool (x); } 178 | inline void write (writer &w, char x) { w.write_char (x); } 179 | inline void write (writer &w, int x) { w.write_int (x); } 180 | inline void write (writer &w, unsigned x) { w.write_unsigned (x); } 181 | inline void write (writer &w, uint64 x) { w.write_uint64 (x); } 182 | extern void write (writer &w, const std::string &s); 183 | template inline void write (writer &w, const T &x) { x.write_self (w); } 184 | -------------------------------------------------------------------------------- /lib/lib.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | unsigned 7 | unsigned_pack (unsigned n, unsigned x, unsigned z) 8 | { 9 | assert (n <= 32); 10 | assert ((x >> n) == 0); 11 | 12 | static const unsigned pack4[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, 7, 9, 11, 13, 15, 2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, }; 13 | static const unsigned zerocount4[16] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0, }; 14 | 15 | unsigned r = 0; 16 | for (unsigned i = 0; i < n; i += 4) 17 | { 18 | unsigned xnib = ((x >> i) & 0xf); 19 | r |= pack4[(xnib << 4) | (z & 0xf)] << i; 20 | z >>= zerocount4[xnib]; 21 | } 22 | assert (z == 0); 23 | return r; 24 | } 25 | 26 | void 27 | stderror (const char *fmt, ...) 28 | { 29 | va_list ap; 30 | va_start (ap, fmt); 31 | 32 | vfprintf (stderr, fmt, ap); 33 | 34 | fprintf (stderr, ": "); 35 | perror (0); 36 | 37 | va_end (ap); 38 | } 39 | 40 | unsigned 41 | fact (unsigned n) 42 | { 43 | unsigned r = 1; 44 | for (unsigned i = n; i >= 2; i --) 45 | r *= i; 46 | return r; 47 | } 48 | 49 | unsigned 50 | choose (unsigned n, unsigned k) 51 | { 52 | if (n < k) 53 | return 0; 54 | 55 | unsigned r = 1; 56 | for (unsigned i = n; i >= k + 1; i --) 57 | r *= i; 58 | 59 | unsigned d = fact (n - k); 60 | assert (r % d == 0); 61 | return r / d; 62 | } 63 | 64 | int 65 | alpha_to_int (char c) 66 | { 67 | if ('a' <= c && c <= 'z') 68 | return c - 'a' + 1; 69 | else 70 | { 71 | assert ('A' <= c && c <= 'Z'); 72 | return - (c - 'A' + 1); 73 | } 74 | } 75 | 76 | hash_t 77 | hash (const std::string &s) 78 | { 79 | size_t n = s.length (); 80 | hash_t h = hash (n); 81 | for (unsigned i = 0; i < n; i ++) 82 | h = hash_combine (h, hash (s[i])); 83 | return h; 84 | } 85 | -------------------------------------------------------------------------------- /lib/map.h: -------------------------------------------------------------------------------- 1 | 2 | /* wrapper for std::map */ 3 | 4 | template 5 | class map : public map_wrapper, K, V> 6 | { 7 | typedef map_wrapper, K, V> base; 8 | 9 | public: 10 | map () { } 11 | map (unsigned dummy_size) : base(dummy_size) { } 12 | map (const map &m) : base(m) { } 13 | map (copy, const map &m) : base(COPY, m) { } 14 | map (initializer_list > il) : base(il) { } 15 | map (reader &r) : base(r) { } 16 | ~map () { } 17 | 18 | map &operator = (const map &m) { base::operator = (m); return *this; } 19 | map &operator = (initializer_list > il) 20 | { 21 | base::operator = (il); 22 | return *this; 23 | } 24 | }; 25 | 26 | template 27 | using map_iter = map_wrapper_iter, K, V>; 28 | 29 | template 30 | using map_const_iter = map_wrapper_const_iter, K, V>; 31 | -------------------------------------------------------------------------------- /lib/mapcommon.h: -------------------------------------------------------------------------------- 1 | 2 | template map & 3 | mapassign (map &to, unsigned dummy_size, const ullmanmap &from) 4 | { 5 | assert (dummy_size == from.size ()); 6 | 7 | to = map (); 8 | for (ullmanmap_const_iter i = from; i; i ++) 9 | to.push (i.key (), i.val ()); 10 | return to; 11 | } 12 | 13 | template ullmanmap & 14 | mapassign (ullmanmap &to, unsigned size, const map &from) 15 | { 16 | to = ullmanmap (size); 17 | for (typename map::const_iter i = from; i; i ++) 18 | to.push (i.key (), i.val ()); 19 | return to; 20 | } 21 | 22 | template map & 23 | mapassign (map &to, unsigned dummy_size, const map &from) 24 | { 25 | // todo: ?? careful about allocation: this unref's the previous object pointed to by to 26 | to = map (COPY, from); 27 | return to; 28 | } 29 | -------------------------------------------------------------------------------- /lib/maybe.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | class maybe 4 | { 5 | private: 6 | bool present; 7 | T v; 8 | 9 | public: 10 | maybe () : present(0) { } 11 | maybe (const T &v_) : present(1), v(v_) { } 12 | maybe (const maybe &m) : present(m.present), v(m.v) { } 13 | maybe (reader &r); 14 | ~maybe () { } 15 | 16 | maybe &operator = (const maybe &m) { present = m.present; v = m.v; return *this; } 17 | 18 | bool is_some () const { return present; } 19 | bool is_none () const { return !present; } 20 | T &some () { assert (present); return v; } 21 | 22 | bool operator == (const maybe &m) const 23 | { 24 | if (present != m.present) 25 | return 0; 26 | if (present) 27 | return v == m.v; 28 | } 29 | bool operator != (const maybe &m) const { return !operator == (m); } 30 | 31 | void write_self (writer &w) const; 32 | hash_t hash_self () const; 33 | }; 34 | 35 | template 36 | maybe::maybe (reader &r) 37 | { 38 | read (r, present); 39 | if (present) 40 | read (r, v); 41 | } 42 | 43 | template void 44 | maybe::write_self (writer &w) const 45 | { 46 | write (w, present); 47 | if (present) 48 | write (w, v); 49 | } 50 | 51 | template hash_t 52 | maybe::hash_self () const 53 | { 54 | if (present) 55 | return hash_combine (hash (0xdeadbeef), hash (v)); 56 | else 57 | return hash (0xcafebabe); 58 | } 59 | -------------------------------------------------------------------------------- /lib/pair.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | class pair 4 | { 5 | public: 6 | F first; 7 | S second; 8 | 9 | public: 10 | pair () { } 11 | pair (const pair &p) : first(p.first), second(p.second) { } 12 | /* F, S might be references. */ 13 | pair (F first_, S second_) : first(first_), second(second_) { } 14 | pair (reader &r); 15 | ~pair () { } 16 | 17 | pair &operator = (const pair &p) { first = p.first; second = p.second; return *this; } 18 | 19 | bool operator == (const pair &p) const { return first == p.first && second == p.second; } 20 | bool operator != (const pair &p) const { return !operator == (p); } 21 | bool operator < (const pair &p) const { return (first < p.first 22 | || (first == p.first && second < p.second)); } 23 | 24 | void write_self (writer &w) const; 25 | hash_t hash_self () const { return hash_combine (hash (first), hash (second)); } 26 | }; 27 | 28 | template 29 | pair::pair (reader &r) 30 | { 31 | read (r, first); 32 | read (r, second); 33 | } 34 | 35 | template void 36 | pair::write_self (writer &w) const 37 | { 38 | write (w, first); 39 | write (w, second); 40 | } 41 | 42 | template 43 | class triple 44 | { 45 | public: 46 | F first; 47 | S second; 48 | T third; 49 | 50 | triple () { } 51 | triple (const triple &t) 52 | : first(t.first), second(t.second), third(t.third) 53 | { } 54 | triple (const F &first_, const S &second_, const T &third_) 55 | : first(first_), second(second_), third(third_) 56 | { } 57 | triple (reader &r); 58 | ~triple () { } 59 | 60 | triple &operator = (const triple &t) 61 | { 62 | first = t.first; 63 | second = t.second; 64 | third = t.third; 65 | return *this; 66 | } 67 | 68 | bool operator == (const triple &t) const 69 | { 70 | return first == t.first && second == t.second && third == t.third; 71 | } 72 | bool operator != (const triple &t) const { return !operator == (t); } 73 | 74 | bool operator < (const triple &t) const 75 | { 76 | if (first < t.first) 77 | return 1; 78 | else if (first > t.first) 79 | return 0; 80 | 81 | if (second < t.second) 82 | return 1; 83 | else if (second > t.second) 84 | return 0; 85 | 86 | return third < t.third; 87 | } 88 | 89 | void write_self (writer &w) const; 90 | hash_t hash_self () const 91 | { 92 | hash_t h = hash (first); 93 | h = hash_combine (h, hash (second)); 94 | return hash_combine (h, hash (third)); 95 | } 96 | }; 97 | 98 | template 99 | triple::triple (reader &r) 100 | { 101 | read (r, first); 102 | read (r, second); 103 | read (r, third); 104 | } 105 | 106 | template void 107 | triple::write_self (writer &w) const 108 | { 109 | write (w, first); 110 | write (w, second); 111 | write (w, third); 112 | } 113 | -------------------------------------------------------------------------------- /lib/priority_queue.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | class priority_queue 4 | { 5 | private: 6 | class weighted 7 | { 8 | public: 9 | V v; 10 | int pri; 11 | 12 | public: 13 | weighted () { } 14 | weighted (const weighted &w) : v(w.v), pri(w.pri) { } 15 | weighted (const V &v_, int pri_) : v(v_), pri(pri_) { } 16 | ~weighted () { } 17 | 18 | weighted &operator = (const weighted &w) { v = w.v; pri = w.pri; } 19 | 20 | bool operator == (const weighted &w) const { return v == w.v && pri == w.pri; } 21 | bool operator != (const weighted &w) const { return !operator == (w); } 22 | 23 | bool operator < (const weighted &w) const { return pri > w.pri || (pri == w.pri && v < w.v); } 24 | }; 25 | 26 | map pri; 27 | set s; 28 | 29 | public: 30 | priority_queue () { } 31 | priority_queue (const priority_queue &q) : pri(q.pri), s(q.s) { } 32 | priority_queue (copy, const priority_queue &q) : pri(COPY, q.pri), s(COPY, q.s) { } 33 | ~priority_queue () { } 34 | 35 | priority_queue &operator = (const priority_queue &q) { pri = q.pri; s = q.s; } 36 | 37 | bool is_empty () const { return s.is_empty (); } 38 | bool operator % (const V &v) const { return pri % v; } 39 | void push (const V &v, int p) 40 | { 41 | assert (! (pri % v)); 42 | pri.push (v, p); 43 | s.push (weighted (v, p)); 44 | } 45 | priority_queue &operator -= (const V &v) 46 | { 47 | maybe old_p = pri.remove_with_value (v); 48 | if (old_p.is_some ()) 49 | s.yank (weighted (v, old_p.some ())); 50 | return *this; 51 | } 52 | void yank (const V &v) { assert (pri % v); operator -= (v); } 53 | void insert (const V &v, int p) 54 | { 55 | int *old_p = pri ^ v; 56 | if (old_p) 57 | { 58 | if (*old_p != p) 59 | { 60 | s.yank (weighted (v, *old_p)); 61 | s.push (weighted (v, p)); 62 | *old_p = p; 63 | } 64 | } 65 | else 66 | { 67 | pri.push (v, p); 68 | s.push (weighted (v, p)); 69 | } 70 | } 71 | V pop () 72 | { 73 | weighted w = s.pop (); 74 | pri.yank (w.v); 75 | return w.v; 76 | } 77 | const V &top () const { return s.head ().v; } 78 | 79 | unsigned card () const { return s.card (); } 80 | }; 81 | -------------------------------------------------------------------------------- /lib/refcount.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifndef NDEBUG 5 | uint64 allocations = 0; 6 | uint64 deallocations = 0; 7 | 8 | class finalize 9 | { 10 | public: 11 | finalize (); 12 | ~finalize (); 13 | }; 14 | 15 | finalize::finalize () 16 | { 17 | } 18 | 19 | finalize::~finalize () 20 | { 21 | // assert (allocations == deallocations); 22 | } 23 | 24 | static finalize finalizer; 25 | #endif 26 | -------------------------------------------------------------------------------- /lib/refcount.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef NDEBUG 3 | extern uint64 allocations, deallocations; 4 | #endif 5 | 6 | inline void *operator new (size_t size) 7 | { 8 | #ifndef NDEBUG 9 | allocations ++; 10 | #endif 11 | return malloc (size); 12 | } 13 | inline void *operator new [] (size_t size) 14 | { 15 | #ifndef NDEBUG 16 | allocations ++; 17 | #endif 18 | return malloc (size); 19 | } 20 | 21 | inline void operator delete (void *p) 22 | { 23 | #ifndef NDEBUG 24 | deallocations ++; 25 | #endif 26 | free (p); 27 | } 28 | inline void operator delete [] (void *p) 29 | { 30 | #ifndef NDEBUG 31 | deallocations ++; 32 | #endif 33 | free (p); 34 | } 35 | 36 | class refcounted 37 | { 38 | private: 39 | template friend class ptr; 40 | 41 | mutable unsigned refcount; 42 | 43 | public: 44 | refcounted () : refcount(0) { } 45 | refcounted (const refcounted &rc) = delete; 46 | ~refcounted () { } 47 | 48 | refcounted &operator = (const refcounted &rc) = delete; 49 | }; 50 | 51 | template 52 | class ptr 53 | { 54 | private: 55 | template friend class ptr; 56 | 57 | T *p; 58 | 59 | void ref (T *newp) { assert (p == 0); p = newp; if (p) p->refcount ++; } 60 | void unref () { if (p && -- p->refcount == 0) { delete p; } p = 0; } 61 | 62 | public: 63 | ptr () : p(0) { } 64 | ptr (const ptr &r) : p(0) { ref (r.p); } 65 | template ptr (S *p_) : p(0) { ref (p_); } 66 | template ptr (const ptr &r) : p(0) { ref (r.p); } 67 | ~ptr () { unref (); } 68 | 69 | ptr &operator = (const ptr &r) { unref (); ref (r.p); return *this; } 70 | template ptr &operator = (S *p_) { unref (); ref (p_); return *this; } 71 | 72 | template bool operator == (const ptr &r) const { return p == r.p; } 73 | template bool operator != (const ptr &r) const { return p != r.p; } 74 | 75 | template bool operator == (S *p_) const { return p == p_; } 76 | template bool operator != (S *p_) const { return p != p_; } 77 | 78 | bool operator == (int x) const { assert (x == 0); return p == 0; } 79 | bool operator != (int x) const { assert (x == 0); return p != 0; } 80 | 81 | T &operator * () const { assert (p); return *p; } 82 | T *get () const { assert (p); return p; } 83 | T *operator -> () const { assert (p); return p; } 84 | }; 85 | -------------------------------------------------------------------------------- /lib/set.h: -------------------------------------------------------------------------------- 1 | 2 | /* wrapper for std::set */ 3 | 4 | template 5 | class set : public set_wrapper, T> 6 | { 7 | typedef set_wrapper, T> base; 8 | 9 | public: 10 | set () { } 11 | set (const set &m) : base(m) { } 12 | set (copy, const set &m) : base(COPY, m) { } 13 | set (initializer_list il) : base(il) { } 14 | set (reader &r) : base(r) { } 15 | ~set () { } 16 | 17 | set &operator = (const set &m) { base::operator = (m); return *this; } 18 | set &operator = (initializer_list il) { base::operator = (il); } 19 | 20 | bool operator == (const set &s) const; 21 | bool operator != (const set &s) const { return !operator == (s); } 22 | bool operator < (const set &s) const; 23 | bool operator <= (const set &s) const; 24 | 25 | bool toggle (const T &v); 26 | 27 | set &operator |= (const set &s); 28 | set &operator &= (const set &s); 29 | set &operator ^= (const set &s); 30 | }; 31 | 32 | template 33 | using set_iter = set_wrapper_iter, T>; 34 | 35 | template 36 | using set_const_iter = set_wrapper_const_iter, T>; 37 | 38 | template bool 39 | set::operator == (const set &s) const 40 | { 41 | typename std::set::const_iterator i = this->impl->t.begin (), 42 | j = s.impl->t.begin (), 43 | iend = this->impl->t.end (), 44 | jend = s.impl->t.end (); 45 | 46 | while (i != iend && j != jend && *i == *j) 47 | i ++, j ++; 48 | 49 | return i == iend && j == jend; 50 | } 51 | 52 | template bool 53 | set::operator < (const set &s) const 54 | { 55 | typename std::set::const_iterator i = this->impl->t.begin (), 56 | j = s.impl->t.begin (), 57 | iend = this->impl->t.end (), 58 | jend = s.impl->t.end (); 59 | 60 | while (i != iend && j != jend && *i == *j) 61 | i ++, j ++; 62 | 63 | return (i == iend && j != jend) || (i != iend && j != jend && *i < *j); 64 | } 65 | 66 | template bool 67 | set::operator <= (const set &s) const 68 | { 69 | typename std::set::const_iterator i = this->impl->t.begin (), 70 | j = s.impl->t.begin (), 71 | iend = this->impl->t.end (), 72 | jend = s.impl->t.end (); 73 | 74 | while (i != iend && j != jend && *i == *j) 75 | i ++, j ++; 76 | 77 | return i == iend 78 | || (i != iend && j != jend && *i <= *j); 79 | } 80 | 81 | template bool 82 | set::toggle (const T &v) 83 | { 84 | typename std::set::const_iterator i = this->impl->t.lower_bound (v), 85 | end = this->impl->t.end (); 86 | if (i != end && *i == v) 87 | { 88 | this->impl->t.erase (i); 89 | return 1; 90 | } 91 | else 92 | { 93 | if (i == this->impl->t.begin ()) 94 | this->impl->t.insert (v); 95 | else 96 | { 97 | typename std::set::const_iterator j = --i; 98 | assert (*j < v); 99 | this->impl->t.insert (j, v); 100 | } 101 | return 0; 102 | } 103 | } 104 | 105 | template set & 106 | set::operator |= (const set &s) 107 | { 108 | std::set news; 109 | std::set_union (this->impl->t.begin (), this->impl->t.end (), 110 | s.impl->t.begin (), s.impl->t.end (), 111 | inserter (news, news.begin ())); 112 | this->impl->t = news; 113 | return *this; 114 | } 115 | 116 | template set & 117 | set::operator &= (const set &s) 118 | { 119 | std::set news; 120 | std::set_intersection (this->impl->t.begin (), this->impl->t.end (), 121 | s.impl->t.begin (), s.impl->t.end (), 122 | inserter (news, news.begin ())); 123 | this->impl->t = news; 124 | return *this; 125 | } 126 | 127 | template set & 128 | set::operator ^= (const set &s) 129 | { 130 | #if 0 131 | printf ("before:\n"); 132 | printf ("this:"); 133 | for (typename std::set::const_iterator i = this->impl->t.begin (); i != this->impl->t.end (); i ++) 134 | printf (" %d", *i); 135 | printf ("\n"); 136 | printf ("s:"); 137 | for (typename std::set::const_iterator i = s.impl->t.begin (); i != s.impl->t.end (); i ++) 138 | printf (" %d", *i); 139 | printf ("\n"); 140 | #endif 141 | 142 | #if 1 143 | typename std::set::const_iterator i = this->impl->t.begin (), 144 | iend = this->impl->t.end (), 145 | j = s.impl->t.begin (), 146 | jend = s.impl->t.end (); 147 | 148 | while (i != iend && j != jend && *i == *j) 149 | { 150 | this->impl->t.erase (i); 151 | i = this->impl->t.begin (); 152 | j ++; 153 | } 154 | 155 | if (i == iend) 156 | this->impl->t.insert (j, jend); 157 | else 158 | { 159 | if (j != jend && *j < *i) 160 | { 161 | i = this->impl->t.insert (*j).first; 162 | j ++; 163 | } 164 | 165 | while (j != jend) 166 | { 167 | assert (*i < *j); 168 | 169 | typename std::set::const_iterator iprev = i ++; 170 | if (i == iend) 171 | { 172 | while (j != jend) 173 | { 174 | iprev = this->impl->t.insert (iprev, *j); 175 | j ++; 176 | } 177 | break; 178 | } 179 | else if (*i == *j) 180 | { 181 | this->impl->t.erase (i); 182 | i = iprev; 183 | j ++; 184 | } 185 | else 186 | { 187 | while (j != jend && *j < *i) 188 | { 189 | iprev = this->impl->t.insert (iprev, *j); 190 | j ++; 191 | } 192 | if (j != jend && *j == *i) 193 | { 194 | this->impl->t.erase (i); 195 | i = iprev; 196 | j ++; 197 | } 198 | } 199 | } 200 | } 201 | #endif 202 | 203 | #if 0 204 | std::set news; 205 | std::set_symmetric_difference (this->impl->t.begin (), this->impl->t.end (), 206 | s.impl->t.begin (), s.impl->t.end (), 207 | inserter (news, news.begin ())); 208 | this->impl->t = news; 209 | #endif 210 | 211 | #if 0 212 | printf ("after:\n"); 213 | printf ("this:"); 214 | for (typename std::set::const_iterator i = this->impl->t.begin (); i != this->impl->t.end (); i ++) 215 | printf (" %d", *i); 216 | printf ("\n"); 217 | #endif 218 | 219 | return *this; 220 | } 221 | -------------------------------------------------------------------------------- /lib/set_wrapper.h: -------------------------------------------------------------------------------- 1 | 2 | /* wrapper for STL maps */ 3 | 4 | template class set_wrapper_iter; 5 | template class set_wrapper_const_iter; 6 | 7 | template 8 | class set_wrapper 9 | { 10 | friend class set_wrapper_iter; 11 | friend class set_wrapper_const_iter; 12 | 13 | protected: 14 | class set_wrapper_impl : public refcounted 15 | { 16 | public: 17 | S t; 18 | 19 | public: 20 | set_wrapper_impl () = default; 21 | set_wrapper_impl (const set_wrapper_impl &) = delete; 22 | set_wrapper_impl (const S &t_) : t(t_) { } 23 | set_wrapper_impl (initializer_list il) : t(il) { } 24 | ~set_wrapper_impl () = default; 25 | 26 | set_wrapper_impl &operator = (const set_wrapper_impl &) = delete; 27 | }; 28 | 29 | ptr impl; 30 | 31 | public: 32 | typedef set_wrapper_iter iter; 33 | typedef set_wrapper_const_iter const_iter; 34 | 35 | public: 36 | set_wrapper () : impl(new set_wrapper_impl) { } 37 | set_wrapper (const set_wrapper &s) : impl(s.impl) { } 38 | set_wrapper (copy, const set_wrapper &s) 39 | : impl(new set_wrapper_impl (s.impl->t)) 40 | { } 41 | set_wrapper (initializer_list il) 42 | : impl(new set_wrapper_impl (il)) 43 | { } 44 | set_wrapper (reader &r); 45 | ~set_wrapper () { } 46 | 47 | set_wrapper &operator = (const set_wrapper &s) { impl = s.impl; return *this; } 48 | set_wrapper &operator = (initializer_list li) 49 | { 50 | impl->t = li; 51 | } 52 | 53 | // range-based for 54 | typename S::const_iterator begin () const { return impl->t.begin (); } 55 | typename S::const_iterator end () const { return impl->t.end (); } 56 | 57 | T pop () 58 | { 59 | typename S::const_iterator i = impl->t.begin (); 60 | assert (i != impl->t.end ()); 61 | T tmp = *i; 62 | impl->t.erase (i); 63 | return tmp; 64 | } 65 | 66 | bool is_empty () const { return impl->t.empty (); } 67 | unsigned card () const { return impl->t.size (); } 68 | const T &head () const; 69 | const T &tail () const; 70 | 71 | void clear () { impl->t.clear (); } 72 | void push (const T &v) { assert (impl->t.find (v) == impl->t.end ()); impl->t.insert (v); } 73 | void operator += (const T &v) { impl->t.insert (v); } 74 | void operator -= (const T &v) { impl->t.erase (v); } 75 | void yank (const T &v) { assert (operator % (v)); impl->t.erase (v); } 76 | 77 | bool operator % (const T &v) const { return impl->t.find (v) != impl->t.end (); } 78 | bool operator () (const T &v) const { return operator % (v); } 79 | 80 | void write_self (writer &w) const; 81 | hash_t hash_self () const; 82 | }; 83 | 84 | template 85 | class set_wrapper_iter 86 | { 87 | ptr::set_wrapper_impl> impl; 88 | typename S::const_iterator i, end; 89 | bool deleted; 90 | 91 | public: 92 | set_wrapper_iter (set_wrapper &s) : impl(s.impl), i(s.impl->t.begin ()), end(s.impl->t.end ()), deleted(0) { } 93 | ~set_wrapper_iter () { } 94 | 95 | void del () 96 | { 97 | assert (!deleted); 98 | typename S::const_iterator iprev = i ++; 99 | impl->t.erase (iprev); 100 | deleted = 1; 101 | } 102 | 103 | const T &val () const { assert (!deleted); return *i; } 104 | operator bool () const { assert (!deleted); return i != end; } 105 | set_wrapper_iter &operator ++ () { if (deleted) deleted = 0; else i ++; return *this; } 106 | void operator ++ (int) { operator ++ (); } 107 | }; 108 | 109 | template 110 | class set_wrapper_const_iter 111 | { 112 | ptr::set_wrapper_impl> impl; 113 | typename S::const_iterator i, end; 114 | 115 | public: 116 | set_wrapper_const_iter (const set_wrapper &s) : impl(s.impl), i(s.impl->t.begin ()), end(s.impl->t.end ()) { } 117 | ~set_wrapper_const_iter () { } 118 | 119 | const T &val () const { return *i; } 120 | operator bool () const { return i != end; } 121 | set_wrapper_const_iter &operator ++ () { i ++; return *this; } 122 | void operator ++ (int) { i ++; } 123 | }; 124 | 125 | template 126 | set_wrapper::set_wrapper (reader &r) 127 | : impl(new set_wrapper_impl) 128 | { 129 | unsigned n; 130 | read (r, n); 131 | T x; 132 | for (unsigned i = 0; i < n; i ++) 133 | { 134 | read (r, x); 135 | push (x); 136 | } 137 | } 138 | 139 | template const T & 140 | set_wrapper::head () const 141 | { 142 | set_wrapper_const_iter i = *this; 143 | assert (i); 144 | return i.val (); 145 | } 146 | 147 | template const T & 148 | set_wrapper::tail () const 149 | { 150 | typename S::const_reverse_iterator i = impl->t.rbegin (); 151 | assert (i != impl->t.rend ()); 152 | return *i; 153 | } 154 | 155 | template void 156 | set_wrapper::write_self (writer &w) const 157 | { 158 | write (w, card ()); 159 | for (const_iter i = *this; i; i ++) 160 | write (w, i.val ()); 161 | } 162 | 163 | template hash_t 164 | set_wrapper::hash_self () const 165 | { 166 | hash_t h = hash (card ()); 167 | unsigned j = 0; 168 | for (const_iter i = *this; i && j < 10; i ++, j ++) 169 | h = hash_combine (h, hash (i.val ())); 170 | return h; 171 | } 172 | -------------------------------------------------------------------------------- /lib/setcommon.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | unsigned unsigned_set (const ullmanset<1> &s) 5 | { 6 | assert (s.size () <= unsigned_bits); 7 | 8 | unsigned v = 0; 9 | for (ullmanset_const_iter<1> i = s; i; i ++) 10 | v = unsigned_bitset (v, i.val ()); 11 | return v; 12 | } 13 | 14 | unsigned 15 | unsigned_set (const bitset &s) 16 | { 17 | assert (s.size () <= unsigned_bits); 18 | 19 | unsigned v = 0; 20 | for (bitset_const_iter i = s; i; i ++) 21 | v = unsigned_bitset (v, i.val ()); 22 | return v; 23 | } 24 | 25 | unsigned 26 | unsigned_set (const set &s) 27 | { 28 | unsigned v = 0; 29 | for (set_const_iter i = s; i; i ++) 30 | v = unsigned_bitset (v, i.val ()); 31 | return v; 32 | } 33 | 34 | /* bitset */ 35 | 36 | bitset::bitset (const ullmanset<1> &t) 37 | : n(0) 38 | { 39 | *this = bitset (t.size ()); 40 | for (ullmanset_const_iter<1> i = t; i; i ++) 41 | push (i.val ()); 42 | } 43 | 44 | bitset & 45 | bitset::operator = (const ullmanset<1> &t) 46 | { 47 | *this = bitset (t.size ()); 48 | for (ullmanset_const_iter<1> i = t; i; i ++) 49 | push (i.val ()); 50 | return *this; 51 | } 52 | 53 | smallbitset::smallbitset (const ullmanset<1> &t) 54 | : n(t.size ()), x(0) 55 | { 56 | assert (n <= 58); 57 | 58 | for (ullmanset_const_iter<1> i = t; i; i ++) 59 | push (i.val ()); 60 | } 61 | -------------------------------------------------------------------------------- /lib/setcommon.h: -------------------------------------------------------------------------------- 1 | 2 | extern unsigned unsigned_set (const ullmanset<1> &s); 3 | extern unsigned unsigned_set (const bitset &s); 4 | extern unsigned unsigned_set (const set &s); 5 | 6 | smallbitset::smallbitset (const bitset &t) 7 | : n(t.size ()), 8 | x(0) 9 | { 10 | assert (t.size () <= max_size); 11 | if (n) 12 | { 13 | assert (t.v.size () == 1); 14 | x = t.v[0]; 15 | } 16 | assert ((x >> n) == 0); 17 | } 18 | 19 | template 20 | ullmanset::ullmanset (const bitset &t) 21 | : d(0) 22 | { 23 | *this = ullmanset (t.size ()); 24 | for (bitset_const_iter i = t; i; i ++) 25 | push (i.val ()); 26 | } 27 | 28 | template ullmanset & 29 | ullmanset::operator = (const bitset &t) 30 | { 31 | *this = ullmanset (t.size ()); 32 | for (bitset_const_iter i = t; i; i ++) 33 | push (i.val ()); 34 | return *this; 35 | } 36 | 37 | template set & 38 | setassign (set &to, unsigned dummy_size, const ullmanset &from) 39 | { 40 | assert (dummy_size == from.size ()); 41 | 42 | to = set (); 43 | for (ullmanset_const_iter i = from; i; i ++) 44 | to.push (i.val ()); 45 | return to; 46 | } 47 | 48 | template ullmanset & 49 | setassign (ullmanset &to, unsigned size, const set &from) 50 | { 51 | to = ullmanset (size); 52 | for (set_const_iter i = from; i; i ++) 53 | to.push (i.val ()); 54 | return to; 55 | } 56 | -------------------------------------------------------------------------------- /lib/show.h: -------------------------------------------------------------------------------- 1 | 2 | inline void newline () { printf ("\n"); } 3 | inline void comment () { printf ("%% "); } 4 | inline void show (int i) { printf ("%d", i); } 5 | inline void show (unsigned i) { printf ("%d", i); } 6 | inline void display (int i) { printf ("%d\n", i); } 7 | inline void display (unsigned i) { printf ("%d\n", i); } 8 | 9 | template inline void show (const T &e) { e.show_self (); } 10 | template inline void display (const T &e) { e.display_self (); } 11 | 12 | template inline void display (const char *h, const T &e) 13 | { 14 | printf ("%s", h); 15 | e.display_self (); 16 | } 17 | -------------------------------------------------------------------------------- /lib/smallbitset.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | smallbitset::smallbitset (reader &r) 5 | { 6 | uint64 t; 7 | read (r, t); 8 | n = t >> 58; 9 | x = t; 10 | 11 | assert (n <= max_size); 12 | } 13 | 14 | #if 0 15 | smallbitset::smallbitset (const unsignedset &t) 16 | : n(t.size ()), 17 | x(0) 18 | { 19 | assert (n <= max_size); 20 | for (unsignedset_const_iter i = t; i; i ++) 21 | push (i.val ()); 22 | } 23 | #endif 24 | 25 | void 26 | smallbitset::write_self (writer &w) const 27 | { 28 | write (w, x | (((uint64)n) << 58)); 29 | } 30 | 31 | void 32 | smallbitset::show_self () const 33 | { 34 | printf ("%d:", n); 35 | for (unsigned i = n; i >= 1; i --) 36 | printf ("%c", operator % (i) ? '1' : '0'); 37 | } 38 | 39 | void 40 | smallbitset::display_self () const 41 | { 42 | show_self (); 43 | newline (); 44 | } 45 | -------------------------------------------------------------------------------- /lib/smallbitset.h: -------------------------------------------------------------------------------- 1 | 2 | class smallbitset_iter; 3 | class smallbitset_const_iter; 4 | 5 | class smallbitset 6 | { 7 | private: 8 | friend class smallbitset_iter; 9 | friend class smallbitset_const_iter; 10 | 11 | unsigned n : 6; 12 | uint64 x : 58; 13 | 14 | public: 15 | static const unsigned max_size = 58; 16 | 17 | typedef smallbitset_iter iter; 18 | typedef smallbitset_const_iter const_iter; 19 | 20 | public: 21 | smallbitset () : n(0), x(0) { } 22 | explicit smallbitset (unsigned n_) : n(n_), x(0) { assert (n_ <= max_size); } 23 | explicit smallbitset (reader &r); 24 | smallbitset (unsigned n_, uint64 x_) 25 | : n(n_), x(x_ & uint64_fill (n_)) 26 | { 27 | assert (n <= max_size); 28 | assert ((x >> n) == 0); 29 | } 30 | 31 | smallbitset (const smallbitset &bs) : n(bs.n), x(bs.x) { } 32 | explicit smallbitset (const ullmanset<1> &t); 33 | // explicit smallbitset (const unsignedset &t); 34 | explicit inline smallbitset (const bitset &t); 35 | 36 | ~smallbitset () { } 37 | 38 | smallbitset &operator = (const smallbitset &bs) { n = bs.n; x = bs.x; return *this; } 39 | smallbitset &operator = (const bitset &t) { *this = smallbitset (t); return *this; } 40 | // smallbitset &operator = (const unsignedset &t) { *this = smallbitset (t); return *this; } 41 | smallbitset &operator = (const ullmanset<1> &t) { *this = smallbitset (t); return *this; } 42 | 43 | bool is_empty () const { assert ((x >> n) == 0); return x == 0; } 44 | unsigned card () const { assert ((x >> n) == 0); return uint64_bitcount (x); } 45 | unsigned size () const { return n; } 46 | unsigned head () const { assert (x); return uint64_ffs (x); } 47 | unsigned pop () 48 | { 49 | assert (x); 50 | 51 | unsigned i = uint64_ffs (x); 52 | x = uint64_bitclear (x, i); 53 | return i; 54 | } 55 | 56 | bool subset (const smallbitset &bs) const 57 | { 58 | assert (n == bs.n); 59 | assert ((x >> n) == 0); 60 | assert ((bs.x >> n) == 0); 61 | return (x & bs.x) == x; 62 | } 63 | 64 | void push (unsigned i) { assert (! (*this % i)); operator += (i); } 65 | void yank (unsigned i) { assert (*this % i); operator -= (i); } 66 | void operator += (unsigned i) { assert (i <= n); x = uint64_bitset (x, i); } 67 | void operator -= (unsigned i) { assert (i <= n); x = uint64_bitclear (x, i); } 68 | 69 | void toggle (unsigned i) { assert (i <= n); x = uint64_bittoggle (x, i); } 70 | void toggle () { x ^= (((uint64)1) << n) - 1; } 71 | 72 | smallbitset &operator |= (const smallbitset &bs) { assert (n == bs.n); x |= bs.x; return *this; } 73 | smallbitset &operator &= (const smallbitset &bs) { assert (n == bs.n); x &= bs.x; return *this; } 74 | smallbitset &operator ^= (const smallbitset &bs) { assert (n == bs.n); x ^= bs.x; return *this; } 75 | 76 | bool operator == (const smallbitset &bs) const { return n == bs.n && x == bs.x; } 77 | bool operator != (const smallbitset &bs) const { return !operator == (bs); } 78 | 79 | inline bool operator % (unsigned i) const { return uint64_bittest (x, i); } 80 | inline bool operator () (unsigned i) const { return operator % (i); } 81 | 82 | void show_self () const; 83 | void display_self () const; 84 | 85 | void write_self (writer &w) const; 86 | hash_t hash_self () const { assert ((x >> n) == 0); return hash_combine (hash (n), hash (x)); } 87 | }; 88 | 89 | class smallbitset_const_iter 90 | { 91 | uint64 x; 92 | unsigned b; 93 | 94 | public: 95 | smallbitset_const_iter (const smallbitset &bs) : x(bs.x), b(0) { if (x) b = uint64_ffs (x); } 96 | smallbitset_const_iter (const smallbitset_const_iter &i) : x(i.x), b(i.b) { } 97 | ~smallbitset_const_iter () { } 98 | 99 | smallbitset_const_iter &operator = (const smallbitset_const_iter &i) { x = i.x; b = i.b; return *this; } 100 | 101 | unsigned val () const { return b; } 102 | operator bool () const { return (bool)x; } 103 | void operator ++ () { assert (x); x = uint64_bitclear (x, b); if (x) b = uint64_ffs (x); } 104 | void operator ++ (int) { operator ++ (); } 105 | }; 106 | 107 | class smallbitset_iter 108 | { 109 | smallbitset *bs; 110 | uint64 x; 111 | unsigned b; 112 | bool deleted; 113 | 114 | public: 115 | smallbitset_iter (smallbitset &bs_) 116 | : bs(&bs_), x(bs_.x), b(0), deleted(0) 117 | { 118 | if (x) 119 | b = uint64_ffs (x); 120 | } 121 | smallbitset_iter (const smallbitset_iter &i) 122 | : bs(i.bs), x(i.x), b(i.b), deleted(i.deleted) { } 123 | ~smallbitset_iter () { } 124 | 125 | smallbitset_iter &operator = (const smallbitset_iter &i) 126 | { 127 | bs = i.bs; 128 | x = i.x; 129 | b = i.b; 130 | deleted = i.deleted; 131 | return *this; 132 | } 133 | 134 | void del () { assert (!deleted); (*bs) -= b; deleted = 1; } 135 | unsigned val () const { assert (!deleted); return b; } 136 | operator bool () const { assert (!deleted); return (bool)x; } 137 | void operator ++ () 138 | { 139 | assert (x); 140 | 141 | x = uint64_bitclear (x, b); 142 | if (x) 143 | b = uint64_ffs (x); 144 | deleted = 0; 145 | } 146 | void operator ++ (int) { operator ++ (); } 147 | }; 148 | -------------------------------------------------------------------------------- /lib/ullmanmap.h: -------------------------------------------------------------------------------- 1 | 2 | template class ullmanmap_iter; 3 | template class ullmanmap_const_iter; 4 | 5 | template 6 | class ullmanmap 7 | { 8 | private: 9 | friend class ullmanmap_iter; 10 | friend class ullmanmap_const_iter; 11 | 12 | ullmanset present; 13 | basedvector values; 14 | 15 | public: 16 | typedef ullmanmap_iter iter; 17 | typedef ullmanmap_const_iter const_iter; 18 | 19 | public: 20 | ullmanmap () { } 21 | ullmanmap (unsigned size) : present(size), values(size) { } 22 | ullmanmap (unsigned size, const map &m); // common 23 | ullmanmap (const ullmanmap &m) : present(m.present), values(m.values) { } 24 | ullmanmap (copy, const ullmanmap &m) : present(COPY, m.present), values(COPY, m.values) { } 25 | ullmanmap (reader &r); 26 | ~ullmanmap () { } 27 | 28 | ullmanmap &operator = (const ullmanmap &m) { present = m.present; values = m.values; return *this; } 29 | ullmanmap &operator = (const map &m); // common 30 | 31 | unsigned size () const { return present.size (); } 32 | 33 | pair head (); 34 | void clear () { present.clear (); } 35 | unsigned card () { return present.card (); } 36 | void operator -= (unsigned k) { present -= k; } 37 | 38 | void push (unsigned k, const V &v) { present.push (k); values[k] = v; } 39 | void set (unsigned k, const V &v) { present += k; values[k] = v; } 40 | 41 | V &operator [] (unsigned k) { if (! (present % k)) { present.push (k); values[k] = V (); } return values[k]; } 42 | const V &operator [] (unsigned k) const { assert (present % k); return values[k]; } 43 | const V &operator () (unsigned k) const { assert (present % k); return operator [] (k); } 44 | const V &operator () (unsigned k, const V &d) const { if (present % k) return values[k]; else return d; } 45 | 46 | pair find (unsigned k) 47 | { 48 | bool p = present % k; 49 | return pair (operator [] (k), p); 50 | } 51 | 52 | bool operator % (unsigned k) const { return present % k; } 53 | 54 | unsigned nth (unsigned p) const { return present.nth (p); } 55 | unsigned position (unsigned k) const { return present.position (k); } 56 | 57 | void write_self (writer &w) const; 58 | }; 59 | 60 | template 61 | ullmanmap::ullmanmap (unsigned size, const map &m) 62 | : present(size), values(size) 63 | { 64 | for (typename map::const_iter i = m; i; i ++) 65 | push (i.key (), i.val ()); 66 | } 67 | 68 | template 69 | ullmanmap::ullmanmap (reader &r) 70 | : present(r), 71 | values(r) 72 | { 73 | } 74 | 75 | template ullmanmap & 76 | ullmanmap::operator = (const map &m) 77 | { 78 | /* assume the ullman map is already allocated */ 79 | clear (); 80 | for (typename map::const_iter i = m; i; i ++) 81 | push (i.key (), i.val ()); 82 | return *this; 83 | } 84 | 85 | template void 86 | ullmanmap::write_self (writer &w) const 87 | { 88 | write (w, present); 89 | write (w, values); 90 | } 91 | 92 | template 93 | class ullmanmap_iter 94 | { 95 | private: 96 | ullmanset_iter i; 97 | basedvector &values; 98 | 99 | public: 100 | ullmanmap_iter (ullmanmap &m) : i(m.present), values(m.values) { } 101 | ~ullmanmap_iter () { } 102 | 103 | void del () { i.del (); } 104 | unsigned key () const { return i.val (); } 105 | V &val () { return values[i.val ()]; } 106 | const V &val () const { return values[i.val ()]; } 107 | operator bool () const { return (bool)i; } 108 | void operator ++ () { i ++; } 109 | void operator ++ (int) { i ++; } 110 | }; 111 | 112 | template 113 | class ullmanmap_const_iter 114 | { 115 | private: 116 | ullmanset_const_iter i; 117 | const basedvector &values; 118 | 119 | public: 120 | ullmanmap_const_iter (const ullmanmap &m) : i(m.present), values(m.values) { } 121 | ~ullmanmap_const_iter () { } 122 | 123 | unsigned key () const { return i.val (); } 124 | const V &val () const { return values[i.val ()]; } 125 | operator bool () const { return (bool)i; } 126 | void operator ++ () { i ++; } 127 | void operator ++ (int) { i ++; } 128 | }; 129 | -------------------------------------------------------------------------------- /lib/unionfind.h: -------------------------------------------------------------------------------- 1 | 2 | template 3 | class unionfind 4 | { 5 | unsigned n_sets; 6 | basedvector parent; 7 | 8 | public: 9 | unionfind (unsigned size); 10 | unionfind (const unionfind &u) : n_sets(u.n_sets), parent(u.parent) { } 11 | unionfind (copy, const unionfind &u) : n_sets(u.n_sets), parent(COPY, u.parent) { } 12 | unionfind (reader &r); 13 | ~unionfind () { } 14 | 15 | unsigned num_sets () const { return n_sets; } 16 | void clear (); 17 | 18 | void join (unsigned x, unsigned y); 19 | unsigned find (unsigned x); 20 | 21 | void write_self (writer &w) const; 22 | }; 23 | 24 | template 25 | unionfind::unionfind (unsigned size) 26 | : n_sets(size), 27 | parent(size) 28 | { 29 | for (unsigned i = 0; i < size; i ++) 30 | parent[i + B] = i + B; 31 | } 32 | 33 | template 34 | unionfind::unionfind (reader &r) 35 | { 36 | read (r, n_sets); 37 | read (r, parent); 38 | } 39 | 40 | template void 41 | unionfind::clear () 42 | { 43 | unsigned size = parent.size (); 44 | n_sets = size; 45 | for (unsigned i = 0; i < size; i ++) 46 | parent[i + B] = i + B; 47 | } 48 | 49 | template void 50 | unionfind::join (unsigned x, unsigned y) 51 | { 52 | unsigned xp = find (x), 53 | yp = find (y); 54 | if (xp != yp) 55 | { 56 | n_sets --; 57 | parent[yp] = xp; 58 | } 59 | } 60 | 61 | template unsigned 62 | unionfind::find (unsigned x) 63 | { 64 | unsigned p = parent[x]; 65 | while (parent[p] != p) 66 | p = parent[p]; 67 | 68 | while (x != p) 69 | { 70 | unsigned xp = parent[x]; 71 | parent[x] = p; 72 | x = xp; 73 | } 74 | 75 | return p; 76 | } 77 | 78 | template void 79 | unionfind::write_self (writer &w) const 80 | { 81 | write (w, n_sets); 82 | write (w, parent); 83 | } 84 | -------------------------------------------------------------------------------- /mpi_aux.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | // #include 6 | 7 | #define DATATAG 1 8 | 9 | void 10 | comm_init (int *argc, char ***argv) 11 | { 12 | MPI_Init (argc, argv); 13 | } 14 | 15 | void 16 | comm_finalize () 17 | { 18 | MPI_Finalize (); 19 | } 20 | 21 | int 22 | self_rank () 23 | { 24 | int node; 25 | MPI_Comm_rank (MPI_COMM_WORLD, &node); 26 | return node; 27 | } 28 | 29 | int 30 | num_tasks () 31 | { 32 | int ntasks; 33 | MPI_Comm_size (MPI_COMM_WORLD, &ntasks); 34 | return ntasks; 35 | } 36 | 37 | void 38 | send_int (int v, int dest) 39 | { 40 | MPI_Send (&v, 1, MPI_INT, dest, DATATAG, MPI_COMM_WORLD); 41 | } 42 | 43 | void 44 | send_string (const char *s, int dest) 45 | { 46 | int n = strlen (s); 47 | MPI_Send (&n, 1, MPI_INT, dest, DATATAG, MPI_COMM_WORLD); 48 | MPI_Send ((void *)s, n, MPI_CHAR, dest, DATATAG, MPI_COMM_WORLD); 49 | } 50 | 51 | void 52 | send_string (const std::string &s, int dest) 53 | { 54 | send_string (s.c_str (), dest); 55 | } 56 | 57 | int 58 | recv_int (int *src) 59 | { 60 | int v; 61 | MPI_Status status; 62 | MPI_Recv (&v, /* message buffer */ 63 | 1, /* one data item */ 64 | MPI_INT, /* of type int */ 65 | MPI_ANY_SOURCE, /* receive from any sender */ 66 | MPI_ANY_TAG, /* any type of message */ 67 | MPI_COMM_WORLD, /* default communicator */ 68 | &status); /* info about the received message */ 69 | if (src) 70 | *src = status.MPI_SOURCE; 71 | return v; 72 | } 73 | 74 | std::string 75 | recv_string (int *src) 76 | { 77 | int n; 78 | MPI_Status status; 79 | MPI_Recv (&n, /* message buffer */ 80 | 1, /* one data item */ 81 | MPI_INT, /* of type int */ 82 | MPI_ANY_SOURCE, /* receive from any sender */ 83 | MPI_ANY_TAG, /* any type of message */ 84 | MPI_COMM_WORLD, /* default communicator */ 85 | &status); /* info about the received message */ 86 | char *s = new char[n + 1]; 87 | MPI_Recv (s, /* message buffer */ 88 | n, /* one data item */ 89 | MPI_CHAR, /* of type int */ 90 | status.MPI_SOURCE, /* receive from any sender */ 91 | MPI_ANY_TAG, /* any type of message */ 92 | MPI_COMM_WORLD, /* default communicator */ 93 | &status); /* info about the received message */ 94 | if (src) 95 | *src = status.MPI_SOURCE; 96 | s[n] = '\0'; 97 | std::string s_std (s); 98 | delete [] s; 99 | return s_std; 100 | } 101 | 102 | #if 0 103 | void 104 | send_htw_knot (unsigned n, bool alternating, unsigned k, int dest) 105 | { 106 | int data[3]; 107 | data[0] = (int)n; 108 | data[1] = (int)alternating; 109 | data[2] = (int)k; 110 | MPI_Send (&data, 3, MPI_INT, dest, DATATAG, MPI_COMM_WORLD); 111 | } 112 | 113 | knot_diagram 114 | recv_knot (int *src) 115 | { 116 | int data[3]; 117 | MPI_Status status; 118 | MPI_Recv (&data, /* message buffer */ 119 | 3, /* one data item */ 120 | MPI_INT, /* of type int */ 121 | MPI_ANY_SOURCE, /* receive from any sender */ 122 | MPI_ANY_TAG, /* any type of message */ 123 | MPI_COMM_WORLD, /* default communicator */ 124 | &status); /* info about the received message */ 125 | if (src) 126 | *src = status.MPI_SOURCE; 127 | 128 | dt_code k = htw_knot ((unsigned)data[0], 129 | (bool)data[1], 130 | (unsigned)data[2]); 131 | return knot_diagram (k); 132 | } 133 | #endif 134 | -------------------------------------------------------------------------------- /mpi_aux.h: -------------------------------------------------------------------------------- 1 | 2 | void comm_init (int *argc, char ***argv); 3 | void comm_finalize (); 4 | 5 | int self_rank (); 6 | int num_tasks (); 7 | 8 | void send_int (int v, int dest); 9 | void send_string (const char *s, int dest); 10 | void send_string (const std::string &s, int dest); 11 | 12 | int recv_int (int *src); 13 | std::string recv_string (int *src); 14 | 15 | inline int recv_int () { return recv_int (0); } 16 | inline std::string recv_string () { return recv_string (0); } 17 | 18 | #if 0 19 | void send_htw_knot (unsigned n, bool alternating, unsigned k, int dest); 20 | knot_diagram recv_knot (int *src); 21 | knot_diagram recv_knot () { return recv_knot (0); } 22 | #endif 23 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_04a: -------------------------------------------------------------------------------- 1 | dadbcda 2 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_05a: -------------------------------------------------------------------------------- 1 | eaebdeac 2 | eaecdeab 3 | ebbccdaeb 4 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_06a: -------------------------------------------------------------------------------- 1 | fafbdeafc 2 | fafbdefac 3 | fafbdfeac 4 | fbbdceafbd 5 | fbccdefacb 6 | fbccdefcab 7 | fcbbbcdefab 8 | fcbbbceafbd 9 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_06n: -------------------------------------------------------------------------------- 1 | fcbbbcDEfAb 2 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_07a: -------------------------------------------------------------------------------- 1 | gagbdefagc 2 | gagbdfagce 3 | gagbefgadc 4 | gagbegfadc 5 | gagcefgabd 6 | gagcefgbad 7 | gagdefgabc 8 | gbbecdefgab 9 | gbbeceafbgd 10 | gbbeceafgbd 11 | gbbeceagfbd 12 | gbcddefacgb 13 | gbcddefagbc 14 | gcbbcceafbgd 15 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_07n: -------------------------------------------------------------------------------- 1 | gbbecDEfGAb 2 | gbbecDEfGaB 3 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_08a: -------------------------------------------------------------------------------- 1 | hahbdegahcf 2 | hahbdfagche 3 | hahbdfaghce 4 | hahbdfahgce 5 | hahbdgeahcf 6 | hahbefgahcd 7 | hahbefgahdc 8 | hahbefghacd 9 | hahbefghadc 10 | hahbeghfadc 11 | hahbehgfadc 12 | hahcdefghab 13 | hahcdfaghbe 14 | hahcdfgbhae 15 | hahcdgfbhae 16 | hahcefghbad 17 | hahcefhgbad 18 | hahcfehgbad 19 | hbbfcdegfhab 20 | hbbfceafgbhd 21 | hbbfceagbhdf 22 | hbbfceagfbhd 23 | hbbfcfaghbed 24 | hbbfcfahgbed 25 | hbbfcfegahdb 26 | hbcedefahgbc 27 | hbcedefahgcb 28 | hbcedegachbf 29 | hbcedegcahbf 30 | hbddefghadbc 31 | hbddefghadcb 32 | hbddefghdabc 33 | hcbbdceagbhdf 34 | hcbcccdfgheab 35 | hcbcccfaghbed 36 | hcbcccfaghebd 37 | hcbcccfghadeb 38 | hcbdbceagbhdf 39 | hdbbbbceagbhdf 40 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_08n: -------------------------------------------------------------------------------- 1 | hahbdFaGCHE 2 | hahbdFagChe 3 | hahbdFaGHCE 4 | hbbfcDEgFHAb 5 | hbbfcDEgFHaB 6 | hcbcccDFgHEAb 7 | hcbcccDFgHEaB 8 | hcbcccdFgHEab 9 | hcbdbceaGbHDF 10 | hdbbbbcEaGBHDF 11 | hdbbbbcEaGBhDf 12 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_09a: -------------------------------------------------------------------------------- 1 | iaibdegahcif 2 | iaibdegahicf 3 | iaibdegaihcf 4 | iaibdfahcieg 5 | iaibdfahgcie 6 | iaibdfgahiec 7 | iaibdgahicfe 8 | iaibdgaihcfe 9 | iaibdgeahicf 10 | iaibdgeaihcf 11 | iaibdgfahiec 12 | iaibefgaihcd 13 | iaibefgaihdc 14 | iaibefghacid 15 | iaibefghaidc 16 | iaibefhadicg 17 | iaibefhgaidc 18 | iaibegfhacid 19 | iaibeghaidcf 20 | iaibeghfaicd 21 | iaibeghfaidc 22 | iaibehgaidcf 23 | iaibfghiaecd 24 | iaibfghiaedc 25 | iaibfhigadec 26 | iaibfhigaedc 27 | iaibfihgaedc 28 | iaicdehgibaf 29 | iaicegfhaibd 30 | iaicegibhadf 31 | iaicegibhdaf 32 | iaicegihadbf 33 | iaicfghiabed 34 | iaicfghibaed 35 | iaicfgihabed 36 | iaicfgihbaed 37 | iaichgfbaied 38 | iaidfghiabce 39 | iaidfghiacbe 40 | iaidfhgibace 41 | iaiefghiabcd 42 | ibbgcdeghiabf 43 | ibbgcdfghiabe 44 | ibbgcdfhgieab 45 | ibbgceafhbidg 46 | ibbgceagbhdif 47 | ibbgceagbhidf 48 | ibbgceagbihdf 49 | ibbgceahfbidg 50 | ibbgcefghiadb 51 | ibbgcefhgiadb 52 | ibbgcfaghbeid 53 | ibbgcfaghbide 54 | ibbgcfaghbied 55 | ibbgcfaghibde 56 | ibbgcfaghibed 57 | ibbgcfahgbeid 58 | ibbgcfahigbed 59 | ibbgcfaihgbed 60 | ibbgcfegaihdb 61 | ibcfdefcghiab 62 | ibcfdefgahibc 63 | ibcfdefgahicb 64 | ibcfdegachbif 65 | ibcfdegachibf 66 | ibcfdegacihbf 67 | ibcfdegaibhcf 68 | ibcfdegaichbf 69 | ibcfdegcahbif 70 | ibcfdegcahibf 71 | ibcfdegcaihbf 72 | ibcfdegchbiaf 73 | ibcfdfhagbice 74 | ibcfdfhaibecg 75 | ibdeefghadbic 76 | ibdeefghadicb 77 | ibdeefghaibcd 78 | ibdeefghaidcb 79 | ibdeefghbaicd 80 | ibdeefghcabid 81 | ibdeefhgdaicb 82 | ibdeefigcahdb 83 | ibdeefigchbda 84 | icbbeceagbhdif 85 | icbbeceagbhidf 86 | icbbeceagbihdf 87 | icbcdcdfgihabe 88 | icbcdcfaghbeid 89 | icbcdcfaghbide 90 | icbcdcfaghbied 91 | icbcdcfaghebid 92 | icbcdcfgiadheb 93 | icbdcceagbhdif 94 | icbebcdhfiabeg 95 | icbebceafhbidg 96 | idbbbcceagbhdif 97 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_09n: -------------------------------------------------------------------------------- 1 | iaibdeGaHCIF 2 | iaibdeGahCif 3 | iaibdegaHcIF 4 | iaibdeGaHICF 5 | iaibeGFHaCID 6 | iaibeGFhaCid 7 | iaicdehgIbaF 8 | iaicEGfHAiBD 9 | ibbgcDEgHIAbF 10 | ibbgcDEgHIaBF 11 | ibbgcdEgHIabF 12 | ibbgcDFgHIAbE 13 | ibbgcDFgHIaBE 14 | ibbgcdFgHIabE 15 | ibbgcDFhGIEAb 16 | ibbgcdFhGIEab 17 | ibbgceaGbHDIF 18 | ibbgceaGbhDif 19 | ibbgceagbHdIF 20 | ibbgceaGbHIDF 21 | ibcfdEFcGHIAB 22 | ibcfdEFcgHiAB 23 | ibcfdEfcGhIaB 24 | ibcfdEfcgHiaB 25 | ibcfdeFGahIbC 26 | ibdeefiGcaHDb 27 | ibdeeFiGchBDa 28 | icbbecEaGBHDIF 29 | icbbecEaGBhDif 30 | icbbeceagbHdIF 31 | icbcdcDFgIHAbE 32 | icbcdcDFgIHaBE 33 | icbcdcdFgIHabE 34 | icbdcceaGbHDIF 35 | icbebcdHfIabEG 36 | icbebcdHfiabeG 37 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_10a: -------------------------------------------------------------------------------- 1 | jajbdegahicjf 2 | jajbdegaicjfh 3 | jajbdegaihcjf 4 | jajbdehaijcgf 5 | jajbdehajicgf 6 | jajbdfagicjeh 7 | jajbdfahciejg 8 | jajbdfahcijeg 9 | jajbdfahcjieg 10 | jajbdfaigcjeh 11 | jajbdfgahjiec 12 | jajbdfiahjceg 13 | jajbdgahicjef 14 | jajbdgahicjfe 15 | jajbdgahijcef 16 | jajbdgahijcfe 17 | jajbdgaihcfje 18 | jajbdgaijhcfe 19 | jajbdgajihcfe 20 | jajbdgeaicjfh 21 | jajbdgfahjiec 22 | jajbdheaijcgf 23 | jajbdheajicgf 24 | jajbdifahjceg 25 | jajbefghajidc 26 | jajbefgiacjdh 27 | jajbefgiahcjd 28 | jajbefhadijcg 29 | jajbefhadjicg 30 | jajbefhajcidg 31 | jajbefhajdicg 32 | jajbefhgajidc 33 | jajbefhiajcdg 34 | jajbefhiajdcg 35 | jajbefhjadicg 36 | jajbegfahijdc 37 | jajbegfiacjdh 38 | jajbegfiahcjd 39 | jajbeghadijfc 40 | jajbeghaidcjf 41 | jajbeghaijcdf 42 | jajbeghaijdcf 43 | jajbeghajicdf 44 | jajbeghajidcf 45 | jajbegiahcjdf 46 | jajbegiahdjfc 47 | jajbegiahjdfc 48 | jajbehfadijcg 49 | jajbehfadjicg 50 | jajbehgadijfc 51 | jajbehgaidcjf 52 | jajbehgajdicf 53 | jajbehifajdcg 54 | jajbeihfajdcg 55 | jajbfghiaejdc 56 | jajbfghiajcde 57 | jajbfghiajced 58 | jajbfghiajedc 59 | jajbfghijacde 60 | jajbfghijaced 61 | jajbfghijaedc 62 | jajbfghjiadce 63 | jajbfgihaejdc 64 | jajbfgihajedc 65 | jajbfgihjaedc 66 | jajbfhgiadjec 67 | jajbfhgiajced 68 | jajbfhigaejcd 69 | jajbfhigaejdc 70 | jajbfhijgaecd 71 | jajbfhijgaedc 72 | jajbfhjiadceg 73 | jajbfijghaedc 74 | jajbfijhgaedc 75 | jajbfjihgaedc 76 | jajcdeghijabf 77 | jajcdeghjiabf 78 | jajcdfahbijeg 79 | jajcdgahibjef 80 | jajcdgahibjfe 81 | jajcdgahijbef 82 | jajcdgahijbfe 83 | jajcdghbijaef 84 | jajcdghbijafe 85 | jajcdgihbjeaf 86 | jajcdhgbijaef 87 | jajcdhgbijafe 88 | jajcdighbjaef 89 | jajcefgihjabd 90 | jajcefjihdabg 91 | jajcegahijdbf 92 | jajcegahjidbf 93 | jajceghaibjdf 94 | jajceghbiajfd 95 | jajceghibjadf 96 | jajcegiahjbdf 97 | jajcegihbjadf 98 | jajcehgaidjbf 99 | jajcehgibjafd 100 | jajcehjgaibdf 101 | jajcehjgbiafd 102 | jajceifbhjdag 103 | jajceigahjdbf 104 | jajceighbjdaf 105 | jajceihgbjdaf 106 | jajcejghibdaf 107 | jajcfghiabjde 108 | jajcfghiabjed 109 | jajcfghibajed 110 | jajcfghijbade 111 | jajcfghijbaed 112 | jajcfgijhbaed 113 | jajcfgjihbaed 114 | jajcgfhijbade 115 | jajcgfhijbaed 116 | jajcgfijhbaed 117 | jajcgfjihbaed 118 | jajchfgibjade 119 | jajchfgibjaed 120 | jajchigabjdef 121 | jajdefghijabc 122 | jajdeghaijcbf 123 | jajdehgaijcbf 124 | jbbhcdeghiabjf 125 | jbbhcdehgijabf 126 | jbbhcdehgjiabf 127 | jbbhcdfghiabje 128 | jbbhcdfighjeab 129 | jbbhcdfigjheab 130 | jbbhcdfihgjeab 131 | jbbhceafhbidjg 132 | jbbhceafhbijdg 133 | jbbhceafhbjidg 134 | jbbhceagbhidjf 135 | jbbhceagbidjfh 136 | jbbhceagbihdjf 137 | jbbhceaghbijfd 138 | jbbhceahbijdgf 139 | jbbhceahbjidgf 140 | jbbhceahfbidjg 141 | jbbhceahfbijdg 142 | jbbhceahfbjidg 143 | jbbhceahgbijfd 144 | jbbhcefghjaidb 145 | jbbhcefhgjaidb 146 | jbbhcefhigjadb 147 | jbbhcefihgjadb 148 | jbbhcfaghbjide 149 | jbbhcfaghbjied 150 | jbbhcfaghibdje 151 | jbbhcfaghibjed 152 | jbbhcfaghjbied 153 | jbbhcfagibejdh 154 | jbbhcfagihbjed 155 | jbbhcfahgibdje 156 | jbbhcfahibjedg 157 | jbbhcfahigbejd 158 | jbbhcfahigbjde 159 | jbbhcfahigbjed 160 | jbbhcfaigbejdh 161 | jbbhcfaigbhejd 162 | jbbhcfaighbejd 163 | jbbhcfaihbjedg 164 | jbbhcfaihgbejd 165 | jbbhcfehajidgb 166 | jbbhcfigajhdbe 167 | jbbhcgahijbfde 168 | jbbhcgahijbfed 169 | jbbhcgaijhbefd 170 | jbbhcgaijhbfed 171 | jbbhcgajihbfed 172 | jbbhcgehaijdbf 173 | jbbhcgehajidbf 174 | jbcgdefajhibcg 175 | jbcgdefajhicbg 176 | jbcgdefcihjbag 177 | jbcgdefgaihjbc 178 | jbcgdefgaihjcb 179 | jbcgdefhgjiacb 180 | jbcgdegachibjf 181 | jbcgdegacibjfh 182 | jbcgdegacihbjf 183 | jbcgdegajbicfh 184 | jbcgdegajcibfh 185 | jbcgdegajhibfc 186 | jbcgdegajhicfb 187 | jbcgdegajihbfc 188 | jbcgdegajihcfb 189 | jbcgdegcahibjf 190 | jbcgdegcaibjfh 191 | jbcgdegcaihbjf 192 | jbcgdegchbiajf 193 | jbcgdegfihcjab 194 | jbcgdeghijcfab 195 | jbcgdehacijbgf 196 | jbcgdehacjibgf 197 | jbcgdehcaijbgf 198 | jbcgdehcajibgf 199 | jbcgdehcgiajfb 200 | jbcgdehgaibjfc 201 | jbcgdehgaicjfb 202 | jbcgdfhagbjice 203 | jbcgdfhaibjecg 204 | jbcgdfhaicjbeg 205 | jbcgdfhajbeicg 206 | jbcgdfhajcibge 207 | jbcgdfhbgjaice 208 | jbcgdfhbiajcge 209 | jbcgdfhbijaecg 210 | jbcgdfhcjaibge 211 | jbdfefghadjicb 212 | jbdfefghajbicd 213 | jbdfefghajbidc 214 | jbdfefghajdicb 215 | jbdfefghajicbd 216 | jbdfefghajicdb 217 | jbdfefgiadbjch 218 | jbdfefgiadhbjc 219 | jbdfefgibadjch 220 | jbdfefgicabjdh 221 | jbdfefgidabjch 222 | jbdfefhgajicbd 223 | jbdfefhiadjbcg 224 | jbdfefhiadjcbg 225 | jbdfefhidajbcg 226 | jbdfefigajcdbh 227 | jbdfefigdhcajb 228 | jbdfefighacdjb 229 | jbdfefjgdihcab 230 | jbdfegjhaidbfc 231 | jbeefcehbaidjg 232 | jbeefcehbaijdg 233 | jbeefdehbaijcg 234 | jbeefdghicejab 235 | jbeefdgihecjab 236 | jbeefdgjhaibec 237 | jbeefghijaebcd 238 | jbeefghijaebdc 239 | jbeefghijaedcb 240 | jbeefghijbaecd 241 | jbeefghijeabcd 242 | jbeefghjiaecbd 243 | jbeefghjicabed 244 | jbeefhjgiacebd 245 | jcbbfceagbhidjf 246 | jcbbfceagbidjfh 247 | jcbbfceagbihdjf 248 | jcbbfceahbijdgf 249 | jcbbfceahbjidgf 250 | jcbcecdfgihabje 251 | jcbcecfaghbjide 252 | jcbcecfaghbjied 253 | jcbcecfagibejdh 254 | jcbcecfagiebjdh 255 | jcbcecfahibjedg 256 | jcbcecfahigbjde 257 | jcbcecfahjibdge 258 | jcbcecfgiahebjd 259 | jcbcecfgjaihebd 260 | jcbddcdghijeabf 261 | jcbddcdghijfabe 262 | jcbddceagbidjfh 263 | jcbddceghijfadb 264 | jcbddcegihjfadb 265 | jcbddcgahijbfde 266 | jcbddcgahijbfed 267 | jcbddcgahijebdf 268 | jcbddcgahijfbde 269 | jcbddcgaihjebdf 270 | jcbddcghijadfbe 271 | jcbddcghijaefbd 272 | jcbeccdhfiabgje 273 | jcbecceafhbidjg 274 | jcbecceaghbidjf 275 | jcbecceahbijdgf 276 | jcbecceahbijgdf 277 | jcbfbceagbidjfh 278 | jcbfbcfaigbjdeh 279 | jcccddeghijbfca 280 | jcccddeghjibcfa 281 | jcccddeghjicbfa 282 | jcccddghaijcbfe 283 | jcccddghaijebcf 284 | jcccddghaijfbce 285 | jcccddghbijafce 286 | jcccddghijbaefc 287 | jcccddgiahjbfce 288 | jdbbbdceagbidjfh 289 | jdbbccceahbijdgf 290 | jdbbccceahbijgdf 291 | jdbbdbceagbidjfh 292 | jdbcbccdfhgijabe 293 | jdbcbccdfhiejabg 294 | jdbccbcfagibejdh 295 | jdbccbcfagiebjdh 296 | jdbccbcfaigbjdeh 297 | jebbbbbceagbidjfh 298 | -------------------------------------------------------------------------------- /mtlinks/hyperbolic_data_10n: -------------------------------------------------------------------------------- 1 | jajbdeGaHICJF 2 | jajbdeGahiCjf 3 | jajbdeGaICJFH 4 | jajbdFaGICJEH 5 | jajbdFagiCjeh 6 | jajbdfaGIcJEH 7 | jajbdFaHCIEJG 8 | jajbdFahCiejg 9 | jajbdfaHcIEJG 10 | jajbdFaHCIJEG 11 | jajbdFahCijeg 12 | jajbdfaHcIJEG 13 | jajbdFaHCJIEG 14 | jajbdFIaHJCEG 15 | jajbdGaHICJEF 16 | jajbdGahiCjef 17 | jajbdgaHIcJEF 18 | jajbdGaHICJFE 19 | jajbdGahiCjfe 20 | jajbdgaHIcJFE 21 | jajbdGaHIJCEF 22 | jajbdGaHIJCFE 23 | jajbdIFaHJCEG 24 | jajbeGfahiJdC 25 | jajbeGHaIDCJF 26 | jajbeGHaiDCjf 27 | jajbeGHaIJCDF 28 | jajbeGHaIJDCF 29 | jajbeGHaijDCf 30 | jajbeghaIJdcF 31 | jajbfHGIaDJEC 32 | jajbfHgIadJEC 33 | jajbfhGiaDjec 34 | jajcdeghIJabF 35 | jajcdeghJIabF 36 | jajcdfaHbIJEG 37 | jajcdgihbJeaF 38 | jajcEFgIHjABD 39 | jajceghibJadF 40 | jajcegihbJadF 41 | jajcEHgAIdjBF 42 | jajcEIgAHjdBf 43 | jbbhcDEgHIAbJF 44 | jbbhcDEgHIaBJF 45 | jbbhcdEgHIabJF 46 | jbbhcDEhGIJAbF 47 | jbbhcDEhGIJaBF 48 | jbbhcdEhGIJabF 49 | jbbhcDEhGJIAbF 50 | jbbhcDEhGJIaBF 51 | jbbhcdEhGJIabF 52 | jbbhcDFgHIAbJE 53 | jbbhcDFgHIaBJE 54 | jbbhcdFgHIabJE 55 | jbbhcDFiGHJEAb 56 | jbbhcdFiGHJEab 57 | jbbhcdFighJeab 58 | jbbhcdfiGHjEab 59 | jbbhcDFiGJHEAb 60 | jbbhcdFiGJHEab 61 | jbbhcDFiHGJEAb 62 | jbbhcdFiHGJEab 63 | jbbhceafHbIDJG 64 | jbbhceafHbiDjg 65 | jbbhceafhbIdJG 66 | jbbhceafHbIJDG 67 | jbbhceaGbHIDJF 68 | jbbhceaGbhiDjf 69 | jbbhceagbHIdJF 70 | jbbhceaGbIDJFH 71 | jbbhcEaGHBIJFD 72 | jbbhcEaHGBIJFD 73 | jbbhcEFihGJAdb 74 | jbbhcfaHGIbDJE 75 | jbbhcfaHGibDje 76 | jbbhcfahgIbdJE 77 | jbbhcFaIGBHEJD 78 | jbbhcFaIgBheJD 79 | jbbhcfaIGbHEJD 80 | jbbhcfaIgbheJD 81 | jbbhcfaIghbeJD 82 | jbcgdeFajHiBcg 83 | jbcgdeFajHibCg 84 | jbcgdeFajhIBcG 85 | jbcgdeFajhIbCG 86 | jbcgdEFcIHJBAG 87 | jbcgdEFciHjBAg 88 | jbcgdEfcIhJbAG 89 | jbcgdEfcIhjbAg 90 | jbcgdEfciHjBag 91 | jbcgdEfciHjbAg 92 | jbcgdefcihJbaG 93 | jbcgdeFgaIhjBc 94 | jbcgdEgfIhcjAb 95 | jbcgdfHaGbjICE 96 | jbdfefIgajcdBH 97 | jbdfeFIGdHCAJB 98 | jbdfefjGdiHCab 99 | jbdfeGjHaIDBFc 100 | jbeefCEHBaIDJG 101 | jbeefCEHBaiDjg 102 | jbeefCEhBaIdJG 103 | jbeefCEhBaidjg 104 | jbeefCEhBaijdg 105 | jbeefDGHICeJAB 106 | jbeefDghIcejAb 107 | jcbbfcEaGBHIDJF 108 | jcbbfcEaGBhiDjf 109 | jcbbfceagbHIdJF 110 | jcbcecDFgIHAbJE 111 | jcbcecDFgIHaBJE 112 | jcbcecdFgIHabJE 113 | jcbcecFaHJIBDGE 114 | jcbcecfaHJIbDGE 115 | jcbcecfaHjibDGe 116 | jcbddcDGhIJEAbF 117 | jcbddcDGhIJEaBF 118 | jcbddcdGhIJEabF 119 | jcbddcDGhIJFAbE 120 | jcbddcDGhIJFaBE 121 | jcbddcdGhIJFabE 122 | jcbddceaGbIDJFH 123 | jcbddcEGhiJFadB 124 | jcbddcgaIHJEbDF 125 | jcbeccdHfIabGJE 126 | jcbecceaHbIJDGF 127 | jcbecceaHbijDgf 128 | jcbecceahbIJdGF 129 | jcbecceaHbIJGDF 130 | jcbfbceaGbIDJFH 131 | jcbfbceaGbiDjfh 132 | jcbfbcFaIGBJDEH 133 | jcbfbcfaIGbJDEH 134 | jcccddEGHiJBFCa 135 | jcccddEGhIjBfCa 136 | jcccddEgHiJbFcA 137 | jcccddEghJibcfA 138 | jdbbcccEaHBIJDGF 139 | jdbbcccEaHBijDgf 140 | jdbbccceahbIJdGF 141 | jdbbdbcEaGBIDJFH 142 | jdbbdbcEaGBIDjFh 143 | jdbbdbcEaGBiDjfh 144 | jdbbdbceagbIdJFH 145 | jdbbdbceagbIdjFh 146 | jdbcbccDFHgIjAbE 147 | jdbcbccDFHgIjaBE 148 | jdbcbccDFhGIJAbE 149 | jdbcbccdFhGIJabE 150 | jdbcbccDFhIEJAbG 151 | jdbcbccDFhIEJaBG 152 | jdbccbcFaIGBJDEH 153 | jdbccbcfaIGbJDEH 154 | jebbbbbcEaGBIDJFH 155 | jebbbbbcEaGBIDjFh 156 | -------------------------------------------------------------------------------- /mutant_knot_groups/dat11: -------------------------------------------------------------------------------- 1 | 440 441 2 | 401 409 3 | 443 445 4 | 518 519 5 | 406 412 6 | 438 442 7 | 408 414 8 | 403 411 9 | 57 231 10 | 407 413 11 | 44 47 12 | 402 410 13 | 252 254 14 | 251 253 15 | 19 25 16 | 24 26 17 | -------------------------------------------------------------------------------- /mutant_knot_groups/dat12: -------------------------------------------------------------------------------- 1 | 1344 1345 1509 2 | 1498 1502 3 | 1377 1422 4 | 1347 1508 5 | 1958 1969 6 | 1355 1517 7 | 1381 1426 8 | 1351 1513 9 | 1311 1319 10 | 1979 1980 11 | 1412 1417 12 | 1495 1516 13 | 1352 1549 14 | 1981 1984 15 | 1519 1520 16 | 1841 1844 17 | 1373 1418 18 | 1316 1322 19 | 1378 1423 20 | 1350 1354 1512 21 | 1544 1552 22 | 1379 1424 23 | 1493 1514 24 | 1375 1420 25 | 1959 1970 26 | 1348 1349 1507 27 | 167 692 28 | 1343 1511 29 | 1496 1500 30 | 1540 1550 31 | 195 693 32 | 1380 1425 33 | 1386 1413 34 | 1374 1419 35 | 1652 1653 36 | 1314 1320 37 | 1410 1415 38 | 1346 1510 39 | 164 166 40 | 811 817 41 | 36 694 42 | 1709 1710 43 | 1494 1515 44 | 1376 1421 45 | 1309 1317 46 | 116 122 182 47 | 1315 1321 48 | 1497 1501 49 | 30 33 157 50 | 1543 1551 51 | 1310 1318 52 | 1387 1414 53 | 45 65 54 | 1411 1416 55 | 114 117 56 | 829 832 57 | 639 680 58 | 29 113 59 | 675 688 60 | 830 831 61 | 91 111 62 | 844 846 63 | 44 64 64 | 67 136 65 | 134 188 66 | 108 120 67 | 101 115 68 | 131 133 69 | 126 132 70 | 102 107 71 | 7 14 72 | 13 15 73 | 154 162 74 | 59 63 75 | 48 60 76 | -------------------------------------------------------------------------------- /nonalternating: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cseed/knotkit/4fdd08f1d1db7b2e64dd8f186d32c8381db79b0f/nonalternating -------------------------------------------------------------------------------- /parallel.cmd: -------------------------------------------------------------------------------- 1 | # mpi job, runtime max 5days 2 | #PBS -l nodes=3:ppn=4,walltime=150:00:00 3 | # xxx PBS -l mem=80gb 4 | # 5 | # sends mail if the process aborts, when it begins, and 6 | # when it ends (abe) 7 | #PBS -m abe 8 | # 9 | module load openmpi/gcc 10 | # go to the directory with the program 11 | cd $HOME/src/knotkit 12 | 13 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/u/cseed/llvm-3.1/lib 14 | export LD_LIBRARY_PATH 15 | 16 | echo $LD_LIBRARY_PATH 17 | 18 | # and run it 19 | numprocs=`wc -l <${PBS_NODEFILE}` 20 | mpiexec -np $numprocs ./mpimain 21 | -------------------------------------------------------------------------------- /planar_diagram.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | planar_diagram::planar_diagram (const std::string &name_, unsigned n_crossings, const int crossings_ar[][4]) 5 | : name(name_), 6 | crossings(n_crossings) 7 | { 8 | for (unsigned i = 1; i <= n_crossings; i ++) 9 | { 10 | for (unsigned j = 1; j <= 4; j ++) 11 | crossings[i].append (crossings_ar[i - 1][j - 1]); 12 | } 13 | } 14 | 15 | planar_diagram::planar_diagram (const knot_diagram &kd) 16 | : name(kd.name), 17 | crossings(kd.planar_diagram_crossings ()) 18 | { 19 | } 20 | 21 | void 22 | planar_diagram::show_knottheory () const 23 | { 24 | printf ("PD["); 25 | for (unsigned i = 1; i <= crossings.size (); i ++) 26 | { 27 | if (i > 1) 28 | printf (","); 29 | printf ("X[%d,%d,%d,%d]", 30 | crossings[i][1], 31 | crossings[i][2], 32 | crossings[i][3], 33 | crossings[i][4]); 34 | } 35 | printf ("]"); 36 | } 37 | 38 | void 39 | planar_diagram::display_self () const 40 | { 41 | printf ("planar_diagram %s ", name.c_str ()); 42 | for (unsigned i = 1; i <= crossings.size (); i ++) 43 | { 44 | int i1 = crossings[i][1], 45 | i2 = crossings[i][2], 46 | i3 = crossings[i][3], 47 | i4 = crossings[i][4]; 48 | 49 | if (i1 >= 10 || i2 >= 10 || i3 >= 10 || i4 >= 10) 50 | printf ("X_%d,%d,%d,%d", i1, i2, i3, i4); 51 | else 52 | printf ("X_%d%d%d%d", i1, i2, i3, i4); 53 | } 54 | printf ("\n"); 55 | } 56 | -------------------------------------------------------------------------------- /planar_diagram.h: -------------------------------------------------------------------------------- 1 | 2 | /* Planar diagram of a knot. For details, see: 3 | http://katlas.org/wiki/Planar_Diagrams */ 4 | 5 | class planar_diagram 6 | { 7 | public: 8 | std::string name; 9 | basedvector, 1> crossings; 10 | 11 | public: 12 | planar_diagram () { } 13 | planar_diagram (const std::string &name, unsigned n_crossings, const int crossings_ar[][4]); 14 | planar_diagram (const std::string &name_, const basedvector, 1> &crossings_) 15 | : name(name_), crossings(crossings_) 16 | { } 17 | planar_diagram (const knot_diagram &kd); 18 | planar_diagram (const planar_diagram &pd) 19 | : name(pd.name), 20 | crossings(pd.crossings) 21 | { } 22 | ~planar_diagram () { } 23 | 24 | void show_knottheory () const; 25 | void display_knottheory () const { show_knottheory (); newline (); } 26 | 27 | void show_self () const { printf ("planar_diagram %s", name.c_str ()); } 28 | void display_self () const; 29 | }; 30 | -------------------------------------------------------------------------------- /rd_parser/location.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Locations for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file rd_parser/location.hh 35 | ** Define the yy::location class. 36 | */ 37 | 38 | #ifndef YY_YY_RD_PARSER_LOCATION_HH_INCLUDED 39 | # define YY_YY_RD_PARSER_LOCATION_HH_INCLUDED 40 | 41 | # include "position.hh" 42 | 43 | 44 | namespace yy { 45 | /* Line 166 of location.cc */ 46 | #line 47 "rd_parser/location.hh" 47 | 48 | /// Abstract a location. 49 | class location 50 | { 51 | public: 52 | 53 | /// Construct a location from \a b to \a e. 54 | location (const position& b, const position& e) 55 | : begin (b) 56 | , end (e) 57 | { 58 | } 59 | 60 | /// Construct a 0-width location in \a p. 61 | explicit location (const position& p = position ()) 62 | : begin (p) 63 | , end (p) 64 | { 65 | } 66 | 67 | /// Construct a 0-width location in \a f, \a l, \a c. 68 | explicit location (std::string* f, 69 | unsigned int l = 1u, 70 | unsigned int c = 1u) 71 | : begin (f, l, c) 72 | , end (f, l, c) 73 | { 74 | } 75 | 76 | 77 | /// Initialization. 78 | void initialize (std::string* f = YY_NULL, 79 | unsigned int l = 1u, 80 | unsigned int c = 1u) 81 | { 82 | begin.initialize (f, l, c); 83 | end = begin; 84 | } 85 | 86 | /** \name Line and Column related manipulators 87 | ** \{ */ 88 | public: 89 | /// Reset initial location to final location. 90 | void step () 91 | { 92 | begin = end; 93 | } 94 | 95 | /// Extend the current location to the COUNT next columns. 96 | void columns (unsigned int count = 1) 97 | { 98 | end += count; 99 | } 100 | 101 | /// Extend the current location to the COUNT next lines. 102 | void lines (unsigned int count = 1) 103 | { 104 | end.lines (count); 105 | } 106 | /** \} */ 107 | 108 | 109 | public: 110 | /// Beginning of the located region. 111 | position begin; 112 | /// End of the located region. 113 | position end; 114 | }; 115 | 116 | /// Join two location objects to create a location. 117 | inline const location operator+ (const location& begin, const location& end) 118 | { 119 | location res = begin; 120 | res.end = end.end; 121 | return res; 122 | } 123 | 124 | /// Add two location objects. 125 | inline const location operator+ (const location& begin, unsigned int width) 126 | { 127 | location res = begin; 128 | res.columns (width); 129 | return res; 130 | } 131 | 132 | /// Add and assign a location. 133 | inline location& operator+= (location& res, unsigned int width) 134 | { 135 | res.columns (width); 136 | return res; 137 | } 138 | 139 | /// Compare two location objects. 140 | inline bool 141 | operator== (const location& loc1, const location& loc2) 142 | { 143 | return loc1.begin == loc2.begin && loc1.end == loc2.end; 144 | } 145 | 146 | /// Compare two location objects. 147 | inline bool 148 | operator!= (const location& loc1, const location& loc2) 149 | { 150 | return !(loc1 == loc2); 151 | } 152 | 153 | /** \brief Intercept output stream redirection. 154 | ** \param ostr the destination output stream 155 | ** \param loc a reference to the location to redirect 156 | ** 157 | ** Avoid duplicate information. 158 | */ 159 | template 160 | inline std::basic_ostream& 161 | operator<< (std::basic_ostream& ostr, const location& loc) 162 | { 163 | position last = loc.end - 1; 164 | ostr << loc.begin; 165 | if (last.filename 166 | && (!loc.begin.filename 167 | || *loc.begin.filename != *last.filename)) 168 | ostr << '-' << last; 169 | else if (loc.begin.line != last.line) 170 | ostr << '-' << last.line << '.' << last.column; 171 | else if (loc.begin.column != last.column) 172 | ostr << '-' << last.column; 173 | return ostr; 174 | } 175 | 176 | 177 | } // yy 178 | /* Line 296 of location.cc */ 179 | #line 180 "rd_parser/location.hh" 180 | 181 | #endif /* !YY_YY_RD_PARSER_LOCATION_HH_INCLUDED */ 182 | -------------------------------------------------------------------------------- /rd_parser/position.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Positions for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file rd_parser/position.hh 35 | ** Define the yy::position class. 36 | */ 37 | 38 | #ifndef YY_YY_RD_PARSER_POSITION_HH_INCLUDED 39 | # define YY_YY_RD_PARSER_POSITION_HH_INCLUDED 40 | 41 | # include // std::max 42 | # include 43 | # include 44 | 45 | # ifndef YY_NULL 46 | # if defined __cplusplus && 201103L <= __cplusplus 47 | # define YY_NULL nullptr 48 | # else 49 | # define YY_NULL 0 50 | # endif 51 | # endif 52 | 53 | 54 | namespace yy { 55 | /* Line 36 of location.cc */ 56 | #line 57 "rd_parser/position.hh" 57 | /// Abstract a position. 58 | class position 59 | { 60 | public: 61 | 62 | /// Construct a position. 63 | explicit position (std::string* f = YY_NULL, 64 | unsigned int l = 1u, 65 | unsigned int c = 1u) 66 | : filename (f) 67 | , line (l) 68 | , column (c) 69 | { 70 | } 71 | 72 | 73 | /// Initialization. 74 | void initialize (std::string* fn = YY_NULL, 75 | unsigned int l = 1u, 76 | unsigned int c = 1u) 77 | { 78 | filename = fn; 79 | line = l; 80 | column = c; 81 | } 82 | 83 | /** \name Line and Column related manipulators 84 | ** \{ */ 85 | /// (line related) Advance to the COUNT next lines. 86 | void lines (int count = 1) 87 | { 88 | column = 1u; 89 | line += count; 90 | } 91 | 92 | /// (column related) Advance to the COUNT next columns. 93 | void columns (int count = 1) 94 | { 95 | column = std::max (1u, column + count); 96 | } 97 | /** \} */ 98 | 99 | /// File name to which this position refers. 100 | std::string* filename; 101 | /// Current line number. 102 | unsigned int line; 103 | /// Current column number. 104 | unsigned int column; 105 | }; 106 | 107 | /// Add and assign a position. 108 | inline position& 109 | operator+= (position& res, const int width) 110 | { 111 | res.columns (width); 112 | return res; 113 | } 114 | 115 | /// Add two position objects. 116 | inline const position 117 | operator+ (const position& begin, const int width) 118 | { 119 | position res = begin; 120 | return res += width; 121 | } 122 | 123 | /// Add and assign a position. 124 | inline position& 125 | operator-= (position& res, const int width) 126 | { 127 | return res += -width; 128 | } 129 | 130 | /// Add two position objects. 131 | inline const position 132 | operator- (const position& begin, const int width) 133 | { 134 | return begin + -width; 135 | } 136 | 137 | /// Compare two position objects. 138 | inline bool 139 | operator== (const position& pos1, const position& pos2) 140 | { 141 | return (pos1.line == pos2.line 142 | && pos1.column == pos2.column 143 | && (pos1.filename == pos2.filename 144 | || (pos1.filename && pos2.filename 145 | && *pos1.filename == *pos2.filename))); 146 | } 147 | 148 | /// Compare two position objects. 149 | inline bool 150 | operator!= (const position& pos1, const position& pos2) 151 | { 152 | return !(pos1 == pos2); 153 | } 154 | 155 | /** \brief Intercept output stream redirection. 156 | ** \param ostr the destination output stream 157 | ** \param pos a reference to the position to redirect 158 | */ 159 | template 160 | inline std::basic_ostream& 161 | operator<< (std::basic_ostream& ostr, const position& pos) 162 | { 163 | if (pos.filename) 164 | ostr << *pos.filename << ':'; 165 | return ostr << pos.line << '.' << pos.column; 166 | } 167 | 168 | 169 | } // yy 170 | /* Line 148 of location.cc */ 171 | #line 172 "rd_parser/position.hh" 172 | #endif /* !YY_YY_RD_PARSER_POSITION_HH_INCLUDED */ 173 | -------------------------------------------------------------------------------- /rd_parser/rd_parser.yy: -------------------------------------------------------------------------------- 1 | 2 | %skeleton "lalr1.cc" 3 | %require "2.4.3" 4 | %defines 5 | %define parser_class_name "rd_parser" 6 | 7 | %parse-param { resolution_diagram &parsed_rd } 8 | 9 | // %no-lines 10 | 11 | %code requires { 12 | #include 13 | } 14 | 15 | %code{ 16 | #define YY_DECL \ 17 | yy::rd_parser::token_type rd_yylex (yy::rd_parser::semantic_type *yylval) 18 | YY_DECL; 19 | 20 | #define CPT_MASK 0x0ffff 21 | #define CPT_MARKED 0x10000 22 | #define CPT_MARKED2 0x20000 23 | } 24 | 25 | %union { 26 | int integer; 27 | int cpt; 28 | bool inside; 29 | basedvector *cpt_vec; 30 | } 31 | 32 | %code { 33 | #define yylex rd_yylex 34 | } 35 | 36 | %token INT 37 | 38 | %token END 0 "end of file" 39 | 40 | %token H T 41 | %token IN OUT 42 | 43 | %type crossing_point_spec crossing_point_1 crossing_point 44 | %type inout 45 | 46 | %type crossing_points 47 | 48 | %% 49 | 50 | %start resolution_diagram; 51 | 52 | resolution_diagram: 53 | INT 54 | { 55 | unsigned n_crossings = $1; 56 | parsed_rd.n_crossings = n_crossings; 57 | 58 | unsigned n_cpts = parsed_rd.num_cpts (); 59 | 60 | parsed_rd.resolved = smallbitset (n_crossings, 0); 61 | parsed_rd.to_resolve = smallbitset (n_crossings, ~0); 62 | parsed_rd.cpt_inside = smallbitset (n_cpts, 0); 63 | 64 | parsed_rd.prev = basedvector (n_cpts); 65 | parsed_rd.next = basedvector (n_cpts); 66 | parsed_rd.cpt_starting_circle = basedvector (n_cpts); 67 | parsed_rd.cpt_ending_circle = basedvector (n_cpts); 68 | 69 | for (unsigned i = 1; i <= n_cpts; i ++) 70 | { 71 | parsed_rd.prev[i] 72 | = parsed_rd.next[i] 73 | = parsed_rd.cpt_starting_circle[i] 74 | = parsed_rd.cpt_ending_circle[i] 75 | = 0; 76 | } 77 | } 78 | ',' starting_circles dual_crossings_opt 79 | ; 80 | 81 | starting_circles: 82 | starting_circle 83 | | starting_circles starting_circle 84 | ; 85 | 86 | starting_circle: 87 | '(' crossing_points ')' 88 | { 89 | unsigned s = ++ parsed_rd.n_starting_circles; 90 | 91 | const basedvector &v = *$2; 92 | unsigned n = v.size (); 93 | unsigned p = v[n] & CPT_MASK; 94 | for (unsigned i = 1; i <= n; i ++) 95 | { 96 | unsigned c = v[i] & CPT_MASK; 97 | 98 | parsed_rd.next[p] = c; 99 | parsed_rd.prev[c] = p; 100 | parsed_rd.cpt_starting_circle[c] = s; 101 | p = c; 102 | 103 | if (v[i] & CPT_MARKED) 104 | parsed_rd.marked_edge = c; 105 | if (v[i] & CPT_MARKED2) 106 | parsed_rd.marked_edge2 = c; 107 | } 108 | } 109 | ; 110 | 111 | dual_crossings_opt: 112 | /* empty */ 113 | | ',' dual_crossings 114 | 115 | dual_crossings: 116 | dual_crossing 117 | | dual_crossing ',' dual_crossings 118 | ; 119 | 120 | dual_crossing: 121 | INT '|' INT 122 | ; 123 | 124 | crossing_points: 125 | crossing_point 126 | { 127 | basedvector *v = 128 | new basedvector (); 129 | v->append ($1); 130 | $$ = v; 131 | } 132 | | crossing_points ',' crossing_point 133 | { 134 | basedvector *v = $1; 135 | v->append ($3); 136 | $$ = v; 137 | } 138 | ; 139 | 140 | crossing_point: 141 | crossing_point_1 142 | | crossing_point_1 '*' 143 | { $$ = $1 | CPT_MARKED; } 144 | | crossing_point_1 '+' 145 | { $$ = $1 | CPT_MARKED2; } 146 | | crossing_point_1 '+' '*' 147 | { $$ = $1 | CPT_MARKED | CPT_MARKED2; } 148 | | crossing_point_1 '*' '+' 149 | { $$ = $1 | CPT_MARKED | CPT_MARKED2; } 150 | ; 151 | 152 | crossing_point_1: 153 | crossing_point_spec inout 154 | { 155 | if ($2) 156 | parsed_rd.cpt_inside.push ($1); 157 | $$ = $1; 158 | } 159 | ; 160 | 161 | crossing_point_spec: 162 | H INT 163 | { $$ = parsed_rd.crossing_to_cpt ($2); } 164 | | T INT 165 | { $$ = parsed_rd.crossing_from_cpt ($2); } 166 | ; 167 | 168 | inout: 169 | IN 170 | | OUT 171 | ; 172 | 173 | %% 174 | 175 | void 176 | yy::rd_parser::error (const yy::rd_parser::location_type &l, 177 | const std::string &m) 178 | { 179 | fprintf (stderr, "rd_parser: parse error.\n"); 180 | exit (EXIT_FAILURE); 181 | } 182 | 183 | void rd_scan_string (const char *s); 184 | 185 | resolution_diagram 186 | parse_resolution_diagram (const char *s) 187 | { 188 | rd_scan_string (s); 189 | 190 | resolution_diagram rd; 191 | yy::rd_parser parser (rd); 192 | parser.parse (); 193 | 194 | return rd; 195 | } 196 | -------------------------------------------------------------------------------- /rd_parser/rd_scanner.ll: -------------------------------------------------------------------------------- 1 | 2 | %{ 3 | #include "rd_parser.hh" 4 | 5 | #define YY_DECL \ 6 | yy::rd_parser::token_type rd_yylex (yy::rd_parser::semantic_type *yylval) 7 | 8 | #define yyterminate() return token::END 9 | 10 | typedef yy::rd_parser::token token; 11 | typedef yy::rd_parser::token_type token_type; 12 | %} 13 | 14 | %option noyywrap nounput batch prefix="rd_yy" 15 | 16 | %% 17 | 18 | -?[0-9]+ { 19 | yylval->integer = atoi (yytext); 20 | return token::INT; 21 | } 22 | 23 | [a-zA-Z]+ { 24 | if (!strcmp (yytext, "h")) 25 | return token::H; 26 | else if (!strcmp (yytext, "t")) 27 | return token::T; 28 | else if (!strcmp (yytext, "in")) 29 | { 30 | yylval->inside = 1; 31 | return token::IN; 32 | } 33 | else if (!strcmp (yytext, "out")) 34 | { 35 | yylval->inside = 0; 36 | return token::OUT; 37 | } 38 | else 39 | { 40 | fprintf (stderr, "rd_parser: unknown identifier `%s'\n", yytext); 41 | exit (EXIT_FAILURE); 42 | } 43 | } 44 | 45 | [\t\r\n ] /* ignore */ 46 | 47 | . { return token_type (yytext[0]); } 48 | 49 | %% 50 | 51 | void 52 | rd_scan_string (const char *s) 53 | { 54 | rd_yy_scan_string (s); 55 | } 56 | -------------------------------------------------------------------------------- /rd_parser/stack.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.7. */ 2 | 3 | /* Stack handling for Bison parsers in C++ 4 | 5 | Copyright (C) 2002-2012 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | /** 34 | ** \file rd_parser/stack.hh 35 | ** Define the yy::stack class. 36 | */ 37 | 38 | #ifndef YY_YY_RD_PARSER_STACK_HH_INCLUDED 39 | # define YY_YY_RD_PARSER_STACK_HH_INCLUDED 40 | 41 | # include 42 | 43 | 44 | namespace yy { 45 | /* Line 34 of stack.hh */ 46 | #line 47 "rd_parser/stack.hh" 47 | template > 48 | class stack 49 | { 50 | public: 51 | // Hide our reversed order. 52 | typedef typename S::reverse_iterator iterator; 53 | typedef typename S::const_reverse_iterator const_iterator; 54 | 55 | stack () : seq_ () 56 | { 57 | } 58 | 59 | stack (unsigned int n) : seq_ (n) 60 | { 61 | } 62 | 63 | inline 64 | T& 65 | operator [] (unsigned int i) 66 | { 67 | return seq_[i]; 68 | } 69 | 70 | inline 71 | const T& 72 | operator [] (unsigned int i) const 73 | { 74 | return seq_[i]; 75 | } 76 | 77 | inline 78 | void 79 | push (const T& t) 80 | { 81 | seq_.push_front (t); 82 | } 83 | 84 | inline 85 | void 86 | pop (unsigned int n = 1) 87 | { 88 | for (; n; --n) 89 | seq_.pop_front (); 90 | } 91 | 92 | inline 93 | unsigned int 94 | height () const 95 | { 96 | return seq_.size (); 97 | } 98 | 99 | inline const_iterator begin () const { return seq_.rbegin (); } 100 | inline const_iterator end () const { return seq_.rend (); } 101 | 102 | private: 103 | S seq_; 104 | }; 105 | 106 | /// Present a slice of the top of a stack. 107 | template > 108 | class slice 109 | { 110 | public: 111 | slice (const S& stack, unsigned int range) 112 | : stack_ (stack) 113 | , range_ (range) 114 | { 115 | } 116 | 117 | inline 118 | const T& 119 | operator [] (unsigned int i) const 120 | { 121 | return stack_[range_ - i]; 122 | } 123 | 124 | private: 125 | const S& stack_; 126 | unsigned int range_; 127 | }; 128 | 129 | } // yy 130 | /* Line 116 of stack.hh */ 131 | #line 132 "rd_parser/stack.hh" 132 | 133 | #endif /* !YY_YY_RD_PARSER_STACK_HH_INCLUDED */ 134 | -------------------------------------------------------------------------------- /serial.cmd: -------------------------------------------------------------------------------- 1 | # serial job 2 | #PBS -l nodes=1:ppn=1,walltime=4:00:00 3 | # xxx PBS -l mem=80gb 4 | # 5 | # sends mail if the process aborts, when it begins, and 6 | # when it ends (abe) 7 | #PBS -m abe 8 | # 9 | # load intel compiler settings before running the program 10 | # since we compiled it with intel 10.1 11 | # module load intel/10.1 12 | # go to the directory with the program 13 | cd $HOME/src/knotkit 14 | # and run it 15 | LD_LIBRARY_PATH=/u/cseed/llvm-3.1/lib ./main 16 | -------------------------------------------------------------------------------- /simplify_chain_complex.h: -------------------------------------------------------------------------------- 1 | 2 | template class simplified_complex_generators 3 | { 4 | unsigned new_n; 5 | ptr > C; 6 | basedvector new_C_to_C_generator; 7 | 8 | public: 9 | simplified_complex_generators (const simplified_complex_generators &g) 10 | : new_n(g.new_n), 11 | C(g.C), 12 | new_C_to_C_generator(g.new_C_to_C_generator) 13 | { } 14 | simplified_complex_generators (unsigned new_n_, 15 | ptr > C_, 16 | basedvector new_C_to_C_generator_) 17 | : new_n(new_n_), 18 | C(C_), 19 | new_C_to_C_generator(new_C_to_C_generator_) 20 | { } 21 | ~simplified_complex_generators () { } 22 | 23 | simplified_complex_generators &operator = (const simplified_complex_generators &); // doesn't exist 24 | 25 | unsigned dim () const { return new_n; } 26 | unsigned free_rank () const { return new_n; } 27 | grading generator_grading (unsigned i) const { return C->generator_grading (new_C_to_C_generator[i]); } 28 | void show_generator (unsigned i) const { C->show_generator (new_C_to_C_generator[i]); } 29 | R generator_ann (unsigned i) const { abort (); } 30 | }; 31 | 32 | template 33 | class chain_complex_simplifier 34 | { 35 | public: 36 | ptr > C; 37 | unsigned n; // |C| 38 | mod_map d; 39 | 40 | ptr > new_C; 41 | mod_map new_d; 42 | 43 | // pi : C -> new_C 44 | mod_map pi; 45 | 46 | // iota : new_C -> C 47 | mod_map iota; 48 | 49 | private: 50 | set canceled; 51 | 52 | basedvector cancel_binv; 53 | basedvector cancel_j; 54 | basedvector, 1> cancel_di; 55 | 56 | basedvector, 1> new_d_columns; 57 | basedvector, 1> preim; 58 | 59 | basedvector, 1> iota_columns; 60 | 61 | void cancel (unsigned i, R b, unsigned j); 62 | 63 | public: 64 | chain_complex_simplifier (ptr > C_, 65 | const mod_map &d_, 66 | maybe dh, maybe dq); 67 | }; 68 | 69 | template void 70 | chain_complex_simplifier::cancel (unsigned i, R b, unsigned j) 71 | { 72 | assert (i != j); 73 | assert (b.is_unit ()); 74 | 75 | R binv = b.recip (); 76 | 77 | canceled.push (i); 78 | canceled.push (j); 79 | 80 | new_d_columns[i].yank (j); 81 | preim[j].yank (i); 82 | 83 | for (linear_combination_const_iter k = new_d_columns[i]; k; k ++) 84 | preim[k.key ()].yank (i); 85 | for (set_const_iter k = preim[i]; k; k ++) 86 | new_d_columns[k.val ()].yank (i); 87 | for (linear_combination_const_iter k = new_d_columns[j]; k; k ++) 88 | preim[k.key ()].yank (j); 89 | 90 | for (set_const_iter kk = preim[j]; kk; kk ++) 91 | { 92 | unsigned k = kk.val (); 93 | R a = new_d_columns[k](j); 94 | assert (a != 0); 95 | 96 | iota_columns[k].mulsub (a * binv, iota_columns[i]); 97 | } 98 | 99 | iota_columns[i].clear (); 100 | iota_columns[j].clear (); 101 | 102 | for (set_const_iter kk = preim[j]; kk; kk ++) 103 | { 104 | unsigned k = kk.val (); 105 | R a = new_d_columns[k](j); 106 | assert (a != 0); 107 | 108 | R abinv = a * binv; 109 | 110 | for (linear_combination_const_iter ll = new_d_columns[i]; ll; ll ++) 111 | { 112 | unsigned ell = ll.key (); 113 | R c = ll.val (); 114 | 115 | assert (! (canceled % k)); 116 | assert (! (canceled % ell)); 117 | assert (k != i); 118 | assert (k != j); 119 | assert (ell != i); 120 | assert (ell != j); 121 | assert (ell != k); 122 | 123 | new_d_columns[k].mulsub (abinv * c, ell); 124 | if (new_d_columns[k] % ell) 125 | preim[ell] += k; 126 | else 127 | preim[ell] -= k; 128 | } 129 | } 130 | 131 | for (set_const_iter k = preim[j]; k; k ++) 132 | new_d_columns[k.val ()].yank (j); 133 | 134 | cancel_binv.append (binv); 135 | cancel_j.append (j); 136 | cancel_di.append (new_d_columns[i]); 137 | 138 | new_d_columns[i] = linear_combination (); 139 | preim[i].clear (); 140 | new_d_columns[j].clear (); 141 | preim[j].clear (); 142 | } 143 | 144 | template 145 | chain_complex_simplifier::chain_complex_simplifier (ptr > C_, 146 | const mod_map &d_, 147 | maybe dh, maybe dq) 148 | : C(C_), n(C_->dim ()), d(d_), 149 | new_d_columns(n), 150 | preim(n), 151 | iota_columns(n) 152 | { 153 | for (unsigned i = 1; i <= n; i ++) 154 | { 155 | new_d_columns[i] = d.column_copy (i); 156 | 157 | for (linear_combination_const_iter j = new_d_columns[i]; j; j ++) 158 | preim[j.key ()].push (i); 159 | 160 | linear_combination x (C); 161 | x.muladd (1, i); 162 | iota_columns[i] = x; 163 | } 164 | 165 | for (unsigned i = n; i >= 1; i --) 166 | { 167 | if (canceled % i) 168 | continue; 169 | 170 | grading igr = C->generator_grading (i); 171 | for (linear_combination_const_iter j = new_d_columns[i]; j; j ++) 172 | { 173 | grading jgr = C->generator_grading (j.key ()); 174 | if (j.val ().is_unit () 175 | && (dh.is_none () 176 | || (jgr.h - igr.h == dh.some ())) 177 | && (dq.is_none () 178 | || (jgr.q - igr.q == dq.some ()))) 179 | { 180 | cancel (i, j.val (), j.key ()); 181 | break; 182 | } 183 | } 184 | } 185 | 186 | // ??? might not be completely simplified 187 | 188 | unsigned new_n = n - canceled.card (); 189 | basedvector new_C_to_C_generator (new_n), 190 | C_to_new_C_generator (n); 191 | for (unsigned i = 1, j = 1; i <= n; i ++) 192 | { 193 | if (canceled % i) 194 | { 195 | C_to_new_C_generator[i] = 0; 196 | continue; 197 | } 198 | 199 | C_to_new_C_generator[i] = j; 200 | new_C_to_C_generator[j] = i; 201 | j ++; 202 | } 203 | 204 | new_C = (new base_module > 205 | (simplified_complex_generators (new_n, C, new_C_to_C_generator))); 206 | map_builder db (new_C); 207 | 208 | for (unsigned i = 1; i <= new_n; i ++) 209 | { 210 | unsigned i0 = new_C_to_C_generator[i]; 211 | 212 | for (linear_combination_const_iter j0 = new_d_columns[i0]; j0; j0 ++) 213 | { 214 | unsigned j = C_to_new_C_generator[j0.key ()]; 215 | assert (j != 0); 216 | 217 | db[i].muladd (j0.val (), j); 218 | } 219 | } 220 | new_d = mod_map (db); 221 | 222 | map_builder iotab (new_C, C); 223 | 224 | for (unsigned i = 1; i <= new_n; i ++) 225 | iotab[i] = iota_columns[new_C_to_C_generator[i]]; 226 | iota = mod_map (iotab); 227 | 228 | map_builder pib (C, new_C); 229 | for (unsigned i = 1; i <= new_n; i ++) 230 | pib[new_C_to_C_generator[i]].muladd (1, i); 231 | 232 | while (cancel_binv.size () > 0) 233 | { 234 | R binv = cancel_binv.pop (); 235 | unsigned j = cancel_j.pop (); 236 | linear_combination di = cancel_di.pop (); 237 | 238 | for (linear_combination_const_iter ll = di; ll; ll ++) 239 | { 240 | R c = ll.val (); 241 | pib[j].mulsub (binv * c, pib[ll.key ()]); 242 | } 243 | } 244 | pi = mod_map (pib); 245 | 246 | assert (d.compose (iota) == iota.compose (new_d)); 247 | assert (new_d.compose (pi) == pi.compose (d)); 248 | assert (pi.compose (iota) == mod_map (new_C, 1)); 249 | } 250 | -------------------------------------------------------------------------------- /smoothing.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | void 5 | smoothing::init (const knot_diagram &d, smallbitset state) 6 | { 7 | unsigned n_edges = d.num_edges (); 8 | 9 | n_circles = 0; 10 | assert (edge_circle.size () == n_edges); 11 | 12 | for (unsigned i = 1; i <= n_edges; i ++) 13 | edge_circle[i] = 0; 14 | 15 | for (unsigned i = 1; i <= n_edges; i ++) 16 | { 17 | if (edge_circle[i]) 18 | continue; 19 | 20 | n_circles ++; 21 | for (unsigned p = edge_to (d, i);;) 22 | { 23 | unsigned e = d.ept_edge (p); 24 | edge_circle[e] = n_circles; 25 | 26 | p = d.resolve_next_ept (p, state % d.ept_crossing[p]); 27 | assert (is_from_ept (d, p)); 28 | if (d.ept_edge (p) == i) 29 | break; 30 | p = d.edge_other_ept (p); 31 | assert (is_to_ept (d, p)); 32 | } 33 | } 34 | 35 | #ifndef NDEBUG 36 | for (unsigned c = 1; c <= d.n_crossings; c ++) 37 | { 38 | assert (crossing_from_inside (d, state, c) 39 | == crossing_to_inside (d, state, c)); 40 | } 41 | #endif 42 | } 43 | 44 | unsigned 45 | smoothing::monomial_from (const knot_diagram &d, const smoothing &from_s, unsigned j) const 46 | { 47 | unsigned j2 = 0; 48 | for (unsigned k = 1; k <= d.num_edges (); k ++) 49 | { 50 | if (unsigned_bittest (j, from_s.edge_circle[k])) 51 | j2 = unsigned_bitset (j2, edge_circle[k]); 52 | } 53 | return j2; 54 | } 55 | 56 | unsigned 57 | smoothing::monomial_from (const knot_diagram &d, const smoothing &from_s, unsigned j, 58 | smallbitset skip) const 59 | { 60 | unsigned j2 = 0; 61 | for (unsigned k = 1; k <= d.num_edges (); k ++) 62 | { 63 | if (skip % k) 64 | continue; 65 | if (unsigned_bittest (j, from_s.edge_circle[k])) 66 | j2 = unsigned_bitset (j2, edge_circle[k]); 67 | } 68 | return j2; 69 | } 70 | 71 | void 72 | smoothing::show_self (const knot_diagram &d, smallbitset state) const 73 | { 74 | printf ("smoothing "); 75 | show (state); 76 | printf (" "); 77 | 78 | smallbitset done (d.num_edges ()); 79 | for (unsigned e = 1; e <= d.num_edges (); e ++) 80 | { 81 | if (done % e) 82 | continue; 83 | 84 | printf ("("); 85 | bool first = 1; 86 | for (unsigned f = e;;) 87 | { 88 | done.push (f); 89 | 90 | unsigned p = edge_to (d, f); 91 | unsigned c = d.ept_crossing (p); 92 | 93 | assert (is_to_ept (d, p)); 94 | 95 | if (f == d.marked_edge) 96 | printf ("*"); 97 | 98 | if (first) 99 | first = 0; 100 | else 101 | printf (", "); 102 | if (is_crossing_from_ept (d, state, p)) 103 | { 104 | printf ("t%d%s", 105 | c, 106 | crossing_from_inside (d, state, c) ? "in" : "out"); 107 | } 108 | else 109 | { 110 | printf ("h%d%s", 111 | c, 112 | crossing_to_inside (d, state, c) ? "in" : "out"); 113 | } 114 | 115 | f = next_edge (d, state, f); 116 | if (f == e) 117 | break; 118 | } 119 | printf (")"); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /smoothing.h: -------------------------------------------------------------------------------- 1 | 2 | class smoothing : public refcounted 3 | { 4 | public: 5 | unsigned n_circles; 6 | 7 | unsigned num_monomials () const { return ((unsigned)1) << n_circles; } 8 | unsigned num_generators (bool markedp_only) 9 | { 10 | return markedp_only 11 | ? ((unsigned)1) << (n_circles - 1) 12 | : ((unsigned)1) << n_circles; 13 | } 14 | 15 | basedvector edge_circle; 16 | 17 | unsigned crossing_from_circle (const knot_diagram &d, unsigned c) const 18 | { 19 | return edge_circle[d.ept_edge (d.crossings[c][2])]; 20 | } 21 | unsigned crossing_to_circle (const knot_diagram &d, unsigned c) const 22 | { 23 | return edge_circle[d.ept_edge (d.crossings[c][4])]; 24 | } 25 | 26 | unsigned ept_circle (const knot_diagram &d, unsigned p) const 27 | { 28 | return edge_circle[d.ept_edge (p)]; 29 | } 30 | 31 | unsigned edge_from (const knot_diagram &d, unsigned e) const 32 | { 33 | return d.edge_smoothing_from_ept (e); 34 | } 35 | unsigned edge_to (const knot_diagram &d, unsigned e) const 36 | { 37 | return d.edge_smoothing_to_ept (e); 38 | } 39 | 40 | bool is_from_ept (const knot_diagram &d, unsigned p) const 41 | { 42 | return d.is_smoothing_from_ept (p); 43 | } 44 | bool is_to_ept (const knot_diagram &d, unsigned p) const 45 | { 46 | return d.is_smoothing_to_ept (p); 47 | } 48 | 49 | bool crossing_from_inside (const knot_diagram &d, smallbitset state, unsigned c) const 50 | { 51 | unsigned p = d.crossings[c][2]; 52 | return (state % c) == is_to_ept (d, p); 53 | } 54 | bool crossing_from_outside (const knot_diagram &d, smallbitset state, unsigned c) const 55 | { 56 | return !crossing_from_inside (d, state, c); 57 | } 58 | bool crossing_to_inside (const knot_diagram &d, smallbitset state, unsigned c) const 59 | { 60 | unsigned p = d.crossings[c][4]; 61 | unsigned e = d.ept_edge (p); 62 | return (state % c) == is_to_ept (d, p); 63 | } 64 | 65 | bool is_crossing_from_ept (const knot_diagram &d, smallbitset state, unsigned p) const 66 | { 67 | unsigned c = d.ept_crossing (p); 68 | return p == d.crossings[c][2] 69 | || (state % c 70 | ? p == d.crossings[c][3] 71 | : p == d.crossings[c][1]); 72 | } 73 | 74 | unsigned next_edge (const knot_diagram &d, smallbitset state, unsigned e) const 75 | { 76 | unsigned p = edge_to (d, e); 77 | unsigned p2 = d.resolve_next_ept (p, state % d.ept_crossing[p]); 78 | assert (is_from_ept (d, p2)); 79 | return d.ept_edge (p2); 80 | } 81 | unsigned prev_edge (const knot_diagram &d, smallbitset state, unsigned e) const 82 | { 83 | unsigned p = edge_from (d, e); 84 | unsigned p2 = d.resolve_next_ept (p, state % d.ept_crossing[p]); 85 | assert (is_to_ept (d, p2)); 86 | return d.ept_edge (p2); 87 | } 88 | 89 | public: 90 | smoothing () : n_circles(0) { } 91 | smoothing (const knot_diagram &d) 92 | : edge_circle(d.num_edges ()) 93 | { } 94 | smoothing (const knot_diagram &d, smallbitset state) 95 | : edge_circle(d.num_edges ()) 96 | { 97 | init (d, state); 98 | } 99 | smoothing (const smoothing &s) 100 | : n_circles(s.n_circles), 101 | edge_circle(s.edge_circle) 102 | { } 103 | ~smoothing () { } 104 | 105 | void init (const knot_diagram &d, smallbitset state); 106 | 107 | smoothing &operator = (const smoothing &s) 108 | { 109 | n_circles = s.n_circles; 110 | edge_circle = s.edge_circle; 111 | return *this; 112 | } 113 | 114 | unsigned monomial_from (const knot_diagram &d, const smoothing &from_s, unsigned j) const; 115 | unsigned monomial_from (const knot_diagram &d, const smoothing &from_s, unsigned j, 116 | smallbitset skip) const; 117 | 118 | void show_self (const knot_diagram &d, smallbitset state) const; 119 | }; 120 | -------------------------------------------------------------------------------- /spanning_tree_complex.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | static bool 5 | find_cycle_1 (map &cycle, const directed_multigraph &bg, 6 | set edges, 7 | unsigned f, 8 | unsigned e, unsigned e_to) 9 | { 10 | for (set_const_iter i = edges; i; i ++) 11 | { 12 | if (i.val () == e) 13 | continue; 14 | 15 | if (bg.edge_from[i.val ()] == e_to) 16 | { 17 | if (i.val () == f) 18 | return 1; 19 | 20 | cycle.push (i.val (), 1); 21 | if (find_cycle_1 (cycle, bg, edges, f, 22 | i.val (), bg.edge_to[i.val ()])) 23 | return 1; 24 | 25 | cycle.yank (i.val ()); 26 | } 27 | else if (bg.edge_to[i.val ()] == e_to) 28 | { 29 | if (i.val () == f) 30 | return 1; 31 | 32 | cycle.push (i.val (), -1); 33 | if (find_cycle_1 (cycle, bg, edges, f, 34 | i.val (), bg.edge_from[i.val ()])) 35 | return 1; 36 | 37 | cycle.yank (i.val ()); 38 | } 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | map 45 | find_cycle (const directed_multigraph &bg, 46 | set edges, 47 | unsigned f, unsigned f_to) 48 | { 49 | map cycle; 50 | 51 | if (bg.edge_to[f] == f_to) 52 | cycle.push (f, 1); 53 | else 54 | { 55 | assert (bg.edge_from[f] == f_to); 56 | cycle.push (f, -1); 57 | } 58 | 59 | bool b = find_cycle_1 (cycle, bg, edges, f, 60 | f, f_to); 61 | assert (b); 62 | 63 | return cycle; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /steenrod_square.h: -------------------------------------------------------------------------------- 1 | 2 | class steenrod_square 3 | { 4 | // cube of resolutions (in steenrod_square, c will denote a cycle) 5 | const cube &cor; 6 | 7 | mod_map d; 8 | const chain_complex_simplifier &s; 9 | 10 | map > KGij; 11 | 12 | // sC, fC take generators as input, not hypercube vertices 13 | Z2 sC (unsigned x, unsigned y) const; 14 | Z2 fC (unsigned x, unsigned y) const; 15 | 16 | pair, // Gxy 17 | map // lxy 18 | > ladybug_matching (unsigned x, unsigned y) const; 19 | 20 | triple, // Gcx 21 | map, // bx 22 | map // sx 23 | > boundary_matching (grading cgr, 24 | linear_combination c, 25 | unsigned x) const; 26 | 27 | set > make_G2cx (grading cgr, 28 | linear_combination c, 29 | unsigned x) const; 30 | Z2 sq2_coeff (grading cgr, 31 | linear_combination c, 32 | unsigned x) const; 33 | 34 | public: 35 | steenrod_square (const cube &cor_, 36 | mod_map &d_, 37 | const chain_complex_simplifier &s_); 38 | ~steenrod_square () { } 39 | 40 | mod_map sq1 () const; 41 | mod_map sq2 () const; 42 | }; 43 | -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | in knotkit/ 2 | - my (or Kh) tangle algebra over Z 3 | - enumerate 2-connect sum knots to test mutation invariance over Z 4 | - add homology orientations for odd Khovanov homology and spectral 5 | sequence over Z 6 | - unify smoothing, resolution_diagram wiring (and knot_diagram?) 7 | - speed up construction of chain maps in chain_complex_simplifer 8 | - move chain_complex_simplifier to algebra/ 9 | - unify chain_complex_simplifer and build_sseq 10 | - remove hardcoded limits (max_...) 11 | - revive testlib 12 | - figure out proper copy interface and consistently support copy and 13 | deepcopy 14 | 15 | in lib/ 16 | - between interoperation between sets that require bounds (bitset, 17 | ullmanset) and those that don't (set, hashset) 18 | 19 | in algebra/ 20 | - linear_combnation can be more efficient (eg no searching when 21 | coefficients die) 22 | - monomial ideals and maybe groebner bases 23 | - cleaner interface for gcd, etc. in fraction_field 24 | - support kernel, cokernel of torsion modules 25 | - change gcd et al so gcd is always positive 26 | - split linear_combination into internal and external versions 27 | 28 | git: 29 | - fix bug in Josh's version 30 | - make this master, merge into Josh's version 31 | - merge in square to master => then write paper! 32 | - merge in other improvements (sped up linear algebra? multivariate (laurent) polynomial?) 33 | - should exponents on polynomials be Z or unsigned? 34 | 35 | general: 36 | - unify simplify_chain_complex, sseq, kernel/image/homology (as much as possible) 37 | - sseq over Z 38 | - quadratic linear solver (enumerator?) 39 | - classes should either COPY or fully SHARE, but not some of each 40 | (e.g. knot_diagram, resolution_diagram, etc.) -- this is the right 41 | semantics. 42 | - clean up/delete setcommon, mapcommon 43 | - incorporate sage dump into standard classes 44 | - update use of tuples in steenrod square 45 | 46 | - test mutation invariance, other questions of Robert and Sucharit 47 | - write paper 48 | 49 | c++11: 50 | - make vector wrap std::vector (probably faster) 51 | 52 | - use tuple instead of pair, triple; and use tie, a great idiom 53 | - standardize ring, field interface so test_ring works for everything 54 | - get clear on default semantics: prefer default when possible 55 | 56 | - standardize use of {} for initializers 57 | - initializer_list for container types 58 | - support for iterator 59 | 60 | - compress Steenrod square data 61 | - get mpimain running again, run 15 xing mutants 62 | 63 | - simplifications to run (5, 8) with symmetries. 64 | 65 | notes: 66 | 67 | all rings (R): multivariate_laurentpoly 68 | 69 | fields (F): Z2 Zp Q fraction_field (for just pids?) 70 | 71 | euclidean domains (E): Z polynomial 72 | 73 | euclidean domain interface: 74 | 75 | num/demon : denom must be a unit 76 | = num.operator / (denom) 77 | 78 | denom.divides (num) 79 | denom | num 80 | 81 | num.divide_exact (denom) 82 | 83 | (q, r) = num.divide_with_remainder (denom) 84 | (q, r) = num / denom 85 | (q, r) = num.operator / (denom) 86 | satisfies r = 0 or f(r) < f(denom) and num = q*denom + r 87 | 88 | gcd (a, b) 89 | lcm (a, b) 90 | r = num.mod (denom) 91 | satisfies r = 0 or f(r) < f(denom) 92 | 93 | 94 | (d, s, t) = a.extended_gcd (b) 95 | satifies d is the gcd and d = a*s + b*t 96 | --------------------------------------------------------------------------------