推斷的過程

前頁 目錄 下頁

概要 一致化 回索 例子

概要 Top

在推斷的過程中(回答查詢或檢索以達成目標),Prolog 解釋程序做些什麼?

  1. 一個 Prolog 程序會被查閱,程序中的事實和規則被載入知識數據庫。

  2. 當有了查詢或目標後,Prolog 解釋程序從上至下搜尋知識數據庫,看看有沒有事實或規則可以和查詢或目標相配合。

  3. 如果有配合的情況,Prolog 解釋程序成功地為查詢找出答案,或得知目標是真的;任何變量的值也在這時候被求出了。

  4. 如果使用者要求更多解(例如在部份 Prolog 解釋程序輸入了分號),Prolog 解釋程序會繼續搜尋。它會記著哪些事實和規則被搜尋過。當它再找不到更多解的時候,它會輸出「no」,並且搜尋結束。

第二步詳盡的解釋

Prolog 解釋程序從目標/查詢開始,跟著一直向後回索,在知識數據庫中找出可以推斷到目標事實和規則。你可以在下面的例子中看見推斷的過程。

一致化 Top

一致化即是透過約束變量的方法,在已有的規則中引伸出出新的規則。

為了要配合到目標或查詢,任何遇見的變量都會以恰當的常數代入去(稱為約束)。

回索 Top

有些時候,多於一個事實/規則可以應用於一個目標/查詢,這時候在知識數據庫中最先出現的事實/規則會被應用,而其他的事實/規則遲些也會被應用,使我們可以找到所有可能的解。這過程稱為回索。

例子 Top

我們會使用以下程序和一些查詢去解釋推斷的過程。

留意︰推斷過程中的每一步中,可能會有多於一個子目標被處理。在這情況下,只有第一個子目標被考慮,如果有一個規則可被應用,它會被應用了的規則當中的子目標取締;如果符合了一個事實,它會被刪去。如果沒有規則或事實可被應用,我們需要回索。

程序四︰一個關於一些電腦、安裝了的軟件以及電腦的使用者
spec(comp1, pc, 32).                                      /* 事實一 */
spec(comp2, mac, 128).                                    /* 事實二 */
spec(comp3, pc, 64).                                      /* 事實三 */
runs(pc, movie_edit, 96).                                 /* 事實四 */
runs(pc, vb, 16).                                         /* 事實五 */
runs(pc, cpp, 28).                                        /* 事實六 */
runs(mac, vb, 24).                                        /* 事實七 */
runs(mac, prolog, 128).                                   /* 事實八 */
access(judy, comp1).                                      /* 事實九 */
access(peter, comp3).                                     /* 事實十 */
access(david, comp1).                                     /* 事實十一 */
access(david, comp2).                                     /* 事實十二 */

can_use(P, SW) :- access(P, Comp), can_run(Comp, SW).     /* 規則一 */

can_run(Comp, SW) :- spec(Comp, CompType, MemAvail),
                     runs(CompType, SW, MemNeeded),
                     MemAvail >= MemNeeded.               /* 規則二 */

Judy 可以使用 VB 嗎?
?- can_use(judy, vb).

層次 推斷的結果 應用了的事實或規則 約束變量
原來的目標 can_use(judy, vb).
為了使原來的目標(can_use(judy, vb))成為真的,根據規則一, 規則中的條件必須是真的(即對於某些 Comp, access(judy, Comp) 和 can_run(Comp, vb))。因此目標可被簡化成以下所見。

為了使用規則一於目標之上,我們做了一次一致化,做法是約束(即賦值) judy 這個值於變量 P,以及約束值 vb 於變量 SW。

規則一

P = judy
SW
= vb
1 access(judy, Comp), can_run(Comp, vb).
一致化後,由事實九得知 access(judy, comp1)是真的。因此,原來的目標是否真的,只取決於 can_run(comp1, vb) 是否真的。

事實九

Comp = comp1
2 can_run(comp1, vb).

事實二

-

3 spec(comp1, CompType, MemAvail),
runs(
CompType, vb, MemNeeded),
MemAvail >= MemNeeded.

事實一

CompType = pc
MemAvail
= 32
4 runs(pc, vb, MemNeeded),
32 >=
MemNeeded.

事實五

MemNeeded = 16
5 32 >=16.
以上是真的,因此我們可以推斷第 4 層中的子目標是真的。而依據同一道理得知第 3 層、第 2 層、第 1 層及原來的目標都是真的。
符合了!
輸出︰yes
整體輸出 yes

David 可以使用 Prolog 嗎?
?- can_use(david, prolog).

此目標示範回索。

層次 推斷的結果 應用了的事實或規則 約束變量
原來的目標 can_use(david, prolog).

規則一

P = david
SW
= prolog
1 access(david, Comp), can_run(Comp, prolog).
事實十一及事實十二都可以應用,但因為事實十一在事實十二之前,因此事實十一會先被應用。

事實十一

Comp = comp1
2 can_run(comp1, prolog).

規則二

-

3 spec(comp1, CompType, MemAvail),
runs(
CompType, prolog, MemNeeded),
MemAvail >= MemNeeded.

事實一

CompType = pc
MemAvail
= 32
4 runs(pc, prolog, MemNeeded),
32 >= MemNeeded.
沒有規則或事實可以再使用,因此需要回索。
失敗了!回索。
3 spec(comp1, CompType, MemAvail),
runs(CompType, prolog, MemNeeded),
MemAvail >= MemNeeded.
沒有未被應用過的規則或事實可以在這�堥洏峞A因此需要回索。
失敗了!回索。
2 can_run(comp1, prolog). 失敗了!回索。
1 access(david, Comp), can_run(Comp, prolog).
事實十一已被使用過,現在我們試試事實十二。

事實十二

Comp = comp2
2 can_run(comp2, prolog).

規則二

-

3 spec(comp2, CompType, MemAvail),
runs(
CompType, prolog, MemNeeded),
MemAvail >= MemNeeded.

事實二

CompType = mac
MemAvail
= 128
4 runs(mac, prolog, MemNeeded),
128 >=
MemNeeded.

事實八

MemNeeded = 128
5 128 >= 128. 符合了!
輸出︰yes
整體輸出 yes

Judy 可以使用什麼軟件?
?- can_use(judy, X).

這查詢示範怎樣回索去找尋所有答案。

層次 推斷的結果 應用了的事實或規則 約束變量
原來的查詢 can_use(judy, X).

規則一

P = judy
1 access(judy, Comp), can_run(Comp, X).

事實十一

Comp = comp1
2 can_run(comp1, X).

規則二

-

3 spec(comp1, CompType, MemAvail),
runs(
CompType, X, MemNeeded),
MemAvail >= MemNeeded.

事實一

CompType = pc
MemAvail
= 32
4 runs(pc, X, MemNeeded),
32 >=
MemNeeded.
事實四 X = movie_edit
MemNeeded
= 96
5 32 >= 96.

失敗了!回索。

4 runs(pc, X, MemNeeded),
32 >=
MemNeeded.
事實五 X = vb
MemNeeded
= 16
5 32 >= 16.
X = vb 是原來查詢的一個解。

回索是需要的,因為可能還有其他的解。

符合了!
輸出︰X = vb
然後回索。

4 runs(pc, X, MemNeeded),
32 >=
MemNeeded.
事實六 X = cpp
MemNeeded
= 28
5 32 >= 28. 符合了!
輸出︰X = cpp
然後回索。
4 runs(pc, X, MemNeeded),
32 >= MemNeeded.
失敗了!回索。
3 spec(comp1, CompType, MemAvail),
runs(CompType, X, MemNeeded),
MemAvail >= MemNeeded.
失敗了!回索。
2 can_run(comp1, X). 失敗了!回索。
1 access(judy, Comp), can_run(Comp, X). 失敗了!回索。
原來的查詢 can_use(judy, X). 失敗了!
由於已回來到最頂層,因此所有答案已經被找出來了。
整體輸出 x = vb
x = cpp

誰可以使用 MovieEdit?
?- can_use(X, movie_edit).

我們一定要回索才可以肯定一個查詢沒有答案。

層次 推斷的結果 應用了的事實或規則 約束變量
原來的查詢 can_use(X, movie_edit).

規則一

SW = movie_edit
1 access(X, Comp), can_run(Comp, movie_edit).

事實九

X = judy
Comp
= comp1
2 can_run(comp1, movie_edit).

規則二

-

3 spec(comp1, CompType, MemAvail),
runs(
CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

事實一

CompType = pc
MemAvail
= 32
4 runs(pc, movie_edit, MemNeeded),
32 >=
MemNeeded.
事實四 MemNeeded = 96
5 32 >= 96. 失敗了!回索。
4 runs(pc, movie_edit, MemNeeded),
32 >=MemNeeded.
失敗了!回索。
3 spec(comp1, CompType, MemAvail),
runs(CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

失敗了!回索。

2 can_run(comp1, movie_edit).

失敗了!回索。

1 access(X, Comp), can_run(Comp, movie_edit).

事實十

X = peter
Comp
= comp3
2 can_run(comp3, movie_edit).

規則二

-

3 spec(comp3, CompType, MemAvail),
runs(
CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

事實三

CompType = pc
MemAvail
= 64
4 runs(pc, movie_edit, MemNeeded),
64 >=
MemNeeded.
事實四 MemNeeded = 96
5 64 >= 96.

失敗了!回索。

4 runs(pc, movie_edit, MemNeeded),
64 >=MemNeeded.
失敗了!回索。
3 spec(comp3, CompType, MemAvail),
runs(CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.
失敗了!回索。
2 can_run(comp3, movie_edit). 失敗了!回索。
1 access(X, Comp), can_run(Comp, movie_edit).

事實十一

X = david
Comp
= comp1
2 can_run(comp1, movie_edit).

規則二

-

3 spec(comp1, CompType, MemAvail),
runs(
CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

事實一

CompType = pc
MemAvail
= 32
4 runs(pc, movie_edit, MemNeeded),
32 >=
MemNeeded.
事實四 MemNeeded = 96
5 32 >= 96.

失敗了!回索。

4 runs(pc, movie_edit, MemNeeded),
32 >=MemNeeded.

失敗了!回索。

3 spec(comp1, CompType, MemAvail),
runs(CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

失敗了!回索。

2 can_run(comp1, movie_edit).

失敗了!回索。

1 access(X, Comp), can_run(Comp, movie_edit).

事實十二

X = david
Comp
= comp2
2 can_run(comp2, movie_edit).

規則二

-

3 spec(comp2, CompType, MemAvail),
runs(
CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

事實二

CompType = mac
MemAvail
= 128
4 runs(mac, movie_edit, MemNeeded),
128 >= MemNeeded.

失敗了!回索。

3 spec(comp2, CompType, MemAvail),
runs(CompType, movie_edit, MemNeeded),
MemAvail >= MemNeeded.

失敗了!回索。

2 can_run(comp2, movie_edit).

失敗了!回索。

1 access(X, Comp), can_run(Comp, movie_edit).

失敗了!回索。

原來的查詢 can_use(X, movie_edit). 失敗了。已到了最頂層,但沒找到答案。
輸出︰no
整體輸出 no

前頁 目錄 下頁