Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

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

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?

question from:https://stackoverflow.com/questions/66061202/how-to-express-a-disjunction-of-inequalities-compactly-without-redundant-answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...