In a previous column ( http://csdl2.computer.org/comp/mags/ds/2006/11/oy002.pdf), I gave an overview of a beginner's course on flexible algorithms that my colleagues and I developed at the Jerusalem College of Technology. Here I briefly describe this notation's main features and present fragments from this course.

The core algorithmic notation of flexible algorithms is based on functions with In parameters and Out parameters (but no In/Out parameters) and conditional statements. As in mathematics, variables and parameters receive a value only once. Blocks and loops (including nested forms) aren't part of the core language but are abbreviations for certain compound forms in the core language. Our notation has an iterative style and includes a once-only assignment statement.

Because our notation can't update variables and parameters, it enables parallel execution.

The course notes ( http://www.rby.name) present examples of flexible algorithms and their execution by three methods that use the same sets and values form:

- parallel execution,
- sequential execution with immediate execution of function calls or activations, and
- sequential execution with delayed execution of function calls or activations.

To save space, I'll only discuss parallel execution here.

Here I present some fragments from the course material.

The following is a flexible algorithm for reversing five values.

Suppose we wish to execute the statement a'b'c'd'e' •= rev5 (1, 2, 3, 4, 5). We begin by writing this as a set of one element, namely {a', b', c', d', e' •= rev5(1, 2, 3, 4, 5) }. The steps of the parallel execution are given below.

For educational reasons, we presented a specific solution for five values before giving a function for reversing part of a vector. We also presented three execution methods for reversing a five-element vector using this general solution. See the course notes( http://www.rby.name) for details.

Two kinds of errors can occur. Syntax errors occur in the flexible algorithm's form or syntax, making executing the algorithm pointless. (In other words, you don't need to execute the algorithm to see that an error exists.) Execution (or *runtime*) errors occur when a flexible algorithm is executed.

The following is an example of a syntax error:

Other syntax errors include brackets that don't balance, punctuation errors, and so forth.

The following is an example of an execution error:

However, if the value of *x* is 3, an error occurs during execution, because two assignments are made to *x*' (a conflict).

Avoiding these errors has the benefit of encouraging students to write in a style that enables but doesn't force parallel execution.

The statement s' •= a 0 + a 1 + … a 7 is equivalent to s' •= ((…(a 0 + a 1) + a 2) + a 3) + … a 7) when fully bracketed. Bracketing the statement in this way forces sequential evaluation. Rebracketing the expression in the following statement enables parallel evaluation:

s' •= (((a 0 + a 1) + (a 2 + a 3)) + ((a 4 + a 5) + (a 6 + a 7))) (1)

Intuitively, the calculation of s' in this way is performed as in figure 1.

Figure 1 . The calculation of s' using statement (1).

In figure 1, it's useful to view each occurrence of *a _{i}* as a separate variable. This view simplifies writing the calculation as a flexible algorithm in which subexpressions can be computed in parallel. So, for example, there are three variables named

Here are three functions for carrying out the computation in this way:

Here's the parallel execution of s' •= add8(1, 2, 3, 4, -1, -2, -3, -4).

Here's how we can generalize the previous example to handle a vector of *n* elements, where *n* is a power of 2. (A simple exercise that the students later perform is generalizing this solution so that it works for vectors of any size, not just a power of 2.)

(You can replace the lines from v 0 •= v 0 + v 1; to v n/2—1 •= v n—2 + v n—1 with a forall loop; see the course notes http://www.rby.name for details.)

Here's the parallel execution of s' •= addn((1, 2, 3, 4, -1, -2, -3, -4), 8).

Another simple exercise is to write a flexible algorithm to find a vector's minimum value using the structure of the function addn. The students need only to replace the operator + with a function min for determining the minimum of two values and then write the definition of the function min.

We use the structure of the function addn to develop the bottom-up merge-sort algorithm. This gives students a gentle introduction to a subtle sorting technique that enables parallel sorting of a vector.

This technique sorts a vector by repeated merging. For simplicity, we assume that the vector's length is a power of 2. For example, suppose we wish to sort a vector of eight elements. We view this as eight single elements, and each single element is sorted. Here, for example, is a vector of eight elements:

(8, 1, 7, 2, 6, 3, 5, 4)

We merge pairs of single elements to obtain

(1,8, 2,7, 3,6, 4,5)

We now have four sorted pairs, and we merge two and two pairs to obtain

(1,2,7,8, 3,4,5,6)

This gives us two sorted runs of four elements, which we merge to obtain a sorted vector:

(1, 2, 3, 4, 5, 6, 7, 8)

At each stage, the sorted run in the vector doubles in size from the previous stage. The number of sorted runs in the vector is halved with respect to the previous stage (see Table 1).

Table 1. Number and size of sorted runs.

The number of sorted runs is like the number of values *n* to be added in the addn function. They would both progress 8, 4, 2, 1 when there are eight values.

Suppose we have a function m2 with specification as follows.

Let's now use the function m2 to define the function mergesort.

(You can replace the lines from v•=m2(v,size,0); to v•=m2(v,size,length of v — (2´size) with a forall loop; see the course notes ( http://www.rby.name) for details.)

The course notes http://www.rby.name contain both a textual (hard to understand) and diagrammatic (easy to understand) development of a hardware block diagram for a serial adder, including its function definition in both textual and diagrammatic forms. (They also include an example of parallel execution in textual form.) Here, we only use the diagrammatic approach.

We assume that there's a function a3b for adding three digits that produces two results—a sum digit and a carry digit. For example, executing c', s' •= a3b(9, 3, 1) would make s' •= 3 and c' •= 1. (Here s' is the sum and c' is the carry, each being a single digit.) Figure 2 shows a diagrammatic representation of a3b.

Figure 2 A diagrammatic representation of a3b

The function add adds two numbers consisting of several digits and an existing single-digit carry. It gives two results, a sum consisting of several digits and a carry consisting of one digit. We assume that both numbers being added and the sum produced consist of *n* + 1 digits, where *n* denotes the position of the least significant digit. The most significant digit has position zero.

Figure 3a represents a function call c', s' •= add(u, v, c, n). We can write equivalent diagrams for this function (see figures 3b and c).

Figure 3 (a) A function call c', s' •= add(u, v, c, n) is equivalent to different diagrams (b—c), depending on whether n > 0 or not.

The call for a 4-digit adder is c', s' •=add(u, v, c, 3) (see figure 4a), which is equivalent to several other diagrams (see figures 4b—d) before resulting in the final diagram (see figure 4e).

Figure 4 A 4-digit adder: (a) the call, (b—d) equivalent diagrams, and (e) the final diagram.

These fragments of the course material are all I can present in the space available, but I hope they give you a good idea of our approach. In the future, I hope to report on using this approach in secondary schools. I also hope to develop material for advanced students, such as the conversion of a flexible algorithm into a parallel algorithm where the parallelism is explicit.

- DS Online's Education Archives
- "Report from the Ubicomp Education Workshop,"
*IEEE Pervasive Computing* - "From Research to Classroom: A Course in Pervasive Computing,"
*IEEE Pervasive Computing* - "An Undergraduate Success Story: A Computer Science and Electrical Engineering Integrative Experience,"
*IEEE Pervasive Computing*

Cite this article:

R.B. Yehezkael, "Flexible Algorithms: Fragments from a Beginners' Course," *IEEE Distributed Systems Online*, vol. 8, no. 2, 2007, art. no. 0702-o2001.

This column is based on "Flexible Algorithms: Selections from a Course for Beginners," a presentation I gave at the 4th IEEE International Conference on Information Technology: Research and Education.

R.B. Yehezkael (formerly Haskell) is an independent academic who retired from the Jerusalem College of Technology. Contact him at rafi@jct.ac.il; http://cc.jct.ac.il/~rafi.