980 likes | 1.17k Views
CLP – (Constraint Logic Programs) Programação Lógica com Restrições. Ruben Carlo Benante Doutorando em Ciência da Computação pelo CIn – UFPE, Recife-PE Mestre em Filosofia pela UNESP, Marília-SP Bacharel em Ciência da Computação pela UNESP, S.J.Rio Preto-SP rcb@cin.ufpe.br Disciplina de MCI
E N D
CLP – (Constraint Logic Programs)Programação Lógica com Restrições • Ruben Carlo Benante • Doutorando em Ciência da Computação peloCIn – UFPE, Recife-PE • Mestre em Filosofia pela UNESP, Marília-SP • Bacharel em Ciência da Computação pela UNESP, S.J.Rio Preto-SP • rcb@cin.ufpe.br • Disciplina de MCI • Prof. Jacques Robin • Baseado nas transparências disponibilizadas na internet por Marriott & Stuckey
Capítulo 4: Programação Lógica com Restrições • Restrições Definidas pelo Usuário • Programando com Regras • Avaliação • Árvores de Derivação e Falhas Finitas • Avaliação de Objetivos • Árvores de Derivação Simplificadas • O esquema CLP
Capítulo 5: Modelos Simples • Modelando • Modelando Escolhas • Otimização
Capítulo 7: Controle de Busca • Estimando a eficiência de um programa CLP • Ordenando as Regras • Ordenando os Literais • Adicionando Restrições Redundantes • Minimização
Capítulo 8: Modelos com Domínios Finitos • Domínios e Rótulos • Restrições Complexas • Rotulando (Labelling) • Modelando Problemas Diferentes
Capítulo 4: Restrições Definidas pelo Usuário (RDU) • Muitos exemplos de modelagem podem ser particionados em duas partes: • Uma descrição geral do objeto ou processo • Uma informação específica sobre uma situação real • O programador deve ser capaz de definir suas próprias restrições específicas ao problema • As Regras permitem isso
Regras Uma RDU para definir o modelo de circuito elétrico: parallel_resistors(V,I,R1,R2) E uma regra definindo-a: parallel_resistors(V,I,R1,R2) :- V = I1 * R1, V = I2 * R2, I1 + I2 = I.
Usando Regras parallel_resistors(V,I,R1,R2) :- V = I1 * R1, V = I2 * R2, I1 + I2 = I. Comportamento com resistores de 10 e 5 Ohms Comportamento com bateria de 10V, com resistores iguais Isso representa a restrição: (substituição macro)
Restrições Definidas pelo Usuário (RDU) • RDU: p(t1,...,tn) onde p é um predicadon-ário e t1,...,tn são expressões • literal: uma restrição primária ou RDU • objetivo (goal): uma seqüência de literais L1,...,Lm • regra: A :- B onde A é RDU e B é um objetivo • programa: uma seqüência de regras
Renomeação (Renamings) • Uma renomeaçãor é um mapa bijetivo de variáveis em variáveis • Um objeto sintático é uma restrição, um RDU, um objetivo ou uma regra • Aplicar uma renomeação em um objeto sintático nos dá um objeto com cada variável x substituída por r(x) • varianteo’ de um objeto o tem sua renomeação como r(o’)=o • Não é substituição de macros
Reescrita de RDU • objetivo G da forma (ou vazio m=0 []) • L1, ..., Li-1, Li, Li+1, ..., Lm • Li é da forma p(t1,...,tn) • R é da forma p(s1,...,sn) :- B • r é a renomeação das variáveis em r(R) e não em G • A reescrita de G com Li por R usando a renomeação r é • L1,...,Li-1,t1=r(s1),...,tn=r(sn),r(B),Li+1,...,Lm
Programando com Regras Considere a função fatorial. Como poderemos escrever regras para o predicado fac(N,F) onde(F = N!) ? (R1) fac(0,1). (R2) fac(N,N*F) :- N >= 1, fac(N-1, F). Note que a definição é recursiva (em termos dela mesma) e imita a definição matemática
Programando com Regras (R1)fac(0,1). (R2)fac(N,N*F) :- N >= 1, fac(N-1, F). Reescrevendo o objetivo fac(2,X) (i.e. o que é 2!) Simplificado na variável X, a resposta é X = 2
Avaliação (Evaluation) • Em cada passo da reescrita, deveremos checar se a conjunção de restrições primitivas pode ser satisfeita • A derivação faz isso • Em cada passo, os literais… • Restrição primitiva: são adicionados ao lado direito (das restrições) • RDU: são reescritos
Avaliação • estado: <G1| C1> ondeG1 é um objetivo e C1 é uma restrição • Passo de derivação: G1 é L1, L2, ..., Lm • L1 é uma restrição primitiva, C2 is C1 /\ L1 • Se solv(C /\ L1) = falseentãoG2 = [] • SenãoG2 = L2, ..., Lm • L1 é uma RDU, C2 é C1 e G2 é a reescrita de G1 com L1 usando alguma regra e a renomeação
Avaliação • derivação de <G0 | C0>: • Onde cada <Gi | Ci> até <Gi+1 | Ci+1> é um passo de derivação • derivação de G é a derivação do estado <G | true>
Derivação de fac(1,Y) Resposta simplificada em Y é Y = 1
Derivações • Para a derivação iniciando em <G0 | C0> • Estado de sucesso:<[] | C> onde solv(C) != false • Derivação de sucesso: o último estado é de sucesso • resposta: simpl(C, vars(<G0 | C0>)) • Estado de falha:<[] | C> onde solv(C) = false • Derivação falha: o último estado é de falha
Árvores de derivação • Árvore de derivação para o objetivo G • Raíz é < G | true > • Os filhos de cada estado são estados alcançáveis em um passo de derivação • Codifica todas as possíveis derivações • Quando o literal mais à esquerda é uma restrição primitiva, somente há um filho • Caso contrário, os filhos estão ordenados conforme a ordem das regras
Exemplo de Árvores de Derivação Derivação falhou Derivação falhou resposta: Y = 1
Árvore de Derivação • O exemplo anterior mostrou três derivações, 2 falharam e uma foi bem sucedida • Falha finita: Se a árvore de derivação é finita e todas as derivações falham • Árvore de Derivação Infinita: algumas derivações são infinitas
Exemplo de árvore de derivação infinita (S1)stupid(X) :- stupid(X). (S2)stupid(1). Resposta: X=1 Resposta: X=1 Derivação Infinita
Avaliação de Objetivos • A Avaliação de um objetivo realiza uma busca em profundidade, e na direção da esquerda para a direita • Quando encontra um estado de sucesso, o sistema retorna a resposta • O usuário pode perguntar por outras respostas, o que faz a busca continuar • A execução pára quando o usuário não pede mais respostas ou a árvore inteira é explorada • A execução entra em laço infinito se a árvore é infinita e não apresenta resposta
Árvores de Derivação Simplificadas • As árvores de derivação são muito grandes • Uma forma simplificada tem a informação considerada mais útil • Restrições na forma simplificada (variáveis na forma do objetivo inicial, e como parte dos estados do objetivo) • Remoção de estados sem interesse
Estados Simplificados • Estado simplificado: <G0 | C0> na derivação de G • substitua C0 por C1=simpl(C0, vars(G,G0)) • se x=t em C1 substitua x por t em G0 levando à G1 • substitua C1 por C2=simpl(C1, vars(G,G1)) • Exemplo
Derivação Simplificada • Um estado é critico se ele é o primeiro ou o último estado de uma derivação, ou se o primeiro literal é uma RDU • Uma derivação simplificada para o objetivo G contém todos os estados críticos na forma simplificada • Similarmente para uma árvore de derivação simplificada
Exemplo de Árvore Simplificada Nota: estados de falha são <[] | false> e estados de sucesso contém as respostas
O Esquema CLP • O esquema define uma família de linguagens de programação • Uma linguagem CLP(X) é definida por • Domínio de restrição X • Resolvedor para o domínio de restrição X • Simplificador para o domínio de restrição X • Nos exemplos usamos CLP(Real) • Outro exemplo seria o CLP(Tree)
CLP(R) • Os elementos são árvores contendo constantes reais • Restrições são para árvores • e para aritimética
Capítulo 5: Modelando • Escolha as variáveis que serão usadas para representar os parâmetros do problema (isto pode ser trivial ou difícil) • Modele as relações idealizadas entre estas variáveis usando as restrições primitivas disponíveis no domínio
Exemplo de Modelagem Uma viajante deseja atravessar o rio infestado de tubarões tão rápido quanto possível. A rota mais rápida é atravessar o rio nadando em linha reta, deixando que a correnteza faça a parte dela livremente. Ela deseja saber onde (P) ela vai parar após essa tarefa? Largura do rio: W Velocidade do rio: S Posição da nadadora: P Velocidade da nadadora: R R P S W
Exemplo de Modelagem Raciocínio: enquanto a nadadora atravessa o rio na sua largura, gastando um tempo T, ela segue junto com a correnteza para o rio abaixo uma distância P dada pela velocidade do rio, com o mesmo tempo T. Daí o modelo: river(W, S, R, P) :- T = W/R, P = S*T. Supondo que ela nade a R=1.5m/s, a velocidade do rio é de S=1m/s e seu comprimento é de W=24m. river(24, 1, 1.5, P). A única resposta é P = 16 Largura do rio: W Velocidade do rio: S Posição da nadadora: P Velocidade da nadadora: R
Exemplo de Modelagem (cont.) Se ela nada numa velocidade entre 1 e 1.3 m/s e não pode se afastar mais que 20m do ponto de origem, será que ela conseguirá? 1 <= R, R <= 1.3, P <= 20, river(24,1,R,P). Esta é a flexibilidade do modelo baseado em restrições!
Escolhas mais complicadas • Uma opção de “call” dá ao seu portador o direito de comprar 100 ações a um preço de exercício E fixo • Uma opção de “put” dá ao seu portador o direito de vender 100 ações a um preço de exercício E fixo • O pagamento (lucro ou prejuízo) de uma opção é determinado por seu custo C e pelo preço corrente da ação S • e.g. custo do call C=$200, Exercício E=$300 • Preço do mercado = $2, não utiliza o call: • pagamento = -$200 • Preço do mercado = $9, utiliza o call: • pagamento = $400
Opções de Mercado call C=200, E = 300 put C=100, E = 300 Operação Borboleta: Compre um “call” por C=100 com E=500 e outro por C=400 com E=100. Venda dois “calls” por C=200, com E=300
Opções de Mercado PG= S – E – C (para compra de “call”)PG = E + C – S (para venda de “call”) (C=100,E=500, compra) PG1 = 100S – 600 p/ S>5PG1 = – 100 p/ S<=5 (C=400,E=100, compra) PG2 = 100S – 500 p/ S>1PG2 = – 100 p/ S<=100 (C=200,E=300, venda)PG3 = – S100 + 500 p/ S>3PG3 = 200 p/ S<=3 Operação Borboleta: Compre um “call” por C=100 com E=500 e outro por C=400 com E=100. Venda dois “calls” por C=200, com E=300 Aplicadas as restrições temos:PG = PG1 + PG2 + 2PG3PG = – 100 p/ s>5PG = – 100 p/ s<1PG = 100S – 200 P/ 1<S<3PG = –100S + 400 p/ 3<S<5
Modelando Funções Modelar uma função com n argumentos como um predicado com n+1 argumentos. Os testes são restrições, e o resultado é uma equação. buy_call_payoff(S,C,E,P) :- 0 <= S, S <= E/100, P = -C. buy_call_payoff(S,C,E,P) :- S >= E/100, P = 100*S - E - C.
Modelando Opções Acrescente um argumento extraB=1 (compra), B = -1 (venda) call_option(B,S,C,E,P) :- 0 <= S, S <= E/100, P = -C * B. call_option(B,S,C,E,P) :- S >= E/100, P = (100*S - E - C)*B. O objetivo é dado por: call_option(1, 7, 200, 300, P) E a resposta é P = 200
Usando o Modelo butterfly(S, P1 + P2 + 2*P3) :- Buy = 1, Sell = -1, call_option(Buy, S, 100, 500, P1), call_option(Buy, S, 400, 100, P2), call_option(Sell, S, 200, 300, P3). Define a curva dada no gráfico anterior, para lucros: P >= 0, butterfly(S,P). Tem duas respostas:
Por quê restrições e não Linguagem C? • Ambos os programas podem responder o objetivo • call_option(1, 7, 200, 300, P). • Mas o CLP pode responder, sem muito esforço, o objetivo: • butterfly(3, P1 + P2 + 2*P3). P = 100 • E até mesmo o objetivo: • P >= 0, butterfly(S,P). P = 100S – 200 /\ 2<=S /\ S<=3 P = -100S + 400 /\ 3<=S /\ s<=4
Otimização • Muitos problemas requerem a “melhor” solução • Literal de minimização: minimize(G,E) • Responde as questões sobre o objetivo G que minimiza a expressão E (no contexto do estado)
Exemplos de Otimização p(X,Y) := X = 1. p(X,Y) :- Y = 1. X >= 0, Y >= 0, minimize(p(X,Y), X+Y) Respostas: X = 1 /\ Y = 0 e X = 0 /\ Y = 1 X >= 0, X >= Y, minimize(true, X-Y) Resposta: X >= 0 /\ X = Y minimize(butterfly(S,P), -P) Resposta: S = 3 /\ P = 100
Avaliação de Otimização • Um valor de v é uma solução para um estado se é alguma das soluções deste estado • Passo da derivação de uma minimização: <G1 | C1> para <G2 | C2> onde G1 = L1,L2,...,Lm, e L1 é “minimize(G,E)” • existe uma solução v de <G | C1> com v(E) = m e para todas as outras soluções w temos que m <= w(E) • Então G2 é G,L2,...,Lm e C2 é C1 /\ E = m • Senão G2 é [] e C2 é falso
Exemplo de Otimização X>=0, Y<=X, m=min(X-Y) m=X-Y Tomemos X=0, o menor X m=-Y Mas Y<=X Y<=0 -Y>=0 Tomemos –Y=0, o menor Y m=0-0 m=0 X-Y=0 X >= 0, minimize(X >= Y, X-Y) Valor mínimo de X-Y é 0 e.g. Simplificado:
Otimização A otimização não precisa necessariamente ser um objetivo: straddle(S,C1+C2,E,P1+P2) :- Buy = 1, call_option(Buy, S, C1, E, P1), put_option(Buy, S, C2, E, P2). best_straddle(C,E,P) :- minimize(straddle(S,C,E,P),-P).
Capítulo 7: Estimando Eficiência • Avaliação é a busca na árvore de derivação • O tamanho e a forma da árvore de derivação determinam a eficiência (ignorando o custo da solução) • Quanto menor: menos busca • Respostas do lado esquerdo da árvore:menos busca antes de achar a primeira resposta • A árvore de derivação depende do modo de uso (MU)
Modo de Uso (MU) • modo de uso (MU): define os tipos de restrições nos argumentos de um predicado quando avaliado • fixo: o conjunto de restrições implica em um único valor para todas as soluções • livre: o conjunto de restrições permite todos os valores • outros: limitado superiormente, limitado inferiormente
Exemplo de Modo de Uso sumlist([], 0). sumlist([N|L], N+S) :- sumlist(L, S). • MU primeiro arg fixo segundo livre • sumlist([1],S). • L=[1,2],S > Z, sumlist(L,S). • Estados na árvore de derivação com a chamada de sumlist <sumlist([1], S)|true> <sumlist(L’,S’)|[1]=[N’|L’]/\S=N’+S’> <sumlist(L’’,S’’)|[]=[N’’|L’’]/\S’=N’’+S’’> <N’’=0,S’’=0|/\S’=N’’+S’’>
Exemplo de Controle de Busca • Pense em escrever um programa para computar: • Raciocíne recursivamente: • A soma de N números é a soma de (N-1) + N • A soma de 0 números é 0 • Problema: sum(1,S) não tem resposta (S1) sum(N, S+N) :- sum(N-1, S). (S2) sum(0, 0).
Exemplo de Controle de Busca Árvore de derivação simplificada para sum(1,S). Note que é infinita no ramo à esquerda, pois N assumiu valores negativos.