このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1308749241/586
#  [1] 授業単元: プログラミング 
#  [2] 問題文(含コード&リンク): http://codepad.org/3dkRTmjJ 
#  
#  生徒の氏名と身長と体重を列挙したデータファイル wh-list.dat がある。
#  このデータを読み込んでBMI値を計算し、BMI値が大きいもの順に、その人の
#  BMI値および肥満か否かを列挙するプログラムkadai13-1.cを書きなさい。
#  ただし、wh-list.datに列挙される人数はプログラム開発時点では全く分から
#  ないものとする。
#  
#  ヒント:
#  ○何をしなければならないかを大まかに書き下してみよう。
#   1. ファイルのオープン(これに先立ってファイル名を取得する必要がある)
#   2. データ構造の用意(これにはファイルにかかれたデータ数を知る必要がありますね。どうやって知るべきか考えよう)
#   3.データの読み込み
#   4.BMIの算出
#   5. BMIの大きい者順に並べ替える(バブルソートを使おう。これが何者か知らない人は「バブルソート」で検索されたい)
#   6. 画面表示
#  
#  ○BMIとは?
#  BMIは次のようにして計算されるものとする。
#  BMI値=体重(キログラム)÷(身長(メートル))^2
#  '^2'は二乗を意味する。
#  このBMI値が25を越えると、肥満とみなされる。
#  
#  ○ファイルポインターがファイルの中間もしくは終わりをさしている時、これをファイルの先頭に戻す関数があります。
#  rewind(FILE *stream);
#  
#  ○wh-list.dat の中身は以下の通りで、氏名  身長(cm) 体重(kg)が列挙されている。
#  yamada  157  62.5
#  tanaka   180  45.1
#  yoneda   190  50.5
#  yamashita 210 80.5
#  toyama   140  80
#  ....
#  
#  ○例えば画面表示は
#  toyama BMI=40.816326 himan
#  nagashima BMI=29.551020 himan
#  yamashita BMI=27.777779 himan
#  takenaka BMI=27.716263 himan
#          .
#          中略
#          .
#  nakano BMI=23.179012
#  yamashita BMI=18.253969
#         .
#         .
#  
#  等と表示されるものとする。
#  

'生徒の氏名と身長と体重を列挙したデータファイル wh-list.dat がある。このデータを読み込んでBMI値を計算し、BMI値が大きいもの順に、その人のBMI値および肥満か否かを列挙する' :-
        user_parameters([_ファイル名]),
        'ファイルのオープン(これに先立ってファイル名を取得する必要がある)'(_ファイル名,Instream),
        データの読み込み(Instream,Lines),
        'BMIの算出と判定'(Lines,_BMIと判定ならび),
        'BMIの大きい者順に並べ替える'(_BMIと判定ならび,_降順に整列したBMIと判定ならび),
        画面表示(_降順に整列したBMIならび),!.

'ファイルのオープン(これに先立ってファイル名を取得する必要がある)'(_ファイル名,Instream) :-
        open(_ファイル名,read,Instream),!.

データの読み込み(Instream,Lines) :-
        get_lines(Instream,Lines),!.

'BMIの算出と判定'([],[]) :- !.
'BMIの算出と判定'([Line|R1],[[_BMI,_名前,_判定]|R2]) :-
        split(Line,[' '],[_名前,_身長単位センチメートル,_体重]),
        _身長単位メートル is _身長単位センチメートル / 100,
        'BMI値=体重(キログラム)÷(身長(メートル))^2'(_体重,_身長単位メートル,_BMI値),
        'BMI値が25を越えると、肥満とみなされる'(_BMI値,_判定),
        'BMIの算出と判定'(R1,R2).

'BMI値=体重(キログラム)÷(身長(メートル))^2'(_体重,_身長,_BMI値) :-
        _BMI値 is _体重 * _身長 ^ 2.

'BMI値が25を越えると、肥満とみなされる'(_BMI値,肥満) :-
        _BMI値 > 25,!.
'BMI値が25を越えると、肥満とみなされる'(_BMI値,'').

'BMIの大きい者順に並べ替える'(_BMIならび,_降順に整列したBMIならび) :-
        バブルソート(_BMIならび,_昇順に整列したBMIならび),
        reverse(_昇順に整列したBMIならび,_降順に整列したBMIならび).

バブルソート(_対象ならび,_整列済みならび) :-
    交換(_対象ならび,_対象ならびの一),
    !,
    バブルソート(_対象ならびの一,_整列済みならび).
バブルソート(_整列済みならび,_整列済みならび).

交換([],[]) :- !,fail.
交換([A,B|R],[B,A|R]) :-
        A @> B,!.
交換([A|R1],[A|R2]) :-
        交換(R1,R2).

画面表示(_降順に整列したBMIならび) :-
        append(_,[[_BMI,_名前,_判定]|R],_降順に整列したBMIならび),
        writef('%t  %t  %t\n',[_名前,_BMI,_判定]),
        R = [].