Recursive function for going through digits not progressing

Viewed 29

I am trying to do a predicate called "all_even", with one parameter. It will take that parameter and check if it's even or odd using mod(); if it is odd then the predicate should stop working, which I persume will be done by the cut (!) feature.

But it seems like my recursive case seems to not be working. When I traced it, the number I inputted, 2968, doesn't change, but is eventually overwritten by some weird number that breaks the whole thing.

For context, here is my current code:

all_even(X) :- mod(X,2)\==0.%base case
    
all_even(X) :- mod(X,2)=:=0,
    all_even(X1), X1 is X // 10. %recursive case

and here's the tracing feedback

Call:all_even(2968)
 Call:2968 mod 2\==0
 Exit:2968 mod 2\==0
 Exit:all_even(2968)

1true

 Redo:all_even(2968)
 Call:2968 mod 2=:=0
 Exit:2968 mod 2=:=0
 Call:all_even(_5638)
 Call:_5638 mod 2\==0
 Exit:_5638 mod 2\==0
 Exit:all_even(_5638)
 Call:_5638 is 2968//10
 Exit:296 is 2968//10
 Exit:all_even(2968)

2true

 Redo:all_even(_5638)
 Call:_5638 mod 2=:=0
 Exception:_5638 mod 2=:=0
Arguments are not sufficiently instantiated
1 Answers

I think there are a couple of problems with your code:

  • the first clause (your base case) succeeds when the number is not even
  • the recursive clause calls all_even(X1) without first computing X1, so later when doing arithmetic operations it will give you the exception that the argument is not sufficiently instantiated.

So you should first compute X1 and then do the recursive call:

all_even(X) :-
  X \= 0,
  mod(X,2)=:=0,
  X1 is X // 10,
  all_even(X1) . %recursive case
all_even(0). %base case

This procedure does not work as a generator because it cannot cope with unbound variables. For that you may use clp(FD):

all_even(0). %base case
all_even(X) :-
  X #\= 0,
  0 #= X mod 2,
  X1 #= X // 10,
  all_even(X1) . %recursive case

sample run:

?- all_even(X), label([X]).
X = 0 ;
X = -8 ;
X = -6 ;
X = -4 ;
X = -2 ;
X = 2 ;
X = 4 ;
X = 6 ;
X = 8 ;
X = -88 ;
X = -86 
...
Related