Dear Joachim, Many thanks for the prompt reply, which was very helpful. Due to the nature of the problem, I cannot impose initial bounds to the variables (these are not generally known ahead of time), so I'm inclined to go with the second option, the use of propia. My only concern is the replacement of "or" with the semicolon operator. I need to deal with arbitrary boolean constraints, potentially containing negations of disjunctions, and I'm not sure if that's compatible with the "infers ic" syntax. In fact I tried it but it doesn't seem to work, e.g. with the definition foo(X) :- ((X #>= 20 and X #=< 20) or (X #>= 100,X #=< 150)) infers ic, labeling([X]). the query foo(A) gives the same error: "out of range in indomain(A{-1.0Inf .. 1.0Inf})". While I could put the boolean conditions in DNF and then use the semicolon operator as in your example, I'd rather not, since the transformation to DNF could take too long. Any suggestions? Many thanks again! P.S. Sorry I can't reply to this thread directly, I'm unable to join the users mailing list because my yahoo email account is apparently deemed unsafe. Mick Hallward wrote: > Hi all, > > I'm an Eclipse beginner with a simple (I hope :>) question. > > With ic loaded, I define a constraint on X such that > X is either in the 20..30 range or in the 100...150 > range: > > foo(X) :- integers([X]), (X #>= 20 and X #=< 20) or > (X #>= 100 and X #=< 150), labeling([X]). > > Now, I would expect a query like foo(A) to result in an > answer like A = 20 or something like that - any value, > really, that respects the constraints of foo. Yet the > query results in the error: > > "out of range in indomain(A{-1.0Inf .. 1.0Inf}) when evaluating > the query foo(A)." > > I wonder why that is. There are two things involved: 1. labeling/1 and indomain/1 refuse to enumerate infinite domains: ?- integers([X]), labeling([X]). out of range in indomain(X{-1.0Inf .. 1.0Inf}) Abort 2. or/2 is implemented via reified constraints which are not strong enough to extract finite bounds for X from your disjunction: ?- X #>= 20 and X #=< 20 or X #>= 100 and X #=< 150. X = X{-1.0Inf .. 1.0Inf} There are 7 delayed goals. Yes (0.00s cpu) One way to make it work is to add initial bounds to X: foo(X) :- integers([X]), X :: 0..200, (X #>= 20 and X #=< 20) or (X #>= 100 and X #=< 150), labeling([X]). ?- foo(X). X = 20 Yes (0.00s cpu, solution 1, maybe more) X = 100 Yes (0.01s cpu, solution 2, maybe more) X = 101 Yes (0.02s cpu, solution 3, maybe more) An alternative solution is to use a stronger implementation for the disjunctive constraint: :- lib(ic). :- lib(propia). foo(X) :- (X #>= 20,X #=< 20 ; X #>= 100,X #=< 150) infers ic, labeling([X]). ?- foo(X). X = 20 Yes (0.00s cpu, solution 1, maybe more) X = 100 Yes (0.01s cpu, solution 2, maybe more) X = 101 Yes (0.02s cpu, solution 3, maybe more) This works because a finite domain is now inferred from the disjunction: ?- (X #>= 20, X #=< 20 ; X #>= 100, X #=< 150) infers ic. X = X{[20, 100 .. 150]} Yes (0.00s cpu) -- JoachimReceived on Fri Dec 03 2010 - 19:02:08 CET
This archive was generated by hypermail 2.3.0 : Wed Sep 25 2024 - 15:13:20 CEST