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 *.o
/gss /kk
/main /main
/testsurfaces /testsurfaces
/serial.cmd.[eo]* /serial.cmd.[eo]*

View File

@ -1,21 +1,22 @@
BISON = /opt/local/bin/bison devel = 1
FLEX = /opt/local/bin/flex
BISON = bison
FLEX = flex
# CXX = g++ # 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 = 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 = -g
OPTFLAGS = -O2 -g # OPTFLAGS = -O2 -g
# OPTFLAGS = -O2 -DNDEBUG # OPTFLAGS = -O2 -DNDEBUG
LDFLAGS = -L/opt/local/lib -L/u/cseed/llvm-3.1/lib LDFLAGS = -L/opt/local/lib
# LDFLAGS = -pg -L/opt/local/lib
CXXFLAGS = $(OPTFLAGS) -Wall -Wno-unused $(INCLUDES) CXXFLAGS = $(OPTFLAGS) -DHOME="\"`pwd`\"" -Wall -Wno-unused $(INCLUDES)
LIB_OBJS = lib/refcount.o \ LIB_OBJS = lib/refcount.o \
lib/lib.o lib/smallbitset.o lib/bitset.o lib/setcommon.o lib/io.o lib/directed_multigraph.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 LIBS = -lgmp -lz
all: gss all: kk
%.o : %.cc %.o : %.cc
$(CXX) -c $(CXXFLAGS) $< -o $@ $(CXX) -c $(CXXFLAGS) $< -o $@
@ -53,8 +54,8 @@ all: gss
%.o : %.cpp %.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@ $(CXX) -c $(CXXFLAGS) $< -o $@
gss: gss.o $(COMMON_OBJS) kk: kk.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o gss $^ $(LIBS) $(CXX) $(LDFLAGS) -o kk $^ $(LIBS)
main: main.o $(COMMON_OBJS) main: main.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o main $^ $(LIBS) $(CXX) $(LDFLAGS) -o main $^ $(LIBS)
@ -65,6 +66,7 @@ mpimain: mpimain.o mpi_aux.o $(COMMON_OBJS)
testlib: testlib.o $(COMMON_OBJS) testlib: testlib.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o testlib $^ $(CXX) $(LDFLAGS) -o testlib $^
ifeq ($(devel),1)
knot_parser/knot_parser.cc knot_parser/knot_parser.hh: knot_parser/knot_parser.yy 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 $(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 rd_parser/rd_scanner.cc: rd_parser/rd_scanner.ll
$(FLEX) -o 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 .PHONY: parser_files
parser_files: \ parser_files: \
@ -95,7 +98,7 @@ parser_files: \
.PHONY: clean .PHONY: clean
clean: clean:
rm -f *.o lib/*.o algebra/*.o knot_parser/*.o rd_parser/*.o 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 rm -f gmon.out
.PHONY: realclean .PHONY: realclean
@ -112,6 +115,6 @@ realclean: clean
$(LIB_OBJS): $(LIB_HEADERS) $(LIB_OBJS): $(LIB_HEADERS)
$(ALGEBRA_OBJS): $(ALGEBRA_HEADERS) $(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 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 // r < i <= n
virtual R generator_ann (unsigned i) const = 0; virtual R generator_ann (unsigned i) const = 0;
basedvector<grading, 1> grading_vector () const;
set<grading> gradings () const; set<grading> gradings () const;
bool is_free () const { return dim () == free_rank (); } bool is_free () const { return dim () == free_rank (); }
@ -1503,6 +1504,15 @@ module<R>::free_ell_poincare_polynomial () const
return r; 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> template<class R> set<grading>
module<R>::gradings () const 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 ++) 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; unsigned j2 = 0;
for (unsigned_const_iter k = j; k; k ++) for (unsigned_const_iter k = j; k; k ++)
{ {
@ -372,7 +379,7 @@ cube<R>::compute_dinv (unsigned c)
{ {
if (!unsigned_bittest (i, c)) if (!unsigned_bittest (i, c))
continue; continue;
int sign = 1; int sign = 1;
for (unsigned j = 1; j < c; j ++) 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); y = to_s.crossing_to_circle (kd, c);
for (unsigned j = 0; j < from_s.num_monomials (); j ++) 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; unsigned j2 = 0;
for (unsigned_const_iter k = j; k; k ++) 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)); assert (is_even (lk));
lk /= 2; lk /= 2;
total_lk += std::abs (lk); total_lk += abs (lk);
} }
return total_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++ /* Skeleton implementation for Bison LALR(1) parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Copyright (C) 2002-2012 Free Software Foundation, Inc.
Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -34,37 +33,41 @@
/* First part of user declarations. */ /* First part of user declarations. */
/* Line 278 of lalr1.cc */
/* Line 311 of lalr1.cc */ #line 38 "knot_parser/knot_parser.cc"
#line 40 "knot_parser/knot_parser.cc"
#include "knot_parser.hh" #include "knot_parser.hh"
/* User implementation prologue. */ /* User implementation prologue. */
/* Line 284 of lalr1.cc */
/* Line 317 of lalr1.cc */ #line 46 "knot_parser/knot_parser.cc"
#line 49 "knot_parser/knot_parser.cc"
/* Unqualified %code blocks. */ /* Unqualified %code blocks. */
/* Line 285 of lalr1.cc */
/* Line 318 of lalr1.cc */
#line 15 "knot_parser/knot_parser.yy" #line 15 "knot_parser/knot_parser.yy"
#define YY_DECL \ #define YY_DECL \
yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval) yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval)
YY_DECL; YY_DECL;
/* Line 285 of lalr1.cc */
/* Line 318 of lalr1.cc */
#line 29 "knot_parser/knot_parser.yy" #line 29 "knot_parser/knot_parser.yy"
#define yylex knot_yylex #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_ #ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS # if defined YYENABLE_NLS && YYENABLE_NLS
@ -78,6 +81,27 @@ YY_DECL;
# endif # endif
#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. */ /* Suppress unused-variable warnings by "using" E. */
#define YYUSE(e) ((void) (e)) #define YYUSE(e) ((void) (e))
@ -128,49 +152,8 @@ do { \
namespace yy { namespace yy {
/* Line 352 of lalr1.cc */
/* Line 380 of lalr1.cc */ #line 157 "knot_parser/knot_parser.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
/// Build a parser object. /// Build a parser object.
knot_parser::knot_parser (knot_diagram &parsed_knot_yyarg) knot_parser::knot_parser (knot_diagram &parsed_knot_yyarg)
@ -198,6 +181,9 @@ namespace yy {
{ {
YYUSE (yylocationp); YYUSE (yylocationp);
YYUSE (yyvaluep); YYUSE (yyvaluep);
std::ostream& yyo = debug_stream ();
std::ostream& yyoutput = yyo;
YYUSE (yyoutput);
switch (yytype) switch (yytype)
{ {
default: default:
@ -271,6 +257,18 @@ namespace yy {
} }
#endif #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 int
knot_parser::parse () knot_parser::parse ()
{ {
@ -278,17 +276,18 @@ namespace yy {
int yychar = yyempty_; int yychar = yyempty_;
int yytoken = 0; int yytoken = 0;
/* State. */ // State.
int yyn; int yyn;
int yylen = 0; int yylen = 0;
int yystate = 0; int yystate = 0;
/* Error handling. */ // Error handling.
int yynerrs_ = 0; int yynerrs_ = 0;
int yyerrstatus_ = 0; int yyerrstatus_ = 0;
/// Semantic value of the lookahead. /// Semantic value of the lookahead.
semantic_type yylval; static semantic_type yyval_default;
semantic_type yylval = yyval_default;
/// Location of the lookahead. /// Location of the lookahead.
location_type yylloc; location_type yylloc;
/// The locations where the error started and ended. /// The locations where the error started and ended.
@ -330,7 +329,7 @@ namespace yy {
/* Try to take a decision without lookahead. */ /* Try to take a decision without lookahead. */
yyn = yypact_[yystate]; yyn = yypact_[yystate];
if (yyn == yypact_ninf_) if (yy_pact_value_is_default_ (yyn))
goto yydefault; goto yydefault;
/* Read a lookahead token. */ /* Read a lookahead token. */
@ -340,7 +339,6 @@ namespace yy {
yychar = yylex (&yylval); yychar = yylex (&yylval);
} }
/* Convert token to internal form. */ /* Convert token to internal form. */
if (yychar <= yyeof_) if (yychar <= yyeof_)
{ {
@ -363,8 +361,8 @@ namespace yy {
yyn = yytable_[yyn]; yyn = yytable_[yyn];
if (yyn <= 0) if (yyn <= 0)
{ {
if (yyn == 0 || yyn == yytable_ninf_) if (yy_table_value_is_error_ (yyn))
goto yyerrlab; goto yyerrlab;
yyn = -yyn; yyn = -yyn;
goto yyreduce; goto yyreduce;
} }
@ -419,8 +417,7 @@ namespace yy {
switch (yyn) switch (yyn)
{ {
case 10: case 10:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 67 "knot_parser/knot_parser.yy" #line 67 "knot_parser/knot_parser.yy"
{ {
unsigned n = (yysemantic_stack_[(3) - (1)].integer), unsigned n = (yysemantic_stack_[(3) - (1)].integer),
@ -439,8 +436,7 @@ namespace yy {
break; break;
case 11: case 11:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 85 "knot_parser/knot_parser.yy" #line 85 "knot_parser/knot_parser.yy"
{ {
unsigned n = (yysemantic_stack_[(3) - (1)].integer), unsigned n = (yysemantic_stack_[(3) - (1)].integer),
@ -460,8 +456,7 @@ namespace yy {
break; break;
case 12: case 12:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 104 "knot_parser/knot_parser.yy" #line 104 "knot_parser/knot_parser.yy"
{ {
unsigned n = (yysemantic_stack_[(4) - (2)].integer), unsigned n = (yysemantic_stack_[(4) - (2)].integer),
@ -481,22 +476,19 @@ namespace yy {
break; break;
case 13: case 13:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 123 "knot_parser/knot_parser.yy" #line 123 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (planar_diagram ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); } { parsed_knot = knot_diagram (planar_diagram ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); }
break; break;
case 14: case 14:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 125 "knot_parser/knot_parser.yy" #line 125 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (planar_diagram ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); } { parsed_knot = knot_diagram (planar_diagram ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); }
break; break;
case 15: case 15:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 130 "knot_parser/knot_parser.yy" #line 130 "knot_parser/knot_parser.yy"
{ {
basedvector<basedvector<int, 1>, 1> even_labels (1); basedvector<basedvector<int, 1>, 1> even_labels (1);
@ -506,36 +498,31 @@ namespace yy {
break; break;
case 16: case 16:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 136 "knot_parser/knot_parser.yy" #line 136 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (dt_code ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); } { parsed_knot = knot_diagram (dt_code ("<parsed>", *(yysemantic_stack_[(4) - (3)].int_vec2))); }
break; break;
case 17: case 17:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 138 "knot_parser/knot_parser.yy" #line 138 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (dt_code ("<parsed>", (yysemantic_stack_[(4) - (3)].string))); } { parsed_knot = knot_diagram (dt_code ("<parsed>", (yysemantic_stack_[(4) - (3)].string))); }
break; break;
case 18: case 18:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 143 "knot_parser/knot_parser.yy" #line 143 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (torus_knot ((yysemantic_stack_[(6) - (3)].integer), (yysemantic_stack_[(6) - (5)].integer))); } { parsed_knot = knot_diagram (torus_knot ((yysemantic_stack_[(6) - (3)].integer), (yysemantic_stack_[(6) - (5)].integer))); }
break; break;
case 19: case 19:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 148 "knot_parser/knot_parser.yy" #line 148 "knot_parser/knot_parser.yy"
{ parsed_knot = knot_diagram (braid ((yysemantic_stack_[(6) - (3)].integer), *(yysemantic_stack_[(6) - (5)].int_vec))); } { parsed_knot = knot_diagram (braid ((yysemantic_stack_[(6) - (3)].integer), *(yysemantic_stack_[(6) - (5)].int_vec))); }
break; break;
case 20: case 20:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 153 "knot_parser/knot_parser.yy" #line 153 "knot_parser/knot_parser.yy"
{ {
unsigned unknot_ar[1][4] = { unsigned unknot_ar[1][4] = {
@ -546,8 +533,7 @@ namespace yy {
break; break;
case 23: case 23:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 168 "knot_parser/knot_parser.yy" #line 168 "knot_parser/knot_parser.yy"
{ {
basedvector<basedvector<int, 1>, 1> *v basedvector<basedvector<int, 1>, 1> *v
@ -558,8 +544,7 @@ namespace yy {
break; break;
case 24: case 24:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 175 "knot_parser/knot_parser.yy" #line 175 "knot_parser/knot_parser.yy"
{ {
basedvector<basedvector<int, 1>, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2); basedvector<basedvector<int, 1>, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2);
@ -569,22 +554,19 @@ namespace yy {
break; break;
case 25: case 25:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 184 "knot_parser/knot_parser.yy" #line 184 "knot_parser/knot_parser.yy"
{ (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); } { (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); }
break; break;
case 26: case 26:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 186 "knot_parser/knot_parser.yy" #line 186 "knot_parser/knot_parser.yy"
{ (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); } { (yyval.int_vec) = (yysemantic_stack_[(3) - (2)].int_vec); }
break; break;
case 27: case 27:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 191 "knot_parser/knot_parser.yy" #line 191 "knot_parser/knot_parser.yy"
{ {
basedvector<int, 1> *v = basedvector<int, 1> *v =
@ -595,8 +577,7 @@ namespace yy {
break; break;
case 28: case 28:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 198 "knot_parser/knot_parser.yy" #line 198 "knot_parser/knot_parser.yy"
{ {
basedvector<int, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec); basedvector<int, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec);
@ -606,8 +587,7 @@ namespace yy {
break; break;
case 29: case 29:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 207 "knot_parser/knot_parser.yy" #line 207 "knot_parser/knot_parser.yy"
{ {
basedvector<basedvector<int, 1>, 1> *v basedvector<basedvector<int, 1>, 1> *v
@ -618,8 +598,7 @@ namespace yy {
break; break;
case 30: case 30:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 214 "knot_parser/knot_parser.yy" #line 214 "knot_parser/knot_parser.yy"
{ {
basedvector<basedvector<int, 1>, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2); basedvector<basedvector<int, 1>, 1> *v = (yysemantic_stack_[(3) - (1)].int_vec2);
@ -629,8 +608,7 @@ namespace yy {
break; break;
case 31: case 31:
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */
#line 223 "knot_parser/knot_parser.yy" #line 223 "knot_parser/knot_parser.yy"
{ {
basedvector<int, 1> *v basedvector<int, 1> *v
@ -644,12 +622,22 @@ namespace yy {
break; break;
/* Line 661 of lalr1.cc */
/* Line 678 of lalr1.cc */ #line 627 "knot_parser/knot_parser.cc"
#line 650 "knot_parser/knot_parser.cc"
default: default:
break; 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); YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc);
yypop_ (yylen); yypop_ (yylen);
@ -673,11 +661,17 @@ namespace yy {
| yyerrlab -- here on detecting error | | yyerrlab -- here on detecting error |
`------------------------------------*/ `------------------------------------*/
yyerrlab: 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 not already recovering from an error, report this error. */
if (!yyerrstatus_) if (!yyerrstatus_)
{ {
++yynerrs_; ++yynerrs_;
error (yylloc, yysyntax_error_ (yystate)); if (yychar == yyempty_)
yytoken = yyempty_;
error (yylloc, yysyntax_error_ (yystate, yytoken));
} }
yyerror_range[1] = yylloc; yyerror_range[1] = yylloc;
@ -732,7 +726,7 @@ namespace yy {
for (;;) for (;;)
{ {
yyn = yypact_[yystate]; yyn = yypact_[yystate];
if (yyn != yypact_ninf_) if (!yy_pact_value_is_default_ (yyn))
{ {
yyn += yyterror_; yyn += yyterror_;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
@ -782,7 +776,13 @@ namespace yy {
yyreturn: yyreturn:
if (yychar != yyempty_) 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 /* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */ this YYABORT or YYACCEPT. */
@ -801,51 +801,9 @@ namespace yy {
// Generate an error message. // Generate an error message.
std::string std::string
knot_parser::yysyntax_error_ (int yystate) knot_parser::yysyntax_error_ (int, int)
{ {
std::string res; return YY_("syntax error");
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;
} }
@ -865,9 +823,9 @@ namespace yy {
54, 58, 59, -36 54, 58, 59, -36
}; };
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE /* YYDEFACT[S] -- default reduction number in state S. Performed when
doesn't specify something else to do. Zero means the default is an YYTABLE doesn't specify something else to do. Zero means the
error. */ default is an error. */
const unsigned char const unsigned char
knot_parser::yydefact_[] = knot_parser::yydefact_[] =
{ {
@ -899,7 +857,7 @@ namespace yy {
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which 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 signed char knot_parser::yytable_ninf_ = -1;
const unsigned char const unsigned char
knot_parser::yytable_[] = knot_parser::yytable_[] =
@ -975,7 +933,7 @@ namespace yy {
3, 10 3, 10
}; };
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE #if YYDEBUG
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */ First, the terminals, then, starting at \a yyntokens_, nonterminals. */
const char* const char*
@ -986,11 +944,10 @@ namespace yy {
"']'", "'('", "','", "')'", "'{'", "'}'", "$accept", "knot", "']'", "'('", "','", "')'", "'{'", "'}'", "$accept", "knot",
"rolfsen_knot", "htw_knot", "mt_link", "planar_diagram", "dt", "rolfsen_knot", "htw_knot", "mt_link", "planar_diagram", "dt",
"torus_link", "braid", "unknot", "alt_spec", "int_vec2", "int_vec", "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. */ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
const knot_parser::rhs_number_type const knot_parser::rhs_number_type
knot_parser::yyrhs_[] = knot_parser::yyrhs_[] =
@ -1115,12 +1072,9 @@ namespace yy {
} // yy } // yy
/* Line 1106 of lalr1.cc */
/* Line 1054 of lalr1.cc */ #line 1077 "knot_parser/knot_parser.cc"
#line 1121 "knot_parser/knot_parser.cc" /* Line 1107 of lalr1.cc */
/* Line 1056 of lalr1.cc */
#line 233 "knot_parser/knot_parser.yy" #line 233 "knot_parser/knot_parser.yy"
@ -1145,4 +1099,3 @@ parse_knot (const char *s)
return d; 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++ /* Skeleton interface for Bison LALR(1) parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Copyright (C) 2002-2012 Free Software Foundation, Inc.
Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify 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 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 This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ 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. */ /* C++ LALR(1) parser skeleton written by Akim Demaille. */
#ifndef PARSER_HEADER_H #ifndef YY_YY_KNOT_PARSER_KNOT_PARSER_HH_INCLUDED
# define PARSER_HEADER_H # define YY_YY_KNOT_PARSER_KNOT_PARSER_HH_INCLUDED
/* "%code requires" blocks. */ /* "%code requires" blocks. */
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */
#line 11 "knot_parser/knot_parser.yy" #line 11 "knot_parser/knot_parser.yy"
#include <knotkit.h> #include <knotkit.h>
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */ #line 52 "knot_parser/knot_parser.hh"
#line 50 "knot_parser/knot_parser.hh"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "stack.hh" #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" #include "location.hh"
/* Enabling traces. */ /* Enabling traces. */
@ -73,43 +61,10 @@ namespace yy {
# define YYDEBUG 0 # define YYDEBUG 0
#endif #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 { namespace yy {
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */ #line 68 "knot_parser/knot_parser.hh"
#line 113 "knot_parser/knot_parser.hh"
/// A Bison parser. /// A Bison parser.
class knot_parser class knot_parser
@ -119,8 +74,7 @@ namespace yy {
#ifndef YYSTYPE #ifndef YYSTYPE
union semantic_type union semantic_type
{ {
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */
#line 21 "knot_parser/knot_parser.yy" #line 21 "knot_parser/knot_parser.yy"
int integer; int integer;
@ -130,9 +84,8 @@ namespace yy {
const char *string; const char *string;
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */ #line 89 "knot_parser/knot_parser.hh"
#line 136 "knot_parser/knot_parser.hh"
}; };
#else #else
typedef YYSTYPE semantic_type; typedef YYSTYPE semantic_type;
@ -194,7 +147,7 @@ namespace yy {
/// Generate an error message. /// Generate an error message.
/// \param state the state where the error occurred. /// \param state the state where the error occurred.
/// \param tok the lookahead token. /// \param tok the lookahead token.
virtual std::string yysyntax_error_ (int yystate); virtual std::string yysyntax_error_ (int yystate, int tok);
#if YYDEBUG #if YYDEBUG
/// \brief Report a symbol value on the debug stream. /// \brief Report a symbol value on the debug stream.
@ -230,6 +183,14 @@ namespace yy {
/// The location stack. /// The location stack.
location_stack_type yylocation_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. /// Internal symbol numbers.
typedef unsigned char token_number_type; typedef unsigned char token_number_type;
/* Tables. */ /* Tables. */
@ -237,7 +198,7 @@ namespace yy {
static const signed char yypact_[]; static const signed char yypact_[];
static const signed char yypact_ninf_; 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. /// Unless\a yytable_ specifies something else to do.
/// Zero means the default is an error. /// Zero means the default is an error.
static const unsigned char yydefact_[]; static const unsigned char yydefact_[];
@ -261,19 +222,12 @@ namespace yy {
/// For a rule, its LHS. /// For a rule, its LHS.
static const unsigned char yyr1_[]; static const unsigned char yyr1_[];
/// For a rule, its RHS length. /// For a rule, its RHS length.
static const unsigned char yyr2_[]; 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
#if YYDEBUG #if YYDEBUG
/// For a symbol, its name in clear.
static const char* const yytname_[];
/// A type to store symbol numbers and -1. /// A type to store symbol numbers and -1.
typedef signed char rhs_number_type; typedef signed char rhs_number_type;
/// A `-1'-separated list of the rules' RHS. /// A `-1'-separated list of the rules' RHS.
@ -328,10 +282,9 @@ namespace yy {
}; };
} // yy } // yy
/* Line 36 of lalr1.cc */
/* Line 35 of lalr1.cc */ #line 287 "knot_parser/knot_parser.hh"
#line 334 "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++ /* Locations for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
Foundation, Inc.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -32,39 +31,55 @@
version 2.2 of Bison. */ version 2.2 of Bison. */
/** /**
** \file location.hh ** \file knot_parser/location.hh
** Define the yy::location class. ** Define the yy::location class.
*/ */
#ifndef BISON_LOCATION_HH #ifndef YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED
# define BISON_LOCATION_HH # define YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED
# include <iostream>
# include <string>
# include "position.hh" # include "position.hh"
namespace yy { namespace yy {
/* Line 164 of location.cc */
/* Line 163 of location.cc */ #line 47 "knot_parser/location.hh"
#line 51 "knot_parser/location.hh"
/// Abstract a location. /// Abstract a location.
class location class location
{ {
public: public:
/// Construct a location. /// Construct a location from \a b to \a e.
location () location (const position& b, const position& e)
: begin (), end () : 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. /// 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; end = begin;
} }
@ -72,19 +87,19 @@ namespace yy {
** \{ */ ** \{ */
public: public:
/// Reset initial location to final location. /// Reset initial location to final location.
inline void step () void step ()
{ {
begin = end; begin = end;
} }
/// Extend the current location to the COUNT next columns. /// Extend the current location to the COUNT next columns.
inline void columns (unsigned int count = 1) void columns (unsigned int count = 1)
{ {
end += count; end += count;
} }
/// Extend the current location to the COUNT next lines. /// 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); end.lines (count);
} }
@ -158,8 +173,7 @@ namespace yy {
} // yy } // yy
/* Line 292 of location.cc */
#line 178 "knot_parser/location.hh"
/* Line 272 of location.cc */ #endif /* !YY_YY_KNOT_PARSER_LOCATION_HH_INCLUDED */
#line 164 "knot_parser/location.hh"
#endif // not BISON_LOCATION_HH

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++ /* Positions for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
Foundation, Inc.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -32,60 +31,71 @@
version 2.2 of Bison. */ version 2.2 of Bison. */
/** /**
** \file position.hh ** \file knot_parser/position.hh
** Define the yy::position class. ** Define the yy::position class.
*/ */
#ifndef BISON_POSITION_HH #ifndef YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED
# define BISON_POSITION_HH # define YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED
# include <algorithm> // std::max
# include <iostream> # include <iostream>
# include <string> # 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 { namespace yy {
/* Line 38 of location.cc */ /* Line 38 of location.cc */
#line 51 "knot_parser/position.hh" #line 57 "knot_parser/position.hh"
/// Abstract a position. /// Abstract a position.
class position class position
{ {
public: public:
/// Construct a position. /// Construct a position.
position () explicit position (std::string* f = YY_NULL,
: filename (0), line (1), column (1) unsigned int l = 1u,
unsigned int c = 1u)
: filename (f)
, line (l)
, column (c)
{ {
} }
/// Initialization. /// Initialization.
inline void initialize (std::string* fn) void initialize (std::string* fn = YY_NULL,
unsigned int l = 1u,
unsigned int c = 1u)
{ {
filename = fn; filename = fn;
line = 1; line = l;
column = 1; column = c;
} }
/** \name Line and Column related manipulators /** \name Line and Column related manipulators
** \{ */ ** \{ */
public:
/// (line related) Advance to the COUNT next lines. /// (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; line += count;
} }
/// (column related) Advance to the COUNT next columns. /// (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); column = std::max (1u, column + count);
} }
/** \} */ /** \} */
public:
/// File name to which this position refers. /// File name to which this position refers.
std::string* filename; std::string* filename;
/// Current line number. /// Current line number.
@ -95,7 +105,7 @@ namespace yy {
}; };
/// Add and assign a position. /// Add and assign a position.
inline const position& inline position&
operator+= (position& res, const int width) operator+= (position& res, const int width)
{ {
res.columns (width); res.columns (width);
@ -111,7 +121,7 @@ namespace yy {
} }
/// Add and assign a position. /// Add and assign a position.
inline const position& inline position&
operator-= (position& res, const int width) operator-= (position& res, const int width)
{ {
return res += -width; return res += -width;
@ -156,7 +166,6 @@ namespace yy {
} // yy } // yy
/* Line 149 of location.cc */
/* Line 145 of location.cc */ #line 171 "knot_parser/position.hh"
#line 162 "knot_parser/position.hh" #endif /* !YY_YY_KNOT_PARSER_POSITION_HH_INCLUDED */
#endif // not BISON_POSITION_HH

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++ /* Stack handling for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Copyright (C) 2002-2012 Free Software Foundation, Inc.
Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify 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 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 This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ 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 { namespace yy {
/* Line 37 of stack.hh */
/* Line 1067 of lalr1.cc */ #line 47 "knot_parser/stack.hh"
#line 44 "knot_parser/stack.hh"
template <class T, class S = std::deque<T> > template <class T, class S = std::deque<T> >
class stack class stack
{ {
public: public:
// Hide our reversed order. // Hide our reversed order.
typedef typename S::reverse_iterator iterator; typedef typename S::reverse_iterator iterator;
typedef typename S::const_reverse_iterator const_iterator; typedef typename S::const_reverse_iterator const_iterator;
@ -84,7 +86,7 @@ namespace yy {
pop (unsigned int n = 1) pop (unsigned int n = 1)
{ {
for (; n; --n) for (; n; --n)
seq_.pop_front (); seq_.pop_front ();
} }
inline inline
@ -98,7 +100,6 @@ namespace yy {
inline const_iterator end () const { return seq_.rend (); } inline const_iterator end () const { return seq_.rend (); }
private: private:
S seq_; S seq_;
}; };
@ -107,10 +108,9 @@ namespace yy {
class slice class slice
{ {
public: public:
slice (const S& stack, unsigned int range)
slice (const S& stack, : stack_ (stack)
unsigned int range) : stack_ (stack), , range_ (range)
range_ (range)
{ {
} }
@ -122,15 +122,12 @@ namespace yy {
} }
private: private:
const S& stack_; const S& stack_;
unsigned int range_; unsigned int range_;
}; };
} // yy } // yy
/* Line 119 of stack.hh */
#line 132 "knot_parser/stack.hh"
/* Line 1153 of lalr1.cc */ #endif /* !YY_YY_KNOT_PARSER_STACK_HH_INCLUDED */
#line 134 "knot_parser/stack.hh"
#endif // not BISON_STACK_HH[]dnl

View File

@ -1,8 +1,6 @@
#include <knotkit.h> #include <knotkit.h>
#define HOME "/Users/cotton/src/knotkit/"
bool verbose = 0; bool verbose = 0;
static const struct { static const struct {
@ -402,7 +400,7 @@ htw_knot (unsigned n, bool alternating, unsigned k)
before += htw_alternating[i]; before += htw_alternating[i];
off = 8 * (before + k - 1); off = 8 * (before + k - 1);
file = HOME "alternating"; file = HOME "/alternating";
} }
else else
{ {
@ -411,7 +409,7 @@ htw_knot (unsigned n, bool alternating, unsigned k)
before += htw_nonalternating[i]; before += htw_nonalternating[i];
off = 10 * (before + k - 1); off = 10 * (before + k - 1);
file = HOME "nonalternating"; file = HOME "/nonalternating";
} }
FILE *fp = fopen (file, "r"); FILE *fp = fopen (file, "r");
if (fp == 0) if (fp == 0)
@ -514,7 +512,7 @@ mt_link (unsigned n, bool alternating, unsigned k)
char buf[1000]; 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"); FILE *fp = fopen (buf, "r");
if (fp == 0) if (fp == 0)
{ {
@ -717,7 +715,7 @@ mutant_knot_groups (unsigned n)
assert (11 <= n && n <= 15); assert (11 <= n && n <= 15);
char buf[1000]; 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"); FILE *fp = fopen (buf, "r");
if (fp == 0) if (fp == 0)

View File

@ -1281,8 +1281,10 @@ compute_forgetfulss (knot_diagram &kd,
if (d == 0) if (d == 0)
break; break;
} }
return sseq (bounds, pages); abort ();
// ???
return sseq (bounds, grading (0, 0), grading (0, 0), pages);
} }
void void
@ -2613,7 +2615,7 @@ main ()
{ {
knot_diagram kd (mt_link (5, 1, 3)); knot_diagram kd (mt_link (5, 1, 3));
show (kd); newline (); show (kd); newline ();
sseq ss = compute_forgetfulss<Q> (kd); sseq ss = compute_forgetfulss<Q> (kd);
ss.texshow (stdout, "L5a3"); ss.texshow (stdout, "L5a3");
} }

View File

@ -66,6 +66,7 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t; typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t; typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t; typedef uint32_t flex_uint32_t;
typedef uint64_t flex_uint64_t;
#else #else
typedef signed char flex_int8_t; typedef signed char flex_int8_t;
typedef short int flex_int16_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; typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif #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; extern FILE *rd_yyin, *rd_yyout;
@ -198,11 +204,6 @@ extern FILE *rd_yyin, *rd_yyout;
#define unput(c) yyunput( c, (yytext_ptr) ) #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 #ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE
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 /* Number of characters read into yy_ch_buf, not including EOB
* characters. * characters.
*/ */
int yy_n_chars; yy_size_t yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it, /* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to * 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. */ /* yy_hold_char holds the character lost when rd_yytext is formed. */
static char yy_hold_char; static char yy_hold_char;
static int yy_n_chars; /* number of characters read into yy_ch_buf */ static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
int rd_yyleng; yy_size_t rd_yyleng;
/* Points to current character in buffer. */ /* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0; 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_buffer (char *base,yy_size_t size );
YY_BUFFER_STATE rd_yy_scan_string (yyconst char *yy_str ); 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_yyalloc (yy_size_t );
void *rd_yyrealloc (void *,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 \ #define YY_DO_BEFORE_ACTION \
(yytext_ptr) = yy_bp; \ (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_hold_char) = *yy_cp; \
*yy_cp = '\0'; \ *yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp; (yy_c_buf_p) = yy_cp;
@ -483,7 +484,7 @@ char *rd_yytext;
typedef yy::rd_parser::token token; typedef yy::rd_parser::token token;
typedef yy::rd_parser::token_type token_type; 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 #define INITIAL 0
@ -522,7 +523,7 @@ FILE *rd_yyget_out (void );
void rd_yyset_out (FILE * out_str ); void rd_yyset_out (FILE * out_str );
int rd_yyget_leng (void ); yy_size_t rd_yyget_leng (void );
char *rd_yyget_text (void ); char *rd_yyget_text (void );
@ -581,7 +582,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \ { \
int c = '*'; \ int c = '*'; \
int n; \ yy_size_t n; \
for ( n = 0; n < max_size && \ for ( n = 0; n < max_size && \
(c = getc( rd_yyin )) != EOF && c != '\n'; ++n ) \ (c = getc( rd_yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \ buf[n] = (char) c; \
@ -666,7 +667,7 @@ YY_DECL
#line 16 "rd_parser/rd_scanner.ll" #line 16 "rd_parser/rd_scanner.ll"
#line 670 "rd_parser/rd_scanner.cc" #line 671 "rd_parser/rd_scanner.cc"
if ( !(yy_init) ) if ( !(yy_init) )
{ {
@ -794,7 +795,7 @@ YY_RULE_SETUP
#line 49 "rd_parser/rd_scanner.ll" #line 49 "rd_parser/rd_scanner.ll"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 798 "rd_parser/rd_scanner.cc" #line 799 "rd_parser/rd_scanner.cc"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
yyterminate(); yyterminate();
@ -981,7 +982,7 @@ static int yy_get_next_buffer (void)
else else
{ {
int num_to_read = yy_size_t num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 ) while ( num_to_read <= 0 )
@ -995,7 +996,7 @@ static int yy_get_next_buffer (void)
if ( b->yy_is_our_buffer ) 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 ) if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8; b->yy_buf_size += b->yy_buf_size / 8;
@ -1026,7 +1027,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */ /* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), 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); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
} }
@ -1148,7 +1149,7 @@ static int yy_get_next_buffer (void)
else else
{ /* need more input */ { /* 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); ++(yy_c_buf_p);
switch ( yy_get_next_buffer( ) ) switch ( yy_get_next_buffer( ) )
@ -1172,7 +1173,7 @@ static int yy_get_next_buffer (void)
case EOB_ACT_END_OF_FILE: case EOB_ACT_END_OF_FILE:
{ {
if ( rd_yywrap( ) ) if ( rd_yywrap( ) )
return EOF; return 0;
if ( ! (yy_did_buffer_switch_on_eof) ) if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE; YY_NEW_FILE;
@ -1424,7 +1425,7 @@ void rd_yypop_buffer_state (void)
*/ */
static void rd_yyensure_buffer_stack (void) static void rd_yyensure_buffer_stack (void)
{ {
int num_to_alloc; yy_size_t num_to_alloc;
if (!(yy_buffer_stack)) { 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. * @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; YY_BUFFER_STATE b;
char *buf; char *buf;
yy_size_t n; yy_size_t n, i;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */ /* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2; n = _yybytes_len + 2;
@ -1608,7 +1608,7 @@ FILE *rd_yyget_out (void)
/** Get the length of the current token. /** Get the length of the current token.
* *
*/ */
int rd_yyget_leng (void) yy_size_t rd_yyget_leng (void)
{ {
return rd_yyleng; return rd_yyleng;
} }

View File

@ -63,8 +63,7 @@ class chain_complex_simplifier
public: public:
chain_complex_simplifier (ptr<const module<R> > C_, chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_, const mod_map<R> &d_,
int dq); maybe<int> dh, maybe<int> dq);
}; };
template<class R> void template<class R> void
@ -145,7 +144,7 @@ chain_complex_simplifier<R>::cancel (unsigned i, R b, unsigned j)
template<class R> template<class R>
chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_, chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
const mod_map<R> &d_, const mod_map<R> &d_,
int dq) maybe<int> dh, maybe<int> dq)
: C(C_), n(C_->dim ()), d(d_), : C(C_), n(C_->dim ()), d(d_),
new_d_columns(n), new_d_columns(n),
preim(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 ()); grading jgr = C->generator_grading (j.key ());
if (j.val ().is_unit () 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 ()); cancel (i, j.val (), j.key ());
break; break;

114
sseq.cpp
View File

@ -2,7 +2,8 @@
#include <knotkit.h> #include <knotkit.h>
sseq_page::sseq_page (const sseq_bounds &b) sseq_page::sseq_page (const sseq_bounds &b)
: rank(b.width ()), : k(0),
rank(b.width ()),
im_rank(b.width ()) im_rank(b.width ())
{ {
for (unsigned i = 0; i < b.width (); i ++) for (unsigned i = 0; i < b.width (); i ++)
@ -140,87 +141,6 @@ sseq_page::delta_poincare_polynomial (const sseq_bounds &b) const
return r; 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
sseq::operator + (const sseq &ss2) const sseq::operator + (const sseq &ss2) const
{ {
@ -280,36 +200,6 @@ sseq::shift (int dh, int dq) const
pages); 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 void
sseq_builder::cancel (unsigned d) sseq_builder::cancel (unsigned d)
{ {

437
sseq.h
View File

@ -7,6 +7,27 @@ class sseq_bounds
public: public:
sseq_bounds () { } 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_) sseq_bounds (int minh_, int maxh_, int minq_, int maxq_)
: minh(minh_), maxh(maxh_), minq(minq_), maxq(maxq_) : minh(minh_), maxh(maxh_), minq(minq_), maxq(maxq_)
{ } { }
@ -41,22 +62,34 @@ class sseq_page
{ {
public: public:
/* bounds come from sseq */ /* bounds come from sseq */
unsigned k;
grading dk_gr;
vector<vector<unsigned> > rank, vector<vector<unsigned> > rank,
im_rank; im_rank;
public: public:
sseq_page () { } sseq_page () { }
sseq_page (const sseq_bounds &b); 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) 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 () { } ~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 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; unsigned total_rank () const;
multivariate_laurentpoly<Z> poincare_polynomial (const sseq_bounds &b) const; multivariate_laurentpoly<Z> poincare_polynomial (const sseq_bounds &b) const;
multivariate_laurentpoly<Z> delta_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 &b1, const sseq_page &pg1,
const sseq_bounds &b2, const sseq_page &pg2); 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 class sseq
@ -78,8 +111,10 @@ class sseq
public: public:
sseq () { } sseq () { }
sseq (const sseq_bounds &b, const basedvector<sseq_page, 1> &pages_) sseq (const sseq_bounds &b,
: bounds(b), pages(pages_) const basedvector<sseq_page, 1> &pages_)
: bounds(b),
pages(pages_)
{ } { }
sseq (const sseq_bounds &b) sseq (const sseq_bounds &b)
: bounds(b) : bounds(b)
@ -87,7 +122,12 @@ class sseq
sseq (const sseq &ss) : bounds(ss.bounds), pages(ss.pages) { } sseq (const sseq &ss) : bounds(ss.bounds), pages(ss.pages) { }
~sseq () { } ~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 operator + (const sseq &ss2) const; // direct sum
sseq otimes (const sseq &ss2) const; // tensor product 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 bounds == ss.bounds && pages == ss.pages; }
bool operator != (const sseq &ss) const { return !operator == (ss); } bool operator != (const sseq &ss) const { return !operator == (ss); }
bool equal_as_spaces (const sseq &ss) const; template<class M> void texshow (FILE *fp, M m);
void texshow (FILE *fp, std::string name);
}; };
#if 0 template<class R, class M>
template<class R> class simplified_complex_generators 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; dk.check_grading (dk_gr);
ptr<const module<R> > C;
basedvector<unsigned, 1> new_C_to_C_generator;
public: grading m_dk_gr = m.map_delta(dk_gr);
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 () { }
simplified_complex_generators &operator = (const simplified_complex_generators &) = delete; for (unsigned i = 0; i < b.width (); i ++)
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)
{ {
mod_map<R> local_pi0 (C, 1), vector<unsigned> r (b.height ()),
local_iota0 (C, 1); im_r (b.height ());
for (unsigned j = 0; j < b.height (); j ++)
r[j] = im_r[j] = 0;
local_pi0[i].clear (); rank[i] = r;
local_pi0[j].clear (); im_rank[i] = im_r;
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);
} }
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 (); grading gr = m(C->generator_grading (i));
R a = new_d0[k](j); rank[(unsigned)(gr.h - b.minh)][(unsigned)(gr.q - b.minq)] ++;
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;
}
} }
for (set_const_iter<unsigned> k = preim[j]; k; k ++) ptr<const free_submodule<R> > im = dk.image ();
new_d0[k.val ()].yank (j); for (unsigned i = 1; i <= im->dim (); i ++)
new_d0[i].clear ();
preim[i].clear ();
new_d0[j].clear ();
preim[j].clear ();
#if 0 // expensive
if (build_pi_iota)
{ {
assert (pi0.compose (d) == new_d0.compose (pi0)); grading gr = m(im->generator_grading (i));
assert (iota0.compose (new_d0) == d.compose (iota0)); 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_, template<class M> void
const mod_map<R> &d_, sseq_page::texshow (FILE *fp, const sseq_bounds &b, const char *label, M m)
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_)
{ {
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 (unsigned i = 1; i <= n; i ++)
{ {
for (linear_combination_const_iter j = d[i]; j; j ++) if (i == n)
preim[j.key ()].push (i); 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); char buf[1000];
iota0 = mod_map<R> (C, 1); if (i == n)
sprintf (buf, "$E_\\infty = E_{%d}$", pages[i].k);
#if 0 // expensive else
assert (pi0.compose (d) == new_d0.compose (pi0)); sprintf (buf, "$E_{%d}$", pages[i].k);
assert (iota0.compose (new_d0) == d.compose (iota0)); pages[i].texshow (fp, bounds, buf, m);
#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
} }
} }
#endif
class sseq_builder class sseq_builder
{ {