Consider what I have tried:
dif_to_orto(A, B, C) :-
( dif(A, B)
; dif(A, C)
).
While this definition is fine from a declarative viewpoint it contains many redundancies. Think of:
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 2.
A = 1, B = 2, C = 2
; A = 1, B = 2, C = 2. % unexpected redundant solution
And not even in this case:
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 3.
A = 1, B = 2, C = 3
; A = 1, B = 2, C = 3. % unexpected redundant solution
At least, here is a case without redundancy...
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 1.
A = 1, B = 2, C = 1
; false. % unexpected inefficient leftover choicepoint
...but with a resource-wasting leftover choicepoint.
Rare are the occasions where this definition is efficient:
?- dif_to_orto(A, B, C), A = 1, B = 1, C = 2.
A = 1, B = 1, C = 2.
Also that the most general query produces two answers sounds very inefficient to me:
?- dif_to_orto(A, B, C).
dif:dif(A,B)
; dif:dif(A,C).
... which produces also the following redundancy:
?- dif_to_orto(1, B, B).
dif:dif(1,B)
; dif:dif(1,B). % unexpected redundant answer
One dif/2
would be enough!
Is there a way to avoid all these redundancies and inefficiencies?