2014-05-22 1 views
14

목록에있는 요소의 수를 숫자로 계산하는 작은 프로그램을 작성하고 있습니다. 나는 다음과 같은 코드를 실행하면프롤로그 - 인수가 충분히 인스턴스화되지 않았습니다.

not_number([],0). 
not_number([X|T],R):- 
    not(number(X)), 
    R1 is R+1, 
    not_number(T,R1). 

not_number([_|Tail],Result):- 
    not_number(Tail,Result). 

:

?- not_number([1,2,3,5], R). 

내가 그 R = 0 (그것이 있어야로)

R = 0. 

하지만 경우를 얻고 다음은 내 코드입니다 목록에 등장 인물 :

?- not_number([1,2,3,5,a], R). 

다음이 오류가 발생합니다 :

ERROR: not_number/2: Arguments are not sufficiently instantiated 
    Exception: (10) not_number([a], _G247) ? 

누군가 코드에 무슨 문제가 있다고 설명 할 수 있습니까? 나는 프롤로그를 처음 보았습니다.

A는 우측 (B)에

모든 B에게 이미 알려져되어야이다

+9

'not_number ([a], R)'의 경우'R '이 인스턴스화되지 않은 경우'R1은 R + 1 '입니다. 귀하의 재귀 사례는 약간 거슬러 올라갑니다. 'not_number (T, R1), R은 R1 + 1'을 원한다. – lurker

+0

완벽하게 작동합니다! – Eddwhis

+0

[이 페이지] (http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse19)도'is' –

답변

9

최상의 대답은 comment에 의해 lurker에 있었기 때문에이 답변을 작성했습니다. 나는 그것을 실제 답변으로 보여주고 싶다.

R이 인스턴스화되지 않은 경우 R1 is R+1을 수행하기 때문에 코드가 작동하지 않습니다. 귀하의 재귀 사례는 약간 거슬러 올라갑니다. 이 작업을 수행 할 :가 호출 될 때

not_number([X|T],R):- 
    not(number(X)), 
    not_number(T,R1), 
    R is R1+1. 

가 지금 is의 오른쪽이 인스턴스화됩니다.

4

내 문제는 다음과 같이 산술적으로 계산한다는 것이다. 변수가 없습니다. (작동, 지금이 코드를 테스트)

not_number(X, Y) :- not_number(X, Y, 0). 
not_number([], Y, Y). 
not_number([H|T], Y, Z) :- 
    \+ (number(H)), 
    Z1 is Z+1, 
    not_number(T, Y, Z1). 

not_number([H|T], Y, Z) :- 
    number(H), 
    not_number(T, Y, Z). 

:

은 당신이 뭔가를 할 수 있습니다.

이제 세 번째 인수는 누적 계산기입니다. 그것은 얼마나 많은 숫자가 없는지를 세어 봅니다. 목록이 비어 있으면이 세 번째 인수는 두 번째 인수와 통합되어 올바른 대답이됩니다.

프롤로그는 기회가 주어지면 가능한 모든 경로를 통과합니다.

cat(adam). 
cat(eve). 

다음 질문 : 당신은 같은 것을 할 경우

?- cat(X). 

당신은 모두 답변을 얻을 수있다 : X = 아담과 X = 이브. 너무 코드에 적용 : 목록의 머리가 숫자가 아닌 경우, 당신은 여전히이 작업을 수행 할 수 있다는주의 사항 : 당신이 원하는 대답을하지 제공

not_number([_|Tail],Result):- 
    not_number(Tail,Result). 

합니다. 당신은 당신을 관심없는 노선을 차단해야합니다. 이 경우,이 요소가 숫자가 아닌 경우에만 우리는 1 카운터를 증가시키지 않으면 목록의 요소를 건너 뛸 수 있도록

number(Head). 

을 추가합니다.

다른 결과를 찾기 위해 프롤로그를 적용하려면 ";"을 눌러야합니다. (이 아담과 이브 예제에서와 같이) 키보드에서.

0

이러한 문제에 대한 일반적인 해결책은 제약을 사용하는 것입니다.

예를 들어, 사용자가 제약 조건 만 사용하면 예상대로 프로그램이 작동합니다. 나는 ISO-를 사용하는 코드를 변경 한 것이

 
?- not_number([1,2,3,5], R). 
R = 0. 

참고 :

:- use_module(library(clpfd)). 

not_number([],0). 
not_number([X|T],R):- 
    \+ number(X), 
    R1 #= R+1, 
    not_number(T,R1). 

not_number([_|Tail],Result):- 
    not_number(Tail,Result). 

샘플 쿼리 및 그 결과 : 간단하게 모든 방향에 작동 정수 연산을 얻기 위해 (#=)/2에 의해 (is)/2 교체 대신 not/1 대신 술어 (\+)/1을 입력하십시오.

+0

'? - not_number ([A, A, B], N) .'에는 하나의 해답 인'N = -3'이 있습니다. 그건 내게 맞지 않아. – repeat

+1

범인은? 물론 'number/1'은 유형을 테스트하면서 인스턴스화를위한 테스트를 혼합합니다. 해결 방법 :'\ + number (X) '대신'functor (X, _, _), \ + number (X)'를 사용하십시오. 아니면, 더 나은,'re_/3'과 올바른 reified 테스트 술어 ... – repeat

+0

매우 사실. 'must_be (nonvar, X)'를 제안합니다. OP가보고 한 근본적인 문제가 선언적 산술을 사용하여 해결되었으므로 이제이 추가 점을 논의 할 수 있습니다. – mat