本文介绍了不要在 Prolog 中重复解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个包含以下内容的数据库:

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 中重复解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 15:53