2016-04-16 3 views
0

У меня есть следующее правило:Пролог: найти максимальное значение между некоторыми результатами запроса

compute_stats(A, B, C) 

, который возвращается, как вы можете видеть, три значения каждой итерации:

  • А представляет собой целое число, ;
  • B - другое целое;
  • C - это список.

Я хотел бы спросить вас, как найти результат с наивысшим значением A (целое число).

Пример:

Если я позвоню

compute_stats(A, B, C). 

я получаю в результате что-то вроде

A = 1000, 
B = 10, 
C = ['example1', 'example2']; 

A = 1200, 
B = 3, 
C = ['example3', 'example4']; 

A = 800, 
B = 7, 
C = ['example5', 'example6']; 

Теперь мне нужно еще одно правило, которое дает мне только

A = 1200, 
B = 3, 
C = ['example3', 'example4']; 

потому что имеет максимальную А.

Я пробовал много разных вещей, но они, кажется, не работает :(

Спасибо советы!

+0

Первое предложение: переименовать свой предикат имя, которое описывает это время отношения. 'get' здесь не подходит. Кто или что такое 'get'? Это императив, команда, ориентированная на императивные/командные языки программирования. – false

+0

Вы правы. Я новичок и все еще должен вникать в такое мышление! – Nano

+0

Так что дайте ему лучшее имя. (Как отредактировать в конце) – false

ответ

0

Существует несколько способов сделать это. Один из способов - воспользоваться тем, что setof/3 сортирует результаты поиска.

max_stats(MaxA, MaxB, MaxC) :- 
    setof(A-B-C, get_stats(A,B,C), R), % All results ordered by A (ascending) 
    reverse(R, [MaxA-MaxB-MaxC|_]).  % Maximum results 

Здесь setof/3 собирает, в порядке возрастания, список «кортежей» A-B-C, которые все результаты get_stats(A,B,C). Поскольку вы хотите максимальное значение, мы отменяем порядок этого результата (с reverse/2) и принимаем первый элемент этого списка как максимум. Заказ на условия вида A-B-C будет заказан первым в соответствии с порядком сортировки A, поэтому результаты будут предоставлены для максимальных A.


В комментариях от @false у вас может быть несколько максимальных результатов (которые имеют такое же значение, как максимум). Один из способов справиться с этим у max_stats есть аргумент-список, который представляет собой список максимальных результатов:

max_stats(MaxResults) :- 
    setof(A-B-C, get_stats(A,B,C), R),  % All results ordered by A (ascending) 
    reverse(R, DescendingList), 
    all_max(DescendingList, MaxResults). % Maximum results 

% all_max/2 assumes the first argument is in descending order 
% and the second argument is the list of just the maximum values 
% of the first list 

all_max([X], [X]). 
all_max([X, Y|_], [X]) :- X @> Y. 
all_maxx([X, Y|T], [X|S]) :- 
    equal_elements(X, Y), 
    all_max([X|T], S). 

equal_elements(X-_-_, X-_-_). 
+0

Спасибо, он отлично работает, и код чист и прост! – Nano

+0

OP запросил наивысший уровень A. Не для высших A-B-C. – false

+0

@false - ОП запросил у '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'как можно найти результат с наивысшим значением A *. Разве это не означает, что 'setof' вроде' A-B-C' достигает того, что я описываю (слегка) в своем ответе? – lurker

Смежные вопросы