2014-09-21 60 views
0

有沒有辦法讓prolog規則只執行一次? 例如,我有這樣的算法,副本第一和每一個第n個元素從列表1到列表2:Prolog使規則執行一次

ith_element(N, List1, List2) :- 
    X is N - 1, 
    length(A,X), 
    append(A, [Head | Tail], List1), 
     everyNth(N, Tail, Rest -> 
     List2 = [Head | Rest] 
    ; List2 = [Head | []] 
    ). 

我能以某種方式使該會的第一要素,從列表1只複製一次的規則?我只是在學習Prolog,在任何地方都找不到類似的東西。

回答

1

我認爲你應該保持第一元素「打補丁」圈外:

firstAndEveryNth(N, [F|List1], [F|List2]) :- 
    everyNth(N, [F|List1], List2). 

編輯你可以編碼在參數進一步信息,當然,這是種「奇怪的黑客」

everyNth(N, [F|List1], [F|List2]) :- 
    integer(N), % or N \= every(_), 
    everyNth(every(N), [F|List1], List2). 

everyNth(every(N), List1, List2) :- 
    X is N - 1, 
    length(A, X), 
    ( append(A, [Head | Tail], List1), 
     everyNth(every(N), Tail, Rest) 
    -> List2 = [Head | Rest] 
    ; List2 = [] 
    ). 

編輯交換的規則,應該工作爲好,而不需要檢查的「型」 N個

everyNth(every(N), List1, List2) :- 
    !, % needed to avoid an error on backtracking 
    X is N - 1, 
    length(A, X), 
    ( append(A, [Head | Tail], List1), 
     everyNth(every(N), Tail, Rest) 
    -> List2 = [Head | Rest] 
    ; List2 = [] 
    ). 

everyNth(N, [F|List1], [F|List2]) :- 
    everyNth(every(N), [F|List1], List2). 
+0

這就是我會這麼做的,但目標是不使用輔助謂詞。這個問題正在把我推上牆。 – user3614293 2014-09-21 06:11:37

+0

不能使用任何支持謂詞,只能追加和長度。 – user3614293 2014-09-21 17:45:05

+1

然後交換規則。 'everyNth(every(N),List1,List2):-'只在需要時纔會觸發 – CapelliC 2014-09-21 17:53:18