ECLiPSe CLP具有内置谓词暂停(+目标,+ Prio,+ CondList),其中CondList通常具有X - >的形式。研究所。但是如何在实例化整个列表之前暂停?如果你做List - > inst,它将从一个元素实例化的那一刻起成功。旁注:列表没有固定的大小。
答案 0 :(得分:3)
suspend/3原语只能将目标连接到暂停时已存在的变量。但是当列表以递增方式(从前到后)构建时,现有列表的" tail" -variable将被实例化,并且扩展列表现在具有新的"尾部" - 变量。这会导致您看到的行为,即在创建第一个列表元素后立即唤醒目标:
?- 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)