SlideShare uma empresa Scribd logo
Linguagem de Programação 
Lógica ‐ Prolog
Prof. Iális Cavalcante

Engenharia da Computação – UFC/Sobral
0. Sumário
 Ambiente
 Iniciando um programa
 Fatos e Regras
 Operadores e Aritmética
 Estruturas
 Recursividade
 Listas
Ambiente
 Recursos requeridos:
 ◦ Editor de texto (escrita de programas);
 ◦ Ambiente de desenvolvimento (SWI-Prolog - http://www.swi-
   prolog.org/);
 ◦ Controle dos diretórios e arquivos;
 Interpretador vs Compilador
 ◦ Um compilador transforma seu programa em um arquivo
   executável, cujo arquivo pode ser executado fora do
   ambiente de desenvolvimento.
 ◦ Um interpretador executa seu programa linha por linha
   dentro dos recursos do ambiente de desenvolvimento.
 ◦ Interpretador Prolog
Iniciando um programa
 Escreva um programa com o código abaixo:
 gosta(maria,comida).
 gosta(maria,vinho).
 gosta(joao, vinho).
 gosta(joao, maria).
 ◦ Não coloque espaço após o ponto;
 ◦ Não escreva qualquer termo com letra maiúscula;
 ◦ Adicione uma linha em branco ao final de tudo;
 Salve como “intro.pl”
 Abra o arquivo no SWI-Prolog
 Verifique a compilação (há erros?)
 Entre com: [intro].
Iniciando um programa
 Teste o comando listing.
 Execute algumas consultas:
 ◦ gosta(maria,comida).
 ◦ gosta(joao, vinho).
 ◦ gosta(joao, comida).
 Quando terminado pode sair de intro
 com o comando halt
Fatos e Regras
 O programa criado anteriormente pode ser adicionado
 por mais fatos.
 Realize novos testes a cada modificação:
 ◦ gosta(joao,X).
 ◦ gosta(maria,X).
 ◦ gosta(Y, comida).
 ◦ gosta(Y, vinho).
 Para a formação de uma regra é necessário a estrutura
 condicional a partir de um operador:
                Operador    Significado
                       :-       if
                       ,       and
                       ;        or
Fatos e Regras
 Exemplo de fatos:
 amiga(joana,maria).
 amiga(maria,joana).
 amiga(maria,clara).
 amiga(clara,maria).
 ama(joana,maria).
 ama(maria,joana).
 Exemplo de regra (amiga_intima):
 amiga_intima(Ela1,Ela2) :-
 amiga(Ela1,Ela2), amiga(Ela2,Ela1), ama(Ela1,Ela2), ama(Ela2,Ela1).
 ?- amiga_intima(maria,joana).
 yes
 ?- amiga_intima(maria,clara).
 no
Fatos e Regras
 Exercícios: crie regras para expressar as
 seguintes frases...
 ◦ João gosta de qualquer coisa que Maria gosta.
    João gosta de alguma coisa se Maria gosta de alguma
    coisa.
 ◦ João gosta de qualquer um que gosta de
   vinho.
    João gosta de alguém se alguém gosta de vinho.
 ◦ João gosta de qualquer um que goste deles
   mesmos.
Fatos e Regras
                         James I




            Charles I                   Elizabeth




Catherine   Charles II       James II

                                         Sophia




                                        George I
Fatos e Regras
 Defina os fatos presentes nessa árvore da família...
 % macho(P) é verdadeiro quando P é macho
 macho(james1).
 macho(charles1).
 macho(charles2).
 macho(james2).
 macho(george1).
 % femea(P) é verdadeiro quando P é fêmea
 femea(catherine).
 femea(elizabeth).
 femea(sophia).
Fatos e Regras
 Continuando...
 % pai(C,P) é verdadeiro quando C tem um pai chamado P
 pai(charles1, james1).
 pai(elizabeth, james1).
 pai(charles2, charles1).
 pai(catherine, charles1).
 pai(james2, charles1).
 pai(sophia, elizabeth).
 pai(george1, sophia).


 Salve o programa como familia.pl e faça
 algumas buscas.
Fatos e Regras
 ◦ George I é o pai de Charles I?
 ◦ Quem é o pai de Charles I?
 ◦ Quem são os filhos de Charles I?
 Tente adicionar as seguintes regras e verifique o
 resultado:
 ◦ M é a mãe de P se ela é um pai de P e é fêmea.
 ◦ F é o pai de P se ele é pai de P e é macho.
 ◦ X é irmã(o) de Y se ambos têm os mesmos pais.
Operadores e Aritmética
 Aridade
 ◦ A aridade de um predicado é simplesmente o
   número de argumentos que ele possui.
 ◦ Prolog se referencia à aridade porque permite
   diferentes predicados com o mesmo
   nome mas com aridade diferente.
    O uso desse recurso não é recomendável:
    legibilidade...
 Uso de espaços
 ◦ Evitar ao máximo, principalmente na definição
   dos fatos.
Operadores e Aritmética
 Comentários
 % - para uma linha simples
 /*
    Para mais de uma linha a ser comentada
 */
 Entrada/Saída simples
 ◦ nl – move o cursor para uma nova linha na
   tela
 ◦ write(X) – escreve X na tela
Operadores e Aritmética
 Operadores relacionais: <, >, >=, =<, =, etc.
 ◦ positive(N) :- N>0.
 ◦ non_zero(N) :- N<0 ; N>0.
 Operadores aritméticos: +, -, *, /
 ◦ Funções como sqrt, exp, cos,... Mas com comportamento
   diferente.
 ◦ “1+4”, “3+2” e “5*1” são trabalhados de formas diferentes.
 primo(2).
 primo(3).
 primo(5).
 ...
 ◦ As consultas “primo(1+1)” or “primo(5*1)” falharão!
 ◦ “X is 1+1, primo(X).” terá sucesso!
Operadores e Aritmética
 Teste a expressão:
 ◦ X is sqrt(9),Y is 2 ** 4, Z is floor(3.14).
 Teste as expressões a seguir e entenda o
 funcionamento das relações em Prolog:
 ◦ N is 1+1.
 ◦ N is 1+1, P is N*2, Q is P+Q.
 ◦ N is X+1.
 ◦ I is I+1.
 ◦ I is 6, I is I+1.
 ◦ I is 6, J is I+1.
 Apenas duas consultas são válidas!
Operadores e Aritmética
 Todas as operações em Prolog são tratadas como
 relações.
 Sendo uma função definida em C/C++ para calcular o
 valor mínimo entre dois números:

 int minimum(int x, int y) {
       if (x < y) return x;
       else return y;
 }


 Em Prolog, essa função será representada por uma
 relação.
Operadores e Aritmética
 Em geral, uma função que tem k argumentos
 será representada em Prolog como uma relação
 com:
 ◦ k+1 argumentos;
 ◦ Sendo que o último é usado para carregar o
   resultado;
 Então em Prolog, escreve-se:
 % minimum(X,Y,Z) é verdadeiro se Z é o mínimo de X e Y
 minimum(X,Y,X) :- X<Y.
 minimum(X,Y,Y) :- X>=Y.
Estruturas (Structure)
 Forma geral:
 estrutura-nome (atributo, ..., atributo )
 Parece um predicado, mas aqui
 representam objeto. Não representam
 relações.
 Se diferenciam, porque estruturas
 sempre surgem como argumentos.
Estruturas
  Supondo que queremos representar carros como os atributos:
  marca, anos de uso (idade), preço. Chamaremos uma estrutura
  carro de três lugares, por exemplo: carro(ford,3,5000)
  representando um carro Ford de 3 anos de uso com valor de
  venda R$ 5.000,00.
% possui(P,C) é verdadeiro se P tem um carro que combina com C
possui(joao, carro(ford,3,5000)).
possui(joao, carro(opel,2,6000)).
possui(gil, carro(toyota,5,1000)).
possui(gil, carro(ford,2,2000)).


  E fazemos a pergunta: “Que tipo de Ford o Gil possui?"
  Consulta: possui(gil, carro(ford, Idade, Preco))
  Resposta: Idade=2, Preco=2000
Estruturas
Se quiser somente recuperar a informação sobre alguns campos pode-se
utilizar o marcador _ (underline) que retorna qualquer valor existente
| ?- possui(Pessoa, carro(ford,_,_)).
Pessoa = joao ? ;
Pessoa = gil
yes
◦ O underscore "_" indica que não se quer saber qual fato se casa com os
  campos apresentados.
◦ Se quiser saber qual marca de carro foi vendida abaixo de 5000, deve-se
  verificar:
| ?- possui(_, carro(Marca,_,Preco)), Preco < 5000.
Marca = toyota
Preco = 1000 ? ;


Marca = ford
Preco = 2000
yes
Recursividade
 Quando se usa a recursão deve-se conhecer três coisas:
 ◦ Algum conjunto (ou “estrutura de dados”) sobre a qual está sendo feita
   a recursão: exemplos comuns incluem números, arrays, árvores, etc.
 ◦ Uma definição de caso base, normalmente lida com uma estrutura
   vazia.
 ◦ Uma definição de caso recursivo, explicando como trabalhar um caso
   não-trivial em termos de algumas versões de valores menores que ele
   mesmo.
 Fatorial: por definição, o fatorial de algum número n, escrito n! é
 n*n-1*n-2*…*1. Nós podemos expressar em termos de recursão
 como segue:
 ◦ Estrutura de Dados: números naturais
 ◦ Caso Base: 0! = 1
 ◦ Caso Recursivo: Para qualquer n>0, nós temos n! = n * (n-1)!
 ◦ Perceba que foi definido n! em termos de (n-1)!. Pode-se fazer isso a
   partir do momento que se conhece que (n-1) < n
Listas
 O formato de uma lista segue uma seqüência de
 valores, correspondente a um vetor em C.
 Exemplo: [joao, maria, patricia]
 [‘string’, 6, maria, X] também é válida;
 Lista vazia: [ ]
 Lista não-vazia: contém cabeça (head) com o
 primeiro elemento e cauda (tail) contendo os
 outros elementos.
 Exemplo: [joao, maria, patricia]
 ◦ Cabeça: joao
 ◦ Cauda: [maria, patricia]
Listas
 Notação específica para listas:
 [Hd | Tl] denota que a lista possui cabeça Hd e
 com cauda uma lista Tl.
 [joao, maria, patricia] -> [ joao | [maria, patricia] ] ->
 -> [joao | [maria | [patricia] ] ] -> [joao | [maria | [patricia | [ ] ] ] ]
 Processamento de listas utiliza regras de
 unificação:
 ◦ O único termo que unifica com [ ] é [ ];
 ◦ [H1 | T1] unifica com [H2 | T2] se H1 unifica com H2
   e T1 unifica com T2
Listas
 Quase todos os predicados que utilizam listas são
 recursivos:
 ◦ Caso base: a lista vazia [ ];
 ◦ Caso recursivo: para uma lista da forma [H | T], execute alguma
   ação na cabeça H e chame o predicado recursivamente usando a
   cauda T.
 Tamanho de uma lista: size(Lista,Tam).
 % size(List,N) is true if List has N elements
 size([],0).
 size([H|T],N) :- size(T,N1), N is N1+1.
 Definindo:
 ◦ O tamanho da lista vazia é 0;
 ◦ O tamanho da lista [H | T] é: 1+(tamanho de T).
Listas
Somando uma lista: supondo que seja formada apenas por números.
% somaLista(List, N) é verdadeiro se os elementos de Lista somam
  para N
somaLista([],0).
somaLista([H|T],N) :- somaLista (T,N1), N is N1+H.
Verificação de elemento na lista:
% contem(Elem, Lista) é verdadeiro se Lista contém Elem
contem(X,[X|_]).
contem(X,[_|T]) :- contem(X,T).


contem(2, [1,2,3])
contem(E, [1,2,3])
contem(E, [2,1,2])
contem(E, [])
Listas como Acumuladores
% print_to(N) - prints out all the numbers down from N to 0
print_to(0) :- write(0).
print_to(N) :- N>0, write(N), nl, N1 is N-1, print_to(N1).
  print_to(5).
  Imprime todos os números entre N e 0, N ≥ 0.
  Como armazenar este resultado em um vetor? [H| T]



       collect_to(0,[]).
       collect_to(N,[N|T]) :- N>0, N1 is N-1, collect_to(N1,T).
Listas como Acumuladores
  Unindo duas listas:
   ◦ O predicado join_list(L1,L2,L3) define “se quisermos juntar L1 e
     L2 conseguimos L3".
  Considerando as possibilidades para L1
   ◦ L1 é uma lista vazia, neste caso L3 é L2
   ◦ L1 está na forma[H1 | T1].
     Se fixar L2 ao seu final, consegue-se uma lista em que a cabeça
     ainda é H1, mas cuja cauda é a junção de T1 e L2


join_list(L1,L2,L3) :- L1=[], L3=L2.
join_list(L1,L2,L3) :- L1=[H1|T1], join_list(T1,L2,T3), L3=[H1|T3].


  Outras possibilidades?
Listas como Acumuladores
join_list([], L2, L2).
join_list([H1|T1], L2, [H1|L3]) :- join_list(T1,L2,L3).

join_list([],L2,L3) :- L3=L2.
join_list([H1|T1],L2,L3) :- join_list(T1,L2,T3), L3=[H1|T3].

join_list([1,2],[6,7],X).
join_list(X, [5,6], [3,5,6]).
join_list([3,4],Y, [3,4,5,6]).
join_list(X,Y,[1,2]).
Listas como Acumuladores
  Invertendo uma lista (duas maneiras):
% bad_reverse(L1,L2) - uma implementação ruim de inversão de lista
bad_reverse([],[]).
bad_reverse([H|T], L2) :-
bad_reverse(T,NT), append(NT,[H],L2).

% myreverse(?List, ?Reversed)
% é verdadeiro quando Reversed possui os mesmos elementos que List
  mas em ordem inversa
good_reverse(List, Reversed) :- good_reverse(List, [], Reversed).

good_reverse([], Reversed, Reversed).
good_reverse([Head|Tail], SoFar, Reversed) :- good_reverse(Tail,
  [Head|SoFar], Reversed).
Listas como Acumuladores
 Exercícios:
 ◦ Escreva predicados para os seguintes
   problemas:
    cutlast(L1,L2) que é verdadeiro se L2 é L1 com o
    último elemento removido.
    trim(L1,N,L2) que é verdadeiro se L2 contém
    somente os N primeiros elementos de L1
    evens(L1,L2) que é verdadeiro se L2 contém
    somente aqueles elementos de L1 que são pares, e
    na mesma ordem.
Backtracking e Cut
  Suponha um programa que avalie a necessidade
  de atendimento de um paciente de acordo com
  sua idade:
grau(N, primeiro) :- N>=70.
grau(N, segundo) :- N<70, N>=63.
grau(N, terceiro) :- N<63, N>=55.
grau(N, quarto) :- N<55, N>=50.
grau(N, espera) :- N<50, N>=40.
grau(N, falha) :- N<40.
  grau(75, G) -> G = primeiro
  Mas avalia ainda todas as outras condições!
Backtracking e Cut
int pri(int n) { return n>=70; }
int seg(int n) { return n<70 && n>=63; }       Avalia todos!
// ... preenchendo o resto ...
int fal(int n) { return n<40; }


switch(n) {
    case(pri(n)): cout << “Primeiro"; break;
    case(seg(n)): cout << “Segundo"; break;
    case(ter(n)): cout << “Terceiro"; break;
                                               Avalia apenas o válido!
    case(qua(n)): cout << “Quarto"; break;
    case(esp(n)): cout << “Espera"; break;
    case(fal(n)): cout << “Falha";
}
Backtracking e Cut
  Para melhorar o desempenho pode-se usar o recurso:
  ! (cut).
  Funciona como o break em C;

grau(N, primeiro) :- N>=70, !.
grau(N, segundo) :- N>=63, !.
grau(N, terceiro) :- N>=55, !.
grau(N, quarto) :- N>=50, !.
grau(N, espera) :- N>=40, !.
grau(N, falha) :- N<40.

Mais conteúdo relacionado

PDF
Seminário Prolog
PDF
Minicurso Prolog
PDF
Linguagem Prolog - Antonio Rufino
PPT
IA Prolog
PDF
Listas em Prolog
PPTX
Introdução ao Prolog
PPT
Aula Prolog 01
PPT
Introdução a Programação em Lógica e Prolog
Seminário Prolog
Minicurso Prolog
Linguagem Prolog - Antonio Rufino
IA Prolog
Listas em Prolog
Introdução ao Prolog
Aula Prolog 01
Introdução a Programação em Lógica e Prolog

Mais procurados (20)

PPTX
Aula prolog 02 ia
PPT
Aula Prolog 02
PPT
Aula Prolog 03
PDF
Aula3 sintaxe semantica
PDF
Introdução ao Prolog - Prof. Sérgio S. Costa
PDF
Introducao ao python - Luciana Mota
PDF
Heap - Python
PDF
Pged 04
PDF
Introdução Programação Funcional
PDF
PDF
Pged 05
PDF
Algebra Boole
PDF
Paradigma Funcional - Caso de Estudo Haskell
PPT
08.type systems
PDF
ICC-05 Álgebra Booleana
PPTX
Python: Funcionalidades Básicas
PDF
PDF
TDC 2014 POA: Programacao funcional Por que Importa?
PPTX
Aula prolog 02 ia
Aula Prolog 02
Aula Prolog 03
Aula3 sintaxe semantica
Introdução ao Prolog - Prof. Sérgio S. Costa
Introducao ao python - Luciana Mota
Heap - Python
Pged 04
Introdução Programação Funcional
Pged 05
Algebra Boole
Paradigma Funcional - Caso de Estudo Haskell
08.type systems
ICC-05 Álgebra Booleana
Python: Funcionalidades Básicas
TDC 2014 POA: Programacao funcional Por que Importa?
Anúncio

Semelhante a Programacao logica (20)

ODP
Pymordida0 Semana de computação da SOCIESC - 2008/10
PDF
Aula01
KEY
Python 02
PDF
Conhecendo ou relembrando C
PPT
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
PPT
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
PPT
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
PPT
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
PPT
Introdução a Algoritmos e Programas.ppt
PPT
Aula3PythonBasico.ppt
PPT
Aula3PythonBasico (1).ppt
PPT
1 ANO - A linguagem dos números - 2008.ppt
PPT
Java Básico :: Introdução
PPT
Módulo 2 - Conceitos básicos sobre algoritmos.ppt
PDF
Programação funcional
PPT
Aula de Prolog 07 - Estruturas de Dados
PPTX
Tipos de Dados em Python: Como Manipulamos Dados em Python?
PDF
aula algoritmos e programação LinguagemC.pdf
Pymordida0 Semana de computação da SOCIESC - 2008/10
Aula01
Python 02
Conhecendo ou relembrando C
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
Unidade-I-Introdução-a-Algoritmos-e-Programas.ppt
Introdução a Algoritmos e Programas.ppt
Aula3PythonBasico.ppt
Aula3PythonBasico (1).ppt
1 ANO - A linguagem dos números - 2008.ppt
Java Básico :: Introdução
Módulo 2 - Conceitos básicos sobre algoritmos.ppt
Programação funcional
Aula de Prolog 07 - Estruturas de Dados
Tipos de Dados em Python: Como Manipulamos Dados em Python?
aula algoritmos e programação LinguagemC.pdf
Anúncio

Mais de Ialis Cavalcante (15)

PPTX
Assembleia com os Discentes - SACEC
PPT
Minicurso Ercemapi 2011
PDF
Unidade7 1
PDF
05 poo-ii
PDF
Unidade06
PDF
Introducao ao greenfoot
PDF
Dinamicas
PDF
Interface grafica
PDF
Unidade05
PDF
Unidade04
PDF
Unidade03
PDF
Unidade02
PDF
Técnicas de PDI com Java - Ercemapi 2009
PPT
CCT 23Maio2009 Sobral
PDF
Introducao ao LaTeX
Assembleia com os Discentes - SACEC
Minicurso Ercemapi 2011
Unidade7 1
05 poo-ii
Unidade06
Introducao ao greenfoot
Dinamicas
Interface grafica
Unidade05
Unidade04
Unidade03
Unidade02
Técnicas de PDI com Java - Ercemapi 2009
CCT 23Maio2009 Sobral
Introducao ao LaTeX

Último (20)

PDF
Ementa 2 semestre PEI Orientação de estudo
PDF
Fiqh da adoração (islamismo)
PPTX
ELEMENTOS E FUNÇÕES DE LINGUAGEM (EMOTIVA, REFERENCIAL, CONATIVA, POÉTICA, FÁ...
PPTX
Ocupação e transformação dos territórios.pptx
PPTX
norma regulamentadora numero vinte nr 20
PDF
A Revolução Francesa de 1789 slides história
PPTX
TREINAMENTO DE INSPETOR DE ANDAIMES.pptx
PDF
manual-orientacao-asb_5a8d6d8d87160aa636f63a5d0.pdf
PDF
Organizador Curricular da Educação em Tempo Integral.pdf
PDF
Combate a Incêndio - Estratégias e Táticas de Combate a Incêndio por Francis...
PDF
Metabolismo_energético_3ano_pre_vest_2026.pdf
PDF
Uma Introdução às Ciências do Alcorão (Islam)
PPTX
QuestõesENEMVESTIBULARPARAESTUDOSEAPRENDIZADO.pptx
PPTX
ACIDOS NUCLEICOS - REPLICAÇÃO DO DNA - E.M.
PPTX
disciplulado curso preparatorio para novos
DOC
PPP 2024 (2) (2) feito EM REELABORAÇÃO MORENA ( ABRIL 2024).doc
PPTX
16. MODERNISMO - PRIMEIRA GERAÇÃO - EDIÇÃO 2021 (1).pptx
PDF
[Slides] A Literatura no ENEM 2017 (1).pdf
PDF
metabolismo energtico das clulas-131017092002-phpapp02.pdf
PDF
A relação entre funções executivas e desempenho acadêmico em crianças com Tra...
Ementa 2 semestre PEI Orientação de estudo
Fiqh da adoração (islamismo)
ELEMENTOS E FUNÇÕES DE LINGUAGEM (EMOTIVA, REFERENCIAL, CONATIVA, POÉTICA, FÁ...
Ocupação e transformação dos territórios.pptx
norma regulamentadora numero vinte nr 20
A Revolução Francesa de 1789 slides história
TREINAMENTO DE INSPETOR DE ANDAIMES.pptx
manual-orientacao-asb_5a8d6d8d87160aa636f63a5d0.pdf
Organizador Curricular da Educação em Tempo Integral.pdf
Combate a Incêndio - Estratégias e Táticas de Combate a Incêndio por Francis...
Metabolismo_energético_3ano_pre_vest_2026.pdf
Uma Introdução às Ciências do Alcorão (Islam)
QuestõesENEMVESTIBULARPARAESTUDOSEAPRENDIZADO.pptx
ACIDOS NUCLEICOS - REPLICAÇÃO DO DNA - E.M.
disciplulado curso preparatorio para novos
PPP 2024 (2) (2) feito EM REELABORAÇÃO MORENA ( ABRIL 2024).doc
16. MODERNISMO - PRIMEIRA GERAÇÃO - EDIÇÃO 2021 (1).pptx
[Slides] A Literatura no ENEM 2017 (1).pdf
metabolismo energtico das clulas-131017092002-phpapp02.pdf
A relação entre funções executivas e desempenho acadêmico em crianças com Tra...

Programacao logica

  • 1. Linguagem de Programação  Lógica ‐ Prolog Prof. Iális Cavalcante Engenharia da Computação – UFC/Sobral
  • 2. 0. Sumário Ambiente Iniciando um programa Fatos e Regras Operadores e Aritmética Estruturas Recursividade Listas
  • 3. Ambiente Recursos requeridos: ◦ Editor de texto (escrita de programas); ◦ Ambiente de desenvolvimento (SWI-Prolog - http://www.swi- prolog.org/); ◦ Controle dos diretórios e arquivos; Interpretador vs Compilador ◦ Um compilador transforma seu programa em um arquivo executável, cujo arquivo pode ser executado fora do ambiente de desenvolvimento. ◦ Um interpretador executa seu programa linha por linha dentro dos recursos do ambiente de desenvolvimento. ◦ Interpretador Prolog
  • 4. Iniciando um programa Escreva um programa com o código abaixo: gosta(maria,comida). gosta(maria,vinho). gosta(joao, vinho). gosta(joao, maria). ◦ Não coloque espaço após o ponto; ◦ Não escreva qualquer termo com letra maiúscula; ◦ Adicione uma linha em branco ao final de tudo; Salve como “intro.pl” Abra o arquivo no SWI-Prolog Verifique a compilação (há erros?) Entre com: [intro].
  • 5. Iniciando um programa Teste o comando listing. Execute algumas consultas: ◦ gosta(maria,comida). ◦ gosta(joao, vinho). ◦ gosta(joao, comida). Quando terminado pode sair de intro com o comando halt
  • 6. Fatos e Regras O programa criado anteriormente pode ser adicionado por mais fatos. Realize novos testes a cada modificação: ◦ gosta(joao,X). ◦ gosta(maria,X). ◦ gosta(Y, comida). ◦ gosta(Y, vinho). Para a formação de uma regra é necessário a estrutura condicional a partir de um operador: Operador Significado :- if , and ; or
  • 7. Fatos e Regras Exemplo de fatos: amiga(joana,maria). amiga(maria,joana). amiga(maria,clara). amiga(clara,maria). ama(joana,maria). ama(maria,joana). Exemplo de regra (amiga_intima): amiga_intima(Ela1,Ela2) :- amiga(Ela1,Ela2), amiga(Ela2,Ela1), ama(Ela1,Ela2), ama(Ela2,Ela1). ?- amiga_intima(maria,joana). yes ?- amiga_intima(maria,clara). no
  • 8. Fatos e Regras Exercícios: crie regras para expressar as seguintes frases... ◦ João gosta de qualquer coisa que Maria gosta. João gosta de alguma coisa se Maria gosta de alguma coisa. ◦ João gosta de qualquer um que gosta de vinho. João gosta de alguém se alguém gosta de vinho. ◦ João gosta de qualquer um que goste deles mesmos.
  • 9. Fatos e Regras James I Charles I Elizabeth Catherine Charles II James II Sophia George I
  • 10. Fatos e Regras Defina os fatos presentes nessa árvore da família... % macho(P) é verdadeiro quando P é macho macho(james1). macho(charles1). macho(charles2). macho(james2). macho(george1). % femea(P) é verdadeiro quando P é fêmea femea(catherine). femea(elizabeth). femea(sophia).
  • 11. Fatos e Regras Continuando... % pai(C,P) é verdadeiro quando C tem um pai chamado P pai(charles1, james1). pai(elizabeth, james1). pai(charles2, charles1). pai(catherine, charles1). pai(james2, charles1). pai(sophia, elizabeth). pai(george1, sophia). Salve o programa como familia.pl e faça algumas buscas.
  • 12. Fatos e Regras ◦ George I é o pai de Charles I? ◦ Quem é o pai de Charles I? ◦ Quem são os filhos de Charles I? Tente adicionar as seguintes regras e verifique o resultado: ◦ M é a mãe de P se ela é um pai de P e é fêmea. ◦ F é o pai de P se ele é pai de P e é macho. ◦ X é irmã(o) de Y se ambos têm os mesmos pais.
  • 13. Operadores e Aritmética Aridade ◦ A aridade de um predicado é simplesmente o número de argumentos que ele possui. ◦ Prolog se referencia à aridade porque permite diferentes predicados com o mesmo nome mas com aridade diferente. O uso desse recurso não é recomendável: legibilidade... Uso de espaços ◦ Evitar ao máximo, principalmente na definição dos fatos.
  • 14. Operadores e Aritmética Comentários % - para uma linha simples /* Para mais de uma linha a ser comentada */ Entrada/Saída simples ◦ nl – move o cursor para uma nova linha na tela ◦ write(X) – escreve X na tela
  • 15. Operadores e Aritmética Operadores relacionais: <, >, >=, =<, =, etc. ◦ positive(N) :- N>0. ◦ non_zero(N) :- N<0 ; N>0. Operadores aritméticos: +, -, *, / ◦ Funções como sqrt, exp, cos,... Mas com comportamento diferente. ◦ “1+4”, “3+2” e “5*1” são trabalhados de formas diferentes. primo(2). primo(3). primo(5). ... ◦ As consultas “primo(1+1)” or “primo(5*1)” falharão! ◦ “X is 1+1, primo(X).” terá sucesso!
  • 16. Operadores e Aritmética Teste a expressão: ◦ X is sqrt(9),Y is 2 ** 4, Z is floor(3.14). Teste as expressões a seguir e entenda o funcionamento das relações em Prolog: ◦ N is 1+1. ◦ N is 1+1, P is N*2, Q is P+Q. ◦ N is X+1. ◦ I is I+1. ◦ I is 6, I is I+1. ◦ I is 6, J is I+1. Apenas duas consultas são válidas!
  • 17. Operadores e Aritmética Todas as operações em Prolog são tratadas como relações. Sendo uma função definida em C/C++ para calcular o valor mínimo entre dois números: int minimum(int x, int y) { if (x < y) return x; else return y; } Em Prolog, essa função será representada por uma relação.
  • 18. Operadores e Aritmética Em geral, uma função que tem k argumentos será representada em Prolog como uma relação com: ◦ k+1 argumentos; ◦ Sendo que o último é usado para carregar o resultado; Então em Prolog, escreve-se: % minimum(X,Y,Z) é verdadeiro se Z é o mínimo de X e Y minimum(X,Y,X) :- X<Y. minimum(X,Y,Y) :- X>=Y.
  • 19. Estruturas (Structure) Forma geral: estrutura-nome (atributo, ..., atributo ) Parece um predicado, mas aqui representam objeto. Não representam relações. Se diferenciam, porque estruturas sempre surgem como argumentos.
  • 20. Estruturas Supondo que queremos representar carros como os atributos: marca, anos de uso (idade), preço. Chamaremos uma estrutura carro de três lugares, por exemplo: carro(ford,3,5000) representando um carro Ford de 3 anos de uso com valor de venda R$ 5.000,00. % possui(P,C) é verdadeiro se P tem um carro que combina com C possui(joao, carro(ford,3,5000)). possui(joao, carro(opel,2,6000)). possui(gil, carro(toyota,5,1000)). possui(gil, carro(ford,2,2000)). E fazemos a pergunta: “Que tipo de Ford o Gil possui?" Consulta: possui(gil, carro(ford, Idade, Preco)) Resposta: Idade=2, Preco=2000
  • 21. Estruturas Se quiser somente recuperar a informação sobre alguns campos pode-se utilizar o marcador _ (underline) que retorna qualquer valor existente | ?- possui(Pessoa, carro(ford,_,_)). Pessoa = joao ? ; Pessoa = gil yes ◦ O underscore "_" indica que não se quer saber qual fato se casa com os campos apresentados. ◦ Se quiser saber qual marca de carro foi vendida abaixo de 5000, deve-se verificar: | ?- possui(_, carro(Marca,_,Preco)), Preco < 5000. Marca = toyota Preco = 1000 ? ; Marca = ford Preco = 2000 yes
  • 22. Recursividade Quando se usa a recursão deve-se conhecer três coisas: ◦ Algum conjunto (ou “estrutura de dados”) sobre a qual está sendo feita a recursão: exemplos comuns incluem números, arrays, árvores, etc. ◦ Uma definição de caso base, normalmente lida com uma estrutura vazia. ◦ Uma definição de caso recursivo, explicando como trabalhar um caso não-trivial em termos de algumas versões de valores menores que ele mesmo. Fatorial: por definição, o fatorial de algum número n, escrito n! é n*n-1*n-2*…*1. Nós podemos expressar em termos de recursão como segue: ◦ Estrutura de Dados: números naturais ◦ Caso Base: 0! = 1 ◦ Caso Recursivo: Para qualquer n>0, nós temos n! = n * (n-1)! ◦ Perceba que foi definido n! em termos de (n-1)!. Pode-se fazer isso a partir do momento que se conhece que (n-1) < n
  • 23. Listas O formato de uma lista segue uma seqüência de valores, correspondente a um vetor em C. Exemplo: [joao, maria, patricia] [‘string’, 6, maria, X] também é válida; Lista vazia: [ ] Lista não-vazia: contém cabeça (head) com o primeiro elemento e cauda (tail) contendo os outros elementos. Exemplo: [joao, maria, patricia] ◦ Cabeça: joao ◦ Cauda: [maria, patricia]
  • 24. Listas Notação específica para listas: [Hd | Tl] denota que a lista possui cabeça Hd e com cauda uma lista Tl. [joao, maria, patricia] -> [ joao | [maria, patricia] ] -> -> [joao | [maria | [patricia] ] ] -> [joao | [maria | [patricia | [ ] ] ] ] Processamento de listas utiliza regras de unificação: ◦ O único termo que unifica com [ ] é [ ]; ◦ [H1 | T1] unifica com [H2 | T2] se H1 unifica com H2 e T1 unifica com T2
  • 25. Listas Quase todos os predicados que utilizam listas são recursivos: ◦ Caso base: a lista vazia [ ]; ◦ Caso recursivo: para uma lista da forma [H | T], execute alguma ação na cabeça H e chame o predicado recursivamente usando a cauda T. Tamanho de uma lista: size(Lista,Tam). % size(List,N) is true if List has N elements size([],0). size([H|T],N) :- size(T,N1), N is N1+1. Definindo: ◦ O tamanho da lista vazia é 0; ◦ O tamanho da lista [H | T] é: 1+(tamanho de T).
  • 26. Listas Somando uma lista: supondo que seja formada apenas por números. % somaLista(List, N) é verdadeiro se os elementos de Lista somam para N somaLista([],0). somaLista([H|T],N) :- somaLista (T,N1), N is N1+H. Verificação de elemento na lista: % contem(Elem, Lista) é verdadeiro se Lista contém Elem contem(X,[X|_]). contem(X,[_|T]) :- contem(X,T). contem(2, [1,2,3]) contem(E, [1,2,3]) contem(E, [2,1,2]) contem(E, [])
  • 27. Listas como Acumuladores % print_to(N) - prints out all the numbers down from N to 0 print_to(0) :- write(0). print_to(N) :- N>0, write(N), nl, N1 is N-1, print_to(N1). print_to(5). Imprime todos os números entre N e 0, N ≥ 0. Como armazenar este resultado em um vetor? [H| T] collect_to(0,[]). collect_to(N,[N|T]) :- N>0, N1 is N-1, collect_to(N1,T).
  • 28. Listas como Acumuladores Unindo duas listas: ◦ O predicado join_list(L1,L2,L3) define “se quisermos juntar L1 e L2 conseguimos L3". Considerando as possibilidades para L1 ◦ L1 é uma lista vazia, neste caso L3 é L2 ◦ L1 está na forma[H1 | T1]. Se fixar L2 ao seu final, consegue-se uma lista em que a cabeça ainda é H1, mas cuja cauda é a junção de T1 e L2 join_list(L1,L2,L3) :- L1=[], L3=L2. join_list(L1,L2,L3) :- L1=[H1|T1], join_list(T1,L2,T3), L3=[H1|T3]. Outras possibilidades?
  • 29. Listas como Acumuladores join_list([], L2, L2). join_list([H1|T1], L2, [H1|L3]) :- join_list(T1,L2,L3). join_list([],L2,L3) :- L3=L2. join_list([H1|T1],L2,L3) :- join_list(T1,L2,T3), L3=[H1|T3]. join_list([1,2],[6,7],X). join_list(X, [5,6], [3,5,6]). join_list([3,4],Y, [3,4,5,6]). join_list(X,Y,[1,2]).
  • 30. Listas como Acumuladores Invertendo uma lista (duas maneiras): % bad_reverse(L1,L2) - uma implementação ruim de inversão de lista bad_reverse([],[]). bad_reverse([H|T], L2) :- bad_reverse(T,NT), append(NT,[H],L2). % myreverse(?List, ?Reversed) % é verdadeiro quando Reversed possui os mesmos elementos que List mas em ordem inversa good_reverse(List, Reversed) :- good_reverse(List, [], Reversed). good_reverse([], Reversed, Reversed). good_reverse([Head|Tail], SoFar, Reversed) :- good_reverse(Tail, [Head|SoFar], Reversed).
  • 31. Listas como Acumuladores Exercícios: ◦ Escreva predicados para os seguintes problemas: cutlast(L1,L2) que é verdadeiro se L2 é L1 com o último elemento removido. trim(L1,N,L2) que é verdadeiro se L2 contém somente os N primeiros elementos de L1 evens(L1,L2) que é verdadeiro se L2 contém somente aqueles elementos de L1 que são pares, e na mesma ordem.
  • 32. Backtracking e Cut Suponha um programa que avalie a necessidade de atendimento de um paciente de acordo com sua idade: grau(N, primeiro) :- N>=70. grau(N, segundo) :- N<70, N>=63. grau(N, terceiro) :- N<63, N>=55. grau(N, quarto) :- N<55, N>=50. grau(N, espera) :- N<50, N>=40. grau(N, falha) :- N<40. grau(75, G) -> G = primeiro Mas avalia ainda todas as outras condições!
  • 33. Backtracking e Cut int pri(int n) { return n>=70; } int seg(int n) { return n<70 && n>=63; } Avalia todos! // ... preenchendo o resto ... int fal(int n) { return n<40; } switch(n) { case(pri(n)): cout << “Primeiro"; break; case(seg(n)): cout << “Segundo"; break; case(ter(n)): cout << “Terceiro"; break; Avalia apenas o válido! case(qua(n)): cout << “Quarto"; break; case(esp(n)): cout << “Espera"; break; case(fal(n)): cout << “Falha"; }
  • 34. Backtracking e Cut Para melhorar o desempenho pode-se usar o recurso: ! (cut). Funciona como o break em C; grau(N, primeiro) :- N>=70, !. grau(N, segundo) :- N>=63, !. grau(N, terceiro) :- N>=55, !. grau(N, quarto) :- N>=50, !. grau(N, espera) :- N>=40, !. grau(N, falha) :- N<40.