1 O que é Prolog? História. Características. Conceitos Básicos. Fatos. A sintaxe e as regras do Prolog. Executando um programa em Prolog. Campos de uso e algumas aplicações. “Hello World” em Prolog. 99 bottles of beer em Prolog. Bibliografia. 2 Prolog é uma linguagem de programação que se enquadra no paradigma de Programação em Lógica Matemática. É uma linguagem de uso geral que é especialmente associada com a inteligência artificial e lingüística computacional. Consiste numa linguagem puramente lógica, que pode ser chamada de Prolog puro, e numa linguagem concreta, a qual acrescenta o Prolog puro com componentes extra-lógicos. 3 Apesar do longo tempo de desenvolvimento, Prolog ainda não é uma linguagem portável, já que cada implementação usa rotinas completamente diferentes e incompatíveis entre si. Por exemplo, um programa trivial que faz um loop de ler uma linha da console e escreve a mesma linha, terminando quando for entrada uma linha vazia, é impossível de ser escrito de forma que qualquer interpretador consiga rodar. 4 O nome Prolog para a linguagem concreta foi escolhido por Philippe Roussel como uma abreviação de “PROgrammation en LOGique”. Foi criada em meados de 1972 por Alain Colmerauer e Philippe Roussel, baseados no conceito de Robert Kowalski da interpretação procedimental das cláusulas de Horn. 5 A motivação para isso veio em parte da vontade de reconciliar o uso da lógica como uma linguagem declarativa de representação do conhecimento com a representação procedimental do conhecimento, que era popular na América do Norte no final da década de 1960 para início de 1970. 6 Muito do desenvolvimento moderno do Prolog veio dos projetos de computadores da quinta geração (FGCS), que desenvolveu uma variante do Prolog chamada Kernel Language para seu primeiro sistema operacional. 7 O Prolog é uma linguagem declarativa, ou seja, ao invés de o programa estipular a maneira de chegar à solução passo-a-passo, como acontece nas linguagens procedimentais ou orientadas a objeto, ele fornece uma descrição do problema que se pretende computar utilizando uma coleção de fatos e regras (lógica) que indicam como deve ser resolvido o problema proposto. Como podemos ver, o Prolog é mais direcionado ao conhecimento do que aos próprios algoritmos. 8 Além de ser uma linguagem declarativa, outro fato que o difere das outras linguagens é a questão de não possuir estruturas de controle (if-else, do-while, for, switch) presentes na maioria das linguagens de programação. Para isso utilizamos métodos lógicos para declarar como o programa deverá atingir o seu objetivo. 9 Um programa em Prolog pode rodar em um modo interativo, o usuário poderá formular queries utilizando os fatos e as regras para produzir a solução através do mecanismo de unificação. 10 O Prolog é baseado num subconjunto do cálculo de predicados de primeira ordem, o que é definido por cláusulas de Horn. A execução de um programa em Prolog é efetivamente a prova de um teorema por resolução de primeira ordem. Alguns conceitos fundamentais são unificação, recursão, e backtracking. 11 Em Prolog são fornecidos os fatos e as regras para uma base de dados, que posteriormente serão executadas consultas (queries) em cima da base de dados. 12 A estrutura de um fato é formada por um predicado, seus argumentos (objetos) e finalizamos a instrução com um ponto(.) equivalente ao ponto-vírgula das linguagens comuns de programação. Veja a seguir: predicado(argumento1,argumento2...). O predicado é a relação sobre os quais os objetos irão interagir. Exemplos: -> amiga(joana, maria). Definimos uma relação de amizade entre dois objetos, joana e maria. -> homem(jose). Note que quando usamos apenas um objeto, o predicado passa a ser uma característica do próprio objeto. 13 Então apenas para concluir, é importante ressaltar que os nomes dos predicados e dos objetos devem sempre começar por letra minúscula como devem ter notado nos exemplos anteriores. Os predicados são escritos primeiro, seguido pelos objetos que são separados por vírgula. Também é importante lembrar de que a ordem dos objetos poderá interferir no resultado de uma aplicação. 14 Sintaxe: Prolog não emprega tipos de dados do mesmo modo que as linguagens de programação mais comuns normalmente fazem. Todos os dados são tratados como sendo de um único tipo, Termo, cuja natureza depende da forma como esse termo foi declarado. Ou seja, os elementos léxicos utilizados na sua declaração determinam se esse termo será um número, um texto, uma variável, uma estrutura complexa e assim por diante. 15 Com exceção de átomos numéricos, funções ou predicados construídos, os nomes em Prolog para constantes, variáveis, funções e predicados, não têm nenhum significado intrínseco e podem ser escolhidos livremente pelo programador. Em geral, duas notações distintas denotarão ou serão objetos distintos. Como em qualquer linguagem de programação, a cada nome deve ser dado um escopo. 16 Em Prolog, as regras de escopo são: O escopo de uma variável é a asserção (fato, regra, ou consulta) na qual aparece. O escopo de qualquer outro nome (constante, nome de função, ou nome de predicado) é todo o programa. Isto significa que um nome de variável pode ser utilizado e reutilizado a vontade no programa para denotar variáveis diferentes, enquanto qualquer outra notação representa, ou é, o mesmo objeto para o programa todo. 17 Átomos: As constantes de texto são introduzidas por meio de átomos. Um átomo é uma seqüência constituída de letras, números e underscore, mas iniciando com uma letra minúscula. Se um átomo não alfanumérico é necessário, pode-se usar qualquer seqüência entre aspas simples (ex: 'um átomo contendo espaços'). 18 Um átomo pode ser definido das seguintes maneiras: começando com letra minúscula: pedro henrique_iv como uma sequência de caracteres entre aspas simples: 'quem é você?' 'eu não sei'. 19 Números: Um número é uma seqüência de dígitos, permitindo também os sinais de . (para números reais), - (número negativo) e e (notação científica). Algumas implementações do Prolog não fazem distinção entre inteiros e números reais. Exemplos: 321 3.21 20 Váriaveis: Uma variável Prolog é como uma incógnita, cujo valor é desconhecido a princípio mas, após descoberto, não sofre mais mudanças. Um tipo especial de variável, a variável anônima (explicada mais adiante), é uma expressão que significa 'qualquer variável', e é escrita como um único subtraço (_). Exemplos: X Nome Rei_da_Espanha 21 Termos compostos: Termos compostos são a única forma de se expressar estruturas de dados complexas em Prolog. Um termo composto consiste de uma cabeça, também chamada funtor (que é obrigatoriamente um átomo) e parâmetros (de quaisquer tipos) listados entre parênteses e separados por vírgulas. O número de parâmetros, chamado aridade do termo, é significativo. Um termo é identificado por sua cabeça e aridade, normalmente escrita como funtor/aridade. Átomos e números também podem ser identificados dessa forma, como um termo de aridade zero (ex: um_atomo/0). 22 Strings: São normalmente escritas como uma seqüência de caracteres entre aspas. É comum serem representadas internamente como listas de códigos de caracteres, em geral utilizando a codificação local ou Unicode, se o sistema dá suporte a Unicode. O ISO Prolog também permite que strings sejam representadas por uma lista de átomos com um único caractere. 23 Questões: A sintaxe das questões varia de acordo com os compiladores existentes, mas basicamente é um fato antecedido de um ponto de interrogação ou o comando apropriado para o tipo de compilador. Por exemplo: ?- amiga(joana,maria). Quando uma questão é feita, o Prolog realiza uma busca na sua base de conhecimento, procurando um fato que seja igual ao da questão. Se o fato for encontrado é retornado "YES", caso contrário o programa retornará a saída "NO". 24 Operadores: No Prolog existem tanto os operadores relacionais quanto os aritméticos. Entre os operadores relacionais temos: Igualdade: = Diferença: \= (em alguns compiladores o operador de diferença é "<>") Menor que: < Maior que: > Menor ou igual: =< (alguns compiladores seguem a versão ">=") Maior ou igual: >= 25 Vamos construir um pequeno exemplo com operadores relacionais para verificar se o número passado é positivo ou negativo. Para isso, construiremos a seguinte regra: positivo(numero) :- numero > 0. Em seguida realizaremos uma consulta: ?- positivo(2). Que retornará "Yes". 26 Agora vamos aos operadores ariméticos. São eles: +, -, *, /, mod, is. O operador mod é utilizado quando quisermos obter o módulo, e o operador is é utilizado para obtermos um resultado. 27 Verifique a seguinte regra: o_dobro(Numero,Result) :- Result is Numero * 2. Realizaremos a questão: ?- o_dobro(5,X). Obteremos o resultado: X = 10 É importante lembrar que uma variável terá que receber o valor da operação aritmética através do operador "is". 28 Entrada e saída: Já vimos como atribuir os fatos, como construir regras e fazer questões sobre elas, mas tudo que recebemos como retorno, foi um "Yes" ou "No". Assim como nas outras linguagens, o Prolog também possui propriedades de entrada e saída de dados, são eles read() e write(). 29 Vamos ver um pequeno exemplo: ola :- read(X), write('Olá '), write(X). Faremos a chamada: ?- ola. 'Luciano'. Note que a regra não possuiu nenhum parâmetro, portanto colocamos apenas o nome da regra sem atributos, e em seguida o dado a ser lido pelo comando read(X), lembrando que cada instrução sempre é finalizada com um ponto(.). 30 É importante ressaltar que dados equivalentes ao tipo "String" de outras linguagens, devem sempre ser utilizados entre apóstrofos, caso contrário, quando digitássemos o nome "Luciano", o compilador iria aceitar a entrada como uma variável não alocada, e imprimiria um valor estranho na saída. 31 Regras: Utilizamos as regras para fazermos a construção de questões complexas. Especificamos situações que podem ser verdadeiras se algumas condições forem satisfeitas. 32 Para utilizarmos uma regra, usamos o símbolo ":-" que indica uma condição (se). Vamos exemplificar o uso da regra com um exemplo simples. Dados os fatos: pai(arthur,silvio). pai(arthur,carlos). pai(carlos,xico). pai(silvio,ricardo). 33 Utilizaremos a seguinte regra: avo(X,Z) :- pai(X,Y), pai(Y,Z). Isso significa que se alguém é pai de uma pessoa, que por sua vez é pai de outra pessoa, então ele é avô. Vamos realizar uma querie para conferir a regra: ?- avo(arthur,xico),avo(arthur,ricardo). Retornará a saída: "YES" Ou seja, "arthur" é avô de "xico" e "ricardo", pois "arthur" é pai de "silvio" e "carlos", que por sua vez são pais de "xico" e "ricardo". 34 Para executar os exemplos mostrados, foi utilizada a ferramenta JPE (Java Prolog Environment), desenvolvido por estudantes da UFRJ. O JPE é um ambiente muito simples e ágil de se trabalhar, capaz de executar instruções do padrão SWI Prolog. O download pode ser feito através do site http://jpe.dcc.ufrj.br/pt/index.php. 35 36 Como podemos ver na figura, o JPE é uma IDE muito simples, constituída basicamente de 3 pontos principais: 1- Na barra superior, colocaremos as questões. Note que não é necessário utilizar o operador "?" antes das consultas, pois o JPE se responsabilizará por isso. 2- A parte central será onde colocaremos todos os nossos fatos e regras. 3- A parte inferior apresenta um console, mostrando todas as ações feitas pelo compilador e imprimindo a saída do programa. 37 Como podemos ver, o Prolog é uma linguagem muito poderosa, principalmente na área de Inteligência Artificial onde é líder absoluta. Entre as implementações do Prolog, podemos citar o Visual Prolog (Turbo Prolog), o SWI Prolog, GNU Prolog, Amzi! Prolog, entre muitas outras já existentes. 38 Algumas outras: LPA Prolog (http://www.lpa.co.uk/) Open Prolog (http://www.cs.tcd.ie/open-prolog/) Ciao Prolog (http://www.clip.dia.fi.upm.es/Software/Ciao) YAP Prolog (http://www.ncc.up.pt/~vsc/Yap) Strawberry Prolog (http://www.dobrev.com/) SICStus Prolog (http://www.sics.se/sicstus/) B-Prolog (http://www.probp.com/) tuProlog (http://tuprolog.sourceforge.net/) - Código Aberto integrável ao Java XSB (http://xsb.sourceforge.net/) Trinc Prolog (http://www.trinc-prolog.com) hProlog ( http://www.cs.kuleuven.ac.be/~bmd/hProlog/ ) ilProlog ( http://www.pharmadm.com/dmax.asp ) CxProlog ( http://ctp.di.fct.unl.pt/~amd/cxprolog/ ) NanoProlog ( http://ctp.di.fct.unl.pt/~amd/cxprolog/ ) 39 hello :- display('Hello World!') , nl . 40 % 99 bottles of beer song implemented in Prolog % Released into the public domain in 2006 by Brent Spillner wall_capacity(99). wait(_) :- true. report_bottles(0) :- write('no more bottles of beer'), !. report_bottles(X) :- write(X), write(' bottle'), (X = 1 -> true ; write('s')), write(' of beer'). report_wall(0, FirstLine) :(FirstLine = true -> write('No ') ; write('no ')), report_bottles('more'), write(' on the wall'), !. report_wall(X, _) :- report_bottles(X), write(' on the wall'). sing_verse(0) :- !, report_wall('No more', true), write(', '), report_bottles('no more'), write('.'), nl, write('Go to the store and buy some more, '), wall_capacity(NewBottles), report_wall(NewBottles, false), write('.'), nl. sing_verse(X) :- report_wall(X, true), write(', '), report_bottles(X), write('.'), nl, write('Take one down and pass it around, '), Y is X - 1, report_wall(Y, false), write('.'), nl, nl, wait(5), sing_verse(Y). :- wall_capacity(Bottles), sing_verse(Bottles). 41 http://www.linhadecodigo.com.br/Artigo.aspx?id=1697 PROLOG. Disponível em: http://www.din.uem.br/ia/ferramen/prolog/. PROLOG, Wikipédia - Enciclopédia livre. Disponível em: http://pt.wikipedia.org/wiki/Prolog. JACQUES ROBIN, Slides sobre Fundamentos do Prolog. 42