Introdução a Prolog Aula “teórico-prática”. O que é Prolog? Linguagem mais divulgada do...

Preview:

Citation preview

Introdução a PrologAula “teórico-prática”

O que é Prolog? Linguagem mais divulgada do paradigma de Programação

em Lógica Baseado em cláusulas de Horn

P1 P2 P3 ... Pn Q Operacionalização simples, prática e eficiente da metáfora da

programação em lógica Metáfora da programação em lógica

Programar = Declarar axiomas e regras Teoria Lógica x Prolog

Axiomas: Fatos prolog Regras: Regras prolog Teoremas: Deduzidos a partir dos fatos e regras

Exemplo - Fatosparent(pam, bob).parent(tom, bob).parent(tom, liz).parent(bob, ann).parent(bob, pat).parent(pat, jim).

female(pam).female(ann).female(pat).female(liz).male(bob).male(tom).male(jim).

pam tom

bob

jim

ann pat

liz

Exemplo – Perguntas à base de fatos

Bob é filho de Jim?- parent(jim, bob).falseBob é filho de quem?- parent(X, bob).X = pam ;X = tom ;Encontre X e Y tal que X é

“progenitor” de Y.parent(X, Y).X = pamY = bob ;...

pam tom

bob

jim

ann pat

liz

Exemplo – RegrasQuem é o pai de bob?- parent(X, bob),

male(X).X = tomDefinindo uma regra para paifather(X, Y) :- parent(X,

Y), male(X).Isto é a sintaxe em prolog parax, y parent(x, y) male(x)

father(x, y)Agora podemos perguntar- father(X, bob).X = tom

pam tom

bob

jim

ann pat

liz

Exercício 1 Defina as regras: (arquivo family.P)

mother(X,Y) sister(X, Y) grandparent(X, Y)

Defina a regra: aunt(X, Y)

Dica: você pode usar a regra sister(X, Y) definida anteriormente

Exemplo – Regras recursivas Quais são os ancestrais de jim? Podemos expressar a relação

ancestor(X, Y) por uma regra recursiva

ancestor(X, Y) :- father(X, Y).ancestor(X, Y) :- father(X, Z), ancestor(Z, Y). Faça as perguntas

Quem são os ancestrais de Jim? Bob é ancestral de quem? E Jim?

pam tom

bob

jim

ann pat

liz

Sintaxe de Prolog fato -> fa. (abreviação para Formula Atômica) regra -> fa0 :- fa1, ... , faN. consulta -> fa1, ... , faN. fa -> pred(termo1, ... , termoN) | preop termo1 termo2 | termo1 inop termo2 | termo1 termo2 postop termo -> constante | variável | fa constante -> átomos | números pred -> átomo

Sintaxe de Prolog (2) variável ex: C, Chico, Francisco_carvalho, Chico1, _fatc, _ átomo ex: c, fatc, =>, francisco_carvalho, chico1, ‘chico ia’ número ex: 23 termos, fatos, regras e consultas sem variáveis:

instanciados (ground) ex.: person(bob,40,cs).

termos, fatos e regras com variáveis: universais ex.: father(adao,X). father(X, Y) :- parent(X, Y), male(X).

consultas com variáveis: existenciais ex.: - father(F,P).

Intepretação de um programa Prolog P :- Q, R.

Interpretações declarativas P é verdadeiro se Q e R forem verdadeiros. Q e R implica P.

Interpretações procedurais Para resolver o problema P:

Primeiro resolva o subproblema Q Depois resolva o subproblema R

Para satisfazer P: Primeiro satisfaça Q E então satisfaça R

Interpretador Prolog: Controle e Busca (funcionamento procedural) Aplica regra de resolução:

com estratégia linear (sempre tenta unificar último fato a provar com a conclusão de uma cláusula do programa),

na ordem escrita das cláusulas no programa, com encadeamento de regras regressivo (backward-chaining), busca em profundidade e da esquerda para direita das premissas das cláusulas, e com backtracking sistemático e linear quando a unificação

falha, e sem occur-check na unificação.

Prolog e aritmética Operadores aritméticos

+ adição - subtração * multiplicação / divisão ** potenciação // divisão inteira mod módulo (resto da divisão

inteira) O atribuidor is

Variável is Expr. Aritmética

Exemplos- X = 1 + 2X = 1 + 2- X is 1 + 2X = 3- X is 5/2, Y is 5//2,

Z is 5 mod 2.X = 2.5Y = 2Z = 1

Prolog e aritmética (2) Operadores de comparação

> maior que < menor que >= maior ou igual =< menor ou igual =:= teste de igualdade

aritmética =\= teste de diferença

aritmética

Exemplos- 1 + 2 =:= 2 + 1.yes- 1 + 2 = 2 + 1.no- 1 + A = B + 2.A = 2B = 1

Exemplo Aritmético - Fatorialfactorial(0, 1).factorial(N, Fn) :-

N > 0, M is N - 1,factorial(M, Fm),Fn is N * Fm.

(arquivo fac.P)- factorial(10, X).X = 362880- factorial(10, 362880).yes- factorial(10, 10000).no

Exercício 2 Defina uma regra fib(X, Y) que calcula o número de fibonacci

de X, atribuindo-o a Y. A sequência de Fibonacci é definida matematicamente como

fib(1) = 1 fib(2) = 1 fib(n) = fib(n – 1) + fib(n – 2)

Use seu programa para calcular o fib(5). O que acontece quando você calcula o fib(30)?

Adicionando e removendo cláusulas dinamicamente Um programa prolog pode ser visto como um banco de dados

Relações Explícitas: fatos Implícitas: regras

Predicados built-in permitem a atualização do programa em tempo de execução Adicionar uma nova cláusula

assert, asserta, assertz Remover uma cláusula

retract No XSB módulos com predicados dinâmicos devem ser

carregados com o comando load_dyn/1

Usando assert para tornar o programa fib eficientefib(1, 1).fib(2, 1).fib(N, Fn) :-

N > 2,M is N - 1,fib(M, Fm),O is N - 2,fib(O, Fo),Fn is Fm + Fo,asserta(fib(N, Fn)).

Agora os resultados parciais são armazenados, não precisando serem recalculados.

Teste fib(40, X).

Ferramentas de Debug trace/0 : ativa o modo de rastreamento. O sistema interage com o usuário cada vez que um predicado é:

ativado inicialmente (call) retorna com sucesso (exit) vai fazer backtracking (redo) falhou completamente (fail)

Podem ser observados predicados específicos com o comando spy(predicado/aridade).

Diferentes ações escolhidas na interação com o debugador: Creep (step), Leap (continuar até próximo spy), Skip (desabilita trace até

o final desta execução), Abort (aborta a execução atual). notrace/0, nospy/1.

Mais um Exemplo Vamos definir a função

Se X < 3 então Y = 0 Se 3 X e X < 6 então Y = 2 Se 6 X então Y = 4

(arquivo funct.P)f(X, 0) :- X < 3.f(X, 2) :- 3 =< X, X < 6.f(X, 4) :- 6 =< X.

3 6 X

Y

2

4

Execução do exemplo Como prolog se comporta quando

fazemos uma consulta? Vamos acompanhar a execução

de uma consulta ativando o mecanismo de trace do xsb.- trace.

• Agora façamos a consulta: f(1, Y), 2 < Y.

f(X, 0) :- X < 3.f(X, 2) :- 3 =< X, X < 6.f(X, 4) :- 6 =< X.

(0) Call: f(1,_h454) ? c(1) Call: 1 < 3 ? c(1) Exit: 1 < 3 ? c(0) Exit: f(1,0) ? c(2) Call: 2 < 0 ? c(2) Fail: 2 < 0 ? c(0) Redo: f(1,0) ? c(1) Redo: 1 < 3 ? c(1) Fail: 1 < 3 ? c(3) Call: 3 =< 1 ? c(3) Fail: 3 =< 1 ? c(4) Call: 6 =< 1 ? c(4) Fail: 6 =< 1 ? c(0) Fail: f(1,_h454) ? c

f(X, 0) :- X < 3.f(X, 2) :- 3 =< X, X < 6.f(X, 4) :- 6 =< X.

Diagrama da execução do exemplo

f(1, Y)2 < Y

1 < 32 < 0

3 ≤ 11 < 62 < 2

6 ≤ 12 < 4

2 < 0 no

no noCUT

Regra 1Y = 0

Regra 2Y = 2

Regra 3Y = 4

Regras mutuamenteexclusivas

Evitar backtracking inútil: ! (o cut) op built-in de pruning, logicamente sempre verificado com efeito colateral de impedir backtracking:

na sua esquerda na cláusula que ocorre em outras cláusulas com a mesma conclusão

ex: A :- B, C, D. C :- M, N, !, P, Q. C :- R.

impede backtracking P -> N permite backtracking N -> M, Q -> P, D -> (R xor Q), (P xor R) -> B R tentado:

unicamente se M ou N falha nunca se P ou Q falha

Cut: exemplo Otimizando o exemplo anterior:

f(X, 0) :- X < 3, !.f(X, 2) :- 3 =< X, X < 6, !.f(X, 4) :- 6 =< X.

Nesse caso os cuts alteram apenas o comportamento procedural do programa.

Se removermos os cuts o programa continuará produzindo os mesmos resultados.

Green cuts

Cut: exemplo (2) Podemos otimizar ainda mais

o programa, pensando-o da seguinte forma:if (X < 3) then Y = 0else if (X < 6) then Y = 2else Y = 4

Eliminamos assim 2 comparações desnecessárias.

Versão anterior:f(X, 0) :- X < 3, !.f(X, 2) :- 3 =< X, X < 6, !.f(X, 4) :- 6 =< X.

Reescrevemos para:f(X, 0) :- X < 3, !.f(X, 2) :- X < 6, !.f(X, 4).

Cut: exemplo(3) O que acontece agora se os cuts forem removidos?

f(X, 0) :- X < 3.f(X, 2) :- X < 6.f(X, 4).

f(1, Y).Y = 0;Y = 2;Y = 4;

Neste caso os cuts afetam a semântica do programa Red cuts

Hipótese do mundo fechado Ao contrário da Lógica de 1a ordem, Prolog não permite nem

fatos, nem conclusões de regras negativos: ~animal_lover(geber).~kill(X,Y) :- animal_lover(X), animal(Y).

Princípio de economia: declarar e deduzir apenas o que é verdadeiro, supor que tudo que não é mencionado nem dedutível é falso

(hipótese do mundo fechado) Operador de negação por falha

Podemos usar o ! para implementar um operador de negação por falha, tal que: not p(X) verificado sse p(X) falha

Negação por falha Uma maneira de definir a negação por falha:

not(P) :- P, !, fail ; true.

fail é o objetivo que sempre falha, enquanto que true sempre tem sucesso.

not já é pré-definido (built-in) no interpretador prolog, como um operador pré-fixo.- not true.no- not fail.yes

Voltando ao exemplo da família... Definimos a relação sister(X, Y) como:

sister(X, Y) :- female(X), parent(Z, X), parent(Z, Y). Vimos que isso também deduz que uma mulher é irmã dela

mesma: logicamente correto pela definição acima. Podemos usar a negação por falha para alcançar o resultado

desejado. sister(X, Y) :- female(X), parent(Z, X), parent(Z, Y), not(X = Y).

Exemplo da família- sister(X, pat).X = ann;no Conforme o comportamento

esperado. Experimento:

Modifique a relação sister(X, Y) para sister(X, Y) :- not(X = Y),

female(X), parent(Z, X), parent(Z, Y).

Agora consulte: - sister(X, pat).

pam tom

bob

jim

ann pat

liz

O que aconteceu? Afinal de contas de acordo com a lógica:

a b c d e é equivalente a d a b c e Negação por falha não tem a mesma semântica da negação

da lógica. Vamos acompanhar o trace da consulta:

- trace.- sister(X, pat).(0) Call: sister(_h446,pat) ? c(1) Call: not _h446 = pat ? c(1) Fail: not _h446 = pat ? c(0) Fail: sister(_h446,pat) ? c

O que aconteceu? (2) Problema com objetivos não instanciados

Quantificação de variáveis diferente na negação por falha not(X = pat) não é interpretado como “existe X tal que

not(X = pat)” A quantificação na negação por falha é universal

Para todo X: not(X = pat)? O que é claramente falso, pois X (não instanciado) unifica-se

perfeitamente com pat Conclusão: cuidado ao usar cuts e negação por falha.

Prolog: listas [ e ]: início e fim de lista , separação entre elementos |: separação entre 1° elemento (cabeça) e resto da lista (calda)

açúcar sintático para predicado .(Head,Tail)ex.: [a,[b,c],d] açúcar sintático para .(a,.(.(b,.(c,[])),.(d,[])))

- [a,b,X,p(Y,C)] = [Head|Tail] Head = a, Tail = [b,X,p(Y,C)]- [[p(X),[a]],q([b,c])] = [[H|T1]|T2] H = p(X), T1 = [[a]], T2 = [q([b,c])]- member(X,[X|_]).- member(X,[Y|Z]) :- member(X,Z). - member(b,[a,b,c]) -> yes.- member(X,[a,b,c]) -> X = a ; X = b ; X = c ; no.

Exemplo: Append append(L1, L2, L3): L1 e L2 são duas listas e L3 é a sua

concatenação. Append de uma lista vazia com uma segunda lista é a própria

segunda lista: append([], L, L).

Append de uma lista [X|L1] com a lista L2 é uma lista [X|L3], onde L3 é a concatenação da cauda da primeira (L1) com L2. append([X|L1], L2, [X|L3]) :-

append(L1, L2, L3).

Exemplo: Append (2) Exemplos do uso do append

Qual o resultado da concatenação das listas [a, b] e [c, d]? - append([a,b], [c,d], X). X = [a, b, c, d]

Que listas concatenadas resultam na lista [a, b, c, d]? - append(X, Y, [a, b, c, d]). X = [] Y = [a,b,c,d];

X = [a] Y = [b,c,d]; …

Exercícios 3 Usando o append, escreva uma regra para apagar os três

últimos elementos de uma lista L, produzindo uma lista L1 (arquivo append.P)

Defina a relação last(Item, List) de forma que Item é o último elemento de List de duas formas diferentes: usando append sem usar append

Prolog x prog. imperativa

Interativo: compilação transparente integrada na interpretação rodar programa = consultar um BD

Gerenciamento automático da memória Mecanismo único de manipulação de dados -- unificação de

termos lógicos -- implementando: atribuição de valor passagem de parâmetros alocação de estruturas leitura e escrita em campos de estruturas

Prolog x prog. imperativa (2)

Estrutura de dados única: termo Prolog variáveis lógicas sem tipo estático (tipos dinâmicos)

Controle implícito built-in na estratégia de resolução, ex: Em programação imperativa

procedure c(E) const e0:tipoE0; var E:tipoE, S0:tipoS0, l1:tipo-I1, S1:tipoS1; do if E = e0 then do S0 := call p0(e0); return S0; end; else do I1 := call p1(E); S1 := call p2(E,l1); return S1; end; end;

Em Prolog c(e0,S0) :- p0(e0,S0). c(E,S1) :- p1(E,I1), p2(E,I1,S1).

Prolog x prog. funcional

Matematicamente, predicado = relação: não-determinismo:

respostas múltiplas (disponíveis por backtracking), unificação e busca built-in, livra o programador da implementação do controle;

bi-direcionalidade: cada argumento pode ser entrada ou saída, dependendo do

contexto de chamada, única definição para usos diferentes: verificador, instanciador,

resolvedor de restrições, enumerador. integração imediata com BD relacional

Prolog x prog. funcional (2)

Append em Haskell:append [] L = L append H:T L = H : append T L?- append([a,b],[c,d])[a,b,c,d]

Append em Prolog:append([],L,L).append([H|T1],L,[H|T2]) :- append(T1,L,T2).?- append([a,b],[c,d],R).R = [a,b,c,d].

Append relacional codifica várias funções

Vários usos do mesmo predicado

verificador: ?- append([a,b],[c],[a,b,c]). -> yes.?- append([a,b],[c],[a]). -> no.

instanciador:?- append([a,b],[c],R). -> R = [a,b,c].?- append(H,[c],[a,b,c]). -> H = [a,b].

resolvedor de restrições:?- append(X,Y,[a,b,c]). -> X = [], Y = [a,b,c] ; -> X = [a], Y = [b,c] ...

enumerador: ?- append(X,Y,Z). -> X = [], Y =[], Z = [] ; -> X = [_], Y = [], Z = [_] ...

Prolog x programação OO

Funcionalidades built-in: + unificação e busca - tipos, herança e encapsulamento

Ontologicamente: Entidade Atômica (EA): em OO, valor de tipo built-in

em Prolog, átomo (argumento ou predicado) Entidade Composta (EC): em OO, objeto

em Prolog, fato Relação simples entre EC e EA: em OO, atributo de tipo built-in

em Prolog, posição em um predicado Relação simples entre ECs: em OO, atributo de tipo objeto

em Prolog, predicado Relação complexa entre entidades: em OO, método

em Prolog, conjunto de regras

Prolog x programação OO: exemplo Em OO:

pt[subclass_of planobj; attrs[X inst_of int, Y inst_of int]; mets[right(Pt inst_of pt) {return self.X >= Pt.X}]]pt1[inst_of pt; attrs[X = 0, Y = 0]]pt2[inst_of pt; attrs[X = 1, Y =1]]?- pt1.right(pt2) -> no.

Em Prolog:pt(0,0).pt(1,1).planobj(pt(_,_)).right(pt(X1,_),pt(X2,_)) :- X1 >= X2.?- right(pt(0,0),pt(1,1)). -> no.

Programação em Lógica: Disciplina Eletiva de Graduação e Pós Prolog aprofundado Programação por resolução de restrições a base lógica

(Constraint Logic Programming) extensão de Prolog com resoluções de inequações e equações restrições quantitativas (N, Z, R, C)

ou qualitativas (tipos, ontologias) Escalonamento, raciocínio espacial, otimização,

automação industrial, CAD/CAM, música computacional Programação em lógica funcional Programação em lógica orientada a objetos Programação multiparadigma a base lógica:

lógica + restrições + funcional + OO todo a IA e mais !

Programação em Lógica: Disciplina Eletiva de Graduação e Pós Programação em lógica para engenharia de software

especificação formal prototipagem rápida aceleração do modelo de desenvolvimento em espiral

Programação em lógica probabilista e bayesiana raciocínio com incerteza

Programação em lógica indutiva aprendizagem de máquina, agentes adaptativos,

mineração de dados, descoberta de conhecimento em BD,programação automática, bio-informática

Programação em lógica multiagentes sistemas inteligentes distribuídos comercio eletrônico jogos, competição de futebol de robôs

Programação em Lógica: Disciplina Eletiva de Graduação e Pós Bancos de dados dedutivos:

descoberta de conhecimento em BD, sistemas especialistas de grande porte, servidores de conhecimento ontológico

Bancos de dados dedutivos orientada a objetos Bancos de dados dedutivos temporais Bancos de dados de restrições:

GIS, BD espaciais, BD espaço-temporais, integração de dados e interoperabilidade

Bancos de dados de restrições orientada a objetos toda a IA de grande escala e mais !

Bancos de dados probabilistas: BD de sensores, data warehousing, integração de dados com fontes

não confiáveis ou mutuamente inconsistentes,

Programação em Lógica: Disciplina Eletiva de Graduação e Pós Gramáticas lógicas:

Parser e gerador de linguagem built-in em Prolog Basta desenvolver gramática (i.e., como com lex e yacc) Mineração da web, extração de informação na Internet, compilação tradução automática, geração automática de resumos, chatterbots

APIs Prolog/Java e Prolog/XML sistemas de informação inteligentes distribuídos e heterogêneos a infra-

estrutura web integração de dados, interoperabilidade entre sistemas, mediadores, data

warehousing comercio eletrônico agentes inteligentes de recuperação, classificação, extração e notificação de

informação na web, na Internet, em Intranet inteligência na computação pervasiva toda a IA embutida e mais !

Programação em Lógica: Disciplina Eletiva de Graduação e Pós-Graduação Aplicação fio condutor para ilustração dos conceitos

“By the year 2050, develop a team of fully autonomous humanoid robots that can win against the human world soccer champion team.” http://www.robocup.org

Programação em Lógica: Disciplina Eletiva de Graduação e Pós

Introdução a PrologFIM

Exercício 1 - Respostasmother(X, Y) :- parent(X, Y), female(X).sister(X, Y) :- female(X), parent(Z, X), parent(Z, Y).grandparent(X, Y) :- parent(X, Z), parent(Z, Y).aunt(X, Y) :- sister(X, Z), parent(Z, Y).

Quais são as respostas devolvidas para sister(X, pat). ? Por que isso ocorre? Como isso pode ser evitado?

Cenas dos próximos slides...

Exercício 2 - Respostafib(1, 1).fib(2, 1).fib(N, Fn) :-

N > 2,M is N - 1,fib(M, Fm),O is N - 2,fib(O, Fo),Fn is Fm + Fo.

O programa tem comportamento exponencial, para cada passo calculamos toda a seqüência de fibonacci.

Os mesmos valores são calculados várias vezes...

Exercícios 3 - Respostadel3(L, L1) :- append(L1, [_, _, _], L).

last(Item, List) :- append(_, [Item], List).

last2(Item, [Item]).last2(Item, [_|XL]) :- last2(Item, XL).