递归程序,用于计算在Prolog中不起作用的余弦的Taylor近似值 [英] Recursive program to compute Taylor approx of cosine not functioning in Prolog

查看:105
本文介绍了递归程序,用于计算在Prolog中不起作用的余弦的Taylor近似值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还是Prolog的新手,我不确定为什么此代码无法正常工作.我认为,基本情况或递归情况的最后3行都可能出现问题.其他一切都很好.

I'm still pretty new to Prolog, and i'm not sure why this code isn't working. I believe it is most likely a problem with the base case or in the last 3 lines of the recursive case. Everything else works just fine.

该程序确定通过序列近似计算的余弦值

要这样做,它需要计算2K的阶乘,也就是-1 ^ K,然后在最终方程式中使用这两个计算(在%递归情况下完成).

to do so it needs to calculate the factorial of 2K, also -1 ^ K, and then uses these 2 calculations in the final equation (this is done in % Recursive Case).

% Factorial from class
fact(0, 1).
fact(N, F) :- 
    N > 0,
    N1 is N-1,
    fact(N1, F1),
    F is F1 * N.

% Calculate -1 ^ K
signCnt(0,1).
signCnt(K,S) :- 
    K > 0,
    K1 is K - 1,
    signCnt(K1,S1),
    S is S1 * -1.

% Base case
cosN(N,_,_,0).

% Recursive case
cosN(K,N,X,Y) :- K < N,
    signCnt(K,S),
    K2 is 2 * K,
    fact(K2,F),
    Yk is (S * X**K2)/F,
    K1 is K + 1,
    cosN(K1,N,X,Y1),
    Y is Y1 + Yk.

cosN(N,X,Y) :- 
    N>0,
    cosN(0,N,X,Y).

输入应采用

?- cosN(25,pi,Y).

,预期输出为

Y = -1.0 ;
false.

但是,它无法正确进行递归,并且输出最终看起来像这样:

however, it doesn't go through the recursion properly and the output ends up looking like this:

其中5pi可以是任何东西,只要pi保持为pi形式(即pi/2,pi/3),也就不应该添加任何其他行,因为我们得到了一行数量限制.行应被编辑/替换.任何指向我正确方向的事情也将不胜感激.

where 5 and pi could be anything so long as pi remains in form pi (i.e. pi/2, pi/3), also there shouldn't be any additional lines added, as we were given a line number restriction. Lines should be edited/replaced. Anything to point me in the right direction would be greatly appreciated too.

(感谢Guy Coder进行帮助格式化)

(Thank you to Guy Coder for help formatting)

由Guy Coder编辑

Edit by Guy Coder

使用SWI-Prolog的一些测试用例

Some test cases using SWI-Prolog

:- begin_tests(cosine_approximation).

factorial_test_case_generator(0,1).
factorial_test_case_generator(1,1).
factorial_test_case_generator(2,2).
factorial_test_case_generator(3,6).
factorial_test_case_generator(4,24).
factorial_test_case_generator(5,120).
factorial_test_case_generator(6,720).
factorial_test_case_generator(7,5040).
factorial_test_case_generator(8,40320).
factorial_test_case_generator(20,2432902008176640000).

test('factorial',[nondet,forall(factorial_test_case_generator(N,Factorial))]) :-
    fact(N,Factorial).

signCnt_test_case_generator(0,1).
signCnt_test_case_generator(1,-1).
signCnt_test_case_generator(2,1).
signCnt_test_case_generator(3,-1).
signCnt_test_case_generator(4,1).
signCnt_test_case_generator(5,-1).

test('signCnt',[nondet,forall(signCnt_test_case_generator(N,Sign))]) :-
    signCnt(N,Sign).

:- end_tests(cosine_approximation).

示例运行:

?- make.
% c:/users/eric/documents/projects/prolog/so_question_161 compiled 0.00 sec, 5 clauses
% PL-Unit: cosine_approximation .......... done
% All 10 tests passed
true.

推荐答案

基本情况是错误的,应该是cosN(N,N,_,0).因为在程序完成递归过程后,K和N必须都等于N.

Base case was wrong, should've been cosN(N,N,_,0). as K and N must both be equal to N when the program is finished the recursive process.

测试用例:

:- begin_tests(cosine_approximation).

factorial_test_case_generator(0,1).
factorial_test_case_generator(1,1).
factorial_test_case_generator(2,2).
factorial_test_case_generator(3,6).
factorial_test_case_generator(4,24).
factorial_test_case_generator(5,120).
factorial_test_case_generator(6,720).
factorial_test_case_generator(7,5040).
factorial_test_case_generator(8,40320).
factorial_test_case_generator(20,2432902008176640000).

test('factorial',[nondet,forall(factorial_test_case_generator(N,Factorial))]) :-
    fact(N,Factorial).

signCnt_test_case_generator(0,1).
signCnt_test_case_generator(1,-1).
signCnt_test_case_generator(2,1).
signCnt_test_case_generator(3,-1).
signCnt_test_case_generator(4,1).
signCnt_test_case_generator(5,-1).

test('signCnt',[nondet,forall(signCnt_test_case_generator(N,Sign))]) :-
    signCnt(N,Sign).

cosN_test_case_generator(3,pi/2,0.01996895776487828).
cosN_test_case_generator(5,pi,-0.9760222126236076).
cosN_test_case_generator(25,pi,-1.0).
cosN_test_case_generator(10,pi/2,-3.3306690738754696e-15).

test('cosN',[nondet,forall(cosN_test_case_generator(N,X,Y))]) :-
    cosN(N,X,Y).

:- end_tests(cosine_approximation).

示例运行:

?- make.
% /Users/oliverclarke/prolog/lab5-quiz compiled 0.00 sec, 3 clauses
% PL-Unit: cosine_approximation .................... done
% All 20 tests passed
true.

这篇关于递归程序,用于计算在Prolog中不起作用的余弦的Taylor近似值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆