このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1260532772/2
#  [1] 授業単元: プログラミング演習 
#  [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10259.txt 
#  
# ●基本課題 1a (2分木データの生成と表示) 
# 2分木の節を格納するためのデータ構造(Tree 型)を,次のように定義する. 
# 
#       typedef struct _tree { 
#         char           node;          /* 節のデータ (1文字) */ 
#         struct _tree  *left;          /* 左の子へのポインタ */ 
#         struct _tree  *right;         /* 右の子へのポインタ */ 
#       } Tree; 
# 
# 2分木の枝と葉のデータを生成するための次の2つの関数を作れ. 
# 
#       Tree *branch(char x, Tree *l, Tree *r); 
#               節を格納する記憶領域を確保 
#               節を初期化(節データを x,左右の子へのポインタを l, r に設定) 
#               生成した Tree 型データへのポインタを戻り値として返す 
# 
#       Tree *leaf(char x); 
#               節を格納する記憶領域を確保 
#               節を初期化(節データを x,左右の子へのポインタを NULL に設定) 
#               生成した Tree 型データへのポインタを戻り値として返す 
# 関数 branch() と leaf() を使って,算術式を表す2分木のデータを生成し, 
# 各2分木の根へのポインタを,Tree * 型の変数に格納せよ. 
# ●基本課題 1b (2分木を扱う再帰関数の作成) 
# 
# 2分木の「高さ」を求める関数 height() を作れ. 
# また,十分な数の検査データを作り,動作の正しさを検証せよ. 

branch(X,TreeL,TreeR,Tree,L1,L2) :-
    get_node_no(No),
    assertz('Tree'(No,X,TreeL,TreeR)),
    L2 = [No|L1].

leaf(X,Tree,L1,L2) :-
    get_node_no(No),
    assertz('Tree'(No,X,[],[])),
    L2 = [No|L1].

算術式二分木の生成(_算術式,Tree) :-
    retract('Tree'(_)),
    算術式の開始点(_開始点),
    算術式二分木(_算術式,Tree,[],L2),
    asserta('Tree'(Tree)).
    
算術式二分木(Atom,Tree,L1,L2) :-
    atom(Atom),
    leaf(Atom,Tree,L1,L2),!.
算術式二分木((_式1,_式2),Tree,L1,L4) :-
    算術式二分木(_式1,Tree1,L1,L2),
    算術式二分木(_式2,tree2,L2,L3),
    branch(',',Tree1,Tree2,Tree,L3,L4),!.
算術式二分木(_式,Tree,L1,L4) :-
    function(_式,_関数,2),
    arg(1,_式,_式1),
    arg(2,_式,_式2),
    算術式二分木(_式1,Tree1,L1,L2),
    算術式二分木(_式2,Tree2,L2,L3),),
    branch(_関数,Tree1,Tree2,Tree,L3,L4),!.

get_node_no(L,No) :-
    repeat,
    No is randam mod 3711219,
    \+(member(No,L)),!.