[acm press the 1996 acm conference - boston, massachusetts, united states (1996.11.16-1996.11.20)]...

10
An Integrating, Transformation-Oriented Approach to Concurrency Control and Undo in Group Editors Matthias Ressel, Doris Nitsche-Ruhland, and Rul Institute for Computer Science University of Stuttgart Breitwiesenstr. 20–22, D-70565 Stuttgart, Germany Gunzenhauser {ressel,nitsche,rul}@ informatik.uni-stuttgart.de ABSTRACT Concurrency control and group undo are important issues in the design of groupware, especially for interactive group edi- tors. We present an improved version of an existing distributed algorithm for concurrency control that is based on operation transformations. Since the usability of the algorithm relies on its formal correctness, we present a set of necessary and suffi- cient conditions to be satisfied in order to ensure consistency in a replicated architecture. We identify desirable proper- ties of operation transformations and show how our approach can be employed to implement group undo. The approach has been applied to build a prototypical group editor for text; some experiences gained are presented. Keywords Concurrency Control, Group Editors, Group Undo, Group- ware, Interaction Model, Operation Transformation. INTRODUCTION Groupware systems, i.e., multi-user applications for coopera- tive work [2, 5], present remarkable challenges for application designers. Concurrency control and group undo are two of them. Concurrency control covers the management of parallel threads of human-computer interaction including potential conflicts. These typically arise in synchronous collaborative work when different users concurrently manipulate a shared object. A replicated architecture, where users work on copies of the shared object and instructions are exchanged by mes- sage passing, has been identified as appropriate for groupware [4]. In this way, users may continue local work even if the net- work fails. Screen updates – a frequent operation in common graphical user interfaces – can be accelerated, independently of network delays. The responsiveness of the user interface can be improved by the immediate execution of each individ- ual’s operations at the local site. Methods for concurrency Permissionto make digital/bardcopies of all or pan of thk materialfor personal or classroomuse is granted withoutfee provided that the copies are not made or distributedfor profit or commercial advantage, the copy- right notice, the title of the publication and its date appear, and notice is given that copyright is by permission of the ACM, Inc. To copy otherwise, to repubtish, to post on sewers or to redistribute to tists, requires specific perrniasion andlor fee. Computer Supported Cooperative Work ’96, Cambridge MA USA @ 1996ACM o_89791-7fj5_o/96/l 1 ..$3.50 control supporting this are called optimistic [6]. This entails, however, that operations are not necessarily executed in the same sequence at different sites. Certain operations have then to be executed in an application state different from the one they were originally issued in. The usability of a method for concurrency control relies both on its correctness, i.e., being able to maintain consistency among the copies of a shared object, and on the production of meaningful results that meet users’ expectations. Undo in a groupware system has to enable a user to revert the effects of an operation even if other users have issued further operations afterwards [l]. Therefore group undo has to define the effects of undoing an operation that might not be the last one in the interaction history. Undo of such operations has to be interpreted and executed, however, in the current state of the application. The transformation-oriented dOPT-algorithm by Ellis and Gibbs [4] forms a promising approach to optimistic concur- rency control. Their basic idea is to take an operation executed in some past state and to transform it in a way that it can be applied to the current state. We included the dOPT-algorithm in a framework for building group editors. In practise, how- ever, the dOPT-algorithm did not work in all cases. We found out, that inconsistent application states may result if one user issues and executes more than one operation concurrently to an operation of another user. An example will be given in the body of this paper. Fortunately, we came up with an im- proved version of the dOPT-algorithm that will be presented here. A novel multi-dimensional model of concurrent inter- action forms the core of our approach, enabling us to prove its correctness. It turned out, that our algorithm can help to implement group undo as well. Thus we contribute a new, integrating, transformation-oriented approach to both concur- rency control and group undo. Finally, we present some expe- riences we have gained in building a prototypical group text editor. MODEL OF A GROUPWARE SYSTEM Before presenting our approach of request transfotmations some understanding of a groupware system is necessary. The definitions have been taken in main parts from [4], but they have been modified if appropriate. A groupware system con- 288

Upload: rul

Post on 21-Dec-2016

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

An Integrating, Transformation-Oriented Approach

to Concurrency Control and Undo in Group Editors

Matthias Ressel, Doris Nitsche-Ruhland, and RulInstitute for Computer Science

University of Stuttgart

Breitwiesenstr. 20–22,

D-70565 Stuttgart, Germany

Gunzenhauser

{ressel,nitsche,rul}@ informatik.uni-stuttgart.de

ABSTRACTConcurrency control and group undo are important issues inthe design of groupware, especially for interactive group edi-tors. We present an improved version of an existing distributedalgorithm for concurrency control that is based on operationtransformations. Since the usability of the algorithm relies onits formal correctness, we present a set of necessary and suffi-cient conditions to be satisfied in order to ensure consistencyin a replicated architecture. We identify desirable proper-ties of operation transformations and show how our approachcan be employed to implement group undo. The approachhas been applied to build a prototypical group editor for text;some experiences gained are presented.

KeywordsConcurrency Control, Group Editors, Group Undo, Group-ware, Interaction Model, Operation Transformation.

INTRODUCTIONGroupware systems, i.e., multi-user applications for coopera-tive work [2, 5], present remarkable challenges for applicationdesigners. Concurrency control and group undo are two ofthem.

Concurrency control covers the management of parallelthreads of human-computer interaction including potentialconflicts. These typically arise in synchronous collaborativework when different users concurrently manipulate a sharedobject. A replicated architecture, where users work on copiesof the shared object and instructions are exchanged by mes-sage passing, has been identified as appropriate for groupware[4]. In this way, users may continue local work even if the net-work fails. Screen updates – a frequent operation in commongraphical user interfaces – can be accelerated, independentlyof network delays. The responsiveness of the user interfacecan be improved by the immediate execution of each individ-ual’s operations at the local site. Methods for concurrency

Permissionto make digital/bardcopiesof all or pan of thk materialforpersonalor classroomuse is granted withoutfee providedthat the copiesare not made or distributedfor profit or commercial advantage, the copy-right notice, the title of the publication and its date appear, and notice isgiven that copyright is by permission of the ACM, Inc. To copy otherwise,to repubtish, to post on sewers or to redistribute to tists, requires specificperrniasion andlor fee.Computer Supported Cooperative Work ’96, Cambridge MA USA@ 1996ACM o_89791-7fj5_o/96/l1 ..$3.50

control supporting this are called optimistic [6]. This entails,however, that operations are not necessarily executed in thesame sequence at different sites. Certain operations have thento be executed in an application state different from the onethey were originally issued in. The usability of a method forconcurrency control relies both on its correctness, i.e., beingable to maintain consistency among the copies of a sharedobject, and on the production of meaningful results that meetusers’ expectations.

Undo in a groupware system has to enable a user to revert theeffects of an operation even if other users have issued furtheroperations afterwards [l]. Therefore group undo has to definethe effects of undoing an operation that might not be the lastone in the interaction history. Undo of such operations has tobe interpreted and executed, however, in the current state ofthe application.

The transformation-oriented dOPT-algorithm by Ellis andGibbs [4] forms a promising approach to optimistic concur-rency control. Their basic idea is to take an operation executedin some past state and to transform it in a way that it can beapplied to the current state. We included the dOPT-algorithmin a framework for building group editors. In practise, how-ever, the dOPT-algorithm did not work in all cases. We foundout, that inconsistent application states may result if one userissues and executes more than one operation concurrently toan operation of another user. An example will be given inthe body of this paper. Fortunately, we came up with an im-proved version of the dOPT-algorithm that will be presentedhere. A novel multi-dimensional model of concurrent inter-action forms the core of our approach, enabling us to proveits correctness. It turned out, that our algorithm can help toimplement group undo as well. Thus we contribute a new,integrating, transformation-oriented approach to both concur-rency control and group undo. Finally, we present some expe-riences we have gained in building a prototypical group texteditor.

MODEL OF A GROUPWARE SYSTEMBefore presenting our approach of request transfotmationssome understanding of a groupware system is necessary. Thedefinitions have been taken in main parts from [4], but theyhave been modified if appropriate. A groupware system con-

288

Page 2: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

sists of a set S’ of application states, a set U of users and aset O of operations. For convenience, users shall be iden-tified by natural numbers, hence U = {1,2, . . . . m}. Sincewe are interested in groupware with a replicated architectureeach user’s site will hold a local application state s that ismodified only by the local application process. SO E S shalldenote the initial application state which is identical for allsites. apply is a function from S x O x U into S and computesthe resulting state s’ when user u applies operation o to appli-cation state s: apply (s, o, u) = s’. We assume the existenceof an identity operation 1, that applied to any state s resultsin the same states, independently of the user u. A groupwareapplication has to define the function apply for any allowablecombination of states, operations and users. The domain ofdefinition of apply is usually a proper subset of S x O x Uand can be used to specify restrictions that certain users maynot issue certain operations or may not issue any operationsat all. A groupware application has to define an inverse oper-ation G for every operation o that should be reversible, whereapply (apply (s, o, u), b, u) = s. New here is that the userinformation acts as an argument of the apply function.

In a simple group editor, e.g., S is the set of character strings, Oconsists of operations to delete and insert characters, to movethe cursor, etc. The insertion of a character cat buffer positionp is denoted by lms/p, c]. The deletion of character c fromposition p is denoted by Del[p, c]. Operation Del[2, a], e.g.,can only be applied if the second element of the current stringis an “a”. The inverse operation of Del[2, a] is 1rM[2, a].

Input from a user generates a request, that is broadcast to theother participants for execution. We make the assumptionthat a user generates requests sequentially, hence they can beserially numbered starting with number 1. If this is seen asa restriction, each parallel input thread may be regarded asanother virtual user. So a request can be identified uniquelyby the user identification and its serial number.

Each site executes the requests in a sequential but possiblydifferent order. Typically, a process will execute local requestsas soon as possible in order to guarantee short response times.Since by assumption the requests from each user are executedin the same order as generated, i.e., as given by their serialnumber, a set of executed request can be described by thenumber of requests it contains from each user. This motivatesthe definition of a state vector v = (xl, X2, . . . . x~ ), whereZi denotes the number of executed requests from user i. Thei-th component of a vector v will be written as v [i]. A statevector VI is defined to be smaller (earlier) than vz if eachcomponent of VI is smaller than or equal to the correspondingcomponent in vz and at least one component is smaller.

We do not consider application states when a request is inexecution. Therefore the state vector corresponding to anyapplication state that is of interest is uniquely defined.

We define arequestr more formally as a quadruple (u, k, v, o),where u G U is the user issuing the request, k E N is its serialnumber, v ~ Nn is the state vector that describes what re-quests had already been executed in the state when the requestwas generated and should have been executed originally, andfinally o E O is the operation to be applied.

u(r), k(r), v(r), and o(r) will be used to denote the corre-sponding components of a request. w(r) shall describe thestate vector after the execution of request r. For a given re-quest r, it follows: W[U] = V[U]+ 1 and w[i] = v[z], i # u,where u = u(r), w = w(r), and v = v(r). Compared to [4],no special priority value is needed, the user id fulfills this rolesufficiently. The serial number is new, it is mainly used incombination with the user id to identify user requests.

A request r is executed in the state s ● S corresponding tothe state vector v(r) by evaluating apply(s, o(r), u(r)).

Definition of Correctness

Similarly to the definition by Ellis and Gibbs [4] we define agroupware system as correct when it satisfies the precedenceproperty and the convergence property.

A request rl is said to precede r2, when its execution mighthave an effect on r2. E.g., request rl precedes request r2, ifr2 is issued in an application state, where rl has already beenexecuted. The precedence relation defines a partial orderamong requests. In particular, it is not possible that anyrequests depend upon each other cyclically.

The precedence property requires that – on every site – arequest has to be executed after all preceding requests. As hasbeen found by Ellis and Gibbs [4], the precedence property issatisfied, if a request r is made executable in a state with statevector v if and only if its state vector v(r) is smaller than orequal to v: v(r) < v.

The convergence property requires that the application statedepends only on the set of executed requests and not on thedistinct execution sequence at each site.

A sequence of requests p = r1r2 . . . rl is said to be a validsequence if b’i = 1 ...1 – 1 : w(ri) = v(ri+l). We definev(p) := v(rl ) and w(p) := w(rt). The execution of a validsequence of request is defined as the sequential execution ofits requests. Two valid sequences pl, PZ of requests are saidto be equivalent, PI ~ PZ, if being executed in the same initialstate they produce the same state (cf the use of this equivalencerelation in Definition 1 below).

REQUEST TRANSFORMATIONS

Requests that cannot be executed in the original applicationstate as specified by their state vector are transformed in orderto take into account any requests that have been executedafterwards.

Example 1 Using a group text editor, user 1 deletes charac-ter “b” at position 2, Del [2, b], and user 2 concurrently insertscharacter “a” at position 1, Ins [1, a], (cf fig. 1). Both users ap-ply their operations immediately to their own identical copiesof the application state, here the string “xby”. At site 1, theexecuted deletion request does not affect the insertion becausethe deletion may only have effects on the text to the right ofposition 2 (cf fig. 1a). At site 2, the executed insertion re-quest, however, requires that the deletion operation is shiftedone position to the right, yielding the operation Del [3, b]. Inthis way, both the resulting strings are “axy”. ❑

289

Page 3: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

Ins[l, a]

L

———+~lns[l, a] lns[l, a]

axby LDel[2, b]

‘~ ~ De,[2,b]

a) Site 1 b) Site 2

Figure 1: Necessary transformation in Example 1

The idea behind our transformation-based method is to a~-ply the transformations repeatedly to obtain valid and there~yexecutable sequences of requests at every site. In contrastto the dOPT-algorithm, intermediate requests being the re-sults of transformation steps are memorized. This forms thefoundation for the correctness of our method.

Example 2 Let the initial string of a text editor be “abed”.User 1 deletes the character “c” at position 3, Del [3, c]. User2 first deletes character “a” at position 1, Del [1, a], and theninserts character “x” in front of the character at position 3,Ins [3, z] (cf fig. 2). According to the dOPT-algorithm, a re-quest rj from site j has to be transformed with respect to allrequests in the linear history, which were not accounted for byuser j, i.e., requests which are already executed locally, butwhich were not executed on site j prior to the generation ofrj. Therefore, when site 1 receives the message from site 2with operation Del [1,a], this k transformed with respect toDel [3, c], requiring no modification. When the second opera-tion, Ins [3, x], arrives this is also transformed with respect toDel [3, c], again requiring no modification. These operationsyield a final string of “bdx” at site 1 (s. fig. 2a). When site 2receives a message from site 1 with operation Del [3, c] thisis transformed twice, first with respect to Del [1, a] yieldingDel [2, c] and then with respect to 1ns[3, z], requiring no fur-ther modification. The final string at site 2 is “bxd”. Thefinal strings at $ite 1 and 2 are different, the application statesbecame inconsistent. ❑

The reason, why the dOPT-algorithm fails in this case, isthat transforming Ins [3, x) with respect to the original oper-ation Del [3, c] and with respect to the transformed operation

Ins[3, x]

Del[l, a]

m

a) Site 1

&!El~Ins[3, x]—

AH

— ~Del[l, a]

-wDel[3, c]

ETIns [3, x]

Hi

Del[l, a]

H

b) Site 2

Del[2, cl. . . . . . .

t

Del[3, c]

Figure 2: Inconsistent transformations at different sites(Counterexample for dOPT-algorithm)

Figure 3: Consistent transformations

Del [2, c] gives different results. To produce consistent appli-cation states, at site 1 (cf fig. 2a) the second operation fromsite 2, Ins [3, ~], should have been transformed with respectto De/ [2, c], the result of transforming Del [3, c] with respectto Del [1, a] (cf fig. 3). In fact, it took us a long time to detectthis flaw. Our solution became evident, however, as we hadthe idea of visualizing transformations as grid-like diagrams.

L-Transformation functionsFormally, we define a transformation function tfas a functionfrom R x R into R x R being defined for all rl, rz < R withv(rl) = V(TZ) and u(rl) # u(rz), such that rlr~ and rzrjare valid sequences with w(?-lrj) = w(rzrj ) if flrl, rz) =(r!, rj). For convenience, we also define functions to retrievethe components of a transformation: ~1 (rl, rz ) := rj andzf2(7-l,r2) := rj, if @(rl, rz) = (r~, rj).

Definition 1 (Transformation Property 1)Iffl?-l,rz) = (rj, rj) thenrl r; ~ rz r;

The transformation property ensures that the effect of exe-cuting request rl followed by the transformed request rj isthe same as executing request r-z followed by the transformedrequest rj. This property is illustrated in fig. 4.

‘2’-+f+......

rl :rl’

y

Figure 4 L-Transformation: r-1r2’ = T27-1’

Definition 2 (Symmetry Property)If ~rl,rz) = (r~,r~), then flr2, rl) = (rj,rj)

The Symmetry Property ensures that in a replicated archi-tecture, given two requests, every user process will computethe same transformed requests, not depending on the order inwhich they are handed to the tffunction.

A transformation function that satisfies the TransformationProperty 1 and the Symmetry Property is referred to as anL-transformation function. The notion L-transformation isderived from the L-shape formed by the requests rl and r2that are to be transformed (cf fig. 4).

290

Page 4: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

L

5

4

3

E

023 014 015

2022

1021 012 013

100111 2 ~ 4 5

a)

,L

5

4

3

2

1

B 1012345

b)

Figure 5: a) Set of user requests, b) Interaction modelwith a possible execution path

A transformation function &that satisfies the Symmetry Prop-erty can be reduced to a function tfl by defining tj(rl, rz ) =

(Lf~(~1, ~2), &I(T2, n)). Since the user id, the serial numberand the state vector of the resulting request can be deducedfrom the arguments of tjl, it is actually sufficient to definethe operation of the resulting request. So, for convenience,another function T1 is introduced, where T1 (TU,rz ) = o~ if

?fl(~l, 7’2) = (ul, h, v!, o;) (cf use of this function in thedefinitions of transformation rules below).

INTERACTION MODELAs has been shown in preceding figures, requests and L-transformations can be represented as grid-based diagrams.The axes represent users, grid points represent states witha certain state vector, and arrows represent requests, beingeither original or the result of some transformation. Fig. 5shows a set of eight requests, five from user 1 and three fromuser 2. The origin of each arrow describes the state vectorof the request represented by this arrow. The operation of arequest may be written next to the arrow. From our assump-tion, that each user generates and executes his or her requestsin sequence, it follows, that each row and each column maycontain at most one original user request.

Application of the L-transformation function will yield furtherrequests that will build a dense network of arrows spreadingacross the coordinate grid, representing a model of interaction(fig. 5b). Any execution sequence of requests that satisfies thePrecedence Property corresponds one-to-one to a path in thediagram.

More formally we define an interaction model for a set M ofuser requests and for an initial state so as a labeled, directedgraph G with vertices V and edges E ~ V x V. Verticesare labeled with application states, edges with requests (al-though, it is often more convenient to label them just with theoperation, since the other components of a requests can bedetermined by the position and direction of an edge). The setof vertices, edges and their labels are defined recursively asfollows:

‘t@=(o,o, . ., O) c V, labeled so (1)

if r ● M and v(r) c V, then (2)

w(r) E V and

(v(r), w(r)) @ E, labeled r

Figure 6: Transformation Property 2: Consistent trans-formations of request r

if v E V, labeled s, and(v, w) c E, labeled r, then (3)

w is labeled with value of apply (s, o(r), u(r))

if (v, WI), (v, w2) E E labeled rl, r2, resp., then (4)

(wl, w) E E, labeled r; and

(W2, w) ~ E, labeled r; where

tj(rl, 7-2)= (r~, r;) and w = Sup(wl, W2)

SUP(WI, w2) in step (4) denotes a state vector that has as co-ordinates the maximum of the corresponding coordinates ofthe vectors WI and W2 (e.g., sup((l, 3), (5, 2)) = (5, 3)).Hence, if ~rl, r2) = (r~,rj), then w(r~) = w(?-j) =Sup(w(rl), W(?-2)).

Step (1) represents the initialization of the application state,step (2) the generation of new user requests, step (3) thestate transitions, and step (4) the request transformations. Bydefinition, each edge and each vertex will have at least onelabel. We are interested only in interaction models whosevertices have unique labels. That implies that the convergenceproperty is satisfied, provided that the initial states are identicalat each site.

Proof of correctnessThe Transformation Property 1 and the Symmetry Property arenecessary conditions, since otherwise an interaction modelthat consists of just one transformation would lead to am-biguous labeling and thus to inconsistent application statesat different sites. In fact, these two necessary conditions areeven sufficient conditions for a groupware system with m = 2users to be correct. It can easily be seen, that from a uniquelabeling of v. and unique labels at the edges representing orig-inal requests – due to the unambiguity of the transformationfunction – it follows that all additional labels of edges will beunique, too. With Transformation Property 1 it then follows,that the labels of the vertices will also be unique. Q.e.d.

The proof for more than two users is more complex: A requestcan be transformed along different, albeit equivalent paths,not necessarily yielding the same request. In the simplestcase, a request can be transformed along the two paths of

291

Page 5: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

a simple transformation step, as shown in fig. 6. Requestr may be transformed first with respect to ?’1and then to T-Lyielding @l(YI (r, T-1),T-i)– or it may be transformed first withrespect to r2 and then to rj yielding &l ($1 (r, TZ), r~ ). Notethat different sites might choose different paths for r to betransformed. So we have to make sure that both paths lead tothe same resulting request

Definition 3 (Transformation Property 2) (fig. 6)If~rl,rz) = (r; ,~;),then ~l(~l(r,rl),rj) = til(til(r,rz),r~).

Transformation Property 2 is necessary to make the labelingof edges unique. That it is sufficient will be shown in the nexttheorem.

Theorem 1The state vectors of an interaction model for m > 2 willhave unique labels if the transformation function tf is an L-transformation function satisfying Transformation Property 2.

ProofiLet the length IvI of a state vector v = (xl, x2, ..., x~) bedefined as follows: lv\ := ~~1 w. We prove by mathe-matical induction that the following assertion is true for alln ~ IVo: The labeling of edges (VI, V2), where Ivl / = n,and the labeling of vertices v, where IvI = n, will be unique,provided the transformation function used in step (4) satisfiesTransformation Properties 1 and 2 and the Symmetry Property.

n = O: Edges (vl, V2) with Ivl / = O start in V. and can belabeled only in step (2) of the definition of the interactionmodel. Thus they must have a unique label. The assertion isalso true for vertices with Ivl = O, since (O, O, . . . . O) can belabeled only in step(1).

n + n + 1: Suppose the assertion is true for O < i ~ n.First let e = (vl, V2) be an edge with Ivl I = n + 1. It eitherrepresents an original request, in which case the assertion fol-lows immediately, or it is the result of some transformation. Ifthere is only one such transformation, the uniqueness followsfrom the assumption and the unique definition of step (4). Ifthere is more than one possible transformation, the assertionfollows from Transformation Property 2 and the assumption.Second, let v be a vertex with Ivl = n+ 1. If v is the endpointof an edge for an original request, then the assertion followsimmediately (no other edge may lead into this vertex sincethat would entail cyclic dependencies among requests, beingimpossible for a set of user requests). Otherwise there will beseveral edges leading into v. According to transformation step(4) edges leading into a vertex are always created in pairs. Inthis case the unique labeling of v follows from the assumptionand the application of Transformation Property 1. Q.e.d.

THE ADOPTED-ALGORITHMNext we present and discuss the adOPTed-algorithm,that implements the application-independent parts of ourtransformation-oriented approach to concurrency control (s.figs. 7 and 8). Large parts could be taken from the dOPT-algorithm [4]. The most important differences are: TheadOPTed-algorithm introduces a multi-dimensional interac-tion model to store necessary information (2.5) and a double

recursive function Translate Request (7. 1). Both features com-bined guarantee the correctness of our adOPTed-algorithm.

Each user process manages the following local data structures:the application state s, a counter k for locally generated re-quests, a site’s state vector v, its request queue Q, a requestlog L, and an n-dimensional interaction model G. The statevector v holds the number of executions for each user. Therequest queue Q is used to store generated (3 .3) and incoming(4.4) requests that have to wait for execution. The request logL stores a copy of each original request (3.4, 4.5) so that arequest can be easily accessed by its key consisting of user

(1.1)Main:

(1.2) Initialize

(1.3) while not aborted

(1.4) if there is an input o

(1.5) Generate Request (o) ; locally

(1.6) Execute Request

(1.7) else

(1.8) Receive Request ; from remote

(1.9) Execute Request

(2.1) Initialize:

(2.2) S+so ; the initial application state

(2.3) L +- empty set

(2.4) Q + empty set

(2.5) G e initial interaction model

(2.6) ‘U+(O,O,.... O) ; initial state vector

(2.7) kel ; initial request id

(2.8) u + identification of local participant

(3.1) Generate Request (o):

(3.2) r +- (u, k,v, O)

(3.3) Q-Q+r(3.4) LeL+r(3.5) k+-k+l(3.6) broadcast r to other participants

(4.1) Receive Request:

(4.2) if there is a request from network

(4.3) choose request r(4.4) Qi-Q+r(4.5) L+-L+r

(5.1) Execute Request:

(5.2) if there is r in Q satisfying Executable? (r,v), then

(5.3) choose executable request T = (j, kj, Vj, Oj )

(5.4) QeQ– T(5.5) r“ ~ Translate Request (r,v)

(5.6) apply operation 0(7-”) as user j to states

(5.7) increment j-th component of v.

(6.1) Executable? (r,v):

(6.2) logical value of v(r) < v

Figure 7: The adOPTed-algorithm for concurrencycontrol as executed by each user process (part I)

292

Page 6: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

(7.1) Translate Request (r, v)

(7.2) (~)kj)Vj)Oj) +7’

(7.3) if Vj=v then

(7.4) add request r to model G(7.5) return T

(7.6) else if G contains / for T translated to v

(7.7) return 7-’

(7.8) else

(7.9) let z be such that

(7.10) Reachable? (Decr(v, z)) and

(7.11) Vj [’i] <= Z}[’i] – 1(7.12) v’ + Decr(v, i)

(7.13) ri + Request (i, v[zJ)

(7.14) r: + Translate Request (ri, v’)

(7.15) / + Translate Request (T, v’)

(7.16) (r”, 7-:) + tf(r’, ?-:)(7.17) add requests r“, r; to model G(7.18) return 7-”

(8.1) Reachable? (v)

(6.2) for every i in U:

(8.3) V[2]=0

(8.4) orw(Request (i, v[i])) < v

(9.1) Deer (v, z):

(9.2) return copy of v with z-th component decremented

(10.1) Request (i, j)

(10.2) return j-th request from user i in L

Figure 8: The adOPTed-algorithm for concurrencycontrol (part II)

id u and serial number k (10.1). The interaction model Gis mainly used to store transformed requests that might beneeded later. It would be possible to store application stateslike in the formal definition of the interaction model, but thisis not necessary for the algorithm to work.

The main procedure of the adOPTed-algorithm initializes alldata structures (2.2 - 2.8) and then runs into a loop (1.3 - 1.9)accepting operations from the local user, accepting requestsfrom the network, and executing local and remote requests, Ofspecial interest are the routines Execute Request and Translate

‘2~-----------or’Translate Request (ri, v’) v’ ~ #

~Translate Request (r, v’)

tUser i I

_User j II .

7Jj 7-

Figure 9: Recursive Definition of Translate Request(r, v)

Request. To execute a request, the request queue is scannedfor executable requests: A request is executable if its statevector v(r) is smaller than or equal to the current state vec-tor v (6.1 f.). If more than one request is executable, localrequests are preferred in step (5.3). This guarantees that nolocal request is waiting for execution when the local userissues further operations. The chosen executable request isdeleted from the queue (5.4) and then handed to the functionTranslate Request (7. 1ff.), to translate it to the current statevector. Translate Request translates a request r from its state

vector V(T) to a state specified by the given state vector v. Thisis done recursively: If both states are equal (7.3) the requestis returned. Otherwise (cf fig. 9) an immediate predecessor v’of v in the interaction model is determined (7.9 - 7.12), suchthat T may be translated into v’. Condition (7.10) makes surethat v’ is contained in the interaction model. Condition (7.11)guarantees that v’ is a successor of Vj, i.e., v’ can be reachedfrom Vj. If more than one such predecessor exist, it is safe tochoose any one, since the proof of Theorem 1 shows that thepath along which request r will be translated does not affectthe result. If v’ is a predecessor of v along the i-th coordi-nate axis, then let T-ibe the v[i]-th request from user i (7.13).Request ri is also translatable to v. The function TranslateRequest is called recursively to translate requests r and ri intostate vector v’. The requests obtained, r’ and r;, are then fedinto the transformation function ~ (7.16). The transformedversion r“ of request # is finally returned by function Trans-late Request. The operation of the request r“ is then appliedto the current state (5.6). The appropriate index of the currentstate vector is incremented (5.7).

The adOPTed-algorithm does not perform all possible trans-formations as suggested by step (4) of the formal definition ofthe interaction model. Rather only those requests needed infunction Translate Request are actually computed. All originaland computed requests are inserted into the interaction model(7.4, 7.1 7). Before translating a request it is first checkedwhether the result is already contained in the interaction model(7.6). In this way, every request has to be computed at mostonce.

When the request queue is growing too fast – in case receivedremote requests have to wait for execution – it may be appro-priate to notify the local user and to lock the user interface sothat for some time further input is impossible and the requestqueue can be shortened. If there is evidence that there willbe no more requests with state vectors smaller than a certainvalue, then the corresponding information in the interactionmodel may be cleared. The information can be restored fromthe request log, since it is possible to rebuild the completeinteraction model unambiguously from the original set M ofuser requests and from the initial application state so.

TRANSFORMATION RULESWhile the algorithm is application-independent, the transfor-mations have to be defined for every application. This hap-pens by defining a set of partial functions that cover the wholedomain. We call these partial functions transformation rules.

Transformation rules can be defined in several ways to satisfythe L-transformation properties. This may not be confusedwith the fact that the values of a transformation function ~

293

Page 7: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

7-2” = rz

qB-—-+=r!rl

rz’

rl ?’1’

a) 7-Z

Figure 10: a) Undo Property, b) Duality of transforma-tions

are unique, once the function is defined. Usually there isan infinite number of solutions. E.g., if the operations ofthe results of an L-transformation function are extended byapplying some extra operation oextra, the requests obtainedwill also satisfy the Transformation Properties. In practice,however, this will yield meaningless results. E.g., an extraoperation of inserting an asterisk at the beginning of the textbuffer will give consistent application states at all user sites,although not making any sense to the users.

Useful propertiesThe restrictions given for L-transformation functions are suf-ficient to guarantee consistent states at different sites, but froma user’s point of view some transformations are more appro-priate than others. We have identified especially two desirableproperties. We will refer to a request whose operation is theidentity operation I as a noop request.

Definition 4 (Noop Property)Let rI be a noop request. Then for all requests r ~ R:flr~,r) = (r~, r).

The Noop Property expresses the intuitively clear require-ment, that users do not expect the effect of their operationsbeing modified by some concurrently issued noop operation ofanother user. This property seems rather artificial, but it helpsto identify inappropriate transformation rules, like the exam-ple given above that inserts an extra asterisk. Provided anundo command is supported, the following property is moreimportant.

Definition 5 (Undo Property) (s. fig. 10a)Let fi be an undo request for rl. For all requests r2 ~ R: If

!f(Tl,m) = (r~,rj) and fjlfi, rj) = (fi’, r~), then rz = r;and 7Y’ = ~

The motivation for the Undo Property is clear. When a userexecutes an operation and, changing his mind, immediatelyundoes the operation, other users’ operations should not beaffected. Another interesting property is implied by the UndoProperty making it possible to compute transformations backand forth.

Theorem 2If the Undo Property is satisfied, transformations are invert-ible:

?f1(r2, n) =ri +=+ ffl(r~,fi) = T2 (5)

ProofiEquivalence (5) follows easily from the Undo Property (cffig. 10a).

Even L-transformation rules not satisfying the Undo or NoopProperty may be valuable, e.g., in experimental scenarios ofcollaborative arts where the overall effect need not meet userexpectations, but may in contrast be surprising.

Finding transformation rulesProbably there does not exist a constructive way of finding aset of transformation rules to define a transformation functionfor a given application which satisfies the necessary conditionsfor correct groupware, either for m = 2 or form >2 users.A heuristic method we used for finding rules, is the follow-ing: Mark the base edges on a transformation square with theconcurrent operations to be transformed, then mark the suc-cessor states with the result from applying the operations tothe original state. Decide what would be an appropriate totalresult after applying both operations and adjust the operationsaccordingly. This methods works fine, e.g., with simple textediting operations, the total result of concurrent operationsusually being unambiguous. To find rules that also satisfy theUndo Property you have to make sure that the original requestcan be reconstructed from the information contained in any ofthe transformed requests.

It is an open question under what conditions it is possible tomix generic transformation rules with any special application-dependent rules without interfering with the validity of, e.g.,the Transformation Property 2. It would be very helpful if suchgeneral conditions could be established since this would offerthe opportunity to start with a set of generic transformationrules and to add specialized rules when appropriate.

Transformation rules for text editingNext we show how to define a transformation rule for twoinsert operations of a text editor.

~I((uI,kl,VI,~~s[Pl,cl]), (u2, ~21v2>~TM[P2>c2])) (6)

{

Ins[pl, c~] ifpl < pz.—.— or (P1 = p2 and U1 < U2)

Ins [pl + 1, cl] otherwise

If the insert operation to be transformed inserts its character ata lower position (pl < p2) the operation will not be changed.If it inserts a character at a higher position (pl > p2), thenthe position will be shifted to the right (P1 + 1). If the po-sitions are equal, the operation whose request has a largeruser id is shifted to the right. This definition slightly differsfrom the one given by Ellis and Gibbs in [4]. They dropan insertion if position and character of both insertion arethe same. For example, typing “Hel 10 Mark” and typing“Hel 10 Matthew” would result in something like “Hel 10Marktthew”. We prefer our definition - keeping both in-serted characters – for several reasons. First, the insertionsare actually different, since they are performed by differentusers. Group text editors that distinguish between text insertedby different users make this obvious by presenting these textstrings in different colors or in different fonts. Second, theUndo Property is not satisfied, since immediate undoing oftyping “Hel 10 Mark” in the example given above would

294

Page 8: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

yield “tthew” and not “Hel 10 Mat t hew”. Finally, froma user’s point of view, it is better, by default, to leave infor-mation on the screen, instead of hiding it. The rare case whenusers concurrently insert the same character, e.g., to fix thesame typographical error, is handled by the awareness pro-vided: After noticing the redundant character on the screenit can be deleted. In fact, if both users would react concur-rently, oscillation could result, but such a case has never beenobserved in practice.

Next we define the transfomnation of two delete operations.

Tl((ul, kl, vl, Del[p,, c,]), (u2,k2,v2,Del[p2,c 2]))

{

Del[p~, c~] ifpl < pz.—.—Del[p~ – l,cI] if pa < p~

(7)

This means that a delete operation remains unmodified if an-other deletion has occurred before to its right. The deleteoperation has to be shifted one position to the left if anotherdeletion has happened before to its left.

For identical positions the following definition, given also byEllis and Gibbs in [4], seems obvious:

T1((ul, kl, vl, Del[pl, cl]), (~2,~2, ~2, ~e~[P2jc21))

:= I ifpl =p2 (8)

This rule works fine from the users’ point of view as longas nobody undoes one of the delete operations. In this caseeither the Noop Property or the Undo Property will fail tohold. Therefore we defined the following alternative rule forthe transformation of identical delete operations:

T1 (rl, rz) := shadow(rl , {7-2}) (9)

if o(rl ) = 0(T3) = Dei[p, c].

Shadow is a meta operation. S$adow(rl, {r2 }) means that arequest, here rl, cannot be executed as long as the requestsin the set of conflicting requests, here {T2}, have not beenundone. This may be referred to as rl being shadowed by rz.The transformation of a request containing a shadow opera-tion with respect to a request undoing one of the conflictingrequests, will delete the conflicting request from the set. If theset of conflicting request becomes empty, the shadowed re-quest can be executed again. The transformation with respectto any other request r yields another shadow operation, wherethe set of conflicting operations is extended by r. In this way,it is possible to satisfy the Undo Property without offendingthe Noop Property.

Transformations for other combinations of characterwise in-sert and delete functions are straightforward and have alreadybeen proposed by Ellis and Gibbs [4]. More complex trans-formation rules for composed operations can be found in [1O].

Duality of transformations for concurrency control andfor undoPrakash and Knister [9] provide a transformation-based mech-anism for undo in groupware and selective undo in single-userapplications. Transformations are applied to swap neighboredoperations of a linear history in order to move an operation

that is to be undone to the end of the history. Their trans-formations bear a strong resemblance to the transformationsused by our method.

Let rl and r2 represent a sequence of requests to be swapped(cf fig. 10h). The problem of transposing is to find a pair(rj, r; ) of requests such that the two sequences rlrz and rjr~are equivalent. rl rz = r~rj.

Theorem 3A solution to the transposing problem is formed by rj =

t~l (r2, fi) and rj = fi’, where fi’ := @l(m, rh).

Proofl——

rlrz = rlrzrl’rl’ (lo)— r 1fir.jfi’ (11)

— rjfi’ (12)

Equivalences (10) and (12) hold because of the neutrality ofdo-undo-pairs, equivalence (11 ) holds because of the trans-formation property 1 being applied to the transformation step(cf fig. 10b). Q.e.d.

In this way, the Transpose function given in [9] can be de-duced from our transformation function. E.g., let rl andr2 be requests to be swapped, where o(rl ) = Ins [4,x] ando(rz) = lrLs[l, ~]. Then O(E) will be Del[4, z]. It fol-lows, that o(rj) = Ins[l, y] and o(v’) = Del[5, z]. Fi-

nally, o(r~ ) = o(fi’) = 1ns[5, x]. As expected, the pair(lns[l, y), 1rM[5, z]) is identical to the result computed bythe Transpose function defined in [9]. In contrast to our trans-formation function, however, the Transpose function in [9]is only partially defined. In critical cases where insert ordelete operations happen to overlap, the value of the functionremains undefined and transposing will not be possible.

Not unexpectedly, several more similarities between the trans-formations used in both approaches can be found. E.g., ourUndo property corresponds to the Inverse Property 2 in [9],our Identity Property to the Transpose Property 4, and ourTransformation Property 2 to the Transpose Property 5.

GROUP UNDOA problem related to concurrency control is group undo. Mak-ing some operation or several operations undone is an impor-tant user intention that any editor should support [1]. Twoimportant types of group undo can usually be distinguished:global group undo and local group undo [1]. Global groupundo applies the undo operation to the last operation executed,no matter who was the initiator. Local group undo only affectssomeone’s own operations. Global group undo is appropriatefor a sequential track of interaction as, e.g., enforced by somefloor control mechanism. For group editors, where each useredits concurrently having his or her own insertion point, localgroup undo has to be provided. With global group undo, theoperation to be executed only depends on the operation tobe undone, e.g., being its inverse operation. In the case oflocal undo, it additionally depends on requests having beenexecuted in the meantime.

Most known undo schemes rely on the fact, that the applicationhas to be in the state immediately following the execution of

295

Page 9: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

Figuremation

—/‘r

F‘u

‘-l ‘7-:

/

1: Definition of local group undo by transfor-

the operation to be undone. Otherwise it will not be possibleto apply, e.g., the inverse operation to the application state inorder to make the effect undone.

Example 3 An operation like 1ns[2,a] can be immediatelyundone by the operation Del[2,a]. If, however, another oper-ation like 1ns[2,EZlhas already been applied, this would resultin deleting the wrong character, namely the letter H and not aas desired. In order to delete the right character, Del[2,a] hadto be transformed to Del[3,a], taking into account the laterinsert operation. ❑

As Example 3 suggests, the problem of single-step localgroup undo may be solved by applying transformations tothe inverse operations. Assume, you want to undo a request‘r = (Ui, ki, vi, oz) from the history, v being the current statevector (s. fig. 11). Introduce an additional virtual user il, thatgenerates an undo request F that reverts the effect of r in thestate described by state vector Wi = w(r). The request 7 isthen translated to the current state vector v of the application:Translate Request(F, v) = # (cf fig. 8). Now generate a re-quest F’ of your own in the current state v, whose operationequals the operation o(?’ ) of the translated undo request. Theextra user is needed, since the path from Wato v may containrequests from the user that issued the undo command. All thetransformations on this path are defined, however, only forrequests from different users.

Undoing the most recent request will yield the expected resultthe application state prior to the execution of this request.Note that our definition of group undo depends on the sametransformation function tfused for the purpose of concurrencycontrol.

USAGE EXPERIENCE

For testing the adOPTed-algorithm, we have built the pro-totypical group editor JOINT EMACS, an EMACS-style texteditor. JOINT EMACS has been implemented completely inCLOS (Common Lisp Object System). Its user interface hasbeen built with XIT [7]. The functionality of JOINT EMACSincludes, among other things, stringwise insert and delete op-erations and local group undo. Each author’s text is presentedwith a selectable background color or – optionally - in a certainfont. JOINTEMACS provides a “Replay’’-function allowing toreview the interaction history. The current state of interactioncan be saved and later reloaded. The grid structure can be

.:—: JOM tmacs @fhlatth ias Resse4

Joint Emacs,. !@&tt:J Replay... )~

atiti-op..—. .

-, 4

.>-

Pbsent Participants [and

Figure 12: User interface of the group editor JOINTEMACS

visualized (limited to three dimensions) making it possible toanalyze the interaction pattern.

JOINT EMACS supports a high degree of fine-grained mutualawareness, i.e., users are able to see and understand the activ-ities of other users in order to gain the right context for theirown work [3]. Conflicts that cannot be solved easily corre-late with situations where the users are manipulating closelyrelated parts. With a high probability, those conflicts can beavoided by seeing each other’s operations.

JOINT EMACS is experimental. Its main intention has beento show that our approach for concurrency control and groupundo is feasible. Nevertheless, the editor is in daily use inour group as an innovative communication tool. Comparedto other text-based communication tools like mail or talk,JOINT EMACS offers the advantage that the communicatedinformation can be modified by any participant. E.g., the firstuser may type some text, a second user may immediately fixany typos, and a third user may change the line breaking, allactivities being performed concurrently. JOINTEMACS is alsoused to write group e-mails, i.e., e-mails written by severalsenders cooperatively.

JOINTEMACS is presently in use in various sessions with up to6 users in real-world situations. A maximum of 9 users (theupper bound implemented) issuing operations concurrentlyhave been tested successfully. Typical sessions, however,include 2 to 3 participants.

Unforeseen problemsIn earlier versions of our editor we encountered a strange be-havior. With cursors at the same position, when each usertyped some text string – the individual characterwise inser-tions being not necessarily concurrent – the strings got inter-mixed. Actually, we found out the reason for that was not amistake in the adOPTed-algorithm – the individual text copies

296

Page 10: [ACM Press the 1996 ACM conference - Boston, Massachusetts, United States (1996.11.16-1996.11.20)] Proceedings of the 1996 ACM conference on Computer supported cooperative work - CSCW

showed consistent, although unexpected results – but a flawin the definition of the apply function. Originally, for everyinsert operation any cursor located at the insert position wasshifted to the right. We could fix the problem by shifting acursor to the right only if its owner has a lower id than theuser performing the insert operation.

When reverting the effect of several delete operations ofneighbored characters, we observed another strange effect,described also in [9]. E.g., let the initial string be “ah”. User 1deletes the character “a” and user 2 deletes the character “b”.Then both users undo their delete operations. The resultingstring may be “ha”, if a certain sequence of delete and undooperations is chosen. This result is totally unexpected froma user’s point of view. The reason for this anomaly is, thatthe relative positions of the delete operations are not explicitlyremembered. In fact, we found that the ordering between suchdelete operations may be determined – when needed – fromthe information implicitly contained in the interaction model.

PerformanceAs long as the interaction is sequential, our algorithm pro-duces little overhead. The computation of transformations isonly needed when concurrency increases. Unfortunately, thiscoincides with periods of high user activity. In this case, theright balance between awareness and responsiveness has tobe found: The longer you wait for handling remote requests,the more concurrent requests will accumulate and the longerit will take to compute the transformations needed. We there-fore included several adjustable parameters, that, e.g., allowto control the priority given to local user requests in relationto the handling of incoming requests from other users.

CONCLUSIONIn our research we developed an integrating approach to con-currency control and group undo that is based on the dOPT-algorithm by Ellis and Gibbs. We proved the correctness ofour adOPTed-algorithm by finding necessary and sufficientpreconditions to be satisfied for producing identical applica-tion states in a replicated groupware architecture. The Noopand Undo Properties were identified as conditions to be sat-isfied if the algorithm is to produce acceptable results from auser’s point of view. We showed how the problem of localgroup undo can be reduced to a concurrency problem by re-garding undo operations as concurrently generated operations.We further showed how the transformation-based approachby Knister and Prakash used for group undo relates to ourapproach. Many of the results mentioned in the theoreticalpart of this work would not have been attained without theexperiences gained by implementing the group editor JOINTEMACSand putting it to use.

Our approach for concurrency control and undo in group edi-tors is to be seen as an alternative and a complement to otherknown techniques rather than as a replacement. In fact, thedetected strong relationship between transformations used forconcurrency control and transformations used for group undoseems promising to put further research into the question,how results from different approaches can be combined. Wehope, that our theoretically-based work will inspire other re-searchers to look for innovative ways of computer-supportedinteraction.

ACKNOWLEDGEMENTWe would like to thank the reviewers, whose valuable critiqueand comments helped to improve this paper. Without thesupport of our former colleagues in the research group DRUID,Jiirgen Herczeg and Hubertus Hohl, this work could not havebeen realized.

REFERENCES1.

2,

3.

4.

5.

6.

7.

8.

9.

10.

Gregory D. Abowd and Alan J. Dix, Giving undo atten-tion. Interacting with Computers, 4(3):3 17–342, 1992,

Ronald M. Baecker, editor. Readings in Groupwareand Computer-supported Cooperative Work: AssistingHunzan-Human Collaboration. Morgan Kaufmann Pub-lishers, San Mateo, CA, 1993.

Paul Dourish and Victoria Bellotti. Awareness and coor-dination in shared workspaces. In Jon Turner and RobertKraut, editors, Proceedings of the CSCW ’92, pages 107–114. ACM Press, 1992.

C. A. Ellis and S. J. Gibbs. Concurrency control in group-ware systems. In Proceedings of the ACM SIGA40D ‘89Conference on the Management of Data, pages 399-407,Seattle, Washington, 1989. ACM, New York.

C.A. Ellis, S.J. Gibbs, and G.L. Rein. Groupware: Someissues and experiences. Communications of the ACM,34(l) :38-58, January 1991.

Saul Greenberg and David Marwood. Real time group-ware as a distributed system: Concurrency control and itseffect on the interface. In Richard Furuta and ChristineNeuwirth, editors, Proceedings of the CSCW ’94, pages207–21 7. ACM Press, 1994.

Jurgen Herczeg, Hubertus Hohl, and Matthias Ressel.Progress in building user interface toolkits: The worldaccording to XIT. In Proceedings of the ACM Sympo-sium on User Interface Sof~are and Technology, pages181–1 90, November 1992.

Jonathan P. Munson and Prasun Dewan. A flexible objectmerging framework. In Richard Furuta and ChristineNeuwirth, editors, Proceedings of the CSCW ’94, pages231 –242. ACM Press, 1994.

Atul Prakash and Michael J. Knister. A framework forundoing actions in collaborative systems. ACM Trans-actions on Computer-Human Interaction, 1(4): 295–330,December 1994.

Matthias Ressel. Cooperative Interaktionsunterstutzungin Groupware. In Heinz-Dieter Becker, editor, Sof~are-Ergonomie ’95. German Chapter of the ACM, Teubner,Stuttgart, 1995.

297