このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1295800051/32
#  部品工場のDB設計で、いくつかの部品テーブルがあったとする。 
#  部品はいくつかの工程を経て製品になり、製品テーブルに新たな製品が登録される。 
#  そのとき部品テーブルから使われた部品は削除されなければいけない。 
#   
#  こういう時、部品の削除処理はモデルクラスとコントローラーどちらに書く? 
#  コントローラーで明示的に部品の削除を行うか、 
#  暗黙的にモデルクラス(製品クラス)でsave()するときに使った部品を全て部品テーブルから削除するか。 
#   
#  RDBのテーブルとO/Rマッピングされたクラスがある状況の話。 
# 
# 

部品はいくつかの工程を経て製品になり、製品テーブルに新たな製品が登録される(_新たな製品) :-
        必要部品の情報を集める(_必要製品・部品ならび),
        必要複合部品の調達(_必要複合部品・部品ならび,_調達複合部品ならび,_不足複合部品ならび),
        必要部品の調達(_必要複合部品・部品ならび,_調達部品ならび,_不足部品ならび),
        不足製品・部品がない(_不足部品ならび),
        製品の制作・完成(_調達複合部品ならび,_調達部品ならび),
        部品・製品テーブルから削除(製品(_新たな製品,_在庫数量)),
        _追加された数量 is _在庫数量 + 1,
        asserta(製品(_新たな製品,_追加された数量)),!.

製品・複合部品をN個作成する(_N個,_製品) :-
        length(Ln,_N個),
        製品・複合部品をLn個作成する(Ln,_製品,_充足部品ならび,_不足部品ならび).

製品・複合部品をLn個作成する([],_) :- !.
製品・複合部品をLn個作成する([_|Ln],_製品) :-
        部品はいくつかの工程を経て製品になり、製品テーブルに新たな製品が登録される(_製品),
        製品・複合部品をLn個作成する(Ln,_製品).

必要複合部品の情報を集める(_製品,_必要複合部品ならび) :-
        findall(_複合部品,
                    必要部品(_製品,_複合部品)),
                _必要複合部品ならび).

必要部品の情報を集める(_製品,_必要部品ならび) :-
        findall(_部品,
                    必要部品(_製品,_製品)),
                _必要部品ならび).

必要複合部品の調達([],[],[]) :- !.
必要複合部品の調達([[_複合部品,_数量]|R1],[[_複合部品,_充足数量]|R2],R3) :-
        部品・複合部品(複合部品,_複合部品,N),
        N >= _数量,
        部品・複合部品テーブルの更新(_複合部品,_必要数量,_充足数量,_不足数量),
        必要複合部品の調達(R1,R2,R3),!.
必要複合部品の調達([[__複合部品,_必要数量]|R1],[[_複合部品,_充足数量]|R2],[[_複合部品|_不足数量]|R3]) :-
        部品・複合部品(複合部品,_複合部品,N),
        N < _必要数量,
        _不足個数 is _必要数量 - N,
        製品・複合部品をN個作成する(_不足個数,_複合部品),
        部品・複合部品テーブルの更新(_複合部品,_必要数量,_充足数量,_不足数量),
        必要複合部品の調達(R1,R2,R3),!.

必要部品の調達([],[],[]) :- !.
必要部品の調達([[_部品,_数量]|R1],[[_部品,_充足数量]|R2],R3) :-
        部品・複合部品(部品,_部品,N),
        N >= _数量,
        部品・複合部品テーブルの更新(_部品,_必要数量,_充足数量,_不足数量),
        必要部品の調達(R1,R2,R3),!.
必要部品の調達([[_部品,_必要数量]|R1],[[_部品,_充足数量]|R2],[[_部品|_不足数量]|R3]) :-
        部品・複合部品(部品,_部品,N),
        N < _必要数量,
        _不足個数 is _必要数量 - N,
        部品・複合部品テーブルの更新(_部品,_必要数量,_充足数量,_不足数量),
        必要部品の調達(R1,R2,R3),!.

部品・複合部品テーブルの更新(_部品,_必要数量,_充足数量,_不足数量) :-
        部品・複合部品テーブルから削除(部品・複合部品(_複合部品または部品,_部品,_充足数量)),
        _充足数量 < _必要数量,
        _不足数量 is _必要数量 - _充足数量,
        asserta(部品・複合部品(_複合部品または部品,_部品,N_1)),!.
部品・複合部品テーブルの更新(_部品,_必要数量,_必要数量,0) :-
        部品・複合部品テーブルから削除(部品・複合部品(_複合部品または部品,_部品,_在庫数量)),
        _在庫数量 >= _必要数量,
        _在庫残数量 is _在庫数量 - _必要数量,
        asserta(部品・複合部品(_複合部品または部品,_部品,_在庫残数量)),!.

部品・複合部品テーブルから削除(_複合部品または部品,_部品,_在庫数量) :-
        retract(部品・複合部品(_複合部品または部品,_部品,_在庫数量)),!.
部品・複合部品テーブルから削除(_複合部品または部品,_部品,0) :-
        asserta(部品・複合部品(_複合部品または部品,_部品,0)).

製品の制作・完成(_調達複合部品ならび,_調達部品ならび) :- true.