Чтобы получить два самых больших числа из трех (V1
, V2
и V3
), вы можете действовать следующим образом: Отсортируйте список [V1,V2,V3]
и возьмите два последних элемента списка [_,X,Y]
, возведите их в квадрат и просуммируйте.
:- use_module(library(lists)).
:- use_module(library(clpfd)).
squareTwoLargest(V1,V2,V3, R) :-
Zs = [_,X,Y],
chain(Zs, #=<),
permutation([V1,V2,V3],Zs),
R #= X*X + Y*Y.
Пример запроса:
?- squareTwoLargest(20,30,10, R).
R = 1300
Лучшая реализация
Приведенный выше код основан на «сортировке перестановками», что делает его неэффективным более чем одним способом.
Цель squareTwoLargest(X,Y,Z, R)
достигается несколько раз и дает избыточные ответы, если два или более из X
, Y
и Z
равны. Об этом свидетельствуют следующие два запроса:
?- squareTwoLargest(0,10,10, R).
R = 200 ;
R = 200 ;
false.
?- squareTwoLargest(10,10,10, R).
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
false.
Мы можем устранить избыточные ответы, используя сеть сортировки размера 3. Подробнее см. этот ответ на вопрос упорядочение списков с программированием логики ограничений< /а>.
list_sorted__SN3([A0,A1,A2], [D0,D1,C2]) :-
B1 #= min(A1,A2), B2 #= max(A1,A2),
C0 #= min(A0,B2), C2 #= max(A0,B2),
D0 #= min(C0,B1), D1 #= max(C0,B1).
squareTwoLargest__SN(V1,V2,V3, R) :-
list_sorted__SN3([V1,V2,V3],[_,X,Y]),
R #= X*X + Y*Y.
Рассмотрим следующие запросы:
?- squareTwoLargest__SN(20,30,10, R).
R = 1300. % works like it did before
?- squareTwoLargest__SN(20,20,10, R).
R = 800. % succeeds deterministically
?- squareTwoLargest__SN(20,20,20, R).
R = 800. % succeeds deterministically
Обратите внимание, что все избыточные ответы крайних случаев, показанных выше, были удалены.
person
repeat
schedule
14.04.2015
=
цели передis
- person false   schedule 13.04.2015is/2
требует, чтобы второй аргумент был полностью реализован. Кроме того, в Прологе есть предикаты, а не функции. предикат завершается успешно или неудачно (или не завершается :)) и не возвращает значение. Однако он может создавать экземпляры аргументов. Таким образом, ваше использованиеsquare
не сработает. Ваше использованиеmin(X, Y)
также будет проблематичным. - person lurker   schedule 13.04.2015R is L1 * L1 + L2 * L2
? - person Marcus Vinícius Monteiro   schedule 13.04.2015=
передis
(при условии, что я также написалR is L1 * L1 + L2 * L2
вместо использованияsquare
? - person Marcus Vinícius Monteiro   schedule 13.04.2015square(L1, S1), square(L2, S2), R is S1 + S2
- person lurker   schedule 13.04.2015L1^2
вместоsquare(L1)
- person false   schedule 13.04.2015