LispとPrologの課題中
とりあえず Prologを触ってます。 初めて触る処理系なので、GNU Prolog を Vine にインストールするも勝手が分からず。
と、とりあえず、ここは お決まりの "Hello world!!" 辺りを………
……文字列出力って、できなくね? orz
て、テストコードもかけないのか……っ!! というわけで必死中…
追記 22:05
リスト操作で躓く。
-- code --
test([F | B], F, B).
test([F | B], F, B) :- test(B, F1, B1).
-- 実行 --
-? test([1, 2, 3], X, Y);
X = 1
Y = [2, 3] ;
X = 1
Y = [2, 3] ;
X = 1
Y = [2, 3] ;
私としては
X = 1 Y = [2, 3] ; X = 2 Y = [3] ; X = 3 Y = [] ;
見たいな結果を期待したんだけれど…あーれー?^^;
追記 22:30
もっと単純にってことで、あるリスト(配列)の中に指定した値があるかどうかチェックする関数を作ってみました。
-- コード --
valid([F | T], Y) :- F is Y.
valid([F | T], Y) :- valid(T, Y).
-- 実行 --
-? valid([1, 2, 9], 7).
No.
-? valid([1, 2, 9], 9).
Yes.
うぉおおおおおおおお!動いたああああーーーーーーーーー!!
よ、ようやく自分の思ったとおりに動くコードが書けたよぉぉおお! コレだけでもう満足だ俺。(ぉ
追記 00:52
なんか動くものが出来たけど…結果が正しくない orz
やっている事は、深さ優先探索。 現状では四角形の4ノードで、左上から右下へ探索を行ってみる。 …が、上手くいかない。orz 隣同士のノードだと見つかってくれるんですが…うむむむ。
% 比較関数 -> 文字は =:= , =\= で比較できんようなので… orz
is_eq(F, F).
% list に 第2引数が含まれてるのかな?
is_member([F | _], F).
is_member([_ | T], D) :- is_member(T, D).
% list に 第2引数が含まれて無いのかな?
is_not_member([], _).
is_not_member([F | T], Y) :- not(is_eq(F, Y)), is_not_member(T, Y).
% list の先頭に A を追加。 ただし、既にメンバであった場合は挿入しない。
list_push_front(L, A, [A | L]) :- is_not_member(L, A).
list_push_front(L, _A, L).
% list の先頭に list を追加。 ただし、既にメンバである要素は挿入しない。
list_push_front_list(L, [A | B], X) :- list_push_front(L, A, X1), list_push_front_list(X1, B, X).
list_push_front_list(L, [], L).
% 第1引数のノードリストを OL に追加。 ただし、CLに存在する要素は挿入しない。
add_node_list([F | T], OL, CL, OL_OUT) :- is_not_member(CL, F), list_push_front(OL, F, OL_TMP), add_node_list(T, OL_TMP, CL, OL_OUT).
add_node_list(_L, OL, _CL, OL).
add_node_list([], OL, _CL, OL).
% 探索済みノードに追加
add_cl(NODE, CL, [NODE | CL]).
% ノードリストの追加云々
node(a, OL, CL, OL_OUT) :- add_node_list([b, c], OL, CL, OL_OUT).
node(b, OL, CL, OL_OUT) :- add_node_list([a, d], OL, CL, OL_OUT).
node(c, OL, CL, OL_OUT) :- add_node_list([a, d], OL, CL, OL_OUT).
node(d, OL, CL, OL_OUT) :- add_node_list([b, c], OL, CL, OL_OUT).
% 再起呼び出し
rec(G, [F_OL | _T_OL], _CL) :- is_eq(G, F_OL). % 探索終了
rec(G, [F_OL | T_OL], CL) :- add_cl(F_OL, CL, CL1), node(F_OL, T_OL, CL1, OL_OUT), rec(G, OL_OUT, CL1).
depth_first_search(START, GOAL) :- rec(GOAL, [START], []).
とりあえず、Prolog にはなれてきた感じ。 イメージ的には 関数のオーバーロード拡張版 やね。 上にある関数から順番に実行して、失敗したら次の関数〜 みたいな。
ただ、戻り値(と言って良いのか?)が、関数の引数としてしか受け取れないってのはちょっと混乱かなぁ。 …あぁ、もしかして関数じゃなくて述語って言うべきなんでしょうか。^^;