outros aspectos da linguagem prolog

7
Outros aspectos da linguagem Prolog ogica Computacional – 2 o ano LCC 2011/2012 1 Utiliza¸ ao de cut e nega¸c˜aoporfalha 1.1 Predicado cut O predicado pr´ e-definido cut (!) permite eliminar ramos nas ´arvores de deriva¸c˜ ao de predicados Prolog. Operacionalmente, o cut pode ser caracterizado da seguinte forma: Durante o processo de prova, a primeira passagem pelo cut ´ e sempre verdadeira (com sucesso). Se por backtracking se voltar ao cut, ent˜ ao o cut faz falhar o predicado que est´ a na cabe¸ca da regra. Autiliza¸c˜ ao do cut est´ a normalmente associada a quest˜oes de eficiˆ encia: os ramos da ´ arvore que s˜ ao eliminados acabariam eventualmente por falhar, e assim poupamos trabalho ao motor de inferˆ encia do Prolog. Estautiliza¸c˜ ao do cut ´ e considerada benigna (tamb´ em designados como green cut ), porque n˜ao se afecta o significado l´ogico dos predicados. Tomemos como exemplo um predicado que verifique se o terceiro argumento ´ eom´ ınimo dos dois primeiros. Poder´ ıa ser definido como: minimo(X,Y,Y) :- X >= Y. minimo(X,Y,X) :- X < Y. Mas podemos facilmente observar que, uma vez verificado que X>=Y, n˜ao faz sentido tentar verificar que X<Y. Assim sendo, faz sentido colocar um cut no final da primeira cl´ ausula: minimo(X,Y,Y) :- X >= Y, !. minimo(X,Y,X) :- X < Y. O cut pode ser melhor compreendido quando verificamos o seu impacto na cons- tru¸c˜ ao da ´ arvore de inferˆ encia para um dado objectivo. Considere-se ent˜ ao o objectivo minimo(8,3,X): 1

Upload: melanie-stevenson

Post on 24-Nov-2015

28 views

Category:

Documents


7 download

TRANSCRIPT

  • Outros aspectos da linguagem Prolog

    Logica Computacional 2o ano LCC

    2011/2012

    1 Utilizacao de cut e negacao por falha

    1.1 Predicado cut

    O predicado pre-definido cut (!) permite eliminar ramos nas arvores de derivacao depredicados Prolog. Operacionalmente, o cut pode ser caracterizado da seguinte forma:

    Durante o processo de prova, a primeira passagem pelo cut e sempre verdadeira (comsucesso).

    Se por backtracking se voltar ao cut, entao o cut faz falhar o predicado que esta nacabeca da regra.

    A utilizacao do cut esta normalmente associada a questoes de eficiencia: os ramos da arvoreque sao eliminados acabariam eventualmente por falhar, e assim poupamos trabalho aomotor de inferencia do Prolog. Esta utilizacao do cut e considerada benigna (tambemdesignados como green cut), porque nao se afecta o significado logico dos predicados.Tomemos como exemplo um predicado que verifique se o terceiro argumento e o mnimodos dois primeiros. Podera ser definido como:

    minimo(X,Y,Y) :- X >= Y.

    minimo(X,Y,X) :- X < Y.

    Mas podemos facilmente observar que, uma vez verificado que X>=Y, nao faz sentido tentarverificar que X= Y, !.

    minimo(X,Y,X) :- X < Y.

    O cut pode ser melhor compreendido quando verificamos o seu impacto na cons-trucao da arvore de inferencia para um dado objectivo. Considere-se entao o objectivominimo(8,3,X):

    1

  • minimo(8,3,X)

    8 >= 3, !

    !

    true [X = 3]

    X = 3 /

    A construcao da arvore segue o procedimento normal ate ser tratado o predicado cut(sinalizado com o nodo vermelho). Esse predicado sucede sempre, mas como efeito lateralfaz com que o backtracking sobre o no que esteve na origem desse cut seja bloqueado (nocaso, o no da raiz sinalizado com a cor laranja). Na arvore, esse bloqueio esta representadocom um arco riscado com origem nesse no, e que nos recordara que nao devemos procurarnovas alternativas quando se estiver a realizar o backtracking. A construcao da arvoresegue depois o seu curso normal: como se esgotam os objectivos apresenta-se a solucaoencontrada (X = 3), e essa sera a unica solucao porque por backtracking nao se encontramalternativas a ser testadas (o unico no que dispunha de alternativas foi bloqueado pelocut).

    Neste exemplo poderamos perguntar se nao seria tambem correcto eliminar o predicadoX= Y falhar, e nesse casoe verdade que X= Y, !, Y=Z.

    minimo(X,Y,X).

    E importante referir que, neste ultimo caso, a utilizacao do cut altera propositadamenteo comportamento do programa. Essas utilizacoes do cut sao normalmente consideradasmais perigosas(designadas por red cuts) porque obrigam a que o programador detenhauma ideia muito precisa sobre o processo de construcao da derivacao por parte do Prolog.Outras situacoes onde e tpica a utilizacao de red cuts e para impedir que a execucao doprograma entre em ciclo, ou excluir solucoes indesejaveis.

    Exerccio 1 Defina um predicado prep(-X,+L) que verifique se o elemento X e o primeiro

    2

  • elemento que ocorre repetido numa lista L (e.g. prep(3,[1,3,5,3,5[) devera retornarverdadeiro, e prep(5,[1,3,5,3,5]) falso.

    Exerccio 2 Considere a seguinte base de conhecimento:

    q(0,X,Y) :- p(X), !, p(Y).

    q(_,X,b) :- p(X).

    q(_,c,Y) :- p(Y), !.

    p(a). p(b).

    1. Quais sao as solucoes admissveis para os objectivos q(1,X,Y) e q(0,X,Y)?

    2. Apresente as arvores de derivacao correspondentes aos objectivos da alnea anterior.

    3. Considere o seguinte programa que pretende inserir o primeiro argumento (um numero)na lista ordenada passada no segundo argumento.

    insert(X,[H|T],[H|T1]) :- X>H, !, insert(X,T,T1).

    insert(X,L,[X|L]).

    Mostre, avaliando um objectivo apropriado, que o programa esta incorrecto. Como opodera corrigir?

    1.2 Negacao por falha

    Por vezes pretende-se garantir que um dado predicado nao e valido. A utilizacao do cut(em conjuncao com o predicado pre-definido fail que falha sempre) permite codificar umaforma restrita de negacao: a negacao por falha. Considere o seguinte predicado:

    neg(X) :- X, !, fail.

    neg(X).

    Note que neg(X) falha sempre que o Prolog consiga construir uma derivacao para X. Poroutro lado, sucede se falhar na construcao dessa derivacao (entra na segunda clausula, quee trivialmente satisfeita).

    Obs.: o predicado pre-definido do Prolog \+ corresponde ao predicado neg apresen-tado.

    Exerccio 3

    Verifique o resultado de neg em alguns dos predicados definidos nesta ficha.

    Considere o seguinte programa:

    estudante(paulo).

    casado(joao).

    estudanteSolteiro(X) :- \+ casado(X), estudante(X).

    Como explica a resposta a`s questoes estudanteSolteiro(paulo) e estudanteSolteiro(X)?

    3

  • 1.3 Tracing e Debug

    Uma forma expedita de detectar problemas em programas Prolog consiste em utilizaro mecanismo de tracing. Esse mecanismo permite monitorizardeterminados predicadosdurante o processo de inferencia. Considere-se o objectivo member(X,[1,2]), X mod 2=:= 0:

    ?- trace(member).

    % member/2: [call, redo, exit, fail]

    true.

    [debug] ?- member(X,[1,2]), X mod 2 =:= 0.

    T Call: (8) member(_G318, [1, 2])

    T Exit: (8) member(1, [1, 2])

    T Redo: (8) member(_G318, [1, 2])

    T Call: (9) member(_G318, [2])

    T Exit: (9) member(2, [2])

    T Exit: (8) member(2, [1, 2])

    X = 2 ;

    T Redo: (9) member(_G318, [2])

    T Call: (10) member(_G318, [])

    T Fail: (10) member(_G318, [])

    fail.

    Note que o Prolog sinalizada diferentes eventos relativos ao predicado observado:

    Call: o predicado em resolucao;

    Exit: o predicado foi resolvido com sucesso (pode por isso ser removido da lista de objec-tivos);

    Redo: nova visita ao predicado (por backtracking);

    Fail: predicado falha definitivamente (ja nao existem mais alternativas para o backtrac-king).

    Exerccio 4 Interprete o resultado do trace apresentado na respectiva arvore de inferencia.Realize o trace para uma das restantes arvores construdas nesta ficha.

    2 Estrategia Gerar e Testar

    O mecanismo de backtracking do Prolog torna possvel codificar, de forma directa, aestrategia de gerar e testar para encontrar a solucao de um determinado problema. Segundoesta estrategia, o problema e decomposto em duas fases:

    1. Gera-se solucoes cadidataspara o problema.

    4

  • 2. Verifica-se se a solucao candidatasatisfaz os requisitos do problema (e e, portanto,uma solucao efectiva).

    Podemos assim identificar o padrao com a seguinte regra Prolog:

    resolve(X) :- gera(X), testa(X).

    Note-se o papel preponderante do backtracking para encontrar uma dada solucao pararesolve(X): o predicado gera(X) instancia X com uma possvel solucao. No caso detesta(X) falhar (a solucao proposta nao satisfaz os requisitos impostos pelo problema), omecanismo de backtracking permite que gera(X) instancie uma nova alternativa, ate quese encontre a solucao pretendida.

    O predicado gera acaba normalmente por se revelar o ponto crtico na aplicacao destaestrategia: por um lado, pretende-se que ele cubra todas as possveis solucoes para oproblema (caso contrario, podemos nunca gerar a solucao requerida). Por outro, e porquestoes de eficiencia, vamos pretender que ele produza o mnimo de solucoes erradas(para minimizar o espaco de busca) na pratica, este esforco de minimizacao traduz-sepor eliminar candidatos notoriamente errados e por encontrar codificacoes apropriadas paraas possveis solucoes.

    Vejamos um exemplo concreto: pretende-se encontrar um divisor para um dado numeroN (diferente de 1 e N).

    fromToL(L,U,[]) :- U < L, !.

    fromToL(L,U,[L|X]) :- L1 is L+1, fromToL(L1,U,X).

    gera(N,X) :- fromToL(2,N-1,L), member(X,L).

    testa(N,X) :- N mod X =:= 0.

    divisor(N,X) :- gera(N,X), testa(N,X).

    Mas o programa apresentado pode ser consideravelmente optimizado se observarmosque nos e suficiente encontrar um divisor entre 2 e sqrt(N) (se X>sqrt(N) e um divisor deN, entao tambem sera N/XN .

    Exerccio 7 Uma forma simples de descrever um algoritmo de ordenacao e encontraruma permutacao da lista dada que esteja ordenada. Essa descricao pode ser directa-mente codificada em Prolog usando a estrategia generate-and-test. Codifique o predicadoslowSort/2 que implemente essa estrategia. (obs: utilize para o efeito os predicados rele-vantes definidos na Ficha I)

    5

  • 2.1 Problema das n-rainhas

    Um exemplo classico de programacao em Prolog consiste em escrever um predicado quepermita resolver o problema das n rainhas. Esse problema consiste em dispor n rainas numtabuleiro de damas com dimensao n n, sem que qualquer rainha se encontre ameacadapor outra. Como um exemplo de uma solucao temos (num tabuleiro 4 4):

    -----------------

    | | | Q | |

    -----------------

    | Q | | | |

    -----------------

    | | | | Q |

    -----------------

    | | Q | | |

    -----------------

    Note que cada linha e cada coluna deve conter uma, e so uma, rainha (porque?). Ditoisto, verificamos que uma forma expedita de representar as solucoes para este problemaconsiste em utilizar uma lista que informe qual a coluna em que e colocada a rainha de cadauma das linhas (a solucao do exemplo seria [3,1,4,2], querendo dizer que a rainha daprimeira linha aparece na terceira coluna, a da segunda linha na primeira coluna, etc.) desta forma, aparece uma rainha em cada linha por construcao. A restricao de apareceruma unica rainha por cada coluna e traduzida por deverem aparecer na lista todos osnumeros de 1 a 4, ou seja, a lista deve ser uma permutacao de [1,2,3,4]. Temos assimresolvido o sub-problema de gerar solucoes candidatas: sao simplesmente permutacoes dalista [1..N].

    Na fase de teste, falta unicamente verificar que nenhuma rainha esta no alcance dadiagonal de uma outra. Para isso notamos que:

    Duas rainhas estao numa diagonal / se e so se a soma da linha e coluna da posicaode cada uma delas for igual;

    Duas rainhas estao numa diagonal \ se e so se a diferenca da linha e coluna da posicaode cada uma delas for igual.

    Exerccio 8 Com base no que foi referido, codifique um predicado nrainhas(+N,?X) quedetermine uma solucao para o problema das N-rainhas.

    3 Predicados de Segunda Ordem e outros predicados

    primitivos disponibilizados pelo Prolog

    Predicados de segunda ordem Existem meta-predicados que permitem coleccionar todas assolucoes para um dado objectivo de prova (ver Users Manual ou o help).

    6

  • findall(?Template,:Goal,?Bag): Bag e a lista de instancias de Template encon-tradas nas provas de Goal. A ordem da lista corresponde a` ordem em que saoencontradas as respostas. Se nao existirem instanciacoes para Template, Bag unificacom a lista vazia.

    bagof(?Template,:Goal,?Bag): Semelhante a findall, mas se Goal falhar, bagoffalha.

    setof(?Template,:Goal,?Set): Semelhante a bagof, mas a lista e ordenada e semrepeticoes.

    Exemplo:

    | ?- findall(X, member(X,[1,2,3]), L).

    L = [1,2,3]

    yes

    Relacionados com os apresentados, encontramos outros predicados de ordem superior,como o bem conhecido map (do Haskell). No Prolog o predicado maplist implementaa funcionalidade analoga.

    Exerccio 9 Teste os predicados apresentados codificando exemplos apropriados. Utilizeo predicado findall para determinar todas as solucoes para o problema das N rainhas comN=8.

    3.1 Outras caractersticas do Prolog

    Manipulacao da base de conhecimento: O Prolog permite manipular dinamicamentea base de conhecimento (inserir ou remover factos ou regras). Para isso disponibiliza ospredicados assert, retract, rectractall (e variantes...).

    Input/Output: tal como qualquer linguagem com o mnimo de preocupacoes praticas, epossvel realizar operacoes de Input/Output. Para o efeito dispoe-se dos predicados write,read (entre outros, e com muitas variantes...); open e close para maniputacao de ficheiros,etc...

    Exerccio 10

    1. Consulte a documentacao relativa aos predicados referidos e teste cada um deles comexemplos apropriados.

    2. Estenda o programa das N rainhas com um predicado runQueens que interrogueo utilizador sobre o numero de rainhas a considerar e imprima no ecran todas assolucoes admissveis.

    7

    Utilizao de cut e negao por falhaPredicado cutNegao por falhaTracing e Debug

    Estratgia Gerar e TestarProblema das n-rainhas

    Predicados de Segunda Ordem e outros predicados primitivos disponibilizados pelo PrologOutras caractersticas do Prolog