Why do circular references and recursion make my program fail?

房东的猫 提交于 2019-12-01 09:26:28

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 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.

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).

Using tabling with XSB:

:- table foo/1.

foo(X) :- foo(X).

bar(X) :- bar(X).

and then:

| ?- [tabled].
[tabled loaded]

yes
| ?- foo(1).

no
| ?- bar(1).    % does not finish

Your definitions - and how you interpret them:

man(socrates).

Socrates is a man.

mortal(X) :- man(X).

Every man is a mortal.

immortal(X) :- immortal(X).

Every immortal is immortal.


Your definitions - and how Prolog interprets them:

man(socrates).

If you ask about the manhood of Socrates, I know it's true.

mortal(X) :- man(X).

If you ask me about the mortality of someone, I'll check his manhood (and if that's true, so is the mortality).

immortal(X) :- immortal(X).

If you ask me about the immortality of someone, I'll check his immortality. (Do you still wonder how that leads to an infinite loop?)


If you want to state that someone is immortal if he can't be proven mortal, then you can use:

immortal(X) :- not( mortal(X) ).

How about this little program:

 loopy(Y) :- read(X), Z is X+Y, print(Z), nl, loopy(Y).

Your Mr. Prolog would infer, that loopy(Y) has already been called and would fail.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!