(So far nobody commented your code. So I will try)
stepen/1
loops
I assume you refer here to the non-negative powers of two. That is, 2^(-1)
and the like are not considered.
First of all, your stepen/1
definition produces an error in ISO conforming systems like gnu-prolog or sicstus-prolog.
| ?- stepen(6).
! Type error in argument 2 of (is)/2
! expected an integer, but found 3.0
! goal: _193 is 3.0 mod 2
This is due to X1 is X/2
which always produces a float or an error, but never an integer. You may replace this by X1 is X div 2
or equivalently X1 is X >> 1
.
Will this program now always terminate? After all X div 2
will approach zero. From the negative side, it will end at -1
which then will fail. But from the positive side, it will stay at 0
!
Here is the looping program (failure-slice) reduced to its minimum:
?- stepen(0).
stepen(2) :- false.
stepen(X):-
X mod 2=:=0,
X1 is X div 2,
stepen(X1), false. % stepen means power(in Serbian).
As Nicholas Carey has suggested, you can simplify this predicate to:
stepen(X) :-
X > 0,
X /\ (X-1) =:= 0.
vadi/2
logic
In your definition, this predicate is true, if all nodes of the trees are powers of two. I assume you wanted to "filter out" the powers. The easiest way to do this is by using DCGs instead of spojii/3
vl. append/3
. Let's first consider a simpler case, just the nodes of a tree:
nodes(nil) --> [].
nodes(t(X, L, R)) -->
[X],
nodes(L),
nodes(R).
?- T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), phrase(nodes(T),L).
T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), L = [1,2,3,4,5].
Now, you no longer want all elements, but only certain, I will use a separate nonterminal for that:
st(E) --> {stepen(E)}, [E].
st(E) --> {\+stepen(E)}. % nothing!
Or more compactly:
st(E) --> {stepen(E)} -> [E] ; [].
Now, the final non-terminal is:
stepeni(nil) --> [].
stepeni(t(X,L,R)) -->
st(X),
stepeni(L),
stepeni(R).
?- T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), phrase(stepeni(T),L).
T = t(1,nil,t(2,t(3,nil,t(4,nil,nil)),t(5,nil,nil))), L = [1,2,4].