So im trying to define natural numbers so far i did this:
1 nat(0). % 0 zero is a natural, can be a stoping case
2 nat(X):- 0>X , !,fail. %if is less then zero then its not a natural.
3 nat(X):- nat(Z), X is Z+1. %if its bigger than zero do recursively for the number-1
When i do this it gives me "Instantiation error in argument 2 of (>)/2", so he can't instantiate X in line 2 but if take out the fail he does the comparation (>) fine and has no problem instantiating X , so why he complains if i put the fail?
If you want to generate natural numbers, you can do it without using cuts or the fail/0
control construct. For example:
nat(Nat) :-
next_integer(0, Nat).
next_integer(I, I).
next_integer(I, K) :-
J is I + 1,
next_integer(J, K).
Sample call:
| ?- nat(Nat).
Nat = 0 ? ;
Nat = 1 ? ;
Nat = 2 ? ;
Nat = 3 ?
...
But this predicate will not work if instead you want to test if a term is a natural number. For example, the following call will result in a stack overflow in most Prolog systems (as we cannot generate a negative integer by incrementing from zero):
| ?- nat(-3).
If you are using a Prolog system providing a CLP(FD) library, you can use a better definition:
nat(Nat) :-
Nat #>= 0,
next_integer(0, Nat).
next_integer(I, I).
next_integer(I, K) :-
J is I + 1,
next_integer(J, K).
And then use the same predicate for generating and testing. For example, using SWI-Prolog and library(clpfd)
:
?- nat(Nat).
Nat = 0 ;
Nat = 1 ;
Nat = 2 ;
Nat = 3
...
?- nat(-3).
false.
Without using a constraints library, you will need to write something like:
nat(Nat) :-
( var(Nat) ->
next_integer(0, Nat)
; integer(Nat), Nat >= 0
).