1

我只是想知道我将如何制作一个事实,例如

family(original, [dad/1, mom/2, child/5, granny/10]).

其中original将是家庭的名称,列表由标题和速度组成。

如何将数字与标题(例如dad/1)分开,所以我可以这样做:

time_needed(dad,1).
time_needed(mom,2).
time_needed(child,5).
time_needed(granny,10).
4

2 回答 2

2

你在你的例子中写的很好。您可以与任何声明为中缀二元运算符的分隔符配对。这包括/, +, ,,-等等......然后由于统一,您可以通过这种方式进行模式匹配:

test :-
    family(X, [Title/Speed|_]),
    time_needed(Title, Speed).

在这里,我只匹配第一个元素的模式,但你可以看到这个想法。

不过,请注意,通常-使用它来代替/分隔对。特别是,如果您使用 SWI,则该pairs库使用Key-Value语法。

于 2012-04-12T06:49:41.893 回答
1

您需要断言列表的元素。请注意,这样您会丢失original密钥。

:- dynamic time_needed/2.
assert_family(Key) :-
  family(Key, List),
  assert_list(List).

assert_list([]).
assert_list([N/V|Es]) :-
  assertz(time_needed(N, V)),
  assert_list(Es).

你打电话给assert_family(original).

如果您的 Prolog 有 forall/2(或 maplist/2 + library(lambda)),则代码可能更紧凑:

:- dynamic time_needed/2.
assert_family(Key) :-
  family(Key, List),
  forall(member(N/V, List),
         assertz(time_needed(N, V))).

即递归循环现在它在forall/2 中'内联'。但是那个库谓词隐藏在句法简单的后面一些奇怪的行为......使用更简单的递归循环。

于 2012-04-12T08:22:43.310 回答