Ryo Hatano JAIST April 16, 2012s1220010/Prolog_2.pdf · 人工知能特論 -Prolog 演習2- Ryo...
Transcript of Ryo Hatano JAIST April 16, 2012s1220010/Prolog_2.pdf · 人工知能特論 -Prolog 演習2- Ryo...
人工知能特論- Prolog 演習 2-
Ryo HatanoJAIST
April 16, 2012
1
お知らせ
• 間違い箇所の修正– 前回のスライドの修正版をアップロードしました
• レポートについて– 授業後に資料がアップされます
– 大雑把に説明すると, グラフ探索• カット, 否定, リスト, 再帰, 論理外述語を使います
• 本日の話題– 前半: 理論系の話まとめ (論理学とPrologの関係)– 後半: 実用向けの話 (プログラミング)
(用語, 意味合いの理解・識別は大事!)
2
前回の復習
fruit(apple).fruit(tomato). vegetable(tomato).
plant(X) :- fruit(X).plant(X) :- vegetable(X).
プログラム インタープリタ
?- plant(X)X = apple ;X = tomato true
plant
fruit vegetable
探索制御以外の基本的な記法, 用語, Prologの使用方法を解説
apple tomato tomato
探索木
事実節
規則節
←質問節
述語: plant, fruit, vegetable変数: X定数: apple, tomatoバックトラック
∀X[ fruit(X)∨vegetable(X)→plant(X) ]
対応する論理式(規則のみ)
3
Prolog構文の構成要素 (再掲)
(以降, 見慣れないものがあっても, だいたいこの中のどれかに当てはまる)
• 算術, 比較, 代入, ユーザー定義• 単一化, バックトラック制御• コメント
演算子
+
節
頭部 :- 本体.
述語(項, 項, …, 項)
変数 定数 関数
データ構造
4
目次
1. お知らせ
2. 前回の復習
3. Prolog の二面性
4. 再帰
5. カット
6. 糖衣構文
7. リスト
8. データベースの操作
9. レポート
←ループの話
←if文や否定(not) の話
←動的なプログラミングに用いる
←配列(可変長) のようなもの
5
Prologの二面性
• 宣言的側面– 目標(論理関係)がどのようなものか
• 手続き的側面– 目標をどのように得るか(手続きの実行順序)
– Prolog の手続き的詳細(解の探索等)は, 導出原理(resolution)に基づく
p :- a, b, c.
←推論(本体内の目標の出現順序は関係ない)
p :- a, b, c.
実行順序→ (本体内の目標の出現順序も結果に影響)
6
宣言的側面と手続き的側面の相違
• 例
is は定数を代入するもの
変数が具体化されていないものは代入できない
p(X, Y):- init(X), assign(X, Y). p(X, Y):- assign(X, Y), init(X). init(X):- X is 0. assign(X, Y):- Y is X.
p(Xは0である) かつ p(YはXである) → p(Yは0である)
←こちらはエラーになる
対応する論理式
7
目次
1. お知らせ
2. 前回の復習
3. Prolog の二面性
4. 再帰
5. カット
6. 糖衣構文
7. リスト
8. データベースの操作
9. レポート
←ループの話
←if文や否定(not) の話
←動的なプログラミングに用いる
←配列(可変長) のようなもの
8
再帰 (Recursion)
• 自分自身を呼び出すこと
– 節の頭部と同じ述語を本体で呼び出す規則
– ループの実現に用いる
– 述語を呼び出す毎の規則の状態(変数のアドレス, 値等) はメモリ上に保持される (再帰から戻ってくるときに値を拾い上げていく)
再帰の例
factorial(0, 1).factorial(N, Result):-
N2 is N – 1,factorial(N2, Result2), Result is N * Result2.
←停止条件
9
再帰 (Recursion) 続き
• 停止条件が必要
– 再帰規則よりも実行優先順位を高くする
(再帰を含む規則より上の行に停止条件を書く)
無限ループする場合は節の並び, 停止条件の存在を疑おう
宣言的(論理的)に正しくても, 手続き的に処理が無限ループする例
factorial(N, Result):-N2 is N – 1,factorial(N2, Result2)Result is N * Result2.
factorial(0, 1).
10
末尾再帰 適化 (Tail recursion optimization)
• 再帰呼び出しを規則の末尾に置いたもの
• 実行環境によって再帰定義が繰り返しに変換される
• 再帰より効率は良いが, 可読性が落ちる高速(はやい!), メモリ使用量が減る(安い!), 読みづらい(うまい?)
11
• 部屋に誰かいる
• 天井のバナナを取りたい
• 部屋内を探索してバナナを取る
使用する述語
Monkey & Banana problem
move(state(前), command, state(後)).state(X, Y, BOX, Has).canget(state):- ←再帰規則
この組み合わせだけで解ける!
12
Monkey & Banana problem 続き
state(atdoor, onfloor, atwindow, hasnot)
state(atwindow, onbox, atwindow, hasnot)
state(P2’, onfloor, P2’, hasnot)
state(P2’, onbox, P2’, hasnot)
state(middle, onbox, middle, has)
walk(atdoor, P2)
push(atwindow, P2’)
climb
GraspP2’ = middle
state(P2, onfloor, atwindow, hasnot)climb(onfloor, onbox)P2 = atwindow
state(atwindow, onfloor, atwindow, hasnot)バックトラック(onbox→onfloor)
(他のバックトラックは省略)
13
目次
1. お知らせ
2. 前回の復習
3. Prolog の二面性
4. 再帰
5. カット
6. 糖衣構文
7. リスト
8. データベースの操作
9. レポート
←ループの話
←if文や否定(not) の話
←動的なプログラミングに用いる
←配列(可変長) のようなもの
14
カット (Cut)
• バックトラックを制御するための機能
• 「! 」記号を通過すると, それよりも前にバックトラック
しなくなる
• 条件分岐や否定, ループの実現, 実行効率の改善等に用いられる
↓!は擬似的な目標として扱われる
←可能な別解がすべて破棄される
カットの例
not(male(john)):- male(john), !, fail.
not(male(john)):- true.
カットを通過して戻ったらまずい
15
Cut による条件分岐の実現
• IF-THEN-ELSE
• 節の並べ替えによる意味の異なり例
Cut は手続き的意味だけでなく, 宣言的意味も変えてしまうので注意
p:- a, !, b.p:- c
sub(X):- condition(X, Y), !, then(Y).
sub(X):- then(X).if部 then部
else部 (if-then 部を増やせば, else-if も可能)
p:- c.p:- a, !, b.
(a ∧ b) ∨ (¬a ∧ c) c ∨ (a ∧ b)≠
≠
|| ||
16
失敗による否定 (Negation as failure)
• カットにより定義される– 厳密には数学論理の否定と異なる
– データベース中に, 証明するに足る情報がないということ
を述べるだけ
• 否定の表記は2種類
– not (P) … 述語
– ¥+ P … 演算子
(引数は文であることに注意. 変数・定数ではない)
否定の定義
not(P) :- P, !, fail.not(_) :- true.
17
目次
1. お知らせ
2. 前回の復習
3. Prolog の二面性
4. 再帰
5. カット
6. 糖衣構文
7. リスト
8. データベースの操作
9. レポート
←ループの話
←if文や否定(not) の話
←動的なプログラミングに用いる
←配列(可変長) のようなもの
18
糖衣構文 (Syntax sugar)
• 省略記法の一種
– 読み書きの負荷を低減するために難解な記法を省略
– 元の記法の機能とほぼ同じ機能を提供
– Prolog では演算子の定義, リスト等で利用
(人の感覚に近いが, 言語の核から離れた記法)
(実行効率, 手続きの異なり等が多少は存在)
19
リスト (List)
• 配列のようなもの
• 構文– [Head | Tail]– [Item1, Item2, …, | Tail]– Head:先頭の1要素
– Tail:残り全ての要素のリスト
– Item: 要素(項)– 末尾は空のリスト [] – 「|」はリスト要素の分割, 結合に用いる
?- [a, b, c] = [A, B, C]. A = a, B = b, C = c.
?- [a, b, c] = [a, b | [c]]. true.
リストの例
20
リスト (List) 続き
• 内部的にはBinary tree 表現
– [root, sub1, sub2]– .(root, .(sub1, .(sub2, [])))Binary tree のままだと記述が面倒なので前頁の糖衣構文が用意されている
root
.
sub1
sub2 []
.
.
[root | Tail] の実際の構造
Tail
21
リストの操作
• リストの分割・結合・探索
←一段取り払われていることに注意
?- conc(a, [b, c], Res). Res = [a, b, c]
?- conc(Head, Tail, [a,b,c])Head = aTail = [b, c]
conc(Head, Tail, [Head|Tail]).
member(Head, [Head|Tail]).member(X, [Head|Tail]):- member(X, Tail).
分割・結合例(簡易版)
インタープリタ
検索例
ひとつのプログラムを複数の目的に利用できる(Prologの特徴)
22
目次
1. お知らせ
2. 前回の復習
3. Prolog の二面性
4. 再帰
5. カット
6. 糖衣構文
7. リスト
8. データベースの操作
9. レポート
←ループの話
←if文や否定(not) の話
←動的なプログラミングに用いる
←配列(可変長) のようなもの
23
論理外述語 (Extra-logical predicates)
• 本来の機能の他に, 副作用を持つ述語
• 例
– ストリームの取り扱い
– データベースの操作
– 項の動的組み立て・分解, etc…
24
ストリームの取り扱い
• ストリーム– ファイルとの交信手段
– ユーザーからの入力も擬似ファイルによって同様に実現
• ストリーム関連述語– see(F) 入力ストリームをFに設定
– seen 現在の入力ファイルを閉じる
– tell(F) 出力ストリームをFに設定
– told 現在の出力ファイルを閉じる
– user ユーザー端末を示す擬似ファイル
– end_of_file ファイル終端を示す定数
ファイル入力の基本的な手続き(出力も同様)
see(File), read_from_file(Info), seen, see(user), process(Info), …
(read_from_file とprocess 部分は自分で定義)
25
ストリームの取り扱い 続き
• read(Term) 項を読み込む
• write(Term) 項を書き込む
• tab(N) N個の空白を出力する
• nl 改行する
• put(C) 文字を出力する
• get(C) 文字を入力する
• consult(F) 全ての節を読み込む
26
データベースの操作
• assert(C) – 常に成功し, 副作用として節Cをデータベースに加える
– 規則を加えるときは, 括弧で引数としての規則を囲む
– asserta(C) データベースの先頭に節を加える
– assertz(C) データベースの末尾に節を加える
• retract(C) – Cにマッチする節を取り除く
– retractall(C) Cにマッチする全ての節を取り除く
(同じ要素が無駄に追加されることもあるので注意)
(中間結果などをassert することにより無駄な計算を省く)
:-dynamic ans/1.proc([]).proc(X):- calc(X, R, Tail), setans(R), proc(Tail).setans(X):- ¥+ ans(X), retractall(ans(_)), assertz(ans(X)).setans(_):- true.
assert 例
←動的に操作する述語を指定する
27
データベースの操作 続き
• listing– 定義済み述語の一覧を表示
– listing(述語名) 述語名の述語定義の一覧を表示
• 注意– assert/retract によって, プログラム全体の振る舞いが動的に変わる
– テスト, デバッグ時は振る舞いの再現がなされるようにする
28
レポート
• 提出期限: 5月7日(月) 9:20• 提出方法: メール
• 内容: プログラムの作成
• 詳細は下記参照– http://www.jaist.ac.jp/~s1220010/report.pdf
29
Graph
)10(S
)4(1N
)7(2N
)2(6N
)4(3N
)3(4N
)2(5N
)0(G
30
• 経験的知識を用いた探索法
• ヒューリスティック関数: ゴールまでの距離を返す
• 選択ルール: も距離が短いものを選ぶ
• この例では, S→N2→N4→G
山登り法
S(10)
N2(7) N1(8)
N4(4)
N3(6)
G(1)N5(3)
ノード名(ヒューリスティック関数の値)
(説明が大雑把なので配布資料の定義をきちんと確認すること)
経験的知識:ゴールまでの距離が近いほうの分岐を選んでいけば早く着く
31
授業で取り扱わなかった話題
• グリーンカットとレッドカット
• 失敗駆動ループ
• ユーザー定義の演算子
• 超論理述語
• メタインタプリタ
• DCGによる構文解析
• 他プログラミング言語との連携, etc…