prolog 內部謂詞


內部謂詞

和其他語言一樣,prolog也提供一些基本的輸入輸出函數。

內部謂詞是指已經在prolog中事先定義好的謂詞,在內存中的動態數據庫中是沒有內部謂詞子句的。(當我們運行某個.pl 文件的時候,該文件的內容會加載到內存中。所以內存中會有文件中的謂詞子句),當解釋器遇到內部謂詞的目標,它就直接調用事先定義好的程序。

內部謂詞一般所完成的工作和邏輯無關,所以這些文詞也叫做非邏輯謂詞。雖然如此,但這些謂詞也可以所謂prolog的目標,所以他們也有四個端口:call exit redo  fail

 

常用的輸出謂詞

write/1   %謂詞名為 ‘write’  參數數量為 1 個

1 ?- write('hello world').
hello world
true.

此謂詞被調用是永遠成功,它把它的參數作為字符串輸出到屏幕上

當回溯時,它永遠失敗,所以,回溯不會吧已經輸出到屏幕上的字符刪掉

 

nl/0


?- nl
.
true.

此謂詞沒有參數,它的作用的在屏幕上輸出一個回車符。

和write一樣,從call端口嗲用時永遠成功,但是回溯時總是失敗。

 

tab/1


?- write('hello'),tab(10),write('world').
hello          world
true.

此謂詞有一個參數,該謂詞的作用是在屏幕上輸出n個空格 n=參數值

其控制流程和write nl一樣

fail/0

?- fail.
false.

該謂詞沒有參數,他的調用永遠失敗,從而引起回溯。

 

以前我們靠“;”來釋放已經綁定的變量,進入目標的redo端口,變量的輸出靠解釋器完成,現在我們可以使用I/O謂詞來顯示變量。靠fail來引起自動回溯。

1 ?- location(X,kitchen),write(X),nl,fail.
apple
broccoli
crackers
false.

 

 該目標的運行流程如下:

 SWI-Prolog的debug信息如下:

?- location(X,kitchen),write(X),nl,fail.
 T Call: (8) location(_G263, kitchen)
 T Exit: (8) location(apple, kitchen)
 T Call: (8) write(apple)
apple
 T Exit: (8) write(apple)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
 T Redo: (8) location(_G263, kitchen)
 T Exit: (8) location(broccoli, kitchen)
 T Call: (8) write(broccoli)
broccoli
 T Exit: (8) write(broccoli)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
 T Redo: (8) location(_G263, kitchen)
 T Exit: (8) location(crackers, kitchen)
 T Call: (8) write(crackers)
crackers
 T Exit: (8) write(crackers)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
false.

 

 我覺得教程中的debug信息更好,摘錄如下:

localtion(X,kitchen),write(X),nl,fail.

call location(X,kitchen)
exit(2) location(apple,kitchen)
call write(apple)
apple
exit write(apple)
call nl   %調用內部謂詞  nl,會在屏幕上輸出空格

exit nl
call fail
fail fail   %fail 失敗會引起自動回溯
redo nl     %回溯到上一次成功匹配的子句,重新開始在該子句后面查找。I/O謂詞應該就是重新運行
fail nl
redo write(apple)
fail write(apple)
redo location(X,kitchen)
exit(6) location(broccoli,kitchen)
call  write(broccoli)
broccoli
exit  write(broccoli)
call nl

exit nl
call fail
fail fail
redo nl
fail nl
redo write(broccoli)
fail write(broccoli)
redo kitchen(X,kitchen)
exit(7) kitchen(crackers,kitchen)
call write(crackers)
crackers
exit write(crackers)
call nl

exit nl
call fail
fail fail
redo nl
fail nl
redo write(crackers)
fail write(crackers)
redo location(X,kitchen)
fail location(X,kitchen)
no

那么如下子句執行的結果是什么呢?以及它的流程是如何進行的呢?

?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
office
   desk
   computer
cellar
   washing mechine


%該結果中沒有體現出 nl 這個內置謂詞運行的結果——即沒有回車符,但是在下面的debug信息中,卻顯示着,nl確實執行過。

 

 

如下為使用SWI-prolog的debug信息

2 ?- door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.
 T Call: (8) door(kitchen, _G438)
 T Exit: (8) door(kitchen, office)
 T Call: (8) write(office)
office
 T Exit: (8) write(office)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) location(_G442, office)
 T Exit: (8) location(desk, office)
 T Call: (8) tab(3)
   
 T Exit: (8) tab(3)
 T Call: (8) write(desk)
desk
 T Exit: (8) write(desk)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
 T Redo: (8) location(_G442, office)
 T Exit: (8) location(computer, office)
 T Call: (8) tab(3)
   
 T Exit: (8) tab(3)
 T Call: (8) write(computer)
computer
 T Exit: (8) write(computer)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
 T Redo: (8) door(kitchen, _G438)
 T Exit: (8) door(kitchen, cellar)
 T Call: (8) write(cellar)
cellar
 T Exit: (8) write(cellar)
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) location(_G442, cellar)
 T Exit: (8) location('washing mechine', cellar)
 T Call: (8) tab(3)
   
 T Exit: (8) tab(3)
 T Call: (8) write('washing mechine')
washing mechine
 T Exit: (8) write('washing mechine')
 T Call: (8) nl

 T Exit: (8) nl
 T Call: (8) fail
 T Fail: (8) fail
false.

同樣,我覺得SWI-prolog的debug信息不是很好,所以我就按照前幾次的邏輯,自己寫了下面這個debug信息(如有錯誤,請指出)

goal  door(kitchen,R),write(R),nl,location(T,R),tab(3),write(T),nl,fail.

call door(kitchen,R)
exit(3) door(kitchen,office)
call write(office)
office
exit write(office)
call nl

exit nl
call location(T,office)
exit(2) location(desk,office)
call tab(3)
    exit tab(3)
call write(desk)
   desk
exit write(desk)
call nl
   
exit nl
call fail
fail fail
redo nl
fail nl
redo write(desk)
fail write(desk)
redo tab(3)
fail tab(3)
redo location(T,office)
exit(5) location(computer,office)
call tab(3)
    exit tab(3)
call write(computer)
    computer
exit write(computer)
call nl

exit nl
call fail
fail fail
redo nl
fail nl
redo write(computer)
fail write(computer)
redo tab(3)
fail tab(3)
redo location(T,office)
fail location(T,office)
redo nl
fail nl
redo write(office)
fail write(office)
redo door(kitchen,R)
exit(6) door(kitchen,cellar)
call write(cellar)
cellar
exit write(cellar)
call nl

exit nl
call location(T,cellar)
exit(9) location('washing mechine',cellar)
call tab(3)
   exit tab(3)
call write('washing mechine')
    washing mechine
exit write('washing mechine')
call nl

exit nl
call fail
fail fail
redo nl
fail nl
redo write('washing meching')
fail write('washing meching')
redo tab(3)
fail tab(3)
redo location(T,cellar)
fail location(T,cellar)
redo nl
fail nl
redo write(cellar)
fail write(cellar)
redo door(kitchen,R)
fail door(kitchen,R)
no
  

 其他內部謂詞:

比較類:

1、 = 
   等於    綁定變量
2、  \= 
    不等於
3、 >, <
    大於,小於
4、>= ,=< 
    大於等於, 小於等於 5、 ==
    強等於
1 ?- 1 = 1.
true.

2 ?- X = 1.
X = 1.

3 ?- 1>1.
false.

4 ?- 1<2.
true.

5 ?- 1>=1.
true.

6 ?- 1 == 1.
true.

表達式類

1is
    X is Y , Y可以被實例化為表達式,該謂詞先對Y 求值,得到一個整數,如X未實例化,
  則X 實例化為這一結果,且目標成功,否則,如X 已經實例化,那么 is 退化為 = 來判斷成功與否 2 、+ 加法運算 3、 — 減法運算 4、* 乘法運算 5、/ 除法運算 6. mod 取模運算 優先級: +—(正負號),mod,*/, +—(加、減)

 

?- X is 4.
X = 4.

?- S is 4+1.
S = 5.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM