为什么循环引用和递归会使我的程序失败? [英] Why do circular references and recursion make my program fail?

查看:132
本文介绍了为什么循环引用和递归会使我的程序失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了这个简单的Prolog程序.

I wrote this simple Prolog program.

man(socrates).
mortal(X) :- man(X).
immortal(X) :- immortal(X).

我问了一些常见的问题,例如苏格拉底是男人还是苏格拉底是凡人.

I asked it the usual questions, such as whether Socrates is a man or if Socrates is a mortal.

?- man(socrates).
true.                    //we know for a fact that Socrates is a man
?- mortal(socrates).
true.                    //and it can logically be inferred that Socrates is mortal
?- immortal(socrates).
                         //but we can't seem to figure out if he's immortal

由于immortal的递归定义而崩溃.循环引用还会使它崩溃或出现错误,并显示Out of stack space.

It crashed because of the recursive definition of immortal. Circular references also make it crash or error with Out of stack space.

在我看来,至少在这种情况下,对于Prolog先生而言,得出结论,从该程序中的规则得出苏格拉底是不朽的,将是微不足道的.如何?我想它可以检查堆栈并查看它是否正在遍历已经遍历的规则.

It seems to me that, at least in this case, it would be fairly trivial for Mr. Prolog to conclude that from the rules in the program, it cannot be inferred that Socrates is immortal. How? I imagine it could examine the stack and see if it is traversing a rule that has already been traversed.

有没有理由不执行该程序的原因?这样做会不会引起我的注意,还是存在已经进行了这种分析的Prolog实施?

Is there a reason why this isn't already implemented? Would there be some problem with doing so that I am overlooking, or are there implementations of Prolog that already perform such analysis?

推荐答案

在我看来,至少在这种情况下,对于Prolog先生得出结论,从程序规则中得出结论,苏格拉底是不朽的,将是微不足道的.

It seems to me that, at least in this case, it would be fairly trivial for Mr. Prolog to conclude that from the rules in the program, it cannot be inferred that Socrates is immortal.

Prolog使用不完整的推理算法来提高效率.它的意思是成为一种编程语言,在这种语言中,程序除了具有程序性之外,还具有逻辑意义,而不是成熟的定理证明者.您必须注意子句的编写顺序,防止循环定义等.

Prolog uses an incomplete inference algorithm for efficiency. It's meant to be a programming language where programs have a logical meaning in addition to a procedural one, not a full-blown theorem prover. You have to be careful with the order in which you write the clauses, prevent circular definitions, etc.

关于谓词immortal的逻辑含义,它是

As for the logical meaning of your predicate immortal, it's

immortal(X) -> immortal(X)

是重言式,可以在不更改其逻辑含义的情况下从程序/理论中删除.这意味着如果有助于改善程序含义(摆脱无限循环),则应将其删除.

which is a tautology and can be removed from your program/theory without changing its logical meaning. This means you should remove it if that helps to improve the procedural meaning (gets rid of an infinite loop).

这篇关于为什么循环引用和递归会使我的程序失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆