このディレクトリの索引
http://toro.2ch.net/test/read.cgi/db/1316769778/319
#  tbl_rosen (駅名と備考は1:1) 
#  路線名  駅名  備考 
#  ---------------------- 
#  A線   i駅   備考1 
#  A線   j駅   備考2 
#  A線   k駅   備考3 
#  B線   k駅   備考3 
#  B線   l駅   備考4 
#  B線   m駅   備考5 
#  C線   n駅   備考6 
#  D線   k駅   備考3 
#  D線   o駅   備考7 
#   
#  tbl_shop 
#  店名  最寄駅 
#  --------------- 
#  X店   j駅 
#  X店   m駅 
#  X店   o駅 
#  Y店   l駅 
#  Z店   k駅 
#   
#  tbl_rosenは鉄道路線とその駅名のテーブル(1路線に対して1〜n駅ある)、 
#  tbl_shopは、スーパーの名前と最寄駅(1店に対して0〜nの最寄駅がある) 
#   
#  <やりたいこと> 
#  ・その店に鉄道で行くことが出来る駅のリストを作成したい 
#  ・ある特定の路線は除外(上の例だと、D線は対象外) 
#  ・乗り換えは考慮しない。 
#   
#  →例えば、Z店はk駅が最寄りで、k駅はA線、B線、D線の乗り入れ。D線を除外すると、 
#  i、j、k、l、m駅から電車(±徒歩)でZ店に行ける 
#   
#  <最終的に出力したいテーブル) 
#  tbl_output 
#  店名  最寄駅  備考 
#  ---------------------- 
#  X店   i駅   備考1 
#  X店   j駅   備考2 
#  X店   k駅   備考3 
#  X店   l駅   備考4 
#  X店   m駅   備考5 
#  Y店   k駅   備考3 
#  Y店   l駅   備考4 
#  Y店   m駅   備考5 
#  Z店   i駅   備考1 
#  Z店   j駅   備考2 
#  Z店   k駅   備考3 
#  Z店   l駅   備考4 
#  Z店   m駅   備考5 
#   
#   
#  2段階に分ければ(駅で結合して店名、路線名でグループ化(D線除外)した 
#  テンポラリテーブルをつくって、さらにtbl_rosenと結合する)普通にできるのですが、 
#  出来れば一発のSQLで出力したいのですが、SQL自体にまだ馴染みが薄く、 
#  どのように書いて良いのかわかりません 
#   
#  よろしくお願いします(PostgreSQL8.4です) 
# 
# 

'その店に鉄道で行くことが出来る駅のリストを作成したい ・ある特定の路線は除外(上の例だと、D線は対象外)・乗り換えは考慮しない。 '(_店名,_除外する路線名ならび,L) :-
        店候補(_店名,R),
        その店に鉄道で行くことができる駅候補(_店名,_路線名ならび),
        その店に鉄道で行くことが出来る駅のリストを作成する(_店名,_除外する路線名ならび,_路線名ならび),
        R = [].

店候補(_店名,R) :-
        findsetof(_店名,(
                    tbl_shop(_店名,_,_)),
                _店名ならび),
        append(_,[_店名|R],_店名ならび).

その店に鉄道で行くことができる駅候補(_店名,_路線名ならび) :-
        findsetof(_路線名,(
                    tbl_shop(_店名,_最寄駅,_備考1),
                    tbl_rosen(_路線名,_最寄駅,_備考2)),
                 _路線名ならび).

その店に鉄道で行くことが出来る駅のリストを作成する(_店名,_除外する路線名ならび,_路線名ならび) :-
        append(_,[_路線名|R],_路線名ならび),
        tbl_rosen(_路線名,_駅名,_備考),
        \+((member(_路線名,_除外する路線名ならび)),
        assertz(tbl_output(_店名,_駅名,_備考)),
        R = [].

findsetof(A,B,L) :-
        findall(A,B,C),
        setof(A,member(A,C),L).

findsetof(A,B) :-
        findall(A,B,C),
        setof(A,member(A,C),D),
        member(A,D).