2014-09-21 2 views
0

프롤로그 규칙을 한 번만 실행하는 방법이 있습니까? 예를 들어 , 나는이 알고리즘을 복사하는 제 목록 1에서 목록 2에 대한 모든 n 번째 요소 :프롤로그를 한 번만 실행하십시오.

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

+0

지원 술어를 사용할 수없고, append와 length 만 사용할 수 있습니다. – user3614293

+1

그런 다음 규칙을 교환하십시오. 'EveryNth (every (N), List1, List2) : -'는 필요할 때만 실행됩니다. – CapelliC

관련 문제