Tipo dos termos Predicados de sistema para tipos • integer( X ) X é um inteiro • atom( X ) X é um átomo • atomic( X ) X é um inteiro ou um átomo % aplana( Xs, Ys ) Ys é uma lista com os elementos de Xs (fechada) aplana( Xs, Ys ) aplana( Xs, [], Ys ). aplana( [X|Xs], S, Ys ) lista( X ), aplana( X, [Xs| S], Ys ). aplana( [X|Xs], S, [X|Ys] ) atomic( X ), X \=[], aplana( Xs, S, Ys ). aplana( [], [X|S], Ys ) aplana( X, S, Ys ). aplana( [], [], [] ). lista( [X|Xs] ). este programa aplana uma lista usando uma stack implementada como uma lista manipulada por unificação — a estrutura é construída top-down Prolog - 1 Estrutura dos termos Predicados de manipulação da estrutura • functor( Termo, Functor, Aridade ) o functor principal de Termo é Functor com aridade Aridade • arg( N, Termo, Arg ) Arg é o Nésimo argumento de Termo • Termo =.. Lista se a cabeça da lista contém o functor do termo e o resto da lista os seus argumentos Nota: estes predicados são bidireccionais; functor e univ (=..) também constroem Prolog - 2 Análise de subtermos % subtermo( Sub, Termo ) Sub é um subtermo do termo fechado Termo subtermo( Termo, Termo ). subtermo( Sub, Termo ) functor( Term, F, N ), N>0, subtermo( N, Sub, Termo ). subtermo( N, Sub, Termo ) N>1, N1 is N-1, subtermo( N1, Sub, Termo ). subtermo( N, Sub, Termo ) arg( N, Termo, Arg ), subtermo( Sub, Arg ). % subtermo( Sub, Termo ) Sub é um subtermo do termo fechado Termo subtermo( Termo, Termo ). subtermo( Sub, Termo ) Termo =.. [F|Args], subtermo_lista( Sub, Args ). subtermo_lista( Sub, [Arg|Args] ) subtermo( Sub, Arg ). subtermo_lista( Sub, [Arg|Args] ) subtermo_lista( Sub, Args ). Prolog - 3 Predicados meta-lógicos Predicados de tipo meta-lógicos • var( X ) X é uma variável • nonvar( X ) X não é uma variável • X == Y X e Y são o mesmo termo (a mesma variável, etc...) • X \== Y X e Y não são o mesmo termo soma( X, Y, Z ) nonvar( X ), nonvar( Y ), Z is X+Y. soma( X, Y, Z ) nonvar( X ), nonvar( Z ), Y is Z-X. soma( X, Y, Z ) nonvar( Y ), nonvar( Z ), X is Z-Y. Prolog - 4 Predicados meta-lógicos estes predicados são meta-lógicos porque referir-se ao nome de uma variável está fora da lógica de primeira ordem não se pode representar este predicado com uma tabela de todos os seus factos (são em número infinito) interesse: permitir implementar predicados bidireccionais à custa de predicados de sistema (unidireccionais) escolher a melhor ordem para os golos, conforme a instanciação dos argumentos (em especial para garantir o correcto funcionamento da negação e dos predicados de sistema) para evitar instanciações indesejadas nos predicados de análise de termos Prolog - 5 Termos fechados % fechado( Termo ) Termo está completamente instanciado fechado( Termo ) nonvar( Termo ), atomic( Termo ). fechado( Termo ) nonvar( Termo ), functor( Termo, F, N ), N>0, fechado( N, Termo ). fechado( N, Termo ) N>0, arg( N, Termo, Arg ), fechado( Arg ), N1 is N-1, fechado( N1, Termo ). fechado( 0, Termo ) Prolog - 6 Entrada/saída predicados extra-lógicos — produzem efeitos laterais, para além de sucederem, normalmente só uma vez, i.e. em retrocesso falham nível do termo read( X ) — lê um termo do canal de entrada (até um ponto final) e unifica-o com X, sucedendo ou falhando em conformidade write( X ) — escreve o termo X no canal de saída 'Isto é um átomo que inclui espaços' "Isto " é uma notação ao jeito das strings, equivalente à lista de inteiros [73, 115, 116, 111, 32] que contém os códigos ASCII dos caracteres na string name( X, Y ) — converte o nome de constante X para a cadeia de caracteres Y correspondente e vice-versa display( X ) — escreve o termo X em notação prefixa Prolog - 7 Entrada/saída nível do carácter put( N ) — coloca o carácter de código ASCII N no canal de saída get0( N ) — N é o código ASCII do carácter seguinte no canal de entrada get( N ) — N é o código ASCII do carácter não branco seguinte no canal de entrada caracter( C ) 97 =< C, C=< 122. caracter( C ) 65 =< C, C=< 90. caracter( 95 ). separador( 32 ). terminador( 46 ). % minúsculas % maiúsculas % underscore % espaço % ponto Prolog - 8 Lista de palavras le_lista_palavras( Ws ) get( C ), le_lista_palavras( C, Ws ). le_lista_palavras( C, [W | Ws] ) caracter( C ), le_palavra( C, W, C1 ), le_lista_palavras( C1, Ws ). le_lista_palavras( C, Ws ) separador( C ), get( C1 ), le_lista_palavras( C1, Ws ). le_lista_palavras( C, [] ) terminador( C ). le_palavra( C, W, C1 ) caracteres( C, Cs, C1 ), name( W, Cs ). caracteres( C, [C|Cs], C0 ) caracter( C ), !, get0( C1 ), caracteres( C1, Cs, C0 ). caracteres( C, [], C ) not caracter( C ). Prolog - 9 Ficheiros inicialmente, há um canal aberto para entrada e para saída chamado user e que está ligado ao terminal entrada see( F ) — abre um canal de leitura para o ficheiro F e torna-o corrente • se já estiver aberto, limita-se a pôr o canal como corrente • todas as leituras são do canal corrente seeing( F ) — F é unificado com o nome do ficheiro no canal de entrada corrente seen — fecha o canal de entrada corrente Prolog - 10 Ficheiros saída tell( F ) — semelhante a see( F ), mas para escrita • a linha de texto só é enviada para o canal quando ocorrer um fim de linha (nl) telling( F ) — como seeing( F ) told — fecha o canal de saída corrente Prolog - 11 Acesso ao programa listing, listing( Pred ) — escreve no écran as cláusulas do programa, ou só do predicado clause( Head, Body ) — percorre, em retrocesso, as cláusulas do programa que unificam com Head, o qual tem que estar instanciado assert( Clausula ) —adiciona a cláusula no fim da definição do respectivo predicado definição do predicado member/2 • assert( member( X, [X|Xs] ) ). • assert( (member( X, [Y|Xs] ) member( X, Xs )) ). asserta( Clausula ) — adiciona no princípio Prolog - 12 Acesso ao programa retract( Clausula ) — elimina a primeira cláusula que unifica com Clausula forma de copiar termos, criando variáveis novas • copy( X, Y ) assert( $tmp( X ) ), retract( $tmp( Y ) ). consult( F ) — lê o programa no ficheiro F, fazendo o assert das cláusulas e executando as directivas que encontrar ( G ) reconsult( F ) — semelhante a consult mas faz primeiro retract a todos os predicados para os quais vai fazer assert (substitui, em vez de adicionar) Prolog - 13 Funções de memorização pode-se usar a capacidade de manipular o programa para gravar resultados de computações parciais, para reutilização em fases subsequentes ideia geral: uma pilha de altura N passa-se para B passando a pilha de altura N-1 para o poste auxiliar C, o disco N para B e a pilha de C para B; esta segunda passagem é igual à primeira, a menos de instanciações, e pode ser resolvida pelo lema entretanto memorizado [efeito lateral para além da Programação em Lógica] — bottom-up testa_hanoi só instancia os Postes no fim para gravar soluções gerais nos lemas Prolog - 14 Torres de Hanoi % hanoi( N, A, B, C, Moves ) Moves é a sequência de passos para transferir N discos do poste A para o B usando C, segundo as regras do puzzle Torre de Hanoi hanoi( 1, A, B, C, [A to B] ). hanoi( N, A, B, C, Moves ) N>1, N1 is N-1, lema( hanoi(N1,A,C,B,Ms1) ), hanoi( N1,C,B,A,Ms2 ), append( Ms1, [A to B|Ms2], Moves ), lema( P ) P, asserta((P!)). testa_hanoi( N, Postes, Passos ) hanoi( N, A, B, C, Passos ), Postes=[A, B, C]. Prolog - 15 Operadores forma standard de ler e escrever os termos é com o functor seguido dos respectivos argumentos entre parênteses certas expressões ficam mais legíveis usando operadores: 5 + 3 versus '+'( 5, 3 ) comando: op( Precedencia, Tipo, Op ) Precedência de 1 a 1200 • ',' tem precedência 1000; logo, operadores que possam aparecer como argumentos devem ter precedência inferior a 1000 ou ficar entre parênteses, que corresponde a precedência 0: assert( (a b) ) Tipo pretende desambiguar expressões definindo o tipo de associatividade e a posição (infixo: xfx, xfy, yfx; prefixo: fx, fy; posfixo: xf, yf) Prolog - 16 Operadores X+Y+Z (X + Y) + Z yfx X +( Y + Z) xfy f - operador argumentos x: têm que ter precedência inferior a f argumentos y: têm que ter precedência superior a f legal? op(1000, xfy, ',') a, b, c op(500, yfx, [(+),(-)]) op(500, fx, [(+),(-)]) -5+3 Prolog - 17 Ciclos interactivos os programas interactivos baseiam-se no processamento de efeitos laterais (leituras ou escritas, asserts, etc.) eco read( X ), eco( X ). eco( X ) eof( X ), !. eco( X ) write( X ), nl, read( Y ), !, eco( Y ). eof( end_of_file ). se estiver a ler do teclado, basta escrever end_of_file; se o canal de entrada for um ficheiro, é esse o termo que aparece ao chegar ao fim (não esquecer que os termos terminam com um '.') Prolog - 18 Interpertador de comandos exemplo de uma shell para executar comandos (termina com o comando fim): shell shell_prompt, read( Golo ), shell( Golo ). shell( fim ) !. shell( Golo ) ground( Golo ), !, resolve_instanciado( Golo ), shell. shell( Golo ) resolve( Golo ), shell. resolve( Golo ) Golo, write( Golo ), nl, fail. resolve( Golo ) write( 'Nao ha mais.' ), nl. resolve_instanciado( Golo ) Golo, write( 'Sim.' ), nl. resolve_instanciado( Golo ) write( 'Nao.' ), nl. shell_prompt write( 'Comando> ' ). Prolog - 19 Ciclos baseados em falha os ciclos anteriores são baseados em recursão na cauda (enrolam sempre) sucedem e portanto instanciam variáveis se não forem bem optimizados ocupam muito a stack em computações longas se só interessam os efeitos laterais e há problemas de espaço, usar um ciclo repeat-fail (a computação oscila entre o repeat e o fail) eco repeat, read( X ), eco( X ), !. eco( X ) eof( X ), !. eco( X ) write( X ), nl, fail. eof( end_of_file ). Prolog - 20 Consultar Comentários repeat sucede sempre; implementável como • repeat. • repeat repeat. predicado interior ao ciclo (eco/1, ciclo/0) falha sempre, excepto na cláusula de saída cut na cláusula com repeat para evitar ciclo infinito em retrocesso de fora do ciclo como consultar um ficheiro consult( Ficheiro ) see( Ficheiro ), ciclo, seen. ciclo repeat, read( Clausula ), processa( Clausula ), !. processa( end_of_file ) !. processa( Clausula ) assert( Clausula ), fail. Prolog - 21 Não determinismo solucao( X ) gera( X ), testa( X ). geração e teste é um método geral que aproveita muitas vezes o funcionamento bidireccional dos predicados intersecta( Xs, Ys ) member( X, Xs ), member( X, Ys ). implementações tendem a ser ineficientes se a geração não for dirigida; para obviar a isso imbrica-se o teste na geração Prolog - 22 Problema das raínhas % rainhas( N, Rainhas ) Rainhas é uma lista com a posição em cada coluna que resolve o problema rainhas( N, Rs ) gama( 1, N, Ns ), rainhas( Ns, [], Qs ). rainhas( NaoRs, JaRs, Rs ) selecciona( R, NaoRs, NaoRs1 ), not ataca(R, JaRs ), rainhas( NaoRs1, [R, JaRs, Rs] ). rainhas( [], Rs, Rs ). gama( M, N, [M|Ns] ) M<N, M1 is M+1, gama( M1, N, Ns ). gama( N, N, [N] ). select( X, [X|Xs], Xs ). select( X, [Y|Ys], [Y|Zs] ) select( X, Ys, Zs ). ataca( X, Xs ) ataca( X, 1, Xs ). ataca( X, N, [Y|Ys] X is Y+N; X is Y-N. ataca( X, N, [Y|Ys] ) N1 is N+1, ataca( X, N1, Ys ). Prolog - 23 Conjuntos de soluções obter todos os filhos de um dado pai solução com acumulador filhos( X, Fs ) filhos( X, [], Fs ). filhos( X, A, Fs ) pai( X, F ), not member( F, A ), !, filhos( X, [F|A], Fs ). filhos( X, Fs, Fs ). defeitos • ineficiência — cada solução recomeça no início da árvore de pesquisa • falta de generalidade — instanciação progressiva reduz número de soluções implementação com conjuntos — ideia semelhante à das funções de memorização • só percorre a árvore de pesquisa uma vez e não instancia as variáveis porque tem um ciclo com falha logo após o assert • criar cláusulas (e depois destruí-las) é inerentemente pesado Prolog - 24 Predicados de conjuntos bagof( Termo, Golo, Intancias ) Instancias é o multiconjunto de todas as instâncias de Termo para as quais o Golo é satisfeito (inclui repetidos) setof( Termo, Golo, Intancias ) semelhante, mas sem valores repetidos e ordenado filhos( X, Filhos ) setof( Y, pai(X,Y), Filhos ) chamada: filhos( terach, Fs ) resposta: Fs= [haran, nachor, abraao] chamada: filhos( X, Fs ) respostas: • • • • X= terach Fs= [haran, nachor, abraao] ; X= haran Fs= [lot, milcah, yiscah]; X= abraao Fs= [isaac]; X= isaac Fs= [jacob] Prolog - 25 Quantificação existencial se se pretender todos os filhos independentemente dos pais, é necessário quantificar existencialmente o pai para este não aparecer na solução (evitando a partição) setof( Y, X^pai(X,Y), Filhos ) resp.: [haran, nachor, abraao, lot, milcah, yiscah, isaac, jacob] o que dá? setof( Pai-Filhos, setof( X, pai(Pai,X), Filhos ), Ys ) resp.: [terach-[haran, nachor, abraao], haran-[lot, milcah, yiscah], abraao-[isaac], isaac-[jacob]] Prolog - 26 Outras técnicas número de soluções de G: setof( X, G, Ys ), length( Ys, NSol) pesquisa em profundidade: regra de computação normal do Prolog pesquisa em largura: para cada nó, obter o conjunto dos que lhe estão directamente ligados e processá-los antes de descer para o nível inferior Prolog - 27 Predicados de segunda ordem • mapa( Xs, P, Ys ) Ys é a lista dos resultados da aplicação de P a cada X definição de segunda ordem mapa( [X|Xs], P, [Y|Ys] ) P( X, Y ), mapa( Xs, P, Ys ). mapa( [], P, [] ). • implementação em Prolog mapa( [X|Xs], P, [Y|Ys] ) aplica( P, X, Y ), mapa( Xs, P, Ys ). mapa( [], P, [] ). aplica( P, X, Y ) G =.. [P,X,Y], G. Prolog - 28 Listas de diferença ideia: representar sequências de elementos como diferenças entre pares de listas 1,2,3 pode ser a diferença entre – – – – [1,2,3,4,5] e [4,5] ou [1,2,3,8] e [8] ou [1,2,3] e [] ou [1,2,3|Xs] e Xs para realçar o facto de se tratar de uma mesma estrutura, podese usar um operador para representar as listas de diferença Xhead/Xtail ou dois argumentos separados vantagem: eficiência, faz a concatenação em tempo constante e não linear no 1º arg Prolog - 29 Exemplo de listas de diferença • • • • • • • • • • • • • • • • • • • Xs Xs/Ys • • • • • • • • • • • • • • Ys Ys/Zs • • • • • • • Zs Xs/Zs % append_ld( As, Bs, Cs ) a lista de diferença Cs é o resultado de concatenar as listas de diferença compatíveis As e Bs append_ld( Xs/Ys, Ys/Zs, Xs/Zs). • chamada: append_ld( [a,b,c|Ls]/Ls, [1,2]/[], Ks ) resultado: Ls=[1,2] Ks= [a,b,c,1,2]/[] generalização do conceito de acumulador aplana( xs, Ys ) aplana_ld( Xs, Ys/[] ). aplana_ld( [X|Xs], Ys/Zs ) aplana_ld( X, Ys/Ys1 ), aplana_ld( Xs, Ys1/Zs). aplana_ld( X, [X|Xs]/Xs ) atomic( X ), X \= []. aplana_ld( [], Xs/Xs ). Prolog - 30 Estruturas incompletas % ve( Chave, Dicionario, Valor ) Dicionario contém Valor indexado por Chave ( Dicionário é constituído por pares (Chave, Valor) ) ve( Chave, [(Chave,Valor)|Dic], Valor ). ve( Chave, [(Chave1,Valor1) | Dic ], Valor ) Chave \= Chave1, ve( Chave, Dic, Valor ). uso do dicionário ( implementado com lista, mas podia ser árvore binária, ...) ve( fatima, [(ana,1611),(joao,4245)|Dic],1812) sucede e instancia o dicionário mais um pouco ve( joao, [(ana,1611),(joao,4245), (fatima,1812)|Dic], X ) sucede com X=4245 Prolog - 31 Meta-interpretadores Meta-interpretador — interpretador de uma linguagem escrito na própria linguagem. % resolve( Golo ) Golo é verdade relativamente ao programa em causa interpretador trivial (e pouco útil... embora usado no exemplo da shell) resolve( G ) G. interpretador de três linhas resolve( true ). resolve( (A,B) ) resolve( A ), resolve( B ). resolve( A ) clause( A, B ), resolve( B ). % true % conjunção % redução Prolog - 32 Meta-interpretadores especiais granularidade do metainterpretador de 3 linhas é suficiente para resolver problemas interessantes, sem tornar o sistema demasiado lento; permite controlar a ordem de execução dos golos ou registar um traço da execução % resolve( G, Arvore ) Arvore contem uma árvore de prova de G resolve( true, true ). resolve( (A,B), (ProvaA, ProvaB ) resolve( A, ProvaA ), resolve( B, ProvaB ). resolve( A, true ) sistema( A ), A. % tabela para sistema/1 resolve( A, (A Prova) ) clause( A, B ), resolve( B, Prova ). Prolog - 33 Janelas de texto wcreate(janTexto,text,`Janelinha`,200,125,400,225,0). • cria uma janela de topo wedtsel((janTexto,1), 0, 30000 ). • selecciona texto no controlo 1 da janTexto wedtsel((janTexto,1), Ini, Fim ). • Interroga sobre quais os limite de uma seleccao wedttxt((janTexto,1), Dados ). • le o texto seleccionado wedttxt((janTexto,1), `Olare meu` ). • escreve no texto seleccionado wclose( janTexto ). • fecha a janela wedtlin( (janTexto,1), 100, IniLinha, FimLinha ). • indica os offsets de inicio e fim de linha para um offset dado; so wedtsel altera a seleccao Prolog - 34 Mais interface Windows wcount( (janTexto,1), Caract, Palavras, Linhas ). • conta wedtfnd( (janTexto,1), 0, 30000, `Goal`, Ini, Fim ). • offsets da palavra em pesquisa wdict( D ). • devolve uma lista com os nomes das janelas de topo msgbox( 'Prologochi', 'Tenho fome.', 48, Codigo ). • dialogo com um estilo indicando numero de botoes, cada qual correspondendo a um codigo de retorno dirbox( 'Ficheiros', 'Escolha um:', '*.doc', Fich ). • ficheiro chdir( Corrente ). • muda de directorio corrente exec('notepad.exe',' ',_). • executa um programa externo Prolog - 35 Construção de janelas wcreate( janGeral, dialog, `Dialogo`, 200, 125, 400, 225, 16'90c80000 ). • cria um janela de dialogo de topo wcreate( (janGeral,1), button, `Pois`, 10, 150, 80, 32, 16'50010000 ). • cria um botao na janela wcreate( janGeral, dialog, `Dialogo`, 200, 125, 400, 225, 16'80c80000 ). • cria um janela invisivel de dialogo de topo wshow( janGeral, 1 ), wfocus((janGeral,1)). • mostra (1), esconde (0), iconifica (2), maximiza (3) e foca wcreate(janBotoes,user,`Botoes`, 200,125,400,225,0 ). • cria um janela user - faz parte do MDI (Multiple Document Interface), janela do LPA-Prolog; um diálogo é autónomo wcreate( (janBotoes,1), button, `Pois`, 10, 150, 80, 32, 16'50010000 ). • cria um botao na janela Prolog - 36 Botões wcreate( (janBotoes,2), button, `Nao da`, 100, 150, 80, 32, 16'50010003 ). • checkBox wcreate( (janBotoes,3), button, `Esta`, 190, 150, 80, 32, 16'50010009 ). • radioButton wcreate( (janBotoes,4), button, `Aquela`, 280, 150, 80, 32, 16'50010009 ). • cria um botao na janela wenable( (janBotoes,2), 1 ). • activa/desactiva controlo wbtnsel( (janBotoes,3), Est ). • interroga/poe o estado de botoes wcreate( (janBotoes,5), edit, `Notas`, 10, 200, 80, 64, 16'50810005 ). • cria uma caixa de texto na janela Prolog - 37 Caixas de texto e listas wedtsel( (janBotoes,5), 30, 40 ), wedttxt( (janBotoes,5), `Novo texto aqui! ` ). • selecciona e altera texto wtext( (janBotoes,5), T ). • le (ou escreve, se T instanciado) o conteudo da janela wcreate( (janBotoes,6), listbox, ` `, 10,125,80,64, 16'50a10002 ). • cria uma lista wlbxadd( (janBotoes,6), -1, `Amarelo` ). • adiciona elementos a lista na posicao default wlbxadd( (janBotoes,6), -1, `Vermelho` ). wlbxadd( (janBotoes,6), -1, `Verde` ). wlbxsel( (janBotoes,6), 2, 1 ). • selecciona o elemento 3 como activo wlbxget( (janBotoes,6), 1, T ). • consulta o 2 elemento da lista Prolog - 38 Menús wmcreate( menu1 ). • cria um menu. wmnuadd( menu1, -1, `&Sopas`, 1000). • acrescenta uma linha Sopas no fim com codigo 1000 wmnuadd( menu1, -1, `&Pratos`, 1001). wmnuadd( menu1, -1, `&Sobre`, 1002). wmnuadd( 0, 3, `Menu`, menu1). • adiciona menu ao menu geral da aplicacao wmnusel(menu1,0,1). • poe marca na primeira opcao do menu wmdict( D ). • devolve a lista de menus activos wmnudel(0,3). • retira a entrada do menu1 na barra do WIN-Prolog (menu 0) wmclose( menu1 ). • elimina menu, depois de ter sido retirado de onde quer que seja usado Prolog - 39 Mensagens Arquitectura geral interacção com Windows baseada em eventos que interrompem o Prolog, são processados e retomam o golo interrompido só alguns eventos do Windows chegam ao Prolog (menus, diálogos, …) processamento recepção da mensagem pelo LPA-Prolog • anzol: ‘?MESSAGE?’(Window, Message, Data, Goal), apanha todas as mensagens em bruto, excepto as usadas internamente nos menus Edit e Windows separação em classes e processamento de parâmetros interrupção do programa, desactivação das interrupções, chamada de um processador da mensagem (handler) • anzol: ‘?FIND?’/4, ‘?TIMER?’/3 • reactivação das interrupções, retoma do golo interrompido Prolog - 40 Processadores de mensagens Esquema dos anzóis '?CLASS?'(Window, Message, Data, Goal):!, ..., wflag(1), Goal. '?CLASS?'(Window, Message, Data, Goal):class_hook(Window, Message, Data, Goal). CLASS é uma das classes existentes se existir o anzol, é chamado, senão chama-se directamente class_hook/3 Window é o controlo antes do que chamou o anzol o anzol pode processar alguns casos e deixar os outros para a rotina geral não esquecer de reactivar as interrupções (wflag(1)) e de chamar o golo interrompido Prolog - 41 Mensagens predefinidas '?FIND?'(Window, msg_fbfndnxt, Goal):!, fndbox(``, 1), wflag(1), Goal. '?FIND?'(Window, Message, Goal):find_hook(Window, Message, Goal). Ignora as mensagens Find Next '?CHANGE?'(Window, msg_cbclose, Goal):!, msgbox('Mensagem','A janela vai fechar!',0,_), chgbox(``,``, -1), wflag(1), Goal. '?CHANGE?'(Window, Message, Goal):change_hook(Window, Message, Goal). Processa as mensagens Close Prolog - 42 Ciclo com Timer go( S ):- T is S*4660, abolish(intervalo/1), assert(intervalo(T)), timer( 1, T), repeat, write('Diga'), read(X), processa(X). processa( fim ):- !, timer( 1, 0). processa( X ):- write(X), nl, fail. '?TIMER?'(Timer, Inter, Goal):msgbox('Aviso', 'Timer em accao', 0, _), wflag(1), intervalo(T), timer( Timer, T), Goal. Prolog - 43 Gráficos wcreate( (janBotoes,7), grafix, ` `, 100,125,80,64, 16'50800000 ). • cria um grafico wgfx( (janBotoes, 7), [brsh(128,0,0,0), elip(10,10,70,54)]). • sequencia de operacoes Prolog - 44