逆阶乘函数(Prolog)
我必须写一个Prolog程序来计算阶乘函数的逆,而不用除法。我还被告知:“函数的逆函数不一定是函数”。这是一个普通的阶乘谓词逆阶乘函数(Prolog),prolog,factorial,Prolog,Factorial,我必须写一个Prolog程序来计算阶乘函数的逆,而不用除法。我还被告知:“函数的逆函数不一定是函数”。这是一个普通的阶乘谓词 fact(0,1). fact(N,F) :- N>0, N1 is N-1, fact(N1,F1), F is N * F1. 我在其他一些帖子上读到过,你应该能够转换论点,但这个版本似乎不是这样。有人能帮我找出原因吗?我想你需要改变逻辑,改变评估的“流程”。N是未知的,但fact/2假定是有界的 如果您使fact/2尾部递归,添加累加器,您将能够更好地解决此
fact(0,1).
fact(N,F) :- N>0, N1 is N-1, fact(N1,F1), F is N * F1.
我在其他一些帖子上读到过,你应该能够转换论点,但这个版本似乎不是这样。有人能帮我找出原因吗?我想你需要改变逻辑,改变评估的“流程”。N是未知的,但fact/2假定是有界的 如果您使fact/2尾部递归,添加累加器,您将能够更好地解决此问题,因为您还可以添加已知阶乘(如K)和未知阶乘(如U),然后测试:
if F1 equals K (we have found the solution), unify U to N
if F1 > K, there is no solution... let Prolog fail...
否则,就有点作弊了
?- between(1,inf,X), fact(X,F), F >= 120.
X = 5,
F = 120
当然,那个片段不仅是个骗局,而且效率极低
一个有效的方法,实现我上面给出的提示
factinv(1, 0). % conventional
factinv(K, U) :- factinv(1, K, 1, U).
factinv(C, K, N, U) :-
F is C * N,
( F < K
-> M is N+1,
factinv(F, K, M, U)
; F == K
-> N = U
).
factinv(1,0)。%传统的
factinv(K,U):-factinv(1,K,1,U)。
factinv(C、K、N、U):-
F是C*N,
(FM是N+1,
factinv(F、K、M、U)
;F==K
->N=U
).
这个怎么样?我们只是在使用谓词fact/2的过程中生成阶乘,如果我们得到一个匹配的阶乘,我们就会停止,否则我们会生成下一个阶乘
fact(0,1).
fact(N,F) :- N>0, N1 is N-1, fact(N1,F1), F is N * F1.
inv_fact(1,0).
inv_fact(Value,Number) :- inv_fact(Value,1,Number).
inv_fact(Value,Num,Num) :- fact(Num,Value).
inv_fact(Value,Num,Number) :- fact(Num,V), Value < V,!,false.
inv_fact(Value,Num,Number) :- fact(Num,V),
not(Value=V),
NumNew is Num+1,
inv_fact(Value,NumNew,Number).
事实(0,1)。
事实(N,F):-N>0,N1是N-1,事实(N1,F1),F是N*F1。
库存事实(1,0)。
库存事实(值,编号):-库存事实(值,1,编号)。
inv_事实(Value,Num,Num):-事实(Num,Value)。
inv_事实(值,Num,Number):-事实(Num,V),值
有关干净的关系型解决方案,请参阅,但如果我们正在这样做:
inv_fact(RF, N) :-
( between(0,RF,N),
fact(N,F),
F >= RF
-> F = RF
; false
).
inv_fact(1, 1).
因为
N>0
要求N
为基本算术值。N1也是N-1
bit。这句话的意思是调用invfact(X,1)
应该成功两次。对吧?我想是的。所以我必须改变函数体?我会用你的fact
变成一个生成谓词,这样就可以生成一个高达给定值的阶乘列表,因为成对更好,(N,F),其中F是N!-然后从列表的末尾搜索我的索引。我对Prolog很不熟悉。有没有可能为我指出正确的方向来完成这个问题?谢谢false帮助我改进我的答案。