Prolog - 如何在一系列事实中使用事实?

时间:2013-03-28 21:57:59

标签: arrays prolog label

初学者在这里进行序言;只是想问一个问题,以摆脱我对任务问题的一些困惑。

假设我有一个事实清单(在这种情况下,他们吃的人和食物清单和物品数量),

label(test,
  [eats(george,apple,3),
   eats(bob,orange,1),
   eats(joe,steak,1)]).

如何使用此数组中的事实?例如,我将如何使其工作?

eaten(Person,Food):-
  eats(Person,Food,_).

2 个答案:

答案 0 :(得分:1)

我认为你的问题没有意义,因为缺乏背景。

可能用于将其推送到DB中的事实列表:

?- maplist(assert, [eats(george,apple,3), eats(bob,orange,1), eats(joe,steak,1)]).
true.

?- eats(Person,Food,_).
Person = george,
Food = apple ;
Person = bob,
Food = orange ;
Person = joe,
Food = steak.

但同样,这完全取决于你剩下的规则......

编辑通常,“信息流”是相反的:我们从数据库事实开始,将相关数据收集到列表中并处理列表。 Daniel解释了如何访问列表中的元素。请注意,在列表中的事实声明之后,您的规则将可以访问事实。根据您列出的规则,在:

之后
?- retractall(eats(_,_,_)),
   maplist(assert, [eats(george,apple,3), eats(bob,orange,1), eats(joe,steak,1)]).

?- eaten(bob,X).
X = orange.

HTH

答案 1 :(得分:1)

我想我明白了你在问什么。答案是像这样使用member/2

eaten(Person, Food) :- 
  label(test, Eating),
  member(eats(Person, Food, _), Eating).

这是你想要的结果吗?

?- eaten(P, F).
P = george,
F = apple ;
P = bob,
F = orange ;
P = joe,
F = steak.

根据经验,传递列表可能更“标准”,而不是将其存储在像这样的大块中。我可能会说这是eats/3 结构而不是事实的列表,但这种用法模糊了这种区别,因为数据库中的内容是一个名为label的arity 2事实,而不是一组称为eats的arity 3事实。但它们实际上是在数据库中,以迂回的方式。有趣。

这种使用member来浏览列表的方法也常用于为过程提供选项。例如,open/4使用它。