Best way to generate integers in Prolog

I want to generate integers, and I'm looking for a better way to do this. Example:

?- number2(N).
N = 0;
N = 1;
N = 2;
...
(and so on)

Now I just use length/2:

number2(N) :- length(_, N).

But I think there should be a better way (without creating a temporary list). I could probably write code based on the code length/2, but I'm looking for a solution that uses pre-existing built-in predicates. Is there a built-in predicate that will work better than length/2? I could not find anything like it.

+4
source share
3 answers

It is hard to satisfy your decision; and probably not worth the effort. In the end, there are currently three assumptions that everyone is wrong for one or the other case:

?- time( (number2_gk(N), N == 10000) ). % your original
% 20,002 inferences, 0.007 CPU in 0.007 seconds (99% CPU, 3006132 Lips)
N = 10000 

?- time( (number2_cc(N), N == 10000) ). % quadratic overhead
% 50,025,001 inferences, 28.073 CPU in 28.196 seconds (100% CPU, 1781945 Lips)
N = 10000 

?- time( (next_integer(N), N == 10000) ).
% 20,002 inferences, 0.011 CPU in 0.011 seconds (100% CPU, 1822247 Lips)
N = 10000 

number2_cc(-1) next_integer(-1) , length/2 , SICStus .

, CC , .

mat :

goal_expansion(length(Ls,L), between(0,infinite,L)) :-
   var_property(Ls, fresh(true)).

as(N) :-
   length(L,N),
   phrase(a, L).

a --> [a], a.
a --> [].

as(N) N.

, - , library(clpfd):

nat(N) :-
   nat(N, 0).

nat(N, N0) :-
  N #>= N0,
  (  N = N0
  ;  N1 is N0+1,
     nat(N, N1)
  ).

?- time( (nat(N), N == 10000) ).
% 1,850,152 inferences, 0.544 CPU in 0.545 seconds (100% CPU, 3399793 Lips)

, . .

?- N in 1..2, nat(N).
+3

:

next_integer(I) :-
    next_integer(0, I).

next_integer(I, I).
next_integer(I, J) :-
    I2 is I + 1,
    next_integer(I2, J).

:

?- next_integer(I).
I = 0 ;
I = 1 ;
I = 2 ;
I = 3 ;
...

, . :

?- next_integer(-5, I).
I = -5 ;
I = -4 ;
I = -3 ;
I = -2 ;
I = -1 ;
I = 0 ;
I = 1 ;
I = 2 ;
I = 3 ;
...
+3

/3 , .. ,
/2
( . ):

/**
 * above(L, X):
 * The predicate succeeds for every integer X above the integer L.
 */
% above(+Integer, -Integer)

, ,
, :

gen_int(X) :-
    above(0, Y),
    (X is Y; X is -Y-1).

0, -1, 1, -2 .. , , :

gen_nat(X) :-
    above(0, X).

0, 1, 2 .. gen_int/1
gen_nat/1 SICStus Prolog, . .

, .

Bye

+3

Source: https://habr.com/ru/post/1611163/


All Articles