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.
This commit is contained in:
Cotton Seed 2013-03-25 16:39:15 -04:00
parent 76bc2c9200
commit ad0f60f5c0
19 changed files with 1326 additions and 880 deletions

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
*~
*.o
/gss
/kk
/main
/testsurfaces
/serial.cmd.[eo]*

View File

@ -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

157
README
View File

@ -1 +1,156 @@
I modified cotton's readme.
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, 554586, arXiv:math/0210213.
D. Bar-Natan, Khovanovs homology for tangles and cobordisms,
Geom. Topol. 9 (2005), 14431499, 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 <invariant> [options...] <link>
compute <invariant> for knot or link <link>
<invariant> 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 <file> : write output to <file>
(stdout is the default)
-f <field> : ground field (if applicable)
(Z2 is the default)
-v : verbose: report progress as the computation proceeds
<field> can be one of:
Z2, Z3, Q
<link> 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.

View File

@ -53,7 +53,8 @@ class module : public refcounted
// r < i <= n
virtual R generator_ann (unsigned i) const = 0;
basedvector<grading, 1> grading_vector () const;
set<grading> gradings () const;
bool is_free () const { return dim () == free_rank (); }
@ -1503,6 +1504,15 @@ module<R>::free_ell_poincare_polynomial () const
return r;
}
template<class R> basedvector<grading, 1>
module<R>::grading_vector () const
{
basedvector<grading, 1> v (dim ());
for (unsigned i = 1; i <= dim (); i ++)
v[i] = generator_grading (i);
return v;
}
template<class R> set<grading>
module<R>::gradings () const
{

View File

@ -329,6 +329,13 @@ cube<R>::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<R>::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<R>::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 ++)
{

126
gss.cpp
View File

@ -1,126 +0,0 @@
#include <knotkit.h>
const char *program_name;
void
usage ()
{
printf ("usage: %s [-f] [-h] [-o <file>] [-v] <knot>\n", program_name);
printf (" compute Szabo's geometric spectral sequence for knot <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 <file> : write output to <file>\n");
printf (" (stdout is the default)\n");
printf (" -v : verbose: report progress as the computation proceeds\n");
printf ("<knot> 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 <knot> 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<Z2> 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);
}

660
kk.cpp Normal file
View File

@ -0,0 +1,660 @@
#include <knotkit.h>
const char *program_name;
void
usage ()
{
printf ("usage: %s <invariant> [options...] <link>\n", program_name);
printf (" compute <invariant> for knot or link <link>\n");
printf ("<invariant> 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 <file> : write output to <file>\n");
printf (" (stdout is the default)\n");
printf (" -f <field> : ground field (if applicable)\n");
printf (" (Z2 is the default)\n");
printf (" -v : verbose: report progress as the computation proceeds\n");
printf ("<field> can be one of:\n");
printf (" Z2, Z3, Q\n");
printf ("<link> 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<class R> mod_map<R>
compute_link_splitting_d (knot_diagram &kd,
cube<R> &c,
basedvector<R, 1> 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<unsigned, unsigned> 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<unsigned, R> crossing_over_sign;
// crossings
set<unsigned> pending;
set<unsigned> 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<R> untwisted_d = c.compute_d (1, 0, 0, 0, 0);
assert (untwisted_d.compose (untwisted_d) == 0);
mod_map<R> 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<Z2> c (kd, reduced);
ptr<const module<Z2> > C = c.khC;
mod_map<Z2> 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<sseq_page, 1> pages;
unsigned k = 1;
for (;;)
{
chain_complex_simplifier<Z2> s (C, d,
maybe<int> (k), maybe<int> (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<class R> void
compute_invariant ()
{
if (!strcmp (invariant, "kh"))
{
cube<R> c (kd, reduced);
ptr<const module<R> > C = c.khC;
mod_map<R> d = c.compute_d (1, 0, 0, 0, 0);
unsigned m = kd.num_components ();
hg_grading_mapper mapper (m);
chain_complex_simplifier<R> s (C, d,
maybe<int> (1), maybe<int> (0));
C = s.new_C;
d = s.new_d;
sseq_bounds b (C, mapper);
sseq_page pg (b, 2, grading (0, 0), mod_map<R> (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<R> c (kd, reduced);
ptr<const module<R> > C = c.khC;
unsigned m = kd.num_components ();
basedvector<R, 1> comp_weight (m);
for (unsigned i = 1; i <= m; i ++)
comp_weight[i] = R ((int)(i - 1));
mod_map<R> d = compute_link_splitting_d (kd, c, comp_weight);
hg_grading_mapper mapper (m);
sseq_bounds b (C, mapper);
basedvector<sseq_page, 1> pages;
int k = 0;
for (;;)
{
chain_complex_simplifier<R> s (C, d,
maybe<int> (1 - 2*k), maybe<int> (-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<R> c (kd, reduced);
ptr<const module<R> > C = c.khC;
mod_map<R> 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<sseq_page, 1> pages;
int k = 0;
for (;;)
{
chain_complex_simplifier<R> s (C, d,
maybe<int> (1), maybe<int> (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<R> c (kd, 0);
ptr<const module<R> > C = c.khC;
mod_map<R> 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<R> s (C, d,
maybe<int> (1), maybe<int> (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<grading, basedvector<unsigned, 1> > hq_gens,
ptr<const module<Z2> > H)
{
fprintf (fp, "hom={");
bool first = 1;
for (map<grading, basedvector<unsigned, 1> >::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<grading, basedvector<unsigned, 1> > hq_gens,
std::string name,
grading delta,
mod_map<Z2> f)
{
fprintf (fp, "%s={", name.c_str ());
bool first = 1;
for (map<grading, basedvector<unsigned, 1> >::const_iter i = hq_gens; i; i ++)
{
grading from_hq = i.key ();
basedvector<unsigned, 1> from_gens = i.val ();
grading to_hq = from_hq + delta;
if (hq_gens % to_hq)
{
basedvector<unsigned, 1> 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<const module<Z2> > H,
mod_map<Z2> sq1,
mod_map<Z2> sq2)
{
unsigned n = H->dim ();
map<grading, basedvector<unsigned, 1> > hq_gens;
for (unsigned i = 1; i <= H->dim (); i ++)
hq_gens[H->generator_grading (i)].append (i);
unsigned t = 0;
for (map<grading, basedvector<unsigned, 1> >::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<Z2> c (kd);
mod_map<Z2> d = c.compute_d (1, 0, 0, 0, 0);
chain_complex_simplifier<Z2> s (c.khC, d, maybe<int> (1), maybe<int> (0));
assert (s.new_d == 0);
steenrod_square sq (c, d, s);
mod_map<Z2> sq1 = sq.sq1 ();
mod_map<Z2> sq2 = sq.sq2 ();
ptr<const module<Z2> > 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, <invariant> or <knot> 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<Z2> ();
else if (!strcmp (field, "Z3"))
compute_invariant<Zp<3> > ();
else if (!strcmp (field, "Q"))
compute_invariant<Q> ();
else
{
fprintf (stderr, "error: unknown field %s\n", field);
exit (EXIT_FAILURE);
}
}
if (file)
fclose (outfp);
}

View File

@ -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;

View File

@ -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 ("<parsed>", *(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 ("<parsed>", *(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<basedvector<int, 1>, 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 ("<parsed>", *(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 ("<parsed>", (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<basedvector<int, 1>, 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<basedvector<int, 1>, 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<int, 1> *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<int, 1> *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<basedvector<int, 1>, 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<basedvector<int, 1>, 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<int, 1> *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;
}

View File

@ -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 <knotkit.h>
/* 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 <string>
#include <iostream>
#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 */

View File

@ -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 <iostream>
# include <string>
# 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 */

View File

@ -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 <algorithm> // std::max
# include <iostream>
# include <string>
# include <algorithm>
# 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 */

View File

@ -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 <deque>
#ifndef YY_YY_KNOT_PARSER_STACK_HH_INCLUDED
# define YY_YY_KNOT_PARSER_STACK_HH_INCLUDED
# include <deque>
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 T, class S = std::deque<T> >
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 */

View File

@ -1,8 +1,6 @@
#include <knotkit.h>
#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)

View File

@ -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<Q> (kd);
ss.texshow (stdout, "L5a3");
}

View File

@ -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;
}

View File

@ -63,8 +63,7 @@ class chain_complex_simplifier
public:
chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_,
int dq);
maybe<int> dh, maybe<int> dq);
};
template<class R> void
@ -145,7 +144,7 @@ chain_complex_simplifier<R>::cancel (unsigned i, R b, unsigned j)
template<class R>
chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_,
int dq)
maybe<int> dh, maybe<int> dq)
: C(C_), n(C_->dim ()), d(d_),
new_d_columns(n),
preim(n),
@ -173,8 +172,10 @@ chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > 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;

114
sseq.cpp
View File

@ -2,7 +2,8 @@
#include <knotkit.h>
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)
{

437
sseq.h
View File

@ -7,6 +7,27 @@ class sseq_bounds
public:
sseq_bounds () { }
template<class R, class M> sseq_bounds (ptr<const module<R> > 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<vector<unsigned> > rank,
im_rank;
public:
sseq_page () { }
sseq_page (const sseq_bounds &b);
template<class R, class M> sseq_page (const sseq_bounds &b,
unsigned k_,
grading dk_gr_,
mod_map<R> 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<Z> poincare_polynomial (const sseq_bounds &b) const;
multivariate_laurentpoly<Z> 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<class M> 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<sseq_page, 1> &pages_)
: bounds(b), pages(pages_)
sseq (const sseq_bounds &b,
const basedvector<sseq_page, 1> &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<class M> void texshow (FILE *fp, M m);
};
#if 0
template<class R> class simplified_complex_generators
template<class R, class M>
sseq_page::sseq_page (const sseq_bounds &b,
unsigned k_,
grading dk_gr_,
mod_map<R> dk,
M m)
: k(k_),
dk_gr(dk_gr_),
rank(b.width ()),
im_rank(b.width ())
{
unsigned new_n;
ptr<const module<R> > C;
basedvector<unsigned, 1> 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<const module<R> > C_,
basedvector<unsigned, 1> 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 R>
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<const module<R> > C;
unsigned n; // |C|
const mod_map<R> &d;
ptr<const module<R> > new_C;
mod_map<R> new_d;
// chain homotopy equivalences
// pi : C -> new_C, iota : new_C -> C
mod_map<R> pi, iota;
private:
basedvector<linear_combination, 1> new_d0;
basedvector<set<unsigned>, 1> preim;
bool build_pi_iota;
mod_map<R> pi0, iota0;
set<unsigned> canceled;
void cancel (unsigned i, R b, unsigned j);
public:
chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_,
int dh,
bool build_pi_iota_ = 0);
};
template<class R> void
chain_complex_simplifier<R>::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<unsigned> 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<R> local_pi0 (C, 1),
local_iota0 (C, 1);
vector<unsigned> 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<unsigned> 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<unsigned> kk = preim[j]; kk; kk ++)
ptr<const module<R> > 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<unsigned> 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<const free_submodule<R> > 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<class R>
chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &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<class M> 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<class M> 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<R> (C, 1);
iota0 = mod_map<R> (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<unsigned, 1> 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<R, simplified_complex_generators<R> >
(simplified_complex_generators<R> (new_n, C, new_C_to_C_generator)));
new_d = mod_map<R> (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<R> (C, new_C);
iota = mod_map<R> (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
{