如何在Prolog中表达同义词?

时间:2018-08-19 09:38:31

标签: prolog

比方说,我有一个规则库,它说如果我们的蛋糕不好,那么我们就不应该吃它:

do_not_eat(cake) :- is_bad(cake).

让我们进一步说我们的布朗尼蛋糕变质了:

is_bad(brownie).

我如何在Prolog中表达布朗尼应被视为蛋糕的代名词,因此不应食用蛋糕?我知道我可以用变量改写第一个规则

do_not_eat(Cake) :- is_bad(Cake)

,一切都会很好地统一。但是,我想知道是否可以说出“使browniecake同义”或“适用于cake的任何内容都应适用于{{1 }}”?我尝试添加规则brownie,但似乎并没有解决问题。我一直在使用GnuProlog。

1 个答案:

答案 0 :(得分:1)

一种解决方案是将您的规则更改为:

do_not_eat(Cake) :- cake(Cake), is_bad(Cake).

并定义:

cake(brownie).
cake(cupcakes).
...

您也可以概括该解决方案。例如:

do_not_eat(Food) :- food(Food), is_bad(Food).

,然后定义:

food(Food) :- cake(Food).

一个更强大但更重的解决方案是定义代表您的概念的对象层次。然后,您可以简单地拥有从蛋糕继承的布朗尼和从食物继承的蛋糕。使用支持GNU Prolog的Logtalk:

------- cakes.lgt -------
:- object(food).

    :- public(do_not_eat/0).
    do_not_eat :-
        % ask the receiver of the do_not_eat/0 message if it's bad
        ::is_bad.

    :- public(is_bad/0).

:- end_object.


:- object(cake,
    extends(food)).

    % cakes are bad for your health
    is_bad.

:- end_object.


% anything that applies to cake also applies to brownie
:- object(brownie,
    extends(cake)).

:- end_object.
-------------------------

然后,您可以:

$ gplgt
...
| ?- {cakes}.
...
% (0 warnings)

(5 ms) yes
| ?- cake::do_not_eat.

yes
| ?- brownie::do_not_eat.

yes