Rule to calculate power of a number when the exponent is Negative in Prolog?

前端 未结 3 1873
北恋
北恋 2021-01-16 15:19

I have a power function pow that attempts to calculate the value of B to the power of E. So far I handle the cases-
1. exponent i

3条回答
  •  感情败类
    2021-01-16 15:27

    To start, your second clause is non tail recursive (you can read about the subject here). It means that eventually, you will run out of call stack memory when running it. A good thing would be to use an accumulator to make it tail recursive. You can achieve that as follows :

    % we add an accumulator to poW/3, making it pow/4.
    pow(B, E, Result) :- pow(B, E, 1, Result).
    
    % when we hit 0, our accumulator holds B^E so we unify it with result.
    pow(_, 0, Accu, Accu) :- !.
    
    % at each step, we multiply our accumulator by B
    pow(B, E, Accu, Result) :-
        NewE is E - 1,
        NewAccu is Accu * B,
        pow(B, NewE, NewAccu, Result).
    

    Then, you can simply handle the negative case by adding this clause on top of the others (it simply tells prolog that a negative power is the inverse of the positive one) :

    pow(B, E, Result) :-
        E < 0,
        PositiveE is - E,
        pow(B, PositiveE, 1, R),
        !,
        Result is 1 / R.
    

    Note that you can do it directly with your code :

    pow(B, E, Result) :-
        E < 0,
        PositiveE is - E,
        pow(B, PositiveE, R),
        !,
        Result is 1 / R.
    

    Plus, we now introduced a very red cut (see here for the meaning of red cut if necessary). So it'd be better to turn into a green cut with this modification :

    pow(B, E, Result) :-
        E < 0,
        PositiveE is - E,
        pow(B, PositiveE, 1, R),
        !,
        Result is 1 / R.
    
    % we add an accumulator to poW/3, making it pow/4.
    pow(B, E, Result) :-
        E >= 0, %************* HERE *****************
        pow(B, E, 1, Result).
    
    % when we hit 0, our accumulator holds B^E so we unify it with result.
    pow(_, 0, Accu, Accu) :- !.
    
    % at each step, we multiply our accumulator by B
    pow(B, E, Accu, Result) :-
        NewE is E - 1,
        NewAccu is Accu * B,
        pow(B, NewE, NewAccu, Result).
    

提交回复
热议问题