3
count([],0).
count([_|Tail], N) :- count(Tail, N1), N is N1 + 1.

This count all the elements, but I need to count only the numbers.

coder
  • 12,832
  • 5
  • 39
  • 53
Alexandre Rocha
  • 101
  • 1
  • 1
  • 8

2 Answers2

5

Prolog has an ISO builtin predicate number/1 that checks whether the given parameter is a number.

We can simply use an if-then-else statement that either increments N is N1+1, or sets N = N1, like:

count([],0).
count([H|Tail], N) :-
    count(Tail, N1),
    (  number(H)
    -> N is N1 + 1
    ;  N = N1
    ).
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

You could use number/1 iso built-in predicate:

count([],0).
count([H|Tail], N) :- number(H),count(Tail, N1), N is N1 + 1.
count([H|Tail], N) :- \+number(H),count(Tail, N).
coder
  • 12,832
  • 5
  • 39
  • 53
  • When I try ?- count([1,3,4,5,a,f,v], 0). The answer is false, instead of the count of number elements – Alexandre Rocha Jun 12 '17 at 23:33
  • Yes the answer that prolog gives you is right!! – coder Jun 12 '17 at 23:38
  • `count([X], 0))`. succeeds, but `X = 1, count([X], 0)` fails. – false Jun 13 '17 at 08:04
  • @false I don't see anything wrong, `X = 1, count([X], 0) `clearly must fails and the only thought is what should `count([X], 0) ` do ?? (succeeding in last case is not that bad...) – coder Jun 13 '17 at 08:13
  • 1
    For a relational solution (that is, a solution which maintains that the definition is a relation) you have at least two options: produce an instantiation error (as with [`number_itype/1`](https://stackoverflow.com/a/30600104/772868)), or use, say `number_type(N) :- freeze(N, number(N))` - but then you would need a `non_number_type(N) :- freeze(N, \+ number(N)).` too. – false Jun 13 '17 at 08:17
  • 1
    Another option might be that you loop in that case. Not the best option but better than producing an incorrect result. – false Jun 13 '17 at 08:19
  • @false ,thanks for the helpful comments !! – coder Jun 13 '17 at 08:23