Создайте список пары ключ-значение - PullRequest
1 голос
/ 01 июня 2019

У меня есть эти факты:

name(john),
name(mary),
name(jack),

Когда я «повторяю» все факты, я нахожу для каждого имени что-то вроде рейтинга (число). Я хочу, чтобы этот рейтинг был в паре с именем типа 2-john или john-2, сохранял их в списке и сортировал список по номеру. Как я могу сделать это в ProLog?

name(PersonsName), findRating(PersonsName, Rating), fail.

1 Ответ

2 голосов
/ 01 июня 2019

@ false дал правильный ответ в комментарии:

setof(V-K, ( name(K), rating(K, V) ), VKs)

Личная сторонняя шутка для @false, которая была больше :-.:)

Я просто расширю это здесь для тех, кому нужны недостающие части.

Сначала факты должны быть фактами, то есть

name(john), не являетсяфакт, потому что это заканчивается ,.Факт должен заканчиваться точкой (.).

Следующие факты необходимы, чтобы связать рейтинг с человеком.

rating(john,2).
rating(mary,3).
rating(jack,4).

Теперь для setof / 3

Подпись setof / 3: setof(+Template, +Goal, -Set)

Goal - это запрос, который вернет необходимые данные, в данном случае цель - name(K), rating(K,V), но, поскольку этоболее чем одно утверждение обернуто в () становится ( name(K), rating(K, V) )

Пример выполнения:

?- name(Name),rating(Name,Rating).
Name = john,
Rating = 2 ;
Name = mary,
Rating = 3 ;
Name = jack,
Rating = 4.

Хотя это дает нам необходимые данные, оно не в формате, который полезен ивозвращает результаты по одному.

Template - формат данных в результате, в данном случае V-K, где V для Value - рейтинг, а K для Key это ключ.Результат будет выглядеть так: 2-john.

Вот пример того, что мы продемонстрировали с помощью запроса и примера:

rating(V-K) :-
    name(K),
    rating(K,V).

?- rating(Ratings).
Ratings = 2-john ;
Ratings = 3-mary ;
Ratings = 4-jack.

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

Set - это то, что собрано в результат.

Поскольку вы запросили отсортированный результат, вместо bagof/3 используется setof/3.Как отмечено в setof/3: sorts the result using sort/2 to get a sorted list of alternatives without duplicates.

Чтобы упростить выполнение запроса вместо того, чтобы каждый раз набирать весь набор / 3, просто поместите его в предикат.

ratings(VKs) :-
    setof(V-K,(name(K),rating(K,V)),VKs).

Полный код.

name(john).
name(mary).
name(jack).

rating(john,2).
rating(mary,3).
rating(jack,4).

ratings(VKs) :-
    setof(V-K,(name(K),rating(K,V)),VKs).

Пример выполнения:

?- ratings(VKs).
VKs = [2-john, 3-mary, 4-jack].

Примечание. Это также можно сделать с помощью библиотеки (assoc):Списки ассоциаций , но для этой проблемы использование setof/3 гораздо более кратко.

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