あなたは述語を「組み合わせる」ことはできませんが、それらの両方が成功した場合にのみ成功する2つ(またはそれ以上)の述語間の論理積を持つことができます:上記の
reverseEven(List, Reversed) :-
evenlength(List), % This must succeed
reverse(List, Reversed). % and this one in order this case to succeed
reverseEven(_, []). % this will succeed otherwise
最もではありません効率的な実装(たとえば、偶数長のチェックの後にカット!
演算子を使用することができます)。しかしそれはアイデアを示しています。
更新 ところで、あなたのreverse
述語は次のようになります。
reverse([],[]). % Empty list is a reverse of empty list
reverse([H|T], R):-
reverse(T,ReverseT), append(ReverseT, [H], R).
アップデート2おかげ@Lurker。上記のコードは2つの答えを生成します。最初のものは正しいでしょう。 Prologにさらに検索を依頼すれば、2番目の節が常に真であるため、空のリストである別の答えが見つかります。これを解決するために、リストの長さが否定演算子を使用していないことを明示的にチェックするか、または私がよりエレガントであると分かっているのは、空のリストに別の節を追加するだけです。余分な要素を持つリストで既存evenlength
:
reverseEven([], []).
reverseEven(List, Reversed) :-
evenlength(List), % This must succeed
reverse(List, Reversed). % and this one in order this case to succeed
reverseEven([H|T], []) :-
evenlength([H|[H|T]]).
残念ながら、このコードは 'reverseEven([A、B]、R)'の二つの溶液を生成します。 1つは正しく( 'R = [b、a]')、もう1つは正しくない、 'R = []'です。 – lurker
@lurkerあなたは正しいです、ありがとうございます。本当に質問の焦点ではありませんが、答えを更新します。 –
私はそれが焦点ではないことに同意しますが、解決策を提供する際には解決策が正しいこと、またはOPが完全な解決策を見つけるための練習問題として残しておくことが明白です。 :) – lurker