Reputation: 809
I would like to have a predicate isPowTwo/1
which holds for every power of two. Here is my approach:
isPowTwo(N) :- N > 0, N is N /\ (-N).
It works good, if I give integers to it:
?- isPowTwo(2).
true.
?- isPowTwo(4).
true.
?- isPowTwo(6).
false.
But it does not work when I want it to use as a generator:
?- isPowTwo(N).
ERROR: >/2: Arguments are not sufficiently instantiated
How can I write a predicate that generates powers of two, in ascending order?
Edit: It is important to use normal integers and not Peano numbers.
Upvotes: 2
Views: 294
Reputation: 809
I have found another approach which works good as generator (faster than the CLP(FD) version using length(_, N)
as goal), does not use clpfd
, but tends to end in an infinite-loop if used as verifier:
isPowTwo(1).
isPowTwo(N) :- isPowTwo(N1), N is N1 * 2.
See its behavior:
?- isPowTwo(N).
N = 1 ;
N = 2 ;
N = 4 ;
N = 8 ;
N = 16 ;
N = 32 ;
N = 64 ;
N = 128 ;
N = 256 ;
N = 512 ;
N = 1024 ;
...
?- isPowTwo(4).
true ;
... (infinite loop)
?- isPowTwo(3).
... (infinite loop)
Upvotes: 0
Reputation: 40768
Are you reasoning over integers? → Use your Prolog system's CLP(FD) constraints.
power_of_two(N) :- N #> 0, N #= 2^_.
?- power_of_two(2). true. ?- power_of_two(4). true. ?- power_of_two(6). false.
?- power_of_two(N). N in 1..sup, 2^_G844#=N.
?- power_of_two(N), length(_, N). N = 1 ; N = 2 ; N = 4 ; N = 8 ; N = 16 ; N = 32 ; etc.
Normal integers, no Peano numbers, are used.
Constraints allow us to state the solution in a pure, general and concise way.
Upvotes: 2