Reputation: 167
I was just wondering how I would make a fact such as
family(original, [dad/1, mom/2, child/5, granny/10]).
where original
would be the name of the family, and the list is composed of titles and speeds.
how do I separate the number from the title (eg. dad/1
), so I can do something like this:
time_needed(dad,1).
time_needed(mom,2).
time_needed(child,5).
time_needed(granny,10).
Upvotes: 1
Views: 291
Reputation: 7493
What you wrote in your example is fine. You can make pairs with any delimiter that is declared as infix binary operator. That includes /
, +
, ,
, -
etc... You can then pattern match pairs this way thanks to unification:
test :-
family(X, [Title/Speed|_]),
time_needed(Title, Speed).
Here I only pattern matched the first element but you can see the idea.
Though, note that usually -
is used instead of /
to delimit pairs. In particular, if you use SWI, the pairs
library uses a Key-Value
syntax.
Upvotes: 2
Reputation: 60014
You need to assert elements of the list. Note that this way you lose the original
key.
:- 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).
and you call assert_family(original).
If your Prolog has forall/2 (or maplist/2 + library(lambda)) the code could be more compact:
:- dynamic time_needed/2.
assert_family(Key) :-
family(Key, List),
forall(member(N/V, List),
assertz(time_needed(N, V))).
i.e. the recursive loop now it's 'inlined' in forall/2. But that library predicate hides behind syntactic simplicity some weird behaviour... Go with the simpler recursive loop.
Upvotes: 1