First commit in git. This is a cleaned up version of r114 from the

now deprecated SVN repository.
This commit is contained in:
Cotton Seed 2011-12-09 15:50:25 -05:00
parent 2eae290b42
commit dcbe4127bd
113 changed files with 236578 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
/gss
/main

106
Makefile Normal file
View File

@ -0,0 +1,106 @@
BISON = /opt/local/bin/bison
FLEX = /opt/local/bin/flex
CXX = g++
INCLUDES = -I/opt/local/include -I.
OPTFLAGS = -g
# OPTFLAGS = -O2 -g
# OPTFLAGS = -O2 -DNDEBUG
LDFLAGS = -L/opt/local/lib
# LDFLAGS = -pg -L/opt/local/lib
CXXFLAGS = $(OPTFLAGS) -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
ALGEBRA_OBJS = algebra/algebra.o algebra/Q.o algebra/grading.o algebra/polynomial.o
KNOTKIT_OBJS = planar_diagram.o dt_code.o knot_diagram.o cube.o spanning_tree_complex.o \
smoothing.o cobordism.o knot_tables.o sseq.o \
knot_parser/knot_parser.o knot_parser/knot_scanner.o \
rd_parser/rd_parser.o rd_parser/rd_scanner.o
COMMON_OBJS = $(KNOTKIT_OBJS) $(ALGEBRA_OBJS) $(LIB_OBJS)
LIB_HEADERS = lib/lib.h lib/show.h lib/refcount.h lib/pair.h lib/maybe.h lib/vector.h \
lib/set.h lib/ullmanset.h lib/bitset.h lib/smallbitset.h lib/setcommon.h \
lib/map_wrapper.h lib/map.h lib/hashmap.h lib/ullmanmap.h lib/mapcommon.h \
lib/unionfind.h lib/priority_queue.h lib/io.h \
lib/directed_multigraph.h
ALGEBRA_HEADERS = algebra/algebra.h algebra/grading.h algebra/module.h \
algebra/Z2.h algebra/linear_combination.h algebra/Z.h algebra/Q.h \
algebra/polynomial.h algebra/multivariate_polynomial.h \
algebra/laurentpoly.h algebra/fraction_field.h
KNOTKIT_HEADERS = knotkit.h planar_diagram.h dt_code.h knot_diagram.h \
smoothing.h cobordism.h cube.h spanning_tree_complex.h cube_impl.h sseq.h
LIBS = -lgmp
all: gss
%.o : %.cc
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
gss: gss.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o gss $^ $(LIBS)
main: main.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o main $^ $(LIBS)
testlib: testlib.o $(COMMON_OBJS)
$(CXX) $(LDFLAGS) -o testlib $^
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
knot_parser/knot_scanner.cc: knot_parser/knot_scanner.ll
$(FLEX) -o knot_parser/knot_scanner.cc knot_parser/knot_scanner.ll
javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh: javakh_parser/javakh_parser.yy
$(BISON) javakh_parser/javakh_parser.yy -o javakh_parser/javakh_parser.cc
javakh_parser/javakh_scanner.cc: javakh_parser/javakh_scanner.ll
$(FLEX) -o javakh_parser/javakh_scanner.cc javakh_parser/javakh_scanner.ll
rd_parser/rd_parser.cc rd_parser/rd_parser.hh: rd_parser/rd_parser.yy
$(BISON) rd_parser/rd_parser.yy -o rd_parser/rd_parser.cc
rd_parser/rd_scanner.cc: rd_parser/rd_scanner.ll
$(FLEX) -o rd_parser/rd_scanner.cc rd_parser/rd_scanner.ll
.PHONY: parser_files
parser_files: \
knot_parser/knot_parser.cc knot_parser/knot_parser.hh \
knot_parser/knot_scanner.cc \
javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh \
javakh_parser/javakh_scanner.cc \
rd_parser/rd_parser.cc rd_parser/rd_parser.hh \
rd_parser/rd_scanner.cc
.PHONY: clean
clean:
rm -f *.o lib/*.o algebra/*.o knot_parser/*.o rd_parser/*.o
rm -f main gss
rm -f gmon.out
.PHONY: realclean
realclean: clean
rm -f knot_parser/knot_parser.cc knot_parser/knot_parser.hh
rm -f knot_parser/knot_scanner.cc
rm -f knot_parser/location.hh knot_parser/position.hh knot_parser/stack.hh
rm -f javakh_parser/javakh_parser.cc javakh_parser/javakh_parser.hh
rm -f javakh_parser/javakh_scanner.cc
rm -f javakh_parser/location.hh javakh_parser/position.hh javakh_parser/stack.hh
rm -f rd_parser/rd_parser.cc rd_parser/rd_parser.hh
rm -f rd_parser/rd_scanner.cc
rm -f rd_parser/location.hh rd_parser/position.hh rd_parser/stack.hh
$(LIB_OBJS): $(LIB_HEADERS)
$(ALGEBRA_OBJS): $(ALGEBRA_HEADERS) $(LIB_HEADERS)
$(KNOTKIT_OBJS) main.o gss.o: $(KNOTKIT_HEADERS) $(ALGEBRA_HEADERS) $(LIB_HEADERS)

19
algebra/Q.cpp Normal file
View File

@ -0,0 +1,19 @@
#include <algebra/algebra.h>
void
Q::reduce ()
{
unsigned c = unsigned_gcd ((unsigned)std::abs (n), d);
n /= (int)c;
d /= c;
}
void
Q::show_self () const
{
if (d == 1)
printf ("%d", n);
else
printf ("%d/%u", n, d);
}

63
algebra/Q.h Normal file
View File

@ -0,0 +1,63 @@
class Q
{
public:
typedef linear_combination<Q> linear_combination;
// typedef linear_combination_iter<Q> linear_combination_iter;
typedef linear_combination_const_iter<Q> linear_combination_const_iter;
private:
int n;
unsigned d;
void reduce ();
public:
Q () : n(0), d(1) { }
Q (int x) : n(x), d(1) { }
Q (int n_, unsigned d_) : n(n_), d(d_) { assert (d != 0); reduce (); }
Q (const Q &q) : n(q.n), d(q.d) { }
~Q () { }
Q &operator = (const Q &q) { n = q.n; d = q.d; return *this; }
Q &operator = (int x) { n = x; d = 1; return *this; }
bool operator == (const Q &q) const { return n == q.n && d == q.d; }
bool operator == (int x) const { return n == x && d == 1; }
bool operator != (int x) const { return !operator == (x); }
bool is_unit () const { return n != 0; }
Q operator + (const Q &x) const { return Q (n*x.d + x.n*d, d*x.d); }
Q operator - (const Q &x) const { return Q (n*x.d - x.n*d, d*x.d); }
Q operator * (const Q &x) const { return Q (n*x.n, d*x.d); }
Q operator / (const Q &x) const { return operator * (x.recip ()); }
Q recip () const
{
assert (is_unit ());
if (n < 0)
return Q (-d, -n);
else
return Q (d, n);
}
Q &operator += (const Q &x) { n = n*x.d + x.n*d; d *= x.d; reduce (); return *this; }
Q &operator -= (const Q &x) { n = n*x.d - x.n*d; d *= x.d; reduce (); return *this; }
Q &operator *= (const Q &x) { n *= x.n; d *= x.d; reduce (); return *this; }
Q &operator /= (const Q &x) { return operator *= (x.recip ()); }
bool divides (const Q &q) const { return (n != 0) || (q.n == 0); }
bool operator | (const Q &q) const { return divides (q); }
Q gcd (const Q &q) const
{
assert (n != 0 && q.n != 0);
return Q (1);
}
static void show_ring () { printf ("Q"); }
void show_self () const;
void display_self () const { show_self (); newline (); }
};

169
algebra/Z.h Normal file
View File

@ -0,0 +1,169 @@
class Z
{
public:
typedef linear_combination<Z> linear_combination;
typedef linear_combination_const_iter<Z> linear_combination_const_iter;
enum steal { STEAL };
private:
class Z_impl : public refcounted
{
public:
mpz_t x;
public:
Z_impl () { mpz_init (x); }
Z_impl (int init) { mpz_init_set_si (x, init); }
Z_impl (copy, mpz_srcptr init) { mpz_init_set (x, init); }
Z_impl (steal, mpz_srcptr init) { x[0] = *init; }
~Z_impl () { mpz_clear (x); }
};
ptr<Z_impl> impl;
Z (steal, mpz_srcptr init) : impl(new Z_impl (STEAL, init)) { }
public:
Z () : impl(new Z_impl) { }
Z (int init) : impl(new Z_impl (init)) { }
Z (const Z &z) : impl(z.impl) { }
Z (copy, const Z &z) : impl(new Z_impl (COPY, z.impl->x)) { }
~Z () { }
Z &operator = (const Z &z) { impl = z.impl; return *this; }
Z &operator = (int x) { impl = new Z_impl (x); return *this; }
bool operator == (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) == 0; }
bool operator == (int y) const { return mpz_cmp_si (impl->x, y) == 0; }
bool operator != (int y) const { return !operator == (y); }
bool operator < (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) < 0; }
bool is_unit () const
{
return *this == 1 || *this == -1;
}
Z operator + (const Z &z) const
{
mpz_t x;
mpz_init (x);
mpz_add (x, impl->x, z.impl->x);
return Z (STEAL, x);
}
Z operator - (const Z &z) const
{
mpz_t x;
mpz_init (x);
mpz_sub (x, impl->x, z.impl->x);
return Z (STEAL, x);
}
Z operator * (const Z &z) const
{
mpz_t x;
mpz_init (x);
mpz_mul (x, impl->x, z.impl->x);
return Z (STEAL, x);
}
Z operator / (const Z &z) const
{
if (mpz_cmp_si (z.impl->x, 1) == 0)
return *this;
else
{
assert (mpz_cmp_si (z.impl->x, -1) == 0);
mpz_t x;
mpz_init (x);
mpz_neg (x, impl->x);
return Z (STEAL, x);
}
}
Z recip () const
{
assert (is_unit ());
return Z (COPY, *this);
}
Z &operator += (const Z &z)
{
mpz_add (impl->x, impl->x, z.impl->x);
return *this;
}
Z &operator -= (const Z &z)
{
mpz_sub (impl->x, impl->x, z.impl->x);
return *this;
}
Z &operator *= (const Z &z)
{
mpz_mul (impl->x, impl->x, z.impl->x);
return *this;
}
Z &operator /= (const Z &z)
{
if (mpz_cmp_si (z.impl->x, 1) == 0)
;
else
{
assert (mpz_cmp_si (z.impl->x, -1) == 0);
mpz_neg (impl->x, impl->x);
}
return *this;
}
bool divides (const Z &n) const
{
// d = *this
return mpz_divisible_p (n.impl->x, impl->x);
}
bool operator | (const Z &z) const { return divides (z); }
Z div (const Z &d) const
{
// n = *this
mpz_t q;
mpz_init (q);
mpz_divexact (q, impl->x, d.impl->x);
return Z (STEAL, q);
}
triple<Z, Z, Z> extended_gcd (const Z &z) const
{
mpz_t d, s, t;
mpz_inits (d, s, t, 0);
mpz_gcdext (d, s, t, impl->x, z.impl->x);
return triple<Z, Z, Z> (Z (STEAL, d),
Z (STEAL, s),
Z (STEAL, t));
}
Z gcd (const Z &z) const
{
mpz_t d;
mpz_gcd (d, impl->x, z.impl->x);
return Z (STEAL, d);
}
Z lcm (const Z &z) const
{
mpz_t m;
mpz_lcm (m, impl->x, z.impl->x);
return Z (STEAL, m);
}
static void show_ring () { printf ("Z"); }
void show_self () const { mpz_out_str (stdout, 10, impl->x); }
void display_self () const { show_self (); newline (); }
};

66
algebra/Z2.h Normal file
View File

@ -0,0 +1,66 @@
class Z2
{
public:
typedef linear_combination<Z2> linear_combination;
// typedef linear_combination_iter<Z2> linear_combination_iter;
typedef linear_combination_const_iter<Z2> linear_combination_const_iter;
private:
bool v;
public:
Z2 () : v(0) { }
Z2 (int x) : v((bool)(x & 1)) { }
Z2 (bool v_) : v(v_) { }
Z2 (const Z2 &x) : v(x.v) { }
~Z2 () { }
Z2 &operator = (const Z2 &x) { v = x.v; return *this; }
Z2 &operator = (int x) { v = (bool)(x & 1); return *this; }
bool operator == (const Z2 &x) const { return v == x.v; }
bool operator == (int x) const { return v == (bool)(x & 1); }
bool operator != (int x) const { return !operator == (x); }
bool is_unit () const { return v; }
Z2 operator + (const Z2 &x) const { return Z2 (v ^ x.v); }
Z2 operator - (const Z2 &x) const { return Z2 (v ^ x.v); }
Z2 operator * (const Z2 &x) const { return Z2 (v & x.v); }
Z2 operator / (const Z2 &x) const { assert (x.v); return *this; }
Z2 recip () const { assert (v); return *this; }
Z2 &operator += (const Z2 &x) { v ^= x.v; return *this; }
Z2 &operator -= (const Z2 &x) { v ^= x.v; return *this; }
Z2 &operator *= (const Z2 &x) { v &= x.v; return *this; }
Z2 &operator /= (const Z2 &x) { assert (x.v); return *this; }
bool divides (Z2 x) const { return v || !x.v; }
bool operator | (const Z2 x) const { return divides (x); }
Z2 div (Z2 x) const
{
assert (x.divides (*this));
return *this;
}
Z2 gcd (Z2 x) const
{
assert (v && x.v);
return Z2 (1);
}
triple<Z2, Z2, Z2> extended_gcd (Z2 x) const
{
if (v)
return triple<Z2, Z2, Z2> (Z2 (1), Z2 (1), Z2 (0));
else
return triple<Z2, Z2, Z2> (Z2 (1), Z2 (0), Z2 (1));
}
static void show_ring () { printf ("Z2"); }
void show_self () const { printf ("%d", (int)v); }
void display_self () const { printf ("%d\n", (int)v); }
};

105
algebra/algebra.cpp Normal file
View File

@ -0,0 +1,105 @@
#include <algebra/algebra.h>
unsigned
unsigned_gcd (unsigned a, unsigned b)
{
while (b != 0)
{
unsigned t = a % b;
a = b;
b = t;
}
return a;
}
unsigned
int_gcd (int a, int b)
{
return unsigned_gcd ((unsigned)std::abs (a),
(unsigned)std::abs (b));
}
uint64
uint64_gcd (uint64 a, uint64 b)
{
while (b != 0)
{
uint64 t = a % b;
a = b;
b = t;
}
return a;
}
uint64
int64_gcd (int64 a, int64 b)
{
return uint64_gcd ((uint64)std::abs (a),
(uint64)std::abs (b));
}
static triple<unsigned, int, int>
extended_gcd_1 (unsigned a, unsigned b)
{
if (b == 0)
return triple<unsigned, int, int> (a, 1, 0);
unsigned t = a % b;
if (!t)
return triple<unsigned, int, int> (b, 0, 1);
else
{
triple<unsigned, int, int> s = extended_gcd (b, t);
unsigned d = s.first;
int x = s.third,
y = s.second - s.third * (a / b);
assert ((int)d == (int)a*x + (int)b*y);
return triple<unsigned, int, int> (d, x, y);
}
}
triple<unsigned, int, int>
extended_gcd (int a, int b)
{
triple<unsigned, int, int> t = extended_gcd_1 (std::abs (a),
std::abs (b));
unsigned d = t.first;
int x = t.second,
y = t.third;
if (a < 0)
x *= -1;
if (b < 0)
y *= -1;
assert ((int)d == a*x + b*y);
return triple<unsigned, int, int> (d, x, y);
}
unsigned
unsigned_lcm (unsigned a, unsigned b)
{
return (a / unsigned_gcd (a, b)) * b;
}
uint64
uint64_lcm (uint64 a, uint64 b)
{
return (a / uint64_gcd (a, b)) * b;
}
unsigned int_lcm (int a, int b)
{
return unsigned_lcm ((unsigned)std::abs (a),
(unsigned)std::abs (b));
}
uint64 int64_lcm (int64 a, int64 b)
{
return uint64_lcm ((uint64)std::abs (a),
(uint64)std::abs (b));
}

66
algebra/algebra.h Normal file
View File

@ -0,0 +1,66 @@
#include <gmp.h>
#include <lib/lib.h>
inline int recip (int x)
{
assert (x == 1 || x == -1);
return x;
}
template<class T> inline T recip (const T &x) { return x.recip (); }
template<class T> inline T
pow (const T &x, int d)
{
if (d == 0)
return 1;
else if (d == 1)
return x;
else if (d < 0)
return pow (recip (x), -d);
else
{
T x2 = x * x;
if (d & 1)
return x * pow (x2, (d - 1) / 2);
else
return pow (x2, d / 2);
}
}
unsigned unsigned_gcd (unsigned a, unsigned b);
uint64 uint64_gcd (uint64 a, uint64 b);
unsigned int_gcd (int a, int b);
uint64 int64_gcd (int64 a, int64 b);
unsigned unsigned_lcm (unsigned a, unsigned b);
uint64 uint64_lcm (uint64 a, uint64 b);
unsigned int_lcm (int a, int b);
uint64 int64_lcm (int64 a, int64 b);
// (d, x, y) = gcd (a, b) where x*a + y*b = d
triple<unsigned, int, int> extended_gcd (int a, int b);
template<class R> class linear_combination;
template<class R> class linear_combination_const_iter;
template<class R> class module;
#include <algebra/multivariate_polynomial.h>
#include <algebra/laurentpoly.h>
#include <algebra/grading.h>
#include <algebra/module.h>
#include <algebra/Z2.h>
#include <algebra/linear_combination.h>
#include <algebra/Z.h>
#include <algebra/Q.h>
#include <algebra/polynomial.h>
#include <algebra/fraction_field.h>

3
algebra/fields.cpp Normal file
View File

@ -0,0 +1,3 @@
#include <algebra/algebra.h>

241
algebra/fraction_field.h Normal file
View File

@ -0,0 +1,241 @@
template<class T> class fraction_field
{
public:
typedef linear_combination<fraction_field> linear_combination;
typedef linear_combination_const_iter<fraction_field> linear_combination_const_iter;
private:
T num;
T denom;
enum reduced { REDUCED };
void reduce ();
void check ();
public:
fraction_field () : num(0), denom(1) { }
fraction_field (int x) : num(x), denom(1) { }
fraction_field (T num_) : num(num_), denom(1) { }
fraction_field (T num_, T denom_) : num(num_), denom(denom_) { assert (denom != 0); reduce (); }
fraction_field (reduced, T num_, T denom_)
: num(num_), denom(denom_)
{
assert (denom != 0);
#ifndef NDEBUG
check ();
#endif
}
fraction_field (const fraction_field &q) : num(q.num), denom(q.denom) { }
fraction_field (copy, const fraction_field &q) : num(COPY, q.num), denom(COPY, q.denom) { }
~fraction_field () { }
fraction_field &operator = (const fraction_field &q) { num = q.num; denom = q.denom; return *this; }
fraction_field &operator = (int x) { num = x; denom = 1; return *this; }
bool operator == (const fraction_field &q) const { return num * q.denom == q.num * denom; }
bool operator == (int x) const { return num == denom * T (x); }
bool operator != (int x) const { return !operator == (x); }
bool is_unit () const { return num != 0; }
fraction_field operator + (const fraction_field &x) const
{
T d = denom.gcd (x.denom);
T e = denom.divide_exact (d),
xe = x.denom.divide_exact (d);
T new_num = num * xe;
new_num += x.num * e;
return fraction_field (new_num, denom*xe);
}
fraction_field operator - (const fraction_field &x) const
{
T d = denom.gcd (x.denom);
T e = denom.divide_exact (d),
xe = x.denom.divide_exact (d);
T new_num = num * xe;
new_num -= x.num * e;
return fraction_field (new_num, denom*xe);
}
fraction_field operator * (const fraction_field &x) const
{
T d1 = num.gcd (x.denom);
T d2 = denom.gcd (x.num);
return fraction_field (REDUCED,
num.divide_exact (d1) * x.num.divide_exact (d2),
denom.divide_exact (d2) * x.denom.divide_exact (d1));
}
fraction_field operator / (const fraction_field &x) const
{
assert (x.num != 0);
T d1 = num.gcd (x.num);
T d2 = denom.gcd (x.denom);
return fraction_field (REDUCED,
num.divide_exact (d1) * x.denom.divide_exact (d2),
denom.divide_exact (d2) * x.num.divide_exact (d1));
}
fraction_field &invert ()
{
assert (num != 0);
T t = num;
num = denom;
denom = t;
return *this;
}
fraction_field recip () const
{
assert (num != 0);
return fraction_field (T (COPY, denom),
T (COPY, num));
}
fraction_field &operator += (const fraction_field &x)
{
T d = denom.gcd (x.denom);
T e = denom.divide_exact (d),
xe = x.denom.divide_exact (d);
num *= xe;
num += x.num * e;
denom *= xe;
reduce ();
return *this;
}
fraction_field &operator -= (const fraction_field &x)
{
T d = denom.gcd (x.denom);
T e = denom.divide_exact (d),
xe = x.denom.divide_exact (d);
num *= xe;
num -= x.num * e;
denom *= xe;
reduce ();
return *this;
}
fraction_field &operator *= (const fraction_field &x)
{
T d1 = num.gcd (x.denom);
num = num.divide_exact (d1);
T d2 = denom.gcd (x.num);
denom = denom.divide_exact (d2);
num *= x.num.divide_exact (d2);
denom *= x.denom.divide_exact (d1);
#ifndef NDEBUG
check ();
#endif
return *this;
}
fraction_field &operator /= (const fraction_field &x)
{
assert (x.num != 0);
T d1 = num.gcd (x.num);
num = num.divide_exact (d1);
T d2 = denom.gcd (x.denom);
denom = denom.divide_exact (d2);
num *= x.denom.divide_exact (d2);
denom *= x.num.divide_exact (d1);
#ifndef NDEBUG
check ();
#endif
return *this;
}
// d | n, d.divides (n)
bool divides (const fraction_field &n) const
{
// d = *this
return (num != 0) || (n.num == 0);
}
bool operator | (const fraction_field &q) const { return divides (q); }
fraction_field div (const fraction_field &d) const { return operator / (d); }
fraction_field gcd (const fraction_field &q) const
{
assert (num != 0 && q.num != 0);
return fraction_field (1);
}
triple<fraction_field, fraction_field, fraction_field> extended_gcd (const fraction_field &x) const
{
if (*this != 0)
return triple<fraction_field, fraction_field, fraction_field> (*this, 1, 0);
else
return triple<fraction_field, fraction_field, fraction_field> (x, 0, 1);
}
static void show_ring () { printf ("fraction_field("); T::show_ring (); printf (")"); }
void show_self () const;
void display_self () const { show_self (); newline (); }
};
template<class T> void
fraction_field<T>::reduce ()
{
if (num == 0)
{
denom = 1;
return;
}
T d = num.gcd (denom);
num = num.divide_exact (d);
denom = denom.divide_exact (d);
}
template<class T> void
fraction_field<T>::check ()
{
if (num == 0)
return;
// check denom == 1
// assert (num.gcd (denom) == 1);
}
template<class T> void
fraction_field<T>::show_self () const
{
if (denom == 1)
show (num);
else
{
printf ("(");
show (num);
printf (")/(");
show (denom);
printf (")");
}
}

22
algebra/grading.cpp Normal file
View File

@ -0,0 +1,22 @@
#include <algebra/algebra.h>
grading
grading::mirror_grading (unsigned nplus, unsigned nminus, bool torsion) const
{
return grading (torsion ? (1-h) : -h,
-q);
}
void
grading::show_self () const
{
printf ("(%d, %d)", h, q);
}
void
grading::display_self () const
{
printf ("(%d, %d)\n", h, q);
}

49
algebra/grading.h Normal file
View File

@ -0,0 +1,49 @@
class grading
{
public:
int h, q;
public:
grading () : h(0), q(0) { }
grading (int h_, int q_) : h(h_), q(q_) { }
grading (const grading &gr) : h(gr.h), q(gr.q) { }
~grading () { }
grading &operator = (const grading &gr) { h = gr.h; q = gr.q; return *this; }
grading operator + (const grading &gr) const
{
return grading (h + gr.h, q + gr.q);
}
grading operator - (const grading &gr) const
{
return grading (h - gr.h, q - gr.q);
}
grading &operator += (const grading &gr)
{
h += gr.h;
q += gr.q;
return *this;
}
grading &operator -= (const grading &gr)
{
h -= gr.h;
q -= gr.q;
return *this;
}
bool operator == (const grading &gr) const { return h == gr.h && q == gr.q; }
bool operator < (const grading &gr) const
{
return h < gr.h
|| (h == gr.h && q < gr.q);
}
grading mirror_grading (unsigned nplus, unsigned nminus, bool torsion) const;
void show_self () const;
void display_self () const;
};

399
algebra/laurentpoly.h Normal file
View File

@ -0,0 +1,399 @@
template<class C, class E> class laurentpoly;
class exponent1
{
public:
int first;
public:
exponent1 () : first(0) { }
explicit exponent1 (unsigned first_) : first(first_) { }
exponent1 (const exponent1 &e) : first(e.first) { }
~exponent1 () { }
exponent1 &operator = (const exponent1 &e) { first = e.first; return *this; }
inline laurentpoly<int, exponent1> operator + (const exponent1 &e) const;
exponent1 &operator *= (const exponent1 &e) { first += e.first; return *this; }
exponent1 operator * (const exponent1 &e) const { return exponent1 (first + e.first); }
template<class T> laurentpoly<T, exponent1> operator * (const T &c) const
{
laurentpoly<T, exponent1> r;
r.addeq (c, *this);
return r;
}
bool operator == (int x) const { assert (x == 0); return !first; }
bool operator != (int x) const { return !operator == (x); }
bool operator == (const exponent1 &e) const { return first == e.first; }
bool operator != (const exponent1 &e) const { return !operator == (e); }
bool operator < (const exponent1 &e) const { return first < e.first; }
exponent1 operator ^ (int p) const { return exponent1 (first * p); }
void show_self () const { printf ("(%d)", first); }
void display_self () const { show_self (); newline (); }
};
class exponent2
{
public:
int first,
second;
public:
exponent2 () : first(0), second(0) { }
explicit exponent2 (int i) : first(0), second(0) { assert (i == 0); }
exponent2 (int first_, int second_) : first(first_), second(second_) { }
exponent2 (const exponent2 &e) : first(e.first), second(e.second) { }
~exponent2 () { }
exponent2 &operator = (const exponent2 &e) { first = e.first; second = e.second; return *this; }
inline laurentpoly<int, exponent2> operator + (const exponent2 &e) const;
exponent2 &operator *= (const exponent2 &e) { first += e.first; second += e.second; return *this; }
exponent2 operator * (const exponent2 &e) const { return exponent2 (first + e.first, second + e.second); }
template<class T> laurentpoly<T, exponent2> operator * (const T &c) const
{
laurentpoly<T, exponent2> r;
r.addeq (c, *this);
return r;
}
bool operator == (int x) const { assert (x == 0); return !first && !second; }
bool operator != (int x) const { return !operator == (x); }
bool operator == (const exponent2 &e) const { return first == e.first && second == e.second; }
bool operator != (const exponent2 &e) const { return !operator == (e); }
bool operator < (const exponent2 &e) const { return first < e.first
|| (first == e.first && second < e.second); }
exponent2 operator ^ (int p) const { return exponent2 (first * p, second * p); }
void show_self () const { printf ("(%d,%d)", first, second); }
void display_self () const { show_self (); newline (); }
unsigned texwidth () const
{
if (!first && !second)
return 1;
unsigned w = 0;
if (first == 1)
w ++;
else if (first < 0)
w += 3;
else if (first)
w += 2;
if (second == 1)
w ++;
else if (second < 0)
w += 3;
else if (second)
w += 2;
return w;
}
void texshow (FILE *fp) const
{
if (!first && !second)
printf ("1");
else
{
if (first == 1)
printf ("t");
else if (first)
printf ("t^{%d}", first);
if (second == 1)
printf ("q");
else if (second)
printf ("q^{%d}", second);
}
}
};
#if 0
template<class T, class E> laurentpoly<T, E> operator * (const T &c, const E &e)
{
return e*c;
}
#endif
template<class C, class E>
class laurentpoly
{
public:
typedef typename map<E, C>::iter map_iter;
typedef typename map<E, C>::const_iter map_const_iter;
map<E, C> m;
public:
laurentpoly () { }
explicit laurentpoly (const C &c) { m.push (E (0), c); }
explicit laurentpoly (const E &e) { m.push (e, 1); }
laurentpoly (const laurentpoly &p) : m(p.m) { }
laurentpoly (copy, const laurentpoly &p) : m(COPY, p.m) { }
~laurentpoly () { }
laurentpoly &operator = (const laurentpoly &p) { m = p.m; return *this; }
laurentpoly &operator = (const C &c) { m.clear (); m.push (E (0), c); }
bool operator == (const laurentpoly &p) { return m == p.m; }
bool operator != (const laurentpoly &p) { return m != p.m; }
laurentpoly &operator += (const laurentpoly &p);
laurentpoly &operator -= (const laurentpoly &p);
laurentpoly &operator *= (const laurentpoly &p) { operator = (*this * p); }
laurentpoly &operator *= (const C &s);
laurentpoly &subeq (const C &s, const E &e);
laurentpoly &addeq (const C &s, const E &e);
laurentpoly &muleq (const C &s, const E &e);
laurentpoly &muladdeq (const C &s, const E &e, const laurentpoly &p);
laurentpoly operator - () const;
laurentpoly operator + (const E &e) const { return *this + laurentpoly (e); }
laurentpoly operator + (const C &c) const { return *this + laurentpoly (c); }
laurentpoly operator + (const laurentpoly &p) const;
laurentpoly operator - (const laurentpoly &p) const;
laurentpoly operator * (const laurentpoly &p) const;
laurentpoly operator * (const E &e) const;
laurentpoly operator * (const C &s) const;
C aug () const
{
C r = 0;
for (map_const_iter i = m; i; i ++)
r += i.val ();
return r;
}
void show_self () const;
void display_self () const { show_self (); newline (); }
void texshow (FILE *fp);
};
template<class C, class E> inline laurentpoly<C, E> operator + (const E &e, const laurentpoly<C, E> &p) { return p + e; }
template<class C, class E> inline laurentpoly<C, E> operator + (const C &c, const laurentpoly<C, E> &p) { return p + c; }
template<class C, class E> inline laurentpoly<C, E> operator * (const C &s, const laurentpoly<C, E> &p) { return p * s; }
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::operator += (const laurentpoly &p)
{
for (map_const_iter i = p.m; i; i ++)
addeq (i.val (), i.key ());
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::operator -= (const laurentpoly &p)
{
for (map_const_iter i = p.m; i; i ++)
subeq (i.val (), i.key ());
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::operator *= (const C &s)
{
for (map_iter i = m; i; i ++)
i.val () *= s;
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::addeq (const C &s, const E &e)
{
pair<C &, bool> x = m.find (e);
if (!x.second)
x.first = s;
else
x.first += s;
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::subeq (const C &s, const E &e)
{
pair<C &, bool> x = m.find (e);
if (!x.second)
x.first = -s;
else
x.first -= s;
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::muleq (const C &s, const E &e)
{
map<C, E> new_m;
for (map_const_iter i = m; i; i ++)
m.push (e * m.key (), s * m.val ());
m = new_m;
return *this;
}
template<class C, class E> laurentpoly<C, E> &
laurentpoly<C, E>::muladdeq (const C &s, const E &e, const laurentpoly &p)
{
for (map_const_iter i = p.m; i; i ++)
addeq (s * i.val (), e * i.key ());
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator - () const
{
map<C, E> new_m;
for (map_const_iter i = m; i; i ++)
new_m.push (m.key (), -m.val ());
return laurentpoly (new_m);
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator + (const laurentpoly &p) const
{
laurentpoly r (COPY, *this);
r += p;
return r;
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator - (const laurentpoly &p) const
{
laurentpoly r (COPY, *this);
r -= p;
return r;
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator * (const laurentpoly &p) const
{
laurentpoly r (*this);
for (map_const_iter i = m; i; i ++)
r.muladdeq (i.val (), i.key (), p.m);
return r;
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator * (const C &s) const
{
laurentpoly r (COPY, *this);
for (map_iter i = r.m; i; i ++)
i.val () *= s;
return r;
}
template<class C, class E> laurentpoly<C, E>
laurentpoly<C, E>::operator * (const E &e) const
{
laurentpoly r;
for (map_const_iter i = m; i; i ++)
r.addeq (i.val (), i.key () * e);
return r;
}
template<class C, class E> void
laurentpoly<C, E>::show_self () const
{
if (m.card () == 0)
{
printf ("0");
return;
}
bool first = 1;
for (map_const_iter i = m; i; i ++)
{
if (i.val () != 0)
{
if (!first)
printf (" + ");
if (i.val () == 1)
show (i.key ());
else
{
show (i.val ());
printf ("*");
show (i.key ());
}
first = 0;
}
}
}
template<class C, class E> void
laurentpoly<C, E>::texshow (FILE *fp)
{
bool first = 1;
unsigned w = 0;
for (map_const_iter i = m; i; i ++)
{
if (i.val () == 0)
continue;
if (w > 47)
{
fprintf (fp, " \\\\\n");
fprintf (fp, " & & & ");
w = 0;
}
if (first)
first = 0;
else
{
printf ("+");
w += 3;
}
if (i.val () == 1)
{
i.key ().texshow (fp);
w += i.key ().texwidth ();
}
else
{
fprintf (fp, "%d", i.val ());
w ++;
if (i.key () != 0)
{
i.key ().texshow (fp);
w += i.key ().texwidth ();
}
}
}
}
typedef laurentpoly<int, exponent1> intpoly1;
typedef laurentpoly<int, exponent2> intpoly2;
inline laurentpoly<int, exponent1>
exponent1::operator + (const exponent1 &e) const
{
intpoly1 r;
r.addeq (1, *this);
r.addeq (1, e);
return r;
}
inline laurentpoly<int, exponent2>
exponent2::operator + (const exponent2 &e) const
{
intpoly2 r;
r.addeq (1, *this);
r.addeq (1, e);
return r;
}

View File

@ -0,0 +1,472 @@
template<class R> class linear_combination_const_iter;
template<class R>
class linear_combination
{
private:
// friend class linear_combination_iter<R>;
friend class linear_combination_const_iter<R>;
friend class module<R>;
friend class free_submodule<R>;
friend class quotient_module<R>;
friend class mod_map<R>;
typedef module<R> Rmod;
public:
// typedef linear_combination_iter<R> iter;
typedef linear_combination_const_iter<R> const_iter;
private:
ptr<const Rmod> m;
map<unsigned, R> v;
public:
linear_combination () { }
explicit linear_combination (ptr<const Rmod> m_) : m(m_) { }
linear_combination (ptr<const Rmod> m_, int x)
: m(m_)
{
assert (x == 0);
}
linear_combination (const linear_combination &lc) : m(lc.m), v(lc.v) { }
linear_combination (copy, const linear_combination &lc)
: m(lc.m)
{
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
v.push (i.key (), R (COPY, i.val ()));
}
~linear_combination () { }
linear_combination &operator = (const linear_combination &lc)
{
m = lc.m;
v = lc.v;
return *this;
}
bool operator == (const linear_combination &lc2) const
{
assert (m == lc2.m);
linear_combination lc3 (COPY, *this);
lc3 -= lc2;
return lc3 == 0;
}
bool operator == (int x) const
{
assert (x == 0);
#ifndef NDEBUG
check ();
#endif
return v.is_empty ();
}
bool operator != (int x) const { return !operator == (x); }
bool homogeneous () const
{
if (v.is_empty ())
return 1;
pair<unsigned, R> p = v.head ();
grading hq = m->generator_grading (p.first);
for (typename map<unsigned, R>::const_iter i = v; i; i ++)
{
if (hq != m->generator_grading (i.key ()))
return 0;
}
return 1;
}
pair<unsigned, R> head () const { return v.head (); }
grading hq () const
{
// assert (homogeneous ());
pair<unsigned, R> p = v.head ();
return m->generator_grading (p.first);
}
R annihilator () const;
void set (R c, unsigned i)
{
if (c == 0)
v -= i;
else
v[i] = c;
}
linear_combination operator * (R c) const
{
linear_combination r (COPY, *this);
r *= c;
return r;
}
linear_combination operator + (const linear_combination &lc) const
{
linear_combination r (COPY, *this);
r += lc;
return r;
}
linear_combination operator - (const linear_combination &lc) const
{
linear_combination r (COPY, *this);
r -= lc;
return r;
}
linear_combination &operator += (unsigned i) { return muladd (1, i); }
linear_combination &operator -= (unsigned i) { return mulsub (1, i); }
linear_combination &operator *= (R c);
linear_combination &operator /= (R c);
linear_combination &operator += (const linear_combination &lc);
linear_combination &operator -= (const linear_combination &lc);
linear_combination &muladd (R c, unsigned i);
linear_combination &muladd (R c, const linear_combination &lc);
linear_combination &mulsub (R c, unsigned i);
linear_combination &mulsub (R c, const linear_combination &lc);
void yank (unsigned i) { v.yank (i); }
void clear () { v.clear (); }
bool operator % (unsigned i) const { return v % i; }
R operator () (unsigned i) const { return v(i, R (0)); }
unsigned card () const { return v.card (); }
#ifndef NDEBUG
void check () const
{
for (typename map<unsigned, R>::const_iter i = v; i; i ++)
assert (!m->is_zero (i.val (), i.key ()));
}
#endif
void show_self () const;
void display_self () const { show_self (); newline (); }
};
template<class R> linear_combination<R>
operator * (R c, const linear_combination<R> &lc)
{
return lc * c;
}
template<class R>
class linear_combination_const_iter
{
typename map<unsigned, R>::const_iter i;
public:
linear_combination_const_iter (const linear_combination<R> &lc) : i(lc.v) { }
~linear_combination_const_iter () { }
operator bool () const { return i; }
linear_combination_const_iter &operator ++ () { i ++; return *this; }
void operator ++ (int) { i ++; }
unsigned key () const { return i.key (); }
R val () { return i.val (); }
};
template<class R> R
linear_combination<R>::annihilator () const
{
R r (1);
for (typename map<unsigned, R>::const_iter i = v; i; i ++)
r = r.lcm (m->annihilator (i.val (), i.key ()));
return r;
}
template<class R> linear_combination<R> &
linear_combination<R>::operator *= (R c)
{
if (c == 0)
v.clear ();
else if (c != 1)
{
for (typename map<unsigned, R>::iter i = v; i; i ++)
i.val () *= c;
}
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::operator += (const linear_combination &lc)
{
assert (m == lc.m);
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
{
unsigned k = i.key ();
R &c = v[k];
c += i.val ();
if (m->is_zero (c, k))
v -= k;
}
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::operator -= (const linear_combination &lc)
{
assert (m == lc.m);
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
{
unsigned k = i.key ();
R &c = v[k];
c -= i.val ();
if (m->is_zero (c, k))
v -= k;
}
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::muladd (R c, unsigned i)
{
R &ic = v[i];
ic += c;
if (m->is_zero (ic, i))
v -= i;
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::muladd (R c, const linear_combination &lc)
{
assert (m == lc.m);
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
{
unsigned k = i.key ();
R &vc = v[k];
vc += (c * i.val ());
if (vc == 0)
v -= k;
}
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::mulsub (R c, unsigned i)
{
R &ic = v[i];
ic -= c;
if (m->is_zero (ic, i))
v -= i;
return *this;
}
template<class R> linear_combination<R> &
linear_combination<R>::mulsub (R c, const linear_combination &lc)
{
assert (m == lc.m);
for (typename map<unsigned, R>::const_iter i = lc.v; i; i ++)
{
unsigned k = i.key ();
R &vc = v[k];
vc -= (c * i.val ());
if (vc == 0)
v -= k;
}
return *this;
}
template<class R> void
linear_combination<R>::show_self () const
{
bool first = 1;
for (typename map<unsigned, R>::const_iter i = v; i; i ++)
{
if (first)
first = 0;
else
printf (" + ");
show (i.val ());
printf ("*%d", i.key ());
}
}
template<>
class linear_combination<Z2>
{
private:
// friend class linear_combination_iter<Z2>;
friend class linear_combination_const_iter<Z2>;
friend class module<Z2>;
friend class free_submodule<Z2>;
friend class quotient_module<Z2>;
friend class mod_map<Z2>;
typedef module<Z2> Z2mod;
public:
typedef linear_combination_const_iter<Z2> const_iter;
private:
ptr<const Z2mod> m;
set<unsigned> v;
public:
linear_combination () { }
linear_combination (ptr<const Z2mod> m_) : m(m_) { }
linear_combination (const linear_combination &lc) : m(lc.m), v(lc.v) { }
linear_combination (copy, const linear_combination &lc) : m(lc.m), v(COPY, lc.v) { }
~linear_combination () { }
linear_combination &operator = (const linear_combination &lc)
{
m = lc.m;
v = lc.v;
return *this;
}
bool operator == (const linear_combination &lc) const { assert (m == lc.m); return v == lc.v; }
bool operator == (int x) const { assert (x == 0); return v.is_empty (); }
bool operator != (int x) const { return !operator == (x); }
pair<unsigned, Z2> head () const { return pair<unsigned, Z2> (v.head (), Z2 (1)); }
grading hq () const
{
// assert (homogeneous ());
return m->generator_grading (v.head ());
}
Z2 annihilator () const
{
return Z2 (operator == (0) ? 1 : 0);
}
void set (Z2 c, unsigned i)
{
if (c == 0)
v -= i;
else
v += i;
}
linear_combination operator * (Z2 c) const
{
if (c == 1)
return *this;
else
return linear_combination (m);
}
linear_combination operator + (const linear_combination &lc) const
{
linear_combination r (COPY, *this);
r += lc;
return r;
}
linear_combination operator - (const linear_combination &lc) const
{
linear_combination r (COPY, *this);
r -= lc;
return r;
}
linear_combination &operator *= (Z2 c)
{
if (c == 0)
v.clear ();
return *this;
}
linear_combination &operator /= (Z2 c) { assert (c == 1); return *this; }
linear_combination &operator += (unsigned i) { v.toggle (i); return *this; }
linear_combination &operator -= (unsigned i) { v.toggle (i); return *this; }
linear_combination &muladd (Z2 c, unsigned i)
{
if (c == 1)
operator += (i);
return *this;
}
linear_combination &mulsub (Z2 c, unsigned i)
{
if (c == 1)
operator -= (i);
return *this;
}
linear_combination &operator += (const linear_combination &lc) { v ^= lc.v; return *this; }
linear_combination &operator -= (const linear_combination &lc) { v ^= lc.v; return *this; }
linear_combination &muladd (Z2 c, const linear_combination &lc)
{
if (c == 1)
operator += (lc);
return *this;
}
linear_combination &mulsub (Z2 c, const linear_combination &lc)
{
if (c == 1)
operator -= (lc);
return *this;
}
void yank (unsigned i) { v.yank (i); }
void clear () { v.clear (); }
bool operator % (unsigned i) const { return v % i; }
Z2 operator () (unsigned i) const { return Z2 (v % i); }
unsigned card () const { return v.card (); }
#ifndef NDEBUG
void check () const;
#endif
void show_self () const;
void display_self () const { show_self (); newline (); }
};
inline void
linear_combination<Z2>::show_self () const
{
bool first = 1;
for (set_const_iter<unsigned> i = v; i; i ++)
{
if (first)
first = 0;
else
printf ("+");
printf ("%d", i.val ());
}
}
inline linear_combination<Z2>
operator * (Z2 c, const linear_combination<Z2> &lc)
{
return lc * c;
}
template<>
class linear_combination_const_iter<Z2>
{
set<unsigned>::const_iter i;
public:
linear_combination_const_iter (const linear_combination<Z2> &lc) : i(lc.v) { }
~linear_combination_const_iter () { }
operator bool () const { return i; }
linear_combination_const_iter &operator ++ () { i ++; return *this; }
void operator ++ (int) { i ++; }
unsigned key () const { return i.val (); }
Z2 val () { return Z2 (1); }
};

1255
algebra/module.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,495 @@
/* multivariate polynomial in a (vector) variable x with coefficients
in T. */
enum variable { VARIABLE };
template<unsigned n>
class multivariate_monomial
{
private:
unsigned v[n];
public:
multivariate_monomial ()
{
for (unsigned i = 0; i < n; i ++)
v[i] = 0;
}
multivariate_monomial (variable, unsigned j)
{
for (unsigned i = 0; i < n; i ++)
v[i] = 0;
assert (j >= 1 && j <= n);
v[j - 1] = 1;
}
multivariate_monomial (const multivariate_monomial &e)
{
for (unsigned i = 0; i < n; i ++)
v[i] = e.v[i];
}
~multivariate_monomial () { }
multivariate_monomial &operator = (const multivariate_monomial &e)
{
for (unsigned i = 0; i < n; i ++)
v[i] = e.v[i];
return *this;
}
unsigned degree () const
{
unsigned d = 0;
for (unsigned i = 0; i < n; i ++)
d += v[i];
return d;
}
bool operator == (const multivariate_monomial &e) const
{
for (unsigned i = 0; i < n; i ++)
{
if (v[i] != e.v[i])
return 0;
}
return 1;
}
bool operator < (const multivariate_monomial &e) const
{
for (unsigned i = 0; i < n; i ++)
{
if (v[i] < e.v[i])
return 1;
if (v[i] > e.v[i])
return 0;
}
return 0;
}
multivariate_monomial operator + (const multivariate_monomial &e) const
{
multivariate_monomial m;
for (unsigned i = 0; i < n; i ++)
m.v[i] = v[i] + e.v[i];
return m;
}
bool divides (const multivariate_monomial &num) const
{
for (unsigned i = 0; i < n; i ++)
{
if (v[i] > num.v[i])
return 0;
}
return 1;
}
bool operator | (const multivariate_monomial &num) const { return divides (num); }
multivariate_monomial &mineq (const multivariate_monomial &e)
{
for (unsigned i = 0; i < n; i ++)
{
if (e.v[i] < v[i])
v[i] = e.v[i];
}
return *this;
}
multivariate_monomial operator - (const multivariate_monomial &denom) const
{
multivariate_monomial m;
for (unsigned i = 0; i < n; i ++)
{
assert (v[i] >= denom.v[i]);
m.v[i] = v[i] - denom.v[i];
}
return m;
}
void show_self () const
{
printf ("x^(");
for (unsigned i = 0; i < n; i ++)
{
if (i > 0)
printf (",");
printf ("%d", v[i]);
}
printf (")");
}
};
template<class T, unsigned n>
class multivariate_polynomial
{
public:
typedef linear_combination<multivariate_polynomial<T, n> > linear_combination;
typedef linear_combination_const_iter<multivariate_polynomial<T, n> >
linear_combination_const_iter;
private:
typedef multivariate_monomial<n> monomial;
map<monomial, T> coeffs;
explicit multivariate_polynomial (const map<monomial, T> &coeffs_) : coeffs(coeffs_) { }
public:
multivariate_polynomial () { }
multivariate_polynomial (int x)
{
T c (x);
if (c != 0)
coeffs.push (monomial (), c);
}
multivariate_polynomial (T c)
{
if (c != 0)
coeffs.push (monomial (), c);
}
multivariate_polynomial (T c, variable, unsigned i)
{
if (c != 0)
coeffs.push (monomial (VARIABLE, i), c);
}
multivariate_polynomial (T c, const monomial &m)
{
if (c != 0)
coeffs.push (m, c);
}
multivariate_polynomial (const multivariate_polynomial &p) : coeffs(p.coeffs) { }
multivariate_polynomial (copy, const multivariate_polynomial &p) : coeffs(COPY, p.coeffs) { }
~multivariate_polynomial () { }
multivariate_polynomial &operator = (const multivariate_polynomial &p)
{
coeffs = p.coeffs;
return *this;
}
multivariate_polynomial &operator = (int x)
{
coeffs = map<monomial, T> ();
T c (x);
if (c != 0)
coeffs.push (monomial (), c);
return *this;
}
multivariate_polynomial &operator = (T c)
{
coeffs = map<monomial, T> ();
if (c != 0)
coeffs.push (monomial (), c);
return *this;
}
bool is_unit () const;
bool operator == (multivariate_polynomial p) const
{
#ifndef NDEBUG
check ();
p.check ();
#endif
return coeffs == p.coeffs;
}
bool operator == (int x) const
{
#ifndef NDEBUG
check ();
#endif
T c (x);
if (c == 0)
return coeffs.is_empty ();
else
{
if (coeffs.card () != 1)
return 0;
pair<monomial, T> p = coeffs.head ();
return p.first.degree () == 0
&& p.second == c;
}
}
bool operator != (int x) const { return !operator == (x); }
multivariate_polynomial &operator += (multivariate_polynomial p);
multivariate_polynomial &operator -= (multivariate_polynomial p);
multivariate_polynomial &operator *= (multivariate_polynomial p) { return operator = (*this * p); }
multivariate_polynomial &operator *= (T s);
multivariate_polynomial &add_term (T c, variable, unsigned i)
{
monomial m (VARIABLE, i);
T &c2 = coeffs[m];
c2 += c;
if (c2 == 0)
coeffs -= m;
return *this;
}
multivariate_polynomial operator - () const { return multivariate_polynomial () - *this; }
multivariate_polynomial operator + (multivariate_polynomial p) const
{
multivariate_polynomial r (COPY, *this);
r += p;
return r;
}
multivariate_polynomial operator - (multivariate_polynomial p) const
{
multivariate_polynomial r (COPY, *this);
r -= p;
return r;
}
multivariate_polynomial operator * (const multivariate_polynomial &p) const;
monomial common_monomial () const;
pair<multivariate_polynomial, multivariate_polynomial>
uncommon_factors (multivariate_polynomial b, basedvector<multivariate_polynomial, 1> ds);
maybe<multivariate_polynomial>
divides_exactly (const multivariate_polynomial &n) const;
multivariate_polynomial divide_exact (const multivariate_polynomial &d) const;
bool operator | (const multivariate_polynomial &num) const { abort (); }
#ifndef NDEBUG
void check () const;
#endif
static void show_ring ()
{
T::show_ring ();
switch (n)
{
case 0: break;
case 1: printf ("[x_1]"); break;
case 2: printf ("[x_1, x_2]"); break;
default:
printf ("[x_1, ..., x_%d]", n);
break;
}
}
void display_self () const { show_self (); newline (); }
void show_self () const;
};
template<class T, unsigned n> bool
multivariate_polynomial<T, n>::is_unit () const
{
// ??? is_singleton
if (coeffs.card () != 1)
return 0;
pair<monomial, T> p = coeffs.head ();
return p.first.degree () == 0
&& p.second.is_unit ();
}
template<class T, unsigned n> multivariate_polynomial<T, n> &
multivariate_polynomial<T, n>::operator += (multivariate_polynomial p)
{
for (typename map<monomial, T>::const_iter i = p.coeffs; i; i ++)
{
monomial m = i.key ();
T &c = coeffs[m];
c += i.val ();
if (c == 0)
coeffs -= m;
}
return *this;
}
template<class T, unsigned n> multivariate_polynomial<T, n> &
multivariate_polynomial<T, n>::operator -= (multivariate_polynomial p)
{
for (typename map<monomial, T>::const_iter i = p.coeffs; i; i ++)
{
monomial m = i.key ();
T &c = coeffs[m];
c -= i.val ();
if (c == 0)
coeffs -= m;
}
return *this;
}
template<class T, unsigned n> multivariate_polynomial<T, n> &
multivariate_polynomial<T, n>::operator *= (T s)
{
if (s == 0)
coeffs.clear ();
else
{
for (typename map<monomial, T>::iter i = coeffs; i; i ++)
i.val () *= s;
}
}
template<class T, unsigned n> multivariate_polynomial<T, n>
multivariate_polynomial<T, n>::operator * (const multivariate_polynomial &p) const
{
multivariate_polynomial r;
for (typename map<monomial, T>::const_iter i = coeffs; i; i ++)
for (typename map<monomial, T>::const_iter j = p.coeffs; j; j ++)
{
monomial m = i.key () + j.key ();
T &c = r.coeffs[m];
c += i.val () * j.val ();
if (c == 0)
r.coeffs -= m;
}
return r;
}
template<class T, unsigned n> multivariate_monomial<n>
multivariate_polynomial<T, n>::common_monomial () const
{
monomial m = coeffs.head ().first;
for (typename map<monomial, T>::const_iter i = coeffs; i; i ++)
m.mineq (i.key ());
return m;
}
template<class T, unsigned n> pair<multivariate_polynomial<T, n>,
multivariate_polynomial<T, n> >
multivariate_polynomial<T, n>::uncommon_factors (multivariate_polynomial b,
basedvector<multivariate_polynomial, 1> ds)
{
multivariate_polynomial a = *this;
monomial m = a.common_monomial ();
m.mineq (b.common_monomial ());
multivariate_polynomial mp (1, m);
a = a.divide_exact (mp);
b = b.divide_exact (mp);
L:
for (unsigned i = 1; i <= ds.size (); i ++)
{
const multivariate_polynomial &d = ds[i];
maybe<multivariate_polynomial> aq = d.divides_exactly (a);
if (aq.is_some ())
{
maybe<multivariate_polynomial> bq = d.divides_exactly (b);
if (bq.is_some ())
{
a = aq.some ();
b = bq.some ();
goto L;
}
}
}
return pair<multivariate_polynomial, multivariate_polynomial> (a, b);
}
template<class T, unsigned n> maybe<multivariate_polynomial<T, n> >
multivariate_polynomial<T, n>::divides_exactly (const multivariate_polynomial &num) const
{
const multivariate_polynomial &d = *this;
multivariate_polynomial r (COPY, num);
multivariate_polynomial q;
pair<monomial, T> d_leading_term = d.coeffs.tail ();
for (;;)
{
if (r == 0)
{
// ??
assert (q*d == num);
return maybe<multivariate_polynomial> (q);
}
pair<monomial, T> r_leading_term = r.coeffs.tail ();
if (d_leading_term.first | r_leading_term.first)
{
multivariate_polynomial m (r_leading_term.second / d_leading_term.second,
r_leading_term.first - d_leading_term.first);
r -= m * d;
q += m;
}
else
return maybe<multivariate_polynomial> ();
}
}
template<class T, unsigned n> multivariate_polynomial<T, n>
multivariate_polynomial<T, n>::divide_exact (const multivariate_polynomial &d) const
{
maybe<multivariate_polynomial> r = d.divides_exactly (*this);
return r.some ();
}
#ifndef NDEBUG
template<class T, unsigned n> void
multivariate_polynomial<T, n>::check () const
{
for (typename map<monomial, T>::const_iter i = coeffs; i; i ++)
assert (i.val () != 0);
}
#endif
template<class T, unsigned n> void
multivariate_polynomial<T, n>::show_self () const
{
unsigned first = 1;
for (typename map<monomial, T>::const_iter i = coeffs; i; i ++)
{
monomial m = i.key ();
T c = i.val ();
assert (c != 0);
if (first)
first = 0;
else
printf (" + ");
if (m.degree () == 0)
{
if (c == 1)
printf ("1");
else
show (c);
}
else
{
if (c != 1)
{
show (c);
printf ("*");
}
show (m);
}
}
if (first)
printf ("0");
}

125
algebra/polynomial.cpp Normal file
View File

@ -0,0 +1,125 @@
#include <knotkit.h>
polynomial<Z2>
polynomial<Z2>::operator * (polynomial<Z2> p) const
{
set<unsigned> r_coeffs;
for (set_const_iter<unsigned> i = coeffs; i; i ++)
for (set_const_iter<unsigned> j = p.coeffs; j; j ++)
r_coeffs.toggle (i.val () + j.val ());
return polynomial<Z2> (r_coeffs);
}
pair<polynomial<Z2>, polynomial<Z2> >
polynomial<Z2>::divide_with_remainder (polynomial d) const
{
assert (d != 0);
polynomial<Z2> r (COPY, *this);
polynomial<Z2> q;
unsigned d_leading_exponent = d.coeffs.tail ();
for (;;)
{
if (r == 0)
break;
unsigned r_leading_exponent = r.coeffs.tail ();
if (r_leading_exponent < d_leading_exponent)
break;
for (set_const_iter<unsigned> i = d.coeffs; i; i ++)
r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ());
q.coeffs.toggle (r_leading_exponent - d_leading_exponent);
}
assert (r == 0 || r.degree () < d.degree ());
// assert (*this == q*d + r);
return pair<polynomial<Z2>, polynomial<Z2> > (q, r);
}
polynomial<Z2>
polynomial<Z2>::mod (polynomial d) const
{
assert (d != 0);
polynomial<Z2> r (COPY, *this);
unsigned d_leading_exponent = d.coeffs.tail ();
for (;;)
{
if (r == 0)
break;
unsigned r_leading_exponent = r.coeffs.tail ();
if (r_leading_exponent < d_leading_exponent)
break;
for (set_const_iter<unsigned> i = d.coeffs; i; i ++)
r.coeffs.toggle (r_leading_exponent - d_leading_exponent + i.val ());
}
assert (r == 0 || r.degree () < d.degree ());
return r;
}
bool
polynomial<Z2>::divides (polynomial d) const
{
return mod (d) == 0;
}
polynomial<Z2>
polynomial<Z2>::divide_exact (polynomial d) const
{
pair<polynomial<Z2>, polynomial<Z2> > qr = divide_with_remainder (d);
assert (qr.second == 0);
return qr.first;
}
polynomial<Z2>
polynomial<Z2>::gcd (polynomial b) const
{
// ??? can return *this
polynomial a = *this;
while (b != 0)
{
pair<polynomial<Z2>, polynomial<Z2> > a_qr = a.divide_with_remainder (b);
a = b;
b = a_qr.second;
}
return a;
}
void
polynomial<Z2>::show_self () const
{
unsigned first = 1;
for (set_const_iter<unsigned> i = coeffs; i; i ++)
{
unsigned e = i.val ();
if (first)
first = 0;
else
printf (" + ");
if (e == 0)
printf ("1");
else
{
if (e == 1)
printf ("x");
else
printf ("x^%d", e);
}
}
if (first)
printf ("0");
}

446
algebra/polynomial.h Normal file
View File

@ -0,0 +1,446 @@
/* univariate polynomial in a single variable `x' with coefficients in
T. */
template<class T>
class polynomial
{
private:
map<unsigned, T> coeffs;
polynomial (const map<unsigned, T> &coeffs_) : coeffs(coeffs_) { }
public:
polynomial () { }
polynomial (int x)
{
T c (x);
if (c != 0)
coeffs.push (0, c);
}
polynomial (T c)
{
if (c != 0)
coeffs.push (0, c);
}
polynomial (int x, unsigned e)
{
T c (x);
if (c != 0)
coeffs.push (e, c);
}
polynomial (T c, unsigned e)
{
if (c != 0)
coeffs.push (e, c);
}
polynomial (const polynomial &p) : coeffs(p.coeffs) { }
polynomial (copy, const polynomial &p) : coeffs(COPY, p.coeffs) { }
~polynomial () { }
polynomial &operator = (const polynomial &p) { coeffs = p.coeffs; return *this; }
polynomial &operator = (int x)
{
coeffs = map<unsigned, T> ();
T c (x);
if (c != 0)
coeffs.push (0, c);
return *this;
}
polynomial &operator = (T c)
{
coeffs = map<unsigned, T> ();
if (c != 0)
coeffs.push (0, c);
return *this;
}
unsigned degree () const;
bool is_unit () const;
bool operator == (polynomial p) const
{
#ifndef NDEBUG
check ();
p.check ();
#endif
return coeffs == p.coeffs;
}
bool operator == (int x) const
{
T c (x);
if (c == 0)
return coeffs.is_empty ();
else if (coeffs.card () != 1)
return 0;
else
{
pair<unsigned, T> p = coeffs.head ();
return p.first == 0
&& p.second == c;
}
}
bool operator != (int x) const { return !operator == (x); }
polynomial &operator += (polynomial p);
polynomial &operator -= (polynomial p);
polynomial &operator *= (polynomial p) { return operator = (*this * p); }
polynomial &operator *= (T s);
polynomial &add_term (T c, unsigned e)
{
T &c2 = coeffs[e];
c2 += c;
if (c2 == 0)
coeffs -= e;
return *this;
}
polynomial operator - () const { return polynomial () - *this; }
polynomial operator + (polynomial p) const
{
polynomial r (COPY, *this);
r += p;
return r;
}
polynomial operator - (polynomial p) const
{
polynomial r (COPY, *this);
r -= p;
return r;
}
polynomial operator * (polynomial p) const;
pair<polynomial, polynomial> divide_with_remainder (polynomial d) const;
polynomial mod (polynomial d) const;
bool divides (polynomial d) const;
polynomial divide_exact (polynomial d) const;
polynomial gcd (polynomial b) const;
#ifndef NDEBUG
void check () const;
#endif
static void show_ring () { T::show_ring (); printf ("[x]"); }
void display_self () const { show_self (); newline (); }
void show_self () const;
};
template<class T> unsigned
polynomial<T>::degree () const
{
return coeffs.tail ().first;
}
template<class T> bool
polynomial<T>::is_unit () const
{
// ??? is_singleton
if (coeffs.card () != 1)
return 0;
pair<unsigned, T> p = coeffs.head ();
return p.first == 0
&& p.second.is_unit ();
}
template<class T> polynomial<T> &
polynomial<T>::operator += (polynomial p)
{
for (typename map<unsigned, T>::const_iter i = p.coeffs; i; i ++)
{
unsigned e = i.key ();
T &c = coeffs[e];
c += i.val ();
if (c == 0)
coeffs -= e;
}
return *this;
}
template<class T> polynomial<T> &
polynomial<T>::operator -= (polynomial p)
{
for (typename map<unsigned, T>::const_iter i = p.coeffs; i; i ++)
{
unsigned e = i.key ();
T &c = coeffs[e];
c -= i.val ();
if (c == 0)
coeffs -= e;
}
return *this;
}
template<class T> polynomial<T> &
polynomial<T>::operator *= (T s)
{
if (s == 0)
coeffs.clear ();
else
{
for (typename map<unsigned, T>::iter i = coeffs; i; i ++)
i.val () *= s;
}
}
template<class T> polynomial<T>
polynomial<T>::operator * (polynomial p) const
{
polynomial r;
for (typename map<unsigned, T>::const_iter i = coeffs; i; i ++)
for (typename map<unsigned, T>::const_iter j = p.coeffs; j; j ++)
{
unsigned e = i.key () + j.key ();
T &c = r.coeffs[e];
c += i.val () * j.val ();
if (c == 0)
r.coeffs -= e;
}
return r;
}
template<class T> pair<polynomial<T>, polynomial<T> >
polynomial<T>::divide_with_remainder (polynomial d) const
{
assert (d != 0);
polynomial r (COPY, *this);
polynomial q;
pair<unsigned, T> d_leading_term = d.coeffs.tail ();
for (;;)
{
if (r == 0)
break;
pair<unsigned, T> r_leading_term = r.coeffs.tail ();
if (r_leading_term.first < d_leading_term.first)
break;
polynomial m (r_leading_term.second / d_leading_term.second,
r_leading_term.first - d_leading_term.first);
r -= m * d;
q += m;
}
assert (r == 0 || r.degree () < d.degree ());
// assert (*this == q*d + r);
return pair<polynomial, polynomial> (q, r);
}
template<class T> polynomial<T>
polynomial<T>::mod (polynomial d) const
{
pair<polynomial<T>, polynomial<T> > qr = divide_with_remainder (d);
return qr.second;
}
template<class T> bool
polynomial<T>::divides (polynomial d) const
{
pair<polynomial<T>, polynomial<T> > qr = divide_with_remainder (d);
return qr.second == 0;
}
template<class T> polynomial<T>
polynomial<T>::divide_exact (polynomial d) const
{
pair<polynomial<T>, polynomial<T> > qr = divide_with_remainder (d);
assert (qr.second == 0);
return qr.first;
}
template<class T> polynomial<T>
polynomial<T>::gcd (polynomial b) const
{
polynomial a = *this;
while (b != 0)
{
pair<polynomial<T>, polynomial<T> > a_qr = a.divide_with_remainder (b);
a = b;
b = a_qr.second;
}
return a;
}
#ifndef NDEBUG
template<class T> void
polynomial<T>::check () const
{
for (typename map<unsigned, T>::const_iter i = coeffs; i; i ++)
assert (i.val () != 0);
}
#endif
template<class T> void
polynomial<T>::show_self () const
{
unsigned first = 1;
for (typename map<unsigned, T>::const_iter i = coeffs; i; i ++)
{
unsigned e = i.key ();
T c = i.val ();
assert (c != 0);
if (first)
first = 0;
else
printf (" + ");
if (e == 0 && c == 1)
printf ("1");
else if (e == 0)
show (c);
else if (c == 1)
{
if (e == 1)
printf ("x");
else
printf ("x^%d", e);
}
else
{
show (c);
if (e == 1)
printf ("*x");
else
printf ("*x^%d", e);
}
}
if (first)
printf ("0");
}
template<>
class polynomial<Z2>
{
private:
set<unsigned> coeffs;
explicit polynomial (const set<unsigned> &coeffs_) : coeffs(coeffs_) { }
public:
polynomial () { }
explicit polynomial (int x)
{
Z2 c (x);
if (c != 0)
coeffs.push (0);
}
explicit polynomial (Z2 c)
{
if (c != 0)
coeffs.push (0);
}
polynomial (Z2 c, unsigned e)
{
if (c != 0)
coeffs.push (e);
}
polynomial (const polynomial &p) : coeffs(p.coeffs) { }
polynomial (copy, const polynomial &p) : coeffs(COPY, p.coeffs) { }
~polynomial () { }
polynomial &operator = (const polynomial &p) { coeffs = p.coeffs; return *this; }
polynomial &operator = (int x)
{
coeffs = set<unsigned> ();
Z2 c (x);
if (c != 0)
coeffs.push (0);
return *this;
}
polynomial &operator = (Z2 c)
{
coeffs = set<unsigned> ();
if (c == 1)
coeffs.push (0);
return *this;
}
bool operator == (polynomial p) const { return coeffs == p.coeffs; }
bool operator == (int x) const
{
Z2 c (x);
if (c == 0)
return coeffs.is_empty ();
else
return coeffs.card () == 1
&& coeffs.head () == 0;
}
bool operator != (int x) const { return !operator == (x); }
unsigned degree () const { return coeffs.tail (); }
polynomial &operator += (polynomial p) { coeffs ^= p.coeffs; return *this; }
polynomial &operator -= (polynomial p) { coeffs ^= p.coeffs; return *this; }
polynomial &operator *= (polynomial p) { return operator = (*this * p); }
polynomial &operator *= (Z2 s)
{
if (s == 0)
coeffs.clear ();
return *this;
}
polynomial &add_term (Z2 c, unsigned e)
{
if (c == 1)
coeffs.toggle (e);
return *this;
}
polynomial operator - () const { return polynomial (COPY, *this); };
polynomial operator + (polynomial p) const
{
polynomial r (COPY, *this);
r += p;
return r;
}
polynomial operator - (polynomial p) const
{
polynomial r (COPY, *this);
r -= p;
return r;
}
polynomial operator * (polynomial p) const;
pair<polynomial, polynomial> divide_with_remainder (polynomial d) const;
polynomial mod (polynomial d) const;
bool divides (polynomial d) const;
polynomial divide_exact (polynomial d) const;
polynomial gcd (polynomial b) const;
static void show_ring () { printf ("Z2[x]"); }
void display_self () const { show_self (); newline (); }
void show_self () const;
};

BIN
alternating Normal file

Binary file not shown.

1415
cobordism.cpp Normal file

File diff suppressed because it is too large Load Diff

208
cobordism.h Normal file
View File

@ -0,0 +1,208 @@
static const unsigned max_cpts = max_crossings * 2;
enum reverse_crossing_t { REVERSE_CROSSING };
enum reverse_orientation_t { REVERSE_ORIENTATION };
class resolution_diagram
{
public:
unsigned n_crossings;
smallbitset resolved;
smallbitset to_resolve;
unsigned n_starting_circles;
unsigned n_ending_circles;
unsigned marked_edge; // edge from cpt
unsigned marked_edge2;
smallbitset cpt_inside;
/* prev, next cpt on circle in some orientation */
basedvector<unsigned, 1> prev, next;
basedvector<unsigned, 1> cpt_starting_circle;
basedvector<unsigned, 1> cpt_ending_circle;
unsigned num_cpts () const { return n_crossings * 2; }
unsigned crossing_from_cpt (unsigned c) const
{
assert (between (1, c, n_crossings));
return c * 2 - 1;
}
unsigned crossing_to_cpt (unsigned c) const
{
assert (between (1, c, n_crossings));
return c * 2;
}
unsigned is_from_cpt (unsigned pt) const
{
assert (between (1, pt, num_cpts ()));
return is_odd (pt);
}
unsigned is_to_cpt (unsigned pt) const
{
assert (between (1, pt, num_cpts ()));
return is_even (pt);
}
unsigned cpt_crossing (unsigned pt) const
{
assert (between (1, pt, num_cpts ()));
return (pt + 1) / 2;
}
unsigned other_cpt (unsigned pt) const
{
assert (between (1, pt, num_cpts ()));
if (is_odd (pt))
return pt + 1;
else
return pt - 1;
}
unsigned marked_starting_circle () const
{
assert (marked_edge);
return cpt_starting_circle[marked_edge];
}
unsigned marked_ending_circle () const
{
assert (marked_edge);
unsigned c = cpt_crossing (marked_edge);
if (to_resolve(c))
{
if (is_to_cpt (marked_edge) != cpt_inside(marked_edge))
return cpt_ending_circle[crossing_from_cpt (c)];
else
return cpt_ending_circle[crossing_to_cpt (c)];
}
else
{
if (is_from_cpt (marked_edge))
return cpt_ending_circle[crossing_from_cpt (c)];
else
return cpt_ending_circle[crossing_to_cpt (c)];
}
}
unsigned crossing_from (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_starting_circle[crossing_from_cpt (c)];
}
unsigned crossing_to (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_starting_circle[crossing_to_cpt (c)];
}
unsigned crossing_ending_from (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_ending_circle[crossing_from_cpt (c)];
}
unsigned crossing_ending_right (unsigned c) const { return crossing_ending_from (c); }
unsigned crossing_ending_to (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_ending_circle[crossing_to_cpt (c)];
}
unsigned crossing_ending_left (unsigned c) const { return crossing_ending_to (c); }
bool crossing_from_inside (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_inside % crossing_from_cpt (c);
}
bool crossing_from_outside (unsigned c) const { return !crossing_from_inside (c); }
bool crossing_to_inside (unsigned c) const
{
assert (between (1, c, n_crossings));
return cpt_inside % crossing_to_cpt (c);
}
bool crossing_to_outside (unsigned c) const { return !crossing_to_inside (c); }
unsigned left_cpt (unsigned pt) const
{
if (cpt_inside % pt)
return next[pt];
else
return prev[pt];
}
unsigned right_cpt (unsigned pt) const
{
if (cpt_inside % pt)
return prev[pt];
else
return next[pt];
}
bool crossing_orientation (unsigned common, unsigned i) const;
bool crossing_is_split (unsigned c) const { return crossing_from (c) == crossing_to (c); }
bool crossing_is_join (unsigned c) const { return crossing_from (c) != crossing_to (c); }
bool marked_edge_left (unsigned p) const;
void compute_prev ();
void check ();
public:
resolution_diagram ();
resolution_diagram (unsigned n_crossings_,
unsigned n_starting_circles_,
unsigned n_ending_circles_);
resolution_diagram (reverse_crossing_t,
const resolution_diagram &rd,
smallbitset to_reverse);
resolution_diagram (reverse_orientation_t,
const resolution_diagram &rd);
resolution_diagram (const resolution_diagram &rd); // copies
resolution_diagram (copy, const resolution_diagram &rd);
resolution_diagram (reader &r);
~resolution_diagram () { }
resolution_diagram &operator = (const resolution_diagram &rd);
bool operator == (const resolution_diagram &rd) const;
/* reverse, reverse_orientation leave starting/ending circle numbers
unchanged. */
void reverse ();
void reverse_orientation ();
knot_diagram as_knot_diagram () const;
void d (basedvector<pair<unsigned, unsigned>, 1> &out) const;
void twisted_barE (basedvector<triple<unsigned, unsigned, set<unsigned> >, 1> &out) const;
void twin_arrows_P (basedvector<pair<unsigned, unsigned>, 1> &out) const;
void write_self (writer &w) const;
hash_t hash_self () const;
void show_self () const;
void display_self () const { show_self (); newline (); }
};
class resolution_diagram_builder
{
public:
ullmanset<1> gl_crossings;
ullmanset<1> gl_starting_circles, gl_ending_circles;
basedvector<set<unsigned>, 1> lg_edges;
resolution_diagram rd;
public:
resolution_diagram_builder ();
resolution_diagram_builder (const resolution_diagram_builder &); // doesn't exist
~resolution_diagram_builder () { }
resolution_diagram_builder &operator = (const resolution_diagram_builder &); // doesn't exist
void init (const knot_diagram &d,
smallbitset from_state, const smoothing &from_s,
smallbitset to_state, const smoothing &to_s,
smallbitset crossings);
void mirror ();
void reverse_orientation ();
void reverse_crossing (const knot_diagram &d,
const smoothing &from_s, const smoothing &to_s,
unsigned c);
};

11
cube.cpp Normal file
View File

@ -0,0 +1,11 @@
#include <knotkit.h>
sseq
compute_szabo_sseq (const cube<Z2> &c)
{
mod_map<Z2> d = c.compute_d (0, 0, 0, 0, 0);
sseq_builder builder (c.khC, d);
return builder.build_sseq ();
}

120
cube.h Normal file
View File

@ -0,0 +1,120 @@
class map_rules
{
public:
map_rules () { }
map_rules (const map_rules &); // doesn't exist
virtual ~map_rules () { }
map_rules &operator = (const map_rules &); // doesn't exist
virtual void map (basedvector<pair<unsigned, unsigned>, 1> &out,
resolution_diagram_builder &rdb) const = 0;
};
template<class R>
class cube /* of resolutions */
{
public:
typedef typename R::linear_combination linear_combination;
typedef typename R::linear_combination_const_iter linear_combination_const_iter;
public:
bool markedp_only;
knot_diagram &kd;
unsigned n_crossings;
unsigned n_resolutions;
unsigned n_generators;
vector<unsigned> resolution_circles;
vector<unsigned> resolution_generator1;
ptr<const module<R> > khC;
mod_map<R> compute_map (unsigned dh, unsigned max_n,
bool mirror,
bool reverse_orientation,
unsigned to_reverse,
const map_rules &rules) const;
mod_map<R> compute_d (unsigned dh, unsigned max_n,
bool mirror,
bool reverse_orientation,
unsigned to_reverse) const;
mod_map<R> compute_twin_arrows_P (bool mirror,
bool reverse_orientation,
unsigned to_reverse) const;
mod_map<R> H_i (unsigned c);
mod_map<R> compute_nu () const;
mod_map<R> compute_X (unsigned p) const;
void check_reverse_crossings ();
void check_reverse_orientation ();
public:
cube (knot_diagram &d_, bool markedp_only_ = 0);
~cube () { }
grading compute_generator_grading (unsigned g) const;
grading compute_state_monomial_grading (unsigned state, unsigned monomial) const;
unsigned generator (unsigned i, unsigned j) const;
pair<unsigned, unsigned> generator_state_monomial (unsigned g) const;
ptr<const module<R> > compute_kh () const;
void show_state (unsigned state) const;
void show_state_monomial (unsigned state, unsigned monomial) const;
void show_self () const { printf ("cube"); }
void display_self () const;
};
class twisted_map_rules
{
public:
twisted_map_rules () { }
twisted_map_rules (const twisted_map_rules &); // doesn't exist
virtual ~twisted_map_rules () { }
map_rules &operator = (const twisted_map_rules &); // doesn't exist
virtual void map (basedvector<triple<unsigned, unsigned, set<unsigned> >, 1> &out,
resolution_diagram_builder &rdb) const = 0;
};
template<class F>
class twisted_cube
{
public:
typedef fraction_field<polynomial<F> > R;
public:
const cube<R> &c;
public:
twisted_cube (const cube<R> &c_)
: c(c_)
{ }
twisted_cube (const twisted_cube &); // doesn't exist
~twisted_cube () { }
twisted_cube &operator = (const twisted_cube &); // doesn't exist
mod_map<R> compute_twisted_map (basedvector<int, 1> edge_weight,
unsigned dh,
unsigned to_reverse,
const twisted_map_rules &rules) const;
mod_map<R> compute_twisted_barE (basedvector<int, 1> edge_weight,
unsigned dh, unsigned to_reverse) const;
mod_map<R> twisted_d0 (basedvector<int, 1> edge_weight) const;
};
extern sseq compute_szabo_sseq (const cube<Z2> &c);
#include <cube_impl.h>

728
cube_impl.h Normal file
View File

@ -0,0 +1,728 @@
template<class R>
class khC_generators
{
const cube<R> &c;
public:
khC_generators (const khC_generators &g) : c(g.c) { }
khC_generators (const cube<R> &c_) : c(c_) { }
~khC_generators () { }
khC_generators &operator = (const khC_generators &); // doesn't exist
unsigned dim () const { return c.n_generators; }
unsigned free_rank () const { return c.n_generators; }
grading generator_grading (unsigned i) const { return c.compute_generator_grading (i); }
void show_generator (unsigned i) const
{
pair<unsigned, unsigned> sm = c.generator_state_monomial (i);
c.show_state_monomial (sm.first, sm.second);
}
R generator_ann (unsigned i) const { abort (); }
};
template<class R> mod_map<R>
cube<R>::compute_map (unsigned dh, unsigned max_n,
bool mirror,
bool reverse_orientation,
unsigned to_reverse,
const map_rules &rules) const
{
mod_map<R> r (khC);
smoothing from_s (kd);
smoothing to_s (kd);
resolution_diagram_builder rdb;
ullmanset<1> free_circles (max_circles);
ullmanset<1> from_circles (max_circles);
if (verbose)
{
fprintf (stderr, "computing differential...\n");
fprintf (stderr, "%d resolutions.\n", n_resolutions);
}
basedvector<pair<unsigned, unsigned>, 1> out;
for (unsigned fromstate = 0; fromstate < n_resolutions; fromstate ++)
{
if (verbose
&& (fromstate & unsigned_fill (n_crossings > 4
? n_crossings - 4
: 0)) == 0)
fprintf (stderr, "%d / %d resolutions done.\n", fromstate, n_resolutions);
unsigned n_zerocrossings = n_crossings - unsigned_bitcount (fromstate);
unsigned n_cobordisms = ((unsigned)1) << n_zerocrossings;
from_s.init (kd, smallbitset (n_crossings, fromstate));
unionfind<1> u (from_s.n_circles);
basedvector<unsigned, 1> from_circle_edge_rep (from_s.n_circles);
for (unsigned j = 1; j <= kd.num_edges (); j ++)
from_circle_edge_rep[from_s.edge_circle[j]] = j;
for (unsigned j = 0; j < n_cobordisms; j ++)
{
if (dh && unsigned_bitcount (j) != dh)
continue;
if (max_n && unsigned_bitcount (j) > max_n)
continue;
unsigned tostate = unsigned_pack (n_crossings, fromstate, j);
unsigned crossings = tostate & ~fromstate;
int sign = 1;
for (unsigned i = 1; i <= n_crossings; i ++)
{
if (unsigned_bittest (crossings, i))
break;
if (unsigned_bittest (fromstate, i))
sign *= -1;
}
// printf ("fromstate = %d, tostate = %d, sign = %d\n", fromstate, tostate, sign);
u.clear ();
from_circles.clear ();
for (unsigned_const_iter k = crossings; k; k ++)
{
unsigned c = k.val ();
unsigned from = from_s.ept_circle (kd, kd.crossings[c][1]),
to = from_s.ept_circle (kd, kd.crossings[c][3]);
from_circles += from;
from_circles += to;
u.join (from, to);
}
if (from_s.n_circles - from_circles.card () + 1 != u.num_sets ())
continue;
to_s.init (kd, smallbitset (n_crossings, tostate));
rdb.init (kd,
smallbitset (n_crossings, fromstate), from_s,
smallbitset (n_crossings, tostate), to_s,
smallbitset (n_crossings, crossings));
if (mirror)
rdb.mirror ();
if (reverse_orientation)
rdb.reverse_orientation ();
if (to_reverse)
rdb.reverse_crossing (kd, from_s, to_s, to_reverse);
// display (rdb.rd);
out.resize (0);
rules.map (out, rdb);
if (out.size () == 0)
continue;
free_circles.clear ();
for (unsigned i = 1; i <= from_s.n_circles; i ++)
{
if (! (rdb.gl_starting_circles % i))
free_circles.push (i);
}
unsigned n_free_circles = free_circles.card ();
unsigned n_free_monomials = ((unsigned)1) << n_free_circles;
for (unsigned i = 0; i < n_free_monomials; i ++)
{
unsigned m_from = 0,
m_to = 0;
for (unsigned_const_iter jj = i; jj; jj ++)
{
unsigned s = free_circles.nth (jj.val () - 1);
m_from = unsigned_bitset (m_from, s);
m_to = unsigned_bitset (m_to, to_s.edge_circle[from_circle_edge_rep[s]]);
}
for (unsigned j = 1; j <= out.size (); j ++)
{
unsigned v_from = m_from,
v_to = m_to;
unsigned l_from = out[j].first,
l_to = out[j].second;
for (unsigned_const_iter kk = l_from; kk; kk ++)
{
unsigned s = rdb.gl_starting_circles.nth (kk.val () - 1);
v_from = unsigned_bitset (v_from, s);
}
for (unsigned_const_iter kk = l_to; kk; kk ++)
{
unsigned s = rdb.gl_ending_circles.nth (kk.val () - 1);
v_to = unsigned_bitset (v_to, s);
}
if (markedp_only)
{
unsigned p = from_s.edge_circle[kd.marked_edge];
if (unsigned_bittest (v_from, p))
continue;
assert (!unsigned_bittest (v_to, p));
}
r[generator (fromstate, v_from)].muladd
(sign, generator (tostate, v_to));
}
}
}
}
if (verbose)
{
fprintf (stderr, "%d / %d resolutions done.\n", n_resolutions, n_resolutions);
fprintf (stderr, "computing differential done.\n");
}
return r;
}
class d_rules : public map_rules
{
public:
d_rules () { }
d_rules (const d_rules &); // doesn't exist
~d_rules () { }
d_rules &operator = (const d_rules &); // doesn't exist
void map (basedvector<pair<unsigned, unsigned>, 1> &out,
resolution_diagram_builder &rdb) const
{
rdb.rd.d (out);
}
};
template<class R> mod_map<R>
cube<R>::compute_d (unsigned dh, unsigned max_n,
bool mirror,
bool reverse_orientation,
unsigned to_reverse) const
{
return compute_map (dh, max_n,
mirror, reverse_orientation, to_reverse,
d_rules ());
}
class twin_arrows_P_rules : public map_rules
{
public:
twin_arrows_P_rules () { }
twin_arrows_P_rules (const twin_arrows_P_rules &); // doesn't exist
~twin_arrows_P_rules () { }
twin_arrows_P_rules &operator = (const twin_arrows_P_rules &); // doesn't exist
void map (basedvector<pair<unsigned, unsigned>, 1> &out,
resolution_diagram_builder &rdb) const
{
rdb.rd.twin_arrows_P (out);
}
};
template<class R> mod_map<R>
cube<R>::compute_twin_arrows_P (bool mirror,
bool reverse_orientation,
unsigned to_reverse) const
{
assert (kd.marked_edge);
mod_map<R> one (khC, 1);
mod_map<R> X = compute_X (kd.marked_edge);
mod_map<R> preP = compute_map (0, 0,
mirror, reverse_orientation, to_reverse,
twin_arrows_P_rules ());
return X.compose (one + preP);
}
template<class R> mod_map<R>
cube<R>::compute_nu () const
{
assert (!markedp_only);
mod_map<R> nu (khC);
for (unsigned i = 0, j = 1; i < n_resolutions; i ++)
{
smoothing s (kd, smallbitset (n_crossings, i));
for (unsigned j = 0; j < s.num_monomials (); j ++)
{
for (unsigned k = 1; k <= s.n_circles; k ++)
{
if (!unsigned_bittest (j, k))
{
unsigned j2 = unsigned_bitset (j, k);
nu[generator (i, j)].muladd (1, generator (i, j2));
}
}
}
}
nu.check_grading (0, 2);
assert (nu.compose (nu) == 0);
return nu;
}
template<class R> mod_map<R>
cube<R>::compute_X (unsigned p) const
{
assert (!markedp_only);
/* define Khovanov's map X */
mod_map<R> X (khC);
for (unsigned i = 0, j = 1; i < n_resolutions; i ++)
{
smoothing r (kd, smallbitset (n_crossings, i));
for (unsigned j = 0; j < r.num_monomials (); j ++)
{
unsigned s = r.edge_circle[p];
if (unsigned_bittest (j, s))
{
unsigned j2 = unsigned_bitclear (j, s);
X[generator (i, j)].muladd (1, generator (i, j2));
}
}
}
assert (X.compose (X) == 0);
return X;
}
template<class R> mod_map<R>
cube<R>::H_i (unsigned c)
{
mod_map<R> H_c (khC, 0);
for (unsigned i = 0; i < n_resolutions; i ++)
{
if (unsigned_bittest (i, c))
continue;
smoothing from_s (kd, smallbitset (n_crossings, i));
unsigned i2 = unsigned_bitset (i, c);
smoothing to_s (kd, smallbitset (n_crossings, i2));
basedvector<unsigned, 1> from_circle_edge_rep (from_s.n_circles);
for (unsigned j = 1; j <= kd.num_edges (); j ++)
from_circle_edge_rep[from_s.edge_circle[j]] = j;
unsigned from = from_s.crossing_from_circle (kd, c),
to = from_s.crossing_to_circle (kd, c);
for (unsigned j = 0; j < from_s.num_monomials (); j ++)
{
unsigned j2 = 0;
for (unsigned_const_iter k = j; k; k ++)
{
unsigned s = k.val ();
j2 = unsigned_bitset (j2, to_s.edge_circle[from_circle_edge_rep[s]]);
}
linear_combination &v = H_c[generator (i, j)];
if (from == to
&& unsigned_bittest (j, from))
{
j2 = unsigned_bitset (j2,
to_s.crossing_from_circle (kd, c));
j2 = unsigned_bitset (j2,
to_s.crossing_to_circle (kd, c));
v.muladd (1, generator (i2, j2));
}
else if (from != to
&& !unsigned_bittest (j, from)
&& !unsigned_bittest (j, to))
{
assert (! unsigned_bittest (j2,
to_s.crossing_from_circle (kd, c)));
v.muladd (1, generator (i2, j2));
}
}
}
H_c.check_grading (grading (1, 2));
return H_c;
}
template<class R> void
cube<R>::check_reverse_crossings ()
{
for (unsigned c = 1; c <= n_crossings; c ++)
{
mod_map<R> H_c = H_i (c);
mod_map<R> d = compute_d (2, 0, 0, 0, 0, 0),
r_d = compute_d (2, 0, 0, 0, 0, c);
mod_map<R> d_1 = d.graded_piece (1, 0);
assert (d_1 == r_d.graded_piece (1, 0));
assert (d_1.compose (d_1) == 0);
mod_map<R> d_2 = d.graded_piece (2, 2),
r_d_2 = r_d.graded_piece (2, 2);
assert (d_1.compose (d_2) == d_2.compose (d_1));
assert (d_1.compose (r_d_2) == r_d_2.compose (d_1));
assert (d_2 + r_d_2 == H_c.compose (d_1) + d_1.compose (H_c));
}
}
template<class R> void
cube<R>::check_reverse_orientation ()
{
mod_map<R> d = compute_d (2, 0, 0, 0, 0, 0),
n_d = compute_d (2, 0, 0, 0, 1, 0);
mod_map<R> d_1 = d.graded_piece (1, 0);
assert (d_1 == n_d.graded_piece (1, 0));
assert (d_1.compose (d_1) == 0);
mod_map<R> d_2 = d.graded_piece (2, 2),
n_d_2 = n_d.graded_piece (2, 2);
// in fact, Szabo's d_2 matches on the nose
assert (d_2 == n_d_2);
}
template<class R>
cube<R>::cube (knot_diagram &kd_, bool markedp_only_)
: markedp_only(markedp_only_),
kd(kd_),
n_crossings(kd.n_crossings),
n_resolutions(((unsigned)1) << n_crossings),
n_generators(0),
resolution_circles(n_resolutions),
resolution_generator1(n_resolutions)
{
// printf ("%% %s\n", kd.name.c_str ());
// printf ("smoothings:\n");
smoothing s (kd);
for (unsigned i = 0; i < n_resolutions; i ++)
{
smallbitset state (n_crossings, i);
s.init (kd, state);
resolution_circles[i] = s.n_circles;
resolution_generator1[i] = n_generators + 1;
n_generators += s.num_generators (markedp_only);
#if 0
s.show_self (kd, state);
newline ();
#endif
}
// printf ("(cube) n_generators = %d\n", n_generators);
khC = new base_module<R, khC_generators<R> > (khC_generators<R> (*this));
}
template<class R> unsigned
cube<R>::generator (unsigned i, unsigned j) const
{
if (markedp_only)
{
smoothing s (kd, smallbitset (n_crossings, i));
unsigned p = s.edge_circle[kd.marked_edge];
assert (!unsigned_bittest (j, p));
return resolution_generator1[i] + unsigned_discard_bit (j, p);
}
else
return resolution_generator1[i] + j;
}
template<class R> pair<unsigned, unsigned>
cube<R>::generator_state_monomial (unsigned g) const
{
unsigned i = resolution_generator1.upper_bound (g) - 1;
assert (g >= resolution_generator1[i]
&& (i + 1 >= n_resolutions
|| g < resolution_generator1[i + 1]));
return pair<unsigned, unsigned> (i, g - resolution_generator1[i]);
}
template<class R> grading
cube<R>::compute_generator_grading (unsigned g) const
{
pair<unsigned, unsigned> sm = generator_state_monomial (g);
return compute_state_monomial_grading (sm.first, sm.second);
}
template<class R> grading
cube<R>::compute_state_monomial_grading (unsigned state, unsigned monomial) const
{
grading r;
r.h = unsigned_bitcount (state) - kd.nminus;
r.q = 2 * unsigned_bitcount (monomial) - resolution_circles[state]
+ unsigned_bitcount (state) + kd.nplus - 2 * kd.nminus;
/* reduced-only is shifted up 1 in q-grading */
if (markedp_only)
r.q ++;
return r;
}
template<class R> ptr<const module<R> >
cube<R>::compute_kh () const
{
// display ("khC:\n", *khC);
mod_map<R> d = compute_d (1, 0, 0, 0, 0);
chain_complex_simplifier<Z> s (khC, d, 1);
// display ("s.new_C:\n", *s.new_C);
return s.new_d.homology ();
}
template<class R> void
cube<R>::show_state (unsigned state) const
{
for (unsigned i = n_crossings; i >= 1; i --)
printf (unsigned_bittest (state, i) ? "1" : "0");
}
template<class R> void
cube<R>::show_state_monomial (unsigned state, unsigned monomial) const
{
show_state (state);
printf (":");
smoothing s (kd, smallbitset (n_crossings, state));
char c = 'a';
for (unsigned i = 1; i <= s.n_circles; i ++, c ++)
{
if (!unsigned_bittest (monomial, i))
printf ("%c", c);
}
}
template<class R> void
cube<R>::display_self () const
{
for (unsigned i = 0, j = 1; i < n_resolutions; i ++)
{
smoothing s (kd, smallbitset (n_crossings, i));
printf (" %03d: ", i);
s.show_self (kd, smallbitset (n_crossings, i));
newline ();
}
// khC->display_self ();
// d.display_self ();
}
template<class F> mod_map<typename twisted_cube<F>::R>
twisted_cube<F>::compute_twisted_map (basedvector<int, 1> edge_weight,
unsigned dh, unsigned to_reverse,
const twisted_map_rules &rules) const
{
mod_map<R> r (c.khC);
knot_diagram &kd = c.kd;
unsigned n_crossings = c.n_crossings;
unsigned n_resolutions = c.n_resolutions;
smoothing from_s (kd);
smoothing to_s (kd);
resolution_diagram_builder rdb;
ullmanset<1> free_circles (max_circles);
ullmanset<1> from_circles (max_circles);
basedvector<triple<unsigned, unsigned, set<unsigned> >, 1> out;
for (unsigned fromstate = 0; fromstate < n_resolutions; fromstate ++)
{
unsigned n_zerocrossings = n_crossings - unsigned_bitcount (fromstate);
unsigned n_cobordisms = ((unsigned)1) << n_zerocrossings;
from_s.init (kd, smallbitset (n_crossings, fromstate));
unionfind<1> u (from_s.n_circles);
basedvector<unsigned, 1> from_circle_edge_rep (from_s.n_circles);
for (unsigned j = 1; j <= kd.num_edges (); j ++)
from_circle_edge_rep[from_s.edge_circle[j]] = j;
for (unsigned j = 0; j < n_cobordisms; j ++)
{
if (dh && unsigned_bitcount (j) != dh)
continue;
unsigned tostate = unsigned_pack (n_crossings, fromstate, j);
unsigned crossings = tostate & ~fromstate;
int sign = 1;
for (unsigned i = 1; i <= n_crossings; i ++)
{
if (unsigned_bittest (crossings, i))
break;
if (unsigned_bittest (fromstate, i))
sign *= -1;
}
// printf ("fromstate = %d, tostate = %d, sign = %d\n", fromstate, tostate, sign);
u.clear ();
from_circles.clear ();
for (unsigned_const_iter k = crossings; k; k ++)
{
unsigned c = k.val ();
unsigned from = from_s.ept_circle (kd, kd.crossings[c][1]),
to = from_s.ept_circle (kd, kd.crossings[c][3]);
from_circles += from;
from_circles += to;
u.join (from, to);
}
if (from_s.n_circles - from_circles.card () + 1 != u.num_sets ())
continue;
to_s.init (kd, smallbitset (n_crossings, tostate));
rdb.init (kd,
smallbitset (n_crossings, fromstate), from_s,
smallbitset (n_crossings, tostate), to_s,
smallbitset (n_crossings, crossings));
if (to_reverse)
rdb.reverse_crossing (kd, from_s, to_s, to_reverse);
// display (rdb.rd);
out.resize (0);
rules.map (out, rdb);
if (out.size () == 0)
continue;
free_circles.clear ();
for (unsigned i = 1; i <= from_s.n_circles; i ++)
{
if (! (rdb.gl_starting_circles % i))
free_circles.push (i);
}
unsigned n_free_circles = free_circles.card ();
unsigned n_free_monomials = ((unsigned)1) << n_free_circles;
for (unsigned i = 0; i < n_free_monomials; i ++)
{
unsigned m_from = 0,
m_to = 0;
for (unsigned_const_iter jj = i; jj; jj ++)
{
unsigned s = free_circles.nth (jj.val () - 1);
m_from = unsigned_bitset (m_from, s);
m_to = unsigned_bitset (m_to, to_s.edge_circle[from_circle_edge_rep[s]]);
}
for (unsigned j = 1; j <= out.size (); j ++)
{
unsigned v_from = m_from,
v_to = m_to;
unsigned l_from = out[j].first,
l_to = out[j].second;
for (unsigned_const_iter kk = l_from; kk; kk ++)
{
unsigned s = rdb.gl_starting_circles.nth (kk.val () - 1);
v_from = unsigned_bitset (v_from, s);
}
for (unsigned_const_iter kk = l_to; kk; kk ++)
{
unsigned s = rdb.gl_ending_circles.nth (kk.val () - 1);
v_to = unsigned_bitset (v_to, s);
}
int w = 0;
for (set_const_iter<unsigned> le = out[j].third; le; le ++)
{
for (set_const_iter<unsigned> ge = rdb.lg_edges[le.val ()]; ge; ge ++)
w += edge_weight[ge.val ()];
}
if (c.markedp_only)
{
unsigned p = from_s.edge_circle[kd.marked_edge];
if (unsigned_bittest (v_from, p))
continue;
assert (!unsigned_bittest (v_to, p));
}
// ??? sign
r[c.generator (fromstate, v_from)].muladd
(polynomial<F> (1) + polynomial<F> (1, w),
c.generator (tostate, v_to));
}
}
}
}
return r;
}
class twisted_barE_rules : public twisted_map_rules
{
public:
twisted_barE_rules () { }
twisted_barE_rules (const twisted_barE_rules &); // doesn't exist
~twisted_barE_rules () { }
twisted_barE_rules &operator = (const twisted_barE_rules &); // doesn't exist
void map (basedvector<triple<unsigned, unsigned, set<unsigned> >, 1> &out,
resolution_diagram_builder &rdb) const
{
rdb.rd.twisted_barE (out);
}
};
template<class F> mod_map<typename twisted_cube<F>::R>
twisted_cube<F>::compute_twisted_barE (basedvector<int, 1> edge_weight,
unsigned dh, unsigned to_reverse) const
{
return compute_twisted_map (edge_weight,
dh, to_reverse,
twisted_barE_rules ());
}
template<class F> mod_map<typename twisted_cube<F>::R>
twisted_cube<F>::twisted_d0 (basedvector<int, 1> edge_weight) const
{
mod_map<R> d0 (c.khC);
for (unsigned i = 0, j = 1; i < c.n_resolutions; i ++)
{
smoothing r (c.kd, smallbitset (c.n_crossings, i));
unsigned marked_s = c.markedp_only
? r.edge_circle[c.kd.marked_edge]
: 0;
for (unsigned j = 0; j < r.num_monomials (); j ++)
{
if (c.markedp_only
&& unsigned_bittest (j, marked_s))
continue;
for (unsigned s = 1; s <= r.n_circles; s ++)
{
if (unsigned_bittest (j, s))
{
int w = 0;
for (unsigned k = 1; k <= c.kd.num_edges (); k ++)
if (r.edge_circle[k] == s)
w += edge_weight[k];
unsigned j2 = unsigned_bitclear (j, s);
d0[c.generator (i, j)].muladd (polynomial<F> (1) + polynomial<F> (1, w),
c.generator (i, j2));
}
}
}
}
return d0;
}

54
dt_code.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <knotkit.h>
dt_code::dt_code (const std::string &name_, const char *p)
: name(name_)
{
unsigned n_crossings = alpha_to_int (*p++);
unsigned n_components = alpha_to_int (*p++);
even_labels = basedvector<basedvector<int, 1>, 1> (n_components);
for (unsigned i = 1; i <= n_components; i ++)
even_labels[i] = basedvector<int, 1> (alpha_to_int (*p++));
for (unsigned i = 1; i <= n_components; i ++)
{
for (unsigned j = 1; j <= even_labels[i].size (); j ++)
even_labels[i][j] = alpha_to_int (*p++) * 2;
}
if (*p == '\n')
p++;
assert (*p == 0);
assert (num_crossings () == n_crossings);
}
unsigned
dt_code::num_crossings () const
{
unsigned n = 0;
for (unsigned i = 1; i <= even_labels.size (); i ++)
n += even_labels[i].size ();
return n;
}
void
dt_code::display_self () const
{
printf ("dt_code %s [", name.c_str ());
for (unsigned i = 1; i <= even_labels.size (); i ++)
{
if (i > 1)
printf (", ");
printf ("[");
for (unsigned j = 1; j <= even_labels[i].size (); j ++)
{
if (j > 1)
printf (", ");
printf ("%d", even_labels[i][j]);
}
printf ("]");
}
printf ("]\n");
}

49
dt_code.h Normal file
View File

@ -0,0 +1,49 @@
/* Dowker and Thistlethwaite codes */
/* minus = over */
class dt_code
{
public:
std::string name;
basedvector<basedvector<int, 1>, 1> even_labels;
public:
dt_code ();
dt_code (const std::string &name_, unsigned n_crossings, int even_labels_ar[])
: name(name_), even_labels(1)
{
even_labels[1] = basedvector<int, 1> (n_crossings);
for (unsigned i = 0; i < n_crossings; i ++)
even_labels[1][i + 1] = even_labels_ar[i];
}
dt_code (const std::string &name_, const basedvector<int, 1> &even_labels_)
: name(name_), even_labels(1)
{
even_labels[1] = even_labels_;
}
dt_code (const std::string &name_, const basedvector<basedvector<int, 1>, 1> &even_labels_)
: name(name_), even_labels(even_labels_)
{
}
dt_code (const std::string &name_, const char *p);
dt_code (const dt_code &dt)
: name(dt.name), even_labels(dt.even_labels)
{ }
~dt_code () { }
dt_code &operator = (const dt_code &dt)
{
name = dt.name;
even_labels = dt.even_labels;
return *this;
}
unsigned num_crossings () const;
unsigned num_components () const { return even_labels.size (); }
void show_self () const { printf ("dt_code %s", name.c_str ()); }
void display_self () const;
};

126
gss.cpp Normal file
View File

@ -0,0 +1,126 @@
#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);
}

809
knot_diagram.cpp Normal file
View File

@ -0,0 +1,809 @@
#include <knotkit.h>
knot_diagram::knot_diagram (const planar_diagram &pd)
: name(pd.name),
n_crossings(pd.crossings.size ()),
marked_edge(0),
crossings(n_crossings),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
basedvector<basedvector<pair<unsigned, unsigned>, 1>, 1> edge_ci (num_edges ());
for (unsigned c = 1; c <= n_crossings; c ++)
{
for (unsigned i = 1; i <= 4; i ++)
{
unsigned e = pd.crossings[c][i];
edge_ci[e].append (pair<unsigned, unsigned> (c, i));
}
crossings[c] = basedvector<unsigned, 1> (4);
}
smallbitset done (num_edges ());
for (unsigned c0 = 1; c0 <= n_crossings; c0 ++)
{
for (unsigned i0 = 1; i0 <= 2; i0 ++)
{
unsigned e = pd.crossings[c0][i0];
if (done % e)
continue;
for (unsigned c = c0, i = i0;;)
{
crossings[c][i] = edge_to_ept (e);
done.push (e);
ept_crossing[edge_to_ept (e)] = c;
ept_index[edge_to_ept (e)] = i;
i = add_base1_mod4 (i, 2);
e = pd.crossings[c][i];
crossings[c][i] = edge_from_ept (e);
ept_crossing[edge_from_ept (e)] = c;
ept_index[edge_from_ept (e)] = i;
if (edge_ci[e][1].first == c
&& edge_ci[e][1].second == i)
{
c = edge_ci[e][2].first;
i = edge_ci[e][2].second;
}
else
{
assert (edge_ci[e][2].first == c && edge_ci[e][2].second == i);
c = edge_ci[e][1].first;
i = edge_ci[e][1].second;
}
if (c == c0 && i == i0)
break;
}
}
}
assert (done.card () == num_edges ());
calculate_smoothing_orientation ();
calculate_nminus_nplus ();
}
class dt_layout
{
public:
knot_diagram &kd;
unsigned n_components;
basedvector<unsigned, 1> comp_first_edge,
comp_last_edge;
basedvector<unsigned, 1> edge_to_crossing;
smallbitset edge_to_under;
smallbitset placed;
public:
dt_layout (const dt_code &dt, knot_diagram &kd_);
dt_layout (const dt_layout &); // doesn't exist
~dt_layout () { }
dt_layout &operator = (const dt_layout &); // doesn't exist
unsigned find_crossing (unsigned prevc, unsigned previ, unsigned target,
bool under, unsigned dir);
bool layout_2 (unsigned e,
unsigned prevc, unsigned previ,
unsigned c, unsigned i);
bool layout_1 (unsigned e,
unsigned prevc, unsigned previ);
unsigned comp_next_edge (unsigned e) const;
void layout ();
};
dt_layout::dt_layout (const dt_code &dt, knot_diagram &kd_)
: kd(kd_),
n_components(dt.num_components ()),
comp_first_edge(n_components),
comp_last_edge(n_components),
edge_to_crossing(kd.num_edges ()),
edge_to_under(kd.num_edges ()),
placed(kd.n_crossings)
{
unsigned k = 1;
for (unsigned i = 1; i <= dt.even_labels.size (); i ++)
{
comp_first_edge[i] = 2 * k - 1;
comp_last_edge[i] = 2 * (k + dt.even_labels[i].size () - 1);
for (unsigned j = 1; j <= dt.even_labels[i].size (); j ++, k ++)
{
int as = dt.even_labels[i][j];
unsigned a = abs (as),
b = 2 * k - 1;
if (as > 0)
edge_to_under.push (a);
else
edge_to_under.push (b);
edge_to_crossing[a] = edge_to_crossing[b] = k;
}
}
}
unsigned
dt_layout::find_crossing (unsigned prevc, unsigned previ, unsigned target,
bool under, unsigned dir)
{
assert (!kd.crossings[prevc][previ]);
assert (placed % prevc);
unsigned c = prevc,
i = add_base1_mod4 (previ, dir);
for (;;)
{
if (c == prevc && i == previ)
return 0;
if (c == target && under == (i == 1 || i == 3) && kd.crossings[c][i] == 0)
return i;
unsigned p = kd.crossings[c][i];
if (p)
{
unsigned p2 = kd.edge_other_ept (p);
c = kd.ept_crossing[p2];
i = kd.ept_index[p2];
}
i = add_base1_mod4 (i, dir);
}
}
unsigned
dt_layout::comp_next_edge (unsigned e) const
{
for (unsigned comp = 1; comp <= n_components; comp ++)
{
if (comp_first_edge[comp] <= e
&& e <= comp_last_edge[comp])
{
if (e == comp_last_edge[comp])
return comp_first_edge[comp];
else
return e + 1;
}
}
abort ();
}
bool
dt_layout::layout_2 (unsigned e,
unsigned prevc, unsigned previ,
unsigned c, unsigned i)
{
assert (placed % prevc);
assert (placed % c);
unsigned from = kd.edge_from_ept (e),
to = kd.edge_to_ept (e);
assert (kd.crossings[prevc][previ] == 0);
kd.crossings[prevc][previ] = from;
kd.ept_crossing[from] = prevc;
kd.ept_index[from] = previ;
assert (kd.crossings[c][i] == 0);
kd.crossings[c][i] = to;
kd.ept_crossing[to] = c;
kd.ept_index[to] = i;
if (layout_1 (comp_next_edge (e), c, add_base1_mod4 (i, 2)))
return 1;
kd.crossings[prevc][previ] = 0;
kd.crossings[c][i] = 0;
kd.ept_crossing[from] = kd.ept_crossing[to] = 0;
kd.ept_index[from] = kd.ept_index[to] = 0;
return 0;
}
bool
dt_layout::layout_1 (unsigned e, unsigned prevc, unsigned previ)
{
if (kd.crossings[prevc][previ])
{
unsigned from = kd.edge_from_ept (e);
assert (kd.crossings[prevc][previ] == from);
assert (kd.ept_crossing[from] == prevc);
assert (kd.ept_index[from] == previ);
for (unsigned e = 1; e <= kd.num_edges (); e ++)
{
unsigned to = kd.edge_to_ept (e);
unsigned prevc = edge_to_crossing[e];
if (placed % prevc
&& !kd.ept_crossing[to])
{
unsigned previ1 = edge_to_under % e ? 3 : 4;
if (layout_1 (comp_next_edge (e), prevc, previ1))
return 1;
unsigned previ2 = edge_to_under % e ? 1 : 2;
return layout_1 (comp_next_edge (e), prevc, previ2);
}
}
/* done! */
return 1;
}
unsigned c = edge_to_crossing[e];
if (placed % c)
{
unsigned i = find_crossing (prevc, previ, c, edge_to_under % e, 1);
if (i && layout_2 (e, prevc, previ, c, i))
return 1;
unsigned i2 = find_crossing (prevc, previ, c, edge_to_under % e, 3);
return i2 && layout_2 (e, prevc, previ, c, i2); // return i && ... ??
}
else
{
unsigned i = (edge_to_under % e) ? 1 : 2;
placed.push (c);
if (!layout_2 (e, prevc, previ, c, i))
{
placed -= c;
return 0;
}
else
return 1;
}
}
void
dt_layout::layout ()
{
unsigned last = comp_last_edge[1];
unsigned prevc = edge_to_crossing[last];
unsigned previ = (edge_to_under % last) ? 3 : 4;
placed.push (prevc);
bool b = layout_1 (comp_first_edge[1], prevc, previ);
assert (b);
assert (placed.card () == kd.n_crossings);
}
knot_diagram::knot_diagram (const dt_code &dt)
: name(dt.name),
n_crossings(dt.num_crossings ()),
marked_edge(0),
crossings(n_crossings),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
basedvector<unsigned, 1> v (4);
v[1] = v[2] = v[3] = v[4] = 0;
crossings[i] = v;
}
dt_layout layout (dt, *this);
layout.layout ();
calculate_nminus_nplus ();
calculate_smoothing_orientation ();
}
knot_diagram::knot_diagram (mirror, const knot_diagram &kd)
: name("mirror(" + kd.name + ")"),
n_crossings(kd.n_crossings),
marked_edge(0),
crossings(n_crossings),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
basedvector<unsigned, 1> v (4);
v[1] = kd.crossings[i][1];
v[2] = kd.crossings[i][4];
v[3] = kd.crossings[i][3];
v[4] = kd.crossings[i][2];
crossings[i] = v;
}
for (unsigned i = 1; i <= n_crossings; i ++)
{
for (unsigned j = 1; j <= 4; j ++)
{
unsigned c = crossings[i][j];
ept_crossing[c] = i;
ept_index[c] = j;
}
}
calculate_smoothing_orientation ();
calculate_nminus_nplus ();
assert (nminus == kd.nplus);
assert (nplus == kd.nminus);
}
void
knot_diagram::check_crossings ()
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = crossings[i][j];
assert (ept_crossing[p] == i);
assert (ept_index[p] == j);
}
}
}
void
knot_diagram::rotate_crossing (unsigned c)
{
std::swap (crossings[c][1], crossings[c][3]);
std::swap (crossings[c][2], crossings[c][4]);
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = crossings[c][j];
ept_index[p] = j;
}
}
knot_diagram::knot_diagram (connect_sum,
const knot_diagram &d1,
const knot_diagram &d2)
: name(d1.name + "\\#" + d2.name),
n_crossings(d1.n_crossings + d2.n_crossings),
marked_edge(0),
crossings(n_crossings),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
for (unsigned i = 1; i <= d1.n_crossings; i ++)
crossings[i] = basedvector<unsigned, 1> (COPY, d1.crossings[i]);
for (unsigned i = 1; i <= d2.n_crossings; i ++)
{
basedvector<unsigned, 1> v (4);
for (unsigned j = 1; j <= 4; j ++)
v[j] = d1.num_epts () + d2.crossings[i][j];
crossings[d1.n_crossings + i] = v;
}
unsigned p1 = d1.edge_from_ept (1);
crossings[d1.ept_crossing[p1]][d1.ept_index[p1]]
= edge_from_ept (d1.num_edges () + 1);
unsigned p2 = d2.edge_from_ept (1);
crossings[d1.n_crossings + d2.ept_crossing[p2]][d2.ept_index[p2]]
= d1.edge_from_ept (1);
for (unsigned i = 1; i <= n_crossings; i ++)
{
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = crossings[i][j];
ept_crossing[p] = i;
ept_index[p] = j;
}
}
#ifndef NDEBUG
check_crossings ();
#endif
orient ();
calculate_smoothing_orientation ();
calculate_nminus_nplus ();
}
knot_diagram::knot_diagram (const std::string &name_, unsigned n_crossings_, unsigned crossings_ar[][4])
: name(name_),
n_crossings(n_crossings_),
marked_edge(0),
crossings(n_crossings),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
basedvector<unsigned, 1> v (4);
v[1] = crossings_ar[i - 1][0];
v[2] = crossings_ar[i - 1][1];
v[3] = crossings_ar[i - 1][2];
v[4] = crossings_ar[i - 1][3];
crossings[i] = v;
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = crossings[i][j];
ept_crossing[p] = i;
ept_index[p] = j;
}
}
calculate_smoothing_orientation ();
calculate_nminus_nplus ();
}
knot_diagram::knot_diagram (const std::string &name_, const basedvector<basedvector<unsigned, 1>, 1> &crossings_)
: name(name_),
n_crossings(crossings_.size ()),
marked_edge(0),
crossings(crossings_),
ept_crossing(num_epts ()),
ept_index(num_epts ()),
nminus(0), nplus(0)
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
for (unsigned j = 1; j <= 4; j ++)
{
unsigned p = crossings[i][j];
ept_crossing[p] = i;
ept_index[p] = j;
}
}
calculate_smoothing_orientation ();
calculate_nminus_nplus ();
}
void
knot_diagram::orient ()
{
bitset done (num_edges ());
for (unsigned i = 1; i <= num_edges (); i ++)
{
if (done % i)
continue;
unsigned p = edge_to_ept (i);
for (;;)
{
unsigned e = ept_edge (p);
done.push (e);
if (is_from_ept (p))
{
unsigned e_from = edge_from_ept (e),
e_to = edge_to_ept (e),
c_from = ept_crossing[e_from],
c_to = ept_crossing[e_to],
j_from = ept_index[e_from],
j_to = ept_index[e_to];
ept_crossing[e_to] = c_from;
ept_index[e_to] = j_from;
ept_crossing[e_from] = c_to;
ept_index[e_from] = j_to;
crossings[c_from][j_from] = e_to;
crossings[c_to][j_to] = e_from;
p = e_to;
}
p = crossings[ept_crossing[p]][add_base1_mod4 (ept_index[p], 2)];
if (ept_edge (p) == i)
break;
p = edge_other_ept (p);
}
}
assert (done.card () == num_edges ());
#ifndef NDEBUG
check_crossings ();
#endif
}
void
knot_diagram::calculate_nminus_nplus ()
{
assert (nplus == 0 && nminus == 0);
for (unsigned i = 1; i <= n_crossings; i ++)
{
if (is_to_ept (crossings[i][1]) == is_to_ept (crossings[i][4]))
nplus ++;
else
nminus ++;
}
}
void
knot_diagram::calculate_smoothing_orientation ()
{
edge_smoothing_oriented = set<unsigned> ();
set<unsigned> done;
vector<unsigned> q;
for (unsigned i = 1; i <= num_edges (); i ++)
{
if (done % i)
continue;
edge_smoothing_oriented.push (i);
done.push (i);
q.append (i);
while (q.size () != 0)
{
unsigned e = q.pop ();
assert (done % e);
unsigned p = edge_smoothing_to_ept (e);
unsigned r = resolve_next_ept (p, 0);
unsigned f = ept_edge (r);
if (done % f)
assert (is_smoothing_from_ept (r));
else
{
if (is_from_ept (r))
edge_smoothing_oriented.push (f);
done.push (f);
q.append (f);
}
unsigned r2 = resolve_next_ept (p, 1);
unsigned f2 = ept_edge (r2);
if (done % f2)
assert (is_smoothing_from_ept (r2));
else
{
if (is_from_ept (r2))
edge_smoothing_oriented.push (f2);
done.push (f2);
q.append (f2);
}
}
}
assert (done.card () == num_edges ());
}
unsigned
knot_diagram::resolve_next_ept (unsigned p, bool resolution) const
{
static unsigned lookup[2][4] = { { 2, 1, 4, 3 }, { 4, 3, 2, 1 } };
unsigned c = ept_crossing[p],
i = ept_index[p];
assert (i >= 1 && i <= 4);
i = lookup[(int)resolution][i - 1];
return crossings[c][i];
}
static unsigned crossing_index_corner (unsigned c, unsigned i)
{
return (c - 1) * 4 + i;
}
static unsigned corner_crossing (unsigned x)
{
return (x - 1) / 4 + 1;
}
static unsigned corner_index (unsigned x)
{
return ((x - 1) % 4) + 1;
}
directed_multigraph
knot_diagram::black_graph (basedvector<unsigned, 1> &bg_edge_height) const
{
unsigned n_corners = n_crossings * 4;
#if 1
for (unsigned c = 1; c <= n_crossings; c ++)
for (unsigned j = 1; j <= 4; j ++)
{
unsigned x = crossing_index_corner (c, j);
assert (x >= 1 && x <= n_corners);
assert (corner_crossing (x) == c);
assert (corner_index (x) == j);
}
for (unsigned x = 1; x <= n_corners; x ++)
{
unsigned c = corner_crossing (x);
assert (c >= 1 && c <= n_crossings);
unsigned j = corner_index (x);
assert (j >= 1 && j <= 4);
assert (crossing_index_corner (c, j) == x);
}
#endif
unionfind<1> u (n_corners);
unsigned n_edges = num_edges ();
for (unsigned i = 1; i <= n_edges; i ++)
{
unsigned i_from = edge_from_ept (i),
i_to = edge_to_ept (i);
u.join (crossing_index_corner (ept_crossing (i_from),
ept_index (i_from)),
crossing_index_corner (ept_crossing (i_to),
add_base1_mod4 (ept_index (i_to), 3)));
u.join (crossing_index_corner (ept_crossing (i_from),
add_base1_mod4 (ept_index (i_from), 3)),
crossing_index_corner (ept_crossing (i_to),
ept_index (i_to)));
}
ullmanset<1> present (n_corners);
for (unsigned i = 1; i <= n_corners; i ++)
present += u.find (i);
basedvector<unsigned, 1> edge_from, edge_to;
basedvector<unsigned, 1> edge_height;
for (unsigned i = 1; i <= n_crossings; i ++)
{
edge_from.append (present.position (u.find (crossing_index_corner (i, 1))) + 1);
edge_to.append (present.position (u.find (crossing_index_corner (i, 3))) + 1);
edge_height.append (1);
edge_from.append (present.position (u.find (crossing_index_corner (i, 2))) + 1);
edge_to.append (present.position (u.find (crossing_index_corner (i, 4))) + 1);
edge_height.append (0);
}
assert (u.num_sets () == present.card ());
directed_multigraph bwg (u.num_sets (), edge_from, edge_to);
// display ("bwg:\n", bwg);
assert (bwg.num_components () == 2);
basedvector<unsigned, 1> edge_inj,
vertex_inj;
directed_multigraph bg = bwg.component (1, edge_inj, vertex_inj);
bg_edge_height = basedvector<unsigned, 1> (bg.num_edges ());
for (unsigned i = 1; i <= bg.num_edges (); i ++)
bg_edge_height[i] = edge_height[edge_inj[i]];
return bg;
}
basedvector<basedvector<int, 1>, 1>
knot_diagram::planar_diagram_crossings () const
{
unsigned n_edges = num_edges ();
ullmanset<1> edges (n_edges);
for (unsigned e = 1; e <= n_edges; e ++)
{
if (edges % e)
continue;
for (unsigned i = e;;)
{
edges.push (i);
unsigned c = ept_crossing[edge_to_ept (i)],
j = ept_index[edge_to_ept (i)];
unsigned j2 = add_base1_mod4 (j, 2);
assert (is_from_ept (crossings[c][j2]));
i = ept_edge (crossings[c][j2]);
if (i == e)
break;
}
}
assert (edges.card () == n_edges);
basedvector<basedvector<int, 1>, 1> r (n_crossings);
unsigned k = 0;
bool first = 1;
for (unsigned i = 1; i <= n_edges; i ++)
{
unsigned e = edges.nth (i - 1);
unsigned c = ept_crossing[edge_to_ept (e)],
j = ept_index[edge_to_ept (e)];
if (j == 1)
{
basedvector<int, 1> v (4);
v[1] = edges.position (ept_edge (crossings[c][1])) + 1;
v[2] = edges.position (ept_edge (crossings[c][2])) + 1;
v[3] = edges.position (ept_edge (crossings[c][3])) + 1;
v[4] = edges.position (ept_edge (crossings[c][4])) + 1;
r[++ k] = v;
}
else if (j == 3)
{
basedvector<int, 1> v (4);
v[1] = edges.position (ept_edge (crossings[c][3])) + 1;
v[2] = edges.position (ept_edge (crossings[c][4])) + 1;
v[3] = edges.position (ept_edge (crossings[c][1])) + 1;
v[4] = edges.position (ept_edge (crossings[c][2])) + 1;
r[++ k] = v;
}
unsigned j2 = add_base1_mod4 (j, 2);
assert (is_from_ept (crossings[c][j2]));
unsigned e2 = ept_edge (crossings[c][j2]);
unsigned i2 = edges.position (e2) + 1;
#if 0
assert ((i == n_edges && i2 == 1)
|| i2 == i + 1);
#endif
}
assert (k == n_crossings);
return r;
}
hash_t
knot_diagram::hash_self () const
{
// ??? we can do better
unsigned n_loops = 0;
for (unsigned i = 1; i <= num_edges (); i ++)
{
if (ept_edge (edge_from_ept (i)) == ept_edge (edge_to_ept (i)))
n_loops ++;
}
return hash_combine (hash (n_crossings),
hash (n_loops));
}
void
knot_diagram::show_ept (unsigned p) const
{
unsigned e = ept_edge (p);
if (is_to_ept (p))
printf (">");
printf ("%d", e);
if (is_from_ept (p))
printf (">");
}
void
knot_diagram::show_self () const
{
printf ("knot_diagram %s", name.c_str ());
}
void
knot_diagram::display_self () const
{
comment (); printf ("knot_diagram %s\n", name.c_str ());
comment (); printf ("n_crossings = %d, n+ = %d, n- = %d\n", n_crossings, nplus, nminus);
if (marked_edge)
{
comment ();
printf ("marked_edge = %d\n", marked_edge);
}
comment ();
for (unsigned i = 1; i <= crossings.size (); i ++)
{
printf ("%d:(", i);
show_ept (crossings[i][1]);
printf (" ");
show_ept (crossings[i][2]);
printf (" ");
show_ept (crossings[i][3]);
printf (" ");
show_ept (crossings[i][4]);
printf (")");
}
printf ("\n");
}

161
knot_diagram.h Normal file
View File

@ -0,0 +1,161 @@
static inline unsigned
add_base1_mod4 (unsigned x, unsigned y)
{
assert (between (1, x, 4));
assert (between (0, y, 4));
return ((x - 1 + y) % 4) + 1;
}
enum mirror { MIRROR };
enum connect_sum { CONNECT_SUM };
class knot_diagram
{
public:
std::string name;
unsigned n_crossings;
unsigned marked_edge;
basedvector<basedvector<unsigned, 1>, 1> crossings;
basedvector<unsigned, 1> ept_crossing;
basedvector<unsigned, 1> ept_index;
/* true if the smoothing orientation for an edge matches the link
orientation */
set<unsigned> edge_smoothing_oriented;
unsigned nminus, nplus;
unsigned num_edges () const { return n_crossings * 2; }
unsigned num_epts () const { return n_crossings * 4; }
unsigned ept_edge (unsigned p) const
{
assert (between (1, p, num_epts ()));
return (p + 1) / 2;
}
unsigned edge_other_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
if (is_odd (p))
return p + 1;
else
return p - 1;
}
unsigned edge_from_ept (unsigned e) const
{
assert (between (1, e, num_edges ()));
return e * 2 - 1;
}
unsigned edge_to_ept (unsigned e) const
{
assert (between (1, e, num_edges ()));
return e * 2;
}
unsigned is_from_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
return is_odd (p);
}
unsigned is_to_ept (unsigned p) const { return !is_from_ept (p); }
unsigned is_under_ept (unsigned p) const
{
assert (between (1, p, num_epts ()));
return ept_index[p] == 1 || ept_index[p] == 3;
}
unsigned is_over_ept (unsigned p) const { return !is_under_ept (p); }
bool is_crossing_from_ept (unsigned p) const
{
assert (is_under_ept (p));
return ept_index[p] == 1;
}
bool is_crossing_to_ept (unsigned p) const { return !is_crossing_from_ept (p); }
/* wrt smoothing orientation */
unsigned edge_smoothing_from_ept (unsigned e) const
{
return edge_smoothing_oriented % e
? edge_from_ept (e)
: edge_to_ept (e);
}
unsigned edge_smoothing_to_ept (unsigned e) const
{
return edge_smoothing_oriented % e
? edge_to_ept (e)
: edge_from_ept (e);
}
bool is_smoothing_from_ept (unsigned p) const
{
unsigned e = ept_edge (p);
return p == edge_smoothing_from_ept (e);
}
bool is_smoothing_to_ept (unsigned p) const { return !is_smoothing_from_ept (p); }
void orient ();
void calculate_nminus_nplus ();
void calculate_smoothing_orientation ();
void check_crossings ();
void rotate_crossing (unsigned c);
public:
knot_diagram ()
: n_crossings(0),
marked_edge(0),
nminus(0),
nplus(0)
{ }
explicit knot_diagram (const planar_diagram &pd);
explicit knot_diagram (const dt_code &dt);
knot_diagram (mirror, const knot_diagram &kd);
knot_diagram (connect_sum,
const knot_diagram &d1,
const knot_diagram &d2);
knot_diagram (const std::string &name_, unsigned n_crossings_, unsigned crossings_ar[][4]);
knot_diagram (const std::string &name_, const basedvector<basedvector<unsigned, 1>, 1> &crossings_);
knot_diagram (const knot_diagram &kd)
: name(kd.name),
n_crossings(kd.n_crossings),
marked_edge(kd.marked_edge),
crossings(kd.crossings),
ept_crossing(kd.ept_crossing),
ept_index(kd.ept_index),
edge_smoothing_oriented(kd.edge_smoothing_oriented),
nminus(kd.nminus), nplus(kd.nplus)
{ }
~knot_diagram () { }
knot_diagram &operator = (const knot_diagram &kd)
{
name = kd.name;
n_crossings = kd.n_crossings;
marked_edge = kd.marked_edge;
crossings = kd.crossings;
ept_crossing = kd.ept_crossing;
ept_index = kd.ept_index;
edge_smoothing_oriented = kd.edge_smoothing_oriented;
nminus = kd.nminus;
nplus = kd.nplus;
return *this;
}
directed_multigraph black_graph (basedvector<unsigned, 1> &bg_edge_height) const;
unsigned resolve_next_ept (unsigned p, bool resolution) const;
int writhe () const { return (int)nplus - (int)nminus; }
basedvector<basedvector<int, 1>, 1> planar_diagram_crossings () const;
hash_t hash_self () const;
void show_ept (unsigned p) const;
void show_self () const;
void display_self () const;
};

1148
knot_parser/knot_parser.cc Normal file

File diff suppressed because it is too large Load Diff

337
knot_parser/knot_parser.hh Normal file
View File

@ -0,0 +1,337 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Skeleton interface for Bison LALR(1) parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* C++ LALR(1) parser skeleton written by Akim Demaille. */
#ifndef PARSER_HEADER_H
# define PARSER_HEADER_H
/* "%code requires" blocks. */
/* Line 35 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"
#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. */
#ifndef YYDEBUG
# 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"
/// A Bison parser.
class knot_parser
{
public:
/// Symbol semantic values.
#ifndef YYSTYPE
union semantic_type
{
/* Line 35 of lalr1.cc */
#line 21 "knot_parser/knot_parser.yy"
int integer;
bool alternating;
basedvector<int, 1> *int_vec;
basedvector<basedvector<int, 1>, 1> *int_vec2;
const char *string;
/* Line 35 of lalr1.cc */
#line 136 "knot_parser/knot_parser.hh"
};
#else
typedef YYSTYPE semantic_type;
#endif
/// Symbol locations.
typedef location location_type;
/// Tokens.
struct token
{
/* Tokens. */
enum yytokentype {
END = 0,
INT = 258,
PD = 259,
DT = 260,
BR = 261,
LINK = 262,
X = 263,
T = 264,
U = 265,
UNKNOT = 266,
ALT = 267,
NONALT = 268,
STRING = 269
};
};
/// Token type.
typedef token::yytokentype token_type;
/// Build a parser object.
knot_parser (knot_diagram &parsed_knot_yyarg);
virtual ~knot_parser ();
/// Parse.
/// \returns 0 iff parsing succeeded.
virtual int parse ();
#if YYDEBUG
/// The current debugging stream.
std::ostream& debug_stream () const;
/// Set the current debugging stream.
void set_debug_stream (std::ostream &);
/// Type for debugging levels.
typedef int debug_level_type;
/// The current debugging level.
debug_level_type debug_level () const;
/// Set the current debugging level.
void set_debug_level (debug_level_type l);
#endif
private:
/// Report a syntax error.
/// \param loc where the syntax error is found.
/// \param msg a description of the syntax error.
virtual void error (const location_type& loc, const std::string& msg);
/// Generate an error message.
/// \param state the state where the error occurred.
/// \param tok the lookahead token.
virtual std::string yysyntax_error_ (int yystate);
#if YYDEBUG
/// \brief Report a symbol value on the debug stream.
/// \param yytype The token type.
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
virtual void yy_symbol_value_print_ (int yytype,
const semantic_type* yyvaluep,
const location_type* yylocationp);
/// \brief Report a symbol on the debug stream.
/// \param yytype The token type.
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
virtual void yy_symbol_print_ (int yytype,
const semantic_type* yyvaluep,
const location_type* yylocationp);
#endif
/// State numbers.
typedef int state_type;
/// State stack type.
typedef stack<state_type> state_stack_type;
/// Semantic value stack type.
typedef stack<semantic_type> semantic_stack_type;
/// location stack type.
typedef stack<location_type> location_stack_type;
/// The state stack.
state_stack_type yystate_stack_;
/// The semantic value stack.
semantic_stack_type yysemantic_stack_;
/// The location stack.
location_stack_type yylocation_stack_;
/// Internal symbol numbers.
typedef unsigned char token_number_type;
/* Tables. */
/// For a state, the index in \a yytable_ of its portion.
static const signed char yypact_[];
static const signed char yypact_ninf_;
/// For a state, default rule to reduce.
/// Unless\a yytable_ specifies something else to do.
/// Zero means the default is an error.
static const unsigned char yydefact_[];
static const signed char yypgoto_[];
static const signed char yydefgoto_[];
/// What to do in a state.
/// \a yytable_[yypact_[s]]: what to do in state \a s.
/// - if positive, shift that token.
/// - if negative, reduce the rule which number is the opposite.
/// - if zero, do what YYDEFACT says.
static const unsigned char yytable_[];
static const signed char yytable_ninf_;
static const signed char yycheck_[];
/// For a state, its accessing symbol.
static const unsigned char yystos_[];
/// 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
#if YYDEBUG
/// A type to store symbol numbers and -1.
typedef signed char rhs_number_type;
/// A `-1'-separated list of the rules' RHS.
static const rhs_number_type yyrhs_[];
/// For each rule, the index of the first RHS symbol in \a yyrhs_.
static const unsigned char yyprhs_[];
/// For each rule, its source line number.
static const unsigned char yyrline_[];
/// For each scanner token number, its symbol number.
static const unsigned short int yytoken_number_[];
/// Report on the debug stream that the rule \a r is going to be reduced.
virtual void yy_reduce_print_ (int r);
/// Print the state stack on the debug stream.
virtual void yystack_print_ ();
/* Debugging. */
int yydebug_;
std::ostream* yycdebug_;
#endif
/// Convert a scanner token number \a t to a symbol number.
token_number_type yytranslate_ (int t);
/// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed.
/// \param yytype The symbol type.
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
inline void yydestruct_ (const char* yymsg,
int yytype,
semantic_type* yyvaluep,
location_type* yylocationp);
/// Pop \a n symbols the three stacks.
inline void yypop_ (unsigned int n = 1);
/* Constants. */
static const int yyeof_;
/* LAST_ -- Last index in TABLE_. */
static const int yylast_;
static const int yynnts_;
static const int yyempty_;
static const int yyfinal_;
static const int yyterror_;
static const int yyerrcode_;
static const int yyntokens_;
static const unsigned int yyuser_token_number_max_;
static const token_number_type yyundef_token_;
/* User arguments. */
knot_diagram &parsed_knot;
};
} // yy
/* Line 35 of lalr1.cc */
#line 334 "knot_parser/knot_parser.hh"
#endif /* ! defined PARSER_HEADER_H */

255
knot_parser/knot_parser.yy Normal file
View File

@ -0,0 +1,255 @@
%skeleton "lalr1.cc"
%require "2.4.3"
%defines
%define parser_class_name "knot_parser"
%parse-param { knot_diagram &parsed_knot }
// %no-lines
%code requires {
#include <knotkit.h>
}
%code{
#define YY_DECL \
yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval)
YY_DECL;
}
%union {
int integer;
bool alternating;
basedvector<int, 1> *int_vec;
basedvector<basedvector<int, 1>, 1> *int_vec2;
const char *string;
}
%code {
#define yylex knot_yylex
}
%token <integer> INT
%token END 0 "end of file"
%token PD DT BR LINK X T
%token U UNKNOT
%token <alternating> ALT NONALT
%token <string> STRING
%type <alternating> alt_spec
%type <int_vec> int_vec int_vec_1
%type <int_vec2> int_vec2
%type <int_vec> crossing
%type <int_vec2> crossing_vec
%%
%start knot;
knot:
rolfsen_knot
| htw_knot
| mt_link
| planar_diagram
| dt
| torus_link
| unknot
| braid
;
rolfsen_knot:
INT '_' INT
{
unsigned n = $1,
k = $3;
if (n >= 1 && n <= 10
&& k >= 1 && k <= rolfsen_crossing_knots (n))
parsed_knot = knot_diagram (rolfsen_knot (n, k));
else
{
fprintf (stderr, "knot_parser: no such Rolfsen knot `%d_%d'\n",
n, k);
exit (EXIT_FAILURE);
}
}
;
htw_knot:
INT alt_spec INT
{
unsigned n = $1,
k = $3;
bool alt = $2;
if (n >= 1 && n <= 16
&& k >= 1 && k <= htw_knots (n, alt))
parsed_knot = knot_diagram (htw_knot (n, alt, k));
else
{
fprintf (stderr, "knot_parser: no such HTW knot `%d%c%d'\n",
n, alt ? 'a' : 'n', k);
exit (EXIT_FAILURE);
}
}
;
mt_link:
LINK INT alt_spec INT
{
unsigned n = $2,
k = $4;
bool alt = $3;
if (n >= 1 && n <= 14
&& k >= 1 && k <= mt_links (n, alt))
parsed_knot = knot_diagram (mt_link (n, alt, k));
else
{
fprintf (stderr, "knot_parser: no such MT link `%d%c%d'\n",
n, alt ? 'a' : 'n', k);
exit (EXIT_FAILURE);
}
}
;
planar_diagram:
PD '[' int_vec2 ']'
{ parsed_knot = knot_diagram (planar_diagram ("<parsed>", *$3)); }
| PD '[' crossing_vec ']'
{ parsed_knot = knot_diagram (planar_diagram ("<parsed>", *$3)); }
;
dt:
DT '[' int_vec_1 ']'
{
basedvector<basedvector<int, 1>, 1> even_labels (1);
even_labels[1] = *$3;
parsed_knot = knot_diagram (dt_code ("<parsed>", even_labels));
}
| DT '[' int_vec2 ']'
{ parsed_knot = knot_diagram (dt_code ("<parsed>", *$3)); }
| DT '[' STRING ']'
{ parsed_knot = knot_diagram (dt_code ("<parsed>", $3)); }
;
torus_link:
T '(' INT ',' INT ')'
{ parsed_knot = knot_diagram (torus_knot ($3, $5)); }
;
braid:
BR '[' INT ',' int_vec ']'
{ parsed_knot = knot_diagram (braid ($3, *$5)); }
;
unknot:
UNKNOT
{
unsigned unknot_ar[1][4] = {
{ 2, 1, 3, 4, },
};
parsed_knot = knot_diagram ("U", 1, unknot_ar);
}
;
alt_spec:
ALT
| NONALT
;
int_vec2:
int_vec
{
basedvector<basedvector<int, 1>, 1> *v
= new basedvector<basedvector<int, 1>, 1> ();
v->append (*$1);
$$ = v;
}
| int_vec2 ',' int_vec
{
basedvector<basedvector<int, 1>, 1> *v = $1;
v->append (*$3);
$$ = v;
}
;
int_vec:
'{' int_vec_1 '}'
{ $$ = $2; }
| '[' int_vec_1 ']'
{ $$ = $2; }
;
int_vec_1:
INT
{
basedvector<int, 1> *v =
new basedvector<int, 1> ();
v->append ($1);
$$ = v;
}
| int_vec_1 ',' INT
{
basedvector<int, 1> *v = $1;
v->append ($3);
$$ = v;
}
;
crossing_vec:
crossing
{
basedvector<basedvector<int, 1>, 1> *v
= new basedvector<basedvector<int, 1>, 1> ();
v->append (*$1);
$$ = v;
}
| crossing_vec ',' crossing
{
basedvector<basedvector<int, 1>, 1> *v = $1;
v->append (*$3);
$$ = v;
}
;
crossing:
X '[' INT ',' INT ',' INT ',' INT ']'
{
basedvector<int, 1> *v
= new basedvector<int, 1> ();
v->append ($3);
v->append ($5);
v->append ($7);
v->append ($9);
$$ = v;
}
%%
void
yy::knot_parser::error (const yy::knot_parser::location_type &l,
const std::string &m)
{
fprintf (stderr, "knot_parser: parse error.\n");
exit (EXIT_FAILURE);
}
void knot_scan_string (const char *s);
knot_diagram
parse_knot (const char *s)
{
knot_scan_string (s);
knot_diagram d;
yy::knot_parser parser (d);
parser.parse ();
return d;
}

View File

@ -0,0 +1,17 @@
// includes knotkit
#include "knot_parser.hh"
void knot_scan_string (const char *s);
knot_diagram
parse_knot (const char *s)
{
knot_scan_string (s);
knot_diagram d;
yy::knot_parser parser (d);
parser.parse ();
return d;
}

View File

@ -0,0 +1,2 @@
knot_diagram parse_knot (const char *s);

1782
knot_parser/knot_scanner.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
%{
#include "knot_parser.hh"
#define YY_DECL \
yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval)
#define yyterminate() return token::END
typedef yy::knot_parser::token token;
typedef yy::knot_parser::token_type token_type;
%}
%option noyywrap nounput batch prefix="knot_yy"
%%
-?[0-9]+ {
yylval->integer = atoi (yytext);
return token::INT;
}
[a-zA-Z]+ {
if (!strcmp (yytext, "a"))
{
yylval->alternating = 1;
return token::ALT;
}
else if (!strcmp (yytext, "L"))
return token::LINK;
else if (!strcmp (yytext, "n"))
{
yylval->alternating = 0;
return token::NONALT;
}
else if (!strcmp (yytext, "T"))
return token::T;
else if (!strcmp (yytext, "U")
|| !strcmp (yytext, "unknot"))
return token::UNKNOT;
else if (!strcmp (yytext, "X"))
return token::X;
else if (!strcmp (yytext, "BR"))
return token::BR;
else if (!strcmp (yytext, "PD"))
return token::PD;
else if (!strcmp (yytext, "DT")
|| !strcmp (yytext, "DTCode"))
return token::DT;
else if (!strcmp (yytext, "BR"))
return token::BR;
else
{
yylval->string = strdup (yytext);
return token::STRING;
}
}
[\t\r\n ] /* ignore */
. { return token_type (yytext[0]); }
%%
void
knot_scan_string (const char *s)
{
knot_yy_scan_string (s);
}

165
knot_parser/location.hh Normal file
View File

@ -0,0 +1,165 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Locations for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/**
** \file location.hh
** Define the yy::location class.
*/
#ifndef BISON_LOCATION_HH
# define BISON_LOCATION_HH
# include <iostream>
# include <string>
# include "position.hh"
namespace yy {
/* Line 163 of location.cc */
#line 51 "knot_parser/location.hh"
/// Abstract a location.
class location
{
public:
/// Construct a location.
location ()
: begin (), end ()
{
}
/// Initialization.
inline void initialize (std::string* fn)
{
begin.initialize (fn);
end = begin;
}
/** \name Line and Column related manipulators
** \{ */
public:
/// Reset initial location to final location.
inline void step ()
{
begin = end;
}
/// Extend the current location to the COUNT next columns.
inline void columns (unsigned int count = 1)
{
end += count;
}
/// Extend the current location to the COUNT next lines.
inline void lines (unsigned int count = 1)
{
end.lines (count);
}
/** \} */
public:
/// Beginning of the located region.
position begin;
/// End of the located region.
position end;
};
/// Join two location objects to create a location.
inline const location operator+ (const location& begin, const location& end)
{
location res = begin;
res.end = end.end;
return res;
}
/// Add two location objects.
inline const location operator+ (const location& begin, unsigned int width)
{
location res = begin;
res.columns (width);
return res;
}
/// Add and assign a location.
inline location& operator+= (location& res, unsigned int width)
{
res.columns (width);
return res;
}
/// Compare two location objects.
inline bool
operator== (const location& loc1, const location& loc2)
{
return loc1.begin == loc2.begin && loc1.end == loc2.end;
}
/// Compare two location objects.
inline bool
operator!= (const location& loc1, const location& loc2)
{
return !(loc1 == loc2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param loc a reference to the location to redirect
**
** Avoid duplicate information.
*/
inline std::ostream& operator<< (std::ostream& ostr, const location& loc)
{
position last = loc.end - 1;
ostr << loc.begin;
if (last.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
ostr << '-' << last;
else if (loc.begin.line != last.line)
ostr << '-' << last.line << '.' << last.column;
else if (loc.begin.column != last.column)
ostr << '-' << last.column;
return ostr;
}
} // yy
/* Line 272 of location.cc */
#line 164 "knot_parser/location.hh"
#endif // not BISON_LOCATION_HH

162
knot_parser/position.hh Normal file
View File

@ -0,0 +1,162 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Positions for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/**
** \file position.hh
** Define the yy::position class.
*/
#ifndef BISON_POSITION_HH
# define BISON_POSITION_HH
# include <iostream>
# include <string>
# include <algorithm>
namespace yy {
/* Line 38 of location.cc */
#line 51 "knot_parser/position.hh"
/// Abstract a position.
class position
{
public:
/// Construct a position.
position ()
: filename (0), line (1), column (1)
{
}
/// Initialization.
inline void initialize (std::string* fn)
{
filename = fn;
line = 1;
column = 1;
}
/** \name Line and Column related manipulators
** \{ */
public:
/// (line related) Advance to the COUNT next lines.
inline void lines (int count = 1)
{
column = 1;
line += count;
}
/// (column related) Advance to the COUNT next columns.
inline 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.
unsigned int line;
/// Current column number.
unsigned int column;
};
/// Add and assign a position.
inline const position&
operator+= (position& res, const int width)
{
res.columns (width);
return res;
}
/// Add two position objects.
inline const position
operator+ (const position& begin, const int width)
{
position res = begin;
return res += width;
}
/// Add and assign a position.
inline const position&
operator-= (position& res, const int width)
{
return res += -width;
}
/// Add two position objects.
inline const position
operator- (const position& begin, const int width)
{
return begin + -width;
}
/// Compare two position objects.
inline bool
operator== (const position& pos1, const position& pos2)
{
return (pos1.line == pos2.line
&& pos1.column == pos2.column
&& (pos1.filename == pos2.filename
|| (pos1.filename && pos2.filename
&& *pos1.filename == *pos2.filename)));
}
/// Compare two position objects.
inline bool
operator!= (const position& pos1, const position& pos2)
{
return !(pos1 == pos2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param pos a reference to the position to redirect
*/
inline std::ostream&
operator<< (std::ostream& ostr, const position& pos)
{
if (pos.filename)
ostr << *pos.filename << ':';
return ostr << pos.line << '.' << pos.column;
}
} // yy
/* Line 145 of location.cc */
#line 162 "knot_parser/position.hh"
#endif // not BISON_POSITION_HH

136
knot_parser/stack.hh Normal file
View File

@ -0,0 +1,136 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Stack handling for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef BISON_STACK_HH
# define BISON_STACK_HH
#include <deque>
namespace yy {
/* Line 1067 of lalr1.cc */
#line 44 "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;
stack () : seq_ ()
{
}
stack (unsigned int n) : seq_ (n)
{
}
inline
T&
operator [] (unsigned int i)
{
return seq_[i];
}
inline
const T&
operator [] (unsigned int i) const
{
return seq_[i];
}
inline
void
push (const T& t)
{
seq_.push_front (t);
}
inline
void
pop (unsigned int n = 1)
{
for (; n; --n)
seq_.pop_front ();
}
inline
unsigned int
height () const
{
return seq_.size ();
}
inline const_iterator begin () const { return seq_.rbegin (); }
inline const_iterator end () const { return seq_.rend (); }
private:
S seq_;
};
/// Present a slice of the top of a stack.
template <class T, class S = stack<T> >
class slice
{
public:
slice (const S& stack,
unsigned int range) : stack_ (stack),
range_ (range)
{
}
inline
const T&
operator [] (unsigned int i) const
{
return stack_[range_ - i];
}
private:
const S& stack_;
unsigned int range_;
};
} // yy
/* Line 1153 of lalr1.cc */
#line 134 "knot_parser/stack.hh"
#endif // not BISON_STACK_HH[]dnl

730
knot_tables.cpp Normal file
View File

@ -0,0 +1,730 @@
#include <knotkit.h>
#define HOME "/Users/cotton/src/knotkit/"
bool verbose = 0;
static const struct {
const char *name;
int crossing_ar[3][4];
} rolfsen3[] = {
{ "3_{1}", { { 1, 5, 2, 4 }, { 3, 1, 4, 6 }, { 5, 3, 6, 2 } } }
};
static const struct {
const char *name;
int crossing_ar[4][4];
} rolfsen4[] = {
{ "4_{1}", { { 4, 2, 5, 1 }, { 8, 6, 1, 5 }, { 6, 3, 7, 4 }, { 2, 7, 3, 8 } } }
};
static const struct {
const char *name;
int crossing_ar[5][4];
} rolfsen5[] = {
{ "5_{1}", { { 2, 8, 3, 7 }, { 4, 10, 5, 9 }, { 6, 2, 7, 1 }, { 8, 4, 9, 3 }, { 10, 6, 1, 5 } } },
{ "5_{2}", { { 1, 5, 2, 4 }, { 3, 9, 4, 8 }, { 5, 1, 6, 10 }, { 7, 3, 8, 2 }, { 9, 7, 10, 6 } } }
};
static const struct {
const char *name;
int crossing_ar[6][4];
} rolfsen6[] = {
{ "6_{1}", { { 1, 7, 2, 6 }, { 3, 10, 4, 11 }, { 5, 3, 6, 2 }, { 7, 1, 8, 12 }, { 9, 4, 10, 5 }, { 11, 9, 12, 8 } } },
{ "6_{2}", { { 1, 8, 2, 9 }, { 3, 11, 4, 10 }, { 5, 1, 6, 12 }, { 7, 2, 8, 3 }, { 9, 7, 10, 6 }, { 11, 5, 12, 4 } } },
{ "6_{3}", { { 4, 2, 5, 1 }, { 8, 4, 9, 3 }, { 12, 9, 1, 10 }, { 10, 5, 11, 6 }, { 6, 11, 7, 12 }, { 2, 8, 3, 7 } } }
};
static const struct {
const char *name;
int crossing_ar[7][4];
} rolfsen7[] = {
{ "7_{1}", { { 1, 9, 2, 8 }, { 3, 11, 4, 10 }, { 5, 13, 6, 12 }, { 7, 1, 8, 14 }, { 9, 3, 10, 2 }, { 11, 5, 12, 4 }, { 13, 7, 14, 6 } } },
{ "7_{2}", { { 2, 10, 3, 9 }, { 4, 14, 5, 13 }, { 6, 12, 7, 11 }, { 8, 2, 9, 1 }, { 10, 8, 11, 7 }, { 12, 6, 13, 5 }, { 14, 4, 1, 3 } } },
{ "7_{3}", { { 1, 9, 2, 8 }, { 3, 11, 4, 10 }, { 5, 1, 6, 14 }, { 7, 13, 8, 12 }, { 9, 3, 10, 2 }, { 11, 5, 12, 4 }, { 13, 7, 14, 6 } } },
{ "7_{4}", { { 2, 10, 3, 9 }, { 4, 12, 5, 11 }, { 6, 14, 7, 13 }, { 8, 4, 9, 3 }, { 10, 2, 11, 1 }, { 12, 8, 13, 7 }, { 14, 6, 1, 5 } } },
{ "7_{5}", { { 2, 10, 3, 9 }, { 4, 2, 5, 1 }, { 6, 14, 7, 13 }, { 8, 12, 9, 11 }, { 10, 4, 11, 3 }, { 12, 6, 13, 5 }, { 14, 8, 1, 7 } } },
{ "7_{6}", { { 1, 13, 2, 12 }, { 3, 9, 4, 8 }, { 5, 1, 6, 14 }, { 7, 10, 8, 11 }, { 9, 3, 10, 2 }, { 11, 6, 12, 7 }, { 13, 5, 14, 4 } } },
{ "7_{7}", { { 1, 10, 2, 11 }, { 3, 13, 4, 12 }, { 5, 14, 6, 1 }, { 7, 5, 8, 4 }, { 9, 2, 10, 3 }, { 11, 9, 12, 8 }, { 13, 6, 14, 7 } } }
};
static const struct {
const char *name;
int crossing_ar[8][4];
} rolfsen8[] = {
{ "8_{1}", { { 1, 9, 2, 8 }, { 3, 7, 4, 6 }, { 5, 12, 6, 13 }, { 7, 3, 8, 2 }, { 9, 1, 10, 16 }, { 11, 15, 12, 14 }, { 13, 4, 14, 5 }, { 15, 11, 16, 10 } } },
{ "8_{2}", { { 1, 10, 2, 11 }, { 3, 13, 4, 12 }, { 5, 15, 6, 14 }, { 7, 1, 8, 16 }, { 9, 2, 10, 3 }, { 11, 9, 12, 8 }, { 13, 5, 14, 4 }, { 15, 7, 16, 6 } } },
{ "8_{3}", { { 6, 2, 7, 1 }, { 14, 10, 15, 9 }, { 10, 5, 11, 6 }, { 12, 3, 13, 4 }, { 4, 11, 5, 12 }, { 2, 13, 3, 14 }, { 16, 8, 1, 7 }, { 8, 16, 9, 15 } } },
{ "8_{4}", { { 2, 11, 3, 12 }, { 4, 9, 5, 10 }, { 6, 16, 7, 15 }, { 8, 14, 9, 13 }, { 10, 1, 11, 2 }, { 12, 3, 13, 4 }, { 14, 8, 15, 7 }, { 16, 6, 1, 5 } } },
{ "8_{5}", { { 1, 7, 2, 6 }, { 3, 9, 4, 8 }, { 5, 12, 6, 13 }, { 7, 3, 8, 2 }, { 9, 15, 10, 14 }, { 11, 1, 12, 16 }, { 13, 4, 14, 5 }, { 15, 11, 16, 10 } } },
{ "8_{6}", { { 2, 9, 3, 10 }, { 4, 14, 5, 13 }, { 6, 16, 7, 15 }, { 8, 12, 9, 11 }, { 10, 1, 11, 2 }, { 12, 8, 13, 7 }, { 14, 6, 15, 5 }, { 16, 4, 1, 3 } } },
{ "8_{7}", { { 2, 9, 3, 10 }, { 4, 14, 5, 13 }, { 6, 15, 7, 16 }, { 8, 1, 9, 2 }, { 10, 5, 11, 6 }, { 12, 4, 13, 3 }, { 14, 12, 15, 11 }, { 16, 7, 1, 8 } } },
{ "8_{8}", { { 1, 7, 2, 6 }, { 3, 12, 4, 13 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 16, 10, 1 }, { 11, 14, 12, 15 }, { 13, 4, 14, 5 }, { 15, 10, 16, 11 } } },
{ "8_{9}", { { 6, 2, 7, 1 }, { 14, 8, 15, 7 }, { 10, 3, 11, 4 }, { 2, 13, 3, 14 }, { 12, 5, 13, 6 }, { 4, 11, 5, 12 }, { 16, 10, 1, 9 }, { 8, 16, 9, 15 } } },
{ "8_{10}", { { 2, 14, 3, 13 }, { 4, 9, 5, 10 }, { 6, 11, 7, 12 }, { 8, 15, 9, 16 }, { 10, 5, 11, 6 }, { 12, 2, 13, 1 }, { 14, 7, 15, 8 }, { 16, 4, 1, 3 } } },
{ "8_{11}", { { 1, 10, 2, 11 }, { 3, 13, 4, 12 }, { 5, 15, 6, 14 }, { 7, 1, 8, 16 }, { 9, 2, 10, 3 }, { 11, 9, 12, 8 }, { 13, 7, 14, 6 }, { 15, 5, 16, 4 } } },
{ "8_{12}", { { 4, 2, 5, 1 }, { 10, 8, 11, 7 }, { 8, 3, 9, 4 }, { 2, 9, 3, 10 }, { 14, 6, 15, 5 }, { 16, 11, 1, 12 }, { 12, 15, 13, 16 }, { 6, 14, 7, 13 } } },
{ "8_{13}", { { 1, 9, 2, 8 }, { 3, 14, 4, 15 }, { 5, 12, 6, 13 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 16, 12, 1 }, { 13, 4, 14, 5 }, { 15, 6, 16, 7 } } },
{ "8_{14}", { { 2, 12, 3, 11 }, { 4, 8, 5, 7 }, { 6, 15, 7, 16 }, { 8, 14, 9, 13 }, { 10, 2, 11, 1 }, { 12, 10, 13, 9 }, { 14, 4, 15, 3 }, { 16, 5, 1, 6 } } },
{ "8_{15}", { { 1, 7, 2, 6 }, { 3, 15, 4, 14 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 13, 10, 12 }, { 11, 1, 12, 16 }, { 13, 5, 14, 4 }, { 15, 11, 16, 10 } } },
{ "8_{16}", { { 2, 7, 3, 8 }, { 4, 10, 5, 9 }, { 6, 1, 7, 2 }, { 8, 14, 9, 13 }, { 10, 15, 11, 16 }, { 12, 6, 13, 5 }, { 14, 3, 15, 4 }, { 16, 11, 1, 12 } } },
{ "8_{17}", { { 6, 2, 7, 1 }, { 14, 8, 15, 7 }, { 8, 3, 9, 4 }, { 2, 13, 3, 14 }, { 12, 5, 13, 6 }, { 4, 9, 5, 10 }, { 16, 12, 1, 11 }, { 10, 16, 11, 15 } } },
{ "8_{18}", { { 6, 2, 7, 1 }, { 8, 3, 9, 4 }, { 16, 11, 1, 12 }, { 2, 14, 3, 13 }, { 4, 15, 5, 16 }, { 10, 6, 11, 5 }, { 12, 7, 13, 8 }, { 14, 10, 15, 9 } } },
{ "8_{19}", { { 2, 14, 3, 13 }, { 5, 11, 6, 10 }, { 7, 15, 8, 14 }, { 9, 5, 10, 4 }, { 11, 7, 12, 6 }, { 12, 2, 13, 1 }, { 15, 9, 16, 8 }, { 16, 4, 1, 3 } } },
{ "8_{20}", { { 1, 7, 2, 6 }, { 4, 13, 5, 14 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 10, 15, 11, 16 }, { 12, 9, 13, 10 }, { 14, 3, 15, 4 }, { 16, 11, 1, 12 } } },
{ "8_{21}", { { 1, 7, 2, 6 }, { 4, 13, 5, 14 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 13, 10, 12 }, { 11, 1, 12, 16 }, { 14, 3, 15, 4 }, { 15, 11, 16, 10 } } }
};
static const struct {
const char *name;
int crossing_ar[9][4];
} rolfsen9[] = {
{ "9_{1}", { { 1, 11, 2, 10 }, { 3, 13, 4, 12 }, { 5, 15, 6, 14 }, { 7, 17, 8, 16 }, { 9, 1, 10, 18 }, { 11, 3, 12, 2 }, { 13, 5, 14, 4 }, { 15, 7, 16, 6 }, { 17, 9, 18, 8 } } },
{ "9_{2}", { { 2, 8, 3, 7 }, { 4, 14, 5, 13 }, { 6, 4, 7, 3 }, { 8, 2, 9, 1 }, { 10, 18, 11, 17 }, { 12, 16, 13, 15 }, { 14, 6, 15, 5 }, { 16, 12, 17, 11 }, { 18, 10, 1, 9 } } },
{ "9_{3}", { { 1, 11, 2, 10 }, { 3, 15, 4, 14 }, { 5, 13, 6, 12 }, { 7, 17, 8, 16 }, { 9, 1, 10, 18 }, { 11, 3, 12, 2 }, { 13, 5, 14, 4 }, { 15, 7, 16, 6 }, { 17, 9, 18, 8 } } },
{ "9_{4}", { { 2, 14, 3, 13 }, { 4, 12, 5, 11 }, { 6, 16, 7, 15 }, { 8, 18, 9, 17 }, { 10, 6, 11, 5 }, { 12, 4, 13, 3 }, { 14, 2, 15, 1 }, { 16, 8, 17, 7 }, { 18, 10, 1, 9 } } },
{ "9_{5}", { { 2, 14, 3, 13 }, { 4, 12, 5, 11 }, { 6, 16, 7, 15 }, { 8, 18, 9, 17 }, { 10, 6, 11, 5 }, { 12, 4, 13, 3 }, { 14, 2, 15, 1 }, { 16, 10, 17, 9 }, { 18, 8, 1, 7 } } },
{ "9_{6}", { { 1, 13, 2, 12 }, { 3, 7, 4, 6 }, { 5, 15, 6, 14 }, { 7, 3, 8, 2 }, { 9, 17, 10, 16 }, { 11, 1, 12, 18 }, { 13, 5, 14, 4 }, { 15, 9, 16, 8 }, { 17, 11, 18, 10 } } },
{ "9_{7}", { { 2, 10, 3, 9 }, { 4, 12, 5, 11 }, { 6, 16, 7, 15 }, { 8, 6, 9, 5 }, { 10, 4, 11, 3 }, { 12, 2, 13, 1 }, { 14, 18, 15, 17 }, { 16, 8, 17, 7 }, { 18, 14, 1, 13 } } },
{ "9_{8}", { { 1, 16, 2, 17 }, { 3, 14, 4, 15 }, { 5, 11, 6, 10 }, { 7, 1, 8, 18 }, { 9, 13, 10, 12 }, { 11, 7, 12, 6 }, { 13, 4, 14, 5 }, { 15, 2, 16, 3 }, { 17, 9, 18, 8 } } },
{ "9_{9}", { { 1, 13, 2, 12 }, { 3, 9, 4, 8 }, { 5, 15, 6, 14 }, { 7, 17, 8, 16 }, { 9, 3, 10, 2 }, { 11, 1, 12, 18 }, { 13, 5, 14, 4 }, { 15, 7, 16, 6 }, { 17, 11, 18, 10 } } },
{ "9_{10}", { { 1, 13, 2, 12 }, { 3, 11, 4, 10 }, { 5, 17, 6, 16 }, { 7, 15, 8, 14 }, { 9, 1, 10, 18 }, { 11, 3, 12, 2 }, { 13, 5, 14, 4 }, { 15, 7, 16, 6 }, { 17, 9, 18, 8 } } },
{ "9_{11}", { { 2, 7, 3, 8 }, { 4, 13, 5, 14 }, { 6, 15, 7, 16 }, { 8, 12, 9, 11 }, { 10, 17, 11, 18 }, { 12, 3, 13, 4 }, { 14, 5, 15, 6 }, { 16, 2, 17, 1 }, { 18, 9, 1, 10 } } },
{ "9_{12}", { { 2, 9, 3, 10 }, { 4, 16, 5, 15 }, { 6, 14, 7, 13 }, { 8, 3, 9, 4 }, { 10, 18, 11, 17 }, { 12, 8, 13, 7 }, { 14, 6, 15, 5 }, { 16, 2, 17, 1 }, { 18, 12, 1, 11 } } },
{ "9_{13}", { { 2, 12, 3, 11 }, { 4, 14, 5, 13 }, { 6, 16, 7, 15 }, { 8, 18, 9, 17 }, { 10, 6, 11, 5 }, { 12, 4, 13, 3 }, { 14, 2, 15, 1 }, { 16, 10, 17, 9 }, { 18, 8, 1, 7 } } },
{ "9_{14}", { { 1, 12, 2, 13 }, { 3, 10, 4, 11 }, { 5, 16, 6, 17 }, { 7, 1, 8, 18 }, { 9, 4, 10, 5 }, { 11, 2, 12, 3 }, { 13, 9, 14, 8 }, { 15, 6, 16, 7 }, { 17, 15, 18, 14 } } },
{ "9_{15}", { { 2, 9, 3, 10 }, { 4, 7, 5, 8 }, { 6, 15, 7, 16 }, { 8, 3, 9, 4 }, { 10, 14, 11, 13 }, { 12, 17, 13, 18 }, { 14, 5, 15, 6 }, { 16, 2, 17, 1 }, { 18, 11, 1, 12 } } },
{ "9_{16}", { { 1, 9, 2, 8 }, { 3, 11, 4, 10 }, { 5, 15, 6, 14 }, { 7, 5, 8, 4 }, { 9, 3, 10, 2 }, { 11, 17, 12, 16 }, { 13, 1, 14, 18 }, { 15, 7, 16, 6 }, { 17, 13, 18, 12 } } },
{ "9_{17}", { { 1, 9, 2, 8 }, { 3, 12, 4, 13 }, { 5, 16, 6, 17 }, { 7, 1, 8, 18 }, { 9, 3, 10, 2 }, { 11, 4, 12, 5 }, { 13, 11, 14, 10 }, { 15, 6, 16, 7 }, { 17, 15, 18, 14 } } },
{ "9_{18}", { { 2, 12, 3, 11 }, { 4, 2, 5, 1 }, { 6, 16, 7, 15 }, { 8, 14, 9, 13 }, { 10, 18, 11, 17 }, { 12, 4, 13, 3 }, { 14, 8, 15, 7 }, { 16, 10, 17, 9 }, { 18, 6, 1, 5 } } },
{ "9_{19}", { { 2, 14, 3, 13 }, { 4, 11, 5, 12 }, { 6, 4, 7, 3 }, { 8, 17, 9, 18 }, { 10, 5, 11, 6 }, { 12, 8, 13, 7 }, { 14, 2, 15, 1 }, { 16, 9, 17, 10 }, { 18, 16, 1, 15 } } },
{ "9_{20}", { { 1, 11, 2, 10 }, { 3, 16, 4, 17 }, { 5, 13, 6, 12 }, { 7, 3, 8, 2 }, { 9, 1, 10, 18 }, { 11, 15, 12, 14 }, { 13, 7, 14, 6 }, { 15, 4, 16, 5 }, { 17, 9, 18, 8 } } },
{ "9_{21}", { { 2, 7, 3, 8 }, { 4, 13, 5, 14 }, { 6, 15, 7, 16 }, { 8, 12, 9, 11 }, { 10, 17, 11, 18 }, { 12, 5, 13, 6 }, { 14, 3, 15, 4 }, { 16, 2, 17, 1 }, { 18, 9, 1, 10 } } },
{ "9_{22}", { { 1, 7, 2, 6 }, { 3, 8, 4, 9 }, { 5, 14, 6, 15 }, { 7, 11, 8, 10 }, { 9, 2, 10, 3 }, { 11, 17, 12, 16 }, { 13, 1, 14, 18 }, { 15, 4, 16, 5 }, { 17, 13, 18, 12 } } },
{ "9_{23}", { { 2, 16, 3, 15 }, { 4, 12, 5, 11 }, { 6, 4, 7, 3 }, { 8, 18, 9, 17 }, { 10, 14, 11, 13 }, { 12, 6, 13, 5 }, { 14, 8, 15, 7 }, { 16, 2, 17, 1 }, { 18, 10, 1, 9 } } },
{ "9_{24}", { { 1, 13, 2, 12 }, { 3, 7, 4, 6 }, { 5, 1, 6, 18 }, { 7, 14, 8, 15 }, { 9, 16, 10, 17 }, { 11, 3, 12, 2 }, { 13, 10, 14, 11 }, { 15, 8, 16, 9 }, { 17, 5, 18, 4 } } },
{ "9_{25}", { { 2, 10, 3, 9 }, { 4, 17, 5, 18 }, { 6, 12, 7, 11 }, { 8, 4, 9, 3 }, { 10, 14, 11, 13 }, { 12, 8, 13, 7 }, { 14, 2, 15, 1 }, { 16, 5, 17, 6 }, { 18, 16, 1, 15 } } },
{ "9_{26}", { { 2, 10, 3, 9 }, { 4, 11, 5, 12 }, { 6, 17, 7, 18 }, { 8, 15, 9, 16 }, { 10, 14, 11, 13 }, { 12, 3, 13, 4 }, { 14, 2, 15, 1 }, { 16, 5, 17, 6 }, { 18, 7, 1, 8 } } },
{ "9_{27}", { { 2, 9, 3, 10 }, { 4, 7, 5, 8 }, { 6, 14, 7, 13 }, { 8, 15, 9, 16 }, { 10, 18, 11, 17 }, { 12, 3, 13, 4 }, { 14, 6, 15, 5 }, { 16, 2, 17, 1 }, { 18, 12, 1, 11 } } },
{ "9_{28}", { { 1, 16, 2, 17 }, { 3, 15, 4, 14 }, { 5, 3, 6, 2 }, { 7, 13, 8, 12 }, { 9, 7, 10, 6 }, { 11, 18, 12, 1 }, { 13, 9, 14, 8 }, { 15, 5, 16, 4 }, { 17, 10, 18, 11 } } },
{ "9_{29}", { { 2, 10, 3, 9 }, { 4, 17, 5, 18 }, { 6, 12, 7, 11 }, { 8, 4, 9, 3 }, { 10, 15, 11, 16 }, { 12, 6, 13, 5 }, { 14, 1, 15, 2 }, { 16, 7, 17, 8 }, { 18, 13, 1, 14 } } },
{ "9_{30}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 1, 6, 18 }, { 7, 12, 8, 13 }, { 9, 3, 10, 2 }, { 11, 6, 12, 7 }, { 13, 10, 14, 11 }, { 15, 4, 16, 5 }, { 17, 15, 18, 14 } } },
{ "9_{31}", { { 1, 9, 2, 8 }, { 3, 10, 4, 11 }, { 5, 13, 6, 12 }, { 7, 1, 8, 18 }, { 9, 16, 10, 17 }, { 11, 15, 12, 14 }, { 13, 7, 14, 6 }, { 15, 4, 16, 5 }, { 17, 3, 18, 2 } } },
{ "9_{32}", { { 2, 8, 3, 7 }, { 4, 9, 5, 10 }, { 6, 13, 7, 14 }, { 8, 16, 9, 15 }, { 10, 5, 11, 6 }, { 12, 17, 13, 18 }, { 14, 3, 15, 4 }, { 16, 2, 17, 1 }, { 18, 11, 1, 12 } } },
{ "9_{33}", { { 1, 15, 2, 14 }, { 3, 16, 4, 17 }, { 5, 12, 6, 13 }, { 7, 5, 8, 4 }, { 9, 2, 10, 3 }, { 11, 6, 12, 7 }, { 13, 1, 14, 18 }, { 15, 11, 16, 10 }, { 17, 8, 18, 9 } } },
{ "9_{34}", { { 2, 13, 3, 14 }, { 4, 17, 5, 18 }, { 6, 16, 7, 15 }, { 8, 4, 9, 3 }, { 10, 5, 11, 6 }, { 12, 8, 13, 7 }, { 14, 1, 15, 2 }, { 16, 11, 17, 12 }, { 18, 10, 1, 9 } } },
{ "9_{35}", { { 2, 12, 3, 11 }, { 4, 16, 5, 15 }, { 6, 14, 7, 13 }, { 8, 18, 9, 17 }, { 10, 4, 11, 3 }, { 12, 2, 13, 1 }, { 14, 6, 15, 5 }, { 16, 10, 17, 9 }, { 18, 8, 1, 7 } } },
{ "9_{36}", { { 2, 15, 3, 16 }, { 4, 11, 5, 12 }, { 6, 4, 7, 3 }, { 8, 17, 9, 18 }, { 10, 5, 11, 6 }, { 12, 10, 13, 9 }, { 14, 1, 15, 2 }, { 16, 7, 17, 8 }, { 18, 13, 1, 14 } } },
{ "9_{37}", { { 1, 10, 2, 11 }, { 3, 14, 4, 15 }, { 5, 1, 6, 18 }, { 7, 17, 8, 16 }, { 9, 2, 10, 3 }, { 11, 9, 12, 8 }, { 13, 4, 14, 5 }, { 15, 13, 16, 12 }, { 17, 7, 18, 6 } } },
{ "9_{38}", { { 2, 14, 3, 13 }, { 4, 10, 5, 9 }, { 6, 16, 7, 15 }, { 8, 4, 9, 3 }, { 10, 18, 11, 17 }, { 12, 6, 13, 5 }, { 14, 2, 15, 1 }, { 16, 12, 17, 11 }, { 18, 8, 1, 7 } } },
{ "9_{39}", { { 1, 12, 2, 13 }, { 3, 17, 4, 16 }, { 5, 10, 6, 11 }, { 7, 18, 8, 1 }, { 9, 14, 10, 15 }, { 11, 2, 12, 3 }, { 13, 6, 14, 7 }, { 15, 5, 16, 4 }, { 17, 8, 18, 9 } } },
{ "9_{40}", { { 1, 15, 2, 14 }, { 3, 12, 4, 13 }, { 5, 11, 6, 10 }, { 7, 3, 8, 2 }, { 9, 18, 10, 1 }, { 11, 17, 12, 16 }, { 13, 9, 14, 8 }, { 15, 6, 16, 7 }, { 17, 5, 18, 4 } } },
{ "9_{41}", { { 1, 15, 2, 14 }, { 3, 12, 4, 13 }, { 5, 16, 6, 17 }, { 7, 3, 8, 2 }, { 9, 18, 10, 1 }, { 11, 4, 12, 5 }, { 13, 9, 14, 8 }, { 15, 6, 16, 7 }, { 17, 10, 18, 11 } } },
{ "9_{42}", { { 1, 4, 2, 5 }, { 5, 10, 6, 11 }, { 3, 9, 4, 8 }, { 9, 3, 10, 2 }, { 16, 12, 17, 11 }, { 14, 7, 15, 8 }, { 6, 15, 7, 16 }, { 18, 14, 1, 13 }, { 12, 18, 13, 17 } } },
{ "9_{43}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 1, 6, 18 }, { 6, 12, 7, 11 }, { 9, 3, 10, 2 }, { 10, 14, 11, 13 }, { 12, 8, 13, 7 }, { 15, 4, 16, 5 }, { 17, 15, 18, 14 } } },
{ "9_{44}", { { 2, 9, 3, 10 }, { 3, 16, 4, 17 }, { 5, 1, 6, 18 }, { 6, 12, 7, 11 }, { 8, 1, 9, 2 }, { 10, 14, 11, 13 }, { 12, 8, 13, 7 }, { 15, 4, 16, 5 }, { 17, 15, 18, 14 } } },
{ "9_{45}", { { 2, 9, 3, 10 }, { 3, 16, 4, 17 }, { 5, 1, 6, 18 }, { 7, 12, 8, 13 }, { 8, 1, 9, 2 }, { 11, 6, 12, 7 }, { 13, 10, 14, 11 }, { 15, 4, 16, 5 }, { 17, 15, 18, 14 } } },
{ "9_{46}", { { 2, 10, 3, 9 }, { 3, 14, 4, 15 }, { 6, 17, 7, 18 }, { 8, 11, 9, 12 }, { 10, 2, 11, 1 }, { 13, 4, 14, 5 }, { 15, 13, 16, 12 }, { 16, 7, 17, 8 }, { 18, 5, 1, 6 } } },
{ "9_{47}", { { 1, 15, 2, 14 }, { 4, 17, 5, 18 }, { 6, 16, 7, 15 }, { 8, 4, 9, 3 }, { 10, 5, 11, 6 }, { 12, 8, 13, 7 }, { 13, 3, 14, 2 }, { 16, 11, 17, 12 }, { 18, 10, 1, 9 } } },
{ "9_{48}", { { 1, 10, 2, 11 }, { 3, 14, 4, 15 }, { 6, 17, 7, 18 }, { 9, 2, 10, 3 }, { 11, 9, 12, 8 }, { 13, 4, 14, 5 }, { 15, 13, 16, 12 }, { 16, 7, 17, 8 }, { 18, 5, 1, 6 } } },
{ "9_{49}", { { 1, 15, 2, 14 }, { 4, 12, 5, 11 }, { 6, 16, 7, 15 }, { 7, 3, 8, 2 }, { 10, 18, 11, 17 }, { 12, 4, 13, 3 }, { 13, 9, 14, 8 }, { 16, 6, 17, 5 }, { 18, 10, 1, 9 } } }
};
static const struct {
const char *name;
int crossing_ar[10][4];
} rolfsen10[] = {
{ "10_{1}", { { 2, 11, 3, 12 }, { 4, 20, 5, 19 }, { 6, 18, 7, 17 }, { 8, 16, 9, 15 }, { 10, 14, 11, 13 }, { 12, 1, 13, 2 }, { 14, 10, 15, 9 }, { 16, 8, 17, 7 }, { 18, 6, 19, 5 }, { 20, 4, 1, 3 } } },
{ "10_{2}", { { 1, 13, 2, 12 }, { 3, 14, 4, 15 }, { 5, 3, 6, 2 }, { 7, 17, 8, 16 }, { 9, 19, 10, 18 }, { 11, 1, 12, 20 }, { 13, 4, 14, 5 }, { 15, 7, 16, 6 }, { 17, 9, 18, 8 }, { 19, 11, 20, 10 } } },
{ "10_{3}", { { 2, 10, 3, 9 }, { 4, 17, 5, 18 }, { 6, 15, 7, 16 }, { 8, 4, 9, 3 }, { 10, 2, 11, 1 }, { 12, 20, 13, 19 }, { 14, 7, 15, 8 }, { 16, 5, 17, 6 }, { 18, 14, 19, 13 }, { 20, 12, 1, 11 } } },
{ "10_{4}", { { 2, 13, 3, 14 }, { 4, 11, 5, 12 }, { 6, 20, 7, 19 }, { 8, 18, 9, 17 }, { 10, 16, 11, 15 }, { 12, 1, 13, 2 }, { 14, 3, 15, 4 }, { 16, 10, 17, 9 }, { 18, 8, 19, 7 }, { 20, 6, 1, 5 } } },
{ "10_{5}", { { 2, 13, 3, 14 }, { 4, 17, 5, 18 }, { 6, 16, 7, 15 }, { 8, 6, 9, 5 }, { 10, 19, 11, 20 }, { 12, 1, 13, 2 }, { 14, 3, 15, 4 }, { 16, 8, 17, 7 }, { 18, 9, 19, 10 }, { 20, 11, 1, 12 } } },
{ "10_{6}", { { 2, 11, 3, 12 }, { 4, 16, 5, 15 }, { 6, 18, 7, 17 }, { 8, 20, 9, 19 }, { 10, 14, 11, 13 }, { 12, 1, 13, 2 }, { 14, 10, 15, 9 }, { 16, 6, 17, 5 }, { 18, 8, 19, 7 }, { 20, 4, 1, 3 } } },
{ "10_{7}", { { 1, 12, 2, 13 }, { 3, 15, 4, 14 }, { 5, 19, 6, 18 }, { 7, 17, 8, 16 }, { 9, 1, 10, 20 }, { 11, 2, 12, 3 }, { 13, 11, 14, 10 }, { 15, 9, 16, 8 }, { 17, 7, 18, 6 }, { 19, 5, 20, 4 } } },
{ "10_{8}", { { 1, 12, 2, 13 }, { 3, 10, 4, 11 }, { 5, 15, 6, 14 }, { 7, 17, 8, 16 }, { 9, 19, 10, 18 }, { 11, 2, 12, 3 }, { 13, 20, 14, 1 }, { 15, 7, 16, 6 }, { 17, 9, 18, 8 }, { 19, 5, 20, 4 } } },
{ "10_{9}", { { 1, 13, 2, 12 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 3, 8, 2 }, { 9, 19, 10, 18 }, { 11, 1, 12, 20 }, { 13, 4, 14, 5 }, { 15, 6, 16, 7 }, { 17, 9, 18, 8 }, { 19, 11, 20, 10 } } },
{ "10_{10}", { { 1, 11, 2, 10 }, { 3, 18, 4, 19 }, { 5, 16, 6, 17 }, { 7, 14, 8, 15 }, { 9, 13, 10, 12 }, { 11, 3, 12, 2 }, { 13, 20, 14, 1 }, { 15, 6, 16, 7 }, { 17, 4, 18, 5 }, { 19, 8, 20, 9 } } },
{ "10_{11}", { { 2, 15, 3, 16 }, { 4, 13, 5, 14 }, { 6, 2, 7, 1 }, { 8, 18, 9, 17 }, { 10, 20, 11, 19 }, { 12, 5, 13, 6 }, { 14, 3, 15, 4 }, { 16, 12, 17, 11 }, { 18, 10, 19, 9 }, { 20, 8, 1, 7 } } },
{ "10_{12}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 13, 7, 14 }, { 8, 19, 9, 20 }, { 10, 1, 11, 2 }, { 12, 7, 13, 8 }, { 14, 5, 15, 6 }, { 16, 4, 17, 3 }, { 18, 16, 19, 15 }, { 20, 9, 1, 10 } } },
{ "10_{13}", { { 2, 17, 3, 18 }, { 4, 8, 5, 7 }, { 6, 13, 7, 14 }, { 8, 2, 9, 1 }, { 10, 20, 11, 19 }, { 12, 16, 13, 15 }, { 14, 5, 15, 6 }, { 16, 3, 17, 4 }, { 18, 12, 19, 11 }, { 20, 10, 1, 9 } } },
{ "10_{14}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 11, 6, 10 }, { 7, 19, 8, 18 }, { 9, 1, 10, 20 }, { 11, 5, 12, 4 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 7, 18, 6 }, { 19, 9, 20, 8 } } },
{ "10_{15}", { { 2, 6, 3, 5 }, { 4, 16, 5, 15 }, { 6, 2, 7, 1 }, { 8, 17, 9, 18 }, { 10, 19, 11, 20 }, { 12, 7, 13, 8 }, { 14, 4, 15, 3 }, { 16, 14, 17, 13 }, { 18, 9, 19, 10 }, { 20, 11, 1, 12 } } },
{ "10_{16}", { { 1, 10, 2, 11 }, { 3, 15, 4, 14 }, { 5, 17, 6, 16 }, { 7, 19, 8, 18 }, { 9, 2, 10, 3 }, { 11, 20, 12, 1 }, { 13, 9, 14, 8 }, { 15, 7, 16, 6 }, { 17, 5, 18, 4 }, { 19, 12, 20, 13 } } },
{ "10_{17}", { { 6, 2, 7, 1 }, { 12, 4, 13, 3 }, { 20, 15, 1, 16 }, { 16, 7, 17, 8 }, { 18, 9, 19, 10 }, { 8, 17, 9, 18 }, { 10, 19, 11, 20 }, { 14, 6, 15, 5 }, { 2, 12, 3, 11 }, { 4, 14, 5, 13 } } },
{ "10_{18}", { { 2, 14, 3, 13 }, { 4, 10, 5, 9 }, { 6, 17, 7, 18 }, { 8, 15, 9, 16 }, { 10, 20, 11, 19 }, { 12, 2, 13, 1 }, { 14, 12, 15, 11 }, { 16, 7, 17, 8 }, { 18, 5, 19, 6 }, { 20, 4, 1, 3 } } },
{ "10_{19}", { { 1, 13, 2, 12 }, { 3, 15, 4, 14 }, { 5, 10, 6, 11 }, { 7, 16, 8, 17 }, { 9, 18, 10, 19 }, { 11, 1, 12, 20 }, { 13, 3, 14, 2 }, { 15, 8, 16, 9 }, { 17, 6, 18, 7 }, { 19, 5, 20, 4 } } },
{ "10_{20}", { { 2, 8, 3, 7 }, { 4, 15, 5, 16 }, { 6, 4, 7, 3 }, { 8, 2, 9, 1 }, { 10, 18, 11, 17 }, { 12, 20, 13, 19 }, { 14, 5, 15, 6 }, { 16, 14, 17, 13 }, { 18, 12, 19, 11 }, { 20, 10, 1, 9 } } },
{ "10_{21}", { { 1, 15, 2, 14 }, { 3, 13, 4, 12 }, { 5, 17, 6, 16 }, { 7, 11, 8, 10 }, { 9, 18, 10, 19 }, { 11, 1, 12, 20 }, { 13, 3, 14, 2 }, { 15, 5, 16, 4 }, { 17, 7, 18, 6 }, { 19, 8, 20, 9 } } },
{ "10_{22}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 16, 7, 15 }, { 8, 14, 9, 13 }, { 10, 1, 11, 2 }, { 12, 19, 13, 20 }, { 14, 6, 15, 5 }, { 16, 8, 17, 7 }, { 18, 4, 19, 3 }, { 20, 9, 1, 10 } } },
{ "10_{23}", { { 2, 13, 3, 14 }, { 4, 11, 5, 12 }, { 6, 18, 7, 17 }, { 8, 19, 9, 20 }, { 10, 1, 11, 2 }, { 12, 3, 13, 4 }, { 14, 7, 15, 8 }, { 16, 6, 17, 5 }, { 18, 16, 19, 15 }, { 20, 9, 1, 10 } } },
{ "10_{24}", { { 2, 14, 3, 13 }, { 4, 10, 5, 9 }, { 6, 17, 7, 18 }, { 8, 6, 9, 5 }, { 10, 4, 11, 3 }, { 12, 20, 13, 19 }, { 14, 2, 15, 1 }, { 16, 7, 17, 8 }, { 18, 12, 19, 11 }, { 20, 16, 1, 15 } } },
{ "10_{25}", { { 1, 11, 2, 10 }, { 3, 15, 4, 14 }, { 5, 13, 6, 12 }, { 7, 18, 8, 19 }, { 9, 1, 10, 20 }, { 11, 5, 12, 4 }, { 13, 7, 14, 6 }, { 15, 3, 16, 2 }, { 17, 8, 18, 9 }, { 19, 17, 20, 16 } } },
{ "10_{26}", { { 1, 12, 2, 13 }, { 3, 14, 4, 15 }, { 5, 17, 6, 16 }, { 7, 19, 8, 18 }, { 9, 1, 10, 20 }, { 11, 4, 12, 5 }, { 13, 2, 14, 3 }, { 15, 11, 16, 10 }, { 17, 9, 18, 8 }, { 19, 7, 20, 6 } } },
{ "10_{27}", { { 1, 11, 2, 10 }, { 3, 18, 4, 19 }, { 5, 16, 6, 17 }, { 7, 14, 8, 15 }, { 9, 13, 10, 12 }, { 11, 3, 12, 2 }, { 13, 20, 14, 1 }, { 15, 4, 16, 5 }, { 17, 6, 18, 7 }, { 19, 8, 20, 9 } } },
{ "10_{28}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 20, 12, 1 }, { 13, 18, 14, 19 }, { 15, 4, 16, 5 }, { 17, 6, 18, 7 }, { 19, 12, 20, 13 } } },
{ "10_{29}", { { 2, 15, 3, 16 }, { 4, 2, 5, 1 }, { 6, 11, 7, 12 }, { 8, 18, 9, 17 }, { 10, 20, 11, 19 }, { 12, 5, 13, 6 }, { 14, 3, 15, 4 }, { 16, 14, 17, 13 }, { 18, 10, 19, 9 }, { 20, 8, 1, 7 } } },
{ "10_{30}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 11, 6, 10 }, { 7, 19, 8, 18 }, { 9, 1, 10, 20 }, { 11, 5, 12, 4 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 9, 18, 8 }, { 19, 7, 20, 6 } } },
{ "10_{31}", { { 2, 6, 3, 5 }, { 4, 16, 5, 15 }, { 6, 2, 7, 1 }, { 8, 17, 9, 18 }, { 10, 19, 11, 20 }, { 12, 7, 13, 8 }, { 14, 4, 15, 3 }, { 16, 14, 17, 13 }, { 18, 11, 19, 12 }, { 20, 9, 1, 10 } } },
{ "10_{32}", { { 2, 14, 3, 13 }, { 4, 10, 5, 9 }, { 6, 15, 7, 16 }, { 8, 17, 9, 18 }, { 10, 20, 11, 19 }, { 12, 2, 13, 1 }, { 14, 12, 15, 11 }, { 16, 7, 17, 8 }, { 18, 5, 19, 6 }, { 20, 4, 1, 3 } } },
{ "10_{33}", { { 6, 2, 7, 1 }, { 14, 6, 15, 5 }, { 20, 15, 1, 16 }, { 16, 7, 17, 8 }, { 8, 19, 9, 20 }, { 18, 9, 19, 10 }, { 10, 17, 11, 18 }, { 2, 14, 3, 13 }, { 12, 4, 13, 3 }, { 4, 12, 5, 11 } } },
{ "10_{34}", { { 1, 7, 2, 6 }, { 3, 14, 4, 15 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 20, 10, 1 }, { 11, 18, 12, 19 }, { 13, 16, 14, 17 }, { 15, 4, 16, 5 }, { 17, 12, 18, 13 }, { 19, 10, 20, 11 } } },
{ "10_{35}", { { 1, 11, 2, 10 }, { 3, 18, 4, 19 }, { 5, 3, 6, 2 }, { 7, 14, 8, 15 }, { 9, 12, 10, 13 }, { 11, 1, 12, 20 }, { 13, 8, 14, 9 }, { 15, 6, 16, 7 }, { 17, 4, 18, 5 }, { 19, 17, 20, 16 } } },
{ "10_{36}", { { 2, 15, 3, 16 }, { 4, 14, 5, 13 }, { 6, 12, 7, 11 }, { 8, 18, 9, 17 }, { 10, 8, 11, 7 }, { 12, 6, 13, 5 }, { 14, 20, 15, 19 }, { 16, 1, 17, 2 }, { 18, 10, 19, 9 }, { 20, 4, 1, 3 } } },
{ "10_{37}", { { 4, 2, 5, 1 }, { 10, 4, 11, 3 }, { 12, 8, 13, 7 }, { 8, 12, 9, 11 }, { 18, 15, 19, 16 }, { 16, 5, 17, 6 }, { 6, 17, 7, 18 }, { 20, 13, 1, 14 }, { 14, 19, 15, 20 }, { 2, 10, 3, 9 } } },
{ "10_{38}", { { 2, 16, 3, 15 }, { 4, 12, 5, 11 }, { 6, 10, 7, 9 }, { 8, 17, 9, 18 }, { 10, 6, 11, 5 }, { 12, 20, 13, 19 }, { 14, 2, 15, 1 }, { 16, 14, 17, 13 }, { 18, 7, 19, 8 }, { 20, 4, 1, 3 } } },
{ "10_{39}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 19, 6, 18 }, { 7, 11, 8, 10 }, { 9, 1, 10, 20 }, { 11, 7, 12, 6 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 5, 18, 4 }, { 19, 9, 20, 8 } } },
{ "10_{40}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 19, 7, 20 }, { 8, 13, 9, 14 }, { 10, 1, 11, 2 }, { 12, 9, 13, 10 }, { 14, 5, 15, 6 }, { 16, 4, 17, 3 }, { 18, 16, 19, 15 }, { 20, 7, 1, 8 } } },
{ "10_{41}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 10, 6, 11 }, { 7, 19, 8, 18 }, { 9, 6, 10, 7 }, { 11, 1, 12, 20 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 9, 18, 8 }, { 19, 5, 20, 4 } } },
{ "10_{42}", { { 1, 9, 2, 8 }, { 3, 18, 4, 19 }, { 5, 14, 6, 15 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 20, 12, 1 }, { 13, 17, 14, 16 }, { 15, 4, 16, 5 }, { 17, 13, 18, 12 }, { 19, 6, 20, 7 } } },
{ "10_{43}", { { 4, 2, 5, 1 }, { 10, 4, 11, 3 }, { 14, 8, 15, 7 }, { 20, 11, 1, 12 }, { 12, 19, 13, 20 }, { 8, 14, 9, 13 }, { 18, 15, 19, 16 }, { 16, 5, 17, 6 }, { 6, 17, 7, 18 }, { 2, 10, 3, 9 } } },
{ "10_{44}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 20, 6, 1 }, { 7, 19, 8, 18 }, { 9, 7, 10, 6 }, { 11, 5, 12, 4 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 10, 18, 11 }, { 19, 9, 20, 8 } } },
{ "10_{45}", { { 4, 2, 5, 1 }, { 12, 6, 13, 5 }, { 10, 3, 11, 4 }, { 2, 11, 3, 12 }, { 20, 14, 1, 13 }, { 14, 7, 15, 8 }, { 6, 19, 7, 20 }, { 18, 15, 19, 16 }, { 16, 10, 17, 9 }, { 8, 18, 9, 17 } } },
{ "10_{46}", { { 1, 15, 2, 14 }, { 3, 9, 4, 8 }, { 5, 11, 6, 10 }, { 7, 16, 8, 17 }, { 9, 5, 10, 4 }, { 11, 19, 12, 18 }, { 13, 1, 14, 20 }, { 15, 3, 16, 2 }, { 17, 6, 18, 7 }, { 19, 13, 20, 12 } } },
{ "10_{47}", { { 2, 9, 3, 10 }, { 4, 11, 5, 12 }, { 6, 17, 7, 18 }, { 8, 1, 9, 2 }, { 10, 3, 11, 4 }, { 12, 5, 13, 6 }, { 14, 20, 15, 19 }, { 16, 14, 17, 13 }, { 18, 7, 19, 8 }, { 20, 16, 1, 15 } } },
{ "10_{48}", { { 6, 2, 7, 1 }, { 8, 4, 9, 3 }, { 14, 6, 15, 5 }, { 20, 15, 1, 16 }, { 16, 9, 17, 10 }, { 18, 11, 19, 12 }, { 10, 17, 11, 18 }, { 12, 19, 13, 20 }, { 2, 8, 3, 7 }, { 4, 14, 5, 13 } } },
{ "10_{49}", { { 1, 7, 2, 6 }, { 3, 17, 4, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 15, 10, 14 }, { 11, 19, 12, 18 }, { 13, 1, 14, 20 }, { 15, 5, 16, 4 }, { 17, 11, 18, 10 }, { 19, 13, 20, 12 } } },
{ "10_{50}", { { 1, 10, 2, 11 }, { 3, 19, 4, 18 }, { 5, 13, 6, 12 }, { 7, 15, 8, 14 }, { 9, 17, 10, 16 }, { 11, 20, 12, 1 }, { 13, 9, 14, 8 }, { 15, 7, 16, 6 }, { 17, 3, 18, 2 }, { 19, 5, 20, 4 } } },
{ "10_{51}", { { 2, 18, 3, 17 }, { 4, 11, 5, 12 }, { 6, 13, 7, 14 }, { 8, 15, 9, 16 }, { 10, 19, 11, 20 }, { 12, 7, 13, 8 }, { 14, 5, 15, 6 }, { 16, 2, 17, 1 }, { 18, 9, 19, 10 }, { 20, 4, 1, 3 } } },
{ "10_{52}", { { 1, 13, 2, 12 }, { 3, 19, 4, 18 }, { 5, 10, 6, 11 }, { 7, 14, 8, 15 }, { 9, 16, 10, 17 }, { 11, 1, 12, 20 }, { 13, 8, 14, 9 }, { 15, 6, 16, 7 }, { 17, 3, 18, 2 }, { 19, 5, 20, 4 } } },
{ "10_{53}", { { 1, 7, 2, 6 }, { 3, 17, 4, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 15, 10, 14 }, { 11, 19, 12, 18 }, { 13, 1, 14, 20 }, { 15, 5, 16, 4 }, { 17, 13, 18, 12 }, { 19, 11, 20, 10 } } },
{ "10_{54}", { { 2, 16, 3, 15 }, { 4, 9, 5, 10 }, { 6, 11, 7, 12 }, { 8, 19, 9, 20 }, { 10, 5, 11, 6 }, { 12, 18, 13, 17 }, { 14, 2, 15, 1 }, { 16, 14, 17, 13 }, { 18, 7, 19, 8 }, { 20, 4, 1, 3 } } },
{ "10_{55}", { { 2, 10, 3, 9 }, { 4, 18, 5, 17 }, { 6, 12, 7, 11 }, { 8, 2, 9, 1 }, { 10, 8, 11, 7 }, { 12, 6, 13, 5 }, { 14, 20, 15, 19 }, { 16, 14, 17, 13 }, { 18, 4, 19, 3 }, { 20, 16, 1, 15 } } },
{ "10_{56}", { { 2, 16, 3, 15 }, { 4, 10, 5, 9 }, { 6, 12, 7, 11 }, { 8, 17, 9, 18 }, { 10, 6, 11, 5 }, { 12, 20, 13, 19 }, { 14, 2, 15, 1 }, { 16, 14, 17, 13 }, { 18, 7, 19, 8 }, { 20, 4, 1, 3 } } },
{ "10_{57}", { { 1, 4, 2, 5 }, { 3, 16, 4, 17 }, { 5, 20, 6, 1 }, { 7, 13, 8, 12 }, { 9, 7, 10, 6 }, { 11, 18, 12, 19 }, { 13, 9, 14, 8 }, { 15, 2, 16, 3 }, { 17, 10, 18, 11 }, { 19, 14, 20, 15 } } },
{ "10_{58}", { { 2, 15, 3, 16 }, { 4, 10, 5, 9 }, { 6, 13, 7, 14 }, { 8, 6, 9, 5 }, { 10, 20, 11, 19 }, { 12, 7, 13, 8 }, { 14, 18, 15, 17 }, { 16, 1, 17, 2 }, { 18, 12, 19, 11 }, { 20, 4, 1, 3 } } },
{ "10_{59}", { { 1, 4, 2, 5 }, { 3, 17, 4, 16 }, { 5, 20, 6, 1 }, { 7, 14, 8, 15 }, { 9, 7, 10, 6 }, { 11, 19, 12, 18 }, { 13, 8, 14, 9 }, { 15, 11, 16, 10 }, { 17, 3, 18, 2 }, { 19, 13, 20, 12 } } },
{ "10_{60}", { { 2, 15, 3, 16 }, { 4, 8, 5, 7 }, { 6, 11, 7, 12 }, { 8, 14, 9, 13 }, { 10, 17, 11, 18 }, { 12, 5, 13, 6 }, { 14, 20, 15, 19 }, { 16, 1, 17, 2 }, { 18, 9, 19, 10 }, { 20, 4, 1, 3 } } },
{ "10_{61}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 1, 8, 20 }, { 9, 3, 10, 2 }, { 11, 19, 12, 18 }, { 13, 6, 14, 7 }, { 15, 4, 16, 5 }, { 17, 11, 18, 10 }, { 19, 13, 20, 12 } } },
{ "10_{62}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 13, 7, 14 }, { 8, 19, 9, 20 }, { 10, 1, 11, 2 }, { 12, 5, 13, 6 }, { 14, 7, 15, 8 }, { 16, 4, 17, 3 }, { 18, 16, 19, 15 }, { 20, 9, 1, 10 } } },
{ "10_{63}", { { 1, 9, 2, 8 }, { 3, 19, 4, 18 }, { 5, 17, 6, 16 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 15, 12, 14 }, { 13, 1, 14, 20 }, { 15, 7, 16, 6 }, { 17, 5, 18, 4 }, { 19, 13, 20, 12 } } },
{ "10_{64}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 14, 7, 13 }, { 8, 16, 9, 15 }, { 10, 1, 11, 2 }, { 12, 19, 13, 20 }, { 14, 8, 15, 7 }, { 16, 4, 17, 3 }, { 18, 6, 19, 5 }, { 20, 9, 1, 10 } } },
{ "10_{65}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 18, 12, 19 }, { 13, 20, 14, 1 }, { 15, 4, 16, 5 }, { 17, 6, 18, 7 }, { 19, 12, 20, 13 } } },
{ "10_{66}", { { 1, 11, 2, 10 }, { 3, 13, 4, 12 }, { 5, 19, 6, 18 }, { 7, 15, 8, 14 }, { 9, 5, 10, 4 }, { 11, 3, 12, 2 }, { 13, 17, 14, 16 }, { 15, 9, 16, 8 }, { 17, 1, 18, 20 }, { 19, 7, 20, 6 } } },
{ "10_{67}", { { 1, 14, 2, 15 }, { 3, 19, 4, 18 }, { 5, 17, 6, 16 }, { 7, 11, 8, 10 }, { 9, 1, 10, 20 }, { 11, 7, 12, 6 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 5, 18, 4 }, { 19, 9, 20, 8 } } },
{ "10_{68}", { { 1, 11, 2, 10 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 18, 8, 19 }, { 9, 13, 10, 12 }, { 11, 3, 12, 2 }, { 13, 20, 14, 1 }, { 15, 4, 16, 5 }, { 17, 8, 18, 9 }, { 19, 6, 20, 7 } } },
{ "10_{69}", { { 2, 13, 3, 14 }, { 4, 17, 5, 18 }, { 6, 2, 7, 1 }, { 8, 19, 9, 20 }, { 10, 7, 11, 8 }, { 12, 3, 13, 4 }, { 14, 12, 15, 11 }, { 16, 5, 17, 6 }, { 18, 16, 19, 15 }, { 20, 9, 1, 10 } } },
{ "10_{70}", { { 2, 15, 3, 16 }, { 4, 11, 5, 12 }, { 6, 13, 7, 14 }, { 8, 20, 9, 19 }, { 10, 7, 11, 8 }, { 12, 5, 13, 6 }, { 14, 18, 15, 17 }, { 16, 1, 17, 2 }, { 18, 10, 19, 9 }, { 20, 4, 1, 3 } } },
{ "10_{71}", { { 1, 4, 2, 5 }, { 3, 8, 4, 9 }, { 11, 15, 12, 14 }, { 5, 13, 6, 12 }, { 13, 7, 14, 6 }, { 9, 19, 10, 18 }, { 15, 20, 16, 1 }, { 19, 16, 20, 17 }, { 17, 11, 18, 10 }, { 7, 2, 8, 3 } } },
{ "10_{72}", { { 2, 15, 3, 16 }, { 4, 12, 5, 11 }, { 6, 14, 7, 13 }, { 8, 18, 9, 17 }, { 10, 8, 11, 7 }, { 12, 6, 13, 5 }, { 14, 20, 15, 19 }, { 16, 1, 17, 2 }, { 18, 10, 19, 9 }, { 20, 4, 1, 3 } } },
{ "10_{73}", { { 2, 15, 3, 16 }, { 4, 7, 5, 8 }, { 6, 13, 7, 14 }, { 8, 12, 9, 11 }, { 10, 17, 11, 18 }, { 12, 5, 13, 6 }, { 14, 20, 15, 19 }, { 16, 1, 17, 2 }, { 18, 9, 19, 10 }, { 20, 4, 1, 3 } } },
{ "10_{74}", { { 1, 12, 2, 13 }, { 3, 15, 4, 14 }, { 5, 17, 6, 16 }, { 7, 1, 8, 20 }, { 9, 19, 10, 18 }, { 11, 2, 12, 3 }, { 13, 11, 14, 10 }, { 15, 7, 16, 6 }, { 17, 5, 18, 4 }, { 19, 9, 20, 8 } } },
{ "10_{75}", { { 1, 14, 2, 15 }, { 3, 17, 4, 16 }, { 5, 18, 6, 19 }, { 7, 5, 8, 4 }, { 9, 20, 10, 1 }, { 11, 9, 12, 8 }, { 13, 2, 14, 3 }, { 15, 13, 16, 12 }, { 17, 6, 18, 7 }, { 19, 10, 20, 11 } } },
{ "10_{76}", { { 2, 11, 3, 12 }, { 4, 18, 5, 17 }, { 6, 20, 7, 19 }, { 8, 14, 9, 13 }, { 10, 16, 11, 15 }, { 12, 1, 13, 2 }, { 14, 10, 15, 9 }, { 16, 8, 17, 7 }, { 18, 6, 19, 5 }, { 20, 4, 1, 3 } } },
{ "10_{77}", { { 1, 7, 2, 6 }, { 3, 14, 4, 15 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 18, 10, 19 }, { 11, 20, 12, 1 }, { 13, 16, 14, 17 }, { 15, 4, 16, 5 }, { 17, 12, 18, 13 }, { 19, 10, 20, 11 } } },
{ "10_{78}", { { 1, 7, 2, 6 }, { 3, 17, 4, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 13, 10, 12 }, { 11, 1, 12, 20 }, { 13, 18, 14, 19 }, { 15, 5, 16, 4 }, { 17, 14, 18, 15 }, { 19, 11, 20, 10 } } },
{ "10_{79}", { { 6, 2, 7, 1 }, { 8, 4, 9, 3 }, { 12, 6, 13, 5 }, { 18, 13, 19, 14 }, { 16, 9, 17, 10 }, { 10, 17, 11, 18 }, { 20, 15, 1, 16 }, { 14, 19, 15, 20 }, { 2, 8, 3, 7 }, { 4, 12, 5, 11 } } },
{ "10_{80}", { { 1, 17, 2, 16 }, { 3, 11, 4, 10 }, { 5, 19, 6, 18 }, { 7, 13, 8, 12 }, { 9, 5, 10, 4 }, { 11, 15, 12, 14 }, { 13, 9, 14, 8 }, { 15, 1, 16, 20 }, { 17, 3, 18, 2 }, { 19, 7, 20, 6 } } },
{ "10_{81}", { { 4, 2, 5, 1 }, { 8, 4, 9, 3 }, { 12, 6, 13, 5 }, { 16, 9, 17, 10 }, { 20, 17, 1, 18 }, { 18, 13, 19, 14 }, { 14, 19, 15, 20 }, { 10, 15, 11, 16 }, { 6, 12, 7, 11 }, { 2, 8, 3, 7 } } },
{ "10_{82}", { { 1, 12, 2, 13 }, { 3, 15, 4, 14 }, { 5, 19, 6, 18 }, { 7, 1, 8, 20 }, { 9, 2, 10, 3 }, { 11, 16, 12, 17 }, { 13, 9, 14, 8 }, { 15, 10, 16, 11 }, { 17, 5, 18, 4 }, { 19, 7, 20, 6 } } },
{ "10_{83}", { { 2, 7, 3, 8 }, { 4, 10, 5, 9 }, { 6, 1, 7, 2 }, { 8, 16, 9, 15 }, { 10, 17, 11, 18 }, { 12, 19, 13, 20 }, { 14, 6, 15, 5 }, { 16, 3, 17, 4 }, { 18, 13, 19, 14 }, { 20, 11, 1, 12 } } },
{ "10_{84}", { { 2, 10, 3, 9 }, { 4, 2, 5, 1 }, { 6, 13, 7, 14 }, { 8, 12, 9, 11 }, { 10, 4, 11, 3 }, { 12, 17, 13, 18 }, { 14, 20, 15, 19 }, { 16, 7, 17, 8 }, { 18, 6, 19, 5 }, { 20, 16, 1, 15 } } },
{ "10_{85}", { { 2, 7, 3, 8 }, { 4, 10, 5, 9 }, { 6, 1, 7, 2 }, { 8, 16, 9, 15 }, { 10, 17, 11, 18 }, { 12, 19, 13, 20 }, { 14, 6, 15, 5 }, { 16, 3, 17, 4 }, { 18, 11, 19, 12 }, { 20, 13, 1, 14 } } },
{ "10_{86}", { { 2, 7, 3, 8 }, { 4, 10, 5, 9 }, { 6, 1, 7, 2 }, { 8, 15, 9, 16 }, { 10, 18, 11, 17 }, { 12, 20, 13, 19 }, { 14, 4, 15, 3 }, { 16, 5, 17, 6 }, { 18, 14, 19, 13 }, { 20, 12, 1, 11 } } },
{ "10_{87}", { { 2, 11, 3, 12 }, { 4, 14, 5, 13 }, { 6, 1, 7, 2 }, { 8, 16, 9, 15 }, { 10, 8, 11, 7 }, { 12, 19, 13, 20 }, { 14, 18, 15, 17 }, { 16, 10, 17, 9 }, { 18, 4, 19, 3 }, { 20, 5, 1, 6 } } },
{ "10_{88}", { { 4, 2, 5, 1 }, { 20, 14, 1, 13 }, { 8, 3, 9, 4 }, { 2, 9, 3, 10 }, { 14, 7, 15, 8 }, { 18, 15, 19, 16 }, { 12, 6, 13, 5 }, { 10, 18, 11, 17 }, { 16, 12, 17, 11 }, { 6, 19, 7, 20 } } },
{ "10_{89}", { { 2, 7, 3, 8 }, { 4, 13, 5, 14 }, { 6, 12, 7, 11 }, { 8, 1, 9, 2 }, { 10, 15, 11, 16 }, { 12, 19, 13, 20 }, { 14, 18, 15, 17 }, { 16, 9, 17, 10 }, { 18, 5, 19, 6 }, { 20, 4, 1, 3 } } },
{ "10_{90}", { { 2, 9, 3, 10 }, { 4, 13, 5, 14 }, { 6, 20, 7, 19 }, { 8, 16, 9, 15 }, { 10, 3, 11, 4 }, { 12, 18, 13, 17 }, { 14, 1, 15, 2 }, { 16, 12, 17, 11 }, { 18, 8, 19, 7 }, { 20, 6, 1, 5 } } },
{ "10_{91}", { { 6, 2, 7, 1 }, { 20, 6, 1, 5 }, { 16, 9, 17, 10 }, { 10, 3, 11, 4 }, { 2, 18, 3, 17 }, { 14, 7, 15, 8 }, { 8, 15, 9, 16 }, { 12, 20, 13, 19 }, { 18, 12, 19, 11 }, { 4, 13, 5, 14 } } },
{ "10_{92}", { { 1, 9, 2, 8 }, { 3, 19, 4, 18 }, { 5, 12, 6, 13 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 11, 17, 12, 16 }, { 13, 4, 14, 5 }, { 15, 1, 16, 20 }, { 17, 7, 18, 6 }, { 19, 15, 20, 14 } } },
{ "10_{93}", { { 2, 17, 3, 18 }, { 4, 12, 5, 11 }, { 6, 20, 7, 19 }, { 8, 15, 9, 16 }, { 10, 6, 11, 5 }, { 12, 4, 13, 3 }, { 14, 7, 15, 8 }, { 16, 1, 17, 2 }, { 18, 13, 19, 14 }, { 20, 10, 1, 9 } } },
{ "10_{94}", { { 1, 9, 2, 8 }, { 3, 10, 4, 11 }, { 5, 14, 6, 15 }, { 7, 1, 8, 20 }, { 9, 17, 10, 16 }, { 11, 4, 12, 5 }, { 13, 19, 14, 18 }, { 15, 2, 16, 3 }, { 17, 13, 18, 12 }, { 19, 7, 20, 6 } } },
{ "10_{95}", { { 2, 16, 3, 15 }, { 4, 11, 5, 12 }, { 6, 17, 7, 18 }, { 8, 13, 9, 14 }, { 10, 19, 11, 20 }, { 12, 7, 13, 8 }, { 14, 2, 15, 1 }, { 16, 9, 17, 10 }, { 18, 5, 19, 6 }, { 20, 4, 1, 3 } } },
{ "10_{96}", { { 1, 16, 2, 17 }, { 3, 10, 4, 11 }, { 5, 1, 6, 20 }, { 7, 12, 8, 13 }, { 9, 4, 10, 5 }, { 11, 19, 12, 18 }, { 13, 6, 14, 7 }, { 15, 2, 16, 3 }, { 17, 15, 18, 14 }, { 19, 9, 20, 8 } } },
{ "10_{97}", { { 2, 12, 3, 11 }, { 4, 18, 5, 17 }, { 6, 13, 7, 14 }, { 8, 6, 9, 5 }, { 10, 20, 11, 19 }, { 12, 7, 13, 8 }, { 14, 2, 15, 1 }, { 16, 10, 17, 9 }, { 18, 4, 19, 3 }, { 20, 16, 1, 15 } } },
{ "10_{98}", { { 1, 10, 2, 11 }, { 3, 17, 4, 16 }, { 5, 13, 6, 12 }, { 7, 19, 8, 18 }, { 9, 15, 10, 14 }, { 11, 20, 12, 1 }, { 13, 7, 14, 6 }, { 15, 3, 16, 2 }, { 17, 9, 18, 8 }, { 19, 5, 20, 4 } } },
{ "10_{99}", { { 6, 2, 7, 1 }, { 10, 4, 11, 3 }, { 16, 11, 17, 12 }, { 14, 7, 15, 8 }, { 8, 15, 9, 16 }, { 20, 13, 1, 14 }, { 12, 19, 13, 20 }, { 18, 6, 19, 5 }, { 2, 10, 3, 9 }, { 4, 18, 5, 17 } } },
{ "10_{100}", { { 2, 9, 3, 10 }, { 4, 17, 5, 18 }, { 6, 12, 7, 11 }, { 8, 1, 9, 2 }, { 10, 16, 11, 15 }, { 12, 19, 13, 20 }, { 14, 8, 15, 7 }, { 16, 3, 17, 4 }, { 18, 5, 19, 6 }, { 20, 13, 1, 14 } } },
{ "10_{101}", { { 2, 12, 3, 11 }, { 4, 18, 5, 17 }, { 6, 14, 7, 13 }, { 8, 20, 9, 19 }, { 10, 6, 11, 5 }, { 12, 2, 13, 1 }, { 14, 10, 15, 9 }, { 16, 4, 17, 3 }, { 18, 16, 19, 15 }, { 20, 8, 1, 7 } } },
{ "10_{102}", { { 2, 9, 3, 10 }, { 4, 12, 5, 11 }, { 6, 18, 7, 17 }, { 8, 16, 9, 15 }, { 10, 19, 11, 20 }, { 12, 6, 13, 5 }, { 14, 1, 15, 2 }, { 16, 8, 17, 7 }, { 18, 4, 19, 3 }, { 20, 13, 1, 14 } } },
{ "10_{103}", { { 2, 9, 3, 10 }, { 4, 17, 5, 18 }, { 6, 12, 7, 11 }, { 8, 1, 9, 2 }, { 10, 16, 11, 15 }, { 12, 19, 13, 20 }, { 14, 8, 15, 7 }, { 16, 5, 17, 6 }, { 18, 3, 19, 4 }, { 20, 13, 1, 14 } } },
{ "10_{104}", { { 6, 2, 7, 1 }, { 16, 4, 17, 3 }, { 18, 9, 19, 10 }, { 14, 7, 15, 8 }, { 20, 13, 1, 14 }, { 8, 17, 9, 18 }, { 10, 19, 11, 20 }, { 12, 6, 13, 5 }, { 4, 12, 5, 11 }, { 2, 16, 3, 15 } } },
{ "10_{105}", { { 1, 11, 2, 10 }, { 3, 16, 4, 17 }, { 5, 1, 6, 20 }, { 7, 18, 8, 19 }, { 9, 13, 10, 12 }, { 11, 3, 12, 2 }, { 13, 7, 14, 6 }, { 15, 4, 16, 5 }, { 17, 8, 18, 9 }, { 19, 15, 20, 14 } } },
{ "10_{106}", { { 1, 15, 2, 14 }, { 3, 10, 4, 11 }, { 5, 17, 6, 16 }, { 7, 13, 8, 12 }, { 9, 2, 10, 3 }, { 11, 18, 12, 19 }, { 13, 1, 14, 20 }, { 15, 5, 16, 4 }, { 17, 7, 18, 6 }, { 19, 8, 20, 9 } } },
{ "10_{107}", { { 1, 11, 2, 10 }, { 3, 16, 4, 17 }, { 5, 1, 6, 20 }, { 7, 14, 8, 15 }, { 9, 13, 10, 12 }, { 11, 3, 12, 2 }, { 13, 18, 14, 19 }, { 15, 4, 16, 5 }, { 17, 8, 18, 9 }, { 19, 7, 20, 6 } } },
{ "10_{108}", { { 1, 15, 2, 14 }, { 3, 11, 4, 10 }, { 5, 12, 6, 13 }, { 7, 16, 8, 17 }, { 9, 3, 10, 2 }, { 11, 18, 12, 19 }, { 13, 1, 14, 20 }, { 15, 8, 16, 9 }, { 17, 6, 18, 7 }, { 19, 5, 20, 4 } } },
{ "10_{109}", { { 6, 2, 7, 1 }, { 10, 4, 11, 3 }, { 18, 11, 19, 12 }, { 16, 7, 17, 8 }, { 8, 17, 9, 18 }, { 20, 15, 1, 16 }, { 12, 19, 13, 20 }, { 14, 6, 15, 5 }, { 2, 10, 3, 9 }, { 4, 14, 5, 13 } } },
{ "10_{110}", { { 1, 14, 2, 15 }, { 3, 10, 4, 11 }, { 5, 1, 6, 20 }, { 7, 17, 8, 16 }, { 9, 4, 10, 5 }, { 11, 19, 12, 18 }, { 13, 2, 14, 3 }, { 15, 7, 16, 6 }, { 17, 13, 18, 12 }, { 19, 9, 20, 8 } } },
{ "10_{111}", { { 1, 9, 2, 8 }, { 3, 19, 4, 18 }, { 5, 11, 6, 10 }, { 7, 14, 8, 15 }, { 9, 3, 10, 2 }, { 11, 17, 12, 16 }, { 13, 1, 14, 20 }, { 15, 6, 16, 7 }, { 17, 5, 18, 4 }, { 19, 13, 20, 12 } } },
{ "10_{112}", { { 2, 10, 3, 9 }, { 4, 11, 5, 12 }, { 6, 19, 7, 20 }, { 8, 14, 9, 13 }, { 10, 15, 11, 16 }, { 12, 18, 13, 17 }, { 14, 1, 15, 2 }, { 16, 4, 17, 3 }, { 18, 5, 19, 6 }, { 20, 7, 1, 8 } } },
{ "10_{113}", { { 2, 8, 3, 7 }, { 4, 14, 5, 13 }, { 6, 11, 7, 12 }, { 8, 16, 9, 15 }, { 10, 2, 11, 1 }, { 12, 19, 13, 20 }, { 14, 18, 15, 17 }, { 16, 10, 17, 9 }, { 18, 4, 19, 3 }, { 20, 5, 1, 6 } } },
{ "10_{114}", { { 1, 8, 2, 9 }, { 3, 11, 4, 10 }, { 5, 14, 6, 15 }, { 7, 12, 8, 13 }, { 9, 17, 10, 16 }, { 11, 18, 12, 19 }, { 13, 6, 14, 7 }, { 15, 1, 16, 20 }, { 17, 2, 18, 3 }, { 19, 5, 20, 4 } } },
{ "10_{115}", { { 6, 2, 7, 1 }, { 14, 6, 15, 5 }, { 20, 15, 1, 16 }, { 16, 7, 17, 8 }, { 8, 19, 9, 20 }, { 18, 11, 19, 12 }, { 10, 4, 11, 3 }, { 4, 10, 5, 9 }, { 12, 17, 13, 18 }, { 2, 14, 3, 13 } } },
{ "10_{116}", { { 2, 16, 3, 15 }, { 4, 17, 5, 18 }, { 6, 12, 7, 11 }, { 8, 1, 9, 2 }, { 10, 4, 11, 3 }, { 12, 19, 13, 20 }, { 14, 8, 15, 7 }, { 16, 9, 17, 10 }, { 18, 5, 19, 6 }, { 20, 13, 1, 14 } } },
{ "10_{117}", { { 1, 14, 2, 15 }, { 3, 8, 4, 9 }, { 5, 18, 6, 19 }, { 7, 17, 8, 16 }, { 9, 20, 10, 1 }, { 11, 4, 12, 5 }, { 13, 7, 14, 6 }, { 15, 2, 16, 3 }, { 17, 13, 18, 12 }, { 19, 10, 20, 11 } } },
{ "10_{118}", { { 6, 2, 7, 1 }, { 18, 6, 19, 5 }, { 20, 13, 1, 14 }, { 12, 19, 13, 20 }, { 14, 7, 15, 8 }, { 8, 3, 9, 4 }, { 2, 16, 3, 15 }, { 10, 18, 11, 17 }, { 16, 10, 17, 9 }, { 4, 11, 5, 12 } } },
{ "10_{119}", { { 1, 16, 2, 17 }, { 3, 10, 4, 11 }, { 5, 1, 6, 20 }, { 7, 2, 8, 3 }, { 9, 14, 10, 15 }, { 11, 19, 12, 18 }, { 13, 4, 14, 5 }, { 15, 8, 16, 9 }, { 17, 7, 18, 6 }, { 19, 13, 20, 12 } } },
{ "10_{120}", { { 2, 10, 3, 9 }, { 4, 18, 5, 17 }, { 6, 12, 7, 11 }, { 8, 4, 9, 3 }, { 10, 16, 11, 15 }, { 12, 20, 13, 19 }, { 14, 8, 15, 7 }, { 16, 2, 17, 1 }, { 18, 14, 19, 13 }, { 20, 6, 1, 5 } } },
{ "10_{121}", { { 2, 11, 3, 12 }, { 4, 10, 5, 9 }, { 6, 2, 7, 1 }, { 8, 16, 9, 15 }, { 10, 17, 11, 18 }, { 12, 8, 13, 7 }, { 14, 20, 15, 19 }, { 16, 3, 17, 4 }, { 18, 6, 19, 5 }, { 20, 14, 1, 13 } } },
{ "10_{122}", { { 1, 8, 2, 9 }, { 3, 11, 4, 10 }, { 5, 12, 6, 13 }, { 7, 16, 8, 17 }, { 9, 15, 10, 14 }, { 11, 18, 12, 19 }, { 13, 1, 14, 20 }, { 15, 2, 16, 3 }, { 17, 6, 18, 7 }, { 19, 5, 20, 4 } } },
{ "10_{123}", { { 8, 2, 9, 1 }, { 10, 3, 11, 4 }, { 12, 6, 13, 5 }, { 4, 18, 5, 17 }, { 18, 11, 19, 12 }, { 2, 15, 3, 16 }, { 16, 10, 17, 9 }, { 20, 14, 1, 13 }, { 14, 7, 15, 8 }, { 6, 19, 7, 20 } } },
{ "10_{124}", { { 1, 9, 2, 8 }, { 3, 11, 4, 10 }, { 5, 13, 6, 12 }, { 7, 19, 8, 18 }, { 9, 3, 10, 2 }, { 11, 5, 12, 4 }, { 14, 20, 15, 19 }, { 16, 14, 17, 13 }, { 17, 7, 18, 6 }, { 20, 16, 1, 15 } } },
{ "10_{125}", { { 1, 4, 2, 5 }, { 3, 8, 4, 9 }, { 5, 14, 6, 15 }, { 20, 16, 1, 15 }, { 16, 10, 17, 9 }, { 18, 12, 19, 11 }, { 10, 18, 11, 17 }, { 12, 20, 13, 19 }, { 13, 6, 14, 7 }, { 7, 2, 8, 3 } } },
{ "10_{126}", { { 1, 7, 2, 6 }, { 4, 15, 5, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 10, 17, 11, 18 }, { 12, 19, 13, 20 }, { 14, 9, 15, 10 }, { 16, 3, 17, 4 }, { 18, 11, 19, 12 }, { 20, 13, 1, 14 } } },
{ "10_{127}", { { 1, 7, 2, 6 }, { 4, 15, 5, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 15, 10, 14 }, { 11, 19, 12, 18 }, { 13, 1, 14, 20 }, { 16, 3, 17, 4 }, { 17, 11, 18, 10 }, { 19, 13, 20, 12 } } },
{ "10_{128}", { { 1, 9, 2, 8 }, { 3, 11, 4, 10 }, { 5, 13, 6, 12 }, { 7, 19, 8, 18 }, { 9, 5, 10, 4 }, { 11, 3, 12, 2 }, { 14, 20, 15, 19 }, { 16, 14, 17, 13 }, { 17, 7, 18, 6 }, { 20, 16, 1, 15 } } },
{ "10_{129}", { { 1, 7, 2, 6 }, { 3, 17, 4, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 10, 19, 11, 20 }, { 12, 17, 13, 18 }, { 14, 9, 15, 10 }, { 15, 5, 16, 4 }, { 18, 11, 19, 12 }, { 20, 13, 1, 14 } } },
{ "10_{130}", { { 1, 7, 2, 6 }, { 4, 15, 5, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 10, 19, 11, 20 }, { 12, 17, 13, 18 }, { 14, 9, 15, 10 }, { 16, 3, 17, 4 }, { 18, 11, 19, 12 }, { 20, 13, 1, 14 } } },
{ "10_{131}", { { 1, 7, 2, 6 }, { 4, 15, 5, 16 }, { 5, 9, 6, 8 }, { 7, 3, 8, 2 }, { 9, 15, 10, 14 }, { 11, 19, 12, 18 }, { 13, 1, 14, 20 }, { 16, 3, 17, 4 }, { 17, 13, 18, 12 }, { 19, 11, 20, 10 } } },
{ "10_{132}", { { 1, 8, 2, 9 }, { 3, 18, 4, 19 }, { 5, 12, 6, 13 }, { 7, 10, 8, 11 }, { 9, 2, 10, 3 }, { 11, 6, 12, 7 }, { 14, 20, 15, 19 }, { 16, 14, 17, 13 }, { 17, 4, 18, 5 }, { 20, 16, 1, 15 } } },
{ "10_{133}", { { 2, 16, 3, 15 }, { 4, 2, 5, 1 }, { 7, 13, 8, 12 }, { 9, 7, 10, 6 }, { 11, 18, 12, 19 }, { 13, 9, 14, 8 }, { 14, 20, 15, 19 }, { 16, 4, 17, 3 }, { 17, 10, 18, 11 }, { 20, 6, 1, 5 } } },
{ "10_{134}", { { 2, 16, 3, 15 }, { 4, 2, 5, 1 }, { 7, 13, 8, 12 }, { 9, 7, 10, 6 }, { 10, 18, 11, 17 }, { 13, 9, 14, 8 }, { 14, 20, 15, 19 }, { 16, 4, 17, 3 }, { 18, 12, 19, 11 }, { 20, 6, 1, 5 } } },
{ "10_{135}", { { 1, 4, 2, 5 }, { 3, 16, 4, 17 }, { 5, 20, 6, 1 }, { 7, 13, 8, 12 }, { 9, 7, 10, 6 }, { 10, 18, 11, 17 }, { 13, 9, 14, 8 }, { 15, 2, 16, 3 }, { 18, 12, 19, 11 }, { 19, 14, 20, 15 } } },
{ "10_{136}", { { 2, 17, 3, 18 }, { 4, 2, 5, 1 }, { 7, 14, 8, 15 }, { 9, 7, 10, 6 }, { 12, 19, 13, 20 }, { 13, 8, 14, 9 }, { 15, 11, 16, 10 }, { 16, 3, 17, 4 }, { 18, 11, 19, 12 }, { 20, 6, 1, 5 } } },
{ "10_{137}", { { 1, 15, 2, 14 }, { 4, 8, 5, 7 }, { 6, 19, 7, 20 }, { 9, 17, 10, 16 }, { 11, 8, 12, 9 }, { 13, 3, 14, 2 }, { 15, 11, 16, 10 }, { 17, 12, 18, 13 }, { 18, 4, 19, 3 }, { 20, 5, 1, 6 } } },
{ "10_{138}", { { 1, 15, 2, 14 }, { 4, 8, 5, 7 }, { 6, 19, 7, 20 }, { 8, 12, 9, 11 }, { 10, 15, 11, 16 }, { 12, 18, 13, 17 }, { 13, 3, 14, 2 }, { 16, 9, 17, 10 }, { 18, 4, 19, 3 }, { 20, 5, 1, 6 } } },
{ "10_{139}", { { 1, 11, 2, 10 }, { 4, 18, 5, 17 }, { 5, 13, 6, 12 }, { 7, 15, 8, 14 }, { 9, 1, 10, 20 }, { 11, 3, 12, 2 }, { 13, 7, 14, 6 }, { 16, 4, 17, 3 }, { 18, 16, 19, 15 }, { 19, 9, 20, 8 } } },
{ "10_{140}", { { 1, 15, 2, 14 }, { 3, 10, 4, 11 }, { 5, 12, 6, 13 }, { 6, 18, 7, 17 }, { 8, 16, 9, 15 }, { 11, 4, 12, 5 }, { 13, 1, 14, 20 }, { 16, 8, 17, 7 }, { 18, 10, 19, 9 }, { 19, 3, 20, 2 } } },
{ "10_{141}", { { 2, 11, 3, 12 }, { 4, 9, 5, 10 }, { 5, 19, 6, 18 }, { 7, 15, 8, 14 }, { 10, 1, 11, 2 }, { 12, 3, 13, 4 }, { 13, 17, 14, 16 }, { 15, 9, 16, 8 }, { 17, 1, 18, 20 }, { 19, 7, 20, 6 } } },
{ "10_{142}", { { 1, 15, 2, 14 }, { 4, 12, 5, 11 }, { 6, 18, 7, 17 }, { 8, 16, 9, 15 }, { 10, 4, 11, 3 }, { 12, 6, 13, 5 }, { 13, 1, 14, 20 }, { 16, 8, 17, 7 }, { 18, 10, 19, 9 }, { 19, 3, 20, 2 } } },
{ "10_{143}", { { 2, 11, 3, 12 }, { 4, 9, 5, 10 }, { 6, 19, 7, 20 }, { 7, 15, 8, 14 }, { 10, 1, 11, 2 }, { 12, 3, 13, 4 }, { 13, 17, 14, 16 }, { 15, 9, 16, 8 }, { 18, 5, 19, 6 }, { 20, 17, 1, 18 } } },
{ "10_{144}", { { 1, 9, 2, 8 }, { 3, 16, 4, 17 }, { 5, 14, 6, 15 }, { 7, 11, 8, 10 }, { 9, 3, 10, 2 }, { 12, 20, 13, 19 }, { 15, 4, 16, 5 }, { 17, 6, 18, 7 }, { 18, 12, 19, 11 }, { 20, 14, 1, 13 } } },
{ "10_{145}", { { 1, 14, 2, 15 }, { 3, 18, 4, 19 }, { 6, 13, 7, 14 }, { 8, 6, 9, 5 }, { 9, 16, 10, 17 }, { 11, 2, 12, 3 }, { 12, 7, 13, 8 }, { 15, 20, 16, 1 }, { 17, 4, 18, 5 }, { 19, 10, 20, 11 } } },
{ "10_{146}", { { 1, 14, 2, 15 }, { 4, 10, 5, 9 }, { 6, 14, 7, 13 }, { 8, 17, 9, 18 }, { 10, 4, 11, 3 }, { 12, 8, 13, 7 }, { 15, 20, 16, 1 }, { 16, 11, 17, 12 }, { 18, 5, 19, 6 }, { 19, 3, 20, 2 } } },
{ "10_{147}", { { 2, 8, 3, 7 }, { 3, 18, 4, 19 }, { 6, 11, 7, 12 }, { 8, 16, 9, 15 }, { 10, 2, 11, 1 }, { 13, 4, 14, 5 }, { 14, 18, 15, 17 }, { 16, 10, 17, 9 }, { 19, 13, 20, 12 }, { 20, 5, 1, 6 } } },
{ "10_{148}", { { 2, 17, 3, 18 }, { 4, 9, 5, 10 }, { 6, 19, 7, 20 }, { 7, 13, 8, 12 }, { 10, 3, 11, 4 }, { 11, 15, 12, 14 }, { 13, 9, 14, 8 }, { 16, 1, 17, 2 }, { 18, 5, 19, 6 }, { 20, 15, 1, 16 } } },
{ "10_{149}", { { 1, 17, 2, 16 }, { 4, 9, 5, 10 }, { 5, 19, 6, 18 }, { 7, 13, 8, 12 }, { 10, 3, 11, 4 }, { 11, 15, 12, 14 }, { 13, 9, 14, 8 }, { 15, 1, 16, 20 }, { 17, 3, 18, 2 }, { 19, 7, 20, 6 } } },
{ "10_{150}", { { 1, 17, 2, 16 }, { 3, 7, 4, 6 }, { 5, 1, 6, 20 }, { 8, 14, 9, 13 }, { 10, 8, 11, 7 }, { 11, 18, 12, 19 }, { 14, 10, 15, 9 }, { 15, 3, 16, 2 }, { 17, 12, 18, 13 }, { 19, 5, 20, 4 } } },
{ "10_{151}", { { 2, 15, 3, 16 }, { 4, 19, 5, 20 }, { 6, 3, 7, 4 }, { 8, 14, 9, 13 }, { 10, 8, 11, 7 }, { 11, 18, 12, 19 }, { 14, 10, 15, 9 }, { 16, 1, 17, 2 }, { 17, 12, 18, 13 }, { 20, 5, 1, 6 } } },
{ "10_{152}", { { 1, 7, 2, 6 }, { 3, 9, 4, 8 }, { 5, 19, 6, 18 }, { 7, 3, 8, 2 }, { 10, 16, 11, 15 }, { 12, 20, 13, 19 }, { 14, 10, 15, 9 }, { 16, 12, 17, 11 }, { 17, 5, 18, 4 }, { 20, 14, 1, 13 } } },
{ "10_{153}", { { 2, 17, 3, 18 }, { 3, 11, 4, 10 }, { 6, 19, 7, 20 }, { 7, 13, 8, 12 }, { 9, 5, 10, 4 }, { 11, 15, 12, 14 }, { 13, 9, 14, 8 }, { 16, 1, 17, 2 }, { 18, 5, 19, 6 }, { 20, 15, 1, 16 } } },
{ "10_{154}", { { 1, 17, 2, 16 }, { 3, 7, 4, 6 }, { 5, 1, 6, 20 }, { 8, 14, 9, 13 }, { 10, 8, 11, 7 }, { 12, 18, 13, 17 }, { 14, 10, 15, 9 }, { 15, 3, 16, 2 }, { 18, 12, 19, 11 }, { 19, 5, 20, 4 } } },
{ "10_{155}", { { 1, 11, 2, 10 }, { 3, 13, 4, 12 }, { 5, 14, 6, 15 }, { 6, 19, 7, 20 }, { 9, 16, 10, 17 }, { 11, 3, 12, 2 }, { 13, 19, 14, 18 }, { 15, 8, 16, 9 }, { 17, 4, 18, 5 }, { 20, 7, 1, 8 } } },
{ "10_{156}", { { 1, 13, 2, 12 }, { 3, 8, 4, 9 }, { 5, 14, 6, 15 }, { 7, 18, 8, 19 }, { 10, 15, 11, 16 }, { 11, 1, 12, 20 }, { 13, 6, 14, 7 }, { 16, 9, 17, 10 }, { 17, 4, 18, 5 }, { 19, 3, 20, 2 } } },
{ "10_{157}", { { 2, 8, 3, 7 }, { 3, 10, 4, 11 }, { 5, 18, 6, 19 }, { 8, 15, 9, 16 }, { 11, 4, 12, 5 }, { 14, 1, 15, 2 }, { 16, 9, 17, 10 }, { 17, 13, 18, 12 }, { 19, 6, 20, 7 }, { 20, 13, 1, 14 } } },
{ "10_{158}", { { 3, 9, 4, 8 }, { 4, 11, 5, 12 }, { 6, 20, 7, 19 }, { 9, 17, 10, 16 }, { 12, 5, 13, 6 }, { 14, 1, 15, 2 }, { 15, 11, 16, 10 }, { 17, 3, 18, 2 }, { 18, 8, 19, 7 }, { 20, 13, 1, 14 } } },
{ "10_{159}", { { 2, 10, 3, 9 }, { 4, 11, 5, 12 }, { 5, 19, 6, 18 }, { 7, 1, 8, 20 }, { 8, 14, 9, 13 }, { 10, 15, 11, 16 }, { 12, 18, 13, 17 }, { 14, 1, 15, 2 }, { 16, 4, 17, 3 }, { 19, 7, 20, 6 } } },
{ "10_{160}", { { 1, 13, 2, 12 }, { 4, 18, 5, 17 }, { 6, 14, 7, 13 }, { 8, 4, 9, 3 }, { 10, 15, 11, 16 }, { 11, 1, 12, 20 }, { 14, 6, 15, 5 }, { 16, 9, 17, 10 }, { 18, 8, 19, 7 }, { 19, 3, 20, 2 } } },
{ "10_{161}", { { 1, 13, 2, 12 }, { 4, 18, 5, 17 }, { 6, 14, 7, 13 }, { 8, 4, 9, 3 }, { 9, 17, 10, 16 }, { 11, 1, 12, 20 }, { 14, 6, 15, 5 }, { 15, 11, 16, 10 }, { 18, 8, 19, 7 }, { 19, 3, 20, 2 } } },
{ "10_{162}", { { 2, 9, 3, 10 }, { 5, 12, 6, 13 }, { 6, 18, 7, 17 }, { 8, 16, 9, 15 }, { 10, 19, 11, 20 }, { 11, 4, 12, 5 }, { 14, 1, 15, 2 }, { 16, 8, 17, 7 }, { 18, 4, 19, 3 }, { 20, 13, 1, 14 } } },
{ "10_{163}", { { 1, 8, 2, 9 }, { 3, 11, 4, 10 }, { 6, 14, 7, 13 }, { 9, 17, 10, 16 }, { 11, 18, 12, 19 }, { 12, 8, 13, 7 }, { 14, 6, 15, 5 }, { 15, 1, 16, 20 }, { 17, 2, 18, 3 }, { 19, 5, 20, 4 } } },
{ "10_{164}", { { 2, 12, 3, 11 }, { 3, 16, 4, 17 }, { 6, 14, 7, 13 }, { 8, 15, 9, 16 }, { 9, 5, 10, 4 }, { 12, 2, 13, 1 }, { 14, 19, 15, 20 }, { 17, 10, 18, 11 }, { 18, 5, 19, 6 }, { 20, 8, 1, 7 } } },
{ "10_{165}", { { 1, 8, 2, 9 }, { 3, 12, 4, 13 }, { 4, 17, 5, 18 }, { 7, 2, 8, 3 }, { 9, 14, 10, 15 }, { 11, 17, 12, 16 }, { 13, 6, 14, 7 }, { 15, 20, 16, 1 }, { 18, 5, 19, 6 }, { 19, 11, 20, 10 } } }
};
unsigned
rolfsen_crossing_knots (unsigned n)
{
assert (n <= 10);
switch (n)
{
case 0: // ??? really?
case 1:
case 2:
return 0;
case 3:
return sizeof rolfsen3 / sizeof rolfsen3[0];
case 4:
return sizeof rolfsen4 / sizeof rolfsen4[0];
case 5:
return sizeof rolfsen5 / sizeof rolfsen5[0];
case 6:
return sizeof rolfsen6 / sizeof rolfsen6[0];
case 7:
return sizeof rolfsen7 / sizeof rolfsen7[0];
case 8:
return sizeof rolfsen8 / sizeof rolfsen8[0];
case 9:
return sizeof rolfsen9 / sizeof rolfsen9[0];
case 10:
return sizeof rolfsen10 / sizeof rolfsen10[0];
default: abort ();
}
}
planar_diagram
rolfsen_knot (unsigned n, unsigned k)
{
assert (n <= 10);
assert (k >= 1);
assert (k <= rolfsen_crossing_knots (n));
k --;
switch (n)
{
case 3:
return planar_diagram (rolfsen3[k].name, 3, rolfsen3[k].crossing_ar);
case 4:
return planar_diagram (rolfsen4[k].name, 4, rolfsen4[k].crossing_ar);
case 5:
return planar_diagram (rolfsen5[k].name, 5, rolfsen5[k].crossing_ar);
case 6:
return planar_diagram (rolfsen6[k].name, 6, rolfsen6[k].crossing_ar);
case 7:
return planar_diagram (rolfsen7[k].name, 7, rolfsen7[k].crossing_ar);
case 8:
return planar_diagram (rolfsen8[k].name, 8, rolfsen8[k].crossing_ar);
case 9:
return planar_diagram (rolfsen9[k].name, 9, rolfsen9[k].crossing_ar);
case 10:
return planar_diagram (rolfsen10[k].name, 10, rolfsen10[k].crossing_ar);
default: abort ();
}
}
unsigned htw_alternating[16] = {
0, 0, 1, 1, 2, 3, 7, 18, 41, 123, 367, 1288, 4878, 19536, 85263, 379799
};
unsigned htw_nonalternating[16] = {
0, 0, 0, 0, 0, 0, 0, 3, 8, 42, 185, 888, 5110, 27436, 168030, 1008906
};
unsigned
htw_knots (unsigned n, bool alternating)
{
assert (between (1, n, 16));
if (alternating)
return htw_alternating[n - 1];
else
return htw_nonalternating[n - 1];
}
unsigned
htw_knots (unsigned n)
{
assert (between (1, n, 16));
return htw_alternating[n - 1] + htw_nonalternating[n - 1];
}
dt_code
htw_knot (unsigned n, bool alternating, unsigned k)
{
assert (between (1, n, 16));
assert (between (1, k, htw_knots (n, alternating)));
const char *file;
long off;
if (alternating)
{
unsigned before = 0;
for (unsigned i = 0; i < n - 1; i ++)
before += htw_alternating[i];
off = 8 * (before + k - 1);
file = HOME "alternating";
}
else
{
unsigned before = 0;
for (unsigned i = 0; i < n - 1; i ++)
before += htw_nonalternating[i];
off = 10 * (before + k - 1);
file = HOME "nonalternating";
}
FILE *fp = fopen (file, "r");
if (fp == 0)
{
stderror ("fopen: %s", file);
exit (EXIT_FAILURE);
}
if (fseek (fp, off, SEEK_SET) != 0)
{
stderror ("fseek");
exit (EXIT_FAILURE);
}
unsigned char buf[10];
size_t count = (n + 1) / 2;
if (!alternating)
count += 2;
if (fread (buf, 1, count, fp) != count)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
fclose (fp);
fp = 0;
int even_labels_ar[16];
for (unsigned i = 0; i < n; i ++)
{
unsigned j = buf[i / 2];
j = is_even (i)
? j >> 4
: j & 0xf;
if (j == 0)
j = 16;
j *= 2;
even_labels_ar[i] = j;
}
if (!alternating)
{
unsigned signs = buf[count - 2] << 8 | buf[count - 1];
for (unsigned i = 0; i < n; i ++)
{
if (!unsigned_bittest (signs, 16 - i))
even_labels_ar[i] *= -1;
}
}
char buf2[100];
sprintf (buf2, "%d%c%d", n, alternating ? 'a' : 'n', k);
return dt_code (std::string (buf2), n, even_labels_ar);
}
dt_code
htw_knot (unsigned n, unsigned k)
{
assert (between (1, n, 16));
assert (k >= 1);
unsigned na = htw_knots (n, 1);
if (k <= na)
return htw_knot (n, 1, k);
else
return htw_knot (n, 0, k - na);
}
unsigned mt_alternating[14] = {
0, 0, 0, 1, 3, 8, 14, 39, 96, 297, 915, 3308, 12417, 51347,
};
unsigned mt_nonalternating[14] = {
0, 0, 0, 0, 0, 1, 2, 11, 36, 155, 644, 3144, 16454, 91616,
};
unsigned
mt_links (unsigned n, bool alternating)
{
assert (between (1, n, 14));
if (alternating)
return mt_alternating[n - 1];
else
return mt_nonalternating[n - 1];
}
dt_code
mt_link (unsigned n, bool alternating, unsigned k)
{
assert (between (1, n, 14));
assert (between (1, k, mt_links (n, alternating)));
char buf[1000];
sprintf (buf, HOME "mtlinks/hyperbolic_data_%02d%c", n, alternating ? 'a' : 'n');
FILE *fp = fopen (buf, "r");
if (fp == 0)
{
stderror ("fopen: %s", buf);
exit (EXIT_FAILURE);
}
char *p;
for (unsigned i = 1; i <= k; i ++)
{
if (fgets (buf, 1000, fp) == 0)
{
stderror ("fgets: %s", buf);
exit (EXIT_FAILURE);
}
assert (alpha_to_int (buf[0]) == (int)n);
}
fclose (fp);
char buf2[1000];
sprintf (buf2, "L%d%c%d", n, alternating ? 'a' : 'n', k);
return dt_code (buf2, buf);
}
planar_diagram
torus_knot (unsigned n_strands, unsigned n_shifts)
{
basedvector<basedvector<int, 1>, 1> crossings ((n_strands - 1) * n_shifts);
for (unsigned i = 1; i <= crossings.size (); i ++)
crossings[i].resize (4);
basedvector<unsigned, 1> start_strands (n_strands),
strands (n_strands),
new_strands (n_strands);
unsigned n_crossings = 0;
unsigned n_edges = 0;
for (unsigned i = 1; i <= n_strands; i ++)
strands[i] = start_strands[i] = ++ n_edges;
for (unsigned i = 1; i <= n_shifts; i ++)
{
if (i == n_shifts)
new_strands = start_strands;
else
{
for (unsigned j = 1; j <= n_strands; j ++)
new_strands[j] = ++ n_edges;
}
unsigned p = strands[1];
for (unsigned j = 1; j < n_strands; j ++)
{
unsigned c = ++ n_crossings;
unsigned newp;
if (j == n_strands - 1)
newp = new_strands[n_strands];
else
newp = ++ n_edges;
crossings[c][1] = strands[j + 1];
crossings[c][2] = newp;
crossings[c][3] = new_strands[j];
crossings[c][4] = p;
p = newp;
}
basedvector<unsigned, 1> tmp = new_strands;
new_strands = strands;
strands = tmp;
}
assert (n_crossings == crossings.size ());
assert (n_edges == n_crossings * 2);
char buf[1000];
sprintf (buf, "T(%d,%d)", n_strands, n_shifts);
return planar_diagram (std::string (buf), crossings);
}
planar_diagram
braid (unsigned n_strands, unsigned n_twists, int twists_ar[])
{
basedvector<int, 1> twists (n_twists);
for (unsigned i = 1; i <= n_twists; i ++)
twists[i] = twists_ar[i - 1];
return braid (n_strands, twists);
}
planar_diagram
braid (unsigned n_strands, const basedvector<int, 1> &twists)
{
unsigned n_crossings = twists.size ();
unsigned e = 0;
basedvector<unsigned, 1> final_strands (n_strands);
basedvector<unsigned, 1> strands (n_strands);
for (unsigned i = 1; i <= n_strands; i ++)
{
++ e;
final_strands[i] = strands[i] = e;
}
basedvector<unsigned, 1> last_twist (n_strands);
for (unsigned i = 1; i <= n_strands; i ++)
last_twist[i] = 0;
for (unsigned i = 1; i <= twists.size (); i ++)
{
unsigned t = std::abs (twists[i]);
last_twist[t] = i;
last_twist[t + 1] = i;
}
#ifndef NDEBUG
for (unsigned i = 1; i <= n_strands; i ++)
assert (last_twist[i] != 0);
#endif
basedvector<basedvector<int, 1>, 1> crossings (n_crossings);
for (unsigned i = 1; i <= n_crossings; i ++)
crossings[i] = basedvector<int, 1> (4);
for (unsigned i = 1; i <= twists.size (); i ++)
{
unsigned t = std::abs (twists[i]);
unsigned e1 = strands[t],
e4 = strands[t + 1];
unsigned e2, e3;
if (last_twist[t] == i)
{
assert (final_strands[t] != 0);
e2 = final_strands[t];
strands[t] = final_strands[t] = 0;
}
else
{
e ++;
e2 = e;
strands[t] = e;
}
if (last_twist[t + 1] == i)
{
assert (final_strands[t + 1] != 0);
e3 = final_strands[t + 1];
strands[t + 1] = final_strands[t + 1] = 0;
}
else
{
e ++;
e3 = e;
strands[t + 1] = e;
}
if (twists[i] > 0)
{
crossings[i][1] = e1;
crossings[i][2] = e2;
crossings[i][3] = e3;
crossings[i][4] = e4;
}
else
{
crossings[i][1] = e2;
crossings[i][2] = e3;
crossings[i][3] = e4;
crossings[i][4] = e1;
}
}
assert (e == n_crossings * 2);
#ifndef NDEBUG
for (unsigned i = 1; i <= n_strands; i ++)
assert (final_strands[i] == 0);
#endif
return planar_diagram ("abraid", crossings);
}
basedvector<basedvector<unsigned, 1>, 1>
mutant_knot_groups (unsigned n)
{
assert (11 <= n && n <= 15);
char buf[1000];
sprintf (buf, HOME "mutant_knot_groups/dat%d", n);
FILE *fp = fopen (buf, "r");
if (fp == 0)
{
stderror ("fopen: %s", buf);
exit (EXIT_FAILURE);
}
basedvector<basedvector<unsigned, 1>, 1> r;
while (fgets (buf, sizeof buf, fp) != 0)
{
const char *p = buf;
basedvector<unsigned, 1> g;
unsigned i;
int k;
while (sscanf (p, "%d%n", &i, &k) == 1)
{
g.append (i);
p += k;
}
assert (*p == '\n');
assert (g.size () > 0);
r.append (g);
}
return r;
}

45
knotkit.h Normal file
View File

@ -0,0 +1,45 @@
// includes lib.h
#include <algebra/algebra.h>
extern bool verbose;
static const unsigned max_edges = 58;
static const unsigned max_crossings = 29;
static const unsigned max_circles = 58;
class knot_diagram;
#include <planar_diagram.h>
#include <dt_code.h>
#include <knot_diagram.h>
#include <sseq.h>
#include <smoothing.h>
#include <cobordism.h>
#include <cube.h>
#include <spanning_tree_complex.h>
unsigned rolfsen_crossing_knots (unsigned n);
planar_diagram rolfsen_knot (unsigned n, unsigned k);
unsigned htw_knots (unsigned n, bool alternating);
unsigned htw_knots (unsigned n);
dt_code htw_knot (unsigned n, bool alternating, unsigned k);
dt_code htw_knot (unsigned n, unsigned k);
unsigned mt_links (unsigned n, bool alternating);
dt_code mt_link (unsigned n, bool alternating, unsigned k);
planar_diagram torus_knot (unsigned n_strands, unsigned n_shifts);
planar_diagram braid (unsigned n_strands, const basedvector<int, 1> &twists);
planar_diagram braid (unsigned n_strands, unsigned n_twists, int twists_ar[]);
knot_diagram parse_knot (const char *s);
resolution_diagram parse_resolution_diagram (const char *s);
// 11 <= n <= 15
basedvector<basedvector<unsigned, 1>, 1> mutant_knot_groups (unsigned n);

107
lib/bitset.cpp Normal file
View File

@ -0,0 +1,107 @@
#include <lib/lib.h>
bool
bitset::is_empty () const
{
unsigned nw = v.size ();
for (unsigned i = 0; i < nw; i ++)
{
if (v[i] != 0)
return 0;
}
return 1;
}
unsigned
bitset::card () const
{
unsigned c = 0;
unsigned nw = v.size ();
for (unsigned i = 0; i < nw; i ++)
c += word_bitcount (v[i]);
assert (c <= n);
return c;
}
unsigned
bitset::head () const
{
bitset_const_iter i = *this;
assert (i);
return i.val ();
}
unsigned
bitset::pop ()
{
unsigned i = head ();
operator -= (i);
return i;
}
bitset &
bitset::operator |= (const bitset &bs)
{
assert (n == bs.n);
assert (v.size () == bs.v.size ());
int nw = v.size ();
for (int i = 0; i < nw; i ++)
v[i] |= bs.v[i];
return *this;
}
bitset &
bitset::operator &= (const bitset &bs)
{
assert (n == bs.n);
assert (v.size () == bs.v.size ());
int nw = v.size ();
for (int i = 0; i < nw; i ++)
v[i] &= bs.v[i];
return *this;
}
bitset &
bitset::operator ^= (const bitset &bs)
{
assert (n == bs.n);
assert (v.size () == bs.v.size ());
int nw = v.size ();
for (int i = 0; i < nw; i ++)
v[i] ^= bs.v[i];
return *this;
}
bool
bitset::operator == (const bitset &bs) const
{
assert (n == bs.n);
assert (v.size () == bs.v.size ());
int nw = v.size ();
for (int i = 0; i < nw; i ++)
{
if (v[i] != bs.v[i])
return 0;
}
return 1;
}
void
bitset_const_iter::find_next ()
{
unsigned wn = v.size ();
while (!w)
{
wi ++;
if (wi < wn)
w = v[wi];
else
break;
}
if (wi < wn)
b = word_ffs (w);
}

138
lib/bitset.h Normal file
View File

@ -0,0 +1,138 @@
typedef uint64 word_t;
static const unsigned word_bits = uint64_bits;
static const unsigned word_bit_mask = uint64_bit_mask;
inline unsigned word_bitcount (word_t x) { return uint64_bitcount (x); }
inline unsigned word_ffs (word_t x) { return uint64_ffs (x); }
inline word_t word_bitset (word_t x, unsigned i) { return uint64_bitset (x, i); }
inline word_t word_bitclear (word_t x, unsigned i) { return uint64_bitclear (x, i); }
inline bool word_bittest (word_t x, unsigned i) { return uint64_bittest (x, i); }
class bitset_iter;
class bitset_const_iter;
class bitset
{
private:
friend class bitset_iter;
friend class bitset_const_iter;
friend class smallbitset;
unsigned n;
vector<word_t> v;
public:
typedef bitset_iter iter;
typedef bitset_const_iter const_iter;
public:
bitset () : n(0) { }
inline bitset (unsigned n_);
bitset (const bitset &bs) : n(bs.n), v(bs.v) { }
bitset (copy, const bitset &bs) : n(bs.n), v(COPY, bs.v) { }
// explicit bitset (const unsignedset &t);
explicit bitset (const ullmanset<1> &t);
~bitset () { }
bitset &operator = (const bitset &bs) { n = bs.n; v = bs.v; return *this; }
// bitset &operator = (const unsignedset &t);
bitset &operator = (const ullmanset<1> &t);
bool is_empty () const;
unsigned card () const;
unsigned size () const { return n; }
unsigned head () const;
unsigned pop ();
void push (unsigned i) { assert (! (*this % i)); operator += (i); }
void yank (unsigned i) { assert (*this % i); operator -= (i); }
inline void operator += (unsigned i);
inline void operator -= (unsigned i);
bitset &operator |= (const bitset &bs);
bitset &operator &= (const bitset &bs);
bitset &operator ^= (const bitset &bs);
bool operator == (const bitset &bs) const;
bool operator != (const bitset &bs) const { return !operator == (bs); }
inline bool operator % (unsigned i) const;
inline bool operator () (unsigned i) const { return operator % (i); }
};
class bitset_const_iter
{
private:
const vector<word_t> &v;
unsigned wi;
word_t w;
unsigned b;
void find_next ();
void advance ()
{
assert (wi < v.size ());
assert (word_bittest (w, b));
w = word_bitclear (w, b);
find_next ();
}
public:
bitset_const_iter (const bitset &bs) : v(bs.v), wi(0), w(v[0]) { find_next (); }
~bitset_const_iter () { }
int val () const { assert (wi < v.size ()); return wi * word_bits + b; }
bitset_const_iter &operator ++ () { advance (); return *this; }
void operator ++ (int) { advance (); }
operator bool () const { return wi < v.size (); }
};
bitset::bitset (unsigned n_)
: n(n_),
v((n_ + word_bits - 1) / word_bits)
{
unsigned wn = v.size ();
for (unsigned i = 0; i < wn; i ++)
v[i] = 0;
}
void
bitset::operator += (unsigned i)
{
assert (i >= 1);
assert (i <= n);
unsigned w = (i - 1) / word_bits;
unsigned b = (i - 1) & word_bit_mask;
v[w] = word_bitset (v[w], b + 1);
}
void
bitset::operator -= (unsigned i)
{
assert (i >= 1);
assert (i <= n);
unsigned w = (i - 1) / word_bits;
unsigned b = (i - 1) & word_bit_mask;
v[w] = word_bitclear (v[w], b + 1);
}
bool
bitset::operator % (unsigned i) const
{
assert (i >= 1);
assert (i <= n);
unsigned w = (i - 1) / word_bits;
unsigned b = (i - 1) & word_bit_mask;
return word_bittest (v[w], b + 1);
}

182
lib/directed_multigraph.cpp Normal file
View File

@ -0,0 +1,182 @@
#include <lib/lib.h>
unsigned
directed_multigraph::num_components () const
{
unionfind<1> u (n_vertices);
unsigned n_edges = num_edges ();
for (unsigned i = 1; i <= n_edges; i ++)
u.join (edge_from[i], edge_to[i]);
return u.num_sets ();
}
directed_multigraph
directed_multigraph::component (unsigned v,
basedvector<unsigned, 1> &edge_inj,
basedvector<unsigned, 1> &virtex_inj) const
{
unionfind<1> u (n_vertices);
unsigned n_edges = num_edges ();
for (unsigned i = 1; i <= n_edges; i ++)
u.join (edge_from[i], edge_to[i]);
ullmanset<1> comp_vertices (n_vertices);
for (unsigned i = 1; i <= n_vertices; i ++)
{
if (u.find (v) == u.find (i))
comp_vertices.push (i);
}
unsigned comp_n_vertices = comp_vertices.card ();
virtex_inj = basedvector<unsigned, 1> (comp_n_vertices);
for (unsigned i = 1; i <= comp_n_vertices; i ++)
virtex_inj[i] = comp_vertices.nth (i - 1);
basedvector<unsigned, 1> comp_edge_from,
comp_edge_to;
for (unsigned i = 1; i <= n_edges; i ++)
{
if (comp_vertices % edge_from[i])
{
comp_edge_from.append (comp_vertices.position (edge_from[i]) + 1);
comp_edge_to.append (comp_vertices.position (edge_to[i]) + 1);
edge_inj.append (i);
}
}
return directed_multigraph (comp_n_vertices,
comp_edge_from,
comp_edge_to);
}
class spanning_tree_builder
{
public:
const directed_multigraph &g;
basedvector<set<unsigned>, 1> vertex_edges;
ullmanset<1> tree;
ullmanset<1> visited_edges;
ullmanset<1> visited_vertices;
ullmanset<1> edges_to_visit;
basedvector<set<unsigned>, 1> trees;
void enumerate (unsigned i);
public:
spanning_tree_builder (const directed_multigraph &g_);
};
spanning_tree_builder::spanning_tree_builder (const directed_multigraph &g_)
: g(g_),
vertex_edges(g.n_vertices),
tree(g.num_edges ()),
visited_edges(g.num_edges ()),
visited_vertices(g.n_vertices),
edges_to_visit(g.num_edges ())
{
for (unsigned i = 1; i <= g.num_edges (); i ++)
{
vertex_edges[g.edge_from[i]] += i;
vertex_edges[g.edge_to[i]] += i;
}
for (set_const_iter<unsigned> i = vertex_edges[1]; i; i ++)
edges_to_visit += i.val ();
enumerate (1);
}
void
spanning_tree_builder::enumerate (unsigned i)
{
assert (i >= 1);
if (visited_vertices.card () == g.n_vertices)
{
set<unsigned> s;
setassign (s, tree.size (), tree);
trees.append (s);
return;
}
if (i > g.num_edges ()
|| i > edges_to_visit.card ())
return;
unsigned e = edges_to_visit.nth (i - 1);
unsigned visited_edges_card = visited_edges.card ();
visited_edges.push (e);
unsigned from = g.edge_from[e],
to = g.edge_to[e];
if (! ((visited_vertices % from) && (visited_vertices % to)))
{
unsigned edges_to_visit_card = edges_to_visit.card ();
unsigned visited_vertices_card = visited_vertices.card ();
unsigned tree_card = tree.card ();
tree.push (e);
if (! (visited_vertices % from))
{
visited_vertices += from;
for (set_const_iter<unsigned> j = vertex_edges[from]; j; j ++)
{
if (! (visited_edges % j.val ()))
edges_to_visit += j.val ();
}
}
if (! (visited_vertices % to))
{
visited_vertices += to;
for (set_const_iter<unsigned> j = vertex_edges[to]; j; j ++)
{
if (! (visited_edges % j.val ()))
edges_to_visit += j.val ();
}
}
// with e
enumerate (i + 1);
tree.restore (tree_card);
visited_vertices.restore (visited_vertices_card);
edges_to_visit.restore (edges_to_visit_card);
}
// without e
enumerate (i + 1);
visited_edges.restore (visited_edges_card);
}
basedvector<set<unsigned>, 1>
directed_multigraph::spanning_trees () const
{
spanning_tree_builder builder (*this);
return builder.trees;
}
void
directed_multigraph::display_self () const
{
printf ("directed_multigraph\n");
printf (" n_vertices %d\n", n_vertices);
printf (" n_edges %d\n", num_edges ());
printf (" edges:\n");
for (unsigned i = 1; i <= num_edges (); i ++)
{
printf (" % 4d: %d -> %d\n",
i,
edge_from[i],
edge_to[i]);
}
}

52
lib/directed_multigraph.h Normal file
View File

@ -0,0 +1,52 @@
class directed_multigraph
{
public:
unsigned n_vertices;
basedvector<unsigned, 1> edge_from,
edge_to;
public:
directed_multigraph () : n_vertices(0) { }
directed_multigraph (unsigned n_vertices_,
basedvector<unsigned, 1> edge_from_,
basedvector<unsigned, 1> edge_to_)
: n_vertices(n_vertices_),
edge_from(edge_from_),
edge_to(edge_to_)
{
}
directed_multigraph (const directed_multigraph &g)
: n_vertices(g.n_vertices),
edge_from(g.edge_from),
edge_to(g.edge_to)
{ }
directed_multigraph (copy, const directed_multigraph &g)
: n_vertices(g.n_vertices),
edge_from(COPY, g.edge_from),
edge_to(COPY, g.edge_to)
{
}
directed_multigraph &operator = (const directed_multigraph &g)
{
n_vertices = g.n_vertices;
edge_from = g.edge_from;
edge_to = g.edge_to;
return *this;
}
unsigned num_edges () const { return edge_from.size (); }
unsigned num_components () const;
// the component containing the vertex v
directed_multigraph component (unsigned v,
basedvector<unsigned, 1> &edge_inj,
basedvector<unsigned, 1> &virtex_inj) const;
basedvector<set<unsigned>, 1> spanning_trees () const;
void display_self () const;
};

23
lib/hashmap.h Normal file
View File

@ -0,0 +1,23 @@
/* wrapper for std::unordered_map */
template<class K>
struct hasher : public std::unary_function<K, hash_t>
{
hash_t operator () (const K &k) const { return hash (k); }
};
template<class K, class V>
class hashmap : public map_wrapper<std::tr1::unordered_map<K, V, hasher<K> >, K, V>
{
typedef map_wrapper<std::tr1::unordered_map<K, V, hasher<K> >, K, V> base;
public:
hashmap () { }
hashmap (const hashmap &m) : base(m) { }
hashmap (copy, const hashmap &m) : base(COPY, m) { }
hashmap (reader &r) : base(r) { }
~hashmap () { }
hashmap &operator = (const hashmap &m) { base::operator = (m); return *this; }
};

152
lib/io.cpp Normal file
View File

@ -0,0 +1,152 @@
#include <lib/lib.h>
writer::writer (const std::string &filename)
: fp(0)
{
fp = fopen (filename.c_str (), "w");
if (fp == 0)
{
stderror ("fopen: %s", filename.c_str ());
exit (EXIT_FAILURE);
}
}
writer::~writer ()
{
if (fp)
{
fclose (fp);
fp = 0;
}
}
reader::reader (const std::string &filename)
: fp(0)
{
fp = fopen (filename.c_str (), "r");
if (fp == 0)
{
stderror ("fopen: %s", filename.c_str ());
exit (EXIT_FAILURE);
}
}
reader::~reader ()
{
if (fp)
{
fclose (fp);
fp = 0;
}
}
void
writer::write_char (char x)
{
if (fwrite (&x, sizeof x, 1, fp) != 1)
{
stderror ("fwrite");
exit (EXIT_FAILURE);
}
}
void
writer::write_bool (bool x)
{
if (fwrite (&x, sizeof x, 1, fp) != 1)
{
stderror ("fwrite");
exit (EXIT_FAILURE);
}
}
void
writer::write_int (int x)
{
if (fwrite (&x, sizeof x, 1, fp) != 1)
{
stderror ("fwrite");
exit (EXIT_FAILURE);
}
}
void
writer::write_unsigned (unsigned x)
{
if (fwrite (&x, sizeof x, 1, fp) != 1)
{
stderror ("fwrite");
exit (EXIT_FAILURE);
}
}
void
writer::write_uint64 (uint64 x)
{
if (fwrite (&x, sizeof x, 1, fp) != 1)
{
stderror ("fwrite");
exit (EXIT_FAILURE);
}
}
bool
reader::read_bool ()
{
bool x;
if (fread (&x, sizeof x, 1, fp) != 1)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
return x;
}
char
reader::read_char ()
{
char x;
if (fread (&x, sizeof x, 1, fp) != 1)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
return x;
}
int
reader::read_int ()
{
int x;
if (fread (&x, sizeof x, 1, fp) != 1)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
return x;
}
unsigned
reader::read_unsigned ()
{
unsigned x;
if (fread (&x, sizeof x, 1, fp) != 1)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
return x;
}
uint64
reader::read_uint64 ()
{
uint64 x;
if (fread (&x, sizeof x, 1, fp) != 1)
{
stderror ("fread");
exit (EXIT_FAILURE);
}
return x;
}

59
lib/io.h Normal file
View File

@ -0,0 +1,59 @@
class writer
{
public:
FILE *fp;
public:
writer (const std::string &filename);
writer (const writer &); // doesn't exist
~writer ();
writer &operator = (const writer &); // doesn't exist
void write_bool (bool x);
void write_char (char x);
void write_int (int x);
void write_unsigned (unsigned x);
void write_uint64 (uint64 x);
};
class reader
{
public:
FILE *fp;
public:
reader (const std::string &filename);
reader (const reader &); // doesn't exist
~reader ();
reader &operator = (const reader &); // doesn't exist
bool read_bool ();
char read_char ();
int read_int ();
unsigned read_unsigned ();
uint64 read_uint64 ();
};
inline void read (reader &r, bool &x) { x = r.read_bool (); }
inline void read (reader &r, char &x) { x = r.read_char (); }
inline void read (reader &r, int &x) { x = r.read_int (); }
inline void read (reader &r, unsigned &x) { x = r.read_unsigned (); }
inline void read (reader &r, uint64 &x) { x = r.read_uint64 (); }
template<class T> inline void read (reader &r, T &x) { x = T(r); }
inline void ctor_read (reader &r, bool *p) { *p = r.read_bool (); }
inline void ctor_read (reader &r, char *p) { *p = r.read_char (); }
inline void ctor_read (reader &r, int *p) { *p = r.read_int (); }
inline void ctor_read (reader &r, unsigned *p) { *p = r.read_unsigned (); }
inline void ctor_read (reader &r, uint64 *p) { *p = r.read_uint64 (); }
template<class T> inline void ctor_read (reader &r, T *p) { new (p) T (r); }
inline void write (writer &w, bool x) { w.write_bool (x); }
inline void write (writer &w, char x) { w.write_char (x); }
inline void write (writer &w, int x) { w.write_int (x); }
inline void write (writer &w, unsigned x) { w.write_unsigned (x); }
inline void write (writer &w, uint64 x) { w.write_uint64 (x); }
template<class T> inline void write (writer &w, const T &x) { x.write_self (w); }

74
lib/lib.cpp Normal file
View File

@ -0,0 +1,74 @@
#include <lib/lib.h>
#include <stdarg.h>
unsigned
unsigned_pack (unsigned n, unsigned x, unsigned z)
{
assert (n <= 32);
assert ((x >> n) == 0);
static const unsigned pack4[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, 7, 9, 11, 13, 15, 2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, };
static const unsigned zerocount4[16] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0, };
unsigned r = 0;
for (unsigned i = 0; i < n; i += 4)
{
unsigned xnib = ((x >> i) & 0xf);
r |= pack4[(xnib << 4) | (z & 0xf)] << i;
z >>= zerocount4[xnib];
}
assert (z == 0);
return r;
}
void
stderror (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
fprintf (stderr, ": ");
perror (0);
va_end (ap);
}
unsigned
fact (unsigned n)
{
unsigned r = 1;
for (unsigned i = n; i >= 2; i --)
r *= i;
return r;
}
unsigned
choose (unsigned n, unsigned k)
{
if (n < k)
return 0;
unsigned r = 1;
for (unsigned i = n; i >= k + 1; i --)
r *= i;
unsigned d = fact (n - k);
assert (r % d == 0);
return r / d;
}
int
alpha_to_int (char c)
{
if ('a' <= c && c <= 'z')
return c - 'a' + 1;
else
{
assert ('A' <= c && c <= 'Z');
return - (c - 'A' + 1);
}
}

166
lib/lib.h Normal file
View File

@ -0,0 +1,166 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <algorithm>
#include <tr1/functional>
#include <tr1/unordered_map>
/* just need to implement ==, < */
template<class T> bool operator != (const T &a, const T &b) { return ! (a == b); }
template<class T> bool operator <= (const T &a, const T &b) { return (a < b) || (a == b); }
template<class T> bool operator > (const T &a, const T &b) { return ! (a <= b); }
template<class T> bool operator >= (const T &a, const T &b) { return ! (a < b); }
typedef enum copy { COPY, COPY1 } copy;
typedef enum copy2 { COPY2 } copy2;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef long long int64;
typedef unsigned long long uint64;
typedef size_t hash_t;
inline hash_t hash (bool x) { return (hash_t)x; }
inline hash_t hash (char x) { return (hash_t)x; }
inline hash_t hash (unsigned char x) { return (hash_t)x; }
inline hash_t hash (short x) { return (hash_t)x; }
inline hash_t hash (unsigned short x) { return (hash_t)x; }
inline hash_t hash (int x) { return (hash_t)x; }
inline hash_t hash (unsigned x) { return (hash_t)x; }
inline hash_t hash (long x) { return (hash_t)x; }
inline hash_t hash (unsigned long x) { return (hash_t)x; }
inline hash_t hash (uint64 x) { return (hash_t)((x >> 32) ^ x); }
template<class T>
inline hash_t hash (const T &x)
{
return x.hash_self ();
}
inline hash_t
hash_combine (hash_t a, hash_t b)
{
return (a ^ b) * 131;
}
/* uint64 */
static const unsigned uint64_bits = 64;
static const unsigned uint64_bit_mask = 0x3f;
static const unsigned unsigned_bits = 32;
static const unsigned unsigned_bit_mask = 0x1f;
inline unsigned uint64_bitcount (uint64 x) { return __builtin_popcountll (x); }
inline unsigned uint64_ffs (uint64 x) { assert (x != 0); return __builtin_ctzll (x) + 1; }
inline uint64 uint64_bitmask (unsigned i) { assert (i >= 1 && i <= uint64_bits); return ((uint64)1) << (i - 1); }
inline unsigned uint64_fill (unsigned b) { assert (b <= uint64_bits); return ((uint64)1 << b) - 1; }
inline uint64 uint64_bitset (uint64 x, unsigned i) { return x | uint64_bitmask (i); }
inline uint64 uint64_bitclear (uint64 x, unsigned i) { return x & ~uint64_bitmask (i); }
inline uint64 uint64_bittoggle (uint64 x, unsigned i) { return x ^ uint64_bitmask (i); }
inline bool uint64_bittest (uint64 x, unsigned i) { return (bool)(x & uint64_bitmask (i)); }
/* unsigned */
inline unsigned unsigned_bitmask (unsigned i) { assert (i >= 1 && i <= unsigned_bits); return ((unsigned)1) << (i - 1); }
inline unsigned unsigned_fill (unsigned b) { assert (b <= unsigned_bits); return ((unsigned)1 << b) - 1; }
inline unsigned unsigned_discard_bit (unsigned w, unsigned i)
{
assert (i >= 1 && i <= unsigned_bits);
return (w & ((((unsigned)1) << (i - 1)) - 1))
| ((w >> i) << (i - 1));
}
inline unsigned unsigned_bitset (unsigned w, unsigned i) { return w | unsigned_bitmask (i); }
inline unsigned unsigned_bitclear (unsigned w, unsigned i) { return w &~ unsigned_bitmask (i); }
inline bool unsigned_bittest (unsigned w, unsigned i) { return (bool)(w & unsigned_bitmask (i)); }
inline unsigned unsigned_bitcount (unsigned w) { return __builtin_popcount (w); }
inline unsigned unsigned_ffs (unsigned w) { assert (w); return __builtin_ctzl (w) + 1; }
/* pack the bits of z into the zeros of x, where x has n bits. */
unsigned unsigned_pack (unsigned n, unsigned x, unsigned z);
inline bool is_odd (int x) { return x & 1; }
inline bool is_odd (unsigned x) { return x & 1; }
inline bool is_even (int x) { return !is_odd (x); }
inline bool is_even (unsigned x) { return !is_odd (x); }
inline unsigned unsigned_2pow (unsigned e) { return ((unsigned)1) << e; }
class unsigned_const_iter
{
private:
unsigned x;
unsigned b;
public:
unsigned_const_iter (unsigned x_) : x(x_), b(0) { if (x) b = unsigned_ffs (x); }
unsigned_const_iter (const unsigned_const_iter &i) : x(i.x), b(i.b) { }
~unsigned_const_iter () { }
unsigned_const_iter &operator = (const unsigned_const_iter &i) { x = i.x; b = i.b; return *this; }
unsigned val () const { assert (x); return b; }
operator bool () { return (bool)x; }
void operator ++ () { assert (x); x = unsigned_bitclear (x, b); if (x) b = unsigned_ffs (x); }
void operator ++ (int) { operator ++ (); }
};
inline bool between (unsigned a, unsigned x, unsigned b) { return a <= x && x <= b; }
void stderror (const char *fmt, ...);
int alpha_to_int (char c);
#include <lib/io.h>
#include <lib/show.h>
#include <lib/refcount.h>
#include <lib/pair.h>
#include <lib/maybe.h>
#include <lib/vector.h>
#include <lib/set.h>
class bitset;
template<unsigned B> class ullmanset;
unsigned fact (unsigned n);
unsigned choose (unsigned n, unsigned k);
inline int random_int (int from, int to)
{
assert (to >= from);
return from + (random () % (to - from + 1));
}
#include <lib/smallbitset.h>
#include <lib/bitset.h>
#include <lib/ullmanset.h>
#include <lib/setcommon.h>
#include <lib/map_wrapper.h>
#include <lib/map.h>
#include <lib/hashmap.h>
#include <lib/ullmanmap.h>
#include <lib/mapcommon.h>
#include <lib/unionfind.h>
#include <lib/priority_queue.h>
#include <lib/directed_multigraph.h>

18
lib/map.h Normal file
View File

@ -0,0 +1,18 @@
/* wrapper for stl map */
template<class K, class V>
class map : public map_wrapper<std::map<K, V>, K, V>
{
typedef map_wrapper<std::map<K, V>, K, V> base;
public:
map () { }
map (unsigned dummy_size) : base(dummy_size) { }
map (const map &m) : base(m) { }
map (copy, const map &m) : base(COPY, m) { }
map (reader &r) : base(r) { }
~map () { }
map &operator = (const map &m) { base::operator = (m); return *this; }
};

221
lib/map_wrapper.h Normal file
View File

@ -0,0 +1,221 @@
/* wrapper for stl maps */
template<class M, class K, class V> class map_wrapper_iter;
template<class M, class K, class V> class map_wrapper_const_iter;
template<class M, class K, class V>
class map_wrapper
{
private:
friend class map_wrapper_iter<M, K, V>;
friend class map_wrapper_const_iter<M, K, V>;
class map_impl : public refcounted
{
public:
M t;
};
ptr<map_impl> impl;
public:
typedef map_wrapper_iter<M, K, V> iter;
typedef map_wrapper_const_iter<M, K, V> const_iter;
public:
map_wrapper () : impl(new map_impl) { }
map_wrapper (unsigned dummy_size) : impl(new map_impl) { }
map_wrapper (const map_wrapper &m) : impl(m.impl) { }
map_wrapper (copy, const map_wrapper &m) : impl(new map_impl) { impl->t = M (m.impl->t); }
map_wrapper (reader &r);
~map_wrapper () { }
map_wrapper &operator = (const map_wrapper &m) { impl = m.impl; return *this; }
/* returns the pair associated to the smallest key */
pair<K, V> head () const
{
typename M::const_iterator i = impl->t.begin ();
assert (i != impl->t.end ());
return pair<K, V> (i->first, i->second);
}
/* returns the pair associated to the largest key */
pair<K, V> tail () const
{
typename M::const_reverse_iterator i = impl->t.rbegin ();
assert (i != impl->t.rend ());
return pair<K, V> (i->first, i->second);
}
maybe<V> remove_with_value (const K &k)
{
typename M::iterator i = impl->t.find (k);
if (i == impl->t.end ())
return maybe<V> ();
else
{
V v = i->second;
impl->t.erase (i);
return maybe<V> (v);
}
}
void clear () { impl->t.clear (); }
bool is_empty () const { return impl->t.empty (); }
unsigned card () const { return impl->t.size (); }
void yank (const K &k) { assert (operator % (k)); impl->t.erase (k); }
V yank_with_value (const K &k)
{
typename M::iterator i = impl->t.find (k);
assert (i != impl->t.end ());
V v = i->second;
impl->t.erase (i);
return v;
}
void operator -= (const K &k) { impl->t.erase (k); }
void push (const K &k, const V &v) { assert (!operator % (k)); impl->t.insert (std::pair<K, V> (k, v)); }
void set (const K &k, const V &v) { operator [] (k) = v; }
pair<V &, bool> find (const K &k)
{
typename M::iterator i = impl->t.find (k);
bool present;
if (i == impl->t.end ())
{
i = impl->t.insert (std::pair<K, V> (k, V ())).first;
present = 0;
}
else
present = 1;
return pair<V &, bool> (i->second, present);
}
V *operator ^ (const K &k)
{
typename M::iterator i = impl->t.find (k);
return i == impl->t.end () ? 0 : &i->second;
}
const V *operator ^ (const K &k) const
{
typename M::const_iterator i = impl->t.find (k);
return i == impl->t.end () ? 0 : &i->second;
}
V &operator [] (const K &k) { return impl->t[k]; }
const V &operator [] (const K &k) const
{
typename M::const_iterator i = impl->t.find (k);
assert (i != impl->t.end ());
return i->second;
}
const V &operator () (const K &k) const { return operator [] (k); }
const V &operator () (const K &k, const V &d) const
{
typename M::const_iterator i = impl->t.find (k);
if (i == impl->t.end ())
return d;
else
return i->second;
}
bool operator % (const K &k) const
{
typename M::const_iterator i = impl->t.find (k);
return i != impl->t.end ();
}
bool operator == (const map_wrapper &m) const;
void write_self (writer &w) const;
};
template<class M, class K, class V>
map_wrapper<M, K, V>::map_wrapper (reader &r)
: impl(new map_impl)
{
unsigned card_ = r.read_unsigned ();
K k;
V v;
for (unsigned i = 0; i < card_; i ++)
{
read (r, k);
read (r, v);
push (k, v);
}
}
template<class M, class K, class V> bool
map_wrapper<M, K, V>::operator == (const map_wrapper &m) const
{
// event bettr: use (ordered) dual iterators
if (card () != m.card ())
return 0;
for (const_iter i = *this; i; i ++)
{
// ??? inefficient: use operator ^
if (! (m % i.key ())
|| m(i.key ()) != i.val ())
return 0;
}
return 1;
}
template<class M, class K, class V> void
map_wrapper<M, K, V>::write_self (writer &w) const
{
write (w, card ());
for (const_iter i = *this; i; i ++)
{
write (w, i.key ());
write (w, i.val ());
}
}
template<class M, class K, class V>
class map_wrapper_iter
{
private:
map_wrapper<M, K, V> &m;
typename M::iterator i, end;
bool deleted;
public:
map_wrapper_iter (map_wrapper<M, K, V> &m_) : m(m_), i(m_.impl->t.begin ()), end(m_.impl->t.end ()), deleted(0) { }
~map_wrapper_iter () { }
void del ()
{
assert (!deleted);
typename M::iterator iprev = i ++;
m.impl->t.erase (iprev);
deleted = 1;
}
const K &key () const { assert (!deleted); return i->first; }
V &val () { assert (!deleted); return i->second; }
operator bool () const { assert (!deleted); return i != end; }
void operator ++ () { if (deleted) deleted = 0; else i ++; }
void operator ++ (int) { operator ++ (); }
};
template<class M, class K, class V>
class map_wrapper_const_iter
{
private:
typename M::const_iterator i, end;
public:
map_wrapper_const_iter (const map_wrapper<M, K, V> &m) : i(m.impl->t.begin ()), end(m.impl->t.end ()) { }
~map_wrapper_const_iter () { }
const K &key () const { return i->first; }
const V &val () { return i->second; }
operator bool () const { return i != end; }
void operator ++ () { i ++; }
void operator ++ (int) { i ++; }
};

28
lib/mapcommon.h Normal file
View File

@ -0,0 +1,28 @@
template<class V, unsigned B> map<unsigned, V> &
mapassign (map<unsigned, V> &to, unsigned dummy_size, const ullmanmap<V, B> &from)
{
assert (dummy_size == from.size ());
to = map<unsigned, V> ();
for (ullmanmap_const_iter<V, B> i = from; i; i ++)
to.push (i.key (), i.val ());
return to;
}
template<class V, unsigned B> ullmanmap<V, B> &
mapassign (ullmanmap<V, B> &to, unsigned size, const map<unsigned, V> &from)
{
to = ullmanmap<V, B> (size);
for (typename map<unsigned, V>::const_iter i = from; i; i ++)
to.push (i.key (), i.val ());
return to;
}
template<class K, class V> map<K, V> &
mapassign (map<K, V> &to, unsigned dummy_size, const map<K, V> &from)
{
// todo: ?? careful about allocation: this unref's the previous object pointed to by to
to = map<K, V> (COPY, from);
return to;
}

58
lib/maybe.h Normal file
View File

@ -0,0 +1,58 @@
template <class T>
class maybe
{
private:
bool present;
T v;
public:
maybe () : present(0) { }
maybe (const T &v_) : present(1), v(v_) { }
maybe (const maybe &m) : present(m.present), v(m.v) { }
maybe (reader &r);
~maybe () { }
maybe &operator = (const maybe &m) { present = m.present; v = m.v; return *this; }
bool is_some () const { return present; }
bool is_none () const { return !present; }
T &some () { assert (present); return v; }
bool operator == (const maybe &m) const
{
if (present != m.present)
return 0;
if (present)
return v == m.v;
}
bool operator != (const maybe &m) const { return !operator == (m); }
void write_self (writer &w) const;
hash_t hash_self () const;
};
template<class T>
maybe<T>::maybe (reader &r)
{
read (r, present);
if (present)
read (r, v);
}
template<class T> void
maybe<T>::write_self (writer &w) const
{
write (w, present);
if (present)
write (w, v);
}
template<class T> hash_t
maybe<T>::hash_self () const
{
if (present)
return hash_combine (hash (0xdeadbeef), hash (v));
else
return hash (0xcafebabe);
}

94
lib/pair.h Normal file
View File

@ -0,0 +1,94 @@
template <class F, class S>
class pair
{
public:
F first;
S second;
public:
pair () { }
pair (const pair &p) : first(p.first), second(p.second) { }
/* F, S might be references. */
pair (F first_, S second_) : first(first_), second(second_) { }
pair (reader &r);
~pair () { }
pair &operator = (const pair &p) { first = p.first; second = p.second; return *this; }
bool operator == (const pair &p) const { return first == p.first && second == p.second; }
bool operator < (const pair &p) const { return (first < p.first
|| (first == p.first && second < p.second)); }
void write_self (writer &w) const;
hash_t hash_self () const { return hash_combine (hash (first), hash (second)); }
};
template <class F, class S>
pair<F, S>::pair (reader &r)
{
read (r, first);
read (r, second);
}
template<class F, class S> void
pair<F, S>::write_self (writer &w) const
{
write (w, first);
write (w, second);
}
template<class F, class S, class T>
class triple
{
public:
F first;
S second;
T third;
triple () { }
triple (const triple &t)
: first(t.first), second(t.second), third(t.third)
{ }
triple (const F &first_, const S &second_, const T &third_)
: first(first_), second(second_), third(third_)
{ }
~triple () { }
triple &operator = (const triple &t)
{
first = t.first;
second = t.second;
third = t.third;
return *this;
}
bool operator == (const triple &t) const
{
return first == t.first && second == t.second && third == t.third;
}
bool operator < (const triple &t) const
{
if (first < t.first)
return 1;
else if (first > t.first)
return 0;
if (second < t.second)
return 1;
else if (second > t.second)
return 0;
if (third < t.third)
return 1;
else if (third > t.third)
return 0;
}
hash_t hash_self () const
{
hash_t h = hash (first);
h = hash_combine (h, hash (second));
return hash_combine (h, hash (third));
}
};

78
lib/priority_queue.h Normal file
View File

@ -0,0 +1,78 @@
template<class V>
class priority_queue
{
private:
class weighted
{
public:
V v;
int pri;
public:
weighted () { }
weighted (const weighted &w) : v(w.v), pri(w.pri) { }
weighted (const V &v_, int pri_) : v(v_), pri(pri_) { }
~weighted () { }
weighted &operator = (const weighted &w) { v = w.v; pri = w.pri; }
bool operator == (const weighted &w) const { return v == w.v && pri == w.pri; }
bool operator < (const weighted &w) const { return pri > w.pri || (pri == w.pri && v < w.v); }
};
map<V, int> pri;
set<weighted> s;
public:
priority_queue () { }
priority_queue (const priority_queue &q) : pri(q.pri), s(q.s) { }
priority_queue (copy, const priority_queue &q) : pri(COPY, q.pri), s(COPY, q.s) { }
~priority_queue () { }
priority_queue &operator = (const priority_queue &q) { pri = q.pri; s = q.s; }
bool is_empty () const { return s.is_empty (); }
bool operator % (const V &v) const { return pri % v; }
void push (const V &v, int p)
{
assert (! (pri % v));
pri.push (v, p);
s.push (weighted (v, p));
}
priority_queue &operator -= (const V &v)
{
maybe<int> old_p = pri.remove_with_value (v);
if (old_p.is_some ())
s.yank (weighted (v, old_p.some ()));
return *this;
}
void yank (const V &v) { assert (pri % v); operator -= (v); }
void insert (const V &v, int p)
{
int *old_p = pri ^ v;
if (old_p)
{
if (*old_p != p)
{
s.yank (weighted (v, *old_p));
s.push (weighted (v, p));
*old_p = p;
}
}
else
{
pri.push (v, p);
s.push (weighted (v, p));
}
}
V pop ()
{
weighted w = s.pop ();
pri.yank (w.v);
return w.v;
}
const V &top () const { return s.head ().v; }
unsigned card () const { return s.card (); }
};

25
lib/refcount.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <lib/lib.h>
#ifndef NDEBUG
uint64 allocations = 0;
uint64 deallocations = 0;
class finalize
{
public:
finalize ();
~finalize ();
};
finalize::finalize ()
{
}
finalize::~finalize ()
{
// assert (allocations == deallocations);
}
static finalize finalizer;
#endif

84
lib/refcount.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef NDEBUG
extern uint64 allocations, deallocations;
#endif
inline void *operator new (size_t size)
{
#ifndef NDEBUG
allocations ++;
#endif
return malloc (size);
}
inline void *operator new [] (size_t size)
{
#ifndef NDEBUG
allocations ++;
#endif
return malloc (size);
}
inline void operator delete (void *p)
{
#ifndef NDEBUG
deallocations ++;
#endif
free (p);
}
inline void operator delete [] (void *p)
{
#ifndef NDEBUG
deallocations ++;
#endif
free (p);
}
class refcounted
{
private:
template<class T> friend class ptr;
mutable unsigned refcount;
public:
refcounted () : refcount(0) { }
refcounted (const refcounted &rc); // doesn't exist
~refcounted () { }
refcounted &operator = (const refcounted &rc); // doesn't exist
};
template<class T>
class ptr
{
private:
template<class S> friend class ptr;
T *p;
void ref (T *newp) { assert (p == 0); p = newp; if (p) p->refcount ++; }
void unref () { if (p && -- p->refcount == 0) { delete p; } p = 0; }
public:
ptr () : p(0) { }
ptr (const ptr &r) : p(0) { ref (r.p); }
template<class S> ptr (S *p_) : p(0) { ref (p_); }
template<class S> ptr (const ptr<S> &r) : p(0) { ref (r.p); }
~ptr () { unref (); }
ptr &operator = (const ptr &r) { unref (); ref (r.p); return *this; }
template<class S> ptr &operator = (S *p_) { unref (); ref (p_); return *this; }
template<class S> bool operator == (const ptr<S> &r) const { return p == r.p; }
template<class S> bool operator != (const ptr<S> &r) const { return p != r.p; }
template<class S> bool operator == (S *p_) const { return p == p_; }
template<class S> bool operator != (S *p_) const { return p != p_; }
bool operator == (int x) const { assert (x == 0); return p == 0; }
bool operator != (int x) const { assert (x == 0); return p != 0; }
T &operator * () const { assert (p); return *p; }
T *get () const { assert (p); return p; }
T *operator -> () const { assert (p); return p; }
};

341
lib/set.h Normal file
View File

@ -0,0 +1,341 @@
/* wrap for std::set */
template<class T> class set_iter;
template<class T> class set_const_iter;
template<class T>
class set
{
private:
friend class set_iter<T>;
friend class set_const_iter<T>;
class set_impl : public refcounted
{
public:
std::set<T> t;
};
ptr<set_impl> impl;
public:
typedef set_iter<T> iter;
typedef set_const_iter<T> const_iter;
public:
set () : impl(new set_impl) { }
set (unsigned dummy_size) : impl(new set_impl) { }
set (const set &s) : impl(s.impl) { }
set (copy, const set &s) : impl(new set_impl) { impl->t = std::set<T> (s.impl->t); }
set (reader &r);
~set () { }
set &operator = (const set &s) { impl = s.impl; return *this; }
T pop ()
{
typename std::set<T>::const_iterator i = impl->t.begin ();
assert (i != impl->t.end ());
T tmp = *i;
impl->t.erase (i);
return tmp;
}
bool is_empty () const { return impl->t.empty (); }
unsigned card () const { return impl->t.size (); }
const T &head () const;
const T &tail () const;
bool operator == (const set &s) const;
bool operator < (const set &s) const;
bool operator <= (const set &s) const;
void clear () { impl->t.clear (); }
void push (const T &v) { assert (impl->t.find (v) == impl->t.end ()); impl->t.insert (v); }
bool toggle (const T &v);
void operator += (const T &v) { impl->t.insert (v); }
void operator -= (const T &v) { impl->t.erase (v); }
void yank (const T &v) { assert (operator % (v)); impl->t.erase (v); }
set &operator |= (const set<T> &s);
set &operator &= (const set<T> &s);
set &operator ^= (const set<T> &s);
bool operator % (const T &v) const { return impl->t.find (v) != impl->t.end (); }
bool operator () (const T &v) const { return operator % (v); }
void write_self (writer &w) const;
hash_t hash_self () const;
};
template<class T>
class set_iter
{
set<T> &s;
typename std::set<T>::const_iterator i, end;
bool deleted;
public:
set_iter (set<T> &s_) : s(s_), i(s_.impl->t.begin ()), end(s_.impl->t.end ()), deleted(0) { }
~set_iter () { }
void del ()
{
assert (!deleted);
typename std::set<T>::const_iterator iprev = i ++;
s.impl->t.erase (iprev);
deleted = 1;
}
const T &val () const { assert (!deleted); return *i; }
operator bool () const { assert (!deleted); return i != end; }
set_iter &operator ++ () { if (deleted) deleted = 0; else i ++; return *this; }
void operator ++ (int) { operator ++ (); }
};
template<class T>
class set_const_iter
{
typename std::set<T>::const_iterator i, end;
public:
set_const_iter (const set<T> &s) : i(s.impl->t.begin ()), end(s.impl->t.end ()) { }
~set_const_iter () { }
const T &val () const { return *i; }
operator bool () const { return i != end; }
set_const_iter &operator ++ () { i ++; return *this; }
void operator ++ (int) { i ++; }
};
template<class T>
set<T>::set (reader &r)
{
unsigned n;
read (r, n);
T x;
for (unsigned i = 0; i < n; i ++)
{
read (r, x);
push (x);
}
}
template<class T> const T &
set<T>::head () const
{
set_const_iter<T> i = *this;
assert (i);
return i.val ();
}
template<class T> const T &
set<T>::tail () const
{
typename std::set<T>::const_reverse_iterator i = impl->t.rbegin ();
assert (i != impl->t.rend ());
return *i;
}
template<class T> bool
set<T>::operator == (const set &s) const
{
typename std::set<T>::const_iterator i = impl->t.begin (),
j = s.impl->t.begin (),
iend = impl->t.end (),
jend = s.impl->t.end ();
while (i != iend && j != jend && *i == *j)
i ++, j ++;
return i == iend && j == jend;
}
template<class T> bool
set<T>::operator < (const set &s) const
{
typename std::set<T>::const_iterator i = impl->t.begin (),
j = s.impl->t.begin (),
iend = impl->t.end (),
jend = s.impl->t.end ();
while (i != iend && j != jend && *i == *j)
i ++, j ++;
return (i == iend && j != jend) || (i != iend && j != jend && *i < *j);
}
template<class T> bool
set<T>::operator <= (const set &s) const
{
typename std::set<T>::const_iterator i = impl->t.begin (),
j = s.impl->t.begin (),
iend = impl->t.end (),
jend = s.impl->t.end ();
while (i != iend && j != jend && *i == *j)
i ++, j ++;
return i == iend
|| (i != iend && j != jend && *i <= *j);
}
template<class T> bool
set<T>::toggle (const T &v)
{
typename std::set<T>::const_iterator i = impl->t.lower_bound (v),
end = impl->t.end ();
if (i != end && *i == v)
{
impl->t.erase (i);
return 1;
}
else
{
if (i == impl->t.begin ())
impl->t.insert (v);
else
{
typename std::set<T>::const_iterator j = --i;
assert (*j < v);
impl->t.insert (j, v);
}
return 0;
}
}
template<class T> set<T> &
set<T>::operator |= (const set<T> &s)
{
std::set<T> news;
std::set_union (impl->t.begin (), impl->t.end (),
s.impl->t.begin (), s.impl->t.end (),
inserter (news, news.begin ()));
impl->t = news;
return *this;
}
template<class T> set<T> &
set<T>::operator &= (const set<T> &s)
{
std::set<T> news;
std::set_intersection (impl->t.begin (), impl->t.end (),
s.impl->t.begin (), s.impl->t.end (),
inserter (news, news.begin ()));
impl->t = news;
return *this;
}
template<class T> set<T> &
set<T>::operator ^= (const set<T> &s)
{
#if 0
printf ("before:\n");
printf ("this:");
for (typename std::set<T>::const_iterator i = impl->t.begin (); i != impl->t.end (); i ++)
printf (" %d", *i);
printf ("\n");
printf ("s:");
for (typename std::set<T>::const_iterator i = s.impl->t.begin (); i != s.impl->t.end (); i ++)
printf (" %d", *i);
printf ("\n");
#endif
#if 1
typename std::set<T>::const_iterator i = impl->t.begin (),
iend = impl->t.end (),
j = s.impl->t.begin (),
jend = s.impl->t.end ();
while (i != iend && j != jend && *i == *j)
{
impl->t.erase (i);
i = impl->t.begin ();
j ++;
}
if (i == iend)
impl->t.insert (j, jend);
else
{
if (j != jend && *j < *i)
{
i = impl->t.insert (*j).first;
j ++;
}
while (j != jend)
{
assert (*i < *j);
typename std::set<T>::const_iterator iprev = i ++;
if (i == iend)
{
while (j != jend)
{
iprev = impl->t.insert (iprev, *j);
j ++;
}
break;
}
else if (*i == *j)
{
impl->t.erase (i);
i = iprev;
j ++;
}
else
{
while (j != jend && *j < *i)
{
iprev = impl->t.insert (iprev, *j);
j ++;
}
if (j != jend && *j == *i)
{
impl->t.erase (i);
i = iprev;
j ++;
}
}
}
}
#endif
#if 0
std::set<T> news;
std::set_symmetric_difference (impl->t.begin (), impl->t.end (),
s.impl->t.begin (), s.impl->t.end (),
inserter (news, news.begin ()));
impl->t = news;
#endif
#if 0
printf ("after:\n");
printf ("this:");
for (typename std::set<T>::const_iterator i = impl->t.begin (); i != impl->t.end (); i ++)
printf (" %d", *i);
printf ("\n");
#endif
return *this;
}
template<class T> void
set<T>::write_self (writer &w) const
{
write (w, card ());
for (const_iter i = *this; i; i ++)
write (w, i.val ());
}
template<class T> hash_t
set<T>::hash_self () const
{
hash_t h = hash (card ());
unsigned j = 0;
for (const_iter i = *this; i && j < 10; i ++, j ++)
h = hash_combine (h, hash (i.val ()));
return h;
}

60
lib/setcommon.cpp Normal file
View File

@ -0,0 +1,60 @@
#include <lib/lib.h>
unsigned unsigned_set (const ullmanset<1> &s)
{
assert (s.size () <= unsigned_bits);
unsigned v = 0;
for (ullmanset_const_iter<1> i = s; i; i ++)
v = unsigned_bitset (v, i.val ());
return v;
}
unsigned
unsigned_set (const bitset &s)
{
assert (s.size () <= unsigned_bits);
unsigned v = 0;
for (bitset_const_iter i = s; i; i ++)
v = unsigned_bitset (v, i.val ());
return v;
}
unsigned
unsigned_set (const set<unsigned> &s)
{
unsigned v = 0;
for (set_const_iter<unsigned> i = s; i; i ++)
v = unsigned_bitset (v, i.val ());
return v;
}
/* bitset */
bitset::bitset (const ullmanset<1> &t)
: n(0)
{
*this = bitset (t.size ());
for (ullmanset_const_iter<1> i = t; i; i ++)
push (i.val ());
}
bitset &
bitset::operator = (const ullmanset<1> &t)
{
*this = bitset (t.size ());
for (ullmanset_const_iter<1> i = t; i; i ++)
push (i.val ());
return *this;
}
smallbitset::smallbitset (const ullmanset<1> &t)
: n(t.size ()), x(0)
{
assert (n <= 58);
for (ullmanset_const_iter<1> i = t; i; i ++)
push (i.val ());
}

55
lib/setcommon.h Normal file
View File

@ -0,0 +1,55 @@
extern unsigned unsigned_set (const ullmanset<1> &s);
extern unsigned unsigned_set (const bitset &s);
extern unsigned unsigned_set (const set<unsigned> &s);
smallbitset::smallbitset (const bitset &t)
: n(t.size ()),
x(0)
{
assert (t.size () <= max_size);
if (n)
{
assert (t.v.size () == 1);
x = t.v[0];
}
assert ((x >> n) == 0);
}
template<unsigned B>
ullmanset<B>::ullmanset (const bitset &t)
: d(0)
{
*this = ullmanset (t.size ());
for (bitset_const_iter i = t; i; i ++)
push (i.val ());
}
template<unsigned B> ullmanset<B> &
ullmanset<B>::operator = (const bitset &t)
{
*this = ullmanset (t.size ());
for (bitset_const_iter i = t; i; i ++)
push (i.val ());
return *this;
}
template<unsigned B> set<unsigned> &
setassign (set<unsigned> &to, unsigned dummy_size, const ullmanset<B> &from)
{
assert (dummy_size == from.size ());
to = set<unsigned> ();
for (ullmanset_const_iter<B> i = from; i; i ++)
to.push (i.val ());
return to;
}
template<unsigned B> ullmanset<B> &
setassign (ullmanset<B> &to, unsigned size, const set<unsigned> &from)
{
to = ullmanset<B> (size);
for (set_const_iter<unsigned> i = from; i; i ++)
to.push (i.val ());
return to;
}

16
lib/show.h Normal file
View File

@ -0,0 +1,16 @@
inline void newline () { printf ("\n"); }
inline void comment () { printf ("%% "); }
inline void show (int i) { printf ("%d", i); }
inline void show (unsigned i) { printf ("%d", i); }
inline void display (int i) { printf ("%d\n", i); }
inline void display (unsigned i) { printf ("%d\n", i); }
template<class T> inline void show (const T &e) { e.show_self (); }
template<class T> inline void display (const T &e) { e.display_self (); }
template<class T> inline void display (const char *h, const T &e)
{
printf ("%s", h);
e.display_self ();
}

44
lib/smallbitset.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <lib/lib.h>
smallbitset::smallbitset (reader &r)
{
uint64 t;
read (r, t);
n = t >> 58;
x = t;
assert (n <= max_size);
}
#if 0
smallbitset::smallbitset (const unsignedset &t)
: n(t.size ()),
x(0)
{
assert (n <= max_size);
for (unsignedset_const_iter i = t; i; i ++)
push (i.val ());
}
#endif
void
smallbitset::write_self (writer &w) const
{
write (w, x | (((uint64)n) << 58));
}
void
smallbitset::show_self () const
{
printf ("%d:", n);
for (unsigned i = n; i >= 1; i --)
printf ("%c", operator % (i) ? '1' : '0');
}
void
smallbitset::display_self () const
{
show_self ();
newline ();
}

147
lib/smallbitset.h Normal file
View File

@ -0,0 +1,147 @@
class smallbitset_iter;
class smallbitset_const_iter;
class smallbitset
{
private:
friend class smallbitset_iter;
friend class smallbitset_const_iter;
unsigned n : 6;
uint64 x : 58;
public:
static const unsigned max_size = 58;
typedef smallbitset_iter iter;
typedef smallbitset_const_iter const_iter;
public:
smallbitset () : n(0), x(0) { }
explicit smallbitset (unsigned n_) : n(n_), x(0) { assert (n_ <= max_size); }
explicit smallbitset (reader &r);
smallbitset (unsigned n_, uint64 x_)
: n(n_), x(x_ & uint64_fill (n_))
{
assert (n <= max_size);
assert ((x >> n) == 0);
}
smallbitset (const smallbitset &bs) : n(bs.n), x(bs.x) { }
explicit smallbitset (const ullmanset<1> &t);
// explicit smallbitset (const unsignedset &t);
explicit inline smallbitset (const bitset &t);
~smallbitset () { }
smallbitset &operator = (const smallbitset &bs) { n = bs.n; x = bs.x; return *this; }
smallbitset &operator = (const bitset &t) { *this = smallbitset (t); return *this; }
// smallbitset &operator = (const unsignedset &t) { *this = smallbitset (t); return *this; }
smallbitset &operator = (const ullmanset<1> &t) { *this = smallbitset (t); return *this; }
bool is_empty () const { assert ((x >> n) == 0); return x == 0; }
unsigned card () const { assert ((x >> n) == 0); return uint64_bitcount (x); }
unsigned size () const { return n; }
unsigned head () const { assert (x); return uint64_ffs (x); }
unsigned pop ()
{
assert (x);
unsigned i = uint64_ffs (x);
x = uint64_bitclear (x, i);
return i;
}
bool subset (const smallbitset &bs) const
{
assert (n == bs.n);
assert ((x >> n) == 0);
assert ((bs.x >> n) == 0);
return (x & bs.x) == x;
}
void push (unsigned i) { assert (! (*this % i)); operator += (i); }
void yank (unsigned i) { assert (*this % i); operator -= (i); }
void operator += (unsigned i) { assert (i <= n); x = uint64_bitset (x, i); }
void operator -= (unsigned i) { assert (i <= n); x = uint64_bitclear (x, i); }
void toggle (unsigned i) { assert (i <= n); x = uint64_bittoggle (x, i); }
void toggle () { x ^= (((uint64)1) << n) - 1; }
smallbitset &operator |= (const smallbitset &bs) { assert (n == bs.n); x |= bs.x; return *this; }
smallbitset &operator &= (const smallbitset &bs) { assert (n == bs.n); x &= bs.x; return *this; }
smallbitset &operator ^= (const smallbitset &bs) { assert (n == bs.n); x ^= bs.x; return *this; }
bool operator == (const smallbitset &bs) const { return n == bs.n && x == bs.x; }
bool operator != (const smallbitset &bs) const { return !operator == (bs); }
inline bool operator % (unsigned i) const { return uint64_bittest (x, i); }
inline bool operator () (unsigned i) const { return operator % (i); }
void show_self () const;
void display_self () const;
void write_self (writer &w) const;
hash_t hash_self () const { assert ((x >> n) == 0); return hash_combine (hash (n), hash (x)); }
};
class smallbitset_const_iter
{
uint64 x;
unsigned b;
public:
smallbitset_const_iter (const smallbitset &bs) : x(bs.x), b(0) { if (x) b = uint64_ffs (x); }
smallbitset_const_iter (const smallbitset_const_iter &i) : x(i.x), b(i.b) { }
~smallbitset_const_iter () { }
smallbitset_const_iter &operator = (const smallbitset_const_iter &i) { x = i.x; b = i.b; return *this; }
unsigned val () const { return b; }
operator bool () const { return (bool)x; }
void operator ++ () { assert (x); x = uint64_bitclear (x, b); if (x) b = uint64_ffs (x); }
void operator ++ (int) { operator ++ (); }
};
class smallbitset_iter
{
smallbitset *bs;
uint64 x;
unsigned b;
bool deleted;
public:
smallbitset_iter (smallbitset &bs_)
: bs(&bs_), x(bs_.x), b(0), deleted(0)
{
if (x)
b = uint64_ffs (x);
}
smallbitset_iter (const smallbitset_iter &i)
: bs(i.bs), x(i.x), b(i.b), deleted(i.deleted) { }
~smallbitset_iter () { }
smallbitset_iter &operator = (const smallbitset_iter &i)
{
bs = i.bs;
x = i.x;
b = i.b;
deleted = i.deleted;
return *this;
}
void del () { assert (!deleted); (*bs) -= b; deleted = 1; }
unsigned val () const { assert (!deleted); return b; }
operator bool () const { assert (!deleted); return (bool)x; }
void operator ++ ()
{
assert (x);
x = uint64_bitclear (x, b);
if (x)
b = uint64_ffs (x);
deleted = 0;
}
void operator ++ (int) { operator ++ (); }
};

128
lib/ullmanmap.h Normal file
View File

@ -0,0 +1,128 @@
template<class V, unsigned B> class ullmanmap_iter;
template<class V, unsigned B> class ullmanmap_const_iter;
template<class V, unsigned B>
class ullmanmap
{
private:
friend class ullmanmap_iter<V, B>;
friend class ullmanmap_const_iter<V, B>;
ullmanset<B> present;
basedvector<V, B> values;
public:
typedef ullmanmap_iter<V, B> iter;
typedef ullmanmap_const_iter<V, B> const_iter;
public:
ullmanmap () { }
ullmanmap (unsigned size) : present(size), values(size) { }
ullmanmap (unsigned size, const map<unsigned, V> &m); // common
ullmanmap (const ullmanmap &m) : present(m.present), values(m.values) { }
ullmanmap (copy, const ullmanmap &m) : present(COPY, m.present), values(COPY, m.values) { }
ullmanmap (reader &r);
~ullmanmap () { }
ullmanmap &operator = (const ullmanmap &m) { present = m.present; values = m.values; return *this; }
ullmanmap &operator = (const map<unsigned, V> &m); // common
unsigned size () const { return present.size (); }
pair<unsigned, V> head ();
void clear () { present.clear (); }
unsigned card () { return present.card (); }
void operator -= (unsigned k) { present -= k; }
void push (unsigned k, const V &v) { present.push (k); values[k] = v; }
void set (unsigned k, const V &v) { present += k; values[k] = v; }
V &operator [] (unsigned k) { if (! (present % k)) { present.push (k); values[k] = V (); } return values[k]; }
const V &operator [] (unsigned k) const { assert (present % k); return values[k]; }
const V &operator () (unsigned k) const { assert (present % k); return operator [] (k); }
const V &operator () (unsigned k, const V &d) const { if (present % k) return values[k]; else return d; }
pair<V &, bool> find (unsigned k)
{
bool p = present % k;
return pair<V &, bool> (operator [] (k), p);
}
bool operator % (unsigned k) const { return present % k; }
unsigned nth (unsigned p) const { return present.nth (p); }
unsigned position (unsigned k) const { return present.position (k); }
void write_self (writer &w) const;
};
template<class V, unsigned B>
ullmanmap<V, B>::ullmanmap (unsigned size, const map<unsigned, V> &m)
: present(size), values(size)
{
for (typename map<unsigned, V>::const_iter i = m; i; i ++)
push (i.key (), i.val ());
}
template<class V, unsigned B>
ullmanmap<V, B>::ullmanmap (reader &r)
: present(r),
values(r)
{
}
template<class V, unsigned B> ullmanmap<V, B> &
ullmanmap<V, B>::operator = (const map<unsigned, V> &m)
{
/* assume the ullman map is already allocated */
clear ();
for (typename map<unsigned, V>::const_iter i = m; i; i ++)
push (i.key (), i.val ());
return *this;
}
template<class V, unsigned B> void
ullmanmap<V, B>::write_self (writer &w) const
{
write (w, present);
write (w, values);
}
template<class V, unsigned B>
class ullmanmap_iter
{
private:
ullmanset_iter<B> i;
basedvector<V, B> &values;
public:
ullmanmap_iter (ullmanmap<V, B> &m) : i(m.present), values(m.values) { }
~ullmanmap_iter () { }
void del () { i.del (); }
unsigned key () const { return i.val (); }
V &val () { return values[i.val ()]; }
const V &val () const { return values[i.val ()]; }
operator bool () const { return (bool)i; }
void operator ++ () { i ++; }
void operator ++ (int) { i ++; }
};
template<class V, unsigned B>
class ullmanmap_const_iter
{
private:
ullmanset_const_iter<B> i;
const basedvector<V, B> &values;
public:
ullmanmap_const_iter (const ullmanmap<V, B> &m) : i(m.present), values(m.values) { }
~ullmanmap_const_iter () { }
unsigned key () const { return i.val (); }
const V &val () const { return values[i.val ()]; }
operator bool () const { return (bool)i; }
void operator ++ () { i ++; }
void operator ++ (int) { i ++; }
};

352
lib/ullmanset.h Normal file
View File

@ -0,0 +1,352 @@
template<unsigned B> class ullmanset_iter;
template<unsigned B> class ullmanset_const_iter;
template<unsigned B>
class ullmanset
{
private:
friend class ullmanset_iter<B>;
friend class ullmanset_const_iter<B>;
class keypos
{
public:
unsigned key;
unsigned pos;
};
class data
{
public:
unsigned refcount;
unsigned size;
unsigned n;
keypos kp[1];
};
data *d;
void ref (data *newd) { assert (!d); d = newd; if (d) d->refcount ++; }
void unref ();
inline void delete_at_pos (unsigned p);
public:
typedef ullmanset_iter<B> iter;
typedef ullmanset_const_iter<B> const_iter;
public:
ullmanset () : d(0) { }
ullmanset (unsigned size);
ullmanset (const ullmanset &s) : d(0) { ref (s.d); }
ullmanset (copy, const ullmanset &s);
// ullmanset (const unsignedset &t);
ullmanset (const bitset &t);
ullmanset (reader &r);
~ullmanset () { unref (); }
ullmanset &operator = (const ullmanset &s) { unref (); ref (s.d); return *this; }
// ullmanset &operator = (const unsignedset &t);
ullmanset &operator = (const bitset &t);
unsigned size () const { return d ? d->size : 0; }
bool is_empty () const { assert (d); return d->n == 0; }
unsigned card () const { assert (d); return d->n; }
unsigned head () const { assert (d); assert (d->n > 0); return d->kp[0].key; }
bool operator == (const ullmanset &s);
bool operator != (const ullmanset &s) { return !operator == (s); }
void restore (unsigned old_card)
{
assert (d);
assert (d->n >= old_card);
d->n = old_card;
}
void clear () { if (d) { d->n = 0; } }
inline void push (unsigned k);
inline void operator += (unsigned k); // ??? should these be inline?
inline void operator -= (unsigned k);
void yank (unsigned k) { assert (operator % (k)); operator -= (k); }
void toggle (unsigned k)
{
if (operator % (k))
operator -= (k);
else
operator += (k);
}
ullmanset &operator |= (const ullmanset &s);
ullmanset &operator &= (const ullmanset &s);
ullmanset &operator ^= (const ullmanset &s);
bool operator % (unsigned k) const
{
assert (d);
assert ((k - B) >= 0);
assert ((k - B) < d->size);
unsigned p = d->kp[k - B].pos;
return p < d->n && d->kp[p].key == k;
}
bool operator () (unsigned k) const { return operator % (k); }
// always 0-based
unsigned nth (unsigned p) const { assert (d); assert (p < d->n); return d->kp[p].key; }
unsigned position (unsigned k) const { assert (operator % (k)); return d->kp[k - B].pos; }
void write_self (writer &w) const;
};
template<unsigned B> void
ullmanset<B>::unref ()
{
if (d && --d->refcount == 0)
{
delete [] (char *)d;
d = 0;
}
}
template<unsigned B> void
ullmanset<B>::delete_at_pos (unsigned p)
{
assert (d);
assert (p < d->n);
unsigned n = --d->n;
if (p != n)
{
unsigned ell = d->kp[n].key;
d->kp[ell - B].pos = p;
d->kp[p].key = ell;
}
}
template<unsigned B>
ullmanset<B>::ullmanset (unsigned size)
: d(0)
{
data *newd = (data *)new char[sizeof (data)
+ sizeof (keypos) * size
- sizeof (keypos)];
newd->refcount = 0;
newd->size = size;
newd->n = 0;
ref (newd);
}
template<unsigned B>
ullmanset<B>::ullmanset (copy, const ullmanset &s)
: d(0)
{
if (s.d)
{
unsigned bytes = (sizeof (data)
+ sizeof (keypos) * s.d->size
- sizeof (keypos));
data *newd = (data *)new char[bytes];
memcpy (newd, s.d, bytes);
newd->refcount = 0;
ref (newd);
}
}
template<unsigned B>
ullmanset<B>::ullmanset (reader &r)
: d(0)
{
unsigned size_ = r.read_unsigned ();
if (size_ > 0)
{
data *newd = (data *)new char[sizeof (data) + sizeof (keypos) * (size_ - 1)];
newd->refcount = 0;
newd->size = size_;
newd->n = 0;
ref (newd);
}
unsigned card_ = r.read_unsigned ();
for (unsigned i = 0; i < card_; i ++)
push (r.read_unsigned ());
}
template<unsigned B> bool
ullmanset<B>::operator == (const ullmanset &s)
{
assert (d);
assert (s.d);
if (d->n != s.d->n)
return 0;
for (iter i = *this; i; i ++)
{
if (!s(i.val ()))
return 0;
}
return 1;
}
template<unsigned B> void
ullmanset<B>::push (unsigned k)
{
assert (d);
assert (!operator % (k));
unsigned p = d->n ++;
d->kp[p].key = k;
d->kp[k - B].pos = p;
}
template<unsigned B> void
ullmanset<B>::operator += (unsigned k)
{
assert (d);
assert ((k - B) >= 0);
assert ((k - B) < d->size);
if (!operator % (k))
{
unsigned p = d->n ++;
d->kp[p].key = k;
d->kp[k - B].pos = p;
}
}
template<unsigned B> void
ullmanset<B>::operator -= (unsigned k)
{
assert (d);
assert ((k - B) >= 0);
assert ((k - B) < d->size);
if (operator % (k))
{
unsigned p = d->kp[k - B].pos;
delete_at_pos (p);
}
}
template<unsigned B> ullmanset<B> &
ullmanset<B>::operator |= (const ullmanset &s)
{
for (iter i = s; i; i ++)
operator += (i.val ());
}
template<unsigned B> ullmanset<B> &
ullmanset<B>::operator &= (const ullmanset<B> &s)
{
for (iter i = *this; i; i ++)
{
unsigned k = i.val ();
if (!s(k))
i.del ();
}
}
template<unsigned B> ullmanset<B> &
ullmanset<B>::operator ^= (const ullmanset<B> &s)
{
for (const_iter i = s; i; i ++)
{
int k = i.val ();
if (operator % (k))
operator -= (k);
else
push (k);
}
return *this;
}
template<unsigned B> void
ullmanset<B>::write_self (writer &w) const
{
write (w, size ());
write (w, card ());
for (const_iter i = *this; i; i ++)
write (w, i.val ());
}
template<unsigned B>
class ullmanset_iter
{
private:
ullmanset<B> &s;
unsigned i;
bool deleted;
public:
ullmanset_iter (ullmanset<B> &s_) : s(s_), i(0), deleted(0) { assert (s_.d); }
~ullmanset_iter () { }
void del () { assert (!deleted); assert (i < s.d->n); s.delete_at_pos (i); }
unsigned val () const { assert (!deleted); assert (i < s.d->n); return s.d->kp[i].key; }
unsigned pos () const { assert (!deleted); assert (i < s.d->n); return i; }
operator bool () const { assert (!deleted); return i < s.d->n; }
void operator ++ () { if (deleted) deleted = 0; else i ++; }
void operator ++ (int) { operator ++ (); }
};
template<unsigned B>
class ullmanset_const_iter
{
private:
const ullmanset<B> &s;
unsigned i;
public:
ullmanset_const_iter (const ullmanset<B> &s_) : s(s_), i(0) { assert (s_.d); }
~ullmanset_const_iter () { }
unsigned val () const { assert (i < s.d->n); return s.d->kp[i].key; }
unsigned pos () const { assert (i < s.d->n); return i; }
operator bool () const { return i < s.d->n; }
void operator ++ () { i ++; }
void operator ++ (int) { i ++; }
};
/* interoperating with other set types */
template<unsigned B>
set<unsigned> &operator |= (set<unsigned> &s, const ullmanset<B> &t)
{
for (ullmanset_const_iter<B> i = t; i; i ++)
s += i.val ();
return s;
}
template<unsigned B>
ullmanset<B> &operator |= (ullmanset<B> &s, const set<unsigned> &t)
{
for (set_const_iter<unsigned> i = t; i; i ++)
s += i.val ();
return s;
}
template<unsigned B>
ullmanset<B> &operator &= (ullmanset<B> &s, const set<unsigned> &t)
{
for (ullmanset_const_iter<B> i = s; i; i ++)
{
int k = i.val ();
if (!t(k))
i.del ();
}
return s;
}
template<unsigned B>
ullmanset<B> &operator ^= (ullmanset<B> &s, const set<unsigned> &t)
{
for (set_const_iter<unsigned> i = t; i; i ++)
{
int k = i.val ();
if (s % k)
s -= (k);
else
s.push (k);
}
return s;
}

83
lib/unionfind.h Normal file
View File

@ -0,0 +1,83 @@
template<unsigned B>
class unionfind
{
unsigned n_sets;
basedvector<unsigned, B> parent;
public:
unionfind (unsigned size);
unionfind (const unionfind &u) : n_sets(u.n_sets), parent(u.parent) { }
unionfind (copy, const unionfind &u) : n_sets(u.n_sets), parent(COPY, u.parent) { }
unionfind (reader &r);
~unionfind () { }
unsigned num_sets () const { return n_sets; }
void clear ();
void join (unsigned x, unsigned y);
unsigned find (unsigned x);
void write_self (writer &w) const;
};
template<unsigned B>
unionfind<B>::unionfind (unsigned size)
: n_sets(size),
parent(size)
{
for (unsigned i = 0; i < size; i ++)
parent[i + B] = i + B;
}
template<unsigned B>
unionfind<B>::unionfind (reader &r)
{
read (r, n_sets);
read (r, parent);
}
template<unsigned B> void
unionfind<B>::clear ()
{
unsigned size = parent.size ();
n_sets = size;
for (unsigned i = 0; i < size; i ++)
parent[i + B] = i + B;
}
template<unsigned B> void
unionfind<B>::join (unsigned x, unsigned y)
{
unsigned xp = find (x),
yp = find (y);
if (xp != yp)
{
n_sets --;
parent[yp] = xp;
}
}
template<unsigned B> unsigned
unionfind<B>::find (unsigned x)
{
unsigned p = parent[x];
while (parent[p] != p)
p = parent[p];
while (x != p)
{
unsigned xp = parent[x];
parent[x] = p;
x = xp;
}
return p;
}
template<unsigned B> void
unionfind<B>::write_self (writer &w) const
{
write (w, n_sets);
write (w, parent);
}

386
lib/vector.h Normal file
View File

@ -0,0 +1,386 @@
template<class T>
class vector
{
protected:
class data
{
public:
unsigned refcount;
unsigned n;
unsigned c;
T p[1];
};
data *d;
static data *alloc (unsigned n_, unsigned c_, unsigned initn, T *init);
void unref ();
void ref (data *newd) { assert (d == 0); d = newd; if (d) d->refcount ++; }
T &at (unsigned i) { return operator [] (i); }
const T &at (unsigned i) const { return operator [] (i); }
public:
vector () : d(0) { }
explicit vector (unsigned n_);
vector (const vector &v) : d(0) { ref (v.d); }
vector (const vector &v, const vector &u);
vector (copy, const vector &v);
vector (copy2, const vector &v);
vector (unsigned n_, T *p_);
vector (unsigned n_, const vector &v_);
explicit vector (reader &r);
~vector () { unref (); }
vector &operator = (const vector &v) { unref (); ref (v.d); return *this; }
bool operator < (const vector &v) const;
bool operator == (const vector &v) const;
bool operator % (unsigned i) { return d && i < d->n; }
T &operator [] (unsigned i) { assert (d); assert (i < d->n); return d->p[i]; }
const T &operator [] (unsigned i) const { assert (d); assert (i < d->n); return d->p[i]; }
const T &operator () (unsigned i) const { return operator [] (i); }
/* ??? break resize into grow_capacity/resize, and specialize this
to in-place ctor from v */
void append (const T &v)
{
if (!d)
reserve (4);
else if (d->n == d->c)
reserve (d->c * 2);
assert (d && d->n < d->c);
new (&d->p[d->n ++]) T (v);
}
const T &top () const
{
unsigned n = size ();
assert (n > 0);
return at (n - 1);
}
T pop ();
unsigned capacity () const { return d ? d->c : 0; }
unsigned size () const { return d ? d->n : 0; }
void resize (unsigned new_size);
void reserve (unsigned c);
void sort () { assert (d); sort (0, d->n); }
void sort (unsigned from, unsigned len);
template<typename C> void sort (unsigned from, unsigned len, C comp);
unsigned lower_bound (const T &v) const;
unsigned upper_bound (const T &v) const;
void write_self (writer &w) const;
hash_t hash_self () const;
};
template<class T> typename vector<T>::data *
vector<T>::alloc (unsigned n_, unsigned c_, unsigned initn, T *init)
{
if (c_ > 0)
{
data *d = (data *)new char[sizeof (data) + sizeof (T) * (c_ - 1)];
d->refcount = 1;
d->c = c_;
d->n = n_;
if (initn > n_)
initn = n_;
for (unsigned i = 0; i < initn; i ++)
new (&d->p[i]) T (init[i]);
for (unsigned i = initn; i < n_; i ++)
new (&d->p[i]) T ();
return d;
}
else
return 0;
}
template<class T> void
vector<T>::unref ()
{
if (d && -- d->refcount == 0)
{
for (unsigned i = 0; i < d->n; i ++)
d->p[i].~T ();
delete [] (char *)d;
}
d = 0;
}
template<class T>
vector<T>::vector (const vector &v, const vector &u)
: d(0)
{
if (v.d)
{
unsigned vn = v.d->n,
un = u.size ();
d = alloc (vn, vn + un, v.d->n, v.d->p);
d->n = vn + un;
for (unsigned i = 0; i < un; i ++)
new (&d->p[vn + i]) T (u[i]);
}
else
{
if (u.d)
d = alloc (u.d->n, u.d->n, u.d->n, u.d->p);
}
}
template<class T>
vector<T>::vector (copy, const vector &v)
: d(0)
{
if (v.d)
d = alloc (v.d->n, v.d->n, v.d->n, v.d->p);
}
template<class T>
vector<T>::vector (copy2, const vector &v)
: d(0)
{
if (v.d && v.d->n > 0)
{
unsigned n = v.d->n;
d = (data *)new char[sizeof (data) + sizeof (T) * (n - 1)];
d->refcount = 1;
d->c = n;
d->n = n;
for (unsigned i = 0; i < n; i ++)
new (&d->p[i]) T (COPY1, v.d->p[i]);
}
}
template<class T>
vector<T>::vector (unsigned n_)
: d(0)
{
d = alloc (n_, n_, 0, 0);
}
template<class T>
vector<T>::vector (reader &r)
: d(0)
{
unsigned n_;
read (r, n_);
if (n_ > 0)
{
d = (data *)new char[sizeof (data) + sizeof (T) * (n_ - 1)];
d->refcount = 1;
d->c = n_;
d->n = n_;
for (unsigned i = 0; i < n_; i ++)
ctor_read (r, &d->p[i]);
}
}
template<class T>
vector<T>::vector (unsigned n_, T *p_)
: d(0)
{
d = alloc (n_, n_, n_, p_);
}
template<class T>
vector<T>::vector (unsigned n_, const vector &v)
: d(0)
{
if (v.d)
d = alloc (n_, n_, v.d->n, v.d->p);
else
d = alloc (n_, n_, 0, 0);
}
template<class T> bool
vector<T>::operator < (const vector &v) const
{
unsigned n = size (),
vn = v.size ();
if (n < vn)
return 1;
else if (n > vn)
return 0;
for (unsigned i = 0; i < n; i ++)
{
if (at (i) < v[i])
return 1;
else if (at (i) > v[i])
return 0;
}
return 0;
}
template<class T> bool
vector<T>::operator == (const vector &v) const
{
unsigned n = size ();
if (n != v.size ())
return 0;
for (unsigned i = 0; i < n; i ++)
{
if (at (i) != v[i])
return 0;
}
return 1;
}
template<class T> T
vector<T>::pop ()
{
unsigned n = size ();
assert (n > 0);
T tmp = at (n - 1);
resize (n - 1);
return tmp;
}
template<class T> void
vector<T>::reserve (unsigned newc)
{
if (newc <= capacity ())
return;
data *newd;
if (d)
newd = alloc (d->n, newc, d->n, d->p);
else
newd = alloc (0, newc, 0, 0);
unref ();
d = newd;
}
template<class T> void
vector<T>::resize (unsigned new_size)
{
unsigned n = size ();
if (new_size == n)
return;
reserve (new_size);
assert (d);
assert (new_size <= capacity ());
if (new_size < n)
{
for (unsigned i = new_size; i < n; i ++)
d->p[i].~T ();
}
else
{
for (unsigned i = n; i < new_size; i ++)
new (&d->p[i]) T ();
}
d->n = new_size;
}
template<class T> void
vector<T>::sort (unsigned from, unsigned len)
{
assert (d);
assert (from < d->n);
assert (from + len <= d->n);
std::sort (&d->p[from], &d->p[from + len]);
}
template<class T> template<typename C> void
vector<T>::sort (unsigned from, unsigned len, C comp)
{
assert (d);
assert (from < d->n);
assert (from + len <= d->n);
std::sort (&d->p[from], &d->p[from + len], comp);
}
template<class T> void
vector<T>::write_self (writer &w) const
{
if (d)
{
write (w, d->n);
for (unsigned i = 0; i < d->n; i ++)
write (w, d->p[i]);
}
else
{
unsigned n = 0;
write (w, n);
}
}
template<class T> hash_t
vector<T>::hash_self () const
{
unsigned n = size ();
hash_t h = hash (n);
for (unsigned i = 0; i < n; i ++)
h = hash_combine (h, hash (d->p[i]));
return h;
}
template<class T> unsigned
vector<T>::lower_bound (const T &v) const
{
T *r = std::lower_bound (&d->p[0], &d->p[d->n], v);
return r - &d->p[0];
}
template<class T> unsigned
vector<T>::upper_bound (const T &v) const
{
T *r = std::upper_bound (&d->p[0], &d->p[d->n], v);
return r - &d->p[0];
}
template<class T, unsigned B>
class basedvector : public vector<T>
{
public:
basedvector () { }
explicit basedvector (unsigned n_) : vector<T>(n_) { }
explicit basedvector (vector<T> &v_) : vector<T>(v_) { }
basedvector (unsigned n_, T *p_) : vector<T>(n_, p_) { }
basedvector (unsigned n_, const vector<T> &v_) : vector<T>(n_, v_) { }
basedvector (copy, const vector<T> &v_) : vector<T>(COPY, v_) { }
basedvector (copy2, const vector<T> &v_) : vector<T>(COPY2, v_) { }
basedvector (const vector<T> &v_, const vector<T> &u_) : vector<T>(v_, u_) { }
explicit basedvector (reader &r) : vector<T>(r) { }
~basedvector () { }
vector<T> &operator = (const vector<T> &v) { vector<T>::operator = (v); }
bool operator % (unsigned i) { return vector<T>::operator % (i - B); }
T &operator [] (unsigned i) { return vector<T>::operator [] (i - B); }
const T &operator [] (unsigned i) const { return vector<T>::operator [] (i - B); }
const T &operator () (unsigned i) const { return vector<T>::operator () (i - B); }
void sort () { vector<T>::sort (); }
void sort (unsigned from, unsigned len) { vector<T>::sort (from - B, len); }
template<typename C> void sort (unsigned from, unsigned len, C comp) { vector<T>::sort (from - B, len, comp); }
unsigned lower_bound (const T &v) const { return vector<T>::lower_bound (v) + B; }
unsigned upper_bound (const T &v) const { return vector<T>::upper_bound (v) + B; }
};

8
main.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <knotkit.h>
int
main ()
{
}

View File

@ -0,0 +1 @@
dadbcda

View File

@ -0,0 +1,3 @@
eaebdeac
eaecdeab
ebbccdaeb

View File

@ -0,0 +1,8 @@
fafbdeafc
fafbdefac
fafbdfeac
fbbdceafbd
fbccdefacb
fbccdefcab
fcbbbcdefab
fcbbbceafbd

View File

@ -0,0 +1 @@
fcbbbcDEfAb

View File

@ -0,0 +1,14 @@
gagbdefagc
gagbdfagce
gagbefgadc
gagbegfadc
gagcefgabd
gagcefgbad
gagdefgabc
gbbecdefgab
gbbeceafbgd
gbbeceafgbd
gbbeceagfbd
gbcddefacgb
gbcddefagbc
gcbbcceafbgd

View File

@ -0,0 +1,2 @@
gbbecDEfGAb
gbbecDEfGaB

View File

@ -0,0 +1,39 @@
hahbdegahcf
hahbdfagche
hahbdfaghce
hahbdfahgce
hahbdgeahcf
hahbefgahcd
hahbefgahdc
hahbefghacd
hahbefghadc
hahbeghfadc
hahbehgfadc
hahcdefghab
hahcdfaghbe
hahcdfgbhae
hahcdgfbhae
hahcefghbad
hahcefhgbad
hahcfehgbad
hbbfcdegfhab
hbbfceafgbhd
hbbfceagbhdf
hbbfceagfbhd
hbbfcfaghbed
hbbfcfahgbed
hbbfcfegahdb
hbcedefahgbc
hbcedefahgcb
hbcedegachbf
hbcedegcahbf
hbddefghadbc
hbddefghadcb
hbddefghdabc
hcbbdceagbhdf
hcbcccdfgheab
hcbcccfaghbed
hcbcccfaghebd
hcbcccfghadeb
hcbdbceagbhdf
hdbbbbceagbhdf

View File

@ -0,0 +1,11 @@
hahbdFaGCHE
hahbdFagChe
hahbdFaGHCE
hbbfcDEgFHAb
hbbfcDEgFHaB
hcbcccDFgHEAb
hcbcccDFgHEaB
hcbcccdFgHEab
hcbdbceaGbHDF
hdbbbbcEaGBHDF
hdbbbbcEaGBhDf

View File

@ -0,0 +1,96 @@
iaibdegahcif
iaibdegahicf
iaibdegaihcf
iaibdfahcieg
iaibdfahgcie
iaibdfgahiec
iaibdgahicfe
iaibdgaihcfe
iaibdgeahicf
iaibdgeaihcf
iaibdgfahiec
iaibefgaihcd
iaibefgaihdc
iaibefghacid
iaibefghaidc
iaibefhadicg
iaibefhgaidc
iaibegfhacid
iaibeghaidcf
iaibeghfaicd
iaibeghfaidc
iaibehgaidcf
iaibfghiaecd
iaibfghiaedc
iaibfhigadec
iaibfhigaedc
iaibfihgaedc
iaicdehgibaf
iaicegfhaibd
iaicegibhadf
iaicegibhdaf
iaicegihadbf
iaicfghiabed
iaicfghibaed
iaicfgihabed
iaicfgihbaed
iaichgfbaied
iaidfghiabce
iaidfghiacbe
iaidfhgibace
iaiefghiabcd
ibbgcdeghiabf
ibbgcdfghiabe
ibbgcdfhgieab
ibbgceafhbidg
ibbgceagbhdif
ibbgceagbhidf
ibbgceagbihdf
ibbgceahfbidg
ibbgcefghiadb
ibbgcefhgiadb
ibbgcfaghbeid
ibbgcfaghbide
ibbgcfaghbied
ibbgcfaghibde
ibbgcfaghibed
ibbgcfahgbeid
ibbgcfahigbed
ibbgcfaihgbed
ibbgcfegaihdb
ibcfdefcghiab
ibcfdefgahibc
ibcfdefgahicb
ibcfdegachbif
ibcfdegachibf
ibcfdegacihbf
ibcfdegaibhcf
ibcfdegaichbf
ibcfdegcahbif
ibcfdegcahibf
ibcfdegcaihbf
ibcfdegchbiaf
ibcfdfhagbice
ibcfdfhaibecg
ibdeefghadbic
ibdeefghadicb
ibdeefghaibcd
ibdeefghaidcb
ibdeefghbaicd
ibdeefghcabid
ibdeefhgdaicb
ibdeefigcahdb
ibdeefigchbda
icbbeceagbhdif
icbbeceagbhidf
icbbeceagbihdf
icbcdcdfgihabe
icbcdcfaghbeid
icbcdcfaghbide
icbcdcfaghbied
icbcdcfaghebid
icbcdcfgiadheb
icbdcceagbhdif
icbebcdhfiabeg
icbebceafhbidg
idbbbcceagbhdif

View File

@ -0,0 +1,36 @@
iaibdeGaHCIF
iaibdeGahCif
iaibdegaHcIF
iaibdeGaHICF
iaibeGFHaCID
iaibeGFhaCid
iaicdehgIbaF
iaicEGfHAiBD
ibbgcDEgHIAbF
ibbgcDEgHIaBF
ibbgcdEgHIabF
ibbgcDFgHIAbE
ibbgcDFgHIaBE
ibbgcdFgHIabE
ibbgcDFhGIEAb
ibbgcdFhGIEab
ibbgceaGbHDIF
ibbgceaGbhDif
ibbgceagbHdIF
ibbgceaGbHIDF
ibcfdEFcGHIAB
ibcfdEFcgHiAB
ibcfdEfcGhIaB
ibcfdEfcgHiaB
ibcfdeFGahIbC
ibdeefiGcaHDb
ibdeeFiGchBDa
icbbecEaGBHDIF
icbbecEaGBhDif
icbbeceagbHdIF
icbcdcDFgIHAbE
icbcdcDFgIHaBE
icbcdcdFgIHabE
icbdcceaGbHDIF
icbebcdHfIabEG
icbebcdHfiabeG

297
mtlinks/hyperbolic_data_10a Normal file
View File

@ -0,0 +1,297 @@
jajbdegahicjf
jajbdegaicjfh
jajbdegaihcjf
jajbdehaijcgf
jajbdehajicgf
jajbdfagicjeh
jajbdfahciejg
jajbdfahcijeg
jajbdfahcjieg
jajbdfaigcjeh
jajbdfgahjiec
jajbdfiahjceg
jajbdgahicjef
jajbdgahicjfe
jajbdgahijcef
jajbdgahijcfe
jajbdgaihcfje
jajbdgaijhcfe
jajbdgajihcfe
jajbdgeaicjfh
jajbdgfahjiec
jajbdheaijcgf
jajbdheajicgf
jajbdifahjceg
jajbefghajidc
jajbefgiacjdh
jajbefgiahcjd
jajbefhadijcg
jajbefhadjicg
jajbefhajcidg
jajbefhajdicg
jajbefhgajidc
jajbefhiajcdg
jajbefhiajdcg
jajbefhjadicg
jajbegfahijdc
jajbegfiacjdh
jajbegfiahcjd
jajbeghadijfc
jajbeghaidcjf
jajbeghaijcdf
jajbeghaijdcf
jajbeghajicdf
jajbeghajidcf
jajbegiahcjdf
jajbegiahdjfc
jajbegiahjdfc
jajbehfadijcg
jajbehfadjicg
jajbehgadijfc
jajbehgaidcjf
jajbehgajdicf
jajbehifajdcg
jajbeihfajdcg
jajbfghiaejdc
jajbfghiajcde
jajbfghiajced
jajbfghiajedc
jajbfghijacde
jajbfghijaced
jajbfghijaedc
jajbfghjiadce
jajbfgihaejdc
jajbfgihajedc
jajbfgihjaedc
jajbfhgiadjec
jajbfhgiajced
jajbfhigaejcd
jajbfhigaejdc
jajbfhijgaecd
jajbfhijgaedc
jajbfhjiadceg
jajbfijghaedc
jajbfijhgaedc
jajbfjihgaedc
jajcdeghijabf
jajcdeghjiabf
jajcdfahbijeg
jajcdgahibjef
jajcdgahibjfe
jajcdgahijbef
jajcdgahijbfe
jajcdghbijaef
jajcdghbijafe
jajcdgihbjeaf
jajcdhgbijaef
jajcdhgbijafe
jajcdighbjaef
jajcefgihjabd
jajcefjihdabg
jajcegahijdbf
jajcegahjidbf
jajceghaibjdf
jajceghbiajfd
jajceghibjadf
jajcegiahjbdf
jajcegihbjadf
jajcehgaidjbf
jajcehgibjafd
jajcehjgaibdf
jajcehjgbiafd
jajceifbhjdag
jajceigahjdbf
jajceighbjdaf
jajceihgbjdaf
jajcejghibdaf
jajcfghiabjde
jajcfghiabjed
jajcfghibajed
jajcfghijbade
jajcfghijbaed
jajcfgijhbaed
jajcfgjihbaed
jajcgfhijbade
jajcgfhijbaed
jajcgfijhbaed
jajcgfjihbaed
jajchfgibjade
jajchfgibjaed
jajchigabjdef
jajdefghijabc
jajdeghaijcbf
jajdehgaijcbf
jbbhcdeghiabjf
jbbhcdehgijabf
jbbhcdehgjiabf
jbbhcdfghiabje
jbbhcdfighjeab
jbbhcdfigjheab
jbbhcdfihgjeab
jbbhceafhbidjg
jbbhceafhbijdg
jbbhceafhbjidg
jbbhceagbhidjf
jbbhceagbidjfh
jbbhceagbihdjf
jbbhceaghbijfd
jbbhceahbijdgf
jbbhceahbjidgf
jbbhceahfbidjg
jbbhceahfbijdg
jbbhceahfbjidg
jbbhceahgbijfd
jbbhcefghjaidb
jbbhcefhgjaidb
jbbhcefhigjadb
jbbhcefihgjadb
jbbhcfaghbjide
jbbhcfaghbjied
jbbhcfaghibdje
jbbhcfaghibjed
jbbhcfaghjbied
jbbhcfagibejdh
jbbhcfagihbjed
jbbhcfahgibdje
jbbhcfahibjedg
jbbhcfahigbejd
jbbhcfahigbjde
jbbhcfahigbjed
jbbhcfaigbejdh
jbbhcfaigbhejd
jbbhcfaighbejd
jbbhcfaihbjedg
jbbhcfaihgbejd
jbbhcfehajidgb
jbbhcfigajhdbe
jbbhcgahijbfde
jbbhcgahijbfed
jbbhcgaijhbefd
jbbhcgaijhbfed
jbbhcgajihbfed
jbbhcgehaijdbf
jbbhcgehajidbf
jbcgdefajhibcg
jbcgdefajhicbg
jbcgdefcihjbag
jbcgdefgaihjbc
jbcgdefgaihjcb
jbcgdefhgjiacb
jbcgdegachibjf
jbcgdegacibjfh
jbcgdegacihbjf
jbcgdegajbicfh
jbcgdegajcibfh
jbcgdegajhibfc
jbcgdegajhicfb
jbcgdegajihbfc
jbcgdegajihcfb
jbcgdegcahibjf
jbcgdegcaibjfh
jbcgdegcaihbjf
jbcgdegchbiajf
jbcgdegfihcjab
jbcgdeghijcfab
jbcgdehacijbgf
jbcgdehacjibgf
jbcgdehcaijbgf
jbcgdehcajibgf
jbcgdehcgiajfb
jbcgdehgaibjfc
jbcgdehgaicjfb
jbcgdfhagbjice
jbcgdfhaibjecg
jbcgdfhaicjbeg
jbcgdfhajbeicg
jbcgdfhajcibge
jbcgdfhbgjaice
jbcgdfhbiajcge
jbcgdfhbijaecg
jbcgdfhcjaibge
jbdfefghadjicb
jbdfefghajbicd
jbdfefghajbidc
jbdfefghajdicb
jbdfefghajicbd
jbdfefghajicdb
jbdfefgiadbjch
jbdfefgiadhbjc
jbdfefgibadjch
jbdfefgicabjdh
jbdfefgidabjch
jbdfefhgajicbd
jbdfefhiadjbcg
jbdfefhiadjcbg
jbdfefhidajbcg
jbdfefigajcdbh
jbdfefigdhcajb
jbdfefighacdjb
jbdfefjgdihcab
jbdfegjhaidbfc
jbeefcehbaidjg
jbeefcehbaijdg
jbeefdehbaijcg
jbeefdghicejab
jbeefdgihecjab
jbeefdgjhaibec
jbeefghijaebcd
jbeefghijaebdc
jbeefghijaedcb
jbeefghijbaecd
jbeefghijeabcd
jbeefghjiaecbd
jbeefghjicabed
jbeefhjgiacebd
jcbbfceagbhidjf
jcbbfceagbidjfh
jcbbfceagbihdjf
jcbbfceahbijdgf
jcbbfceahbjidgf
jcbcecdfgihabje
jcbcecfaghbjide
jcbcecfaghbjied
jcbcecfagibejdh
jcbcecfagiebjdh
jcbcecfahibjedg
jcbcecfahigbjde
jcbcecfahjibdge
jcbcecfgiahebjd
jcbcecfgjaihebd
jcbddcdghijeabf
jcbddcdghijfabe
jcbddceagbidjfh
jcbddceghijfadb
jcbddcegihjfadb
jcbddcgahijbfde
jcbddcgahijbfed
jcbddcgahijebdf
jcbddcgahijfbde
jcbddcgaihjebdf
jcbddcghijadfbe
jcbddcghijaefbd
jcbeccdhfiabgje
jcbecceafhbidjg
jcbecceaghbidjf
jcbecceahbijdgf
jcbecceahbijgdf
jcbfbceagbidjfh
jcbfbcfaigbjdeh
jcccddeghijbfca
jcccddeghjibcfa
jcccddeghjicbfa
jcccddghaijcbfe
jcccddghaijebcf
jcccddghaijfbce
jcccddghbijafce
jcccddghijbaefc
jcccddgiahjbfce
jdbbbdceagbidjfh
jdbbccceahbijdgf
jdbbccceahbijgdf
jdbbdbceagbidjfh
jdbcbccdfhgijabe
jdbcbccdfhiejabg
jdbccbcfagibejdh
jdbccbcfagiebjdh
jdbccbcfaigbjdeh
jebbbbbceagbidjfh

155
mtlinks/hyperbolic_data_10n Normal file
View File

@ -0,0 +1,155 @@
jajbdeGaHICJF
jajbdeGahiCjf
jajbdeGaICJFH
jajbdFaGICJEH
jajbdFagiCjeh
jajbdfaGIcJEH
jajbdFaHCIEJG
jajbdFahCiejg
jajbdfaHcIEJG
jajbdFaHCIJEG
jajbdFahCijeg
jajbdfaHcIJEG
jajbdFaHCJIEG
jajbdFIaHJCEG
jajbdGaHICJEF
jajbdGahiCjef
jajbdgaHIcJEF
jajbdGaHICJFE
jajbdGahiCjfe
jajbdgaHIcJFE
jajbdGaHIJCEF
jajbdGaHIJCFE
jajbdIFaHJCEG
jajbeGfahiJdC
jajbeGHaIDCJF
jajbeGHaiDCjf
jajbeGHaIJCDF
jajbeGHaIJDCF
jajbeGHaijDCf
jajbeghaIJdcF
jajbfHGIaDJEC
jajbfHgIadJEC
jajbfhGiaDjec
jajcdeghIJabF
jajcdeghJIabF
jajcdfaHbIJEG
jajcdgihbJeaF
jajcEFgIHjABD
jajceghibJadF
jajcegihbJadF
jajcEHgAIdjBF
jajcEIgAHjdBf
jbbhcDEgHIAbJF
jbbhcDEgHIaBJF
jbbhcdEgHIabJF
jbbhcDEhGIJAbF
jbbhcDEhGIJaBF
jbbhcdEhGIJabF
jbbhcDEhGJIAbF
jbbhcDEhGJIaBF
jbbhcdEhGJIabF
jbbhcDFgHIAbJE
jbbhcDFgHIaBJE
jbbhcdFgHIabJE
jbbhcDFiGHJEAb
jbbhcdFiGHJEab
jbbhcdFighJeab
jbbhcdfiGHjEab
jbbhcDFiGJHEAb
jbbhcdFiGJHEab
jbbhcDFiHGJEAb
jbbhcdFiHGJEab
jbbhceafHbIDJG
jbbhceafHbiDjg
jbbhceafhbIdJG
jbbhceafHbIJDG
jbbhceaGbHIDJF
jbbhceaGbhiDjf
jbbhceagbHIdJF
jbbhceaGbIDJFH
jbbhcEaGHBIJFD
jbbhcEaHGBIJFD
jbbhcEFihGJAdb
jbbhcfaHGIbDJE
jbbhcfaHGibDje
jbbhcfahgIbdJE
jbbhcFaIGBHEJD
jbbhcFaIgBheJD
jbbhcfaIGbHEJD
jbbhcfaIgbheJD
jbbhcfaIghbeJD
jbcgdeFajHiBcg
jbcgdeFajHibCg
jbcgdeFajhIBcG
jbcgdeFajhIbCG
jbcgdEFcIHJBAG
jbcgdEFciHjBAg
jbcgdEfcIhJbAG
jbcgdEfcIhjbAg
jbcgdEfciHjBag
jbcgdEfciHjbAg
jbcgdefcihJbaG
jbcgdeFgaIhjBc
jbcgdEgfIhcjAb
jbcgdfHaGbjICE
jbdfefIgajcdBH
jbdfeFIGdHCAJB
jbdfefjGdiHCab
jbdfeGjHaIDBFc
jbeefCEHBaIDJG
jbeefCEHBaiDjg
jbeefCEhBaIdJG
jbeefCEhBaidjg
jbeefCEhBaijdg
jbeefDGHICeJAB
jbeefDghIcejAb
jcbbfcEaGBHIDJF
jcbbfcEaGBhiDjf
jcbbfceagbHIdJF
jcbcecDFgIHAbJE
jcbcecDFgIHaBJE
jcbcecdFgIHabJE
jcbcecFaHJIBDGE
jcbcecfaHJIbDGE
jcbcecfaHjibDGe
jcbddcDGhIJEAbF
jcbddcDGhIJEaBF
jcbddcdGhIJEabF
jcbddcDGhIJFAbE
jcbddcDGhIJFaBE
jcbddcdGhIJFabE
jcbddceaGbIDJFH
jcbddcEGhiJFadB
jcbddcgaIHJEbDF
jcbeccdHfIabGJE
jcbecceaHbIJDGF
jcbecceaHbijDgf
jcbecceahbIJdGF
jcbecceaHbIJGDF
jcbfbceaGbIDJFH
jcbfbceaGbiDjfh
jcbfbcFaIGBJDEH
jcbfbcfaIGbJDEH
jcccddEGHiJBFCa
jcccddEGhIjBfCa
jcccddEgHiJbFcA
jcccddEghJibcfA
jdbbcccEaHBIJDGF
jdbbcccEaHBijDgf
jdbbccceahbIJdGF
jdbbdbcEaGBIDJFH
jdbbdbcEaGBIDjFh
jdbbdbcEaGBiDjfh
jdbbdbceagbIdJFH
jdbbdbceagbIdjFh
jdbcbccDFHgIjAbE
jdbcbccDFHgIjaBE
jdbcbccDFhGIJAbE
jdbcbccdFhGIJabE
jdbcbccDFhIEJAbG
jdbcbccDFhIEJaBG
jdbccbcFaIGBJDEH
jdbccbcfaIGbJDEH
jebbbbbcEaGBIDJFH
jebbbbbcEaGBIDjFh

915
mtlinks/hyperbolic_data_11a Normal file
View File

@ -0,0 +1,915 @@
kakbdegahjckfi
kakbdegaicjfkh
kakbdegaicjkfh
kakbdegaickjfh
kakbdegajhckfi
kakbdehaijcgkf
kakbdehaijckfg
kakbdehaijckgf
kakbdehaijkcfg
kakbdehaijkcgf
kakbdehajicgkf
kakbdehajkicgf
kakbdehakjicgf
kakbdfagicjekh
kakbdfagicjkeh
kakbdfagickjeh
kakbdfahcjekgi
kakbdfahcjiekg
kakbdfahicjkge
kakbdfaicjkehg
kakbdfaickjehg
kakbdfaigcjkeh
kakbdfaigckjeh
kakbdfaihcjkge
kakbdfaijcekgh
kakbdfajicekgh
kakbdfgaikjehc
kakbdfhaijkecg
kakbdfhaikjecg
kakbdfiahjcekg
kakbdgahickjef
kakbdgahickjfe
kakbdgahijcekf
kakbdgahijckfe
kakbdgahikcjfe
kakbdgahjcfkei
kakbdgahjickfe
kakbdgaihjcekf
kakbdgaijckfeh
kakbdgaijhckef
kakbdgaijhckfe
kakbdgajhcfkei
kakbdgajhcifke
kakbdgajhicfke
kakbdgajickfeh
kakbdgajihcfke
kakbdgajkicfhe
kakbdgeahjckfi
kakbdgeaicjkfh
kakbdgeaickjfh
kakbdgeajhckfi
kakbdgfaikjehc
kakbdghaijkefc
kakbdghaijkfec
kakbdhaijkcgef
kakbdhaijkcgfe
kakbdhajkicfge
kakbdhajkicgfe
kakbdhakjicgfe
kakbdheaijckfg
kakbdheaijckgf
kakbdheaijkcfg
kakbdheaijkcgf
kakbdheajkicgf
kakbdheakjicgf
kakbdhfaijkecg
kakbdhfaikjecg
kakbdhgaijkefc
kakbdhgaijkfec
kakbdifahjcekg
kakbefgakijcdh
kakbefgakijdch
kakbefghaijkcd
kakbefgiacjkdh
kakbefgiackjdh
kakbefgiajdkch
kakbefgiakjdhc
kakbefgjahckdi
kakbefgjaidkch
kakbefgkaijcdh
kakbefgkaijdch
kakbefhakijcgd
kakbefhakijdgc
kakbefhakjicgd
kakbefhakjidgc
kakbefhiajcdkg
kakbefhiajdckg
kakbefhiajkdcg
kakbefhiakcjdg
kakbefhiakjdcg
kakbefhjakidcg
kakbefhkaijdgc
kakbefhkajidgc
kakbefiadjkchg
kakbefiadkjchg
kakbefigakdjch
kakbefihajkdcg
kakbefihakjdcg
kakbefjhaidkcg
kakbefjhakdgci
kakbegfajikcdh
kakbegfiacjkdh
kakbegfiackjdh
kakbegfjahckdi
kakbeghajdckfi
kakbeghajicdkf
kakbeghajidckf
kakbeghajkicdf
kakbeghajkidcf
kakbeghakjicdf
kakbeghakjidcf
kakbeghiajckfd
kakbeghiajkdfc
kakbegiahckjdf
kakbegiajckfdh
kakbegiajdkcfh
kakbegiakdjchf
kakbegifadjkch
kakbegifadkjch
kakbegifakcjdh
kakbegifakdjch
kakbegihajkdfc
kakbegjadikcfh
kakbegjahdkfci
kakbegjahidkcf
kakbegjahkdfci
kakbegjakidfch
kakbegjhacfkdi
kakbegjhaikfcd
kakbegjhaikfdc
kakbegkiajcdfh
kakbehfiajckdg
kakbehgajdckfi
kakbehgajdickf
kakbehgfaijkdc
kakbehgiadjkfc
kakbehgiajckfd
kakbehgiajkfdc
kakbehiajkdcgf
kakbehiakjdcgf
kakbehifadjkgc
kakbehifajkcdg
kakbehifajkdcg
kakbehifakjcdg
kakbehifakjdcg
kakbehigajkcfd
kakbehjakidfcg
kakbehjfaickdg
kakbehjfaidkgc
kakbehjfaikdgc
kakbehjgaikfcd
kakbehjgaikfdc
kakbeifadjkchg
kakbeifadkjchg
kakbeifahjdkgc
kakbeifgadjkch
kakbeifhajdkcg
kakbeigahjdkcf
kakbeigakdjchf
kakbeigakjdfch
kakbeigfadjkch
kakbeighacjkfd
kakbeighajdkfc
kakbeighajkfcd
kakbeihajkdcgf
kakbeihakjdcgf
kakbeihfadjkgc
kakbeihgajdkfc
kakbeihgajkcfd
kakbeijahcdkgf
kakbeijakcdfgh
kakbeikgajdcfh
kakbejgadikcfh
kakbfghiakcjde
kakbfghiakcjed
kakbfghiakjdce
kakbfghiakjdec
kakbfghiakjedc
kakbfghijacdke
kakbfghijacked
kakbfghijadcke
kakbfghijakdec
kakbfghijakedc
kakbfghikajdec
kakbfghikajedc
kakbfghjaeckdi
kakbfghjakdcei
kakbfghjiacked
kakbfghkiajecd
kakbfgihakjdce
kakbfgijaekcdh
kakbfgijaekdch
kakbfgijhakedc
kakbfgjhiakecd
kakbfgjihakedc
kakbfgjkiadech
kakbfhgiadkjec
kakbfhgiakcjed
kakbfhgijacked
kakbfhgjaeckdi
kakbfhgjiacked
kakbfhigjadcke
kakbfhijakecdg
kakbfhijakedcg
kakbfhijgaekdc
kakbfhijgakcde
kakbfhijgakced
kakbfhijgakedc
kakbfhjgiadkec
kakbfhjigaekdc
kakbfhjigakedc
kakbfhkiadcjeg
kakbfhkiajecgd
kakbfhkjiacged
kakbfighakjecd
kakbfigjakdech
kakbfigjhadkce
kakbfihjgadkec
kakbfihjgakced
kakbfijgaekdch
kakbfijghaekcd
kakbfijghaekdc
kakbfijhakdecg
kakbfijhakedcg
kakbfijhgaekcd
kakbfijhgaekdc
kakbfikhadjecg
kakbfikjgadceh
kakbfjigaekdch
kakbfjihakedcg
kakbgeficajkdh
kakbgehkiajcfd
kakbgejkiadcfh
kakbghijkafcde
kakbghijkafced
kakbghijkafedc
kakbghikjafdce
kakbghjikafedc
kakbgijkcadefh
kakbgijkhaefcd
kakbgijkhaefdc
kakbgijkhafecd
kakbgijkhafedc
kakbgikhjadfce
kakbgjkhiafedc
kakbgjkihafedc
kakbgkjihafedc
kakcdeihjkbagf
kakcdeihkjbagf
kakcdfagibjkeh
kakcdfahibjkge
kakcdfaihbjkge
kakcdfaijbekgh
kakcdfajibekgh
kakcdfjhikbeag
kakcdfjihkbeag
kakcdgahijbkfe
kakcdgahjibkfe
kakcdgaijbkfeh
kakcdgajibkfeh
kakcdghbijakfe
kakcdghbjiakfe
kakcdhajkibfge
kakcdhgbijakfe
kakcdhgbjiakfe
kakcefghikjbad
kakcefgjikdbah
kakcefijhkbadg
kakcefjhikdbag
kakcefjihkbadg
kakcefkhidjbag
kakcefkihjbagd
kakceghjbiakfd
kakcegiajkbfdh
kakcegjaibkfdh
kakcegjbiakdfh
kakcehfbijkadg
kakcehfbikjadg
kakcehfiajkbdg
kakcehfiakjbdg
kakcehfjaibkdg
kakcehgbijkafd
kakcehgiajkbfd
kakcehgjbiakdf
kakcehgjiakfbd
kakcehigajbkfd
kakcehijadbkfg
kakcehijbdakgf
kakcehjbidkafg
kakcehjiadkbfg
kakcehkbijadfg
kakcehkbijadgf
kakcehkbijdafg
kakcehkbijdagf
kakcehkiajdbfg
kakcehkiajdbgf
kakcehkjiadfbg
kakceiahjkbdgf
kakceiahkjbdgf
kakceigajkdfbh
kakceighbkjfad
kakceigjbkdfah
kakceikhbdjfag
kakcejgaidkfbh
kakcfekhijdbag
kakcfghijbaked
kakcfghjibaked
kakcfgijabkedh
kakcfgijbakedh
kakcfgjiabkedh
kakcfgjibakedh
kakcfhgijakbed
kakcfhgjiakbed
kakcfhigbjkade
kakcfhikbjeadg
kakcfhjkbieagd
kakcfhjkiaebgd
kakcfhkiajbdge
kakcfhkibjadeg
kakcfhkibjaedg
kakcfhkijadbeg
kakcfhkjbidaeg
kakcfhkjbieagd
kakcfhkjiadbeg
kakcfhkjiaebgd
kakcfigkbjdeah
kakcfihgbjkaed
kakcfihkbjdaeg
kakcfikgbjdaeh
kakcfikhbjdeag
kakcfikhbjedag
kakcgeiakjbfdh
kakcgfhjibaked
kakcghijkabfde
kakcghijkabfed
kakcghijkbafde
kakcghijkbafed
kakcghjkiabefd
kakcghjkiabfed
kakcghjkibaefd
kakcghjkibafed
kakcghkjiabfed
kakcghkjibafed
kakcgihjkbdafe
kakcgihkjbdafe
kakchfijbkeadg
kakchfjibkeadg
kakcihfbajkedg
kakcihfbakjedg
kakcihgbajkefd
kakcihgjbakfde
kakcihgjbakfed
kakdfhikbjaceg
kakdfhjaikcbeg
kakdghijkabcfe
kakdghijkacbfe
kakdghijkcbafe
kakdghikjabcfe
kakdghikjacbfe
kakdghikjcbafe
kakdgihjkbacfe
kakdgihkjbacfe
kakdhgikjcbafe
kakeghijkabcdf
kakeghijkabdcf
kakeghijkbadcf
kakfghijkabcde
kbbicdeghjabkfi
kbbicdehgijabkf
kbbicdehgjiabkf
kbbicdehijkabgf
kbbicdehikjabgf
kbbicdfghjabkei
kbbicdfhijkabeg
kbbicdfhjgkabei
kbbicdfhjikabeg
kbbicdfihjkeabg
kbbicdfjghkieab
kbbicdfjhgkieab
kbbicdfjhkiegab
kbbicdgfiabjkeh
kbbicdgfiabkjeh
kbbicdghijkabef
kbbicdgihjkeabf
kbbiceafhbijdkg
kbbiceafhbjdkgi
kbbiceafhbjidkg
kbbiceafibjkdhg
kbbiceafibkjdhg
kbbiceagbhjdkfi
kbbiceagbidjfkh
kbbiceagbidjkfh
kbbiceagbidkjfh
kbbiceagbjhdkfi
kbbiceaghbikjfd
kbbiceagjbikdfh
kbbiceahbijdgkf
kbbiceahbijdkfg
kbbiceahbijdkgf
kbbiceahbijkdfg
kbbiceahbijkdgf
kbbiceahbjidgkf
kbbiceahbjkidgf
kbbiceahbkjidgf
kbbiceahfbijdkg
kbbiceahfbjdkgi
kbbiceahfbjidkg
kbbiceahgbikjfd
kbbiceaifbjkdhg
kbbiceaifbkjdhg
kbbiceajgbikdfh
kbbicefgikajdhb
kbbicefhigkajdb
kbbicefhijkadbg
kbbicefigkajdhb
kbbicefihgkajdb
kbbicefihjkadbg
kbbiceghijkadbf
kbbicegihjkadbf
kbbicegijhkfadb
kbbicegjihkfadb
kbbicfaghibkjed
kbbicfaghjbdkei
kbbicfaghjbidke
kbbicfagibejdkh
kbbicfagibejkdh
kbbicfagibekjdh
kbbicfagibkdjeh
kbbicfagibkejdh
kbbicfagihbkjed
kbbicfagijbkdeh
kbbicfagijbkedh
kbbicfagikbejdh
kbbicfahgbijked
kbbicfahgjbdkei
kbbicfahgjbidke
kbbicfahibejkgd
kbbicfahibjedkg
kbbicfahibjkdeg
kbbicfahibjkedg
kbbicfahibkejdg
kbbicfahibkjdeg
kbbicfahibkjedg
kbbicfahigbkjde
kbbicfahigbkjed
kbbicfahjbidkeg
kbbicfahjbiekgd
kbbicfahjbikegd
kbbicfahjbkdgei
kbbicfahjgbekdi
kbbicfaigbejdkh
kbbicfaigbejkdh
kbbicfaigbekjdh
kbbicfaihbejkgd
kbbicfaihbjedkg
kbbicfaihbkejdg
kbbicfaijgbkedh
kbbicfaijhbegkd
kbbicfajgbhekdi
kbbicfajghbekdi
kbbicfajhgbekdi
kbbicfajhgbiekd
kbbicfajigbkedh
kbbicfehakidjgb
kbbicfehakijdgb
kbbicfehakjidgb
kbbicfghijkadeb
kbbicfghijkaedb
kbbicfgijhkaedb
kbbicfgjihkaedb
kbbicfigajhdbke
kbbicgahijbfdke
kbbicgahijbfked
kbbicgahijbkdef
kbbicgahijbkdfe
kbbicgahijbkfed
kbbicgahijkbdef
kbbicgahijkbdfe
kbbicgahijkbfed
kbbicgahikbfjed
kbbicgahikjbedf
kbbicgahjibfked
kbbicgahjibkfed
kbbicgahjikbfed
kbbicgaihjbekfd
kbbicgaihjbfdke
kbbicgaihjbkdfe
kbbicgaijhbefkd
kbbicgaijhbfekd
kbbicgaijhbfkde
kbbicgaijhbfked
kbbicgaijkhbfde
kbbicgaijkhbfed
kbbicgaikjbedfh
kbbicgajhibfekd
kbbicgajihbfekd
kbbicgajkhibfed
kbbicgajkihbfed
kbbicgakjihbfed
kbbicgehaijdbkf
kbbicgehajidbkf
kbbicgehajkidbf
kbbicgehakjidbf
kbbicgfhiakjdeb
kbbicgfhiakjedb
kbchdefakhjbcgi
kbchdefakhjcbgi
kbchdefchijkabg
kbchdefchikjabg
kbchdefcihjbakg
kbchdefgaijkbch
kbchdefgaijkcbh
kbchdefhaijkbcg
kbchdefhaijkcbg
kbchdefhajikgbc
kbchdefhajikgcb
kbchdefhgijakbc
kbchdegachjbkfi
kbchdegacibjfkh
kbchdegacibjkfh
kbchdegacibkjfh
kbchdegacjhbkfi
kbchdegakbicjfh
kbchdegakcibjfh
kbchdegakhibjfc
kbchdegakhicjfb
kbchdegakihbjfc
kbchdegakihcjfb
kbchdegcahjbkfi
kbchdegcaibjfkh
kbchdegcaibjkfh
kbchdegcaibkjfh
kbchdegcajhbkfi
kbchdegchbjakfi
kbchdegchijkafb
kbchdegchjikafb
kbchdegfijckbah
kbchdegfjihckab
kbchdeghaijkbfc
kbchdeghaijkcfb
kbchdeghajikbfc
kbchdeghajikcfb
kbchdeghibjkafc
kbchdeghijbkcaf
kbchdeghjbikcfa
kbchdeghjibkfac
kbchdeghjicfkba
kbchdeghjikcfab
kbchdegijhbfkac
kbchdegijhbfkca
kbchdegijkhcfab
kbchdehacijbgkf
kbchdehacijbkfg
kbchdehacijbkgf
kbchdehacijkbfg
kbchdehacijkbgf
kbchdehacjibgkf
kbchdehacjkibgf
kbchdehackjibgf
kbchdehakbijcgf
kbchdehakbjicgf
kbchdehakcijbgf
kbchdehakcjibgf
kbchdehakibjfcg
kbchdehakicjfbg
kbchdehcaijbgkf
kbchdehcaijbkfg
kbchdehcaijbkgf
kbchdehcaijkbfg
kbchdehcaijkbgf
kbchdehcajibgkf
kbchdehcajkibgf
kbchdehcakjibgf
kbchdehcgiakjfb
kbchdehcibjkafg
kbchdehcibjkagf
kbchdehcjibkfag
kbchdehgaibkjfc
kbchdehgaickjfb
kbchdfhaibjeckg
kbchdfhaicjbekg
kbchdfhaikbjceg
kbchdfhajcibgke
kbchdfhajckibeg
kbchdfhajkbicge
kbchdfhajkcibge
kbchdfhakbejcgi
kbchdfhakcjibge
kbchdfhakjbicge
kbchdfhbgjaicke
kbchdfhbiajkceg
kbchdfhbiakjceg
kbchdfhbjaickeg
kbchdfhbjakcgei
kbchdfhbjakicge
kbchdfhciajbkeg
kbchdfhcjaibgke
kbchdfiagbkjche
kbchdfiaghckjbe
kbchdfiagjckebh
kbchdfiagkcejbh
kbchdfiahbjkceg
kbchdfiahbkjceg
kbchdfiahgbkjce
kbchdfiahkbejcg
kbchdfiajbkechg
kbchdfiakbejcgh
kbchdfiakbejchg
kbchdfiakgbejch
kbchdfiakhcejbg
kbchdfiechjakgb
kbchdfihckjaegb
kbdgefghadijkbc
kbdgefghakjicbd
kbdgefghakjidcb
kbdgefghcijkdab
kbdgefghdaijkbc
kbdgefghdibjkac
kbdgefghdijckab
kbdgefghiabjkcd
kbdgefghiabjkdc
kbdgefghiajckbd
kbdgefghibajkcd
kbdgefghibajkdc
kbdgefgiadbjckh
kbdgefgiadbjkch
kbdgefgiadbkjch
kbdgefgiadjckbh
kbdgefgiadkjchb
kbdgefgiakbcjdh
kbdgefgiakbdjch
kbdgefgiakcbjdh
kbdgefgiakdjchb
kbdgefgiakhbjcd
kbdgefgiakhbjdc
kbdgefgibadjckh
kbdgefgibadjkch
kbdgefgibadkjch
kbdgefgibakcjdh
kbdgefgicabjdkh
kbdgefgicabjkdh
kbdgefgicabkjdh
kbdgefgidabjckh
kbdgefgidabjkch
kbdgefgidabkjch
kbdgefgidajckbh
kbdgefgidakjchb
kbdgefgidhjkacb
kbdgefgidjbckah
kbdgefgidjcbkah
kbdgefgidkbjcha
kbdgefgihajkcdb
kbdgefgihajkdcb
kbdgefgihjbkcda
kbdgefgihjbkdca
kbdgefhgakjicbd
kbdgefhgdijckab
kbdgefhgdijkbac
kbdgefhgiajckbd
kbdgefhgiajckdb
kbdgefhiadjbckg
kbdgefhiadjcbkg
kbdgefhiadjkcbg
kbdgefhiadkbjcg
kbdgefhiadkjcbg
kbdgefhiakbjcdg
kbdgefhiakdjcbg
kbdgefhibajkcdg
kbdgefhibakjcdg
kbdgefhicajbkdg
kbdgefhidajbckg
kbdgefhidkjbcga
kbdgefhjbaickdg
kbdgefhjbakcgdi
kbdgefhjcaikbdg
kbdgefhjcibkadg
kbdgefigakcdjbh
kbdgefigakhdjbc
kbdgefigdakcjbh
kbdgefighajkcbd
kbdgefighjbkcad
kbdgefigjacdkbh
kbdgefihcajdkbg
kbdgefihcjbdkag
kbdgefihdajkcbg
kbdgefihdakjcbg
kbdgefjgcahdkbi
kbdgefjgdhcakbi
kbdgefjgdhikacb
kbdgefjgdihcakb
kbdgefjghacdkbi
kbdgefjghaikdbc
kbdgefjghibkdac
kbdgefjgiacdkbh
kbdgefjgihbdakc
kbdgefjhcaikdbg
kbdgefjhcibkdag
kbdgefjhdaickbg
kbdgefjhdakcgbi
kbdgefjhdibckag
kbdgegjhaidbfkc
kbdgegjhdicakbf
kbdgegjhdkcafbi
kbdgegkhaidbjfc
kbdgegkhcajidbf
kbdgegkhcijbdfa
kbdgegkhcjibdfa
kbeffcehbaijdkg
kbeffcehbajdkgi
kbeffcehbajidkg
kbeffceibajkdhg
kbeffdehbaijckg
kbeffdehbajckgi
kbeffdeibajkchg
kbeffdghiekjabc
kbeffdgijeckbah
kbeffdgjhaibekc
kbeffdgjicekbah
kbeffdgjiehckab
kbeffdhkiacjebg
kbeffdigjhackbe
kbeffghijaebckd
kbeffghijaebkdc
kbeffghijaecbkd
kbeffghijaekcdb
kbeffghijaekdcb
kbeffghijakbcde
kbeffghijakbedc
kbeffghijakecdb
kbeffghijakedcb
kbeffghijbakcde
kbeffghijcabkde
kbeffghijcbakde
kbeffghijdabcke
kbeffghijdacbke
kbeffghjiaebkdc
kbeffghjiaecbkd
kbeffghjiakbedc
kbeffghjieabkdc
kbeffghkiaejdbc
kbeffghkidabjec
kbeffghkidajceb
kbeffghkidbajec
kbeffghkidjbcea
kbeffgihjbakced
kbeffgihjcaekbd
kbeffgikhcajdbe
kbeffgikhcjbdae
kbeffgjhidabkec
kbeffgjhieakdbc
kbeffhjgiakcebd
kcbbgceagbhjdkfi
kcbbgceagbidjfkh
kcbbgceagbidjkfh
kcbbgceagbidkjfh
kcbbgceagbjhdkfi
kcbbgceahbijdgkf
kcbbgceahbijdkfg
kcbbgceahbijdkgf
kcbbgceahbijkdfg
kcbbgceahbijkdgf
kcbbgceahbjidgkf
kcbbgceahbjkidgf
kcbbgceahbkjidgf
kcbcfcdfgijabkeh
kcbcfcdfgjhabkei
kcbcfcdfgjiabkeh
kcbcfcdfhkijabeg
kcbcfcfaghibjkde
kcbcfcfaghibjked
kcbcfcfagibejdkh
kcbcfcfagibejkdh
kcbcfcfagibekjdh
kcbcfcfagibkdjeh
kcbcfcfagibkejdh
kcbcfcfagiebjdkh
kcbcfcfagiebjkdh
kcbcfcfagiebkjdh
kcbcfcfahgbijked
kcbcfcfahibjedkg
kcbcfcfahibjkdeg
kcbcfcfahibjkedg
kcbcfcfahibkejdg
kcbcfcfahibkjdeg
kcbcfcfahibkjedg
kcbcfcfahigbkjde
kcbcfcfahijbkdeg
kcbcfcfahjbidkeg
kcbcfcfahjbiekgd
kcbcfcfahjbikegd
kcbcfcfahjbkdgei
kcbcfcfahjibdgke
kcbcfcfgiajebkdh
kcbcfcfgjahebkdi
kcbcfcfgjaiebkdh
kcbcfcfgjaihebkd
kcbdecdghijeabkf
kcbdecdghijfabke
kcbdecdghjkiabfe
kcbdecdghkjiabfe
kcbdecdgikhjfabe
kcbdeceagbidjfkh
kcbdeceagbidjkfh
kcbdeceagbidkjfh
kcbdeceghikfajdb
kcbdecegihkfajdb
kcbdecgahijbfdke
kcbdecgahijbfked
kcbdecgahijbkdef
kcbdecgahijbkdfe
kcbdecgahijbkfed
kcbdecgahijdbfke
kcbdecgahijdbkef
kcbdecgahijebdkf
kcbdecgahijfbdke
kcbdecgahijfbked
kcbdecgahikebjdf
kcbdecgahjibkfed
kcbdecgahjifbked
kcbdecgahkiebjfd
kcbdecgaihjbekfd
kcbdecgaihjbkdfe
kcbdecgaihjebdkf
kcbdecgaikjbedfh
kcbdecghijadfbke
kcbdecghijaefbkd
kcbdecghjkadifbe
kcbdecghjkaeifbd
kcbdecghjkaifbed
kcbdecghkaidjfeb
kcbedcdhfjabgkei
kcbedceafhbjdkgi
kcbedceaghbjdkfi
kcbedceahbijdgkf
kcbedceahbijdkfg
kcbedceahbijdkgf
kcbedceahbijgdkf
kcbfccdifjabkgeh
kcbfccdifjabkheg
kcbfcceafibjkdhg
kcbfcceafibjkhdg
kcbfcceagbidjfkh
kcbfcceagibjkhfd
kcbfcceahibjkdfg
kcbfcceahibjkdgf
kcbfcceaijbdkgfh
kcbfcceaijbdkhfg
kcbfccfagibejdkh
kcbfccfeiahjbdkg
kcbgbcdeghjabkfi
kcbgbcdfghjabkei
kcbgbcdfgjkabehi
kcbgbcdfhjikabeg
kcbgbcdjgkiabefh
kcbgbceafhbjdkgi
kcbgbceagbijdkfh
kcbgbceajbgikfdh
kcbgbceajbhikfdg
kcbgbcefgjiakbdh
kcbgbcefhjiakbdg
kcbgbcejghkadbfi
kcbgbcejhgkadbfi
kcbgbcfaghjbdkei
kcbgbcfagijbdkeh
kcbgbcfagjbiekdh
kcbgbcfahgjbdkei
kcbgbcfajhbkdgei
kcccedegacibjfkh
kcccedegacibjkfh
kcccedegcaibjfkh
kcccedegcaibjkfh
kcccedeghijckabf
kcccedeghikbjacf
kcccedeghjibkfac
kcccedeghjickfab
kcccedeghjifckba
kcccedghaijbkcef
kcccedghaijbkcfe
kcccedghaijbkfec
kcccedghaijcbkef
kcccedghaijcbkfe
kcccedghaijebckf
kcccedghaikfjecb
kcccedghakifjebc
kcccedghakjibcfe
kcccedghbijafcke
kcccedghijbfekac
kcccedghikaebjfc
kcccedghikaejcfb
kcccedghikajbfce
kcccedghikbaejfc
kcccedgiahjbfcke
kcccedgiahjcfkbe
kcccedgiahkbfjce
kcccedgiajhbfkce
kcccedgihjbfakec
kccdddfhaibjckge
kdbbbeceagbidjfkh
kdbbbeceagbidjkfh
kdbbbeceagbidkjfh
kdbbcdceahbijdgkf
kdbbcdceahbijdkfg
kdbbcdceahbijdkgf
kdbbcdceahbijgdkf
kdbbdcceagbidjfkh
kdbbebceagbhjdkfi
kdbbebceagbijdkfh
kdbbebceagbjkdfhi
kdbcbdcdfhiejabkg
kdbccccfagibejdkh
kdbccccfagiebjdkh
kdbccccfgiajebdkh
kdbcdbcfahjbkideg
kdbcdbcfajhbkdgei
kebbbbcceagbidjfkh

644
mtlinks/hyperbolic_data_11n Normal file
View File

@ -0,0 +1,644 @@
kakbdeGaHJCKFI
kakbdeGahjCkfi
kakbdegaHJcKFI
kakbdeGaICJFKH
kakbdeGaiCjfkh
kakbdegaIcJFKH
kakbdegaIcjFkh
kakbdegaicJfKH
kakbdeGaICJKFH
kakbdeGaiCjkfh
kakbdegaIcJKFH
kakbdeGaICKJFH
kakbdeHaIJCKFG
kakbdeHaijCkfg
kakbdehaIJcKFG
kakbdeHaIJCKGF
kakbdeHaijCkgf
kakbdehaIJcKGF
kakbdeHaIJKCFG
kakbdeHaIJKCGF
kakbdFaGICJEKH
kakbdFagiCjekh
kakbdfaGIcJEKH
kakbdFaGICJKEH
kakbdFagiCjkeh
kakbdfaGIcJKEH
kakbdfagIcJKEH
kakbdFaGICKJEH
kakbdFagiCkjeh
kakbdfaGIcKJEH
kakbdFaHCJEKGI
kakbdFahCjekgi
kakbdfaHcJEKGI
kakbdFaHICJKGE
kakbdFahiCjkge
kakbdfaHIcJKGE
kakbdFaICJKEHG
kakbdFaICKJEHG
kakbdFaIHCJKGE
kakbdFaihCjkge
kakbdfaIHcJKGE
kakbdFaIJCEKGH
kakbdFaijCekgh
kakbdfaIJcEKGH
kakbdFaJICEKGH
kakbdFajiCekgh
kakbdfaJIcEKGH
kakbdFHaIJKECG
kakbdFHaIKJECG
kakbdFIaHJCEKG
kakbdGaHICKJEF
kakbdGahiCkjef
kakbdgaHIcKJEF
kakbdGaHICKJFE
kakbdGahiCkjfe
kakbdgaHIcKJFE
kakbdGaHIJCEKF
kakbdGaHIJCKFE
kakbdGahijCkfe
kakbdgaHIJcKFE
kakbdGaHIKCJFE
kakbdGaHJICKFE
kakbdGahjiCkfe
kakbdgaHJIcKFE
kakbdGaIHJCEKF
kakbdGaihjCekf
kakbdgaIHJcEKF
kakbdgaIHjcEkf
kakbdgaihJceKF
kakbdGaIJCKFEH
kakbdGaJHCIFKE
kakbdGaJhCifKE
kakbdGajHCIFke
kakbdGajhCifke
kakbdgaJhcifKE
kakbdGaJHICFKE
kakbdGajHICFke
kakbdgaJhicfKE
kakbdGaJICKFEH
kakbdgeaIcJKFH
kakbdHaJKICFGE
kakbdHFaIJKECG
kakbdHFaIKJECG
kakbdIFaHJCEKG
kakbefGHaIJKCD
kakbefGhaIjkCd
kakbefgiajdKcH
kakbefHIajCDkg
kakbefhiaJcdKG
kakbefHIajDCkg
kakbefhiaJdcKG
kakbefJHaIDKCG
kakbeGFaJIKCDH
kakbegFaJiKcDH
kakbegFaJikcDh
kakbegfajiKcdH
kakbeGFIaCJKDH
kakbeGFiaCjkdh
kakbegfIacJKDH
kakbeGFIaCKJDH
kakbeGFiaCkjdh
kakbegfIacKJDH
kakbegfJahcKDI
kakbeGHaJKICDF
kakbeGHaJKIDCF
kakbeGHajkIDCf
kakbeghaJKidcF
kakbeGHiajCkfd
kakbeGHIaJKDFC
kakbeGhiajKdfC
kakbegHIajkDfc
kakbegiajdKcfH
kakbeGIHaJKDFC
kakbeGIHajKDfC
kakbeGihajKdfC
kakbegIHajkDfc
kakbegihaJkdFc
kakbeGJaHIDKCF
kakbeGjaHIDKcF
kakbegJahidkCf
kakbeHFIaJCKDG
kakbeHFiaJCkdG
kakbeHGfaIJKDC
kakbehGIaDjkFc
kakbeHIgajkCfd
kakbeIFaHJDKGC
kakbeiFHaJDkcG
kakbeIGHaCJKFD
kakbeIGHaJDKFC
kakbeIGHaJKFCD
kakbeIHGaJDKFC
kakbeiHGajDkfc
kakbeIJaHCDKGF
kakbeIKGaJDCFH
kakbfgHkIaJECd
kakbfHgiadKjeC
kakbfHGIJaCKED
kakbfHGijaCked
kakbfHGJIaCKED
kakbfHGjiaCked
kakbfhgJIacKED
kakbfHJGIaDKEC
kakbfHkIaJECGd
kakbfiGhakJecD
kakbgEJKIaDCFH
kakbgEJKiaDCfH
kakbgejkIadcFh
kakbgIJKCaDEFH
kakcdeihJKbaGF
kakcdeihKJbaGF
kakcdfaHIbJKGE
kakcdfaIJbEKGH
kakcdfjHIkbEag
kakcdfjhiKbeaG
kakcdfjihKbeaG
kakcEFgHIkjBAd
kakcEfghIkjBad
kakcefIJhkbaDg
kakcefijhKbadG
kakcEfjhIkdBag
kakcefjihKbadG
kakcEFkHIdjBAg
kakcEfkhIdjBag
kakcEghJBIakFD
kakcEghjBiakfd
kakceGiajkBfdh
kakcegjaIbkFdh
kakcegjbIakdFh
kakcEHfIAjkBDg
kakcEHfIAkjBDg
kakcehfiaKJbdG
kakcEhfjAibkdg
kakceHfjaiBkdg
kakcEhgjBiakdf
kakcEHgJIAkFBD
kakcEhijAdbkfg
kakceHijadBkfg
kakcEhijBdakgf
kakcEJgAIdkFBh
kakcFHgIJAkBED
kakcFHgJIAkBED
kakcFhigBjkade
kakcGeIakjBfDh
kakcGeiakjBfdh
kakcihgJbakfDE
kbbicDEgHJAbKFI
kbbicDEgHJaBKFI
kbbicdEgHJabKFI
kbbicDEhGIJAbKF
kbbicDEhGIJaBKF
kbbicdEhGIJabKF
kbbicDEhGJIAbKF
kbbicDEhGJIaBKF
kbbicdEhGJIabKF
kbbicDEhIJKAbGF
kbbicDEhIJKaBGF
kbbicdEhIJKabGF
kbbicDEhIKJAbGF
kbbicDEhIKJaBGF
kbbicdEhIKJabGF
kbbicDFgHJAbKEI
kbbicDFgHJaBKEI
kbbicdFgHJabKEI
kbbicDFhIJKAbEG
kbbicDFhIJKaBEG
kbbicdFhIJKabEG
kbbicDFhJGKAbEI
kbbicDFhJGKaBEI
kbbicdFhJGKabEI
kbbicdFhjGKabei
kbbicDFhJIKAbEG
kbbicDFhJIKaBEG
kbbicdFhJIKabEG
kbbicDFiHJKEAbG
kbbicDFiHJKEaBG
kbbicdFiHJKEabG
kbbicDFjGHKIEAb
kbbicdFjGHKIEab
kbbicdFjghKieab
kbbicdfjGHkIEab
kbbicDFjHGKIEAb
kbbicdFjHGKIEab
kbbicDFjHKIEGAb
kbbicdFjHKIEGab
kbbicDGfIAbJKEH
kbbicdGfIabJKEH
kbbicDGfIAbKJEH
kbbicdGfIabKJEH
kbbicDGhIJKAbEF
kbbicDGhIJKaBEF
kbbicdGhIJKabEF
kbbicDGiHJKEAbF
kbbicDGiHJKEaBF
kbbicdGiHJKEabF
kbbiceafHbIJDKG
kbbiceafHbijDkg
kbbiceafhbIJdKG
kbbiceafHbJDKGI
kbbiceaGbHJDKFI
kbbiceaGbhjDkfi
kbbiceagbHJdKFI
kbbiceaGbIDJFKH
kbbiceaGbiDjfkh
kbbiceagbIdJFKH
kbbiceagbIdjFkh
kbbiceagbidJfKH
kbbiceaGbIDJKFH
kbbiceaGbiDjkfh
kbbiceagbIdJKFH
kbbiceaGbIDKJFH
kbbicEaGHBIKJFD
kbbicEaGJBIKDFH
kbbiceaHbIJDKFG
kbbiceaHbijDkfg
kbbiceahbIJdKFG
kbbiceaHbIJDKGF
kbbiceaHbijDkgf
kbbiceahbIJdKGF
kbbiceaHbIJKDFG
kbbiceaHbIJKDGF
kbbicEaHGBIKJFD
kbbicEaJGBIKDFH
kbbicEFhiJKadBG
kbbicEFihGKAjdb
kbbicEGhiJKadBF
kbbiceGijHKFadb
kbbicEGjiHKFAdb
kbbiceGjiHKFadb
kbbicfagIbeJDKH
kbbicfagIbejDkh
kbbicfagibeJdKH
kbbicfagIbeJKDH
kbbicFaHGBIJKED
kbbicfaHGbIJKED
kbbicfaHgbijKeD
kbbicfaHGJbDKEI
kbbicfaHGjbDkei
kbbicfahgJbdKEI
kbbicfaHGJbIDKE
kbbicfaHIbJEDKG
kbbicfaHIbjEDkg
kbbicfahibJedKG
kbbicfaHIbJKDEG
kbbicfaHIbJKEDG
kbbicfaHIbjkEDg
kbbicfahibJKedG
kbbicFaHJBIDKEG
kbbicfaHJbIDKEG
kbbicfaHJbiDkEG
kbbicFaHJBIEKGD
kbbicfaHJbIEKGD
kbbicFaHJBIKEGD
kbbicfaHJbIKEGD
kbbicfaIHbJEDKG
kbbicFaIJHBEGKD
kbbicFaIJhBegKD
kbbicfaIJHbEGKD
kbbicfaIJhbegKD
kbbicfaijHbEGkd
kbbicfajGbHEkdi
kbbicfeHakiDjgb
kbbicfehakIdJGb
kbbicGaIHJBEKFD
kbbicGaIhJBeKFD
kbbicgaIHJbEKFD
kbbicgaIhJbeKFD
kbbicgaIhJbekFD
kbbicgaiHjbEkfd
kbbicGaIKJBEDFH
kbbicgaIKJbEDFH
kbchdeFakHjBcgi
kbchdeFakHjbCgi
kbchdeFakhJBcGI
kbchdeFakhJbCGI
kbchdEFcHIJKABG
kbchdEFchIjkABg
kbchdEfcHiJKAbG
kbchdEfcHiJKaBG
kbchdEfcHijkAbg
kbchdEfchIjkAbg
kbchdEfchIjkaBg
kbchdefchiJKabG
kbchdEFcHIKJABG
kbchdEFchIkjABg
kbchdEfcHiKJAbG
kbchdEfcHiKJaBG
kbchdEfcHikjAbg
kbchdEfchIkjAbg
kbchdEfchIkjaBg
kbchdefchiKJabG
kbchdEFcIHJBAKG
kbchdEFciHjBAkg
kbchdEfcIhJbAKG
kbchdEfcIhjbAkg
kbchdEfciHjBakg
kbchdEfciHjbAkg
kbchdefcihJbaKG
kbchdeFGaiJKbCH
kbchdeFHaiJKbCG
kbchdefHaiJKbcG
kbchdeFhaJikgBc
kbchdefHajIKGcb
kbchdEfhgIjakBc
kbchdeFHgIjaKbC
kbchdeFhgIjakBc
kbchdeFhgiJakBc
kbchdegacIbJFKH
kbchdegacIbjFkh
kbchdegacibJfKH
kbchdegacIbJKFH
kbchdegcaIbJFKH
kbchdegcaIbjFkh
kbchdegcaibJfKH
kbchdegcaIbJKFH
kbchdegchIJkaFb
kbchdegchJIkaFb
kbchdEgfIjckbAh
kbchdegfijcKbaH
kbchdEgFjIhcKAb
kbchdEgfJihckAb
kbchdEgfjIhckAb
kbchdeGFjiHCKab
kbchdEGHiBJKaFC
kbchdEghjBikcfa
kbchdEGhJICFkBa
kbchdEGhjICFkBa
kbchdEghJikcfAb
kbchdEGIjHBFKaC
kbchdEGiJHBFkAc
kbchdEGiJHBFkaC
kbchdfhaibJecKG
kbchdfhaikbJceG
kbchdfhaJckibEg
kbchdfHakbeJCGI
kbchdfHakbejCgi
kbchdfhakbeJcGI
kbchdfhbgJaicKE
kbchdfhbJaickEg
kbchdfhbJakicgE
kbchdfhcIajbkEg
kbchdfiahbJKceG
kbchdfIakbeJCGH
kbdgefGHadiJkBC
kbdgefGhadIjKbC
kbdgefGhadIjkBc
kbdgefGhadiJkbC
kbdgeFGhcIJKdAB
kbdgeFGhciJkdAB
kbdgeFgHcIjKDaB
kbdgeFgHciJkDaB
kbdgeFghciJkdAb
kbdgefGHdaIJKBC
kbdgefGHdaiJkBC
kbdgefGhdaIjkBc
kbdgefGhdaiJkbC
kbdgeFGhdiBJkaC
kbdgeFghdiJckaB
kbdgefgHIabjKcD
kbdgefGHIajCKbD
kbdgefgHIbajKcD
kbdgefgiadjcKbH
kbdgeFGIdHJKACB
kbdgeFGIdhJkACB
kbdgeFgIdhJkACb
kbdgeFgidHjKacB
kbdgefGidhJkacB
kbdgefGIhaJkCDb
kbdgefGihaJkdcB
kbdgeFGIhjBkCDa
kbdgeFGihJBkdcA
kbdgeFhJciBkaDg
kbdgefIgakcdJBH
kbdgefIgJacdKBH
kbdgefjGcaHDkbi
kbdgeFJGdHCAKBI
kbdgefJgdhcaKBI
kbdgefjGdiHCakb
kbdgefJgIacdKBH
kbdgeGJHaIDBFKC
kbdgegJhaidbfKC
kbdgegkHcajIDbf
kbdgeGkHcjiBDfa
kbeffCEHBaIJDKG
kbeffCEHBaijDkg
kbeffCEhBaIJdKG
kbeffCEhBaijdkg
kbeffcehbaIJdKG
kbeffCEhBajdkgi
kbeffDGHIekJABC
kbeffDghIekjAbc
kbeffDGIJeCKBAH
kbeffDgIJecKBAH
kbeffdgijecKbaH
kbeffDGJICeKBAH
kbeffDgjIcekbAh
kbeffdigjHacKbe
kbeffgHkIaeJDBc
kbeffgHkIaejDBc
kbeffghkIdabJEc
kcbbgcEaGBHJDKFI
kcbbgcEaGBhjDkfi
kcbbgceagbHJdKFI
kcbbgcEaGBIDJFKH
kcbbgcEaGBIDjFkh
kcbbgcEaGBiDJfKH
kcbbgcEaGBiDjfkh
kcbbgceagbIdJFKH
kcbbgceagbIdjFkh
kcbbgceagbidJfKH
kcbbgcEaGBIDJKFH
kcbbgcEaGBiDjkfh
kcbbgceagbIdJKFH
kcbbgcEaHBIJDKFG
kcbbgcEaHBijDkfg
kcbbgceahbIJdKFG
kcbbgcEaHBIJDKGF
kcbbgcEaHBijDkgf
kcbbgceahbIJdKGF
kcbcfcDFgIJAbKEH
kcbcfcDFgIJaBKEH
kcbcfcDFgIjAbkEh
kcbcfcDFgIjaBkEh
kcbcfcDFgiJAbKeH
kcbcfcDFgiJaBKeH
kcbcfcdFgIJabKEH
kcbcfcdFgIjabkEh
kcbcfcdFgiJabKeH
kcbcfcdfgIJabKEH
kcbcfcdfgiJabKeH
kcbcfcDFgJHAbKEI
kcbcfcDFgJHaBKEI
kcbcfcdFgJHabKEI
kcbcfcDFgJIAbKEH
kcbcfcDFgJIaBKEH
kcbcfcdFgJIabKEH
kcbcfcDFhKIJAbEG
kcbcfcDFhKIJaBEG
kcbcfcdFhKIJabEG
kcbcfcfagHIbjKDe
kcbcfcfagHIbjKdE
kcbcfcfagHibJkDe
kcbcfcfagHibJkdE
kcbcfcFaHGBIJKED
kcbcfcfaHGbIJKED
kcbcfcfaHgbijKeD
kcbcfcFaHIBJEDKG
kcbcfcFaHIBjEDkg
kcbcfcfaHIbJEDKG
kcbcfcfaHIbjEDkg
kcbcfcfahibJedKG
kcbcfcFaHIBJKDEG
kcbcfcFaHJBIDKEG
kcbcfcfaHJbIDKEG
kcbcfcfaHJbiDkEG
kcbcfcFaHJBIEKGD
kcbcfcfaHJbIEKGD
kcbcfcFaHJBIKEGD
kcbcfcfaHJbIKEGD
kcbcfcFaHJIBDGKE
kcbcfcfaHJIbDGKE
kcbcfcfaHjibDGke
kcbcfcfahJIbdgKE
kcbcfcfgIajebkDh
kcbcfcfgiaJebKdH
kcbdecDGhIJEAbKF
kcbdecDGhIJEaBKF
kcbdecdGhIJEabKF
kcbdecDGhIJFAbKE
kcbdecDGhIJFaBKE
kcbdecdGhIJFabKE
kcbdecDGhJKIAbFE
kcbdecDGhJKIaBFE
kcbdecdGhJKIabFE
kcbdecDGhKJIAbFE
kcbdecDGhKJIaBFE
kcbdecdGhKJIabFE
kcbdecDGiKHJFAbE
kcbdecDGiKHJFaBE
kcbdecdGiKHJFabE
kcbdecdGikHjFabe
kcbdecdgiKhJfabE
kcbdeceaGbIDJFKH
kcbdeceaGbIDjFkh
kcbdeceaGbiDJfKH
kcbdeceaGbiDjfkh
kcbdeceagbidJfKH
kcbdeceaGbIDJKFH
kcbdeceaGbIDKJFH
kcbdecEGhiKFajdB
kcbdecgahkIebJFd
kcbdecGaIHJBEKFD
kcbdecGaIhJBeKFD
kcbdecgaIHJbEKFD
kcbdecgaiHjbEkfd
kcbdecgaIHJEbDKF
kcbdecGaIKJBEDFH
kcbdecgaIKJbEDFH
kcbedcdHfJabGKEI
kcbedceaHbIJDGKF
kcbedceaHbijDgkf
kcbedceahbIJdGKF
kcbedceaHbIJDKFG
kcbedceaHbIJDKGF
kcbedceaHbIJGDKF
kcbfccdIfJabKGEH
kcbfccdIfjabKGeH
kcbfccdifJabkgEh
kcbfccdIfJabKHEG
kcbfcceafIbJKDHG
kcbfcceafIbjkDhg
kcbfcceafibJKdHG
kcbfcceafIbJKHDG
kcbfcceaGbIDJFKH
kcbfcceaGbiDjfkh
kcbfcceagbIdJFKH
kcbfccEaGIBJKHFD
kcbfccEaIJBDKGFH
kcbfccEaIJBDKHFG
kcbfccfeIahJbDKG
kcbgbcDEgHJAbKFI
kcbgbcDEgHJAbkFi
kcbgbcDEgHJaBKFI
kcbgbcDEgHJaBkFi
kcbgbcDEgHjAbkfi
kcbgbcdEgHJabKFI
kcbgbcdEgHJabkFi
kcbgbcdEgHjabkfi
kcbgbcdeghJabKFI
kcbgbcdeghJabkFi
kcbgbcDFgHJAbKEI
kcbgbcDFgHJaBKEI
kcbgbcdFgJKabEHI
kcbgbcdFgjkabehi
kcbgbcDFhJIKAbEG
kcbgbcDFhjIkAbeg
kcbgbcdFhJIKabEG
kcbgbcdFhjIkabeg
kcbgbcdfhJiKabEG
kcbgbcDJgKIAbEFH
kcbgbcDJgKIaBEFH
kcbgbcdJgKIabEFH
kcbgbceafhbJdKGI
kcbgbceaJbGIKFDH
kcbgbceaJbGIkFDh
kcbgbceaJbgiKfDH
kcbgbceaJbgikfDh
kcbgbceajbGIkFdh
kcbgbceaJbHIKFDG
kcbgbceJghKadbFI
kcbgbceJghkadbfI
kcbgbceJhgKadbFI
kcbgbceJhgkadbfI
kcbgbcfaHGJbDKEI
kcbgbcfaHGjbDkei
kcbgbcFaJHBKDGEI
kcbgbcfaJHbKDGEI
kcccedeGacIBJFKH
kcccedeGacIBjFkh
kcccedeGaciBJfKH
kcccedeGaciBjfkh
kcccedegacibJfKH
kcccedeGacIBJKFH
kcccedEGHiJCKaBF
kcccedEGhIjCKaBf
kcccedEgHiJckAbF
kcccedEghIjckAbf
kcccedEghIjckaBf
kcccedeGhijCKabf
kcccedEGHiKBJaCF
kcccedEGhIKBjAcF
kcccedEghIkbjAcf
kcccedEgHjIbkFAc
kcccedEGhJifCkBa
kcccedEghJifckBa
kcccedEghJifckbA
kcccedeGhjifCkba
kcccedgHakIfJEBc
kcccedgHakIfjEBc
kcccedgHakifJeBc
kcccedghakIfjEbc
kcccedGHijBFEKac
kccdddfHaIbJCKGE
kdbbbecEaGBIDJFKH
kdbbbecEaGBIDjFkh
kdbbbecEaGBiDJfKH
kdbbbeceagbidJfKH
kdbbcdcEaHBIJDGKF
kdbbcdcEaHBijDgkf
kdbbcdceahbIJdGKF
kdbbdccEaGBIDJFKH
kdbbdccEaGBiDjfkh
kdbbdcceagbIdJFKH
kdbbebceagbhJdKFI
kdbbebceagbhJdkFi
kdbbebcEaGBJKDFHI
kdbbebcEaGBjkDfhi
kdbbebceagbJKdFHI
kdbcbdcDFhIEJAbKG
kdbcbdcDFhIEJaBKG
kdbccccfgIaJebDKH
kdbcdbcfaHJbKIDEG
kdbcdbcfaHjbkIDeg
kdbcdbcFaJHBKDGEI
kdbcdbcfaJHbKDGEI

3308
mtlinks/hyperbolic_data_12a Normal file

File diff suppressed because it is too large Load Diff

3144
mtlinks/hyperbolic_data_12n Normal file

File diff suppressed because it is too large Load Diff

12417
mtlinks/hyperbolic_data_13a Normal file

File diff suppressed because it is too large Load Diff

16454
mtlinks/hyperbolic_data_13n Normal file

File diff suppressed because it is too large Load Diff

51347
mtlinks/hyperbolic_data_14a Normal file

File diff suppressed because it is too large Load Diff

91616
mtlinks/hyperbolic_data_14n Normal file

File diff suppressed because it is too large Load Diff

16
mutant_knot_groups/dat11 Normal file
View File

@ -0,0 +1,16 @@
440 441
401 409
443 445
518 519
406 412
438 442
408 414
403 411
57 231
407 413
44 47
402 410
252 254
251 253
19 25
24 26

75
mutant_knot_groups/dat12 Normal file
View File

@ -0,0 +1,75 @@
1344 1345 1509
1498 1502
1377 1422
1347 1508
1958 1969
1355 1517
1381 1426
1351 1513
1311 1319
1979 1980
1412 1417
1495 1516
1352 1549
1981 1984
1519 1520
1841 1844
1373 1418
1316 1322
1378 1423
1350 1354 1512
1544 1552
1379 1424
1493 1514
1375 1420
1959 1970
1348 1349 1507
167 692
1343 1511
1496 1500
1540 1550
195 693
1380 1425
1386 1413
1374 1419
1652 1653
1314 1320
1410 1415
1346 1510
164 166
811 817
36 694
1709 1710
1494 1515
1376 1421
1309 1317
116 122 182
1315 1321
1497 1501
30 33 157
1543 1551
1310 1318
1387 1414
45 65
1411 1416
114 117
829 832
639 680
29 113
675 688
830 831
91 111
844 846
44 64
67 136
134 188
108 120
101 115
131 133
126 132
102 107
7 14
13 15
154 162
59 63
48 60

774
mutant_knot_groups/dat13 Normal file
View File

@ -0,0 +1,774 @@
5713 5851
5489 5490
5111 5171
6077 6084
5185 5379
6159 6185
5480 5481
6258 6263
6160 6184 6187
5112 5170
6853 7483
5217 5395
6170 6197 6199
5530 5572
8642 8660
5744 5897
7278 7279
5741 5894
5485 5486
5103 5163
5337 5365
5119 5178
6169 6198
5529 5539
6165 6191 6194
5602 5644
6168 6211
6069 6074
5104 5162
5105 5164
7282 7284
5808 5938
5106 5165
6162 6189
8690 8729
5720 5854
5705 5912
3377 3380
5809 5937 5940
7286 7289
5190 5378
8696 8723
8745 8824
5678 5758
6072 6076
6164 6192
8639 8644
5861 5984
6094 6126
7455 7724
8721 8735
8697 8724
8615 8616
5605 5643
5817 5968
8629 8646
6172 6201
5784 5820
5108 5166
5118 5177
5735 5879
6259 6264
5357 5415
5617 5830
8045 8047
8678 8713
5905 5949
6846 6848
7812 7832
5814 5965
5701 5908
5359 5417
5350 5432
5723 5877
6158 6183 6188
5505 5594
8726 8739
8663 8820
6171 6212
7288 7292
5187 5387
8641 8716
6621 6652
8643 8661
5121 5180
5040 5053
5841 5952
631 636 2616
5124 5183
6373 6379
5340 5368
5299 5731
6533 6563
7391 8524
5671 5760
5860 5983 8268
5522 5584
5213 5382
5314 5325 5514
7808 7855
6624 6655
5608 5648
5331 5356
8640 8645
5039 5042 5054
5244 5371
5029 5033
5328 5426
5754 5829
6646 6666
5675 5766
5726 5849
5102 5161
5343 6239
5303 5527
8689 8731
5846 5961
5866 5935
5845 5960 5962
5362 5420
5804 5878
7285 7290
5621 5833
5247 5374
5107 5167
8725 8743
5990 6005
5886 5927
5702 5909
5281 5293
6154 6174
5300 5301 5508
5842 5951 5954
8681 8708
5203 5377
5795 5974
5815 5966
6117 6210
6161 6186
8704 8710
5211 5380
4911 4961
5495 5497
5335 5363
3333 3343
5184 5385
5196 5421
5046 5058
6894 8520
6053 6078
5673 5800
5311 5836
5315 5507
8765 8772
6173 6200 6202
6988 8521
5316 5523
5844 5956
6228 6229
6619 6650
4907 4957
7957 8279
5478 5573
5904 5980
5460 5582
5901 5945
5476 5583
7811 7834
8728 8742
535 544
5812 5963
6071 6075
6531 6561
8720 8734
5696 5971
5115 5174
5026 5050
5345 6241
5988 6003
8795 8808
6157 6208
5308 5309 5837
5618 5831
8687 8740
5351 5433
5779 5826
7064 7079
1638 3072
8706 8741
7126 7127
5907 5975
6163 6190 6195
5304 5305 5524
5051 5060
8749 8750 8775 8812 8814 8816
5613 5746
5358 5416
5739 5892
8630 8647
7635 8536
5711 5959
8770 8774
5619 5832
5888 5929
5250 5253
8722 8733
8692 8718
5681 5803
5285 5297
4943 4949
5859 5982
8150 8335
5200 5425
5242 5369
6093 6127
5787 5823
5682 5768
8388 8395
5687 5729
5670 5761
7083 7128
4906 4955
7453 7722
5858 5981
7277 7281
8684 8702
5469 5540
5302 5513
5344 6240
5110 5169
5241 5334
528 557 2614
5704 5916
6671 7276
5677 5762
5615 5750
6123 6182
8691 8730
7820 8012
6001 6002
8512 8516
8736 8737
5120 5179
6649 6669
4908 4958
994 3035
5742 5895
5811 5942
5117 5175
7454 7723
5283 5295
6265 6269
5348 5430
8780 8801
6099 6130
5201 5375
638 2618
5679 5759
4918 4946
5047 5059 5089
5414 5429
5188 5384
5692 5734
8744 8825
5317 5326 5528
5353 5435
1538 3038
8013 8391
4909 4959
5336 5364
5807 5936 5941
5318 5327 5857
5700 5914
7958 8280
5749 5764
8142 8488
8683 8709
8703 8712
8766 8773
5902 5944
5319 5856
8620 8626 8651 8657
7819 8287
1231 1237
5611 5647
8662 8821
5084 5092
6096 6129
8778 8818
6375 6380
6674 7519
6167 6196
5186 5386
8685 8700
8619 8625 8650 8656
5306 5730
8617 8623 8648 8654
5189 5383
4902 4952
6623 6654
8679 8714
5204 5226 5388 5402
3378 3381
5282 5294
5212 5381
5239 5332
549 556
5782 5818
5900 5978
5526 5586
8144 8336
5320 5855
525 542
5360 5418
3289 3425
5669 5798
5840 5950 5955
5885 5926
7690 8519
6166 6193
6532 6562
5198 5423
5862 5933
1697 3042
5887 5928
5816 5967
3198 3421
6134 6144
4904 4954
3334 3344
5044 5056
5338 5366
5684 5765
8776 8777 8817 8819
5708 5913
5122 5181
1459 3071
6648 6668
5752 5827
5210 5232 5394 5406
4900 4950
5045 5057
5197 5422
6120 6153
5510 5595
5709 5957
5206 5228 5390
8789 8792
5683 5769
8698 8699
5245 5372
8748 8752 8811 8815
5614 5745
5109 5168
6771 6976
7815 7833
8686 8695
8747 8826
5791 5972
6118 6151
5525 5585
5911 5977
5930 5943
5113 5172
7821 8288
5740 5893
665 2620
8705 8711
5352 5434
6371 6377
5910 5976
7331 7334
5444 5459
6622 6653
5123 5182
2720 2727
5989 6004
5717 5871
5813 5964
3225 3255
3182 3192
6121 6180
360 414 1392
5243 5370
5607 5646
995 3039
5219 5233 5396 5407
5676 5801
5024 5048
6139 6205
8682 8701
3177 3184
5307 5839
5329 5354
8779 8782 8802 8803
5810 5939
8746 8827
5511 5596
5693 5969
5038 5043 5052
7338 7339
5843 5953
6057 6080
108 2619
867 3040
8727 8738
5412 5427
3179 3257
5781 5788
5349 5431
5721 5875
5932 5947
5284 5296
5202 5376
632 637 2617
4905 4956
7335 7337
1232 1238
6155 6206
5114 5173
8665 8822
7062 7106
5743 5896
5891 5923
5724 5847
4910 4960
5312 5313 5835
6249 6254
4901 4951
6056 6079
5620 5834
6098 6131
5116 5176
5889 5921
3352 3416
6135 6203
482 485
5783 5819
5477 5574
8622 8628 8653 8659
529 558 2615
8783 8799
8794 8797 8809 8810
8603 8605
5205 5221 5227 5389
5468 5541
5248 5251
3299 3408
5883 5924
541 555 664
5703 5915
8664 8823
3161 3166
5225 5238 5401 5411
8751 8813
5041 5055
5246 5373
6132 6142
5903 5979
3210 3216
5672 5799
5199 5424
1396 1718
2800 2801
104 107 527
5223 5236 5399 5409
5690 5732
359 413 2613
596 601
5025 5049
6647 6667
5685 5727
5747 5757
5361 5419
5680 5802
355 402
5027 5031
5712 5869
6237 6238
5220 5234 5397
167 186
5794 5973
8675 8680
6620 6651
133 195
5240 5333
8043 8049
5865 5934
5339 5367
3196 3419
3250 3282
5906 5948
906 916
505 554 815
5080 5090
4903 4953
3235 3267
5753 5828
6376 6381
536 545
403 408
6007 6008
184 200
8091 8093
4916 4944
5674 5767
5207 5229 5391 5403
6091 6125
3287 3423
276 350
2448 2596
3265 3277
5616 5751
5777 5824
5208 5230 5392 5404
1995 2006
526 543
3209 3213
5310 5838
5931 5946
72 79 657
171 621
76 524
480 481
3241 3251
6372 6378
354 400
419 434
5330 5355
5710 5958
4941 4947
3171 3186
3180 3194
8796 8807
6119 6152
926 940
3249 3281
5443 5458
938 945
3181 3195
8601 8604
5695 5970
6245 6252
6122 6181
3236 3268
5028 5032
3272 3285
3234 3262
328 389
162 203
5785 5821
5722 5876
8798 8806
3172 3187
8781 8800
8618 8624 8649 8655
5413 5428
5222 5235 5398 5408
6156 6207
2576 2612
125 193
96 106
8621 8627 8652 8658
5691 5733
5083 5091
343 396
3228 3247
399 597
6138 6204
7189 7191
5725 5848
6772 6977
5249 5252
4917 4945
3208 3221
3296 3406
130 192
113 124
3207 3223
5748 5763
8 29
3349 3414
311 376
3271 3286
3231 3273
3227 3246
7063 7107
4942 4948
6133 6143
3245 3284
345 406
157 160 358
2503 2608
381 410
323 346
70 74 390
5890 5922
5686 5728
1813 1831
2504 2566
150 154
5884 5925
3248 3261
3205 3220
1160 1162
3183 3193
6095 6128
275 314
3178 3185
3331 3335
1155 1161
244 265
3258 3279
3238 3254
181 205
132 191
374 393
5224 5237 5400 5410
140 189
3204 3219
5600 5642
3317 3320
139 188
291 337
948 3041
312 377
917 1201
1316 3048
69 73
1781 1816
3229 3233
1996 2022
1179 1425
3199 3422
927 941
5209 5231 5393 5405
344 405
3290 3426
5778 5825
128 190
5716 5870
127 202
182 206
3001 3024
1604 3058
947 3037
385 411
156 353
3197 3420
3230 3283
3278 3280
341 372
340 404
243 253
436 608
1993 2024
573 593
3288 3424
939 946
2404 2929
5786 5822
1069 3044
1486 3043
218 232
3237 3239
3328 3339
3332 3341
1063 3059
209 438
335 409
112 123
290 336
384 412
309 366
6248 6253
583 595
1022 3036
1123 1394
668 690
301 386
3167 3169 3188 3190
1126 1163
1991 2021
46 67
1990 2020
590 599
7 28
2407 2656
3329 3340
2802 2808
242 270
293 308
168 187
185 201
239 272
733 739
1997 2636
584 589
2138 2624
3168 3170 3189 3191
316 349
520 538
361 395
2197 2803
318 378
64 77
165 183
738 740
56 71
234 269
5606 5645
1114 1143
138 166
338 365
208 325
967 1059
654 662
518 530
313 317
233 268
294 407
3264 3276
57 63
305 364
471 483
3266 3275
3240 3253
394 397
519 550
207 430
429 433
217 231
3242 3252
508 539
141 142
306 356
303 401
199 204
93 102
507 517
3232 3259
488 511
513 546
292 307
23 27
11 24
129 136 194 197
3374 3375
512 514
1662 3034
3348 3351 3411
3224 3226
135 137 196 198
322 348
324 347
3292 3301 3405 3409
373 392
3294 3298 3347 3403
3346 3354 3413 3417
3355 3415
375 391
3302 3407
3368 3394
3293 3295 3402
3345 3356 3412 3418
3291 3303 3404 3410
304 362
3393 3399
274 281
623 629
3363 3365 3395 3396
3388 3390 3400 3401
3147 3149
3145 3148

4435
mutant_knot_groups/dat14 Normal file

File diff suppressed because it is too large Load Diff

29049
mutant_knot_groups/dat15 Normal file

File diff suppressed because it is too large Load Diff

BIN
nonalternating Normal file

Binary file not shown.

56
planar_diagram.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <knotkit.h>
planar_diagram::planar_diagram (const std::string &name_, unsigned n_crossings, const int crossings_ar[][4])
: name(name_),
crossings(n_crossings)
{
for (unsigned i = 1; i <= n_crossings; i ++)
{
for (unsigned j = 1; j <= 4; j ++)
crossings[i].append (crossings_ar[i - 1][j - 1]);
}
}
planar_diagram::planar_diagram (const knot_diagram &kd)
: name(kd.name),
crossings(kd.planar_diagram_crossings ())
{
}
void
planar_diagram::display_bohua () const
{
printf ("%s\t[", name.c_str ());
for (unsigned i = 1; i <= crossings.size (); i ++)
{
if (i > 1)
printf (",");
printf ("[%d,%d,%d,%d]",
crossings[i][1],
crossings[i][2],
crossings[i][3],
crossings[i][4]);
}
printf ("]\n");
}
void
planar_diagram::display_self () const
{
printf ("planar_diagram %s ", name.c_str ());
for (unsigned i = 1; i <= crossings.size (); i ++)
{
int i1 = crossings[i][1],
i2 = crossings[i][2],
i3 = crossings[i][3],
i4 = crossings[i][4];
if (i1 >= 10 || i2 >= 10 || i3 >= 10 || i4 >= 10)
printf ("X_%d,%d,%d,%d", i1, i2, i3, i4);
else
printf ("X_%d%d%d%d", i1, i2, i3, i4);
}
printf ("\n");
}

28
planar_diagram.h Normal file
View File

@ -0,0 +1,28 @@
/* Planar diagram of a knot. For details, see:
http://katlas.org/wiki/Planar_Diagrams */
class planar_diagram
{
public:
std::string name;
basedvector<basedvector<int, 1>, 1> crossings;
public:
planar_diagram () { }
planar_diagram (const std::string &name, unsigned n_crossings, const int crossings_ar[][4]);
planar_diagram (const std::string &name_, const basedvector<basedvector<int, 1>, 1> &crossings_)
: name(name_), crossings(crossings_)
{ }
planar_diagram (const knot_diagram &kd);
planar_diagram (const planar_diagram &pd)
: name(pd.name),
crossings(pd.crossings)
{ }
~planar_diagram () { }
void display_bohua () const;
void show_self () const { printf ("planar_diagram %s", name.c_str ()); }
void display_self () const;
};

165
rd_parser/location.hh Normal file
View File

@ -0,0 +1,165 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Locations for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/**
** \file location.hh
** Define the yy::location class.
*/
#ifndef BISON_LOCATION_HH
# define BISON_LOCATION_HH
# include <iostream>
# include <string>
# include "position.hh"
namespace yy {
/* Line 163 of location.cc */
#line 51 "rd_parser/location.hh"
/// Abstract a location.
class location
{
public:
/// Construct a location.
location ()
: begin (), end ()
{
}
/// Initialization.
inline void initialize (std::string* fn)
{
begin.initialize (fn);
end = begin;
}
/** \name Line and Column related manipulators
** \{ */
public:
/// Reset initial location to final location.
inline void step ()
{
begin = end;
}
/// Extend the current location to the COUNT next columns.
inline void columns (unsigned int count = 1)
{
end += count;
}
/// Extend the current location to the COUNT next lines.
inline void lines (unsigned int count = 1)
{
end.lines (count);
}
/** \} */
public:
/// Beginning of the located region.
position begin;
/// End of the located region.
position end;
};
/// Join two location objects to create a location.
inline const location operator+ (const location& begin, const location& end)
{
location res = begin;
res.end = end.end;
return res;
}
/// Add two location objects.
inline const location operator+ (const location& begin, unsigned int width)
{
location res = begin;
res.columns (width);
return res;
}
/// Add and assign a location.
inline location& operator+= (location& res, unsigned int width)
{
res.columns (width);
return res;
}
/// Compare two location objects.
inline bool
operator== (const location& loc1, const location& loc2)
{
return loc1.begin == loc2.begin && loc1.end == loc2.end;
}
/// Compare two location objects.
inline bool
operator!= (const location& loc1, const location& loc2)
{
return !(loc1 == loc2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param loc a reference to the location to redirect
**
** Avoid duplicate information.
*/
inline std::ostream& operator<< (std::ostream& ostr, const location& loc)
{
position last = loc.end - 1;
ostr << loc.begin;
if (last.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
ostr << '-' << last;
else if (loc.begin.line != last.line)
ostr << '-' << last.line << '.' << last.column;
else if (loc.begin.column != last.column)
ostr << '-' << last.column;
return ostr;
}
} // yy
/* Line 272 of location.cc */
#line 164 "rd_parser/location.hh"
#endif // not BISON_LOCATION_HH

162
rd_parser/position.hh Normal file
View File

@ -0,0 +1,162 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Positions for Bison parsers in C++
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/**
** \file position.hh
** Define the yy::position class.
*/
#ifndef BISON_POSITION_HH
# define BISON_POSITION_HH
# include <iostream>
# include <string>
# include <algorithm>
namespace yy {
/* Line 38 of location.cc */
#line 51 "rd_parser/position.hh"
/// Abstract a position.
class position
{
public:
/// Construct a position.
position ()
: filename (0), line (1), column (1)
{
}
/// Initialization.
inline void initialize (std::string* fn)
{
filename = fn;
line = 1;
column = 1;
}
/** \name Line and Column related manipulators
** \{ */
public:
/// (line related) Advance to the COUNT next lines.
inline void lines (int count = 1)
{
column = 1;
line += count;
}
/// (column related) Advance to the COUNT next columns.
inline 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.
unsigned int line;
/// Current column number.
unsigned int column;
};
/// Add and assign a position.
inline const position&
operator+= (position& res, const int width)
{
res.columns (width);
return res;
}
/// Add two position objects.
inline const position
operator+ (const position& begin, const int width)
{
position res = begin;
return res += width;
}
/// Add and assign a position.
inline const position&
operator-= (position& res, const int width)
{
return res += -width;
}
/// Add two position objects.
inline const position
operator- (const position& begin, const int width)
{
return begin + -width;
}
/// Compare two position objects.
inline bool
operator== (const position& pos1, const position& pos2)
{
return (pos1.line == pos2.line
&& pos1.column == pos2.column
&& (pos1.filename == pos2.filename
|| (pos1.filename && pos2.filename
&& *pos1.filename == *pos2.filename)));
}
/// Compare two position objects.
inline bool
operator!= (const position& pos1, const position& pos2)
{
return !(pos1 == pos2);
}
/** \brief Intercept output stream redirection.
** \param ostr the destination output stream
** \param pos a reference to the position to redirect
*/
inline std::ostream&
operator<< (std::ostream& ostr, const position& pos)
{
if (pos.filename)
ostr << *pos.filename << ':';
return ostr << pos.line << '.' << pos.column;
}
} // yy
/* Line 145 of location.cc */
#line 162 "rd_parser/position.hh"
#endif // not BISON_POSITION_HH

1030
rd_parser/rd_parser.cc Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More