3 pontos por GN⁺ 2023-09-14 | 1 comentários | Compartilhar no WhatsApp
  • Prolog organiza programas em torno de uma única cláusula (clause) e de um modelo de dados centrado em terms, permitindo expressar relações computáveis mesmo com uma sintaxe pequena
  • A abordagem declarativa descreve o que é verdadeiro em vez do procedimento de execução, de modo que a mesma relação pode ser usada para calcular, gerar e consultar
  • Prolog puro se baseia em Horn clauses e resolution, e o impacto da adição de restrições e cláusulas sobre o conjunto de soluções é logicamente previsível
  • O próprio programa é um term Prolog, o que facilita ler, analisar e transformar outros programas; reescritas em tempo de compilação também permitem criar linguagens específicas de domínio
  • Graças à dinamicidade em tempo de execução e a mecanismos implícitos como busca, unificação e propagação de restrições, ele é amplamente usado em processamento de linguagem, bancos de dados, verificação e otimização

Uma linguagem pequena feita de cláusulas e terms

  • Todos os dados em Prolog são representados como um term Prolog
  • O elemento central da linguagem é uma única clause, cujo formato básico é Head :- Body.
    • O significado é que se Body é verdadeiro, então Head é verdadeiro
    • O operador infixo (:-)/2 representa a seta , que aponta da direita para a esquerda
    • Se Head é sempre verdadeiro, :- Body pode ser omitido
  • Essa estrutura basta para escrever um primeiro programa Prolog útil
  • Todos os cálculos conhecidos podem ser descritos por essas cláusulas, portanto Prolog é uma linguagem Turing completa
    • Uma Turing machine pode ser implementada descrevendo, por meio de cláusulas, a relação que leva ao próximo estado a partir do estado atual e do símbolo sob a cabeça da fita, entre outros elementos
    • Um exemplo de implementação está em turing.pl

Programação declarativa e pensamento centrado em relações

  • Prolog é uma linguagem declarativa que expressa o que é verdadeiro sobre as soluções de interesse, em vez de como encontrá-las
  • Essa característica permite especificações concisas, claras e gerais
  • A relação entre uma lista e seu comprimento pode ser descrita assim
list_length([], 0).
list_length([_|Ls], N) :-
        N #> 0,
        N #= N0 + 1,
        list_length(Ls, N0).
  • Em alguns sistemas Prolog, é necessário incluir uma biblioteca separada para usar aritmética declarativa de inteiros
  • Declarativamente, essa definição pode ser lida assim:
    • O comprimento da lista vazia [] é 0
    • Se o comprimento de Ls é N0 e N é N0 + 1, então o comprimento de [_|Ls] é N; essa relação só é verdadeira quando N é maior que 0
  • A mesma relação pode ser usada em vários modos
    • list_length("abc", L) retorna L = 3
    • list_length(Ls, 3) encontra uma lista de comprimento 3 na forma Ls = [_A,_B,_C]
    • list_length(Ls, L) enumera respostas gerais, da lista vazia a listas de comprimento crescente
  • Prolog normalmente relata todas as respostas por meio de backtracking
  • length/2 está incluído no rascunho Prologue for Prolog e é fornecido, com o mesmo significado, como predicado embutido em quase todas as implementações de Prolog

Prolog como programação lógica

  • Entre as linguagens declarativas estão as linguagens de programação funcional e as de programação lógica
  • Funções são casos especiais de relações, e a programação funcional pode ser vista como uma forma restrita de programação lógica
  • Prolog tem raízes na logic
  • Um programa Prolog puro é composto por um conjunto de Horn clauses
  • A execução pode ser vista como um caso especial de resolution
  • Graças à conexão com a lógica formal, é possível aplicar depuração declarativa com base nas propriedades lógicas do programa
    • Ao adicionar restrições, o conjunto de soluções no máximo diminui
    • Ao adicionar cláusulas, o conjunto de soluções no máximo se expande
    • Essa propriedade dos programas Prolog puros é chamada de monotonicidade
  • O GUPU system, de Ulrich Neumerkel, é um exemplo de aplicação dessas ideias

A propriedade homoicônica de tratar programas como dados

  • Programas Prolog também são terms Prolog válidos
  • Graças a essa característica, é fácil para um programa Prolog analisar, transformar e interpretar outros programas Prolog
  • Com o predicado embutido read/1, é possível ler terms Prolog e, portanto, também cláusulas Prolog
  • Prolog possui um poderoso mecanismo de macros que reescreve programas em tempo de compilação
    • Isso permite implementar linguagens específicas de domínio que tornam as tarefas mais naturais de resolver
  • list_length(Ls,N) e N#>0 parecem diferentes na notação, mas são apenas formas mais legíveis expressas graças aos operadores prefixos, infixos e postfixos de Prolog
    • Por exemplo, o term Prolog +(a,b) pode ser escrito como a+b em notação de operador
    • Como a sintaxe abstrata é uniforme, todos os terms Prolog podem ser lidos e processados independentemente da forma como foram escritos
  • Operadores definidos pelo usuário para finalidades específicas podem ser definidos dinamicamente

Dinamicidade em tempo de execução e extensibilidade

  • Programas Prolog podem ser facilmente gerados, chamados e modificados em tempo de execução
  • Essa característica aumenta a expressividade e viabiliza a implementação de predicados de ordem superior, que recebem outros predicados como argumentos
  • Também é possível implementar técnicas altamente dinâmicas, como adaptive parsing
  • Prolog é adequado para escrever programas que são estendidos com regras personalizadas fornecidas por outros programadores ou por usuários comuns
  • Um interpretador para Prolog puro pode ser definido em duas linhas de código Prolog
  • O tema é abordado em A Couple of Meta-interpreters in Prolog

Diversas áreas de uso e mecanismos implícitos

  • A natureza relacional de Prolog torna os programas flexíveis e gerais
  • Essa característica desempenha um papel importante no processamento de linguagem e na representação de conhecimento em bancos de dados
  • Sistemas Prolog modernos oferecem os recursos necessários desde logic puzzles simples até aplicações de grande escala
  • A versatilidade e a força de Prolog têm raízes em mecanismos implícitos como busca, unificação, indexação de argumentos e propagação de restrições
  • Desenvolvedores podem usar esses mecanismos para delegar muitas tarefas ao motor Prolog

1 comentários

 
GN⁺ 2023-09-14
Opiniões do Hacker News
  • Concordo quase totalmente com esse sentimento aqui. Usei Prolog em três disciplinas de IA na universidade, cobrindo quase todo o "AI: A Modern Approach" e programação em Prolog, e foi realmente uma experiência de entortar a forma de pensar
    Eu sempre precisava de um aquecimento para voltar a pensar do jeito Prolog e, naquele semestre, acabava escrevendo código espaguete terrivelmente prologuiano até em outras linguagens. Na época, a maior desvantagem era que a interoperabilidade com outras coisas era complicada: era preciso colocar Prolog dentro da JVM, usar uma implementação com poucos recursos ou depender de bindings em C. Ele é ótimo para certas tarefas, especialmente problemas de satisfação de restrições, mas eu achava que não combinava quando entravam coisas como interfaces de usuário ou acesso ao sistema de arquivos. Naquele tempo, o SWI também estava atrasado, e usávamos soluções proprietárias como Sicstus; quando verifiquei recentemente, o SWI já tinha alcançado as implementações proprietárias, então hoje eu provavelmente escolheria o SWI. A prova de Prolog foi a mais assustadora da universidade: três problemas de live coding em 60 minutos, seguidos de uma prova oral; mas acabei me saindo bem, gastando 40 minutos no problema fácil e resolvendo os outros dois em poucos minutos. Em disciplinas seguintes, foi divertido implementar agentes para jogar e competir em torneios, e "The Art of Prolog" e "The Craft of Prolog" estão entre os melhores livros de programação que já li

    • Considero The Art of Prolog, junto com Concepts, Techniques, and Models of Computer Programming, Paradigms of AI Programming e Structure and Interpretation of Computer Programs, parte do cânone da programação com tipagem dinâmica
      The Craft of Prolog também é excelente, mas é tão específico de programação de sistemas Prolog antigos que alguns capítulos hoje estão datados. Muitas ideias do Prolog continuam vivas em programação por conjuntos de respostas e em Datalog, e Datalog é excelente para criar analisadores estáticos modernos: https://arxiv.org/abs/2012.10086
    • Ainda me lembro da expressão dos alunos de graduação saindo da primeira aula de Prolog. Metade choque, metade preocupação
      De repente fiquei curioso sobre como os chatbots lidariam com Prolog. Será que viram o bastante? Conseguiriam raciocinar desse jeito?
    • Fico pensando por que é tão difícil. Não é só busca em profundidade transformada em linguagem?
  • Prolog é bacana, e vale a pena aprender nem que seja pela diversão de experimentar um paradigma de programação estranho. Muitos conceitos são expressos de um jeito completamente diferente e, quando o paradigma faz sentido, acabam ficando muito mais simples
    Por exemplo, em Prolog, normalmente você não manipula coleções diretamente; você fornece informações sobre quais são os itens da coleção e deixa a implementação descobrir. Desenhar uma árvore de dependências também é possível com três regras: o que são as entidades, como determinar a relação entre as entidades X e Y, e como representar isso. Dito isso, por ser difícil, é complicado convencer alguém a aprender ou usar, e ainda não encontrei uma forma de integrá-lo de maneira fluida a outros apps. Sei que FFI é uma opção, mas não estou convencido de que esteja pronto para produção. Nos últimos meses procurei alternativas a Prolog mais próximas de “produção”, mas LispWorks e Franz Allegro CL são caros demais e não muito amigáveis à integração. Eu realmente gostaria de conhecer exemplos de boa integração de Prolog em software moderno. Como o XPCE não funciona no Mac, também estou procurando uma solução de GUI. Como notebook online, vale dar uma olhada no Swish: https://swish.swi-prolog.org

    • Não é uma resposta direta, mas David Hovell usou Prolog para impor a consistência da configuração de rede do Windows NT
      Pelo que ouvi, isso já foi removido, então não é um caso “moderno”, mas é um exemplo realmente bonito de aplicação de Prolog. Vale muito a pena ler a sequência que vai de https://news.ycombinator.com/item?id=36821871 para https://web.archive.org/web/20030218034509/http://www.resear.... Link relacionado: https://news.ycombinator.com/item?id=14046420
    • Não sei se isso se encaixa, mas os predicados de submissão do Gerrit eram configurados em Prolog e agora estão planejados para descontinuação. Um produto interno com que trabalhei no Google era construído em torno de uma base de conhecimento em Datalog gerada por código, que podia ser consultada diretamente ou por meio de consultas geradas pela UI
      Ambos funcionavam muito bem, mas os casos de uso eram limitados. Minha experiência com Prolog na universidade foi divertida, mas eu não gostaria de usá-lo a menos que o problema tivesse, essencialmente, a forma de Prolog. Assim que você começa a implementar algo um pouco mais complexo, as abstrações começam a vazar por todos os lados, e a sensação passa a ser mais de lutar contra o algoritmo de backtracking do que de aproveitar os pontos fortes da linguagem
    • Racket tem o Racklog
      Racklog é uma incorporação de programação lógica ao estilo Prolog em Racket, e “incorporação” quer dizer que você não perde o Racket. Dá para escrever trechos de código no estilo Prolog lado a lado com código Racket comum. Ele inclui a maior parte dos recursos do Prolog, inclusive metalógica e predicados “de conjunto” de segunda ordem, deixando de fora apenas funcionalidades que são mais fáceis e eficientes de fazer com subexpressões Racket. https://docs.racket-lang.org/racklog/index.html Racket também tem GUI e, na prática, quase tudo de que você possa precisar
    • Hoje em dia digo o mesmo sobre CUE. É uma ferramenta bem capaz de chacoalhar a forma de pensar, mas oferece uma nova maneira de controlar a complexidade de configurações e schemas
      CUE é muito mais fácil de inserir em fluxos de trabalho existentes, o que o torna bom para transformar as vantagens da programação lógica em algo prático. https://cuelang.org | https://cuetorials.com
  • Durante alguns anos, desenvolvendo em C++ software de otimização de cadeia de suprimentos, usei o software de propagação de restrições da ILOG, o Solver, que hoje pertence à IBM. Na época também avaliei o BinProlog, que tinha propagação de intervalos embutida, compilava para x86 nativo e tinha uma interoperabilidade FFI razoável
    Mesmo assim, parece que acabou ficando para trás em relação ao SWI Prolog e à toolchain GNU. GUI provavelmente deve ser vista como uma área especializada completamente diferente, e nós usávamos nosso próprio mecanismo de renderização de canvas em C++ e uma ferramenta horrível de desenvolvimento 4GL integrado chamada “4D” ou “Fourth Dimension”. https://www.tomshw.it/data/images/2/0/4/3/infor-advanced-sch...

  • A linguagem Shen, de Mark Tarver, inclui uma implementação completa de Prolog: https://shenlanguage.org/SD/Prolog.html
    Há também o capítulo correspondente de The Book of Shen: https://shenlanguage.org/TBoS/tbos_359.html Tarver também escreveu dois livros sobre programação lógica, acompanhados de software. Logic, Proof and Computation: https://shenlanguage.org/lpc.html Programming the Logic Lab: https://shenlanguage.org/logiclab.html

    • Gosto de Shen, mas nunca consegui me aprofundar de verdade. Assinei a versão profissional por meio ano, e gostava das implementações de Shen feitas sobre várias linguagens de programação
      Pattern matching, verificação de tipos opcional e Prolog embutido são impressionantes. O criador acabou sendo marginalizado pela comunidade mais ampla por causa de sua postura diplomática, mas ele é brilhante, e a adoção permaneceu nichada e de ponta. Se uma organização como a Mozilla estivesse por trás, acho que teria tido um apelo muito mais popular. As palestras de @deech hoje já são antigas, mas continuam excelentes e relevantes: https://www.youtube.com/watch?v=lMcRBdSdO_U, https://www.youtube.com/watch?v=BUJNyHAeAc8 Só leve em conta que sou entusiasta de APL/J/BQN
  • Lembro de ter aprendido Prolog cerca de 25 anos atrás em um curso de IA + ciência da computação. Usei bastante no módulo de processamento de linguagem natural
    No começo era frustrante e irritante, mas, depois que você se acostumava, era surpreendentemente divertido; e, como recursão era a única forma de fazer repetição, também era uma ótima introdução à recursão

    • Uma das coisas que Prolog me ensinou foi a importância de um professor capaz de se colocar no lugar do aluno
      Na universidade, aprendemos Prolog principalmente com matemáticos que usavam quase só esse tipo de linguagem; para eles, Prolog era uma forma de pensar muito natural. Em contrapartida, para alunos que tinham usado sobretudo linguagens procedurais, era confuso e frustrante, e todo mundo se enrolava tentando escrever Prolog como se fosse outra linguagem. Só na terceira ou quarta disciplina usando Prolog, depois de estudar os algoritmos por trás dele, é que a forma correta de usá-lo entrou na minha cabeça. Mais tarde, ajudei um graduando que estava sofrendo com Prolog, e o ponto central era não tentar fazer Prolog se comportar como as linguagens que ele já conhecia, mas mudar a forma de pensar a resolução de problemas para se adequar ao mundo do Prolog. Depois de uma conversa bem longa, veio o verdadeiro momento de iluminação, e ele concluiu o trabalho muito bem
    • Comigo foi parecido. No início, eu tentava escrever código imperativo com sintaxe de Prolog, o que era frustrante e irritante
      Mas, depois que o novo paradigma fez sentido na minha cabeça, passei a gostar muito. Só esse momento de compreensão já valeu a pena ter feito a disciplina
    • Acho que o mais correto seria “também é ótimo como introdução à recursão, já que é a única forma de recursar”
    • Fiz Prolog há alguns anos no bacharelado em ciência da computação também. Não foi uma parte grande, apenas um pequeno componente da disciplina de IA, mas ainda assim foi divertido
  • Outros comentários falam de Prolog em geral, mas quero dizer que The Power of Prolog é uma série de tutoriais muito boa
    Os vídeos também valem a pena, e Markus consegue prender bem o interesse de espectadores e leitores

    • Como alguém que primeiro se frustrou com Prolog e depois teve uma “iluminação”, recomendo começar pelo vídeo Preparing Prolog, do Markus: https://www.metalevel.at/prolog/videos/preparing_prolog
      Esse vídeo me ajudou a enxergar Prolog como um movimento atual e progressista dentro da programação
  • Prolog é uma linguagem linda. Já escrevi dezenas de milhares de linhas com raciocínio matemático, raciocínio baseado em regras etc.; para esses domínios, ela se encaixa perfeitamente, e o trabalho é extremamente divertido
    Para outros tipos de aplicação, há dois problemas. Primeiro, o paradigma é tão diferente que ele não combina bem com bibliotecas e outras linguagens. Segundo, criar uma GUI decente é quase impossível, também porque não combina com o paradigma

    • Participei da escrita da parte de interoperabilidade com Go do GoLog, e fazer interface com outras linguagens não é particularmente difícil
      Normalmente, do lado do Prolog, a interface externa se parece com um predicado em que todos os argumentos estão instanciados; do lado externo, interage-se com o Prolog como se fosse um banco de dados SQL. Você envia consultas, decompõe consultas, pede mais soluções ou aciona o backtracking. Dá para dizer que esse tipo de interação não é “interessante”, mas ela funciona assim porque as bibliotecas não aproveitam de fato os recursos úteis do Prolog. Se quiser, é possível criar uma camada de interoperabilidade mais espessa, agrupando várias funções de biblioteca em uma única interface de predicado no lado do Prolog e chamando uma sub-rotina específica conforme o modo de instanciação dos argumentos. Mas isso não é muito diferente de expor uma biblioteca C a uma linguagem orientada a objetos como Python, agrupando várias funções C como acessores de propriedades ou métodos de uma estrutura de dados
  • Uso Prolog ativamente para análise de dados. No começo, foi necessário passar por uma fase de me forçar a fazer tudo que fosse possível em Prolog, para entender como transformar perguntas em problemas simbólicos

Isso porque Prolog tem um suporte péssimo para computação científica e manipulação de strings. Depois de passar dessa etapa, a solução em Prolog muitas vezes é mais elegante do que a próxima melhor alternativa. Além disso, como é um paradigma lógico, vale a pena dedicar tempo para entender como prova por negação + unificação = programação lógica. Entre as linguagens de programação que aprendi, foi de longe a que mais ampliou minha visão

  • O suporte de Prolog para manipulação de strings é bem decente. Quase nenhuma linguagem moderna popular oferece algo como DCG por padrão
    O Prolog padrão não vem com regex embutido, mas as implementações populares normalmente oferecem bibliotecas para isso. Se eu tiver de fazer muito trabalho com strings e escolher entre C e Prolog, com certeza escolheria Prolog. Entre Python e Prolog, dependeria da tarefa
  • Interessante; você poderia dar um exemplo de como usar isso em análise de dados?
  • Isso também foi discutido há 1 ano: https://news.ycombinator.com/item?id=31641014
    De qualquer forma, é um ótimo site, e fico feliz que esse tema tenha voltado à tona
  • As 10 linhas em que implementei busca em grafos A* em Prolog foram as 10 linhas de código mais difíceis da minha vida
  • Na faculdade, fiz uma disciplina de Prolog. Tive de implementar um solucionador de Sudoku e, em certo ponto, travei
    Eu já tinha escrito um solucionador em Java antes, então tentei portar esse código para Prolog, mas não funcionou de jeito nenhum. No fim, recomecei do zero e escrevi um código simples em Prolog que verificava se um Sudoku era válido, e percebi que, ao executar aqueles predicados, também dava para resolver o Sudoku. Assim, concluí o solucionador em menos de 10 linhas. Foi um verdadeiro momento eureka, e Prolog é muito poderoso, mas é injustamente pouco usado na prática. Felizmente, tive a oportunidade de trabalhar com Datalog e OWL