2016-05-20 3 views
0

私は2つの与えられた別の述語の整数のリストを引数として分割する述語を実装しようとしています。次のような定義が与えられます。述語によるプロローグ分割リスト - 述語の結果をチェックする方法?

split(P, L, L1, L2), 

:私はこのコードを変更しようとしています

P - predicate to split upon 
L - list to split 
L1 - result list of integers that return true on predicate check 
L2 - result list of integers that return false on predicate check 

、問題の整数を大きく/小さくまたはそれに等しいかどうかをハードコーディングされたチェックでリストを分割していますX(これは動作します):テスト目的のために

split(X, [], [], []). 
split(X, [H|T], [H|L1], L2) :- H=<X, split(X, T, L1, L2). 
split(X, [H|T], L1, [H|L2]) :- H>X, split(X, T, L1, L2). 

が、私は次のようにも番号があるかどうかを確認するためにRosettaCodeから述語をコピー:

even(N) :- 
(between(0, inf, N); integer(N)), 
0 is N mod 2. 

そしてここでは、上記のコードの私の修正ですが、それを返し、「構文エラー:演算子が期待される」最後の2行に:

split2(P, [], [], []). 
split2(P, [H|T], [H|L1], L2) :- P(H), split2(P, T, L1, L2). 
split2(P, [H|T], L1, [H|L2]) :- \+ P(H), split2(P, T, L1, L2). 

私は私のエラーは、述語がtrueを返すかどうかをチェックしていると思いますまたは偽であるが、適切な方法を見つけることができない。

EDIT:このため、私の呼び出しを追加するのを忘れ:

?- split2(even,[2,7,4,8,-1,5],L1,L2) 

答えて

1

あなたはこのような述語を呼び出すことはできません、あなたはcallを使用する必要があります。

?- A = between(0,3,1), A. % OK, because A can be evaluated as it is 
A = between(0, 3, 1). 

?- A = between, A(0,3,1). % won't work 
ERROR: Syntax error: Operator expected 
ERROR: A = between, 
ERROR: ** here ** 
ERROR: A(0,3,1) . 
?- A = between, call(A, 0, 3, 1). % OK, using call 
A = between. 

?- A = between(0, 3), call(A, 1). % Partial application 
A = between(0, 3). 

があることに注意してくださいあなたが行っていることを正確に行うライブラリ述語は、library(apply)、espを見てください。 include/3at the implementationもやや異なっているので、選択肢を残すことはありません。

PS:入力リストが正面になるように引数を並べ替えることは、これを確定的にするための第一歩です。また、2つの節(call(P,H)\+ call(P,H))の原因となる選択ポイントを取り除く必要があります。これは、SWI-Prologライブラリのように->で行うことができます。

多分あなたは選択肢のポイントに悩まされていないか、より一般的な述語を作りたいと思うかもしれません。私はそこにPrologタグのStackoverflow上の解決策があると確信しています。

+0

「あなたの後ろにあるのとまったく同じライブラリ述語があります」 - 私はそうだと思いますが、自分自身でPrologを学びたいと思います。あなたがあなたの答えをもっと詳しく説明できるなら、私はとても感謝しています。あなたが私の質問から分かるように、私はPrologを初めて使っていて、これを修正する方法は本当に分かりません。どんな助けでも大歓迎です(私はこれをGoogleにしようとしますが、検索する)。私の質問への修正には多くの変更が必要ですか? – Asunez

+0

@Asunez私の答えをもう一度読んでください。簡単な例を使用してエラーを再現し、修正方法を示します。 –

+0

@Asunez私が提供したリンク、特に 'include/3'の実装を示すリンクを気にしたなら、' call'を使って述語を評価する方法の例を見ることができます。他の人々のコードを読むことは、プログラミング方法を学ぶ最も基本的な方法の1つです。 –

関連する問題