CoffeeRun
CoffeeRun

Reputation: 71

Zipwith application in prolog

I have a hard time understanding this application of zipwith in Prolog and wondered if someone gets it. I already have an idea of what functor does, but I don't see how it applies in that case. I vaguely think that the two arg place arg no 1 and arg no 2 of CL into A and B, but they aren't used after that. Here is the predicate:

zipWith( _, [], [], [] ).
zipWith( OP, [A | AS], [B | BS], [CL | RS] ) :-
   functor( CL, OP, 2 ),
   arg( 1, CL, A ),
   arg( 2, CL, B ),
   zipWith( OP, AS, BS, RS ).

and here is an example of the use of this predicate:

| ?- zipWith( F, L1, L2, [b(w, w), b(f, g)] ).
F = b,
L1 = [w,f],
L2 = [w,g] ?yes

Upvotes: 1

Views: 85

Answers (2)

Will Ness
Will Ness

Reputation: 71065

Here's an equivalent code:

zipWith(      _,  []      , []      , []       ).
zipWith(     OP,  [A | AS], [B | BS], [T | RS] ) :-
   T  =.. [  OP,   A,        B     ],                %% T = OP( A, B )
   zipWith(  OP,       AS,       BS,       RS  ).

T =.. [ OP, A, B] is the same as T = OP( A, B ) except that in the latter the logical variable isn't actually allowed, in the functor position. Thus, the following all hold:

T = p(a,b), T =.. [p, a, b].
p(a,b) =.. [p, a, b].
p(a,b) =.. [P, A, B], P=p, A=a, B=b.
...

zipWith( p, [a,b,c], [x,y,z], [p(a,x), p(b,y), p(c,z)] ).
zipWith( p, [a,b,c], XYZ, [p(a,x), p(b,y), p(c,z)] ), XYZ = [x,y,z].
zipWith( p, ABC, [x,y,z], [p(a,x), p(b,y), p(c,z)] ), ABC = [a,b,c].
zipWith( P, ABC, [x,y,z], [p(a,x), p(b,y), p(c,z)] ), ABC = [a,b,c], P=p.
....

So the elements of the first two lists are just pared up, in the third.

Upvotes: 1

CapelliC
CapelliC

Reputation: 60014

functor/3 acts as a guard, that every element of the list match the intended compound.

Here is an alternative coding, making use of the so called univ and library(yall):

zipWith( F, L1, L2, L ) :-
    maplist({F}/[A,B,C]>>(C=..[F,A,B]), L1, L2, L).

Upvotes: 1

Related Questions