Как приостановить работу в ECLiPSe CLP, пока не будет создан полный список? - PullRequest
0 голосов
/ 28 мая 2018

ECLiPSe CLP имеет встроенный предикат приостановки (+ Goal, + Prio, + CondList), в результате чего CondList часто имеет форму X -> inst.Но как вы можете приостановить работу, пока не будет создан весь список?Если вы сделаете List -> inst, это произойдет с момента создания одного элемента.Sidenote: список не имеет фиксированного размера.

1 Ответ

0 голосов
/ 29 мая 2018

Примитив suspend / 3 может связывать цель только с переменными, которые уже существуют во время ожидания.Но когда список создается постепенно (спереди назад), переменная "tail" существующего списка становится экземпляром, и расширенный список теперь имеет новую переменную "tail".Это приводит к поведению, которое вы видите, когда цель просыпается сразу после создания первого элемента списка:

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

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

Если вы хотите дождаться завершения списка, используйте следующую схему, гдевы повторно приостанавливаете каждый раз, когда сталкиваетесь с необоснованным хвостом списка:

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).

, который ведет себя как нужно

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

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

В качестве альтернативы, если вы используете последнюю версию ECLiPSe, вы можете использовать eval_to_complete_list / 2 .В этом примере он будет распространять постепенно построенный список Ys на вспомогательную переменную Xs, как только завершится Ys, что, в свою очередь, вызывает приостановленную цель:

?- 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)
...