简体   繁体   中英

Arithmetic on Two Lists Prolog

So I have a HW problem I've been working on for a couple days and I'm stuck on the last part. In Prolog, I'm supposed to write a function that takes in two lists ((x1, x2, …, xn), (y1, y2, …yn) ) and finds the distance between both. The output is the result of the math done on the list. Formula: sqrt((x1-y1) (x1-y1) + (x2-y2) (x2-y2) + … + (xn-yn)*(xn-yn)) Here's what I have so far:

distance([],[], 0).
distance([Ha|Ta],[Hb|Tb], Sum) :-
   distance(Ta,Tb, Rest),
   Sum is sqrt( (Ha-Hb)*(Ha-Hb)) + Rest.

It is quite near. Off the top of my head, just sum the squares ( distance_aux ) and then return the square root of the accumulated sum:

distance(L1, L2, D) :-
        distance_aux(L1, L2, SQSUM),
        D is sqrt(SQSUM).

distance_aux([],[],0).
distance_aux([Ha|Ta],[Hb|Tb], Sum) :-
   distance_aux(Ta,Tb, Rest),
   Sum is (Ha-Hb)*(Ha-Hb) + Rest.

You can also add the simplified rule distance([], [], 0). , although it is not necessary.

Prolog has lists , not arrays.

Your code doesn't implement the formula shown, because sqrt must be computed after the sum of products. In the code below, I introduce also an accumulator, making the loop tail recursive (more efficient).

distance(Xs, Ys, Dist) :-
  distance(Xs, Ys, 0, Dist).

distance([], [], Acc, Dist) :- 
    Dist is sqrt(Acc).
distance([X|Xs], [Y|Ys], Acc, Dist) :-
    Sum is (Y-X)*(Y-X) + Acc,
    distance(Xs, Ys, Sum, Dist).

Depending on your Prolog library, the code could be simpler:

distance(Xs, Ys, Dist) :-
    foldl(distpoint, Xs, Ys, 0, Sq),
    Dist is sqrt(Sq).
distpoint(X, Y, S, D) :- D is S+(Y-X)*(Y-X).

The formula you have given squares the entire summation, rather than squaring each individual couple - which is what you are doing in your code. Using an auxiliary solves that issue:

distance_sum([], [], 0).
distance_sum([Ha|Ta], [Hb|Tb], Sum) :-
   distance_sum(Ta, Tb, Rest),
   Sum is ((Ha-Hb) * (Ha-Hb)) + Rest.

distance(A, B, Sum) :- distance_sum(A, B, DSum), Sum is sqrt(DSum).

So an example would be:

distance([1,2,3], [4,5,6], Sum).
Sum = 5.196152422706632.

Working:

sqrt( (1-4)*(1-4) + (2-5)*(2-5) + (3-6)*(3-6) )
sqrt( 3*3 + 3*3 + 3*3 )
sqrt( 27 )
5.19615

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM