Querying a data knowledge in prolog

我们两清 提交于 2020-01-24 07:53:05

问题


Let's say i have some data in this form:

plot('Jurrassic Park",'action')
plot('Jurrassic Park",'drama')
plot('Jurrassic Park",'adventure')
plot('pulp fiction",'retro')
plot('pulp fiction",'crime')
....

where in plot(X,Y) X is a movie and Y is this movies genre.

What i would like to do is query this database and get all the movies that have 3 equal genres. For example if there is another movie that is action,drama,adventure i would like it to be paired with Jurassic park.What i have done so far:

predic(X,Y,Z,Z2,Z3):-
   plot(X,Z), plot(Y,Z), X \= Y,
   plot(X,Z2), plot(Y,Z2), X \= Y, Z\=Z2,
   plot(X,Z3), plot(Y,Z3), X \= Y, Z\=Z3,Z2\=Z3

The problem is that this may return multiple instances of moves (X,Y)(i want it to return just one) because it returns all the possible combinations between Z,Z2,Z3.It will return (Jurassic Park,Jurassic World,action,adventure,drama) and it will also return (Jurassic Park,Jurassic World,action,drama,adventure).

So how could i make my query stop after finding the 1st combination of Z,Z2,Z3 which satisfies the predicates needs? I can't use "!" because i want this query to return all the possible pairs of movies with 3 common genres and not just 1.


回答1:


You can enforce order in the terms Zi, by adding constraints Zi @< Zi+1. Here we thus use the (@<)/2 predicate [swi-doc], that checks the standard order on terms:

predic(X, Y, Z1, Z2, Z3) :- 
    plot(X, Z1), plot(Y,Z1),
    X \= Y,
    plot(X, Z2), plot(Y,Z2),
    Z1 @< Z2,
    plot(X, Z3), plot(Y,Z3),
    Z2 @< Z3.

If you are only interested in distinct sets of two movies being similar, you can make use of the distinct/1 meta-predicate:

predic(X, Y) :-
    predic(X, Y, _, _, _).

similars(X, Y) :-
    distinct(predic(X, Y)).



回答2:


I would suggest to use the standard aggregation setof, basic list processing, and pattern matching:

predic(X, Y, A,B,C) :-
  setof(P, Q^plot(P, Q), Ps),
  append(_, [X|Ys], Ps),
  member(Y, Ys),
  setof(P, P^plot(X,P), [A,B,C|_]),
  setof(P, P^plot(Y,P), [A,B,C|_]).


来源:https://stackoverflow.com/questions/59514597/querying-a-data-knowledge-in-prolog

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!