Простой эффективный способ - просто связать факт размера с каждым животным.
size(bat,1).
size(penguin,2).
size(crocodile,3).
Затем добавьте один предикат с двумя предложениями, чтобы выбрать большее из двух животных.
larger(A,B,A) :-
size(A,S1),
size(B,S2),
S1 > S2.
larger(A,B,B) :-
size(A,S1),
size(B,S2),
S2 >= S1.
Примеры:
?- larger(penguin,crocodile,X).
X = crocodile.
?- larger(penguin,bat,X).
X = penguin ;
false.
?- larger(bat,bat,X).
X = bat.
Обратите внимание, что для примеров, когда второе животное меньше, оно пробует первое предложение и успешно, но затем имеет точку выбора, поэтому пробует второе предложение и терпит неудачу.Это чистое решение.
Если вы хотите использовать разрез, чтобы избежать выбора точки, которая является нечистой, вы можете сделать следующее
larger_2(A,B,A) :-
size(A,S1),
size(B,S2),
S1 > S2,
!.
larger_2(A,B,B) :-
size(A,S1),
size(B,S2),
S2 >= S1,
!.
Примеры:
?- larger_2(penguin,crocodile,X).
X = crocodile.
?- larger_2(penguin,bat,X).
X = penguin.
?- larger_2(bat,bat,X).
X = bat.
Другой способкак отметил Дэниел Лайонс, использовать - > / 2
larger_3(A,B,Larger) :-
size(A,SA),
size(B,SB),
(
SA > SB
->
Larger = A
;
Larger = B
).
Этот вариант - не один оператор только ->/2
, а комбинация обоих -> / 2 и ; 2 .
Это также не оставляет точки выбора и является нечистым, поскольку оно также использует разрез (!
).Используя list / 1 , мы можем увидеть реализацию в Прологе.
?- listing('->'/2).
:- meta_predicate 0->0.
system:A->B :-
call(( A
-> B
)).
true.
?- listing(;/2).
:- meta_predicate 0;0.
system:A:B;A:C :- !,
call(A:(B;C)).
system:A:B;C:D :-
call(A:(B;C:D)).
true.
Обратите внимание на сокращение !
.
Как работают два оператора вместе, отмечено вSWI-Prolog документация .
The combination ;/2 and ->/2 acts as if defined as:
If -> Then; _Else :- If, !, Then.
If -> _Then; Else :- !, Else.
If -> Then :- If, !, Then.
Еще один момент, который следует отметить при использовании ->/2
с ;/2
, заключается в том, что синтаксическая компоновка среди многих программистов Prolog должна использовать ()
с комбинацией и смещением операторов ->/2
и ;2
, так что ;
выделяется.
(
% condition
->
% true
;
% false
)
Когда ;
используется в качестве оператора ИЛИ, а не смещения, ;
часто упускается при быстром сканировании исходного кода, поскольку вместо этого он выглядит как запятая ,
;
.
Также обратите внимание на отсутствие .
или ,
после
SA > SB
и
Larger = A
и
Larger = B
но в конце нужен оператор,
).