2

私はzipWith関数を持っています:

zipW(_, [], _, []) :-
  !.
zipW(_, _, [], []) :-
  !.    
zipW(F,[H1|T1],[H2|T2],[H3|R]) :-
  X =.. [F, H1,H2, H3],
  call(X),
  zipW(F, T1, T2, R).

正常に動作しますが、差分リストに対して実行したいので、追加しました

zipW(F, DL-A, DL2-B, NL) :-
  zipW(F,DL,DL2,NL).

しかし、私がテストを実行すると

44 ?- A=[1,2,3|X]-X,B=[5,5,5|Y]-Y, zipW(add,A,B,C).

ローカルスタックからimというエラーが表示されますが、何が間違っていますか?

4

1 に答える 1

1

まず第一に、差分リストは、オープンエンド(通常)リストとそのエンディングリスト(セル/ポインター/ログ変数)のペアに他なりません。の場合[1,2,3|X]Xはその終了リストセルであり、まだ割り当てられていない/インスタンス化されていません。ペアリングのポイントは、変数の2番目の部分をインスタンス化することにより、リストの最初の部分を簡単に拡張できることです。

X=[4]ペアリング後[1,2,3,4]-[4]も差分リストですが、拡張することはできません。を使用すると、とX=[4|Y]のペアリングが新しい差分リストになります。[1,2,3,4|Y]Y

2つを1つの複合項にパッケージ化する必要はありません。述語に対して、2つの異なる引数で2つを持ち運ぶことができます。

したがって、zipWith述語の場合、終了条件のみが変更されます。

zipW(_,L1,Z1,_ ,_ ,L3,Z3) :- L1=@=Z1, L3=Z3, !.  % 1st exhausted
zipW(_,_ ,_ ,L2,Z2,L3,Z3) :- L2=@=Z2, L3=Z3, !.  % 2nd exhausted

var,varテストは、ペアと2つの等しいグラウンドリストのペアの両方で成功します。どちらの場合も、空の差分リストを表します。

作業条項は簡単に修正できます。

zipW(F, [H1|T1],Z1, [H2|T2],Z2, [H3|R], Z3) :-
      X =.. [F, H1, H2, H3],
      call(X),
      zipW(F, T1,Z1, T2,Z2, R,Z3).

SWI Prologでテスト済み:

3 ?- A=[1,2,3|X],B=[10,11,12,13|Y],zipW(plus, A,X, B,Y, C,Z).

A = [1, 2, 3|X]
B = [10, 11, 12, 13|Y]
C = [11, 13, 15|Z] ;

No
4 ?- 
于 2012-08-05T13:14:14.317 に答える