2013-10-27 2 views
2

몇 가지 사실을 기반으로 프롤로그를 사용하여 가장 오래된 사람을 찾아야합니다. 예를 들어 다음과 같이프롤로그에서 가장 오래된 사람 찾기

?- oldest(rose). 
True. 

?- oldest(X). 
X = rose. 

내 코드는하지만, 제대로 동작하지 않습니다 :

age(john, 10). 
age(mary, 15). 
age(rose, 75). 
age(jack, 49). 
age(carl, 17). 
age(lucy, 66). 

콘솔 출력해야

oldest(P) :- age(P, X) , age(_, Y) , X >= Y. 

내가 오류를 찾을 수 없습니다,하지만 난 그것이 역 추적과 관련된 것이라고 생각해보십시오. 누군가 날 도와 줄 수 있니? 나는 프롤로그에게 새로운 사람이다.

답변

2

올바른가 수익률 물론, 증가했다고

oldest(P) :- age(P, X) , \+ (age(_, Y) , Y > X). 

해야 ...

(\+)/1 다음은

다른 방법은 오래된 사람을 찾을 수있다 목표), '목표에 대한 해결책이없는 경우 실패'를 의미합니다.

SWI - 프롤로그 편집는, 라이브러리 (aggregate가) ...

oldest(P) :- aggregate(max(A,Pers), age(Pers,A), max(_,P)). 
+0

감사합니다. 하지만이 정의와 내 차이점은 무엇입니까? 왜 이거 작동합니까? – renatov

+1

당신의 코드는 글자 그대로'가장 오래된 '술어를 읽으면 * 거의 * 하나 더 젊은 사람이 첫 번째 사람을 찾는다 – CapelliC

+1

@renatov'가장 오래된'술어를 문자 그대로 읽으면''P''가 가장 오래된 것입니다 ** **''X''가' P' *와 * 나이가'Y', *,'Y'가'X'보다 작거나 같은 사람이 있습니다. 'P'보다 더 어린 사람이 한 명이라면 성공할 것입니다. 그것은 * 다른 모든 *이 더 젊어 야한다는 제약을 확립하지 않습니다. – lurker

1

oldest/1 정의가 유효하지 않습니다. (CapelliC의 답변에 왜 및 어떻게 수정해야하는지 나와 있습니다.) (not과 같이

oldest(X) :- 
    findall((Age, Name), age(Name, Age), List), 
    sort(List, SList), 
    reverse(SList, [(_, X) | _]). 
+0

덕분에 훨씬 더이 작업을 수행 할 수 있습니다, 그것은했다. 그러나 그 일을하는 데 더 간결한 방법이 있습니까? 아, 왜 가장 오래된/1에 대한 나의 정의가 유효하지 않습니까? – renatov

관련 문제