• Aucun résultat trouvé

A New Self-Stabilizing Minimum Spanning Tree Construction with

N/A
N/A
Protected

Academic year: 2022

Partager "A New Self-Stabilizing Minimum Spanning Tree Construction with"

Copied!
19
0
0

Texte intégral

(1)

c The British Computer Society 2015. All rights reserved.

For Permissions, please email: [email protected] doi:10.1093/comjnl/bxv110

A New Self-Stabilizing Minimum Spanning Tree Construction with

Loop-Free Property

Lélia Blin

1∗

, Maria Potop-Butucaru

2

, Stéphane Rovedakis

3

and Sébastien Tixeuil

4

1Sorbonne Universités, UPMC Univ Paris 06, CNRS, Université d’Evry-Val-d’Essonne, LIP6 UMR 7606, 4 place Jussieu 75005, Paris, France

2Sorbonne Universités, UPMC Univ Paris 06, CNRS, LIP6 UMR 7606, 4 place Jussieu 75005, Paris, France

3CEDRIC, Conservatoire National des Arts et Métier, Paris, France

4Sorbonne Universités, UPMC Univ Paris 06, CNRS, Institut universitaire de France, LIP6 UMR 7606, 4 place Jussieu 75005, Paris, France

Corresponding author: [email protected]

The minimum spanning tree (MST) construction is a classical problem in Distributed Computing for creating a globally minimized structure distributedly. Self-stabilization is versatile technique for forward recovery that permits to handle any kind of transient faults in a unified manner. The loop-free property provides interesting safety assurance in dynamic networks where edge-cost changes during operation of the protocol. We present a new self-stabilizing MST protocol that improves on previous known approaches in several ways. First, it makes fewer system hypotheses as the size of the network (or an upper bound on the size) neednotbe known to the participants. Secondly, it is loop-free in the sense that it guarantees that a spanning tree structure is always preserved while edge costs change dynamically and the protocol adjusts to a new MST. Finally, time complexity matches the best known

results, while space complexity results show that this protocol is the most efficient to date.

Keywords: self-stabilizing algorithm; loop-free property; minimum spanning tree construction Received 16 February 2015; revised 22 October 2015

Handling editor: Iain Stewart

1. INTRODUCTION

Since its introduction in a centralized context [1,2], the min- imum spanning tree (MST) construction problem gained a benchmark status in distributed computing thanks to the influ- ential seminal work of [3]. Given an edge-weighted graph G=(V,E,w), wherewdenotes the edge-weight function, the MST problem consist in computing a treeT spanningV, such thatThas minimum weight among all spanning trees ofG.

One of the most versatile techniques to ensure forward recov- ery of distributed systems is that ofself-stabilization [4, 5].

A distributed algorithm is self-stabilizing if after faults and attacks hit the system and place it in some arbitrary global state, the system recovers from this catastrophic situation without external (e.g. human) intervention in finite time. A recent trend in self-stabilizing research is to complement

the self-stabilizing abilities of a distributed algorithm with some additionalsafetyproperties that are guaranteed when the permanent and intermittent failures that hit the system satisfy some conditions. In addition to being self-stabilizing, a pro- tocol could thus also tolerate a limited number of topology changes [6], crash faults [7,8], nap faults [9,10], Byzantine faults [11,12] and sustained edge cost changes [13,14].

This last property is especially relevant when building span- ning trees in dynamic networks, since the cost of a particular edge is likely to evolve through time. If an MST protocol is onlyself-stabilizing, it may adjust to the new costs in such a way that a previously constructed MST evolves into a discon- nected or a looping structure (of course, in the absence of new edge cost changes, the self-stabilization property guarantees thateventuallya new MST is constructed). Of course, if edge The Computer Journal Advance Access published December 9, 2015

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(2)

costs change unexpectedly and continuously, an MST cannot be maintained at all times. Now, a packet routing algorithm is loop free[15,16] if at any point in time the routing tables are free of loops, despite possible modification of the edge-weights in the graph (i.e. for any two nodesuandv, the actual routing tables determines a simple path fromutov, at any time). The loop-freeproperty [13,14] in self-stabilization guarantees that, a spanning tree being constructed (not necessarily an MST), then the self-stabilizing convergence to a ‘minimal’ (for some metric) spanning tree maintains a spanning tree at all times (obviously, this spanning tree is not ‘minimal’ at all times).

The consequence of this safety property in addition to that of self-stabilization is that the spanning tree structure can still be used (e.g. for routing) while the protocol is adjusting, and makes it suitable for networks that undergo such very frequent dynamic changes.

Related works. Gupta and Srimani [17] have presented the first self-stabilizing algorithm for the MST problem. It applies on graphs whose nodes have unique identifiers, whose edges have integer edge weights, and a weight can appear at most once in the whole network. To construct the (unique) MST, every node performs the same algorithm. The MST construction is based on the computation of all the shortest paths (for a certain cost function) between all the pairs of nodes. While executing the algorithm, every node stores the cost of all paths from it to all the other nodes. To implement this algorithm, the authors assume that every node knows the numbernof nodes in the network, and that the identifiers of the nodes are in{1,. . .,n}. Every nodeu stores the weight of the edgeeu,v placed in the MST for each nodev=u. Therefore, the algorithm requires v=ulogw(eu,v)

bits of memory at nodeu. Since all the weights are distinct integers, the memory requirement at each node is(nlogn)bits.

Higham and Liang [18] have proposed another self- stabilizing algorithm for the MST problem. As in [17], their work applies to undirected connected graphs with unique inte- ger edge weights and unique node identifiers, where every node has an upper bound on the number of nodes in the system. The algorithm performs roughly as follows: every edge aims at deciding whether it eventually belongs to the MST or not. For this purpose, every non tree-edgeefloods the network to find a potential cycle, and whenereceives its own message back along a cycle, it uses information collected by this message (i.e. the maximum edge weight of the traversed cycle) to decide whetherecould potentially be in the MST or not. If the edge ehas not received its message back after the time-out inter- val, it decides to become tree edge. The core memory of each node holds onlyO(logn)bits, but the information exchanged between neighboring nodes is of size O(nlogn) bits, thus only slightly improving that of [17]. The time complexity of the algorithm in [19] isO(n2)but the memory increases to O(log2n). The algorithm of this paper is not loop-free, but is the first paper implementing the algorithm [3] in a self-stabilizing manner without using a general transformer. It is also the first

paper using labeling schemes (nearest common ancestor) for the design of a self stabilizing MST protocol.

To our knowledge, none of the self-stabilizing MST con- struction protocols is loop-free. Since the aforementioned two protocols also make use of the knowledge of the global number of nodes in the system, and assume that no two edge costs can be equal, these extra hypotheses make them suitable for static networks only.

Relatively few works investigate merging self-stabilization and loop free routing, with the notable exception of [13,14].

The first solution to the problem is due to Cobb and Gouda [13], yet requires that an upper bound on the network diameter is known to every participant. No such assumption is made in [14]. Also, both protocols use only a reasonable amount of memory (O(logn) bits per node). However, the metrics that are considered in [13,14] are derivative of the shortest path (a.k.a.SP) metric, that is considered a much easier task in the distributed setting than that of the MST, since the associated metric islocally optimizable[20], allowing essentially locally greedy approaches to perform well. In contrast, some sort of global optimization is needed for MST, which often drives higher complexity costs and thus less flexibility in dynamic networks.

Our contributions. We describe a new self-stabilizing algorithm for the MST problem. Contrary to previous self- stabilizing MST protocols, our algorithm does not make any assumption about the network size (including upper bounds) or the unicity of the edge weights. Moreover, our solution improves on the memory space usage since each participant needs onlyO(logn)bits,1and node identifiers are not needed.

In addition to improving over system hypotheses and com- plexity, our algorithm provides additional safety properties to self-stabilization, as it is loop-free. Compared with previ- ous protocols that are both self-stabilizing and loop-free, our protocol is the first to consider non-monotonous tree metrics.

The key techniques that are used in our scheme include fast construction of a spanning tree, that is continuously improved by means of a pre-order construction over the nodes. The cycles that are considered over time are precisely those obtained by adding one edge to the evolving spanning tree. Considering solely that type of cycles reduces the memory requirement at each node compared with [17,18] because the latter con- sider all possible paths connecting pairs of nodes. Moreover, constructing and using a pre-order on the nodes allows our algorithm to proceed in a completely asynchronous manner, and without any information about the size of the network, as opposed to [17,18]. The main characteristics of our solution are presented in Table1, where a boldface denotes the most useful (or efficient) feature for a particular criterium.

1 Note that one may use the techniques proposed in [21] in order to construct a self-stabilizing MST starting from non-stabilizing solutions. This technique would increase the memory complexity.

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(3)

A New Self-Stabilizing MST Construction with Loop-Free Property 3 TABLE 1. Distributed self-stabilizing algorithms for the MST and

loop-free SP problems.

Unique Memory

Metric Size known weights usage Loop-free

[17] MST Yes Yes O(nlogn) No

[18] MST Upper bound Yes O(nlogn) No

[13] SP Upper bound No (logn) Yes

[14] SP No No (logn) Yes

This paper MST No No O(logn) Yes

A preliminary version of this paper has appeared in [22]. This journal version contains all details of the algorithm (rules and predicates) and all the proofs of correctness and all the proofs of time and space complexity.

2. MODEL AND NOTATIONS

We consider an undirected weighted connected network G=(V,E,w)whereVis the set of nodes,Eis the set of edges andw:E→R+is a positive cost function. Nodes represent processors and edges represent bidirectional communication links. Additionally, we consider that G=(V,E,w) is a net- work in which the weight of the communication links may change value, but we made the classical assumption that the memory space used by the edge weights isO(logn). We con- sider anonymous networks (i.e. the processors have no IDs), with one distinguished node, called theroot.2Throughout the paper, the root is denotedr. We denote by deg(v)the number ofv’s neighbors inG. The deg(v)edges incident to any nodev are labeled from 1 to deg(v)is called the port number, so that a processor can distinguish the different edges incident to a node thanks to the port number.

The processors asynchronously execute their programs con- sisting of a set of variables and a finite set of rules. The variables are part of the shared register which is used to communicate with the neighbors. A processor can read and write its own registers and can read the shared registers of its neighbors. Each processor executes a program consisting of a sequence of guarded rules.

Eachrulecontains aguard(boolean expression over the vari- ables of a node and its neighborhood) and anaction(update of the node variables only). Any rule whose guard istrueis said to beenabled. A node with one or more enabled rules is said to beprivilegedand may make amoveexecuting the action corre- sponding to the chosen enabled rule.

2Observe that the two self-stabilizing MST algorithms mentioned in the Previous Work section assume that the nodes have distinct IDs with no distin- guished nodes. Nevertheless, if the nodes have distinct IDs, then it is possible to elect one node as a leader in a self-stabilizing manner. Conversely, if there exists one distinguished node in an anonymous network, then it is possible to assign distinct IDs to the nodes in a self-stabilizing manner [5]. Note that it is not possible to compute deterministically an MST in a fully anonymous network (i.e. without any distinguished node), as proved in [17].

A local stateof a node is the value of the local variables of the node and the state of its program counter. A configu- ration of the system G=(V,E) is the cross product of the local states of all nodes in the system. The transition from a configuration to the next one is produced by the execution of an action of at least one node. Acomputation of the system is defined as a weakly fair, maximal sequence of configura- tions, e=(c0,c1,. . .,ci,. . .), where each configuration ci+1

follows fromci by the execution of a single action of at least one node. During an execution step, one or more processors execute an action and a processor may take at most one action.

Weak fairness of the sequence means that if any action inG is continuously enabled along the sequence, it is eventually chosen for execution.Maximality means that the sequence is either infinite or it is finite and no action ofGis enabled in the final global state.

In the sequel, we consider the system can start in any config- uration. That is, the local state of a node can be corrupted. Note that we do not make any assumption on the bound of corrupted nodes. In the worst case all the nodes in the system may start in a corrupted configuration. In order to tackle these faults we use self-stabilization techniques.

Definition 1 (Self-stabilization). Let LA be a non-empty legitimacy predicate3of an algorithmAwith respect to a speci- fication predicate Spec such that every configuration satisfying LAsatisfies Spec. AlgorithmAis self-stabilizing with respect to Spec iff the following two conditions hold:

(i) Every computation ofAstarting from a configuration satisfyingLApreservesLA(closure).

(ii) Every computation of A starting from an arbitrary configuration contains a configuration that satisfiesLA

(convergence).

We define below aloop-freeconfiguration of a system as a configuration which contains paths with no cycle between any couple of nodes in the system. Given two nodesu,vV, we noteP(u,v)the path betweenuandvas the collection of edges betweenuandv.

Definition 2 (Loop-free configuration). Let Cycle(u,v) be the following predicate defined for two nodes u,vV on configuration C:Cycle(u,v)≡ ∃P(u,v),P(v,u):P(u,v)P(v,u)= ∅.A loop-free configuration is a configuration of the system which satisfies:∀u,vV, Cycle(u,v)=false.

We use the definition of a loop-free configuration to define a loop-free stabilizingsystem.

Definition3 (Loop-free stabilization). A distributed system is called loop-free stabilizing if and only if it is self-stabilizing and there exists a non-empty set of configurations such that

3 A legitimacy predicate is defined over the configurations of a system and is an indicator of its correct behavior.

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(4)

the following conditions hold: (i)every computation starting from a loop-free configuration reaches a loop-free config- uration (closure). (ii) Every computation starting from an arbitrary configuration contains a loop-free configuration (convergence).

In the sequel we study the loop-free self-stabilizing LoopFreeMST problem. The legitimacy predicate LA for theLoopFreeMSTproblem is the conjunction of the following two predicates: (i) a treeTspanning the network is constructed, (ii)T is an MST ofG(i.e.∀T,W(T)W(T), withT be a spanning tree ofGandW(S)=

eSw(e)be the cost of the subgraphS).

3. THE ALGORITHMLOOPFREEMST

In this section, we describe our self-stabilizing algorithm for the MST problem. We call this algorithmLoopFreeMST. In the next section, we shall prove the correctness of this algo- rithm, and demonstrate that it satisfies all the desired properties listed in Section 1, including the loop-free property. Let us begin by an informal description ofLoopFreeMSTaiming at underlining its main features.

3.1. High-level description

LoopFreeMSTis based on the red rule. That is, for construct- ing an MST, the algorithm successively deletes the edge of maximum weight within every cycle. For this purpose, a span- ning tree is maintained, together with a pre-order labeling of its nodes. Given the current spanning treeT maintained by our algorithm, every edgeeof the graph that is not in the span- ning tree creates a unique cycle in the graph when added toT.

This cycle is calledfundamental cycle, and is denoted by Ce. (Formally, this cycle depends onT; nevertheless no confusion should arise from omittingT in the notation ofCe). Ifw(e)is not the maximum weight of all the edges inCe, then, according to the red rule, our algorithm swapsewith the edgef ofCe

with maximum weight. This swapping procedure is called an

improvement. A straightforward consequence of the red rule is that if no improvements are possible then the current spanning tree is a minimum one.

AlgorithmLoopFreeMSTcan be decomposed in three pro- cedures: (i) tree construction, (ii) token label circulation and (iii) cycle improvement.

The latter procedure (cycle improvement) is in fact the core of our contribution. Indeed, the two first procedures use exist- ing self-stabilizing algorithms, one for building a spanning tree and the other for labelling its nodes. We will show how to com- pose the original procedure ‘Cycle improvement’ with these two procedures. Note that ‘Cycle improvement’ differs from the previous self-stabilizing implementation of the improve- ment swapping in [18] by the fact that it does not require any a priori knowledge of the network, and it is loop-free.

LoopFreeMSTstarts by constructing a spanning tree of the graph, using the self-stabilizing loop-free algorithm ‘Tree con- struction’ described in [14]. The two other procedures are per- formed concurrently. A token perpetually circulates along the edges of the current spanning tree, in a self-stabilizing manner.

This token circulation uses algorithms proposed in [23,24] as follows. A non-tree-edge can belong to at most one fundamental cycle, but a tree-edge can belong to several fundamental cycles.

Therefore, to avoid simultaneous possibly conflicting improve- ments, our algorithm considers the cycles in order. For this pur- pose, the token labels the nodes of the current tree in a depth first search (DFS) order (pre-order). This labeling is then used to find the unique path between two nodes in the spanning tree in a dis- tributed manner, and enables computing the fundamental cycle resulting from adding one edge to the current spanning tree.

We now sketch the description of the procedure ‘Cycle improvement’ (see Fig.1). When the token arrives at a nodeu in a stateDone, it checks whetheruhas some incident edges not in the current spanning treeTconnectinguwith some other nodevwith smaller label. If it is the case, then its enters in state Verify. Lete= {u,v}. Nodeuthen initiates a traversal of the fundamental cycle Ce for finding the edge f with maximum weight in this cycle. Ifw(f)=w(e), then no improvement is performed. Else an improvement is possible, anduenters State

FIGURE 1. Evolution of the node’s state in cycle improvement module. Each arrow depicts the transition between each node status by the execution of a rule given on each arrow (the ruleRBadLabis depicted in dashed arrow).

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(5)

A New Self-Stabilizing MST Construction with Loop-Free Property 5

FIGURE 2. Example of a loop-free improvement of the current spanning tree. The direction of the edges indicates the parent relation. Edges in the spanning tree are depicted as plain lines; edges not in the spanning tree are denoted by dotted lines.

Improve. Exchangingeandf inT results in a new treeT. When the improvement is terminated u enters in State End.

The key issue here is to perform this exchange in a loop-free manner. Indeed, one cannot be sure that two modifications of the current tree (i.e. removingf fromT, and addingetoT) that are applied at two distant nodes will occur simultaneously. And if they do not occur simultaneously, then there will a time inter- val during which the nodes will not be connected by a spanning tree. Our solution for preserving the loop-free property relies on a sequence of successive local and atomic changes, involving a single variable. This variable is a pointer to the current parent of a node in the current spanning tree. To get the flavor of our method, let us consider the example depicted in Fig.2. In this example, our algorithm has to exchange the edgee= {10, 12}

of weight 9, with the edge f = {7, 8}of weight 10 (Fig. 2a).

Currently, the token is at node 12. The improvement is per- formed in two steps, by a sequence of two local changes. First, node 10 switches its parent from 8 to 12 (Fig.2b). Next, node 8 switches its parent from 7 to 10 (Fig.2c). A spanning tree is preserved at any time during the execution of these changes.

Note that any modification of the spanning tree makes the current labeling globally inaccurate, i.e. it is not necessarily a pre-order anymore. However, the labeling remains a pre-order in the portion of the tree involved in the exchange. For instance, consider again the example depicted in Fig.2c. When the token will eventually reach node A, it will label it by some label >12. The exchange ofe= {10, 12}andf = {7, 8}has not changed the pre-order for the fundamental cycle including edge

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(6)

Algorithm 1: Frame of algorithmLoopFreeMSTfor nodev ifv is in a coherent spanning tree T of Gthen/*algorithm [14]/*

ifCoherent token circulation for vthen/* algorithms [23,24]*/

ifv has a coherent labelthen/*ruleRBadLab*/

ifToken(v)∧ ∃u∈N(v):e= {u,v} ∈T(labelu<labelv)then/* ruleRV*/

LetfCethe edge with the maximum weight ofCe; ifw{f}>w{e}then/*Improve the cycle: rulesRIandRE*/

parentu:=v;

else

Continue DFS token circulation /* ruleRDFS*/

end else

Continue DFS token circulation /* ruleRDFS*/

end

if¬Token(v)then

if vC(e)αthenVerify cycle: ruleRV;

if vC(e)w{f}>w{e}thenImprove the cycle: rulesRIandRE*/;

end

ifdv=dparentv+1then Distance correction: rulesRPandRP*/;

else

Correct the Label /* ruleRD*/

end else

Assure coherent token circulation /*algorithms [23,24]*/

end else

Construct a spanning treeTofG/* algorithm [14]*/

end

α:C(e)fundamental cycle involved by the node with the token;

{A, 12}. However, when the token will eventually reach nodeB and label it> , the exchange ofe= {10, 12}andf = {7, 8} has changed the pre-order for the fundamental cycle including edge{B, 9}: the parent of node labeled 10 is labeled 12 whereas it should have a label smaller than 10 in a pre-order. When the pre-order is modified by an exchange, the inaccurately labeled node changes its state toBadLab, and stops the traversal of the fundamental cycle. The token is then informed that it can discard this cycle, and carry on the traversal of the tree. A frame of the algorithmLoopFreeMSTis given in Algorithm1, this frame give an overview of the algorithm and give references of the algorithm rules given in the detailed level description.

3.2. Detailed level description

We now enter into the details of Algorithm LoopFreeMST.

First, let us state all variables used by the algorithm. Later on, we will describe its predicates and its rules.

3.2.1. Variables

For any nodevV(G), we denote byN(v)the set of all neigh- bors ofvinG. AlgorithmLoopFreeMSTmaintains the setN(v)

at every nodev. We use the following notations:

(i) parentv: is the port number of the parent ofvin the current spanning tree;

(ii) labelv: is the integer label assigned tov;

(iii) dv: is the distance (in hops) fromvto the root in the current spanning tree;

(iv) statev: is the state of nodev, with values in {Done, Verify,Improve,End,Propag,BadLab};4 (v) DefCyclev: LetCethe current fundamental cycle with

e= {x,y},DefCyclev=(x,y).

(vi) VarCyclev: a pair of variables: the first one is the maxi- mum edge-weight in the current fundamental cycle; the second one is a (boolean) variable in{Before,After};5 (vii) sucv: is the port number of the successor ofvin the cur-

rent fundamental cycle.

3.2.2. Consistency rules

The first task executed byLoopFreeMSTis to check the con- sistency of the variables of each node see Fig.1.Doneis the

4 The statePropagis detailed in Consistency rules.

5 For details see Section3.2.5Cycle improvement rules.

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(7)

A New Self-Stabilizing MST Construction with Loop-Free Property 7

FIGURE 3. Corrections predicates used by the algorithm.

standard state of a node when this node does not have the token, or is not currently visited by the traversal of a fundamental cycle.

When the state of a node is not consistent regarding to its neigh- borhood, then the state of the node becomesBadLabby exe- cuting RuleRBadLab. There is one predicate inRBadLabfor each state, except for statePropag, to check whether the variables of the node are consistent (see Fig.3). The ruleRDallows the node to return to the standard stateDone. More precisely, ruleRD resets the variables, and stops the participation of the node to any improvement (i.e. reset the state of the node regarding the cycle improvement module). This rule is enabled when: (i) the nodev detects an inconsistent state in the fundamental cycle currently examined (see PredicateCohCycle(v)), (ii) a new token circu- lation was initiated by the root and the token is forwarded by the parent of nodevin the tree (see PredicateResetCirc(v)) or

RBadLab: Bad label

if CohCycle(v)∧Error(v)∧(DefCycle[0]v=labelv) then

statev:=BadLab;

end

(iii) the token was deleted at the nodevwhich has initiated a ver- ification or an improvement in a fundamental cycle (see Predi- cateResetInit(v)).

RD: Improvement consistency

if ¬CohCycle(v)∨ResetCirc(v)∨ResetInit(v)then statev:=Done;

DefCyclev:=(labelv,done);

VarCyclev:=(0,Before);

sucv:= ∅;

end

3.2.3. Tree construction

LoopFreeMST starts by constructing a spanning tree of the graph, using the self-stabilizing loop-free generic algorithm

‘Tree construction’ described in [14].

This algorithm uses a parameter called r-operator intro- duced in [25]. Anr-operator allows to compute various static distributed tasks such as shortest path calculus or depth- first search tree construction. An r-operator is based on the

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(8)

binary operator ⊕, called infimum, defined in [26]. This binary operator is associative, commutative and idempo- tent (i.e. xx=x) which defines a partial order relation

over a setS:xyif and only if xy=x. The set S has a greatest element e that verifies xe for every x∈S∪ {e}. The structure (S∪ {e},⊕) is an Abelian idempotent semi-group with e as identity element. The binary operatoron a set S∪ {e}is an r-operator if there exist a surjective mapping r (called r-mapping), such that it verifies the following conditions: (i) r-associativity:

(xy)r(z)=x(yz); (ii) r-commutativity: r(x) y=r(y)x; (iii) r-idempotency: r(x)x=r(x) and (iv) right identity element:∃e∈S∪ {e},xe=x. Moreover, it is proved in [25] that to be self-stabilizing a system must execute at every processor a strictly idempotentr-operator. An r-operatorbased on the infimum⊕is strictly idempotent if, for anyx∈S\{e},x<r(x)(i.e.xr(x)andr(x)=x).

Hence, to construct a Breadth First Search (BFS) tree using the generic algorithm ‘Tree construction’ we must use the following strictly idempotent r-operator described in [25]:

minc(x,y)=min(x,y+1) on set N∪ {∞}, with ∞ as its identity element. It is based on the infimum min and on the sur- jectiver-mappingr(x)=x+1. Thisr-operator is used at each node and the root node has 0 as the first term of everyminc computation and every other node has∞as the first term of everyminccomputation.

This algorithm constructs a BFS and maintains two variables used by the Cycle improvement procedure:parentanddistance.

During the execution of our algorithm, these two variables are subject to the same rules as in [14]. After each modification of the spanning tree, the new distance to the parent is propagated in sub-trees by RulesRPandRP.

RP: Distance propagation

if CohDone(v)∧ ¬AskV(v)(sucv=

parentv)(Pr(v)=parentv)(dv=dparentv+1)∧ (stateparentv=Improve∨stateparentv=Propag) then

statev:=Propag;

dv:=dparentv+1;

end

RP: End distance propagation

if statev=Propag∧EndPropag(v)then statev:=Done;

DefCyclev:=(labelv,done);

VarCyclev:=(0,Before);

sucv:= ∅;

end

3.2.4. Token circulation and pre-order labeling

LoopFreeMSTuses the algorithm described in [23] to provide each nodevwith a labellabelv. Each label is unique in the net- work traversed by the token. This labeling is used to find the unique path between two nodes in the spanning tree, in a dis- tributed manner. For this purpose, we use the snap-stabilizing algorithm described in [24] for the circulation of a token in the spanning tree (a snap-stabilizing algorithm stabilizes in 0 steps thus algorithm in [24] allows to always have a correct token circulation).

Moreover, a token is used at a nodevwhenvneeds to exam- ine if an improvement is possible in a fundamental cycle, defined by an adjacent non-tree edgee= {u,v}. To this end, Algorithm LoopFreeMSThas to keep the token atvduring a finite time (the time to verify if an improvement can be done in the funda- mental cycle), then the token is released and it continues its cir- culation in the tree. A nodevhas the token when PredicateInit(v) is satisfied (PredicateDFSF(v)is true at nodevif the token was forwarded by its parent, this predicate is defined in the token cir- culation algorithm [24]). In this case, RuleRDFSmonitors the circulation of the token and when executed it modifies the state at nodevin order to release the token (i.e. thanks to the compo- sition used the token circulation algorithm can be executed atv, see Section3.2.6). Therefore, a token carries on its tree traversal if one of the following three conditions is satisfied: (i) there is no improvement which could be initiated by the node which holds the token, (ii) an improvement was performed in the current fun- damental cycle or (iii) inconsistent node labels were detected in the current fundamental cycle. PredicateContinueDFS(v)is true when one of the above cases is satisfied, and RuleRDFScan be executed byv.

RDFS: Continue DFS token circulation

ifCohCycle(v)∧Init(v)∧ContinueDFS(v)then statev:=Done;

DefCycle[1]v=done;

end

Inputs to token circulation algorithm.The token circulation algorithm we use [24] performs a token circulation on a tree.

Therefore, we have to give several inputs at each nodevfor the token circulation algorithm (Fig.4):

1. to indicate ifvis the root of the spanning tree or not;

2. the parent ofvin the spanning tree (i.e.Pv=parentv withPvthe parent variable atvused in [24]);

3. and the set of children ofvin the spanning tree. Note that the set of the children is not stored in the memory of the node, this set is computed when it is necessary by the function C(v)= {u:uN(v)∧parentu=v}

(see [24]).

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(9)

A New Self-Stabilizing MST Construction with Loop-Free Property 9

FIGURE 4. Predicates used by the algorithm.

However, we have to take care of when these inputs are updated, otherwise the token can be caught out in a sub-graph and it could not return to the root because of modification on tree edges done by the cycle improvement module in paral- lel and used by the token circulation algorithm. Therefore, these inputs are refreshed in the next forward of the token to a node by its parent (i.e. to the next token circulation), more precisely when the following predicate is satisfied at a nodev:

DFSF(v)∧DefCycle[0]v=labelv. The circulation of several tokens involves a more frequent update of the above inputs;

however, it is not impeding because this enables to prevent the backward of the previous token at a point in the tree and to speed up its deletion by the token circulation algorithm. Thus, only the last token circulation can safely return to the root since no other token circulation follows it.

None and multiple token circulations.The initial system state can contain no token circulation. We use a snap-stabilizing token circulation algorithm which needs an action from the root in order to guarantee a correct new token circulation. To this end, the root of the spanning tree tries to initiate perma- nently a new token circulation. However, the token circulation algorithm allows the root to start a new token circulation only when the previous one is finished. This allows us to use no information on the network to initiate a token circulation, such as a time-out interval based on network diameter.

The system can start from a configuration where several tokens circulations are initiated. This situation is managed by the token circulation which deletes these tokens (except the last token circulation initiated by the root) by blocking these one in sub-graphs obtained by the presence of several tokens.

Indeed, a token circulation is represented as a directed path from the root to the node having the token in the algorithm we

use [24]. Therefore, illegal roots of token circulations are in the network and are used to delete these tokens (i.e. paths with illegal roots), except the last one which has a legal root (the root of the spanning tree).

3.2.5. Cycle improvement rules

The procedure ‘Cycle improvement’ is the core of LoopFreeMST. Its role is to avoid disconnection of the current spanning tree, while successively improving the tree until reaching an MST. The procedure can be decomposed in four tasks: (i) to check whether the fundamental cycle of the non-tree edge has an improvement or not, (ii) perform the improvement if any, (iii) update the distances and (iv) resume the token circulation.

RV: Verify rule if

CohCycle(v)∧ ¬Error(v)∧(InitVerify(v)∨[¬Init(v)∧ (CohDone(v)∨statev=Propag)∧AskV(v)])then

statev:=Verify;

ifDFSF(v)then

DefCycle[1]v:=LabCand(v); else

DefCyclev:=DefCyclePr(v); VarCyclev:=(MaxC(v),WayC(v));

sucv:=Succ(v);

end end

Let us start by describing the first task. A nodeuin stateDone changes its state toVerifyif its variables are in consistent

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(10)

state, it has a token, and it has identified a candidate (i.e. an incident non-tree edgee= {u,v}whose other extremityvhas a smaller label than the one ofu). The latter is under the control of PredicateInitVerify(v), and the variableDefCyclevcontains the label ofuandv. If the three conditions are satisfied, then the verification of the fundamental cycleCeis initiated from node u, by applying ruleRV. The goal of this verification is 2-fold:

first, to verify whetherCe exists or not, and, second, to save information about the maximum edge weight and the location of the edge of maximum weight inCe. These information are stored in the variableVarCyclev, which takes values returned by Predicates MaxC(v) andWayC(v). The first one returns the maximum edge weight encountered in the part of the cycle crossed and the second one the position of an edge of maxi- mum weight. In order to respect the orientation in the current spanning tree, the nodeuor vthat initiates the improvement depends on the localization of the maximum weight edgef in Ce. More precisely, letrbe the least common ancestor of nodes uandvin the current tree. Iff occurs beforerinTin the traver- sal ofCefromustarting by edge(u,v), then the improvement starts fromu, otherwise the improvement starts fromv. To get the flavor of our method, let us consider the example depicted on Fig. 2. In this example, f occurs after the least common ancestor (node 6). Therefore node 10 atomically swaps its par- ent to respect the orientation. However, if one replaces in the same example the weight of edge{11, 6}by 11 instead of 3, thenf would occur beforer, and thus node 12 would have to atomically swaps its parent. The relative places off andrin the cycle is indicated by PredicateWayC(v)that returns two different values: Before or After. During the improvement of the tree, the fundamental cycle is modified. It is crucial to save information about this cycle during this modification. In particular, the successor of a nodewin a cycle, stored in the variable sucw, must be preserved. Its value is computed by PredicateSucc(v)which uses node labels to identify the cur- rent examined fundamental cycle. Each node is able to compute its predecessor in the fundamental cycle by applying Predicate Pr(v). The state of a node is compared with the ones of its suc- cessor and predecessor to detect potential inconsistent values.

At the end of this task, the nodeulearns the maximum weight of the cycleCeand can decide whether it is possible to make an improvement or not. If not, but there is another non-tree edge e that is candidate for potential replacement, thenu verifies Ce. Otherwise the token carries on its traversal, and ruleRP is applied.

IfCecan yield an improvement, then ruleRIis executed. By this rule, a node enters in stateImprove, and changes its parent to its predecessor ifVarCycle[1]v=Before(respectively, to its successor ifVarCycle[1]v=After). For this purpose, it uses the variablesucvand the predicatePr(v). At the end of an improve- ment, it is necessary to inform the node holding the token that it has to carry on its traversal, this is the role of ruleRE. It is also necessary to inform all nodes impacted by the modification that they have to update their distances to the root (see Section3.2.3).

RI: Improve rule

if CohCycle(v)∧ ¬Error(v)∧CohVerify(v)∧ Improve(v)∧ ¬CAncestor(v)∧[(DFSF(v)∧ AskV(v))∨AskI(v)]then

statev:=Improve;

ifDFSF(v)(statePr(v)=Improve)then VarCyclev:=VarCyclePr(v);

end if

(DFSF(v)∧VarCycle[1]v=Before)∨ ¬DFSF(v) then

parentv:=Pr(v);

end

ifstatesucv=Improvethen VarCyclev:=VarCyclesucv; parentv:=sucv;

end

ifw(v,sucv)≥VarCycle[0]vthen sucv=Succ(v);

dv:=dparentv+1;

end end

RE: End of improvement rule

if CohCycle(v)∧ ¬Error(v)∧EndImprove(v)∧ EndPropag(v)then

statev:=End;

end

3.2.6. Module composition

All the different modules presented, except the tree construc- tion parts of the correction module, need the presence of a spanning tree inG. Thus, we must execute the tree construc- tion rules first if an incorrect value regarding the spanning tree is detected. To this end, these rules are composed using the level composition defined in [27], i.e. if PredicateCohTree(v) (see Fig. 3) is not verified, then the tree construction rules are executed, otherwise the other modules can be executed.

The token circulation algorithm and the naming algorithm are composed together using the conditional composition described in [23], i.e. the naming algorithm is executed when a logical expression (based on guards of token circulation algorithm) is true. Finally, we compose the token circulation algorithm and the cycle improvement module with a condi- tional composition using Predicate ContinueDFS(v) (see Fig.5). This allows to execute the token circulation algorithm only if the cycle improvement module does not need the token on a node. Figure 6 shows how the modules are composed together.

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(11)

A New Self-Stabilizing MST Construction with Loop-Free Property 11

FIGURE 5. Predicates used by the algorithm.

FIGURE 6. Composition of the presented modules. If Predicate CohTree(v) is false then the Tree construction module is executed otherwise the other modules are executed. When the Tree construction module is not used, the Token circulation module is executed only if PredicateContinueDFS(v)is true, otherwise the Labeling module is executed first and then Cycle improvement module (see Predicate CohCycle(v)).

4. CORRECTNESS PROOF

Paths between pairs of nodes are used to define a loop-free configuration in Definition2. In the remainder, given a config- urationγthe variablesparentvof each nodevinγ are used to define the paths used in Definition2.

We first define below legitimate configuration of LoopFreeMSTalgorithm.

Definition 4 (Legitimate configuration). A configuration γ of AlgorithmLoopFreeMSTis legitimate ifγ satisfies the following conditions:

(1) γis a loop-free configuration,

(2) a tree T spanning the network G is constructed, (3) T is an MST of G(i.e.T,W(T)W(T),with Tbe a

spanning tree of G and W(S)=

eSw(e)be the cost of the subgraph S).

Lemma1. Conditions given in[27]are satisfied to use the level composition between Tree construction layer and the other lay- ers in AlgorithmLoopFreeMST.

Proof. In [27], Gouda and Herman define a way to compose together two self-stabilizing algorithms, namedlevel composi- tion. To use this composition technique, the two self-stabilizing algorithmsA1andA2must satisfy two main conditions:

(1) A1andA2must becompatible, that is a variable used in A1andA2must have the same type inA1andA2; more- over, in a distributed environment no two neighbors write in the same variable.

(2) A set of boolean variables given in input is not used either byA1, nor byA2.

Condition 1 is satisfied by the model we use because a node cannot write in the variable maintained by one of its neigh- bor. Moreover, according to the description of Algorithm LoopFreeMST, the variables of the first layer used in the other layers have the same type (i.e. variableparentvanddv).

Condition 2 is also satisfied since we use a boolean defined by PredicateCohTree(v)to detect if the first layer or other layers must be executed at each nodevV.

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(12)

Therefore, AlgorithmLoopFreeMSTsatisfies all the condi- tions given in [27] to use properly the level composition.

We use the generic algorithm proposed in [14] to construct a BFS spanning tree using ther-operator given in Section3.2.3.

Note that we use this algorithm because it satisfies the loop-free property. Therefore, in the remainder we suppose there is a con- structed spanning tree. More formally, given a configurationγ a spanning tree inγ is defined by the variablesparentvof the cycle improvement module (parentv variable is also shared with the tree construction module) at each nodevV.

In the following, we use the term ofcoherent statusfor a node in a status in the cycle improvement module which is consistent with the status of its neighbors in a fundamental cycle (i.e. a node vin a coherent status verifies PredicateCohCycle(v)).

Theorem 1 (LoopFreeMST). Starting from an arbitrary spanning tree of the network G,LoopFreeMSTalgorithm is a loop-free stabilizing algorithm and reaches a configuration which satisfies Definition4.

Proof. LetT a spanning tree of networkGandva node ofT.

If an error is detected on the state of a nodevthen according to Lemma2, the algorithm bootstraps the state ofv, otherwise the token continues its circulation in the tree until a verification on a node is needed (Lemma4). When the token is on a node that has candidate edges not in the tree (i.e. whose fundamental cycle is not yet checked), according to Corollary1 the algo- rithm verifies if a cycle improvement (see Section3.1for the definition of a cycle improvement) must be performed using these not tree edges and according to Lemma6 an improve- ment is performed if an improvement is possible. Moreover, the algorithm performs all possible improvements (Lemma8) until no improvement is feasible (Lemma14and Corollary2), i.e. an MST is reached.

Starting from a spanning treeTof the network, during the exe- cution of the algorithm no cycle is created and a spanning tree structure is preserved (see Corollary3). Moreover, according to Lemma15ifT is MST, thenTis maintained by the algorithm.

Lemma 2 (Bootstrap). A node v in an inconsistent state (regarding the state of its neighbors in the cycle) for the cycle improvement module eventually verifies Predicate CohCycle(v).

Proof. A node may have six different states in the algorithm:

Done,Verify,Improve,End, BadLab and Propag.

The coherence of a node in these different states is defined, respectively, by predicates CohDone, CohVerify, CohImp, CohEnd, and CohError. For the state Propag, we detect if the propagation is done using Predicate EndPropag(v)to allow the execution of RuleRD to reinitialize the state of the node. According to the algorithm description, if a nodevis in

an inconsistent state (i.e. does not respect one of the previous mentioned predicates), PredicateCohCycle(v)is not verified since the previous mentioned predicates are exclusives (a node can be in one of the status given above). Thus,vcan execute Rule RD to correct its variables in order to satisfy Predicate CohDone(v). As a consequence Predicate CohCycle(v) is satisfied too (see RuleRD).

Lemma 3. If CohCycle(v)=true and Succ(v)= ∅ then eventually a node v is in status BadLab and satisfies CohError(v).

Proof. We show that if a node vin a fundamental cycle has no successor because of bad labels, thenvchanges its status toBadLab. Predicate Succ(v)is in charge to give the suc- cessor of a node in a fundamental cycle based on the node labels, following Observation 1. Thus, if Predicate Succ(v) returns no successor this implies that bad labels disturb the computation of the successor. PredicateError(v)is in charge to detect bad labels. We show that a nodevwhich is part of a fundamental cycle (i.e. satisfies Predicate CohCycle(v)) and detects an error or has its successor in status BadLab changes its status to BadLab(except the initiator node, i.e.

DefCycle[0]v=labelv). We do not consider the statusDone since in this status no node has a successor (see Predicate Error(v).

Consider any nodev(except the initiator node) which satis- fies PredicateCohCycle(v). To change its status toBadLab a node must execute Rule RBadLab and we must consider two cases: a node with no successor, or a node with a suc- cessor in statusBadLab. In the first case, a nodevsatisfies Predicate Error(v) (see Predicate Error(v)) and v can exe- cute Rule RBadLab. After the execution of Rule RBadLab, v satisfies Predicate CohError(v) since statev=BadLab, Succ(v)= ∅andDefCyclev=DefCyclePr(v). In the second case, suppose that for a nodevwe havestatesucv=BadLab.

According to Predicate AskE(v), Error(v)=true and thus vcan execute RuleRBadLab to change its status toBadLab.

After the execution of Rule RBadLab, v satisfies Predicate CohError(v) since statev=BadLab, AskE(v)=true and DefCyclev=DefCyclePr(v). One can show by induction fol- lowing the same argument that any node part of a fundamental cycle with bad labels changes its status toBadLab(except the initiator node).

Lemma 4 (Token release). Starting from a configuration where a spanning tree T is constructed,if a node v has the DFS token and satisfies CohCycle(v) then eventually Predicate ContinueDFS(v)returns true.

Proof. Predicate ContinueDFS(v) notices when the DFS token must continue its circulation in the tree. The DFS token must continue its circulation in four cases: (1) a node in status Done has no candidate edge, (2) a node in status Verify

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

(13)

A New Self-Stabilizing MST Construction with Loop-Free Property 13 with no possible improvement has no candidate edge, (3) an

improvement was done in the fundamental cycle or (4) bad labels are detected in the fundamental cycle.

In Case 1, for node v, CohDone(v)=true (otherwise according to Lemma 2 its state is reinitialized). In Case 2, for node v, CohVerify(v)=true (otherwise according to Lemma2its state is reinitialized) and PredicateImproveF(v) is used to detect possible improvements (see the proof of Lemma5). For Cases 1 and 2, ifvhas no candidate Predicate Candidate(v)=false(see PredicateCandidate(v)and proof of Lemma5) and thus PredicateContinueDFS(v)is satisfied.

In Case 3, according to Lemma 7 the initiator node v satis- fies Predicate CohEnd(v) and Predicate ContinueDFS(v) returns true. Finally in Case 4, according to Lemma3the suc- cessor of the initiator nodevis in statusBadLabso Predicate AskE(v)=true and Predicate Error(v) returns true. Thus, PredicateContinueDFS(v)returns true.

Therefore, in all the above cases PredicateContinueDFS(v) returns true andvcan execute RuleRDFS to allow the token circulation. It then changes its status to Done and sets DefCycle[1]v to done to force the verification of all adja- cent candidate edges in the next tree traversal by the DFS token.

Observation 1. Let T be a tree spanning V and correctly labeled. Let an edgee= {u,v} ∈E,eT,Ceits fundamental cycle andxthe fundamental cycle root ofCe. There is always a pathP(u,v)inT betweenuandv, such that P(u,v)can be decomposed in two parts: a sub-pathP(x,u)P(u,v)(respec- tively, P(x,v)P(u,v)) with increasing labels from x to u (respectively,xtov).

Lemma5 (Cycle verification). Let v be a node of T such that v has the DFS token with at least an adjacent edge e= {u,v} ∈ E,eT whose fundamental cycle is not already verified by the algorithm. Eventually the cycle improvement module verifies if there is an improvement in Ce.

Proof. Suppose first that v has the DFS token and vis in a coherent status Done, otherwise according to Lemma 2 its state is corrected. Lete= {u,v}be a not tree edge, which is a candidate edge forv, i.e. we have Candidate(v)=end. We consider thatlabelu<labelvsince a candidate edge for nodev is an adjacent not tree edgee= {u,v}withlabelu<labelv, see predicateLabCand(v). Since vis in a coherent statusDone and Candidate(v)=end, we have variable DefCycle[1]v

equal to done, Predicate CohCycle(v) and InitVerify(v) return true, whereas Predicate Error(v) returns false. Thus, vcan execute RuleRV. Note that RuleRDFS cannot be exe- cuted since Predicate ContinueDFS(v) returns false since Candidate(v)=end. As a consequencevstops the DFS token and becomes the initiator node of cycleCewithuas target node (see RuleRV).

After the execution of RuleRV,vis in statusVerifyand according to PredicateSucc(v)vselects its father as next node

in the cycle (i.e.sucv=parentv). Note that sincevis in coher- ent statusDonevariableVarCyclev=(0,Before). CycleCeis decomposed in two parts (see Lemma1): (1) from the initiator vto the rootxofCeand (2) fromxto the target nodeu. In the following we prove by induction on the length of cycleCethat a nodeabelonging toCeexecutes RuleRVand eventually is in statusVerify. Moreover, variablesucadescribes the succes- sor ofainCe(i.e. encodes the cycleCe).

Case 1. Consider a coherent node a in status Done (see Lemma2) which has not the DFS token (i.e. PredicateInit(a)is false). Consider the successor node ofCe’s initiator nodev. As described above,vis in statusVerifyandsucv=a. Accord- ing to Predicate Pr(a),vis the predecessor ofa in cycleCe

sinceais the parent ofvin the tree. Thus, PredicateAskV(a) returns true anda could execute RuleRV. Therefore,a is in statusVerifyand selects its parent as its successor inCe, like v. Moreover,acomputes the new heaviest edge fromvtoaand note that the heaviest edge location is before (i.e.Before) the root of Ce (see, respectively, predicates MaxC andWayC).

Using the same scheme, we can show that all nodes on Ce

betweenvandx(includingx) execute RuleRVand are in status Verify.

Case 2. Consider a coherent node a in status Done (see Lemma2) which has not the DFS token (i.e. PredicateInit(a) is false) and is the successor node ofx. As described in Case 1,xis in statusVerify. Sincexis the parent ofain the tree, PredicatePr(a)returnsxas predecessor ofa. Thus, Predicate AskV(a)returns true andacan execute RuleRV.aselects as its successor inCethe child with the highest label smaller than target node’s ulabel (see predicates MaxL(a)andSucc(a)).

Moreover,acomputes the new heaviest edge fromvtoaand if ahas a different heaviest edgeanotice that the heaviest edge location is after (i.e.After) the root ofCeotherwiseatakes the location of its predecessor (see respectively predicatesMaxC and WayC). Using the same scheme, we can show that all nodes onCe betweenxandu (includingu) execute RuleRV and are in statusVerify. Note that the target nodeuselectsv as its successor inCe(see PredicateSucc(u)).

Consider now thatvhas the DFS token, is in a coherent sta- tus Verifyand predecessor of v is in status Verify (i.e.

AskV(v)=true). Note that the predecessor of vis the target nodeu. As described in Case 2, target nodeuknows the weight of the heaviest edgee inCe(eT). Thus,vcould check if there is an improvement inCe(see PredicateImprove(v)).

Corollary 1 (Node cycles verification). Let T a span- ning tree and v be a node of T such that v has the DFS token.

Eventually for each adjacent candidate edge e of v,the cycle improvement module verifies if there is an improvement in Ce. Proof. We prove that while there is no improvement initiated byv, each edgee= {u,v} ∈E,eTis eventually examined by the cycle improvement module. We consider the two cases: (1) there is no improvement initiated byvor (2) an improvement

by guest on December 10, 2015http://comjnl.oxfordjournals.org/Downloaded from

Références

Documents relatifs

As I came to understand what happens in such circles, the relationship between the bodily ontology and the social ontology became more apparent, so that the juncture was not only

Fast Self-Stabilizing Minimum Spanning Tree Construction Using Compact Nearest Common Ancestor Labeling Scheme ∗.. L´

When the token is on a node that has candidate edges not in the tree (i.e. whose fundamental cycle is not yet checked), according to Corollary 1 the algorithm verifies if

Macro RecoverEdge(v) returns the local internal edge of v which has the common ancestor nearest from the root among the internal edges that were not taken into account by its

• hRemove, init edge, deg max, target, pathi: it is used to reduce the degree of a maximum degree node by deleting an adjacent edge then it changes edge orientation in the

In conclusion, the composition of these four layers provides us a self-stabilizing algorithm for centers computation or minimum diameter spanning tree construc- tion under

Le flyer avec la phrase “The City Is Not A Tree” qui accompagne l’affichage était envoyé de manière anonyme.. Il indiquait que l’art pouvait aussi exister en dehors des musées

In summary, the absence of lipomatous, sclerosing or ®brous features in this lesion is inconsistent with a diagnosis of lipo- sclerosing myxo®brous tumour as described by Ragsdale