LEONARDO: a software visualization system - Semantic Scholar

1 downloads 0 Views 408KB Size Report
1Starting from November 1, 1997, the author's new a liation will be: Dipartimento di Sistemi ed Informatica,. Universit a di Firenze, Via Cesare Lombroso 6/17, ...
LEONARDO: a software visualization system P. Crescenzi1 C. Demetrescu I. Finocchi R. Petreschi e-mail:

Dipartimento di Scienze dell'Informazione Universita degli Studi di Roma \La Sapienza" Via Salaria 113, 00198 Roma, Italy

fpiluc, demetres, finocchi, [email protected]

ABSTRACT In this paper we present a new software visualization tool, called LEONARDO, which allows to visualize algorithms on graphs (but is easily extendable to other kinds of data structures). LEONARDO's main peculiarities are a complete use of the undo/redo mode, bounded only by the potentiality of the working machine, and a mapping between concrete and abstract data structures allowed by a new logic visualization language.

1. Introduction In the last ten years the importance of software visualization has grown more and more in view of its utility for a better understanding of the philosophy of an algorithm. An ideal approach to verify the correctness of algorithms is to test their single steps, leading the mental image of their formal properties to a visual e ect. On the other hand, this kind of visualization may help the comprehension of an algorithm because it makes visible something that may be hidden to a rst reading. According to the two taxonomies of [10] and [8], several di erent live visualization tools have been realized so far, where a tool is said to be \live" when run-time and visualization-time are considered synonymous, i.e., the user may interact with the visualization as the program is running. In the following we will brie y describe three of them. Zeus [2], the latest evolution of Balsa [5, 6, 1], is constructed on the idea of \interesting events" that must be annotated by the visualizer in the code. This implies that the visualizer must know very well the code, but, at the same time, it allows to customize the visualization according to the e ective necessities of the user. The two most recent works that make use of Zeus introduce the use of color and sound [3] and add the three-dimensional extension [4], respectively. UWPI [7] automatically provides visualizations for the high-level \abstract" data structures designed by the programmer. To this aim, its heart is an \inferencer" which analyzes each of the data structures in the source code and suggests a number of plausible abstractions for each. Finally, PAVANE [11] was designed to provide declarative three-dimensional visualizations of concurrent programs. In PAVANE the visualizer declares a transformation between the state of a computation and the nal image, according to a \declarative" style [9]. In contrast with the \imperative" one (interesting events), this approach requires a minimal knowledge of the program and doesn't require code's modi cation: this issue can be important in a concurrent framework since the execution may be non-deterministic, due to the fact that the invasive visualization code can change the outcome of a computation. All these systems allow the control of the speed of execution, support multiple views of di erent programs and, in general, guarantee an high level of interactivity. Unfortunately, they appear not to 1 Starting from November 1, 1997, the author's new aliation will be: Dipartimento di Sistemi ed Informatica, Universita di Firenze, Via Cesare Lombroso 6/17, 50134 Firenze, Italy (e-mail: [email protected] .it).

146

be simple for the user. Moreover, at the best of our knowledge, no live tool supports the execution in undo/redo mode. In this paper we present a new software visualization tool, called LEONARDO, which allows to visualize algorithms on graphs (but is easily extendable to other kinds of data structures). LEONARDO's main peculiarities are the following: 





 

At any time, the successive step in the execution of a program may be either the forward statement or the backward one. This implies a complete use of the undo/redo mode, bounded only by the potentiality of the working machine (see Section 3). A mapping between concrete and abstract data structures is allowed by a new logic visualization language, called Alpha. This transformation is automatically realized by an inference engine each time the change of the memory image is \signi cant" (see Section 4). Basically, LEONARDO can be used to visualize programs of arbitrarily large complexity. As far as we know, most of previously existing software visualization tools have been used to animate \toy" programs. LEONARDO includes a graph editor that allows the user to test the program on graphs \userfriendly" de ned. As far as we know, no other software visualization tool has this feature. Last, but not least, the system appears to be really simple to be used (see Section 5) and doesn't seem to discourage everyone who is interested in visualizing his own programs.

LEONARDO has been implemented for the MAC-OS by using the C++ language within the MetrowerksTM PowerPlant framework. Due to the fact that we used an object-oriented programming language, the implementation of LEONARDO for di erent platforms would only require the realization of some speci c classes: we estimate that this would not require more than one man-month of code writing.

2. LEONARDO's structure In this section we introduce the overall structure of LEONARDO, an integrated environment concerning both the design and the implementation of a program and the execution and the animation of the program itself. In Fig. 1 the single components of this environment are shown. Regarding the compile-time part (the upper one), it is worth observing the presence of three compilers: one for Pascal language, one for ANSI C language, and one for the new declarative language Alpha. The main feature of Alpha language is the possibility to be embedded into both Pascal and C programs, allowing the interpretation of the state of the computation through declarative instructions. Let us consider, for example, the following piece of code: ... int matrix [10][10]; /** Graph(Out 1); Node(Out N, 1) For N: InRange(N,0,9); Arc(X,Y,1) If matrix[X][Y]==1; **/ ...

147

source

Text Editor

source

lexical analysis

C Preprocessor

Syntax coloring

Errors C Compiler

Alpha Compiler

Pascal Compiler

Errors

Errors object file

object file

Linker processes scheduling

Source Trace window

executable file

multi-tasking

Run Time forward

AAAA AAA AAAA AAA AAAAAAA Graph Editor

Compile Time

backward

data input

Virtual

text output

Machine

current instruction

temporary file on secondary memory

AAA AAA AAAAAA undo / redo buffer

Console window

machine control control window

computation state

visualization event: a variable has been modified query: what to visualize ?

Inference Engine

answer: abstract information of visual objects (nodes, arcs, features ...)

AAAA AAA AAAAAAA Visualizer

visual objects

Offscreen drawing

smooth transitions

Figure 1: LEONARDO's structure

148

Multiple views

The Alpha predicates (which are included within /** and **/) tell the visualizer to interpret as a graph the concrete data structure matrix. In this way, the visualized image will automatically re ect the changes to the variable matrix with no explicit action of the user, as it is required in the imperative visualization approach. It is worth noticing that the Alpha declarations will be ignored by a standard C (or Pascal) compiler since they will be considered as a comment. In the lower part of Fig. 1, we have to distinguish two kernels: on one hand, the stack-based virtual machine for the program execution, on the other, the inference engine and the visualizer for the program animation. The virtual machine is designed to execute programs both step-by-step and in continuous mode, controlling the speed and the direction of the executions. Preemptive multi-task modality and multiple views are allowed.

3. Undo/Redo The execution of a program, that is, a process, may be intuitively viewed as a series of atomic transformations of its states (in this context the state may be de ned as the code and the memory image). These transformations are called \events" and di er in the various software visualization systems for their \granularity": in LEONARDO an event is the passage from a Pascal/C statement to one of its adjacent ones. The observation of the events allows the user to understand how the program works. Since the analysis of an event may require a deeper insight of events already encountered, the possibility of going back to a previous state appears to be a fundamental feature. In literature, this possibility seems to be connected only with the \post-mortem" systems, i.e., systems in which visualization acts after the process has run. On the contrary, LEONARDO is a live system that allows the user to interact with both directions of the program execution. The undo/redo mechanism has been realized by specifying a format of the virtual machine instructions which is characterized by the inversion modality. Speci c information are either stored or gathered from temporary les on secondary memory, but the execution uidity is not a ected since this interaction is managed in an asynchronous way. The dimension of the temporary les is limited only by the available space on the secondary memory. As an example we consider the sum of two integer values of 1 byte each. Let X = 00000111, Y = 00000001 and Z = X + Y = 00001000. X and Y are stored on the top of the run-time stack. In forward mode, the addition operator puts X and Y onto the undo/redo bu er and the sum Z on the top of the stack. In backward mode, instead, the stack is popped while the bytes concerning X and Y are retrieved from the undo/redo bu er and pushed again onto the run-time stack. For what concerns the undo/redo of the visualization, basically nothing has to be done. Indeed, the presence of the inference engine guarantees that it is sucient to restore the computation state: the image will be automatically re-generated starting from this state. The undo/redo modality is guaranteed by LEONARDO also for printing instructions: actually, printing in backward mode is operationally equivalent to delete part of the console.

4. Declarative visualization One of the main novelties of LEONARDO consists of the approach followed in order to implement the declarative visualization. The basic motivation behind this approach is the same that inspired the development of logic programming languages, that is, the fact that there are several advantages when preferring declaratively represented knowledge: (a) such knowledge can be changed easily; (b) it can be used for di erent purposes; (c) it can be extended, beyond that explicitly represented, by reasoning processes; and (d) can be accessed by \introspective" programs. In our context, the advantages of using a declarative approach seem to be extremely valuable. Indeed, expressing the visualization events by means of declarations makes the change of these events very easy to be performed: for instance, if the programmer decides to implement the graph by means

149

of an adjacency matrix instead of an adjacency list, the only thing to be done (from the visualization point of view) is to modify the Alpha Arc predicate (see the next section). Moreover, our approach allows the user to make the visualizer interpret any kind of data structures (di erently from the procedural approach in which data structures are constrained by the available library functions). Indeed, it is even possible to have no data structure at all: for instance, the user could de ne a graph implicitly (e.g. exists an arc from node i to node j if and only if i is prime and j = i2 ). Finally, the structure of the graph may depend indirectly on data that are not explicitly used to de ne the structure itself. Our inference engine, in fact, allows to reason on the Alpha predicates in order to derive new knowledge from that explicitly de ned by the user. On the other hand, it must be said that the declarative approach usually is more costly and slower than the procedural one. However, the overall complexity of LEONARDO hides, in a certain sense, the price to be paid in order to use a declarative visualization. The experiments we have performed seem to indicate that, after all, the system does not really su er of the fact that processing declarative knowledge is less ecient than executing procedures. Using the declarative approach requires, of course, a certain amount of initial e ort in order to understand how the declarations have to be inserted. However, once this has been learned, visualizing a program becomes extremely easy and does not require a deep understanding of the program itself. Moreover, declarations can describe formal properties of the algorithm: if the user does not see these properties re ected in the visualization, then he/she can conclude that either the algorithm or its implementation is wrong (unless the declarations are not correctly written!). 4.1. The Alpha language

Alpha can be seen as a logic programming language mainly devoted to the description of a set of visual objects. An Alpha program consists of a sequence of predicates that de ne these objects and their interrelationships. Syntactically, a predicate is de ned by means of a sequence of head-body pairs. The head speci es the name of the predicate and its formal parameters (that is, the way the predicate communicates with the environment) while the body speci es the computations that de ne abstract objects or allow to verify relationships among objects. Due to the lack of space, we cannot formally de ne the language and we will thus limit ourselves to give a simple example of an Alpha program (another example related to visualization will be presented in the next section). The following declarations compute the factorial of an integer number: fact(0, Out 1) Otherwise fact(N, Out F) If N>0 For Z:fact(N-1, Z) Assign F=N*Z;

In this case, there are two rst head-body pairs separated by the keyword Otherwise. The rst pair de nes the base case declaring that the factorial of 0 is equal to 1. The second pair introduces an auxiliary variable Z that receives as value the factorial of N-1. The factorial of N is then assigned to F and is correctly declared as N*Z.

5. An example In this nal section, we will brie y describe an example of the usage of LEONARDO. In particular, we will show how the well-known depth- rst visit of a directed graph can be animated in our framework. 5.1. The program

First let us analyze the code. The rst part includes some headers and de ne one constant and some data structures: 150

Figure 2: The state of LEONARDO after loading of the graph #include #define MAX_NODES 100 int int int int

gNumNodes; g[MAX_NODES][MAX_NODES]; father[MAX_NODES]; visited[MAX_NODES];

The second part of the code contains the main Alpha declarations: /** Graph(Out 1); Directed(1); Node(Out N,1) For InRange(N,0,gNumNodes-1); Arc(X,Y,1) If g[X][Y]==1; ArcColor(X,Y,Out Blue,1) If X==father[Y]; ArcWidth(X,Y,Out 3,1) If X==father[Y]; **/

151

Figure 3: The state of LEONARDO after calling DFS(0)

Basically, these declarations tell the visualizer that: (a) one directed graph exists whose label is 1; (b) the number of nodes of the graph is equal to the value of variable gNumNodes; (c) an arc exists between two nodes X and Y if and only if the value of g[X][Y] is 1 (that is, g represents the adjacency matrix of the graph); (d) if X is the father of Y with respect to the depth- rst order then the arc from X to Y is colored with blue and is thicker than the standard ones. The third part of the code interacts with the graph editor in order to initialize the graph: void LoadGraph(){ int i; OpenGraphEditor(); gNumNodes=GetNodesCount(); for (i=1 ; i