[m-dev.] diff: lpQ - new module for linear programming over Q

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Fri Mar 13 12:05:11 AEDT 1998


Hello Vanessa,

I have one or two comments on your implementation of rationals.

>
> % file: rat.m
> % authors: conway, vjteag Jan 1998. 
> % 
> % Implements a rational number type and a set of basic operations on 
> % rational numbers.
> 
> :- module rat.

[...]

> 
> rat:'<'(r(An, Ad), r(Bn, Bd)) :-
> 	An*Bd < Bn*Ad.
> 
> rat:'>'(r(An, Ad), r(Bn, Bd)) :-
> 	An*Bd > Bn*Ad.
> 
> rat:'=<'(r(An, Ad), r(Bn, Bd)) :-
> 	An*Bd =< Bn*Ad.
> 
> rat:'>='(r(An, Ad), r(Bn, Bd)) :-
> 	An*Bd >= Bn*Ad.
> 
> 
> :- func ratnorm(rat) = rat.
> 
> rat(Num, Den) = ratnorm(r(Num, Den)).
> 
> rat:'='(r(An, Ad), r(Bn, Bd)) :-
> 	ratnorm(r(An, Ad)) = ratnorm(r(Bn, Bd)).

Why not implement this like the inequalities?  That is,

rat:'='(r(An, Ad), r(Bn, Bd)) :-
	An*Bd = Bn*Ad.


> rat:numer(r(Num, _)) = Num.
> 
> rat:denom(r(_, Den)) = Den.

Would it be a good idea to call ratnorm/1 on the input before returning
the numerator/denominator?

> :- func gcd(int, int) = int.
> 

There is a better way to calculate GCDs.  Here is a piece of code
outlining the general idea:

gcd(A, B) = GCD :-
        (B = 0 ->
                GCD = A
        ;
                GCD = gcd(B, mod(A, B))
        ).


Notice the lack of need for testing special cases.  You will need
to check that the version of 'mod' required for this algorithm is
the same as what is supplied by the Mercury library; if it isn't,
you'll have to write your own.

I give no guarantee that this code is optimal, so try to improve it
by all means!

Cheers,
Mark



More information about the developers mailing list