SheafSystem  0.0.0.0
poset_slicer.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 POSET_SLICER
19 
20 #include "SheafSystem/poset_slicer.h"
21 #include "SheafSystem/assert_contract.h"
22 #include "SheafSystem/poset.h"
23 #include "SheafSystem/subposet.h"
24 #include "SheafSystem/subposet_member_iterator.h"
25 #include "SheafSystem/total_poset_member.h"
26 
27 // inlines placed here so they will be visible when called
28 // Not put in header file because they are olny used here and
29 // to avoid including poset_member.h in poset_slicer.h
30 
31 inline bool
32 sheaf::poset_slicer::
33 only_shallowest()
34 {
35  return ( (_mode == MAXIMAL) && _in_down_set) || ((_mode == MINIMAL) && !_in_down_set);
36 }
37 
38 inline bool
39 sheaf::poset_slicer::
40 only_deepest()
41 {
42  return ( (_mode == MINIMAL) && _in_down_set) || ((_mode == MAXIMAL) && !_in_down_set);
43 }
44 
45 inline bool
46 sheaf::poset_slicer::
47 layer_contains_member(const abstract_poset_member* xmbr)
48 {
49  return ( (_layer == 0) || _layer->contains_member(xmbr) );
50 }
51 
52 inline bool
53 sheaf::poset_slicer::
54 slice_contains_member(abstract_poset_member* xmbr)
55 {
56  return ( (_slice == 0) || _slice->contains_member(xmbr) );
57 }
58 
59 inline void
60 sheaf::poset_slicer::
61 insert_member(abstract_poset_member* xmbr)
62 {
63  _slice->insert_member(xmbr);
64 }
65 
66 
68 bool
70 invariant() const
71 {
72  bool result = true;
73 
74  result = result && poset_traverser::invariant();
75  // result = result && ( (_layer != 0) ? ( _layer->host() == _host ) : true );
76  // result = result && ( (_slice != 0) ? ( _slice->host() == _host ) : true );
77  result = result && ( (_layer != 0) ? ( _layer->host()->is_same_state(_host) ) : true );
78  result = result && ( (_slice != 0) ? ( _slice->host()->is_same_state(_host) ) : true );
79 
80  return result;
81 }
82 
83 
87  : poset_dft(xhost)
88 {
89 
90  // preconditions:
91 
92  require(xhost != 0);
93 
94  // body:
95 
96  // initialize data members
97 
98  _layer = 0;
99  _slice = 0;
100 
101  // postconditions:
102 
103  ensure(invariant());
104 }
105 
106 
110 {
111 
112  // preconditions:
113 
114  // body:
115 
116  // postconditions:
117 
118 }
119 
120 
124 find(abstract_poset_member* xanchor, subposet* xlayer, bool xdown, slice_mode xmode)
125 {
126  subposet* result;
127 
128  // Preconditions:
129 
130  require(has_same_host(xanchor));
131  require(has_same_host(xlayer));
132 
133  // Body:
134 
135  result = new subposet(_host);
136  find_pa(xanchor, xlayer, xdown, result, xmode);
137 
138  // Postconditions:
139 
140  ensure(invariant());
141  ensure(has_same_host(result));
142  ensure(unexecutable(result is intersection(xmode members of xdown set
143  of xanchor, xlayer)));
144 
145  // Exit
146 
147  return result;
148 }
149 
150 
152 void
154 find_pa(abstract_poset_member* xanchor, subposet* xlayer, bool xdown, subposet* result, slice_mode xmode)
155 {
156  // Preconditions:
157 
158  require(has_same_host(xanchor));
159  require(xlayer != 0 ? has_same_host(xlayer) : true);
160  require(has_same_host(result));
161 
162  // Body:
163 
164  _layer = xlayer;
165  _slice = result;
166  _mode = xmode;
167  _select_only_shallowest = only_shallowest();
168  _select_only_deepest = only_deepest();
169  _depth_below_shallowest = -1;
170  _height_above_deepest = -1;
171 
172 
173  traverse(xanchor, xdown);
174 
175  // clean up
176 
177  _slice = 0;
178 
179 
180  // Postconditions:
181 
182  ensure(invariant());
183  ensure(unexecutable(result is xmode members of union(intersection(xdown set
184  of xanchor, xlayer), old result)));
185 
186  // Exit
187 
188  return;
189 }
190 
191 
195 find(subposet* xanchor, subposet* xlayer, bool xdown, slice_mode xmode)
196 {
197  subposet* result;
198 
199  // Preconditions:
200 
201  require(has_same_host(xanchor));
202  require(has_same_host(xlayer));
203 
204  // Body:
205 
206  result = new subposet(_host);
207  find_pa(xanchor, xlayer, xdown, result, xmode);
208 
209  // Postconditions:
210 
211  ensure(invariant());
212  ensure(has_same_host(result));
213  ensure(unexecutable(result is intersection(xmode memberss of xdown set
214  of xanchor, xlayer)));
215 
216  // Exit
217 
218  return result;
219 }
220 
221 
223 void
225 find_pa(const subposet* xanchor, subposet* xlayer, bool xdown, subposet* result, slice_mode xmode)
226 {
227  // Preconditions:
228 
229  require(has_same_host(xanchor));
230  require(xlayer != 0 ? has_same_host(xlayer) : true);
231  require(has_same_host(result));
232  require(!xanchor->is_same_state(result));
233 
234  // Body:
235 
236  _layer = xlayer;
237  _slice = result;
238  _mode = xmode;
239  _in_down_set = xdown;
240  _select_only_shallowest = only_shallowest();
241  _select_only_deepest = only_deepest();
242  _depth_below_shallowest = -1;
243  _height_above_deepest = -1;
244 
245  // The down or up set of a subposet is the union of the
246  // down or up sets of its members. In order to get the
247  // down or up sets of all the members, start a DFT at
248  // each member. Take the union implicitly (and efficiently)
249  // by accumulating in a single result and by not
250  // resetting the _visited markers between traversals.
251 
253 
254  poset_member_iterator* itr = xanchor->member_iterator();
255  while(!itr->is_done())
256  {
257  if(!has_been_visited(itr))
258  {
259  // traverse down or up set of itr without resetting markers
260  traverse(itr, _in_down_set, false);
261  }
262  itr->next();
263  }
264 
265  delete itr;
266 
267  // clean up
268 
269  _anchor = 0;
270  _slice = 0;
271 
272  // Postconditions:
273 
274  ensure(invariant());
275  ensure(unexecutable(result is xmode members of union(intersection(xdown set
276  of xanchor, xlayer), old result) ));
277 
278  // Exit
279 
280  return;
281 }
282 
283 
288 {
289  subposet* result;
290 
291  // Preconditions:
292 
293  require(has_same_host(xanchor));
294 
295  // Body:
296 
297  result = new subposet(_host);
298  find_jims_pa(xanchor, result, xmode);
299 
300  // Postconditions:
301 
302  ensure(invariant());
303  ensure(has_same_host(result));
304  ensure(unexecutable(result is xmode jims of xanchor));
305 
306  // Exit
307 
308  return result;
309 }
310 
311 
313 void
316 {
317  // Preconditions:
318 
319  require(has_same_host(xanchor));
320  require(has_same_host(result));
321 
322  // Body:
323 
324  subposet* jims = &(host()->jims());
325 
326  // find_pa(xanchor, jims, sheaf_constants::DOWN, result, xmode);
327  find_pa(xanchor, jims, true, result, xmode);
328 
329  // Postconditions:
330 
331  ensure(invariant());
332  ensure(unexecutable(result is xmode members of union(jims of xanchor, old result)));
333 
334  // Exit
335 
336  return;
337 }
338 
339 
343 find_jims(const subposet* xanchor, slice_mode xmode)
344 {
345  subposet* result;
346 
347  // Preconditions:
348 
349  require(has_same_host(xanchor));
350 
351  // Body:
352 
353  result = new subposet(_host);
354  find_jims_pa(xanchor, result, xmode);
355 
356  // Postconditions:
357 
358  ensure(invariant());
359  ensure(unexecutable(result is xmode jims of xanchor));
360 
361  // Exit
362 
363  return result;
364 }
365 
366 
368 void
370 find_jims_pa(const subposet* xanchor, subposet* result, slice_mode xmode)
371 {
372  // Preconditions:
373 
374  require(has_same_host(xanchor));
375  require(has_same_host(result));
376  require(!xanchor->is_same_state(result));
377 
378  // Body:
379 
380  _layer = &(host()->jims());
381 
382  _slice = result;
383  _mode = xmode;
384  _in_down_set = true;
385  _select_only_shallowest = only_shallowest();
386  _select_only_deepest = only_deepest();
387  _depth_below_shallowest = -1;
388  _height_above_deepest = -1;
389 
390 
391  // The down set of a subposet is the union of the
392  // down sets of its members. In order to get the
393  // down sets of all the members, start a DFT at
394  // each member. Take the union implicitly (and efficiently)
395  // by accumulating in a single result and by not
396  // resetting the _visited markers between traversals.
397 
399 
400  poset_member_iterator* itr = xanchor->member_iterator();
401  while(!itr->is_done())
402  {
403  if(!has_been_visited(itr))
404  {
405  // traverse down set of itr without resetting markers
406  traverse(itr, _in_down_set, false);
407  }
408  itr->next();
409  }
410 
411  delete itr;
412 
413  // forget pointer to anchor and result
414 
415  _anchor = 0;
416  _slice = 0;
417 
418  // Postconditions:
419 
420  ensure(invariant());
421  ensure(unexecutable(result is xmode members of union(jims of xanchor, old result)));
422 
423  // Exit
424 
425  return;
426 }
427 
428 
433 {
434  subposet* result;
435 
436  // Preconditions:
437 
438  require(has_same_host(xanchor));
439 
440  // Body:
441 
442  result = new subposet(_host);
443  down_set_pa(xanchor, result, xmode);
444 
445  // Postconditions:
446 
447  ensure(invariant());
448  ensure(has_same_host(result));
449  ensure(unexecutable(result is xmode members of down set
450  of xanchor));
451 
452  // Exit
453 
454  return result;
455 }
456 
457 
459 void
462 {
463  // Preconditions:
464 
465  require(has_same_host(xanchor));
466  require(has_same_host(result));
467 
468  // Body:
469 
470  find_pa(xanchor, 0, true, result, xmode);
471 
472  // Postconditions:
473 
474  ensure(invariant());
475  ensure(unexecutable(result is union(xmode members of down set
476  of xanchor, old result)));
477 
478  // Exit
479 
480  return;
481 }
482 
483 
488 {
489  subposet* result;
490 
491  // Preconditions:
492 
493  require(has_same_host(xanchor));
494 
495  // Body:
496 
497  result = new subposet(_host);
498  up_set_pa(xanchor, result, xmode);
499 
500  // Postconditions:
501 
502  ensure(invariant());
503  ensure(has_same_host(result));
504  ensure(unexecutable(result is xmode members of up set
505  of xanchor));
506 
507  // Exit
508 
509  return result;
510 }
511 
512 
514 void
517 {
518  // Preconditions:
519 
520  require(has_same_host(xanchor));
521  require(has_same_host(result));
522 
523  // Body:
524 
525  // find_pa(xanchor, 0, sheaf_constants::UP, result, xmode);
526  find_pa(xanchor, 0, false, result, xmode);
527 
528  // Postconditions:
529 
530  ensure(invariant());
531  ensure(unexecutable(result is xmode members of union(up set
532  of xanchor, old result)));
533 
534  // Exit
535 
536  return;
537 }
538 
539 
543 down_set(const subposet* xanchor, slice_mode xmode)
544 {
545  subposet* result;
546 
547  // Preconditions:
548 
549  require(has_same_host(xanchor));
550 
551  // Body:
552 
553  result = new subposet(_host);
554  down_set_pa(xanchor, result, xmode);
555 
556  // Postconditions:
557 
558  ensure(invariant());
559  ensure(unexecutable(result is xmode members of down set
560  of xanchor));
561 
562  // Exit
563 
564  return result;
565 }
566 
567 
569 void
571 down_set_pa(const subposet* xanchor, subposet* result, slice_mode xmode)
572 {
573  // Preconditions:
574 
575  require(has_same_host(xanchor));
576  require(has_same_host(result));
577  require(!xanchor->is_same_state(result));
578 
579  // Body:
580 
581  vertical_set_pa(xanchor, result, xmode, true);
582 
583  // Postconditions:
584 
585  ensure(invariant());
586  ensure(unexecutable(result is xmode members of union(down set
587  of xanchor, old result)));
588 
589  // Exit
590 
591  return;
592 }
593 
594 
598 up_set(const subposet* xanchor, slice_mode xmode)
599 {
600  subposet* result;
601 
602  // Preconditions:
603 
604  require(has_same_host(xanchor));
605 
606  // Body:
607 
608  result = new subposet(_host);
609  up_set_pa(xanchor, result, xmode);
610 
611  // Postconditions:
612 
613  ensure(invariant());
614  ensure(unexecutable(result is xmode members of up set
615  of xanchor));
616 
617  // Exit
618 
619  return result;
620 }
621 
622 
624 void
626 up_set_pa(const subposet* xanchor, subposet* result, slice_mode xmode)
627 {
628  // Preconditions:
629 
630  require(has_same_host(xanchor));
631  require(has_same_host(result));
632  require(!xanchor->is_same_state(result));
633 
634  // Body:
635 
636  vertical_set_pa(xanchor, result, xmode, false);
637 
638  // Postconditions:
639 
640  ensure(invariant());
641  ensure(unexecutable(result is xmode members of union(up set
642  of xanchor, old result)));
643 
644  // Exit
645 
646  return;
647 }
648 
649 
650 void
651 sheaf::poset_slicer::
652 vertical_set_pa(const subposet* xanchor, subposet* result, slice_mode xmode, bool xdown)
653 {
654  // Preconditions:
655 
656  require(has_same_host(xanchor));
657  require(has_same_host(result));
658  require(!xanchor->is_same_state(result));
659 
660  // Body:
661 
662  _layer = 0;
663  _slice = result;
664  _mode = xmode;
665  _in_down_set = xdown;
666  _select_only_shallowest = only_shallowest();
667  _select_only_deepest = only_deepest();
668  _depth_below_shallowest = -1;
669  _height_above_deepest = -1;
670 
671  // The down (up) set of a subposet is the union of the
672  // down (up) sets of its members. In order to get the
673  // down (up) sets of all the members, start a DFT at
674  // each member. Take the union implicitly (and efficiently)
675  // by accumulating in a single result and by not
676  // resetting the _visited markers between traversals.
677 
679 
680  poset_member_iterator* itr = xanchor->member_iterator();
681  while(!itr->is_done())
682  {
683  if(!has_been_visited(itr))
684  {
685  // traverse down set of itr without resetting markers
686  traverse(itr, _in_down_set, false);
687  }
688  itr->next();
689  }
690 
691  delete itr;
692 
693  // clean up
694 
695  _anchor = 0;
696  _slice = 0;
697 
698  // Postconditions:
699 
700  ensure(invariant());
701  ensure(unexecutable(result is xmode members of union(xdown set
702  of xanchor, old result)));
703 
704  // Exit
705 
706  return;
707 }
708 
709 void
710 sheaf::poset_slicer::
711 previsit_action(abstract_poset_member* xmbr)
712 {
713 
714  // Preconditions:
715 
716  require(xmbr != 0);
717  require(xmbr->is_attached());
718  require(xmbr->host() == host());
719  require(has_been_visited(xmbr));
720 
721  // Body:
722 
723  // If we are below the shallowest selected member, we're getting deeper.
724 
725  if(_depth_below_shallowest >= 0)
726  _depth_below_shallowest++;
727 
728  // We're going down, so we don't know if were above the deepest member yet.
729 
730  _height_above_deepest = -1;
731 
732  // If selecting all or shallowest, look for them on the way down
733 
734  if( ( (_mode == ALL) || (_select_only_shallowest && ( _depth_below_shallowest < 0)) ) &&
735  layer_contains_member(xmbr) )
736  {
737  // Found the shallowest member;
738  // insert it in result
739 
740  insert_member(xmbr);
741 
742  // Depth below shallowest is 0 now.
743 
744  _depth_below_shallowest = 0;
745  }
746 
747  // Postconditions:
748 
749  // Exit:
750 
751  return;
752 }
753 
754 
755 void
756 sheaf::poset_slicer::
757 link_action(abstract_poset_member* xmbr, abstract_poset_member* linked_mbr)
758 {
759 
760  // Preconditions:
761 
762  // Body:
763 
764  // If xmbr is below a shallowest member and linked_mbr
765  // has previously been accepted as a shallowest member,
766  // remove it.
767 
768  if( (_select_only_shallowest && (_depth_below_shallowest >= 0)) && slice_contains_member(linked_mbr))
769  {
770  _slice->remove_member(linked_mbr);
771  }
772  else if( (_select_only_deepest && (_height_above_deepest < 0)) && slice_contains_member(linked_mbr))
773  {
774  _height_above_deepest = 1;
775  }
776 
777  // Postconditions:
778 
779  // Exit
780 
781  return;
782 }
783 
784 
785 void
786 sheaf::poset_slicer::
787 postvisit_action(abstract_poset_member* xmbr)
788 {
789 
790  // Preconditions:
791 
792  // Body:
793 
794  // If we're below the shallowest member, we're getting shallower
795 
796  if(_depth_below_shallowest >= 0)
797  _depth_below_shallowest--;
798 
799  // If we're above the deepest member, we're getting higher.
800 
801  if(_height_above_deepest >= 0)
802  _height_above_deepest++;
803 
804  // If selecting only deepest members, look for them on the way up.
805 
806  if(_select_only_deepest && (_height_above_deepest < 0) && layer_contains_member(xmbr) )
807  {
808  // Found the deepest member;
809  // insert it in the result
810 
811  insert_member(xmbr);
812 
813  // height above deepest is 0 now
814 
815  _height_above_deepest = 0;
816  }
817 
818  // Postconditions:
819 
820  // Exit
821 
822  return;
823 }
824 
825 
826 void
828 find_pa(const block<scoped_index>& xanchor,
829  subposet* xlayer,
830  bool xdown,
831  subposet* result,
832  slice_mode xmode)
833 {
834  // Preconditions:
835 
836  require(xlayer != 0 ? has_same_host(xlayer) : true);
837  require(host()->contains_members(xanchor));
838  require(has_same_host(result));
839 
840  // Body:
841 
842  _layer = xlayer;
843  _slice = result;
844  _mode = xmode;
845  _in_down_set = xdown;
846  _select_only_shallowest = only_shallowest();
847  _select_only_deepest = only_deepest();
848  _depth_below_shallowest = -1;
849  _height_above_deepest = -1;
850 
851  // The down set of a subposet is the union of the
852  // down sets of its members. In order to get the
853  // down sets of all the members, start a DFT at
854  // each member. Take the union implicitly (and efficiently)
855  // by accumulating in a single result and by not
856  // resetting the _visited markers between traversals.
857 
859 
860  total_poset_member lanchor;
861 
862  for(int i=0; i < xanchor.ct(); i++)
863  {
864  lanchor.attach_to_state(host(), xanchor[i]);
865 
866  if(!has_been_visited(&lanchor))
867  {
868  // Traverse down set of itr without resetting markers.
869 
870  traverse(&lanchor, _in_down_set, false);
871  }
872  }
873 
874  lanchor.detach_from_state();
875 
876  // clean up
877 
878  _anchor = 0;
879  _slice = 0;
880 
881  // Postconditions:
882 
883  ensure(invariant());
884  ensure(unexecutable(result is xmode members of union(intersection(xdown set
885  of xanchor, xlayer), old result) ));
886 
887  // Exit
888 
889  return;
890 }
891 
892 
893 
894 
895 
896 
897 
898 
899 
void find_pa(abstract_poset_member *xanchor, subposet *xlayer, bool xdown, subposet *result, slice_mode xmode=ALL)
Finds the intersection of the down set (up set) of xanchor with xlayer if xdown (!xdown), pre-allocated.
poset_state_handle * host() const
The poset which this is a handle to a component of.
A client handle for a subposet.
Definition: subposet.h:86
subposet * up_set(abstract_poset_member *xanchor, slice_mode xmode=ALL)
find the up set of the poset member xanchor, auto-allocated
virtual bool invariant() const
Class invariant.
size_type ct() const
The number of items currently in use.
bool has_been_visited(const abstract_poset_member *xmbr) const
True if xmbr has been previously visited.
subposet_member_iterator * member_iterator() const
An iterator for members of this poset; handle version.
Definition: subposet.cc:912
bool _in_down_set
True if traversing down from anchor().
void traverse(const abstract_poset_member *xanchor, bool down, bool reset_markers=true)
Traverse the down set (down == true) or up set (down == false) of xanchor. If reset_markers, reset all visited markers to false before begining.
A client handle for a general, abstract partially order set.
virtual bool invariant() const
Class invariant.
Definition: poset_slicer.cc:70
virtual bool contains_member(pod_index_type xmbr_hub_id) const
True if this poset contains poset member with hub id xmbr_hub_id.
Definition: subposet.cc:955
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 mark_members_not_visited()
Sets the visited markers false for all members.
poset_slicer(const poset_state_handle *xhost)
Constructor.
Definition: poset_slicer.cc:86
subposet * find_jims(abstract_poset_member *xanchor, slice_mode xmode=ALL)
Find jims in the down set of the poset member xanchor, auto-allocated.
void find_jims_pa(abstract_poset_member *xanchor, subposet *result, slice_mode xmode=ALL)
Find jims in the down set of the poset member xanchor, pre-allocated.
subposet * down_set(abstract_poset_member *xanchor, slice_mode xmode=ALL)
find the down set of the poset member xanchor, auto-allocated
bool has_same_host(const poset_component *other) const
True if other is not void and is attached to the same host as this.
void up_set_pa(abstract_poset_member *xanchor, subposet *result, slice_mode xmode=ALL)
find the up set of the poset member xanchor, pre-allocated
virtual bool is_attached() const
True if this handle is attached to a non-void state.
virtual void insert_member(pod_index_type xmbr_hub_id)
Inserts the member of host() with hub id xmbr_hub_id.
Definition: subposet.cc:1091
abstract_poset_member * _anchor
The member which is the starting point of this traversal.
virtual void next()=0
Makes this the next member of the subset.
void down_set_pa(abstract_poset_member *xanchor, subposet *result, slice_mode xmode=ALL)
find the down set of the poset member xanchor, pre-allocated
virtual bool is_done() const =0
True if iteration finished.
~poset_slicer()
Destructor.
virtual void detach_from_state()
Detach this handle from its state, if any.
slice_mode
Include only maximal, minimal, or all members in slice.
Definition: poset_slicer.h:57
poset_state_handle * host()
The poset being traversed (mutable version).
virtual void remove_member(pod_index_type xmbr_hub_id)
Removes the member of host() with hub id xmbr_hub_id.
Definition: subposet.cc:1209
virtual subposet & jims()
The subset of all jims (mutable version)
poset_state_handle * _host
The poset being traversed.
bool is_same_state(const poset_state_handle *xother) const
True if this is attached to the same state as xother.
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.
An abstract client handle for a member of a poset.
subposet * find(abstract_poset_member *xanchor, subposet *xlayer, bool xdown, slice_mode xmode=ALL)
Finds the intersection of the down set (up set) of xanchor with xlayer if xdown (!xdown), auto-allocated.
Abstract traverser (internal iterator) for poset which traverses the cover relation graph in depth fi...
Definition: poset_dft.h:44
A client handle for an unrestricted member of a poset. A total_poset_member is guaranteed not to be r...