Re: [eclipse-clp-users] Out of range error

From: Joachim Schimpf <joachim.schimpf_at_...269...>
Date: Fri, 03 Dec 2010 14:04:30 +1100
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)



-- Joachim
Received on Fri Dec 03 2010 - 03:04:40 CET

This archive was generated by hypermail 2.3.0 : Tue Apr 16 2024 - 09:13:20 CEST