Find the term with the lowest 2nd argument in the list using Prolog

I have a list like this:

L = [range(2,3), range(5,6), range(10,9), range(-2,-30), range(-5,-30)]

Now I need to make the term the range(-5,-30)first element of this list, because it is the term with the smallest Y, in case 2 members have the lowest Y, I will choose the one with the lowest X.

I do not know how to do this using Prolog, I tried something like:

find_n_make_first([F,S|T]) :-
 F =.. [_,Fx,Fy],
 S =.. [_,Sx,Sy],
 (   Sy<Fy ->
 find_n_make_first([S,F|T])
 ;   Fy<Sy ->
 find_n_make_first([F,S|T])
 ;   Fy = Sy ->
 (   Sx<Fx ->
 find_n_make_first([S,F|T])
 ;   Fx<Sx ->
 find_n_make_first([F,S|T])
 )
 ).

But it does not work.

+4
source share
1 answer

, , , . , . : " ". . :

?- list_sortedby2([range(2,3),range(10,9),range(-2,-30),range(-5,-30)], Us).
Us = [range(-5,-30),range(-2,-30),range(2,3),range(10,9)].

, !

:- use_module(library(lambda)).

list_sortedby2(Ts, Us) :-
   must_be_ground(Ts),
   maplist(\T^(A2+T)^arg(2,T,A2), Ts, A2Ts), % or map1(Ts, A2Ts)
   sort(A2Ts, A2Us),
   maplist(\ (_+U)^U^true, A2Us, Us).        % or map2(A2Us, Us)

must_be_ground(Ss) :-
   ( ground(Ss) -> true
   ; throw(error(instantiation_error,_))
   ).

maplist/3 & lambda; :

map1([], []).
map1([T|Ts], [A2+T|A2Ts]) :-
   arg(2, T, A2),
   map1(Ts, A2Ts).

map2([], []).
map2([_+U|A2Us], [U|Us]) :-
   map2(A2Us, Us).

- : arg(2, T, A2) ( T = range(_, A2) ), range/2. , list_sortedby2([f(1,2)], Us) , . ( , , , .)

+3

Source: https://habr.com/ru/post/1598663/


All Articles