next up previous contents
Next: Test --- Process Up: Some General Program Previous: Generate --- Test

Finite and Infinite Generators

We define a predicate integer_with_two_digit_square/1 to produce a positive integer that has a square which is greater than or equal to 10 and less than 100.

 
integer_with_two_digit_square(X):-

int(X),

test_square(X).

test_square(X):-

Y is X*X,

Y >= 10,

Y < 100.

Here is the definition of int/1 which is a finite generator ---because there are only a finite number of unit clauses (containing no variables) used to define int/1.
 
int(1).

int(2).

int(3).

int(4).

int(5).

The goal integer_with_two_digit_square(X) eventually fails because the generator runs out of potential solutions. Now we define a version of int/1 which is an infinite generator (verifying this is left as an `exercise for the reader'!).
 
int(1).

int(N):-

int(N1),

N is N1 +1.

On backtracking, this will generate a new solution for integer_with_two_digit_square(X) until we test 10. From then on, we will keep generating with int/1 and failing with test_square/1. We are trapped in a generate---test cycle with no way out.
The usual way out is to ensure that once we have found the solution we want then we commit ourselves to that solution and forbid backtracking from ever seeking another solution. Again, the usual solution is to place a cut ( !/0) after the test. This results in:
 
integer_with_two_digit_square(X):-

int(X),

test_square(X),!.

and the example demonstrates the (usually necessary) fix to stop a program using the generate --- test schema from overgenerating. However, our solution now provides for only one solution to be generated!


Paul Brna
Mon May 24 20:14:48 BST 1999