Orbiter 2022
Combinatorial Objects
poset_classification_recognize.cpp
Go to the documentation of this file.
1// poset_classification_recognize.cpp
2//
3// Anton Betten
4//
5// started July 19, 2014
6
8#include "discreta/discreta.h"
11
12using namespace std;
13
14namespace orbiter {
15namespace layer4_classification {
16namespace poset_classification {
17
18
19void poset_classification::recognize_start_over(
20 int size, int f_implicit_fusion,
21 int lvl, int current_node,
22 int &final_node, int verbose_level)
23// Called from poset_orbit_node::recognize_recursion
24// when trace_next_point returns FALSE
25// This can happen only if f_implicit_fusion is TRUE
26{
27 int f_v = (verbose_level >= 1);
28 int f_vv = (verbose_level >= 2);
30
31 if (f_v) {
32 cout << "poset_classification::recognize_start_over" << endl;
33 }
34 // this is needed if implicit fusion nodes are used:
35 if (lvl == size - 1) {
36 if (f_v) {
37 cout << "poset_classification::recognize_start_over "
38 "lvl == size - 1" << endl;
39 }
40 final_node = current_node;
41 exit(1);
42 }
43
44
45 Sorting.lint_vec_heapsort(set[lvl + 1], size /* - 1 */);
46 // we don't keep the last point (i.e., the (len + 1)-th) extra
47 Lint_vec_copy(set[lvl + 1], set[0], size);
48 //int_vec_copy(size, set[lvl + 1], gen->set[0]);
49 if (f_vv) {
51 cout << endl;
52 }
53 Poset->A->element_move(
54 transporter->ith(lvl + 1),
55 transporter->ith(0), FALSE);
56 if (f_v) {
57 cout << "poset_classification::recognize_start_over "
58 "before recognize_recursion" << endl;
59 }
61 size, f_implicit_fusion,
62 0, 0, final_node,
63 verbose_level);
64 if (f_v) {
65 cout << "poset_classification::recognize_start_over "
66 "after recognize_recursion" << endl;
67 }
68 if (f_v) {
69 cout << "poset_classification::recognize_start_over done" << endl;
70 }
71}
72
73void poset_classification::recognize_recursion(
74 int size, int f_implicit_fusion,
75 int lvl, int current_node, int &final_node,
76 int verbose_level)
77// this routine is called by upstep_work::recognize
78// we are dealing with a set of size size.
79// the tracing starts at lvl = 0 with current_node = 0
80{
81 //if (my_node == 9 && my_extension == 4) {verbose_level += 10;}
82 int pt0, current_extension;
83 int f_v = (verbose_level >= 1);
84 //int f_vv = (verbose_level >= 2);
85 //int f_v10 = (verbose_level >= 10);
86 int f_vvv = (verbose_level >= 3);
87 int f_v4 = (verbose_level >= 3);
88 int f_v5 = (verbose_level >= 3);
89 int f_failure_to_find_point;
90 int node;
91
92
93 node = current_node - Poo->first_node_at_level(lvl);
94
95
96 if (f_v) {
97 cout << "poset_classification::recognize_recursion at ";
98 cout << "(" << lvl << "/" << node << ")" << endl;
99 }
100
101
102 if (lvl == size) {
103 if (f_v) {
104 cout << "poset_classification::recognize_recursion at ";
105 cout << "(" << lvl << "/" << node << ") "
106 "lvl == size, terminating" << endl;
107 }
108 final_node = current_node;
109 return;
110 }
111
113
114 //O = &root[current_node];
115 O = Poo->get_node(current_node);
116 if (f_vvv) {
117 cout << "poset_classification::recognize_recursion"
118 << " lvl = " << lvl
119 << " current_node = " << current_node
120 << " verbose_level = " << verbose_level
121 << endl;
122 cout << "node=" << O->get_node() << " prev=" << O->get_prev()
123 << " pt=" << O->get_pt() << endl;
124 orbiter_kernel_system::Orbiter->Lint_vec->set_print(cout, set[lvl], size);
125 cout << endl;
126 }
127 if (f_v4) {
128 if (Poset->f_print_function) {
129 (*Poset->print_function)(cout, size, set[lvl],
130 Poset->print_function_data);
131 }
132 }
133
134#if 0
135 if (f_debug) {
136 if (!O->check_node_and_set_consistency(this, lvl - 1,
137 gen->set[lvl])) {
139 cout << "upstep_work::recognize_recursion: "
140 "node and set inconsistent, the node "
141 "corresponds to" << endl;
142 O->store_set_to(this, lvl - 1, set3);
143 int_set_print(cout, set3, lvl);
144 cout << endl;
145 exit(1);
146 }
147 }
148#endif
149
150 if (lvl == 0 && f_base_case) {
151 long int *cur_set = set[0];
152 long int *next_set = set[0 + Base_case->size];
153 int *cur_transporter = transporter->ith(0);
154 int *next_transporter = transporter->ith(0 + Base_case->size);
155
156 O->trace_starter(this, size,
157 cur_set, next_set,
158 cur_transporter, next_transporter,
159 0 /*verbose_level */);
160 if (f_v) {
161 cout << "poset_classification::recognize_recursion at ";
162 cout << "(" << lvl << "/" << node << ") "
163 "after trace_starter, "
164 "calling recognize_recursion" << endl;
165 }
167 size, f_implicit_fusion,
168 Base_case->size, Base_case->size, final_node,
169 verbose_level);
170
171 if (f_v) {
172 cout << "poset_classification::recognize_recursion at ";
173 cout << "(" << lvl << "/" << node << ") "
174 "after recognize_recursion" << endl;
175 }
176
177 return;
178 }
179
180 if (f_v) {
181 cout << "poset_classification::recognize_recursion at ";
182 cout << "(" << lvl << "/" << node << ") "
183 "before O->trace_next_point_wrapper" << endl;
184 }
185 if (!O->trace_next_point_wrapper(this,
186 lvl, current_node, size - 1 /*len*/,
187 f_implicit_fusion, f_failure_to_find_point,
188 0 /*verbose_level - 5*/)) {
189
190 // FALSE in trace_next_point_wrapper
191 // can only happen if f_implicit_fusion is true.
192
193
194 if (f_v) {
195 cout << "poset_classification::recognize_recursion at ";
196 cout << "(" << lvl << "/" << node
197 << ") O->trace_next_point_wrapper "
198 "returns FALSE, starting over" << endl;
199 }
200
201
203 size, f_implicit_fusion,
204 lvl, current_node, final_node,
205 verbose_level);
206 if (f_v) {
207 cout << "poset_classification::recognize_recursion at ";
208 cout << "(" << lvl << "/" << node << ") "
209 "O->trace_next_point_wrapper "
210 "returns FALSE, after over" << endl;
211 }
212 }
213
214 if (f_v) {
215 cout << "poset_classification::recognize_recursion at ";
216 cout << "(" << lvl << "/" << node << ") after "
217 "O->trace_next_point_wrapper" << endl;
218 }
219
220 if (f_failure_to_find_point) {
221 cout << "poset_classification::recognize_recursion "
222 "failure to find point" << endl;
223 exit(1);
224 }
225
226 pt0 = set[lvl + 1][lvl];
227
228 if (f_v) {
229 cout << "poset_classification::recognize_recursion at ";
230 cout << "(" << lvl << "/" << node << ") trying to find "
231 "extension for point pt0=" << pt0 << endl;
232 }
233
234
235
236
237 current_extension = O->find_extension_from_point(this, pt0, FALSE);
238
239 if (f_v) {
240 cout << "poset_classification::recognize_recursion at ";
241 cout << "(" << lvl << "/" << node << "/" << current_extension
242 << ") current_extension=" << current_extension << endl;
243 }
244 if (current_extension == -1) {
245
246 cout << "poset_classification::recognize_recursion failure in "
247 "find_extension_from_point" << endl;
248
249 cout << "poset_classification::recognize_recursion "
250 "the original set is" << endl;
252 cout << endl;
253 //if (gen->f_print_function) {
254 //(*gen->print_function)(cout, size, gen->set[0],
255 //gen->print_function_data);
256 //}
257 cout << "poset_classification::recognize_recursion "
258 "the current set is" << endl;
259 orbiter_kernel_system::Orbiter->Lint_vec->set_print(cout, set[lvl + 1], size);
260 cout << endl;
261 //if (f_print_function) {
262 //(*print_function)(cout, size, set[lvl + 1],
263 //print_function_data);
264 //}
265 cout << "poset_classification::recognize_recursion "
266 "the node corresponds to" << endl;
267 O->store_set_to(this, lvl - 1, Poo->set3);
269 cout << endl;
270
271 cout << "poset_classification::recognize_recursion "
272 "lvl = " << lvl << endl;
273 cout << "poset_classification::recognize_recursion "
274 "current_node = " << current_node << endl;
275
276 exit(1);
277
278 }
279
280
281
282 if (f_v5) {
283 cout << "poset_classification::recognize_recursion point " << pt0
284 << " is extension no " << current_extension << endl;
285 }
286 if (f_allowed_to_show_group_elements && f_v4) {
287 int *transporter1 = transporter->ith(lvl + 1);
288 cout << "recognize_recursion transporter element:" << endl;
289 Poset->A2->element_print_quick(transporter1, cout);
290 //A2->element_print_as_permutation(transporter1, cout);
291 cout << endl;
292 }
293
294
295
296 // now lvl < size - 1
297
298 if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_FUSION) {
299 int next_node;
300
301 if (f_v4) {
302 cout << "poset_classification::recognize_recursion at ";
303 cout << "(" << lvl << "/" << node << "/"
304 << current_extension << ")";
305 cout << " fusion node " << O->get_node() << endl;
306 }
307 next_node = O->apply_isomorphism(this,
308 lvl, current_node,
309 current_extension, size - 1 /* len */,
310 FALSE /* f_tolerant */, verbose_level - 6);
311
312 if (f_v) {
313 cout << "poset_classification::recognize_recursion "
314 "lvl " << lvl << " at ";
315 cout << "(" << lvl << "/" << node << "/"
316 << current_extension << ")";
317 cout << " fusion from " << O->get_node() << " to "
318 << next_node << endl;
319 }
320 if (next_node == -1) {
321 cout << "poset_classification::recognize_recursion "
322 "next_node == -1" << endl;
323 exit(1);
324 }
325 if (f_v5) {
326 cout << "poset_classification::recognize_recursion at ";
327 cout << "(" << lvl << "/" << node << "/"
328 << current_extension << ")";
329 cout << " after apply_isomorphism, "
330 "next_node=" << next_node << endl;
331 }
332#if 0
333 if (next_node < path[lvl + 1]) {
334 if (f_v) {
335 cout << "poset_classification::recognize_recursion "
336 "lvl " << lvl << " not canonical" << endl;
337 cout << "next_node=" << next_node << endl;
338 //cout << "path[lvl + 1]=" << path[lvl + 1] << endl;
339 }
340 return not_canonical;
341 }
342#endif
343
344
345
347 size, f_implicit_fusion,
348 lvl + 1, next_node, final_node,
349 verbose_level);
350
351 return;
352
353 }
354 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_EXTENSION) {
355 int next_node;
356
357 if (f_v4) {
358 cout << "poset_classification::recognize_recursion "
359 "extension node" << endl;
360 }
361 next_node = O->get_E(current_extension)->get_data();
362 if (f_v) {
363 cout << "poset_classification::recognize_recursion at ";
364 cout << "(" << lvl << "/" << node << "/"
365 << current_extension << ")";
366 cout << " extension from " << O->get_node() << " to "
367 << next_node << endl;
368 }
369
371 size, f_implicit_fusion,
372 lvl + 1, next_node, final_node,
373 verbose_level);
374
375 return;
376 }
377 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_UNPROCESSED) {
378 cout << "poset_classification::recognize_recursion "
379 "unprocessed node, "
380 "this should not happen" << endl;
381 exit(1);
382 }
383 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_PROCESSING) {
384 cout << "poset_classification::recognize_recursion "
385 "processing node, "
386 "this should not happen" << endl;
387 exit(1);
388 }
389 cout << "poset_classification::recognize_recursion "
390 "unknown type of extension" << endl;
391 exit(1);
392}
393
394void poset_classification::recognize(
395 long int *the_set, int size, int *transporter,
396 int f_implicit_fusion,
397 int &final_node, int verbose_level)
398// This routine is called from upstep
399// (upstep_work::upstep_subspace_action).
400// It in turn calls poset_orbit_node::recognize_recursion
401// It tries to compute an isomorphism
402// of the set in set[0][0,...,len]
403// (i.e. of size len+1) to the
404// set in S[0,...,len] which sends set[0][len] to S[len].
405// Since set[0][0,...,len] is a permutation
406// of S[0,...,len], this isomorphism is
407// in fact an automorphism which maps S[len]
408// to one of the points in S[0,...,len - 1].
409// If this is done for all possible points
410// in S[0,...,len - 1],
411// a transversal for H in the stabilizer
412// of S[0,...,len] results,
413// where H is the point stabilizer of S[len]
414// in the set-stabilizer of S[0,...,len-1],
415// (which is a subgroup of S[0,...,len]).
416{
417 int f_v = (verbose_level >= 1);
418 int f_vv = (verbose_level >= 2);
419 int f_vvv = (verbose_level >= 3);
420
421 if (f_vvv) {
422 cout << "poset_classification::recognize" << endl;
423 }
424 // put in default values just in case we are doing a
425 // tolerant search and do not have a final result
426 final_node = -1;
427
428 Lint_vec_copy(the_set, set[0], size);
429
430 Poset->A->element_one(poset_classification::transporter->ith(0), 0);
431
432 if (f_vv) {
433 Lint_vec_print(cout, set[0], size);
434 cout << endl;
435 if (Poset->f_print_function) {
436 (*Poset->print_function)(cout, size, set[0],
437 Poset->print_function_data);
438 }
439 }
440 if (size > sz) {
441 cout << "poset_classification::recognize size > sz" << endl;
442 cout << "size=" << size << endl;
443 cout << "gen->sz=" << sz << endl;
444 exit(1);
445 }
446
447 //nb_times_trace++;
448
449
450 Lint_vec_copy(set[0], Poo->set0, size);
451
453 size, f_implicit_fusion,
454 0, 0, // start from the very first node
455 final_node,
456 verbose_level);
457
458 if (f_v) {
459 cout << "poset_classification::recognize "
460 "after recognize_recursion, "
461 "copying transporter" << endl;
462 }
463
464
465 Poset->A->element_move(
466 poset_classification::transporter->ith(size),
467 transporter, 0);
468
469
470 if (f_v) {
471 cout << "poset_classification::recognize done" << endl;
472 }
473}
474
475
476}}}
477
a collection of functions related to sorted vectors
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void element_one(void *elt, int verbose_level)
Definition: action_cb.cpp:224
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void recognize_start_over(int size, int f_implicit_fusion, int lvl, int current_node, int &final_node, int verbose_level)
void recognize_recursion(int size, int f_implicit_fusion, int lvl, int current_node, int &final_node, int verbose_level)
void print_level_extension_coset_info(int prev_level, int prev, int cur_extension, int coset, int nb_cosets)
to represent one poset orbit; related to the class poset_classification
int trace_next_point_wrapper(poset_classification *gen, int lvl, int current_node, int len, int f_implicit_fusion, int &f_failure_to_find_point, int verbose_level)
int check_node_and_set_consistency(poset_classification *gen, int i, long int *set)
int apply_isomorphism(poset_classification *gen, int lvl, int current_node, int current_extension, int len, int f_tolerant, int verbose_level)
void trace_starter(poset_classification *gen, int size, long int *cur_set, long int *next_set, int *cur_transporter, int *next_transporter, int verbose_level)
int find_extension_from_point(poset_classification *gen, long int pt, int verbose_level)
void store_set_to(poset_classification *gen, int i, long int *to)
void(* print_function)(std::ostream &ost, int len, long int *S, void *data)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FALSE
Definition: foundations.h:234
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects
#define EXTENSION_TYPE_PROCESSING
#define EXTENSION_TYPE_FUSION
#define EXTENSION_TYPE_UNPROCESSED
#define EXTENSION_TYPE_EXTENSION