이것은 min()
숫자 목록에서 가장 작은 요소를 찾아야하는 Prolog의 내 기능입니다. 내 아이디어는 Result
목록의 모든 요소보다 작거나 같은지 테스트하는 것이 었습니다 . 목록의 헤드는 비워 질 때까지 제거됩니다. 이 지점에 도달하면 설정된 결과가 정확합니다.
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
SWI-Prolog에서이 파일을 참조 할 때 값이 min([5, 3, 7, 6], 3)
true를 반환 하는 최소 요소인지 테스트 할 수 있습니다 . 그러나 min([5, 3, 7, 6], X)
A의 값을 찾을 수없는 X
그러나 다만 반환 true
.
값을 찾으려면 어떻게해야 X
합니까?
추적을 켜면 스크립트의 문제점을 볼 수 있습니다.
1 ?- trace.
true.
원래 버전 :
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
산출:
[trace] 2 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G4129) ? creep
Call: (7) _G4129=<5 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (7) _G4129=<5 ? creep
정리되지 않은 변수를 5와 비교하려고합니다. 해결 방법 : 비교 전에 변수가 인스턴스화되도록 스크립트에서 줄을 바꿉니다.
/** Version 1 */
min([], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
산출:
[trace] 5 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G517) ? creep
Call: (7) min([3, 7, 6], _G517) ? creep
Call: (8) min([7, 6], _G517) ? creep
Call: (9) min([6], _G517) ? creep
Call: (10) min([], _G517) ? creep
Exit: (10) min([], _G517) ? creep
Call: (10) _G517=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G517=<6 ?
[trace] 102 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G3067) ? creep
Call: (7) min([3, 7, 6], _G3067) ? creep
Call: (8) min([7, 6], _G3067) ? creep
Call: (9) min([6], _G3067) ? creep
Call: (10) min([], _G3067) ? creep
Exit: (10) min([], _G3067) ? creep
Call: (10) _G3067=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G3067=<6 ?
이런 식으로 스크립트는 조금 더 진행되지만 꼬리의 최소값을 계산할 때 비정상적인 변수와 다시 비교됩니다. 해결 방법 : 변화 min([], Result).
에 min([Result], Result)
.
/** version 2 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
산출:
[trace] 8 ?- min([5,3,7,6],3).
Call: (6) min([5, 3, 7, 6], 3) ? creep
Call: (7) min([3, 7, 6], 3) ? creep
Call: (8) min([7, 6], 3) ? creep
Call: (9) min([6], 3) ? creep
Call: (10) min([], 3) ? creep
Fail: (10) min([], 3) ? creep
Fail: (9) min([6], 3) ? creep
Fail: (8) min([7, 6], 3) ? creep
Fail: (7) min([3, 7, 6], 3) ? creep
Fail: (6) min([5, 3, 7, 6], 3) ? creep
false.
이제 프로그램은 거짓 만 반환합니다. 꼬리의 최소값이 머리보다 작거나 같은 경우 만 고려하기 때문입니다. 이 프로그램은 입력 목록이 감소하여 정렬 될 때만 올바른 결과를 반환합니다 (따라서 꼬리의 최소값이 재귀 적으로 머리보다 작음).
[trace] 10 ?- min([5,4,3,2],X).
Call: (6) min([5, 4, 3, 2], _G2469) ? creep
Call: (7) min([4, 3, 2], _G2469) ? creep
Call: (8) min([3, 2], _G2469) ? creep
Call: (9) min([2], _G2469) ? creep
Exit: (9) min([2], 2) ? creep
Call: (9) 2=<3 ? creep
Exit: (9) 2=<3 ? creep
Exit: (8) min([3, 2], 2) ? creep
Call: (8) 2=<4 ? creep
Exit: (8) 2=<4 ? creep
Exit: (7) min([4, 3, 2], 2) ? creep
Call: (7) 2=<5 ? creep
Exit: (7) 2=<5 ? creep
Exit: (6) min([5, 4, 3, 2], 2) ? creep
X = 2 .
따라서 다음 절을 추가하여 꼬리의 최소값이 머리보다 엄격하게 큰 경우를 처리해야합니다.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
그리고 여기에 최종 버전이 있습니다.
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
(로 추적 해제 nodebug.
)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다