Execution Strategy

EDEN is neither purely declarative (in which case the execution strategy does not affect the result) nor purely procedural (some side-effect are triggered rather than called explicitly). Therefore, the user needs to aware of the execution strategy in order to make the most out of EDEN.

EDEN takes precedence of formula evaluation over actions. This means that EDEN will update all the value changes to the variables first. The triggered actions are queued in an action queue. After all the variables are updated, those actions queued will be performed. This will ensure that any reference to a variable will get the most up-to-date value.

EDEN also uses a breath-first scheme of evaluation. Under such scheme, the interpreter spends more time on scheduling the order of evaluation than a depth-first scheme but it has an advantage of doing the evaluation of variable or the triggered actions only once in each phase. For example:

proc dummy : A {  /* dummy() will be executed when A changes */
        auto i;   /* local variable */
        for (i = 1; i <= 10; i++) {
                V = i;
        }
}

proc Print_V : V {
        write(V, ' ');
}

A = 1;     /* change A to trigger dummy() */

the interpreter will produces the output:

        10

rather than

        1 2 3 4 5 6 7 8 9 10

While the depth-first scheme is good at monitoring the change of values, the breath-first scheme the current implementation using is more efficient in producing the final result. Should the later output is preferred, the user has to force the interpreter to execute the actions in the action queue by a eager() statement. For the above example, the required result can be generated if dummy is alternatively defined as:

proc dummy : A {   /* dummy() will be executed when A changes */
        auto i;   /* local variable */
        for (i = 1; i <= 10; i++) {
                V = i;
                eager();   /* force execution of action queue */
        }
}

One should not presume the order of action execution. A general principle is that if the order of execution will significantly affect the result, it is likely that it is not a good program. However, some sort of ordering is necessary. A typical example is the simulation of a clocked system. In a clocked system, there should be actions such as:

proc clocking : clock {   /* a clocking process */
        clock++;           /* advance the clock */
}

proc device1: clock {  /* action synchronised by clock */
        ...   /* action body */
}

proc device2: clock {
        ...   /* action body */
}

...

In these cases, the clocking action should be executed last so that it would not block out other actions to be performed in this clock cycle. To solve this scheduling problem, EDEN has a to-do list (in fact two to-do lists, one currently executing and the other one is really to be executed). The clocking action above should be rewritten as:

proc clocking : clock {   /* a clocking process */
        todo("clock++;");        /* advance the clock in future */
}

This will cause the statement:

clock++;

to be saved in the (future) to-do list. After all the triggerred actions and things-to-do in the current to-do list have been executed, the system will perform those statements in the future (now becomes the current) to-do list. In this case, when clock++ is executed, all other actions will be triggered and executed in this 'clock cycle' and another clock++ statement is scheduled to do after all the necessary actions are performed in this clock cycle.


[BACK] [HOME] [UP] [HELP]