2

私は Prolog の初心者で、5 未満の整数を見つける単純なジェネレーターを作成しようとしています。

gen(0).
gen(X):- X<5

gen(X) を使用してプログラムを実行すると、X = 0 のみが出力され、何かを入力するように求められます。Enter キーを押すと、「?-」が再び表示されます。

彼に 0 から 5 までの数字を生成させる方法は? SWI-Prolog を使用しています。ありがとう

4

4 に答える 4

4

使用したくない場合はbetween/3、補助手順を使用してジェネレーターを簡単に作成できますgen/3

gen(Num):-
  gen(0, 5, Num).

gen(Cur, Top, Cur):- Cur < Top.
gen(Cur, Top, Next):-
  Cur < Top,
  succ(Cur, Cur1),  % or Cur1 is Cur+1
  gen(Cur1, Top, Next).

補助プロシージャgen/3は、現在生成されている番号と最上位の番号を追跡し、3 番目の引数を現在生成されている番号にバインドします。

の最初の節はgen/3成功し、入力数値が上より下の場合、出力数値を入力数値にバインドします。

2 番目の句は、現在の番号をインクリメントし、再帰的にそれ自体を呼び出して、バックトラック時に次の番号を取得します。

于 2012-08-24T13:37:30.467 に答える
3

整数の列挙専用の組み込み述語は between(Low,High,Num) です。

それを使用して、あなたは書くでしょうgen(X) :- between(0,4,X).

私はこのように間に再実装しました

gen(X) :- between_(0, 4, X).

/* between_(I,J,K) is true if K is an integer between I and J inclusive.    */
between_(I,J,I) :- I =< J.
between_(I,J,K) :- I < J, I1 is I+1, between_(I1,J,K).

質問の興味深い部分は、引数だけの素朴な実装が永遠にループする理由を理解することです...

gen(0).
gen(X) :- gen(Y), X is Y + 1, X < 5.

?- gen(X).
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
^CAction (h for help) ? goals
[374,153] 3<5
[374,152] gen(3)
[374,151] gen(_G1013)
[374,150] gen(_G1013)
[374,149] gen(_G1013)
于 2012-08-24T13:38:19.297 に答える
2

gen / 1は0から5までの整数を生成する必要があるため(技術的には、5未満の整数の場合は、負の値も生成する必要があります)、次のようにすることができます。

gen(0).
gen(1).
gen(2).
gen(3).
gen(4).
gen(5).

これは技術的にchackの制限を満たしますxD

gen/2最初の引数が実行できる最大数を定義する述語の場合:

gen(N,R):-
    N>0,
    R is N-1.
gen(N,R):-
    N>1,
    NN is N-1,
    gen(NN,R).

ただし、これには最初の引数を使用できるという利点があります。最初の解決策を回避するためのルールの言い換えは、ルールを変更せずに5のすべての出現箇所を他の番号に置き換えることができ、プログラムは引き続き機能するはずであるということです。また、リスト(要素が正確に1つでない限り)、タプル、または基本的に引数として2つの変数を持つ任意の用語、および任意の種類のエンコーディング(2^X*3*Yなど)を使用できないことも追加する必要があります。最初のプログラムに触発されました:

gen(X):-
    clause(g(_),_) ->
    g(X) ; (generate(5),!, g(X)).

generate(-1):-
    compile_predicates([g/1]).
generate(N):-
    assert(g(N)),
    NN is N-1,
    generate(NN).

compile_predicates/1速度を向上させるためだけのものです。最大数を変更した場合は、VMを再起動する必要があることに注意してください。もう1つのオプションは、コンパイルを避けて、を呼び出す前にg/1aを追加することです。もちろん、明らかな問題は、メタ述語に依存しているため、純粋なプロローグではないということです。retract_all(g(_))generate/1

まあ、これらすべての制限があるので、それは確かに不可能に見えます

于 2012-08-25T23:25:48.697 に答える
-1

組み込み関数の使用はどうnumlistですか?

?- numlist(0,4,X).
X = [0, 1, 2, 3, 4].
于 2012-08-24T12:43:40.127 に答える