planning: consider implications of tree-diff application to arbitrary data structures

This commit is contained in:
Fischlurch 2016-02-19 01:13:44 +01:00
parent c0ee98d73d
commit 40b69e1fd2
3 changed files with 98 additions and 38 deletions

View file

@ -95,14 +95,14 @@ namespace diff{
* - \c after shortcut to \c pick existing elements up to the designated point.
* As a special notation, \c after(Ref::ATTRIBUTES) allows to fast forward
* to the first child element, while \c after(Ref::END) means to accept
* all of the existing data contents as-is (possibly to append further
* all of the existing data contents as-is (presumably to append further
* elements beyond that point).
* - \c mut bracketing construct to open a nested sub scope. The element
* designated by the ID of the argument needs to be a #Record
* ("nested child object"). Moreover, this element must have been
* mentioned with the preceding diff verbs at that level, which means
* that the element as such must already be present in the altered
* target structure. The \c mut(ID) verb then opens this nested
* - \c mut bracketing construct to open a nested sub scope, for mutation.
* The element designated by the ID of the argument needs to be a
* ["nested child object"](\ref Record). Moreover, this element must
* have been mentioned with the preceding diff verbs at that level,
* which means that the element as such must already be present in the
* altered target structure. The `mut(ID)` verb then opens this nested
* record for diff handling, and all subsequent diff verbs are to be
* interpreted relative to this scope, until the corresponding
* \c emu(ID) verb is encountered. As a special notation, right
@ -114,7 +114,7 @@ namespace diff{
* - \c emu bracketing construct and counterpart to \c mut(ID). This verb
* must be given precisely at the end of the nested scope (it is
* not allowed to "return" from the middle of a scope, for sake
* of sanity). At this point, ths child scope is left and the
* of sanity). At this point, this child scope is left and the
* parent scope with all existing diff state is popped from an
* internal stack
*/

View file

@ -8034,7 +8034,7 @@ Used this way, diff representation helps to separate structure and raw data in e
:Chunks of raw data are attached inline to the structural diff, assuming that each element implicitly knows the kind of data to expect
</pre>
</div>
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201510020048" tags="Model GuiPattern design draft" changecount="44">
<div title="TreeDiffImplementation" creator="Ichthyostega" modifier="Ichthyostega" created="201412210015" modified="201602190009" tags="Model GuiPattern design draft" changecount="54">
<pre>//This page details decisions taken for implementation of Lumiera's diff handling framework//
This topic is rather abstract, since diff handling is multi purpose within Lumiera: Diff representation is seen as a meta language and abstraction mechanism; it enables tight collaboration without the need to tie and tangle the involved implementation data structures. Used this way, diff representation reduces coupling and helps to cut down overall complexity -- so to justify the considerable amount of complexity seen within the diff framework implementation.
@ -8045,13 +8045,13 @@ Provided as a loosely coupled collection of tools in the namespace {{{lib::diff}
:*lightweight copyable values
:*equality comparable
:*bearing distinct identity
:*unique //as far as concerned//
:*unique //as far as relevant//
;data sequence
:any collection of data is delivered in the form of a sequence, which might or might not be //ordered,// but in any case will be traversed once only.
:any collection of data is delivered in the form of a sequence, which is //stable// (retains a given sequence order), and allows for defined traversal in that order.
;diff language
:a diff represents the changes necessary to transform an input sequence (&quot;old sequence&quot;) into a target sequence (&quot;new sequence&quot;)
:differences are spelled out in ''linearised form'': as a sequence of constant-size diff actions (called &amp;raquo;diff verbs&amp;laquo;)
:they are conceived as operations, which, when applied consuming the input sequence, will produce the target sequence of the diff.
:*differences are spelled out in ''linearised form'': as a sequence of constant-size diff actions (called &amp;raquo;diff verbs&amp;laquo;)
:*these are conceived as operations, which, when applied consuming the input sequence, will produce the target sequence of the diff.
!{{red{WIP 12/2014}}}building a list diff detector
transforming the algorithm sketch (&amp;rarr; see [[technical documentation|http://lumiera.org/documentation/technical/library/DiffFramework.html]]) into working code incurs some challenges at the level of technical details.
@ -8102,7 +8102,7 @@ __Questions for Design (6/15)__
Within this framework, we represent //object-like// entities through a special flavour of the GenNode: Basically, an object is a flat collection of children, yet given in accordance to a distinct ''object protocol''. The relevant ''meta'' information is spelled out first, followed by the ''attributes'' and finally the ''children''. The distinction between these lies in the mode of handling. Meta information is something we need to know before we're able to deal with the actual stuff. Prominent example is the type of the object. Attributes are considered unordered, and will typically be addressed by-name. Children are an ordered collection of recursive instances of the same data structure. (Incidentally, we do not rule out the possibility that also an attribute holds a recursive subtree; only the mode of access is what makes the distinction).
Here the question arises as to what extent the //language// needs to know about these object semantics. While a commitment for precision might lead us towards strict language definition, in fact, languages usable in practice need largely not be defined at all, since they are applied against a context. And since the use of the language itself might guide us from one context to another, the possibility of multiple levels of language arises. We use this observation as guideline and hint to keep our diff language open. Basically, it is just a sequence of verbs, which needs an actual interpreter implementation, which in turn naturally leads itself to attachment to some working context. At this point, we get a //binding// between sequences of language terms and the operational semantics, which in turn defines the limits of legal language constructs. As long as both sides agree upon the same structural conventions, the exchange works without strict codification. We should better strive at defining our object semantics precisely though. Any leeway can be allowed, as long as it conforms with the general layout and as long as it doesn't open the path to later confusion.
Here the question arises as to what extent the //language// needs to know about these object semantics. While a commitment for precision might lead us towards strict language definition, in fact, languages usable in practice need largely not be defined at all, since they are applied against a context. And since the use of the language itself might guide us from one context to another, the possibility of multiple levels of language arises. We use this observation as guideline and hint to keep our diff language open. Basically, it is just a sequence of verbs, which needs an actual interpreter implementation, which in turn naturally leads itself to attachment to some working context. At this point, we get a //binding// between sequences of language terms and the operational semantics, which in turn defines the limits of legal language constructs. As long as both sides agree upon the same structural conventions, the exchange works without strict codification. We should better strive at defining our object semantics precisely though. Any leeway can be allowed, as long as it conforms with the general layout and as long as it doesn't open a path to confusion later.
Based on these considerations we establish the &quot;two lists&quot; schematics:
* we make our objects look like lists of attributes and children
@ -8111,11 +8111,16 @@ Based on these considerations we establish the &quot;two lists&quot; schematics:
** metadata given by //magic attributes// (just a {{{&quot;type&quot;}}} attribute for now)
** occurrence of the first child switches from attribute zone to child scope
** children are recognisable by the form of their ID
Relying on these rules, we're able to arrive at a sensible binding systematically, while most of the implementation is just a specialisation of list diffing.
Relying on these rules, we're able to systematically build and derive a sensible binding, while most of the implementation is just a specialisation of list diffing.
!!!handling of actual mutation
This question is closely linked to the semantics of equality. In a simple list diff, this matter doesn't pose any problems; when an element is different, it is a different element, and this change can be encoded as a deletion and insertion of a new element. Not so in tree diff handling. We do not want to delete and re-build whole subtrees, because some tiny bit is altered somewhere down. Thus, a recursive sub-structure can be considered //the same entity,// yet still //mutated.// Our diff handling framework deals with the identity first, followed by an recourse into investigating //inner changes.// This recursive investigation is spelled out as a bracketed construct, which can be processed by recursive invocation. In the end, at the level of the tree leaves, handling those inner mutations boils down to invoking the //mutation closure,// as mentioned above. The knowledge of type context is thus confined to the receiving client, as long as every GenNode implementation offers support to detect an inner mutation and allows to install and invoke such a specifically typed closure to deal with the mutation. The twist to note is the point, //where// this closure is installed: it certainly doesn't make sense to install it on the generating side.
!!!conceptual mismatch
In the attempt to represent changes to a data structure in the form of //abstracted diff(erences),// we're facing a conceptual mismatch on two levels
* even a generic, [[DOM-like structure|ExternalTreeDescription]] has more inherent rigidity than is compatible with the notion of describing differences. //We'll have to reject some diffs//
* any real language-object implementation bears rich shades of semantics, which are impossible to represent symbolically. //We'll have to paraphrase and omit some aspects//
!!!use cases of tree diff application
Within the context of GuiModelUpdate, we discern two distinct situations necessitating an update driven by diff:
* a GenNode representing an object pulls diff information provided by Proc. This information contains mutations of attributes, and //some// of these attributes are relevant for the GUI and thus represented within the GuiModel
@ -8193,7 +8198,7 @@ On receiving the terms of this &quot;diff language&quot;, it is possible to gene
i.e. a ''unified diff'' or the ''predicate notation'' used above to describe the list diffing algorithm, just by accumulating changes.
</pre>
</div>
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201509300059" tags="Model Concepts GuiPattern design draft" changecount="53">
<div title="TreeMutator" creator="Ichthyostega" modifier="Ichthyostega" created="201503292115" modified="201602182152" tags="Model Concepts GuiPattern design draft" changecount="55">
<pre>The TreeMutator is an intermediary to translate a generic structure pattern into heterogeneous local invocation sequences.
!Motivation
@ -8257,11 +8262,11 @@ All these basic operations are implicitly stateful, i.e. they work against an as
!!!how to provide the actual operations
To ease the repetitive part of the wiring, which is necessary for each individual application case, we can allow for some degree of //duck typing,// as far as building the TreeMutator is concerned. If there is a type, which provides the above mentioned functions for child management, these can be hooked up automatically into a suitable adapter. Otherwise, the client may supply closures, using the same definition pattern as shown for the attributes above. Here, the ID argument is optional and denotes a //type filter,// whereas the closure itself must accept a name-ID argument. The purpose of this construction is the ability to manage collections of similar children. For example
{{{
.addChild(&quot;Fork&quot;), [&amp;](string type, string id) {
.addChild(&quot;Fork&quot;, [&amp;](string type, string id) {
ForkType kind = determineForkType(type);
this.forks_.push_back(MyForkImpl(kind, id);
})
.mutateChild(&quot;Fork&quot;), [&amp;](string id) {
.mutateChild(&quot;Fork&quot;, [&amp;](string id) {
MyForkImpl&amp; fork = findFork(id);
return fork.getMutator();
})
@ -8282,7 +8287,7 @@ Unfortunately, the {{{operator=}}} is right-associative in C++, with no option t
!!!Architecture
The distinguising trait or Lumiera's diff handling framework is to treat a //diff language// as a scope, where some verbs or predications gain a specific meaning. While a concrete {{{DiffApplicator}}} binds to a specific agent or target environment, the meaning of the binding remains implicit. This approach bears on the observation, that dealing with structural differences actually addresses //several layers of language.// An odered collection is one of them, some kind of object notion another one, and the exact meaning of structure yet another one.
The distinguising trait or Lumiera's diff handling framework is to treat a //diff language// as a scope, where some verbs or predications gain a specific meaning. While a concrete {{{DiffApplicator}}} binds to a specific agent or target environment, the meaning of the binding remains implicit. This approach draws upon the observation, that dealing with structural differences actually addresses //several layers of language.// An odered collection is one of them, some kind of object notion another one, and the exact meaning of structure yet another one.
In accordance with this understanding, the TreeMutator is shaped to form the attachment point of such a language construct onto a given structural context, which, through this very construct, remains opaque and thus decoupled. In the simple exemplary case of list diffing, the {{{DiffApplicator}}} requries the specialisation of some {{{DiffApplicationStrategy}}} to the concrete data container in use, most likely a STL {{{vector}}}. In a similar vein, a {{{DiffApplicator}}} for structural transformations requires the {{{DiffApplicationStrategy}}}'s specialisation to a TreeMutator. Which -- consequently -- needs to expose an API well suited to implement what a structural diff language might want to express. Yet, in addition, the TreeMutator also needs a binding API, allowing him to be linked into the actual structures subject to manipulation.

View file

@ -489,8 +489,7 @@
<i>noch einmal</i>&#160;implementieren
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
@ -514,8 +513,7 @@
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1455669004941" ID="ID_853385575" MODIFIED="1455669197237">
<richcontent TYPE="NODE"><html>
@ -530,8 +528,7 @@
des Tree-Mutators voraus
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
@ -544,8 +541,7 @@
ist jedoch schon prototypisch implementiert
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<node CREATED="1455669266289" ID="ID_476883926" MODIFIED="1455669272315" TEXT="hier kein expliziter Stack"/>
<node CREATED="1455669272760" ID="ID_837691598" MODIFIED="1455669282883" TEXT="sondern der Call-Stack ist der Stack (Rekursion)"/>
<node CREATED="1455669313986" ID="ID_1730130372" MODIFIED="1455669321877" TEXT="brauche generiischen Rahmen">
@ -558,7 +554,65 @@
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
<node CREATED="1455669221255" ID="ID_1712552545" MODIFIED="1455669237745" TEXT="Repr&#xe4;sentation der &quot;aktuellen Position&quot;"/>
<node CREATED="1455669345167" ID="ID_310849010" MODIFIED="1455669353721" TEXT="generischen Rahmen f&#xfc;r Mut-Operationen"/>
<node CREATED="1455669238213" ID="ID_731780565" MODIFIED="1455669252935" TEXT="Einleiten der Rekursion"/>
<node CREATED="1455669238213" ID="ID_731780565" MODIFIED="1455669252935" TEXT="Einleiten der Rekursion">
<node CREATED="1455842313629" ID="ID_179960248" MODIFIED="1455842321264" TEXT="ich h&#xe4;tte es gern echt-rekursiv"/>
<node CREATED="1455842321828" ID="ID_1622068738" MODIFIED="1455842336974" TEXT="widerspricht aber unserem DiffApplicator"/>
</node>
<node CREATED="1455833678448" HGAP="35" ID="ID_1439118587" MODIFIED="1455833692637" TEXT="Probleme" VSHIFT="6">
<icon BUILTIN="flag-pink"/>
<node CREATED="1455833736586" ID="ID_1233162987" MODIFIED="1455833741893" TEXT="Feld vs Attribut">
<node CREATED="1455834007278" ID="ID_196347476" MODIFIED="1455834009696" TEXT="Feld">
<node CREATED="1455834060110" ID="ID_1872959165" MODIFIED="1455834067177" TEXT="ist da per Struktur"/>
<node CREATED="1455834067837" ID="ID_944456076" MODIFIED="1455834075400" TEXT="hat immer einen Wert"/>
</node>
<node CREATED="1455834010264" ID="ID_1604005834" MODIFIED="1455834012705" TEXT="Attribut">
<node CREATED="1455834109112" ID="ID_879864381" MODIFIED="1455834119178" TEXT="wird per Key angesprochen"/>
<node CREATED="1455834121926" ID="ID_504132661" MODIFIED="1455834189337" TEXT="kann abwesend sein"/>
</node>
<node CREATED="1455834013389" ID="ID_133168935" MODIFIED="1455834058219" TEXT="Widerspr&#xfc;che">
<node CREATED="1455834227528" ID="ID_1606302361" MODIFIED="1455834231179" TEXT="Feld hinzuf&#xfc;gen"/>
<node CREATED="1455834231647" ID="ID_1275813367" MODIFIED="1455834236914" TEXT="Feld l&#xf6;schen"/>
<node CREATED="1455834237999" ID="ID_254859574" MODIFIED="1455834251313" TEXT="Feld suchen"/>
<node CREATED="1455834400273" ID="ID_54362263" MODIFIED="1455834403925" TEXT="Zuweisung"/>
<node CREATED="1455834252068" ID="ID_1918373755" MODIFIED="1455834285644" TEXT="Ordnung"/>
</node>
</node>
<node CREATED="1455833774965" ID="ID_677756898" MODIFIED="1455833794349" TEXT="&#xc4;ndern wider die Natur"/>
<node CREATED="1455833858794" ID="ID_483179827" MODIFIED="1455833863844" TEXT="zus&#xe4;tzliche Ordnungsstruktur"/>
<node CREATED="1455842653928" ID="ID_1996966445" MODIFIED="1455842665480">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Diff kennt keine <i>Zuweisung</i>
</p>
</body>
</html>
</richcontent>
<node CREATED="1455842674973" ID="ID_1910702757" MODIFIED="1455842682008" TEXT="L&#xf6;schen + Neueinf&#xfc;gen"/>
<node CREATED="1455842682524" ID="ID_1597781391" MODIFIED="1455842710444" TEXT="unn&#xf6;tiger Aufwand (Allokation)"/>
<node CREATED="1455842711008" ID="ID_1470911011" MODIFIED="1455842721083" TEXT="f&#xfc;hrt zu &quot;Flackern&quot; im UI"/>
<node CREATED="1455843001833" HGAP="46" ID="ID_617738816" MODIFIED="1455843009974" TEXT="L&#xf6;sungen" VSHIFT="16">
<node CREATED="1455843011048" ID="ID_1280199494" MODIFIED="1455843047471" TEXT="Spezialvereinbarung">
<node CREATED="1455843048699" ID="ID_1949875245" MODIFIED="1455843054766" TEXT="Einf&#xfc;gen des gleichen Attributes"/>
<node CREATED="1455843055122" ID="ID_880285017" MODIFIED="1455843061285" TEXT="geht nur unmittelbar danach"/>
<node CREATED="1455843061633" ID="ID_1466937234" MODIFIED="1455843065597" TEXT="geht nur mit Attributen"/>
</node>
<node CREATED="1455843068672" ID="ID_695348733" MODIFIED="1455843072795" TEXT="neues Verb">
<node CREATED="1455843074288" ID="ID_251586851" MODIFIED="1455843077987" TEXT="SET"/>
<node CREATED="1455843120961" ID="ID_1340712241" MODIFIED="1455843131556" TEXT="setzt Element-Identit&#xe4;t voraus"/>
<node CREATED="1455843134111" ID="ID_1830155209" MODIFIED="1455843174534" TEXT="funkioniert (theoretisch) auch bei Kindern"/>
<node CREATED="1455843262862" ID="ID_779223103" MODIFIED="1455843311047" TEXT="Frage: Auto-PICK">
<icon BUILTIN="help"/>
<node CREATED="1455843317119" ID="ID_755404987" MODIFIED="1455843331097" TEXT="Ja: aber was dann mit Umordnungen"/>
<node CREATED="1455843336405" ID="ID_1210482014" MODIFIED="1455843358109" TEXT="Nein: aber was dann wenn out-of-order"/>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
</node>
@ -1192,7 +1246,7 @@
</node>
</node>
<node CREATED="1448063874479" HGAP="43" ID="ID_739054690" MODIFIED="1453546352792" TEXT="UI-Modell" VSHIFT="1"/>
<node CREATED="1434128074725" FOLDED="true" HGAP="28" ID="ID_933994138" MODIFIED="1455421918775" TEXT="Diff-System" VSHIFT="1">
<node CREATED="1434128074725" FOLDED="true" HGAP="28" ID="ID_933994138" MODIFIED="1455842048164" TEXT="Diff-System" VSHIFT="1">
<font NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="pencil"/>
<node CREATED="1434128278990" ID="ID_106354755" MODIFIED="1434128283641" TEXT="Diff-Darstellung"/>
@ -2435,7 +2489,7 @@
<node CREATED="1443735643536" ID="ID_1397296376" MODIFIED="1443735648747" TEXT="nach Zonen geordnet"/>
</node>
<node CREATED="1443735736427" ID="ID_735577464" MODIFIED="1443735739943" TEXT="Konformit&#xe4;t">
<node CREATED="1443736349465" FOLDED="true" ID="ID_1312270317" MODIFIED="1443739939854" TEXT="strikt">
<node CREATED="1443736349465" FOLDED="true" ID="ID_1312270317" MODIFIED="1455841580926" TEXT="strikt">
<richcontent TYPE="NOTE"><html>
<head>
@ -2457,14 +2511,14 @@
<node CREATED="1443735750626" ID="ID_1965990187" MODIFIED="1443736021880" TEXT="erstes Kind er&#xf6;ffnet Scope"/>
<node CREATED="1443736449419" ID="ID_1376225902" MODIFIED="1443736603427" TEXT="danach Attribute wegsortieren"/>
<node CREATED="1443736688027" ID="ID_1189409086" MODIFIED="1443737477829" TEXT="Attribut-Handhabung">
<node CREATED="1443737483704" FOLDED="true" ID="ID_1359413673" MODIFIED="1443739954500" TEXT="Modell &quot;Liste&quot;">
<node CREATED="1443737483704" FOLDED="true" ID="ID_1359413673" MODIFIED="1455841883232" TEXT="Modell &quot;Liste&quot;">
<icon BUILTIN="button_ok"/>
<node CREATED="1443737510238" ID="ID_1135997794" MODIFIED="1443737510238" TEXT="Duplikate anh&#xe4;ngen"/>
<node CREATED="1443737516852" ID="ID_636329172" MODIFIED="1443737527750" TEXT="Einf&#xfc;gen erlauben"/>
<node CREATED="1443737528578" ID="ID_1554159544" MODIFIED="1443737538461" TEXT="Umordnen erlauben"/>
<node CREATED="1443737570229" ID="ID_28119998" MODIFIED="1443737576392" TEXT="L&#xf6;schen erfordert Ansteuern"/>
</node>
<node CREATED="1443737497870" FOLDED="true" ID="ID_113467015" MODIFIED="1443739953318" TEXT="Modell &quot;Map&quot;">
<node CREATED="1443737497870" FOLDED="true" ID="ID_113467015" MODIFIED="1455841885008" TEXT="Modell &quot;Map&quot;">
<icon BUILTIN="button_cancel"/>
<node CREATED="1443737705058" ID="ID_1320189713" MODIFIED="1443737716690" TEXT="Operationen an Storage delegieren"/>
<node CREATED="1443737578803" ID="ID_1670234515" MODIFIED="1443737602756" TEXT="Duplikate &#xfc;berschreiben"/>
@ -2472,7 +2526,7 @@
<node CREATED="1443737747941" ID="ID_1552219906" MODIFIED="1443737757207" TEXT="Umordnungen verweigern/ignorieren"/>
<node CREATED="1443737769122" ID="ID_697980786" MODIFIED="1443737777276" TEXT="L&#xf6;schen an beliebiger Stelle wirksam"/>
</node>
<node CREATED="1443738082216" FOLDED="true" HGAP="38" ID="ID_870184525" MODIFIED="1443739486557" TEXT="Abw&#xe4;gung" VSHIFT="7">
<node CREATED="1443738082216" FOLDED="true" HGAP="38" ID="ID_870184525" MODIFIED="1455841845325" TEXT="Abw&#xe4;gung" VSHIFT="7">
<icon BUILTIN="button_ok"/>
<node CREATED="1443738097022" ID="ID_1609921484" MODIFIED="1443738178020" TEXT="Modelle schlie&#xdf;en sich aus">
<richcontent TYPE="NOTE"><html>
@ -2528,7 +2582,7 @@
</body>
</html></richcontent>
</node>
<node CREATED="1443738592971" ID="ID_790837479" MODIFIED="1443739191673" TEXT="bei uns: hoch effizient">
<node CREATED="1443738592971" ID="ID_790837479" MODIFIED="1455841731908" TEXT="bei uns: hoch effizient">
<richcontent TYPE="NOTE"><html>
<head>
@ -2544,10 +2598,11 @@
kommen wir auf lineare Komplexit&#228;t f&#252;r die Verarbeitung
</p>
<p>
+ NlogN f &#252;r den Index zur Diff-Erzeugung
+ NlogN f&#252;r den Index zur Diff-Erzeugung
</p>
</body>
</html></richcontent>
</html>
</richcontent>
</node>
</node>
<node CREATED="1443738199160" ID="ID_955544777" MODIFIED="1443738201508" TEXT="Nachteile">
@ -2638,7 +2693,7 @@
</node>
</node>
</node>
<node CREATED="1443739215487" FOLDED="true" HGAP="42" ID="ID_1540836182" MODIFIED="1443739482884" TEXT="Entscheidung">
<node CREATED="1443739215487" FOLDED="true" HGAP="42" ID="ID_1540836182" MODIFIED="1455841419071" TEXT="Entscheidung">
<icon BUILTIN="info"/>
<node CREATED="1443739221631" ID="ID_338047062" MODIFIED="1443739227649" TEXT="&quot;Listen&quot;-Modell"/>
<node CREATED="1443739228542" ID="ID_773218806" MODIFIED="1443739244615" TEXT="eindeutig vorzuziehen"/>
@ -3064,7 +3119,7 @@
<icon BUILTIN="yes"/>
</node>
</node>
<node CREATED="1446159438278" FOLDED="true" HGAP="29" ID="ID_563496669" MODIFIED="1446356526122" VSHIFT="8">
<node CREATED="1446159438278" FOLDED="true" HGAP="29" ID="ID_563496669" MODIFIED="1455841217005" VSHIFT="8">
<richcontent TYPE="NODE"><html>
<head>