FOR loops

Independent processing of N tokens

In the simplest case you want to do the same task for independent data. In the workflow arena this generally means that you want to process the stream of tokens. Which in turn means that there is no loop at all, just input tokens entering the processing workflow and result tokens leaving it. Whenever possible, try to express your problem this way.

The following example shows the design for a file processing pipeline workflow. The first composite is continuously watching a directory and outputs new files packed in arrays. The ArrayToSequence actor creates a stream of file tokens from each array token. The rest of the workflow is processing each file independently from the others.

Note: Because of the changing rate of token outputs for each input token in ArrayToSequence, this workflow cannot run under SDF. However, the rest of the workflow can run under SDF as well. If you prefer SDF over PN, you can put the processing pipeline (right to the ArrayToSequence actor)into a composite actor with its own SDF director. This way you save computing resources by using a single thread for the whole processing, however, this way you loose the parallel processing capabilities of PN.

Processing pipeline for independent tokens

Processing a token iteratively N times

The author of this howto is not aware of whether this type of looping can be solved differently from the general WHILE loops in Kepler. So, please, read on to the next section.

WHILE / DO-WHILE loops

If the looping condition depends on the actual data, you need to implement the WHILE (or UNTIL) loop within the workflow control. There is no special actor or workflow construction for loops. You have to realize a WHILE loop quite similar to assembly languages, using conditional branching and jumping (have you ever heard about GOTO?).

While loop in PN

In PN, one can merge independent token streams with NondeterministicMerge, so the control flow of a while loop is easy to implement. The entry point of the loop is reached from two places: from outside to begin a loop, and from the end of the loop. If the condition holds the processing (the token) goes on the loop-inside workflow, otherwise through the exit point. The following example multiplies the a number with itself as long as the input is less than 1000. So the result is 65536 for input=2 (producing the numbers 4, 16, 256 and 65536 within the loop).
While loop in PN

Download this workflow

Do-while loop in PN

In a do-while loop, the condition is evaluated at the end of the loop, so the loop-inside part is executed at least once. The following until loop produces 65536 for input 2 as well as the above while loop. However, for inputs greater than 1001, this workflow will still do one multiplication in contrast to the while loop. The following example multiplies the a number with itself as long as the result is less than 1000.
Do-while loop in PN

Download this workflow

While loop in DDF

In DDF, the NondeterministicMerge cannot be used but there is another solution. We can use DDFBooleanSelect as we have used it for merging tokens from the branches of an IF-THEN-ELSE. However, for this we need an additional control input, therefore the result of the condition evaluation should be delivered to the select actor, too. The following figure shows the replacement of the merge actor for the select actor and the additional connections. This workflow has a cycle dependency at the select actor and therefore hangs in deadlock right at the beginning.
While loop in PN

When a workflow is drawn with a loop, the dependency graph of actors will have a cycle. The SampleDelay actor has the key role in breaking the dependency cycle in the workflow; without that the actors would wait forever for their first input. The SampleDelay is a special actor that outputs one or more tokens without input so that it brings the workflow execution in motion.

The same workflow as above with PN realized in DDF looks like the following. A SampleDelay actor is put into the control path to the select actor, which emits a false token at the beginning. This breaks the dependency, and the select actor passes the initial value coming on its false branch.
While loop in PN

Download this workflow

A nice example from Ptolemy demos

The next example is taken from Ptolemy to demonstrate a data-dependent loop. This workflow is actually a nested loop. The external loop is a FOR loop, where Ramp produces the numbers from 1 to N, and N is set in the DDFDirector as number of firing. The internal WHILE loop is then realized in the control flow within the workflow, using BooleanSwitch and DDFBooleanSelect.
Ptolemy example for data-dependent loop

Download this workflow

Special cases

Processing a file line-by-line, in SDF

Ptolemy developers were nice to provide the LineReader actor that reads a file line-by-line and produces a string token for each line. It has an EndOfFile output port, too, which outputs true when EOF is reached. With this actor, a loop on the content of a file can be realized in SDF! The loop is controlled simply by the output of the LineReader actor. Its implementation ensures (its postfire() returns false when EOF is reached, see the actor's documentation) that the loop stops when the end of file is reached.
Processing the lines of a text file

Download this workflow

Processing a file line-by-line, with external trigger

The good news is over. The above file reader loop runs in itself. But in most cases you want to put this worfklow into a larger workflow, run it when needed and do something more after finishing with the file. The author of this howto could not create such workflows in SDF, so the next example reverts back to DDF (or PN).
Processing the lines of a text file

Download this workflow