TreeExplorer: finish test coverage of expand+transform
This commit is contained in:
parent
9e9c6c3ec6
commit
085b304a38
3 changed files with 63 additions and 30 deletions
|
|
@ -22,11 +22,12 @@
|
|||
|
||||
/** @file iter-tree-explorer.hpp
|
||||
** Building tree expanding and backtracking evaluations within hierarchical scopes.
|
||||
** Based on the <b>Lumiera Forward Iterator</b> concept and using the basic IterAdaptor templates,
|
||||
** these components allow to implement typical evaluation strategies, like e.g. depth-first or
|
||||
** breadth-first exploration of a hierarchical structure. Since the access to this structure is
|
||||
** Based on the *Lumiera Forward Iterator* concept and using the basic IterAdaptor templates,
|
||||
** these components allow to implement typical evaluation strategies, like conditional expanding
|
||||
** or depth-first exploration of a hierarchical structure. Since the access to this structure is
|
||||
** abstracted through the underlying iterator, what we effectively get is a functional datastructure.
|
||||
** The implementation is based on the IterStateWrapper, which is one of the basic helper templates
|
||||
** The implementation is based on the idea of a "state core", which is wrapped right into the iterator
|
||||
** itself (value semantics) -- similar to the IterStateWrapper, which is one of the basic helper templates
|
||||
** provided by iter-adapter.hpp.
|
||||
**
|
||||
** @remark as of 2017, this template, as well as the initial IterExplorer (draft from 2012) can be
|
||||
|
|
@ -38,13 +39,14 @@
|
|||
** separate the _mechanics of evaluation_ from the actual logic of the target domain.
|
||||
**
|
||||
** # Iterators as Monad
|
||||
** The fundamental idea behind the implementation technique used here is the \em Monad pattern
|
||||
** known from functional programming. A Monad is a (abstract) container created by using some specific functions.
|
||||
** This is an rather abstract concept with a wide variety of applications (things like IO state, parsers, combinators,
|
||||
** The fundamental idea behind the implementation technique used here is the _Monad pattern_
|
||||
** known from functional programming. A Monad is a container holding some arbitrarily typed base value; the monad can
|
||||
** be seen as "amplifying" and enhancing the contained base value by attaching additional properties or capabilities
|
||||
** This is a rather detached concept with a wide variety of applications (things like IO state, parsers, combinators,
|
||||
** calculations with exception handling but also simple data structures like lists or trees). The key point with any
|
||||
** monad is the ability to \em bind a function into the monad; this function will work on the \em internals of the
|
||||
** monad and produce a modified new monad instance. In the simple case of a list, "binding" a function
|
||||
** basically means to map the function onto the elements in the list.
|
||||
** monad is the ability to _bind a function_ into the monad; this function will work on the _contained base values_
|
||||
** and produce a modified new monad instance. In the simple case of a list, "binding" a function basically means
|
||||
** to _map the function onto_ the elements in the list.
|
||||
**
|
||||
** ## Rationale
|
||||
** The primary benefit of using the monad pattern is to separate the transforming operation completely from
|
||||
|
|
@ -57,6 +59,22 @@
|
|||
** - and this evaluation needs to be done asynchronously and in parallel (no locking, immutable data)
|
||||
** - and a partial evaluation needs to be stored as continuation (not relying on the stack for partial results)
|
||||
**
|
||||
** # A Pipeline builder
|
||||
** Based on such concepts, structures and evaluation patterns, the TreeExplorer serves the purpose to provide
|
||||
** building blocks to assemble a _processing pipeline_, where processing will happen _on demand,_ while iterating.
|
||||
** TreeExplorer itself is both a Lumiera Forward Iterator based on some wrapped data source, and at the same time
|
||||
** it is a builder to chain up processing steps to work on the data pulled from that source. These processing steps
|
||||
** are attached as _decorators_ wrapping the source, in the order the corresponding builder functions were invoked.
|
||||
** - the _expand operation_ installs a function to consume one element and replace it by the sequence of elements
|
||||
** (``children'') produced by that _»expansion functor«_. But this expansion does not happen automatically and
|
||||
** on each element, rather it is triggered by issuing a dedicated `expandChildren()` call on the processing
|
||||
** pipeline. Thus, binding the expansion functor has augmented the data source with the ability to explore
|
||||
** some part in more detail _when required.
|
||||
** - the _transform operation_ installs a function to be mapped onto each element retrieved from the underlying source
|
||||
** - in a similar vein, the _filter operation_ binds a predicate to decide about using or discarding data
|
||||
** - in concert, expand- and transform operation allow to build hierarchy evaluation algorithms without exposing
|
||||
** any knowledge regarding the concrete hierarchy used and explored as data source.
|
||||
**
|
||||
** @todo WIP-WIP-WIP initial draft as of 11/2017
|
||||
**
|
||||
** @see IterTreeExplorer_test
|
||||
|
|
@ -229,6 +247,8 @@ namespace lib {
|
|||
}//(End) namespace iter_explorer : predefined policies and configurations
|
||||
|
||||
|
||||
|
||||
|
||||
namespace { // TreeExplorer traits
|
||||
|
||||
using meta::enable_if;
|
||||
|
|
@ -496,6 +516,8 @@ namespace lib {
|
|||
iterNext(); // consume current head element
|
||||
if (not isnil(expanded))
|
||||
expansions_.push (move(expanded));
|
||||
|
||||
SRC::expandChildren();
|
||||
}
|
||||
|
||||
/** diagnostics: current level of nested child expansion */
|
||||
|
|
|
|||
|
|
@ -572,10 +572,14 @@ namespace test{
|
|||
* in that case it might even happen that the downstream consumer does not even see the
|
||||
* items resulting from child expansion, because they are evaluated and then filtered
|
||||
* away by a transformer and filter placed in between.
|
||||
* @note a corollary of the aforementioned is the observation that having several expand
|
||||
* layers is rather not useful in practice. Due to the nested inheritance structure
|
||||
* of the assembled TreeExplorer, it is the expansion layer most on top in the chain
|
||||
* who will receive the `expandChildren()` call.
|
||||
* @note as a consequence of the flexible automatic adapting of bound functors, it is
|
||||
* possible for bound functors within different "layers" to collaborate, based on
|
||||
* additional knowledge regarding the embedded data source internals. This test
|
||||
* demonstrates a transform functor, which takes the _source iterator_ as argument
|
||||
* and invokes `it.expandChildren()` to manipulate the underlying evaluation.
|
||||
* However, since the overall evaluation is demand driven, there are inherent
|
||||
* limitations to such a setup, which bends towards fragility when leaving
|
||||
* the realm of pure functional evaluation.
|
||||
*/
|
||||
void
|
||||
verify_combinedExpandTransform()
|
||||
|
|
@ -590,13 +594,13 @@ namespace test{
|
|||
++ii;
|
||||
CHECK (8 == *ii);
|
||||
ii.expandChildren();
|
||||
cout << materialise(ii) <<endl;/////////////////////////////////TODO "8-4-2-6-4-2"
|
||||
CHECK ("6-4-2-6-4-2" == materialise(ii) );
|
||||
|
||||
|
||||
// the following contrived example demonstrates
|
||||
// how intermediary processing steps may interact
|
||||
|
||||
cout << materialise (
|
||||
CHECK (materialise (
|
||||
treeExplore(CountDown{5})
|
||||
.expand([](uint j){ return CountDown{j-1}; })
|
||||
.transform([](int v){ return 2*v; })
|
||||
|
|
@ -605,13 +609,14 @@ namespace test{
|
|||
auto elm = *it;
|
||||
if (elm == 6)
|
||||
{
|
||||
it.expandChildren();
|
||||
elm *= 10;
|
||||
it.expandChildren(); // NOTE at that point we're forced to decide if
|
||||
elm = *it * 10; // we want to return the parent or the 1st child
|
||||
}
|
||||
return elm;
|
||||
})
|
||||
.transform([](float f){ return f/2; })
|
||||
) <<endl;///////////////////////////////////////////TODO "5-4-30-1-2-1"
|
||||
.transform([](float f){ return 0.055 + f/2; })
|
||||
)
|
||||
== "5.055-4.055-20.055-1.055-2.055-1.055" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5710,7 +5710,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1512363286920" ID="ID_1420123769" MODIFIED="1512363305422" TEXT="Zusammenspiel">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1512363297486" ID="ID_531127457" MODIFIED="1512516890757" TEXT="re-evaluate">
|
||||
<node COLOR="#338800" CREATED="1512363297486" FOLDED="true" ID="ID_531127457" MODIFIED="1512521973765" TEXT="re-evaluate">
|
||||
<linktarget COLOR="#5a92a2" DESTINATION="ID_531127457" ENDARROW="Default" ENDINCLINATION="385;167;" ID="Arrow_ID_556443427" SOURCE="ID_579206895" STARTARROW="None" STARTINCLINATION="844;55;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -5719,10 +5719,11 @@
|
|||
<node CREATED="1512363380411" ID="ID_1008917631" MODIFIED="1512363473668" TEXT="expandChildren ändert aktuellen Gehalt der Quelle">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1512363397897" ID="ID_1178182932" MODIFIED="1512363487789" TEXT="aber downstream reagiert (bisher) nur auf iterate()">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1512363397897" ID="ID_1178182932" MODIFIED="1512521936459" TEXT="aber downstream reagiert (bisher) nur auf iterate()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1512363421797" ID="ID_1732504592" MODIFIED="1512363505534" TEXT="Folge: geCacheter Wert aus Transformer überdeckt">
|
||||
<node CREATED="1512363421797" ID="ID_1732504592" MODIFIED="1512521966101" TEXT="Folge: geCacheter Wert aus Transformer überdeckt">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -6247,9 +6248,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1510969031379" ID="ID_722056043" MODIFIED="1512358551383" TEXT="verify_combinedExpandTransform();">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1512363192308" ID="ID_1913090689" MODIFIED="1512363209302" TEXT="expand über Transformer hinweg">
|
||||
<node COLOR="#338800" CREATED="1510969031379" ID="ID_722056043" MODIFIED="1512521923184" TEXT="verify_combinedExpandTransform();">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1512363192308" FOLDED="true" ID="ID_1913090689" MODIFIED="1512522127007" TEXT="expand über Transformer hinweg">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1512363626338" ID="ID_1302720848" MODIFIED="1512363637547" TEXT="funktioniert out-of-the-Box">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
|
|
@ -6257,12 +6259,16 @@
|
|||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1512363210130" ID="ID_480959271" MODIFIED="1512363224156" TEXT="expand aus manipulierendem Transformer">
|
||||
<node COLOR="#338800" CREATED="1512363210130" FOLDED="true" ID="ID_480959271" MODIFIED="1512522130630" TEXT="expand aus manipulierendem Transformer">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1512363649158" ID="ID_1152388495" MODIFIED="1512363655383" TEXT="ebenso">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1512363659085" ID="ID_1079241242" MODIFIED="1512363737038" TEXT="TODO output CHECK">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1512522106792" ID="ID_1499481842" MODIFIED="1512522120926" TEXT="naja fast noch fastiger">
|
||||
<icon BUILTIN="smiley-neutral"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1512363659085" ID="ID_1079241242" MODIFIED="1512521919442" TEXT="TODO output CHECK">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1512363228751" ID="ID_579206895" MODIFIED="1512516921091" TEXT="Problem: re-evaluate nach expand">
|
||||
|
|
|
|||
Loading…
Reference in a new issue