Search code examples
prologsicstus-prolog

Setting order method in Sicstus prolog Samsort


I am trying to sort a list of lists such as Books=[[5,1,science,24,3,2018],[6,1,math,24,3,2019],[4,2,science,24,5,2019],[6,2,science,23,3,2019],[3,1,math,24,3,2020]]. I want to order this list based on the 5th value of each element. I tried to use

samsort(sortDateBooks, Books, Output).
sortDateBooks(Book1,Book2):-nth0(5,Book1, Date1),nth0(5,Book2, Date2), Date1<Date2.

The output variable is never filled with data and the original list is also not changed.

I feel that I am not declaring de order predicate properly but can't find any examples.

Thank you for your help.


Solution

  • I am not sure if this is what you want to do, if yes, then this may give you some hints:

    1. Here collect dates will act as findall. It will search for all the years and put them in a list e.g. [2019,2018,2019,2019,2020].

    2. sortBook(Sorted) predicate first finds all the Years using collectdates predicate, then sorts them. Notice that in sort I've used @=<, this will not remove any repeated values. You will get [2018,2019,2019,2019,2020].

    3. s predicate simply takes each year, searches for the information and puts it in a List.

    s predicate will take each year and check through each book, so this may lead to extras. append is used to decrease extra brackets, set predicate simply removes duplicates if any.

    sortBook(Sorted):-
        Book=[[6,2,science,23,3,2019],[5,1,science,24,3,2018],[6,1,math,24,3,2019],[4,2,science,24,5,2019]
               ,[3,1,math,24,3,2020]],
        collectdates(Book,Clist),
        sort(0, @=<, Clist,  SList),
        s(SList,Book,Sorted1),append(Sorted1,Sorted2),set(Sorted2,Sorted).
        
     collectdates([],[]).   
     collectdates([H|T],[Last|List]):-
        last(H,Last),
        collectdates(T,List).
    
    s([],_,[]).
    s([H|T],[B|L],[W|List]):-
        sortBook1(H,[B|L],W),
        s(T,[B|L],List).
    sortBook1(_,[],[]).
    sortBook1(H,[B|L],[B|List]):-
        member(H,B),
        sortBook1(H,L,List).
    sortBook1(H,[B|L],List):-
        \+member(H,B),
        sortBook1(H,L,List).
    
    set([],[]).
    set([H|T],[H|T2]):-
        subtract(T,[H],T3),
        set(T3,T2). 
    

    Example:

    ?-sortBook(Sorted).
    Sorted = [[5, 1, science, 24, 3, 2018], [6, 2, science, 23, 3, 2019], [6, 1, math, 24, 3, 2019], [4, 2, science, 24, 5, 2019], [3, 1, math, 24, 3, 2020]]
    false