Library: verify proper working of logic constructs

uncovers some minor implementation bugs, as can be expected...
This commit is contained in:
Fischlurch 2024-03-26 02:29:24 +01:00
parent 3711bf185c
commit c0439b265c
3 changed files with 203 additions and 34 deletions

View file

@ -135,7 +135,7 @@ namespace lib {
iterNestedKeys (string key, string const& iterDef)
{
return explore (util::RegexSearchIter{iterDef, ACCEPT_DATA_ELM})
.transform ([&](smatch mat){ return key+"."+string{mat[1]}+"."; });
.transform ([key](smatch mat){ return key+"."+string{mat[1]}+"."; });
}
//-----------Syntax-for-key-value-data-from-string------
@ -424,6 +424,11 @@ namespace lib {
throw error::Invalid{_Fmt{"Conflicting ...%s${else} ⟷ ...%s|↯|${else}"}
% abbrev(clashLead()) % abbrev(lead())};
};
auto __checkClosed = [&] {
if (not scope_.empty())
throw error::Invalid{_Fmt{"Unclosed Logic tags: |↯|${end %s %s} missing"}
% scopeClause() % scopeKey()};
};
// Primitives used for code generation....
auto add = [&](Code c, string v){ actions.push_back (Action{c,v});};
@ -510,8 +515,11 @@ namespace lib {
StrView tail = parseIter->tail;
++parseIter;
if (not parseIter)
add (TEXT, string{tail});
} // add final action to supply text after last active tag
{//add final action to supply text after last active tag
add (TEXT, string{tail});
__checkClosed();
}
}
};
inline TextTemplate::ActionSeq
@ -611,7 +619,7 @@ namespace lib {
{
REQUIRE (iter);
DataSource nested{*this};
nested.keyPrefix_ = *iter;
nested.keyPrefix_ += *iter;
return nested;
}
};
@ -709,7 +717,7 @@ namespace lib {
, ctxStack_{}
, rendered_{}
{
instantiateNext();
rendered_ = instantiateNext();
}
/**
@ -798,7 +806,7 @@ namespace lib {
inline bool
TextTemplate::InstanceCore<SRC>::openIteration (string key)
{
if (dataSrc_.contains(key))
if (conditional (key))
if (DataCtxIter dataIter = dataSrc_.getSequence(key))
{
ctxStack_.push (NestedCtx{move (dataIter)

View file

@ -34,8 +34,6 @@
#include "lib/test/diagnostic-output.hpp"///////////////////////TODO
#include "lib/stat/csv.hpp"
//#include <chrono>
//#include <array>
#include <map>
//using std::array;
@ -71,7 +69,6 @@ namespace test {
simpeUsage();
verify_parsing();
verify_instantiation();
verify_keySubstituton();
verify_conditional();
verify_iteration();
verify_Map_binding();
@ -350,12 +347,18 @@ for} tail...
VERIFY_FAIL ("Conflicting ... precipitous ${else} ⟷ ... callous |↯|${else}"
, TextTemplate::compile("${if smarmy} precipitous ${else} callous ${else} horror"));
VERIFY_FAIL ("Unclosed Logic tags: |↯|${end if sleazy} missing"
, TextTemplate::compile("${if sleazy} precipitous ${else} horror"));
VERIFY_FAIL ("Unclosed Logic tags: |↯|${end for horror} missing"
, TextTemplate::compile("${for horror}${if flimsy} atrocious ${end if} precipitous"));
}
/** @test TODO Compile a template and instantiate with various data bindings.
* @todo WIP 4/24 🔁 define implement
/** @test Compile a template and instantiate with various data bindings.
* @todo WIP 4/24 define implement
*/
void
verify_instantiation()
@ -367,34 +370,81 @@ for} tail...
auto insta = temple.submit (string{"phi=Φ, b=b, a=a"});
CHECK (not isnil(insta));
CHECK (join(insta,"") == "⁐a⁐ / ⁐b⁐ = (⁐a⁐ + ⁐b⁐)/⁐a⁐ ≕ ⁐Φ⁐"_expect);
CHECK (temple.render("phi=Φ,a=μ,b=ν") == "μ / ν = (μ + ν)/μ ≕ Φ"_expect );
CHECK (temple.render("phi=schmuh,a=8,b=5") == "8 / 5 = (8 + 5)/8 ≕ schmuh"_expect);
CHECK (temple.render("phi=1.6180,a=55,b=34") == "55 / 34 = (55 + 34)/55 ≕ 1.6180"_expect);
}
/** @test TODO
* @todo WIP 4/24 🔁 define implement
*/
void
verify_keySubstituton()
{
UNIMPLEMENTED ("nebbich");
}
/** @test TODO
* @todo WIP 4/24 🔁 define implement
/** @test Segments of the text-template can be included
* conditionally, based on interpretation of a controlling key
* @todo WIP 4/24 define implement
*/
void
verify_conditional()
{
TextTemplate t1{"Value ${if val}= ${val} ${else}missing${endif}..."};
CHECK (t1.render("val=55") == "Value = 55 ..."_expect );
CHECK (t1.render("val=\"\"") == "Value missing..."_expect); // empty value counts as false
CHECK (t1.render("val=\" \"") == "Value = ..."_expect ); // one space counts as content (=true)
CHECK (t1.render("val=false") == "Value missing..."_expect); // various bool-false tokens recognised
CHECK (t1.render("val=NO" ) == "Value missing..."_expect);
CHECK (t1.render("val= 0 " ) == "Value missing..."_expect);
CHECK (t1.render("val=true") == "Value = true ..."_expect); // bool true token treated as content
CHECK (t1.render("vol=high") == "Value missing..."_expect); // missing key treated as false
TextTemplate t2{"Solution${if val} is ${val} ${endif val}..."};
CHECK (t2.render("val=42") == "Solution is 42 ..."_expect );
CHECK (t2.render("nil=42") == "Solution..."_expect );
TextTemplate t3{" 1 ${if a} 2 ${if b} 3 ${else} ${b} ${endif b} 4 ${else}${if a} 5 ${else} ${a} ${endif a}${endif a} 6 "};
CHECK (t3.render("a=2,b=3") == " 1 2 3 4 6 "_expect ); // ^^^^^ Note can never be true here
CHECK (t3.render("a=2,b=0") == " 1 2 0 4 6 "_expect );
CHECK (t3.render("a=0,b=3") == " 1 0 6 "_expect ); // thus if a ≙ false we see only 1 §{a} 6
CHECK (t3.render("a=0,b=0") == " 1 0 6 "_expect );
}
/** @test TODO
* @todo WIP 4/24 🔁 define implement
/** @test Segments of the text-template can be iterated...
* - there is a control-key to guide the iteration
* - how this key translates into nested data scopes
* is defined by the implementation of the data binding
* - for this test we use the Map-binding, which synthesises
* key prefixes and expects bindings for those decorated keys
* - typically, keys in inner scopes will shadow outer keys,
* as is here demonstrated with the "x" key at top level
* - loops and conditionals can be nested
* @todo WIP 4/24 define implement
*/
void
verify_iteration()
{
TextTemplate t1{"▶${for i} ${x} ▷${else} ∅${end for} ◇ ${i} ▶"};
CHECK (t1.render("i=\"1,2,3\", i.1.x=3, i.2.x=5, i.3.x=8 ") == "▶ 3 ▷ 5 ▷ 8 ▷ ◇ 1,2,3 ▶"_expect ); // fully defined
CHECK (t1.render("i=\"3,1,2\", i.1.x=3, i.2.x=5, i.3.x=8 ") == "▶ 8 ▷ 3 ▷ 5 ▷ ◇ 3,1,2 ▶"_expect ); // order changed
CHECK (t1.render("i=\"3,2,3\", i.1.x=3, i.2.x=5, i.3.x=8 ") == "▶ 8 ▷ 5 ▷ 8 ▷ ◇ 3,2,3 ▶"_expect ); // duplicate entities
CHECK (t1.render("i=\"3,2,1\", i.2.x=5, i.3.x=8 ") == "▶ 8 ▷ 5 ▷ ▷ ◇ 3,2,1 ▶"_expect ); // missing key for entity-1
CHECK (t1.render("i=\"3,2,1\", x=↯, i.2.x=5, i.3.x=8 ") == "▶ 8 ▷ 5 ▷ ↯ ▷ ◇ 3,2,1 ▶"_expect ); // top-level key "x" partially shadowed
CHECK (t1.render("i=\"p,q,r\", x=↯, i.q.x=5, i.3.x=8 ") == "▶ ↯ ▷ 5 ▷ ↯ ▷ ◇ p,q,r ▶"_expect ); // arbitrary names for the entities
CHECK (t1.render("i= 0 , x=↯, i.q.x=5, i.3.x=8 ") == "▶ ∅ ◇ 0 ▶"_expect ); // "0" is false, thus no iteration
CHECK (t1.render(" x=↯, i.q.x=5, i.3.x=8 ") == "▶ ∅ ◇ ▶"_expect ); // no binding for iteration-control key i
TextTemplate t2{"▶${for i}${if x}${for j}${x}▷${else}${x}●${end for j}${end if x} 🔁 ${end for i} ▶"};
CHECK (t2.render("i=\"1,2\",j=\"1,2\", x=1 , i.1.j.1.x=11, i.1.j.2.x=12, i.2.j.1.x=21, i.2.j.2.x=22") == "▶11▷12▷ 🔁 21▷22▷ 🔁 ▶"_expect );
CHECK (t2.render("i=\"1,2\",j=\"1,2\", i.1.x=1, i.1.j.1.x=11, i.1.j.2.x=12, i.2.j.1.x=21, i.2.j.2.x=22") == "▶11▷12▷ 🔁 🔁 ▶"_expect );
CHECK (t2.render("i=\"1,2\" , x=00 , i.1.j.1.x=11, i.1.j.2.x=12, i.2.j.1.x=21, i.2.j.2.x=22") == "▶00● 🔁 00● 🔁 ▶"_expect );
CHECK (t2.render("i=\"1,2\" , x=00 , i.1.x =10, i.2.x =20, ") == "▶10● 🔁 20● 🔁 ▶"_expect );
CHECK (t2.render(" j=\"1,2\" ") == "▶ ▶"_expect );
CHECK (t2.render(" ") == "▶ ▶"_expect );
}

View file

@ -112933,7 +112933,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node CREATED="1710856716918" ID="ID_1752947576" MODIFIED="1710856723204" TEXT="r&#xfc;ckw&#xe4;rts vorgehen">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1710856729291" FOLDED="true" ID="ID_1875406462" MODIFIED="1711336349160" TEXT="die Instantiierung erfolgt lazy &#x27f9; Iterator-Pipeline">
<node COLOR="#338800" CREATED="1710856729291" FOLDED="true" ID="ID_1875406462" MODIFIED="1711422512870" TEXT="die Instantiierung erfolgt lazy &#x27f9; Iterator-Pipeline">
<icon BUILTIN="button_ok"/>
<node CREATED="1710856916531" ID="ID_1047340326" MODIFIED="1710856926342" TEXT="die ActionSeq konsumieren"/>
<node CREATED="1710857877562" ID="ID_707601175" MODIFIED="1710857911451" TEXT="Instantiierungs-Prozessor : function-mapping"/>
@ -113044,6 +113044,65 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node COLOR="#435e98" CREATED="1711327193389" ID="ID_916304521" MODIFIED="1711329584228" TEXT="false &#x27f8; wenn Iterationsende und Sub-Kontext wieder geschlossen"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1711422529847" ID="ID_1508406926" MODIFIED="1711430394240" TEXT="Fehler im Test">
<linktarget COLOR="#cc1b4e" DESTINATION="ID_1508406926" ENDARROW="Default" ENDINCLINATION="-826;130;" ID="Arrow_ID_1713125172" SOURCE="ID_1960745987" STARTARROW="None" STARTINCLINATION="163;-13;"/>
<icon BUILTIN="messagebox_warning"/>
<node COLOR="#435e98" CREATED="1711421996815" ID="ID_655708616" MODIFIED="1711427161933" TEXT="Segfault">
<icon BUILTIN="broken-line"/>
<node CREATED="1711422594855" ID="ID_1879348202" MODIFIED="1711422626062" TEXT="Lambda f&#xfc;r Parsen der Loop-steuer-Def hat den key per ref gebunden"/>
<node CREATED="1711422627122" ID="ID_764195158" MODIFIED="1711422644756" TEXT="der ist aber ein Funktions-Argument, also zur Auswertungszeit des Iterators nicht mehr da"/>
</node>
<node COLOR="#435e98" CREATED="1711422646456" ID="ID_1796895529" MODIFIED="1711427158733" TEXT="Endlosschleife">
<icon BUILTIN="broken-line"/>
<node CREATED="1711423880248" ID="ID_1259614532" MODIFIED="1711423891916" TEXT="die Schleife selber funktioniert wie intendiert"/>
<node COLOR="#5b280f" CREATED="1711423892649" ID="ID_1394348462" MODIFIED="1711423918337" TEXT="die JUMP-Action hinter dem Schleifen-Ende hat refIDX = 0">
<icon BUILTIN="broken-line"/>
<node CREATED="1711423922501" ID="ID_1277866015" MODIFIED="1711423937167" TEXT="keinwunderda&#xdf;erdal&#xe4;ngerl&#xe4;uft...">
<icon BUILTIN="smiley-oh"/>
</node>
<node CREATED="1711424688240" ID="ID_1873166142" MODIFIED="1711424693035" TEXT="wa-Rum?">
<node CREATED="1711424703077" ID="ID_261676191" MODIFIED="1711424708409" TEXT="Code sieht korrekt aus"/>
<node CREATED="1711424709924" ID="ID_109560395" MODIFIED="1711424726910" TEXT="best&#xe4;tigt(Debugger): schon im Parser stimmt die Verlinkung nicht"/>
</node>
<node CREATED="1711424732696" ID="ID_1762660183" MODIFIED="1711424752827" TEXT="Ha! Postfix = &quot; {end for}&quot;"/>
<node COLOR="#5b280f" CREATED="1711424753679" ID="ID_993415231" MODIFIED="1711424783564" TEXT="ich hab das End-Tag nicht richtig geschrieben">
<icon BUILTIN="closed"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1711424785642" ID="ID_1760059190" MODIFIED="1711424804568" TEXT="deshalb wurde die Verlinkung einfach nie ausgef&#xfc;llt">
<icon BUILTIN="info"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1711424806399" ID="ID_306190348" MODIFIED="1711425486013" STYLE="fork" TEXT="da fehlt eine Fehlermeldung">
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1711425416214" ID="ID_835870610" MODIFIED="1711425427395" TEXT="kann man leicht in den Compiler einbauen"/>
<node CREATED="1711425428202" ID="ID_461061819" MODIFIED="1711425439031" TEXT="ganz am Ende, wenn das Postfix angef&#xfc;gt wurde"/>
<node COLOR="#338800" CREATED="1711425440851" ID="ID_411681205" MODIFIED="1711425456212" TEXT="innersten noch offenen Scope ausgeben">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711425463856" ID="ID_229463353" MODIFIED="1711425469933" TEXT="Test erg&#xe4;nzen">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#dfcea9" COLOR="#435e98" CREATED="1711427164058" ID="ID_1041347901" MODIFIED="1711427218065" TEXT="bool-Auswertung fehlt vor Iteration">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1711427222132" ID="ID_1449836758" MODIFIED="1711427230943" TEXT="sollte nicht nur pr&#xfc;fen ob es den Key gibt"/>
<node CREATED="1711427231705" ID="ID_1684885250" MODIFIED="1711427243365" TEXT="sondern auch ob er nicht als &quot;false&quot; zu deuten ist"/>
<node COLOR="#338800" CREATED="1711427247193" ID="ID_1504951696" MODIFIED="1711427256435" TEXT="kann einfach an conditional(key) delegieren">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1711430266969" ID="ID_223278898" MODIFIED="1711430285901" TEXT="nested key decoration broken">
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1711430287964" ID="ID_1230421271" MODIFIED="1711430322146" TEXT="sollte funktionieren, da wir immer vom &#xe4;u&#xdf;eren Scope aus absteigen">
<icon BUILTIN="help"/>
</node>
<node COLOR="#338800" CREATED="1711430324212" ID="ID_184273294" MODIFIED="1711430385917" TEXT="Ha! nested.keyPrefix_&#xfc;bersschrieben &#x2014; anstatt es zu konkatenieren">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#dfe0aa" COLOR="#0f4569" CREATED="1711330603683" ID="ID_296531042" MODIFIED="1711335981711" TEXT="brauche zumindest elementares MapS-Binding">
<arrowlink COLOR="#b54881" DESTINATION="ID_702455242" ENDARROW="Default" ENDINCLINATION="-279;-482;" ID="Arrow_ID_1670013683" STARTARROW="None" STARTINCLINATION="-190;11;"/>
@ -113111,7 +113170,7 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1710856784967" ID="ID_201927694" MODIFIED="1711377572718" TEXT="Parsing soll eager sein (wegen Syntax-Fehlern)">
<node COLOR="#338800" CREATED="1710856784967" FOLDED="true" ID="ID_201927694" MODIFIED="1711377572718" TEXT="Parsing soll eager sein (wegen Syntax-Fehlern)">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1711057133538" ID="ID_1870486170" MODIFIED="1711312266549" TEXT="versuche aber trotzdem ein Pipeline-Design">
<richcontent TYPE="NOTE"><html>
@ -113622,8 +113681,8 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node COLOR="#435e98" CREATED="1711322831209" ID="ID_1835045684" MODIFIED="1711322849605" TEXT="auch f&#xfc;r leere Tags"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710793507744" ID="ID_1535977723" MODIFIED="1711385697214" TEXT="verify_instantiation">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1710793507744" ID="ID_1535977723" MODIFIED="1711421968205" TEXT="verify_instantiation">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1711385671550" ID="ID_723905669" MODIFIED="1711385695507" TEXT="erstes einfaches Beispiel mit reiner Substitution">
<icon BUILTIN="button_ok"/>
</node>
@ -113633,15 +113692,67 @@ std::cout &lt;&lt; tmpl.render({&quot;what&quot;, &quot;World&quot;}) &lt;&lt; s
<node COLOR="#338800" CREATED="1711385683468" ID="ID_1138359217" MODIFIED="1711385691931" TEXT="demonstriere den Iterator">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711421971683" ID="ID_861228445" MODIFIED="1711421985324" TEXT="demonstriere Substitution mit verschiedenen Datenwerten">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710793450480" ID="ID_703630650" MODIFIED="1710793457496" TEXT="verify_keySubstituton">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710793458511" ID="ID_1365018556" MODIFIED="1710793492318" TEXT="verify_conditional">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#5b280f" CREATED="1710793450480" ID="ID_703630650" MODIFIED="1711421894062" TEXT="verify_keySubstituton">
<icon BUILTIN="button_cancel"/>
<node CREATED="1711421895581" HGAP="22" ID="ID_1243542741" MODIFIED="1711421913669" TEXT="ist redundant (bereits mit der instantiation abgedeckt)" VSHIFT="3"/>
</node>
<node COLOR="#338800" CREATED="1710793458511" ID="ID_1365018556" MODIFIED="1711421966452" TEXT="verify_conditional">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1711421916565" ID="ID_76645182" MODIFIED="1711421959262" TEXT="einfaches if-then-else">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711421943934" ID="ID_963387515" MODIFIED="1711421959261" TEXT="Interpretation der Datenwerte in bool">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711421925505" ID="ID_1492589933" MODIFIED="1711421959261" TEXT="nur conditional ohne else">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711421936615" ID="ID_1902863277" MODIFIED="1711421959261" TEXT="verschachtelte conditionals">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1710793497322" ID="ID_1570698863" MODIFIED="1711430569216" TEXT="verify_iteration">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1711422519921" ID="ID_1960745987" MODIFIED="1711430403263" TEXT="funktioniert noch nicht">
<arrowlink COLOR="#cc1b4e" DESTINATION="ID_1508406926" ENDARROW="Default" ENDINCLINATION="-826;130;" ID="Arrow_ID_1713125172" STARTARROW="None" STARTINCLINATION="163;-13;"/>
<icon BUILTIN="broken-line"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#fffee5" CREATED="1711430573352" HGAP="30" ID="ID_318954589" MODIFIED="1711430606039" TEXT="das war ergiebig: diverse Bugs erschlagen" VSHIFT="9">
<font NAME="SansSerif" SIZE="11"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1711430409118" ID="ID_1641567471" MODIFIED="1711430612564" TEXT="eine Loop mit Conditionals">
<node COLOR="#338800" CREATED="1711430420469" ID="ID_1599001890" MODIFIED="1711430472758" TEXT="Auswahl der Entity-Keys">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430430036" ID="ID_895752732" MODIFIED="1711430472758" TEXT="Reihenfolge &#xe4;ndern">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430437027" ID="ID_48711571" MODIFIED="1711430472759" TEXT="Umgang mit fehlenden Entity-Keys">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430445937" ID="ID_111533213" MODIFIED="1711430472759" TEXT="Shaddowing eines gleichnamigen Key im &#xe4;u&#xdf;eren Scope">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430459351" ID="ID_633112221" MODIFIED="1711430472760" TEXT="bool-Evaluation ob die Iteration &#xfc;berhaupt stattfindet">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1711430475525" ID="ID_510959655" MODIFIED="1711430612564" TEXT="zwei verschachtelte Loops">
<node COLOR="#338800" CREATED="1711430488535" ID="ID_1372680090" MODIFIED="1711430565865" TEXT="Entity-Keys m&#xfc;ssen mit dem zusammengesetzten Pfad dekoriert sein">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430515005" ID="ID_280429390" MODIFIED="1711430565866" TEXT="Auslassen der Iterations-Definition f&#xfc;r eine Ebene">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1711430547788" ID="ID_1644200252" MODIFIED="1711430565866" TEXT="Mischung mit einem Conditional zwischen den Schleifenebenen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710793497322" ID="ID_1570698863" MODIFIED="1710793501637" TEXT="verify_iteration">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710793522467" ID="ID_1713123157" MODIFIED="1710793546412" TEXT="verify_Map_binding">
<linktarget COLOR="#d00f57" DESTINATION="ID_1713123157" ENDARROW="Default" ENDINCLINATION="104;-13;" ID="Arrow_ID_413173793" SOURCE="ID_1349211278" STARTARROW="None" STARTINCLINATION="-338;-54;"/>