このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1322562648/17
#  前スレの未解決問題。(ほかにあったら転記してね) 
#  979 :デフォルトの名無しさん:2011/11/29(火) 21:17:42.06 
#      [1] 授業単元:コマンドライン引数 
#      [2] 問題文(含コード&リンク): 
#      コマンドライン引数を用いて,以下の計算ができる簡易電卓プログラムを作成せよ. 
#      1. 2 〜5項式までの四則演算(計算順もちゃんと考慮すること) 
#      (出力例)C :¥Programming>dentaku 2 + 5 / 5 + 4 * 2 + 1 
#      答えは 12 
#   
#      C :¥Programming>dentaku 2 * 3 + 1 
#      答えは 7 
#   
#      2.()を用いた演算(かっこの中の計算を最優先する) 
#      (出力例)C :¥Programming>dentaku ( 2 + 3 ) * 7 * ( 3 - 1 ) 
#      答えは 70 
#   
#      3. (sin, cos, tan)の演算 
#      (出力例)C :¥Programming>dentaku sin(90) * 2 + 1 - 2 
#      答えは 1 
#   
#      4.logの演算 
#      (出力例)C :¥Programming>dentaku log(3) * 2 + 1 
#      答えは 1.9542425094 
#   
#      5. 半角スペースを入れ忘れても演算可能 
#      (出力例)C :¥Programming>dentaku 1-2*(3+1)-2 
#      答えは 9 
#      

電卓 :-
        式の入力(Line),
        項に分解(Line,_項ならび),
        '1. 2 〜5項式までの四則演算'(_項ならび,X),
        writef('%12r\n',[X]).

式の入力(Line) :-
        writef('%12r\n',[0]),
        get_line(Line),!.

項に分解(Line,_項ならび) :-
        atom_chars(Line,Chars),
        一旦空白要素を除去する(Chars,Chars2),
        '先頭の符号に注意して、演算子の前後に空白を入れる'(Chars2,Chars3),
        atom_chars(Line2,Chars3),
        split(Line2,[' '],_項ならび).

一旦空白要素を除去する([],[]) :- !.
一旦空白要素を除去する([' '|R1],R2) :-
        一旦空白要素を除去する(R1,R2),!.
一旦空白要素を除去する([A|R1],[A|R2]) :-
        一旦空白要素を除去する(R1,R2).

'先頭の符号に注意して、演算子の前後に空白を入れる'([-,A|R1],[-,A|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
'先頭の符号に注意して、演算子の前後に空白を入れる'(L1,L2) :-
        演算子の前後に空白を入れる(L1,L2),!.

演算子の前後に空白を入れる([],[]),!.
演算子の前後に空白を入れる(['+','-'|R1],[' ','+',' ','-'|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['-','-'|R1],[' ','-',' ','-'|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['*','-'|R1],[' ','*',' ','-'|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['/','-'|R1],[' ','/',' ','-'|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['+'|R1],[' ','+',' '|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['-'|R1],[' ','-',' '|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['*'|R1],[' ','*',' '|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる(['/'|R1],[' ','/',' '|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.
演算子の前後に空白を入れる([A|R1],[A|R2]) :-
        演算子の前後に空白を入れる(R1,R2),!.

'1. 2 〜5項式までの四則演算'(_項ならび,X) :-
        '+,-でグループ化する'(_項ならび,_項ならびの一),
        '要素の四則演算'(_項ならびの一,X).

'+,-でグループ化する'(L,[L0,A|R2]) :-
        append(L0,[A|R],L),
        '+か-'(A),
        '+,-でグループ化する'(R,R2),!.
'+,-でグループ化する'(L,[L]).

'+か-'(+).
'+か-'(-).

'要素の四則演算'([L],X) :-
        ならび評価(L,X),!.
'要素の四則演算'([L1,'+'|R1],X) :-
        ならび評価(L1,A),
        '要素の四則演算'(R1,Y),
        X is A + Y.
'要素の四則演算'([L1,'-',L2|R1],[C|R2]) :-
        ならび評価(L1,A),
        '要素の四則演算'(R1,Y),
        X is A - Y.

ならび評価([A],A) :- !.
ならび評価([A,'*'|R1],X) :-
        ならび評価(R1,Y),
        X is A * Y.
ならび評価([A,'/'|R1],X) :-
        ならび評価(R1,Y),
        X is A // Y.