It seems to me one ought to be able to process binary data with DCGs on a list of bytes. To make it work generally, though, one has to use bitwise operations which means is/2
is involved, which means instantiation order is an issue, which may confound using DCGs to both parse and generate. The idea here is to serialize/deserialize binary data but I think this example is simple enough to illustrate the problem.
Let me illustrate with some code. Suppose I have a binary protocol. I want to read two 4-bit integers from a byte. My naive self tries this:
two_four_bit_ints(High, Low) -->
[B],
{
High is B >> 4,
Low is B /\ 0xF
}.
This seems to work for parsing:
?- phrase(two_four_bit_ints(H,L), [255]).
H = L, L = 15.
?- phrase(two_four_bit_ints(H,L), [0]).
H = L, L = 0.
?- phrase(two_four_bit_ints(H,L), [15]).
H = 0,
L = 15.
?- phrase(two_four_bit_ints(H,L), [240]).
H = 15,
L = 0.
But this is not going to generate:
?- phrase(two_four_bit_ints(15,15), [X]).
ERROR: is/2: Arguments are not sufficiently instantiated
?- phrase(two_four_bit_ints(15,15), X).
ERROR: is/2: Arguments are not sufficiently instantiated
Not sure what to do. I'm bracing for someone to shout "Use clpfd
" but it does not appear to support bit shift operations, and I'd be concerned about the performance effect of invoking such a powerful system in the middle of low-level code.
Since I don't see a lot of helpers for binary around, is there some other more preferred way of doing binary extraction/encoding in Prolog? I'm only using SWI for now so I'm happy to accept suggestions that are not portable to ISO, but if it is portable that's nice too. I was rather hoping to find someone had ported something like Erlang's bit syntax but didn't have any luck searching.
(is)/2
is moded, but on the other hand you are "concerned about the performance effect of invoking such a powerful system [as clpfd] in the middle of low-level code". You will have to choose. Shifting is related to multiplication, division and exponentiation... – Murkis/2
doesn't work for unbound terms on the right side. Just imagine that if it would, prolog would have to define (more than questionable) inverse functions for all arithmetic operations. Especially for operators like>>/2
this seems odd (What shouldA >> B
generate? and in what order?). – Sifuentesis/2
's limitations. I am not saying I requireis/2
. I am saying I want to parse and generate and that I suspectclpfd
would be too heavy in practice. I'm happy to be proven wrong. – Podophyllinclpfd
, where such errors cannot happen at all. – Murk