SheafSystem  0.0.0.0
discretization_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 discretization_iterator
19 
20 #include "SheafSystem/discretization_iterator.h"
21 #include "SheafSystem/assert_contract.h"
22 #include "SheafSystem/section_space_schema_member.h"
23 #include "SheafSystem/section_space_schema_poset.h"
24 #include "SheafSystem/sec_rep_descriptor.h"
25 
26 using namespace fiber_bundle; // Workaround for MS C++ bug.
27 
31 {
32 
33  // Preconditions:
34 
35  // Body:
36 
37  initialize_order(BIORDER);
38 
39  _schema_anchor = 0;
40  _ascending_has_visited = 0;
41  _descending_has_visited = 0;
42 
43  _discretization_member_index.invalidate();
44  _evaluation_member_index.invalidate();
45 
46  // Postconditions:
47 
48  ensure(invariant());
49  ensure(!is_initialized());
50 
51  // Exit
52 
53  return;
54 }
55 
58 {
59 
60  // Preconditions:
61 
62  // Body:
63 
64  not_implemented();
65 
66  // Postconditions:
67 
68  ensure(invariant());
69 
70  // Exit
71 
72  return;
73 }
74 
77 {
78  // Preconditions:
79 
80  // Body:
81 
82  if(_schema_anchor != 0)
83  {
84  _schema_anchor->detach_from_state();
85  delete _schema_anchor;
86  }
87 
90 
91  // if(_ascending_has_visited != _has_visited)
92  // _has_visited = _descending_has_visited;
93 
94  if(_ascending_has_visited != has_visited())
95  put_has_visited(_descending_has_visited);
96 
97  if(_ascending_has_visited != 0)
98  delete _ascending_has_visited;
99 
100  // Postconditions:
101 
102 }
103 
104 bool
106 is_ancestor_of(const any* xother) const
107 {
108  bool result;
109 
110  // Preconditions:
111 
112  // Body:
113 
114  result = dynamic_cast<const discretization_iterator*>(xother) != 0;
115 
116  // Postconditions:
117 
118  // Exit
119 
120  return result;
121 }
122 
125 clone() const
126 {
127  discretization_iterator* result;
128 
129  // Preconditions:
130 
131  // Body:
132 
133  result = new discretization_iterator;
134 
135  // Postconditions:
136 
137  ensure(result != 0);
138  ensure(!result->is_initialized());
139 
140  // Exit
141 
142  return result;
143 }
144 
145 bool
147 invariant() const
148 {
149  bool result = true;
150 
151  // Preconditions:
152 
153  // Body:
154 
155  invariance(depth_first_iterator::invariant());
156 
157  if(invariant_check())
158  {
160 
161  invariance(order()==BIORDER);
162  invariance(is_initialized() ?
163  anchor().is_same_state(&(schema_anchor().base_space())) :
164  true);
165 
166  // Finished, turn invariant check back on.
167 
169  }
170 
171  // Postconditions:
172 
173  // Exit
174 
175  return result;
176 }
177 
178 // OTHER CONSTRUCTORS
179 
180 
184 {
185 
186  // Preconditions:
187 
188  require(xschema_anchor.state_is_read_accessible());
189 
190  // Body:
191 
192  initialize_order(BIORDER);
193 
194  // Set the anchor, filter, and direction
195 
196  _schema_anchor = 0;
197  put_schema_anchor(xschema_anchor);
198  reset();
199 
200  // Postconditions:
201 
202  ensure(invariant());
203  ensure(is_initialized());
204  ensure(schema_anchor().is_same_state(&xschema_anchor));
205  ensure(schema_anchor().is_same_type(&xschema_anchor));
206  ensure(descending());
207  ensure(!strict());
208  ensure(unexecutable(!is_done() implies this is first member));
209 
210  return;
211 }
212 
213 
214 // ITERATOR INTERFACE
215 
216 //$$SCRIBBLE jebutler const correctness
217 
218 bool
221 {
222  bool result;
223 
224  // Preconditions:
225 
226  // Body:
227 
228  result = depth_first_iterator::is_initialized() && (_schema_anchor != 0);
229 
230  // Postconditions:
231 
232  // Exit
233 
234  return result;
235 }
236 
237 void
240 {
241  // Preconditions:
242 
243  // Body:
244 
245  _up_set.clear();
246 
247  _discretization_member_index.invalidate();
248  _evaluation_member_index.invalidate();
249 
251 
252 
253  // Postconditions:
254 
255  ensure(invariant());
256  ensure(is_done());
257 
258  // Exit
259 
260  return;
261 }
262 
263 void
265 next(bool xtruncate)
266 {
267  // Preconditions:
268 
269  require(!is_done());
270 
271  // Body:
272 
273  bool ltruncate = xtruncate;
274 
275  // Continue traversing the graph until the traversal is done
276  // or we find a single- or multi-valued discretization point
277  // and return to the client.
278 
279  depth_first_iterator::next(ltruncate);
280 
281  while(!is_done())
282  {
283  if(action()==PREVISIT_ACTION)
284  {
285  if(_descending)
286  {
287  // Traversing down.
288 
289  if(schema_anchor().discretization().contains_member(index()))
290  {
291  // This member is a disc member
292 
293  if(schema_anchor().is_multivalued() &&
294  schema_anchor().multivalued().contains_member(index()))
295  {
296  // Multivalued is enabled and this disc member is multivalued.
297  // Reverse direction (ascend)
298 
301 
302  // _has_visited = _ascending_has_visited;
303  put_has_visited(_ascending_has_visited);
304  _descending = false;
305  ltruncate = false;
306 
307  _discretization_member_index = _index;
308 
309  }
310  else
311  {
312  // Multivalued is not enabled or this disc member is single valued.
313  // Truncate; move directly to postvisit action on this member.
314 
315  // Truncating assumes discretization is an antichain, which was originally
316  // the assumption. But that is not the case in general and there are some
317  // important pracical cases in which it is not, e.g. cells_cells_const
318  // ordinary maps, for which disc = whole. So never truncate.
319  // Note that the entire multivalued approach embodied in this class is
320  // not obsolete, replaced by multisections, and is_multivalued always returns
321  // false.
322 
323  // ltruncate = true;
324  ltruncate = false;
325  }
326  }
327  else
328  {
329  // This member is not a disc member;
330  // Do not truncate, continue descending.
331 
332  ltruncate = false;
333  }
334  }
335  else
336  {
337  // Traversing up
338 
339  _ascending_has_visited->put(index().pod(),true);
340  _up_set.push_front(index().pod());
341 
342  // If this is an eval member, we don't want to go further up; truncate.
343 
344  ltruncate = schema_anchor().evaluation().contains_member(index());
345  }
346  }
347  else if(action()==POSTVISIT_ACTION)
348  {
349  // If we invoke depth_first_iterator::next() from the postvisit action,
350  // the truncation flag will be ignored, since you can only truncate
351  // in the previsit action. But just to be specific, we'll set it false no
352  // matter what we do here.
353 
354  ltruncate = false;
355 
356  if(_descending)
357  {
358  // Traversing down
359 
360  if(schema_anchor().discretization().contains_member(index()))
361  {
362  // Postvisit of disc member while traversing down;
363  // this is a single-valued "discretization point";
364  // return to the client.
365 
366  _discretization_member_index = _index;
367 
368  break;
369  }
370  else
371  {
372  // Not a disc member; nothing to do.
373  // Continue traversal.
374  }
375  }
376  else
377  {
378  // Traversing up.
379 
380  if(schema_anchor().discretization().contains_member(index()))
381  {
382  // Postvisit of disc member while traversing up.
383  // Have finished traversal over upset of this member.
384  // Reverse direction.
385 
386  _descending = true;
387 
388  // Clear the ascending has visited markers.
389 
390  while(!_up_set.empty())
391  {
392  _ascending_has_visited->put(_up_set.front(), false);
393  _up_set.pop_front();
394  }
395 
396  // Set has visited markers to the descending has visited markers
397 
401  put_has_visited(_descending_has_visited);
402  }
403  else if(schema_anchor().evaluation().contains_member(index()))
404  {
405  // Postvisit of eval member while traversing up.
406  // This is a multi-valued "discretization point";
407  // return to the client.
408 
409  _evaluation_member_index = _index;
410 
411  break;
412  }
413  else
414  {
415  // Postvisit of neither disc nor eval member.
416  // Nothing to do; continue traversal.
417  }
418  } // end if traversing up
419  }
420  else
421  {
422  post_fatal_error_message("unrecognized action");
423  }
424 
425  depth_first_iterator::next(ltruncate);
426 
427  } // end while(!is_done())
428 
429  // Postconditions:
430 
431  ensure(invariant());
432  ensure(!is_done() ? action()==POSTVISIT_ACTION : true);
433  ensure(!is_done() ? schema_anchor().discretization().contains_member(index()) ||
434  schema_anchor().evaluation().contains_member(index()) : true);
435 
436  // Exit
437 
438  return;
439 }
440 
444 {
445  // Preconditions:
446 
447  require(is_initialized());
448 
449  // Body:
450 
451  section_space_schema_member& result = *_schema_anchor;
452 
453  // Postconditions:
454 
455  // Exit
456 
457  return result;
458 }
459 
463 {
464  // Preconditions:
465 
466  require(is_initialized());
467 
468  // Body:
469 
470  section_space_schema_member& result = *_schema_anchor;
471 
472  // Postconditions:
473 
474  // Exit
475 
476  return result;
477 }
478 
479 void
482 {
483 
484  // Preconditions:
485 
486  require(xschema_anchor.state_is_read_accessible());
487 
488  // Body:
489 
490  define_old_variable(bool old_descending = _descending);
491  define_old_variable(bool old_strict = _strict);
492 
493  // Force iterator into a known clean state;
494  // also forces client to reset before using this.
495 
496  force_is_done();
497 
498  // Now (re)initialize.
499 
500  // Set the schema anchor.
501 
502  initialize_schema_anchor(xschema_anchor);
503 
504  // Set the anchor, has_visited markes and filter..
505 
506  initialize_traversal(_schema_anchor->base_space());
507 
508  // Postconditions:
509 
510  ensure(invariant());
511  ensure(is_initialized());
512  ensure(is_done());
513  ensure(anchor().is_same_state(&(xschema_anchor.base_space())));
514  ensure(anchor().is_same_type(&(xschema_anchor.base_space())));
515  ensure(anchor().version() == xschema_anchor.base_space().version());
516  ensure(filter().index() == anchor().version_index());
517  ensure(descending() == old_descending);
518  ensure(strict() == old_strict);
519  ensure(schema_anchor().is_same_state(&xschema_anchor));
520  ensure(schema_anchor().is_same_type(&xschema_anchor));
521  ensure(schema_anchor().version() == xschema_anchor.version());
522 
523  return;
524 }
525 
526 void
528 put_schema_anchor(pod_index_type xschema_anchor_index)
529 {
530 
531  // Preconditions:
532 
533  require(is_initialized());
534  require(schema_anchor().state_is_read_accessible());
535  require(schema_anchor().host()->contains_member(xschema_anchor_index));
536 
537  // Body:
538 
539  define_old_variable(bool old_descending = _descending);
540  define_old_variable(bool old_strict = _strict);
541  define_old_variable(scoped_index old_filter_index = filter().index());
542  define_old_variable(int old_anchor_version = anchor().version());
543  define_old_variable(int old_schema_anchor_version = schema_anchor().version());
544 
545  // Force iterator into a known clean state;
546  // also forces client to reset before using this.
547 
548  force_is_done();
549 
550  // Now reinitialize.
551 
552  // Set the schema anchor.
553 
554  _schema_anchor->attach_to_state(xschema_anchor_index);
555 
556  // Set the anchor.
557 
558  initialize_traversal(_schema_anchor->base_space_id());
559 
560  // Postconditions:
561 
562  ensure(invariant());
563  ensure(is_initialized());
564  ensure(is_done());
565  ensure(anchor().index() == schema_anchor().base_space_id());
566  ensure(anchor().version() == old_anchor_version);
567  ensure(filter().index() == old_filter_index);
568  ensure(descending() == old_descending);
569  ensure(strict() == old_strict);
570  ensure(schema_anchor().index() == xschema_anchor_index);
571  ensure(schema_anchor().version() == old_schema_anchor_version);
572 
573  // Exit
574 
575  return;
576 }
577 
578 void
580 put_schema_anchor(const scoped_index& xschema_anchor_index)
581 {
582 
583  // Preconditions:
584 
585  require(is_initialized());
586  require(schema_anchor().state_is_read_accessible());
587  require(schema_anchor().host()->contains_member(xschema_anchor_index));
588 
589  // Body:
590 
591  define_old_variable(bool old_descending = _descending);
592  define_old_variable(bool old_strict = _strict);
593  define_old_variable(scoped_index old_filter_index = filter().index());
594  define_old_variable(int old_anchor_version = anchor().version());
595  define_old_variable(int old_schema_anchor_version = schema_anchor().version());
596 
597  put_schema_anchor(xschema_anchor_index.hub_pod());
598 
599  // Postconditions:
600 
601  ensure(invariant());
602  ensure(is_initialized());
603  ensure(is_done());
604  ensure(anchor().index() == schema_anchor().base_space_id());
605  ensure(anchor().version() == old_anchor_version);
606  ensure(filter().index() == old_filter_index);
607  ensure(descending() == old_descending);
608  ensure(strict() == old_strict);
609  ensure(schema_anchor().index() ==~ xschema_anchor_index);
610  ensure(schema_anchor().version() == old_schema_anchor_version);
611 
612  // Exit
613 
614  return;
615 }
616 
617 const sheaf::scoped_index&
620 {
621  return _discretization_member_index;
622 }
623 
624 const sheaf::scoped_index&
627 {
628  // Preconditions:
629 
630  require(is_multivalued());
631 
632  return _evaluation_member_index;
633 }
634 
635 bool
638 {
639  // Precondition:
640 
641  require(is_initialized());
642 
643  // Body:
644 
645  bool result = (discretization_member_index().is_valid()) &&
648 
649  // Postconditions:
650 
651  ensure(result == ((discretization_member_index().is_valid()) &&
653  schema_anchor().multivalued().contains_member(discretization_member_index())));
654 
655  // Exit
656 
657  return result;
658 }
659 
660 
661 void
664 {
665  // Preconditions:
666 
667  require(xschema_anchor.state_is_read_accessible());
668  require(is_done());
669 
670  // Body:
671 
672  // Allocate the schema anchor if needed.
673 
674  if(_schema_anchor == 0)
675  {
676  _schema_anchor = xschema_anchor.clone();
677  }
678  else if(!_schema_anchor->is_same_type(&xschema_anchor))
679  {
680  _schema_anchor->detach_from_state();
681  delete _schema_anchor;
682  _schema_anchor = xschema_anchor.clone();
683  }
684 
685  // Set the schema anchor.
686 
687  _schema_anchor->attach_to_state(&xschema_anchor);
688 
689  // Postconditions:
690 
691  // Can not ensure invariant because anchor has not been
692  // reset to base space of schema anchor yet.
693 
694  ensure(is_done());
695  ensure(_schema_anchor->is_same_state(&xschema_anchor));
696  ensure(_schema_anchor->version() == xschema_anchor.version());
697  ensure(_schema_anchor->is_same_type(&xschema_anchor));
698 
699  // Exit
700 
701  return;
702 }
703 
704 void
707 {
708  // Preconditions:
709 
710  require(xanchor.state_is_read_accessible());
711  require(is_done());
712 
713  // Body:
714 
716 
721 
722  _descending_has_visited = has_visited();
723  _ascending_has_visited = new zn_to_bool(*has_visited());
724 
725  // Postconditions:
726 
727  // ensure(_has_visited != 0);
728  // ensure(_descending_has_visited == _has_visited);
729  ensure(has_visited() != 0);
730  ensure(_descending_has_visited == has_visited());
731  ensure(_ascending_has_visited != 0);
732  ensure(is_done());
733 
734  // Exit
735 
736  return;
737 }
virtual void force_is_done()
Force the iterator to be done.
virtual void force_is_done()
Force the iterator to be done.
bool is_valid() const
True if this is a valid id.
Definition: scoped_index.h:832
int version(bool xunalias=true) const
The (possibly aliased) version of this component. The version of the host used when evaluating proper...
virtual bool is_initialized() const
True if this has been initialized for iteration with respect to a specific anchor.
virtual discretization_iterator * clone() const
Make a new instance of the same type as this.
virtual bool is_initialized() const
True if this has been initialized for iteration with respect to a specific anchor.
void initialize_order(order_type xorder)
Initializes _order and _transition_fcn.
bool empty() const
Checks if the container has no elements, i.e. whether begin() == end().
action_type action() const
The type of action the client should take when the iterator returns control to the client...
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
subposet & evaluation()
The evaluation subposet for section spaces on this schema (mutable version).
bool is_multivalued() const
Switch that tells the user if the multivalued subposet exists.
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 put(int i, bool value)
Sets i-th member to value.
Definition: zn_to_bool.cc:537
section_space_schema_member & schema_anchor()
The schema member whose base space is being iterated over; the top member of the domain of iteration ...
reference front()
Returns a reference to the first element in the container.
void put_schema_anchor(const section_space_schema_member &xschema_anchor)
Set schema_anchor() to the same state as xschema_anchor.
void next()
Makes this the next member of the subset.
void invalidate()
Make this id invalid.
Definition: scoped_index.h:852
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 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.
void pop_front()
Removes the first element of the container.
An index within the external ("client") scope of a given id space.
Definition: scoped_index.h:116
virtual void initialize_has_visited(const abstract_poset_member &xanchor)
Initializes the has_visited markers.
bool descending() const
True if iterating over down set of anchor.
void next()
Makes this the next member of the subset.
Iterator over the discretization subposet associated with a section_space_schema_member anchor...
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
virtual void initialize_has_visited(const abstract_poset_member &xanchor)
Initializes the has_visited markers.
const scoped_index & discretization_member_index() const
The current discretization member index.
const scoped_index & evaluation_member_index() const
The current evaluation member index.
bool is_done() const
True if iteration finished.
void first()
Moves this to the first member of the iteration.
bool _descending
True if iterating over the up/down set of anchor.
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...
virtual void detach_from_state()
Detach this handle from its state, if any.
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
total_poset_member & base_space()
The base space component of this (mutable version).
void push_front(const T &value)
Prepends the given element value to the beginning of the container.
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
void clear()
Removes all elements from the container.
zn_to_bool * has_visited() const
The marker bit vector. /.
bool invariant() const
The class invariant.
virtual bool is_ancestor_of(const any *other) const
True if other conforms to this.
A client handle for a poset member which has been prepared for use as a schema for a section space...
bool _strict
True if iterating over the strict up/down set of anchor.
An abstract client handle for a member of a poset.
discretization_iterator()
Default constructor; creates an unattached iterator.
bool invariant() const
The class invariant.
void initialize_schema_anchor(const section_space_schema_member &xanchor)
Initializes the schema anchor.
subposet & filter()
The subposet which is the filter; Defines what is passed, not what is blocked.
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
Namespace for the fiber_bundles component of the sheaf system.
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
virtual void attach_to_state(pod_index_type xbase_space_id, pod_index_type xfiber_schema_id)=0
Attach to the state in host() with component ids xbase_id and xfiber_schema_id.
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
bool is_multivalued() const
True, if the current discretization member is in the multivalued subposet.
bool strict() const
True if iterating over xstrict up/down set of anchor.
scoped_index _index
The index of the lesser end of the current link; the current item in the iteration.
section_space_schema_member * clone(bool xnew_state, bool xauto_access=true) const
Make a new handle instance of current. Attach the new instance to a new state if xnew_state is true...
subposet & multivalued()
The multivalued subposet for section spaces on this schema (mutable version).
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.
pod_index_type base_space_id() const
The member id of the base space component of this.