Is_integer predicate?

I’m using: SWI-Prolog version 8.0.2.

Is there an is_integer predicate in SWI-Prolog? The problem with integer/1 is that it will convert a rational number to an integer. I want to know if a value is natively an integer. Bonus points if there is a system predicate that will check if a value is a positive, non-zero integer. If not, I’ll just write my own.

1 Like

I think is_of_type(integer, X) is what you want. See library(error) for more information on that predicate & the various type names it knows about.

Yes

Of course.

I note a few ways to do this in Wiki: Bug hunting toolbox

The one you probably want is

is_of_type(+Type, @Term)

and for the Type value see the list in must_be/2

?- is_of_type(positive_integer,-1).
false.

?- is_of_type(positive_integer,0).
false.

?- is_of_type(positive_integer,1).
true.

?- is_of_type(positive_integer,0.1).
false.

?- is_of_type(integer,-1).
true.

?- is_of_type(integer,0).
true.

?- is_of_type(integer,1).
true.

?- is_of_type(nonneg,-1).
false.

?- is_of_type(nonneg,0).
true.

?- is_of_type(nonneg,1).
true.
1 Like

integer/1 is an ISO core standard predicate. It does not convert anything, and tests whether the argument is an integer type term.

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)

?- integer(7).
true.

?- integer(7 rdiv 2).
false.

?- integer(6 rdiv 2).
false.

The predicate is defined in section 8.3 type testing of the ISO core standard.
In particular in sub section 8.3.3 integer/1.

2 Likes

Some Prolog systems have an integer/1 evaluable function. Which is something else than an integer/1 predicate.

For example SWI-Prolog itself:

Same as round/1 (backward compatibility).
https://www.swi-prolog.org/pldoc/doc_for?object=f(integer/1)

There are 3 pages on integer/1. One of them says that it is the same as round/1, which indicates that it will succeed if given a rational number, a behavior I didn’t want so I made this post:

https://www.swi-prolog.org/pldoc/doc_for?object=f(integer/1)

However I tried that in the console and it true. integer(1.1) returns false so you are correct in that I can use integer/1 for my purposes::

25 ?- integer(1.1).
false.

Apparently that doc page is incorrect since it does not function similar to round/1? I couldn’t test this because round/1 does not appear to be defined, at least not be default:


26 ?- round(1.1).
Correct to: "ground(1.1)"? no
ERROR: Undefined procedure: round/1

SWI-Prolog has two name spaces. One name space for predicates. And one name space for evaluable functions. round/1 is supposed to be an evaluable function, so you need to use is/2 to invoke it:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.6)

?- X is round(1.1).
X = 1.

That Prolog has predicates and evaluable functions is again rooted in the ISO core standard (ISO/IEC 13211-1 First edition 1995-06-01). Evaluable functors were introduced already there, see section 7.9 Evaluating an Expression.

The ISO core standard depends a minimum set of evaluable functors, which are defined in its own chapter 9 Evaluable functors. They also form the basis for predicates such as (=:=)/2, (>=)/2, etc…, see section 8.7 arithmetic comparison.

1 Like

Wow! I never knew that and that’s really important, especially when looking things up in the docs.

There is no special evaluable function indicator syntax. Its quite common to write round/1, and then from the context the intention is an evaluable functor and not a predicate functor.

1 Like

Unfortunately true. The online docs say

Availability: Arithmetic function (see is/2)”

Which was supposed to give a clue …

1 Like

While the docs are my first stop for info, baring that I look for examples in the SWI-Prolog source code at GitHub as also noted by Jan.

At GitHub to search the code you have to go into a repository, e.g. swip-devel, swish or one of the others.

Once in a repository then use search at the upper left of the page. I typically search just swip-devel.

Searching for round returns many hits

Not all of the hits are Prolog source code but it is real working code.

That is how I learned to use setup_call_cleanup

1 Like