Orbiter 2022
Combinatorial Objects
upstep_work_trace.cpp
Go to the documentation of this file.
1// upstep_work_trace.cpp
2//
3// Anton Betten
4//
5// moved out of upstep_work.cpp: Dec 20, 2011
6
8#include "discreta/discreta.h"
11
12using namespace std;
13
14namespace orbiter {
15namespace layer4_classification {
16namespace poset_classification {
17
18
20 int &final_node, int &final_ex, int f_tolerant,
21 int verbose_level)
22// This routine is called from upstep
23// (upstep_work::upstep_subspace_action).
24// It in turn calls poset_orbit_node::recognize_recursion
25// It tries to compute an isomorphism
26// of the set in set[0][0,...,len]
27// (i.e. of size len+1) to the
28// set in S[0,...,len] which sends set[0][len] to S[len].
29// Since set[0][0,...,len] is a permutation
30// of S[0,...,len], this isomorphism is
31// in fact an automorphism which maps S[len]
32// to one of the points in S[0,...,len - 1].
33// If this is done for all possible points
34// in S[0,...,len - 1],
35// a transversal for H in the stabilizer of
36// S[0,...,len] results,
37// where H is the point stabilizer of S[len]
38// in the set-stabilizer of S[0,...,len-1],
39// (which is a subgroup of S[0,...,len]).
40{
42 int f_v = (verbose_level >= 1);
43 int f_vv = (verbose_level >= 2);
44 //int f_vvv = (verbose_level >= 3);
45 int len = size - 1;
47
48 if (f_v) {
50 cout << "upstep_work::recognize "
51 "verbose_level = " << verbose_level << endl;
52 }
53 // put in default values just in case we are doing a
54 // tolerant search and do not have a final result
55 final_node = -1;
56 final_ex = -1;
57
58 if (f_vv) {
60 Lint_vec_print(cout, gen->get_set_i(0), len + 1);
61 cout << endl;
64 }
65 }
66#if 0
67 if (len >= gen->sz) {
68 cout << "upstep_work::recognize "
69 "len >= sz, "
70 "gen->nb_times_trace="
71 << gen->nb_times_trace << endl;
72 cout << "len=" << len << endl;
73 cout << "gen->sz=" << gen->sz << endl;
74 exit(1);
75 }
76#endif
77 //gen->nb_times_trace++;
78
79#if 0
80 if ((gen->nb_times_trace & ((1 << 17) - 1)) == 0) {
81 cout << "upstep_work::recognize() " << endl;
82 cout << "nb_times_trace=" << gen->nb_times_trace << endl;
83 cout << "nb_times_trace_was_saved="
84 << gen->nb_times_trace_was_saved << endl;
85 }
86#endif
87
89 Sorting.lint_vec_heapsort(gen->get_set0(), size - 1);
90 // important: we keep the last point separate
91
92 if (f_v) {
94 cout << "upstep_work::recognize "
95 "before recognize_recursion"
96 << endl;
97 }
99 0, 0, // start from the very first node
100 final_node, final_ex,
101 f_tolerant,
102 verbose_level);
103 if (f_v) {
105 cout << "upstep_work::recognize "
106 "after recognize_recursion"
107 << endl;
108 }
109 if (f_v) {
110 cout << "upstep_work::recognize "
111 "after recognize_recursion" << endl;
113 cout << " returning " << trace_result_as_text(r) << endl;
114 }
115 return r;
116}
117
119 int lvl, int current_node,
120 int &final_node, int &final_ex,
121 int f_tolerant, int verbose_level)
122// this routine is called from
123// upstep_work::recognize
124// we are dealing with a set of size len + 1.
125// but we can only trace the first len points.
126// the tracing starts at lvl = 0 with current_node = 0
127{
128 //if (my_node == 9 && my_extension == 4) {verbose_level += 10;}
129 int pt0, current_extension;
130 int f_v = (verbose_level >= 1);
131 //int f_vv = (verbose_level >= 2);
132 //int f_v10 = (verbose_level >= 10);
133 int f_vvv = (verbose_level >= 3);
134 int f_v4 = (verbose_level >= 3);
135 int f_v5 = (verbose_level >= 3);
136 int len = size - 1;
137 int f_failure_to_find_point;
138
140
141 O = gen->get_node(current_node);
142 if (f_vvv) {
144 cout << "upstep_work::recognize_recursion"
145 << " lvl = " << lvl
146 << " current_node = " << current_node
147 << " verbose_level = " << verbose_level
148 << endl;
149 cout << "node=" << O->get_node() << " prev="
150 << O->get_prev() << " pt=" << O->get_pt() << endl;
152 cout << endl;
153 }
154 if (current_node < path[lvl]) {
156 cout << "upstep_work::recognize_recursion: "
157 "not canonical" << endl;
158 cout << "current_node=" << current_node << endl;
159 cout << "path[lvl]=" << path[lvl] << endl;
160 return not_canonical;
161 }
162 if (f_v4) {
165 }
166 }
167
168 if (f_debug) {
170 lvl - 1, gen->get_set_i(lvl))) {
172 cout << "upstep_work::recognize_recursion: "
173 "node and set inconsistent, "
174 "the node corresponds to" << endl;
175 O->store_set_to(gen, lvl - 1, gen->get_set3());
177 cout << endl;
178 exit(1);
179 }
180 }
181
182 if (lvl == 0 && gen->has_base_case()) {
183 if (f_v4) {
185 cout << "upstep_work::recognize_recursion "
186 "special handling because of starter" << endl;
187 }
188 long int *cur_set = gen->get_set_i(0);
189 long int *next_set =
191 int *cur_transporter =
192 gen->get_transporter()->ith(0);
193 int *next_transporter =
195
197 size,
198 cur_set,
199 next_set,
200 cur_transporter,
201 next_transporter,
202 0 /*verbose_level */);
203
204 if (f_v) {
206 cout << "upstep_work::recognize_recursion after trace_starter, "
207 "calling find_automorphism_by_tracing_recursion for node "
208 << gen->get_Base_case()->size << endl;
209 }
210 trace_result r;
211
215 final_node,
216 final_ex,
217 f_tolerant,
218 verbose_level);
219 if (f_v) {
221 cout << "upstep_work::recognize_recursion "
222 "after trace_starter, "
223 "after recognize_recursion for node "
224 << gen->get_Base_case()->size << endl;
225 }
226 return r;
227 }
228
229 if (f_v4) {
231 cout << "upstep_work::recognize_recursion lvl=" << lvl
232 << " current_node=" << current_node
233 << " calling O->trace_next_point_wrapper" << endl;
234 }
236 gen,
237 lvl,
238 current_node,
239 len,
241 f_failure_to_find_point,
242 verbose_level - 5)) {
243
244 // FALSE in trace_next_point_wrapper can
245 // only happen if f_implicit_fusion is true.
246
247
248 if (f_v) {
250 cout << "upstep_work::recognize_"
251 "recursion trace_next_point_wrapper returns FALSE, "
252 "starting over" << endl;
253 }
254 trace_result r;
255
256 r = start_over(
257 lvl,
258 current_node,
259 final_node,
260 final_ex,
261 f_tolerant,
262 verbose_level);
263 if (f_v) {
265 cout << "upstep_work::recognize_after start_over" << endl;
266 }
267 return r;
268 }
269
270 if (f_v4) {
271 cout << "upstep_work::recognize_recursion "
272 "after trace_next_point_wrapper" << endl;
273 }
274
275 if (f_failure_to_find_point) {
276 if (f_v) {
277 cout << "upstep_work::recognize_recursion "
278 "failure to find point" << endl;
279 }
281 }
282
283 pt0 = gen->get_set_i(lvl + 1)[lvl];
284 current_extension = O->find_extension_from_point(gen, pt0, FALSE);
285
286 if (current_extension == -1) {
287
288 cout << "upstep_work::recognize_recursion "
289 "failure in find_extension_from_point" << endl;
290 cout << "the original set is" << endl;
292 cout << endl;
293 //if (gen->f_print_function) {
294 //(*gen->print_function)(cout, len + 1, gen->set[0],
295 // gen->print_function_data);
296 //}
297 cout << "the current set is" << endl;
299 cout << endl;
300 //if (gen->f_print_function) {
301 //(*gen->print_function)(cout, len + 1, gen->set[lvl + 1],
302 // gen->print_function_data);
303 //}
304 cout << "the node corresponds to" << endl;
305 O->store_set_to(gen, lvl - 1, gen->get_set3());
307 cout << endl;
308
309 cout << "lvl = " << lvl << endl;
310 cout << "current_node = " << current_node << endl;
311
312 cout << "pt0=" << pt0 << endl;
313 cout << "gen->set[0][lvl]=" << gen->get_set_i(0)[lvl] << endl;
314
315 if (current_node == path[lvl]
316 && pt0 < gen->get_set_i(0)[lvl]) {
317 cout << "since pt0=" << pt0 << " is less than '"
318 "gen->set[0][lvl]=" << gen->get_set_i(0)[lvl]
319 << ", we return not_canonical" << endl;
320 return not_canonical;
321 }
322#if 0
323 if (gen->f_print_function) {
324 (*gen->print_function)(cout, lvl,
325 gen->set3, gen->print_function_data);
326 }
327 gen->print_tree();
328 exit(1);
329#else
330 // it is possible that we trace a set that is not admissible.
331 // This can happen in the set stabilizer routine.
332 // The set stabilizer routine does not know which sets are admissible.
333 // It reduces set-orbits to those that appear in the given set
334 // to be stabilized.
335 // So, when computing the next level, it considers all extensions
336 // and hence may come across a set that is not admissible.
337 // Returning no_result suffices, since we are not really interested
338 // in the full automorphism group of the set in this case.
340#endif
341 }
342
343
344
345 if (f_v5) {
346 cout << "upstep_work::recognize_recursion "
347 "point " << pt0 << " is extension no "
348 << current_extension << endl;
349 }
350 if (gen->allowed_to_show_group_elements() && f_v4) {
351 cout << "upstep_work::recognize_recursion "
352 "transporter element:" << endl;
353 int *transporter = gen->get_transporter()->ith(lvl + 1);
354 gen->get_A2()->element_print_quick(transporter, cout);
355 //gen->A2->element_print_as_permutation(transporter, cout);
356 cout << endl;
357 }
358
359
360 if (lvl == len) {
361 if (f_v) {
363 cout << "upstep_work::recognize_recursion "
364 "calling handle_last_level" << endl;
365 cout << "The element \\alpha is equal to " << endl;
367 gen->get_transporter()->ith(lvl + 1), cout);
368 }
369 trace_result r;
370 if (f_v) {
372 cout << "upstep_work::recognize_recursion "
373 "before handle_last_level" << endl;
374 }
376 lvl,
377 current_node,
378 current_extension,
379 pt0,
380 final_node,
381 final_ex,
382 verbose_level);
383 if (f_v) {
385 cout << "upstep_work::recognize_recursion "
386 "after handle_last_level" << endl;
387 }
388 return r;
389 }
390
391 // now lvl < len
392
393 if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_FUSION) {
394 int next_node;
395
396 if (f_v4) {
398 cout << "upstep_work::find_automorphism_by_"
399 "tracing_recursion at ";
400 cout << "(" << current_node
401 << "/" << current_extension << ")";
402 cout << " fusion node " << O->get_node() << endl;
403 }
404 next_node = O->apply_isomorphism(
405 gen,
406 lvl,
407 current_node,
408 current_extension,
409 len,
410 f_tolerant,
411 verbose_level - 6);
412
413 if (f_v) {
415 cout << "upstep_work::find_automorphism_by_"
416 "tracing_recursion lvl "
417 << lvl << " at ";
418 cout << "(" << current_node
419 << "/" << current_extension << ")";
420 cout << " fusion from " << O->get_node()
421 << " to " << next_node << endl;
422 }
423 if (next_node == -1) {
424 cout << "We return no_result_extension_not_found" << endl;
426 }
427 if (f_v5) {
429 cout << "upstep_work::find_automorphism_by_"
430 "tracing_recursion at ";
431 cout << "(" << current_node << "/"
432 << current_extension << ")";
433 cout << " after apply_isomorphism, "
434 "next_node=" << next_node << endl;
435 }
436 if (next_node < path[lvl + 1]) {
437 if (f_v) {
439 cout << "upstep_work::find_automorphism_by_"
440 "tracing_recursion lvl " << lvl
441 << " not canonical" << endl;
442 cout << "next_node=" << next_node << endl;
443 cout << "path[lvl + 1]=" << path[lvl + 1] << endl;
444 }
445 return not_canonical;
446 }
447
448 if (f_v) {
450 cout << "upstep_work::recognize_recursion "
451 "calling recognize_recursion" << endl;
452 }
453 trace_result r;
454
456 lvl + 1,
457 next_node,
458 final_node,
459 final_ex,
460 f_tolerant,
461 verbose_level);
462
463 if (f_v) {
465 cout << "upstep_work::recognize_recursion "
466 "after recognize_recursion" << endl;
467 }
468 return r;
469
470 }
471 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_EXTENSION) {
472 int next_node;
473
474 if (f_v4) {
475 cout << "extension node" << endl;
476 }
477 next_node = O->get_E(current_extension)->get_data();
478 if (f_v) {
480 cout << "upstep_work::find_automorphism_by_"
481 "tracing_recursion at ";
482 cout << "(" << current_node << "/" << current_extension << ")";
483 cout << " extension from " << O->get_node() << " to "
484 << next_node << endl;
485 }
486 if (f_v) {
487 cout << "upstep_work::recognize_recursion "
488 "calling recognize_recursion" << endl;
489 }
490 trace_result r;
492 lvl + 1,
493 next_node,
494 final_node,
495 final_ex,
496 f_tolerant,
497 verbose_level);
498 if (f_v) {
500 cout << "upstep_work::recognize_recursion "
501 "after recognize_recursion" << endl;
502 }
503 return r;
504 }
505 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_UNPROCESSED) {
506 cout << "unprocessed node at level len, "
507 "this should not happen" << endl;
508 exit(1);
509 }
510 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_PROCESSING) {
511 cout << "processing node at level len, "
512 "this should not happen" << endl;
513 exit(1);
514 }
515 cout << "unknown type of extension" << endl;
516 exit(1);
517}
518
520 int lvl, int current_node,
521 int current_extension, int pt0,
522 int &final_node, int &final_ex,
523 int verbose_level)
524// called from poset_orbit_node::recognize_recursion
525{
526 int f_v = (verbose_level >= 1);
527 int f_vv = (verbose_level >= 2);
528 //int next_node;
529 int my_current_node;
530
531 poset_orbit_node *O = gen->get_node(current_node);
532
533 if (f_v) {
535 cout << "upstep_work::handle_last_level lvl=" << lvl
536 << " node=" << O->get_node()
537 << " current_node=" << current_node
538 << " current_extension=" << current_extension
539 << " pt0=" << pt0
540 << endl;
541 }
542 if (current_node < path[size - 1]) {
543 if (f_v) {
545 cout << "upstep_work::handle_last_level "
546 "current_node=" << current_node
547 << " < " << path[size - 1]
548 << ", i.e. not canonical" << endl;
549 }
550 return not_canonical;
551 }
552 //my_current_node = gen->root[my_node].E[my_extension].data;
553 my_current_node = cur;
554 if (f_v) {
556 cout << "upstep_work::handle_last_level "
557 "my_current_node=" << my_current_node << endl;
558 }
559
560 if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_UNPROCESSED) {
561 if (f_vv) {
563 cout << "upstep_work::handle_last_level "
564 "calling install_fusion_node at ";
565 cout << "(" << current_node << "/"
566 << current_extension << ")" << endl;
567 }
568
570 gen,
571 lvl,
572 current_node,
573 prev,
574 prev_ex,
575 coset,
576 pt0,
577 current_extension,
578 f_debug,
580 verbose_level - 2);
581
582 if (f_vv) {
584 cout << "upstep_work::handle_last_level "
585 "after install_fusion_node at ";
586 cout << "(" << current_node << "/"
587 << current_extension << ")" << endl;
588 }
589
590 if (f_v) {
592 cout << "install fusion node (" << current_node
593 << "/" << current_extension << ") -> ("
594 << prev << "/" << prev_ex << ")" << endl;
595 }
596 if (f_vv) {
598 cout << "upstep_work::handle_last_level "
599 "install_fusion_node at ";
600 cout << "(" << current_node << "/"
601 << current_extension << ")";
602 cout << " done, returning no_result_fusion_"
603 "node_installed" << endl;
604 }
605 final_node = current_node;
606 final_ex = current_extension;
607
609 }
610 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_FUSION) {
611 if (f_vv) {
613 cout << "upstep_work::handle_last_level at ";
614 cout << "(" << current_node << "/" << current_extension
615 << ") fusion node already installed, "
616 "returning no_result" << endl;
617 }
618 final_node = current_node;
619 final_ex = current_extension;
620 // fusion node is already installed
622
623 }
624 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_PROCESSING) {
625 if (f_v) {
627 cout << "upstep_work::handle_last_level: at ";
628 cout << "(" << current_node << "/"
629 << current_extension << ")";
630 cout << " extension node is current node, "
631 "i.e. found an automorphism" << endl;
632 if (gen->allowed_to_show_group_elements() && f_vv) {
634 gen->get_transporter()->ith(lvl + 1), cout);
635 cout << endl;
636 }
637 }
638 final_node = current_node;
639 final_ex = current_extension;
640
641 return found_automorphism;
642 }
643 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_EXTENSION) {
644#if 1
646 cout << "upstep_work::handle_last_level: at";
647 cout << "(" << current_node << "/"
648 << current_extension << ")";
649 cout << " extension node at level len, "
650 "this should not happen" << endl;
651 cout << "the original set is" << endl;
653 cout << endl;
654 cout << "the current set is" << endl;
656 cout << endl;
657 cout << "the node corresponds to" << endl;
658 O->store_set_to(gen, lvl - 1, gen->get_set3());
660 cout << endl;
661 exit(1);
662#else
663 return no_result_extension_not_found; // A Betten Dec 17, 2011 !!!
664#endif
665 }
666 else if (O->get_E(current_extension)->get_type() == EXTENSION_TYPE_NOT_CANONICAL) {
668 cout << "upstep_work::handle_last_level "
669 "reached EXTENSION_TYPE_NOT_CANONICAL, "
670 "returning not_canonical" << endl;
671 return not_canonical;
672 }
673 cout << "upstep_work::handle_last_level: "
674 "fatal: unknown type of extension" << endl;
675 exit(1);
676}
677
679 int lvl, int current_node,
680 int &final_node, int &final_ex,
681 int f_tolerant, int verbose_level)
682// Called from poset_orbit_node::recognize_recursion
683// when trace_next_point returns FALSE
684// This can happen only if f_implicit_fusion is TRUE
685{
686 int f_v = (verbose_level >= 1);
687 int f_vv = (verbose_level >= 2);
689
690 if (f_v) {
692 cout << "upstep_work::start_over" << endl;
693 }
694 // this is needed if implicit fusion nodes are used:
695 if (lvl == size - 1) {
696 if (f_v) {
698 cout << "upstep_work::start_over lvl == size - 1, "
699 "so we return not_canonical" << endl;
700 }
701 final_node = current_node;
702 final_ex = -1;
703 return not_canonical;
704 }
705
706
707 Sorting.lint_vec_heapsort(gen->get_set_i(lvl + 1), size - 1);
708 // we keep the last point (i.e., the (len + 1)-th) extra
709 Lint_vec_copy(gen->get_set_i(lvl + 1), gen->get_set_i(0), size);
710
711 if (f_vv) {
713 cout << endl;
714 }
716 gen->get_transporter()->ith(lvl + 1),
717 gen->get_transporter()->ith(0),
718 FALSE);
719
720 trace_result r;
721 if (f_v) {
723 cout << "upstep_work::start_over "
724 "before recognize_recursion" << endl;
725 }
727 0,
728 0,
729 final_node,
730 final_ex,
731 f_tolerant,
732 verbose_level);
733 if (f_v) {
735 cout << "upstep_work::start_over "
736 "after recognize_recursion" << endl;
737 }
738 if (f_v) {
740 cout << "upstep_work::start_over done" << endl;
741 }
742 return r;
743}
744
745}}}
746
747
a collection of functions related to sorted vectors
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
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)
void install_fusion_node(poset_classification *gen, int lvl, int current_node, int my_node, int my_extension, int my_coset, long int pt0, int current_extension, int f_debug, int f_implicit_fusion, int verbose_level)
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)
trace_result recognize_recursion(int lvl, int current_node, int &final_node, int &final_ex, int f_tolerant, int verbose_level)
trace_result start_over(int lvl, int current_node, int &final_node, int &final_ex, int f_tolerant, int verbose_level)
trace_result handle_last_level(int lvl, int current_node, int current_extension, int pt0, int &final_node, int &final_ex, int verbose_level)
trace_result recognize(int &final_node, int &final_ex, int f_tolerant, int verbose_level)
#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_NOT_CANONICAL
#define EXTENSION_TYPE_EXTENSION