Different behaviout in trace mode and non-trace mode

This code comes from a programming mistake where the following code is expected to behave like if-then-else instead of a disjunction:

?- ((true -> X=a), true); X =b.
X = a ;
X = b.

This is a disjunction because the left hand side’s top level functor is , and not -> such that the unification with the if then else pattern fails:

?- (((true -> X=a),true); X =b) = ((C->G1);G2).

When I turn on trace mode, the second solution is suddenly lost:

[trace]  ?- ((true -> X=a),true); X =b.
   Call: (9) true ? creep
   Exit: (9) true ? creep
   Call: (9) _5566=a ? creep
   Exit: (9) a=a ? creep
   Call: (9) true ? creep
   Exit: (9) true ? creep
X = a .

[trace]  ?- 

Does someone know why this happens?


Is this related to this StackOverflow question?

Out of curiosity are you lambda.xy.x at StackOveflow? If so, thanks for asking here, I too would like to learn more about this.

Yes, sorry, I should have linked the SO question - I didn’t want to do some self-advertising but wanted to pick up on the suggestion to ask here.

Thanks. :clap:

I was the one who made the suggestion. I am GuyCoder at StackOverflow.

Works fine in trace mode, don’t forget the semicolon “;”
when the answer substitution is shown:


Thank you, typical problem between keyboard and computer!

There is a further problem, when using the “trace” command.
Concerning tracability of disjunction. These two queries are structurally different:

trace, (true -> X=a); X=b.

trace, ((true -> X=a); X=b).

See also: SO answer
Only the second query would test (true -> X=a); X=b.

The first query works for me as well:

?- (trace, (true -> X=a)); X=b.
   Call: (9) true ? creep
   Exit: (9) true ? creep
   Call: (9) _5288=a ? creep
   Exit: (9) a=a ? creep
X = a ;
   Call: (9) _5288=b ? creep
   Exit: (9) b=b ? creep
X = b.

I added the parenthesis for clarity but it works also with your exact query.

Well it gives a different answer than (true -> X=a); X=b. So it does not test it, since the trace free query has only one result:

?-  (true -> X=a); X=b.
X = a.

So the trace pickeled query and the trace free query have different results. The way you trace pickeled the query prevents detection of (A->B;C).

While in the original trace free query, (A->B;C) is detected, because (A->B);C and A->B;C are the same. These parenthesis are redundant.

In the trace pickeled query, (A->B;C) is not anymore detected.

Ah sorry, yes certainly - that’s because the term does not have that form anymore:

?- ((trace, (true -> X=a)); X=b) = ((A -> B) ; C).

If I understand it correctly, this is really a syntactic criterion.