[mercury-users] ambiguous overloading causes type ambiguity.

Terrence Brannon princepawn at earthlink.net
Mon Apr 30 13:11:09 AEST 2001


[localhost:mercury/primality/divisors] metaperl% mmc -E --infer-all divisors.m
divisors.m:010: In clause for predicate `divisors:main/2':
divisors.m:010:   error: ambiguous overloading causes type ambiguity.
divisors.m:010:   Possible type assignments include:
divisors.m:010: V_15 :: string or (pred string)
	You will need to add an explicit type qualification to resolve the
	type ambiguity.
	The way to add an explicit type qualification
	is to insert a call to a dummy predicate whose `:- pred'
	declaration specifies the appropriate argument types.
[localhost:mercury/primality/divisors] metaperl% 

=== here is line 10:

main --> io__read_line_as_string(W0), 

=== and here is the program

:- module divisors.
:- interface.
:- import_module io.

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

:- implementation.
:- import_module std_util, int, list, bool, string.

main --> io__read_line_as_string(W0), 
     (
	{ W0 = eof },
	print("Nothing could be read"), nl
	;
	{ W0 = error(Err) },
	print(io__error_message(Err)), nl
	;
	{ W0 = ok(W),
	  I = string__det_to_int(W) },
	  io__write_string(test(I))
     ).

%	{ I = string__det_to_int(W) }, io__write_string(test(I)).
% main --> io__read_line_as_string(result(W)), { I = string__det_to_int(W) }, io__write_string(test(I)).
% main --> io__read_line_as_string(io__result(W)), { I = string__det_to_int(W) }, io__write_string(test(I)).

:- func test(int) = string.
:- mode test(in) = out is det.
test(X) = Ans :- (
	   prime(X) -> Ans = "is prime"
	   ;
	   Ans = "is not prime"
	   ).



%  Abelson and Sussman, SICP, Section 1.2.6

%  Since ancient times, mathematicians have been fascinated by problems
%  concerning prime numbers, and many people have worked on the problem
%  of determining ways to test if numbers are prime. One way to test if
%  a number is prime is to find the number's divisors. The following
%  program finds the smallest integral divisor (greater than 1) of a
%  given number n. It does this in a straightforward way, by testing n
%  for divisibility by successive integers starting with 2.

% (define (smallest-divisor n)
%   (find-divisor n 2))
% (define (find-divisor n test-divisor)
%   (cond ((> (square test-divisor) n) n)
%         ((divides? test-divisor n) test-divisor)
%         (else (find-divisor n (+ test-divisor 1)))))
% (define (divides? a b)
%   (= (remainder b a) 0))

:- func smallest_divisor(int) = int.
smallest_divisor(N) = find_divisor(N,2).


:- func find_divisor(int, int) = int.
find_divisor(N,TestDivisor) = Ans :-
 (
 TestDivisor*TestDivisor > N ->  Ans = N
  ;			  
 divides(TestDivisor,N)      ->  Ans = TestDivisor
  ;
 Ans = find_divisor(N,(1 + TestDivisor))
 )
 .

:- pred divides(int, int).
:- mode divides(in , in ) is semidet.
divides(A,B) :- rem(B,A) = 0.

% We can test whether a number is prime as follows: n is prime if and only if n is its own smallest divisor.

% (define (prime? n)
%   (= n (smallest-divisor n)))

:- pred prime(int). 
:- mode prime(in) is semidet.

prime(N) :- N = smallest_divisor(N).


% The end test for find-divisor is based on the fact that if n is not
% prime it must have a divisor less than or equal to n. This means
% that the algorithm need only test divisors between 1 and
% n. Consequently, the number of steps required to identify n as prime
% will have order of growth (n).


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