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 - 03:04:40 CET
This archive was generated by hypermail 2.3.0 : Wed Sep 25 2024 - 15:13:20 CEST