このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1274827528/955
#  [1] 授業単元:プログラミング  
#  [2] 問題文(含コード&リンク): 
#  以下のプログラムで、pointを昇順に並び替えるプログラムを作る。ソートの部分のみを書き換え、プログラムを作りなさい。  
#  http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10713.txt 
#  
# struct data {
# int car_num;
# char name[MAX_LEN];
# char cons[MAX_LEN];
# char nationality[MAX_LEN];
# int birth;
# double point;
# };
%
% ここでは単位節で定義された述語データベースの整列について考えよう。
%

f1(1,'Jenson Button','McLaren','British',1980,106).
f1(2,'Lewis Hamilton','McLaren','British',1985,109).
f1(3,'Michael Schumacher','Mercedes GP','German',1969,34).
f1(4,'Nico Rosberg','Mercedes GP','German',1985,74).
f1(5,'Sebastian Vettel','Red Bull','German',1987,90).
f1(6,'Mark Webber','Red Bull','Australian',1976,103).
f1(7,'Felipe Massa','Ferrari','Brazilian',1981,67).
f1(8,'Fernando Alonso','Ferrari','Spanish',1981,94).
f1(9,'Rubens Barrichello','Williams','Brazilian',1972,7).
f1(10,'Nico Hulkenberg','Williams','German',1987,1).
f1(11,'Robert Kubica','Renault','Polish',1984,73).
f1(12,'Vitaly Petrov','Renault','Russian',1984,6).
f1(14,'Adrian Sutil','Force India','German',1983,23).
f1(15,'Vitantonio Liuzzi','Force India','Italian',1981,12).
f1(16,'Sebastien Buemi','Toro Rosso','Swiss',1988,5).
f1(17,'Jaime Alguersuari','Toro Rosso','Spanish',1990,3).
f1(18,'Jarno Trulli','Lotus','Italian',1974,0).
f1(19,'Heikki Kovalainen','Lotus','Finnish',1981,0).
f1(20,'Karun Chandhok','HRT','Indian',1984,0).
f1(21,'Bruno Senna','HRT','Brazilian',1983,0).
f1(22,'Pedro de la Rosa','BMW Sauber','Spanish',1971,0).
f1(23,'Kamui Kobayashi','BMW Sauber','Japanese',1986,1).
f1(24,'Timo Glock','Virgin','German',1982,0).
f1(25,'Lucas di Grassi','Virgin','Brazilian',1984,0).

pointを昇順に並び替える(L) :-
        clause_sort([1],f1/6,L).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pointを昇順に並び替える(L) :-
        データ構造(f1,_データ構造ならび),
        list_nth(N,_データ構造ならび,[point|_]),
        length(_データ構造ならび,Len),
        length(L0,Len),
        P =.. [f1|L0],
        findall(L0,P,L1),
        findall([_point|L2],(
                    member(L2,L1),
                    list_nth(N,L2,_point)),
                L3),
        sort(L3,L4),
        findall(L5,member([_|L5],L4),L).

データ構造ならび(f1,[[car_num],[name],[cons],[nationality],[birth],[point]]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pointを昇順に並び替える(X) :-
        データ構造(f1,_データ構造ならび),
        list_nth(M,_データ構造ならび,[point|_]),
        length(_データ構造ならび,Len),
        clause_sort([M],f1/Len,X),

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clause_sort(_順ならび,_関数 / _引数,X) :-
    functor(_頭部,_関数,_引数),
    findall(U,(clause(_頭部,_本体) , clause_sort_1(_順ならび,_頭部,_本体,U)),L),
    sort(L,L2),
    clause_sort_2(L2,X),!.

clause_sort_1([],_頭部,_本体,[(_頭部 :- _本体)]) :- !.
clause_sort_1([_鍵位置|R1],_頭部,_本体,[A|R2]) :-
    arg(_鍵位置,_頭部,A),
    clause_sort_1(R1,_頭部,_本体,R2).

clause_sort_2([],[]) :-
    !.
clause_sort_2([L|R1],[_頭部|R2]) :-
    last(L,(_頭部 :- true)),
    clause_sort_2(R1,R2),
    !.
clause_sort_2([L|R1],[Q|R2]) :-
    last(L,Q),
    clause_sort_2(R1,R2),!.