6

SWI-Prolog インタープリターが自動的にセミコロンを実行するようにするにはどうすればよいですか? バックトラッキングのために多くの結果 (約 300) があり、それらすべてにセミコロンをプッシュしたくありません。

すべてのソリューションのリストは必要ありません。セミコロンやスペースを押したくないだけなので、バックトラックされたソリューションをバックグラウンドで出力するプログラムをそのままにしておくことができます。

4

4 に答える 4

3

@repeatこれがあなたの基準に合うかどうかわかりませんが、メタインタープリターを開発できませんか? すべての最上位クエリが mi を通過するように mi をロードする方法があるかどうかわかりません。

次のようなものです:

mi1(true).
mi1((A,B)) :-
 mi1(A),
 mi1(B).
mi1(Goal) :-
 Goal \= true,
 Goal \= (_,_),
 Goal =..List,
 maplist(newvar,List,NewList),
 Goal2 =..NewList,
 clause(Goal2, Body),
 List=[_,T],!,
 findnsols(5,I,(Goal =..[_,I],Goal),T),
 mi1(Body).

newvar(V,V2):-
 var(V).
newvar(V,V):-
 nonvar(V).

%test predicates.
natnum1(0).
natnum1(s(X)) :-
 natnum1(X).

 w(w1).
 w(w2).
 w(w3).
 w(w4).
 w(w5).
 w(w6).
 w(w7).
 w(w8).

クエリ:

?- mi1(w(X)).
X = [w1, w2, w3, w4, w5] ;
X = [w6, w7, w8] ;
false.

?- mi1(natnum1(X)).
X = [0, s(0), s(s(0)), s(s(s(0))), s(s(s(s(0))))] ;
X = [s(s(s(s(s(0))))), s(s(s(s(s(s(0)))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] ;
X = [s(s(s(s(s(s(s(s(s(...))))))))), s(s(s(s(s(s(s(s(...)))))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] ;
X = [s(s(s(s(s(s(s(s(s(...))))))))), s(s(s(s(s(s(s(s(...)))))))), s(s(s(s(s(s(s(...))))))), s(s(s(s(s(s(...)))))), s(s(s(s(s(...)))))] 
...

基本的な考え方を示すだけです..これは1引数の述語でのみ機能します..

于 2015-10-20T08:33:44.210 に答える
2

SWI-Prolog についてここに示されている、さまざまな名前を持つ一部の Prolog システムに見られる厄介なグローバル述語を使用した、考えられる解決策。

chunks_of_size(Size, Goal) :-
    Size1 is Size + 1,
    nb_setval('$chunk_size', Size1),
    nb_setval('$chunk_count', Size),
    call((Goal,chunks)).

chunks :-
    nb_getval('$chunk_count', N),
    N > 0,
    M is N - 1,
    nb_setval('$chunk_count', M),
    nl,
    fail.
chunks :-
    nb_getval('$chunk_count', 0),
    nb_getval('$chunk_size', Size),
    nb_setval('$chunk_count', Size),
    write('-----'),
    chunks.

使用例:

?- chunks_of_size(3, (between(1, 12, N), write(N))).
1
2
3
-----
4
5
6
-----
7
8
9
-----
10
11
12
-----
false.

ソリューションの各グループの後でユーザーの操作を停止する場合は、chunks/0述語の 2 番目の句を次のように置き換えます。

chunks :-
    nb_getval('$chunk_count', 0),
    nb_getval('$chunk_size', Size),
    nb_setval('$chunk_count', Size),
    (   write('-----')
    ;   chunks
    ).

この変更により、次のものが得られます。

?- chunks_of_size(3, (between(1, 12, N), write(N))).
1
2
3
-----
N = 3 ;

4
5
6
-----
N = 6 ;

7
8
9
-----
N = 9 ;

10
11
12
-----
N = 12 ;

false.
于 2015-10-20T14:34:37.270 に答える