[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