Comparada com uma linguagem procedural típica como Pascal, Prolog é bem diferente. Em Pascal temos:
entrada -----> programa ----> saída
Em Prolog:
pergunta ----> mundo -----> resposta
ou seja, o programa é a descrição de um mundo artificial, inventado pelo programador. Sobre este mundo são feitas perguntas (a "entrada" do programa) e suas respostas são a saída.
Prolog trabalha com a noção de "mundo fechado", ou seja, tudo o que não for descrito como verdadeiro é considerado falso. Não existe o "não sei", que tanto sucesso trouxe a Sócrates. Por exemplo:
mundo: ama(pedro,sara).
pergunta: ?- ama(pedro,sara).
resposta: Yes
pergunta: ?- ama(pedro,maria).
resposta: No
No mundo diz-se apenas que Pedro ama Sara (com iniciais minúsculas
pois são constantes; veremos isto mais tarde). Portanto, Pedro não
ama Maria, nem ninguém além de Sara.
O mundo é descrito através de fatos e regras. É
preciso conhecer a sintaxe destas cláusulas, e também das
perguntas, para poder programar em Prolog.
Em Prolog, os identificadores são formados por letras, dígitos
e sublinhado (underscore, em inglês: o caractere "_"), e tem que
começar com letra ou sublinhado. Os identificadores que têm
inicial minúscula representam constantes. Aqueles com inicial maiúscula
são variáveis. Os que se iniciam com sublinhado são
variáveis anônimas.
Exemplo de constantes: casa, maria, pedro, comer.
Exemplo de variáveis: X, Valor, Casa_propria, Tail, _ignore.
A descrição do mundo em Prolog se faz através
de fatos e regras. Mas antes vamos falar de termos.
gosta(pedro,sara)
|
\ \
predicado argumentos
Um termo é formado por um funtor (constante) e por uma lista de argumentos separados por vírgula e envoltos em parêntesis. Embora os argumentos possam ser constantes ou variáveis, o funtor é sempre constante. Um fato é um termo seguido de ponto final.
Exemplo: gosta(pedro,sara).
Uma regra possui cabeça e cauda separadas pelo sinal ":-" que significa "if", e termina em ponto final. A cabeça é um termo, e a cauda é uma conjunção de termos, ou seja, uma lista de termos separados por vírgula, que significa "and" no sentido lógico.
Exemplo: gosta(pedro,X) :- bonita(X), alegre(X).
Esta cláusula significa que Pedro gosta de todos os objetos X tais que X é bonita e X é alegre. Em outras palavras, Pedro gosta de X "se" X é bonita e X é alegre.
Fatos e regras são cláusulas. O escopo de uma variável se limita à cláusula onde ela se encontra. Assim, as três ocorrências de X acima se referem à mesma variável, mas as duas ocorrências de X abaixo são variáveis diferentes:
gosta(pedro,X).
ama(jorge,X).
Prolog é uma linguagem interpretada e seu interpretador usa
como prompt o sinal "?-". Uma pergunta tem a mesma sintaxe da cauda de
uma regra. Ao receber uma pergunta, Prolog trata cada um dos termos dela
como metas a serem verificadas contra o banco de dados (descrição
do mundo). Se a meta casa com um fato, ela é tida como verdadeira.
Dizemos que a meta foi satisfeita. Se a meta casa com a cabeça
de uma regra, ela produz sub-metas para cada termo da cauda da regra. Se
uma meta não casa com nenhum fato nem com a cabeça de nenhuma
regra, ela falha, ou seja, é considerada falsa. A falha de
uma meta desencadeia o backtracking.
Casamentos podem levar à instanciação de variáveis.
Na verdade, este e' o único meio de "atribuir" valores a variáveis
em Prolog.
Cada meta possui seu próprio ponteiro ao banco de dados no
caso de uma busca. A ordem das cláusulas no banco é importante,
pois é nesta ordem que elas são testadas para cada meta.
Se uma meta A falha, a resposta dada por Prolog é "No", a não
ser que a meta tenha uma meta anterior a ela numa conjunção.
Neste caso ocorre uma tentativa de re-satisfação da meta
anterior: seu casamento corrente é desfeito (inclusive com desinstanciação
de variáveis) e seu ponteiro no banco de dados é avançado
em busca de outros casamentos. Se encontrados, a meta A é tentada
novamente e assim por diante., num vai-e-vem de satisfação,
falha e re-satisfação, até que a pergunta que deu
origem a tudo tenha todas as metas satisfeitas ou falhe.
O corte (!) é um predicado pré-definido, meta-lógico,
sem argumentos e que sempre é satisfeito, mas nunca é re-satisfeito.
Além disso, se for feita uma tentativa de re-satisfação
do corte, ele não apenas falha como também causa a falha
incondicional da meta-mãe (a meta que casou com a cabeça
da regra onde está o corte).
O corte é usado para implementar negação (em combinação
com o predicado pré-definido fail) ou por questões de eficiência.
Prolog possui os predicados pré-definidos +, -, *, /, mas
um termo como +(2,3) (que pode também ser escrito em notação
infixa: 2 + 3) não é muito diferente de termos como gosta(pedro,
sara). Para "executar" a operação aritmética é
preciso usar o predicado pré-definido is:
X is 2 + 3
Observe o comportamento de Prolog para a pergunta
?- X = 2 + 3.
X = +(2,3)
e agora para
?- X is 2 + 3.
X = 5
Como se vê, é necessário um is para efetuar
a operação. O predicado is requer que no seu lado
direito haja uma expressão aritmética válida e com
todos os argumentos possuindo valores numéricos. Isso inclui as
variáveis, que devem estar instanciadas com valores numéricos.
Ainda falta escrever...
Notas feitas `as pressas por J. Meidanis, Dez/2000.