我写了这个简单的Prolog程序。
man(socrates).
mortal(X) :- man(X).
immortal(X) :- immortal(X).
我问过常见的问题,比如苏格拉底是男人还是苏格拉底是凡人。
?- 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.
在我看来,至少在这种情况下,Prolog先生得出的结论是,根据该计划的规则,无法推断苏格拉底是不朽的,这是相当微不足道的。怎么样?我想它可以检查堆栈并查看它是否遍历已经遍历的规则。
有没有原因尚未实施?这样做会有一些问题,我忽略了,还是Prolog的实现已经进行了这样的分析?
答案 0 :(得分:6)
在我看来,至少在这种情况下,Prolog先生得出的结论是,根据该计划的规则,无法推断苏格拉底是不朽的,这是相当微不足道的。
Prolog使用不完整的推理算法来提高效率。它本来是一种编程语言,除了程序性的程序之外,程序还具有逻辑意义,而不是一个完整的定理证明者。您必须小心编写子句的顺序,防止循环定义等。
至于谓词immortal
的逻辑含义,它是
immortal(X) -> immortal(X)
这是一个重言式,可以在不改变其逻辑含义的情况下从您的程序/理论中删除。这意味着你应该删除它,如果这有助于改善程序意义(摆脱无限循环)。
答案 1 :(得分:3)
将表格与XSB一起使用:
:- table foo/1.
foo(X) :- foo(X).
bar(X) :- bar(X).
然后:
| ?- [tabled].
[tabled loaded]
yes
| ?- foo(1).
no
| ?- bar(1). % does not finish
答案 2 :(得分:2)
您的定义 - 以及您如何解释它们:
man(socrates).
苏格拉底是一个男人。
mortal(X) :- man(X).
每个人都是凡人。
immortal(X) :- immortal(X).
每一个不朽都是不朽的。
您的定义 - 以及Prolog如何解释它们:
man(socrates).
如果你问苏格拉底的男子气概,我知道这是真的。
mortal(X) :- man(X).
如果你问我某人的死亡率,我会检查他的男子气概(如果这是真的,那么死亡率也是如此)。
immortal(X) :- immortal(X).
如果你问我某人的不朽,我会检查他的不朽。 (你是否仍然想知道这会导致无限循环?)
如果你想说一个人是不朽的,如果他不能被证明是凡人,那么你可以使用:
immortal(X) :- not( mortal(X) ).
答案 3 :(得分:0)
这个小程序怎么样:
loopy(Y) :- read(X), Z is X+Y, print(Z), nl, loopy(Y).
你的Prolog先生会推断,已经调用了loopy(Y)并且会失败。