concepts.qbk 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. [/
  2. Copyright (c) 2008-2010 Joachim Faulhaber
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt)
  6. ]
  7. [section Concepts]
  8. [section Naming]
  9. The *icl* is about sets and maps and a useful
  10. implementation of sets and maps using intervals.
  11. In the documentation of the *icl* the different
  12. set and map types are grouped in various ways.
  13. In order to distinguish those groups we use
  14. a naming convention.
  15. Names of concepts start with a capital letter.
  16. So `Set` and `Map` stand for the /concept/ of
  17. a set and a map as defined in the *icl*.
  18. When we talk about `Sets` and `Maps` though,
  19. most of the time we do not not talk about the
  20. concepts themselves but the set of types
  21. that implement those concepts in the *icl*.
  22. The main groups, ['*icl containers*] can be
  23. divided in, are summarized in the next table:
  24. [table
  25. []
  26. [[] [`Set`] [`Map`] ]
  27. [[element container] [__std_set__] [__icl_map__]]
  28. [[interval container][__itv_set__, __sep_itv_set__, __spl_itv_set__][__itv_map__, __spl_itv_map__]]
  29. ]
  30. * Containers std:set, __itv_set__, __sep_itv_set__, __spl_itv_set__
  31. are models of concept `Set`.
  32. * Containers __icl_map__, __itv_map__, __spl_itv_map__
  33. are models of concept `Map`.
  34. * Containers that are ['*implemented*] using elements or element value pairs
  35. are called ['*element containers*].
  36. * Containers that are ['*implemented*] using intervals or interval value pairs
  37. (also called segments) are called ['*interval containers*].
  38. * When we talk about `Sets` or `Maps` we abstract from the way they are implemented.
  39. * When we talk about /element containers/ or /interval containers/
  40. we refer to the way they are implemented.
  41. * __std_set__ is a model of the icl's `Set` concept.
  42. * __std_map__ is ['*not*] a model of the icl's `Map` concept.
  43. * The *icl's* element map
  44. is always denoted qualified as __icl_map__
  45. to avoid confusion with`std::map`.
  46. [endsect][/ Naming]
  47. [section Aspects]
  48. There are two major ['*aspects*] or ['*views*] of icl containers. The first and predominant
  49. aspect is called __bi_conceptual__. The second and minor aspect is called __bi_iterative__.
  50. [/ table
  51. [[Aspect] [Abstraction level][] [] [Practical]]
  52. [[__Conceptual__][more abstract][concept related] [iterator independent][interval_sets(maps) can be used as sets(maps)
  53. except for element iteration.]]
  54. [[__Iterative__] [less abstract][implementation related][iterator dependent] [interval_sets(maps) iterate over intervals]]
  55. ]
  56. [table
  57. [[][__Conceptual__][__Iterative__]]
  58. [[Abstraction level][more abstract][less abstract]]
  59. [[][sequence of elements is irrelevant][sequence of elements is relevant]]
  60. [[][iterator independent][iterator dependent]]
  61. [[Informs about][membership of elements][sequence of intervals (segmentation)]]
  62. [[Equality][equality of elements][equality of segments]]
  63. [[Practical][interval_sets(maps) can be used as sets(maps)
  64. of elements(element value pairs) ]
  65. [Segmentation information is available.
  66. See e.g. [link boost_icl.examples.time_grids Time grids for months and weeks]]]
  67. ]
  68. On the __conceptual__ aspect
  69. * an `interval` implements a set of elements partially.
  70. * an __itv_set__ implements a set of elements.
  71. * an __itv_map__ implements a map of element value pairs.
  72. On the __iterative__ aspect
  73. * an __itv_set__ implements a set of intervals.
  74. * an __itv_map__ implements a map of interval value pairs.
  75. [endsect][/ Aspects]
  76. [section Sets and Maps]
  77. [h5 A Set Concept]
  78. On the __conceptual__ aspect all __itv_bsets__ are models
  79. of a concept `Set`.
  80. The `Set` concept of the Interval Template Library refers to the
  81. mathematical notion of a set.
  82. [table
  83. [[Function] [Variant][implemented as] ]
  84. [[empty set ] [] [`Set::Set()`] ]
  85. [[subset relation] [] [`bool Set::within(const Set& s1, const Set& s2)const`] ]
  86. [[equality ] [] [`bool is_element_equal(const Set& s1, const Set& s2)`]]
  87. [[set union] [inplace][`Set& operator += (Set& s1, const Set& s2)`] ]
  88. [[] [] [`Set operator + (const Set& s1, const Set& s2)`]]
  89. [[set difference] [inplace][`Set& operator -= (Set& s1, const Set& s2)`] ]
  90. [[] [] [`Set operator - (const Set& s1, const Set& s2)`]]
  91. [[set intersection][inplace][`Set& operator &= (Set& s1, const Set& s2)`] ]
  92. [[] [] [`Set operator & (const Set& s1, const Set& s2)`]]
  93. ]
  94. Equality on `Sets` is not implemented as `operator ==`, because `operator ==`
  95. is used for the stronger lexicographical equality on segments, that takes the
  96. segmentation of elements into account.
  97. Being models of concept `Set`, __icl_set__ and all __itv_bsets__
  98. implement these
  99. operations and obey the associated laws on `Sets`. See e.g.
  100. [@http://en.wikipedia.org/wiki/Algebra_of_sets an algebra of sets here].
  101. [h5 Making intervals complete]
  102. An __itv__ is considered to be a set of elements as well.
  103. With respect to the `Set` concept
  104. presented above __itv__ implements the concept only partially. The reason for
  105. that is that addition and subtraction can not
  106. be defined on __itvs__. Two intervals `[1,2]` and `[4,5]` are not addable to
  107. a ['*single*] new __itv__. In other words __itvs__ are incomplete w.r.t. union and
  108. difference. __Itv_sets__ can be defined as the ['*completion*] of intervals
  109. for the union and difference operations.
  110. When we claim that addition or subtraction can not be defined
  111. on intervals, we are not considering things like e.g.
  112. interval arithmetics, where these operations can be defined,
  113. but with a different semantics.
  114. [h5 A Map Concept]
  115. On the __conceptual__ aspect __icl_map__ and all __itv_bmaps__ are models of a
  116. concept `Map`.
  117. Since a `map` is a `set of pairs`, we try to design the `Map` concept in accordance
  118. to the `Set` concept above.
  119. [table
  120. [[Function] [Variant][implemented as] ]
  121. [[empty map ] [] [`Map::Map()`] ]
  122. [[subset relation] [] [`bool within(const Map& s2, const Map& s2)const`] ]
  123. [[equality ] [] [`bool is_element_equal(const Map& s1, const Map& s2)`]]
  124. [[map union] [inplace][`Map& operator += (Map& s1, const Map& s2)`] ]
  125. [[] [] [`Map operator + (const Map& s1, const Map& s2)`]]
  126. [[map difference] [inplace][`Map& operator -= (Map& s1, const Map& s2)`] ]
  127. [[] [] [`Map operator - (const Map& s1, const Map& s2)`]]
  128. [[map intersection][inplace][`Map& operator &= (Map& s1, const Map& s2)`] ]
  129. [[] [] [`Map operator & (const Map& s1, const Map& s2)`]]
  130. ]
  131. As one can see, on the abstract kernel the signatures of the icl's `Set` and `Map`
  132. concepts are identical, except for the typename.
  133. While signatures are identical
  134. The sets of valid laws are different, which will be described in more detail
  135. in the sections on the
  136. [link boost_icl.semantics.sets semantics of icl Sets] and
  137. [link boost_icl.semantics.maps Maps].
  138. These semantic differences are mainly based on the implementation
  139. of the pivotal member functions `add` and `subtract` for elements
  140. and intervals that again serve for implementing
  141. `operator +=` and `operator -=`.
  142. [endsect][/ Abstract Sets and Maps]
  143. [section:aggrovering Addability, Subtractability and Aggregate on Overlap]
  144. While ['*addition*] and ['*subtraction*] on `Sets`
  145. are implemented as ['*set union*] and ['*set difference*],
  146. for `Maps` we want to implement ['*aggregation*] on
  147. the associated values for the case of collision (of key elements)
  148. or overlap (of key intervals), which has been refered to as
  149. ['*aggregate on overlap*] above.
  150. This kind of `Addability` and `Subtractability` allows to compute
  151. a lot of useful aggregation results on an __itv_map_s__ associated
  152. values, just by adding and subtracting value pairs.
  153. Various examples of ['*aggregate on overlap*] are given in
  154. [link boost_icl.examples section examples].
  155. In addition, this concept of `Addability` and `Subtractability`
  156. contains the classical `Insertability` and `Erasability` of
  157. key value pairs as a special case so it provides a broader
  158. new semantics without loss of the /classical/ one.
  159. Aggregation is implemented for functions `add` and `subtract`
  160. by propagating a `Combiner` functor to combine associated values
  161. of type `CodomainT`. The standard `Combiner` is set as
  162. default template parameter
  163. `template<class>class Combine = inplace_plus`, which
  164. is again generically implemented by `operator +=` for all
  165. Addable types.
  166. For `Combine` functors, the Icl provides an __inverse__ functor.
  167. [table
  168. [[`Combine<T>`] [`inverse<Combine<T> >::type`]]
  169. [[__ip_plus__`<T>`] [__ip_minus__`<T>`] ]
  170. [[__ip_et__`<T>`] [__ip_caret__`<T>`] ]
  171. [[__ip_star__`<T>`] [__ip_slash__`<T>`] ]
  172. [[__ip_max__`<T>`] [__ip_min__`<T>`] ]
  173. [[__ip_identity__`<T>`][__ip_erasure__`<T>`]]
  174. [[`Functor`] [__ip_erasure__`<T>`]]
  175. ]
  176. The meta function __inverse__ is mutually implemented for
  177. all but the default functor `Functor`
  178. such that e.g.
  179. `inverse<inplace_minus<T> >::type` yields `inplace_plus<T>`.
  180. Not in every case, e.g. `max/min`, does the __inverse__ functor
  181. invert the effect of it's antetype. But for the default
  182. it does:
  183. [table
  184. [[] [`_add<Combine<CodomainT> >((k,x))`] [`_subtract<inverse<Combine<CodomainT> >::type>((k,x))`]]
  185. [[Instance] [`_add<inplace_plus<int> >((k,x))`] [`_subtract<inplace_minus<int> >((k,x))`]]
  186. [[Inversion][adds `x` on overlap. This inverts a preceding `subtract` of `x` on `k`][subtracts `x` on overlap. This inverts a preceding `add` of `x` on `k`]]
  187. ]
  188. As already mentioned aggregating `Addability` and `Subtractability`
  189. on `Maps` contains the /classical/ `Insertability` and `Erasability` of
  190. key value pairs as a special case:
  191. [table
  192. [[aggregating function][equivalent /classical/ function]]
  193. [[`_add<inplace_identity<CodomainT> >(const value_type&)`] [`insert(const value_type&)`]]
  194. [[`_subtract<inplace_erasure<CodomainT> >(const value_type&)`][`erase(const value_type&)`]]
  195. ]
  196. The aggregating member function templates `_add` and `_subtract`
  197. are not in the public interface of __itv_bmaps__, because
  198. the `Combine` functor is intended to be an invariant
  199. of __itv_bmap_s__
  200. template instance to avoid, that clients
  201. spoil the aggregation by accidentally calling
  202. varying aggregation functors.
  203. But you could instantiate an __itv_map__ to have
  204. `insert/erase` semantics this way:
  205. ``
  206. interval_map<int,int,partial_absorber,
  207. std::less,
  208. inplace_identity //Combine parameter specified
  209. > m;
  210. interval<int>::type itv = interval<int>::rightopen(2,7);
  211. m.add(make_pair(itv,42)); //same as insert
  212. m.subtract(make_pair(itv,42)); //same as erase
  213. ``
  214. This is, of course, only a clarifying example. Member functions
  215. `insert` and `erase` are available in __itv_bmap_s__ interface
  216. so they can be called directly.
  217. [endsect][/ Addability, Subtractability and Aggregation on Overlap]
  218. [section Map Traits]
  219. Icl maps differ in their behavior dependent on how they handle
  220. [@http://en.wikipedia.org/wiki/Identity_element ['*identity elements*]]
  221. of the associated type `CodomainT`.
  222. [h4 Remarks on Identity Elements]
  223. In the pseudo code snippets below `0` will be used to denote
  224. [@http://en.wikipedia.org/wiki/Identity_element `identity elements`],
  225. which can be
  226. different objects like `const double 0.0`, empty sets, empty strings,
  227. null-vectors etc. dependent of the instance type for parameter `CodomainT`.
  228. The existence of an ['*identity element*] wrt. an `operator+=` is a requirement
  229. for template type `CodomainT`.
  230. [table
  231. [[type] [operation] [identity element]]
  232. [[`int`] [addition] [`0`] ]
  233. [[`string`] [concatenation] [`""`] ]
  234. [[`set<T>`] [union] [`{}`] ]
  235. ]
  236. In these cases the `identity element` value is delivered by the default constructor
  237. of the maps `CodomainT` type. But there are well known exceptions
  238. like e.g. numeric multiplication:
  239. [table
  240. [[type] [operation] [identity element]]
  241. [[`int`] [multiplication] [`1`] ]
  242. ]
  243. Therefore icl functors,
  244. that serve as `Combiner` parameters of icl Maps
  245. implement a static function `identity_element()` to make
  246. sure that the correct `identity_element()` is used
  247. in the implementation
  248. of ['aggregate on overlap].
  249. ``
  250. inplace_times<int>::identity_element() == 1
  251. // or more general
  252. inplace_times<T>::identity_element() == unit_element<T>::value()
  253. ``
  254. [h4 Definedness and Storage of Identity Elements]
  255. There are two /properties/ or /traits/ of icl maps that can be
  256. chosen by a template parameter `Traits`.
  257. The ['*first trait*] relates to the ['*definedness*] of the map. Icl
  258. maps can be *partial* or *total* on the set of values given by
  259. domain type `DomainT`.
  260. * A ['*partial*] map is only defined on those key elements that have been
  261. inserted into the Map. This is usually expected and so ['*partial definedness*]
  262. is the default.
  263. * Alternatively an icl Map can be ['*total*]. It is then considered to
  264. contain a ['*neutral value*] for all key values that are not
  265. stored in the map.
  266. The ['*second trait*] is related to the representation of `identity elements` in
  267. the map. An icl map can be a ['*identity absorber*] or a ['*identity enricher*].
  268. * A ['*identity absorber*] never stores value pairs `(k,0)` that carry identity elements.
  269. * A ['*identity enricher*] stores value pairs `(k,0)`.
  270. For the template parameter `Traits` of icl Maps we have the following
  271. four values.
  272. [table
  273. [[] [identity absorber] [identity enricher]]
  274. [[partial][partial_absorber /(default)/][partial_enricher]]
  275. [[total] [total_absorber] [total_enricher]]
  276. ]
  277. [h4 Map Traits motivated]
  278. Map traits are a late extension to the *icl*. Interval maps have
  279. been used for a couple of years
  280. in a variety of applications at Cortex Software GmbH
  281. with an implementation that resembled the default trait.
  282. Only the deeper analysis of the icl's ['*aggregating Map's
  283. concept*] in the course of preparation of the library for boost
  284. led to the introduction of map Traits.
  285. [h5 Add-Subtract Antinomy in Aggregating Maps]
  286. Constitutional for the absorber/enricher propery is a little
  287. antinomy.
  288. We can insert value pairs to the map by ['*adding*] them to the map
  289. via operations `add, +=` or `+`:
  290. ``{} + {(k,1)} == {(k,1)} // addition``
  291. Further addition on common keys triggers aggregation:
  292. ``{(k,1)} + {(k,1)} == {(k,2)} // aggregation for common key k``
  293. A subtraction of existing pairs
  294. ``{(k,2)} - {(k,2)} == {(k,0)} // aggregation for common key k``
  295. yields value pairs that are associated with 0-values or `identity elements`.
  296. So once a value pair is created for a key `k` it can not be
  297. removed from the map via subtraction (`subtract, -=` or `-`).
  298. The very basic fact on sets, that we can remove what we have
  299. previously added
  300. ``x - x = {}``
  301. does not apply.
  302. This is the motivation for the ['*identity absorber*] Trait.
  303. A identity absorber map handles value pairs that carry
  304. identity elements as ['*non-existent*], which saves the law:
  305. ``x - x = {}``
  306. Yet this introduces a new problem: With such a /identity absorber/
  307. we are /by definition/ unable to store a value `(k,0)` in
  308. the map. This may be unfavorable because it is not inline with the
  309. behavior of stl::maps and this is not necessarily expected by clients
  310. of the library.
  311. [/ CL On the other hand, the notion of a identity absorbing map
  312. is more than just an akademic rescue effort for a formal law.
  313. It turns out that absorber maps have desirable properties
  314. for aggregation computations (see section semantics)
  315. that proved to be useful in practice and are in many cases
  316. just what is needed.]
  317. The solution to the problem is the introduction of the
  318. identity enricher Trait, so the user can choose a map variant
  319. according to her needs.
  320. [h5 Partial and Total Maps]
  321. The idea of a identity absorbing map is,
  322. that an ['*associated identity element*] value of a pair `(k,0)`
  323. ['*codes non-existence*] for it's key `k`.
  324. So the pair `(k,0)` immediately tunnels from
  325. a map where it may emerge into the realm
  326. of non existence.
  327. ``{(k,0)} == {}``
  328. If identity elements do not code ['*non-existence*] but
  329. ['*existence with null quantification*],
  330. we can also think of a map
  331. that has an associated identity element
  332. ['*for every*] key `k` that has no associated value
  333. different from 0.
  334. So in contrast to modelling *all* neutral
  335. value pairs `(k,0)` as being ['*non-existent*]
  336. we can model *all* neutral value pairs `(k,0)` as being
  337. ['*implicitly existent*].
  338. A map that is modelled in this way, is one large vector with
  339. a value `v` for every key `k` of it's domain type `DomainT`.
  340. But only non-identity values are actually stored.
  341. This is the motivation for the definedness-Trait on `icl Maps`.
  342. A ['*partial*] map models the intuitive view that only value
  343. pairs are existent, that are stored in the map.
  344. A ['*total*] map exploits the possibility that all
  345. value pairs that are not stored can be considered
  346. as being existent and ['*quantified*] with the identity element.
  347. [/
  348. partial existential view
  349. total quantifying view
  350. ]
  351. [h4 Pragmatical Aspects of Map Traits]
  352. From a pragmatic perspective value pairs that carry `identity elements` as
  353. mapped values can often be ignored.
  354. If we count, for instance,
  355. the number of overlaps of inserted intervals in an __itv_map__
  356. (see example [link boost_icl.examples.overlap_counter overlap counter]),
  357. most of the time, we are not
  358. interested in whether an overlap has been counted `0` times or
  359. has not been counted at all. A identity enricher map
  360. is only needed, if we want to distinct between non-existence
  361. and 0-quantification.
  362. The following distinction can *not* be made for a __pabsorber__ map
  363. but it can be made for an __penricher__ map:
  364. [pre
  365. (k,v) does not exist in the map: Pair (k,v) has NOT been dealt with
  366. (k,0) key k carries 0 : Pair (k,v) has been dealt with resulting in v=0
  367. ]
  368. Sometimes this subtle distinction is needed. Then a __penricher__
  369. is the right choice. Also, If we want to give two `icl::Maps`
  370. a common set of keys in order to, say, iterate synchronously
  371. over both maps, we need /enrichers/.
  372. [endsect] [/ Map Traits]
  373. [endsect][/ Concepts]