如何在PROLOG中停止无限递归
我有一个关于人的知识库,以及他们基于一个数字对彼此的信任程度,如果 A 信任 B,那么 B 信任 A 的程度相同。
trusts(josemari,lucia,4.0).
trusts(raul,josemari,3.0).
trusts(luis,felipe,2.0).
trusts(manolo,felipe,2.5).
trusts(pepe,vidal,1.0).
trusts(pepe,luis,0.5).
trusts(A,B,K):-
trusts(B,A,K).
这让我陷入无限递归,那么,我怎么能打破递归呢?改变信任谓词不是一个选项,重写知识库添加对立面也不是一个选项。
回答
如果您使用 SWI-Prolog,您可以将谓词表表。只需添加一个table指令:
:- table trusts/3.
trusts(josemari,lucia,4.0).
trusts(raul,josemari,3.0).
trusts(luis,felipe,2.0).
trusts(manolo,felipe,2.5).
trusts(pepe,vidal,1.0).
trusts(pepe,luis,0.5).
trusts(A,B,K):-
trusts(B,A,K).
现在它按预期工作:
?- trusts(josemari, X, Y).
X = lucia,
Y = 4.0 ;
X = raul,
Y = 3.0.
?- trusts(luis, X, Y).
X = pepe,
Y = 0.5 ;
X = felipe,
Y = 2.0.
?- trusts(X, luis, Y).
X = pepe,
Y = 0.5 ;
X = felipe,
Y = 2.0.
?- trusts(A, B, K), K >= 3.0.
A = josemari,
B = lucia,
K = 4.0 ;
A = josemari,
B = raul,
K = 3.0 ;
A = lucia,
B = josemari,
K = 4.0 ;
A = raul,
B = josemari,
K = 3.0 ;
false.
如果您没有 SWI-Prolog 或其他带有表格的实现,则需要定义另一个规则,使用不同的名称:
trusts(josemari,lucia,4.0).
trusts(raul,josemari,3.0).
trusts(luis,felipe,2.0).
trusts(manolo,felipe,2.5).
trusts(pepe,vidal,1.0).
trusts(pepe,luis,0.5).
trusts_commutative(A, B, K):-
trusts(A, B, K).
trusts_commutative(A, B, K):-
trusts(B, A, K).
结果是一样的。
?- trusts_commutative(X, luis, Y).
X = pepe,
Y = 0.5 ;
X = felipe,
Y = 2.0.
?- trusts_commutative(A, B, K), K >= 3.0.
A = josemari,
B = lucia,
K = 4.0 ;
A = raul,
B = josemari,
K = 3.0 ;
A = lucia,
B = josemari,
K = 4.0 ;
A = josemari,
B = raul,
K = 3.0 ;
false.