I'm trying to convert a list of bytes to it's corresponding integer. I would like to bind to the second variable as the documenting comment would suggest. I'm printing it out as a temporary hack.
% bytes_int(+ByteList, -IntegerRepresentation)
% converts a list of bytes to integer representation
% I accounts for bitshifting
bytes_int(BytesList, _) :-
bytes_int(BytesList, 0, 0).
bytes_int([], _, Num) :-
format('~w', Num).
bytes_int([B|Bs], I, Num) :-
B0 is B << I,
Num0 is B0 + Num,
I0 is I + 8,
bytes_int(Bs, I0, Num0).
It's printing the correct value, but I'm not sure why it's not binding to the second variable for further use. What improvements can I do to accomplish this?
?- bytes_int([42, 121, 56], N).
3701034
A first problem that occurs is here:
bytes_int(BytesList, _) :-
bytes_int(BytesList, 0, 0).
You do not bind the result (_
) with a variable in the call. You probably want to use:
bytes_int(BytesList, R) :-
bytes_int(BytesList, 0, R).
Next you do not use an accumulator. The accumulator here can store the cumulative sum you have obtained this far. So we declare an additional parameter:
bytes_int(BytesList, R) :-
bytes_int(BytesList, 0, 0, R).
Now we are set for the real algorithm. In case we reached the end of the list. The thus far cumulative sum, is the final result so:
bytes_int([], _, R, R).
In the other case, we simply update the cumulative sum, update the shift size, and perform recursion on the tail of the list:
bytes_int([H|T], S0, R0, R) :-
R1 is R0 + H << S0,
S1 is S0 + 8,
bytes_int(T, S1, R1, R).
And now putting it all together:
bytes_int(BytesList, R) :-
bytes_int(BytesList, 0, 0, R).
bytes_int([], _, R, R).
bytes_int([H|T], S0, R0, R) :-
R1 is R0 + H << S0,
S1 is S0 + 8,
bytes_int(T, S1, R1, R).
This generates:
?- bytes_int([42, 121, 56], N).
N = 3701034.