gpt4 book ai didi

loops - 在 SWI-Prolog 中打破基于/3 的 "loop",同时保持其后的选择点

转载 作者:行者123 更新时间:2023-12-02 06:47:42 24 4
gpt4 key购买 nike

我需要遍历从 1 到 between/3 的一系列数字(例如使用 Length )其中 Length是给定列表的长度。迭代数,比如 N , 然后应用于谓词,比如 do_something直到它停止失败。即 do_something搜索正确的 N然后所有选择点 between/3必须放弃。但是,do_something的所有选择点使用适当的 N applied 必须被执行。

拳头尝试是这样的:

% main(+InputList, -N, -OutputList)
main(InputList, N, OutputList) :-
length(InputList, Length),
between(1, Length, N),

% cut all between/3 choice points as soon as Num is instantiated
freeze(Num, !),

do_something(InputList, N, OutputList),
Num is N.

这不是 freeze/2不剪between/3选择点。带有 when/2 的版本也没有用。我收集,这是因为两者freeze/2when/2在单独的线程中执行,不影响 between/3 的主线程是。

一段时间后,我得到了以下代码,它完成了所需的工作,但效率很低:

main(InputList, N, OutputList) :-
length (InputList, Length),
between(1, Length, N),
do_something(InputList, N, _),

% cut all prior choice points as soon as proper N is found
!,

% start do_something over!
do_something(InputList, N, OutputList).

低效率是do_something的选择点与适当的 N被执行两次。首先是在剪辑之前,然后是在剪辑之后。

尽管此解决方案适用于我的情况,但不适用于所有 do_something 时的一般情况选择点必须只执行一次。

请注意 N必须是 1..Length 中的最小值范围,并且事先不知道。因此用 do_something 搜索它.

有更好的解决方案吗?有没有办法实现类似于 between/3 的谓词?以某种方式发出信号时可以停止吗?是否可以有一个专门的内置谓词来执行所需的操作?任何富有成效的想法都将受到高度赞赏。

最佳答案

还有另一种可能性使用 *->/2 ,它是 ->/2 的变体,它不会杀死条件的选择点。现在我们不在那里,我们想要杀死一个旧的选择点。我不知道是否有Prolog系统可以这样做。自某些标记以来,大多数都有杀死所有选择点的规定,但我不知道有一个杀死特定的选择点。因此,我们必须插入一些代码来有条件地停止进一步处理。这导致:

main(InputList, N, OutputList) :-
length(InputList, Length),
State = state(cont),
between(1, Length, N),
( State = state(cont)
-> true
; !,
fail
),
( do_something(InputList, N, OutputList)
*-> nb_setarg(1, State, stop)
; fail
).

这是完全不可移植的,尽管许多系统有 *->(有时命名为 if/3)并且许多系统有某种形式的不可回溯赋值,而如果你绝望,你可以为此使用 assert/retract。

在线查看SWISH

Paulo 的回答当然更便于携带。这应该更快,并且不会在返回第一个之前评估 do_something 的所有解决方案,它也不会评估 do_something 两次。

关于loops - 在 SWI-Prolog 中打破基于/3 的 "loop",同时保持其后的选择点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53388456/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com