在推斷的過程中(回答查詢或檢索以達成目標),Prolog 解釋程序做些什麼?
一個 Prolog 程序會被查閱,程序中的事實和規則被載入知識數據庫。
當有了查詢或目標後,Prolog 解釋程序從上至下搜尋知識數據庫,看看有沒有事實或規則可以和查詢或目標相配合。
如果有配合的情況,Prolog 解釋程序成功地為查詢找出答案,或得知目標是真的;任何變量的值也在這時候被求出了。
如果使用者要求更多解(例如在部份 Prolog 解釋程序輸入了分號),Prolog 解釋程序會繼續搜尋。它會記著哪些事實和規則被搜尋過。當它再找不到更多解的時候,它會輸出「no」,並且搜尋結束。
Prolog 解釋程序從目標/查詢開始,跟著一直向後回索,在知識數據庫中找出可以推斷到目標事實和規則。你可以在下面的例子中看見推斷的過程。
一致化即是透過約束變量的方法,在已有的規則中引伸出出新的規則。
為了要配合到目標或查詢,任何遇見的變量都會以恰當的常數代入去(稱為約束)。
有些時候,多於一個事實/規則可以應用於一個目標/查詢,這時候在知識數據庫中最先出現的事實/規則會被應用,而其他的事實/規則遲些也會被應用,使我們可以找到所有可能的解。這過程稱為回索。
我們會使用以下程序和一些查詢去解釋推斷的過程。
留意︰推斷過程中的每一步中,可能會有多於一個子目標被處理。在這情況下,只有第一個子目標被考慮,如果有一個規則可被應用,它會被應用了的規則當中的子目標取締;如果符合了一個事實,它會被刪去。如果沒有規則或事實可被應用,我們需要回索。
| 層次 | 推斷的結果 | 應用了的事實或規則 | 約束變量 | |
|---|---|---|---|---|
| 原來的目標 | can_use(judy, vb).
|
P = judy SW = vb |
||
| 1 | access(judy, Comp), can_run(Comp, 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.
|
符合了! 輸出︰yes |
||
| 整體輸出 | yes | |||
此目標示範回索。
| 層次 | 推斷的結果 | 應用了的事實或規則 | 約束變量 | |
|---|---|---|---|---|
| 原來的目標 | 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.
|
失敗了!回索。 | ||
| 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 | |||
這查詢示範怎樣回索去找尋所有答案。
| 層次 | 推斷的結果 | 應用了的事實或規則 | 約束變量 | |
|---|---|---|---|---|
| 原來的查詢 | 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.
|
符合了! |
||
| 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 |
|||
我們一定要回索才可以肯定一個查詢沒有答案。
| 層次 | 推斷的結果 | 應用了的事實或規則 | 約束變量 |
|---|---|---|---|
| 原來的查詢 | 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 | ||