2011-09-25 2 views
1
append([],Xs,Xs). 
append([Head|Tail],List2,[Head|Tail2]):- 
    append(Tail,List2,Tail2). 

상위 추가 방법은 처음 두 매개 변수 슬롯의 요소를 세 번째 매개 변수에 추가합니다.목록 요소를 추가하는 프롤로그 방법을 이해하는 데 도움이 필요합니다.

?-append([2,1], [3,4], X). 
?-X=[2,1,3,4] 

전 단계에서 볼때는 (propably 잘못이다) 인 ->

  1. APPEND (2 | [1], [3,4], 2 | X)
  2. APPEND ([1], [3,4], X)

  3. APPEND (1 | [] [3,4] 1 | X)

  4. APPEND ([] [3,4 ], [3,4])

그게 전부입니다. 필자는 요소를 더하는 방법에 대해 머리를 감쌀 수 없으며,이 방법이 어떻게 작동하는지에 대한 명확한 설명이 도움이 될 수 있습니다. 나는 [2,1] 배열이 어떻게 최종 결과에 추가되는지 이해하지 못합니다. 재귀의 X

답변

3

당신이

append(2 | [1], [3,4], 2 | X1) -- X = [2|X1] 

append([1], [3,4], X1) 

append(1 | [], [3,4], 1 | X2) -- X1 = [1|X2] 
append ([], [3,4], [3,4]) -- X2 = [3,4] 

그래서 X1 = [1,3,4]X = [2,1,3,4]

1

먼저 볼 수 추적에 이름을 바꾸면 원래 통화와 동일 X하지 않습니다, 당신은에 있습니다 Prolog에서 목록이 어떻게 구현되는지 이해한다. 본질적으로 재귀적인 데이터 구조입니다.

  • 빈 목록은으로 표시되는 0 개 항목의 목록입니다.
  • 비 빈리스트가리스트의 헤드의 (a 프롤로그 용어)로 구성된 구조 ./2로 표시되며,리스트의 꼬리 (모든 항목이 구성된 다른리스트는 제 저장) . 그럼

    • [] — 제로 항목의 목록이 표시된다
    • [a]
    • []
      으로 1 개 항목들의리스트가, 2 개 항목
    • [a,b]
    • .(a,[])
      같은 목록을 나타낸다
      .(a,.(b,[]))
    • [a,b,c] — 3 개의 항목의 목록은
      .(a,.(b,.(c,[])))

대괄호를 사용하여 표준 목록 표기법이 표현의 상단에 단지 문법 설탕입니다. [Head|Tail].(Head,Tail)을 말하는 예의이며 [X,Y,Z|More]은 공손한 말로 .(X,.(Y,.(Z,More)))입니다. (당신은 확실한 것을 알 것입니다 .... Lisp-ishness ... 여기에 내부 목록 표기법에.)

목록이 표시되는 방식을 이해, 다른() 연접 한 목록을 추가하기위한 순진 알고리즘은 이것이다 : 고려해야 할 두 가지 특별한 경우가

먼저이 있습니다 :

  • 비어 있지 않은 목록 X를 빈 목록 Y에 추가 한 결과는 X입니다.
    [1,2,3][]에 붙이고 [1,2,3]을 얻습니다. 참고.이 경우는 아래의 일반적인 경우로 처리 할 수 ​​있습니다 (일반적으로). 전체 목록을 재귀 적으로 반복 할 필요가 없으므로 결국에는 [][]으로 바꿔 최적화 할 수 있습니다.

  • 추가] [] [1,2,3]에 Y는 Y를
    있는 비어 있지 않은 목록에 빈 목록 X를 추가 한 결과 당신은 [1,2,3]를 얻을.

그렇지 않으면, 우리는 보통의 경우가 있습니다

  • 이 사소한하려면 목록 Z.을 생산하는 비어 있지 않은리스트 X에

    추가] 비어 있지 않은리스트 Y :

    우리는 목록 X를 간단하게 되풀이하여 우리가 가서 머리를 터뜨린 다음 그 결과를 Z로 표시합니다. 이 경우 마지막 목록은 []이 아닌 항상 언 바운드이므로 목록 Z는 깨진 목록 구조임을 알 수 있습니다. 이것은 근원 목록, 목록 X가 다 써 버렸을 때 끝까지 고쳐지고 빈 목록 인 특별한 경우로 변질됩니다. 이 시점에서 바인딩되지 않은 마지막 노드는 Y 목록 (0 개 이상의 노드 목록)과 통합되어 올바른 목록 구조를 유지하면서 바인딩됩니다.

append/3의 프롤로그 코드는이 알고리즘을 직접 표현합니다. 앞에서 언급했듯이 첫 번째 절은 선택적인 최적화로, 세 번째 절 (일반 경우)에서 처리 할 수 ​​있습니다. 그렇다고해도, 되돌림은 두 가지 해결책을 제시 할 것입니다.

append(X  , [] , X  ) :- !. ; concatenate empty list X to list Y producing Y 
append([]  , Y , Y  ).  ; concatenate list X to empty list Y producing X 
append([X|Xs] , Y , [X|Zs]) :- ; anything else 
    append(Xs , Y , Zs) 
    . 
관련 문제