Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating integers < limit

I am trying to generate all integers (natural numbers) smaller than a limit, let's say 10. I have a predicate nat(X) which produces all numbers from 0 to infinity.

Now my problem is, if I do:

nat10(X) :- nat(X), X =< 10.

This will never terminate, as it tries to find other solutions with nat(X) until infinity.

I need a construct that let's me fail the whole predicate if one subgoal fails. How would I go about doing that?

like image 593
Blub Avatar asked Mar 20 '23 00:03

Blub


2 Answers

Depending upon the problem being solved, you might want to consider constraint logic programming over finite domains (CLPFD).

But in this context, you need just prevent Prolog from backtracking if X > 10. The current predicate nat10/1 has no such constraint, so we'll add it:

nat10(X) :- nat(X), ( X > 10 -> !, fail ; true ).

So if X > 10, we do a cut (!) to prevent backtracking to nat(X) (thus avoiding generating natural numbers above 10 infinitely) and then simply fail. Otherwise, we succeed (true).

| ?- nat10(X).

X = 1 ? ;

X = 2 ? ;

...

X = 9 ? ;

X = 10 ? ;

(3 ms) no
| ?-
like image 176
lurker Avatar answered Mar 22 '23 14:03

lurker


If you can use clpfd, then this answer is for you!

:- use_module(library(clpfd)).

Simply try:

nat10(X) :-
   X in 0..10,
   indomain(X).
like image 20
repeat Avatar answered Mar 22 '23 15:03

repeat