% vim: set ft=prolog:

%% int(-N) is nondet
%  
%  Verdadeiro se N é um número inteiro não negativo. Este predicado é um
%  gerador. A cada fez que ele é satisfeito ele gera um número.  Os números são
%  gerados usando retrocesso.
%
%  Exemplos
%  ?- int(N).
%  N = 0 ;
%  N = 1 ;
%  N = 2 ;
%  ....

int(0).
int(N) :-
    int(N0), N is N0 + 1.


%% intx(?N) is nondet
%
%  Versão do predicado int/1 que funciona com argumento instanciado ou não.

intx(N) :-
    nonvar(N), !,
    integer(N).

intx(0).
intx(N) :-
    int(N0),
    N is N0 + 1.


%% int_acc(-N) is nondet
%
%  Versão mais eficiente do predicado int/1.

int_acc(N) :-
    int_acc(0, N).

% A é um numero inteiro a partir de A.
int_acc(A, A).
int_acc(A, N) :-
    A1 is A + 1,
    int_acc(A1, N).


%% nao(:Goal) is semidet
%
%  Verdadeiro se Goal não pode ser provado.
%  Veja o predicado \+/1 do Prolog.
%  Exemplos
%  ?- nao(reverse([1, 2, 3], [3, 1, 2])).
%  true.
%  ?- nao(reverse([1, 2, 3], [3, 2, 1])).
%  false.

nao(P) :-
    call(P), !, fail.

nao(_).


%% primeiro_primo_maior_que(+N, -P) is det
%
%  Verdadeiro se P é o menor número primo maior igual a N.
%  Exemplos
%  ?- primeiro_primo_maior_que(10, P).
%  P = 11.

primeiro_primo_maior_que(N, P) :-
    int_acc(N, P),
    primo(P), !.

% O predicado primo/1 a seguir é o mesmo do arquivo fundamentos.pl. Veja uma
% definição alternativa no arquivo corteretrocesso.pl

%% primo(+X)
%  
%  Verdadeiro se X é um número primo.
%  ?- primo(2).
%  true.
%  ?- primo(3).
%  true.
%  ?- primo(5).
%  true.
%  ?- primo(7).
%  true.
%  ?- primo(19).
%  true.
%  ?- primo(4).
%  false.
%  ?- primo(6).
%  false.
%  ?- primo(8).
%  false.
%  ?- primo(9).
%  false.

primo(X) :-
    menor_divisor(X, 2, Y),
    X =:= Y.

% X é o menor divisor de X començando com X
menor_divisor(X, X, X) :- !.

% D é o menor divisor de X començando com D se X é divisível por D.
menor_divisor(X, D, D) :-
    divisivel(X, D), !.

menor_divisor(X, D, Y) :-
    \+ divisivel(X, D),
    D1 is D + 1,
    menor_divisor(X, D1, Y).

divisivel(X, Y) :-
    X rem Y =:= 0.
