Orbiter 2022
Combinatorial Objects
geometric_backtrack_search.cpp
Go to the documentation of this file.
1/*
2 * geometric_backtrack_search.cpp
3 *
4 * Created on: Dec 27, 2021
5 * Author: betten
6 */
7
8
9
10#include "foundations.h"
11
12using namespace std;
13
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace geometry_builder {
19
20
21
23{
24 gg = NULL;
27}
28
30{
33 }
34}
35
36void geometric_backtrack_search::init(gen_geo *gg, int verbose_level)
37{
38 int f_v = (verbose_level >= 1);
39 int i;
40
41 if (f_v) {
42 cout << "geometric_backtrack_search::init" << endl;
43 }
45
47 for (i = 0; i < gg->GB->V; i++) {
48 Row_stabilizer_orbits[i] = NULL;
49 }
52
53
54 if (f_v) {
55 cout << "geometric_backtrack_search::done" << endl;
56 }
57}
58
59
61{
62 int f_v = (verbose_level >= 1);
63
64 if (f_v) {
65 cout << "geometric_backtrack_search::First" << endl;
66 }
67 int I;
68
69 I = 0;
70 while (TRUE) {
71 while (TRUE) {
72 if (I >= gg->GB->v_len) {
73 return TRUE;
74 }
75 if (!BlockFirst(I, verbose_level)) {
76 break;
77 }
78 I++;
79 }
80 // I-th element could not initialize, move on
81 while (TRUE) {
82 if (I == 0) {
83 return FALSE;
84 }
85 I--;
86 if (BlockNext(I, verbose_level)) {
87 break;
88 }
89 }
90 // I-th element has been incremented. Initialize elements after it:
91 I++;
92 }
93}
94
96{
97 int f_v = (verbose_level >= 1);
98
99 if (f_v) {
100 cout << "geometric_backtrack_search::Next" << endl;
101 }
102 int I;
103
104 I = gg->GB->v_len - 1;
105 while (TRUE) {
106 while (TRUE) {
107 if (BlockNext(I, verbose_level)) {
108 break;
109 }
110 if (I == 0) {
111 return FALSE;
112 }
113 I--;
114 }
115 // I-th element has been incremented. Initialize elements after it:
116 while (TRUE) {
117 if (I >= gg->GB->v_len - 1) {
118 return TRUE;
119 }
120 I++;
121 if (!BlockFirst(I, verbose_level)) {
122 break;
123 }
124 }
125 // I-th element could not initialize, move on
126 I--;
127 }
128}
129
130int geometric_backtrack_search::BlockFirst(int I, int verbose_level)
131{
132 int f_v = (verbose_level >= 1);
133
134 if (f_v) {
135 cout << "geometric_backtrack_search::BlockFirst I=" << I << endl;
136 }
137
139 int m;
140
141 m = 0;
142 while (TRUE) {
143 while (TRUE) {
144 if (m >= C->v) {
145 return TRUE;
146 }
147 if (!RowFirstSplit(I, m, verbose_level)) {
148 break;
149 }
150 m++;
151 }
152 // m-th element could not initialize, move on
153 while (TRUE) {
154 if (m == 0) {
155 return FALSE;
156 }
157 m--;
158 if (RowNextSplit(I, m, verbose_level)) {
159 break;
160 }
161 }
162 // m-th element has been incremented. Initialize elements after it:
163 m++;
164 }
165}
166
167int geometric_backtrack_search::BlockNext(int I, int verbose_level)
168{
169 int f_v = (verbose_level >= 1);
170
171 if (f_v) {
172 cout << "geometric_backtrack_search::BlockNext I=" << I << endl;
173 }
175
176 int m;
177
178 m = C->v - 1;
179 while (TRUE) {
180 while (TRUE) {
181 if (RowNextSplit(I, m, verbose_level)) {
182 break;
183 }
184 if (m == 0) {
185 return FALSE;
186 }
187 m--;
188 }
189 // m-th element has been incremented. Initialize elements after it:
190 while (TRUE) {
191 if (m >= C->v - 1) {
192 return TRUE;
193 }
194 m++;
195 if (!RowFirstSplit(I, m, verbose_level)) {
196 break;
197 }
198 }
199 // m-th element could not initialize, move on
200 m--;
201 }
202}
203
204#define GEO_LINE_SPLIT
205
206int geometric_backtrack_search::RowFirstSplit(int I, int m, int verbose_level)
207{
208 int f_v = (verbose_level >= 1);
209
210 if (f_v) {
211 cout << "geometric_backtrack_search::RowFirstSplit "
212 "I=" << I << " m=" << m << endl;
213 }
214
215#ifdef GEO_LINE_SPLIT
216 iso_type *it;
218 int i1;
219
220 i1 = C->i0 + m;
221 it = gg->inc->iso_type_at_line[i1];
222 if (it && it->f_split) {
223 if ((it->Canonical_forms->B.size() % it->split_modulo) != it->split_remainder) {
224 return FALSE;
225 }
226 }
227 if (!RowFirst0(I, m, verbose_level)) {
228 return FALSE;
229 }
230 return TRUE;
231#else
232 return RowFirst0(I, m, verbose_level);
233#endif
234}
235
236int geometric_backtrack_search::RowNextSplit(int I, int m, int verbose_level)
237{
238 int f_v = (verbose_level >= 1);
239
240 if (f_v) {
241 cout << "geometric_backtrack_search::RowNextSplit "
242 "I=" << I << " m=" << m << endl;
243 }
244#ifdef GEO_LINE_SPLIT
245 iso_type *it;
247 int i1;
248
249 i1 = C->i0 + m;
250 it = gg->inc->iso_type_at_line[i1];
251 if (it && it->f_split) {
252 if ((it->Canonical_forms->B.size() % it->split_modulo) != it->split_remainder) {
253 return FALSE;
254 }
255 }
256 if (!RowNext0(I, m, verbose_level)) {
257 return FALSE;
258 }
259 return TRUE;
260#else
261 return LineNext0(gg, I, m, verbose_level);
262#endif
263}
264
265int geometric_backtrack_search::geo_back_test(int I, int verbose_level)
266{
267 int f_v = (verbose_level >= 1);
268
269 if (f_v) {
270 cout << "geometric_backtrack_search::geo_back_test "
271 "I=" << I << endl;
272 }
274 int i0, i1, m, f_already_there, control_line;
275 iso_type *it;
276
277 i0 = C->i0;
278 control_line = i0 + C->v - 1;
279 for (m = 0; m < C->v - 1; m++) {
280 i1 = i0 + m;
281 it = gg->inc->iso_type_at_line[i1];
282
283 if (it && it->f_generate_first && !it->f_beginning_checked) {
284
286 FALSE /* f_partition_fixing_last */,
287 f_already_there,
288 verbose_level - 2);
289
290
291
292 gg->record_tree(i1 + 1, f_already_there);
293
294
295 if (!f_already_there) {
297 continue;
298 }
299 gg->inc->back_to_line = i1;
300 return FALSE;
301 }
302 }
303 return TRUE;
304}
305
306
307int geometric_backtrack_search::RowFirst0(int I, int m, int verbose_level)
308{
309 int f_v = (verbose_level >= 1);
310
311 if (f_v) {
312 cout << "geometric_backtrack_search::RowFirst0 "
313 "I=" << I << " m=" << m << endl;
314 }
316
317 int f_already_there, i1, control_line;
318 iso_type *it;
319
320 i1 = C->i0 + m;
321 if (!RowFirst(I, m, verbose_level)) {
322 return FALSE;
323 }
324 control_line = C->i0 + C->v - 1;
325 it = gg->inc->iso_type_at_line[i1];
326 if (i1 != control_line && it && it->f_generate_first) {
328 return TRUE;
329 }
330 if (i1 == control_line) {
331 if (!geo_back_test(I, verbose_level)) {
332 if (!RowNext(I, m, verbose_level)) {
333 return FALSE;
334 }
335 cout << "geometric_backtrack_search::RowFirst0 "
336 "back_to_line && f_new_situation == TRUE" << endl;
337 exit(1);
338 }
339 // survived the back test,
340 // and now one test of the first kind:
341 }
342 if (i1 == gg->inc->Encoding->v - 1) {
343 // a new geometry is completed
344 // let the main routine add it
345 return TRUE;
346 }
347
348 // now we know we have a partial geometry on i1 < v lines.
349
350 if (it) {
351 // test of the first kind
352 while (TRUE) {
353 if (f_v) {
354 cout << "geometric_backtrack_search::RowFirst0 "
355 "I=" << I << " m=" << m
356 << " before isot_add" << endl;
357 gg->print(cout, i1 + 1, i1 + 1);
358 }
359
361 FALSE /* f_partition_fixing_last */,
362 f_already_there,
363 verbose_level - 2);
364
365 gg->record_tree(i1 + 1, f_already_there);
366
367 if (f_v) {
368 cout << "geometric_backtrack_search::RowFirst0 "
369 "I=" << I << " m=" << m
370 << " after isot_add" << endl;
371 }
372 if (!f_already_there) {
373 break;
374 }
375 if (!RowNext(I, m, verbose_level)) {
376 return FALSE;
377 }
378 }
379 // now: a new geometry has been produced,
380 // f_already_there is FALSE
381 }
382 return TRUE;
383}
384
385int geometric_backtrack_search::RowNext0(int I, int m, int verbose_level)
386{
387 int f_v = (verbose_level >= 1);
388
389 if (f_v) {
390 cout << "geometric_backtrack_search::RowNext0 "
391 "I=" << I << " m=" << m << endl;
392 }
394
395 int f_already_there, i1, control_line;
396 iso_type *it;
397
398 i1 = C->i0 + m;
399 if (!RowNext(I, m, verbose_level)) {
400 return FALSE;
401 }
402 control_line = C->i0 + C->v - 1;
403 it = gg->inc->iso_type_at_line[i1];
404 if (i1 != control_line && it && it->f_generate_first) {
406#if 0
407 gg->inc.nb_GEO[i1] = ((ISO_TYPE *)
408 gg->inc.iso_type[control_line])->nb_GEO;
409#endif
410 return TRUE;
411 }
412 if (i1 == control_line) {
413 if (!geo_back_test(I, verbose_level)) {
414 if (!RowNext(I, m, verbose_level)) {
415 return FALSE;
416 }
417 cout << "geometric_backtrack_search::RowNext0 "
418 "back_to_line && f_new_situation == TRUE" << endl;
419 exit(1);
420 }
421 // survived the back test,
422 // and now one test of the first kind:
423 }
424 if (i1 == gg->inc->Encoding->v - 1) {
425 // a new geometry is completed
426 // let the main routine add it
427 return TRUE;
428 }
429 if (it) {
430 while (TRUE) {
432 FALSE /* f_partition_fixing_last */,
433 f_already_there,
434 verbose_level - 2);
435
436 gg->record_tree(i1 + 1, f_already_there);
437
438
439 if (!f_already_there) {
440 break;
441 }
442 if (!RowNext(I, m, verbose_level)) {
443 return FALSE;
444 }
445 }
446 // now: a new geometry has been produced,
447 // f_already_there is FALSE
448 }
449 return TRUE;
450}
451
452
453int geometric_backtrack_search::RowFirst(int I, int m, int verbose_level)
454{
455 int f_v = (verbose_level >= 1);
456
458 int i1;
459 int ret;
460
461 i1 = C->i0 + m;
462
463 if (f_v) {
464 cout << "geometric_backtrack_search::RowFirst "
465 "I=" << I << " m=" << m << " i1=" << i1 << endl;
466 }
467
468 gg->girth_Floyd(i1, verbose_level);
469
470
471 if (gg->GB->Descr->f_orderly) {
472
473 ret = RowFirstOrderly(I, m, verbose_level);
474
475 }
476 else {
477
478 ret = RowFirstLexLeast(I, m, verbose_level);
479 }
480
481
482 return ret;
483
484}
485
486int geometric_backtrack_search::RowNext(int I, int m, int verbose_level)
487{
488 int f_v = (verbose_level >= 1);
489
490 if (f_v) {
491 cout << "geometric_backtrack_search::RowNext "
492 "I=" << I << " m=" << m << endl;
493 }
495 int i1;
496 int ret;
497
498 i1 = C->i0 + m;
499 if (gg->inc->back_to_line != -1 && gg->inc->back_to_line < i1) {
500 RowClear(I, m);
501 return FALSE;
502 }
503 if (gg->inc->back_to_line != -1 && gg->inc->back_to_line == i1) {
504 gg->inc->back_to_line = -1;
505 }
506
507 if (gg->GB->Descr->f_orderly) {
508
509 ret = RowNextOrderly(I, m, verbose_level);
510
511 }
512 else {
513 ret = RowNextLexLeast(I, m, verbose_level);
514 }
515
516
517 return ret;
518}
519
520int geometric_backtrack_search::RowFirstLexLeast(int I, int m, int verbose_level)
521{
522 int f_v = (verbose_level >= 1);
523
525 int J, i1;
526
527 i1 = C->i0 + m;
528
529 if (f_v) {
530 cout << "geometric_backtrack_search::RowFirstLexLeast "
531 "I=" << I << " m=" << m << " i1=" << i1 << endl;
532 }
533
534
535 J = 0;
536 while (TRUE) {
537 while (TRUE) {
538 if (J >= gg->GB->b_len) {
539 if (f_v) {
540 cout << "geometric_backtrack_search::RowFirstLexLeast" << endl;
541 gg->print(cout, i1 + 1, gg->inc->Encoding->v);
542 }
543 return TRUE;
544 }
545 if (!ConfFirst(I, m, J, verbose_level)) {
546 break;
547 }
548 J++;
549 }
550 // J-th element could not initialize, move on
551 while (TRUE) {
552 if (J == 0) {
553 return FALSE;
554 }
555 J--;
556 if (ConfNext(I, m, J, verbose_level)) {
557 break;
558 }
559 }
560 // J-th element has been incremented. Initialize elements after it:
561 J++;
562 }
563}
564
565int geometric_backtrack_search::RowNextLexLeast(int I, int m, int verbose_level)
566{
567 int f_v = (verbose_level >= 1);
568
570 int J, i1;
571
572 i1 = C->i0 + m;
573
574 if (f_v) {
575 cout << "geometric_backtrack_search::RowNextLexLeast "
576 "I=" << I << " m=" << m << " i1=" << i1 << endl;
577 }
578
579 J = gg->GB->b_len - 1;
580 while (TRUE) {
581 while (TRUE) {
582 if (ConfNext(I, m, J, verbose_level)) {
583 break;
584 }
585 if (J == 0) {
586 return FALSE;
587 }
588 J--;
589 }
590 // J-th element has been incremented. Initialize elements after it:
591 while (TRUE) {
592 if (J >= gg->GB->b_len - 1) {
593 if (f_v) {
594 cout << "geometric_backtrack_search::RowNextLexLeast" << endl;
595 gg->print(cout, i1 + 1, gg->inc->Encoding->v);
596 }
597 return TRUE;
598 }
599 J++;
600 if (!ConfFirst(I, m, J, verbose_level)) {
601 break;
602 }
603 }
604 // J-th element could not initialize, move on
605 J--;
606 }
607}
608
609int geometric_backtrack_search::RowFirstOrderly(int I, int m, int verbose_level)
610{
611 int f_v = (verbose_level >= 1);
612
614 int i1;
615 int ret = FALSE;
616 int f_already_there;
617
618 i1 = C->i0 + m;
619
620 if (f_v) {
621 cout << "geometric_backtrack_search::RowFirstOrderly "
622 "I=" << I << " m=" << m << " i1=" << i1 << endl;
623 }
624
625 iso_type *It;
626
628
629 It = Row_stabilizer_orbits[i1];
630
631 It->init(gg, i1 + 1,
632 FALSE /* f_orderly */,
633 verbose_level);
634
635 if (!RowFirstLexLeast(I, m, verbose_level - 5)) {
636 }
637 else {
638
639 while (TRUE) {
641 TRUE /* f_partition_fixing_last */,
642 f_already_there,
643 0 /*verbose_level - 2*/);
644
645 if (!RowNextLexLeast(I, m, verbose_level - 5)) {
646 break;
647 }
648 }
649 }
650
651 if (f_v) {
652 cout << "geometric_backtrack_search::RowFirstOrderly "
653 "I=" << I << " m=" << m << " i1=" << i1
654 << " number of possible rows: " << It->Canonical_forms->B.size() << endl;
655 }
656
657 if (It->Canonical_forms->B.size()) {
658
659 place_row(I, m, 0 /* idx */, verbose_level);
660
661 ret = TRUE;
663
664 }
665 else {
666 FREE_OBJECT(It);
667 Row_stabilizer_orbits[i1] = NULL;
669 ret = FALSE;
670 }
671
672 return ret;
673}
674
675void geometric_backtrack_search::place_row(int I, int m, int idx, int verbose_level)
676{
677 int f_v = (verbose_level >= 1);
678
679 if (f_v) {
680 cout << "geometric_backtrack_search::place_row "
681 "I=" << I << " m=" << m << " idx=" << idx << endl;
682 }
683
685 int i1;
686
687 i1 = C->i0 + m;
688
689 if (f_v) {
690 cout << "geometric_backtrack_search::place_row "
691 "I=" << I << " m=" << m << " i1=" << i1 << endl;
692 }
693
694 iso_type *It;
695 It = Row_stabilizer_orbits[i1];
696
698 int J, r, j, n, j0;
699
701
702
703 r = 0;
704 for (J = 0; J < gg->GB->b_len; J++) {
706
707 j0 = C->j0;
708
709 for (n = 0; n < C->r; n++, r++) {
710
711 j = OwCF->set[It->sum_R_before + r] - i1 * gg->inc->Encoding->b - j0;
712
713 if (f_v) {
714 cout << "geometric_backtrack_search::place_row "
715 "I=" << I << " m=" << m << " J=" << J
716 << " n=" << n << " j=" << j << " before TryToPlace" << endl;
717 }
718
719 if (!TryToPlace(I, m, J, n, j, verbose_level)) {
720 cout << "geometric_backtrack_search::place_row !TryToPlace" << endl;
721 exit(1);
722 }
723
724 if (f_v) {
725 cout << "geometric_backtrack_search::place_row "
726 "I=" << I << " m=" << m << " J=" << J
727 << " n=" << n << " j=" << j << " after TryToPlace" << endl;
728 }
729
730 gg->Test_semicanonical->markers_update(I, m, J, n, j,
731 i1, j0, r,
732 verbose_level);
733
734 }
735 }
736
737 if (f_v) {
738 cout << "geometric_backtrack_search::place_row "
739 "I=" << I << " m=" << m << " idx=" << idx << " done" << endl;
740 }
741}
742
743int geometric_backtrack_search::RowNextOrderly(int I, int m, int verbose_level)
744{
745 int f_v = (verbose_level >= 1);
746
747 if (f_v) {
748 cout << "geometric_backtrack_search::RowNextOrderly "
749 "I=" << I << " m=" << m << endl;
750 }
751
753 int i1;
754 int ret = FALSE;
755
756 i1 = C->i0 + m;
757
758 if (f_v) {
759 cout << "geometric_backtrack_search::RowNextOrderly "
760 "I=" << I << " m=" << m << " i1=" << i1 << endl;
761 }
762 RowClear(I, m);
763
764 iso_type *It;
765 It = Row_stabilizer_orbits[i1];
766
767
768 if (Row_stabilizer_orbit_idx[i1] == It->Canonical_forms->B.size() - 1) {
769
771 Row_stabilizer_orbits[i1] = NULL;
773 if (f_v) {
774 cout << "geometric_backtrack_search::RowNextOrderly "
775 "I=" << I << " m=" << m << " i1=" << i1 << " finished" << endl;
776 }
777 ret = FALSE;
778 }
779 else {
780
782 place_row(I, m, Row_stabilizer_orbit_idx[i1] /* idx */, verbose_level);
783 if (f_v) {
784 cout << "geometric_backtrack_search::RowNextOrderly "
785 "I=" << I << " m=" << m << " i1=" << i1
786 << " moved on to the next sibling" << endl;
787 gg->print(cout, i1 + 1, gg->inc->Encoding->v);
788 }
789
790 ret = TRUE;
791
792 }
793
794 return ret;
795}
796
798{
799 int J;
800
801 for (J = gg->GB->b_len - 1; J >= 0; J--) {
802 ConfClear(I, m, J);
803 }
804}
805
806int geometric_backtrack_search::ConfFirst(int I, int m, int J, int verbose_level)
807{
808 int f_v = (verbose_level >= 1);
809
810 if (f_v) {
811 cout << "geometric_backtrack_search::ConfFirst "
812 "I=" << I << " m=" << m
813 << " J=" << J << endl;
814 }
816 int n;
817
818
819 if (J == 0) {
820
821 int i1;
822
823 i1 = C->i0 + m;
824
826 i1,
827 verbose_level);
828
829 }
830 n = 0;
831 while (TRUE) {
832 while (TRUE) {
833 if (n >= C->r) {
834 if (f_v) {
835 cout << "geometric_backtrack_search::ConfFirst "
836 "I=" << I << " m=" << m
837 << " J=" << J << " returns TRUE" << endl;
838 }
839 return TRUE;
840 }
841 if (!XFirst(I, m, J, n, verbose_level)) {
842 break;
843 }
844 n++;
845 }
846 // n-th element could not initialize, move on
847 while (TRUE) {
848 if (n == 0) {
849 if (f_v) {
850 cout << "geometric_backtrack_search::ConfFirst "
851 "I=" << I << " m=" << m
852 << " J=" << J << " returns FALSE" << endl;
853 }
854 return FALSE;
855 }
856 n--;
857 if (XNext(I, m, J, n, verbose_level)) {
858 break;
859 }
860 }
861 // n-th element has been incremented. Initialize elements after it:
862 n++;
863 }
864}
865
866int geometric_backtrack_search::ConfNext(int I, int m, int J, int verbose_level)
867{
868 int f_v = (verbose_level >= 1);
869
870 if (f_v) {
871 cout << "geometric_backtrack_search::ConfNext "
872 "I=" << I << " m=" << m << " J=" << J << endl;
873 }
875 int n, i1;
876
877 i1 = C->i0 + m;
878
879
881
882
883 if (C->r == 0) {
884 return FALSE;
885 }
886 n = C->r - 1;
887 while (TRUE) {
888 while (TRUE) {
889 if (XNext(I, m, J, n, verbose_level)) {
890 break;
891 }
892 if (n == 0) {
893 return FALSE;
894 if (f_v) {
895 cout << "geometric_backtrack_search::ConfNext "
896 "I=" << I << " m=" << m
897 << " J=" << J << " returns FALSE" << endl;
898 }
899 }
900 n--;
901 }
902 // n-th element has been incremented. Initialize elements after it:
903 while (TRUE) {
904 if (n >= C->r - 1) {
905 if (f_v) {
906 cout << "geometric_backtrack_search::ConfNext "
907 "I=" << I << " m=" << m
908 << " J=" << J << " returns TRUE" << endl;
909 }
910 return TRUE;
911 }
912 n++;
913 if (!XFirst(I, m, J, n, verbose_level)) {
914 break;
915 }
916 }
917 // n-th element could not initialize, move on
918 n--;
919 }
920}
921
923{
925 int n;
926
927 if (C->r == 0) {
928 return;
929 }
930 for (n = C->r - 1; n >= 0; n--) {
931 XClear(I, m, J, n);
932 }
933}
934
935int geometric_backtrack_search::XFirst(int I, int m, int J, int n, int verbose_level)
936{
937 int f_v = (verbose_level >= 1);
938
939 if (f_v) {
940 cout << "geometric_backtrack_search::XFirst "
941 "I=" << I << " m=" << m << " J=" << J
942 << " n=" << n << endl;
943 }
945 int i1, j0, r, j;
946
947 i1 = C->i0 + m; // current row
948 r = C->r0 + n; // current incidence index
949 j0 = C->j0;
950
951
952 j = gg->Test_semicanonical->row_starter(I, m, J, n,
953 i1, j0, r,
954 verbose_level);
955
956
957 int ret;
958
959 ret = X_First(I, m, J, n, j, verbose_level);
960
961 if (f_v) {
962 cout << "geometric_backtrack_search::XFirst "
963 "I=" << I << " m=" << m << " J=" << J
964 << " n=" << n << " returns " << ret << endl;
965 }
966
967 return ret;
968}
969
970int geometric_backtrack_search::XNext(int I, int m, int J, int n, int verbose_level)
971{
972 int f_v = (verbose_level >= 1);
973
974 if (f_v) {
975 cout << "geometric_backtrack_search::XNext "
976 "I=" << I << " m=" << m
977 << " J=" << J << " n=" << n << endl;
978 }
980 int old_x;
981 int fuse_idx, i1, j0, r, j, k;
982
983 fuse_idx = C->fuse_idx;
984 i1 = C->i0 + m; // current row
985 r = C->r0 + n; // current incidence index
986 j0 = C->j0;
987
988 old_x = gg->inc->Encoding->theX_ir(i1, r);
989
990 gg->girth_test_delete_incidence(i1, r, old_x);
991
992 gg->inc->K[old_x]--;
993 if (gg->GB->Descr->f_lambda) {
994 k = gg->inc->K[old_x];
995 gg->inc->theY[old_x][k] = -1;
996
997 gg->decrement_pairs_point(i1, old_x, k);
998
999 }
1000
1001
1003 i1, j0, r, old_x);
1004
1005
1006
1007#if 0
1008 if (!gg->GB->Descr->f_orderly) {
1009
1010 if (J == 0 && n == 0) {
1011 if (C->f_last_non_zero_in_fuse) {
1012 return FALSE;
1013 }
1014 }
1015
1016 }
1017#endif
1018
1019 for (j = old_x - j0 + 1; j < C->b; j++) {
1020
1021 if (TryToPlace(I, m, J, n, j, verbose_level)) {
1022
1023 gg->Test_semicanonical->marker_move_on(I, m, J, n, j,
1024 i1, j0, r,
1025 verbose_level);
1026
1027 if (f_v) {
1028 cout << "geometric_backtrack_search::XNext "
1029 "I=" << I << " m=" << m << " J=" << J
1030 << " n=" << n << " j=" << j << " returns TRUE" << endl;
1031 }
1032 return TRUE;
1033
1034 }
1035
1036 }
1037 if (f_v) {
1038 cout << "geometric_backtrack_search::XNext "
1039 "I=" << I << " m=" << m << " J=" << J
1040 << " n=" << n << " returns FALSE" << endl;
1041 }
1042 return FALSE;
1043}
1044
1045void geometric_backtrack_search::XClear(int I, int m, int J, int n)
1046{
1048 int old_x;
1049 int i1, j0, r, k;
1050
1051 i1 = C->i0 + m; // current row
1052 r = C->r0 + n; // index of current incidence within the row
1053 j0 = C->j0;
1054 old_x = gg->inc->Encoding->theX_ir(i1, r);
1055 gg->inc->K[old_x]--;
1056
1057
1058 gg->girth_test_delete_incidence(i1, r, old_x);
1059
1060
1061
1063 i1, j0, r, old_x);
1064
1065
1066
1067 gg->inc->Encoding->theX_ir(i1, r) = -1;
1068
1069 if (gg->GB->Descr->f_lambda) {
1070
1071 k = gg->inc->K[old_x];
1072 gg->inc->theY[old_x][k] = -1;
1073
1074 gg->decrement_pairs_point(i1, old_x, k);
1075
1076 }
1077}
1078
1079int geometric_backtrack_search::X_First(int I, int m, int J, int n, int j,
1080 int verbose_level)
1081// Try placing an incidence, starting from column j and moving to the right
1082// j is local coordinate
1083// maintains Decomposition_with_fuse->hbar[], vbar[], f_vbar[][],
1084// inc->Encoding->theX[][], inc->K[]
1085{
1086 int f_v = (verbose_level >= 1);
1087
1089 int fuse_idx, i1, j0, r;
1090
1091 fuse_idx = C->fuse_idx;
1092 i1 = C->i0 + m;
1093 // current row
1094
1095 r = C->r0 + n;
1096 // index of current incidence within the row
1097
1098 j0 = C->j0;
1099
1100#if 0
1101 // f_vbar must be off:
1102 if (f_vbar[i1 * inc->Encoding->dim_n + r]) {
1103 cout << "I = " << I << " m = " << m << ", J = " << J
1104 << ", n = " << n << ", i1 = " << i1
1105 << ", r = " << r << ", j0 = " << j0 << endl;
1106 cout << "X_Fst f_vbar[i1][r]" << endl;
1107 exit(1);
1108 }
1109#endif
1110
1111 for (; j < C->b; j++) {
1112
1113 if (TryToPlace(I, m, J, n, j, verbose_level)) {
1114
1115 gg->Test_semicanonical->markers_update(I, m, J, n, j,
1116 i1, j0, r,
1117 verbose_level);
1118
1119 if (f_v) {
1120 cout << "geometric_backtrack_search::X_First "
1121 "I=" << I << " m=" << m << " J=" << J
1122 << " n=" << n << " j=" << j << " returns TRUE" << endl;
1123 }
1124 return TRUE;
1125 }
1126 // continue with the next choice of j
1127
1128 } // next j
1129
1130 return FALSE;
1131}
1132
1133
1134int geometric_backtrack_search::TryToPlace(int I, int m, int J, int n, int j,
1135 int verbose_level)
1136// Try placing an incidence in column j
1137// j is local coordinate
1138// maintains Decomposition_with_fuse->hbar[], vbar[], f_vbar[][],
1139// inc->Encoding->theX[][], inc->K[]
1140{
1141 int f_v = (verbose_level >= 1);
1142
1144 int fuse_idx, i1, j0, j1, r, k;
1145
1146 fuse_idx = C->fuse_idx;
1147 i1 = C->i0 + m; // current row
1148
1149 r = C->r0 + n; // index of current incidence within the row
1150
1151 j0 = C->j0;
1152
1153 j1 = j0 + j;
1154
1155 if (gg->inc->K[j1] >= gg->Decomposition_with_fuse->K1[fuse_idx * gg->GB->b_len + J]) {
1156
1157 // column j1 is full, move on
1158
1159 if (f_v) {
1160 cout << "geometric_backtrack_search::TryToPlace "
1161 "I=" << I << " m=" << m << " J=" << J
1162 << " n=" << n << " j=" << j
1163 << " skipped because of column sum" << endl;
1164 }
1165 return FALSE;
1166 }
1167
1168
1169 if (gg->Test_semicanonical->col_marker_test(j0, j, i1)) {
1170 return FALSE;
1171 }
1172
1173 //gg->inc->Encoding->theX[i1 * gg->inc->Encoding->dim_n + r] = j1;
1174 gg->inc->Encoding->theX_ir(i1, r) = j1;
1175 // incidence must be recorded before we call find_square
1176
1177 k = gg->inc->K[j1];
1178
1179 gg->inc->theY[j1][k] = i1;
1180
1181 // and now come the tests:
1182
1183 if (!gg->apply_tests(I, m, J, n, j, verbose_level - 2)) {
1184 if (f_v) {
1185 cout << "geometric_backtrack_search::TryToPlace "
1186 "I=" << I << " m=" << m << " J=" << J
1187 << " n=" << n << " j=" << j <<
1188 " skipped because of test" << endl;
1189 }
1190 return FALSE;
1191 }
1192
1193 // the incidence passes the tests:
1194
1195 // increase column sum:
1196
1197 gg->inc->K[j1]++;
1198
1199
1200 return TRUE;
1201
1202}
1203
1204
1205
1206
1207}}}
1208
a combinatorial object for which a canonical form can be computed using Nauty
Definition: geometry.h:1487
description of a configuration which is part of class decomposition_with_fuse
classification of geometries with a given row-tactical decomposition
void decrement_pairs_point(int i1, int col, int k)
Definition: gen_geo.cpp:572
void girth_test_delete_incidence(int i, int j_idx, int j)
Definition: gen_geo.cpp:589
int apply_tests(int I, int m, int J, int n, int j, int verbose_level)
Definition: gen_geo.cpp:619
void record_tree(int i1, int f_already_there)
Definition: gen_geo.cpp:500
int TryToPlace(int I, int m, int J, int n, int j, int verbose_level)
classification of geometries based on canonical forms
data_structures::classify_using_canonical_forms * Canonical_forms
void add_geometry(inc_encoding *Encoding, int f_partition_fixing_last, int &f_already_there, int verbose_level)
Definition: iso_type.cpp:95
void init(gen_geo *gg, int v, int f_orderly, int verbose_level)
Definition: iso_type.cpp:55
void col_marker_remove(int I, int m, int J, int n, int i1, int j0, int r, int old_x)
void row_init(int I, int m, int J, int i1, int verbose_level)
int row_starter(int I, int m, int J, int n, int i1, int j0, int r, int verbose_level)
void marker_move_on(int I, int m, int J, int n, int j, int i1, int j0, int r, int verbose_level)
void markers_update(int I, int m, int J, int n, int j, int i1, int j0, int r, int verbose_level)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_pvoid(n)
Definition: foundations.h:637
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
the orbiter library for the classification of combinatorial objects