TL;DR: item E
at positionI1
を listEs0
に挿入するために、再帰的なコードを書く必要はありません。
代わりに、作業 (およびそれを正しく行うための心配も!) を用途の広い補助述語に委譲できます。これらはすべてProlog prologueの一部です。定義するには、次のins_/4
ように記述します。
ins_(E, Es0, I1, Es) :-
maplist (any_thing, Es, [_|Es0]),
append (Prefix, Suffix, Es0),
length ([_|Prefix], I1),
append (Prefix, [ E|接尾辞]、Es)。
なんでも(_、 _)。% 補助述語 (上で使用)
maplist(any_thing, Es, [_|Es0])
と同等であることに注意してくださいsame_length(Es, [_|Es0])
。
GNU Prolog バージョン 1.4.4 (64 ビット) を使用したサンプル クエリ1、2、3 :
?- ins_(X, [a,b,c,d,e], N1, Xs)。
N1 = 1、Xs = [ X、a、b、c、d、e]
; N1 = 2、Xs = [a、X、b、c、d、e]
; N1 = 3、Xs = [a、b、X、c、d、e]
; N1 = 4、Xs = [a、b、c、X、d、e]
; N1 = 5、Xs = [a、b、c、d、X、e]
; N1 = 6、Xs = [a、b、c、d、e、X ]
; 間違い。
?- ins_(X, [a,b,c,d,e], 3, Xs)。
Xs = [a,b, X ,c,d,e]
; 間違い。
?- ins_(X, Xs0, 3, [a,b, c ,d,e])。
X = c、Xs0 = [a、b、d、e]
; 間違い。
最も一般的なクエリを忘れないでください!
?-ins(X、Es0、I1、Es)。
Es0 = []、I1 = 1、Es = [ X ]
;
Es0 = [A]、I1 = 1、Es = [ X ,A]
; Es0 = [A]、I1 = 2、Es = [A、X ]
;
Es0 = [A,B]、I1 = 1、Es = [ X、A、B]
; Es0 = [A、B]、I1 = 2、Es = [A、X、B]
; Es0 = [A,B]、I1 = 3、Es = [A,B, X ]
;
Es0 = [A、B、C]、I1 = 1、Es = [ X、A、B、C]
; Es0 = [A、B、C]、I1 = 2、Es = [A、X、B、C]
; Es0 = [A、B、C]、I1 = 3、Es = [A、B、X、C]
; Es0 = [A、B、C]、I1 = 4、Es = [A、B、C、X ]
;
Es0 = [A、B、C、D]、I1 = 1、Es = [ X、A、B、C、D]
; ...
すべてのソリューションの公正な列挙、OK!
編集: SWI-Prolog 7.3.11 および SICStus Prolog 4.3.2 に関する彼の回答で @m09 によってins3/4
定義さ
れ
ている最も一般的なクエリを繰り返しました(どちらもライブラリ述語を備えています)。の基礎となる実装が異なる手続き的セマンティクスを示すのを見て驚いた(「公正な列挙」について)。自分で見て!nth1/4
nth1/4
% SICStus Prolog 4.3.2 % SWI Prolog 7.3.11
% %
?- ins3( X , Es0, I1, Es). %?-ins3( X、Es0、I1、Es)。
I1 = 1、Es0 = []、Es = [ X ] % I1 = 1、Es = [ X |Es0]
; % ; I1 = 2、Es0 = [_A|_Z]、
I1 = 1、Es0 = [_A]、Es = [ X、_A] % Es = [_A、X |_Z]
; I1 = 2、Es0 = [_A]、Es = [_A、X ] % ; I1 = 3、Es0 = [_A、_B|_Z]、
; % Es = [_A,_B, X |_Z]
I1 = 1、Es0 = [_A、_B]、Es = [ X、_A、_B] % ; I1 = 4、Es0 = [_A、_B、_C|_Z]、
; I1 = 2、Es0 = [_A、_B]、Es = [_A、X、_B] % Es = [_A、_B、_C、X |_Z]、
; I1 = 3、Es0 = [_A、_B]、Es = [_A、_B、X ] % ; I1 = 5、Es0 = [_A、_B、_C、_D|_Z]、
; % Es = [_A,_B,_C,_D, X |_Z]
... % ...
脚注 1:上記のすべてのサンプル クエリは、普遍的に終了します。
脚注 2: GNU Prolog トップレベルによって与えられた回答は、少しきれいに印刷されています。
脚注 3:上記のコードはそのまま使用され、追加のライブラリ述語は必要ありません。