Chain-Load: rework the pattern for dynamic rules

...as it turns out, the solution embraced first was the cleanest way
to handle dynamic configuration of parameters; just it did not work
at that time, due to the reference binding problem in the Lambdas.
Meanwhile, the latter has been resolved by relying on the LazyInit
mechanism. Thus it is now possible to abandon the manipulation by
side effect and rather require the dynamic rule to return a
''pristine instance''.

With these adjustments, it is now possible to install a rule
which expands only for some kinds of nodes; this is used here
to crate a starting point for a **reduction rule** to kick in.
This commit is contained in:
Fischlurch 2023-11-30 02:13:39 +01:00
parent 3d5fdce1c7
commit aafd277ebe
6 changed files with 359 additions and 134 deletions

View file

@ -48,11 +48,11 @@
** transformations. A wide array of function signatures can be accepted, as long as it is possible
** somehow to _adapt_ those functions to conform to the overall scheme as defined by the Policy base.
** Such a mapping function can be given directly at construction, or it can be set up later through
** the configuration DSL. As a special twist, it is even possible to bind a function to _manipulate_
** the actual instance of RandomDraw dynamically. Such a function takes `RandomDraw&` as first
** argument, plus any sequence of further arguments which can be adapted from the overall input;
** it is invoked prior to evaluating each input value and can tweak the instance by side-effect.
** After that, the input value is passed to the adapted instance.
** the configuration DSL. As a special twist, it is even possible to change parameters dynamically,
** based on the current input value. This requires the mapping function to construct a pristine
** instance of RandomDraw, apply configuration based on the input and then return this instance
** by value without ever »engaging« and invoking; this dynamically configured instance will
** then be invoked once, passing the current input values to yield the result value.
**
** ## Policy template
** For practical use, the RandomDraw template must be instantiated with a custom provided
@ -344,17 +344,6 @@ namespace lib {
private:
/// metafunction: the given function wants to manipulate `*this` dynamically
template<class SIG>
struct is_Manipulator
: std::false_type { };
template<typename...ARGS>
struct is_Manipulator<void(RandomDraw&, ARGS...)>
: std::true_type { };
/** @internal adapt a function and install it to control drawing and mapping */
template<class FUN>
void
@ -383,10 +372,6 @@ namespace lib {
if constexpr (std::is_same_v<Args, BaseIn>)
// function accepts same arguments as this RandomDraw
return forward<FUN> (fun); // pass-through directly
else
if constexpr (is_Manipulator<Sig>())
// function wants to manipulate *this dynamically...
return adaptIn (applyFirst (forward<FUN> (fun), *this));
else
{// attempt to find a custom adaptor via Policy template
using Adaptor = typename POL::template Adaptor<Sig>;
@ -398,9 +383,9 @@ namespace lib {
* - a function producing the overall result-type is installed as-is
* - a `size_t` result is assumed be a hash and passed into #drawLimited
* - likewise a `double` is assumed to be already a random val to be #limited
* - special treatment is given to a function with `void` result, which is assumed
* to perform some manipulation on this RandomDraw instance by side-effect;
* this allows to changes parameters dynamically, based on the input data.
* - special treatment is given to a function returning a `RandomDraw` instance
* by value; such a function is assumed to set some parametrisation based
* on the input data, allowing to change parameters dynamically.
* @return adapted function which produces a result value of type #Tar
*/
template<class FUN>
@ -426,36 +411,17 @@ namespace lib {
,[this](double rand){ return limited(rand); }
);
else
if constexpr (std::is_same_v<Res, void>) // ◁────────────────────────┨ function manipulates parameters by side-effect
return [functor=std::forward<FUN>(fun)
,processDraw=getCurrMapping()]
if constexpr (std::is_same_v<Res, RandomDraw>) // ◁───────────────────┨ RandomDraw with dynamically adjusted parameters
return [functor=std::forward<FUN>(fun)]
(auto&& ...inArgs) -> _FunRet<RandomDraw>
{
functor(inArgs...); // invoke manipulator with copy
return processDraw (forward<decltype(inArgs)> (inArgs)...);
}; // forward arguments to mapping-fun
{ // invoke manipulator with copy
RandomDraw adaptedDraw = functor(inArgs...);
return adaptedDraw (forward<decltype(inArgs)> (inArgs)...);
}; // forward arguments to mapping-fun
else
static_assert (not sizeof(Res), "unable to adapt / handle result type");
NOTREACHED("Handle based on return type");
}
/** @internal capture the current mapping processing-chain as function.
* RandomDraw is-a function to process and map the input argument into a
* limited and quantised output value. The actual chain can be re-configured.
* This function picks up a snapshot copy of the current configuration; it is
* used to build a chain of functions, which incorporates this current function.
* If no function was configured yet, the default processing chain is returned.
*/
Fun
getCurrMapping()
{
Fun& currentProcessingFunction = *this;
if (currentProcessingFunction)
return Fun{currentProcessingFunction};
else
return Fun{adaptOut(POL::defaultSrc)};
}
};

View file

@ -65,7 +65,7 @@ namespace test{
~Transiently()
{
manipulated_ = originalVal_;
manipulated_ = std::move (originalVal_);
}
template<typename X>

View file

@ -723,32 +723,24 @@ namespace test{
CHECK (d2( 8) == 0);
CHECK (d2( 9) == 0);
CHECK (d2(10) == 0);
// NOTE: once a custom mapping function has been installed,
// the object can no longer be moved, due to reference binding.
VERIFY_ERROR (LIFECYCLE, Draw dx{move(d2)} );
}
/** @test change the generation profile dynamically
* - a »manipulator function« gets the current RandomDraw instance,
* and any arguments that can generally be adapted for mapping functions;
* it uses these arguments to manipulate the state before each new invocation;
/** @test change the generation profile dynamically, based on current input;
* in the example here, the probability is manipulated in each cycle.
* - a »manipulator function« can be installed on top of any existing configuration,
* including another custom mapping function; in the example here, we first install
* a custom mapping for the hash values, to change the cycle to 4 steps only. Then,
* in a second step, a »manipulator« is installed on top, this time accepting the
* raw hash value and manipulating the minValue. After the manipulator was invoked,
* the RandomDraw instance will be evaluated through the mapping-chain present
* prior to installation of the »manipulator« in this case, still the mapping
* to change the cycle to 4 steps length; so in the result, the minValue is
* increased in each cycle.
*/
void
verify_dynamicChange()
{
auto d1 = Draw([](Draw& draw, uint cycle, uint)
{ // manipulate the probability
draw.probability((cycle+1)*0.25);
auto d1 = Draw([](uint cycle, uint)
{ // dynamically control probability
return Draw().probability((cycle+1)*0.25);
});
CHECK (d1( 0) == 0);
@ -788,50 +780,6 @@ namespace test{
CHECK (d1(128+64+56) == -1);
CHECK (d1(128+64+63) == -1);
CHECK (d1(128+64+64) == 1);
// NOTE: once a custom mapping function has been installed,
// the object can no longer be moved, due to reference binding.
VERIFY_ERROR (LIFECYCLE, Draw dx{move(d1)} );
auto d2 = Draw([](size_t hash)
{ // change cycle 4 steps only
return fmod (hash/4.0, 1.0);
});
CHECK (d2( 0) == +1); // 1st cycle
CHECK (d2( 1) == +2);
CHECK (d2( 2) == -2);
CHECK (d2( 3) == -1);
CHECK (d2( 4) == +1); // 2nd cycle
CHECK (d2( 5) == +2);
CHECK (d2( 6) == -2);
CHECK (d2( 7) == -1);
CHECK (d2( 8) == +1); // 3rd cycle
CHECK (d2( 9) == +2);
CHECK (d2(10) == -2);
CHECK (d2(11) == -1);
CHECK (d2(12) == +1);
d2.mapping([](Draw& draw, size_t hash)
{ // manipulate the minVal per cycle
int cycle = hash / 4;
draw.minVal(-2+cycle);
});
CHECK (d2( 0) == +1); // 1st cycle -> minVal ≡ -2
CHECK (d2( 1) == +2);
CHECK (d2( 2) == -2);
CHECK (d2( 3) == -1);
CHECK (d2( 4) == +1); // 2nd cycle -> minVal ≡ -1
CHECK (d2( 5) == +1);
CHECK (d2( 6) == +2);
CHECK (d2( 7) == -1);
CHECK (d2( 8) == +1); // 3rd cycle -> minVal ≡ 0
CHECK (d2( 9) == +1);
CHECK (d2(10) == +2);
CHECK (d2(11) == +2);
CHECK (d2(12) == +1);
}
};

View file

@ -298,9 +298,6 @@ namespace test {
CHECK (stat.indicators[STAT_JOIN].pL == "0.78378378"_expect); // but also almost one join per level to deal with the limitation
CHECK (stat.indicators[STAT_FORK].frac == "0.24609375"_expect); // 25% forks (there is just not enough room for more forks)
CHECK (stat.indicators[STAT_JOIN].frac == "0.11328125"_expect); // and 11% joins
//SHOW_EXPR(graph.getHash())
//SHOW_EXPR(stat.indicators[STAT_NODE].pL)
//SHOW_EXPR(stat.indicators[STAT_JOIN].cL)
}
@ -312,8 +309,27 @@ namespace test {
void
verify_Reduction()
{
ChainLoad32 graph;
// moderate symmetrical expansion with 40% probability and maximal +2 links
graph.expansionRule(graph.rule().mapping([&](Node* n)
{
if (isStart(n))
return graph.rule().probability(1.0).maxVal(8).mapping([](size_t){ return 1.0; });
else
return graph.rule();
}))
.reductionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555))
.buildToplolgy()
.printTopologyDOT()
.printTopologyStatistics()
;
// CHECK (graph.getHash() == 0xAE332109116C5100);
SHOW_EXPR(graph.getHash())
}
//SHOW_EXPR(graph.getHash())
//SHOW_EXPR(stat.indicators[STAT_NODE].pL)
//SHOW_EXPR(stat.indicators[STAT_JOIN].cL)

View file

@ -47,12 +47,13 @@
** configurable _control functions_ driven by each node's (hash)value. This way, each node
** can optionally fork out to several successor nodes, but can also reduce and combine its
** predecessor nodes; additionally, new chains can be spawned (to simulate the effect of
** data loading Jobs without predecessor). The computation always begins with the _root
** node_, proceeds over the node links and finally leads to the _top node,_ which connects
** all chains of computation, leaving no dead end. The probabilistic rules controlling the
** topology can be configured using the lib::RandomDraw component, allowing either just
** to set a fixed probability or to define elaborate dynamic configurations based on the
** graph height or node connectivity properties.
** data loading Jobs without predecessor) and chains can be deliberately pruned, possibly
** splitting the computation into several disjoint sub-graphs. Anyway, the computation always
** begins with the _root node_, proceeds over the node links and finally connects any open
** chains of computation to the _top node,_ leaving no dead end. The probabilistic rules
** controlling the topology can be configured using the lib::RandomDraw component, allowing
** either just to set a fixed probability or to define elaborate dynamic configurations
** based on the graph height or node connectivity properties.
**
** ## Usage
** A TestChainLoad instance is created with predetermined maximum fan factor and a fixed
@ -80,7 +81,7 @@
#include "vault/common.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/test/transiently.hpp"
//#include "vault/gear/job.h"
//#include "vault/gear/activity.hpp"
@ -127,6 +128,7 @@ namespace test {
using util::toString;
using util::showHashLSB;
using lib::meta::_FunRet;
using lib::test::Transiently;
// using std::forward;
// using std::string;
@ -348,6 +350,9 @@ namespace test {
/**
* Use current configuration and seed to (re)build Node connectivity.
* While working in-place, the wiring and thus the resulting hash values
* are completely rewritten, progressing from start and controlled by
* evaluating the _drawing rules_ on the current node, computing its hash.
*/
TestChainLoad&&
buildToplolgy()
@ -358,11 +363,11 @@ namespace test {
Node* node = &nodes_->front();
size_t level{0};
// local copy of all rules (non-copyable, once engaged)
Rule expansionRule = expansionRule_;
Rule reductionRule = reductionRule_;
Rule seedingRule = seedingRule_;
Rule pruningRule = pruningRule_;
// transient snapshot of rules (non-copyable, once engaged)
Transiently originalExpansionRule{expansionRule_};
Transiently originalReductionRule{reductionRule_};
Transiently originalseedingRule {seedingRule_};
Transiently originalPruningRule {pruningRule_};
// prepare building blocks for the topology generation...
auto moreNext = [&]{ return next->size() < maxFan; };
@ -392,10 +397,10 @@ namespace test {
for (Node* o : *curr)
{ // follow-up on all Nodes in current level...
o->calculate();
if (apply (pruningRule,o))
if (apply (pruningRule_,o))
continue; // discontinue
size_t toSeed = apply (seedingRule, o);
size_t toExpand = apply (expansionRule,o);
size_t toSeed = apply (seedingRule_, o);
size_t toExpand = apply (expansionRule_,o);
while (0 < toSeed and spaceLeft())
{ // start a new chain from seed
addNode(this->getSeed());
@ -410,7 +415,7 @@ namespace test {
if (not toReduce)
{ // carry-on chain from o
r = spaceLeft()? addNode():nullptr;
toReduce = apply (reductionRule, o);
toReduce = apply (reductionRule_, o);
}
else
--toReduce;

View file

@ -96233,6 +96233,40 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700239873583" ID="ID_108514069" MODIFIED="1701226056299" TEXT="Reduction">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1701288030605" ID="ID_1831978324" MODIFIED="1701288052215" TEXT="Reduction braucht zur Wirksamkeit bereits bestehende Expansion">
<node CREATED="1701288078679" ID="ID_1660308998" MODIFIED="1701288100383" TEXT="das w&#xe4;re dann wohl im Gegenspiel mit einer Expansion-Rule zu sehen"/>
<node CREATED="1701288101212" ID="ID_1431953126" MODIFIED="1701288125016" TEXT="oder man injiziert punktweise eine Verbreiterung">
<icon BUILTIN="idea"/>
<node CREATED="1701288126724" ID="ID_760448320" MODIFIED="1701288137034" TEXT="wie ganz konkret?"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1701288140416" ID="ID_999842267" MODIFIED="1701288181028">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
das bedingt eine<i>&#160;dynamische Regel</i>
</p>
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701288184464" ID="ID_1197288734" MODIFIED="1701304078220" TEXT="konkret einsetzen &#x2014; ist immer noch schwierig">
<arrowlink COLOR="#dc1c4c" DESTINATION="ID_247521707" ENDARROW="Default" ENDINCLINATION="138;-456;" ID="Arrow_ID_1575949835" STARTARROW="None" STARTINCLINATION="299;17;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node COLOR="#338800" CREATED="1701303968882" ID="ID_245626902" MODIFIED="1701304004316">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
mit Abstrichen: <i>jetzt l&#228;ufts...</i>
</p>
</body>
</html></richcontent>
<linktarget COLOR="#738e9c" DESTINATION="ID_245626902" ENDARROW="Default" ENDINCLINATION="347;32;" ID="Arrow_ID_110894165" SOURCE="ID_1512181041" STARTARROW="None" STARTINCLINATION="-337;15;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700239880388" ID="ID_897183253" MODIFIED="1701226056300" TEXT="Seed">
<icon BUILTIN="flag-yellow"/>
@ -96795,7 +96829,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1700490465981" ID="ID_95937370" MODIFIED="1700490485279" TEXT="der Nutzer bekommt eine builder-DSL auf dem resultierenden, spezialisierten Typ"/>
</node>
</node>
<node COLOR="#11660e" CREATED="1700491763307" FOLDED="true" ID="ID_1225692248" MODIFIED="1701023762914">
<node COLOR="#11660e" CREATED="1700491763307" FOLDED="true" ID="ID_1225692248" MODIFIED="1701297183498">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -98164,6 +98198,57 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1701298245500" FOLDED="true" ID="ID_1820632939" MODIFIED="1701303761341" TEXT="konfigurieren &#x27f7; anwenden &#x27f7; manipulieren">
<linktarget COLOR="#fd331b" DESTINATION="ID_1820632939" ENDARROW="Default" ENDINCLINATION="-47;355;" ID="Arrow_ID_884616087" SOURCE="ID_424443394" STARTARROW="None" STARTINCLINATION="-66;-1;"/>
<linktarget COLOR="#fd1694" DESTINATION="ID_1820632939" ENDARROW="Default" ENDINCLINATION="-121;412;" ID="Arrow_ID_1621910960" SOURCE="ID_130492324" STARTARROW="None" STARTINCLINATION="345;-30;"/>
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701299338958" ID="ID_1360469633" MODIFIED="1701299360186" TEXT="in vollem Umfang ist das mit diesem Design unm&#xf6;glich">
<icon BUILTIN="yes"/>
<node CREATED="1701299382506" ID="ID_1145407722" MODIFIED="1701299394276">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
es ist zu <i>&#187;funktional&#171;</i>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1701299395182" ID="ID_1791740031" MODIFIED="1701299414728" TEXT="man m&#xfc;&#xdf;te einen semantischen Marker erhalten"/>
<node CREATED="1701299435649" ID="ID_798812447" MODIFIED="1701299452689" TEXT="also eine Trennung von Spec, Initialisierung und fertigem Funktor">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1701299454295" ID="ID_1369025351" MODIFIED="1701299468014" TEXT="das sollte ich mir als &#xbb;lessons learned&#xab; f&#xfc;r die Zukunft merken">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1701299646685" ID="ID_1765757565" MODIFIED="1701303745018">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
<u>konkret hilft mir</u>:
</p>
<p>
die &#187;Manipulation&#171; kann <i>per Definitionem</i>
</p>
<p>
auf einem leeren Objekt statfinden...
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
vom konkreten use-Case her gedacht, ist es typischerweise gar nicht hilfreich, wenn das zu manipulierende Objekt schon &#187;Zustand&#171; hat; man schafft viel klarere Verh&#228;ltnisse, wenn es <b>per Definition</b>&#160;ein default-konstruiertes Objekt ist
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1700577811739" ID="ID_1356052727" MODIFIED="1700623391805" TEXT="Konfigurations-DSL aufbauen">
@ -98195,8 +98280,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#435e98" CREATED="1700666732810" ID="ID_275616933" MODIFIED="1700713863719" TEXT="Konstruktions-Problem: wie kommt der Funktor an die aktuelle Instanz?">
<icon BUILTIN="messagebox_warning"/>
<node COLOR="#5b280f" CREATED="1700666796282" FOLDED="true" ID="ID_400868539" MODIFIED="1700713852964" TEXT="L&#xf6;sung-1: gar nicht. Er baut eine neue Instanz">
<node COLOR="#435e98" CREATED="1700666796282" ID="ID_400868539" MODIFIED="1701301129800" TEXT="L&#xf6;sung-1: gar nicht. Er baut eine neue Instanz">
<icon BUILTIN="button_cancel"/>
<icon BUILTIN="forward"/>
<node CREATED="1700666822918" ID="ID_1578832431" MODIFIED="1700666830593" TEXT="auf die L&#xf6;sung bin ich zun&#xe4;chst verfallen"/>
<node CREATED="1700666831243" ID="ID_273291815" MODIFIED="1700666840360" TEXT="sie ist zwar etwas komisch zu verdrahten"/>
<node CREATED="1700666841204" ID="ID_1310803138" MODIFIED="1700666848911" TEXT="aber geht schon mal durch den Compiler"/>
@ -98221,6 +98307,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1701301093185" ID="ID_586926454" MODIFIED="1701301254164" TEXT="nach &#xdc;berarbeitung (LazyInit) &#x27f9; das ist doch die beste L&#xf6;sung">
<linktarget COLOR="#4a61b9" DESTINATION="ID_586926454" ENDARROW="Default" ENDINCLINATION="-232;10;" ID="Arrow_ID_1046391060" SOURCE="ID_830016552" STARTARROW="None" STARTINCLINATION="140;8;"/>
<icon BUILTIN="yes"/>
<node CREATED="1701301143698" ID="ID_1026219449" MODIFIED="1701301177541" TEXT="mit einem neuen Dreh: darf noch nicht &#xbb;engaged&#xab; sein"/>
<node CREATED="1701301199310" ID="ID_1057614214" MODIFIED="1701301210694" TEXT="also default-konstruiert"/>
</node>
</node>
<node CREATED="1700667123763" FOLDED="true" ID="ID_360972195" MODIFIED="1700713850120">
<richcontent TYPE="NODE"><html>
@ -98262,8 +98354,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="hourglass"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1700667358039" FOLDED="true" ID="ID_1159388516" MODIFIED="1700713921748" TEXT="L&#xf6;sung:3 er nimmt diese als Ref-Argument">
<node COLOR="#5b280f" CREATED="1700667358039" FOLDED="true" ID="ID_1159388516" MODIFIED="1701301315106" TEXT="L&#xf6;sung-3: er nimmt diese als Ref-Argument">
<icon BUILTIN="forward"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1700667395811" ID="ID_1168097310" MODIFIED="1700667512459">
<richcontent TYPE="NODE"><html>
<head/>
@ -98380,6 +98473,78 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#5b280f" CREATED="1701301019815" ID="ID_805863162" MODIFIED="1701301045953" TEXT="funktioniert gut &#x2014; ist aber nicht praktikabel">
<icon BUILTIN="closed"/>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1701297752921" FOLDED="true" ID="ID_859980593" MODIFIED="1701303780926">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
dynamische Manipulation<i>&#160;versaut <font face="Monospaced" color="#820cbf">this</font></i>
</p>
</body>
</html></richcontent>
<linktarget COLOR="#925370" DESTINATION="ID_859980593" ENDARROW="Default" ENDINCLINATION="-722;53;" ID="Arrow_ID_508102553" SOURCE="ID_1970553199" STARTARROW="None" STARTINCLINATION="342;-486;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1701297919739" ID="ID_1344551860" MODIFIED="1701297952473" TEXT="der zus&#xe4;tzliche 1.Parameter wird per Referenz an *this gebunden"/>
<node CREATED="1701297953759" ID="ID_986118532" MODIFIED="1701297984590" TEXT="wir m&#xfc;ssen aber das manipulierte *this zur Ergebnis-Ermittlung aufrufen"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1701297986010" ID="ID_1806764026" MODIFIED="1701298005576" TEXT="dieser Aufruf darf nicht erneut in die dynamische selbst-Manipulation laufen">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1701298008255" ID="ID_1603437465" MODIFIED="1701298031784" TEXT="sonst Stackoverflow-TOD"/>
<node CREATED="1701302314721" ID="ID_588221563" MODIFIED="1701302324524" TEXT="ich hab nur ein Funktions-Interface vorgesehen"/>
<node CREATED="1701302325463" ID="ID_425170421" MODIFIED="1701302375268" TEXT="und dies kann nur Eines machen: entweder manipulieren, oder Rechnen"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701298048418" ID="ID_195441633" MODIFIED="1701298131579" TEXT="das hei&#xdf;t: irgend eine Instanz mu&#xdf; kopiert werden">
<icon BUILTIN="clanbomber"/>
<node CREATED="1701298474511" ID="ID_1270719930" MODIFIED="1701298563428" TEXT="Instanz &#x27fc; innere Kopie zur Anwendung">
<icon BUILTIN="full-1"/>
<node CREATED="1701298506437" ID="ID_1149471063" MODIFIED="1701298576807" TEXT="innere Kopie manipulieren">
<icon BUILTIN="full-3"/>
</node>
<node CREATED="1701298514992" ID="ID_1935475450" MODIFIED="1701298579279" TEXT="auf innerer Kopie die Anwendung ausf&#xfc;hren">
<icon BUILTIN="full-4"/>
</node>
<node CREATED="1701298606503" ID="ID_461232980" MODIFIED="1701302415432" TEXT="Ergebnis nach au&#xdf;en durchreichen">
<arrowlink COLOR="#88fe21" DESTINATION="ID_1514969621" ENDARROW="Default" ENDINCLINATION="82;5;" ID="Arrow_ID_1957797667" STARTARROW="None" STARTINCLINATION="-11;70;"/>
<icon BUILTIN="full-5"/>
</node>
</node>
<node CREATED="1701298533974" ID="ID_390102291" MODIFIED="1701298573321" TEXT="Instanz an Manipulationsfunktion binden">
<icon BUILTIN="full-2"/>
</node>
<node CREATED="1701298590273" ID="ID_1514969621" MODIFIED="1701302415432" TEXT="Manipulationsfunktion mu&#xdf; Ergebnis liefern">
<linktarget COLOR="#88fe21" DESTINATION="ID_1514969621" ENDARROW="Default" ENDINCLINATION="82;5;" ID="Arrow_ID_1957797667" SOURCE="ID_461232980" STARTARROW="None" STARTINCLINATION="-11;70;"/>
<icon BUILTIN="full-5"/>
</node>
<node BACKGROUND_COLOR="#efe9a7" COLOR="#c80b2b" CREATED="1701298132446" ID="ID_424443394" MODIFIED="1701300933488" TEXT="(&#x27f6; back to square one)">
<arrowlink COLOR="#fd331b" DESTINATION="ID_1820632939" ENDARROW="Default" ENDINCLINATION="-47;355;" ID="Arrow_ID_884616087" STARTARROW="None" STARTINCLINATION="-66;-1;"/>
<arrowlink COLOR="#fd331b" DESTINATION="ID_130492324" ENDARROW="Default" ENDINCLINATION="380;-27;" ID="Arrow_ID_1549798992" STARTARROW="None" STARTINCLINATION="-178;18;"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1701298903567" HGAP="32" ID="ID_751425030" MODIFIED="1701299794687" TEXT="kann nichst zuverl&#xe4;ssig kopieren (wenn bereits &#xbb;engaged&#xab;)" VSHIFT="18"/>
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1701299771781" ID="ID_522345672" MODIFIED="1701300893893" TEXT="einziger Freiheitsgrad: die Innnere Kopie kann &#xbb;pristine&#xab; sein">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1701300953519" ID="ID_1483996205" MODIFIED="1701303643004" TEXT="&#xfc;berarbeitetetes Schema f&#xfc;r Manipulation">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1701301225512" ID="ID_830016552" MODIFIED="1701303640076" TEXT="l&#xe4;uft jetzt auf eine Variante von L&#xf6;sung-1 hinaus...">
<arrowlink COLOR="#4a61b9" DESTINATION="ID_586926454" ENDARROW="Default" ENDINCLINATION="-232;10;" ID="Arrow_ID_1046391060" STARTARROW="None" STARTINCLINATION="140;8;"/>
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701302425302" ID="ID_1784095576" MODIFIED="1701302459030" TEXT="damit f&#xe4;llt die M&#xf6;glichkeit f&#xfc;r kaskadierte Mappings weg">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1701302851616" ID="ID_705421029" MODIFIED="1701303636565" TEXT="Code wird deutlich einfacher">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1701303614369" ID="ID_1891401017" MODIFIED="1701303628905" TEXT="verh&#xe4;lt sich korrekt">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
@ -98516,7 +98681,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700240183293" ID="ID_1092101612" MODIFIED="1701023918045" TEXT="Regel-Baukasten">
<linktarget COLOR="#5a509e" DESTINATION="ID_1092101612" ENDARROW="Default" ENDINCLINATION="8;265;" ID="Arrow_ID_362060244" SOURCE="ID_1931960006" STARTARROW="None" STARTINCLINATION="415;-28;"/>
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700770889303" FOLDED="true" ID="ID_1475798694" MODIFIED="1700969773151" TEXT="Non-copyable Rules &#x2014; problematisch f&#xfc;r DSL">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700770889303" FOLDED="true" ID="ID_1475798694" MODIFIED="1701304070735" TEXT="Non-copyable Rules &#x2014; problematisch f&#xfc;r DSL">
<icon BUILTIN="messagebox_warning"/>
<node COLOR="#5b280f" CREATED="1700770943791" ID="ID_1199767820" MODIFIED="1700770980394" TEXT="sie m&#xfc;ssen non-copyable sein wegen internem Function-binding">
<icon BUILTIN="broken-line"/>
@ -98538,7 +98703,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="idea"/>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#437298" CREATED="1700969491009" FOLDED="true" ID="ID_1984571390" MODIFIED="1700969900504">
<node COLOR="#437298" CREATED="1700969491009" FOLDED="true" ID="ID_1984571390" MODIFIED="1701304068011">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -98579,9 +98744,134 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...da RandomDraw jetzt so wunderbar elegant kopierbar ist...
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#4575ad" DESTINATION="ID_508651287" ENDARROW="Default" ENDINCLINATION="24;-48;" ID="Arrow_ID_1906631092" STARTARROW="None" STARTINCLINATION="-135;6;"/>
</node>
<node CREATED="1700969673859" ID="ID_1388522888" MODIFIED="1700969690306" TEXT="...da RandomDraw jetzt so wunderbar elegant kopierbar ist..."/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701287975965" FOLDED="true" ID="ID_1183256451" MODIFIED="1701304055910" TEXT="...leider ist damit das Problem nur verschoben">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1701287997534" ID="ID_247521707" MODIFIED="1701288227256" TEXT="...und zwar ist jetzt die M&#xf6;glichkeit dynamischer Modifikation abgeschnitten">
<linktarget COLOR="#dc1c4c" DESTINATION="ID_247521707" ENDARROW="Default" ENDINCLINATION="138;-456;" ID="Arrow_ID_1575949835" SOURCE="ID_1197288734" STARTARROW="None" STARTINCLINATION="299;17;"/>
<icon BUILTIN="broken-line"/>
</node>
<node CREATED="1701289062860" ID="ID_1839120736" MODIFIED="1701289218722" TEXT="dynamische Manipulationen haben einen verschleppten Seiteneffekt, wirken aber nicht">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...w&#228;hrend der Berechnung der Topologie (und das ist die einzige tats&#228;chliche Verwendung der Regeln) arbeiten wir auf lokalen Kopien; eine dynamische &#196;nderung aus der Berechnung heraus hinterl&#228;&#223;t Spuren in der <i>&#187;schwebenden&#171; </i>globalen Regelkonfiguration &#8212; dringt aber grade <i>nicht in die aktivierte Regel-Konfiguration durch.</i>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1701289396695" FOLDED="true" ID="ID_1788063535" MODIFIED="1701303956839" TEXT="sollte es vielleicht genau anders herum sein??">
<icon BUILTIN="idea"/>
<node CREATED="1701289434395" ID="ID_542027357" MODIFIED="1701289452996" TEXT="also wirken &#x2014; aber keine Seiteneffekte hinterlassen?"/>
<node CREATED="1701289485284" ID="ID_1285884711" MODIFIED="1701289501070" TEXT="demnach m&#xfc;&#xdf;ten transient die Rollen vertauscht werden"/>
<node CREATED="1701290070366" ID="ID_1282551984" MODIFIED="1701290080201" TEXT="daf&#xfc;r geeigneter Mechanismus?">
<node CREATED="1701290081821" ID="ID_930381290" MODIFIED="1701290089063" TEXT="klar: es mu&#xdf; ein smart-Handle sein"/>
<node CREATED="1701290089595" ID="ID_1315264416" MODIFIED="1701290102243" TEXT="neulich habe ich das TRANSIENTLY gebaut">
<icon BUILTIN="idea"/>
<node CREATED="1701290121303" ID="ID_250102555" MODIFIED="1701290149289">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
das macht <i>fast genau </i>das hier Ben&#246;tigte
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1701290152867" ID="ID_339962379" MODIFIED="1701290159673" TEXT="ist aber als Test-Tool aufgestellt">
<node CREATED="1701290284560" ID="ID_542573347" MODIFIED="1701290294028" TEXT="sitzt im test-Namespace"/>
<node CREATED="1701290294737" ID="ID_1328070168" MODIFIED="1701290300445" TEXT="definiert ein Makro"/>
<node CREATED="1701290710129" ID="ID_1040357614" MODIFIED="1701290816112" TEXT="(das sind aber alles keine wirklichen Einw&#xe4;nde)">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...zum einen ist TestChainLoad selbst ein Test-Tool
</p>
<p>
...und au&#223;erdem ist der lib::test - Namespace weder verboten noch gef&#228;hrlich
</p>
<p>
...und schlie&#223;lich steht der Makro-Name TRANSIENTLY nicht wirklich in Konkurrenz zu irgendwas
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1701290160826" ID="ID_1301869275" MODIFIED="1701290170877" TEXT="und bietet kein genau passendes API">
<node CREATED="1701290172913" ID="ID_1474344535" MODIFIED="1701290187065" TEXT="entweder man mu&#xdf; zuweisen (machen wir hier nicht)"/>
<node CREATED="1701290188406" ID="ID_651295950" MODIFIED="1701290202498" TEXT="oder man braucht zwei Closures"/>
<node CREATED="1701290226451" ID="ID_1258729842" MODIFIED="1701290235892" TEXT="wir br&#xe4;uchten eine tempor&#xe4;re neben-Storage"/>
<node CREATED="1701290824210" ID="ID_1930989663" MODIFIED="1701290841825" TEXT="das w&#xe4;re eigentlich der Basis-Fall"/>
<node CREATED="1701291085927" ID="ID_941298216" MODIFIED="1701291097644" TEXT="der zieht bereits im ctor die Kopie"/>
<node CREATED="1701291099693" ID="ID_1106394033" MODIFIED="1701291107064" TEXT="und diese liegt im Stack-frame"/>
<node CREATED="1701291107626" ID="ID_723690306" MODIFIED="1701291114150" TEXT="&#x27f9; pa&#xdf;t doch alles"/>
</node>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1701290886620" ID="ID_1327262504" MODIFIED="1701297358727" TEXT="Transiently anpassen und verwenden">
<icon BUILTIN="yes"/>
<node CREATED="1701290910198" ID="ID_996452311" MODIFIED="1701290919610" TEXT="move-Assignment bei der Wiederherstellung"/>
<node CREATED="1701291122231" ID="ID_1055950919" MODIFIED="1701291128444" TEXT="direkt verwenden ohne Makro"/>
<node CREATED="1701303840060" ID="ID_155844306" MODIFIED="1701303948270" TEXT="war nicht das Problem">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...sondern nur eine Verbesserung in der Code-Struktur (deshalb belasse ich es jetzt auch dabei)....
</p>
<p>
Das eigentliche Problem zeigte sich erst einen Schritt weiter: es ist eben nicht m&#246;glich, eine bereits gebundene Mapping-Funktion nochmal zu &#8222;entbinden&#8220; und separat aufzurufen..
</p>
</body>
</html></richcontent>
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701297731915" ID="ID_1970553199" MODIFIED="1701303828166" TEXT="und das n&#xe4;chste Problem folgt sogleich...">
<arrowlink COLOR="#925370" DESTINATION="ID_859980593" ENDARROW="Default" ENDINCLINATION="-722;53;" ID="Arrow_ID_508102553" STARTARROW="None" STARTINCLINATION="342;-486;"/>
<icon BUILTIN="smiley-oh"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1701298245500" ID="ID_130492324" MODIFIED="1701302699365" TEXT="konfigurieren &#x27f7; anwenden &#x27f7; manipulieren">
<arrowlink COLOR="#fd1694" DESTINATION="ID_1820632939" ENDARROW="Default" ENDINCLINATION="-121;412;" ID="Arrow_ID_1621910960" STARTARROW="None" STARTINCLINATION="345;-30;"/>
<linktarget COLOR="#fd331b" DESTINATION="ID_130492324" ENDARROW="Default" ENDINCLINATION="380;-27;" ID="Arrow_ID_1549798992" SOURCE="ID_424443394" STARTARROW="None" STARTINCLINATION="-178;18;"/>
</node>
<node COLOR="#91264c" CREATED="1701299615582" ID="ID_1443941840" LINK="#ID_1369025351" MODIFIED="1701302755234" TEXT="das zeigt: Grenzen des Design sind ausgereizt"/>
<node COLOR="#338800" CREATED="1701302703364" ID="ID_1803877992" LINK="#ID_522345672" MODIFIED="1701302736489" TEXT="kaskadierende Mappings aufgegeben">
<icon BUILTIN="yes"/>
<node COLOR="#227094" CREATED="1701302784681" ID="ID_129815553" MODIFIED="1701302838592" TEXT="das ist schade">
<icon BUILTIN="smily_bad"/>
</node>
<node COLOR="#435e98" CREATED="1701302805815" ID="ID_1512181041" MODIFIED="1701304014700" TEXT="aber im praktischen Gebrauch spielen sie (bisher) keine Rolle">
<arrowlink COLOR="#738e9c" DESTINATION="ID_1332958988" ENDARROW="Default" ENDINCLINATION="347;32;" ID="Arrow_ID_1468697365" STARTARROW="None" STARTINCLINATION="-337;15;"/>
<arrowlink COLOR="#738e9c" DESTINATION="ID_245626902" ENDARROW="Default" ENDINCLINATION="347;32;" ID="Arrow_ID_110894165" STARTARROW="None" STARTINCLINATION="-337;15;"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1701303968882" ID="ID_1332958988" MODIFIED="1701304004316">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
mit Abstrichen: <i>jetzt l&#228;ufts...</i>
</p>
</body>
</html></richcontent>
<linktarget COLOR="#738e9c" DESTINATION="ID_1332958988" ENDARROW="Default" ENDINCLINATION="347;32;" ID="Arrow_ID_1468697365" SOURCE="ID_1512181041" STARTARROW="None" STARTINCLINATION="-337;15;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node CREATED="1701012412539" ID="ID_757448445" MODIFIED="1701012416971" TEXT="Regel-Instanzen">