2013-04-21 8 views
1

저는 프롤로그를 처음 사용하는데 이것에 대한 해답을 얻지 못했습니다.숫자와 문자 목록의 숫자 만 계산하십시오.

내가 원하는 것은 Prolog가 모든 요소가 아닌 목록에서 Number를 계산한다는 것입니다. 그래서 예를 들면 :

getnumbers([1, 2, c, h, 4], X). 

이 날을 주어야한다 :

X=3 

getnumbers([], 0). 
getnumbers([_ | T], N) :- getnumbers(T, N1), N is N1+1. 

내가있어 무엇인가, 그러나 그것은 분명 나에게 목록에있는 모든 요소를 ​​제공합니다. 나는 어떻게 그리고 어디에서 "카운트 번호"를 넣을 지 모른다.

답변

1

당신이 직접 수행하는 방법에 관심이 있다면 자신의 구현을 (SWI-Prolog에, 예를 들어) 내장 술어를 사용하고 검사를 고려 : 물론

include(number, List, Ns), length(Ns, N)

+0

아. 감사합니다. 그러나 내장 된 술어를 사용하지 않으려는 경우 올바른 방향으로 나를 안내 할 수 있습니까? 마찬가지로 기존 코드에 "only numbers"를 구현하십시오. 내가보기에 프롤로그와상의하는 동안 예를 들어 number/1을 사용할 수있는 것처럼 보입니다. 사실입니까? – Majusbeh

0

을, 당신은 확인해야합니다 조건을 만족하는지 확인하기위한 요소의 유형.

number/1 이것은 당신이 찾고있는 술어입니다.

재귀 절에서 사용할 if/then/else 구조체를 참조하십시오. 당신이 목록 (및 SWI - 프롤로그)로 작업 할 때, 당신이 발견 lambda.pl 모듈을 사용할 수 있습니다 평소처럼

0

이 번호/1 일치 프롤로그의 자연적인 패턴을 사용, 그리고 추가 조항 (아래 3)은 숫자가 아닌 사례를 처리합니다.

% 1 - base recursion 
getnumbers([], 0). 

% 2 - will pass ONLY if H is a number 
getnumbers([H | T], N) :- 
    number(H), 
    getnumbers(T, N1), 
    N is N1+1. 

% 3 - if got here, H CANNOT be a number, ignore head, N is unchanged, recurse tail 
getnumbers([_ | T], N) :- 
    getnumbers(T, N). 
+0

세 번째 절도 head *가 숫자 인 경우 일치합니다. – mat

+0

매트를 이해하지 못합니다. 만약 head가 숫자라면, 두 번째 규칙에 의해 잡힐 것이므로, 세 번째 규칙은 1..2..3 순서로 실행될 것이기 때문에 세 번째 규칙에 도달하지 못했습니다. – magus

+0

head가 숫자 인 경우 두 번째 규칙과 세 번째 규칙이 모두 적용됩니다. 역 추적 덕분에 두 가지 방법 모두 시도 될 것입니다. 예를 들어'? - getnumbers ([1])에서 프로그램을 시도 했습니까? – mat

0

문제는 이런 종류의 자주 프롤로그 관용구 첫 공개 소비에 대한 귀하의 조건을 정의하고, 그것은 '노동자'술어를 호출하는 것입니다. 종종 어떤 종류의 누적기를 사용할 것입니다. 문제의 경우, 공공 소비 술어는 같은 것입니다 : 그것은 꼬리 재귀 수 있도록

count_numbers(Xs , N) :- 
    count_numbers_in_list(Xs , 0 , N) . 

count_numbers_in_list([] , N , N) . 
count_numbers_in_list([X|Xs] , T , N) :- 
    number(X) , 
    T1 is T+1 , 
    count_numbers_in_list(Xs , T1 , N) 
    . 

당신은 재귀 비트를 구성 할 수 있습니다뿐만 아니라, 재귀 호출은 데이터 아무것도에 의존한다는 것을 의미 인수리스트 이렇게하면 컴파일러는 각 호출에서 기존 스택 프레임을 재사용 할 수 있으므로 사실상 재귀 적 대신 술어가 반복됩니다. 올바르게 tail-recursive 술어는 무한 길이 목록을 처리 할 수 ​​있습니다. 그렇지 않은 스택은 모든 재귀마다 새로운 스택 프레임을 할당 할 것이고 스택을 날릴 것입니다. 위의 count_numbers_in_list/3은 꼬리 재귀 적입니다. 이되지 않습니다 :

getnumbers([H | T], N) :- 
    number(H), 
    getnumbers(T, N1), 
    N is N1+1. 
1

그대로 논리적으로 순수, 그것은 쉽게 :

number_t(X,Truth) :- number(X), !, Truth = true. 
number_t(X,Truth) :- nonvar(X), !, Truth = false. 
number_t(X,true) :- freeze(X, number(X)). 
number_t(X,false) :- freeze(X,\+number(X)). 

이의이 실행하자 number_t/2 (number_truth/2의 줄임말)을 구체화 형식 시험 조건과 함께 협력하여 메타 조건 tcount/3를 사용하여 OP 추천 검색어 :

 
?- tcount(number_t,[1,2,c,h,4],N). 
N = 3.          % succeeds deterministically 

가변 단조 지연은 항상 l입니다. 끔찍한 소리.고려 : 마침내

 
?- tcount(number_t,[A,B,C,D,E],N), A=1, B=2, C=c, D=h, E=4. 
N = 3, A = 1, B = 2, C = c, D = h, E = 4 ; % succeeds, but leaves choice point 
false. 

, 우리는 다음과 같은 매우 일반적인 질의의 답변 중 일부에서 들여다 보자 놀랍게도 잘 작동 내가 볼

?- tcount(number_t,[A,B,C],N). 
N = 3, freeze(A, number(A)), freeze(B, number(B)), freeze(C, number(C)) ; 
N = 2, freeze(A, number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ; 
N = 2, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ; 
N = 1, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)) ; 
N = 2, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C, number(C)) ; 
N = 1, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ; 
N = 1, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ; 
N = 0, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)). 
+0

이상적으로'number/1','atom/1'에 대한 테스트는 명시 적'nonvar/1' **에 의해 ** 인스턴스화 오류를 발생시키는 것처럼 보호됩니다. – false

관련 문제