このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1308749241/549
#  [1] 授業単元:演習 
#  [2] 問題文(含コード&リンク):http://pastebin.com/index/sg6akdN0 
#  標準入力から「id, 名前, 年月日, 住所」のようなコンマ区切形式 (CSV 形式) の名簿データを受け付けて, 
#  項目を切り出してメモリ中に格納する.また,% で始まる入力行をコマンド入力として解釈し,格納されたデータを表示や整列する 
#  

'標準入力から「id, 名前, 年月日, 住所」のようなコンマ区切形式 (CSV 形式) の名簿データを受け付けて,項目を切り出してメモリ中に格納する.また,% で始まる入力行をコマンド入力として解釈し,格納されたデータを表示や整列する' :-
        get_line(Line),
        テキストの解析処理(Line,1,[]).

テキストの解析処理(end_of_file,N,_オプションモード) :-
        \+member(整列,_オプションモード)),!.
テキストの解析処理(end_of_file,N,_オプションモード) :-
        member(整列,_オプションモード),
        名簿データをならびに変換(LL1),
        sort(LL1,LL2),
        整列した名簿の表示(LL2),!.

テキストの解析処理(_行,N,_オプションモード) :-
        コメント行(_行,_オプションモード,_オプションモードのニ),
        get_line(_行2),
        テキストの解析処理(_行2,N,_オプションモードのニ),!.
テキストの解析処理(_行,N,_オプションモード) :-
        'CSV行'(_行,_オプションモード),
        get_line(_行2),
        N2 is N + 1,
        テキストの解析処理(_行2,N2,_オプションモード).

コメント行(_行,_オプションモード,_オプションモードのニ) :-
        sub_atom(_行,0,1,R,'%'),
        sub_atom(_行,1,R,0,_残り文字列),
        split(_残り文字列,[' ',','],L),
        コメント行解析(L,_オプションモード,_オプションモードのニ).

'CSV行'(_行,N,_オプションモード) :-
        member(表示,_オプションモード),
        writef('%t: %t\n',[N,_行]),
        split(_行,[','],[_id,_名前,_年月日,_住所]),
        assertz(名簿データ(_id,_名前,_年月日,_住所)),
        writef('%q\n',[名簿データ(_id,_名前,_年月日,_住所)]),!.
'CSV行'(_行,N,_オプションモード) :-
        \+(member(表示,_オプションモード)),
        split(_行,[','],[_id,_名前,_年月日,_住所]),
        assertz(名簿データ(_id,_名前,_年月日,_住所)),!.

コメント行解析([],_オプションモード,_オプションモード) :- !.
コメント行解析([非表示|R],_オプションモード,_オプションモードのニ) :-
        ならびから削除(表示,_オプションモード,_オプションモードの一),
        コメント行解析(R,_オプションモードの一,_オプションモードのニ),!.
コメント行解析([_コマンド|R],_オプションモード,_オプションモードのニ) :-
        \+(member(_コマンド|_オプションモード)),
        コメント行解析(R,[_コマンド|_オプションモード],_オプションモードのニ).
コメント行解析([_コマンド|R],_オプションモード,_オプションモードのニ) :-
        member(_コマンド|_オプションモード),
        コメント行解析(R,_オプションモード,_オプションモードのニ).

名簿データをならびに変換(LL) :-
        findall([_id,_名前,_年月日,_住所],(
                    名簿データ(_id,_名前,_年月日,_住所)),
                LL),!.

整列した名簿の表示(LL) :-
        append(_,[L|R],LL),
        writef('%t,%t,%t,%t\n',L),
        R = [].