RabbitFarm

2022-10-16

The Weekly Challenge 186 (Prolog Solutions)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1

You are given two lists of the same size. Write a predicate that merges the two lists.

Solution


zip([], [], []).
zip([Ha|Ta], [Hb|Tb], [Ha, Hb|Tc]):-
    zip(Ta, Tb, Tc).

Sample Run


$ gprolog --consult-file prolog/ch-1.p
| ?- zip([1,2,3],[a,b,c],C).

C = [1,a,2,b,3,c]

Notes

This is a great simple example of recursion in Prolog. If there is any doubt about what is happening here is what trace/0 shows:


| ?- trace.
The debugger will first creep -- showing everything (trace)

yes
{trace}
| ?- zip([1,2,3],[a,b,c],C).
      1    1  Call: zip([1,2,3],[a,b,c],_38) ? 
      2    2  Call: zip([2,3],[b,c],_73) ? 
      3    3  Call: zip([3],[c],_102) ? 
      4    4  Call: zip([],[],_131) ? 
      4    4  Exit: zip([],[],[]) ? 
      3    3  Exit: zip([3],[c],[3,c]) ? 
      2    2  Exit: zip([2,3],[b,c],[2,b,3,c]) ? 
      1    1  Exit: zip([1,2,3],[a,b,c],[1,a,2,b,3,c]) ? 

Given that we know the lists are of the same size we have an extremely elegant solution. That is, we state that the first argument is an element, followed by the rest of the list, and the same goes for the second argument. For the third argument we state that its head is the combined initial two elements from the first and second lists and this unifies our uninstantiated variable.

References

Challenge 186

posted at: 20:00 by: Adam Russell | path: /prolog | permanent link to this entry