このディレクトリの索引
#  出題場所 :: http://toro.2ch.net/test/read.cgi/tech/1381909900/423
#  [1] 授業単元:C言語 
#  [2] 問題文(含コード&リンク): 
#  問題(戻り値がある場合の引数あり) 
#  円錐の半径rと高さhを入力し、円錐の体積を求めるプログラムを作りなさい。 
#  ただし、main関数で円錐の半径rと高さhの入力と計算された円錐の体積の表示を行い、 
#  円錐の体積の計算はtaisekiという関数で行うこと。 
#  また、円周率は3.14を使用すること。 
#  
#  ../test/read.cgi/tech/1381909900/422に続きます 
# 

'円錐の半径rと高さhを入力し、円錐の体積を求めるプログラムを作りなさい。
ただし、主述語で円錐の半径rと高さhの入力と計算された円錐の体積の表示を行い、
円錐の体積の計算は体積という述語で行うこと。
また、円周率は3.14を使用すること。' :-
        数を得る(円錐の半径r,_円錐の半径r),
        数を得る(円錐の高さh,_円錐の高さh),
        '円錐の体積の計算と表示は体積という述語で行うこと。
また、円周率は3.14を使用すること。'(_円錐の半径r,_円錐の高さh,_円錐の体積),
        writef('半径%t,高さ%t の円錐の体積は %t\n',[_円錐の半径r,_円錐の高さh,_円錐の体積]).

'円錐の体積の計算は体積という関数で行うこと。
また、円周率は3.14を使用すること。'(_円錐の半径r,_円錐の高さh,_円錐の体積) :-
        _円周率 = 3.14,
        体積(_円錐の半径r,_円錐の高さh,_円周率,_円錐の体積).

体積(_円錐の半径r,_円錐の高さh,_円周率,_円錐の体積) :-
        _円錐の体積 is _円周率 * _円錐の半径r * _円錐の半径r * _円錐の高さh / 3.


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

数を得る(Instream,_催促文ならび,_数を含む条件,_数ならび) :-
        list(_催促文ならび),
        findall(_数,(
                    member(_催促文,_催促文ならび),
                    数を得る(Instream,_催促文,_数を含む条件,_数)),
                _数ならび),!.
数を得る(Instream,_催促文,_数を含む条件,_数) :-
        催促文の出力(_催促文),
        get_line(Instream,Line),
        '診断: 数を得る'(Line,_数を含む条件,_数),!.
数を得る(Instream,_催促文,_数を含む条件,_数) :-
        数を得る(Instream,_催促文,_数を含む条件,_数).

催促文の出力('') :- !.
催促文の出力(_催促文) :-
        writef('%tを入力してください : ',[_催促文]).

'診断: 数を得る'(end_of_file,_,end_of_file) :- !.
'診断: 数を得る'('',_,_) :- !,fail.
'診断: 数を得る'(Line,_数を含む条件,_数) :-
        atom_to_term(Line,_数,_),
        number(_数),
        '診断: 数を含む条件'(_数,_数を含む条件),!.
'診断: 数を得る'(Line,_数を含む条件,_数) :-
        \+((atom_to_term(Line,_数,_),number(_数))),
        writef('入力された %t からは数が得られません。再入力をお願いします。\n',[Line]),!,
        fail.

'診断: 数を含む条件'(_数,_数を含む条件) :-
        number(_数),
        call(_数を含む条件),!.
'診断: 数を含む条件'(_数,_数を含む条件) :-
        writef('入力された %t は %t が偽となります。\n',[_数,_数を含む条件]),!,
        fail.

数を得る(_催促文,_数を含む条件,_数) :-
        数を得る(user_input,_催促文,_数を含む条件,_数).

数を得る(_催促文,_数) :-
        数を得る(user_input,_催促文,true,_数).

数を得る(_数) :-
        数を得る(user_input,'',true,_数).

n個の数を得る(_n,_催促文,_数ならび) :-
        length(_数ならび,_n),
        findall(_数,(
                    部分ならび(_数ならび,_,_,_何番目,_,_,_,L3),
                    writef('[%t/%t]番目の',[_何番目,_n]),
                    数を得る(_催促文,_数)),
                _数ならび).

一行読み込む(_行) :-
        get_line(_行).

get_line(Stream,X) :-
        get_char(Stream,C),
        get_line_1(Stream,C,Chars),
        atom_chars(X,Chars).

get_line_1(Stream,'\n',[]) :- !.
get_line_1(Stream,end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !.
get_line_1(Stream,C,[C|R]) :-
        get_char(Stream,C2),
        get_line_1(Stream,C2,R).


get_line(X) :-
        get_char(C),
        get_line_1(C,Chars),
        atom_chars(X,Chars).

get_line_1('\n',[]) :- !.
get_line_1(end_of_file,[e,n,d,'_',o,f,'_',f,i,l,e]) :- !.
get_line_1(C,[C|R]) :-
        get_char(C2),
        get_line_1(C2,R).

list([_|_]) :- !.
list([].