问题描述
假设您有一个包含以下内容的数据库:
Suppose you have a database with the following content:
son(a, d).
son(b, d).
son(a, c).
son(b, c).
所以a和b是d和c的儿子.现在你想知道,给定一个更大的数据库,谁是谁的兄弟.一个解决方案是:
So a and b are sons of d and c. Now you want to know, given a bigger database, who is brother to who. A solution would be:
brother(X, Y) :-
son(X, P),
son(Y, P),
X \= Y.
问题在于,如果你问兄弟(X,Y)".并开始按;"你会得到像这样的冗余结果:
The problem with this is that if you ask "brother(X, Y)." and start pressing ";" you'll get redundant results like:
- X = a, Y = b;
- X = b, Y = a;
- X = a, Y = b;
- X = b, Y = a;
我可以理解为什么会得到这些结果,但我正在寻找解决此问题的方法.我能做什么?
I can understand why I get these results but I am looking for a way to fix this. What can I do?
推荐答案
我得到了答案.
% Include the dictionary
:- [p1]. % The dictionary with sons
:- dynamic(found/2).
brother(X, Y) :-
% Get two persons from the database to test
son(X, P),
son(Y, P),
% Test if the two persons are different and were not already used
testBrother(X, Y).
% If it got here it's because there is no one else to test above, so just fail and retract all
brother(_, _) :-
retract(found(_, _)),
fail.
testBrother(X, Y) :-
X \= Y,
\+found(X, Y),
\+found(Y, X),
% If they were not used succed and assert what was found
assert(found(X, Y)).
它最终总是返回失败,但它通过以下方式成功.
It always returns fails in the end but it succeeds with the following.
- 兄弟(X,Y).% 兄弟不重复
- brother('Urraca', X).% 乌拉卡的每一个兄弟不重复
- brother('Urraca', 'Sancho I').% 是的,因为乌拉卡和桑乔我有同一个父亲和母亲.事实上,即使他们只有同一个母亲或同一个父亲,它也会返回true.有点脱离上下文但仍然有效,如果他们有三个或更多共同的父母,它仍然有效
它失败了:
- 兄弟(X,X).% 错误,因为是同一个人
- 兄弟('不',X).% False 因为 not 甚至不在数据库中
- brother('Nope', 'Sancho I').% 错误,同样的原因
这样我可以,例如,问:兄弟(X,Y),然后开始按;"看到每一个兄弟姐妹,没有任何重复.
So like this I can, for example, ask: brother(X, Y), and start pressing ";" to see every brother and sister without any repetition.
我也可以做兄弟(a,b)和兄弟(b,a),假设a和b是数据库中的人.这很重要,因为某些解决方案会使用 @<测试东西,就像兄弟(b,a)会失败.
I can also do brother(a, b) and brother(b, a), assuming a and b are persons in the database. This is important because some solutions would use @< to test things and like so brother(b, a) would fail.
就是这样.
这篇关于不要在 Prolog 中重复解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!