3

In my Prolog course the past semester, I fell a little behind around the time CLP was introduced. Now I'm trying to catch up, and have tried my hand at a past exam that the professor supplied to all students.

In particular, there was this question:

What is the domain of the decision variable Z in CLP(FD) after the following query:

?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y - X.

It seems to me that the answer should be

Z in 1..99

but when I ran it in my SWI-Prolog installation to double-check, I got

Z in -5.. -1\/1..99

which seems to be based on a naive comparison of the maximum and minimum values of X & Y, without regard for the constraint linking them (Y #> X).

I realize that concessions to feasibility have to be made here and the domains returned will sometimes be less restrictive than they could be, but I'm surprised to see it fail on such a simple example.

My questions

  1. I assume that this has to do with how CLP chooses to propagate (or not to propagate) various constraints internally, but I don't understand how it does that - it's all something of a black box for me. How, exactly (or failing that, approximately), does CLP propagate its constraints?
  2. Is there any way to make CLP(FD) apply the constraint appropriately, perhaps by reordering? I've already tried tacking on an extra Y #> X at the end, but that didn't change any of the variables domains.
Community
  • 1
  • 1
Drubbels
  • 327
  • 2
  • 4
  • 11

1 Answers1

2

It seems to me that the answer should be

Z in 1..99

How can you be so sure that you are right? This is one of the nice properties of constraints: You can verify this most easily:

?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X.
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in -5.. -1\/1..99,
Y in 2..100.

?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, Z #< 0.
false.

OK, now I believe what you said.

So you have discovered here an inconsistency which is present also in SICStus' native library(clpfd) as well as library(clpz). First please note that the answer given was not incorrect! It said: Yes, there are solutions provided X in 1..7, Z+X#=Y, X#=<Y+ -1, Z in -5.. -1\/1..99, Y in 2..100. is true. Helas, this is not true.

So that answer is a bit like the legalese in many insurance contracts where they say, yes we will pay, provided all that tiny unreadable print holds, but in reality you could replace that wall of microtext by a big fat false.

In general, such inconsistencies are inevitable since CLP(FD)/CLP(Z) as defined in above systems permits to formulate undecidable problems. Thus, no matter how evolved your constraint solver is, we have the guarantee that there will be always cases that we cannot solve. That's a scientific, mathematical law, much more reliable than empirical laws like gravity or that speed limit.

The inconsistency here is effectively an engineering tradeoff. As long as nobody complains and doesn't have a convincing use case, the developers of such systems will not see a reason to improve. After all, such an improvement might slow down existing use cases.

  1. How, exactly (or failing that, approximately), does CLP propagate its constraints?

Actually, for any problem of realistic size, nobody knows. But this is not necessary either. In the case of CLP(FD), the fundamental element are the domains attached to the logical variables. You see them as (in)/2 goals like Z in -5.. -1\/1..99. Connected between them are the actual constraints. In your case Y #> X and Z #= Y-X. These constraints now only see the domains of the variables and try to maintain consistency between them. As an even coarser approximation, the domains are seen as intervals thus Z in -5 .. 99 instead of above. What (most of them) do not see are the other constraints. In this case, there is no direct connection between Y #> X and Z #= Y-X. And thus the inconsistency. Such limited consistency checks are much easier to implement and also quite fast and often outperform more complete algorithms. With the discovery of better algorithms things evolve. A nice example is all_distinct/1 which maintains consistency between all variables using Regin's algorithm, whereas all_different/1 only maintains consistency between each pair of variables. But in any case: these things evolve and it is a bit of a surprise that this is an exam question.

  1. Is there any way to make CLP(FD) apply the constraint appropriately ...?
?- X in 1..7, Y in -3..100, Y #> X, Z #\= 0, Z #= Y -X, clpfd:contracting([X,Y,Z]).
X in 1..7,
Z+X#=Y,
X#=<Y+ -1,
Z in 1..99,
Y in 2..100.

But most will ignore this issue and just add labeling([],[X,Y])

  1. What is the domain of Z?

That is an ambiguous question. Give both as an answer.

false
  • 10,264
  • 13
  • 101
  • 209
  • Thank you. The 'clpfd:contracting([X,Y,Z])' tip will be useful for me in the future. Unfortuantely I cannot accept yet because the answer doesn't really cover question 1 - 'How, exactly (or failing that, approximately), does CLP propagate its constraints?' - and I'd really like to better understand that bit. – Drubbels Jan 09 '20 at 21:09
  • The exam question very specifically asks 'What is the domain [...]' - my understanding is that the question assumes that the student will *know* that CLP(FD) will only get as far as 'Z in -5.. -1\/1..99', and won't find 'Z in 1..99'. I would like to understand how I could know that. – Drubbels Jan 09 '20 at 21:11
  • +1 for the "Hélas!" alone. The insurance text sets up a "if and only if" between case of disbursement and situation matching the microtext. The microtext must not be *inconsistent* otherwise the contract is **nul et non avenu**, whereas here we can set up an *inconsistent* situation, which has no solutions (and if you computationally link this back into a fragile logic machinery which accepts ["ex contradictione quodlibet"](https://plato.stanford.edu/entries/logic-paraconsistent/#BrieHistExContQuod), woe betide your machinery's output!). – David Tonhofer Jan 10 '20 at 12:20
  • Also, it is not a "speed limit" ... it is the limit of a [hyperbolic rotation](http://physicsinsights.org/hyperbolic_rotations.html). Physics = Fun! And if you break it, I do think undecidable problems become decidable because you now can build time machines. Computation = Physics! Thus Computation = Fun! – David Tonhofer Jan 10 '20 at 12:30
  • Pardon my French misspelling. There is most often no limit on the complexity of a contract, so you only need a text that is complex enough - preferably depending on pending WTO-rulings. – false Jan 10 '20 at 12:42
  • *ex falso quodlibet* is not an accepted reasoning in legal matters. That's why those extensions of Prolog that include negation too much have their difficulties being accepted. And, think of it: two *arbitrary propositions* would be always interconnected by either a implies b or b implies a or both. Can you accept this? – false Jan 10 '20 at 12:54
  • 1
    *Can you accept this?* Of course not. EFQ is not a real-world principle, it is at best a nasty side-effect of certain logics. *There is most often no limit on the complexity of a contract, so you only need a text that is complex enough* Well, that's why we have that massive hierarchy of courts. Quite a lot of human activity seems to be invested in that subsystem. – David Tonhofer Jan 10 '20 at 13:55