计算面积切线圆周 - Prolog

Calculate Area Tangent Circumferences - Prolog

我有以下计算面积的函数。

它接收三个参数,第一个是n代表例数,第二个代表圆周率,第三个是l给我返回结果。

我遇到的问题是,当第一个输入大于 1 时,它不起作用。

这是我的代码:

as(1, [X], A) :-
   A is (sqrt(3.0) * (X*X)) - (3.14 * (X*X))/2.
as(N, [H|_T], A) :-
   A is (sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2,
   N1 is N-1,
   as(N1-1, T, A).     

它应该如何工作的一个例子是:

?- as(4, [1,1,1,1], R).
R = 0.162050807568877130000 ;
R = 0.162050807568877130000 ;
R = 0.162050807568877130000 ;
R = 0.162050807568877130000.

如果你能帮助我,我将不胜感激...

此版本不能满足您的需求是否有原因?

as([H|_], A):- 
  A is (sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2.
as([_|T], A) :- as(T, A).

或者这个?

area(H, Area) :- 
  Area is (sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2.
as(List, Area) :- member(Ratio, List), area(Ratio, Area).
  1. 我完全不明白你为什么需要担心 N
  2. 同时匹配 N[X] 会导致冗余。您不必重复您的公式。
  3. 你有很多单例错误:头部 _T,然后 body 中的 T 将不起作用。
  4. 您正在将 N1-1 传递给递归调用,这不会导致对其求值——但您已经在前一个表达式中求值 N-1,因此只需在此处传递 N1 .同样,我根本不明白这有什么意义。
  5. 我认为使用 succ(N1, N) 而不是加一或减一是个好主意,因为它在两个方向上都有效(当然这里不相关)。
  6. 把列表遍历和计算结合起来对我来说有点恶心。我通常会将事情分解,以便在可以完成的范围内将计算与数据结构分开。这是编程的普遍准则。

既然你想计算每次测量的面积,那么得到一个与无线电测量列表相对应的区域列表不是很合适吗?您的谓词 as/3 的结构似乎表明您正在按照这些思路进行思考。您可以使用 maplist/3:

轻松实现
:- use_module(library(apply)).   % needed for maplist

% a single measurement and the corresponding area
area(X, A) :-
   A is (sqrt(3.0) * (X*X)) - (3.14 * (X*X))/2.

areas(Xs,As) :-
   maplist(area,Xs,As).          % area/2 mapped to Xs results in As 

查询此谓词会产生所需的结果,但在列表中:

?- areas([1,1,5,3],As).
As = [0.16205080756887713, 0.16205080756887713, 4.051270189221931, 1.4584572681198935].