Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pq_tree.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file pq_tree.cpp
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // pq_tree.cpp
5 //
6 //==========================================================================
7 // $Id: pq_tree.cpp,v 1.22 2008/02/03 18:12:07 chris Exp $
8 
9 #include <GTL/pq_tree.h>
10 #include <GTL/debug.h>
11 
12 #include <stack>
13 #include <queue>
14 #include <utility>
15 #include <cstdio>
16 
17 #ifdef __GTL_MSVCC
18 # ifdef _DEBUG
19 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
20 # error SEARCH NOT ENABLED
21 # endif
22 # define new DEBUG_NEW
23 # undef THIS_FILE
24  static char THIS_FILE[] = __FILE__;
25 # endif // _DEBUG
26 #endif // __GTL_MSVCC
27 
29 
30 pq_tree::pq_tree (int id, node n, const list<pq_leaf*>& li)
31 {
32 #ifdef _DEBUG
34 #endif
35  list<pq_leaf*>::const_iterator it;
36  list<pq_leaf*>::const_iterator end = li.end();
37  sons_list sons;
38  pq_leaf* tmp;
39 
40  for (it = li.begin(); it != end; ++it) {
41  tmp = *it;
42  tmp->pos = sons.insert (sons.end(), tmp);
43  }
44 
45  root = new p_node(n, id, sons);
46  pert_root = 0;
47  fail = 0;
48  pseudo = 0;
49 }
50 
52 {
53 #ifdef _DEBUG
55 #endif
56  reset ();
57 
58  if (root) {
59  delete root;
60  }
61 }
62 
63 
64 bool pq_tree::bubble_up (list<pq_leaf*>& leaves)
65 {
66  queue<pq_node*> qu;
67  int block_count = 0;
68  int blocked_siblings = 0;
70  int off_the_top = 0;
71  pq_node* tmp;
72 
73  assert (clear_me.empty());
74 
75  list<pq_leaf*>::const_iterator it = leaves.begin();
76  list<pq_leaf*>::const_iterator lend = leaves.end();
77 
78  while (it != lend) {
79  qu.push (*it);
80  (*it)->lpos = clear_me.insert (clear_me.end(), *it);
82  ++it;
83  }
84 
85  sons_iterator next, prev, end;
86  pq_node* father;
87  int size = pert_leaves_count;
88 
89  while (size + block_count + off_the_top > 1) {
90  if (size == 0) {
91  return false;
92  }
93 
94  tmp = qu.front();
95  qu.pop();
96  size--;
97  tmp->pert_leaves = 0;
98 
99  if (tmp == root) {
100  off_the_top = 1;
101  tmp->mark = pq_node::UNBLOCKED;
102  continue;
103  }
104 
105  tmp->mark = pq_node::BLOCKED;
106 
107  if (tmp->is_endmost) {
108  father = tmp->father;
109  tmp->mark = pq_node::UNBLOCKED;
110  end = father->sons.end();
111 
112  if (father->kind() == pq_node::Q_NODE) {
113  blocked_siblings = 0;
114  next = tmp->pos;
115  prev = tmp->pos;
116  ++next;
117  --prev;
118 
119  if (next != end) {
120  if ((*next)->mark == pq_node::BLOCKED) {
121  ++blocked_siblings;
122  }
123  } else if (prev != end) {
124  if ((*prev)->mark == pq_node::BLOCKED) {
125  ++blocked_siblings;
126  }
127  }
128  }
129 
130  } else {
131  next = tmp->pos;
132  prev = tmp->pos;
133  ++next;
134  --prev;
135  blocked_siblings = 0;
136 
137  if ((*prev)->mark == pq_node::UNBLOCKED) {
138  tmp->mark = pq_node::UNBLOCKED;
139  tmp->father = (*prev)->father;
140  father = tmp->father;
141  end = father->sons.end();
142  } else if ((*prev)->mark == pq_node::BLOCKED) {
143  blocked_siblings++;
144  }
145 
146  if ((*next)->mark == pq_node::UNBLOCKED) {
147  tmp->mark = pq_node::UNBLOCKED;
148  tmp->father = (*next)->father;
149  father = tmp->father;
150  end = father->sons.end();
151  } else if ((*next)->mark == pq_node::BLOCKED) {
152  blocked_siblings++;
153  }
154  }
155 
156  if (tmp->mark == pq_node::UNBLOCKED) {
157  ++(father->pert_children);
158 
159  if (father->mark == pq_node::UNMARKED) {
160  qu.push (father);
161  father->lpos = clear_me.insert (clear_me.end(), father);
162  size++;
163  father->mark = pq_node::QUEUED;
164  }
165 
166  if (father->kind() == pq_node::Q_NODE) {
167  pq_node* tmp;
168 
169  while (next != end) {
170  tmp = *next;
171  if (tmp->mark == pq_node::BLOCKED) {
172  tmp->father = father;
173  tmp->mark = pq_node::UNBLOCKED;
174 
175  if (tmp->kind () != pq_node::DIR) {
176  ++(father->pert_children);
177  }
178  } else if (tmp->kind () == pq_node::DIR &&
179  tmp->mark == pq_node::UNMARKED) {
180  tmp->lpos = clear_me.insert (clear_me.end(), tmp);
181  tmp->father = father;
182  tmp->mark = pq_node::UNBLOCKED;
183  } else {
184  break;
185  }
186 
187  ++next;
188  }
189 
190  while (prev != end) {
191  tmp = *prev;
192  if (tmp->mark == pq_node::BLOCKED) {
193  tmp->father = father;
194  tmp->mark = pq_node::UNBLOCKED;
195 
196  if (tmp->kind () != pq_node::DIR) {
197  ++(father->pert_children);
198  }
199  } else if (tmp->kind () == pq_node::DIR &&
200  tmp->mark == pq_node::UNMARKED) {
201  tmp->lpos = clear_me.insert (clear_me.end(), tmp);
202  tmp->father = father;
203  tmp->mark = pq_node::UNBLOCKED;
204  } else {
205  break;
206  }
207 
208  --prev;
209  }
210 
211  block_count -= blocked_siblings;
212  }
213 
214  } else {
215 
216  //
217  // tmp is BLOCKED
218  //
219 
220  while ((*next)->kind() == pq_node::DIR &&
221  (*next)->mark == pq_node::UNMARKED) {
222  (*next)->mark = pq_node::BLOCKED;
223  (*next)->lpos = clear_me.insert (clear_me.end(), *next);
224  ++next;
225  }
226 
227  while ((*prev)->kind() == pq_node::DIR &&
228  (*prev)->mark == pq_node::UNMARKED) {
229  (*prev)->mark = pq_node::BLOCKED;
230  (*prev)->lpos = clear_me.insert (clear_me.end(), *prev);
231  --prev;
232  }
233 
234  block_count += 1 - blocked_siblings;
235  }
236  }
237 
238  return true;
239 }
240 
241 
242 pq_node* pq_tree::where_bubble_up_failed (list<pq_leaf*>& leaves)
243 {
244 
245  //
246  // Search the first leaf that leads to an interior block.
247  //
248 
249  pq_leaf* le;
250  pq_node* blocked = 0;
251 
252  list<pq_leaf*>::iterator l_it = leaves.begin();
253  list<pq_leaf*>::iterator l_end = leaves.end();
254  q_node* father = 0;
255 
256  while (l_it != l_end ) {
257  le = *l_it;
258  blocked = leads_to_blocked (le);
259 
260  if (blocked != 0) {
261  //
262  // Search the father of this block.
263  //
264 
265  sons_iterator it = blocked->pos;
266  while (!(*it)->is_endmost) {
267  ++it;
268  }
269 
270  father = (*it)->father->Q();
271 
272  //
273  // give all the children the right father.
274  //
275 
276  it = father->sons.begin();
277  sons_iterator end = father->sons.end();
278 
279  while (it != end) {
280  if ((*it)->mark == pq_node::BLOCKED) {
281  (*it)->father = father;
282  (*it)->mark = pq_node::UNBLOCKED;
283  if ((*it)->kind() != pq_node::DIR) {
284  ++(father->pert_children);
285  }
286  }
287 
288  ++it;
289  }
290 
291  //
292  // We have to assure that there isn't any other interior block in the
293  // subtree of father.
294  //
295 
296  pq_node* another = blocked_in_subtree (father);
297 
298  if (another == 0) {
299  break;
300  }
301  }
302 
303  ++l_it;
304  }
305 
306  assert (father != 0);
307 
308  //
309  // delete all pertinent leaves that do not lead to father
310  //
311 
312  l_it = leaves.begin();
313 
314  while (l_it != l_end ) {
315  le = *l_it;
316 
317  if (!leads_to (le, father)) {
318  l_it = leaves.erase (l_it);
319  } else {
320  ++l_it;
321  }
322  }
323 
324  return father;
325 }
326 
327 
329 {
330  if (n->kind() == pq_node::LEAF) {
331  return 0;
332  }
333 
334  if (n->mark == pq_node::BLOCKED) {
335  return n;
336  }
337 
338  sons_iterator it = n->sons.begin();
339  sons_iterator end = n->sons.end();
340 
341  while (it != end) {
342  pq_node* bl = blocked_in_subtree (*it);
343 
344  if (bl) {
345  return bl;
346  }
347 
348  ++it;
349  }
350 
351  return 0;
352 }
353 
354 
355 bool pq_tree::leads_to (pq_node* le, pq_node* other)
356 {
357  if (le == root) {
358  return false;
359  } else if (le->mark == pq_node::BLOCKED) {
360  return false;
361  } else if (le->mark == pq_node::UNMARKED) {
362  return false;
363  } else if (le->father == other) {
364  return true;
365  } else {
366  return leads_to (le->father, other);
367  }
368 }
369 
371 {
372  if (le == root) {
373  return 0;
374  } else if (le->mark == pq_node::BLOCKED) {
375  return le;
376  } else if (le->mark == pq_node::UNMARKED) {
377  return 0;
378  } else {
379  return leads_to_blocked (le->father);
380  }
381 }
382 
383 
384 bool pq_tree::reduce (list<pq_leaf*>& leaves)
385 {
386 
387  GTL_debug::debug_message ("REDUCING %d\n", leaves.front()->id);
388  fail = 0;
389 
390  if (!bubble_up (leaves)) {
391 
392  //
393  // Find the node that has an interior block.
394  //
395 
396  GTL_debug::debug_message ("Bubble-Up failed !!\n");
397  fail = where_bubble_up_failed (leaves);
398  }
399 
400  queue<pq_node*> qu;
401  pq_leaf* le;
402  list<pq_leaf*>::iterator l_it = leaves.begin();
403  list<pq_leaf*>::iterator l_end = leaves.end();
404 
405  while (l_it != l_end ) {
406  le = *l_it;
407  qu.push (le);
408  le->pert_leaves = 1;
409  ++l_it;
410  }
411 
412  pq_node* tmp;
413 
414  while (!qu.empty()) {
415  tmp = qu.front();
416  qu.pop();
417  clear_me.erase (tmp->lpos);
418 
419  if (tmp->mark == pq_node::BLOCKED) {
420  pseudo = new q_node (node(), 0);
421  sons_iterator past = tmp->pos;
422 
423  //
424  // Get maximal connected block of BLOCKED siblings right of tmp
425  //
426 
427  while ((*past)->mark == pq_node::BLOCKED) {
428  (*past)->mark = pq_node::UNBLOCKED;
429  (*past)->father = pseudo;
430 
431  if ((*past)->kind() != pq_node::DIR) {
433  }
434 
435  ++past;
436  }
437 
438 
439  //
440  // Delete surrounding direction indicators
441  //
442 
443  --past;
444 
445  while ((*past)->kind() == pq_node::DIR) {
446  (*past)->clear();
447  clear_me.erase ((*past)->lpos);
448  --past;
449  }
450 
451  pseudo->pert_end = past;
452 
453  //
454  // Get maximal connected block of BLOCKED siblings left of tmp
455  //
456 
457  sons_iterator first = tmp->pos;
458  --first;
459 
460  while ((*first)->mark == pq_node::BLOCKED) {
461  (*first)->mark = pq_node::UNBLOCKED;
462  (*first)->father = pseudo;
463 
464  if ((*first)->kind() != pq_node::DIR) {
466  }
467 
468  --first;
469  }
470 
471 
472  //
473  // Delete surrounding direction indicators
474  //
475 
476  ++first;
477 
478  while ((*first)->kind() == pq_node::DIR) {
479  (*first)->clear();
480  clear_me.erase ((*first)->lpos);
481  ++first;
482  }
483 
484  pseudo->pert_begin = first;
485 
486  GTL_debug::debug_message ("creating pseudo-node as root\n");
488  ++past;
489  pseudo->sons.attach_sublist (first, past);
490  pseudo->pert_cons = true;
491  pseudo->lpos = clear_me.insert (clear_me.end(), pseudo);
492  }
493 
494  if (tmp->pert_leaves == pert_leaves_count) {
495 
496  //
497  // tmp is the root of the pertinent subtree
498  //
499 
500  if (tmp->kind() == pq_node::LEAF) {
501  pert_root = tmp;
502  GTL_debug::debug_message ("full leaf is root\n");
503  } else if (tmp->kind() == pq_node::P_NODE) {
504  if (P1 (tmp->P(), true)) {
505  GTL_debug::debug_message ("P1 matched for root\n");
506  } else if (P2 (tmp->P())) {
507  GTL_debug::debug_message ("P2 matched for root\n");
508  } else if (P4 (tmp->P())) {
509  GTL_debug::debug_message ("P4 matched for root\n");
510  } else if (P6 (tmp->P())) {
511  GTL_debug::debug_message ("P6 matched for root\n");
512  } else {
513  GTL_debug::debug_message ("NO MATCHING FOR P-ROOT\n");
514  fail = tmp;
515  failed_at_root = true;
516  return false;
517  }
518  } else {
519  if (!tmp->Q()->pert_cons) {
520  GTL_debug::debug_message ("pertinent children not consecutive\n");
521  fail = tmp;
522  failed_at_root = true;
523  return false;
524  } else if (Q1 (tmp->Q(), true)) {
525  GTL_debug::debug_message ("Q1 matched for root\n");
526  } else if (Q2 (tmp->Q(), true)) {
527  GTL_debug::debug_message ("Q2 matched for root\n");
528  } else if (Q3 (tmp->Q())) {
529  GTL_debug::debug_message ("Q3 matched for root\n");
530  } else {
531  GTL_debug::debug_message ("NO MATCHING FOR Q-ROOT\n");
532 
533  if (tmp == pseudo) {
534 
535  //
536  // search the real father
537  //
538 
540  pseudo->sons.front()->is_endmost = false;
541  pseudo->sons.back()->is_endmost = false;
543  assert (pseudo->sons.empty());
544 
545  while (!(*it)->is_endmost) {
546  --it;
547  }
548 
549  tmp = (*it)->father;
550  q_node* q_tmp = tmp->Q();
551  q_tmp->pert_begin = pseudo->pert_begin;
552  q_tmp->pert_end = pseudo->pert_end;
554  q_tmp->full_count = pseudo->full_count;
555  q_tmp->pert_cons = pseudo->pert_cons;
556 
557  for (int i = 0; i < q_tmp->partial_count; ++i) {
558  q_tmp->partial_pos[i] = pseudo->partial_pos[i];
559  }
560 
561  delete pseudo;
562  pseudo = 0;
563  }
564 
565  fail = tmp;
566  failed_at_root = true;
567  return false;
568  }
569  }
570 
571  } else {
572 
573  //
574  // tmp is not the root of the pertinent subtree.
575  //
576 
577  if (tmp == pseudo || tmp == root) {
578 
579  //
580  // This should not happen when bubble_up was true.
581  //
582 
583  assert (false);
584 
585  } else {
586  pq_node* father = tmp->father;
587 
588  if (tmp->kind() == pq_node::LEAF) {
589  father->full (tmp->pos);
590  tmp->clear();
591  GTL_debug::debug_message ("full leaf processed\n");
592 
593  } else if (tmp->kind() == pq_node::P_NODE) {
594  if (P1 (tmp->P(), false)) {
595  GTL_debug::debug_message ("P1 matched for non-root\n");
596  } else if (P3 (tmp->P())) {
597  GTL_debug::debug_message ("P3 matched for non-root\n");
598  } else if (P5 (tmp->P())) {
599  GTL_debug::debug_message ("P5 matched for non-root\n");
600  } else {
601  GTL_debug::debug_message ("NO MATCHING FOR P-NON-ROOT\n");
602  fail = tmp;
603  failed_at_root = false;
604  return false;
605  }
606 
607  } else {
608  if (!tmp->Q()->pert_cons) {
609  GTL_debug::debug_message ("pertinent children not consecutive\n");
610  fail = tmp;
611  return false;
612  } else if (Q1 (tmp->Q(), false)) {
613  GTL_debug::debug_message ("Q1 matched for non-root\n");
614  } else if (Q2 (tmp->Q(), false)) {
615  GTL_debug::debug_message ("Q2 matched for non-root\n");
616  } else {
617  GTL_debug::debug_message ("NO MATCHING FOR Q-NON-ROOT\n");
618  fail = tmp;
619  failed_at_root = false;
620  return false;
621  }
622  }
623 
624 
625  //
626  // If all the other pertinent siblings of tmp have already been
627  // matched father of tmp is queued.
628  //
629 
630  --(father->pert_children);
631 
632  if (father->pert_children == 0) {
633  if (father == fail) {
634  failed_at_root = false;
635  return false;
636  } else {
637  qu.push (father);
638  }
639  }
640  }
641  }
642  }
643 
644  return true;
645 }
646 
647 
649 {
650  pq_node* tmp;
651 
652  while (!clear_me.empty()) {
653  tmp = clear_me.front();
654  GTL_debug::debug_message ("Clearing %d\n", tmp->id);
655  clear_me.pop_front();
656  tmp->clear();
657  tmp->pert_children = 0;
658  }
659 
660  if (pert_root) {
661  pert_root->clear();
662  pert_root = 0;
663  }
664 
665  if (pseudo) {
666  pseudo->sons.front()->is_endmost = false;
667  pseudo->sons.back()->is_endmost = false;
669  assert (pseudo->sons.empty());
670  delete pseudo;
671  pseudo = 0;
672  }
673 
674  if (fail) {
675  fail->clear();
676  fail = 0;
677  }
678 }
679 
680 
682  list<direction_indicator>& dirs)
683 {
684  if (act->kind() == pq_node::LEAF) {
685  em.push_back (act->n, ((pq_leaf*) act)->e);
686  return;
687  }
688 
689  sons_iterator it = act->sons.begin();
690  sons_iterator end = act->sons.end();
691 
692  while (it != end) {
693  if ((*it)->kind() == pq_node::DIR) {
694  direction_indicator* dir = (*it)->D();
695  if (dir->mark != pq_node::UNMARKED) {
696  clear_me.erase (dir->lpos);
697  }
698  sons_iterator tmp = it;
699 
700  if (++tmp == ++(dir->pos)) {
701  dir->direction = true;
702  } else {
703  dir->direction = false;
704  }
705 
706  dirs.push_back (*dir);
707 
708  } else {
709  dfs (*it, em, dirs);
710  }
711 
712  ++it;
713  }
714 }
715 
716 
717 void pq_tree::replace_pert (int id, node _n, const list<pq_leaf*>& li,
718  planar_embedding* em, list<direction_indicator>* dirs)
719 {
720  assert (pert_root);
721  assert (!li.empty());
722  pq_leaf* tmp = 0;
723  list<pq_leaf*>::const_iterator it;
724  list<pq_leaf*>::const_iterator end = li.end();
725  sons_list sons;
726  int size = 0;
727 
728  for (it = li.begin(); it != end; ++it) {
729  tmp = *it;
730  tmp->pos = sons.insert (sons.end(), tmp);
731  ++size;
732  }
733 
734  pq_node* ins;
735 
736  if (size == 1) {
737  sons.erase (tmp->pos);
738  ins = tmp;
739  } else {
740  ins = new p_node(_n, id, sons);
741  }
742 
743  if (pert_root->kind() == pq_node::Q_NODE) {
744  q_node* q_root = pert_root->Q();
745  sons_iterator it = q_root->pert_begin;
746  sons_iterator end = q_root->pert_end;
747  sons_iterator tmp = it;
748  sons_iterator sons_end = q_root->sons.end();
749  --tmp;
750 
751  while (tmp != sons_end) {
752  if ((*tmp)->kind() != pq_node::DIR) {
753  break;
754  }
755 
756  --tmp;
757  }
758 
759  it = ++tmp;
760 
761  tmp = end;
762  ++tmp;
763 
764  while (tmp != sons_end) {
765  if ((*tmp)->kind() != pq_node::DIR) {
766  break;
767  }
768 
769  ++tmp;
770  }
771 
772  end = --tmp;
773 
774  ins->is_endmost = (*end)->is_endmost;
775  ++end;
776 
777  while (it != end) {
778  if (em && dirs) {
779  if ((*it)->kind() == pq_node::DIR) {
780  direction_indicator* dir = (*it)->D();
781  clear_me.erase (dir->lpos);
782  sons_iterator tmp = it;
783 
784  if (++tmp == ++(dir->pos)) {
785  dir->direction = true;
786  } else {
787  dir->direction = false;
788  }
789 
790  dirs->push_back (*dir);
791  } else {
792  dfs (*it, *em, *dirs);
793  }
794  }
795 
796  delete *it;
797  it = pert_root->sons.erase (it);
798  }
799 
800  if (pert_root->sons.empty() && pert_root != pseudo) {
801  ins->pos = pert_root->pos;
802  ins->father = pert_root->father;
804  ins->up = pert_root->up;
805  ins->up_id = pert_root->up_id;
806 
807  if (root == pert_root) {
808  root = ins;
809  } else {
810  *(pert_root->pos) = ins;
811  }
812 
813  delete pert_root;
814  pert_root = 0;
815 
816  } else {
817  if (em && dirs) {
818  direction_indicator* ind = new direction_indicator (_n, id);
819  ind->is_endmost = false;
820  ind->pos = pert_root->sons.insert (end, ind);
821  }
822 
823  ins->pos = pert_root->sons.insert (end, ins);
824  ins->father = pert_root;
825  ins->up = _n;
826  ins->up_id = id;
827  }
828 
829  } else {
830  if (em && dirs) {
831  dfs (pert_root, *em, *dirs);
832  }
833 
835  ins->father = pert_root->father;
836  ins->pos = pert_root->pos;
837  ins->up = pert_root->up;
838  ins->up_id = pert_root->up_id;
839 
840  if (root == pert_root) {
841  root = ins;
842  } else {
843  *(pert_root->pos) = ins;
844  }
845 
846  delete pert_root;
847  pert_root = 0;
848  }
849 }
850 
852  list<direction_indicator>& dirs)
853 {
854  dfs (root, em, dirs);
855 }
856 
857 //------------------------------------------------------------------------ P1
858 // Requirements:
859 //
860 // * x is a P-node having only full children
861 // * wheter x is the root or not is specified by the second parameter
862 //
863 
864 bool pq_tree::P1 (p_node* x, bool is_root)
865 {
866  if (x->child_count == x->full_count) {
867  if (!is_root) {
868  x->father->full (x->pos);
869  } else {
870  pert_root = x;
871  }
872 
873  x->sons.splice (x->sons.end(), x->full_sons.begin(),
874  x->full_sons.end());
875  x->clear();
876  return true;
877  }
878 
879  return false;
880 }
881 
882 
883 //----------------------------------------------------------------------- P2
884 // Requirements:
885 //
886 // * x is a P-node having both full and empty children
887 // * x has no partial children
888 // * x is the root of the pertinent subtree
889 // ==> more than one pertinent child
890 // * P1 didn't match
891 // ==> at least one non-full child
892 //
894 {
895  if (x->partial_count != 0) {
896  return false;
897  }
898 
899  p_node* ins = new p_node(x->n, x->id, x->full_sons);
900  ins->father = x;
901  ins->is_endmost = true;
902  ins->pos = x->sons.insert (x->sons.end(), ins);
903  x->child_count -= (x->full_count - 1);
904  x->clear();
905  pert_root = ins;
906  return true;
907 }
908 
909 
910 //------------------------------------------------------------------------ P3
911 // Requirements:
912 //
913 // * x is a P-node having both full and empty children.
914 // * x isn't the root of the pertinent subtree.
915 // * P1 didn't match.
916 // ==> at least one non-full child.
917 // * x has no partial children
918 //
919 
921 {
922  if (x->partial_count != 0) {
923  return false;
924  }
925 
926  q_node* new_q = new q_node (x->n, x->id);
927  pq_node* father = x->father;
928  pq_node* ins;
929 
930  *(x->pos) = new_q;
931  new_q->pos = x->pos;
932  new_q->up = x->up;
933  new_q->up_id = x->up_id;
934  new_q->is_endmost = x->is_endmost;
935  new_q->father = father;
936  new_q->pert_leaves = x->pert_leaves;
937 
938  if (x->full_count > 1) {
939  ins = new p_node (x->n, x->id, x->full_sons);
940  } else {
941  ins = x->full_sons.front();
942  x->full_sons.erase (x->full_sons.begin());
943  assert (x->full_sons.empty());
944  }
945 
946  ins->up = x->n;
947  ins->up_id = x->id;
948  ins->is_endmost = true;
949  ins->father = new_q;
950  ins->pos = new_q->sons.insert (new_q->sons.end(), ins);
951  new_q->pert_cons = true;
952  new_q->pert_begin = ins->pos;
953  new_q->pert_end = ins->pos;
954 
955  if (x->child_count - x->full_count > 1) {
956  ins = x;
957  ins->up = x->n;
958  ins->up_id = x->id;
959  x->child_count -= x->full_count;
960  x->clear();
961  } else {
962  ins = x->sons.front();
963  ins->up = x->n;
964  ins->up_id = x->id;
965  x->sons.erase (x->sons.begin());
966  assert (x->sons.empty());
967  delete x;
968  }
969 
970  ins->is_endmost = true;
971  ins->father = new_q;
972  ins->pos = new_q->sons.insert (new_q->pert_begin, ins);
973  father->partial (new_q->pos);
974 
975  return true;
976 }
977 
978 //------------------------------------------------------------------------ P4
979 // Requirements:
980 //
981 // * x is a P-node and the root of the pertinent subtree.
982 // ==> more than one non-empty child, i.e. at least one full child.
983 // * x has excactly one partial child
984 // * P1 and P2 didn't match
985 // ==> at least one partial child
986 //
988 {
989  if (x->partial_count > 1) {
990  return false;
991  }
992 
993  q_node* part = x->partial_sons.front()->Q();
994  part->n = x->n;
995  part->id = x->id;
996  pq_node* ins;
997 
998  if (x->full_count > 1) {
999  ins = new p_node (x->n, x->id, x->full_sons);
1000  } else {
1001  ins = x->full_sons.front();
1002  x->full_sons.erase (x->full_sons.begin());
1003  assert (x->full_sons.empty());
1004  }
1005 
1006  part->sons.back()->is_endmost = false;
1007  ins->is_endmost = true;
1008 
1009  ins->up = x->n;
1010  ins->up_id = x->id;
1011  ins->father = part;
1012  ins->pos = part->sons.insert (part->sons.end(), ins);
1013  part->pert_end = ins->pos;
1014  x->child_count -= x->full_count;
1015 
1016  if (x->child_count == 1) {
1017  if (root == x) {
1018  root = part;
1019  } else {
1020  *(x->pos) = part;
1021  }
1022 
1023  part->pos = x->pos;
1024  part->is_endmost = x->is_endmost;
1025  part->father = x->father;
1026  part->up = x->up;
1027  part->up_id = x->up_id;
1029 
1030  delete x;
1031  } else {
1032  x->sons.splice (x->sons.end(), part->pos);
1033  x->clear();
1034  }
1035 
1036  pert_root = part;
1037  return true;
1038 }
1039 
1040 
1041 //------------------------------------------------------------------------ P5
1042 // Requirements:
1043 //
1044 // * x is a P-node and not the root of the pertinent subtree
1045 // * x has exactly one partial child.
1046 // * P1 and P3 didn't match
1047 // ==> at least one partial child
1048 //
1050 {
1051  if (x->partial_count > 1) {
1052  return false;
1053  }
1054 
1055  pq_node* father = x->father;
1056  q_node* part = x->partial_sons.front()->Q();
1057  part->n = x->n;
1058  part->id = x->id;
1059  part->up = x->up;
1060  part->up_id = x->up_id;
1061 
1063  part->is_endmost = x->is_endmost;
1064  part->father = father;
1065  *(x->pos) = part;
1066  part->pos = x->pos;
1067  part->pert_leaves = x->pert_leaves;
1068  pq_node* ins;
1069 
1070  if (x->full_count > 1) {
1071  ins = new p_node (x->n, x->id, x->full_sons);
1072  } else if (x->full_count == 1) {
1073  ins = x->full_sons.front();
1074  x->full_sons.erase (x->full_sons.begin());
1075  assert (x->full_sons.empty());
1076  } else {
1077  ins = 0;
1078  }
1079 
1080  if (ins) {
1081  ins->up = x->n;
1082  ins->up_id = x->id;
1083  part->sons.back()->is_endmost = false;
1084  ins->is_endmost = true;
1085  ins->father = part;
1086  ins->pos = part->sons.insert (part->sons.end(), ins);
1087  part->pert_end = ins->pos;
1088  }
1089 
1090  x->child_count -= (x->full_count + 1);
1091 
1092  if (x->child_count > 1) {
1093  ins = x;
1094  ins->up = x->n;
1095  ins->up_id = x->id;
1096  x->clear();
1097  } else if (x->child_count == 1) {
1098  ins = x->sons.front();
1099  ins->up = x->n;
1100  ins->up_id = x->id;
1101  x->sons.erase (x->sons.begin());
1102  delete x;
1103  } else {
1104  ins = 0;
1105  delete x;
1106  }
1107 
1108  if (ins) {
1109  part->sons.front()->is_endmost = false;
1110  ins->is_endmost = true;
1111  ins->father = part;
1112  ins->pos = part->sons.insert (part->sons.begin(), ins);
1113  }
1114 
1115  father->partial (part->pos);
1116  return true;
1117 }
1118 
1119 
1120 //------------------------------------------------------------------------ P6
1121 // Requirements:
1122 //
1123 // * x is the root of the pertinent subtree and has two partial children.
1124 // * P1, P2 and P4 didn't match
1125 // ==> at least two partial children.
1126 //
1128 {
1129  if (x->partial_count > 2) {
1130  return false;
1131  }
1132 
1133 
1134  q_node* part2 = x->partial_sons.front()->Q();
1136  q_node* part1 = x->partial_sons.front()->Q();
1137  part1->n = x->n;
1138  part1->id = x->id;
1139  pq_node* ins;
1140 
1141  if (x->full_count > 1) {
1142  ins = new p_node (x->n, x->id, x->full_sons);
1143  } else if (x->full_count == 1) {
1144  ins = x->full_sons.front();
1145  x->full_sons.erase (x->full_sons.begin());
1146  assert (x->full_sons.empty());
1147  } else {
1148  ins = 0;
1149  }
1150 
1151  part1->sons.back()->is_endmost = false;
1152 
1153  if (ins) {
1154  ins->up = x->n;
1155  ins->up_id = x->id;
1156  ins->is_endmost = false;
1157  ins->pos = part1->sons.insert (part1->sons.end(), ins);
1158  }
1159 
1160  part2->turn ();
1161  part2->sons.front()->is_endmost = false;
1162  part2->sons.back()->father = part1;
1163  part1->sons.splice (part1->sons.end(), part2->sons.begin(),
1164  part2->sons.end());
1165  part1->pert_end = part2->pert_begin;
1166  part1->pert_end.reverse();
1167  x->child_count -= (x->full_count + 1);
1168  delete part2;
1169 
1170  if (x->child_count == 1) {
1171  if (root == x) {
1172  root = part1;
1173  } else {
1174  *(x->pos) = part1;
1175  }
1176  part1->pos = x->pos;
1177  part1->is_endmost = x->is_endmost;
1178  part1->father = x->father;
1179  part1->up = x->up;
1180  part1->up_id = x->up_id;
1182 
1183  delete x;
1184  } else {
1185  x->sons.splice (x->sons.end(), x->partial_sons.begin());
1186  x->clear();
1187  }
1188 
1189  pert_root = part1;
1190  return true;
1191 }
1192 
1193 //------------------------------------------------------------------------ Q1
1194 // Requirements:
1195 //
1196 // * x is a Q-node having only full children
1197 // * wheter x is the root or not is specified by the second parameter
1198 //
1199 bool pq_tree::Q1 (q_node* x, bool is_root)
1200 {
1201  if (x->partial_count > 0) return false;
1202 
1203  if (*(x->pert_begin) == x->sons.front()
1204  && *(x->pert_end) == x->sons.back()) {
1205 
1206  if (!is_root) {
1207  x->father->full (x->pos);
1208  } else {
1209  pert_root = x;
1210  }
1211 
1212  return true;
1213  }
1214 
1215  return false;
1216 }
1217 
1218 
1219 //------------------------------------------------------------------------ Q2
1220 // Requirements:
1221 //
1222 // * Q1 didn't match ==> x has at least one non-full child.
1223 // * wheter x is the root or not is specified by the second parameter
1224 // * x has at most one partial child
1225 // * If x has empty children, the partial child must be at pert_begin;
1226 // if x hasn't any empty children the partial child is allowed to be at
1227 // pert_end, since this can be transformed into the former case.
1228 //
1229 bool pq_tree::Q2 (q_node* x, bool is_root)
1230 {
1231  if (x->partial_count > 1) {
1232  return false;
1233  }
1234 
1235  if (x->partial_count == 1) {
1236  if (x->partial_pos[0] == x->pert_end &&
1237  x->pert_begin == x->sons.begin() &&
1238  x->pert_begin != x->pert_end)
1239  {
1240  if (!is_root) {
1241  q_node* part = (*(x->pert_end))->Q();
1242  x->turn();
1244  x->pert_begin = x->pert_end;
1245  x->pert_end = tmp;
1246  x->pert_begin.reverse();
1247  x->pert_end.reverse();
1248  x->merge (x->pert_begin);
1249  x->pert_begin = part->pert_begin;
1250  delete part;
1251  } else {
1252  q_node* part = (*(x->pert_end))->Q();
1253  part->turn();
1254  x->merge (x->pert_end);
1255  x->pert_end = x->pert_begin;
1256  x->pert_begin = part->pert_begin;
1257  x->pert_end.reverse();
1258  // x->pert_begin.reverse();
1259  delete part;
1260  }
1261 
1262  } else if (x->partial_pos[0] != x->pert_begin) {
1263  return false;
1264  } else {
1265  //
1266  // Partial child is at pert_begin and x has at least one
1267  // empty child (i.e. pert_begin != sons.begin())
1268  //
1269 
1270  q_node* part = x->merge (x->pert_begin);
1271 
1272  if (x->pert_begin == x->pert_end) {
1273  x->pert_end = part->pert_end;
1274  }
1275 
1276  x->pert_begin = part->pert_begin;
1277  delete part;
1278  }
1279  }
1280 
1281  if (!is_root) {
1282  x->father->partial (x->pos);
1283  } else {
1284  pert_root = x;
1285  }
1286 
1287  return true;
1288 }
1289 
1290 
1291 //------------------------------------------------------------------------ Q3
1292 // Requirements:
1293 //
1294 // * x is the root of the pertinent subtree.
1295 // * Q1 and Q2 didn't match
1296 // ==> at least one partial child
1297 // * if there is only one partial child it must be at pert_end, and x must
1298 // have at least one empty and one full child.
1299 // if there are two partial children they must be at pert_begin and
1300 // pert_end.
1301 //
1303 {
1304  if (x->partial_count > 2 || x->partial_count < 1) return false;
1305 
1306  if (x->partial_count == 1) {
1307  if (x->partial_pos[0] != x->pert_end) return false;
1308 
1309  //
1310  // One partial child at pert_end.
1311  //
1312 
1313  } else {
1314  if (x->partial_pos[0] != x->pert_end) {
1315  if (x->partial_pos[1] != x->pert_end ||
1316  x->partial_pos[0] != x->pert_begin) return false;
1317  } else {
1318  if (x->partial_pos[1] != x->pert_begin) return false;
1319  }
1320 
1321  //
1322  // One partial child at pert_begin and one at pert_end
1323  //
1324  }
1325 
1326  q_node* part = (*(x->pert_end))->Q();
1327  part->turn();
1328  x->merge (x->pert_end);
1329  x->pert_end = part->pert_begin;
1330  x->pert_end.reverse();
1331  delete part;
1332 
1333  if (x->partial_count == 2) {
1334  part = x->merge (x->pert_begin);
1335  x->pert_begin = part->pert_begin;
1336  delete part;
1337  }
1338 
1339  pert_root = x;
1340  return true;
1341 }
1342 
1343 
1344 
1345 
1346 GTL_EXTERN ostream& operator<< (ostream& os, const pq_tree& tree)
1347 {
1348  if (!tree.root) return os;
1349 
1350  int id = 0;
1351  pair<pq_node*,int> tmp;
1352  queue<pair<pq_node*,int> > qu;
1353  pq_node* act;
1354 
1355  os << "graph [\n" << "directed 1" << endl;
1356  tree.root->write (os, id);
1357  tmp.first = tree.root;
1358  tmp.second = id;
1359  ++id;
1360  qu.push (tmp);
1361 
1362  while (!qu.empty()) {
1363  tmp = qu.front();
1364  qu.pop();
1365 
1366  if (tmp.first->kind() == pq_node::Q_NODE || tmp.first->kind() == pq_node::P_NODE) {
1367  pq_tree::sons_iterator it = tmp.first->sons.begin();
1368  pq_tree::sons_iterator end = tmp.first->sons.end();
1369 
1370  for (; it != end; ++it) {
1371  act = *it;
1372  act->write (os, id);
1373 
1374  os << "edge [\n" << "source " << tmp.second << endl;
1375  os << "target " << id << "\n]" << endl;
1376 
1377  qu.push (pair<pq_node*,int> (act, id));
1378  ++id;
1379  }
1380  }
1381 
1382  if (tmp.first->kind() == pq_node::P_NODE) {
1383  p_node* P = tmp.first->P();
1386 
1387  for (; it != end; ++it) {
1388  act = *it;
1389  act->write (os, id);
1390 
1391  os << "edge [\n" << "source " << tmp.second << endl;
1392  os << "target " << id << "\n]" << endl;
1393 
1394  qu.push (pair<pq_node*,int> (act, id));
1395  ++id;
1396  }
1397 
1398  it = P->partial_sons.begin();
1399  end = P->partial_sons.end();
1400 
1401  for (; it != end; ++it) {
1402  act = *it;
1403  act->write (os, id);
1404 
1405  os << "edge [\n" << "source " << tmp.second << endl;
1406  os << "target " << id << "\n]" << endl;
1407 
1408  qu.push (pair<pq_node*,int> (act, id));
1409  ++id;
1410  }
1411  }
1412  }
1413 
1414  os << "]" << endl;
1415 
1416  return os;
1417 }
1418 
1421 {
1422  direction_indicator* dir = (*s_it)->D();
1423  sons_iterator res = q_fail->sons.erase(s_it);
1424  clear_me.erase(dir->lpos);
1425  delete dir;
1426  return res;
1427 }
1428 
1429 
1430 //--------------------------------------------------------------------------
1431 // DEBUGGING
1432 //--------------------------------------------------------------------------
1433 
1435 {
1436  if (!root) return true;
1437 
1438  queue<pq_node*> qu;
1439  qu.push (root);
1440  pq_node* tmp;
1441 
1442  while (!qu.empty()) {
1443  tmp = qu.front();
1444  qu.pop();
1445 
1446  if (tmp->kind() == pq_node::LEAF) continue;
1447  if (tmp->kind() == pq_node::DIR) continue;
1448 
1449  sons_iterator it = tmp->sons.begin();
1450  sons_iterator end = tmp->sons.end();
1451  int count = 0;
1452  int endmost_count = 0;
1453 
1454  for (; it != end; ++it) {
1455  ++count;
1456  if ((*it)->is_endmost) {
1457  ++endmost_count;
1458 
1459  if ((*it)->father != tmp) {
1460  GTL_debug::debug_message ("Wrong father !!!\n");
1462  return false;
1463  }
1464  }
1465 
1466  if ((*it)->pos != it) {
1467  GTL_debug::debug_message ("Wrong position !!\n");
1469  return false;
1470  }
1471 
1472  qu.push (*it);
1473  }
1474 
1475  if (tmp->kind() == pq_node::P_NODE
1476  && count != (tmp->P()->child_count)) {
1477  GTL_debug::debug_message ("Wrong number of children !!!\n");
1479  return false;
1480  }
1481 
1482  if (tmp->kind() == pq_node::Q_NODE && count < 2) {
1483  GTL_debug::debug_message ("Q-Node with too few children !!\n");
1485  return false;
1486  }
1487 
1488  if (tmp->kind() == pq_node::P_NODE && count < 2) {
1489  GTL_debug::debug_message ("P-Node with too few children !!\n");
1491  return false;
1492  }
1493 
1494  if (tmp->kind() == pq_node::Q_NODE) {
1495  if (endmost_count == 2) {
1496  if (!(tmp->sons.front()->is_endmost &&
1497  tmp->sons.back()->is_endmost)) {
1498  GTL_debug::debug_message ("Q-node with inner children labeled endmost\n");
1500  return false;
1501  }
1502  } else {
1503  GTL_debug::debug_message ("Q-node with too many or too few endmost children\n");
1505  return false;
1506  }
1507  }
1508  }
1509 
1510  return true;
1511 }
1512 
1513 /*
1514 void pq_tree::insert (pq_node* father, pq_node* ins) {
1515  ins->father = father;
1516  ins->is_endmost = true;
1517 
1518  if (father->kind() == pq_node::Q_NODE) {
1519  father->sons.back()->is_endmost = false;
1520  } else {
1521  ((p_node*)father)->child_count++;
1522  }
1523 
1524  ins->pos = father->sons.insert (father->sons.end(), ins);
1525 }
1526 
1527 
1528 p_node* pq_tree::insert_P (pq_node* father, sons_list& sons)
1529 {
1530  p_node* p = new p_node();
1531  insert (father, p);
1532  pq_node* tmp;
1533 
1534  sons_iterator it = sons.begin();
1535  sons_iterator end = sons.end();
1536 
1537  for (; it != end; ++it) {
1538  p->child_count++;
1539  tmp = *it;
1540  tmp->father = p;
1541  tmp->is_endmost = true;
1542  tmp->pos = p->sons.insert (p->sons.end(), tmp);
1543 
1544  if (tmp->kind() == pq_node::LEAF) {
1545  leaves.push_back ((pq_leaf*)tmp);
1546  }
1547  }
1548 
1549  return p;
1550 }
1551 
1552 
1553 q_node* pq_tree::insert_Q (pq_node* father, sons_list& sons)
1554 {
1555  q_node* q = new q_node();
1556  insert (father, q);
1557  pq_node* tmp;
1558  sons_iterator it = sons.begin();
1559  sons_iterator end = sons.end();
1560 
1561  for (; it != end; ++it) {
1562  tmp = *it;
1563  tmp->is_endmost = false;
1564  tmp->pos = q->sons.insert (q->sons.end(), tmp);
1565 
1566  if (tmp->kind() == pq_node::LEAF) {
1567  leaves.push_back (tmp->L());
1568  }
1569  }
1570 
1571  q->sons.front()->father = q;
1572  q->sons.front()->is_endmost = true;
1573  q->sons.back()->father = q;
1574  q->sons.back()->is_endmost = true;
1575 
1576  return q;
1577 }
1578 
1579 */
1580 
1582 
1583 //--------------------------------------------------------------------------
1584 // end of file
1585 //--------------------------------------------------------------------------