Let's start with some examples, pretending we already have this predicate:
?- pred( [f, 0], X ).
X = [1,1,1,1, 0,0,0,0]. % that's what you said you want, isn't it?
?- pred( [f, 0], [1,1,1,1, 0,0,0,0] ).
yes.
?- pred( [f | [0]], [1,1,1,1 | [0,0,0,0]] ).
yes.
?- pred( [f | HEX], [A,B,C,D | BIN] ), [A,B,C,D] = [1,1,1,1], pred( HEX, BIN).
yes.
?- pred( [f | HEX], [A,B,C,D | BIN] ), hex(f, [A,B,C,D]), pred( HEX, BIN).
yes.
?- pred( [0 | HEX2], [A2,B2,C2,D2 | BIN2] ), hex(0, [A2,B2,C2,D2]), pred( HEX2, BIN2).
yes.
?- pred( [0 | HEX2], [A2,B2,C2,D2 | BIN2] ), hex(0, [A2,B2,C2,D2]),
HEX2 = [], BIN2 = [], pred( HEX2, BIN2).
yes.
Yes? Right? (In case it isn't clear, consider the identity [0] = [0 | []]
).
This means it must also be the case that
?- HEX2 = [], BIN2 = [], pred( HEX2, BIN2).
yes.
?- pred( [], []).
yes.
Voila, we see what the base case must be. Right?
Moreover, we actually have seen there what the recursive case must be, as well. And you don't need any explicit append
calling there. This:
?- pred( [f | HEX], [A,B,C,D | BIN] ), hex(f, [A,B,C,D]), pred( HEX, BIN).
yes.
can be written as
?- pred( [F | HEX], [A,B,C,D | BIN] ), F = f, hex(F, [A,B,C,D]), pred( HEX, BIN).
yes.
but actually, it is easily generalized to
?- pred( [F | HEX], [A,B,C,D | BIN] ), hex(F, [A,B,C,D]), pred( HEX, BIN).
yes.
And there you have it.
See? Prolog is fun. Prolog is easy. Prolog is just saying what you mean.