首页 > 解决方案 > PROLOG - 获取实体验证的所有规则的列表

问题描述

我正在将语言数据形式化为谓词和实体,并在序言中进行一些推理。想象一下,我开始:

breathe(X) :- snore(X).
sleep(X) :- snore(X).
rest(X) :- sleep(X).
live(X) :- breathe(X); eat(X); sleep(X).

snore(john).
sleep(lucy).

我的数据可以变得足够大,我想获得一个实体和谓词列表,以便对其进行迭代并检查一个实体验证了多少个谓词,输出可以是如下列表:

[john, [snore, breathe, sleep, rest, live]]
[lucy, [sleep, rest]]

或谓词

participant(john, [snore, breathe, sleep, rest, live]).
participant(lucy, [sleep, rest]).

感谢您的帮助,我目前不知道。

标签: prologpredicatelinguistics

解决方案


代表关于抽象世界的实时知识可能会变得混乱。根据您使用的 Prolog 系统,有很多不同的可能性和很多差异。

这是您在 SWI-Prolog 中运行的代码示例,但相同的想法应该(或多或少)在任何提供call/Nsetof /3 内置函数的 Prolog 上保持不变。

:- module(list_entities_that_verify_a_pred,
          [participant/2]).

:- redefine_system_predicate(sleep/1).
:- discontiguous breathe/1,sleep/1,rest/1,live/1,snore/1.

breathe(X) :- snore(X).
sleep(X) :- snore(X).
rest(X) :- sleep(X).
live(X) :- breathe(X); /* eat(X);*/ sleep(X).

snore(john).
sleep(lucy).

to_verify(breathe).
to_verify(sleep).
to_verify(rest).
to_verify(live).
to_verify(snore).

participant(Person,Verified) :-
    setof(Pred,(to_verify(Pred),call(Pred,Person)),Verified).

首先,请注意我已经对eat/1 的调用进行了注释,以避免缺少定义异常,因此我们可以尝试调用partecipant/2 谓词:

?- participant(P,L).
P = john,
L = [breathe, live, rest, sleep, snore] ;
P = lucy,
L = [live, rest, sleep].

从架构的角度来看,要注意的要点是引入 to_verify/1,以简化工作流程。


推荐阅读