いつまでたってもPrologには慣れないなあ
単純なクエリなら理解できる。
father(ieyasu, hirotada). father(hirotada, kiyoyasu). granpa(D, A) <- father(D, M), father(M, A).
で
?- granpa(ieyasu, X).
とかすればX=kiyoyasuになることぐらいまでは。
たとえば、リスト二つをつなぎ合わせるappendをPrologでかくと以下
append([], R, R). append([H | T], R, [H | A]) <- append(T, R, A).
これは直感的には考えてしまう。トレースをとれば理解はできるが。
?- append([1,2], [3,4,5], A0). append([H=1 | T=[2]], R=[3,4,5], [H=1, | A1=?]) <- append(T=[2], R=[3,4,5], A1=?) append([H=2 | T=[]], R=[3,4,5], [H=2, | A2=?]) <- append(T=[], R=[3,4,5], A2=?) append([], R=[3,4,5], R=[3,4,5]) A2=[3,4,5] A1=[2,3,4,5] A0=[1,2,3,4,5]
Prologの強力なところは、どこに変数をおいてもいい。たとえば
?- append(T0, [3,4,5], [1,2,3,4,5]). append([H=1 | T1=?], R=[3,4,5], [H=1, | A=[2,3,4,5]]) <- append(T1=?, R=[3,4,5], A=[2,3,4,5]) append([H=2 | T2=?], R=[3,4,5], [H=2, | A=[3,4,5]]) <- append(T2=?, R=[3,4,5], A=[3,4,5]) append([], R=[3,4,5], R=[3,4,5]) T2=[] T1=[2] T0=[1,2]
も
?- append([1,2], R0, [1,2,3,4,5]). append([H=1 | T=[2]], R1=?, [H=1, | A=[2,3,4,5]]) <- append(T=[2], R1=?, A=[2,3,4,5]) append([H=2 | T=[]], R2=?, [H=2, | A=[3,4,5]]) <- append(T=[], R2=?, A=[3,4,5]) append([], R=[3,4,5], R=[3,4,5]) R2=[3,4,5] R1=[3,4,5] R0=[3,4,5]
もできる。
一つ一つをみれば単純なパターンマッチングだ。それが上→下はいいけど、下→上で行われると勘が働かなくなってしまう。あと、問い合わせのコードの上に結果が成り立っている想定がなされるんだが、直感的にわからなくなってるのはこの辺もある。ここは宣言的といってしまえばそれまでだが、一方向的に進む関数型言語でのそれとも違ってかんじる。
appendA acc [] l = acc ++ l appendA acc [h|t] l = appendA (acc ++ [h]) t l append l r = appendA [] l r show $ append [1,2] [2,3,4]