From ad0f60f5c08e59279e97b413a654bac5ec54b1cf Mon Sep 17 00:00:00 2001 From: Cotton Seed Date: Mon, 25 Mar 2013 16:39:15 -0400 Subject: [PATCH] Renamed driver kk. Added support for various invariants (gss + kh, lsss, leess, sq2, s) to prepare for release of the link splitting spectral sequence paper on the arXiv. --- .gitignore | 2 +- Makefile | 31 +- README | 157 ++++++++- algebra/module.h | 12 +- cube_impl.h | 16 +- gss.cpp | 126 ------- kk.cpp | 660 +++++++++++++++++++++++++++++++++++++ knot_diagram.cpp | 2 +- knot_parser/knot_parser.cc | 293 +++++++--------- knot_parser/knot_parser.hh | 115 ++----- knot_parser/location.hh | 60 ++-- knot_parser/position.hh | 59 ++-- knot_parser/stack.hh | 41 ++- knot_tables.cpp | 10 +- main.cpp | 8 +- rd_parser/rd_scanner.cc | 52 +-- simplify_chain_complex.h | 11 +- sseq.cpp | 114 +------ sseq.h | 437 ++++++++++-------------- 19 files changed, 1326 insertions(+), 880 deletions(-) delete mode 100644 gss.cpp create mode 100644 kk.cpp diff --git a/.gitignore b/.gitignore index fec3496..7695f4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ *~ *.o -/gss +/kk /main /testsurfaces /serial.cmd.[eo]* diff --git a/Makefile b/Makefile index a67fcca..1d58f76 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,22 @@ -BISON = /opt/local/bin/bison -FLEX = /opt/local/bin/flex +devel = 1 + +BISON = bison +FLEX = flex # CXX = g++ # CXX = OMPI_CXX=clang++ mpic++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -I/u/cseed/llvm-3.1/lib/c++/v1 -CXX = clang++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -I/u/cseed/llvm-3.1/lib/c++/v1 +CXX = clang++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -INCLUDES = -I/opt/local/include -I. +INCLUDES = -I. -I/opt/local/include -# OPTFLAGS = -g -OPTFLAGS = -O2 -g +OPTFLAGS = -g +# OPTFLAGS = -O2 -g # OPTFLAGS = -O2 -DNDEBUG -LDFLAGS = -L/opt/local/lib -L/u/cseed/llvm-3.1/lib -# LDFLAGS = -pg -L/opt/local/lib +LDFLAGS = -L/opt/local/lib -CXXFLAGS = $(OPTFLAGS) -Wall -Wno-unused $(INCLUDES) +CXXFLAGS = $(OPTFLAGS) -DHOME="\"`pwd`\"" -Wall -Wno-unused $(INCLUDES) LIB_OBJS = lib/refcount.o \ lib/lib.o lib/smallbitset.o lib/bitset.o lib/setcommon.o lib/io.o lib/directed_multigraph.o @@ -45,7 +46,7 @@ KNOTKIT_HEADERS = knotkit.h planar_diagram.h dt_code.h knot_diagram.h \ LIBS = -lgmp -lz -all: gss +all: kk %.o : %.cc $(CXX) -c $(CXXFLAGS) $< -o $@ @@ -53,8 +54,8 @@ all: gss %.o : %.cpp $(CXX) -c $(CXXFLAGS) $< -o $@ -gss: gss.o $(COMMON_OBJS) - $(CXX) $(LDFLAGS) -o gss $^ $(LIBS) +kk: kk.o $(COMMON_OBJS) + $(CXX) $(LDFLAGS) -o kk $^ $(LIBS) main: main.o $(COMMON_OBJS) $(CXX) $(LDFLAGS) -o main $^ $(LIBS) @@ -65,6 +66,7 @@ mpimain: mpimain.o mpi_aux.o $(COMMON_OBJS) testlib: testlib.o $(COMMON_OBJS) $(CXX) $(LDFLAGS) -o testlib $^ +ifeq ($(devel),1) knot_parser/knot_parser.cc knot_parser/knot_parser.hh: knot_parser/knot_parser.yy $(BISON) knot_parser/knot_parser.yy -o knot_parser/knot_parser.cc @@ -82,6 +84,7 @@ rd_parser/rd_parser.cc rd_parser/rd_parser.hh: rd_parser/rd_parser.yy rd_parser/rd_scanner.cc: rd_parser/rd_scanner.ll $(FLEX) -o rd_parser/rd_scanner.cc rd_parser/rd_scanner.ll +endif .PHONY: parser_files parser_files: \ @@ -95,7 +98,7 @@ parser_files: \ .PHONY: clean clean: rm -f *.o lib/*.o algebra/*.o knot_parser/*.o rd_parser/*.o - rm -f main gss mpimain + rm -f main kk mpimain rm -f gmon.out .PHONY: realclean @@ -112,6 +115,6 @@ realclean: clean $(LIB_OBJS): $(LIB_HEADERS) $(ALGEBRA_OBJS): $(ALGEBRA_HEADERS) $(LIB_HEADERS) -$(KNOTKIT_OBJS) main.o mpimain.o gss.o: $(KNOTKIT_HEADERS) $(ALGEBRA_HEADERS) $(LIB_HEADERS) +$(KNOTKIT_OBJS) main.o mpimain.o kk.o: $(KNOTKIT_HEADERS) $(ALGEBRA_HEADERS) $(LIB_HEADERS) mpimain.o mpi_aux.o: mpi_aux.h diff --git a/README b/README index 8986544..9e6dce5 100644 --- a/README +++ b/README @@ -1 +1,156 @@ -I modified cotton's readme. \ No newline at end of file +knotkit is a C++ software package written by Cotton Seed +(cseed@math.princeton.edu) for computing some knot and manifold +invariants appearing in low-dimensional topology. Other contributors +include Josh Batson. + +TABLE OF CONTENTS + +1. INTRO +2. BUILDING +3. USAGE +4. UPCOMING CHANGES +5. FOR DEVELOPERS + +1. INTRO + +In addition to accepting knot presentations in a variety of formats +(see usage below), knotkit contains the following tables of knot data: + +* The Rolfsen knot tables through 10 crossings, extracted from + Bar-Natan's Mathematica package, KnotTheory`, +* The Hoste-Weeks-Thistlewaite knot tables through 16 crossings taken + from knotscape, and +* and the Morwen Thistlewaite hyperbolic link tables taken from + SnapPy. + +This version of knotkit has support to compute the following +invariants: + +* Khovanov homology +See: +M. Khovanov, A Categorification of the Jones Polynomial, Duke + Math. J. 101 (2000), 359--426, arXiv:math/9908171. +D. Bar-Natan, On Khovanov's Categorification of the Jones Polynomial, + Algebraic and Geometric Topology 2 (2002), 337--370. + +* Szabo's geometric spectral sequence +Computing gss was the original motivation for writing knotkit. For +more information on gss, see: +Z. Szabo, A geometric spectral sequence in Khovanov homology, + arXiv:1010.4252, and +C. Seed, Computations of Szabo's Geometric Spectral Sequence in Khovanov + Homology, arXiv:1110.0735. + +* The Batson-Seed link splitting spectral sequence +See: +J. Batson, C. Seed, A Link Splitting Spectral Sequence in Khovanov + Homology. + +* The Lipshitz-Sarkar Steenrod square on Khovanov homology +See: +R. Lipshitz, S. Sarkar, A Khovanov Homotopy Type, arXiv:1112.3932. +R. Lipshitz, S. Sarkar, A Steenrod Square on Khovanov Homology, + arXiv:1204.5776. + +* Bar-Natan's analogue of Lee homology +See: +E. S. Lee, An endomorphism of the Khovanov invariant, Adv. Math. 197 + (2005), 2, 554–586, arXiv:math/0210213. +D. Bar-Natan, Khovanov’s homology for tangles and cobordisms, + Geom. Topol. 9 (2005), 1443–1499, arXiv:math/0410495. +R. Lipshitz, S. Sarkar, A refinement of Rasmussen's s-invariant, + arXiv:1206.3532. + +* The s-invariant coming from Bar-Natan's analogue of Lee homology +In addition to the above references, see: +J. Rasmussen, Khovanov homology and the slice genus, Invent. + Math. 182 2 (2010), 419--447, arXiv:math/0402131. +R. Lipshitz, S. Sarkar, A refinement of Rasmussen's s-invariant, + arXiv:1206.3532. + +2. BUILDING + +To build knotkit on OS X, you will need the latest version of XCode +(available for free in the App Store) and the GNU multiple precision +arithmetic library (GMP). You can get GMP here: + +http://gmplib.org/ + +knotkit also builds under Linux. In addition to GMP, you will need a +C++ compiler which supports C++11. I use LLVM clang, but knotkit +should build with a recent version of GCC. + +knotkit doesn't have a sophisticated build system. To build knotkit, just run: + +make + +from the knotkit source directory. This should build the executable +"kk". For instructions on invoking kk, see usage below. If you run +into a problem, please contact me: Cotton Seed +(cotton@math.princeton.edu). + +3. USAGE + +The usage message for kk is given below. This can also be obtained by +running "kk -h". + +A note about output. The output for commands kh, gss, ls and lee is a +.tex file which renders the bigraded homology group or spectral +sequence. The output for the command sq2 matches the output for the +program written by Lipshitz-Sarkar and is suitable for loading into +Sage. The command s outputs a single line of text. + +usage: kk [options...] + compute for knot or link + can be one of: + kh: Khovanov homology + gss: Szabo's geometric spectral sequence + ls: Batson-Seed link splitting spectral sequence + component weights are 0, 1, ..., m + sq2: Lipshitz-Sarkar Steenrod square on Z/2 Kh + output suitable for Sage + leess: spectral sequence coming from Bar-Natan analogue of Lee's + deformation of Khovanov's complex (whew!) + s: Rasmussen's s-invariant coming from lee +options: + -r : compute reduced theory + -h : print this message + -o : write output to + (stdout is the default) + -f : ground field (if applicable) + (Z2 is the default) + -v : verbose: report progress as the computation proceeds + can be one of: + Z2, Z3, Q + can be one of: + - the unknot, e.g. U or unknot + - a torus knot, e.g. T(2,3) + - a Rolfsen table knot, e.g. 10_124 + - a Hoste-Thistlethwaite-Weeks knot, e.g. 11a12 or 12n214 + - a Morwen Thistlethwaite link, e.g. L9a21 or L14n7631 + - a planar diagram, e.g. + PD[X[1, 4, 2, 5], X[3, 6, 4, 1], X[5, 2, 6, 3]] or + PD[[1, 4, 2, 5], [3, 6, 4, 1], [5, 2, 6, 3]] + - a Dowker-Thistlethwaite code, e.g. + DTCode[6,8,2,4], + DT[dadbcda] or + DT[{6, -8}, {-10, 12, -14, 2, -4}] + - a braid, e.g. BR[2, {-1, -1, -1}] + +4. UPCOMING CHANGES + +The following changes are currently planned: + +* support for Z/p, p arbitrary prime and F(x) field of rational functions +* Roberts' totally twisted Khovanov homology +* the E^3 page of the twisted spectral sequence Kh(L) => \widehat{HF}(\Sigma_L) +* spectral sequences of PIDs: ls over F[x], gss over Z +* maps induced by cobordisms + +5. FOR DEVELOPERS + +If you are interested in contributing to knotkit or using it for a new +application, please contact me: Cotton Seed +(cotton@math.princeton.edu). I am interested in developing knotkit to +be an open platform for performing computations arising in +low-dimensional topology. diff --git a/algebra/module.h b/algebra/module.h index 37bc470..acd217b 100644 --- a/algebra/module.h +++ b/algebra/module.h @@ -53,7 +53,8 @@ class module : public refcounted // r < i <= n virtual R generator_ann (unsigned i) const = 0; - + + basedvector grading_vector () const; set gradings () const; bool is_free () const { return dim () == free_rank (); } @@ -1503,6 +1504,15 @@ module::free_ell_poincare_polynomial () const return r; } +template basedvector +module::grading_vector () const +{ + basedvector v (dim ()); + for (unsigned i = 1; i <= dim (); i ++) + v[i] = generator_grading (i); + return v; +} + template set module::gradings () const { diff --git a/cube_impl.h b/cube_impl.h index 56d7662..e66ebf1 100644 --- a/cube_impl.h +++ b/cube_impl.h @@ -329,6 +329,13 @@ cube::H_i (unsigned c) for (unsigned j = 0; j < from_s.num_monomials (); j ++) { + if (markedp_only) + { + unsigned p = from_s.edge_circle[kd.marked_edge]; + if (unsigned_bittest (j, p)) + continue; + } + unsigned j2 = 0; for (unsigned_const_iter k = j; k; k ++) { @@ -372,7 +379,7 @@ cube::compute_dinv (unsigned c) { if (!unsigned_bittest (i, c)) continue; - + int sign = 1; for (unsigned j = 1; j < c; j ++) { @@ -395,6 +402,13 @@ cube::compute_dinv (unsigned c) y = to_s.crossing_to_circle (kd, c); for (unsigned j = 0; j < from_s.num_monomials (); j ++) { + if (markedp_only) + { + unsigned p = from_s.edge_circle[kd.marked_edge]; + if (unsigned_bittest (j, p)) + continue; + } + unsigned j2 = 0; for (unsigned_const_iter k = j; k; k ++) { diff --git a/gss.cpp b/gss.cpp deleted file mode 100644 index 3f8f28d..0000000 --- a/gss.cpp +++ /dev/null @@ -1,126 +0,0 @@ - -#include - -const char *program_name; - -void -usage () -{ - printf ("usage: %s [-f] [-h] [-o ] [-v] \n", program_name); - printf (" compute Szabo's geometric spectral sequence for knot \n"); - printf ("options:\n"); - printf (" -f : compute unreduced spectral sequence\n"); - printf (" (reduced is the default)\n"); - printf (" -h : print this message\n"); - printf (" -o : write output to \n"); - printf (" (stdout is the default)\n"); - printf (" -v : verbose: report progress as the computation proceeds\n"); - printf (" can be one of:\n"); - printf (" - the unknot, e.g. U or unknot\n"); - printf (" - a torus knot, e.g. T(2,3)\n"); - printf (" - a Rolfsen table knot, e.g. 10_124\n"); - printf (" - a Hoste-Thistlethwaite-Weeks knot, e.g. 11a12 or 12n214\n"); - printf (" - a Morwen Thistlethwaite link, e.g. L9a21 or L14n7631\n"); - printf (" - a planar diagram, e.g.\n"); - printf (" PD[X[1, 4, 2, 5], X[3, 6, 4, 1], X[5, 2, 6, 3]] or\n"); - printf (" PD[[1, 4, 2, 5], [3, 6, 4, 1], [5, 2, 6, 3]]\n"); - printf (" - a Dowker-Thistlethwaite code, e.g.\n"); - printf (" DTCode[6,8,2,4],\n"); - printf (" DT[dadbcda] or\n"); - printf (" DT[{6, -8}, {-10, 12, -14, 2, -4}]\n"); - printf (" - a braid, e.g. BR[2, {-1, -1, -1}]\n"); -} - -int -main (int argc, char **argv) -{ - program_name = argv[0]; - - bool reduced = 1; - const char *knot = 0; - const char *file = 0; - - for (int i = 1; i < argc; i ++) - { - if (argv[i][0] == '-') - { - if (strcmp (argv[i], "-f") == 0) - reduced = 0; - else if (strcmp (argv[i], "-h") == 0) - { - usage (); - exit (EXIT_SUCCESS); - } - else if (!strcmp (argv[i], "-v")) - verbose = 1; - else if (!strcmp (argv[i], "-o")) - { - i ++; - if (i == argc) - { - fprintf (stderr, "error: missing argument to option `-o'\n"); - exit (EXIT_FAILURE); - } - file = argv[i]; - } - else - { - fprintf (stderr, "error: unknown argument `%s'\n", argv[1]); - usage (); - exit (EXIT_FAILURE); - } - } - else - { - if (knot) - { - fprintf (stderr, "error: too many arguments\n"); - usage (); - exit (EXIT_FAILURE); - } - else - knot = argv[i]; - } - } - - if (!knot) - { - fprintf (stderr, "error: missing argument\n"); - usage (); - exit (EXIT_FAILURE); - } - - FILE *outfp = 0; - if (file) - { - outfp = fopen (file, "w"); - if (!outfp) - { - stderror ("fopen: %s", file); - exit (EXIT_FAILURE); - } - } - else - outfp = stdout; - - knot_diagram d = parse_knot (knot); - d.marked_edge = 1; - cube c (d, reduced); - - fprintf (outfp, "\\documentclass{article}\n\ -\\usepackage{amsmath, tikz, hyperref}\n\ -\\DeclareMathOperator{\\rank}{rank}\n\ -\\setlength{\\parindent}{0pt}\n\ -\n\ -\\begin{document}\n\ -\\pagestyle{empty}\n\ -\\tableofcontents\n\ -\\sloppy\n"); - - compute_szabo_sseq (c).texshow (outfp, d.name); - - fprintf (outfp, "\\end{document}\n"); - - if (file) - fclose (outfp); -} diff --git a/kk.cpp b/kk.cpp new file mode 100644 index 0000000..70edb62 --- /dev/null +++ b/kk.cpp @@ -0,0 +1,660 @@ + +#include + +const char *program_name; + +void +usage () +{ + printf ("usage: %s [options...] \n", program_name); + printf (" compute for knot or link \n"); + printf (" can be one of:\n"); + printf (" kh: Khovanov homology\n"); + printf (" gss: Szabo's geometric spectral sequence\n"); + printf (" ls: Batson-Seed link splitting spectral sequence\n"); + printf (" component weights are 0, 1, ..., m\n"); + printf (" sq2: Lipshitz-Sarkar Steenrod square on Z/2 Kh\n"); + printf (" output suitable for Sage\n"); + printf (" leess: spectral sequence coming from Bar-Natan analogue of Lee's\n"); + printf (" deformation of Khovanov's complex (whew!)\n"); + printf (" s: Rasmussen's s-invariant coming from lee\n"); + printf ("options:\n"); + printf (" -r : compute reduced theory\n"); + printf (" -h : print this message\n"); + printf (" -o : write output to \n"); + printf (" (stdout is the default)\n"); + printf (" -f : ground field (if applicable)\n"); + printf (" (Z2 is the default)\n"); + printf (" -v : verbose: report progress as the computation proceeds\n"); + printf (" can be one of:\n"); + printf (" Z2, Z3, Q\n"); + printf (" can be one of:\n"); + printf (" - the unknot, e.g. U or unknot\n"); + printf (" - a torus knot, e.g. T(2,3)\n"); + printf (" - a Rolfsen table knot, e.g. 10_124\n"); + printf (" - a Hoste-Thistlethwaite-Weeks knot, e.g. 11a12 or 12n214\n"); + printf (" - a Morwen Thistlethwaite link, e.g. L9a21 or L14n7631\n"); + printf (" - a planar diagram, e.g.\n"); + printf (" PD[X[1, 4, 2, 5], X[3, 6, 4, 1], X[5, 2, 6, 3]] or\n"); + printf (" PD[[1, 4, 2, 5], [3, 6, 4, 1], [5, 2, 6, 3]]\n"); + printf (" - a Dowker-Thistlethwaite code, e.g.\n"); + printf (" DTCode[6,8,2,4],\n"); + printf (" DT[dadbcda] or\n"); + printf (" DT[{6, -8}, {-10, 12, -14, 2, -4}]\n"); + printf (" - a braid, e.g. BR[2, {-1, -1, -1}]\n"); +} + +FILE *outfp = stdout; + +void tex_header () +{ + fprintf (outfp, "\\documentclass{article}\n\ +\\usepackage{amsmath, tikz, hyperref}\n\ +\\DeclareMathOperator{\\rank}{rank}\n\ +\\setlength{\\parindent}{0pt}\n\ +\n\ +\\begin{document}\n\ +\\pagestyle{empty}\n\ +\\sloppy\n"); +} + +void tex_footer () +{ + fprintf (outfp, "\\end{document}\n"); +} + +const char *knot = 0; +const char *invariant = 0; +const char *field = "Z2"; + +knot_diagram kd; + +bool reduced = 0; + +class hg_grading_mapper +{ + unsigned m; + +public: + hg_grading_mapper (unsigned m_) : m(m_) { } + + grading operator () (grading hq) const + { + int t = hq.q - (int)m; + if (reduced) + t --; + + assert (is_even (t)); + return grading (hq.h, t / 2); + } + + grading map_delta (grading d_hq) const + { + assert (is_even (d_hq.q)); + return grading (d_hq.h, d_hq.q / 2); + } + + void x_label (FILE *fp, int h) const + { + fprintf (fp, "%d", h); + } + void y_label (FILE *fp, int g) const + { + unsigned q = 2*g + (int)m; + if (reduced) + q ++; + + fprintf (fp, "%d", q); + } +}; + +template mod_map +compute_link_splitting_d (knot_diagram &kd, + cube &c, + basedvector comp_weight) +{ + unsigned n = kd.num_components (); + + unionfind<1> u (kd.num_edges ()); + for (unsigned i = 1; i <= kd.n_crossings; i ++) + { + u.join (kd.ept_edge (kd.crossings[i][1]), + kd.ept_edge (kd.crossings[i][3])); + u.join (kd.ept_edge (kd.crossings[i][2]), + kd.ept_edge (kd.crossings[i][4])); + } + + map root_comp; + unsigned t = 0; + for (unsigned i = 1; i <= kd.num_edges (); i ++) + { + if (u.find (i) == i) + { + ++ t; + root_comp.push (i, t); + } + } + assert (t == n); + + assert (comp_weight.size () == n); + + map crossing_over_sign; + + // crossings + set pending; + set finished; + + crossing_over_sign.push (1, R (1)); + pending.push (1); + + while (pending.card () > 0) + { + unsigned x = pending.pop (); + finished.push (x); + + R s = crossing_over_sign(x); + + for (unsigned j = 1; j <= 4; j ++) + { + unsigned p = kd.crossings[x][j]; + R t = kd.is_over_ept (p) ? s : -s; // sign of (x, p) + + unsigned q = kd.edge_other_ept (p); + unsigned x2 = kd.ept_crossing[q]; + + R u = kd.is_over_ept (q) ? -t : t; + + if (crossing_over_sign % x2) + assert (crossing_over_sign(x2) == u); + else + crossing_over_sign.push (x2, u); + + if (! (finished % x2)) + pending += x2; + } + } + assert (finished.card () == kd.n_crossings); + + mod_map untwisted_d = c.compute_d (1, 0, 0, 0, 0); + assert (untwisted_d.compose (untwisted_d) == 0); + + mod_map d = untwisted_d; + for (unsigned x = 1; x <= kd.n_crossings; x ++) + { + unsigned p1 = kd.crossings[x][1], + p2 = kd.crossings[x][2]; + assert (kd.is_over_ept (p2)); + + unsigned r1 = u.find (kd.ept_edge (p1)), + r2 = u.find (kd.ept_edge (p2)); + + unsigned c1 = root_comp(r1), + c2 = root_comp(r2); + + if (c1 != c2) + { + R s = crossing_over_sign(x); + + R w_under = comp_weight[c1]; + R w_over = comp_weight[c2]; + + d = d + c.compute_dinv (x)*(s*(w_over - w_under)); + } + } + + assert (d.compose (d) == 0); + return d; +} + +void +compute_gss () +{ + cube c (kd, reduced); + ptr > C = c.khC; + mod_map d = c.compute_d (0, 0, 0, 0, 0); + + unsigned m = kd.num_components (); + hg_grading_mapper mapper (m); + + sseq_bounds b (C, mapper); + basedvector pages; + + unsigned k = 1; + for (;;) + { + chain_complex_simplifier s (C, d, + maybe (k), maybe (2*k - 2)); + C = s.new_C; + d = s.new_d; + k ++; + + grading dk_gr (k, 2*k - 2); + pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper)); + if (d == 0) + break; + } + + sseq ss (b, pages); + + tex_header (); + fprintf (outfp, "$E_k = %s^{Sz}_k(\\verb~%s~; \\verb~%s~)$:\\\\\n", + (reduced + ? "\\widetilde{E}" + : "E"), + knot, field); + ss.texshow (outfp, mapper); + tex_footer (); +} + +template void +compute_invariant () +{ + if (!strcmp (invariant, "kh")) + { + cube c (kd, reduced); + ptr > C = c.khC; + mod_map d = c.compute_d (1, 0, 0, 0, 0); + + unsigned m = kd.num_components (); + hg_grading_mapper mapper (m); + + chain_complex_simplifier s (C, d, + maybe (1), maybe (0)); + C = s.new_C; + d = s.new_d; + + sseq_bounds b (C, mapper); + sseq_page pg (b, 2, grading (0, 0), mod_map (C), mapper); + + tex_header (); + + fprintf (outfp, "Kh = $%s(\\verb~%s~; \\verb~%s~)$:\\\\\n", + (reduced + ? "\\widetilde{Kh}" + : "Kh"), + knot, + field); + fprintf (outfp, "$\\rank Kh = %d$\\\\\n", C->dim ()); + + char buf[1000]; + sprintf (buf, "$Kh$"); + pg.texshow (outfp, b, buf, mapper); + + tex_footer (); + } + else if (!strcmp (invariant, "lsss")) + { + cube c (kd, reduced); + ptr > C = c.khC; + + unsigned m = kd.num_components (); + basedvector comp_weight (m); + for (unsigned i = 1; i <= m; i ++) + comp_weight[i] = R ((int)(i - 1)); + + mod_map d = compute_link_splitting_d (kd, c, comp_weight); + + hg_grading_mapper mapper (m); + + sseq_bounds b (C, mapper); + basedvector pages; + + int k = 0; + for (;;) + { + chain_complex_simplifier s (C, d, + maybe (1 - 2*k), maybe (-2*k)); + C = s.new_C; + d = s.new_d; + k ++; + + grading dk_gr (1 - 2*k, -2*k); + pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper)); + if (d == 0) + break; + } + + sseq ss (b, pages); + + tex_header (); + fprintf (outfp, "$E_k = %s^{BS}_k(\\verb~%s~; \\verb~%s~)$:\\\\\n", + (reduced + ? "\\widetilde{E}" + : "E"), + knot, + field); + ss.texshow (outfp, mapper); + tex_footer (); + } + else if (!strcmp (invariant, "leess")) + { + cube c (kd, reduced); + ptr > C = c.khC; + + mod_map d = c.compute_d (1, 0, 0, 0, 0); + for (unsigned i = 1; i <= kd.n_crossings; i ++) + d = d + c.H_i (i); + assert (d.compose (d) == 0); + + unsigned m = kd.num_components (); + hg_grading_mapper mapper (m); + + sseq_bounds b (C, mapper); + basedvector pages; + + int k = 0; + for (;;) + { + chain_complex_simplifier s (C, d, + maybe (1), maybe (2*k)); + C = s.new_C; + d = s.new_d; + k ++; + + grading dk_gr (1, 2*k); + pages.append (sseq_page (b, k, dk_gr, d.graded_piece (dk_gr), mapper)); + if (d == 0) + break; + } + + sseq ss (b, pages); + + tex_header (); + fprintf (outfp, "$E_k = %s^{BN}_k(\\verb~%s~; \\verb~%s~)$:\\\\\n", + (reduced + ? "\\widetilde{E}" + : "E"), + knot, field); + ss.texshow (outfp, mapper); + tex_footer (); + } + else if (!strcmp (invariant, "s")) + { + unsigned m = kd.num_components (); + if (m != 1) + { + fprintf (stderr, "error: s-invariant only defined for knots\n"); + exit (EXIT_FAILURE); + } + + cube c (kd, 0); + ptr > C = c.khC; + + mod_map d = c.compute_d (1, 0, 0, 0, 0); + for (unsigned i = 1; i <= kd.n_crossings; i ++) + d = d + c.H_i (i); + assert (d.compose (d) == 0); + + int k = 0; + for (;;) + { + chain_complex_simplifier s (C, d, + maybe (1), maybe (2*k)); + C = s.new_C; + d = s.new_d; + k ++; + + if (d == 0) + break; + } + + assert (C->dim () == 2); + grading gr1 = C->generator_grading (1), + gr2 = C->generator_grading (2); + + int qmin = gr1.q, + qmax = gr2.q; + if (qmax < qmin) + std::swap (qmin, qmax); + + assert (qmax == qmin + 2); + + fprintf (outfp, "s(%s; %s) = %d\n", knot, field, qmin + 1); + } + else + { + fprintf (stderr, "error: unknown invariant %s\n", invariant); + exit (EXIT_FAILURE); + } +} + +void +sage_show (FILE *fp, + map > hq_gens, + ptr > H) +{ + fprintf (fp, "hom={"); + bool first = 1; + for (map >::const_iter i = hq_gens; i; i ++) + { + if (first) + first = 0; + else + fprintf (fp, ", "); + fprintf (fp, "(%d, %d): %d", i.key ().h, i.key ().q, i.val ().size ()); + } + fprintf (fp, "}\n"); +} + +void +sage_show (FILE *fp, + map > hq_gens, + std::string name, + grading delta, + mod_map f) +{ + fprintf (fp, "%s={", name.c_str ()); + + bool first = 1; + for (map >::const_iter i = hq_gens; i; i ++) + { + grading from_hq = i.key (); + basedvector from_gens = i.val (); + + grading to_hq = from_hq + delta; + if (hq_gens % to_hq) + { + basedvector to_gens = hq_gens(to_hq); + + if (first) + first = 0; + else + fprintf (fp, ", "); + fprintf (fp, "(%d, %d): [", from_hq.h, from_hq.q); + bool first2 = 1; + for (unsigned j = 1; j <= from_gens.size (); j ++) + { + unsigned gj = from_gens[j]; + + if (first2) + first2 = 0; + else + fprintf (fp, ", "); + fprintf (fp, "("); + for (unsigned k = 1; k <= to_gens.size (); k ++) + { + unsigned gk = to_gens[k]; + + if (k > 1) + fprintf (fp, ", "); + if (f[gj](gk) == 1) + fprintf (fp, "1"); + else + { + assert (f[gj](gk) == 0); + fprintf (fp, "0"); + } + } + fprintf (fp, ")"); + } + fprintf (fp, "]"); + } + } + fprintf (fp, "}\n"); +} + +void +sage_show_khsq (FILE *fp, + ptr > H, + mod_map sq1, + mod_map sq2) +{ + unsigned n = H->dim (); + + map > hq_gens; + for (unsigned i = 1; i <= H->dim (); i ++) + hq_gens[H->generator_grading (i)].append (i); + + unsigned t = 0; + for (map >::const_iter i = hq_gens; i; i ++) + t += i.val ().size (); + assert (t == n); + + sage_show (fp, hq_gens, H); + sage_show (fp, hq_gens, "sq1", grading (1, 0), sq1); + sage_show (fp, hq_gens, "sq2", grading (2, 0), sq2); +} + +void +compute_sq2 () +{ + cube c (kd); + mod_map d = c.compute_d (1, 0, 0, 0, 0); + + chain_complex_simplifier s (c.khC, d, maybe (1), maybe (0)); + assert (s.new_d == 0); + + steenrod_square sq (c, d, s); + mod_map sq1 = sq.sq1 (); + mod_map sq2 = sq.sq2 (); + + ptr > H = sq1.domain (); + + sage_show_khsq (outfp, H, sq1, sq2); +} + +int +main (int argc, char **argv) +{ + program_name = argv[0]; + + const char *file = 0; + + for (int i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (strcmp (argv[i], "-r") == 0) + reduced = 1; + else if (strcmp (argv[i], "-h") == 0) + { + usage (); + exit (EXIT_SUCCESS); + } + else if (!strcmp (argv[i], "-v")) + verbose = 1; + else if (!strcmp (argv[i], "-f")) + { + i ++; + if (i == argc) + { + fprintf (stderr, "error: missing argument to option `-f'\n"); + exit (EXIT_FAILURE); + } + field = argv[i]; + } + else if (!strcmp (argv[i], "-o")) + { + i ++; + if (i == argc) + { + fprintf (stderr, "error: missing argument to option `-o'\n"); + exit (EXIT_FAILURE); + } + file = argv[i]; + } + else + { + fprintf (stderr, "error: unknown argument `%s'\n", argv[1]); + fprintf (stderr, " use -h for usage\n"); + exit (EXIT_FAILURE); + } + } + else + { + if (knot) + { + fprintf (stderr, "error: too many arguments\n"); + fprintf (stderr, " use -h for usage\n"); + exit (EXIT_FAILURE); + } + else if (invariant) + knot = argv[i]; + else + { + assert (invariant == 0); + invariant = argv[i]; + } + } + } + + if (!knot) + { + fprintf (stderr, "error: too few arguments, or missing\n"); + fprintf (stderr, " use -h for usage\n"); + exit (EXIT_FAILURE); + } + + if (file) + { + outfp = fopen (file, "w"); + if (!outfp) + { + stderror ("fopen: %s", file); + exit (EXIT_FAILURE); + } + } + else + outfp = stdout; + + kd = parse_knot (knot); + kd.marked_edge = 1; + + if (!strcmp (invariant, "sq2")) + { + if (strcmp (field, "Z2")) + { + fprintf (stderr, "warning: sq2 only defined over Z2, ignoring -f %s\n", field); + field = "Z2"; + } + + compute_sq2 (); + } + else if (!strcmp (invariant, "gss")) + { + if (strcmp (field, "Z2")) + { + fprintf (stderr, "warning: gss only defined over Z2, ignoring -f %s\n", field); + field = "Z2"; + } + + compute_gss (); + } + else + { + if (!strcmp (field, "Z2")) + compute_invariant (); + else if (!strcmp (field, "Z3")) + compute_invariant > (); + else if (!strcmp (field, "Q")) + compute_invariant (); + else + { + fprintf (stderr, "error: unknown field %s\n", field); + exit (EXIT_FAILURE); + } + } + + if (file) + fclose (outfp); +} diff --git a/knot_diagram.cpp b/knot_diagram.cpp index 420a8f4..ea6c1b2 100644 --- a/knot_diagram.cpp +++ b/knot_diagram.cpp @@ -626,7 +626,7 @@ knot_diagram::total_linking_number () const assert (is_even (lk)); lk /= 2; - total_lk += std::abs (lk); + total_lk += abs (lk); } return total_lk; diff --git a/knot_parser/knot_parser.cc b/knot_parser/knot_parser.cc index 6b764d5..1de6208 100644 --- a/knot_parser/knot_parser.cc +++ b/knot_parser/knot_parser.cc @@ -1,9 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ +/* A Bison parser, made by GNU Bison 2.6.5. */ /* Skeleton implementation for Bison LALR(1) parsers in C++ - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free - Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,37 +33,41 @@ /* First part of user declarations. */ - -/* Line 311 of lalr1.cc */ -#line 40 "knot_parser/knot_parser.cc" +/* Line 278 of lalr1.cc */ +#line 38 "knot_parser/knot_parser.cc" #include "knot_parser.hh" /* User implementation prologue. */ - -/* Line 317 of lalr1.cc */ -#line 49 "knot_parser/knot_parser.cc" +/* Line 284 of lalr1.cc */ +#line 46 "knot_parser/knot_parser.cc" /* Unqualified %code blocks. */ - -/* Line 318 of lalr1.cc */ +/* Line 285 of lalr1.cc */ #line 15 "knot_parser/knot_parser.yy" #define YY_DECL \ yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval) YY_DECL; - -/* Line 318 of lalr1.cc */ +/* Line 285 of lalr1.cc */ #line 29 "knot_parser/knot_parser.yy" #define yylex knot_yylex +/* Line 285 of lalr1.cc */ +#line 62 "knot_parser/knot_parser.cc" -/* Line 318 of lalr1.cc */ -#line 68 "knot_parser/knot_parser.cc" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS @@ -78,6 +81,27 @@ YY_DECL; # endif #endif +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +# ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).begin = YYRHSLOC (Rhs, 1).begin; \ + (Current).end = YYRHSLOC (Rhs, N).end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \ + } \ + while (/*CONSTCOND*/ false) +# endif + + /* Suppress unused-variable warnings by "using" E. */ #define YYUSE(e) ((void) (e)) @@ -128,49 +152,8 @@ do { \ namespace yy { - -/* Line 380 of lalr1.cc */ -#line 134 "knot_parser/knot_parser.cc" -#if YYERROR_VERBOSE - - /* Return YYSTR after stripping away unnecessary quotes and - backslashes, so that it's suitable for yyerror. The heuristic is - that double-quoting is unnecessary unless the string contains an - apostrophe, a comma, or backslash (other than backslash-backslash). - YYSTR is taken from yytname. */ - std::string - knot_parser::yytnamerr_ (const char *yystr) - { - if (*yystr == '"') - { - std::string yyr = ""; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - yyr += *yyp; - break; - - case '"': - return yyr; - } - do_not_strip_quotes: ; - } - - return yystr; - } - -#endif +/* Line 352 of lalr1.cc */ +#line 157 "knot_parser/knot_parser.cc" /// Build a parser object. knot_parser::knot_parser (knot_diagram &parsed_knot_yyarg) @@ -198,6 +181,9 @@ namespace yy { { YYUSE (yylocationp); YYUSE (yyvaluep); + std::ostream& yyo = debug_stream (); + std::ostream& yyoutput = yyo; + YYUSE (yyoutput); switch (yytype) { default: @@ -271,6 +257,18 @@ namespace yy { } #endif + inline bool + knot_parser::yy_pact_value_is_default_ (int yyvalue) + { + return yyvalue == yypact_ninf_; + } + + inline bool + knot_parser::yy_table_value_is_error_ (int yyvalue) + { + return yyvalue == yytable_ninf_; + } + int knot_parser::parse () { @@ -278,17 +276,18 @@ namespace yy { int yychar = yyempty_; int yytoken = 0; - /* State. */ + // State. int yyn; int yylen = 0; int yystate = 0; - /* Error handling. */ + // Error handling. int yynerrs_ = 0; int yyerrstatus_ = 0; /// Semantic value of the lookahead. - semantic_type yylval; + static semantic_type yyval_default; + semantic_type yylval = yyval_default; /// Location of the lookahead. location_type yylloc; /// The locations where the error started and ended. @@ -330,7 +329,7 @@ namespace yy { /* Try to take a decision without lookahead. */ yyn = yypact_[yystate]; - if (yyn == yypact_ninf_) + if (yy_pact_value_is_default_ (yyn)) goto yydefault; /* Read a lookahead token. */ @@ -340,7 +339,6 @@ namespace yy { yychar = yylex (&yylval); } - /* Convert token to internal form. */ if (yychar <= yyeof_) { @@ -363,8 +361,8 @@ namespace yy { yyn = yytable_[yyn]; if (yyn <= 0) { - if (yyn == 0 || yyn == yytable_ninf_) - goto yyerrlab; + if (yy_table_value_is_error_ (yyn)) + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -419,8 +417,7 @@ namespace yy { switch (yyn) { case 10: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 67 "knot_parser/knot_parser.yy" { unsigned n = (yysemantic_stack_[(3) - (1)].integer), @@ -439,8 +436,7 @@ namespace yy { break; case 11: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 85 "knot_parser/knot_parser.yy" { unsigned n = (yysemantic_stack_[(3) - (1)].integer), @@ -460,8 +456,7 @@ namespace yy { break; case 12: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 104 "knot_parser/knot_parser.yy" { unsigned n = (yysemantic_stack_[(4) - (2)].integer), @@ -481,22 +476,19 @@ namespace yy { break; case 13: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 123 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (planar_diagram ("", *(yysemantic_stack_[(4) - (3)].int_vec2))); } break; case 14: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 125 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (planar_diagram ("", *(yysemantic_stack_[(4) - (3)].int_vec2))); } break; case 15: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 130 "knot_parser/knot_parser.yy" { basedvector, 1> even_labels (1); @@ -506,36 +498,31 @@ namespace yy { break; case 16: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 136 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (dt_code ("", *(yysemantic_stack_[(4) - (3)].int_vec2))); } break; case 17: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 138 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (dt_code ("", (yysemantic_stack_[(4) - (3)].string))); } break; case 18: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 143 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (torus_knot ((yysemantic_stack_[(6) - (3)].integer), (yysemantic_stack_[(6) - (5)].integer))); } break; case 19: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 148 "knot_parser/knot_parser.yy" { parsed_knot = knot_diagram (braid ((yysemantic_stack_[(6) - (3)].integer), *(yysemantic_stack_[(6) - (5)].int_vec))); } break; case 20: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 153 "knot_parser/knot_parser.yy" { unsigned unknot_ar[1][4] = { @@ -546,8 +533,7 @@ namespace yy { break; case 23: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 168 "knot_parser/knot_parser.yy" { basedvector, 1> *v @@ -558,8 +544,7 @@ namespace yy { break; case 24: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 175 "knot_parser/knot_parser.yy" { basedvector, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2); @@ -569,22 +554,19 @@ namespace yy { break; case 25: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 184 "knot_parser/knot_parser.yy" { (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); } break; case 26: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 186 "knot_parser/knot_parser.yy" { (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); } break; case 27: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 191 "knot_parser/knot_parser.yy" { basedvector *v = @@ -595,8 +577,7 @@ namespace yy { break; case 28: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 198 "knot_parser/knot_parser.yy" { basedvector *v = (yysemantic_stack_[(3) - (1)].int_vec); @@ -606,8 +587,7 @@ namespace yy { break; case 29: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 207 "knot_parser/knot_parser.yy" { basedvector, 1> *v @@ -618,8 +598,7 @@ namespace yy { break; case 30: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 214 "knot_parser/knot_parser.yy" { basedvector, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2); @@ -629,8 +608,7 @@ namespace yy { break; case 31: - -/* Line 678 of lalr1.cc */ +/* Line 661 of lalr1.cc */ #line 223 "knot_parser/knot_parser.yy" { basedvector *v @@ -644,12 +622,22 @@ namespace yy { break; - -/* Line 678 of lalr1.cc */ -#line 650 "knot_parser/knot_parser.cc" +/* Line 661 of lalr1.cc */ +#line 627 "knot_parser/knot_parser.cc" default: break; } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action + invokes YYABORT, YYACCEPT, or YYERROR immediately after altering + yychar. In the case of YYABORT or YYACCEPT, an incorrect + destructor might then be invoked immediately. In the case of + YYERROR, subsequent parser actions might lead to an incorrect + destructor call or verbose syntax error message before the + lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); yypop_ (yylen); @@ -673,11 +661,17 @@ namespace yy { | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yytranslate_ (yychar); + /* If not already recovering from an error, report this error. */ if (!yyerrstatus_) { ++yynerrs_; - error (yylloc, yysyntax_error_ (yystate)); + if (yychar == yyempty_) + yytoken = yyempty_; + error (yylloc, yysyntax_error_ (yystate, yytoken)); } yyerror_range[1] = yylloc; @@ -732,7 +726,7 @@ namespace yy { for (;;) { yyn = yypact_[yystate]; - if (yyn != yypact_ninf_) + if (!yy_pact_value_is_default_ (yyn)) { yyn += yyterror_; if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) @@ -782,7 +776,13 @@ namespace yy { yyreturn: if (yychar != yyempty_) - yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + { + /* Make sure we have latest lookahead translation. See comments + at user semantic actions for why this is necessary. */ + yytoken = yytranslate_ (yychar); + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, + &yylloc); + } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ @@ -801,51 +801,9 @@ namespace yy { // Generate an error message. std::string - knot_parser::yysyntax_error_ (int yystate) + knot_parser::yysyntax_error_ (int, int) { - std::string res; - YYUSE (yystate); -#if YYERROR_VERBOSE - int yyn = yypact_[yystate]; - if (yypact_ninf_ < yyn && yyn <= yylast_) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = yylast_ - yyn + 1; - int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; - int count = 0; - for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yyterror_) - ++count; - - // FIXME: This method of building the message is not compatible - // with internationalization. It should work like yacc.c does it. - // That is, first build a string that looks like this: - // "syntax error, unexpected %s or %s or %s" - // Then, invoke YY_ on this string. - // Finally, use the string as a format to output - // yytname_[tok], etc. - // Until this gets fixed, this message appears in English only. - res = "syntax error, unexpected "; - res += yytnamerr_ (yytname_[tok]); - if (count < 5) - { - count = 0; - for (int x = yyxbegin; x < yyxend; ++x) - if (yycheck_[x + yyn] == x && x != yyterror_) - { - res += (!count++) ? ", expecting " : " or "; - res += yytnamerr_ (yytname_[x]); - } - } - } - else -#endif - res = YY_("syntax error"); - return res; + return YY_("syntax error"); } @@ -865,9 +823,9 @@ namespace yy { 54, 58, 59, -36 }; - /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ + /* YYDEFACT[S] -- default reduction number in state S. Performed when + YYTABLE doesn't specify something else to do. Zero means the + default is an error. */ const unsigned char knot_parser::yydefact_[] = { @@ -899,7 +857,7 @@ namespace yy { /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. */ + number is the opposite. If YYTABLE_NINF_, syntax error. */ const signed char knot_parser::yytable_ninf_ = -1; const unsigned char knot_parser::yytable_[] = @@ -975,7 +933,7 @@ namespace yy { 3, 10 }; -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +#if YYDEBUG /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at \a yyntokens_, nonterminals. */ const char* @@ -986,11 +944,10 @@ namespace yy { "']'", "'('", "','", "')'", "'{'", "'}'", "$accept", "knot", "rolfsen_knot", "htw_knot", "mt_link", "planar_diagram", "dt", "torus_link", "braid", "unknot", "alt_spec", "int_vec2", "int_vec", - "int_vec_1", "crossing_vec", "crossing", 0 + "int_vec_1", "crossing_vec", "crossing", YY_NULL }; -#endif -#if YYDEBUG + /* YYRHS -- A `-1'-separated list of the rules' RHS. */ const knot_parser::rhs_number_type knot_parser::yyrhs_[] = @@ -1115,12 +1072,9 @@ namespace yy { } // yy - -/* Line 1054 of lalr1.cc */ -#line 1121 "knot_parser/knot_parser.cc" - - -/* Line 1056 of lalr1.cc */ +/* Line 1106 of lalr1.cc */ +#line 1077 "knot_parser/knot_parser.cc" +/* Line 1107 of lalr1.cc */ #line 233 "knot_parser/knot_parser.yy" @@ -1145,4 +1099,3 @@ parse_knot (const char *s) return d; } - diff --git a/knot_parser/knot_parser.hh b/knot_parser/knot_parser.hh index b604953..6edaa9e 100644 --- a/knot_parser/knot_parser.hh +++ b/knot_parser/knot_parser.hh @@ -1,9 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ +/* A Bison parser, made by GNU Bison 2.6.5. */ /* Skeleton interface for Bison LALR(1) parsers in C++ - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free - Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,41 +30,30 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/** + ** \file knot_parser/knot_parser.hh + ** Define the yy::parser class. + */ + /* C++ LALR(1) parser skeleton written by Akim Demaille. */ -#ifndef PARSER_HEADER_H -# define PARSER_HEADER_H +#ifndef YY_YY_KNOT_PARSER_KNOT_PARSER_HH_INCLUDED +# define YY_YY_KNOT_PARSER_KNOT_PARSER_HH_INCLUDED /* "%code requires" blocks. */ - -/* Line 35 of lalr1.cc */ +/* Line 36 of lalr1.cc */ #line 11 "knot_parser/knot_parser.yy" #include - -/* Line 35 of lalr1.cc */ -#line 50 "knot_parser/knot_parser.hh" +/* Line 36 of lalr1.cc */ +#line 52 "knot_parser/knot_parser.hh" #include #include #include "stack.hh" - - -namespace yy { - -/* Line 35 of lalr1.cc */ -#line 61 "knot_parser/knot_parser.hh" - class position; - class location; - -} // yy - -/* Line 35 of lalr1.cc */ -#line 68 "knot_parser/knot_parser.hh" - #include "location.hh" /* Enabling traces. */ @@ -73,43 +61,10 @@ namespace yy { # define YYDEBUG 0 #endif -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ -do { \ - if (N) \ - { \ - (Current).begin = (Rhs)[1].begin; \ - (Current).end = (Rhs)[N].end; \ - } \ - else \ - { \ - (Current).begin = (Current).end = (Rhs)[0].end; \ - } \ -} while (false) -#endif - namespace yy { - -/* Line 35 of lalr1.cc */ -#line 113 "knot_parser/knot_parser.hh" +/* Line 36 of lalr1.cc */ +#line 68 "knot_parser/knot_parser.hh" /// A Bison parser. class knot_parser @@ -119,8 +74,7 @@ namespace yy { #ifndef YYSTYPE union semantic_type { - -/* Line 35 of lalr1.cc */ +/* Line 36 of lalr1.cc */ #line 21 "knot_parser/knot_parser.yy" int integer; @@ -130,9 +84,8 @@ namespace yy { const char *string; - -/* Line 35 of lalr1.cc */ -#line 136 "knot_parser/knot_parser.hh" +/* Line 36 of lalr1.cc */ +#line 89 "knot_parser/knot_parser.hh" }; #else typedef YYSTYPE semantic_type; @@ -194,7 +147,7 @@ namespace yy { /// Generate an error message. /// \param state the state where the error occurred. /// \param tok the lookahead token. - virtual std::string yysyntax_error_ (int yystate); + virtual std::string yysyntax_error_ (int yystate, int tok); #if YYDEBUG /// \brief Report a symbol value on the debug stream. @@ -230,6 +183,14 @@ namespace yy { /// The location stack. location_stack_type yylocation_stack_; + /// Whether the given \c yypact_ value indicates a defaulted state. + /// \param yyvalue the value to check + static bool yy_pact_value_is_default_ (int yyvalue); + + /// Whether the given \c yytable_ value indicates a syntax error. + /// \param yyvalue the value to check + static bool yy_table_value_is_error_ (int yyvalue); + /// Internal symbol numbers. typedef unsigned char token_number_type; /* Tables. */ @@ -237,7 +198,7 @@ namespace yy { static const signed char yypact_[]; static const signed char yypact_ninf_; - /// For a state, default rule to reduce. + /// For a state, default reduction number. /// Unless\a yytable_ specifies something else to do. /// Zero means the default is an error. static const unsigned char yydefact_[]; @@ -261,19 +222,12 @@ namespace yy { /// For a rule, its LHS. static const unsigned char yyr1_[]; /// For a rule, its RHS length. - static const unsigned char yyr2_[]; - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE - /// For a symbol, its name in clear. - static const char* const yytname_[]; -#endif - -#if YYERROR_VERBOSE - /// Convert the symbol name \a n to a form suitable for a diagnostic. - virtual std::string yytnamerr_ (const char *n); -#endif + static const unsigned char yyr2_[]; #if YYDEBUG + /// For a symbol, its name in clear. + static const char* const yytname_[]; + /// A type to store symbol numbers and -1. typedef signed char rhs_number_type; /// A `-1'-separated list of the rules' RHS. @@ -328,10 +282,9 @@ namespace yy { }; } // yy - -/* Line 35 of lalr1.cc */ -#line 334 "knot_parser/knot_parser.hh" +/* Line 36 of lalr1.cc */ +#line 287 "knot_parser/knot_parser.hh" -#endif /* ! defined PARSER_HEADER_H */ +#endif /* !YY_YY_KNOT_PARSER_KNOT_PARSER_HH_INCLUDED */ diff --git a/knot_parser/location.hh b/knot_parser/location.hh index c123693..7faaf2b 100644 --- a/knot_parser/location.hh +++ b/knot_parser/location.hh @@ -1,9 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ +/* A Bison parser, made by GNU Bison 2.6.5. */ /* Locations for Bison parsers in C++ - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software - Foundation, Inc. + Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,39 +31,55 @@ version 2.2 of Bison. */ /** - ** \file location.hh + ** \file knot_parser/location.hh ** Define the yy::location class. */ -#ifndef BISON_LOCATION_HH -# define BISON_LOCATION_HH +#ifndef YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED +# define YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED -# include -# include # include "position.hh" namespace yy { - -/* Line 163 of location.cc */ -#line 51 "knot_parser/location.hh" +/* Line 164 of location.cc */ +#line 47 "knot_parser/location.hh" /// Abstract a location. class location { public: - /// Construct a location. - location () - : begin (), end () + /// Construct a location from \a b to \a e. + location (const position& b, const position& e) + : begin (b) + , end (e) + { + } + + /// Construct a 0-width location in \a p. + explicit location (const position& p = position ()) + : begin (p) + , end (p) + { + } + + /// Construct a 0-width location in \a f, \a l, \a c. + explicit location (std::string* f, + unsigned int l = 1u, + unsigned int c = 1u) + : begin (f, l, c) + , end (f, l, c) { } /// Initialization. - inline void initialize (std::string* fn) + void initialize (std::string* f = YY_NULL, + unsigned int l = 1u, + unsigned int c = 1u) { - begin.initialize (fn); + begin.initialize (f, l, c); end = begin; } @@ -72,19 +87,19 @@ namespace yy { ** \{ */ public: /// Reset initial location to final location. - inline void step () + void step () { begin = end; } /// Extend the current location to the COUNT next columns. - inline void columns (unsigned int count = 1) + void columns (unsigned int count = 1) { end += count; } /// Extend the current location to the COUNT next lines. - inline void lines (unsigned int count = 1) + void lines (unsigned int count = 1) { end.lines (count); } @@ -158,8 +173,7 @@ namespace yy { } // yy +/* Line 292 of location.cc */ +#line 178 "knot_parser/location.hh" -/* Line 272 of location.cc */ -#line 164 "knot_parser/location.hh" - -#endif // not BISON_LOCATION_HH +#endif /* !YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED */ diff --git a/knot_parser/position.hh b/knot_parser/position.hh index c034a2e..dbbea36 100644 --- a/knot_parser/position.hh +++ b/knot_parser/position.hh @@ -1,9 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ +/* A Bison parser, made by GNU Bison 2.6.5. */ /* Positions for Bison parsers in C++ - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software - Foundation, Inc. + Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,60 +31,71 @@ version 2.2 of Bison. */ /** - ** \file position.hh + ** \file knot_parser/position.hh ** Define the yy::position class. */ -#ifndef BISON_POSITION_HH -# define BISON_POSITION_HH +#ifndef YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED +# define YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED +# include // std::max # include # include -# include + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif namespace yy { - /* Line 38 of location.cc */ -#line 51 "knot_parser/position.hh" +#line 57 "knot_parser/position.hh" /// Abstract a position. class position { public: /// Construct a position. - position () - : filename (0), line (1), column (1) + explicit position (std::string* f = YY_NULL, + unsigned int l = 1u, + unsigned int c = 1u) + : filename (f) + , line (l) + , column (c) { } /// Initialization. - inline void initialize (std::string* fn) + void initialize (std::string* fn = YY_NULL, + unsigned int l = 1u, + unsigned int c = 1u) { filename = fn; - line = 1; - column = 1; + line = l; + column = c; } /** \name Line and Column related manipulators ** \{ */ - public: /// (line related) Advance to the COUNT next lines. - inline void lines (int count = 1) + void lines (int count = 1) { - column = 1; + column = 1u; line += count; } /// (column related) Advance to the COUNT next columns. - inline void columns (int count = 1) + void columns (int count = 1) { column = std::max (1u, column + count); } /** \} */ - public: /// File name to which this position refers. std::string* filename; /// Current line number. @@ -95,7 +105,7 @@ namespace yy { }; /// Add and assign a position. - inline const position& + inline position& operator+= (position& res, const int width) { res.columns (width); @@ -111,7 +121,7 @@ namespace yy { } /// Add and assign a position. - inline const position& + inline position& operator-= (position& res, const int width) { return res += -width; @@ -156,7 +166,6 @@ namespace yy { } // yy - -/* Line 145 of location.cc */ -#line 162 "knot_parser/position.hh" -#endif // not BISON_POSITION_HH +/* Line 149 of location.cc */ +#line 171 "knot_parser/position.hh" +#endif /* !YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED */ diff --git a/knot_parser/stack.hh b/knot_parser/stack.hh index 3c16aa6..e005e60 100644 --- a/knot_parser/stack.hh +++ b/knot_parser/stack.hh @@ -1,9 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ +/* A Bison parser, made by GNU Bison 2.6.5. */ /* Stack handling for Bison parsers in C++ - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free - Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,21 +30,24 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef BISON_STACK_HH -# define BISON_STACK_HH +/** + ** \file knot_parser/stack.hh + ** Define the yy::stack class. + */ -#include +#ifndef YY_YY_KNOT_PARSER_STACK_HH_INCLUDED +# define YY_YY_KNOT_PARSER_STACK_HH_INCLUDED + +# include namespace yy { - -/* Line 1067 of lalr1.cc */ -#line 44 "knot_parser/stack.hh" +/* Line 37 of stack.hh */ +#line 47 "knot_parser/stack.hh" template > class stack { public: - // Hide our reversed order. typedef typename S::reverse_iterator iterator; typedef typename S::const_reverse_iterator const_iterator; @@ -84,7 +86,7 @@ namespace yy { pop (unsigned int n = 1) { for (; n; --n) - seq_.pop_front (); + seq_.pop_front (); } inline @@ -98,7 +100,6 @@ namespace yy { inline const_iterator end () const { return seq_.rend (); } private: - S seq_; }; @@ -107,10 +108,9 @@ namespace yy { class slice { public: - - slice (const S& stack, - unsigned int range) : stack_ (stack), - range_ (range) + slice (const S& stack, unsigned int range) + : stack_ (stack) + , range_ (range) { } @@ -122,15 +122,12 @@ namespace yy { } private: - const S& stack_; unsigned int range_; }; } // yy +/* Line 119 of stack.hh */ +#line 132 "knot_parser/stack.hh" -/* Line 1153 of lalr1.cc */ -#line 134 "knot_parser/stack.hh" - -#endif // not BISON_STACK_HH[]dnl - +#endif /* !YY_YY_KNOT_PARSER_STACK_HH_INCLUDED */ diff --git a/knot_tables.cpp b/knot_tables.cpp index 3445ed7..60370c6 100644 --- a/knot_tables.cpp +++ b/knot_tables.cpp @@ -1,8 +1,6 @@ #include -#define HOME "/Users/cotton/src/knotkit/" - bool verbose = 0; static const struct { @@ -402,7 +400,7 @@ htw_knot (unsigned n, bool alternating, unsigned k) before += htw_alternating[i]; off = 8 * (before + k - 1); - file = HOME "alternating"; + file = HOME "/alternating"; } else { @@ -411,7 +409,7 @@ htw_knot (unsigned n, bool alternating, unsigned k) before += htw_nonalternating[i]; off = 10 * (before + k - 1); - file = HOME "nonalternating"; + file = HOME "/nonalternating"; } FILE *fp = fopen (file, "r"); if (fp == 0) @@ -514,7 +512,7 @@ mt_link (unsigned n, bool alternating, unsigned k) char buf[1000]; - sprintf (buf, HOME "mtlinks/hyperbolic_data_%02d%c", n, alternating ? 'a' : 'n'); + sprintf (buf, HOME "/mtlinks/hyperbolic_data_%02d%c", n, alternating ? 'a' : 'n'); FILE *fp = fopen (buf, "r"); if (fp == 0) { @@ -717,7 +715,7 @@ mutant_knot_groups (unsigned n) assert (11 <= n && n <= 15); char buf[1000]; - sprintf (buf, HOME "mutant_knot_groups/dat%d", n); + sprintf (buf, HOME "/mutant_knot_groups/dat%d", n); FILE *fp = fopen (buf, "r"); if (fp == 0) diff --git a/main.cpp b/main.cpp index 73cf403..669272b 100644 --- a/main.cpp +++ b/main.cpp @@ -1281,8 +1281,10 @@ compute_forgetfulss (knot_diagram &kd, if (d == 0) break; } - - return sseq (bounds, pages); + + abort (); + // ??? + return sseq (bounds, grading (0, 0), grading (0, 0), pages); } void @@ -2613,7 +2615,7 @@ main () { knot_diagram kd (mt_link (5, 1, 3)); show (kd); newline (); - + sseq ss = compute_forgetfulss (kd); ss.texshow (stdout, "L5a3"); } diff --git a/rd_parser/rd_scanner.cc b/rd_parser/rd_scanner.cc index 372c166..6f19fc8 100644 --- a/rd_parser/rd_scanner.cc +++ b/rd_parser/rd_scanner.cc @@ -66,6 +66,7 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -172,7 +173,12 @@ typedef unsigned int flex_uint32_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif -extern int rd_yyleng; +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t rd_yyleng; extern FILE *rd_yyin, *rd_yyout; @@ -198,11 +204,6 @@ extern FILE *rd_yyin, *rd_yyout; #define unput(c) yyunput( c, (yytext_ptr) ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -220,7 +221,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -290,8 +291,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* yy_hold_char holds the character lost when rd_yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int rd_yyleng; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t rd_yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; @@ -319,7 +320,7 @@ static void rd_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); YY_BUFFER_STATE rd_yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE rd_yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE rd_yy_scan_bytes (yyconst char *bytes,int len ); +YY_BUFFER_STATE rd_yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *rd_yyalloc (yy_size_t ); void *rd_yyrealloc (void *,yy_size_t ); @@ -377,7 +378,7 @@ static void yy_fatal_error (yyconst char msg[] ); */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ - rd_yyleng = (size_t) (yy_cp - yy_bp); \ + rd_yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; @@ -483,7 +484,7 @@ char *rd_yytext; typedef yy::rd_parser::token token; typedef yy::rd_parser::token_type token_type; -#line 487 "rd_parser/rd_scanner.cc" +#line 488 "rd_parser/rd_scanner.cc" #define INITIAL 0 @@ -522,7 +523,7 @@ FILE *rd_yyget_out (void ); void rd_yyset_out (FILE * out_str ); -int rd_yyget_leng (void ); +yy_size_t rd_yyget_leng (void ); char *rd_yyget_text (void ); @@ -581,7 +582,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - int n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( rd_yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -666,7 +667,7 @@ YY_DECL #line 16 "rd_parser/rd_scanner.ll" -#line 670 "rd_parser/rd_scanner.cc" +#line 671 "rd_parser/rd_scanner.cc" if ( !(yy_init) ) { @@ -794,7 +795,7 @@ YY_RULE_SETUP #line 49 "rd_parser/rd_scanner.ll" ECHO; YY_BREAK -#line 798 "rd_parser/rd_scanner.cc" +#line 799 "rd_parser/rd_scanner.cc" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -981,7 +982,7 @@ static int yy_get_next_buffer (void) else { - int num_to_read = + yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) @@ -995,7 +996,7 @@ static int yy_get_next_buffer (void) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1026,7 +1027,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -1148,7 +1149,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -1172,7 +1173,7 @@ static int yy_get_next_buffer (void) case EOB_ACT_END_OF_FILE: { if ( rd_yywrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -1424,7 +1425,7 @@ void rd_yypop_buffer_state (void) */ static void rd_yyensure_buffer_stack (void) { - int num_to_alloc; + yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { @@ -1521,12 +1522,11 @@ YY_BUFFER_STATE rd_yy_scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE rd_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +YY_BUFFER_STATE rd_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - int i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -1608,7 +1608,7 @@ FILE *rd_yyget_out (void) /** Get the length of the current token. * */ -int rd_yyget_leng (void) +yy_size_t rd_yyget_leng (void) { return rd_yyleng; } diff --git a/simplify_chain_complex.h b/simplify_chain_complex.h index 6dcfea9..189e48d 100644 --- a/simplify_chain_complex.h +++ b/simplify_chain_complex.h @@ -63,8 +63,7 @@ class chain_complex_simplifier public: chain_complex_simplifier (ptr > C_, const mod_map &d_, - int dq); - + maybe dh, maybe dq); }; template void @@ -145,7 +144,7 @@ chain_complex_simplifier::cancel (unsigned i, R b, unsigned j) template chain_complex_simplifier::chain_complex_simplifier (ptr > C_, const mod_map &d_, - int dq) + maybe dh, maybe dq) : C(C_), n(C_->dim ()), d(d_), new_d_columns(n), preim(n), @@ -173,8 +172,10 @@ chain_complex_simplifier::chain_complex_simplifier (ptr > C_, { grading jgr = C->generator_grading (j.key ()); if (j.val ().is_unit () - && jgr.q - igr.q == dq - ) + && (dh.is_none () + || (jgr.h - igr.h == dh.some ())) + && (dq.is_none () + || (jgr.q - igr.q == dq.some ()))) { cancel (i, j.val (), j.key ()); break; diff --git a/sseq.cpp b/sseq.cpp index 662c8ab..0a1c4aa 100644 --- a/sseq.cpp +++ b/sseq.cpp @@ -2,7 +2,8 @@ #include sseq_page::sseq_page (const sseq_bounds &b) - : rank(b.width ()), + : k(0), + rank(b.width ()), im_rank(b.width ()) { for (unsigned i = 0; i < b.width (); i ++) @@ -140,87 +141,6 @@ sseq_page::delta_poincare_polynomial (const sseq_bounds &b) const return r; } -void -sseq_page::texshow (FILE *fp, const sseq_bounds &b, unsigned dh, bool last) -{ - fprintf (fp, "\ -\\begin{tikzpicture}[scale=.66]\n\ - \\draw[->] (0,0) -- (%d.5,0) node[right] {$t$};\n\ - \\draw[->] (0,0) -- (0,%d.5) node[above] {$q$};\n\ - \\draw[step=1] (0,0) grid (%d,%d);\n", - b.width (), (b.height () + 1) / 2, b.width (), (b.height () + 1) / 2); - - fprintf (fp, " \\draw (%.3f,-0.8) node[below] {$", - ((double)b.width () + 0.5) / 2); - if (last) - fprintf (fp, "E_\\infty = "); - fprintf (fp, "E_{%d}$};\n", - dh); - - /* label axes */ - for (int x = b.minh; x <= b.maxh; x ++) - { - fprintf (fp, "\ - \\draw (%d.5,-.2) node[below] {$%d$};\n", - x - b.minh, x); - } - for (int y = b.minq; y <= b.maxq; y += 2) - { - fprintf (fp, "\ - \\draw (-.2,%d.5) node[left] {$%d$};\n", - (y - b.minq) / 2, y); - } - - for (unsigned i = 0; i < b.width (); i ++) - for (unsigned j = 0; j < b.height (); j ++) - { - int r = rank[i][j]; - if (r == 1) - { - assert (is_even (j)); - fprintf (fp, "\ - \\fill (%d.5, %d.5) circle (.15);\n", - i, j / 2); - } - else if (r > 1) - { - assert (is_even (j)); - fprintf (fp, "\ - \\draw (%d.5, %d.5) node {$%d$};\n", - i, j / 2, r); - } - } - - for (unsigned i = 0; i < b.width (); i ++) - for (unsigned j = 0; j < b.height (); j ++) - { - unsigned r = im_rank[i][j]; - if (r == 0) - continue; - - unsigned dx = dh, - dy = dh - 1; // in "boxes" - assert (dx >= 2); // eliminated d_1 - - double h = sqrt ((double)(dx * dx + dy * dy)); - double xadj = (double)dx / h * 0.3; - double yadj = (double)dy / h * 0.3; - - assert (is_even (j)); - fprintf (fp, " \\draw[->] (%.3f, %.3f) -- ", - (double)i + 0.5 + xadj, (double)(j / 2) + 0.5 + yadj); - if (r > 1) - fprintf (fp, "node[color=red!75!black] {$%d$} ", r); - fprintf (fp, "(%.3f, %.3f);\n", - (double)(i + dx) + 0.5 - xadj, (double)(j / 2 + dy) + 0.5 - yadj); - } - - fprintf (fp, "\ -\\end{tikzpicture}\n"); - - fflush (fp); -} - sseq sseq::operator + (const sseq &ss2) const { @@ -280,36 +200,6 @@ sseq::shift (int dh, int dq) const pages); } -bool -sseq::equal_as_spaces (const sseq &ss) const -{ - if (bounds != ss.bounds - || pages.size () != ss.pages.size ()) - return 0; - - for (unsigned i = 1; i <= pages.size (); i ++) - { - if (!pages[i].equal_as_spaces (ss.pages[i])) - return 0; - } - - return 1; -} - -void -sseq::texshow (FILE *fp, std::string name) -{ - fprintf (fp, "\\section{Knot $%s$}\n", name.c_str ()); - - unsigned n = pages.size (); - for (unsigned i = 1; i <= n; i ++) - fprintf (fp, "$\\rank E_%d = %d$ \\\\\n", - i + 1, pages[i].total_rank ()); - - for (unsigned i = 1; i <= n; i ++) - pages[i].texshow (fp, bounds, i + 1, i == n); -} - void sseq_builder::cancel (unsigned d) { diff --git a/sseq.h b/sseq.h index a928cab..85cfd6a 100644 --- a/sseq.h +++ b/sseq.h @@ -7,6 +7,27 @@ class sseq_bounds public: sseq_bounds () { } + + template sseq_bounds (ptr > C, M m) + { + grading hq1 = m(C->generator_grading (1)); + minh = maxh = hq1.h; + minq = maxq = hq1.q; + + for (unsigned i = 2; i <= C->dim (); i ++) + { + grading hq = m(C->generator_grading (i)); + if (hq.h < minh) + minh = hq.h; + if (hq.h > maxh) + maxh = hq.h; + if (hq.q < minq) + minq = hq.q; + if (hq.q > maxq) + maxq = hq.q; + } + } + sseq_bounds (int minh_, int maxh_, int minq_, int maxq_) : minh(minh_), maxh(maxh_), minq(minq_), maxq(maxq_) { } @@ -41,22 +62,34 @@ class sseq_page { public: /* bounds come from sseq */ + unsigned k; + grading dk_gr; vector > rank, im_rank; public: sseq_page () { } sseq_page (const sseq_bounds &b); + template sseq_page (const sseq_bounds &b, + unsigned k_, + grading dk_gr_, + mod_map d, + M m); sseq_page (const sseq_page &pg) - : rank(pg.rank), im_rank(pg.im_rank) + : k(pg.k), dk_gr(pg.dk_gr), rank(pg.rank), im_rank(pg.im_rank) { } ~sseq_page () { } - bool operator == (const sseq_page &pg) const { return rank == pg.rank && im_rank == pg.im_rank; } + bool operator == (const sseq_page &pg) const + { + return k == pg.k + && dk_gr == pg.dk_gr + && rank == pg.rank + && im_rank == pg.im_rank; + } + bool operator != (const sseq_page &pg) const { return !operator == (pg); } - bool equal_as_spaces (const sseq_page &pg) const { return rank == pg.rank; } - unsigned total_rank () const; multivariate_laurentpoly poincare_polynomial (const sseq_bounds &b) const; multivariate_laurentpoly delta_poincare_polynomial (const sseq_bounds &b) const; @@ -67,7 +100,7 @@ class sseq_page const sseq_bounds &b1, const sseq_page &pg1, const sseq_bounds &b2, const sseq_page &pg2); - void texshow (FILE *fp, const sseq_bounds &b, unsigned dh, bool last); + template void texshow (FILE *fp, const sseq_bounds &b, const char *label, M m); }; class sseq @@ -78,8 +111,10 @@ class sseq public: sseq () { } - sseq (const sseq_bounds &b, const basedvector &pages_) - : bounds(b), pages(pages_) + sseq (const sseq_bounds &b, + const basedvector &pages_) + : bounds(b), + pages(pages_) { } sseq (const sseq_bounds &b) : bounds(b) @@ -87,7 +122,12 @@ class sseq sseq (const sseq &ss) : bounds(ss.bounds), pages(ss.pages) { } ~sseq () { } - sseq &operator = (const sseq &ss) { bounds = ss.bounds; pages = ss.pages; return *this; } + sseq &operator = (const sseq &ss) + { + bounds = ss.bounds; + pages = ss.pages; + return *this; + } sseq operator + (const sseq &ss2) const; // direct sum sseq otimes (const sseq &ss2) const; // tensor product @@ -99,285 +139,158 @@ class sseq bool operator == (const sseq &ss) const { return bounds == ss.bounds && pages == ss.pages; } bool operator != (const sseq &ss) const { return !operator == (ss); } - - bool equal_as_spaces (const sseq &ss) const; - - void texshow (FILE *fp, std::string name); + template void texshow (FILE *fp, M m); }; -#if 0 -template class simplified_complex_generators +template +sseq_page::sseq_page (const sseq_bounds &b, + unsigned k_, + grading dk_gr_, + mod_map dk, + M m) + : k(k_), + dk_gr(dk_gr_), + rank(b.width ()), + im_rank(b.width ()) { - unsigned new_n; - ptr > C; - basedvector new_C_to_C_generator; + dk.check_grading (dk_gr); -public: - simplified_complex_generators (const simplified_complex_generators &g) - : new_n(g.new_n), - C(g.C), - new_C_to_C_generator(g.new_C_to_C_generator) - { } - simplified_complex_generators (unsigned new_n_, - ptr > C_, - basedvector new_C_to_C_generator_) - : new_n(new_n_), - C(C_), - new_C_to_C_generator(new_C_to_C_generator_) - { } - ~simplified_complex_generators () { } + grading m_dk_gr = m.map_delta(dk_gr); - simplified_complex_generators &operator = (const simplified_complex_generators &) = delete; - - unsigned dim () const { return new_n; } - unsigned free_rank () const { return new_n; } - grading generator_grading (unsigned i) const { return C->generator_grading (new_C_to_C_generator[i]); } - void show_generator (unsigned i) const { C->show_generator (new_C_to_C_generator[i]); } - R generator_ann (unsigned i) const { abort (); } -}; - -template -class chain_complex_simplifier -{ - public: - typedef typename R::linear_combination linear_combination; - typedef typename R::linear_combination_const_iter linear_combination_const_iter; - - public: - ptr > C; - unsigned n; // |C| - const mod_map &d; - - ptr > new_C; - mod_map new_d; - - // chain homotopy equivalences - // pi : C -> new_C, iota : new_C -> C - mod_map pi, iota; - - private: - basedvector new_d0; - basedvector, 1> preim; - - bool build_pi_iota; - mod_map pi0, iota0; - set canceled; - - void cancel (unsigned i, R b, unsigned j); - - public: - chain_complex_simplifier (ptr > C_, - const mod_map &d_, - int dh, - bool build_pi_iota_ = 0); - -}; - -template void -chain_complex_simplifier::cancel (unsigned i, R b, unsigned j) -{ - assert (i != j); - assert (b.is_unit ()); - - R binv = b.recip (); - - canceled.push (i); - canceled.push (j); - - new_d0[i].yank (j); - preim[j].yank (i); - - for (linear_combination_const_iter k = new_d0[i]; k; k ++) - preim[k.key ()].yank (i); - for (set_const_iter k = preim[i]; k; k ++) - new_d0[k.val ()].yank (i); - for (linear_combination_const_iter k = new_d0[j]; k; k ++) - preim[k.key ()].yank (j); - - if (build_pi_iota) + for (unsigned i = 0; i < b.width (); i ++) { - mod_map local_pi0 (C, 1), - local_iota0 (C, 1); + vector r (b.height ()), + im_r (b.height ()); + for (unsigned j = 0; j < b.height (); j ++) + r[j] = im_r[j] = 0; - local_pi0[i].clear (); - local_pi0[j].clear (); - - local_iota0[i].clear (); - local_iota0[j].clear (); - - for (linear_combination_const_iter ll = new_d0[i]; ll; ll ++) - { - R c = ll.val (); - local_pi0[j].mulsub (binv * c, ll.key ()); - } - - for (set_const_iter kk = preim[j]; kk; kk ++) - { - unsigned k = kk.val (); - R a = new_d0[k](j); - assert (a != 0); - - local_iota0[k].mulsub (a * binv, i); - } - - pi0 = local_pi0.compose (pi0); - iota0 = iota0.compose (local_iota0); + rank[i] = r; + im_rank[i] = im_r; } - for (set_const_iter kk = preim[j]; kk; kk ++) + ptr > C = dk.domain (); + for (unsigned i = 1; i <= C->dim (); i ++) { - unsigned k = kk.val (); - R a = new_d0[k](j); - assert (a != 0); - - R abinv = a * binv; - - for (linear_combination_const_iter ll = new_d0[i]; ll; ll ++) - { - unsigned ell = ll.key (); - R c = ll.val (); - - assert (! (canceled % k)); - assert (! (canceled % ell)); - assert (k != i); - assert (k != j); - assert (ell != i); - assert (ell != j); - assert (ell != k); - - new_d0[k].mulsub (abinv * c, ell); - if (new_d0[k] % ell) - preim[ell] += k; - else - preim[ell] -= k; - } + grading gr = m(C->generator_grading (i)); + rank[(unsigned)(gr.h - b.minh)][(unsigned)(gr.q - b.minq)] ++; } - for (set_const_iter k = preim[j]; k; k ++) - new_d0[k.val ()].yank (j); - - new_d0[i].clear (); - preim[i].clear (); - new_d0[j].clear (); - preim[j].clear (); - -#if 0 // expensive - if (build_pi_iota) + ptr > im = dk.image (); + for (unsigned i = 1; i <= im->dim (); i ++) { - assert (pi0.compose (d) == new_d0.compose (pi0)); - assert (iota0.compose (new_d0) == d.compose (iota0)); + grading gr = m(im->generator_grading (i)); + im_rank[(unsigned)(gr.h - m_dk_gr.h - b.minh)][(unsigned)(gr.q - m_dk_gr.q - b.minq)] ++; } -#endif } -template -chain_complex_simplifier::chain_complex_simplifier (ptr > C_, - const mod_map &d_, - int dh, - bool build_pi_iota_) - : C(C_), n(C_->dim ()), d(d_), - new_d0(COPY2, d_.explicit_columns ()), - preim(C_->dim ()), - build_pi_iota(build_pi_iota_) + +template void +sseq_page::texshow (FILE *fp, const sseq_bounds &b, const char *label, M m) { + grading m_dk_gr = m.map_delta(dk_gr); + + unsigned dh = m_dk_gr.h, + dq = m_dk_gr.q; + + fprintf (fp, "\ +\\begin{tikzpicture}[scale=.66]\n\ + \\draw[->] (0,0) -- (%d.5,0) node[right] {$t$};\n\ + \\draw[->] (0,0) -- (0,%d.5) node[above] {$q$};\n\ + \\draw[step=1] (0,0) grid (%d,%d);\n", + b.width (), b.height (), b.width (), b.height ()); + + fprintf (fp, " \\draw (%.3f,-0.8) node[below] {%s};\n", + ((double)b.width () + 0.5) / 2, label); + + /* label axes */ + for (int x = b.minh; x <= b.maxh; x ++) + { + fprintf (fp, "\ + \\draw (%d.5,-.2) node[below] {$", + x - b.minh); + m.x_label (fp, x); + fprintf (fp, "$};\n"); + } + for (int y = b.minq; y <= b.maxq; y ++) + { + fprintf (fp, "\ + \\draw (-.2,%d.5) node[left] {$", + y - b.minq); + m.y_label (fp, y); + fprintf (fp, "$};\n"); + } + + for (unsigned i = 0; i < b.width (); i ++) + for (unsigned j = 0; j < b.height (); j ++) + { + int r = rank[i][j]; + if (r == 1) + { + fprintf (fp, "\ + \\fill (%d.5, %d.5) circle (.15);\n", + i, j); + } + else if (r > 1) + { + fprintf (fp, "\ + \\draw (%d.5, %d.5) node {$%d$};\n", + i, j, r); + } + } + + for (unsigned i = 0; i < b.width (); i ++) + for (unsigned j = 0; j < b.height (); j ++) + { + unsigned r = im_rank[i][j]; + if (r == 0) + continue; + + int dx = dh, + dy = dq; // in "boxes" + + double h = sqrt ((double)(dx * dx + dy * dy)); + double xadj = (double)dx / h * 0.3; + double yadj = (double)dy / h * 0.3; + + fprintf (fp, " \\draw[->] (%.3f, %.3f) -- ", + (double)i + 0.5 + xadj, (double)j + 0.5 + yadj); + if (r > 1) + fprintf (fp, "node[color=red!75!black] {$%d$} ", r); + fprintf (fp, "(%.3f, %.3f);\n", + (double)((int)i + dx) + 0.5 - xadj, (double)((int)j + dy) + 0.5 - yadj); + } + + fprintf (fp, "\ +\\end{tikzpicture}\n"); + + fflush (fp); +} + +template void +sseq::texshow (FILE *fp, M m) +{ + unsigned n = pages.size (); for (unsigned i = 1; i <= n; i ++) { - for (linear_combination_const_iter j = d[i]; j; j ++) - preim[j.key ()].push (i); + if (i == n) + fprintf (fp, "$\\rank E_\\infty = \\rank E_%d = %d$ \\\\\n", + pages[i].k, pages[i].total_rank ()); + else + fprintf (fp, "$\\rank E_%d = %d$ \\\\\n", + pages[i].k, pages[i].total_rank ()); } - if (build_pi_iota) + for (unsigned i = 1; i <= n; i ++) { - pi0 = mod_map (C, 1); - iota0 = mod_map (C, 1); - -#if 0 // expensive - assert (pi0.compose (d) == new_d0.compose (pi0)); - assert (iota0.compose (new_d0) == d.compose (iota0)); -#endif - } - - Lretry: - for (unsigned i = n; i >= 1; i --) - { - if (canceled % i) - continue; - - grading igr = C->generator_grading (i); - for (linear_combination_const_iter j = new_d0[i]; j; j ++) - { - grading jgr = C->generator_grading (j.key ()); - assert (jgr.h >= igr.h); - if (j.val ().is_unit () - && jgr.h - igr.h == dh) - { - cancel (i, j.val (), j.key ()); - goto Lretry; - } - } - } - - unsigned new_n = n - canceled.card (); - basedvector new_C_to_C_generator (new_n), - C_to_new_C_generator (n); - for (unsigned i = 1, j = 1; i <= n; i ++) - { - if (canceled % i) - { - C_to_new_C_generator[i] = 0; - continue; - } - - C_to_new_C_generator[i] = j; - new_C_to_C_generator[j] = i; - j ++; - } - - new_C = (new base_module > - (simplified_complex_generators (new_n, C, new_C_to_C_generator))); - new_d = mod_map (new_C); - - for (unsigned i = 1; i <= new_n; i ++) - { - unsigned i0 = new_C_to_C_generator[i]; - - for (linear_combination_const_iter j0 = new_d0[i0]; j0; j0 ++) - { - unsigned j = C_to_new_C_generator[j0.key ()]; - assert (j != 0); - - new_d[i].muladd (j0.val (), j); - } - } - - if (build_pi_iota) - { - pi = mod_map (C, new_C); - iota = mod_map (new_C, C); - - for (unsigned i0 = 1; i0 <= n; i0 ++) - { - for (linear_combination_const_iter j0 = pi0[i0]; j0; j0 ++) - { - unsigned j = C_to_new_C_generator[j0.key ()]; - pi[i0].muladd (j0.val (), j); - } - } - - for (unsigned i = 1; i <= new_n; i ++) - { - unsigned i0 = new_C_to_C_generator[i]; - iota[i] = iota0[i0]; - } - -#if 0 // expensive - assert (pi.compose (d) == new_d.compose (pi)); - assert (d.compose (iota) == iota.compose (new_d)); -#endif + char buf[1000]; + if (i == n) + sprintf (buf, "$E_\\infty = E_{%d}$", pages[i].k); + else + sprintf (buf, "$E_{%d}$", pages[i].k); + pages[i].texshow (fp, bounds, buf, m); } } -#endif class sseq_builder {