Math power的Prolog-tail递归辅助谓词

Math power的Prolog-tail递归辅助谓词,math,prolog,Math,Prolog,我正在尝试为Prolog中的power谓词制作一个尾部递归助手。到目前为止,我有这个,但在测试时,我得到一条消息,说在尝试调用helper谓词时有一个断点。我做错了什么?谢谢你的帮助 trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res). trpow_helper(_, 0, Acc, Acc). trpow_helper(Base, Exp, Acc, Res) :- Exp >

我正在尝试为Prolog中的power谓词制作一个尾部递归助手。到目前为止,我有这个,但在测试时,我得到一条消息,说在尝试调用helper谓词时有一个断点。我做错了什么?谢谢你的帮助

    trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).
    
    trpow_helper(_, 0, Acc, Acc).
    trpow_helper(Base, Exp, Acc, Res) :-
        Exp > 0,
        Decexp is Exp - 1,
        Acc1 is Acc * Base,
        Res = Acc1,
        trpow_helper(Base, Decexp, Acc1, Res).
根据你的代码

trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).

trpow_helper(_, 0, Acc, Acc):- !. /*Cut to avoid bt to second clause*/
trpow_helper(Base, Exp, Acc, Res) :-
    Exp > 0,
    Decexp is Exp - 1,
    Acc1 is Acc * Base, /*removed Res = Acc1, not needed*/
    trpow_helper(Base, Decexp, Acc1, Res).

它现在起作用了

使用CLP,如swi prolog中的CLP:

:- use_module(library(clpfd)).
trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).

trpow_helper(   _, Exp, Acc, Acc):- Exp #= 0.
trpow_helper(Base, Exp, Acc, Res) :-
    Exp #> 0,
    Decexp #= Exp - 1,
    Acc1 #= Acc * Base,
    trpow_helper(Base, Decexp, Acc1, Res).

?- trpow(1, E, 1).
E = 0 ;
E = 1 .
?- trpow(2, E, 4).
E = 2 .
?- trpow(2, E, 8).
E = 3 .
?- trpow(B, 3, 8).
B = 2 .
?- trpow(B, E, 8).
B = 8,
E = 1 ;
B = 2,
E = 3 ;
...

之后,会有更多不实例化B的解决方案。事实上,它会永远循环。

E=1,trpow(1,E,1)。
成功。Neamoins,
trpow(1,E,1),E=1。
失败。在调用trpow/3时,预期会知道Exp,否则Decexp是Exp-1失败。要处理这个用例,您需要对Exp进行约束。您需要CLP。您可以交换子句以获得更一致的行为。更好的做法是在事实中添加
Exp=:=0
。@false这是否回答了您的评论?