How do I fix this triangular sequence (recursion) in prolog Arguments are not sufficiently instantiated?

97 Views Asked by At

Trying to calculate the triangular number sequence in Prolog. This is my solution: where X is the nth position of the sequence and Y is the result.

triang(1, 1).
triang(X, Y) :- 
    X>0,
    A is X - 1,
    triang(A, B), 
    Y is B + X.

?- triang(5,X).
   X = 15

But when i try to do for example triang(X,10) I receive an error

Arguments are not sufficiently instantiated.

I guess this is because X is not defined in the consult.

is there any recommendation how to solve this problem,thank you.

1

There are 1 best solutions below

0
false On

First of all, the result you got is not that bad. It says: sorry, I am unable to come to a conclusion and before producing an incorrect result, I prefer to produce an error.

The actual reason is the following goal

?- X > 0.
   error(instantiation_error,(is)/2).

So here we ask for X that are greater than zero. And there are many, in fact infinitely many. There is no direct way to enumerate that set for this built-in and thus it prefers the error.

However, with library(clpz) or clpfd, there is a better way:

:- use_module(library(clpz)).  % use clpfd for SWI instead
:- op(150, fx, #).

triang(0, 0).
triang(X, Y) :-
    #X #>0,
    #Y #>0,
    #A #= #X - 1,
    #Y #= #B + #X,
    triang(A, B).

?- triang(X,15).
   X = 5
;  false.
?- triang(X,14).
   false.
?- triang(X,X).
   X = 0
;  X = 1
;  false.
?- triang(X,Y).
   X = 0, Y = 0
;  X = 1, Y = 1
;  X = 2, Y = 3
;  X = 3, Y = 6
;  X = 4, Y = 10
;  X = 5, Y = 15
;  X = 6, Y = 21
;  ... .
?- #X #> 0.
   clpz:(X in 1..sup).

So now there is an answer to #X #> 0. The answer is often called a constraint. In this case it tells us that X must be in the interval 1 up to (kind of) infinity.