[mercury-users] Functional square root approximation : help needed
Ralph Becket
rbeck at microsoft.com
Thu Apr 26 23:42:18 AEST 2001
> % Mercurally speaking, this is:
>
> :- mode sqrt_guess(in, in, out) is det.
> sqrt_guess(Y, X, NewGuess) :-
> Quotient = X / Y,
> NewGuess = (Y + Quotient) / 2
> .
You can use functional style here:
:- func improve_guess(float, float) = float.
improve_guess(Guess, X) = (Guess + (X / Guess)) / 2.0.
Notice use of the float `2.0' rather than the int `2'.
> % (define (sqrt-iter guess x)
> % (if (good-enough? guess x)
> % guess
> % (sqrt-iter (improve guess x)
> % x)))
>
> :- mode sqrt_iter(in, in, out) is det.
> sqrt_iter(Guess,X,Answer) :-
> GoodEnough(Guess,X,Bool),
> (
> Bool = yes,
> Answer = Guess
> ;
> Bool = no,
> sqrt_guess(Guess,X,NewGuess),
> Answer = NewGuess
> )
> .
Here you've capitalised `GoodEnough', so the compiler thinks
it's a variable, making this an higher order predicate application.
Also, you've missed off the recursive case in the `Bool = no'
clause.
> :- mode GoodEnough(in, in, out) is det.
> GoodEnough(Guess,X,Bool) :-
> Assessment = abs(Guess * Guess - X),
> ( Assessment < 0.001,
> Bool = yes
> ;
> Bool = no
> )
> .
Same here.
Instead, try
:- func sqrt_iter(float, float) = float.
sqrt_iter(Guess, X) =
( if good_enough(Guess, X)
then Guess
else sqrt_iter(improve_guess(Guess, X), X)
).
:- pred good_enough(float, float).
:- mode good_enough(in, in) is semidet.
good_enough(Guess, X) :-
abs(Guess * Guess - X) < 0.001.
> :- mode main(in,out) is det.
> main(X,Answer) :- sqrt_iter(1.0,X,Answer).
It's a bad idea to use main/2 for anything other than the top-
level predicate in your program. How about this:
:- func square_root(float) = float.
square_root(Num) = sqrt_iter(1.0, Num).
-- Ralph
--------------------------------------------------------------------------
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