image

Access unlimited bootcamps and 650+ courses

50
%OFF
Article image
Fernanda Araujo
Fernanda Araujo23/06/2025 10:31
Share
Savegnago - Lógica de ProgramaçãoRecommended for youSavegnago - Lógica de Programação

Paradigmas de Linguagens de Programação em Python: Python Lógico (Part. 09)

  • #Python

O paradigma lógico baseia-se em declarar fatos e regras, deixando que o computador deduza respostas por meio de raciocínio lógico. Embora Python não seja uma linguagem lógica pura, é possível programar conceitos desse paradigma usando bibliotecas específicas, trazendo o poder da lógica declarativa para projetos reais.

Para ilustrar esse processo, vamos imaginar que somos Nico Robin, a arqueóloga de One Piece, tentando decifrar os antigos Poneglyphs. Assim como um desenvolvedor precisa entender, executar e corrigir seu código, Robin precisa interpretar símbolos, prever falhas e reagir a imprevistos durante a tradução de textos milenares.

🧩 Paradigma Lógico com Python

O paradigma lógico é fundamentado na ideia de que programas são conjuntos de sentenças lógicas, compostas por fatos e regras, e que a execução consiste em consultar essas sentenças para que o sistema deduza as respostas corretas automaticamente. Ele é amplamente utilizado em inteligência artificial, sistemas especialistas, e linguagens como Prolog, que têm suporte nativo para raciocínio lógico.

Embora Python não seja uma linguagem lógica pura, ele oferece ferramentas e bibliotecas que permitem programar com conceitos do paradigma lógico, combinando raciocínio declarativo com a flexibilidade do paradigma imperativo.

Uma das bibliotecas mais populares para programação lógica em Python é a kanren (anteriormente conhecida como logpy). Com ela, podemos definir relações, fatos e regras, e depois fazer consultas lógicas para obter respostas baseadas nesses dados.

Como funciona o kanren?

  • Relações: são estruturas que representam relações entre elementos (ex: parent(X, Y) significa "X é pai/mãe de Y").
  • Fatos: instâncias de relações que definem o conhecimento base do sistema.
  • Variáveis Lógicas: usadas para fazer consultas e encontrar valores que satisfazem as relações.
  • Consultas: perguntas feitas para descobrir quais valores das variáveis tornam as relações verdadeiras.

Exemplo prático

python

from kanren import run, var, Relation, facts


# Criar a relação "detentor" (quem detém o Poneglyph)
detentor = Relation()


# Definir fatos da relação detentor
facts(detentor,
    ("Robin", "Poneglyph do Reino de Alabasta"),
    ("Robin", "Poneglyph do Reino de Wano"),
    ("Jinbe", "Poneglyph do Reino de Fishman Island"))


# Criar variável lógica para consulta
x = var()


# Consultar quais Poneglyphs Robin detém
poneglyphs_da_robin = run(0, x, detentor("Robin", x))
print(poneglyphs_da_robin)
# Saída esperada: ('Poneglyph do Reino de Alabasta', 'Poneglyph do Reino de Wano')

No exemplo acima, facts adiciona dados à relação parent, e run executa a consulta para descobrir todos os valores de x que satisfazem a relação parent(x, "Bart").

Por que usar lógica em Python?

  • Expressividade: permite modelar problemas complexos com regras declarativas, que são mais fáceis de manter e entender.
  • Dedução automática: o sistema encontra soluções para consultas complexas sem que o programador tenha que escrever todo o passo a passo.
  • Integração com código Python: é possível misturar o paradigma lógico com código imperativo e orientado a objetos para criar soluções híbridas poderosas.

📚 Conceitos Básicos: Fatos, Regras e Consultas

  • Fatos: declarações simples que representam dados.
  • Regras: expressões que definem relações entre fatos.
  • Consultas: perguntas feitas ao sistema para deduzir informações baseadas nos fatos e regras.

💻 Exemplo Prático com kanren

python

from kanren import run, var, Relation, facts

# Relação: quem encontrou qual Poneglyph
encontrou = Relation()
facts(encontrou,
    ("Robin", "Poneglyph de Skypiea"),
    ("Robin", "Poneglyph de Ohara"),
    ("Kozuki Oden", "Poneglyph de Laugh Tale"))

x = var()
# Quem encontrou o Poneglyph de Skypiea?
print(run(1, x, encontrou(x, "Poneglyph de Skypiea")))

Este código define uma relação de descoberta de Poneglyphs e consulta quem encontrou o de Skypiea.

🧮 Manipulação Lógica com sympy.logic

python

from sympy.logic.boolalg import Or, And, Not
from sympy import symbols

mapa_antigo, texto_decifrado = symbols('mapa_antigo texto_decifrado')
# A Robin só pode avançar se tiver um mapa ou conseguir decifrar o texto
proxima_etapa = And(Not(mapa_antigo), Or(texto_decifrado, mapa_antigo))

print(proxima_etapa.simplify())

Aqui representamos uma lógica: se o mapa não estiver disponível, Robin só poderá prosseguir se conseguir decifrar o texto. Usamos lógica simbólica para simplificar as condições.

🔄 Simulando Lógica Declarativa em Python Puro

Embora não tenha suporte nativo, é possível criar sistemas simples de lógica usando funções, listas e dicionários para representar fatos e regras e filtrar soluções.

python

# Fatos: personagens e ilhas visitadas
fatos = [
  {"personagem": "Robin", "ilha": "Ohara"},
  {"personagem": "Robin", "ilha": "Skypiea"},
  {"personagem": "Luffy", "ilha": "Skypiea"},
  {"personagem": "Zoro", "ilha": "Wano"},
]


# Regra: quem passou por Skypiea?
def passou_por(ilha):
  return [f["personagem"] for f in fatos if f["ilha"] == ilha]


print(passou_por("Skypiea"))  # ['Robin', 'Luffy']

Aqui criamos uma “regra” com uma função e usamos uma lista de dicionários como base de conhecimento. Essa é uma forma funcional e imperativa de simular inferência lógica.

🎯 Aplicações Práticas

A lógica declarativa é poderosa para sistemas que exigem raciocínio automático e decisões baseadas em regras. Veja alguns exemplos práticos:

🧠 Sistema especialista de decisão (Robin decifrando um Poneglyph)

python

def eh_importante(poneglyph):
  return poneglyph.get("tipo") == "Road" or poneglyph.get("contém") == "História do Século Perdido"

p1 = {"ilha": "Wano", "tipo": "Road", "contém": "Rei dos Mares"}
p2 = {"ilha": "Ohara", "tipo": "Histórico", "contém": "História do Século Perdido"}
p3 = {"ilha": "Dressrosa", "tipo": "Histórico", "contém": "Eventos locais"}

print(eh_importante(p1))  # True
print(eh_importante(p2))  # True
print(eh_importante(p3))  # False

🗺️ Regras de navegação do bando com base nos registros de Robin

python

def deve_visitar(ilhas):
  return [ilha for ilha in ilhas if ilha.get("poneglyph") and ilha["poneglyph"]["tipo"] == "Road"]

ilhas = [
  {"nome": "Wano", "poneglyph": {"tipo": "Road"}},
  {"nome": "Alabasta", "poneglyph": {"tipo": "Histórico"}},
  {"nome": "Drum Island", "poneglyph": None},
]

print(deve_visitar(ilhas))  # [{'nome': 'Wano', 'poneglyph': {'tipo': 'Road'}}]

🧩 Consulta lógica para descobrir conexões entre símbolos nos Poneglyphs

python

pones = [
  {"ilha": "Wano", "simbolos": {"d", "reino", "luz"}},
  {"ilha": "Ohara", "simbolos": {"d", "livros"}},
  {"ilha": "Skypiea", "simbolos": {"sinos", "luz"}},
]

def procurar_ilhas_com(simbolo):
  return [p["ilha"] for p in pones if simbolo in p["simbolos"]]

print(procurar_ilhas_com("d"))     # ['Wano', 'Ohara']
print(procurar_ilhas_com("luz"))   # ['Wano', 'Skypiea']

🔍 Quebra-cabeça lógico: qual ilha tem mais símbolos únicos para Robin decifrar?

python

def ilha_mais_complexa(pones):
  return max(pones, key=lambda p: len(p["simbolos"]))

pones = [
  {"ilha": "Ohara", "simbolos": {"d", "livros", "tempo"}},
  {"ilha": "Skypiea", "simbolos": {"luz", "sinos"}},
  {"ilha": "Wano", "simbolos": {"reino", "d"}},
]

mais_complexa = ilha_mais_complexa(pones)
print(mais_complexa["ilha"])  # Ohara

⚠️ Desafios e Limitações

🚫 Backtracking manual: Robin precisa testar todas as traduções até achar a correta

python

pistas = ["lua", "reino", "voz", "d"]

def decifrar(pistas):
  for tentativa in pistas:
      print(f"Robin testando: {tentativa}")
      if tentativa == "d":
          print("🌟 Significado encontrado!")
          break

decifrar(pistas)

🐢 Performance lenta com grandes registros: muitos Poneglyphs para processar

python

poneglyphs = [{"ilha": f"Ilha {i}", "conteudo": "???", "simbolos": ["a", "b", "c"]} for i in range(100000)]

# Filtrar ilhas que mencionam "d"
ilhas_d = [p for p in poneglyphs if "d" in p["simbolos"]]

print(len(ilhas_d))  # 0 – Nenhuma menciona "d"

🔗 Dependência de bibliotecas externas (como kanren): Robin sozinha não consegue tudo

python

try:
  from kanren import run, var, Relation, facts
except ImportError:
  print("🔗 Biblioteca kanren não encontrada. Robin não consegue usar lógica avançada sem ajuda externa.")

🔚 Conclusão

Integrar o paradigma lógico ao Python é como adicionar uma nova forma de pensar ao seu código — baseada em dedução, relações e inferência automática. Mesmo sem suporte nativo completo, bibliotecas como kanren e sympy.logic nos permitem simular esse estilo com elegância, aplicando lógica declarativa para modelar sistemas baseados em regras e conhecimento.

Mais do que escrever instruções, você passa a estruturar fatos e deixar que o programa tire conclusões por conta própria. Isso é especialmente poderoso em cenários onde as decisões precisam ser derivadas com base em múltiplas condições e relações.

Se a Nico Robin programasse, ela usaria o paradigma lógico como usa seus poderes: consultando informações espalhadas como se fossem Poneglyphs, cruzando dados para encontrar respostas escondidas e agindo com precisão a partir do conhecimento, não da força. Cada relação no código seria como um braço que busca a verdade entre os fatos — silencioso, certeiro e essencial

👉 No próximo artigo, vamos explorar sobre Python declarativo...

image

Share
Recommended for you
Suzano - Python Developer
BairesDev - Machine Learning Practitioner
Santander - Cibersegurança #2
Comments (1)
DIO Community
DIO Community - 23/06/2025 16:47

Fernanda, seu artigo sobre programação lógica em Python é uma ótima introdução ao paradigma lógico e sua aplicação, mesmo em uma linguagem multiparadigma como Python. A analogia com Nico Robin e os Poneglyphs é uma maneira criativa e acessível de explicar como a lógica de predicados funciona, tornando o conteúdo mais atraente e fácil de entender.

Gostei muito de como você explicou a diferença entre Python e Prolog, esclarecendo que, embora Python não seja uma linguagem lógica nativa, ainda é possível simular esse comportamento com bibliotecas como kanren. O exemplo prático com a biblioteca foi muito eficaz para ilustrar a ideia e mostrar como podemos realizar deduções lógicas no Python.

Minha pergunta para você é: quais seriam as possíveis limitações de usar Python para programação lógica em comparação com linguagens nativas como Prolog? E como você acredita que essa abordagem pode ser aplicada em projetos do dia a dia?

Recommended for youSavegnago - Lógica de Programação