4

特定の位置に要素を挿入するプログラムをPrologで作成しようとしています。

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

次のコードがあります。

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

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

4

4 に答える 4

3

ここにあなたが欲しいものを述べましょう。たとえば、「新しい要素をそこに挿入できるように、入力Listを要素の後に分割したい」と言うことができます。Position - 1

append/3(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).

List Position - 1あるいは、「何も触れずに時代の要素をくぐり抜けて、挿入して、また何も触れないようにしたい」と言うこともできますElement

今回の直接の移動は次のようになります。

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

「私の入力は、私の要素がないことを除けば、私の入力Listと同じリストです」と言うこともできます。そして、swi-prologを使用する場合、述語がこれを即座に解決することを理解してください。ResultElementPosition

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

結論は次のとおりです。問題が何であるかを明確に述べ、解決策を簡単に説明する必要があります。

于 2012-04-08T15:13:48.250 に答える
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]).

Pos = 0 または Pos > length(List) + 1 の場合、述語は失敗します。

于 2012-04-08T15:03:13.283 に答える
2

TL;DR: item Eat 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/4nth1/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:上記のコードはそのまま使用さ、追加のライブラリ述語は必要ありません。

于 2015-11-30T22:15:39.913 に答える
0
ins(Element,List,Nth,Result) :-
    length([_|L0],Nth),
    append(L0,[_|R],List),
    append(L0,[Element|R],Result).
于 2012-04-17T07:21:35.870 に答える