Entrada e Saída. Prof. Elaine Faria e Hiran Nonato Programação Lógica UFU 2012

52 

Loading....

Loading....

Loading....

Loading....

Loading....

Texto

(1)

Entrada e Saída

Prof. Elaine Faria e Hiran Nonato

Programação Lógica

(2)

Créditos

•   O  material  a  seguir  consiste  de  adaptações  e 

extensões  dos  originais  gentilmente  cedidos  pelo 

Prof. Alexsandro Santos Soares

(3)

Arquivos de Dados

• A comunicação com o Prolog até agora foi feita por meio 

de consultas realizadas pelo usuários que são respondidas 

através de instanciações de variáveis

• Muitas vezes essa forma de comunicação não é 

suficientemente adequada

– Entrada de dados na forma de linguagem natural – Saída em um dado formato desejado – Entrada e saída para qualquer periférico do computador

(4)

Arquivos de Dados

• Existem predicados pré­definidos com o intuito de 

auxiliar na entrada/saída de dados

– São dependentes da implementação da linguagem 

Prolog usada

(5)

Arquivos de Dados

(6)

Arquivos de Dados

• Durante a execução de um programa Prolog dois arquivos 

estão ativos

– um para entrada  "fonte de entrada corrente" – um para saída  "fonte de saída corrente “

• No início da execução essas duas fontes correspondem ao 

terminal do usuário 

• A fonte de entrada corrente pode ser mudada a qualquer 

momento para um outro arquivo

see(novoArqEnt).

(7)

Arquivo de Entrada

• Exemplo do uso do see

... see(arq1). le_do_arquivo(Informacao). see(user). ...

(8)

Arquivos de Saída

• A fonte de saída corrente pode ser mudada 

– tell(novoArqSai).

• Exemplo do uso do tell

... tell(arq3). grava_no_arquivo(Informacao). tell(user). ...

(9)

Arquivos de Dados

• Dois outros predicados devem ser utilizados para 

fechar os arquivos correntes de entrada e saída 

respectivamente

(10)

Abertura de um arquivo

• Pode­se também abrir um fluxo (stream)

open(‘arquivo.txt‘, write, Fluxo),

...

close(Fluxo),

(11)

Abertura de um arquivo

• Para estender um arquivo existente, temos que 

abrir um fluxo em modo 

append

open(‘arquivo.txt‘, append, Fluxo),

....

close(Fluxo),

...

(12)

Arquivos de Dados

• Os arquivos podem ser processados somente na forma sequencial • A requisição para a leitura irá ocasionar a leitura a partir da posição  corrente dessa fonte de entrada  • Após a leitura, a posição corrente da fonte de entrada será, o próximo  item que ainda não foi lido • Se uma requisição de leitura é feita para o fim do arquivo  retorna a  constante "end_of_file“ • Predicado pre­definido at_end_of_stream(F) usado para verificar se o  fim da stream foi atingido

(13)

Arquivos de Dados

• A saída de informações ocorre de maneira similar à 

entrada 

– A requisição de saída irá adicionar a informação 

requisitada no final da fonte de saída corrente

(14)

Arquivos de Dados

• Há duas maneiras de se utilizar os arquivos em 

Prolog

– Considerando o caractere como elemento básico do 

arquivo

– Considerando unidades maiores como elemento básico 

do arquivo

(15)

Arquivos de Dados

• Usando o caractere como elemento básico arquivo

– Predicados: get e put

• Usando unidades maiores como elemento básico do 

arquivo

– As unidades são os termos Prolog: read e write

• O uso de cada uma dessas modalidades depende do 

contexto do problema

(16)

Processamento de Arquivos de Termos

• read

– Usada para leitura de dados a partir da fonte corrente

read([A],X)

leitura do próximo termo que irá unificar com X Se X é uma variável então X será instanciada com T Se a unificação não for possível então o objetivo read(X) irá falhar Cada termo deve ser seguido por um ponto e um espaço ou enter A representa o arquivo  não é obrigatório

– É determinístico  não ocorre backtracking

(17)

Processamento de Arquivos de Termos

• write

– Fornece a saída de um termo para a fonte corrente

write([A], X)

• tab

– O predicado tab(N) irá ocasionar a saída de N espaços 

• nl

– O predicado nl(sem argumentos) irá ocasionar o início de uma  nova linha

(18)

Exemplo 1 ­ Cubo

cubo :­ read(X), processa(X). processa(fim) :­ !. processa(N) :­ C is N*N*N, write(C), cubo. ?­cubo. 2. 8 5. 25 12. 1728 fim. true

(19)

Exemplo 2 ­ Cubo

cubo :­      write('Próximo valor: '),      read(X),      processa(X). processa(fim) :­ !. processa(N) :­      C is N*N*N,      write('O cubo de '), write(N), write('é '),      write(C), nl, cubo. Dependendo da implementação, uma requisição ("flush/0" para descarregamento dos buffers de I/O) pode  ser necessária após o comando de escrita no prompt

(20)

Exemplo 3 – Escrevendo Lista

• Procedimento escreveLista(L)

escreveLista([]). escreveLista([X | L]) :­ write(X), nl, escreveLista(L).

• Procedimento escreveLista2(L)

escreveLista2([]). escreveLista2([L | LL]) :­ imprime(L), nl, escreveLista2(LL). imprime([]). imprime([X | L]) :­ write(X), tab(1), imprime(L).

(21)

Exemplo 4

• Programa em Prolog que lê o arquivo (casas.txt) e 

o exibe na tela.

principal:­     open('casas.txt',read,F),     read(F,C1),     read(F,C2),       read(F,C3),     read(F,C4),     close(F),     write([C1,C2,C3,C4]), nl. grifinoria. lufa_lufa. corvinal. sonserina. casas.txt:

(22)

Exemplo 5

principal:­     open('casas.txt',read,F),     leiaCasas(F,Casas),     close(F),     write(Casas), nl. leiaCasas(F,[]):­       at_end_of_stream(F). leiaCasas(F,[X|L]):­       \+ at_end_of_stream(F),      read(F,X),       leiaCasas(F, L).

(23)

Exemplo 5 com cortes verdes

principal:­     open('casas.txt',read,F),     leiaCasas(F,Casas),     close(F),     write(Casas), nl. leiaCasas(F,[]):­       at_end_of_stream(F), !. leiaCasas(F,[X|L]):­       \+ at_end_of_stream(F), !,      read(F,X),       leiaCasas(F, L).

(24)

Exemplo 6

• Problema

– Arquivo denominado arq1 contendo termos na forma

item(Nro, Descrição, Preço, Fornecedor)

– Deseja­se produzir um outro arquivo que contenha 

somente os itens fornecidos por um determinado 

fornecedor

– O nome do fornecedor deve ser escrito no início do 

arquivo

(25)

Exemplo – cont.

principal(NomeForn):­     open('C:\\Entrada.txt',read,AEnt),     open('C:\\Saida.txt',write,ASaida),     write(ASaida, NomeForn),     write(ASaida, '\n'),     leiaForn(AEnt,ASaida, NomeForn),     close(AEnt),   close(ASaida). leiaForn(AEnt,_,_):­      at_end_of_stream(AEnt), !. leiaForn(AEnt,ASaida,NomeForn):­      read(AEnt,item(Nro,D,P,NomeForn)),!,      write(ASaida, item(Nro,D,P)),      write(ASaida,'\n'),       leiaForn(AEnt,ASaida,NomeForn). leiaForn(AEnt,ASaida,NomeForn):­      leiaForn(AEnt,ASaida,NomeForn).

(26)

Processamento de caracteres

• Um caractere é escrito na fonte de saída corrente 

por meio do objetivo

put(C)

C é o código ASCII (um número entre 0 e 255) do caractere a ser escrito 

– Exemplo

?­put(65), put(66), put(67). produz a saída: ABC

(27)

Processamento de caracteres

• Um caractere pode ser lido a partir da fonte de 

entrada corrente por meio do objetivo

get0(C)

ocasiona a leitura do caractere corrente e torna a variável C instanciada com o  código ASCII do caractere

(28)

Processamento de caracteres

• Leitura de caracteres imprimíveis saltando sobre 

todos os caracteres não­imprimíveis (espaços em 

branco)

(29)

Processamento de caracteres

• O predicado get_code/2 lê o próximo caracter 

disponível de um fluxo

– Primeiro argumento: um fluxo

(30)

Exemplo usando get_code

leiaPalavra(Fluxo,Palavra):­     get_code(Fluxo,Caracter),     verificaELeiaResto(Caracter,Caracteres,Fluxo),     atom_codes(Palavra,Caracteres).  verificaELeiaResto(10, [], _):­ !. verificaELeiaResto(32, [], _):­ !. verificaELeiaResto(­1, [], _):­ !.  verificaELeiaResto(Caracter,[Caracter|Caracteres],F):­       get_code(F,ProxCaracter),       verificaELeiaResto(ProxCaracter,Caracteres,F).

(31)

Conversão de Termos

• Predicado pré­definido atom_codes/2, que 

relaciona os átomos com o seu código ASCII. 

– atom_codes(X, L) é verdadeiro, se L é a lista dos 

códigos dos caracteres em A

– Exemplo

 atom_codes(zx232, [122, 120, 50, 51, 50])

(32)

Dividindo programas em arquivos

• Muitos predicados Prolog fazem uso dos mesmos 

predicados básicos

– Por exemplo: member/2, append/3

• É claro que você não quer redefini­los a cada vez 

que necessitar deles

– Prolog oferece muitos modos de fazer isto

(33)

Leitura de programas

• A forma mais simples de dizer ao Prolog para ler as 

definições de predicados armazenadas em um 

arquivo é usar os colchetes

?­ [meuArq].

{consulting(meuArq.pl)…}

{meuArq.pl consulted, 233 bytes}

true

(34)

Leitura de programas

• Você também pode consultar mais de um arquivo 

por vez

?­ [meuArq1, meuArq2, meuArq3].

{consulting meuArq1.pl…}

{consulting meuArq2.pl…}

{consulting meuArq3.pl…}

(35)

Leitura de programas

• Você não precisa fazer isto interativamente 

• Ao invés disto, você pode usar uma diretiva na base de 

dados

(36)

Leitura de programas

• Talvez, muitos arquivos, independentemente, 

consultem o mesmo arquivo.

• Verificação extra se as definições dos predicados já 

são conhecidas: ensure_loaded/1

:­ ensure_loaded([meuArq1, meuArq2]).

(37)

Módulos

• Imagine que você está escrevendo um programa que 

gerencie um banco de dados sobre filmes

• Você projetou dois predicados:

– imprimeAtores/1 – imprimeFilmes/1

• Eles estão armazenados em arquivos diferentes

• Ambos usam um predicado auxiliar:

– exibeLista/1

(38)

O arquivo principal .pl

% Arquivo principal.pl

:­ [imprimeAtores]. :­ [imprimeFilmes].

(39)

O arquivo principal .pl

% Arquivo principal.pl

:­ [imprimeAtores]. :­ [imprimeFilmes].

(40)

O arquivo principal .pl

% Arquivo principal.pl :­ [imprimeAtores]. :­ [imprimeFilmes]. ?­ [principal]. {consulting principal.pl}

(41)

O arquivo principal .pl

% Arquivo principal.pl :­ [imprimeAtores]. :­ [imprimeFilmes]. ?­ [principal]. {consulting principal.pl} {consulting imprimeAtores.pl}

(42)

O arquivo principal .pl

% Arquivo principal.pl :­ [imprimeAtores]. :­ [imprimeFilmes]. ?­ [principal]. {consulting principal.pl} {consulting imprimeAtores.pl} {imprimeAtores.pl consulted}

(43)

O arquivo principal .pl

% Arquivo principal.pl :­ [imprimeAtores]. :­ [imprimeFilmes]. ?­ [principal]. {consulting principal.pl} {consulting imprimeAtores.pl} {imprimeAtores.pl consulted} {consulting imprimeFilmes.pl}

(44)

O arquivo principal .pl

% Arquivo principal.pl :­ [imprimeAtores]. :­ [imprimeFilmes]. ?­ [principal]. {consulting principal.pl} {consulting imprimeAtores.pl} {imprimeAtores.pl consulted} {consulting imprimeFilmes.pl} The procedure exibeLista/1 is being  redefined.  Old file: imprimeAtores.pl New file: imprimeFilmes.pl Do you really want to redefine it? (y, n, p, or ?)

(45)

Usando módulos

• Predicado pré­construído module: 

– module/1 e module/2 – Para criar um módulo/biblioteca

• Predicado pré­construído use_module: 

– use_module/1 e use_module/2 – Para importar predicados de uma biblioteca

• Argumentos

– O primeiro argumento é o nome do módulo – O segundo e opcional argumento é uma lista dos predicados  exportados

(46)

Nota sobre módulos em Prolog

• Nem todos os interpretadores Prolog possuem este 

sistema de módulos

• SWI Prolog e Sicstus possuem

• O sistema de módulos do Prolog ainda não é 

compatível com a norma ISO

(47)

O módulo imprimeAtores.pl

% Este é o arquivo:  imprimeAtores.pl :­ module(imprimeAtores,[imprimeAtores/1]). imprimeAtores(Filme):­     filmesAtor(Ator, Lista),     exibeLista(Lista). exibeLista([]):­ nl. exibeLista([X|L]):­      write(X), tab(1),       exibeLista(L).

(48)

O módulo imprimeFilmes.pl

% Este é o arquivo:  imprimeFilmes.pl :­ module(imprimeFilmes,[imprimeFilmes/1]). imprimeFilmes(Diretor):­     diretoresFilme(Filme, Lista),     exibeLista(Lista). exibeLista([]):­ nl. exibeLista([X|L]):­      write(X), nl,       exibeLista(L).

(49)

O arquivo revisado principal.pl

• % Este é o arquivo revisado principal.pl :­ use_module(imprimeAtores). :­ use_module(imprimeFilmes). % Este é o arquivo revisado principal.pl :­ use_module(imprimeAtores,[imprimeAtores/1]). :­ use_module(imprimeFilmes,[imprimeFilmes/1]).

(50)

Bibliotecas

• Muitos dos predicados mais comuns já vem pré­

construídos nos interpretadores Prolog

• Por exemplo, em SWI Prolog, member/2 e append/3 vem 

como parte de uma biblioteca

• Uma biblioteca é um módulo que define predicados 

comuns e pode ser carregada usando os predicados 

normais para importar módulos

(51)

Importando bibliotecas

• Ao especificar o nome de uma biblioteca que você 

quer usar, você pode informar que este módulo é 

uma biblioteca

• Prolog procurará no lugar certo, ou seja, em um 

diretório onde todas as bibliotecas estão guardadas

:­ use_module(library(lists)). 

(52)

Referências

• Luis,  A.  M.  Palazzo,    Introdução  à  Programação 

Prolog, Educat, 1997.

Imagem

Referências

temas relacionados :