The answer of @Steven covers everything there is to answer about this question, but reading the comments it looks like OP is still confused about the different solutions found by Prolog:
"Yes, but I want to relate to more than one movie at the sime time."
"So, the only way to make a database with watched
is to write lots of lines? So, if someone watched 6 movies, it would be: watched(1, 1). watched(1, 2). watched(1, 3). watched(1, 4). watched(1, 5).
?"
It seems as if what you are trying to accomplish is to obtain all the watched movies for a given person, rather than getting separate answers. To do so, you can use extra-logical all-solution predicates. Let's look at its use for your code.
Using @Steven's predicate (trivially edited):
person_watched_movie(P,M) :-
person(PId,P),
watched(PId,MovieIds),
member(MId,MovieIds),
movie(MId,M).
We now simply wrap around the findall/3
predicate like so:
person_watched_movies(Person,Movies) :-
findall(Movie,person_watched_movie(Person,Movie),Movies).
Now you can obtain the list of movies someone/everyone/.. watched at once:
?- person_watched_movies('ana',M).
M = ['Thor 1', 'Thor 2', 'Captain America'].
Let's think about a general query for a second, what should happen when we ask Prolog to find us any movies watched by any person? Well, it should give us any movies available in the facts that were watched at least once - note that duplicates may appear here since multiple people could have watched the same movie. Let's test it!
?- person_watched_movies(X,Y).
Y = ['Thor 1', 'Thor 2', 'Captain America', 'Thor 1', 'Thor 2', 'Captain America 2'].
Great! Moving on, we can also use this predicate to quickly obtain the list of watched movies of some specific people:
Using the disjunction operator:
?- (X='ana' ; X='john'), person_watched_movies(X,Y).
X = ana,
Y = ['Thor 1', 'Thor 2', 'Captain America'] ;
X = john,
Y = ['Thor 1', 'Thor 2', 'Captain America 2'].
Or equivalently, using member/2
and a list:
?- member(X,['ana','john']), person_watched_movies(X,Y).
X = ana,
Y = ['Thor 1', 'Thor 2', 'Captain America'] ;
X = john,
Y = ['Thor 1', 'Thor 2', 'Captain America 2'].
Finally, if you would like to simultaneously retrieve the person who watched the movie, you could make use of the -/2
notation as shown below:
person_watched_movies(Person,Movies) :-
findall(Person-Movie,person_watched_movie(Person,Movie),Movies).
When given the same general query we used before, this will instead output:
?- person_watched_movies(X,Y).
Y = [ana-'Thor 1', ana-'Thor 2', ana-'Captain America', john-'Thor 1', john-'Thor 2', john-'Captain America 2'].
Hope this helps!
watched_movie('ana', 'Thor 2')
? I'm sorry, but I honestly can't tell from your attempts what your actual goal is. – Steven