forked from cseed/knotkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cobordism.h
209 lines (182 loc) · 5.86 KB
/
cobordism.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
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);
};