210 lines
5.9 KiB
C++
210 lines
5.9 KiB
C++
|
|
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;
|
|
bool operator != (const resolution_diagram &rd) const { return !operator == (rd); }
|
|
|
|
/* 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 &) = delete;
|
|
~resolution_diagram_builder () { }
|
|
|
|
resolution_diagram_builder &operator = (const resolution_diagram_builder &) = delete;
|
|
|
|
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);
|
|
};
|