2017-05-25 40 views
1

我學習序言和我被困在代碼中的知識基礎和基本規則是:Prolog的遞歸不工作的其他方式

rectangle(a1, 3, 5). %Name,Width,Height 
    rectangle(a2, 1, 2). 
    rectangle(a3, 4, 3). 

    calcWH(T,C) :- 
     rectangle(T,W,_), C is W. % finds the width of the rect. 

遞歸部分是:

calcWTH([],0). % Base case 
calcWTH([H | T ] ,K) :- 
    length([H|T],L), 
    L =< 3, 
    calcWTH(T,M), 
    calcWH(H,O), 
    K is O+M. 

我想用這個代碼做什麼,用calcWTH我想計算矩形列表的總寬度。例如,

calcWTH([a1,a2,a3],A) 

如預期的那樣返回8。我感到困惑的是,這個代碼只適用於一種方式,而不是其他方式。例如,當我做出這樣

calcWTH(A,3) 

查詢它首先發現A = [A1],則A = [A2,A2,A2〕,事後我希望程序停止,因爲部分length([H|T],L), L =< 3,但它無限期地進入一個循環。我在這裏錯過了什麼?

+2

'C是W'是多餘的。只需將'calcWH(T,W): - 矩形(T,W,_)'(如果你想更加冗長,你應該使用統一,'C = W'表達式評估'C是W')。另外,當對整數進行推理時,如果你想讓某件事情「以另一種方式工作」,你應該使用CLP(FD)而不是'is/2',所以'K#= O + M'。 – lurker

回答

1

想想這是做:

length([H|T],L), L =< 3 
  1. 做一個列表
  2. 檢查其長度小於3,如果是 - 那麼成功,其他明智回到軌道長度/ 2嘗試使另一個列表,然後檢查是否該列表是長度小於3

但我們知道,單/ 2在尺寸較大的順序創建列表, 所以我們知道,如果名單長度3失敗,然後在後面跟蹤創建的下一個列表 將更大,所有其他列表..但 prolog不知道。你可以想象寫一個長度爲 的謂詞,它可以按不同的順序搜索列表,也可以是 ,也可以是從預定義的大尺寸到更小的列表。 然後,我們希望回溯工作原樣。

無論如何,這就是爲什麼你得到無限遞歸,它會不斷嘗試新的列表,不斷增加的大小。

您可能會發現添加約束是來解決問題的好辦法:

Using a constrained variable with `length/2`

+0

感謝您的回答。我通過添加下面的謂詞來解決這個問題:'lengthP(L,K,B): - length(L,B); A是B + 1,A = shellnut