Distributed backtracking

\label{des/ext/back} Distributed backtracking is an important issue for systems that wish to support {\it don't know} non-determinism, in contrast to {\it don't care} nondeterminism where, once a choice is made, all alternatives are thrown away. The examples presented previously were deterministic in the sense that only one solution needed to be produced. The object presented in the following example, however, may produce an infinite number of solutions. \lprog{nat}{ .ds nat.pl } Its use is illustrated by .ds nat.g which will print all natural numbers, eventually. Backtracking is done lazily, in that on backtracking the object evaluating number will start to produce the next solution. \n Note that the goal :- nat!number(X), X = s(s(0)). differs from the goal :- nat!number(s(s(0))). in that the latter only communicates success, whereas the former has to communicate three bindings for X.

Backtracking in the presence of non-logical variables

\paragraphindex{backtracking} \dlpindex{backtracking} In the presence of non-logical variables mutual exclusion is needed for reasons of protection. Mutual exclusion takes effect for active objects only. This protection, however, lasts until the first answer is requested and received. This procedure is motivated by the assumption that any important change of the state of the object can be achieved during the period that the first solution is produced. Backtracking over the second and remaining solutions can be done while other processes are active. We will show how the state of an object can be fixed by binding it to a non-logical variable. Consider another variant of our, by now familiar, travel agency. \lprog{travel}{ .ds travel4.pl } In the clause for reachable we have made explicit the binding of the second argument of member to the value of the city list. Since an instance of travel is now an active object the mutual exclusion mechanism prevents the city list from being changed while the first answer for reachable is being produced. After that, member may backtrack, but with the value of the city list bound to L, as it was at the time of the call. Now suppose that we declare travel in the following, somewhat contrived, manner. \lprog{travel}{ .ds travel5.pl } The reader may check that in this case the city list may be updated, by adding elements to the front, while the process evaluating reachable is backtracking over the possible solutions. In general such interference is not desirable but, as has been shown, this can easily be avoided by binding the state of an object to a logical variable.

Deterministic objects

In many cases we do not need the full power of backtracking over the results in a rendez-vous. For instance, asking the value of a counter results in precisely one answer. Such deterministic behavior is obvious when the call contains no unbound logical variables, since the answer will then be either failure or success. To cope with the cases in which this cannot so easily be decided we have provided a way of declaring an object to be deterministic. Our counter is clearly a deterministic object. \dlpindex{deterministic} \lprog{ctr}{ .ds ctr3.pl } The prefix deterministic enforces that only one solution will be returned for each method call.