为什么在定义转换两个原子关系的谓词时会出现堆栈限制超出错误? [英] Why do i get a stack limit exceeded error when defining a predicate that convert the relation of two atoms?
问题描述
我想知道为什么在这些情况下程序会无限递归:
I want to know why does the program goes in an infinite recursion in those cases:
?- love(kay, amanda).
和
?- love(rob, amanda).
这是代码:
love(amanda, kay).
love(kay, geo).
love(geo, rob).
love(X, Y) :-
love(X, Z),
love(Z, Y).
love(X, Y) :-
love(Y, X).
推荐答案
首先,您的程序总是进入无限循环.无论您使用什么名称.甚至 ?- love(amanda, kay).
循环.为了更好地看到这一点,而不是问 ?-loves(amanda, kay), false.
为什么我这么确定你的程序总是循环?
First, your program always goes into an infinite loop. No matter what names you are using. Even ?- loves(amanda, kay).
loops. To better see this rather ask ?- loves(amanda, kay), false.
Why am I so sure that your program always loops?
要看到这一点,我们需要做一些假动作.通过在您的程序中添加目标 false
,我们得到了一个需要更少(或相等)推理的新程序.
To see this, we need some falsework. By adding goals false
into your program, we get a new program requiring less (or equal) inferences.
love(amanda, kay) :- false.
love(kay, geo) :- false.
love(geo, rob) :- false.
love(X, Y) :-
love(X, Z), false,
love(Z, Y).
love(X, Y) :- false,
love(Y, X).
因为这个片段(称为 failure-slice) 不会终止,您的原始程序不会终止.如您所见,所有人员都已被删除.因此,真实姓名不会影响结果.
Because this fragment (called a failure-slice) does not terminate, your original program will not terminate. As you can see, all the persons have been removed. And thus actual names cannot influence the outcome.
如果你想修正可交换性,不如引入一个进一步的谓词:
If you want to fix commutativity, rather introduce a further predicate:
love2(X, Y) :- love1(X, Y).
love2(X, Y) :- love1(Y, X).
要包含传递闭包,请使用 closure/3:
And to include the transitive closure, use closure/3:
love3(X, Y) :-
closure(love2, X, Y).
这篇关于为什么在定义转换两个原子关系的谓词时会出现堆栈限制超出错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!