Пролог Рекурсия через Набор - PullRequest
0 голосов
/ 12 марта 2020

Я пытаюсь поработать над этим правилом Пролога, которое вы передаете при вводе списка фильмов, и оно возвращает список звезд, которые участвуют в этом конкретном мове ie.

Предикат:

starsin(captain_america,chris_evan).
starsin(avengers,chris_evan).
starsin(ant_man,chris_evan).
starsin(captain_marvel,chris_evan).
starsin(iron_man,chris_evan).
starsin(avengers,tom_holland).
starsin(captain_marvel,tom_holland).
starsin(captain_america,tom_holland).
starsin(iron_man,robert).
starsin(avengers,robert).
starsin(captain_america,robert).

Я пытался использовать набор правил, но каким-то образом я не могу найти способ использовать его рекурсивно:

link([Head],Set) :-
   setof(Star1,starsin(Head,Star1),Set).

Ввод и вывод :

link([ironman],Set).
Set=[chris_evan,robert]

Почему-то я хочу передать более одного элемента в списке, но мне нужно использовать рекурсив.

Могу ли я как-нибудь это сделать?

Ответы [ 2 ]

1 голос
/ 12 марта 2020

У вас есть недетерминированный c предикат starsin(X, Y) если только mov ie X включает в себя кинозвезду Y.

Давайте обобщим это, чтобы сказать нам, какие звезды появляются в любом из список фильмов.

movies_starsin(Movies, Star) :-
    member(Movie, Movies),
    starsin(Movie, Star).

Наконец-то вы хотите что-то вроде этого:

movies_stars(Movies, Stars) :-
    setof(Star, movies_starsin(Movies, Star), Stars).

Надеюсь, это поможет.

[ОБНОВЛЕНИЕ]

У меня было неправильно понял проблему, которая состоит в том, чтобы найти множество звезд, которые появляются в всех фильмах в данном списке. Хорошо:

starsin_all([Movie | Movies], Star) :-
    % Star must appear in Movie.
    starsin(Movie, Star),
    % There can be no OtherMovie in which Star does not appear.
    \+ (
        member(OtherMovie, Movies),
        \+ starsin(OtherMovie, Star)
    ).

all_starsin_all(Movies, Stars) :-
    setof(Star, starsin_all(Movies, Star), Stars).

Вы могли бы эквивалентно написать starsin_all, например:

starsin_all([Movie | Movies], Star) :-
    starsin(Movie, Star),
    forall(member(OtherMovie, Movies), starsin(OtherMovie, Star)).

Приветствия.

0 голосов
/ 12 марта 2020

Возможно, вам нужно что-то вроде maplist/2, которое можно использовать для поиска решения, которое работает с всеми членами списка, что вам и нужно. И затем, поскольку вам нужны все звезды, может быть что-то вроде findall/3.

Я бы посоветовал изменить starsin, чтобы поставить актера на первое место по двум причинам: 1. Имеет больше смысла говорить «Крис Эван играет в Iron Man», чем наоборот. Например, сравнить с, member(X, S) означает «X является членом S». 2. С maplist.

все будет работать проще. Полное решение не даст вам, потому что это выглядит немного по-домашнему. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...