2014-11-03 27 views
1

我對Prolog完全陌生,很難理解它的統一系統。我的問題如下:序言:遞歸建立一個列表 - 無限的解決方案

我有一個約束整數,一個源數組和一個目標數組(它們都是整數數組)。我想過濾Source數組中的元素,以便其餘元素在Target數組中具有對應元素,以便Source數組中的元素與Target數組中的元素之間的差異完全是Constraint。

示例:Constraint = 1,Source = [1,5,7],Target = [2,3,4]。因爲abs(1 - 2)= 1和abs(5 - 4)= 1,所以FilteredSource應該是[1,5]。目標中沒有6或8,所以7是不好的。

根據我使用的參數,我要麼得到錯誤的結果,要麼查詢得到無限循環。

到目前爲止,我想出了這一點:

filterByDistanceConstraint(_Constraint, [], _Target, _). 

filterByDistanceConstraint(Constraint, [SourceHead|SourceTail], Target, FilteredSource) :- 
    filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource), 
    ( 
     passesDistanceConstraint(Constraint, SourceHead, Target) 
    -> 
     append(NewFilteredSource, [SourceHead], FilteredSource), 
     filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource) 
    ; 
     filterByDistanceConstraint(Constraint, SourceTail, Target, FilteredSource) 
    ). 

的passesDistanceConstraint部分似乎工作好,但我會在這裏包括以供參考:

passesDistanceConstraint(_Constraint, _SourceHead, []) :- 
    fail. 
passesDistanceConstraint(Constraint, SourceHead, [TargetHead|TargetTail]) :- 
    Distance is TargetHead - SourceHead, 
    ( abs(Distance) =\= Constraint %test failed 
    -> passesDistanceConstraint(Constraint, SourceHead, TargetTail) 
    ; write('Distance constraint passed for '), write(SourceHead), nl 
    ). 

我肯定這是一個微不足道的問題,但我無法弄清楚,我正在脫掉頭髮。謝謝你的幫助!

回答

0

這應該工作在第一條規則

filterByDistanceConstraint(_Constraint, [], _Target, []). 

filterByDistanceConstraint(Constraint, [SourceHead|SourceTail], Target, FilteredSource) :- 
    ( passesDistanceConstraint(Constraint, SourceHead, Target) 
    -> FilteredSource = [SourceHead|NewFilteredSource] 
    ; FilteredSource = NewFilteredSource 
    ), 
    filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource). 

注[],而不是_,那只有一個第二遞歸調用。

「過濾器」的編程模式是在SWI-Prolog的通過實施包括/ 3或排除/ 3,但在普通的Prolog寫,因爲構件/ 2能夠作爲「枚舉」起作用:

filterByDistanceConstraint(Constraint, Source, Target, FilteredSource) :- 
    findall(E, (member(E, Source), member(C, Target), abs(E - C) =:= Constraint), FilteredSource). 
+0

非常感謝。它工作得很漂亮! – jaga 2014-11-03 17:20:09