MastRofDsastR
MastRofDsastR

Reputation: 161

Prolog Querying: Unifying a variable in a nested compund Term

I have a set of Prolog facts which I am attempting to query, but I am having trouble figuring out how to unify variables that are more deeply nested. An example of a fact in the database is as follows:

character(super,mario, type(human)).
character(donkey,kong, type(ape)).

videogame(year(1991), console(nintendo), title([super,mario,bros]), characters([character(super,mario), character(princess,peach)])).
videogame(year(1999), console(nintendo), title([super,smash,bros]), characters([character(super,mario), character(donkey,kong)])).

So for example, I want to query which characters appear in more than 1 video game. So I know that I want to create two instances of videogame and ensure that the same character appears (by name) in both games, and that those games are not the same game (by title).

Thus I would do something like:

?- videogame(_, _, title(Title1), characters(?????)), videogame(_, _, title(Title2), characters(?????)), not(Title1 == Title2).

However, my issue has been finding a way to create variables within the characters portion such that the "first" and "last" name of the characters unifies with a character that appears in more than one videogame.

I have tried things along the lines of the following (to fill in the question marks above in the full query) to try and unify the first and last name of the character, but they produce the error:

characters(character[First,Last])
characters([First, Last])


 ERROR: Syntax error: Operator expected

I have also tried the following, which just returns false.

?- videogame(_, _, title(Title1), _), videogame(_, _, title(Title2), _), member(actor(First,Last,_), cast), not(Title1 == Title2).

I would appreciate some help so that I can gain a better understanding of how query in Prolog even in the presence of more nested terms.

Upvotes: 1

Views: 148

Answers (1)

CapelliC
CapelliC

Reputation: 60004

with intersection/3 from library(lists) I would write

?- videogame(_,_,title(Title1),characters(Cs1)), videogame(_,_,title(Title2),characters(Cs2)), Title1 @< Title2, intersection(Cs1,Cs2,Common).

Upvotes: 1

Related Questions