私は Prolog の初心者で、5 未満の整数を見つける単純なジェネレーターを作成しようとしています。
gen(0).
gen(X):- X<5
gen(X) を使用してプログラムを実行すると、X = 0 のみが出力され、何かを入力するように求められます。Enter キーを押すと、「?-」が再び表示されます。
彼に 0 から 5 までの数字を生成させる方法は? SWI-Prolog を使用しています。ありがとう
使用したくない場合は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 番目の句は、現在の番号をインクリメントし、再帰的にそれ自体を呼び出して、バックトラック時に次の番号を取得します。
整数の列挙専用の組み込み述語は 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)
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/1
aを追加することです。もちろん、明らかな問題は、メタ述語に依存しているため、純粋なプロローグではないということです。retract_all(g(_))
generate/1
まあ、これらすべての制限があるので、それは確かに不可能に見えます
組み込み関数の使用はどうnumlist
ですか?
?- numlist(0,4,X).
X = [0, 1, 2, 3, 4].