Library: consider how to handle randomness in tests

Using random or pseudo-random numbers as input for tests
can be a very effective tool to spot unintended behaviour in
corner cases, and also helps writing more principled test verifications.
However, investigating failures in randomised tests can be challenging.

A well-proven solution is to exploit the **determinism** of pseudo-random-numbers
by documenting a randomly generated seed, that can be re-injected for investigation.

Up to now, most tests rely on the old library function `rand()`, while
at some places already the C++ standard framework for random number generation
is used, packaged into a custom wrapper. Adding adequate support for
documented seed values seems to be easy to achieve, after switching
existing usages of `rand()` to a suitable drop-in replacement.

After some consideration, I decided ''against'' wiring random generator instances
explicitly, while allowing to do so on occasion, when necessary. Thus
the planned seeding mechanism will rather re-seed a ''implicit default''
generator, which could then be used to construct explicit generator instances
when required (e.g. for multithreaded tests)

As a starting point, this changeset replaces the `randomise()` API call
by a direct access to the ''reseeding functionality'' exposed by the
C++ framework and all default generators. Since we already provide a
dedicated static instance of the plattform entropy source, re-randomisation
can be achieved by seeding from there.

NOTE: there was extended debate in the net, questioning the viability
of the `std::random_seq` -- these arguments, while valid from a theoretical
point of view, seem rather moot when placed into a practical context,
where even 2^32 different generation-paths(cycles) are more than enough
to provide sufficient diffusion of results (unless the goal is really to
engage into Monte-Carlo simulations for scientific research or large model
simulations).

Notable most of the more catchy reprovals raised by Melissa O'Neill
have been refuted by experts of the field, even while being still propagated
at various places in the net, often combined with promoting PCG-Random.
This commit is contained in:
Fischlurch 2024-11-09 23:25:25 +01:00
parent 71af21ffd6
commit 92bc044e9e
4 changed files with 584 additions and 48 deletions

View file

@ -84,8 +84,8 @@ namespace lib {
void
randomiseRandomness()
{
entropyGen.randomise(entropyNucleus);
defaultGen.randomise(entropyNucleus);
entropyGen.reseed(entropyNucleus);
defaultGen.reseed(entropyNucleus);
}
} // namespace lib

View file

@ -80,7 +80,7 @@ namespace lib {
double uni() { return uniformD_(generator_); }
/** inject controlled randomisation */
void randomise(SeedNucleus&);
void reseed (SeedNucleus&);
};
/**
@ -121,9 +121,9 @@ namespace lib {
template<class GEN>
inline void
RandomSequencer<GEN>::randomise (SeedNucleus& nucleus)
RandomSequencer<GEN>::reseed (SeedNucleus& nucleus)
{
generator_.discard (nucleus.getSeed() % 55555);
generator_.seed (nucleus.getSeed());
}

View file

@ -90,11 +90,15 @@ namespace test {
CHECK (r2 == src2.u64());
CHECK (r3 == src2.uni());
src1.randomise(coreOfEvil);
CHECK (src1.i32() != src2.i32());
src1.reseed (coreOfEvil);
CHECK (src1.u64() != src2.u64());
src2.randomise(coreOfEvil);
src2.reseed (coreOfEvil);
CHECK (src1.u64() != src2.u64());
(void) src2.u64();
CHECK (src1.u64() == src2.u64());
CHECK (src1.i32() == src2.i32());
CHECK (src1.uni() == src2.uni());
}
};

View file

@ -14530,9 +14530,7 @@
<node CREATED="1529016854248" FOLDED="true" HGAP="37" ID="ID_1664191705" MODIFIED="1561827482928" TEXT="Abw&#xe4;gung" VSHIFT="5">
<node CREATED="1529016871262" ID="ID_957194065" MODIFIED="1529017825322" TEXT="Variante-2 verschiebt das Problem">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
...denn das eigentliche Problem ist,
@ -14548,9 +14546,7 @@
</node>
<node CREATED="1529017693432" ID="ID_70956393" MODIFIED="1529018209759" TEXT="Variante-3 verwendet zwei Repr&#xe4;sentationen f&#xfc;r die gleiche Sache">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
und zwar f&#252;r die abstrahierte GUI-Location
@ -16587,9 +16583,7 @@
</node>
<node CREATED="1487119230659" ID="ID_651577067" MODIFIED="1518487921076">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Frage: wieviel Interaction Control
@ -19489,9 +19483,7 @@
<icon BUILTIN="info"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1664055752785" ID="ID_1076715259" MODIFIED="1664055785130">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Analyse: welche <i>beweglichen Teile </i>gibt es &#252;berhaupt?
@ -25506,9 +25498,7 @@
</node>
<node CREATED="1612008922562" ID="ID_458884534" MODIFIED="1612009068409" TEXT="nur ein historisches &#xdc;berbleibsel">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
ich wollte mal ein viel generischeres Design schaffen, das sogar eine Art Grundger&#252;st f&#252;r das Zusammenbauen des GUI sein k&#246;nnte. In der vertieften Analyse wurde dann aber klar, da&#223; dieses Design nicht so ohne Weiteres realisierbar ist. Daraufhin habe ich beschlossen, die Idee aufzugeben und stattdessen auf Einzelf&#228;lle zu spezialisieren. Und in einem weiteren Schritt habe ich dann die Themen &quot;Grid&quot; und &quot;Canvas&quot; voneinander getrennt
@ -33489,9 +33479,7 @@
<icon BUILTIN="stop-sign"/>
<node CREATED="1564868166273" ID="ID_945377761" MODIFIED="1564868267923" TEXT="kann das problematische Verhalten reproduzieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
Wenn man einen neuen Gtk::StyleContext erzeugt,
@ -40004,9 +39992,7 @@
<node CREATED="1624112504484" ID="ID_585066990" MODIFIED="1624112524179" TEXT="deaktivieren der anderen Test-zeichen-Funktion (Grounding) beweirkt nichts"/>
<node CREATED="1624112533168" ID="ID_1573289000" MODIFIED="1624113075023" TEXT="der berechnete Radius ist stets konsistent und variiert nicht, wenn man den Clip verschiebt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
ein cout in genau diesem Testcode gibt stets nur alternierend den Allocation-Wert f&#252;r den Ruler-Canvas (konstant 5px) und dann den Main-Canvas (variiert mit Fensterh&#246;he) aus
@ -46632,9 +46618,7 @@
</node>
<node CREATED="1448078778916" ID="ID_1657108949" MODIFIED="1576282358015" TEXT="Fehler l&#xf6;schen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
mark &quot;clearErr&quot;
@ -47207,9 +47191,7 @@
<node CREATED="1455668897947" FOLDED="true" HGAP="211" ID="ID_1897861223" MODIFIED="1576200713578" TEXT="Konsequenzen" VSHIFT="23">
<node CREATED="1455668923175" ID="ID_1183550957" MODIFIED="1575133324169" TEXT="brauche passendes UI-Bus API">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
....so harmlos hat alles angefangen
@ -47738,9 +47720,7 @@
</node>
<node CREATED="1470778603801" ID="ID_1808045935" MODIFIED="1575133326567" TEXT="needed to implement the `del` verb">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
since skipSrc performs both the `del` and the `skip` verb, it can not perform the match itself...
@ -47952,9 +47932,7 @@
<node CREATED="1455928427432" ID="ID_1189452497" MODIFIED="1455928435275" TEXT="push mutator on stack"/>
<node CREATED="1457190622236" ID="ID_1347446227" MODIFIED="1461946862429">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
invoke <b>mutateChild</b>
@ -48183,9 +48161,7 @@
<node CREATED="1456186634006" ID="ID_310265994" MODIFIED="1512926191948" TEXT="Profil des Mutators">
<node CREATED="1456186654411" ID="ID_1341247857" MODIFIED="1575133328189" TEXT="Erzeugen geht schnell">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
nur Zuweisung einiger Referenzen
@ -57147,6 +57123,293 @@
<node COLOR="#435e98" CREATED="1729979325607" ID="ID_677674501" MODIFIED="1729979344958" TEXT="useFrameTable"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730904143330" ID="ID_25783469" MODIFIED="1730904275397" TEXT="#1378 controlled random seed for tests">
<linktarget COLOR="#c4145f" DESTINATION="ID_25783469" ENDARROW="Default" ENDINCLINATION="6546;452;" ID="Arrow_ID_1019579428" SOURCE="ID_1500320757" STARTARROW="None" STARTINCLINATION="1769;146;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1730931170413" HGAP="34" ID="ID_480480032" MODIFIED="1731119671920" TEXT="diverse Zweifel &lt;random&gt; betreffend" VSHIFT="44">
<arrowlink COLOR="#968bb0" DESTINATION="ID_607929754" ENDARROW="Default" ENDINCLINATION="-1401;152;" ID="Arrow_ID_682771755" STARTARROW="None" STARTINCLINATION="-1300;91;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1730931709389" ID="ID_470384484" MODIFIED="1730931818828" TEXT="Mersenne-Twister ist schwergewichtig">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...f&#252;r den Zweck hier; wir brauchen durchaus mengenweise Zufallszahlen mit guten statistischen Eigenschaften, aber wir brauchen weder unglaublich lange Zyklenzahlen, noch bauchen wir einen extrem gro&#223;en Konfigurationsraum
</p>
</body>
</html></richcontent>
<node CREATED="1731114749603" ID="ID_1333921517" MODIFIED="1731114769121" TEXT="man k&#xf6;nnte stattdessen einen Jenkins-PRNG nehmen"/>
<node CREATED="1731114769721" ID="ID_415822546" MODIFIED="1731114790753" TEXT="oder xoroshiro oder vergleichbare moderne Algorithmen"/>
<node CREATED="1731114793582" ID="ID_1481410578" MODIFIED="1731114948438" TEXT="Ma&#xdf;stab: mu&#xdf; PractRand-Test bestehen und allgemein akzeptiert sein">
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1730931890948" HGAP="67" ID="ID_408643074" MODIFIED="1731118671023" TEXT="sollte / kann man die seed-seq unterst&#xfc;tzen?" VSHIFT="5">
<arrowlink COLOR="#3e50ba" DESTINATION="ID_276440200" ENDARROW="Default" ENDINCLINATION="26;-49;" ID="Arrow_ID_715484019" STARTARROW="None" STARTINCLINATION="-29;40;"/>
<icon BUILTIN="help"/>
<icon BUILTIN="hourglass"/>
<node CREATED="1730931907482" ID="ID_417270187" MODIFIED="1730932170717" TEXT="der aktuelle Entwuf verwendet einen uint64_t als seed">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und mein Interface SeedNucleus ist nur darauf ausgelegt (auf den kleinsten gemeinsamen Nenner)
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1730931956979" ID="ID_1736173821" MODIFIED="1730932147229" TEXT="seed-seq ist ein spezielles Ding f&#xfc;r den C++-Standard">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und zu allem &#220;berflu&#223; gibt es auch noch eine recht fragw&#252;rdige standard-Implementierung, std::seed_seq, welche die gegebenen Zahlen in einen Vector auf den Heap speichert.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1730931976544" ID="ID_449303857" MODIFIED="1730932077893" TEXT="aber: jeder PRNG verlangt eigentlich nach einem passenden Seed-Mechanismus">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
meist wird Seeden aus einer einzigen Zahl unterst&#252;tzt, aber viele Algorithmen brauchen eigentlich mehr <i>initial state</i>&#160;und hierf&#252;r ist mehr Seed-Input n&#252;tzlich; wenn man also eine gr&#246;&#223;ere Entropiequelle h&#228;tte, k&#246;nnte man eine bessere Diffusion erreichen
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1730932173054" ID="ID_1175501386" MODIFIED="1730932275229" TEXT="dieses Problem l&#xe4;uft auf einen double-Dispatch hinaus">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...sofern man tats&#228;chlich ein abstrahiertes Interface f&#252;r das Seeding haben m&#246;chte (d.h. im usage-Kontext ist nicht explizit klar, was f&#252;r eine Quelle tats&#228;chlich verwendet wird)
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1731115073844" HGAP="115" ID="ID_276440200" MODIFIED="1731118661070" TEXT="Diskussion" VSHIFT="9">
<linktarget COLOR="#3e50ba" DESTINATION="ID_276440200" ENDARROW="Default" ENDINCLINATION="26;-49;" ID="Arrow_ID_715484019" SOURCE="ID_408643074" STARTARROW="None" STARTINCLINATION="-29;40;"/>
<node CREATED="1731115107291" ID="ID_864947379" MODIFIED="1731117162631" TEXT="der Zweck f&#xfc;r std::seed_seq und mein SeedNucleus &#xfc;berschneiden sich (nur) teilweise">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
<font face="Monospaced" size="5">std::seed_seq </font>
</p>
<ul>
<li>
soll vor allem die Schw&#228;chen des Mersenne-Twister &#252;berbr&#252;cken, welcher einen sehr gro&#223;en <i>initial state</i>&#160;ben&#246;tigt, und f&#252;r einige Eingabe-Sequenzen gef&#228;hrlich degenerieren kann; diese Idee wurde dann verallgemeinert...
</li>
<li>
unabh&#228;ngig davon wurde aber die zweite Variante erlaubt, n&#228;mlich den Random-Generator mit einer einzigen Zahl zu seeden...
</li>
<li>
Melissa O'Neil (sie sp&#228;tere Autorin von PCG-Random) hat den Algorithmus f&#252;r seed_seq dahingehend kritisiert, da&#223; dieser eiene gro&#223;e Menge Entropie nicht optimal nutzt. Dem wurde von verschiedener Seite widersprochen; desweiteren ist fraglich, f&#252;r welche Art Anwendungen diese Frage &#252;berhaupt relevant ist; denn auch nur mit einem einzigen Seed-Value erzeugt der Mersenne-Twiseter 2^32 verschiedene, extrem hochqualitative Sequenzen &#8212; es geht nur um die Frage, ob er auch 2^(624&#183;32) verschiedene Sequenzen erzeugen <i>k&#246;nnte.</i>
</li>
<li>
das Interface f&#252;r &lt;random&gt; ist <b>generisch</b>: es gibt ein <i>Konzept</i>&#160;f&#252;r Seed-seq, und ein <i>Konzept</i>&#160;Generator, und die beiden werden dann jeweils f&#252;r den Einzelfall konkret kombiniert
</li>
</ul>
<p>
<font face="Monospaced" size="5">SeedNucleus </font>
</p>
<ul>
<li>
ist auf die besondere Situation ausgerichtet, da&#223; ein <i>nicht n&#228;her bekannter </i>Generator irgendwann zur Laufzeit eine <i>nicht n&#228;her bekannte Seed-Quelle</i>&#160;bekommen soll
</li>
<li>
es soll also <b>zur Laufzeit<i>&#160;</i></b>aber damit auch <b>dynamisch</b>&#160;umgeschaltet werden zwischen einem festen Seed und deterministischem Verhalten und pseudo- oder echter Randomisierung
</li>
<li>
hier ist also die <i>potentielle reproduzierbarkeit</i>&#160;eine zentrale Hinsicht, wohingegen davon ausgegangen wird, da&#223; durch <i>interaktiven Gebrauch&#160;</i>ohnehin eine unersch&#246;pfliche Entropie-Quelle gegeben ist
</li>
</ul>
</body>
</html></richcontent>
</node>
<node CREATED="1731117195402" ID="ID_1258145243" MODIFIED="1731118502486" TEXT="theoretisch k&#xf6;nnte das Interface SeedNucleus zur Basis einer Seed-seq gemacht werden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und zwar w&#252;rde es gen&#252;gen, statt eines Seed-Value einen Iterator zur&#252;ckzuliefern; dieses Proxy-Objekt m&#252;&#223;te dann allerdings im Typ entsprechend fixiert sein (also z.B. ein uint32_t*). Dann bliebe allerdings auch noch die Frage offen, ob auch der im C++-Standard festgelegte Algorithmus implementiert werden mu&#223;, d.h. ob intern aus dem Aufruf des SeedNucleus wieder eine konforme Seed-seq erzeugt werden soll. <i>Das w&#228;re durchaus machbar </i>(er ist genau spezifiziert und leicht zu implementieren) &#8212; w&#252;rde aber wieder die gleichen Probleme aufwerfen, die auch f&#252;r <font face="Monospaced">std::seed_seq</font>&#160;gelten:
</p>
<ul>
<li>
der Algorithmus mu&#223; die L&#228;nge der gelieferten Seed-Seq und die L&#228;nge der Quell-Sequenz kennen &#10233; beide Infos k&#246;nnte man aus Pointer-Arrithmetik gewinnen (und das bereitzustellende C++ Interface f&#252;r die Seed-seq l&#228;&#223;t auch gar keinen anderen Ausweg zu)
</li>
<li>
alle Unsicherheiten und Einw&#228;nde bez&#252;glich der Qualit&#228;t der Seed-seq. bleiben bestehen (das w&#228;re aber immer noch besser als nur ein einziger Seed-Wert)
</li>
<li>
es bleibt offen, ob dieses Schema auch f&#252;r andere (modernere) PRNG-Algorithmen vorteilhaft ist
</li>
</ul>
</body>
</html>
</richcontent>
</node>
<node CREATED="1731118532378" ID="ID_1249119445" MODIFIED="1731118574223">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
<u>damit wird klar</u>: das aktuelle SeedNucleus-Interface is <i>zun&#228;chst gut genug</i>&#160;(KISS)
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node CREATED="1731119513557" ID="ID_855133847" MODIFIED="1731119527125" TEXT="Framework mu&#xdf; SeedNucleus bereitstellen"/>
<node CREATED="1731119593065" ID="ID_611482095" MODIFIED="1731119612642" TEXT="idealerweise hoch integriert (incl Seed-Aufzeichnung)"/>
<node CREATED="1731118896406" ID="ID_1421362358" MODIFIED="1731118913959" TEXT="mu&#xdf; den eingespeisten Seed speichern/dokumentieren k&#xf6;nnen">
<node CREATED="1731119024672" ID="ID_1486830658" MODIFIED="1731119227210" TEXT="das ist kniffelig: es widerspricht der Offenheit der Interfaces">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
der SeedNucleus soll ja eben grade opaque sein, also m&#246;chte ich da keine zus&#228;tzliche Operation zum State-Speichern hinzunehmen; und f&#252;r die std::seed_seq ergibt sich das Problem, da&#223; die L&#228;nge nicht bekannt ist; man bek&#228;me also u.U eine unbeschr&#228;nkt lange Sequenz von Zahlen als Seed-Zustand
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1731119229401" ID="ID_49565117" MODIFIED="1731119356668" TEXT="aber ein Dekorator w&#xfc;rde sich hier anbieten">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<ul>
<li>
ein SeedNucleus, der einen quell-Nucleus einpackt und den/die ausgelesenen Wert(e) dokumentiert
</li>
<li>
und nat&#252;rlich dann als Gegenst&#252;ck ein Seed-Nucleus der einen festen Wert ausliefert (trivial), oder ggfs. sogar eine Weiche, die entweder die Quelle verwendet, oder einen gegeben Override
</li>
</ul>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1731118832589" ID="ID_732098473" MODIFIED="1731119409643" TEXT="brauche eine reseed()-Operation um einen Seed wiederherzustellen">
<node CREATED="1731118937690" ID="ID_876325939" MODIFIED="1731118961825" TEXT="der C++ - Standard bietet de-facto diese Operation auf allen enthaltenen Engines"/>
<node CREATED="1731118962605" ID="ID_1749223447" MODIFIED="1731118982278" TEXT="notfalls k&#xf6;nnte man aber auch ein in-place Destroy / re-Construct machen"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731119637225" ID="ID_955411605" MODIFIED="1731119733338" TEXT="reseed()-Operation auf unser RandomSequencer-Interface &#xfc;bernehmen">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1731187281299" ID="ID_1511041306" MODIFIED="1731187308599" TEXT="daf&#xfc;r f&#xe4;llt die randomise()-Operation weg">
<icon BUILTIN="yes"/>
<node CREATED="1731187320199" ID="ID_622096601" MODIFIED="1731187577587" TEXT="der Hauptzweck f&#xe4;llt weg">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
eigentlich hatte ich das nur als Vorsichtsma&#223;nahme eingef&#252;rt, da wir noch kein Framework f&#252;r Zufallszahlen in Tests hatten; die Tests liefen seither stets mit einem festen Seed los, aber es sollte eben eine &#187;Hintert&#252;r&#171; geben, mit der man in bestimmte Tests echte Zuf&#228;lligkeit injizieren klnnte
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1731187426374" ID="ID_1937305565" MODIFIED="1731187480844" TEXT="bzw. kann durch reseed() aus der Entropiequelle realisiert werden"/>
<node CREATED="1731187581651" ID="ID_684894821" MODIFIED="1731187950869" TEXT="sollte das discard() gebraucht werden, kann man es ja leicht auf das API herausf&#xfc;hren">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...das w&#228;re nur notwendig, wenn mal eine ganze Familie von Generatoren (z.B. in parallelen Tests) zum Einsatz kommt, und zudem der unterliegende PRNG eine schlechte Diffusion hat. Normalerweise aber erzeugen wir solche Generatoren (gem&#228;&#223; diesem Plan) nun stets aus dem Seed eines Vater-Generators, und wir verwenden qualitativ hochwertige PRNGs, und das sollte eigentlich zur Dekorrelation gen&#252;gen
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731119762690" ID="ID_1637478235" MODIFIED="1731119834979" TEXT="Entwurf: lib::test::Test::useRandom()">
<icon BUILTIN="idea"/>
<node CREATED="1731119858173" ID="ID_1447736454" MODIFIED="1731119870919" TEXT="verwendet einen eingebetteten SeedNucleus"/>
<node COLOR="#5b280f" CREATED="1731120003113" ID="ID_1177767927" MODIFIED="1731176382320" TEXT="jeder Aufruf erzeugt ein neues RandomSequencer-Objekt">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1731119876579" ID="ID_1129580767" MODIFIED="1731119987245" TEXT="sorgt daf&#xfc;r, da&#xdf; der gezogene Seed dokumentiert wird">
<node COLOR="#435e98" CREATED="1731120117194" ID="ID_1685729849" MODIFIED="1731120697456" TEXT="Problem: wo?">
<icon BUILTIN="help"/>
<node CREATED="1731120134129" ID="ID_633936698" MODIFIED="1731120148682" TEXT="STDOUT und STDERR k&#xf6;nnen mit Test-Definitionen interferieren"/>
<node CREATED="1731120153767" ID="ID_760903903" MODIFIED="1731120181309" TEXT="der Output vom Testrunner ist normalerweise im Test-Log nicht sichtbar"/>
<node CREATED="1731120248436" ID="ID_473259633" MODIFIED="1731120275108" TEXT="bisher ist der Testrunner selber ohne Seiteneffekte"/>
<node CREATED="1731120293131" ID="ID_685863529" MODIFIED="1731120310311" TEXT="m&#xfc;&#xdf;te also entweder ein Logfile einf&#xfc;hren oder im Fehlerfall ausgeben">
<node CREATED="1731120519654" ID="ID_236130865" MODIFIED="1731120546192" TEXT="Cehteh&apos;s test.sh erf&#xfc;llt das bereits">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1731120547220" ID="ID_1582896343" MODIFIED="1731120597014" TEXT="es schreibt den kompletten STDOUT nur im Fehlerfall ins Log"/>
<node CREATED="1731120597722" ID="ID_1682502018" MODIFIED="1731120650108" TEXT="es filtert die ITRACE\|INFO\|NOTICE\|WARNING\|ERR -Pr&#xe4;fixe"/>
<node CREATED="1731120684335" ID="ID_1251466681" MODIFIED="1731120694337" TEXT="Fazit: Ausgabe per NOTICE">
<icon BUILTIN="forward"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731120702508" ID="ID_1798637658" MODIFIED="1731120716944" TEXT="es wird also bei jedem Ziehen eines Seed ein NOTICE-Log geschrieben">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731120731502" ID="ID_1120851239" MODIFIED="1731120769966" TEXT="neue Kommandozeilen-Parameter: --seed &lt;zahl&gt;">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1731176387690" ID="ID_94726091" MODIFIED="1731176394537" TEXT="&#xdc;berlegungen zum API">
<node CREATED="1731176395547" ID="ID_37424726" MODIFIED="1731176788372" TEXT="in den meisten F&#xe4;llen will man grade nicht ein separates Generator-Objekt">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und zwar weil das einfach umst&#228;ndlich ist, die Aufrufe sind l&#228;nger, man mu&#223; es durchreichen und ggfs ist dann doch noch irgendwo bei den sonstigen Utilities ein versteckter Aufruf des default-Generators. Es gibt auch nur selten einen Mehrwert, verschiedene Generatoren zu verwenden; das w&#228;re nur notwendig wenn ein komplexer Proze&#223; durchgef&#252;hrt wird, der in Teilen nicht v&#246;llig ablaufstabil ist, z.B. weil in mehreren Threads unabh&#228;ngig voneinander Zufallszahlen gezogen werden.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1731176410657" ID="ID_633466859" MODIFIED="1731176429803" TEXT="sondern es soll ein Seed f&#xfc;r den globalen default-Generator gezogen werden"/>
<node CREATED="1731176432311" ID="ID_1316146764" MODIFIED="1731176574679" TEXT="ein eigenst&#xe4;ndiges Generator-Objekt k&#xf6;nnte man im Einzelfall eigens erzeugen"/>
<node CREATED="1731176808100" ID="ID_515962490" MODIFIED="1731176815919" TEXT="demnach &#x27f9;">
<node CREATED="1731176816814" ID="ID_1980459271" MODIFIED="1731177262259" TEXT="seedRand() zieht einen Seed">
<node CREATED="1731186698753" ID="ID_127278587" MODIFIED="1731186713681" TEXT="der Seed stammt aus einem dem Test &#xfc;bergebenen SeedNucleus"/>
<node CREATED="1731176842048" ID="ID_1519596014" MODIFIED="1731176862001" TEXT="mit diesem wird der default-Generator reseeded"/>
<node CREATED="1731176862637" ID="ID_1163242877" MODIFIED="1731176885007" TEXT="und er wird sofort auch ins Log dokument"/>
<node CREATED="1731176893512" ID="ID_1023102076" MODIFIED="1731176919929" TEXT="falls --seed gegeben, wird jeder Aufruf hier identisch den gegebenen Seed einspielen"/>
</node>
<node CREATED="1731177263762" ID="ID_1481572854" MODIFIED="1731177282680" TEXT="makeRandGen() erzeugt einen sub-Generator">
<node CREATED="1731177285016" ID="ID_306167360" MODIFIED="1731177302182" TEXT="dieser zieht eine Zufallszahl als Seed aus dem globalen Generator"/>
</node>
<node CREATED="1731177591628" ID="ID_1624911975" MODIFIED="1731177628806" TEXT="ein seedRand()-Aufruf mu&#xdf; davor stehen und darf nur einmal pro Testfall auftreten">
<icon BUILTIN="yes"/>
<node CREATED="1731177631334" ID="ID_1783058296" MODIFIED="1731177642233" TEXT="d.h. ich baue keine Magie und kein Caching ein"/>
<node CREATED="1731177648796" ID="ID_1045172770" MODIFIED="1731186652255">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
der Test-Autor ist selber daf&#252;r verantwortlich,<br />die Zufallszahlen-Generierung zu verstehen...
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1731186827432" ID="ID_1343084270" MODIFIED="1731186876763" TEXT="nested Helper-Klassen f&#xfc;r Distributionen">
<node CREATED="1731186885784" ID="ID_1137186891" MODIFIED="1731186909601" TEXT="sie bekommen optional einen Generator als ctor-Argument"/>
<node CREATED="1731186910274" ID="ID_1712434077" MODIFIED="1731186920709" TEXT="oder h&#xe4;ngen sich ansonsten an den default-Generator"/>
<node CREATED="1731186949918" ID="ID_1074918802" MODIFIED="1731187011177" TEXT="man k&#xf6;nnte das sp&#xe4;ter in ein Generatoren-Framework ausbauen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
etwa analog zu dem Framework, welches mein Kollege Oleg Galimov bei der Baaderbank mitgebracht hat (es ist OpenSource, in Java geschrieben)
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
@ -91576,6 +91839,24 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827961401" ID="ID_927640003" MODIFIED="1730827975594" TEXT="die Test-Ontology als Singleton zug&#xe4;nglich machen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730900496156" ID="ID_744198194" MODIFIED="1730900506692" TEXT="erweiterte Verifikationen f&#xfc;r den TestFrame">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1730900509282" ID="ID_683548249" MODIFIED="1730900578353">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
l&#228;uft darauf hinaus,
</p>
<p>
nun den Umbau anzugehen
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#6f2328" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="366;-47;" ID="Arrow_ID_1067356199" STARTARROW="None" STARTINCLINATION="5;52;"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1730827998905" ID="ID_1794368282" MODIFIED="1730828011958" TEXT="Adapter-&#x3bb; bereitstellen">
<icon BUILTIN="flag-yellow"/>
</node>
@ -91620,10 +91901,43 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1728786359782" ID="ID_525505656" MODIFIED="1728786374933" TEXT="Spec und Seed generieren und verarbeiten">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1730835558270" TEXT="Umbau TestFrame">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1728786385349" ID="ID_442258905" MODIFIED="1730900564912" TEXT="Umbau TestFrame">
<arrowlink COLOR="#713558" DESTINATION="ID_257931093" ENDARROW="Default" ENDINCLINATION="-2466;135;" ID="Arrow_ID_121875527" STARTARROW="None" STARTINCLINATION="-2154;-229;"/>
<linktarget COLOR="#77313e" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="381;-48;" ID="Arrow_ID_1047269362" SOURCE="ID_936086670" STARTARROW="None" STARTINCLINATION="-36;80;"/>
<linktarget COLOR="#6f2328" DESTINATION="ID_442258905" ENDARROW="Default" ENDINCLINATION="366;-47;" ID="Arrow_ID_1067356199" SOURCE="ID_683548249" STARTARROW="None" STARTINCLINATION="5;52;"/>
<icon BUILTIN="pencil"/>
<node CREATED="1730900637026" ID="ID_1500320757" MODIFIED="1730904275397" TEXT="brauche Einflu&#xdf; auf den PRNG">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...im Hinblick auf Reproduzierbarkeit sollte die Voraussetzung geschaffen werden, einen Testfall au einem einzigen Seed zu speisen (auch wenn das weitere Framework f&#252;r derart reproduzierbare Testf&#228;lle noch nicht gegeben ist)
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#c4145f" DESTINATION="ID_25783469" ENDARROW="Default" ENDINCLINATION="6546;452;" ID="Arrow_ID_1019579428" STARTARROW="None" STARTINCLINATION="1769;146;"/>
</node>
<node CREATED="1730900645921" ID="ID_1469990348" MODIFIED="1730901263434" TEXT="brauche Umstellung des Headers">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
der Header sollte optional sein (und hinter den Daten liegen), aber die Gegenwart eines Headers sollte explizit erkennbar sein
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1730900658104" ID="ID_1382506504" MODIFIED="1730900815598" TEXT="brauche Daten-Pr&#xfc;fsumme auch nach Manipulation">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
bisher haben wir nur nach einem Standard generierte Serien von Zufallsdaten, das hei&#223;t, wir k&#246;nnten eine Speicher-Korruption erkennen, oder eben da&#223; diese Daten ge&#228;ndert wurden; was aber fehlt die die M&#246;glichkeit, <i>nach einer solchen &#196;nderung</i>&#160;den neuen Stand wieder durch eine Pr&#252;fsumme zu qualifizieren (wodurch man ein <i>erwartetes Ergebnis</i>&#160;feststellen k&#246;nnte)
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
</node>
@ -137843,6 +138157,107 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710186359368" ID="ID_765629285" MODIFIED="1710186365813" TEXT="Info">
<icon BUILTIN="info"/>
<node CREATED="1710186277136" ID="ID_336649935" LINK="https://en.cppreference.com/w/cpp/numeric/random" MODIFIED="1710186690629" TEXT="Standard-Lib: (pseudo)-random number generation"/>
<node CREATED="1730916530347" FOLDED="true" ID="ID_607929754" MODIFIED="1731115515196" TEXT="Probleme / Diskussion">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
&#160;
</p>
</body>
</html></richcontent>
<linktarget COLOR="#968bb0" DESTINATION="ID_607929754" ENDARROW="Default" ENDINCLINATION="-1401;152;" ID="Arrow_ID_682771755" SOURCE="ID_480480032" STARTARROW="None" STARTINCLINATION="-1300;91;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1730916541434" ID="ID_1186515484" MODIFIED="1730916550532" TEXT="nicht klar wie man &#xbb;korrekt&#xab; seeded">
<node CREATED="1730916551768" ID="ID_1877378489" LINK="https://www.pcg-random.org/posts/cpp-seeding-surprises.html" MODIFIED="1730917591055" TEXT="oft zitierter Blog-Artikel der dies problematisiert">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p http-equiv="content-type" content="text/html; charset=utf-8" class="byline author vcard">
Melissa .E. O'Neill
</p>
<p class="dateline">
<a href="https://www.pcg-random.org/posts/cpp-seeding-surprises.html#" rel="bookmark"><time class="published dt-published" datetime="2015-04-16T01:22:00-07:00" itemprop="datePublished" title="2015-04-16 01:22">
2015-04-16</time></a>
</p>
</body>
</html>
</richcontent>
<node CREATED="1730927161676" ID="ID_1870117805" MODIFIED="1730927175433" TEXT="die Autorin von PCG">
<arrowlink COLOR="#a9b4c1" DESTINATION="ID_595255954" ENDARROW="Default" ENDINCLINATION="228;0;" ID="Arrow_ID_1247304219" STARTARROW="None" STARTINCLINATION="228;25;"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1730916627654" ID="ID_307539744" LINK="https://simplecxx.github.io/2021/11/27/debunking-all-myths-about-mt19937.html" MODIFIED="1730916723282" TEXT="Widerspruch hierzu">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
&#187;Simple C++&#171; Dimitrij Mijoski&#160;&#160;2021-11<br /><br />
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1730921869936" ID="ID_897784412" MODIFIED="1730921874684" TEXT="Streitpunkte">
<node CREATED="1730921876360" ID="ID_1711092381" MODIFIED="1730922258576" TEXT="Wahrscheinlichkeit bestimmte (feste) Zahlen zu ziehen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Letztlich werde ich aus der Diskussion zu diesem Aspekt nicht klug. Zumindest aber sind nicht alle m&#246;glichen Ergebniszahlen sofort zu Beginn gleich wahrscheinlich; es wird auch immer wieder ein Zusammenhang impliziert mit dem Umfang des <i>internal state</i>, der beim Mersenne-Twister extrem gro&#223; ist (624 int). Festzuhalten bleibt, da&#223; ein PRNG eine gweisse <b>predictability</b> haben kann, und das hei&#223;t, man sollte sich niemals auf das Auftreten / nicht-auftreten bestimmter Zahlen verlassen. Die Eigenschaften zeigen sich erst im statistischen Durchschnitt. Will man eine echte Zufallszahl, mu&#223; man eine echte Zufallszahl nehmen
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1730922284177" ID="ID_1548923616" MODIFIED="1730922467479" TEXT="Der Zustandsraum f&#xfc;r m&#xf6;gliche Sequenzen ist durch den Seed begrenzt">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...das hei&#223;t, nur wenn man tats&#228;chlich mit 624 ints seeded, erreicht man alle m&#246;glichen Sequenzen. Wobei aber bereits zwei ints (2^64) f&#252;r die meisten praktischen Probleme mehr als genug sein sollte; problematisch wird das nur bei Simulationen und L&#246;sungssuche durch Monte-Carlo.
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1730922568811" ID="ID_1106941071" MODIFIED="1730922708295" TEXT="std::seed_seq mu&#xdf; eine Heap-Allokation machen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...darauf wird nirgends hingeweisen, und es gibt ein Interface, um einen Allokator einzuf&#252;hren. Kritisiert wird auch generell das Interface f&#252;r std::seed_seq &#8212; die Stichhaltigkeit dieser Kritik kann ich nicht beurteilen (anders als da&#223; es nicht &#8222;einfach&#8220; ist)
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1730922731765" ID="ID_648439878" MODIFIED="1730923152857" TEXT="die Standard-Implementierungen bieten keine gute Auswahl">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Es l&#228;uft darauf hinaus, den Mersenne-Twister in Form von std::mt19937 als &#187;default&#171; zu verwenden. Und der ist langsam, braucht viel Speicher und ist kompliziert zu seeden. Au&#223;erdem sind die gebotenen Distributions-Funktionen allesamt nicht portabel (sondern implementation-defined). Leider werden dann in der Diskussion (Reddit, Stackoverflow) diverse Favoriten genannt, f&#252;r die es dann stets auch wieder (ohne tiefere Expertise schwer nachpr&#252;fbare) Einw&#228;nde gibt. Die einzige Alternative, gegen die niemand wirklich etwas einzuwenden hatte (au&#223;er da&#223; es angeblich modernere / schnellere / coolere Alternativen g&#228;be) ist der allseits bekannte Jenkins jsf32
</p>
</body>
</html>
</richcontent>
</node>
</node>
</node>
<node CREATED="1730923153709" ID="ID_1131418575" LINK="https://www.reddit.com/r/cpp/comments/ecrnjl/can_we_do_better_than_the_mersenne_twister/" MODIFIED="1730924006139" TEXT="&quot;can we do better than mersenne?&quot;">
<node CREATED="1730924010003" ID="ID_406338445" LINK="https://burtleburtle.net/bob/rand/smallprng.html" MODIFIED="1730924059005" TEXT="Jenkins"/>
<node CREATED="1730924013155" ID="ID_1112820214" LINK="https://pracrand.sourceforge.net/RNG_engines.txt" MODIFIED="1730924281091" TEXT="PractRand"/>
<node CREATED="1730926918445" ID="ID_595255954" LINK="https://www.pcg-random.org/" MODIFIED="1730927175433" TEXT="PCG-Random">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_595255954" ENDARROW="Default" ENDINCLINATION="228;0;" ID="Arrow_ID_1247304219" SOURCE="ID_1870117805" STARTARROW="None" STARTINCLINATION="228;25;"/>
<node CREATED="1730929577122" HGAP="24" ID="ID_1482800255" MODIFIED="1730929596392" TEXT="ist ein Hobby-Projekt von ihr" VSHIFT="18"/>
<node CREATED="1730929582849" ID="ID_340137516" MODIFIED="1730929590956" TEXT="besteht den PractRand-Test"/>
<node CREATED="1730940355738" ID="ID_472584641" LINK="https://pcg.di.unimi.it/pcg.php" MODIFIED="1730940454177" TEXT="fachliche Kontroverse zwischen Melissa O&apos;Neill und Sebastiano Vigna"/>
</node>
</node>
</node>
</node>
<node CREATED="1710186369715" ID="ID_1826063920" MODIFIED="1710186378766" TEXT="Begriffe/Typen">
<node CREATED="1710186389857" ID="ID_1473096769" MODIFIED="1710186401416" TEXT="Generator (uniform random bit generator)">
@ -137874,6 +138289,9 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
<node CREATED="1710197680765" ID="ID_235148142" MODIFIED="1710197697107" TEXT="damit sind Portabilit&#xe4;ts- und Implementierungsfehler minimiert"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1730916497663" ID="ID_1307499120" MODIFIED="1730916516773" TEXT="Problem: Distributionen sind nicht portabel">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1710197778929" ID="ID_34841952" MODIFIED="1710197787371" TEXT="Engine &#xbb;linear-congruential&#xab;">
<node CREATED="1710197788537" ID="ID_1612784281" MODIFIED="1710197799179" TEXT=" nur m&#xe4;&#xdf;ig schnell"/>
<node CREATED="1710197799755" ID="ID_518732759" MODIFIED="1710197814433" TEXT="relativ kurze Zyklen (limitiert durch Storage)"/>
@ -140278,8 +140696,20 @@ unsigned int ThreadIdAsInt = *static_cast&lt;unsigned int*&gt;(static_cast&lt;vo
</node>
</node>
</node>
<node CREATED="1437693678626" HGAP="117" ID="ID_1536988357" MODIFIED="1557498707241" POSITION="left" TEXT="Doku" VSHIFT="-47">
<node CREATED="1437693687650" ID="ID_1484874437" MODIFIED="1557498707241" TEXT="Sound-Systeme">
<node BACKGROUND_COLOR="#d7cec4" CREATED="1437693678626" HGAP="136" ID="ID_1536988357" MODIFIED="1731199643025" POSITION="left" STYLE="bubble" VSHIFT="-39">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Dokumentation zu<br/>
Themenbereichen
</p>
</body>
</html></richcontent>
<edge COLOR="#61617d" STYLE="sharp_bezier"/>
<font NAME="SansSerif" SIZE="16"/>
<icon BUILTIN="list"/>
<node CREATED="1437693687650" ID="ID_1484874437" MODIFIED="1557498707241" STYLE="fork" TEXT="Sound-Systeme">
<node CREATED="1437693693617" ID="ID_955932218" LINK="https://wiki.debian.org/Sound" MODIFIED="1576282357932" TEXT="siehe die Debian-&#xdc;bersichtsseite">
<richcontent TYPE="NOTE"><html>
<head/>
@ -142814,7 +143244,109 @@ unsigned int ThreadIdAsInt = *static_cast&lt;unsigned int*&gt;(static_cast&lt;vo
<icon BUILTIN="bell"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1446480582168" FOLDED="true" HGAP="46" ID="ID_554745278" MODIFIED="1581813780309" TEXT="Release" VSHIFT="-5">
<node CREATED="1731199725257" HGAP="106" ID="ID_1040358172" MODIFIED="1731199778693" TEXT="Code-Basis" VSHIFT="23">
<icon BUILTIN="go"/>
<node CREATED="1731199757351" ID="ID_77153778" MODIFIED="1731199764674" TEXT="Struktur"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1731199766411" ID="ID_85428678" MODIFIED="1731201905778" TEXT="Aufgaben">
<icon BUILTIN="bell"/>
<node CREATED="1731199789772" ID="ID_1736261073" MODIFIED="1731199796691" TEXT="Copyrights">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1731199802350" FOLDED="true" ID="ID_1389575446" MODIFIED="1731201900295" TEXT="Datei-Pr&#xe4;ambel straffen und vereinheitlichen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1731199829027" ID="ID_1047831531" MODIFIED="1731199833428" TEXT="was ist notwendig?">
<node CREATED="1731199897754" ID="ID_1977560064" MODIFIED="1731201897705" TEXT="eigentlich gen&#xfc;gt eine Lizenz-Datei im Source-Root">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Wenn eine Codebasis als Sammlung von Quellen ver&#246;ffentlicht wird, <b>mu&#223;</b>&#160; der Lizenzhinweis prominent sichtbar direkt beim Zugang zur Quelle gegeben sein. <i>Die Ver&#246;ffentlichung ist rechtlich bindend.</i>&#160;Wenn die Ver&#246;ffentlichung in Form eines Quellbaumes erfolgt, dann mu&#223; das Lizenz-Statement direkt in der Wurzel liegen. Es deckt damit automatisch alle anderen Resourcen in dieser Distribution mit ab, auch wenn in diesen Ressourcen nichts weiter steht. Darin liegt aber eine latente Gefahr: wenn eine Resource ohne direkt angehefteten Lizenz-Marker in ein anderes Projekt kopiert wird, f&#228;llt sie unter dessen allgemeine Lizenzbestimmung. Fehlt jedwede allgemeine Lizenzbestimmung, dann tritt das jeweilige Copyright-Gesetz des Landes in Kraft, und das bedeutet praktisch &#252;berall auf der Welt: der Original-Autor hat die exclusiven Ver&#246;ffentlichungsrechte. Auf rechtlicher Ebene gilt stets, was sich feststellen und belegen l&#228;&#223;t, nicht was jemand beabsichtigt hat oder haben k&#246;nnte.
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1731199941276" ID="ID_1766701003" MODIFIED="1731200158808" TEXT="Pr&#xe4;ambel in jeder Datei wird empfohlen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...und zwar f&#252;r den Fall, da&#223; jemand eine in-sich geschlossene Quelldatei aus dem Projekt heraus kopiert; alle Hinweise direkt in der Datei erh&#246;hen die Wahrscheinlichkeit, da&#223; die Lizenzinformation nicht verlorengeht. Hinweise &#252;ber Haftungsausschlu&#223; und wo man die Lizenz bekommt sind nur eine Empfehlung und haben keine rechtliche Wirkung. Diese ensteht durch die Ver&#246;ffentlichung, und dazu gen&#252;gt ein Statement im Root des Quellbaumes. Diese Einsch&#228;tzung geht sogar aus den Hinweisen im Appendix der GPL selber hervor. Auch auf den Seiten der FSF wird zwar stark nahegelegt, den kopletten Pr&#228;ambel-Text einzuf&#252;gen, aber es handelt sich daber ohne jeden Zweifel nur um eine Empfehlung
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1731199834786" ID="ID_1475726687" MODIFIED="1731200681377" TEXT="ein Copyright-Claim mit initialem Jahr">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Wenn dieser Claim in jeder Quelldatei eigens gepflegt wird, erh&#246;ht das die Sicherheit der Verbindung von Copyright und Lizensierung. Allerdings auch nur, wenn dieser Claim korrekt ist. Es gen&#252;gt, den Zeitpunkt der allerersten signifikanten Sch&#246;pfung und Ver&#246;ffentlichung aufzuf&#252;hren, denn alle weiteren Beitr&#228;ge sind dann bereits durch die GPL gedeckt. Empfohlen wird, sp&#228;tere signifikante Beitr&#228;ge gesondert mit Jahreszahl aufzuf&#252;hren. Jahresbereiche sind nur sinnvoll, wenn in jedem der eingeschlossenen Jahre tats&#228;chlich etwas beigetragen wurde.
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1731199847273" ID="ID_555409518" MODIFIED="1731200959379" TEXT="ein Statement zur Lizenz">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Notwendig w&#228;re das nicht, aber hilfreich, wenn die Datei herausgel&#246;st wird. Es gen&#252;gt ein Hinweis auf die exakte Form der Lizenz. Man kenn &quot;this Program&quot; durch den expliziten Namen ersetzen. Man kann dazu noch auf die COPYING-Datei verweisen. Alle weiteren Infos, z.B. ein Haftungsausschlu&#223; sind nur empfohlen und &#228;ndern nicht die rechtliche Wirkung der Lizenz, unter der ver&#246;ffentlicht wurde
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1731200854085" ID="ID_1145620984" MODIFIED="1731200878179" TEXT="Vorschlag">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
<font face="Monospaced">/* </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;INDEX-ITER.hpp&#160;&#160;-&#160;&#160;iterator with indexed random-access to referred container </font>
</p>
<p>
</p>
<p>
<font face="Monospaced">&#160;&#160;Copyright (C) </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;&#160;&#160;2024,&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Hermann Vosseler &lt;Ichthyostega@web.de&gt; </font>
</p>
<p>
</p>
<p>
<font face="Monospaced">&#160;&#160;**Lumiera** is free software; you can redistribute it and/or modify it </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;under the terms of the GNU General Public License as published by the </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;Free Software Foundation; either version 2 of the License, or (at your </font>
</p>
<p>
<font face="Monospaced">&#160;&#160;option) any later version. See the file COPYING for further details. </font>
</p>
<p>
</p>
<p>
<font face="Monospaced">*/ </font>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="edit"/>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1446480582168" FOLDED="true" HGAP="67" ID="ID_554745278" MODIFIED="1581813780309" TEXT="Release" VSHIFT="39">
<icon BUILTIN="hourglass"/>
<node CREATED="1446480601381" ID="ID_1870415321" MODIFIED="1581813706345" TEXT="release prep: clean-up obsolete information">
<richcontent TYPE="NOTE"><html>