Escolar Documentos
Profissional Documentos
Cultura Documentos
Programas Prolog
Objetos
Nesta aula será vista a sintaxe e (Termos)
semântica de conceitos básicos
em Prolog e introduz objetos de
dados estruturados
Objetos
Os tópicos abordados são: Simples
Estruturas
Objetos simples (átomos,
números, variáveis)
Objetos estruturados
Unificação como operação Constantes
fundamental em objetos Variáveis
(Atômicos)
Operadores
Significado declarativo e
Inteligência Artificial procedural
Átomos Números
José Augusto Baranauskas E-mail: augusto@usp.br
Departamento de Física e Matemática – FFCLRP-USP URL: http://dfm.fmrp.usp.br/~augusto
2
Átomos Números
São cadeias compostas pelos seguintes caracteres: Números usados em Prolog incluem
letras maiúsculas: A, B, ..., Z
letras minúsculas: a, b, ..., z números inteiros e números reais
dígitos: 0, 1, ..., 9
caracteres especiais: + - * / < > = : . & _ ~ Operadores Aritméticos Operadores Relacionais
Podem ser construídos de três maneiras: adição + X>Y X é maior do que Y
cadeias de letras, dígitos e o caractere ‘_’, começando com uma subtração - X<Y X é menor do que Y
letra minúscula: anna, nil, x25, x_25, x_25AB, x_, x__y,
multiplicação * X >= Y X é maior ou igual a Y
tem_filhos, tem_um_filho
cadeias de caracteres especiais: <--->, =====>, ..., .:., ::= divisão / X =< Y X é menor ou igual a Y
cadeias de caracteres entre apóstrofos: ‘Abraão’, divisão inteira //
X =:= Y X é igual a Y
‘América_do_Sul’, ‘América_Latina’ resto divisão inteira mod
X=Y X unifica com Y
potência **
atribuição is X =\= Y X é diferente de Y
3 4
Números Variáveis
O operador = tenta unificar apenas São cadeias de letras, dígitos e caracteres ‘_’,
?- X = 1 + 2. sempre começando com letra maiúscula ou com
X = 1 + 2 o caractere ‘_’
O operador is força a avaliação aritmética X, Resultado, Objeto3, Lista_Alunos, ListaCompras,
?- X is 1 + 2. _x25, _32
X = 3 O escopo de uma variável é dentro de uma
Se a variável à esquerda do operador is já estiver mesma regra ou dentro de uma pergunta
instanciada, Prolog apenas compara o valor da variável Isto significa que se a variável X ocorre em duas
com o resultado da expressão à direita de is regras/perguntas, então são duas variáveis
?- X = 3, X is 1 + 2. distintas
X = 3
Mas a ocorrência de X dentro de uma mesma
?- X = 5, X is 1 + 2.
no regra/pergunta significa a mesma variável
5 6
1
Variáveis Variável Anônima
Uma variável pode estar: Quando uma variável aparece em uma única
Instanciada: quando a variável já referencia cláusula, não é necessário utilizar um nome para
(está unificada a) algum objeto ela
Livre ou não-instanciada: quando a variável Utiliza-se a variável anônima, que é escrita com
não referencia (não está unificada a) um um simples caracter ‘_’. Por exemplo
objeto, ou seja, quando o objeto a que ela temfilho(X) :- progenitor(X,Y).
referencia ainda não é conhecido
Para definir temfilho, não é necessário o nome
Uma vez instanciada, somente Prolog pode do filho(a)
torná-la não-instanciada através de seu
Assim, é o lugar ideal para a variável anônima:
mecanismo de inferência (nunca o
temfilho(X) :- progenitor(X,_).
programador)
7 8
9 10
Estruturas Estruturas
2
Estruturas Estruturas
4 maio 2003 2 4 3 6 4 2
13 14
15 18
3
Unificação de Termos Unificação de Termos
?- data(D,M,2003) = data(D1,maio,A),
Por outro lado, não há unificação entre os termos
data(D,M,2003) = data(15,maio,A1).
D = 15 data(D,M,2003) e data(D1,M1,1948)
M = maio data(X,Y,Z) e ponto(X,Y,Z)
D1 = 15
A unificação é um processo que toma dois termos
A = 2003
A1 = 2003 e verifica se eles unificam
Se os termos não unificam, o processo falha (e as
?- triângulo = triângulo, ponto(1,1) = X, variáveis não se tornam instanciadas)
A = ponto(4,Y), ponto(2,3) = ponto(2,Z).
X = ponto(1,1)
Se os termos unificam, o processo tem sucesso e
A = ponto(4,_G652) também instancia as variáveis em ambos os termos
Y = _G652 para os valores que os tornam idênticos
Z = 3
21 22
unificam são: X unifica com Y que é verdadeiro quando dois termos são o
mesmo. Entretanto, se um dos termos é uma variável, o
X=Y
se S e T são constantes, então S e T unificam operador = causa a instanciação da variável porque o
operador causa unificação
somente se são o mesmo objeto X \= Y X não unifica com Y que é o complemento de X=Y
se S for uma variável e T for qualquer termo, X é literalmente igual a Y (igualdade literal), que é verdadeiro
se os termos X e Y são idênticos, ou seja, eles têm a mesma
então unificam e S é instanciado para T X == Y
estrutura e todos os componentes correspondentes são os
mesmos, incluindo o nome das variáveis
se S e T são estruturas, elas unificam somente X \== Y X não é literalmente igual a Y que é o complemento de X==Y
se X @< Y X precede Y
S e T têm o mesmo functor principal e X @> Y Y precede X
todos seus componentes correspondentes unificam X @=< Y X precede ou é igual a Y
X @>= Y Y precede ou é igual a X
23 24
25 26
4
Precedência de Termos Unificação de Termos
?- X @< 10. ?- g(X) @< f(X,Y). Unificação em Prolog é diferente da unificação
yes yes em Lógica
?- X @< isaque. ?- f(Z,b) @< f(a,A). A unificação Lógica requer a verificação de
yes yes ocorrência de uma variável em um termo (occurs
?- X @< f(X,Y). ?- 12 @< 13. check), que, por razões de eficiência, não é
yes yes implementado em Prolog
?- 10 @< sara. ?- 12.5 @< 20. Mas de um ponto de vista prático, a aproximação
yes yes de Prolog é bem adequada
?- 10 @< f(X,Y). ?- g(X,f(a,Y)) @<
Exemplo:
yes g(X,f(b,Y)).
?- X = f(X).
?- isaque @< sara. yes X = f(f(f(f(f(f(f(f(f(f(...))))))))))
yes
27 28
5
Exemplo: Macaco & Banana Exemplo: Macaco & Banana
Quais os movimentos permitidos que alteram o mundo de O movimento ‘pegar a banana’ com sua pré-condição no
um estado para outro? estado antes do movimento pode ser definido por:
Pegar a banana move(estado(no_centro,acima_caixa,no_centro,não_tem),
Subir na caixa pegar_banana,
estado(no_centro,acima_caixa,no_centro,tem) ).
Empurrar a caixa
Caminhar no chão da sala Este fato diz que após o movimento o macaco tem a banana e ele
permanece acima da caixa no meio da sala
Nem todos os movimentos são possíveis em cada estado
do mundo Vamos expressar o fato que o macaco no chão pode
‘pegar a banana’ somente é possível se o macaco está acima da caminhar de qualquer posição horizontal Pos1 para
caixa diretamente abaixo da banana e o macaco ainda não tem a qualquer posição Pos2
banana move(estado(Pos1,no_chão,Caixa,Banana),
Vamos formalizar em Prolog usando a relação move caminhar(Pos1,Pos2),
move(Estado1,Movimento,Estado2) estado(Pos2,no_chão,Caixa,Banana) ).
onde Estado1 é o estado antes do movimento, Movimento é o De maneira similar, os movimentos ‘empurrar’ e ‘subir’
movimento executado e Estado2 é o estado após o movimento
podem ser especificados
33 34
35 36
6
Listas Listas
O uso de colchetes é apenas uma melhoria da No exemplo [ana, tênis, pedro]
notação, pois internamente listas são ana é a Cabeça da lista
representadas como árvores, assim como todos [tênis, pedro] é a Cauda da lista
objetos estruturados em Prolog A cabeça de uma lista pode ser qualquer objeto
39 40
Listas Listas
?- Lista1 = [a,b,c],
Assim, para representar listas de qualquer Lista2 = .(a,.(b,.(c,[]))).
comprimento, nenhum princípio adicional é Lista1 = [a, b, c]
Lista2 = [a, b, c]
necessário
?- Hobbies1 = .(tênis, .(música,[])),
O exemplo [ana, tênis, pedro] é . Hobbies2 = [esqui, comida],
representando como o termo: L = [ana,Hobbies1,pedro,Hobbies2].
Hobbies1 = [tênis,música]
ana .
.(ana, .(tênis, .(pedro, []) ) ) Hobbies2 = [esqui,comida]
L = [ana, [tênis,música], pedro, [esqui,comida]]
O programador pode escolher tênis .
ambas notações pedro []
41 42
43 44
7
Operações em Listas Predicado de Pertinência
Freqüentemente, é necessário realizar Inicialmente, é necessário definir o nome do predicado
que verifica se um elemento X pertence ou não a uma
operações em listas, por exemplo, buscar lista Y, por exemplo, pertence(X,Y)
um elemento que faz parte de uma lista A primeira condição especifica que um elemento X
Para isso, a recursão é o recurso mais pertence à lista se ele está na cabeça dela. Isto é
indicado como:
amplamente empregado pertence(X,[X|Z]).
Para verificar se um nome está na lista, é A segunda condição especifica que um elemento X
preciso verificar se ele está na cabeça ou pertence à lista se ele pertencer à sua cauda. Isto pode
ser indicado como:
se ele está na cauda da lista pertence(X,[W|Z]) :-
Se o final da lista for atingido, o nome não pertence(X,Z).
está na lista
45 46
49 50
8
Último Elemento de uma Lista Concatenar Listas
O último elemento de uma lista que tenha Se o primeiro argumento é a lista vazia, então o segundo
e terceiro argumentos devem ser o mesmo
somente um elemento é o próprio elemento concatenar([ ],L,L).
ultimo(Elemento, [Elemento]). Se o primeiro argumento é a lista não-vazia, então ela
O último elemento de uma lista que tenha mais tem uma cabeça e uma cauda da forma [X|L1];
de um elemento é o ultimo elemento da cauda concatenar [X|L1] com uma segunda lista L2 resulta na
lista [X|L3], onde L3 é a concatenação de L1 e L2
ultimo(Elemento, [Cabeca|Cauda]) :- concatenar([X|L1],L2,[X|L3]) :- [X | L1]
ultimo(Elemento,Cauda). concatenar(L1,L2,L3).
% concatenar(?/+L1,?/?L2,+/?L)
% ultimo(?Elemento, +Lista) L3
concatenar([ ],L,L).
ultimo(Elemento, [Elemento]).
concatenar([X|L1],L2,[X|L3]) :- X L3
ultimo(Elemento, [Cabeca|Cauda]) :- concatenar(L1,L2,L3).
ultimo(Elemento,Cauda). [X | L3]
51 52
Operadores Operadores
De forma que Prolog entenda apropriadamente A definição de um operador deve aparecer através de
expressões tais como a+b*c, Prolog deve conhecer que * uma diretiva antes da expressão contendo o operador
tem precedência sobre + No exemplo anterior, o operador tem pode ser definido
Assim, a precedência de operadores decide qual é a através da diretiva
correta interpretação de expressões :- op(600,xfx,tem).
Prolog permite a declaração de novos operadores, por Isso informa Prolog que desejamos usar tem como operador, cuja
exemplo, podemos definir os átomos tem e suporta como precedência é 600 e seu tipo é ‘xfx’, que é um tipo de operador
infixo
operadores e escrever no programa fatos tais como:
A forma ‘xfx’ sugere que o operador, denotado pela letra ‘f’ está
pedro tem informação. entre dois argumentos, denotados por ‘x’
chão suporta mesa.
Novamente, a definição de operadores não especifica
Estes fatos são equivalentes à: nenhuma operação ou ação e são usados apenas para
tem(pedro,informação). combinar objetos em estruturas
suporta(chão,mesa).
55 56
9
Operadores Operadores
Os nomes dos operadores devem ser átomos Os especificadores são escolhidos para refletir a
estrutura da expressão, onde:
A precedência varia em algum intervalo, f representa o operador
dependendo da implementação Prolog (1-1200) x representa um argumento cuja precedência é
Há 3 grupos tipos de operadores, indicados pelos
estritamente menor que a do operador
y representa um argumento cuja precedência é menor
especificadores tal como xfx: ou igual à do operador
(1) Operadores infixos de três tipos: xfx, xfy, yfx A precedência de um argumento colocado entre
(2) Operadores pré-fixos de dois tipos: fx, fy parênteses ou de um objeto não estruturado é
(3) Operadores pós-fixos de dois tipos: xf, yf zero
Se um argumento é uma estrutura, então sua
precedência é igual à precedência de seu functor
principal
57 58
Operadores Operadores
Exemplo de alguns operadores pré-definidos
Por exemplo a-b-c é entendido como (a-b)-c e :-op(1200,xfx,[-->,:-]).
não como a-(b-c) :-op(1200,fx,[:-,?-]).
Assumindo que – tenha precedência 500 :-op(1100,xfy,[’;’,|]).
:-op(1050,xfy,->).
O operador – tem que ser definido como yfx :-op(1000,xfy,’,’).
Interpretação
:-op(954,xfy,\).
– – inválida porque a :-op(900,fy,[’\+’,not]).
precedência de b-c :-op(700,xfx,[is,<,=,=..,=@=,=:=,=<,==,=\=,
não é menor do que >,>=,@<, @=<,@>,@>=,\=,\==]).
– c a – a precedência de -
:-op(600,xfy,:).
prec. 0 prec. 0 :-op(500,yfx,[+,-]).
a b b c :-op(500,fx,[+,-]).
:-op(400,yfx,[*,/,//,mod]).
:-op(200,xfx,**).
precedência 500 precedência 500 :-op(200,xfy,^).
59 60
Exemplo Exemplo
:-op(500,fy,~). ~ ou
61 62
10
Predicados para (De)composição Predicados para (De)composição
Termos Termos
atom_chars(A,L): converte um átomo A em uma lista L
Termo =.. L: é verdadeiro se L é uma lista
composta pelos caracteres (e vice-versa)
?- atom_chars(laranja,X). contendo o functor principal de Termo,
X = [l,a,r,a,n,j,a]
?- atom_chars(Z,[m,a,c,a,c,o]). seguido pelos seus argumentos
Z = macaco
number_chars(A,L): Similar ao predicado atom_chars,
=.. é lido como univ
mas para números functor(Termo,F,N): é verdadeiro se
?- number_chars(123.5,X).
X = ['1', '2', '3', '.', '5'] Termo é uma estrutura com functor F e
?- number_chars(X,['1', '2', '3']). aridade N
Z = 123
Algumas implementações Prolog fornecem o predicado arg(N,Termo,A): é verdadeiro se o N-
name(A,L) que tem a mesma funcionalidade que
atom_chars(A,L) e number_chars(A,L) combinados ésimo argumento do Termo é A
63 64
65 66
11
Predicados para (De)composição
Semântica de Programas Prolog
Termos
Algumas implementações Prolog exigem que Considere a cláusula onde P, Q e R são termos:
P :- Q, R.
todas as metas sejam átomos ou estruturas com
Significado Declarativo:
um átomo como functor principal P é verdadeiro se Q e R são verdadeiros
Assim, uma variável, mesmo que instanciada, P segue (conseqüência) de Q e R
não é sintaticamente aceita como uma meta De (a partir de) Q e R segue P
Significado Procedural:
O problema é solucionado através do predicado Para resolver o problema P, resolva primeiro sub-problema Q e
call/1, assim o fragmento anterior torna-se: então o sub-problema R
obter(Functor), Para satisfazer P, primeiro satisfaça Q e então R
calcular(ListaArgumentos), A diferença entre os significados declarativo e procedural
Meta =.. [Functor | ListaArgumentos], é que o último não apenas define as relações lógicas
entre a cabeça da cláusula e as condições no corpo, mas
call(Meta). também a ordem na qual as condições são executadas
69 70
71 72
73 74
12
Significado Procedural Significado Procedural
grande(urso). % Cláusula 1 grande(urso). % Cláusula 1
grande(elefante). % Cláusula 2 grande(elefante). % Cláusula 2
pequeno(gato). % Cláusula 3 pequeno(gato). % Cláusula 3
marrom(urso). % Cláusula 4 marrom(urso). % Cláusula 4
preto(gato). % Cláusula 5 preto(gato). % Cláusula 5
cinza(elefante). % Cláusula 6 cinza(elefante). % Cláusula 6
escuro(Z) :- % Cláusula 7 escuro(Z) :- % Cláusula 7
preto(Z). preto(Z).
escuro(Z) :- % Cláusula 8 escuro(Z) :- % Cláusula 8 (Passo 2)
marrom(Z). marrom(Z). Procure de cima para baixo por
uma cláusula cuja cabeça
(Passo 1) unifique com a primeira
?- escuro(X), grande(X). Pergunta inicial: ?- escuro(X), grande(X). condição da pergunta
escuro(X), grande(X). escuro(X)
75 76
77 78
79 80
13
Significado Procedural Significado Procedural
grande(urso). % Cláusula 1 grande(urso). % Cláusula 1
grande(elefante). % Cláusula 2 (Passo 5) grande(elefante). % Cláusula 2 (Passo 6)
pequeno(gato). % Cláusula 3 meta: marrom(X), grande(X). pequeno(gato). % Cláusula 3 meta: grande(urso).
marrom(urso). % Cláusula 4 marrom(urso). % Cláusula 4
preto(gato). % Cláusula 5 Procure por uma cláusula que preto(gato). % Cláusula 5 Procure por uma cláusula que
cinza(elefante). % Cláusula 6 unifique com marrom(X) cinza(elefante). % Cláusula 6 unifique com grande(urso)
escuro(Z) :- % Cláusula 7 Cláusula 4 encontrada escuro(Z) :- % Cláusula 7 Cláusula 1 encontrada
marrom(urso) grande(urso)
preto(Z). preto(Z).
Esta cláusula não tem corpo, Esta cláusula não tem corpo,
escuro(Z) :- % Cláusula 8 escuro(Z) :- % Cláusula 8
assim a lista de condições assim a lista de condições
marrom(Z). depois de instanciada torna-se: marrom(Z). torna-se vazia.
grande(urso). Isto indica um término com
?- escuro(X), grande(X). uma vez que já se provou ?- escuro(X), grande(X). sucesso e a instanciação
marrom(urso) correspondente é
X instancia com urso X = urso
81 82
Todavia, o que aconteceria se a ordem fosse diferente? consegue(Estado1) :- % movimentar e tentar conseguir
Por exemplo, vamos assumir que a cláusula sobre move(Estado1,Movimento,Estado2), % a banana
consegue(Estado2).
‘caminhar’ apareça em primeiro lugar
83 84
14
Ordem das Cláusulas Pontos Importantes
Nota-se que a segunda cláusula de consegue/1 e Objetos simples em Prolog são átomos, números
cláusula caminhar de move/1 são usadas repetidamente
e variáveis
O macaco caminha sem nunca tentar usar a caixa
Como não há progresso, isso procede infinitamente: Objetos estruturados, ou estruturas, são
Prolog não percebe que não há sentido em continuar utilizados para representar objetos que possuem
utilizando esta linha de raciocínio vários componentes
Este exemplo mostra Prolog tentando resolver um
Estruturas são construídas através de functores;
problema de modo que a solução nunca é encontrada,
embora exista uma solução cada functor é definido por seu nome e aridade
O programa está declarativamente correto, mas O escopo léxico de uma variável é uma cláusula;
proceduralmente incorreto no sentido que ele não é capaz
de produzir uma resposta à pergunta assim o mesmo nome de variável em duas
cláusulas significam duas variáveis diferentes
87 88
Pontos Importantes
Slides baseados em:
Estruturas podem ser vistas como árvores; Prolog
pode ser vista como uma linguagem para Bratko, I.;
Prolog Programming for Artificial Intelligence,
processamento de árvores 3rd Edition, Pearson Education, 2001.
A operação de unificação toma dois termos e Clocksin, W.F.; Mellish, C.S.;
tenta torná-los idênticos através da instanciação Programming in Prolog,
5th Edition, Springer-Verlag, 2003.
das variáveis em ambos os termos
Programas Prolog para o
A ordem das cláusulas pode afetar a eficiência do Processamento de Listas e Aplicações,
programa; uma ordem indevida pode até mesmo Monard, M.C & Nicoletti, M.C., ICMC-USP, 1993
89 90
15