gpt4 book ai didi

prolog - (SWI) 序言 : Order of sub-goals

转载 作者:行者123 更新时间:2023-12-04 16:22:58 25 4
gpt4 key购买 nike

我有两个略有不同的谓词实现,unique_element/2 ,在序言中。当给定一个元素时,谓词成功 X和一个列表 L , 元素 X在列表中只出现一次。下面是实现和结果:
实现1:

%%% unique_element/2
unique_element(Elem, [Elem|T]) :-
not(member(Elem, T)).
unique_element(Elem, [H|T]) :-
member(Elem, T),
H\==Elem,
unique_element(Elem, T),
!.
结果:
?- unique_element(X, [a, a, b, c, c, b]). 
false.

?- unique_element(X, [a, b, c, c, b, d]).
X = a ;
X = d.
实现2:
%%% unique_element/2
unique_element(Elem, [Elem|T]) :-
not(member(Elem, T)).
unique_element(Elem, [H|T]) :-
H\==Elem,
member(Elem, T),
unique_element(Elem, T),
!.
如果您第一眼没有注意到: H\==Elemmember(Elem, T)在第二个实现中翻转,规则 2。
结果:
?- unique_element(X, [a, a, b, c, c, b]).
X = a.

?- unique_element(X, [a, b, c, c, b, d]).
X = a ;
X = d.
问题:在这种情况下,顺序如何影响结果?我意识到规则/事实/等的顺序很重要。不过,这两个被翻转的特定规则似乎没有“连接”或以某种方式相互影响(例如 cut 在错误的位置/顺序)。
注意:我们在这里讨论的是 SWI-Prolog。
注 2:我知道,可能有不同的更好的实现。我的问题是关于更改子目标的顺序。

最佳答案

H\==Elem正在测试执行目标时的句法不等式。但后来的统一可能会使变量相同:

?- H\==Elem, H = Elem.
H = Elem.

?- H\==Elem, H = Elem, H\==Elem.
false.

所以在这里我们测试它们是否(语法上)不同,然后它们仍然是统一的,因此不再不同。因此,这只是一个临时测试。

目标 member(Elem, T)另一方面,如果 Elem 为真实际上是 T 的一个元素.考虑:
 ?- member(Elem, [X]).
Elem = X.

可以读作

(When) does it hold that Elem is an element of the list [X]?



答案是

It holds under certain circumstances, namely when Elem = X.



如果你现在在你的程序中混合这些不同类型的目标,你会得到奇怪的结果,这只能通过详细检查你的程序来解释。

作为初学者,最好只坚持 Prolog 的纯部分。在你的情况下:
  • 使用 dif/2代替 \==
  • 不要使用削减 - 在您的情况下,它将答案的数量限制为两个。如unique_element(X, [a,b,c])
  • 不要使用 not/1也不是 (\+)/1 .它会产生更多的不正确性。考虑 unique_element(a,[a,X]),X=b.错误地失败,而 X=b,unique_element(a,[a,X])正确成功。


  • 这是您程序的直接纯化版本。还有改进的空间!
    non_member(_X, []).
    non_member(X, [E|Es]) :-
    dif(X, E),
    non_member(X, Es).

    unique_element(Elem, [Elem|T]) :-
    non_member(Elem, T).
    unique_element(Elem, [H|T]) :-
    dif(H,Elem),
    % member(Elem, T), % makes unique_element(a,[b,a,a|Xs]) loop
    unique_element(Elem, T).

    ?- unique_element(a,[a,X]).
    dif(X, a)
    ; false. % superfluous

    ?- unique_element(X,[E1,E2,E3]).
    X = E1,
    dif(E1, E3),
    dif(E1, E2)
    ; X = E2,
    dif(E2, E3),
    dif(E1, E2)
    ; X = E3,
    dif(E2, E3),
    dif(E1, E3)
    ; false.

    请注意最后一个查询的读取方式?

    When is X a unique element of (any) list [E1,E2,E3]?



    答案是三重的。一个接一个地考虑:

    X is E1 but only if it is different to E2 and E3



    等等。

    关于prolog - (SWI) 序言 : Order of sub-goals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43553288/

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