Como usar o compilador Prolog online
- Escreva seus fatos e regras no editor ou comece pelo exemplo com Restaurar exemplo.
- Diga o que executar com uma diretiva
:- initialization(main)., em quemainé um predicado que chama os objetivos que você quer testar e imprime os resultados. - Pressione Executar ou use Ctrl + Enter (⌘ + Enter no Mac). O programa é carregado como o arquivo
main.pl, e suas diretivas são executadas durante o carregamento. - Veja no painel Saída o texto impresso, os erros e os avisos. Escolha um limite de tempo de 5, 15 ou 60 segundos e use Parar se uma recursão nunca terminar.
O runtime do SWI-Prolog tem cerca de 4 MB e fica em cache no seu navegador depois da primeira visita. Guarde seu programa com Copiar ou com o download de main.pl, redimensione o texto com A− e A+, troque a disposição dos painéis com o botão de layout e use Tela cheia (Ctrl/⌘ + Shift + F, Esc para sair) para programas mais longos.
Tudo roda no seu navegador. O programa nunca é enviado a um servidor, e o editor guarda sua última versão apenas no armazenamento local do seu navegador.
O que é compatível
A página usa o SWI-Prolog 10 compilado para WebAssembly (swipl-wasm). É o sistema SWI-Prolog de verdade, não um interpretador simplificado.
- Consultar um arquivo: seu código é carregado exatamente como o
consult('main.pl')o carregaria, então cláusulas, operadores e diretivas funcionam. - Predicados de saída:
format/2,write/1,writeln/1,print/1enl/0imprimem no painel de saída. - Listas e predicados de todas as soluções:
member/2,append/3,length/2,msort/2,findall/3,bagof/3,setof/3,forall/2. - Aritmética com
is/2e os operadores de comparação, em inteiros e floats. O20!do exemplo é calculado de forma exata. - Diagnósticos como o SWI-Prolog os imprime, por exemplo avisos de variável singleton e erros como
ERROR: ... Arithmetic: `foo/0' is not a function.
O que é diferente de um Prolog de desktop:
- Não há prompt interativo de consulta
?-, então você não pode digitar consultas e pressionar;para ver mais respostas. Coloque as consultas emmaine imprima as respostas, ou reúna todas comfindall/3ouforall/2. - Sem entrada padrão. O
read/1não tem de onde ler, então escreva seus dados de teste como fatos.
O básico de Prolog em um programa
% Fatos
likes(mary, wine).
likes(john, wine).
likes(john, mary).
% Uma regra: X e Y são amigos se ambos gostam da mesma coisa
friends(X, Y) :- likes(X, Z), likes(Y, Z), X \== Y.
% Recursão sobre uma lista, com um acumulador
sum_list_acc([], Acc, Acc).
sum_list_acc([H|T], Acc0, Sum) :- Acc1 is Acc0 + H, sum_list_acc(T, Acc1, Sum).
% O corte (!) fixa a primeira cláusula que combinar
max(X, Y, X) :- X >= Y, !.
max(_, Y, Y).
main :-
findall(X-Y, friends(X, Y), Pairs), writeln(Pairs),
sum_list_acc([1,2,3,4], 0, S), format("sum = ~w~n", [S]),
max(3, 7, M), format("max = ~w~n", [M]).
:- initialization(main).
Ao ser executado, ele imprime [mary-john,john-mary], sum = 10 e max = 7.
Armadilhas comuns
=é unificação, não atribuição nem aritmética.X = 1 + 2ligaXao termo1+2. UseX is 1 + 2para avaliá-lo e=:=para comparar dois números.- As variáveis começam com letra maiúscula ou
_.nameé um átomo eNameé uma variável, então um erro de digitação em minúscula muda em silêncio o significado de uma cláusula. - Os avisos de singleton significam que uma variável aparece apenas uma vez em uma cláusula, o que geralmente é um erro de digitação. Renomeie-a para
_ou_Namese ela não for usada de propósito. - Use o corte com cuidado. O
max/3acima funciona paramax(3, 7, M), mas a segunda cláusula depende do corte, entãomax(5, 3, 3)tem sucesso por engano. Escrevermax(X, Y, Y) :- X < Y.como segunda cláusula o torna seguro. Um corte mal colocado também pode esconder soluções que, sem ele, ofindallretornaria. - A recursão à esquerda entra em loop. Uma regra como
ancestor(X, Y) :- ancestor(X, Z), parent(Z, Y).entra em recursão infinita. Coloque o objetivoparentprimeiro.
main falha em vez de ter sucesso, o SWI-Prolog imprime um aviso de que o objetivo de inicialização falhou. Adicione chamadas de writeln/1 entre os objetivos para ver até onde ele chega.Perguntas frequentes
Como executo uma consulta?
Escreva-a dentro de um predicado como main e adicione :- initialization(main). no fim do arquivo. Você também pode colocar um objetivo direto em uma diretiva, por exemplo :- X is 2^10, writeln(X).
É Prolog padrão?
É o SWI-Prolog, que segue o padrão ISO e acrescenta muitas extensões. O texto entre aspas duplas é uma string no SWI-Prolog, o que importa se você está acostumado a que ele represente uma lista de códigos de caracteres.
Posso obter todas as respostas de uma consulta?
Sim. Use findall/3 para reuni-las em uma lista ou forall/2 para imprimir cada uma, como o programa de exemplo faz.
Há outras linguagens lógicas ou funcionais disponíveis?
Experimente o Interpretador Scheme online ou o Compilador Clojure online, ou veja todos os compiladores online.
Atualizado