How to use backtrack to increment a variable infin

2019-07-27 11:27发布

问题:

I am currently reading a Prolog book and I am stuck on one of the challenge exercises. I am meant to create a predicate with one argument. When this argument is a variable, it will return the following with backtracking, and X will continue to increment with no limit.

X = 0, X = 1, X = 2, X = 3, X = ...

I made the simple predicate below which backtracks through 0-2 but I can't figure out a way to make it continue infinitely.

backtracking_exercise(X) :-
    X = 0;
    X = 1;
    X = 2.

I was considering using the between/3 predicate but this would be only give a finite amount of numbers. I also experimented with the plus/3 predicate and recursion but no luck. This is what I have come up with, but as you can tell it is currently useless.

backtracking_excercise2(X) :-
    X = 0,
    plus(X,1,Y),
    backtracking_excercise2(Y).

Any tips on how to proceed would be greatly appreciated.

Thank you in advance.

回答1:

A tail-recursive variant of Jim's solution:

plus(N) :-
    next_integer(1, N).

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

To prevent going into an infinite loop when the plus/1 predicate is called with an instantiated argument, i.e. to make the predicate be only a generator, the first clause can be modified to:

plus(N) :-
    var(N),
    next_integer(1, N).


回答2:

You had tagged your question with 'recursion' (since removed) and yet have implemented no recursion. I assume that this challenge is from a chapter on recursion, so I present the following hints (followed by a solution):

Hint 1:

What is the base case? If you want a recursive call to terminate it should have a base case.

Your base case is X = 0.

Hint 2:

What is the recursive step? What do you need to do to the previous iteration in order to generate the next step in the sequence?

Your step is X is OldX + 1.

A Solution:

plus(0).
plus(X) :- plus(N), X is N + 1.

Additional info:

This solution will go infinite for plus(-1). (and, indeed, all negative X).
To avoid this, you'll need more advanced tools (such as DCG or CLP(FD)).