My version was this, I kind of like the simplicity especially if you utilice gprolog min_list, it is short and simple
corresponding(A, B, [A|_], [B|_]). corresponding(A, B, [_|C], [_|D]) :- corresponding(A, B, C, D). min2(A, B, C, D) :- min_list(D, B), corresponding(A, B, C, D).
For min_list implementation, as I posted to StackOverflow (don't double post other time), my smallest with cuts as yours was copy from internet:
% length 1 is base case, all minimums are equal, so cuts smallest([A], A). % shorten by 1 by dropping bigger or equal smallest([A, B|C], D) :- A > B, smallest([B|C], D), !. % cut means this is else branch and need not condition smallest([A, _|C], D) :- smallest([A|C], D).
This is elegant & efficient and as you said, the solution I had got didn't find all the pairs.
It does take a while to get used to Prolog's way of doing stuff coming from the imperative world. And sorry for the double posting. I thought I could have more views & discussions by doing so.