Programação Lógica com Prolog: Fatos, Regras, Consultas e Recorrência

1) Abordagens de linguagem: procedimental vs declarativa

- Linguagem procedimental define um conjunto de instruções que devem ser seguidas para resolver um problema. Exemplo: um programa em uma linguagem imperativa executa passos com um fluxo de controle explícito, acessando módulos e dados para chegar a uma solução.

- Linguagem declarativa, como Prolog, foca em o que deve ser obtido, não no como obter. O problema é apresentado como uma consulta que descreve informações a inferir a partir de fatos e regras existentes.

Observação: em Prolog, a inferência é feita por meio de regras de lógica e um mecanismo de resolução que trabalha com fatos, regras e consultas.

Exemplo prático: Predicados em Prolog podem ser declarados como fatos:

planta(X).
animal(X).

Consultas podem ser feitas para obter informações derivadas a partir desses fatos.

2) Prolog e lógica de predicados

- Prolog é uma linguagem declarativa baseada em lógica de predicados, onde o conhecimento é representado por fatos e regras, e as consultas são usadas para deduzir novas informações a partir deles.

Componentes básicos:

  • Fatos: predicados simples que descrevem o estado do mundo. Ex.: foi(comer,coelho,grama).
  • Regras: definem relações entre predicados de forma condicional. Ex.: predador(X) :- presa(X), caça(X).
  • Consultas: perguntas que pedem proveniência de informações a partir dos fatos e regras. Ex.: predador(raposa)?

Exemplo prático:

alma(X) :- humano(X).
humano(jose).
humano(maria).

Consulta: ?- alma(jose).

Resultado: verdadeiro, pois jose é humano.

3) Fatos, regras e consultas

Fatos descrevem elementos do domínio. Ex.: alimento(urso, peixe).

Regras descrevem condições que implicam novos predicados. Ex.: caçador(X) :- presa(X).

Consultas permitem inferir informações a partir de fatos e regras. Ex.: ?- alimento(urso, Y).

Observação: a consulta funciona como uma padronização de variáveis; o motor de inferência procura substituições que tornam a consulta verdadeira.

4) Casamento de padrões, unificação e resolução

- O Prolog utiliza resolução para inferir consequências a partir de cláusulas (fatos e regras). A ideia é combinar uma cláusula com a negação de uma de suas literais para deduzir uma nova cláusula (cláusulas de Horn).

- Uma cláusula de Horn tem no máximo um literal não negado. Exemplos típicos: p(X) :- q(X), r(X). ou apenas fato como p(a).

Transformação para forma de cláusula de Horn: uma implicação A -> B1, B2, ..., Bn pode ser reescrita como A :- B1, B2, ..., Bn.

- A resolução no Prolog envolve encontrar uma cláusula que contenha o predicado que é a negação da literal da outra cláusula, unificar termos e deduzir o consequente.

Exemplo simples de resolução:

fato(x).
fato(y).
regra(z) :- fato(x), fato(y).

Consulta: ?- regra(Z).

Inferência: se x e y são fatos, então Z é verdadeiro pela regra.

5) Cláusulas de Horn, equivalência e recorrência

Cláusulas de Horn são expressões com no máximo um predicado não negado. Em lógica, ajudam a estruturar o conhecimento para inferência eficiente.

Recorrência (definição recursiva) em Prolog ocorre quando uma regra se usa a si mesma indiretamente para resolver um problema em etapas. Ex.: cadeia alimentar.

Exemplo de recorrência na cadeia alimentar:

alimenta(uso, peixe).
alimenta(uso, raposa).
alimenta(peixe, alga).

cadeia_alimentar(X,Y) :- alimenta(X,Y).
cadeia_alimentar(X,Y) :- alimenta(X,Z), cadeia_alimentar(Z,Y).

Consulta para descobrir quem está na cadeia alimentar do uso:

?- cadeia_alimentar(uso, Quem).

Neste caso, Quem pode ser peixe, raposa, veado, e recursivamente alga.

6) Observações e dicas

  • Pratique transformar implicações em cláusulas de Horn para entender a inferência futura.
  • Para consultas com variáveis, pense na unificação: quais valores satisfazem a satisfação das condições?
  • Recursão é comum em Prolog para percorrer estruturas hierárquicas ou cadeias (ex.: árvore, cadeia alimentar).

Questões sobre o assunto

1) Sobre diferenças entre linguagem procedural e declarativa, escolha a alternativa correta
1.50 Média

Resposta correta: B) Em linguagem declarativa o foco é descrever o que é desejado (o que) e usar fatos/regras para deduzir a solução.

2) Qual é a forma canônica de uma cláusula de Horn em Prolog?
2.50 Difícil

Resposta correta: C) p :- q, r representa uma cláusula de Horn na forma de regra (consequente :- antecedentes).

3) Sobre a recursão (definição recorrente) para cadeia alimentar em Prolog, qual é a ideia principal?
2.50 Difícil

Resposta correta: C) A recursão permite inferir múltiplos níveis na cadeia (ex.: uso → peixe → alga), indo de base até etapas superiores.

4) Considere o seguinte esquema recursivo para cadeia alimentar:
3.50 Extrema

Resposta correta: B) cadeia(uso, Y) é satisfeita por alimento(uso, Y) ou através de recursão alimento(uso, Z), cadeia(Z, Y).

Pontuação Total
0.00

Texto original

O texto original pode conter falhas de gramática ou de concordância, isso ocorre porque ele foi obtido por um processo de extração de texto automático.
Texto extraído do video Fundamentos Matemáticos para Computação - Programação Lógica (Libras)

Olá, alunas e alunos do curso de Fundamentos Matemáticos para a Compratação.
Esta videoaula eu vou falar de programação lógica.
Estabeles sendo a diferença ainda numa linguagem procedimental e uma linguagem declarativa, apresentando o prologue que é uma linguagem declarativa para vincular as ideias de lógica que vimos até agora de lógica proposicional de predicados, depois estabelecer o conceito de clausanas de or e a ideia de recorrência.
Bom, uma linguagem procedimental define um conjunto de instruções a serem seguidas para abordar um problema.
Esse ocasiamento, por exemplo, de uma linguagem como ser que tem um programa principal a partir do qual tem instruções que você vai seguir ainda que acessando diferentes móvulos para resolver aquele problema.
Uma linguagem declarativa, como é o caso do prologue, temos uma outra abordagem para tratar o problema.
O problema não tem vezes desenvolve uma consulta para obter uma determinada informação ou uma dedução a partir de informações disponíveis.
O problema consiste em ter uma informação nova a partir de informações disponíveis.
Então, nesse caso, você tem uma linguagem que utiliza que entrega lógica de predicados e vai consequentemente usar regras de inferência para obter essas conclusões a partir das hipóteses que são representadas como dados que são armazenados nessa determinada base de forma de conhecimento.
Eu espero que depois dessa aula você se sintam motivados a aprender o prologue, sobre a sintaxa do prologue, recomendo esse site aqui em tutorial e vocês teriam uma chance de instalar e programar um pouquinho prologue.
Nessa aula, nós vamos ver quando relacionar a lógica que aprendemos com a programa inoxica que é programando inoxica ou prologue.
Quando o prologue nós vamos ter declarações que são que algo constitui, essas declarações constituem um programa em prologue e elas são placificadas os fatos, o regras e regras.
Os fatos são o que? O que vimos? Os predicados, que vão definir características para elementos em um domínio com o junto universo.
Então, por exemplo, planta x, se ele é x é uma planta, animal x, x é animal.
Então aqui temos um exemplo de dois predicados binários que podemos implementar em prologue, x se alimenta de hipóteso, um predicado binário.
E esses predicados, então, que compõem que caracterizam os fatos, eles montam, são os atos para montar uma base de conhecimento, uma base de dados.
A partir da qual nós podemos fazer consultas.
Por exemplo, eu posso verificar se o viato se alimenta de grama, o que vai ser verdadeiro nesses sabássito conhecimento.
Então, eu vou retornar assim, ou tru, verdadeiro.
Qualivamente, eu não estou aplicando aqui a syntax precisa prologue, estou apenas ilustrando os conceitos fóricos.
O uso se alimenta de coelho, sim, vai ser verdadeiro, então, vai retornar, aticupa.
O uso se alimenta de coelho não, isso não está registrado na base de dados, então, não vai retornar nada.
Além disso, eu posso fazer uma consulta geral do tipo, o uso se alimenta de quê? Aí, vai ser listado que o uso se alimenta de peixe e o uso se alimenta de raposa, mas não se alimenta de quê.
Bom, além disso, eu posso combinar usando, por exemplo, e para verificar se x se alimenta de y e y é uma planta.
Então, nesse caso, para uma consulta, ele vai procurar um padrão aqui para atribuir valores preças variáveis, então, o caso de uc se peixe, ele vai verificar se o uso se alimenta de peixe, o que é verdade, e se peixe é uma planta, o que não é, então, essa consulta não vai retornar nada a ver se ele fala.
Ou eu posso fazer agora uma consulta, vier a de se alimenta de grama, sim, e grama é planta, sim, está cada estado aqui como planta.
Então, vai retornar na verdadeira.
Bom, continuando dessa forma, nós temos, além dos fatos, as regras que descrevem um predicado por meio de condicional.
Então, reparem aqui que a maneira de você expressar isso, por esse exemplo aqui, por a gente está colocando direita para a esquerda a implicação.
Então, si x é ilímpico, não se alimenta de x, e x é animal, então, x é presa.
O que vocês já conseguem representar, visualizar isso aqui, como essa relação lógica.
Eu tenho aqui no e, quando pongo essa proposição com essa, implicando nesta outra proposição.
E uma consulta desse tipo na nossa base de dados, retornaria peixe em raposa.
Vamos ver isso com um pouquinho mais de detalhe.
Por que? Porque quando eu faço a consulta base, eu vou ter esse padrão, esse casamento aqui, de padrão, de 1, e peixe.
Isso aparece aqui, o 1, peixe, peixe.
E como isso é verdadeiro, então, dá um retorno de que temos peixe, como resultado da consulta.
O próximo consulta vem uns, e raposa, o uso raposa, raposa, retorna, verdadeiro.
Então, eu tenho raposa como uma consulta válida.
Se eu agora tento fazer a consulta, viado se alimenta de grana, e grama como animal, vai dar falso, e aí eu não vou ter resultado dessa consulta.
Bom, com essas ideias de mente, agora vamos estabelecer o conceito de cláusulas de hora.
O Horn foi um matemático americano que trabalhou com teoria de ríticulados, áudio brown universal, e fez essa contribuição, né, ao estabelecer essas cláusulas, essa contribuição para o desenvolvimento dessa programação, dessas linguagens declarativas.
Por quê? Porque é uma maneira que você tem através dessas cláusulas, expressar o conhecimento que vai permitir e vai facilitar a inferência de resultados, de formação, de que forma.
Você tem que a cláusula de Horn, ela é definida por ter no máximo um predicado não negado, como é esse caso que é único predicado que não está negado, ou você tem predicados negados por digiunção tendo no máximo uma composição de cláusula como essa, um predicado não negado.
Só que se nós observamos isso aqui, então como que vai facilitar essa questão de inferência como eu estava falando, né? Se a gente observar essa, a maneira que começa a cláusula para a posta, nós podemos reescrever ela usando a equivalência de demorga, deixando essa negação do lado de fora, transformando em e, e temos essa relação, essa nova expressão para a cláusula.
Só que se eu aplicar agora a equivalência condicional, eu tenho essa representação, que é a maneira como eu introduzi o predicar a regra aqui da presa, certo? Beleza? Então, a estuposto, como que vai se dar essa inferência dentro do proogue? A regra de resolução do proogue busco um termo e sua negação, inferindo assim uma cláusula de ó, a partir de outras duas.
A única regra de inferência que vai ser usada é essa chamada, no proogue, essa chamada de resolução, que vocês vão ver uma semelhança, vocês vão lembrar de algo já já visto nas últimas aulas.
Bom, no caso aqui para a gente entender a resolução, nós temos uma cláusula como foi dito e a sua negação.
Bom, nesse caso, essa negação está aparecendo aqui numa outra cláusula de ó, onde eu posso sendo isso verdadeiro, isso aqui sendo verdadeiro também, mas este termo falso implico que esse termo necessariamente precisa ser verdadeiro e eu tenho a resolução.
Bom, estuposto, vamos lembrar que vimos anteriormente na óbrica de predicados.
Nós temos uma hipótese, nós temos essa implicação porque este termo nós já sabemos que podemos representar pela equivalência condicional aqui e aplicando modos pónios, podemos deduzir da linha 1 e 2 o consequente.
Dessa forma, então, a regra passa a ser representada desse jeito na nossa base de conhecimento através de uma cláusula de ó.
O proogue, então, ele busca uma regra que tem o predicado, esse predicado como consequente, como que a gente vai ver isso.
Ele vai procurar no banco por cláusulas que permitam eu aplicar a resolução, então aquele esquema que eu tenho, uma cláusula e sua negação de que for.
Se eu vou fazer essa consulta de presa, então eu tenho essa regra e quando eu faço a consulta, ao banco, então eu vou ter valores atribuídos para essas variáveis.
Então, eu tenho aqui, começando pelo uso e pelo peixe, eu tenho o IP, vai aparecer IP aqui, certo? Eu também, como verdade, além dessa regra, eu tenho esse fato, que é o IP, o uso se alimenta de peixe.
Bom, a partir daí eu posso deduzir esse termo, porque eu tenho esse uso se alimenta de peixe aqui e a negação dele é que me levam a inferir esse segundo teatro.
Então eu aplico, posso aplicar a resolução e deduzir isso, ou lembrando da lógica, nós temos.
Sendo verdadeira essa proposição e lembrando que esse termo eu posso reescrivire, negando esse aqui, trocando o IP, lembrando a aplicação e mantendo o segundo, aplico modos ponens aqui e deduzo este tempo.
Só que se vocês observarem, eu não terminei a minha resolução de aplicar ainda, eu ainda não cheguei na presa no resultado final.
Para eu inferir isso, eu novamente vou agora fazer procurar um termo não negado, que nesse caso vai ser o animal e aí o peixe animal, e aí eu vou poder aplicar novamente a resolução.
Eu tenho uma negação dele, eu entiro esse aqui, que nada mais é do que assumindo essa hipótese e tendo essa implicação da equilhiva de isso aqui com modos ponens, eu deduz isso aqui.
E aí a minha consulta retora, peixe.
Bom, dessa eu também posso usar a cláusula para eu posso usar essa resolução envolvendo cláusulas de or, para inferir uma nova regra.
Nesse contexto, suponho aqui que eu tenho essa regra, se x é uma presa, então x é caçador.
E eu tenho a regra anterior aqui de presa.
Bom, essa regra nós podemos representar do ponto de vista lógico, dessa forma cológica proposicional, que é equivalente a esse termo que reescrita agora como uma cláusula de forma.
Dessa forma eu consigo ter esse termo, certo? E eu tenho esse outro termo para essa regra, beleza? A uma versão cláusulas de or.
Dessa maneira eu vou poder inferir esse termo aqui, gerando uma nova regra, onde o caçado aparece aqui.
Como que eu chego nisso? Eu, se você observar, você tem aqui que essa primeira expressão, vamos pensar e era essa relação em um intuito dessa aula estabelecer como isso ocorre numa linguagem declarativa, mas apresentando como a loja que vocês aprendeu até agora se aplica nesse contexto.
Então, novamente nós temos essa reescrita usando a equivalência condicional da cláusula de forma.
Essa segunda cláusula também é reescrita desse jeito.
Lembre-se, nós colocamos a negação para fora, eu trocamos e aplicamos a lei de demorba naquí e eu percebe que então eu tenho uma situação que é a seguinte.
Esse termo implica em presa e presa implica em caçado.
Logo, esse termo implica em caçado, que nada mais é do que a nova regra.
Então, eu percebe que aqui eu estou usando a lógica proposicional onde eu entiro que se há implica em d e bem implica em c, então há implica em c.
E aí você consegue, automaticamente, inferir essa nova regra.
As regras no Prologue são condicionais, antecedentes no lado direito das regras, quando eu fui dito, e essas regras vão estar decendendo, não é? Com antecedentes fatos ou outras regras.
Porém, na verdade, nós podemos ter a própria regra com antecedente da elamismo.
Então, nesse caso, nós temos o conceito de uma definição recorrente ou recorciida, porque você tem uma regra chamando a ela mesma.
Então, nós temos ela fazendo parte da definição.
Só que, em geral, esse processo recorcivel, ele já é um efeito cascata, que termina num passo base, onde chegamos ao mar e grão, e você não vai ter continuidade.
Bom, nesse conceito, vamos supor que aquele nosso banco de dados se estendeu agora para algo mais amplo como esse no estrada aqui.
E se vamos aplicar essa recorrencia na nossa consulta, nós vamos supor aqui que estamos querendo saber quem está na cadeia alimentado o uso.
Bom, para isso, então, nós vamos ver aqui para descobrir quem está na cadeia alimentado o uso, nós vamos ter que ver se o uso se alimenta de alguma coisa, e se essa alguma, o que está na cadeia alimentada dessa coisa? Quando aquela nossa base, nós vemos que o uso se alimenta de peixe, o uso se alimenta de gachinho, o uso se alimenta de raposa e o uso se alimenta de veado, que já seria retornada aqui nessa consulta.
Certo? Só que depois devemos nos estender para o que está na cadeia alimentar, no caso que está na cadeia alimentado o peixe, do gachinho, da raposa e do veado.
Para fazer isso, então, eu vou mostrar aqui o caso do peixe.
Então, nós temos que o peixe, quando nós vamos analisar o que está na cadeia alimentado, o uso, nós identificamos que vamos fazer um padrão aqui com o peixe, no caso o uso se alimenta do peixe e o peixe.
Vamos agora investigar o que está na cadeia alimentado o peixe.
E aí, recursivamente vemos que peixinho, vamos avaliar o peixe na cadeia alimentado do peixe.
Por que? Porque nós temos no antecedente que o peixe se alimenta de peixinho e o peixe no no por sua vez, abre um ramo para avaliar o que está na cadeia alimentar dele, que nesse caso é a alga.
E essa consulta do peixe do que está na cadeia alimentado do peixe, que é a alga, nos leva o que é o fato de que o peixe se alimenta de alga e não vamos investigar, porque não tem uma cadeia, não vai ter uma cadeia associada a alga.
E aí, encerra-se a consulta.
Com isso nós vamos saber que a alga está na cadeia alimentado do uso, o peixe, está na cadeia alimentado o uso e o peixe está na cadeia alimentado o uso.
A partir daquela primeira consulta, mas teríamos outras a fazer aqui.
Retornar para esse tapa e uma vez esgotada a busca recursiva aqui, retomar nesse ponto.
Bom, dessa forma nós temos um mecanismo de idas e vindas para inferir para realizar essa consulta irrepossível.
Os conceitos dessa aula foram retirados da sessão o ponto 5 do material base.
Eu espero que vocês dêem uma lida com calma.
E que fossem que tentem identificar como pode ser fácil programar em prologue com os conceitos de lógica que vocês já aprendeiram até o momento.
Muito obrigado.