Djellal Mohamed Aniss
Djellal Mohamed Aniss

Reputation: 1733

converting base 10 to base 2 in prolog

am trying to convert base 10 to base 2 using prolog this is my code :

binary(X,B) :- X > -1 , tobin(B,X,1).
tobin(S,0,1) :- S is 0.
tobin(S,0,V) :- V>1 , S is 1.
tobin(S,X,V) :- X > 0 , 
               X1 is X // 2 , 
               V1 is V * 10 ,  
               tobin(S1,X1,V1),  
               S is X mod 2 , 
               S is S + S1 * V1 .

it's not working :/ can you help me ? thank you a lot :D

Upvotes: 1

Views: 324

Answers (2)

Grzegorz Adam Kowalski
Grzegorz Adam Kowalski

Reputation: 5565

If you want to know what was wrong with you original code, study this:

binary(X,B) :- X > -1 , tobin(B,X).
/*tobin(S,0,1) :- S is 0.*/
/* tobin(S,0,V) :- V>1 , S is 1.*/
tobin(0,0).
tobin(S,X) :- X > 0 , 
               X1 is X // 2 , 
               /*V1 is V * 10 ,  */
               tobin(S1,X1),  
               S0 is X mod 2 , 
               S is S0 + S1 * 10 .

There are two main changes:

  • I've renamed S to S0 in one place as without that one of the statements is always false (S is S +...);
  • I've removed third argument from tobin as it wasn't really necessary to pass positional value to recurrent calls and in all this recurrency some error crept in which wasn't clear to me.

After the fixes your code looks nicer that from @damianodamiano (in my opinion):

binary(X,B) :- X > -1 , tobin(B,X).
tobin(0,0).
tobin(S,X) :- X > 0 , 
               X1 is X // 2 , 
               tobin(S1,X1),  
               S0 is X mod 2 , 
               S is S0 + S1 * 10 .

Actually, you can skip binary and call tobin directly (arguments are in reversed order) which makes it even simpler:

tobin(0,0).
tobin(S,X) :- X > 0 , 
               X1 is X // 2 , 
               tobin(S1,X1),  
               S0 is X mod 2 , 
               S is S0 + S1 * 10 .

Main advantage of @damianodamiano would be runtime optimization by tail recursion.

Upvotes: 1

damianodamiano
damianodamiano

Reputation: 2662

I wrote a predicate to solve your problem:

dec2Bin(0,V,_,V).
dec2Bin(N,V,Counter,Val):-
    Reminder is N mod 2,
    N1 is N//2,
    V1 is V + Reminder*(10^Counter),
    Counter1 is Counter + 1,
    dec2Bin(N1,V1,Counter1,Val).

convert(N,V):-
    N > -1,
    dec2Bin(N,0,0,V),
    writeln(V).

?- convert(8,V).
V = 1000.

Upvotes: 1

Related Questions