【问题标题】:Stop condition for recursion in prologprolog中递归的停止条件
【发布时间】:2017-06-15 10:38:46
【问题描述】:

这是我知识库中的事实(http://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/recursion.html(递归练习 2)):

taller(bob,mike).   % bob is taller than mike
taller(mike,jim).   % mike is taller than jim
taller(jim,george). % jim is taller than george

现在我想使用递归来推导出明显“bob”比“george”高的东西。

我尝试添加这条规则来解决这个问题:

taller(X,Y) :- taller(X,Z),taller(Z,Y).

我需要你的帮助来为这个递归设置一个停止条件,因为现在我遇到了堆栈溢出错误:

| ?- taller(bob,george).

Fatal Error: local stack overflow (size: 8192 Kb, environment variable used: LOCALSZ)

谢谢

【问题讨论】:

    标签: recursion prolog transitive-closure


    【解决方案1】:

    问题是您的递归taller/2 谓词定义为:

    taller(X,Y) :-
        taller(X,Z),
        taller(Z,Y).
    

    因此,一个taller/2 谓词可以总是在“调用堆栈”上产生两个新的taller/2 谓词,可以这么说,这种嵌套可以继续下去。 p>

    解决这个问题的一种方法是将知识与传递闭包分开。通过定义一个is_taller/2 谓词,计算taller/2 谓词的传递闭包,如:

    is_taller(X,Y) :-
        taller(X,Y).
    is_taller(X,Y) :-
        taller(X,Z),
        is_taller(Z,Y).
    

    现在可以说是“保证进度”,因为每次调用is_taller/2,它都会调用taller/2。由于taller/2 没有递归,因此可能的答案数量是有限的。由于taller/2严格顺序关系,最终我们会到达最短人,因此回溯将被耗尽。

    所以完整的代码应该是:

    taller(bob,mike).   % bob is taller than mike
    taller(mike,jim).   % mike is taller than jim
    taller(jim,george). % jim is taller than george
    
    is_taller(X,Y) :-
        taller(X,Y).
    is_taller(X,Y) :-
        taller(X,Z),
        is_taller(Z,Y).

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 2013-10-28
      • 2015-08-30
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多