逆阶乘函数(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尾部递归,添加累加器,您将能够更好地解决此

我必须写一个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尾部递归,添加累加器,您将能够更好地解决此问题,因为您还可以添加已知阶乘(如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帮助我改进我的答案。