[mercury-users] Emacs mode; a_solution?
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Jan 4 14:22:06 AEDT 2002
On 03-Jan-2002, Ralph Becket <rafe at cs.mu.OZ.AU> wrote:
> Douglas Michael Auclair, Thursday, 3 January 2002:
> > * Is there a method to solving a system of equations (m variables over
> > n equations, m <= n)? Not talking CLP, as there is only one solution
> > over the systems I'm working ... I get unbound errors when I try:
> >
> > system_of_eqns(A, B) :- 2 * A + B = 5, A - B = 7.
>
> The Mercury modes for integer addition and subtraction work where any
> two of the three arguments are inputs (this isn't true for
> multiplication or floats). However, there's no way of reordering your
> goals to satisfy the two-input requirement, which is why Mercury is
> reporting an error.
>
> You could implement Gaussian elimination, I suppose.
Doing something like that is going to be the most efficient approach.
A less efficient but simpler alternative would be to use a
generate-and-test strategy or a constrain-and-then-generate strategy.
This requires knowing a suitable range for the values of the variables.
For example, if you know that the values of A and B will both be
between -100 and 100, you could write this system_of_eqns/2 as
:- pred system_of_eqns(int::out, int::out) is nondet.
system_of_eqns(A, B) :-
2 * A + B = 5,
A - B = 7,
between(-100, 100, A),
between(-100, 100, B).
%
% between(Min, Max, X):
% X is between Min and Max inclusive
%
:- pred between(int, int, int).
:- mode between(in, in, in) is semidet.
:- mode between(in, in, out) is nondet.
:- pragma promise_pure(between/3).
between(Min::in, Max::in, X::in) :-
X >= Min,
X =< Max.
between(Min::in, Max::in, X::out) :-
( Min = Max ->
X = Min
;
Min < Max,
(
X = Min
;
Min1 is Min + 1,
between(Min1, Max, X)
)
).
This code makes use of mode-specific clauses, which is a new feature in
the latest development versions of Mercury; for Mercury 0.10, you can
write it like this instead:
:- pred system_of_eqns(int::out, int::out) is nondet.
system_of_eqns(A, B) :-
2 * A + B = 5,
A - B = 7,
between_generate(-100, 100, A),
between_check(-100, 100, B).
:- pred between_check(int, int, int).
:- mode between_check(in, in, in) is semidet.
between_check(Min, Max, X) :-
X >= Min,
X =< Max.
:- pred between_generate(int, int, int).
:- mode between_generate(in, in, out) is nondet.
between_generate(Min, Max, X) :-
( Min = Max ->
X = Min
;
Min < Max,
(
X = Min
;
Min1 is Min + 1,
between_generate(Min1, Max, X)
)
).
> > * Writing of CLP ... is constraints.m available for hacking on (I saw
> > mention of it in an archive)?
I'm not sure what you're referring to here. There is a module
`compiler/constraint.m' which is included in the Mercury compiler
source distribution, but I don't think that is what you're after.
The source code for the Mercury modules which implement the CLP(R) interface is
available -- they are in the files clpr/*.m in the mercury-extras distribution.
> > I saw the CLP(R) implementation in the
> > extras package with the associated warnings. I was wondering if there
> > was an open-source, freely-usable implementation to work on and to
> > use.
I believe there are open-source, freely-usable constraint packages
written in C (for a list, try asking on the comp.constraints newsgroup),
and it would be possible to write a Mercury interface to one of these,
using the same approach as is used in the Mercury interface to CLP(R).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list