Better binary data support will be very nice to have a feature in Prolog. However, the relational nature of Prolog makes the overall solution rather complex. Thus, you are faced with a serious decision: either you map some library of other languages directly to Prolog, thereby ignoring the relational nature of Prolog (and ideally protecting all borders with pure creation errors) or you choose a more relational approach.
When choosing a more relational solution, you can use existing libraries like library(clfd) or implement the entire restriction mechanism yourself. With some clever limitations, you can get away with a much simpler approach, but I doubt it will work. Trade-offs in the areas of accuracy and efficiency. Please note that clpfd systems in SICStus or SWI needed literally decades to reach their quality level.
Regardless of how you accept, some notes:
Efficiency library(clpfd)
library(clpfd) in SWI-Prolog has been specially optimized to be (in some cases) comparable in performance to traditional (is)/2 . To see this, compile the rule:
list_len([_|Es], N0) :- N0
and look at the generated code using listing(list_len) :
list_len([_|C], A) :- ( integer(A) -> A>=0+1 ; clpfd:clpfd_geq(A, 1) ), ( integer(A) -> B is A+ -1 ; clpfd:clpfd_equal(B, A-1) ), list_len(C, B).
Effectively, inline elements for parsed expressions such as (is)/2 and (>=)/2 are used for those cases that directly correspond to these primitive operations.
To fully simulate bitrate operations, you will need (div)/2 , which is currently only supported by SICStus library(clpfd) , but not SWI. So an additional headache awaits you here. But as long as you use unsigned non-negative values, the problem does not occur. For general shifts you will need (^)/2 , which is supported by SWI but not SICStus.
And here is the CLPFD version:
two_four_bit_ints(High, Low) --> [B], { B in 0..255, Low in 0..15, High in 0..15, B
Please note that your original program inadvertently determines behavior in rather unintended situations, for example B = -1234 , B = 1+1 . You could add between(0, 255, B) , but then you could easily get combinatorial enumerations (read: explosions).
Existing library(clpfd) implementations can be significantly improved for such cases even more, but to improve them you must use them!
I / O and pio
ISO Prolog supports elementary I / O operations in
- bytes (
get_byte/1 ), - codes (
get_code/1 ) and - characters (
get_char/1 ).
If you want to use DCG, you will definitely want to use library(pio) . Currently, the SWI library(pio) only supports codes .