[mercury-users] sqrt.m:005: error: determinism declaration not satisfied.

Terrence Brannon princepawn at earthlink.net
Fri Apr 27 18:59:51 AEST 2001


[localhost:~/src/mercury/sqrt] metaperl% mmc -E --infer-all sqrt.m
sqrt.m:005: In `main(di, uo)':
sqrt.m:005:   error: determinism declaration not satisfied.
sqrt.m:005:   Declared `det', inferred `semidet'.
sqrt.m:080:   call to `to_float(in, out)' can fail.

... so when I got this error, I changed main/2 to semi det. Then I was
told:

[localhost:~/src/mercury/sqrt] metaperl% mmc -E --infer-all sqrt.m
sqrt.m:005: Error: main/2 must be `det' or `cc_multi'.

... what can I do? everything works when I hardcode the number to find
the square root of, but I am trying to get it from the command
line.. Entire program included for reference.

:- module sqrt.
:- interface.
:- import_module io.

:- pred main(io__state::di, io__state::uo) is semidet.

:- implementation.
:- import_module std_util, float, io, string, list.

%  Section 1.1.7 of Abelson and Sussman 
% "Structure and Interpretation of Computeer Programs"

% How does one compute square roots? The most common way is to use
% Newton's method of successive approximations, which says that whenever
% we have a guess y for the value of the square root of a number x, we
% can perform a simple manipulation to get a better guess (one closer to
% the actual square root) by averaging y with x/y. For example, we can
% compute the square root of 2 as follows. Suppose our initial guess
% is 1:
% 
% Guess		Quotient		Average

% 1		(2/1) = 2		((2 + 1)/2) = 1.5 
% 1.5		(2/1.5) = 1.3333	((1.3333 + 1.5)/2) = 1.4167 
% 1.4167	(2/1.4167) = 1.4118	((1.4167 + 1.4118)/2) = 1.4142 
% 1.4142	...			...

% Mercurally speaking, this is:

:- func improve_guess(float, float) = float.
improve_guess(Guess, X) = (Guess + (X / Guess)) / 2.0.

% Continuing this process, we obtain better and better approximations to
% the square root.
% 
% Now let's formalize the process in terms of procedures. We start with
% a value for the radicand (the number whose square root we are trying
% to compute) and a value for the guess. If the guess is good enough for
% our purposes, we are done; if not, we must repeat the process with an
% improved guess. We write this basic strategy as a procedure:
 
%  (define (sqrt-iter guess x)
%   (if (good-enough? guess x)
%       guess
%       (sqrt-iter (improve guess x)
%                  x)))
 
:- 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)
	)
	.


% We also have to say what we mean by ``good enough.'' The following
% will do for illustration, but it is not really a very good test. (See
% exercise 1.7.) The idea is to improve the answer until it is close
% enough so that its square differs from the radicand by less than a
% predetermined tolerance (here 0.001):

% (define (good-enough? guess x)
%   (< (abs (- (square guess) x)) 0.001))

:- pred good_enough(float, float).
:- mode good_enough(in, in) is semidet.
good_enough(Guess,X) :- abs(Guess * Guess - X) < 0.001.

% Finally, we need a way to get started. For instance, we can always
% guess that the square root of any number is 1

% (define (sqrt x)
%   (sqrt-iter 1.0 x))


% main --> { X = sqrt(22.4) }, io__print(X), io__nl.
main -->
	io__command_line_arguments(ArgV),
	{ if ArgV = [Arg1 | _] then string__to_float(Arg1,X) else (X = 12.0) },
	{ Answer = sqrt(X) },
	io__print(Answer).



:- func sqrt(float) = float.
sqrt(Num) = 
%		 ( if Num < 0 
%		   then io_write_string("no solution"), fail.
sqrt_iter(1.0, Num).

--------------------------------------------------------------------------
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