Aula 17

Prolog online

Outras coisas de Prolog

Prolog permite definir predicados. QQ linguagem permite definir funções. Mas é possível definir novos operadores e novos commandos?

Modificação de sintaxe: operadores

sintaxe: f(x,y) versus x + y

Operadores aritméticos são normalmente left associative

2^3^4 é right associative = 2^(3^4)= 2^{3^4}

prolog: comando op https://www.swi-prolog.org/pldoc/man?predicate=op/3 permite definir predicados e functor como operadodes, definir o tipo (infixo, prefixo, posfixo, e a associatividade).

:- op(200,xfy,pai).

joao pai antonio. em vez de  pai(joao,antonio)

antonio pai maria.

dynamic pai/2 dynamic é um operador prefixo (de 1 argumento).

outras linguagens permitem definir operadores (infixos)

Modificação de sintaxe: comandos

alem de uma sintaxe diferente comandos podem ter uma semântica diferente

:- op(1050,xfy,->).

Cond -> Then :- Cond,!,Then

isso nao é 100% certo - ha uma discussão sutil em https://www.swi-prolog.org/pldoc/man?predicate=-%3E/2

Comandos tem uma versão mais forte que apenas avaliação não tradicional dos argumentos. Voce pode quere acesso as proprias expressoes dos parametros mas para isso expressoes precisam ser vistas como dados do programa - veremos isso em Lisp.

Difference lists

Lembre-se que o append em linguagens que tem lista como tipos predefinidos, demora O(n) onde n é o tamanho da 1a lista

Mesmo em C, voce precisa percorrer a lista para chegar ao ultimo apontador (que aponta para NULL) e troca-lo para apontar para a 2a lista.

Códigos iterativos ou recursivos que repetidamente chamam o append tem complexidade quadrática quando o problema poderia ser resolvido com complexidade linear.

reverte([],[]).
reverte([X|R],Y) :- reverte(R,RR), append(RR,[X],Y).

Diference list é a ideia de criar uma lista com uma variavel sem valor como ultimo elemento. Assim appendar a esta lista é setar essa variavel para a nova lista

d(L,X) = [1,2,3|X]

difappend(d(L1,R1), d(L2,R2), RESPOSTA) :- R1 = L2, 
                   RESPOSTA =d(L1,R2).
                   
difappend([1,2,3|R1], [4,5,6|R2, [1,2,3,4,5,6|R2])

normalmente usa-se o functor - infixo [1,2,3|R1] - R1 em vez de d

Constraint Logic Programming

https://en.wikipedia.org/wiki/Constraint_logic_programming

  1. is em prolog quebra as simetrias. Voce precisa ter o lado direito com todos os valores para calcular e unificar com o lado esquerdo

    X is Y + 2.

se Y=4 então eu atribuo X = 6

mas seria interessante se sabendo que X = 6, o programa pudesse inferir que Y deve assumir o valor 4.

Ou seja, seria bom se X is Y+2 fosse uma relação matemática/aritmética e não uma instrução de computação.

  1. Igualdade e desigualdade também são assimétricas

se X e Y não tem valor, X=Y indica que X e Y estão numa relação matemática, dado 1 eu consigo inferir (determinar) o outro.

Mas X \= Y nao é a mesma coisa. Isso só vai dar certo se ambos tiverem valor e esses valores não forem iguais.

CLP estende o Prolog para raciocinar sobre desigualdade e sobre “algumas” operações matemática.

https://www.swi-prolog.org/pldoc/man?section=clpb

CLP usado em verificação - listas as restriçoes e vefica que há alguma solução.

CLP em otimização (?)