/****************** magica.pro ******************/

/* Defino minha mini-linguagem */

:-op(10, fy, [dado, um, vetor, com, no, qual, o, primeiro, eh, ultimo, intermediarios, 
              sao, incrementos, do, seja, para, se, elemento, imprima, fim]).
:-op(20, xfy, [elementos, e, um, de, a, do, primo]).
:-op(30, xfy, [faca]).

/* Defino os comandos da minha mini-linguagem */

term_expansion((dado um vetor com _ elementos no qual o primeiro eh A e o ultimo B e
os elementos intermediarios sao incrementos do mesmo), vetor(V)) :-
    criar_vetor(A,B,V).

term_expansion((seja i um inteiro), inteiro(i)). % Não interessa...

term_expansion((para I de A a B faca C), _) :-
    criar_vetor(A,B,V), % Seja um vetor de A a B
    member(X,V),        % e X um membro desse vetor
    chame(C,I,X),       % Faça o que foi pedido, usando I como alias pra X
    fail.               % Faça de conta que falhou. Tente de novo, com um novo membro
term_expansion((para _ de _ a _ faca _), feito). % Todos os números de A a B foram visitados

chame((se o elemento I do vetor eh um numero primo ProximaInstrucao), I, X) :-
  vetor(V),
  elemento(X,V,E),
  (primo(E) -> chame(ProximaInstrucao, I, E)).

chame((imprima I), I, X) :-
    writeln(X).

term_expansion(fim do programa, fim_do_programa). % Não interessa...

/* Implemento os comandos */

criar_vetor(A,A,[A]).
criar_vetor(A,B,[A|R]) :-
  A < B,
  A1 is A + 1,
  criar_vetor(A1,B,R).

elemento(_,[],_) :- fail.
elemento(1,[E|_],E) :- !.
elemento(X,[_|R],E) :-
    X1 is X - 1,
    elemento(X1,R,E).

primo(X) :-              % X não é primo se
    X1 is X - 1,
    criar_vetor(2,X1,V), % dado um vetor de 2 a X-1
    member(Y,V),         % existe um Y membro desse vetor
    0 =:= X mod Y,       % tal que X é multiplo de Y
    !, fail.
primo(_).                % Caso contrário ele é primo

/****************** codegolf.pro ******************/

dado um vetor com 20 elementos
no qual o primeiro eh 1 e o ultimo 20 e os 
elementos intermediarios sao incrementos do mesmo.
seja i um inteiro.
para i de 3 a 15 faca
se o elemento i do vetor eh um numero primo 
imprima i.
fim do programa.

/****************** ideone boilerplate ******************/

:- set_prolog_flag(verbose,silent).
:- prompt(_, '').
:- use_module(library(readutil)).

main:-
	process,
	halt.

process:-
	/* your code goes here */
	true.

:- main.