內部謂詞
和其他語言一樣,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.
表達式類
1、is 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.