2017-12-18 185 views
0

下面是我想出的代碼。但是,這裏有兩個問題。 首先,只顯示X的第一個值,即1。其次,如果Y爲假,則不會跳回到菜單1。 希望能在這方面得到一些幫助。需要輸出的完整列表

time(office_hour,1). 
time(office_hour,2). 
menu1 :- 
    write('Input time'),nl, 
    read(Y),nl,time(Y,X),nl,write(X),nl,menu1. 

這是場景的例子。如下所示,僅顯示值1。如何顯示值2? Sry基因,我只是一個新手

?-menu1. 
Input time 
office_hour. 
1. 
Input time 
+0

你應該張貼的行爲也是一個例子。特別是,你輸入了什麼?如果它不是'office_hour',那麼在調用'menu1/0'前'time/2'將會失敗。 –

+0

sry,我已經更新了我的帖子。 這個'time/2'和'menu1/0'是什麼意思? 我不記得任何這樣的任期從我的講師。 – Kimchi

+0

@Kimchi它在Prolog文檔中,如果你看看它。 '/ n'表示'n'參數。所以'time/2'是2個參數的'time'。如果有一個帶3個參數的「time」,它將是一個不同的謂詞,並被描述爲「time/3」。 – lurker

回答

0

您需要允許的Prolog到原路返回得到所有的解決方案。你的謂詞的問題在於它在回溯之前會進行遞歸調用。此外,您繼續爲下一個菜單提示深入一層,這可能不是好的做法,因爲它響應用戶輸入時會不斷消耗更多堆棧。

下面是另一種方法,使用repeat/0謂詞以及fail/0repeat/0只是成功,它允許在回溯期間重新查詢解決方案。並且fail/0總是失敗,這會強制回溯。這是執行連續重複循環的常用方法,並且適用於在菜單上循環。我還調整了nl/0的用法,使輸出稍微整齊一些,我將其重命名爲time/2,因爲它名稱太泛化,可能會與系統謂詞發生衝突。

item_time(office_hour,1). 
item_time(office_hour,2). 

menu1 :- 
    repeat, 
    nl, write('Input time'), nl, 
    read(Y), 
    item_time(Y, X), 
    write(X), nl, 
    fail. 

這將產生:

| ?- menu1. 

Input time 
office_hour. 
1 
2 

Input time 
foo. 

Input time 
... 

這裏會發生什麼事是fail/0將導致謂語從句通過write(X), nl並向time(Y, X)將拿出替代解決方案原路返回,在那些成功解決方案,然後再轉到write(X), nl。如果time(Y, X)找不到更多的解決方案,那麼它最終會失敗,並且該子句一路回溯到調用始終成功的repeat/0。這導致執行再次前進到nl, write('Input time'), ...。如你所見,輸入一些無法識別的東西只是重新提示。爲了使這個更完整,你可以添加被認爲是「相當」的原子,如果你輸入的數據不存在於你的數據庫中,你可以編寫一個診斷信息。這對於學習來說是一個很好的練習。

+0

我可以知道'失敗/ 0'是做什麼的嗎? 我google了一下,它說'總是失敗'... – Kimchi

+0

你已經注意到謂詞可能失敗?就像如果你用'office_hour'以外的東西調用'time/2'作爲第一個參數。就像那樣,但與變量無關。它總是失敗。如果您希望在故障發生之前執行一些諸如打印等副作用,這很有用。 –

+0

@Kimchi我增加了我的答案,解釋失敗一點。普通的Prolog模式是「重複失敗循環」。 – lurker

0

第二個問題:

menu1 :- 
    write('Input time'),nl, 
    read(Y),nl, 
    (time(Y,X) -> 
    write(X),nl 
    ; write('bad input'),nl), 
    menu1. 
+0

'(時間(Y,Z) - > ...)'實際上做了什麼? 我的意思是括號 – Kimchi

+0

If-then-else,試試閱讀說明書:) –

+0

如果我只是寫'time(Y,X) - > write(X),nl ;寫('壞輸入'),沒有括號的nl'? 我知道' - >'表示if-then-else – Kimchi