Home > Archive > Prolog > November 2007 > Counting recursion calls
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Counting recursion calls
|
|
|
| Hello!!!
I've tried to write a predicate that count's number of recursion calls
of it's arguments. For example:
count_calls( fib(3,R),N).
R = 2,
N = 4.
A code something like this:
interpret(true,_,NumOfCalls):-
nonvar(NumOfCslls),
N1 is NumOfCalls + 1,
NumOfCalls is N1,
!.
interpret(true,_,0):-!.
interpret((Goal1,Goal2),FunctorBaseName,
NumOfCalls):-
!,
interpret(Goal1,FunctorBaseName,NumOfCal
ls),
interpret(Goal2,FunctorBaseName,NumOfCal
ls).
interpret(Goal,FunctorBaseName,UpdatedNu
mOfCalls):-
functor_name(Goal,FunctorName),
FunctorName == FunctorBaseName,
clause(Goal,Body),
interpret(Body,FunctorBaseName,NumOfCall
s),
UpdatedNumOfCalls is NumOfCalls + 1.
interpret(Goal,_,_):-
predicate_property(Goal,built_in),
!,
call(Goal).
interpret(Goal,FunctorBaseName,NumOfCall
s):-
clause(Goal,Body),
interpret(Body,FunctorBaseName,NumOfCall
s).
functor_name(Goal,FunctorName):-
functor(Goal,FunctorName,_).
count_calls(Goal,NumOfCalls):-
functor_name(Goal,FunctorBaseName),
interpret(Goal,FunctorBaseName,NumOfCall
s).
But this doesn't work proper for count_calls( fib(3,R), N ).
because sets N to 3.
Any ideas?
| |
| Bart Demoen 2007-11-12, 8:09 am |
| sop3k wrote:
> interpret(true,_,NumOfCalls):-
> nonvar(NumOfCslls),
> N1 is NumOfCalls + 1,
> NumOfCalls is N1,
> !.
This clause contains several strange things:
1) nonvar(NumOfCslls) always fails, because the variable name was mistyped
2) the combination
N1 is NumOfCalls + 1,
NumOfCalls is N1,
has the same effect as
NumOfCalls is NumOfCalls + 1
which asks: please unify (say) 3 with 4 - this is clearly not succeeding ever.
>
> interpret(true,_,0):-!.
>
> interpret((Goal1,Goal2),FunctorBaseName,
NumOfCalls):-
> !,
> interpret(Goal1,FunctorBaseName,NumOfCa
lls),
> interpret(Goal2,FunctorBaseName,NumOfCa
lls).
Why do you wxpect that in a conjunction the number of calls to a particular
predicate is exactlyt the same ?
Of course you don't: you expect NumOfCalls to be destructively updated - that
is not how Prolog works.
Maybe you want
interpret((Goal1,Goal2),FunctorBaseName,
NumOfCalls):-
!,
interpret(Goal1,FunctorBaseName,NumOfCal
ls1),
interpret(Goal2,FunctorBaseName,NumOfCal
ls2),
NumOfCalls is NumOfCalls1 + NumOfCalls2.
>
> interpret(Goal,FunctorBaseName,UpdatedNu
mOfCalls):-
> functor_name(Goal,FunctorName),
> FunctorName == FunctorBaseName,
> clause(Goal,Body),
> interpret(Body,FunctorBaseName,NumOfCal
ls),
> UpdatedNumOfCalls is NumOfCalls + 1.
Missing cut after the == test ?
> interpret(Goal,_,_):-
> predicate_property(Goal,built_in),
> !,
> call(Goal).
Leaving the third argument free is strange here: wouldn't you say that
calling a builtin gives you zero (0) calls to the functor you are interested in ?
> But this doesn't work proper for count_calls( fib(3,R), N ).
> because sets N to 3.
>
> Any ideas?
>
Another idea idea is that you should give count_calls an extra argument
with name CountSoFar (and its meaning should be clear). Initially
it should be 0 (or 1 - figure that out). The general structure of
count_calls would be something like (for the conjunction):
interpret((G1,G2),CountSoFar,FinalCount)
:-
(interpretG1,CountSoFar,IntermediateCoun
t),
interpret(G2,IntermediateCount,FinalCoun
t).
BTW, what if your fib/2 called a fib/3 ? Wouldn't you also count those
fib/3 calls ? Was that your intention ?
Cheers
Bart Demoen
|
|
|
|
|