Search code examples
listprologarea

Calculate Area Tangent Circumferences - Prolog


I have the following function that calculates an area.

It receives three parameters, the first is an n representing the number of cases, the 2nd representing the radio of circumferences, and the 3rd is l giving me back the result.

The problem I have is that when the 1st input is greater than 1 it does not work.

This my code:

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).     

An example of how it should work is:

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

If you could help me, I would be grateful ...


Solution

  • Is there a reason this version isn't sufficient to your needs?

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

    Or maybe this?

    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. I don't understand why you need to worry about N at all.
    2. Matching both N and [X] leads to redundancy. You shouldn't have to repeat your formula.
    3. You have a lot of singleton errors: _T in the head, and then T in the body which will not work.
    4. You are passing N1-1 to the recursive call, which will not cause it to be evaluated—but you already evaluated N-1 in the previous expression, so just pass N1 here. Again, I don't see the point of this at all.
    5. I think it's a good idea to use succ(N1, N) instead of adding or subtracting one, because it works in both directions (not relevant here, of course).
    6. It feels a bit icky to be combining the list traversal with the calculation to me. I would in general break things down so that the calculation is separate from the data structure insofar as that can be done. This is a universal maxim of programming.