這裏有幾個問題。首先,Prolog原子總是小寫或引號; Billy
和Fernando
等是變量,這可能不是你想要的,所以你需要解決這個問題。
其次,有一些混亂的代碼在這裏:「我有一個數字,[900,1000,1100,1200]
的列表,ziekte(V1,_)
是它」
Appointments = [0900,1000,1100,1200],
member(ziekte(Billy,_),Appointments),
你是說這裏有什麼,這顯然是錯誤的 - 這個列表中沒有ziekte/2
結構。
我懷疑你可能患有開始Prolog程序員最常見的疾病:相信Prolog關係「返回」的價值。你認爲ziekte(Billy,_)
會以某種方式導致ziekte/3
在下面被調用,並且不知何故關係的第三個參數會出現在這個位置?它不會 - 結構ziekte(_,_)
和下面定義的謂詞ziekte/3
之間沒有關係,並且Prolog不會評估像這樣的嵌套表達式。
member(X, List)
是做什麼用的?它嘗試統一X
與每個值List
。假設你有一個看起來像L = [appointment(zachary,back-pain,1100), appointment(steven,X,Y), appointment(Z,heartburn,900), ...]
的列表。 member(appointment(billy,Ailment,900), L)
做什麼?它試圖統一:
appointment(billy,Ailment,900) = appointment(zachary,back-pain,1100)
fails
appointment(billy,Ailment,900) = appointment(steven,X,Y)
fails
appointment(billy,Ailment,900) = appointment(Z,heartburn,900)
succeeds with
Ailment = heartburn
Z = billy
如果你覺得這個令人驚訝,你需要更加努力地思考統一!
你有無限遞歸的原因是因爲你的謂詞ziekte/3
自己調用。看看跟蹤:
trace, ziekte(X,Y,Z).
Call: (8) ziekte(_G4078, _G4079, _G4080) ?
Call: (9) _G4239=[900, 1000, 1100, 1200] ?
Exit: (9) [900, 1000, 1100, 1200]=[900, 1000, 1100, 1200] ?
Call: (9) lists:member(ziekte(_G4232, _G4233), [900, 1000, 1100, 1200]) ?
Fail: (9) lists:member(ziekte(_G4232, _G4233), [900, 1000, 1100, 1200]) ?
Redo: (8) ziekte(_G4078, _G4079, _G4080) ?
Call: (9) ziekte(_G4230, _G4231, _G4232) ?
Call: (10) _G4242=[900, 1000, 1100, 1200] ?
Exit: (10) [900, 1000, 1100, 1200]=[900, 1000, 1100, 1200] ?
Call: (10) lists:member(ziekte(_G4235, _G4236), [900, 1000, 1100, 1200]) ?
Fail: (10) lists:member(ziekte(_G4235, _G4236), [900, 1000, 1100, 1200]) ?
Redo: (9) ziekte(_G4230, _G4231, _G4232) ?
Call: (10) ziekte(_G4233, _G4234, _G4235) ?
Call: (11) _G4245=[900, 1000, 1100, 1200] ?
Exit: (11) [900, 1000, 1100, 1200]=[900, 1000, 1100, 1200] ?
Call: (11) lists:member(ziekte(_G4238, _G4239), [900, 1000, 1100, 1200]) ?
Fail: (11) lists:member(ziekte(_G4238, _G4239), [900, 1000, 1100, 1200]) ?
Redo: (10) ziekte(_G4233, _G4234, _G4235) ?
這裏發生的事情是這樣的:你想進入ziekte(X,Y,Z)
。 Prolog發現第一個子句,即頭部爲ziekte(X,Y,Z)
的子句。它立即形成預約時間列表。然後檢查它是否存在ziekte/2
結構。這失敗了。 Prolog回溯並嘗試下一個子句:頭部爲ziekte(_,back-pain,Y)
的那個。本節正文中的第一個表達式是ziekte(Zachary,_,X)
。我們再次發現:Prolog找到了ziekte
的第一個子句,我們馬上回到了開始的地方。
現在你還有其他問題。注意你會得到很多單體變量警告。開始將這些視爲致命錯誤。
你對我的規則條款看起來很奇怪。我不知道他們怎麼可能工作,坦率地說。
我覺得你很迷茫!我強烈建議您查看Prolog的基礎知識。除非你使用Prolog,否則你不能僞造它,它確實與其他所有東西完全不同!
如果我是你,我會先用patient/1
,time/1
和ailment/1
這些事實來映射出域名。我在我的解決方案中大量使用了select/3
,所以我會對其進行審查。還有plus/3
。確保你對結構之間的差異(和相似之處)有一個具體的理解 - 當評估發生時和不發生時。然後回來再試一次!
編輯:對pastebin代碼的評論。
你的粘貼代碼的主要問題是你試圖用sublist/2
產生排列,但它做的是給你有序的子集。你第一次通過你已經產生了一個解決方案集,失敗了,然後你花了你的餘下的時間在sublist/2
。
檢查了這一點:
?- ziekte(Y), sublist([Y1,Y2,Y3,Y4], Y).
Y = [backpain, heartburn, hippain, shingles],
Y1 = backpain,
Y2 = heartburn,
Y3 = hippain,
Y4 = shingles ;
false.
這隻有一個解決辦法,所以你只有真正嘗試一次置換。當你用member([billy,_,Tijd1], Opl)
打線時,你已經設置了Opl = [[billy, backpain, 900], [fernando, heartburn, 1000], [steven, hippain, 1100], [zachary, shingles, 1200]]
。如果您使用某種方法來排列列表以生成不同的分配,但這樣做會很好,但前面的sublist/2
調用沒有更多的解決方案,因此不會有任何其他分配給X1..X4,Y1..Y4,Z1 .. Z4,所以你失敗了,因爲你生成的唯一解決方案不成功。
非常感謝,我從一個解決方案的一般結構到一個不同的問題(類似的結構問題,但關於與寵物的房子)..我會採取你的建議的心臟,並從我這一次從頭開始,謝謝再次。 – Neverendingsearch
嘿丹尼爾里昂,在另一個試圖把握prolog我試圖重做作業(http://pasted.co/4d6de449)..而雖然(我認爲)我越來越接近解決方案(很大程度上感謝你,再次感謝)我現在有一個問題,太多Billies來了(我認爲這與第一個和第三個技巧是關於比利有關)。如果你能找到時間再次照亮你的光芒,我將永遠如此肆意。 – Neverendingsearch
我已經編輯了我的答案,並對您的新代碼進行了一些討論。 –