Re: FD: Arithmetic Constraints

From: Warwick Harvey <wh_at_icparc.ic.ac.uk>
Date: Thu 25 Jan 2001 04:41:14 PM GMT
Message-ID: <3A70572A.BE02A8AE@icparc.ic.ac.uk>
Hi,

rui@omega.di.uminho.pt wrote:
> I was trying to express a constraint like C #= abs(A) in fd. After a few
> attempts it seemed that none of the usual arithmetic constraints, appart
> from the basic operations (+, -, * and /) can be easily represented.
> 
> Is this true? Or am I just being a clueless newbie?

It does indeed seem to be the case.

I'm currently working on a hybrid finite domain / floating point
interval constraint solver, which is intended to eventually replace the
current FD library, and which has better support for this kind of
thing.  But the core of the library isn't likely to be complete for
another couple of months, and it isn't going to be properly useful until
it's integrated with everything else, which could be 6 months.  All of
which doesn't really help you.  Normally we'd fix this kind of
oversight, but since we're planning to make the FD library obsolete
soon, it doesn't make sense for us to spend our limited time on it.

> Is the way around to write those constraints from scratch as user defined
> ones?

That's one way.  If you're not too worried about speed, there are
higher-level ways of doing it though.  Here's one example, which is
easily adapted for other kinds of constraints (e.g. min, max), but might
be a bit on the slow side, since it uses propia:

:- lib(fd).
:- lib(propia).

	% my_abs(Var, Abs):
	% Abs is constrained to be the absolute value of Var.
my_abs(Var, Abs) :-
	my_abs1(Var, Abs) infers most.

my_abs1(Var, Abs) :-
	Abs #>= 0,
	( Abs #= Var ; Abs #= -Var).

If that's too slow for you, and you want to write your own, I suggest
you define max/3 and/or min/3 first, since then you can get 3
constraints for the price of one.  E.g. assuming you have my_max/3:

	% my_min(X, Y, Min):
	% Z is constrained to be the smaller of X and Y.
my_min(X, Y, Min) :-
	NegX #= -X,
	NegY #= -Y,
	NegMin #= -Min,
	my_max(NegX, NegY, NegMin).

	% my_abs(Var, Abs):
	% Abs is constrained to be the absolute value of Var.
my_abs(Var, Abs) :-
	Abs #>= 0,
	NegVar #= -Var,
	my_max(Var, NegVar, Abs).


Unfortunately, you don't get the convenience of being able to use such
user-defined predicates in constraint expressions.  i.e. X #= my_min(Y,
Z) + 2 won't work.  I expect to also fix this in the new hybrid library,
so that it works in much the same way as is/2 does now.

Anyway, hope that helps.

Cheers,
Warwick
Received on Thu Jan 25 16:41:25 2001

This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:07:07 PM GMT GMT