Miller–Rabin primality test: Difference between revisions

Content added Content deleted
No edit summary
Line 1,944: Line 1,944:
: (prime? 4547337172376300111955330758342147474062293202868155909393)
: (prime? 4547337172376300111955330758342147474062293202868155909393)
-> NIL</pre>
-> NIL</pre>

=={{header|Prolog_SWI}}==


<lang prolog>:- module(primality, [is_prime/2]).

% is_prime/2 returns false if N is composite, true if N probably prime
% implements a Miller-Rabin primality test and is deterministic for N < 3.415e+14,
% and is probabilistic for larger N
is_prime(1, Ret) :- Ret = false, !. % 1 is non-prime
is_prime(2, Ret) :- Ret = true, !. % 2 is prime
is_prime(3, Ret) :- Ret = true, !. % 3 is prime
is_prime(N, Ret) :-
N > 3, (N mod 2 =:= 0), Ret = false, !. % even number > 3 is composite
is_prime(N, Ret) :-
N > 3, (N mod 2 =:= 1), % odd number > 3
N < 341550071728321,
deterministic_witnesses(N, L),
is_mr_prime(N, L, Ret), !. % deterministic test
is_prime(N, Ret) :-
random_witnesses(N, 100, [], Out),
is_mr_prime(N, Out, Ret), !. % probabilistic test

% returns list of deterministic witnesses
deterministic_witnesses(N, L) :- N < 1373653,
L = [2, 3].
deterministic_witnesses(N, L) :- N < 9080191,
L = [31, 73].
deterministic_witnesses(N, L) :- N < 25326001,
L = [2, 3, 5].
deterministic_witnesses(N, L) :- N < 3215031751,
L = [2, 3, 5, 7].
deterministic_witnesses(N, L) :- N < 4759123141,
L = [2, 7, 61].
deterministic_witnesses(N, L) :- N < 1122004669633,
L = [2, 13, 23, 1662803].
deterministic_witnesses(N, L) :- N < 2152302898747,
L = [2, 3, 5, 7, 11].
deterministic_witnesses(N, L) :- N < 3474749660383,
L = [2, 3, 5, 7, 11, 13].
deterministic_witnesses(N, L) :- N < 341550071728321,
L = [2, 3, 5, 7, 11, 13, 17].

% random_witnesses/4 returns a list of K witnesses selected at random with range 2 -> N-2
random_witnesses(_, 0, T, T).
random_witnesses(N, K, T, Out) :-
G is N - 2,
H is 1 + random(G),
I is K - 1,
random_witnesses(N, I, [H | T], Out), !.

% find_ds/2 receives odd integer N and returns [D, S] s.t. N-1 = 2^S * D
find_ds(N, L) :-
A is N - 1,
find_ds(A, 0, L), !.

find_ds(D, S, L) :-
D mod 2 =:= 0,
P is D // 2,
Q is S + 1,
find_ds(P, Q, L), !.
find_ds(D, S, L) :-
L = [D, S].

is_mr_prime(N, As, Ret) :-
find_ds(N, L),
L = [D | T],
T = [S | _],
outer_loop(N, As, D, S, Ret), !.

outer_loop(N, As, D, S, Ret) :-
As = [A | At],
Base is powm(A, D, N),
inner_loop(Base, N, 0, S, Result),
( Result == false -> Ret = false
; Result == true, At == [] -> Ret = true
; outer_loop(N, At, D, S, Ret)
).
inner_loop(Base, N, Loop, S, Result) :-
Next_Base is (Base * Base) mod N,
Next_Loop is Loop + 1,
( Loop =:= 0, Base =:= 1 -> Result = true
; Base =:= N-1 -> Result = true
; Next_Loop =:= S -> Result = false
; inner_loop(Next_Base, N, Next_Loop, S, Result)
).</lang>


=={{header|PureBasic}}==
=={{header|PureBasic}}==