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).

我收到一条错误消息,说我不在本地堆栈中,我做错了什么?

4

1 回答 1

1

首先,差异列表只不过是一个开放式(通常)列表及其结尾列表单元/指针/logvar的配对。对于[1,2,3|X],X是它的结束列表单元,仍然未分配/未实例化。配对的要点是能够通过实例化第二部分(变量)轻松扩展第一部分(列表)。

X=[4]配对后[1,2,3,4]-[4]仍然是差异列表,但无法再扩展。如果我们使用,和X=[4|Y]的配对将成为我们新的差异列表。[1,2,3,4|Y]Y

我们不必将两者包装在一个复合术语中,我们可以将两者放在谓词的两个不同参数中。

因此,对于您的zipWith谓词,只有结束条件会改变:

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

对于var,varpair 和一对两个相等的接地列表,测试都成功,这两种情况都表示一个空的差异列表。

工作条款很容易修改:

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 回答