Как Вы делаете вложенный оператор if-else в Prolog?
Если у меня есть эта функция:
min(List1, List2, Output) :-
length(List1, N),
length(List2, M),
( N < M ->
Output = 'true'
; Output = 'false'
).
но что, если бы я хотел также проверить, если N == M? Может быть, так:
min(List1, List2, Output) :-
length(List1, N),
length(List2, M),
( N < M ->
Output = 'true'
; ( N = M ->
Output = 'equal'
; Output = 'other'
)
).
не работает.
2 ответов
ваше гнездование импликации (->
) выглядит правильно здесь. Обратите внимание, что в вашем определении N
и M
будут целыми числами (при условии, что звонки length/2
оба успеха), поэтому можно сравнить с ==
вместо унификации (=
). Фактически, вы даже можете использовать арифметические равенства в SWI-PROLOG, а именно =:=
:
min(List1, List2, Output) :-
length(List1, N),
length(List2, M),
(N < M ->
Output = 'true'
; (N =:= M ->
Output = 'equal'
; Output = 'other'
)
).
тестирование:
1 ?- min([a],[b],O).
O = equal.
2 ?- min([a,c],[b],O).
O = other.
3 ?- min([a,c],[b,d],O).
O = equal.
4 ?- min([a,c],[b,d,e],O).
O = true.
во вложенном if-then-else обычно опускаются избыточные круглые скобки, что дает:
min(List1, List2, Output) :-
length(List1, N),
length(List2, M),
( N < M -> Output = true
; N =:= M -> Output = equal
; Output = other
).
в Prolog, это хорошая практика, чтобы использовать шаблоны когда это возможно, потому что это дает более общие, более декларативные и более читаемые программы, чем использование if-then-else. Для этого конкретного случая условий проверьте compare/3
библиотека сказуемого. compare/3
позволяет вам reify отношение двух длин в атом, и вы можете использовать этот атом для описания три условия с сопоставлением шаблонов:
lists_output(List1, List2, Output) :-
length(List1, L1),
length(List2, L2),
compare(Order, L1, L2),
order_output(Order, Output).
order_output(<, true).
order_output(=, equal).
order_output(>, other).
примеры запросов и результаты:
?- lists_output([_,_], [_,_,_], Output).
Output = true.
?- lists_output([_,_,_], [_,_,_], Output).
Output = equal.
?- lists_output([_,_,_,_], [_,_,_], Output).
Output = other.