This has more to do with operators than unification. What matters here is how the expression 1+2+3 is parsed.
It seems that it is not parsed as +(1,+(2,3)). This depends on the operator definition for +. You check the docs for op/3 (see the table at the bottom) and also query it using current_op/3:
?- current_op(Precedence, Type, +).
Precedence = 200,
Type = fy ;
Precedence = 500,
Type = yfx.
In the expression 1+2+3 you have the yfx “+” twice, so it parses unambiguously to +(+(1,2),3). I checked this using display/1:
?- display(1+2+3).
+(+(1,2),3)
true.
It seems that operators cannot have multiple definitions: you can redefine + (don’t do it
) but then you will only get the other parsing:
?- op(500, xfy, +).
true.
?- display(1+2+3).
+(1,+(2,3))
true.
It really depends on what you are doing. Maybe you could:
- redefine
+ only for a module to be xfy instead of yfx;
- parenthesize your expression as
1+(2+3);
- parse the expression yourself.
The last one is trivial if you have already tokenized it. But it is more important what exactly it is that you are after.
PS: Hmmm, it seems we have been here before. Back then you asked, “what is the use case for (X,Y) besides simply holding values” and my answer would have been “you can use parentheses to parenthesize correctly”. For example, you cannot stuff X, Y inside the parentheses of a compound term since it will parse as two arguments. With display/1 again:
?- display(x, y).
ERROR: stream `x' does not exist
ERROR: In:
ERROR: [13] write_term(x,y,[quoted(true),...|...])
ERROR: [11] toplevel_call(user:user: ...) at lib/swipl/boot/toplevel.pl:1529
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
?- display((x, y)).
','(x,y)
true.