Math power的Prolog-tail递归辅助谓词
我正在尝试为Prolog中的power谓词制作一个尾部递归助手。到目前为止,我有这个,但在测试时,我得到一条消息,说在尝试调用helper谓词时有一个断点。我做错了什么?谢谢你的帮助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 >
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这是否回答了您的评论?