Capítulo 3 Lógica de Primeira Ordem Lógica para Programação LEIC - Tagus Park 1 o Semestre, Ano Lectivo 2007/08 c Inês Lynce and Luísa Coheur
Bibliografia Baseados nos slides de Andrew Rice, Universidade de Cambridge, 2007. Martins J.P., Prolog, Capítulo 5. Ben-Ari M., Mathematical Logic for Computer Science, Springer-Verlag, 2003, Capítulo 8.
Programa de festas Exemplos e mais exemplos... Puzzle da zebra Permutação de listas 8 rainhas ordenada insertion sort Torres de Hanoi Missionários e canibais
Puzzle da zebra (atribuído a Einstein) 5 casas, 5 nacionalidades, 5 marcas de cigarro, 5 bebidas, 5 animais de estimação (todos diferentes) 1. O Inglês vive numa casa vermelha. 2. O Espanhol é dono de um cão. 3. Na casa verde bebe-se café. 4. O Ucraniano bebe chá. 5. A casa verde está imediatamente à direita da casa branca. 6. A pessoa que fuma Old Gold é dona de uma cobra. 7. Na casa amarela fuma-se Kools. 8. Na casa do meio bebe-se leite. 9. O Norueguês vive na primeira casa. 10. A pessoa que fuma Chesterfields vive na casa ao lado da casa onde vive uma raposa. 11. Os cigarros Kools são fumados na casa ao lado da casa onde vive um cavalo. 12. O fumador de Lucky Strike bebe sumo de laranja. 13. O Japonês fuma Parliaments. 14. O Norueguês vive junto à casa azul.
Puzzle da zebra (cont.) Objectivos Onde é que a zebra vive? Em que casa é que se bebe água? Para já vamos considerar apenas a existência de factos e objectivos
Puzzle da zebra: modelação Representação de cada casa house(nationality,pet,smokes,drinks,colour) Representação da fila de casas (designada Houses) (H1,H2,H3,H4,H5)
Puzzle da zebra: código O Inglês vive numa casa vermelha. exists(house(english,,,,red),houses) exists(a,(a,,,, )). exists(a,(,a,,, )). exists(a,(,,a,, )). exists(a,(,,,a, )). exists(a,(,,,,a)). exists(a,,,, ) é satisfeito se a casa A unifica com a primeira casa
Puzzle da zebra: código (cont.) A casa verde está imediatamente à direita da casa branca. rightof(house(,,,,green),house(,,,,ivory),houses) rightof(a,b,(b,a,,, )). rightof(a,b,(,b,a,, )). rightof(a,b,(,,b,a, )). rightof(a,b,(,,,b,a)).
Puzzle da zebra: código (cont.) Na casa do meio bebe-se leite. middlehouse(house(,,,milk, ),Houses) middlehouse(a,(,,a,, )). O Norueguês vive na primeira casa. firsthouse(house(norwegian,,,, ),Houses) firsthouse(a,(a,,,, )).
Puzzle da zebra: código (cont.) A pessoa que fuma Chesterfields vive na casa ao lado da casa onde vive uma raposa. nextto(house(,,chesterfields,, ), house(,fox,,, ),Houses) nextto(a,b,(a,b,,, )). nextto(a,b,(,a,b,, )). nextto(a,b,(,,a,b, )). nextto(a,b,(,,,a,b)). nextto(a,b,(b,a,,, )). nextto(a,b,(,b,a,, )). nextto(a,b,(,,b,a, )). nextto(a,b,(,,,b,a)).
Puzzle da zebra: código - objectivo :- exists(house(english,,,,red),houses), exists(house(spanish,dog,,, ),Houses), exists(house(,,,coffee,green),houses), exists(house(ukranian,,,tea, ),Houses), rightof(house(,,,,green),house(,,,,ivory),houses), exists(house(,snail,oldgold,, ),Houses), exists(house(,,kools,,yellow),houses), middlehouse(house(,,,milk, ),Houses), firsthouse(house(norwegian,,,, ),Houses), nextto(house(,,chesterfields,, ),house(,fox,,, ),Houses), nextto(house(,,kools,, ),house(,horse,,, ),Houses), exists(house(,,luckystrike,orangejuice, ),Houses), exists(house(japanese,,parliaments,, ),Houses), nextto(house(norwegian,,,, ),house(,,,,blue),houses), exists(house(waterdrinker,,,water, ),Houses), exists(house(zebraowner,zebra,,, ),Houses), write( WaterDrinker = ), write(waterdrinker), nl, write( ZebraOwner = ), write(zebraowner),nl, write(houses).
Puzzle da zebra: execução
Puzzle da zebra com LISTAS e REGRAS Houses passa a ser uma lista com 5 elementos do tipo house houses([house(,,,, ), house(,,,, ), house(,,,, ), house(,,,, ), house(,,,, )]). Acrescentar ao objectivo houses(house)
Puzzle da zebra com LISTAS e REGRAS (cont.) Regras para exists, rightof e nextto exists(x,[x ]). exists(x,[ Y]) :- exists(x,y). rightof(a,b,[b,a ]). rightof(a,b,[ Y]) :- rightof(a,b,y). nextto(a,b,[a,b ]). nextto(a,b,[b,a ]). nextto(a,b,[ Y]) :- nextto(a,b,y).
Remoção de um elemento de uma lista (relembrar) remove(cabeca,[cabeca Cauda],Cauda). remove(x,[cabeca Cauda1],[Cabeca Cauda2]) :- remove(x,cauda1,cauda2).
Permutação de listas perm([],[]). perm(lst,[cabeca Cauda]) :- remove(cabeca,lst,res),perm(res,cauda).
Permutação de listas: exemplo
Permutação de listas: aplicação Agora podemos usar este predicado para ajudar a resolver o problema das 8 rainhas.
Resolução de problemas por geração&teste Metodologia usada na resolução do problema das 8 rainhas 1. Gerar uma potencial solução com o predicado perm 2. Verificar se a solução é válida 3. Se não for válida retroceder para encontrar a potencial solução seguinte
Problema das 8 rainhas [5,3,1,7,2,8,6,4]
Problema das 8 rainhas - código oito-rainhas(res) :- perm([1,2,3,4,5,6,7,8],res), diagonaisok(res).
Problema das 8 rainhas - código (cont.) diagonaisok([ ]). diagonaisok([rainha OutrasRainhas]) :- posicaook(rainha,1,outrasrainhas), diagonaisok(outrasrainhas). posicaook(,,[]). posicaook(col,distlinha,[rainha OutrasRainhas]) :- DiagKO1 is Col + DistLinha, Rainha =\= DiagKO1, DiagKO2 is Col - DistLinha, Rainha =\= DiagKO2, DistLinha1 is DistLinha + 1, posicaook(col,distlinha1,outrasrainhas).
Ordenação: predicado ordenada ordenada([]). ordenada([ ]). ordenada([x,y Ys]) :- X=<Y, ordenada([y Ys]).
Ordenação por geração e teste ordena(xs,ys) :- perm(xs,ys), ordenada(ys).
Ordenação: insertion sort Um elemento (tipicamente o primeiro) é removido da lista O resto da lista é ordenada recursivamente O elemento removido é inserido de uma forma ordenada
Ordenação: predicado insert insert(x,[],[x]). insert(x,[y Ys],[Y Zs]) :- X > Y,!, insert(x,ys,zs). insert(x,[y Ys],[X,Y Ys]) :- X =< Y.
Ordenação: insertion sort insertion-sort([x Xs],Ys) :- insertion-sort(xs,zs),!, insert(x,zs,ys). insertion-sort([],[]).