在prolog中编写组合函数很麻烦,它遵循以下数学方程式: b! /((b-c)!* c!)。我是prolog的新手,不确定它到底有什么问题。我收到的错误是:错误:is / 2:算术:'fact1 / 2'不是函数
下面是我的代码:
%fac(0,1).
%fac(N,X) :- N > 0, M is N - 1, fac(M,Y), X is Y * N.
fact1(0,Result) :- Result is 1.
fact1(N,Result) :- N > 0, N1 is N-1,
fact1(N1,Result1), Result is Result1*N.
main :- current_prolog_flag(argv,[BB_S,CC_S]),
atom_number(BB_S,BB),
atom_number(CC_S,CC),
%read_input,
R1 is 1,
R2 is 1,
R3 is 1,
FB is fact1(BB,R1),
ABS is abs(BB - CC),
FE is fact1(ABS,R2),
FC is fact1(CC,R3),
TI is FE * FC,
BF is FB / TI,
%BF is fac(BB) / (fac(abs(BB-CC)) * fac(CC))),
write($BF),
halt.
谢谢您的帮助。
答案 0 :(得分:1)
没关系。我找到了解决方案。但是,为了他人的利益,我在此处发布了解决方案。显然,这些函数没有返回值,而是通过将它们生成的值放在给定变量中来返回。
%fac(0,1).
%fac(N,X) :- N > 0, M is N - 1, fac(M,Y), X is Y * N.
fact1(0,Result) :- Result is 1.
fact1(N,Result) :- N > 0, N1 is N-1, fact1(N1,Result1), Result is Result1*N.
main :- current_prolog_flag(argv,[BB_S,CC_S]),
atom_number(BB_S,BB),
atom_number(CC_S,CC),
%read_input,
fact1(BB,FB), %notice change
ABS is abs(BB - CC),
fact1(ABS,FE), %notice change
fact1(CC,FC), %notice change
TI is FE * FC,
BF is FB / TI,
%BF is fac(BB) / (fac(abs(BB-CC)) * fac(CC))),
print('Number of bracelets: '),
write(BF),
halt.
答案 1 :(得分:1)
基于这个问题,我认为您对谓词是一个误解。谓词只能导致true
或false
(当然,可能会出错,或者,如果您也将它们视为“可能的结果”,则它们可能会永远循环)。谓词可以通过统一尚未固定的变量来响应值。通常在Prolog中,使谓词尽可能通用,以便可以将谓词称为 multidirectional 。
您称谓为:
FB is fact1(BB,R1),
但是fact1
不是一个函数(在is/2
谓词中,函子是已知的函子)。
谓词可以计算事物并通过 unification 传递结果,例如:
?- fac1(5, X).
X = 120 .
因此,我们将第一个参数固定为fac1/2
的{{1}}谓词进行调用,然后Prolog会将5
统一为X
。
我们可以将谓词重写为:
120
我们还可以使main :- current_prolog_flag(argv,[BB_S,CC_S]),
atom_number(BB_S,BB),
atom_number(CC_S,CC),
fact1(BB, FB),
ABS is abs(BB - CC),
fact1(ABS, FA),
fact1(CC, FC),
Res is FB / (FA * FC),
write(Res).
更具声明性:现在,只有在第一个参数固定的情况下(或者第二个参数为fac1
的情况下,它才有效。此外,由于它未使用尾部调用优化(TCO),因此效率较低。我们可以使用1
库来改进谓词,并将其实现为:
clpfd
现在我们可以从多个方向查询阶乘关系:
:- use_module(library(clpfd)).
fac(0, 1).
fac(I, F) :-
I #> 0,
F #= I*F1,
I1 #= I-1,
fac(I1, F1).
因此,我们可以查询哪个?- fac(I, 120).
I = 5 ;
false.
?- fac(I, 130).
false.
?- fac(5, 120).
true ;
false.
?- fac(7, 120).
false.
?- fac(7, Y).
Y = 5040 ;
false.
,i
等于i!
,等等。
我们还可以通过在特定范围内实施产品来提高性能,因此:
120
所以 b
------
| |
| | i
i=a+1
基本上是:
prodrange(A,B,P):- fac(A,FA), fac(B,FB), P是FB / FA。
,但效率更高,因为它是 O(a + b),我们可以将其简化为 O(b-a),方法如下:
prodrange
或更声明性的:
prodrange(A, A, 1).
prodrange(A, B, P) :-
B > A,
B1 is B-1,
prodrange(A, B1, P1),
P is P1 * B1.
然后我们可以实现一个prodrange(A, A, 1).
prodrange(A, B, P) :-
B #> A,
P #= B*P1,
B1 #= B-1,
prodrange(A, B1, P1).
谓词来计算组合数:
comb/3
然后comb(BB, CC, Res) :-
MX is max(BB, CC),
MN is min(BB, CC),
prodrange(MN, MX, Num),
Abs is MX-MN,
fac(Abs, Den),
Res is Num / Den.
如下:
main