SheafSystem  0.0.0.0
depth_first_iterator.cc
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class depth_first_iterator
19 
20 #include "SheafSystem/depth_first_iterator.h"
21 #include "SheafSystem/index_space_iterator.h"
22 #include "SheafSystem/poset_state_handle.h"
23 #include "SheafSystem/assert_contract.h"
24 #include "SheafSystem/subposet.h"
25 #include "SheafSystem/zn_to_bool.h"
26 
27 //#define DIAGNOSTIC_OUTPUT
28 //#undef DIAGNOSTIC_OUTPUT
29 
30 // const bool sheaf::depth_first_iterator::DOWN = true;
31 // const bool sheaf::depth_first_iterator::UP = false;
32 // const bool sheaf::depth_first_iterator::RESET = true;
33 // const bool sheaf::depth_first_iterator::NO_RESET = false;
34 // const bool sheaf::depth_first_iterator::STRICT = true;
35 // const bool sheaf::depth_first_iterator::NOT_STRICT = false;
36 
39 {
40  // Preconditions:
41 
42  // Body:
43 
44  // Release cover iterators.
45 
47 
48  // Delete the anchor;
49 
50  if(_anchor != 0)
51  {
52  // Delete the anchor.
53 
55  delete _anchor;
56  }
57 
58  // Detach the client filter.
59 
61 
62  // Delete the filter and visited marker
63 
64  if(_new_filter)
65  delete _filter;
66  if(_has_visited != 0)
67  delete _has_visited;
68 
69  // Postconditions:
70 
71  // Exit:
72 
73  return;
74 }
75 
76 bool
78 is_ancestor_of(const any* xother) const
79 {
80  bool result;
81 
82  // Preconditions:
83 
84  // Body:
85 
86  result = dynamic_cast<const depth_first_iterator*>(xother) != 0;
87 
88  // Postconditions:
89 
90  // Exit
91 
92  return result;
93 }
94 
97 clone() const
98 {
99  depth_first_iterator* result;
100 
101  // Preconditions:
102 
103  // Body:
104 
105  result = new depth_first_iterator;
106 
107  // Postconditions:
108 
109  ensure(result != 0);
110  ensure(!result->is_initialized());
111 
112  // Exit
113 
114  return result;
115 }
116 
117 bool
119 invariant() const
120 {
121  bool result = true;
122 
123  // Preconditions:
124 
125  // Body:
126 
127  invariance(any::invariant());
128 
129  if(invariant_check())
130  {
132 
133  invariance( is_initialized() ? order() != NOT_AN_ORDER : true);
134  invariance( !is_initialized() ? is_done() : true);
135  invariance( is_initialized() ? anchor().is_attached() == (_has_visited != 0) : true );
136  invariance( is_initialized() == (_has_visited != 0));
137 
138  // The following apparent "invariance" is in fact not true when the graph
139  // is being modified behind the current position of the iterator.
140  // invariance( is_initialized() ? (_has_visited->ub() == anchor().host()->member_index_ub()) : true );
141 
144 
145  //invariance( is_initialized() && !is_done() ? index() == _path_head.item() : true);
146  invariance( (action() == NOT_AN_ACTION) == is_done() );
147  invariance( (_state == NOT_A_STATE) == is_done() );
148  invariance( _new_filter ? _filter != 0 : true );
149  invariance( is_initialized() == (_anchor != 0) );
150  invariance( !is_initialized() ? !_new_filter : true );
151 
152 
153  // Finished, turn invariant checking back on.
154 
156  }
157 
158  // Postconditions:
159 
160  // Exit
161 
162  return result;
163 }
164 
165 
166 // Placeholder for null filter
167 const char*
169 NULL_FILTER = "";
170 
171 
172 // ITERATOR FACET
173 
176 order() const
177 {
178  order_type result;
179 
180  // Preconditions:
181 
182  // Body:
183 
184  result = _order;
185 
186  // Postconditions:
187 
188  // Exit
189 
190  return result;
191 }
192 
193 bool
196 {
197  bool result;
198 
199  // Preconditions:
200 
201  // Body:
202 
203  result = (_anchor != 0) && (_has_visited != 0) && (_filter != 0);
204 
205  // Postconditions:
206 
207  // Exit
208 
209  return result;
210 }
211 
215 {
216  // Preconditions:
217 
218  require(is_initialized());
219 
220  // Body:
221 
222  abstract_poset_member& result = *_anchor;
223 
224  // Postconditions:
225 
226  // Exit
227 
228  return result;
229 }
230 
233 anchor() const
234 {
235  // Preconditions:
236 
237  require(is_initialized());
238 
239  // Body:
240 
241  abstract_poset_member& result = *_anchor;
242 
243  // Postconditions:
244 
245  // Exit
246 
247  return result;
248 }
249 
250 bool
253 {
254  bool result;
255 
256  // Preconditions:
257 
258  // Body:
259 
260  // Always true in this class;
261  // intended to be redefined in descendants.
262 
263  result = true;
264 
265  // Postconditions:
266 
267  // Exit
268 
269  return result;
270 }
271 
272 bool
274 descending() const
275 {
276  bool result;
277 
278  // Preconditions:
279 
280  // Body:
281 
282  result = _descending;
283 
284  // Postconditions:
285 
286  // Exit
287 
288  return result;
289 }
290 
291 bool
293 strict() const
294 {
295  bool result;
296 
297  // Preconditions:
298 
299  // Body:
300 
301  result = _strict;
302 
303  // Postconditions:
304 
305  // Exit
306 
307  return result;
308 }
309 
313 {
314  // Preconditions:
315 
316  // The following precondition is stronger than necessary for
317  // this routine alone, but is consistent with the preconditions for
318  // anchor() and has_visited() and hence easier for the client to understand.
319 
320  require(is_initialized());
321 
322  // Body:
323 
324  subposet& result = _client_filter;
325 
326  // Postconditions:
327 
328  ensure(is_initialized() == result.is_attached());
329 
330  // Exit
331 
332  return result;
333 }
334 
335 bool
337 is_done() const
338 {
339  bool result;
340 
341  // Preconditions:
342 
343  // Body:
344 
345  result = (_state == NOT_A_STATE);
346 
347  // Postconditions:
348 
349  // Exit
350 
351  return result;
352 }
353 
354 void
357 {
358  // Preconditions:
359 
360  // Body:
361 
362  _index.invalidate();
363  _action = NOT_AN_ACTION;
364  _state = NOT_A_STATE;
365 
366  // Clear the path
367 
369 
370  // Clear the filtered path
371 
372  while(!_filtered_path_tail.empty())
373  {
374  _filtered_path_tail.pop();
375  }
376 
377  // Postconditions:
378 
379  ensure(invariant());
380  ensure(is_done());
381 
382  // Exit:
383 }
384 
385 void
387 next(bool xtruncate)
388 {
389  // Preconditions:
390 
391  require(!is_done());
392 
393  // Body:
394 
395  pod_index_type lc_index;
396 
397  // The following while/switch construction is a finite state machine.
398  // Each case in the switch corresponds to a state. In each state, an
399  // action is performed and the result of the action determines the
400  // "input token" of the finite state machine. The transition to the
401  // next state is determined by the transitition function, implemented
402  // as an array indexed by state and token.
403  //
404  // Control enters the while with _state set to some value. Each iteration
405  // of the loop corresponds to a state transition. Iteration continues
406  // until a state is reached which returns to the caller.
407 
415 
416  while(true)
417  {
418 
419 #ifdef DIAGNOSTIC_OUTPUT
420  cout << "in depth_first_iterator::next: _state = " << iterator_state_names[_state];
421  if(is_initialized())
422  {
423  cout << "\t\t_filtered_path_tail: " << _filtered_path_tail.top();
424  cout << "\t _index: " << _index;
425  }
426  cout << endl;
427 #endif
428 
429  switch(_state)
430  {
431  case INIT_COVER_ITERATOR:
432 
433  // Initialize the cover iterator, depending on truncation and direction.
434 
435  if(_path_head_lc != 0)
436  {
438  }
439 
441 
442  if(xtruncate)
443  {
444  // Truncation requested; initialize the iterator to end.
445  // Cover of this will be skipped.
446 
448 
449  // Client has only requested truncation for the current member.
450  // If we pass thorugh this state again, we don't want to truncate.
451 
452  xtruncate = false;
453  }
454 
455  // Test the cover iterator to see if there is a current member of the cover.
456 
457  if(!_path_head_lc->is_done())
458  {
459  // Cover iterator points to the current member of cover;
460  // Now there is a link defined. _index and _path_head refer to
461  // the greater member and _path_head_lc refers to the lesser member.
462 
463  // Check to see if lesser has already been visited.
464 
465  _state = _transition_fcn[INIT_COVER_ITERATOR][PASS];
466  }
467  else
468  {
469  // Cover iterator is finished; we've visited all the cover.
470  // There is no current link, we're in the postvisit action position.
471 
472  // _state = EXECUTE_POSTVISIT_ACTION;
473 
474  _state = _transition_fcn[INIT_COVER_ITERATOR][FAIL];
475  }
476 
477  break;
478 
479  case TEST_HAS_VISITED:
480 
481  // Check to see if we've already visited the
482  // current member of the cover.
483 
484  lc_index = _path_head_lc->hub_pod();
485 
486  if(_visit_once && has_visited(lc_index))
487  {
488  // Current member of cover has been visited and we're only visiting once;
489  // execute the link action then move on to the next member.
490 
491  _state = _transition_fcn[TEST_HAS_VISITED][PASS];
492  }
493  else
494  {
495  // Current member hasn't been visited or
496  // we're visiting more than once; descend
497 
498  _state = _transition_fcn[TEST_HAS_VISITED][FAIL];
499  }
500  break;
501 
502  case INC_COVER_ITERATOR:
503 
504  // Move on to the next member of the cover.
505 
506  _path_head_lc->next();
507 
508  // Test the cover iterator to see if there is a current member of the cover.
509 
510  if(!_path_head_lc->is_done())
511  {
512  // Cover iterator points to the current member of cover;
513  // check to see if it has already been visited.
514 
515  _state = _transition_fcn[INC_COVER_ITERATOR][PASS];
516  }
517  else
518  {
519  // Cover iterator is finished; we've visited all the cover;
520  // the iterator is is in the postvisit action position.
521 
522  _state = _transition_fcn[INC_COVER_ITERATOR][FAIL];
523  }
524 
525  break;
526 
527  case ERASE_COVER_ITERATOR:
528 
529  // Erase the current member of cover and move on,
530  // without trashing the iterator.
531 
532  {
533  // Local scope to avoid compiler complaint about
534  // "jump to case label crosses initialization" of ltmp_itr.
535 
536 
537 #ifdef DIAGNOSTIC_OUTPUT
538  cout << "in depth_first_iterator::next::ERASE_COVER_ITERATOR "
539  << "erasing " << *_path_head_lc
540  << " in cover of " << *_path_head
541  << endl;
542 #endif
543 
545  _path_head_lc->next();
546  _anchor->host()->clear_cover(_descending, litem);
547  }
548 
549  // Test the cover iterator to see if there is a current member of the cover.
550 
551  if(!_path_head_lc->is_done())
552  {
553  // Cover iterator points to the current member of cover;
554  // check to see if it has already been visited.
555 
556  _state = _transition_fcn[ERASE_COVER_ITERATOR][PASS];
557  }
558  else
559  {
560  // Cover iterator is finished; we've visited all the cover;
561  // the iterator is is in the postvisit action position.
562 
563  _state = _transition_fcn[ERASE_COVER_ITERATOR][FAIL];
564  }
565 
566  break;
567 
568  case DESCEND:
569 
570  // Mark the current member of cover.
571 
572  lc_index = _path_head_lc->hub_pod();
573 
574  put_has_visited(lc_index, true);
575 
576  // Descend.
577 
578  if(_index !=~ _anchor->index())
579  {
580  assertion(_index.pod() == _path_head->hub_pod());
581 
582  _path_tail.push(_path_head);
583 
584  // Update the greater end of the link.
585 
586  if(filter(_path_head->hub_pod()))
587  {
589  }
590  }
591 
593  _path_head_lc = 0;
594  _index = lc_index;
595 
596  // This is the first time we've seend this node and we're
597  // about to begin iteration over its cover.
598  // This is the previsit action position.
599 
600  _state = _transition_fcn[DESCEND][PASS];
601 
602  break;
603 
604  case TEST_PATH_TAIL:
605 
606  // Test the path tail to see whether we can ascend or
607  // we're done.
608 
609  if(_index == _anchor->index())
610  {
611  // Tail of path is empty;
612  // _path_head is anchor;
613  // iteration is over.
614 
615  _state = _transition_fcn[TEST_PATH_TAIL][PASS];
616  }
617  else
618  {
619  // Tail of path is not empty; ascend.
620 
621  _state = _transition_fcn[TEST_PATH_TAIL][FAIL];
622  }
623 
624  break;
625 
626  case ASCEND:
627 
628  // Release the path head lower cover.
629 
631  _path_head_lc = 0;
632 
633  if(_path_tail.empty())
634  {
635  // Assend to the anchor.
636 
638  _path_head = 0;
639 
640  // Attach this to the anchor.
641 
642  _index = _anchor->index();
643  }
644  else
645  {
646  // Ascend to the previous link in the path
647 
649 
650  // Update the greater end of the link;
651 
652  if(!_filtered_path_tail.empty() &&
653  (_filtered_path_tail.top() == _path_tail.top()->hub_pod()))
654  {
655  // Filtered path can not be empty at this point.
656 
657  _filtered_path_tail.pop();
658  }
659 
660  _path_head = _path_tail.top();
661  _path_tail.pop();
662 
663  // Attach this to the lesser member of the current link
664 
666  }
667 
668  // We have just ascended from visiting
669  // the lesser member of the link.
670  // This is the link action position;
671 
672  // _state = EXECUTE_LINK_ACTION;
673 
674  _state = _transition_fcn[ASCEND][PASS];
675 
676  break;
677 
678  case EXECUTE_PREVISIT_ACTION:
679 
680  // Only execute the action if the current member passes the filter.
681 
686 
687 #ifdef DIAGNOSTIC_OUTPUT
688 
689  cout << "index: " << _index
690  << " filter value: " << boolalpha << filter(_index) << noboolalpha
691  << endl;
692 #endif
693 
694  if(filter(_index) && (!_strict || !(_index == _anchor->index())) )
695  {
696  // Current member passes the filter, attach and
697  // return to client for previsit action. When client
698  // returns control, initialize iteration over this members cover.
699 
700  attach_item();
701 
702  _state = _transition_fcn[EXECUTE_PREVISIT_ACTION][PASS];
703  _action = PREVISIT_ACTION;
704  return;
705  }
706  else
707  {
708  // Current member doesn't pass the filter;
709  // skip the previsit action and go directly to
710  // initializing iteration over this members cover.
711 
712  _state = _transition_fcn[EXECUTE_PREVISIT_ACTION][FAIL];
713  }
714 
715  break;
716 
717  case EXECUTE_LINK_ACTION:
718 
719 #ifdef DIAGNOSTIC_OUTPUT
720 
721  cout << "\t\t*_path_head_lc: " << *_path_head_lc << endl;
722 #endif
723 
724  // Only execute the link action if the current member passes the filter.
725 
726  if( filter(_index) && (!_strict || !(_index == _anchor->index())) )
727  {
728  // Current member passes the filter, attach and
729  // return to client for postvisit action. When client
730  // returns control, increment the cover iterator.
731 
732  attach_item();
733 
734  _state = _transition_fcn[EXECUTE_LINK_ACTION][PASS];
735  _action = LINK_ACTION;
736  return;
737  }
738  else
739  {
740  // Current member doesn't pass the filter;
741  // skip the link action and go directly to
742  // incrementing the cover iterator.
743 
744  _state = _transition_fcn[EXECUTE_LINK_ACTION][FAIL];
745  }
746 
747  break;
748 
749  case EXECUTE_POSTVISIT_ACTION:
750 
751  // Only execute the action if the current member passes the filter.
752 
754 
755  if( filter(_index) && (!_strict || !(_index == _anchor->index())) )
756  {
757  // Current member passes the filter, attach and
758  // return to client for postvisit action. When client
759  // returns control, test the path to see if we can ascend.
760 
761  attach_item();
762 
763  _state = _transition_fcn[EXECUTE_POSTVISIT_ACTION][PASS];
764  _action = POSTVISIT_ACTION;
765  return;
766  }
767  else
768  {
769  // Current member doesn't pass the filter;
770  // skip the postvisit action and go directly to
771  // testing the path to see if we can ascend.
772 
773  _state = _transition_fcn[EXECUTE_POSTVISIT_ACTION][FAIL];
774  }
775 
776  break;
777 
778  case FINISH:
779 
780  // Iteration is over.
781 
782  _index.invalidate();
783 
784  detach_item();
785 
786  _state = NOT_A_STATE;
787  _action = NOT_AN_ACTION;
788  return;
789  }
790  }
791 
792  // Postconditions:
793 
796 
797  // ensure(invariant());
798 
799  // Exit
800 
801  // return;
802 }
803 
804 void
806 reset(bool xreset_markers)
807 {
808  // Preconditions:
809 
810  require(is_initialized());
811  require(anchor().state_is_read_accessible());
812 
813  // Body:
814 
815  define_old_variable(bool old_descending = _descending);
816  define_old_variable(bool old_strict = _strict);
817 
818  // Force the iteration into a clean state.
819 
820  force_is_done();
821 
822  // Size of host poset may have changed since last reset.
823  // Make sure _has_visited is large enough.
824 
825  _has_visited->extend_to(_anchor->host()->member_index_ub().pod());
826 
827  // Reset the markers as requested.
828 
829  if(xreset_markers)
830 
832 
833  _has_visited->make_false_sa();
834 
835  // Advance to the first item in the iteration
836 
837  first();
838 
839  // Postconditions:
840 
841  ensure(invariant());
842  ensure(descending() == old_descending);
843  ensure(strict() == old_strict);
844 
850 
851 
852  // Exit
853 
854  return;
855 }
856 
857 int
859 ct(bool xreset)
860 {
861  int result = 0;
862 
863  // Preconditions:
864 
865  require(is_initialized());
866  require(xreset ? anchor().state_is_read_accessible(): true);
867 
868  // Body:
869 
870  if(xreset)
871  reset();
872 
873  while(!is_done())
874  {
875  result++;
876  next();
877  }
878 
879  // Postconditions:
880 
881  ensure(result >= 0);
882  ensure(is_done());
883 
884  // Exit
885 
886  return result;
887 }
888 
889 bool
892 {
893 
894  // preconditions:
895 
896  require(is_initialized());
897  require(anchor().host()->contains_member(xhub_id, true));
898 
899  // body:
900 
901  bool result = (*_has_visited)[xhub_id];
902 
903  return result;
904 }
905 
906 bool
908 has_visited(const scoped_index& xid) const
909 {
910 
911  // preconditions:
912 
913  require(is_initialized());
914  require(anchor().host()->contains_member(xid, true));
915 
916  // body:
917 
918  bool result = (*_has_visited)[xid.hub_pod()];
919 
920  return result;
921 }
922 
923 bool
926 {
927 
928  // preconditions:
929 
930  require(is_initialized());
931  require(anchor().state_is_read_accessible());
932  require(xmbr != 0);
933  require(xmbr->is_attached());
934  require(anchor().host()->is_same_state(xmbr->host()));
935 
936  // body:
937 
938  bool result = (*_has_visited)[xmbr->index().hub_pod()];
939 
940  return result;
941 }
942 
943 void
945 put_has_visited(pod_index_type xhub_id, bool xvalue)
946 {
947 
948  // Preconditions:
949 
950  require(is_initialized());
951  require(anchor().state_is_read_accessible());
952  require(anchor().host()->contains_member(xhub_id));
953 
954  // Body:
955 
956  _has_visited->put(xhub_id, xvalue);
957 
958  // Postconditions:
959 
960  ensure(has_visited(xhub_id) == xvalue);
961 
962  return;
963 }
964 
965 void
967 put_has_visited(const scoped_index& xid, bool xvalue)
968 {
969 
970  // Preconditions:
971 
972  require(is_initialized());
973  require(anchor().state_is_read_accessible());
974  require(anchor().host()->contains_member(xid));
975 
976  // Body:
977 
978  _has_visited->put(xid.hub_pod(), xvalue);
979 
980  // Postconditions:
981 
982  ensure(has_visited(xid) == xvalue);
983 
984  return;
985 }
986 
987 bool
989 visit_once() const
990 {
991  return _visit_once;
992 }
993 
994 void
996 put_visit_once(bool xvisit_once)
997 {
998  // Preconditions:
999 
1000  // Body:
1001 
1002  _visit_once = xvisit_once;
1003 
1004  // Postconditions:
1005 
1006  ensure(visit_once() == xvisit_once);
1007 
1008  // Exit:
1009 
1010  return;
1011 }
1012 
1013 bool
1015 is_maximal() const
1016 {
1017  bool result;
1018 
1019  // Preconditions:
1020 
1021  require(is_initialized());
1022 
1023  // Body:
1024 
1025  result = !greater_index().is_valid();
1026 
1027  // Postconditions:
1028 
1029  ensure(result == !greater_index().is_valid());
1030 
1031  // Exit
1032 
1033  return result;
1034 }
1035 
1036 const sheaf::scoped_index&
1039 {
1040  // Preconditions:
1041 
1042  require(is_initialized());
1043  require(!is_done());
1044 
1045  // Body:
1046 
1047  _greater_index =
1048  (_action == LINK_ACTION) ? _index.pod() :
1050 
1051  // Postconditions:
1052 
1053  // Exit
1054 
1055  return _greater_index;
1056 }
1057 
1058 const sheaf::scoped_index&
1061 {
1062  // Preconditions:
1063 
1064  require(is_initialized());
1065  require(!is_done());
1066 
1067  // Body:
1068 
1075 
1076  _lesser_index = (_action == LINK_ACTION) ? _path_head_lc->hub_pod() : _index.pod();
1077 
1078  // Postconditions:
1079 
1080  // Exit
1081 
1082  return _lesser_index;
1083 }
1084 
1087 action() const
1088 {
1089  action_type result;
1090 
1091  // Preconditions:
1092 
1093  // Body:
1094 
1095  result = _action;
1096 
1097  // Postconditions:
1098 
1099  // Exit
1100 
1101  return result;
1102 }
1103 
1104 void
1107 {
1108  // Preconditions:
1109 
1110  require(action() == LINK_ACTION);
1111 
1112  // Body:
1113 
1114  _state = ERASE_COVER_ITERATOR;
1115 
1116  // Postconditions:
1117 
1118  // Exit:
1119 
1120  return;
1121 }
1122 
1123 // INDEX ITERATOR FACET
1124 
1125 const sheaf::scoped_index&
1127 index() const
1128 {
1129  // Preconditions:
1130 
1131  require(!is_done());
1132 
1133  // Body:
1134 
1135  const scoped_index& result = _index;
1136 
1137  // Postconditions:
1138 
1139  ensure( (action() == LINK_ACTION) ? (result == greater_index()) : (result == lesser_index()) );
1140 
1141  // Exit
1142 
1143  return result;
1144 }
1145 
1146 size_t
1148 depth() const
1149 {
1150  int result;
1151 
1152  // Preconditions:
1153 
1154  require(!is_done());
1155 
1156  // Body:
1157 
1158  result = _path_tail.size();
1159 
1160  // Postconditions:
1161 
1162 
1163  // Exit:
1164 
1165  return result;
1166 }
1167 
1168 // PROTECTED MEMBER FUNCTIONS
1169 
1172 {
1173  // Preconditions:
1174 
1175  // Body:
1176 
1177  // Set other members to default values.
1178 
1179  _anchor = 0;
1180  _filter = 0;
1181  _new_filter = false;
1182  _descending = true;
1183  _strict = false;
1184  initialize_order(NOT_AN_ORDER);
1185  _has_visited = 0;
1186  _visit_once = true;
1187  _action = NOT_AN_ACTION;
1188  _state = NOT_A_STATE;
1189  _path_head_lc = 0;
1190  _path_head = 0;
1191 
1192  _index.invalidate();
1193 
1194  // Postconditions:
1195 
1196  ensure(invariant());
1197  ensure(order() == NOT_AN_ORDER);
1198  ensure(!is_initialized());
1199  ensure(descending());
1200  ensure(!strict());
1201  ensure(visit_once());
1202  ensure(is_done());
1203 
1204  // Exit
1205 
1206  return;
1207 }
1208 
1211 {
1212 
1213  // Preconditions:
1214 
1215  // Body:
1216 
1217  // Ensure !is_initialized(), then call assigment operator.
1218 
1219  _anchor = 0;
1220  _new_filter = false;
1221  _filter = 0;
1222  _path_head_lc = 0;
1223  _path_head = 0;
1224 
1225  (*this) = xother;
1226 
1227  // Assignemnt operator ensures is_done, so must reset,
1228  // but markers have already been initialized.
1229 
1230  reset(NO_RESET);
1231 
1232  // Postconditions:
1233 
1234  ensure(invariant());
1235  ensure(order() == xother.order());
1236  ensure(is_initialized() == xother.is_initialized());
1237  ensure(is_initialized() ? anchor().is_same_state(&xother.anchor()) : true);
1238  ensure(is_initialized() ? anchor().version() == xother.anchor().version() : true);
1239  ensure(is_initialized() ? filter().is_same_state(&(const_cast<depth_first_iterator&>(xother).filter())) : true);
1240  ensure(is_initialized() ? descending() == xother.descending() : true);
1241  ensure(is_initialized() ? strict() == xother.strict() : true);
1242  ensure(visit_once() == xother.visit_once());
1243  ensure(unexecutable(this is first member of iteration or is_done()));
1244 
1245  // Exit
1246 
1247  return;
1248 }
1249 
1253 {
1254 
1255  // Preconditions:
1256 
1257  // Body:
1258 
1259  depth_first_iterator& lother = const_cast<depth_first_iterator&>(xother);
1260 
1261  if(is_initialized())
1262  {
1263  // Force this into an uninitialized state.
1264 
1265  force_is_done();
1266 
1267  initialize_order(NOT_AN_ORDER);
1268  _descending = true;
1269  _strict = false;
1270 
1272  delete _anchor;
1273  _anchor = 0;
1274 
1275  delete _has_visited;
1276  _has_visited = 0;
1277  _visit_once = true;
1278 
1279  if(_new_filter)
1280  {
1281  delete _filter;
1282  _filter = 0;
1283  _new_filter = false;
1284  }
1285 
1287  }
1288 
1289  // Now this is not initialized, which implies is_done
1290 
1291  assertion(!is_initialized());
1292  assertion(is_done());
1293 
1294  if(lother.is_initialized())
1295  {
1296  // Initialize this to the same state as xother.
1297 
1298  initialize_order(lother._order);
1299  _descending = lother._descending;
1300  _strict = lother._strict;
1301 
1302  initialize_traversal(lother.anchor());
1303  if(lother.filter().index() != lother.anchor().version_index())
1304  {
1305  initialize_filter(lother.filter().index());
1306  }
1307  }
1308 
1309  _visit_once = lother._visit_once;
1310 
1311  // Postconditions:
1312 
1313  ensure(invariant());
1314  ensure(order() == xother.order());
1315  ensure(is_initialized() == xother.is_initialized());
1316  ensure(is_initialized() ? anchor().is_same_state(&xother.anchor()) : true);
1317  ensure(is_initialized() ? anchor().version() == xother.anchor().version() : true);
1318  ensure(is_initialized() ? filter().is_same_state(&(const_cast<depth_first_iterator&>(xother).filter())) : true);
1319  ensure(is_initialized() ? descending() == xother.descending() : true);
1320  ensure(is_initialized() ? strict() == xother.strict() : true);
1321  ensure(visit_once() == xother.visit_once());
1322  ensure(is_done());
1323 
1324  // Exit
1325 
1326  return *this;
1327 }
1328 
1329 void
1332 {
1333  // Preconditions:
1334 
1335  require(is_initialized());
1336  require(_path_tail.empty()); // must be looking for first member
1337 
1338  // Body:
1339 
1340  // Initialize_index; needed by call to upper/lower_cover
1341  // in first pass through state init_cover_iterator.
1342 
1343  _index = _anchor->index();
1344 
1345  // Mark the anchor as visited.
1346 
1347  put_has_visited(_index, true);
1348 
1349  // Now in the previsit position of _path_head, before the previsit action
1350  // has been taken and before iteration over the cover has begun.
1351 
1352  _state = _transition_fcn[FIRST][PASS];
1353  next();
1354 
1355  // Postconditions:
1356 
1357  ensure(invariant());
1358 
1359  // Exit
1360 
1361  return;
1362 }
1363 
1364 void
1367 {
1368  // Preconditions:
1369 
1370  require(is_initialized());
1371  require(anchor().state_is_read_write_accessible());
1372  require(xmbr != 0);
1373  require(xmbr->is_attached());
1374  require(anchor().host()->contains_member(xmbr));
1375 
1376  // Body:
1377 
1378  // _has_visited->put(xmbr->index().pod(), true);
1379  put_has_visited(xmbr->index(), true);
1380 
1381  // Postconditions:
1382 
1383  ensure(has_visited(xmbr));
1384 
1385  // Exit:
1386 
1387  return;
1388 }
1389 
1390 void
1393 {
1394 
1395  // Preconditions:
1396 
1397  require(is_initialized());
1398  require(xmbr != 0);
1399  require(xmbr->is_attached());
1400  require(anchor().state_is_read_accessible());
1401  require(anchor().host()->contains_member(xmbr));
1402 
1403  // Body:
1404 
1405  put_has_visited(xmbr->index(), false);
1406 
1407  // Postconditions:
1408 
1409  ensure(!has_visited(xmbr));
1410 
1411  // Exit:
1412 
1413  return;
1414 }
1415 
1416 void
1419 {
1420  // Preconditions:
1421 
1422  // Body:
1423 
1424  // Empty in this class; intended for redefinition in descendants;
1425 
1426  // Postconditions:
1427 
1428  // Exit
1429 
1430  return;
1431 }
1432 
1433 void
1436 {
1437  // Preconditions:
1438 
1439  // Body:
1440 
1441  // Empty in the class; intended for redefinition in descendants;
1442 
1443  // Postconditions:
1444 
1445  // Exit
1446 
1447  return;
1448 }
1449 
1450 void
1453 {
1454  // Preconditions:
1455 
1456  // Body:
1457 
1458  _order = xorder;
1460 
1461  // Postconditions:
1462 
1463  ensure(order() == xorder);
1464 
1465  // Exit
1466 
1467  return;
1468 }
1469 
1470 void
1473 {
1474  // Preconditions:
1475 
1476  require(anchor_is_ancestor_of(xanchor));
1477  require(xanchor.state_is_read_accessible());
1478  require(is_done());
1479 
1480  // Body:
1481 
1482  define_old_variable(bool old_descending = _descending);
1483  define_old_variable(bool old_strict = _strict);
1484 
1485  // Allocate anchor if needed and attach to
1486  // the state and version of xanchor.
1487 
1488  initialize_anchor(xanchor);
1489 
1490  // (Re)allocate markers and initialize to false.
1491 
1492  initialize_has_visited(xanchor);
1493 
1494  // Initialize the filter
1495 
1497 
1498 #ifdef DIAGNOSTIC_OUTPUT
1499 
1500  cout << "in depth_first_iterator::initialize_traversal(xanchor): " << endl
1501  << "_anchor = " << *_anchor << endl
1502  << "_filter = " << _filter << endl;
1503 #endif
1504 
1505  // Postconditions:
1506 
1507  ensure(invariant());
1508  ensure(is_initialized());
1509  ensure(is_done());
1510  ensure(anchor().is_same_state(&xanchor));
1511  ensure(anchor().is_same_type(&xanchor));
1512  ensure(anchor().version() == xanchor.version());
1513  ensure(filter().index() == anchor().version_index());
1514  ensure(descending() == old_descending);
1515  ensure(strict() == old_strict);
1516 
1517  // Exit
1518 
1519  return;
1520 }
1521 
1522 void
1525 {
1526  // Preconditions:
1527 
1528  require(is_initialized());
1529  require(anchor().state_is_read_accessible());
1530  require(anchor().host()->contains_member(xanchor_hub_id));
1531  require(is_done());
1532 
1533  // Body:
1534 
1535  define_old_variable(bool old_descending = _descending);
1536  define_old_variable(bool old_strict = _strict);
1537  define_old_variable(scoped_index old_filter_index = filter().index());
1538  define_old_variable(int old_anchor_version = anchor().version());
1539 
1540  // Set the anchor
1541 
1542  _anchor->attach_to_state(xanchor_hub_id);
1543 
1544  // Force the iterator to is_done so
1545  // client must reset before using this.
1546 
1547  force_is_done();
1548 
1549 #ifdef DIAGNOSTIC_OUTPUT
1550 
1551  cout << "in depth_first_iterator::initialize_traversal(xanchor_hub_id): " << endl
1552  << "_anchor = " << *_anchor << endl
1553  << "_filter = " << _filter << endl;
1554 #endif
1555 
1556  // Postconditions:
1557 
1558  ensure(invariant());
1559  ensure(is_initialized());
1560  ensure(is_done());
1561  ensure(anchor().index() == xanchor_hub_id);
1562  ensure(anchor().version() == old_anchor_version);
1563  ensure(filter().index() == old_filter_index);
1564  ensure(descending() == old_descending);
1565  ensure(strict() == old_strict);
1566 
1567  // Exit
1568 
1569  return;
1570 }
1571 
1572 void
1575 {
1576  // Preconditions:
1577 
1578  require(is_initialized());
1579  require(anchor().state_is_read_accessible());
1580  require(anchor().host()->contains_member(xanchor_id));
1581  require(is_done());
1582 
1583  // Body:
1584 
1585  define_old_variable(bool old_descending = _descending);
1586  define_old_variable(bool old_strict = _strict);
1587  define_old_variable(scoped_index old_filter_index = filter().index());
1588  define_old_variable(int old_anchor_version = anchor().version());
1589 
1590  initialize_traversal(xanchor_id.hub_pod());
1591 
1592  // Postconditions:
1593 
1594  ensure(invariant());
1595  ensure(is_initialized());
1596  ensure(is_done());
1597  ensure(anchor().index() ==~ xanchor_id);
1598  ensure(anchor().version() == old_anchor_version);
1599  ensure(filter().index() == old_filter_index);
1600  ensure(descending() == old_descending);
1601  ensure(strict() == old_strict);
1602 
1603  // Exit
1604 
1605  return;
1606 }
1607 
1608 void
1611 {
1612  // Preconditions:
1613 
1614  require(anchor_is_ancestor_of(xanchor));
1615  require(xanchor.state_is_read_accessible());
1616  require(is_done());
1617 
1618  // Body:
1619 
1620  if(_anchor == 0)
1621  {
1622  _anchor = xanchor.clone();
1623  }
1624  else if(!_anchor->is_same_type(&xanchor))
1625  {
1627 
1629  delete _anchor;
1630  _anchor = xanchor.clone();
1631  }
1632 
1633  _anchor->attach_to_state(&xanchor);
1634 
1635  // Set _index to the internal id space of _anchor.
1636 
1637  _index = _anchor->host()->member_id(false);
1640 
1641  // Postconditions:
1642 
1643  // Can't use anchor() yet because it requres is_initialized().
1644 
1645  ensure(_anchor != 0);
1646  ensure(_anchor->is_same_state(&xanchor));
1647  ensure(_anchor->is_same_type(&xanchor));
1648  ensure(is_done());
1649 
1650  // Exit
1651 
1652  return;
1653 }
1654 
1655 void
1658 {
1659  // Preconditions:
1660 
1661  require(xanchor.state_is_read_accessible());
1662  require(is_done());
1663 
1664  // Body:
1665 
1666  if(_has_visited != 0)
1667  {
1668  delete _has_visited;
1669  }
1670 
1671  // Allocate has visited bit vector to be indexed in internal scope.
1672 
1673  pod_index_type lub = xanchor.host()->member_index_ub().pod();
1674  _has_visited = new zn_to_bool(lub);
1675 
1676 
1677  // Postconditions:
1678 
1679  ensure(_has_visited != 0);
1680  ensure(is_done());
1681 
1682  // Exit
1683 
1684  return;
1685 }
1686 
1690 {
1691  return _has_visited;
1692 }
1693 
1694 void
1697 {
1698  _has_visited = xhas_visited;
1699  return;
1700 }
1701 
1702 void
1705 {
1706  // Preconditions:
1707 
1708  require(_anchor != 0);
1709  require(_anchor->state_is_read_accessible());
1710  require(_client_filter.is_attached());
1711  require(is_done());
1712 
1713  // Body:
1714 
1715  // First clean up any existing filter.
1716 
1717  // If this allocated the existing _filter, delete it.
1718 
1719  if(_new_filter)
1720  delete _filter;
1721 
1722  _filter = 0;
1723 
1724  // Initialize the new filter using same scope as _client_filter (internal scope).
1725  // Iterator should traverse downset of the anchor, filtered by
1726  // the intersection of _client_filter with the version filter associated
1727  // with _anchor.version(). If _client_filter is the same as the version filter,
1728  // or if the version filter is the same as the allocated filter (that is,
1729  // the version is the coarsest common refinement and allocated members
1730  // pass the filter) then we don't need to compute the intersection nor
1731  // store the result, we can just use _client_filter._members().
1732 
1733  int lversion = _anchor->version();
1734 
1735  if(lversion == COARSEST_COMMON_REFINEMENT_VERSION)
1736  {
1737  // Version is CCR, use the client filter members as the traversal filter.
1738 
1739  _filter = _client_filter.members();
1740  _new_filter = false;
1741  }
1742  else
1743  {
1744  poset_state_handle* lhost = _anchor->host();
1745  pod_index_type lversion_index = lhost->version_index(lversion);
1746  if(_client_filter.index() == lversion_index)
1747  {
1748  // Client filter is same as version filter;
1749  // use the client filter members as the traversal filter.
1750 
1751  _filter = _client_filter.members();
1752  _new_filter = false;
1753  }
1754  else
1755  {
1756  // Have to allocate a new traversal filter.
1757 
1758  _filter = new zn_to_bool(*(_client_filter.members()));
1759  _new_filter = true;
1760  _filter->b_and_sa(lhost->powerset().member(lversion_index).members());
1761  }
1762  }
1763 
1764  // Postconditions:
1765 
1766  ensure(_filter != 0);
1767  ensure(is_done());
1768 
1769  // Exit
1770 
1771  return;
1772 }
1773 
1774 void
1777 {
1778  // Preconditions:
1779 
1780  require(_anchor != 0);
1781  require(_anchor->state_is_read_accessible());
1782  require(_anchor->host()->includes_subposet(&xfilter));
1783  require(is_done());
1784 
1785  // Body:
1786 
1787  define_old_variable(bool old_descending = _descending);
1788  define_old_variable(bool old_strict = _strict);
1789 
1790  _client_filter.attach_to_state(&xfilter);
1791 
1793 
1794  // Postconditions:
1795 
1796  ensure(invariant());
1797  ensure(_filter != 0);
1798  ensure(_client_filter.is_same_state(&xfilter));
1799  ensure(descending() == old_descending);
1800  ensure(strict() == old_strict);
1801  ensure(is_done());
1802 
1803 
1804  // Exit
1805 
1806  return;
1807 }
1808 
1809 void
1812 {
1813  // Preconditions:
1814 
1815  require(_anchor != 0);
1816  require(_anchor->state_is_read_accessible());
1817  require(_anchor->host()->includes_subposet(xfilter_hub_id));
1818  require(is_done());
1819 
1820  // Body:
1821 
1822  _client_filter.attach_to_state(_anchor->host(), xfilter_hub_id);
1823 
1825 
1826  // Postconditions:
1827 
1828  ensure(_filter != 0);
1829  ensure(_client_filter.index() == xfilter_hub_id);
1830  ensure(is_done());
1831 
1832  // Exit
1833 
1834  return;
1835 }
1836 
1837 void
1840 {
1841  // Preconditions:
1842 
1843  require(_anchor != 0);
1844  require(_anchor->state_is_read_accessible());
1845  require(_anchor->host()->includes_subposet(xfilter_id));
1846  require(is_done());
1847 
1848  // Body:
1849 
1850  initialize_filter(xfilter_id.hub_pod());
1851 
1852  // Postconditions:
1853 
1854  ensure(_filter != 0);
1855  ensure(_client_filter.index() ==~ xfilter_id);
1856  ensure(is_done());
1857 
1858  // Exit
1859 
1860  return;
1861 }
1862 
1863 void
1865 initialize_filter(const std::string& xfilter_name)
1866 {
1867  // Preconditions:
1868 
1869  require(_anchor != 0);
1870  require(_anchor->state_is_read_accessible());
1871  require(!xfilter_name.empty() ?
1872  _anchor->host()->includes_subposet(xfilter_name) :
1873  true);
1874  require(is_done());
1875 
1876  // Body:
1877 
1878  if(xfilter_name.empty())
1879  {
1881  }
1882  else
1883  {
1884  _client_filter.attach_to_state(_anchor->host(), xfilter_name);
1885  }
1886 
1888 
1889  // Postconditions:
1890 
1891  ensure(_filter != 0);
1892  // If _client_filter has multiple names, ensure that at least
1893  // one of them matches.
1894  ensure(!xfilter_name.empty() ?
1895  _client_filter.has_name(xfilter_name) :
1896  _client_filter.has_name(anchor().version_name()));
1897  ensure(is_done());
1898 
1899  // Exit
1900 
1901  return;
1902 }
1903 
1904 void
1907 {
1908  // Preconditions:
1909 
1910  // Body:
1911 
1912  if(_anchor != 0)
1913  {
1915 
1916  if(_path_head_lc != 0)
1917  {
1919  _path_head_lc = 0;
1920  }
1921 
1922  if(_path_head != 0)
1923  {
1925  _path_head = 0;
1926  }
1927 
1928  while(!_path_tail.empty())
1929  {
1931  _path_tail.pop();
1932  }
1933 
1934  _anchor->host()->release_access();
1935  }
1936  else
1937  {
1939 
1940  assertion(_path_head_lc == 0);
1941  assertion(_path_head == 0);
1942  assertion(_path_tail.empty());
1943  }
1944 
1945  // Postconditions:
1946 
1947  ensure(_path_head_lc == 0);
1948  ensure(_path_head == 0);
1949  ensure(_path_tail.empty());
1950 
1951  // Exit:
1952 
1953  return;
1954 }
1955 
1956 const char*
1958 iterator_state_names[NOT_A_STATE+1] =
1959  {
1960  "FIRST",
1961  "INIT_COVER_ITERATOR",
1962  "TEST_HAS_VISITED",
1963  "INC_COVER_ITERATOR",
1964  "ERASE_COVER_ITERATOR",
1965  "DESCEND",
1966  "TEST_PATH_TAIL",
1967  "ASCEND",
1968  "EXECUTE_PREVISIT_ACTION",
1969  "EXECUTE_LINK_ACTION",
1970  "EXECUTE_POSTVISIT_ACTION",
1971  "FINISH",
1972  "NOT_A_STATE"
1973  };
1974 
1977 PREORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1] =
1978  {
1979  // PASS, FAIL
1980 
1981  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // FIRST
1982  TEST_HAS_VISITED, TEST_PATH_TAIL, // INIT_COVER_ITERATOR
1983  INC_COVER_ITERATOR, DESCEND, // TEST_HAS_VISITED
1984  TEST_HAS_VISITED, TEST_PATH_TAIL, // INC_COVER_ITERATOR
1985  NOT_A_STATE, NOT_A_STATE, // ERASE_COVER_ITERATOR
1986  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // DESCEND
1987  FINISH, ASCEND, // TEST_PATH_TAIL
1988  INC_COVER_ITERATOR, INC_COVER_ITERATOR, // ASCEND
1989  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // EXECUTE_PREVISIT_ACTION
1990  NOT_A_STATE, NOT_A_STATE, // EXECUTE_LINK_ACTION,
1991  NOT_A_STATE, NOT_A_STATE // EXECUTE_POSTVISIT_ACTION
1992  };
1993 
1994 
1997 POSTORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1] =
1998  {
1999  // PASS, FAIL
2000 
2001  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // FIRST
2002  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INIT_COVER_ITERATOR
2003  INC_COVER_ITERATOR, DESCEND, // TEST_HAS_VISITED
2004  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INC_COVER_ITERATOR
2005  NOT_A_STATE, NOT_A_STATE, // ERASE_COVER_ITERATOR
2006  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // DESCEND
2007  FINISH, ASCEND, // TEST_PATH_TAIL
2008  INC_COVER_ITERATOR, INC_COVER_ITERATOR, // ASCEND
2009  NOT_A_STATE, NOT_A_STATE, // EXECUTE_PREVISIT_ACTION
2010  NOT_A_STATE, NOT_A_STATE, // EXECUTE_LINK_ACTION,
2011  TEST_PATH_TAIL, TEST_PATH_TAIL // EXECUTE_POSTVISIT_ACTION
2012  };
2013 
2016 LINKORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1] =
2017  {
2018  // PASS, FAIL
2019 
2020  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // FIRST
2021  TEST_HAS_VISITED, TEST_PATH_TAIL, // INIT_COVER_ITERATOR
2022  EXECUTE_LINK_ACTION, DESCEND, // TEST_HAS_VISITED
2023  TEST_HAS_VISITED, TEST_PATH_TAIL, // INC_COVER_ITERATOR
2024  TEST_HAS_VISITED, TEST_PATH_TAIL, // ERASE_COVER_ITERATOR
2025  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // DESCEND
2026  FINISH, ASCEND, // TEST_PATH_TAIL
2027  EXECUTE_LINK_ACTION, EXECUTE_LINK_ACTION, // ASCEND
2028  NOT_A_STATE, NOT_A_STATE, // EXECUTE_PREVISIT_ACTION
2029  INC_COVER_ITERATOR, INC_COVER_ITERATOR, // EXECUTE_LINK_ACTION,
2030  NOT_A_STATE, NOT_A_STATE // EXECUTE_POSTVISIT_ACTION
2031  }
2032 ;
2033 
2036 BIORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1] =
2037  {
2038  // PASS, FAIL
2039 
2040  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // FIRST
2041  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INIT_COVER_ITERATOR
2042  INC_COVER_ITERATOR, DESCEND, // TEST_HAS_VISITED
2043  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INC_COVER_ITERATOR
2044  NOT_A_STATE, NOT_A_STATE, // ERASE_COVER_ITERATOR
2045  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // DESCEND
2046  FINISH, ASCEND, // TEST_PATH_TAIL
2047  INC_COVER_ITERATOR, INC_COVER_ITERATOR, // ASCEND
2048  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // EXECUTE_PREVISIT_ACTION
2049  NOT_A_STATE, NOT_A_STATE, // EXECUTE_LINK_ACTION,
2050  TEST_PATH_TAIL, TEST_PATH_TAIL // EXECUTE_POSTVISIT_ACTION
2051  };
2052 
2055 TRIORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1] =
2056  {
2057  // PASS, FAIL
2058 
2059  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // FIRST
2060  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INIT_COVER_ITERATOR
2061  EXECUTE_LINK_ACTION, DESCEND, // TEST_HAS_VISITED
2062  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // INC_COVER_ITERATOR
2063  TEST_HAS_VISITED, EXECUTE_POSTVISIT_ACTION, // ERASE_COVER_ITERATOR
2064  EXECUTE_PREVISIT_ACTION, EXECUTE_PREVISIT_ACTION, // DESCEND
2065  FINISH, ASCEND, // TEST_PATH_TAIL
2066  EXECUTE_LINK_ACTION, EXECUTE_LINK_ACTION, // ASCEND
2067  INIT_COVER_ITERATOR, INIT_COVER_ITERATOR, // EXECUTE_PREVISIT_ACTION
2068  INC_COVER_ITERATOR, INC_COVER_ITERATOR, // EXECUTE_LINK_ACTION,
2069  TEST_PATH_TAIL, TEST_PATH_TAIL // EXECUTE_POSTVISIT_ACTION
2070  };
2071 
2072 const sheaf::depth_first_iterator::transition_fcn_type
2074 STD_TRANSITION_FCNS[NOT_AN_ORDER+1] =
2075  {
2081  0
2082  };
2083 
2084 
virtual bool has_name(const std::string &xname, bool xauto_access=false) const
True if xname is a name for this.
Definition: subposet.cc:2762
virtual bool invariant() const
Class invariant, intended to be redefined in each descendant. See below for template for invariant in...
Definition: any.cc:153
poset_state_handle * host() const
The poset which this is a handle to a component of.
virtual void force_is_done()
Force the iterator to be done.
void mark_visited(abstract_poset_member *xmbr)
Mark xmbr as visited. Warning: this function can change the state of the iteration in unpredictable w...
A client handle for a subposet.
Definition: subposet.h:86
bool is_valid() const
True if this is a valid id.
Definition: scoped_index.h:832
zn_to_bool * members() const
Get the members of the subposet.
int version(bool xunalias=true) const
The (possibly aliased) version of this component. The version of the host used when evaluating proper...
static const iterator_state BIORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1]
The predefined transition function for biorder iteration. Defines the next state for each combination...
virtual bool is_initialized() const
True if this has been initialized for iteration with respect to a specific anchor.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
bool visit_once() const
True if traversal should only visit a member once; that is, it should not revisit members it has alre...
index_space_iterator & get_cover_id_space_iterator(bool xlower, pod_index_type xmbr_hub_id) const
Allocates an iterator for the lower (xlower true) or upper (xlower false) cover id space of the membe...
void initialize_order(order_type xorder)
Initializes _order and _transition_fcn.
static const iterator_state TRIORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1]
The predefined transition function for triorder iteration. Defines the next state for each combinatio...
pod_index_type version_index() const
The subposet index for the filter associated with version().
void make_false_sa()
Constant function false, self-allocated. Note on terminology: "false" is a keyword, so this function can not be just "false"
Definition: zn_to_bool.cc:955
void initialize_filter()
Initializes the filter subposet from the client filter.
action_type action() const
The type of action the client should take when the iterator returns control to the client...
abstract_poset_member * _anchor
The top member of the down set being iterated over.
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
void erase_cover()
Schedules the lesser member entry in the cover of the greater member of the current link for deletion...
void clear_cover(bool xlower, pod_index_type xmbr_hub_id)
Clears the lower (xlower true) or upper (xlower false) cover set of the member with hub id xmbr_hub_i...
static const char * NULL_FILTER
Placeholder for null filter.
void put_visit_once(bool xvisit_once)
Set visit_once() to xvisit_once.
A client handle for a general, abstract partially order set.
virtual bool includes_subposet(pod_index_type xsubposet_hub_id, bool xauto_access=true) const
True if this poset includes subposet with hub id xsubposet_hub_id.
void initialize_anchor(const abstract_poset_member &xanchor)
Initializes the anchor.
action_type _action
The type of action the client should take; the state of the iterator.
std::stack< pod_index_type > _filtered_path_tail
The tail of the filtered path to the current member of the iteration. Contains only members which pas...
virtual bool anchor_is_ancestor_of(const abstract_poset_member &xmbr) const
True if xmbr conforms to the type of anchor of this.
bool is_same_state(const poset_state_handle *xhost, pod_index_type xhub_id) const
True is this is attached to state with hub id xhub_id in host xhost.
void put(int i, bool value)
Sets i-th member to value.
Definition: zn_to_bool.cc:537
bool _visit_once
True if traversal should only visit a member once; that is, it should not revisit members it has alre...
void invalidate()
Make this id invalid.
Definition: scoped_index.h:852
size_t depth() const
The length of the path from anchor() to the current member.
order_type
The types of order in which the iterator will visit the members of the poset. Determines which action...
const scoped_index & index() const
The index of the component state this handle is attached to.
virtual void next()=0
Makes id() the next id in the iteration.
subposet _client_filter
The filter specified by the client.
depth_first_iterator()
Default constructor; creates an unattached iterator,.
bool is_maximal() const
True if the current member has no greater member within the subposet visited by this iterator...
void attach_to_state(const poset_state_handle *xhost, pod_index_type xhub_id)
Attach this handle to the state with hub id xhub_id in the current version of host xhost...
Abstract base class with useful features for all objects.
Definition: any.h:39
A map from Zn (the integers mod n) to bools. A characteristic function used to represent subsets of Z...
Definition: zn_to_bool.h:52
virtual void detach_item()
Detaches the item handle to the current index. Empty in this class; intended for redefinition in desc...
bool is_done() const
True if iteration is finished.
virtual abstract_poset_member & anchor()
The poset member whose downset is being iterated over; the top member of the domain of iteration (mut...
order_type order() const
The order of the iteration. Determines which actions are exported to the client.
const iterator_state(* _transition_fcn)[FAIL+1]
The current state transition function for the iterator finite state machine. Points to one of the pre...
virtual pod_index_type version_index(int xversion) const
The subposet hub id of the whole() subposet for version xversion.
action_type
The types of action a client should take when the iterator returns control to the client...
An index within the external ("client") scope of a given id space.
Definition: scoped_index.h:116
virtual bool is_attached() const
True if this handle is attached to a non-void state.
scoped_index _lesser_index
The index of the lesser member of the current link.
virtual void initialize_has_visited(const abstract_poset_member &xanchor)
Initializes the has_visited markers.
void release_cover_id_space_iterators()
Release the cover iterators back to the pool of iterators.
bool descending() const
True if iterating over down set of anchor.
bool _new_filter
True if this allocated a new filter;.
static const iterator_state PREORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1]
The predefined transition function for postorder iteration. Defines the next state for each combinati...
void next()
Makes this the next member of the subset.
depth_first_iterator & operator=(const depth_first_iterator &xother)
Assignment operator.
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
scoped_index _greater_index
The index of the greater member of the current link.
virtual void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
const scoped_index & lesser_index() const
The index of the lesser member of the current link.
const scoped_index & greater_index() const
The index of the greater member of the current link.
zn_to_bool * members() const
The characteristic function for the members of this.
Definition: subposet.cc:1277
index_space_iterator * _path_head
The head of the path to the current member of the iteration lesser_index() == this->index() == **_pat...
void mark_not_visited(abstract_poset_member *xmbr)
Mark xmbr as not visited. Warning: this function can change the state of the iteration in unpredictab...
abstract_poset_member * clone(bool xnew_state, bool xauto_access=true) const
Virtual constructor; makes a new handle of the same type as this, attached to a new state (xnew_state...
static const char * iterator_state_names[NOT_A_STATE+1]
The names of the iterator states, convenient for debugging.
const bool NO_RESET
Iteration marker reset control.
Definition: sheaf.h:92
static const transition_fcn_type STD_TRANSITION_FCNS[NOT_AN_ORDER+1]
The set of predefined transition functions.
bool is_done() const
True if iteration finished.
index_space_iterator * _path_head_lc
The lower cover iterator for the head of the path to the current member of the iteration.
static const iterator_state LINKORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1]
The predefined transition function for linkorder iteration. Defines the next state for each combinati...
virtual void detach_from_state()
Detach this handle from its state, if any.
void first()
Moves this to the first member of the iteration.
bool _descending
True if iterating over the up/down set of anchor.
iterator_state _state
The current state of iteration.
virtual void reset(bool xreset_markers=true)
Restarts the iteration over the down set of anchor().
void put_has_visited(pod_index_type xhub_id, bool xvalue)
Set the visited marker for hub id xhub_id to xvalue. Intended for use reseting iterator without havin...
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
virtual ~depth_first_iterator()
Destructor.
std::stack< index_space_iterator * > _path_tail
The tail of the path to the current member of the iteration greater_index() == **(_path_tail.top()) == greater member of current link.
void initialize_traversal(const abstract_poset_member &xanchor)
Initializes the anchor, has_visited markers and filter.
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
zn_to_bool * has_visited() const
The marker bit vector. /.
virtual scoped_index member_index_ub() const
The upper bound on the member_index;.
iterator_state
The states for the finite state machine that controls iteration.
bool invariant() const
The class invariant.
int ct(bool xreset=false)
The number of members of the iteration set, from the current member to the end, inclusive. If xreset, reset before computing the count.
virtual bool is_ancestor_of(const any *other) const
True if other conforms to this.
bool _strict
True if iterating over the strict up/down set of anchor.
void b_and_sa(const zn_to_bool *other)
This AND other, self-allocated.
Definition: zn_to_bool.cc:1181
subposet_state & member(pod_index_type xindex)
The subposet with index xindex (mutable version).
void attach_to_state(const namespace_poset *xns, const poset_path &xpath, bool xauto_access=true)
Attach to the state specified by path xpath in the namespace xns.
virtual depth_first_iterator * clone() const
Make a new instance of the same type as this.
virtual void get_read_access() const
Get read access to the state associated with this.
An abstract client handle for a member of a poset.
void extend_to(int xub)
Make the upper bound at least xub.
Definition: zn_to_bool.cc:362
subposet & filter()
The subposet which is the filter; Defines what is passed, not what is blocked.
static const iterator_state POSTORDER_TRANSITION_FCN[NOT_A_STATE-1][FAIL+1]
The predefined transition function for postorder iteration. Defines the next state for each combinati...
SHEAF_DLL_SPEC bool is_valid(pod_index_type xpod_index)
True if an only if xpod_index is valid.
Definition: pod_types.cc:37
std::string version_name() const
The subposet name for the filter associated with version().
SHEAF_DLL_SPEC pod_index_type invalid_pod_index()
The invalid pod index value.
Definition: pod_types.cc:31
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
virtual void attach_item()
Attaches the item handle to the current index. Empty in this class; intended for redefinition in desc...
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
void force_is_done()
Makes is_done() true.
bool strict() const
True if iterating over xstrict up/down set of anchor.
void release_cover_id_space_iterator(index_space_iterator &xcover_itr) const
Returns xcover_itr to the pool of id space iterators.
poset_powerset_state & powerset() const
The set of subposets of this poset.
scoped_index _index
The index of the lesser end of the current link; the current item in the iteration.
pod_type hub_pod() const
The current unglued hub id in the iteration. synonym for unglued_hub_pod().
order_type _order
The order of the iteration.
virtual const scoped_index & member_id(bool xauto_access) const
An id in the member hub id space; intended for copying to initialize ids to the member id space...
pod_type hub_pod() const
The pod value of this mapped to the unglued hub id space.
Definition: scoped_index.h:710
const scoped_index & index() const
The index of the current member of the iteration.