2009-12-17 6 views
5
내가 목록에서 인스턴스의 수를 믿는다

...프롤로그 : (고정 여러 답변

count(_,[],N,N). 
count(Elem,[Elem|List],N,M) :- !, N1 is N+1, count(Elem,List,N1,M). 
count(Elem,[_|List],N,M) :- count(Elem,List,N,M). 

그래서, 내가 프롤로그이 최대 두 가지 방법을 썼다 (? 컷을 사용하여), 그리고 첫 번째 작품 위의)하지만, 왜 두 번째 나던 (또는 오히려, 나에게 여러 답변을 줄 것입니다 궁금 해서요 - 첫 번째 만 정확합니다) 왜 이것이지?

많은 감사

count(Z,X,R) :- count2(Z,X,R,0). 
count2(W,[H|T],L,A):- (W == H), Lnew is A+1, count2(W,T,L,Lnew). 
count2(W,[H|T],L,A):- count2(W,T,L,A). 
count2(W,[],A,A). 

답변

0

귀하의 질문은 대답 ... 컷이 포함되어 있습니다. 절단은 항상 성공하고 파생 트리를 "절단"하는 부작용이 있습니다. 기본적으로 컷을 되돌릴 수는 없습니다.

첫 번째 예는 목표가 두 번째 규칙과 통합되면 컷을 실행합니다. 어떤 의미에서 그 선택은 고정됩니다. 실패 나 역 추적이있는 경우 컷을 넘기지 않아 여러 답변이 삭제됩니다. 답변이 상호 배타적 인 경우 컷이 유용합니다. 즉, 첫 번째 대답을 찾으면 다른 사람들은 의미가 없습니다.

+0

나는 컷으로 두 번째 시도했다 : count (Z, X, R) : - count2 (Z, X, R, 0). W, [H | T], L, A) : -!, (W == H), Lnew는 A + 1, count2 (W, T, L, Lnew)입니다. 카운트 2 (W, [H | T], L, A) : - count2 (W, T, L, A). count2 (W, [], A, A) 하지만이 코드는 작동하지 않는 것 같습니다. 그래서 코드에 근본적으로 결함이 있다고 생각합니다. –

-1

알아 들었어! 당신은 내가 컷을 방문했다 -

count(Z,X,R) :- count2(Z,X,R,0). 
count2(W,[H|T],L,A):- (W == H), !, Lnew is A+1, count2(W,T,L,Lnew). 
count2(W,[H|T],L,A):- count2(W,T,L,A). 
count2(W,[],A,A). 

감사 빈센트 :

여기에서 작동하는 솔루션입니다!

+0

해결책이 있습니까? 아니! '(!)/0'을 사용하면 해로운 영향을 관찰 할 수 있습니다. 코드가 정확하다는 프로그래머의 확신을 높이는 동시에 (동시에) 코드가 부서 지거나 수리의 가능성을 뛰어 넘어 깨지게 만듭니다. – repeat

2

두 번째 시도가 여러 가지 해결책을 제시하는 이유는 두 번째 count2 절이 W와 H가 같은 값을 갖는 것을 막지 않기 때문입니다. 따라서 count2의 첫 번째 절이 성공하더라도 두 번째 절에서 다시 추적하고 성공할 수 있습니다.

Vincent Ramdhanie가 말한 것처럼 커트를 사용하여이 문제를 해결할 수 있습니다. 또는 커팅을 사용하지 않으려면 두 번째 절에 명시 적으로 체크를 추가하여 W와 H가 통합되지 않도록 할 수 있습니다.

count(Z,X,R) :- count2(Z,X,R,0). 
count2(W,[W|T],L,A):- Lnew is A+1, count2(W,T,L,Lnew). 
count2(W,[H|T],L,A):- W \= H, count2(W,T,L,A). 
count2(_,[],A,A). 

또한 첫 번째 count2 절은 이제 암시 적 통합을 사용합니다. 명백한 수표보다는. 내 의견으로는 조금 더 짧고 읽기 쉽습니다. 물론 통일 이라기보다는 평등을 사용하는 이유가 없다면 말입니다.