Library: RandomDraw - extract as generic component

The idea is to use some source of randomness to pick a
limited parameter value with controllable probability.
While the core of the implementation is nothing more
than some simple numeric adjustments, these turn out
to be rather intricate and obscure; the desire to
package these technicalities into a component
however necessitates to make invocations
at usage site self explanatory.
This commit is contained in:
Fischlurch 2023-11-20 16:38:55 +01:00
parent e127d0ad9a
commit e5f5953b15
5 changed files with 527 additions and 22 deletions

View file

@ -69,6 +69,7 @@
* real implementation this will have to be supplied at usage site through a traits template,
* otherwise it would not be possible to integrate seamlessly with custom data sources (as
* happens in the intended use case, where actually a Node is the data source)
* @note transformed into a generic library component for usage by vault::gear::TestChainLoad
*/
typedef unsigned int uint;

304
src/lib/random-draw.hpp Normal file
View file

@ -0,0 +1,304 @@
/*
RANDOM-DRAW.hpp - randomly pick limited values
Copyright (C) Lumiera.org
2023, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// 8/07 - how to control NOBUG??
// execute with NOBUG_LOG='ttt:TRACE' bin/try
// 1/08 - working out a static initialisation problem for Visitor (Tag creation)
// 1/08 - check 64bit longs
// 4/08 - comparison operators on shared_ptr<Asset>
// 4/08 - conversions on the value_type used for boost::any
// 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible
// 7/08 - combining partial specialisation and subclasses
// 10/8 - abusing the STL containers to hold noncopyable values
// 6/09 - investigating how to build a mixin template providing an operator bool()
// 12/9 - tracking down a strange "warning: type qualifiers ignored on function return type"
// 1/10 - can we determine at compile time the presence of a certain function (for duck-typing)?
// 4/10 - pretty printing STL containers with python enabled GDB?
// 1/11 - exploring numeric limits
// 1/11 - integer floor and wrap operation(s)
// 1/11 - how to fetch the path of the own executable -- at least under Linux?
// 10/11 - simple demo using a pointer and a struct
// 11/11 - using the boost random number generator(s)
// 12/11 - how to detect if string conversion is possible?
// 1/12 - is partial application of member functions possible?
// 5/14 - c++11 transition: detect empty function object
// 7/14 - c++11 transition: std hash function vs. boost hash
// 9/14 - variadic templates and perfect forwarding
// 11/14 - pointer to member functions and name mangling
// 8/15 - Segfault when loading into GDB (on Debian/Jessie 64bit
// 8/15 - generalising the Variant::Visitor
// 1/16 - generic to-string conversion for ostream
// 1/16 - build tuple from runtime-typed variant container
// 3/17 - generic function signature traits, including support for Lambdas
// 9/17 - manipulate variadic templates to treat varargs in several chunks
// 11/17 - metaprogramming to detect the presence of extension points
// 11/17 - detect generic lambda
// 12/17 - investigate SFINAE failure. Reason was indirect use while in template instantiation
// 03/18 - Dependency Injection / Singleton initialisation / double checked locking
// 04/18 - investigate construction of static template members
// 08/18 - Segfault when compiling some regular expressions for EventLog search
// 10/18 - investigate insidious reinterpret cast
// 12/18 - investigate the trinomial random number algorithm from the C standard lib
// 04/19 - forwarding tuple element(s) to function invocation
// 06/19 - use a statefull counting filter in a treeExplorer pipeline
// 03/20 - investigate type deduction bug with PtrDerefIter
// 01/21 - look for ways to detect the presence of an (possibly inherited) getID() function
// 08/22 - techniques to supply additional feature selectors to a constructor call
// 10/23 - search for ways to detect signatures of member functions and functors uniformly
// 11/23 - prototype for a builder-DSL to configure a functor to draw and map random values
/** @file random-draw.hpp
** Build a component to select limited values randomly.
** Prototyping to find a suitable DSL to configure drawing of random numbers and mapping results.
** The underlying implementation shall be extracted from (and later used by) TestChainLoad; the
** random numbers will be derived from node hash values and must be mapped to yield parameters
** limited to a very small value range. While numerically simple, this turns out to be rather
** error-prone, hence the desire to put a DSL in front. The challenge however arises from
** the additional requirement to support various usage patters, all with minimal specs.
**
** The following code lays out the ground structure, while treating Spec as a distinct
** type, which is then mixed into Draw. This logical separation basically was led me to the
** final solution: Draw both _is_ a function and _embodies_ the implementation of this function.
** This somewhat surprising layout is what enables use as a DSL builder, because it allows both
** to have the _builder use_ and the _converter use_ in the same class, even allowing to _define_
** a Draw by giving a function which _produces_ a (dynamically parametrised) Draw.
**
** In this prototype, all of the functor adaptation is also part of the Draw template; for the
** real implementation this will have to be supplied at usage site through a traits template,
** otherwise it would not be possible to integrate seamlessly with custom data sources (as
** happens in the intended use case, where actually a Node is the data source)
**
** @see RandomDraw_test
** @see TestChainLoad_test
** @see SchedulerStress_test
*/
#ifndef LIB_RANDOM_DRAW_H
#define LIB_RANDOM_DRAW_H
#include "lib/meta/function.hpp"
#include "lib/util.hpp"
#include <functional>
#include <utility>
namespace lib {
using lib::meta::_Fun;
using std::function;
using std::forward;
using std::move;
template<typename T, T max>
struct Limited
{
static constexpr T minVal() { return T(0); }
static constexpr T maxVal() { return max; }
T val;
template<typename X>
Limited (X raw)
: val(util::limited (X(minVal()), raw, X(maxVal())))
{ }
};
template<typename T, T max>
struct Spec
{
using Lim = Limited<T,max>;
static constexpr double CAP_EPSILON = 0.0001;
double probability{0};
T maxResult{Lim::maxVal()};
Spec() = default;
explicit
Spec (double p) : probability{p}{ }
Lim
limited (double val)
{
if (probability == 0.0 or val == 0.0)
return Lim{0};
double q = (1.0 - probability);
val -= q;
val /= probability;
val *= maxResult;
val += 1 + CAP_EPSILON;
return Lim{val};
}
};
template<typename T, T max>
struct Draw
: Spec<T,max>
, function<Limited<T,max>(size_t)>
{
using Spc = Spec<T,max>;
using Lim = typename Spc::Lim;
using Fun = function<Lim(size_t)>;
Draw()
: Spc{}
, Fun{[this](size_t hash){ return Spc::limited (asRand (hash)); }}
{ }
template<class FUN>
Draw(FUN&& fun)
: Spc{1.0}
, Fun{adaptOut(adaptIn(std::forward<FUN> (fun)))}
{ }
Draw&&
probability (double p)
{
Spc::probability = p;
return move (*this);
}
Draw&&
maxVal (uint m)
{
Spc::maxResult = m;
return move (*this);
}
template<class FUN>
Draw&&
mapping (FUN&& fun)
{
Fun(*this) = adaptOut(adaptIn(std::forward<FUN> (fun)));
return move (*this);
}
double
asRand (size_t hash)
{
return double(hash % 256)/256;
}
/**
* @internal helper to expose the signature `size_t(size_t)`
* by wrapping a given lambda or functor.
*/
template<class SIG, typename SEL=void>
struct Adaptor
{
static_assert (not sizeof(SIG), "Unable to adapt given functor.");
};
template<typename RES>
struct Adaptor<RES(size_t)>
{
template<typename FUN>
static decltype(auto)
build (FUN&& fun)
{
return std::forward<FUN>(fun);
}
};
template<typename RES>
struct Adaptor<RES(void)>
{
template<typename FUN>
static auto
build (FUN&& fun)
{
return [functor=std::forward<FUN>(fun)]
(size_t)
{
return functor();
};
}
};
template<class FUN>
decltype(auto)
adaptIn (FUN&& fun)
{
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
static_assert (lib::meta::_Fun<FUN>::ARITY <= 1, "Function with zero or one argument expected.");
using Sig = typename lib::meta::_Fun<FUN>::Sig;
return Adaptor<Sig>::build (forward<FUN> (fun));
}
template<class FUN>
decltype(auto)
adaptOut (FUN&& fun)
{
static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
static_assert (lib::meta::_Fun<FUN>::ARITY ==1, "Function with exactly one argument required.");
using Res = typename lib::meta::_Fun<FUN>::Ret;
if constexpr (std::is_same_v<Res, Lim>)
return std::forward<FUN>(fun);
else
if constexpr (std::is_same_v<Res, size_t>)
return [functor=std::forward<FUN>(fun), this]
(size_t rawHash)
{
size_t hash = functor(rawHash);
double randomNum = asRand (hash);
return Spc::limited (randomNum);
};
else
if constexpr (std::is_same_v<Res, double>)
return [functor=std::forward<FUN>(fun), this]
(size_t rawHash)
{
double randomNum = functor(rawHash);
return Spc::limited (randomNum);
};
else
if constexpr (std::is_same_v<Res, Draw>)
return [functor=std::forward<FUN>(fun), this]
(size_t rawHash)
{
Draw parametricDraw = functor(rawHash);
return parametricDraw (rawHash);
};
else
static_assert (not sizeof(Res), "unable to adapt / handle result type");
NOTREACHED("Handle based on return type");
}
};
} // namespace lib
#endif /*LIB_RANDOM_DRAW_H*/

View file

@ -508,6 +508,11 @@ return: 0
END
PLANNED "pick limited numbers randomly" RandomDraw_test <<END
return: 0
END
TEST "fractional arithmetics" Rational_test <<END
return: 0
END

View file

@ -0,0 +1,119 @@
/*
RandomDraw(Test) - verify the component builder for random selected values
Copyright (C) Lumiera.org
2023, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file random-draw-test.cpp
** unit test \ref RandomDraw_test
*/
#include "lib/test/run.hpp"
//#include "lib/test/test-helper.hpp"
#include "lib/random-draw.hpp"
//#include "lib/util.hpp"
//#include <cstdlib>
namespace lib {
namespace test{
// using util::isSameObject;
// using std::rand;
// namespace error = lumiera::error;
// using error::LUMIERA_ERROR_FATAL;
// using error::LUMIERA_ERROR_STATE;
namespace {
// const Literal THE_END = "all dead and hero got the girl";
}
/***********************************************************************************//**
* @test Verify a flexible builder for random-value generators; using a config template,
* these can be outfitted to use a suitable source of randomness and to produce
* values from a desired target type and limited range.
* - TODO
* @see result.hpp
* @see lib::ThreadJoinable usage example
*/
class RandomDraw_test
: public Test
{
void
run (Arg)
{
simpleUse();
verify_numerics();
verify_dynamicChange();
}
/** @test TODO demonstrate a basic usage scenario
* @todo WIP 11/23 🔁 define implement
*/
void
simpleUse()
{
UNIMPLEMENTED ("simple usage example");
}
/** @test TODO verify random number transformations
* @todo WIP 11/23 🔁 define implement
*/
void
verify_numerics()
{
UNIMPLEMENTED ("verify random number transformations");
}
/** @test TODO change the generation profile dynamically
* @todo WIP 11/23 🔁 define implement
*/
void
verify_dynamicChange()
{
UNIMPLEMENTED ("change the generation profile dynamically");
}
};
/** Register this test class... */
LAUNCHER (RandomDraw_test, "unit common");
}} // namespace lib::test

View file

@ -96100,27 +96100,39 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700264860430" ID="ID_911248195" MODIFIED="1700331811934" TEXT="nochmal umst&#xfc;lpen....">
<icon BUILTIN="pencil"/>
<node CREATED="1700264870441" ID="ID_1812170860" MODIFIED="1700264912656">
<node CREATED="1700264870441" ID="ID_1812170860" MODIFIED="1700491182299">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Cap &#10230; Ergebnis-Typ <font face="Monospaced" color="#410ec3"><b>Draw</b></font>
<u>Ausgangspunkt</u>: Cap &#10230; Ergebnis-Typ <font color="#410ec3" face="Monospaced"><b>Draw</b></font>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...dabei ist Cap die bereits geschaffene Hilfs-Komponente, die einen Zahlenwert mit einer Klammer von Iber/Untergrenze speichert und ihn in in diesen Rahmen hinein konditionieren kann. Das war ein relativ leichtgewichtiger erster Schritt, reicht aber nicht aus, um die techniche Komplexit&#228;t aus dem Nutzkontext zu entfernen
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264918159" ID="ID_334644013" MODIFIED="1700331828639" TEXT="diesen aber zugleich als Regel-Builder nutzbar machen">
<node COLOR="#435e98" CREATED="1700264918159" ID="ID_334644013" MODIFIED="1700491041706" TEXT="diesen aber zugleich als Regel-Builder nutzbar machen">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264938245" ID="ID_2732200" MODIFIED="1700331828640" TEXT="und zwar durch eine DSL die darauf als Manipulator-Funktion aufsetzt">
<node COLOR="#435e98" CREATED="1700264938245" ID="ID_2732200" MODIFIED="1700491041705" TEXT="und zwar durch eine DSL die darauf als Manipulator-Funktion aufsetzt">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700264961367" ID="ID_788328130" MODIFIED="1700331818142" TEXT="Einstieg: ein Funktor-Adaptor (wie neulich f&#xfc;r microbenchmark)">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#dfdd97" COLOR="#435e98" CREATED="1700264961367" ID="ID_788328130" MODIFIED="1700491028449" TEXT="Einstieg: ein Funktor-Adaptor (wie neulich f&#xfc;r microbenchmark)">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="idea"/>
<node CREATED="1700265008950" ID="ID_751701905" MODIFIED="1700265018898" TEXT="der Funktor liefert am Ende ein Draw"/>
<node COLOR="#5b280f" CREATED="1700265019715" ID="ID_624547616" MODIFIED="1700345650023" TEXT="aber auf Wunsch kann man auch ein Draw in die Hand bekommen">
<linktarget COLOR="#ad253c" DESTINATION="ID_624547616" ENDARROW="Default" ENDINCLINATION="679;28;" ID="Arrow_ID_124457360" SOURCE="ID_790826770" STARTARROW="None" STARTINCLINATION="-215;-7;"/>
@ -96130,15 +96142,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700331799351" ID="ID_619819862" MODIFIED="1700331808784" TEXT="Baumuster untersuchen (try.cpp)...">
<icon BUILTIN="pencil"/>
<node CREATED="1700342161236" ID="ID_1281138479" MODIFIED="1700342171869" TEXT="1.Enwurf: Funktions-Komposition">
<node COLOR="#338800" CREATED="1700331799351" ID="ID_619819862" MODIFIED="1700490710418" TEXT="Baumuster untersuchen (try.cpp)...">
<icon BUILTIN="button_ok"/>
<node CREATED="1700342161236" FOLDED="true" ID="ID_1281138479" MODIFIED="1700490730479" TEXT="1.Enwurf: Funktions-Komposition">
<node CREATED="1700342178718" ID="ID_1331338727" MODIFIED="1700342198924" TEXT="die Cap-Funktionalit&#xe4;t als eigener Funktor"/>
<node CREATED="1700342199523" ID="ID_1963684995" MODIFIED="1700342217408" TEXT="vorgeschaltet dann die Erzeugung des Zufallswertes"/>
<node CREATED="1700342243501" ID="ID_1390319632" MODIFIED="1700342253999" TEXT="damit w&#xe4;ren wir aber einerm reinen Funktor-Builder"/>
<node CREATED="1700342254915" ID="ID_834526555" MODIFIED="1700342262877" TEXT="w&#xfc;rde gehen, war aber nicht das was mir vorschwebte"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1700342264818" ID="ID_330199412" MODIFIED="1700342273106" TEXT="was will ich denn &#xfc;berhaupt?">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1700342264818" ID="ID_330199412" MODIFIED="1700490702462" TEXT="was will ich denn &#xfc;berhaupt?">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="help"/>
<node CREATED="1700342274840" ID="ID_1272510180" MODIFIED="1700342289356" TEXT="wahrscheinlich alles und nix Bestimmtes...">
@ -96296,7 +96308,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1700345892467" ID="ID_920427348" MODIFIED="1700345909861" TEXT="2.Entwurf: Funktor-Builder + auto-Adaption">
<node CREATED="1700345892467" FOLDED="true" ID="ID_920427348" MODIFIED="1700490969134" TEXT="2.Entwurf: Funktor-Builder + auto-Adaption">
<node CREATED="1700345916752" ID="ID_267595647" MODIFIED="1700345920980" TEXT="Grunds&#xe4;tzlich">
<node CREATED="1700345943261" ID="ID_388408150" MODIFIED="1700345956998" TEXT="Draw und Spec (Bereichseinteilung) werden verschmolzen"/>
<node CREATED="1700345922921" ID="ID_1268721778" MODIFIED="1700345942500" TEXT="Ergebnis ist immer ein Draw (und damit eine Spec)"/>
@ -96364,13 +96376,11 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1700349122079" ID="ID_419191002" MODIFIED="1700349127420" TEXT="Problem mit der Adaptierung">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1700349122079" ID="ID_419191002" MODIFIED="1700490683746" TEXT="Problem mit der Adaptierung">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1700349130966" ID="ID_831772652" MODIFIED="1700349160702" TEXT="verhindert Herausl&#xf6;sen als Library-Klasse (und ist komplex)"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1700359719367" ID="ID_1254612041" MODIFIED="1700359739837" TEXT="damit verbundenes Problem: was ist die Signatur der Draw-Funktion?">
<icon BUILTIN="help"/>
</node>
<node CREATED="1700358795138" ID="ID_1657442729" MODIFIED="1700358800541" TEXT="Analyse der F&#xe4;lle">
<node COLOR="#435e98" CREATED="1700358795138" ID="ID_1657442729" MODIFIED="1700490963019" TEXT="Analyse der F&#xe4;lle">
<icon BUILTIN="forward"/>
<node CREATED="1700358808651" ID="ID_1831518834" MODIFIED="1700358840560" TEXT="RES:Draw">
<node CREATED="1700358871480" ID="ID_67347765" MODIFIED="1700358938939" TEXT="invoke this one instead of the host-Draw"/>
<node CREATED="1700358920993" ID="ID_1393200431" MODIFIED="1700358941509" TEXT="warning: other fields on host-Draw ignored">
@ -96398,8 +96408,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node CREATED="1700359509971" ID="ID_1483199036" MODIFIED="1700359524565" TEXT="ben&#xf6;tigt wird: ein Function-chain-builder"/>
<node CREATED="1700359612504" ID="ID_988711396" MODIFIED="1700359623743" TEXT="Design-Stufe-1: dediziert">
<node CREATED="1700359625649" ID="ID_364635181" MODIFIED="1700359630119" TEXT="Adapter">
<node COLOR="#435e98" CREATED="1700359612504" FOLDED="true" ID="ID_988711396" MODIFIED="1700490963022" TEXT="Design-Stufe-1: dediziert">
<node CREATED="1700359625649" ID="ID_364635181" MODIFIED="1700490618340" TEXT="Adapter">
<linktarget COLOR="#6493ca" DESTINATION="ID_364635181" ENDARROW="Default" ENDINCLINATION="-498;131;" ID="Arrow_ID_493746329" SOURCE="ID_1671789981" STARTARROW="None" STARTINCLINATION="469;19;"/>
<node CREATED="1700361162606" ID="ID_1345527183" MODIFIED="1700361176208" TEXT="adaptOut(&#x3bb;)">
<node CREATED="1700359640066" ID="ID_918713248" MODIFIED="1700359766325" TEXT="&#x3bb;-RES:Draw">
<node CREATED="1700359783118" ID="ID_1603023899" MODIFIED="1700360709335" TEXT="&#x3bb;&#x2081; = adaptIn(&#x3bb;)"/>
@ -96439,8 +96450,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1700361391736" ID="ID_1064796631" MODIFIED="1700361486767" TEXT="wird in jedem Zweig von adaptOut(&#x3bb;) ben&#xf6;tigt"/>
</node>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1700361501097" ID="ID_401015563" MODIFIED="1700361518463" TEXT="noch unklar: was ist der Ergebnis-Typ?">
<node COLOR="#5b280f" CREATED="1700361501097" ID="ID_401015563" MODIFIED="1700490572245" TEXT="noch unklar: was ist der Ergebnis-Typ?">
<icon BUILTIN="help"/>
<icon BUILTIN="button_cancel"/>
<node CREATED="1700361526878" ID="ID_981729861" MODIFIED="1700361562965" TEXT="damit implizierte Frage: ist Draw sinnvollerweise std::function ?"/>
<node CREATED="1700361585230" ID="ID_1897786487" MODIFIED="1700361617245" TEXT="wenn ja: dann w&#xe4;re der Ergebnistyp Draw&amp;">
<node CREATED="1700361662236" ID="ID_430183904" MODIFIED="1700361674294" TEXT="m&#xfc;&#xdf;te auf sich selber referenzieren"/>
@ -96461,9 +96473,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1700361966107" ID="ID_440284003" MODIFIED="1700361977187" TEXT="der operator() hat einen Seiteneffekt"/>
<node CREATED="1700361977817" ID="ID_527836444" MODIFIED="1700361991395" TEXT="anschlie&#xdf;end hold man sich das Ergebnis per Konversions-Operator"/>
</node>
<node CREATED="1700490523806" ID="ID_518227121" MODIFIED="1700490585296" TEXT="Schlu&#xdf;folgerung: f&#xfc;r eine rein zweckgebundene L&#xf6;sung problematisch...">
<arrowlink DESTINATION="ID_556380585" ENDARROW="Default" ENDINCLINATION="-1;-177;" ID="Arrow_ID_1611327128" STARTARROW="None" STARTINCLINATION="-377;0;"/>
<icon BUILTIN="forward"/>
</node>
</node>
<node CREATED="1700365769348" ID="ID_556380585" MODIFIED="1700365775516" TEXT="Design-stufe-2: generisch">
</node>
<node COLOR="#435e98" CREATED="1700365769348" FOLDED="true" ID="ID_556380585" MODIFIED="1700490963023" TEXT="Design-stufe-2: generisch">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_556380585" ENDARROW="Default" ENDINCLINATION="-1;-177;" ID="Arrow_ID_1611327128" SOURCE="ID_518227121" STARTARROW="None" STARTINCLINATION="-377;0;"/>
<icon BUILTIN="forward"/>
<node CREATED="1700365860944" ID="ID_1336006745" MODIFIED="1700365909109" TEXT="es handelt sich dann insgesamt um eine Funktion: Q &#x27fc; Limited&lt;T, T max&gt;">
<node CREATED="1700365917573" ID="ID_1497905227" MODIFIED="1700365934014" TEXT="es sollte eine einzige Funktion sein aus Gr&#xfc;nden der Klarheit"/>
<node CREATED="1700365936094" ID="ID_1933404992" MODIFIED="1700365960831" TEXT="der Zieltyp Limited ist essentieller Bestandteil des Rechenschmas"/>
@ -96535,20 +96553,78 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1700399151659" ID="ID_144021391" MODIFIED="1700399318338" TEXT="Hier erscheint ein Config-Typ sinnvoll">
<node CREATED="1700399151659" ID="ID_144021391" MODIFIED="1700490660062" TEXT="Hier erscheint ein Config-Typ sinnvoll">
<arrowlink COLOR="#a9b4c1" DESTINATION="ID_1619656561" ENDARROW="Default" ENDINCLINATION="-154;13;" ID="Arrow_ID_252746284" STARTARROW="None" STARTINCLINATION="95;-44;"/>
<linktarget COLOR="#a9b4c1" DESTINATION="ID_144021391" ENDARROW="Default" ENDINCLINATION="151;-46;" ID="Arrow_ID_1749412477" SOURCE="ID_568728168" STARTARROW="None" STARTINCLINATION="-189;14;"/>
<linktarget COLOR="#64929e" DESTINATION="ID_144021391" ENDARROW="Default" ENDINCLINATION="-136;11;" ID="Arrow_ID_646571312" SOURCE="ID_39517550" STARTARROW="None" STARTINCLINATION="208;8;"/>
<node CREATED="1700399198368" ID="ID_1781925975" MODIFIED="1700399205813" TEXT="&#xfc;bergeben als Template Paramter"/>
<node CREATED="1700399206449" ID="ID_1309572183" MODIFIED="1700399222443" TEXT="aber mit einem Default &#x27f9; dient als copy-n-paste-Vorlage"/>
<node CREATED="1700399243756" ID="ID_510267956" MODIFIED="1700399258246" TEXT="das Konverter-Funktions-Temlate kann darin direkt enthalten sein"/>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1700359719367" ID="ID_1254612041" MODIFIED="1700490912197" TEXT="damit verbundenes Problem: was ist die Signatur der Draw-Funktion?">
<icon BUILTIN="help"/>
<node CREATED="1700490792506" ID="ID_1607287838" MODIFIED="1700490807908" TEXT="letzten Endes mu&#xdf; sie den Quell- und Zieltyp kennen"/>
<node CREATED="1700490809073" ID="ID_1049199825" MODIFIED="1700490828217" TEXT="und alle Teile m&#xfc;ssen im Draw selber gespeichert werden"/>
<node COLOR="#435e98" CREATED="1700490829158" ID="ID_1235648316" MODIFIED="1700490910411" TEXT="&#x27f9; Draw effectively is-a function source &#x27fc; target"/>
<node COLOR="#435e98" CREATED="1700490897308" ID="ID_1407106079" MODIFIED="1700490906366" TEXT="hinzu kommt Builder-Funktionalit&#xe4;t"/>
</node>
</node>
<node COLOR="#338800" CREATED="1700444194601" ID="ID_1576940362" MODIFIED="1700444225488" TEXT="Funktionalit&#xe4;t deiziert ohne Quell-Typ prototypisch implementieren">
</node>
<node COLOR="#338800" CREATED="1700444194601" ID="ID_1576940362" MODIFIED="1700490083378" TEXT="Funktionalit&#xe4;t dediziert ohne Quell-Typ prototypisch implementieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1700490121573" ID="ID_1457864775" MODIFIED="1700490496554">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Fazit <b>Design-Analyse</b>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="forward"/>
<node CREATED="1700490144136" ID="ID_248814374" MODIFIED="1700490174056" TEXT="der Adapter-Ansatz f&#xfc;hrt zu einer Funktion Ende-zu-Ende"/>
<node CREATED="1700490427387" ID="ID_1671789981" MODIFIED="1700490624419" TEXT="diese wird in zwei Schritten aufgebaut: Adapter am Eingang und Ausgang">
<arrowlink COLOR="#6493ca" DESTINATION="ID_364635181" ENDARROW="Default" ENDINCLINATION="-498;131;" ID="Arrow_ID_493746329" STARTARROW="None" STARTINCLINATION="469;19;"/>
</node>
<node CREATED="1700490175196" ID="ID_1557807559" MODIFIED="1700490345221" TEXT="damit wird eine solche L&#xf6;sung zwangsl&#xe4;ufig generisch (und eine Library-Komponente)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
warum? eine zweckgebundene L&#246;sung mit diesem Komplexit&#228;tsgrad w&#228;re nicht zu rechtfertigen; man w&#252;rde dann nach einer einfacheren Alternative suchen. Konkret komme ich allerdings von dieser einfacheren Alternative her, weil sie immer noch nicht einfach und klar genug war. Insofern bin ich froh, &#252;berhaupt eine L&#246;sung zu haben, die im R&#252;ckblick sinnvoll darstellbar ist
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1700490355020" ID="ID_442374644" MODIFIED="1700490390211" TEXT="die Basis-Komponente ist damit parametrisiert in Quell- und Zieltyp"/>
<node CREATED="1700490391087" ID="ID_39517550" MODIFIED="1700490669142" TEXT="es erscheint sinnvoll, dies in ein Konfigurations-Template zusammenzufassen">
<arrowlink COLOR="#64929e" DESTINATION="ID_144021391" ENDARROW="Default" ENDINCLINATION="-136;11;" ID="Arrow_ID_646571312" STARTARROW="None" STARTINCLINATION="208;8;"/>
</node>
<node CREATED="1700490465981" ID="ID_95937370" MODIFIED="1700490485279" TEXT="der Nutzer bekommt eine builder-DSL auf dem resultierenden, spezialisierten Typ"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700491763307" ID="ID_1225692248" MODIFIED="1700494387962" TEXT="Library-Komponente extrahieren: RandomDraw">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700491815546" ID="ID_1942150407" MODIFIED="1700491825145" TEXT="bestehenden Prototyp konsolidieren">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1700491829216" ID="ID_1294373641" MODIFIED="1700491844930" TEXT="den Spec-Subtyp in RandomDraw integrieren"/>
<node CREATED="1700491953800" ID="ID_75649548" MODIFIED="1700491984631" TEXT="Policy-Template einf&#xfc;hren"/>
<node CREATED="1700491985219" ID="ID_460437503" MODIFIED="1700491990343" TEXT="Adaptierung restrukturieren"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700491877926" ID="ID_1958310493" MODIFIED="1700491890609" TEXT="Test zur Dokumentation">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1700491902622" ID="ID_523469259" MODIFIED="1700491929304" TEXT="soll auch den Proze&#xdf; der Spezialisierung demonstrieren"/>
<node CREATED="1700491930155" ID="ID_1583745392" MODIFIED="1700491949372" TEXT="numerische Grenzen beleuchten"/>
</node>
</node>
</node>
</node>