2017-01-11 1 views
1

this question on an empty list as a difference list을 작성할 때 이러한 구조를 알고 있는지 테스트하고 싶습니다. 그러나 다른 표기법을 비교하는 것만 큼 간단하게 시도했을 때 내가 틀렸다고 생각했고 이 아니고은 실제로 차이 목록으로 무엇이 진행되는지 이해합니다.Prolog 인터프리터에서 차이 목록을 사용하는 방법

?- L = [a,b,c|[d,e]]-[d,e], L = [a,b,c]. 
false % expected true 

나는 이것을 SICStus뿐만 아니라 SWI-Prolog에서도 테스트했습니다. 이 표기법은 Bratko의 Prolog Programming in AI,210 페이지에 쓰여졌 기 때문에이 표기법을 검증했지만 명백하게 통일은 불가능합니다. 왜 그런가요? 이 표기법은 같은 선언적 의미를 가지고 있지 않습니까?

+2

해당 섹션을 읽는 열쇠는 * 표현 *이라는 단어입니다. 책을 살펴보면, 예제가 최상위 레벨 인 AKA 인터프리터와 함께 사용될 수있을 때 접두사 앞에 '?'가 붙습니다. 예를 들어, [a, b, c] - [] 또는 [a, b, c, d, e] - [d, T] - [d, e | T] 또는 [a, b, c | T] -T 여기서 T는 임의의리스트이다. 최상위 수준에서 실행하지만 예제는 * 당신이 생각해야하는 것을 나타 내기 때문에 최상위 수준에서 입력으로 사용할 때의 오류입니다. –

+1

'L '은'[a, b, c | [d, e]] - [d, e]'와'[a, b, c]'둘 다 될 수 없습니다. 이들은 두 개의 다른 구조입니다. – lurker

+0

@lurker 나는 지금 그것을 볼 수 있지만 의견에 분명히 나와 있듯이 차이점 목록의 실용적인 이점을 볼 수없는 이유 일 것입니다. 연결된 목록을 사용하려면 Willem Van Onsem에서 제안한대로 * 마무리 단계가 항상 필요합니다. –

답변

3

당신은 Prolog 인터프리터가 차이 목록을 특별한 것으로 취급한다고 생각합니다. Prolog는 차이 목록 (또는 구문 설탕을 제외한 거의 모든 개념의 개념)을 인식하지 못합니다. 그는 단지보고 :

L=-(|(a, |(b, |(c, |(d, |(e, []))))), |(d, |(e, []))) 
-/2|/2이 펑터이다

a, b, c, d, e[]는 상수이다.

차이리스트는 단순히 프로그래밍 기술 있습니다 (예를 동적 프로그래밍뿐만 아니라 기술처럼, 컴파일러는 감지도 다르게 동적 프로그래밍 프로그램을 취급 할 수 없음). 표현식의 깊숙이 부분적으로 통일되지 않은 부분을 효율적으로 통합하는 데 사용됩니다.

append/3 두 개의 목록이 필요하다고 가정 해보십시오.

%append(A,B,C). 
append([],L,L). 
append([H|T],L,[H|B]) :- 
    append(T,L,B). 

을하지만이 O (n)이에서 실행 : 다음과 같이이 작업을 수행 할 수 있습니다 먼저 전체 첫 번째 목록을 반복해야합니다. 그 목록에 수천 개의 요소가 포함되어 있다면 많은 시간이 걸릴 것입니다.

이제

당신은 당신이 append_diff/3 목록뿐만 아니라 공급합니다 자신 계약,하지만 List 목록의 시작 부분에 대한 참조입니다 튜플 -(List,Tail)을 정의 할 수 있으며, Tail는 말에 대한 참조입니다 통합 목록이 아닙니다. 이 요구 사항을 충족시키는 구조의 예는 Tail-Tail, [a|Tail]-Tail, [1,4,2,5|Tail]-Tail입니다.

이제 효과적으로 할 수 append_diff/3에서 O (1)와 :

append_diff(H1-T1,T1-T2,H1-T2). 

이유는 무엇입니까? 첫 번째 목록의 통합되지 않은 꼬리를 두 번째 목록과 통합하기 때문입니다. 이제 두 번째 목록의 일치하지 않는 꼬리가 최종 목록의 꼬리가됩니다.그래서 예를 들어 가지고 : 위에서 보는 바와 같이 우리는 또한 T2에 대한 참조를 갖고 있기 때문에

append_diff([a|T1]-T1,[1,4,2,5|T2]-T2,L). 

을 술어를 호출하면, T1는, 이제 첫 번째 목록은 [a|[1,4,2,5|T2]] 이하 [a,1,4,2,5|T2]에 붕괴, [1,4,2,5|T2]로 통합됩니다, 우리는 "프롤로그에서 아무것도 으로 반환되었습니다", "[a,1,4,2,5|T2]-T2"을 반환 할 수 있습니다 : 열린 꼬리가있는 새로운 차이 목록 T2. 당신은 특별한 의미를 자신-을 제공 때문에 그러나 이것은 단지입니다 : 프롤로그 - 단순히 -입니다, 그것은하지 마이너스, 그것은 계산하지 않는 차이 등 프롤로그 펑에 의미를를 첨부하지 않습니다. - 대신 +을 사용했다면 그다지 큰 차이가 없었을 것입니다.

다시 질문에 답하십시오 : 당신은 단순히 L = -([a,b,c,d,e],[d,e]) 이상상태라고 Prolog에 상태. 이제이 두 표현식이 통일 될 수 없음이 분명합니다. 그래서 Prolog는 false라고 말합니다.

+0

이제는 통합되지 않는 이유를 이해하지만 어떻게 append_diff/3을 이해할 수 없습니까? 실제로 유용 할 것이다. 내 말은, 그것이 당신이 appending하는 방법이라면 결과는'[a, 1,4,2,5 | T2] -T2'가 될 것입니다. '[a, 1,4,2,5]'와 같이 원하는 가치가 아직 없습니다. 맞습니까? –

+0

@BramVanroy : 여러분은 diff리스트를 "finalize"하는 술어'finalize (A - [], A). '를 정의 할 수 있습니다. 그런 다음'finalize ([a, 1,4,2,5 | T2] -T2, Result) '를 호출하면 결과가'[a, 1,4,2,5]'가됩니다. 그러나 전에 말했듯이, 데이터를 어떻게 해석 할 것인가는 모두 문제입니다. '[a, 1,4,2,5 | T2] -T2'를'[a, 1,4,2,5]'와 같은 목록 *으로 해석 할 수 있습니다. –

+0

하지만 Prolog는 그와 같은 구조를 해석하지 않으므로'finalize/2' 단계는 실행 가능한 연결 목록이 필요합니다. 맞습니까? 예를 들어 [a, b] 및 [c, d]를 추가하려고합니다. 제안 된 솔루션 : conc_d ([a, b | T] -T, [d, e | T1] -T1, L). 그러나 결과는'L = [a, b, c, d | T1] -T1'을 사용하지만, 프로그래머로서'[a, b, c, d]'가 필요합니다. 요점을 놓치고 있다는 느낌이 들지만 실용적인 이점을 보지 못하거나 실제로 차이점 목록을 사용하는 방법을 보지 못합니다. –

관련 문제