简体   繁体   中英

How to suspend in ECLiPSe CLP until full list is instantiated?

ECLiPSe CLP has a built-in predicate suspend(+Goal, +Prio, +CondList) whereby CondList often is of the form X -> inst. But how can you suspend until a whole list is instantiated? If you do List -> inst, it will succeed from the moment one element is instantiated. Sidenote: the list does not have a fixed size.

The suspend/3 primitive can only connect a goal to variables that already exist at suspend-time. But when a list is built up incrementally (from front to back), the "tail"-variable of the existing list becomes instantiated, and the extended list now has a new "tail"-variable. This leads to the behaviour you see, where the goal is woken immediately after the first list element has been created:

?- suspend(writeln(now:Xs), 0, Xs->inst), length(Xs, 5).
now : [_510|_511]

Xs = [_510, _520, _522, _524, _526]
Yes (0.00s cpu)

If you want to wait for the list to be complete, use the following scheme, where you re-suspend every time you encounter an uninstantiated list tail:

write_complete_list(Xs) :-
    write_complete_list(Xs, Xs).

write_complete_list(Xs, Ts) :- var(Ts), !,
    suspend(write_complete_list(Xs,Ts), 0, Ts->inst).
write_complete_list(Xs, [_|Ts]) :-
    write_complete_list(Xs, Ts).
write_complete_list(Xs, []) :-    % Xs is now a complete list
    writeln(now:Xs).

which behaves as desired

?- write_complete_list(Xs), length(Xs, 5).
now : [_514, _542, _570, _598, _626]

Xs = [_514, _542, _570, _598, _626]
Yes (0.00s cpu)

Alternatively, if you are using the latest release of ECLiPSe, you could employ eval_to_complete_list/2 . In this example, it will propagate the incrementally constructed list Ys to the auxiliary variable Xs as soon as Ys is complete, which in turn triggers the suspended goal:

?- suspend(writeln(now:Xs), 0, Xs->inst), eval_to_complete_list(Ys, Xs), length(Ys, 5).
now : [_597, _626, _655, _684, _713]

Xs = [_597, _626, _655, _684, _713]
Ys = [_597, _626, _655, _684, _713]
Yes (0.00s cpu)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM