4

2つ以上の結果が返される場合にrule1成功する実装方法は?rule2

rule1(X) :-
    rule2(X, _).

結果をカウントして、成功するタイミングの最小値を設定するにはどうすればよいですか?

4

2 に答える 2

5

結果をカウントし、それが true の場合に最小値を設定するにはどうすればよいですか?

結果が何を意味するのかは明確ではありません。そこで、いくつか推測してみます。結果は次のようになります。

解決策。たとえば、ゴールmember(X,[1,2,1])には 2 つのソリューションがあります。3つではありません。この場合、どちらかsetof/3または類似の述語を使用することを検討してください。いずれにせよ、setof/3抱えている問題に取り組む前に、まず理解する必要があります。

答え。ゴールmember(X,[1,2,1])には3つの答えがあります。目標member(X,[Y,Z])には 2 つの答えがありますが、無限に多くの解があります。

したがって、少なくとも一定数の回答があることを確認したい場合は、次のように定義します。

at_least(目標、N) :-
   \+ \+ call_nth(ゴール, N).

call_nth/2 別の SO-answerで定義されています。

他の SO 回答は正しくないことに注意してください。それらは終了しないか、予期しないインスタンス化を生成しません。

于 2012-11-15T09:30:39.477 に答える
2

library( aggregate ) を使用して解を数えることができます

:- use_module(library(aggregate)).

% it's useful to declare this for modularization
:- meta_predicate at_least(0, +).

at_least(Predicate, Minimum) :-
      aggregate_all(count, Predicate, N),
      N >= Minimum.

例:

?- at_least(member(_,[1,2,3]),3).
true.

?- at_least(member(_,[1,2,3]),4).
false.

edit here は、グローバル変数に SWI-Prolog 機能を使用する、より効率的な方法です。

at_least(P, N) :-
    nb_setval(at_least, 0),
    P,
    nb_getval(at_least, C),
    S is C + 1,
    ( S >= N, ! ; nb_setval(at_least, S), fail ).

この定義では、P はN 回だけ呼び出されます。(返されるものを表示するサービス述語 m/2 を紹介します)

m(X, L) :- member(X, L), writeln(x:X).

?- at_least(m(X,[1,2,3]),2).
x:1
x:2
X = 2.

@false コメントのアカウントを編集してみました

 ?- call_nth(m(X,[1,2,3]),2).
x:1
x:2
X = 2 ;
x:3
false.

ここからcall_nthで。

実用的な観点から、 nb_setval (vs nb_setarg ) は、グローバル変数とローカル変数の間の通常のトレードオフに苦しんでいると思います。つまり、いくつかのタスクでは、条件を受け入れるための限界ヒットが何であるかを知るのに便利な場合があります。これが必要ない場合は、nb_setarg の方がクリーンです。

結論: より良い方法は明らかに call_nth を使用することであり、二重否定の「トリック」を使用して過度の変数のインスタンス化を解決します。

于 2012-11-15T07:33:38.990 に答える