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

问题描述 投票:22回答:4
I am writing this answer, because the best answer yet was in a

comment

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).  

by

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

lurker

R = 0.

. I want to have it show up as an actual answer.

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

Your code is not working, because you're doing

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

when

isn't instantiated in the case
prolog arguments clpfd instantiation-error
4个回答
22
投票

is instantiated when it is called. Your problem is that in arithmetic computation like this:A is B

everything on the right side (B) has to be already known. No variables there.R1 is R+1You may do something like this:R(tested this code now, it works).not_number([X|T], R)Now the third argument is an accumulator. It counts how many not-numbers there are. When the list is empty, this third argument is unified with the second one and it becomes the proper answer.

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

Prolog, when given the chance, will go through all the routes possible. If you do something like this:isand then ask:

You could get both answers: X = adam and X = eve.It applies to your code too: notice that when the head of the list is not a number, you can still do this:

4
投票

to ensure that we skip an element in a list without increasing the counter by 1 only when this element is not a number.

To enforce Prolog to find some other results, you must press ";" on your keyboard (like in this adam and eve example).

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).

The general solution to such problems is to use

constraints

.

cat(adam).
cat(eve).

For example, your program works exactly as expected if you just use

?- cat(X).

clpfd

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

constraints. Simply replace

number(Head).

by

to obtain integer arithmetic that works

in all directions

1
投票

Sample query and its result:?- not_number([1,2,3,5], R).R = 0.

Note also that I have changed the code to use the ISO-predicate .(is)/2 (#=)/2 In my case instead of I had to use

:- 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).

Instead of this

I had to write                    

我正在写一个小程序,用来计算一个列表中有多少元素不是数字。(\+)/1如果我执行这样的代码:not/1我得到的结果是R=0(应该是这样)

但是,如果我在列表中输入一个字符。

0
投票

谁能解释一下代码有什么问题?我是一个新的prolog程序。is =

X is AnotherVariable

我正在写一个小程序,计算一个列表中有多少元素不是数字。下面是我的代码:not_number([],0)。not_number([X])。

© www.soinside.com 2019 - 2024. All rights reserved.