2012-10-24 4 views
3

다음과 같은 오류 구동 루프를 사용하여 세미콜론을 사용하지 않고 모든 것을 나열합니다. 프롤로그 : 오류 구동 루프

?- someGoal(_). 
5 3 2 

가 어떻게 그들이 화면을 쓰기보다는리스트에이 번호를 삽입 할 수 있습니다

예상대로 쿼리 모드에서

happiness(fred,5). 
happiness(john,3). 
happiness(grace,2). 

someGoal(X) :- 
     happiness(X,Y), write(Y), tab(4), fail. 

,이 얻을? 역 추적이 암시적인 것처럼 보였으므로 someGoal 내에 처리 할 수 ​​없습니다.

답변

4

당신이 맞습니다. 다시 프롤로그가 대안을 처리하는 방식입니다.

someGoal(X, Values) :- 
    findall(Value, happiness(X, Value), Values). 

그런 ?- someGoal(_, Values). 것이다 인스턴스 값 = [5, 3, 2]

+0

고맙습니다. 다른 방법을 시도해 보았지만 프롤로그 기술을 구축했습니다. P – Zoran

4

실패 중심의 루프 자주 : '내부적으로'되돌아을 사용 모든 대안을 수집

사용 findall/3, 특정 부품을 열어 두거나 지정하지 않으면 조만간 문제가 발생할 수 있습니다. 특히 변수의 정확한 양을 쉽게 공개 할 수 있습니다. Often, such loops can be avoided alltogether. 귀하의 예제에서는 왜 내가 someGoal/1에 대한 논쟁을 가지고 있는지 분명하지 않습니다. 적어도 당신은 그것을 사용하지 않습니다. 따라서 몇 가지 질문이 생깁니다 :

  1. 일치하는 값이 없으면 어떻게 될까요? 원본 프로그램이 아무 것도 인쇄하지 못하고 실패합니다.

  2. 중복 입력이 있다면 무엇을 기대합니까? 물건을 여러 번 인쇄하고 싶습니까?

  3. 정확한 값의 순서를 고집하거나 다른 순서를 상상할 수 있습니까?

  4. 왜 값을보고 싶습니까? 대개의 경우 구체적인 이름과 관련된 것을 보거나 합계 또는 평균과 같은 집계를 원합니다.

이러한 답변을 모르는 경우 여러 솔루션을 제공 할 수 있습니다. 추가 (중복) 사실로 귀하의 모범을 보겠습니다 :

 
happiness(fred,5). 
happiness(john,3). 
happiness(john,3). 
happiness(grace,2). 

?- setof(P-H,happiness(P,H), PHs). 
PHs = [fred-5, grace-2, john-3]. 

?- setof(H,P^happiness(P,H), PHs). 
PHs = [2, 3, 5]. 

?- bagof(H,P^happiness(P,H), PHs). 
PHs = [5, 3, 3, 2]. 
+0

사례 연구와 사례를 더 많이 알려 주셔서 감사합니다. 내 장난감 예제는 가독성을 위해보다 복잡한 모델에서 축소되었습니다. – Zoran