2012-04-08 10 views
4

私はプログラムを特定の位置に要素を挿入するPrologに書き込もうとしています。リストの長さ、要素を挿入する

?- ins(a, [1,2,3,4,5], 3, X). 
X = [1,2,a,3,4,5]. 

Iは、次のコードを有する:

ins(X,[H|T],P,OUT) :- 
    length([T3],P), 
    concatenate(X,[H],T), 
    ins(...). 

問題は、問題がどこにあるか(私も知っているが背面から与えられたインデックスの要素Xに挿入されることであるが - >は明らかであるlength([T3],P)頭からではなく後ろからリストの長さ)。どのくらいの要素を切り取ったのかを覚えようとしていましたが、「切り捨て要素数」= PのときにはXを挿入しましたが、実際にはPrologで書き込むことはできません。何か案は?

答えて

3
% ins(Val,List,Pos,Res) 

ins(Val,[H|List],Pos,[H|Res]):- Pos > 1, !, 
           Pos1 is Pos - 1, ins(Val,List,Pos1,Res). 
ins(Val, List, 1, [Val|List]). 

あなたがここに欲しいものを順位= 0またはPOS>長(一覧)+ 1

2

レッツ・状態ならば、述語は失敗します。たとえば、「Listの入力をPosition - 1要素の後に分割して、そこに新しい要素を挿入できるようにしたい」と言うことができます。

append/3と直接traduction(DCGが良いところでだろう):

ins(Element, List, Position, Result) :- 
    PrefixLength is Position - 1, 
    length(Prefix, PrefixLength), 
    append(Prefix, Suffix, List), 
    append(Prefix, [Element], Temp), 
    append(Temp, Suffix, Result). 

それともあなたが言うことができます:「私は何も触れず、私のListPosition - 1倍の要素を通過し、その後Elementを挿入したいですもう一度触れないでください "。

この時間は直接traductionは次のようになります。

ins2(Element, List, 1, [Element|List]). 
ins2(Element, [Head|Tail], Position, [Head|Result]) :- 
    Position > 1, 
    NewPosition is Position - 1, 
    ins2(Element, Tail, NewPosition, Result). 

あなたがあまりにもすることを述べることができます:「それはない私のElementPositionとして番目の要素を持っている以外私の入力Listは私Result 1に等しいリストです」そしてあなたはSWI-プロローグを使用している場合、述語は即座にこれを解決することを実現:

ins3(Element, List, Position, Result) :- 
    nth1(Position, Result, Element, List). 

ボトムラインは次のようになります。簡単な言葉でどのような問題が明らかにし、解決策を表示させたい状態。

+0

pos> 1、newPosは私が探していたものです。:) thx a lot – Johnzzz

0
ins(Element,List,Nth,Result) :- 
    length([_|L0],Nth), 
    append(L0,[_|R],List), 
    append(L0,[Element|R],Result). 
+1

このコードは問題に答えるかもしれませんが、問題を解決する方法と使用する理由を説明する方が良いでしょう。それ。コードのみの回答は長期的には有用ではありません。 –

+0

'? - ins_(a、[1,2,3,4,5]、3、[1,2、a、3,4,5]) 'というクエリは成功しません。 '? - ins_(a、[1,2,3,4,5]、3、[1,2、a、4,5]).'というクエリが成功すれば失敗します。バグを修正するには、正確に4文字を削除する必要があります:) – repeat

2

TL; DR:リストEs0に位置I1でアイテムEを挿入するには、我々は再帰的なコードを書く必要はありません。

代わりに、Prolog prologueの一部である多彩な補助述語に作業(およびそれを正しく得ることについての心配)を委任できます。 ins_/4を定義するために、我々は書く:maplist(any_thing, Es, [_|Es0])same_length(Es, [_|Es0])と同等であることを

 
ins_(E, Es0, I1, Es) :- 
    maplist (any_thing, Es, [_|Es0]), 
    append (Prefix, Suffix, Es0), 
    length ([_|Prefix], I1), 
    append (Prefix, [E|Suffix], Es). 

any_thing(_, _).      % auxiliary predicate (used above) 

注意を。

サンプルは、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] 
; false. 

?- ins_(X, [a,b,c,d,e], 3, Xs). 
    Xs = [a,b,X,c,d,e] 
; false. 

?- ins_(X, Xs0, 3, [a,b,c,d,e]).    
    X = c, Xs0 = [a,b,d,e] 
; false. 

はのが最も一般的なクエリを忘れないようにしましょう!

 
?- 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!

EDIT: SWI-Prologの7.3.11およびSICStusプロローグ4.3.2(両方ともライブラリ述語nth1/4を備えています)に by @m09 in his answerを定義したように私はins3/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:上記のコードはと同じようにで使用されていますが、追加のライブラリ述語は必要ありません。

関連する問題