SSU Guard -- can it be non-determinstic?

Can a guard in SSU clause be non-deterministic – or would this interfere with having the SSU predicate be deterministic upon backtracking – and hence guards must be deterministic.

And, if they are non-deterministic – what is the expected correct behavior during backtracking?

You can try it out. What will happen if you have this:

between_1_and_3(X), between(1, 3, X) => true.

and now call it with ?- between_1_and_3(X).


I guess, my question is whether having a non-deterministic guard should raise an error or at least a warning.

Running your example with X unbound is indeed instructive – Prolog finds the first and concludes without choice point

And, calling it with an argument between 1 and 3 succeeds as well, isn’t this a kind of semantic inconsistency.

But, i think the conceptual issue is deeper – since this is inherently a deterministic predicate, there will be no backtracking in the guard – and, likely, any choice points generated by a guard are pruned.

So, i guess, one can use a non-determinstic guard, just that, it will be treated deterministically, since a choice point generated when encountering the guard will be pruned by the => operator.


After all, it performs SSU on the head, runs the guard and commits to the first solution of the guard. I think the guard should better not unify to any of the head arguments and should not have side effects, but otherwise I see not much reason to restrict it. Ideally we would check that the head is not instantiated by the guard, but that is (too) hard to enforce efficiently at runtime.

Thank you.

I am trying to come up with a description of the idiom at work here and intended clause design – and the rationale behind it.


between_1_and_3(X, Y), integer(X) => between(1, X, Y).

I just noticed that if the body is non deterministic, then there are again choice points. For some reason i thought that the clause would leave no choice points – for the clause committed to.

So, its up to the developer to a) ensure that the guard does not instantiate the variables in the head, in particular not the output variables, and b) that the body is determinant, and c) to provide mutual exclusive and exhaustive guard cases, to obtain the benefit of a determinant and steadfast predicate.

So, what exactly is the added value of =>, beside avoiding the need to include a cut, after the guard.

Is it the added runtime checks and raised exception for a non-complete case analysis provided by guards?

Of course, there is added value by the => construct to make the developers intent explicit.


Why does this fail?

between_1_and_3(X, Y), between(1,2, X) => X=2, between(1, X, Y).

I guess, because, the guard gets committed to the first solution – i guess this clarifies why we don’t want the guard to instantiate a head variable, since the declarative reading here seems to make no sense.

Does it make sense to require for => all input variables, i.e. those mentioned in guards, to be ground? Although, the below, wouldn’t fit – but, declaring X a var effectively means its an output variable.

between_1_and_3(X, Y), var(X) => X=1, between(1, X, Y).


comparing the below, the runtime checks become more apparent, with the first raising an exception and the second (t(X)) simply failing, when called unbound.

between_1_and_3(X, Y), integer(X) => X=1, between(1, X, Y).

t(X) :-