# How to express a disjunction of inequalities compactly without redundant answers/solutions

How about this one:

```
dif_to_orto(A, B, C) :-
dif(A-A, B-C).
```

The test cases:

```
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 2.
A = 1,
B = C, C = 2.
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 3.
A = 1,
B = 2,
C = 3.
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 1.
A = C, C = 1,
B = 2.
?- dif_to_orto(A, B, C), A = 1, B = 1, C = 2.
A = B, B = 1,
C = 2.
?- dif_to_orto(A, B, C).
dif(f(B, A), f(A, C)).
?- dif_to_orto(1, B, B).
dif(B, 1).
```

This solution first awaits for 2 of the 3 variables to be comparable, then if it cannot decide whether the constraint should succeed adds a new constraint:

```
dif_to_orto(A, B, C) :-
when((?=(A, B) ; ?=(A, C) ; ?=(B, C)),
( ?=(A, B) ->
( A\==B -> true ; dif(A, C) )
;
(
?=(A, C) ->
( A\==C -> true ; dif(A, B) )
;
( B\==C -> true ; dif(A, B) )
)
)).
```

Sample runs:

```
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 2.
A = 1,
B = C, C = 2.
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 3.
A = 1,
B = 2,
C = 3.
?- dif_to_orto(A, B, C), A = 1, B = 2, C = 1.
A = C, C = 1,
B = 2.
?- dif_to_orto(A, B, C).
when((?=(A, C);?=(B, C);?=(A, B)), (?=(A, B)->(A\==B->true;dif(A, C));?=(A, C)->(A\==C->true;dif(A, B));B\==C->true;dif(A, B))).
?- dif_to_orto(1, 2, Z).
true.
?- dif_to_orto(1, B, B).
dif(B, 1).
```

Reversing the checks:

```
dif_to_orto(A, B, C) :-
when((?=(A, B) ; ?=(A, C) ; ?=(B, C)),
(
A==B -> dif(A, C)
;
((A==C ; B==C) -> dif(A, B) ; true)
)).
```

Here is one suggestion. As far as I can tell, it does not create choice points or redundant solutions:

```
dif_to_orto(A, B, C) :-
when(?=(A,B),(A==B->dif(A,C);true)),
when(?=(A,C),(A==C->dif(A,B);true)).
```

For each disjunct, wait until it is known to be true or false. Once known, check its truth and, if false, then post the other disjunct.