I am trying my hand at relational prolog. Part of my program needs to deal with bitmasks. It however seems that prolog code handles bit makes, such as to set a bit or clear a bit doesn't work relationally -- i.e. it only works in setting a bit, but not in the other direction, identifying what bit is set.
For example:
setbit(X, N, V) :-
N1 #= 1<< N,
V #= X \/ N1.
this code only work in one direction, where X and N are given and V is calculated. If one provides V and N, then X is not derived, but rather its left as an uninstantiated expression.
Does this mean that calculating with bit maps and masks is out of scope of relational prolog.
?- setbit(0,1,X).
X = 2.
?- setbit(X, 1, 2).
2#=X\/2.
the latter doesn't bind X to 0.
thank you,
Daniel
Edit: based on the comments below, the following code works very well:
setbit(X, N, V) :-
X in 0..1,
label([X]),
N1 #= 1<< N,
V #= X \/ N1.
clearbit(X, N, V) :-
X in 0..1,
label([X]),
current_prolog_flag(max_tagged_integer, MTI),
N1 #= MTI /\ \(1<<N),
% N1 #= 0xffffffffffffff /\ \(1<<N),
V #= X /\ N1
Note, the current_prolog_flag -- it retrieves the maximum integer fitting into one word on the current machine architecture -- on 64 bit its 54 bits, the rest of the bits are used for housekeeping.
I am not great at clpfd
, but I think the problem here is that you haven't given X a finite domain or asked for its values to be enumerated. This works:
?- setbit(X, 1, 2), X in 0..1, label([X]).
X = 0 ;
false.
The second expression there, X in 0..1
says you want X to be zero or one, and the third says, "give me the values X can obtain."