gpt4 book ai didi

Prolog 统一了一个变量和一个术语然后忘记了统一

转载 作者:行者123 更新时间:2023-12-01 11:14:24 24 4
gpt4 key购买 nike

我编写了以下谓词,用于识别两个列表何时相同,除了索引 I1I2 处的两个元素被交换:

swapped(I1, I2, List, NewList) :-
% The lists are the same length and the two indices are swapped.
same_length(List, NewList),
nth0(I1, List, V1), nth0(I2, List, V2),
nth0(I1, NewList, V2), nth0(I2, NewList, V1),
% All the other indices remain the same.
proper_length(List, Length), Lim is Length - 1,
numlist(0, Lim, Indices),
forall((member(I, Indices), I \= I1, I \= I2),
(nth0(I, List, V), nth0(I, NewList, V))).

以下 swipl 输出演示了我的问题:

?- swapped(0, 1, [1,2,3], L).
L = [2, 1, _G5035].

?- swapped(0, 1, [1,2,3], [2,1,3]).
true.

?- swapped(0, 1, [1,2,3], [2,1,4]).
false.

既然它可以识别出 3 是唯一正确的术语,为什么它会为第三个元素返回一个变量而不仅仅是 3?这些是统一发生然后被遗忘的跟踪的最后四个部分:

   Call: (10) lists:nth0(2, [2, 1, _G6121], 3) ? creep
Exit: (10) lists:nth0(2, [2, 1, 3], 3) ? creep
^ Exit: (8) forall(user: (member(_G6145, [0, 1, 2]), _G6145\=0, _G6145\=1), user: (nth0(_G6145, [1, 2, 3], _G6162), nth0(_G6145, [2, 1, _G6121], _G6162))) ? creep
Exit: (7) swapped(0, 1, [1, 2, 3], [2, 1, _G6121]) ? creep

我不怀疑有更好的方法来交换两个元素(也许递归地),但我想知道为什么会发生这种情况以及如何解决它;我显然缺乏一些 Prolog 知识。

谢谢!

最佳答案

forall/2 是所谓的 ' failure driven loop '.然后在周期之间取消实例化。

在 SWI-Prolog 中,有 foreach/2,这解决了您的第一个查询的问题。

...
numlist(0, Lim, Indices),
foreach((member(I, Indices), I \= I1, I \= I2),
(nth0(I, List, V), nth0(I, NewList, V))).

测试:

?- swapped(0, 1, [1,2,3], L).
L = [2, 1, 3].

在 SWI-Prolog 中,有时了解内置函数的更好方法是检查源代码。您可以看到 foreach/2 是一个相当复杂的谓词...在 swipl 提示符下,尝试 ?- edit(foreach).,或点击文档页面的源链接(带圆圈的 :- ).

关于Prolog 统一了一个变量和一个术语然后忘记了统一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54619741/

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