Prolog 如何为数字计数谓词实例化Y?

Prolog 如何为数字计数谓词实例化Y?,prolog,Prolog,我有一个方法,它遍历一个数字X,并计算其中有多少位是偶数(这就是Y参数的用途) 当然,通过调用count_偶数(插入任意数字,0)并在基本大小写中添加write(y)很容易得到结果,但是我需要确保在为第二个参数输入变量时,该方法可以工作,比如count_偶数(插入任意数字,a) 当然,这需要实例化Y,但是在递归方法中放置一个简单的Y为0将导致Y始终为0或1,我不希望这样。有什么想法吗?您可以使用0在基本情况下扭转计算并实例化Y。在每一个偶数步中,它都会递增 其他问题:在递归情况下,必须确保X>0

我有一个方法,它遍历一个数字X,并计算其中有多少位是偶数(这就是Y参数的用途)

当然,通过调用count_偶数(插入任意数字,0)并在基本大小写中添加write(y)很容易得到结果,但是我需要确保在为第二个参数输入变量时,该方法可以工作,比如count_偶数(插入任意数字,a


当然,这需要实例化Y,但是在递归方法中放置一个简单的Y为0将导致Y始终为0或1,我不希望这样。有什么想法吗?

您可以使用
0
在基本情况下扭转计算并实例化
Y
。在每一个偶数步中,它都会递增

其他问题:在递归情况下,必须确保
X>0
,否则在回溯过程中会得到额外的错误答案。此外,算术不相等是
=\=
\=
相反,它统一了项,取反,对于
mod(8,2)==0
)也是如此)。这也会给你额外的错误结果

固定代码:

count_even(0,0). %base case
count_even(X,Y) :- X > 0, X1 is X // 10, %recursive case
                  ((mod(X,2)=:=0, count_even(X1,Y1), Y is Y1 + 1); %if X is even
                   (mod(X,2)=\=0, count_even(X1,Y))). %if X is odd

试着这样做:

even_digits( N, Y ) :-  % the general case
    N > 0,              % - for N > 0,
    N1 is div(N,10) ,   % - get all digits to the left of the one's place
    D  is mod(N,10) ,   % - get the one's digit
    even_digits(N1,T) , % - recurse down on N1
    ( is_even(D)        % - if the one's digit is even
      -> Y is T+1       % - add 1 to the earlier result
      ;  Y is T         % - otherwise, we're done.
    ).                  % Easy!
even_digits( 0, 0 ).    % the base case. The question is... is zero even, odd, or signless. I've decided that it is signless here.

is_even(N) :- 0 =:= mod(N,2).
但这让你在一个奇怪的地方,零。零是一个正数的数字用完的点,但它本身也是一个数字

您可能会发现将数字视为一个原子并将其分解为一系列数字更容易

even_digits( N, R ) :-
    number_chars(N,Ds),
    even_digits( Ds, 0 , R ).

even_digits( []     , N , N ).
even_digits( [D|Ds] , T , N ) :-
    ( member( D, ['0','2','4','6','8'] )
      -> T1 is T+1
      ;  T1 is T
    ),
    even_digits(Ds, T1, N).
这适用于负数、零、带分数的数字

even_digits( N, R ) :-
    number_chars(N,Ds),
    even_digits( Ds, 0 , R ).

even_digits( []     , N , N ).
even_digits( [D|Ds] , T , N ) :-
    ( member( D, ['0','2','4','6','8'] )
      -> T1 is T+1
      ;  T1 is T
    ),
    even_digits(Ds, T1, N).