Thursday, November 22, 2012

The hunt for a generic sort

WikiCFP is quite useful for collecting together information about conferences you may be interested in submitting to. It even has a nice google calendar view, where you can see the deadlines of your selected conferences coming up. However, you may need to have additional information about each conference, so it's conceivable that a small database may be a good idea here.

We will use Prolog as our database engine, not only because we absolutely love it, but because XSB offers a very generic sorting routine, called parsort/4:


parsort(+L1, +SortSpec, +ElimDupl, ?L2)
  - L1 is the list we want to sort
  - SortSpec is a sorting specification; can be asc(I) or dsc(I), where I is an argument number. So asc(1) means sort in ascending order with respect to the first argument of the terms in List, desc(3) means sort in descending order with respect to the third argument of the terms in List e.t.c.
  - if ElimDupl is non-zero, then the duplicate elimination is performed before returning the output, and if it's zero duplicate elimination is not performed
  - L2 is the variable that holds the final result.

Okay, so let's start with defining our facts. We will use a separate source file that will contain information about the conferences that we are interested in, stored as Prolog facts of the form

conf(ShortName,FullName,Dates,Deadline,Website).

The first thing we need is a prediate that will take as input a list of conf/5 facts and print out their contents in a pretty way:


print_list(PD,PW,[pconf(Name,Descr,When,Deadline,Web)|Confs]) :-
        write(Name),
        atom_length(Name,NLen), T1 is 10 - NLen, tab(T1),
        ( PD == 1
        -> write(Descr), atom_length(Descr,DLen), T2 is 80 - DLen, tab(T2)
        ; true
        ),
        write(When), atom_length(When,WLen), T3 is 20 - WLen, tab(T3),
        write_deadline(Deadline), tab(2),
        ( PW == 1
        -> write(Web), atom_length(Web,WeLen), T5 is 20 - WeLen, tab(T5)
        ; true
        ),
        nl,
        print_list(PD,PW,Confs),
        fail.

I call the technique used here "print-by-failure"; the call to "fail" in the end of the definition of print_list/3 ensures that things will continue to get printed out until the list is empty. Deadlines are represented by terms of the form deadline(Month,Day,Year). We want to print out information just for the conferences for which the deadline hasn't passed yet, so the following predicate is also useful:



before(today(M,D1,Y),deadline(M,D,Y)) :-
        D1 < D, !.
before(today(M1,_D1,Y),deadline(M,_D,Y)) :-
        M1 < M, !.
before(today(_M1,_D1,Y1),deadline(_M,_D,Y)) :-
        Y1 < Y.

And last but not least, the predicate that will generate a list containing the information needed from the conf/5 facts, print out a nice table and then call print_list/3 to do the rest:



show_confs(PD,PW) :-
        findall(pconf(Name,Descr,When,deadline(M,D,Y),Web),
                ( conf(Name,Descr,When,deadline(M,D,Y),Web), datime(datime(Y1,M1,D1,_,_,_)), 
                  before(today(M1,D1,Y1),deadline(M,D,Y)) ),
                List),
        write('Name'), tab(6), %10
        ( PD == 1
        -> write('Description'), tab(69) % 80
        ; true
        ),
        write('Date'), tab(16), % 20
        write('Deadline'), tab(8), % 16
        ( PW == 1
        -> write('Web'), tab(17) % 20
        ; true
        ),nl,
        writeln('------------------------------------------------------------------------------------------------------------------------------------------------------'),
        parsort(List,[asc(4)],1,SList),
        print_list(PD,PW,SList).

The nice thing with parsort/4 is that we can change the way our output will look like without any change to the sorting routine at all! The only thing we need is a different specification of the sorting specifications. Here, for example, I want to sort in ascending order with respect to the deadline of each conference, which is pretty handy. Try to do all this with 50 lines of C code... :)

No comments:

Post a Comment