UNIVERSIDADE ESTADUAL DE MARINGÁ
DEPARTAMENTO DE INFORMÁTICA
MESTRADO EM CIÊNCIA DA COMPUTAÇÃO
Programação Funcional e Programação Lógica
Uma Implementação Prática
Trabalho apresentado à
disciplina de Linguagem de
Programação do curso de
Mestrado em Ciência da
Computação, da
Universidade Estadual de
Maringá.
Docente: Profº Drº Sérgio Roberto Pereira da Silva
Dorival José Batista
Késsia Rita da Costa Marchi
Roberto Pereira
MARINGÁ, Dezembro de 2006.
2
Sumário
Índice de Figuras ......................................................................................................... 3
Introdução ................................................................................................................... 6
Organização do Trabalho ........................................................................................... 6
1 - Definição do Problema ........................................................................................... 7
2 - PROLOG................................................................................................................ 8
2.1 - Conexão com Banco de Dados MySql ................................................................ 8
2.2 - Implementação. ................................................................................................... 9
2.2.3 - Questões pré-determinadas para a resolução do problema. ......................... 12
3 - Scheme.................................................................................................................. 21
3.1 - Conexão com Banco de Dados .......................................................................... 21
3.3 - Implementação .................................................................................................. 23
3.3.1 - Questões pré-determinadas para a resolução do problema. ......................... 25
4 - Conclusão ............................................................................................................. 35
5 – Referencias Bibliográficas................................................................................... 37
3
Índice de Figuras
Figura 1 – Diagrama Entidade Relacionamento ................................................................................. 07
Figura 2 – Gerenciador de Fontes de Dados ...................................................................................... 08
Figura 3 – Configuração da Fonte de Dados do Sistema .................................................................... 09
Figura 4 – Fonte de Dados para Access ............................................................................................. 22
Figura 5 – Seleção de Fonte de Dados ............................................................................................... 23
4
Índice de Tabelas
Tabela 1 – Conexão do Prolog ao BD Mysql ....................................................................................... 09
Tabela 2 – Predicado Conectado ......................................................................................................... 09
Tabela 3 – Predicado Departamento .................................................................................................... 10
Tabela 4 – Predicado Curso ................................................................................................................ 10
Tabela 5 – Predicado Professor ........................................................................................................... 10
Tabela 6 – Predicado Disciplina .......................................................................................................... 10
Tabela 7 – Predicado Turno ................................................................................................................ 10
Tabela 8 – Predicado Dia .................................................................................................................... 10
Tabela 9 – Predicado Horário.............................................................................................................. 10
Tabela 10 – Predicado Grupo de Pesquisa ........................................................................................... 10
Tabela 11 – Predicado Linha de Pesquisa ............................................................................................ 10
Tabela 12 – Predicado Aluno .............................................................................................................. 10
Tabela 13 – Predicado Projeto............................................................................................................. 10
Tabela 14 – Predicado Artigo.............................................................................................................. 12
Tabela 15 – Predicado Professor x Disciplina ...................................................................................... 12
Tabela 16 – Resposta – Professor x Disciplina .................................................................................... 12
Tabela 17 – Predicado Hora x Professor .............................................................................................. 13
Tabela 18 – Resposta – Hora x Professor ............................................................................................ 13
Tabela 19 – Resposta – Hora x Disciplina ........................................................................................... 14
Tabela 20 – Predicado Professor Pesquisador ...................................................................................... 14
Tabela 21 – Resposta – Professor Pesquisador..................................................................................... 15
Tabela 22 – Predicado Professor x Artigo ........................................................................................... 15
Tabela 23 – Resposta – Professor x Artigo .......................................................................................... 15
Tabela 24 – Resposta – Professor X Artigo Autoria ............................................................................. 16
Tabela 25 – Predicado Artigo.............................................................................................................. 17
Tabela 26 – Resposta Artigo Professor ................................................................................................ 18
Tabela 27 – Resposta Artigo Professor Autoria ................................................................................... 19
Tabela 28 – Predicado Professor x Departamento ............................................................................... 19
Tabela 29 – Resposta – Professor x Departamento............................................................................... 19
Tabela 30 – Predicado Professor x Curso ............................................................................................ 20
Tabela 31 – Resposta Professor x Curso .............................................................................................. 21
Tabela 32 – Predicado Professor x Projeto .......................................................................................... 21
Tabela 33 – Resposta Professor x Projeto ............................................................................................ 21
Tabela 34 – Função de conexão .......................................................................................................... 22
Tabela 35 – Alocação de 'Environment Handle' e um 'Connection Handle' ........................................... 22
Tabela 36 – Chamada externa ao drive ODBC .................................................................................... 23
Tabela 37 – Função União .................................................................................................................. 23
Tabela 38 – Função Pertence? ............................................................................................................. 24
Tabela 39 – Chamada e Execução do Script SQL ................................................................................ 24
Tabela 40 – Função HSTMT............................................................................................................... 24
Tabela 41 – Chamada e Execução do Script SQL ................................................................................ 24
Tabela 42 – Chamada e Execução do Script SQL – 1ª questão ............................................................. 25
Tabela 43 – Buffers e Indicadores – 1ª questão. ................................................................................... 25
Tabela 44 – Chamada da função cônsul e o resultado – 1ª questão. ..................................................... 26
Tabela 45 – Buffer, indicadores e rotinas de execução – 2ª questão. .................................................... 26
Tabela 46 – Chamada da função cônsul e o resultado – 2ª questão. ..................................................... 27
Tabela 47 – Chamada e Execução do Script SQL – 3ª questão ............................................................. 27
Tabela 48 – Buffers e Indicadores – 3ª questão. ................................................................................... 28
Tabela 49 – Chamada da função cônsul e o resultado de professor – 3ª questão.................................... 28
Tabela 50– Buffer, indicadores e rotinas de execução – 4ª questão. ..................................................... 29
Tabela 51 – Chamada da função cônsul e o resultado – 4ª questão. ..................................................... 30
Tabela 52 – Buffer, indicadores e rotinas de execução – 5ª questão. .................................................... 30
Tabela 53– Chamada da função cônsul e o resultado – 5ª questão. ....................................................... 31
Tabela 54 – Buffer, indicadores e rotinas de execução – 6ª questão. .................................................... 31
Tabela 55– Chamada da função cônsul e o resultado – 6ª questão. ...................................................... 32
Tabela 56 – Buffer, indicadores e rotinas de execução – 7ª questão. .................................................... 32
Tabela 57– Chamada da função cônsul e o resultado – 7ª questão. ....................................................... 33
5
Tabela 58 – Buffer, indicadores e rotinas de execução – 8ª questão. ..................................................... 34
Tabela 59– Chamada da função cônsul e o resultado – 8ª questão. ....................................................... 34
6
Introdução
Neste trabalho realizaremos uma abordagem sobre Programação Lógica e sobre
Programação Funcional. A programação em lógica se desenvolveu no início dos anos
70, para atender alguns trabalhos sobre prova de teoremas. No decorrer de sua evolução,
manteve-se seu formalismo simples e poderoso, sendo igualmente eficiente tanto para a
representação do conhecimento, quanto como ferramenta para programação.
No contexto da Programação Lógica, a primeira linguagem de programação que
surgiu foi o PROLOG, uma linguagem orientada ao processamento simbólico que
representa uma implementação da lógica como linguagem de programação. O PROLOG
e o maior exemplo de linguagem de programação lógica, e será discutido neste trabalho.
Já a Programação Funcional foi desenvolvida principalmente a partir do final
dos anos 50. É um paradigma de programação que trata a computação como uma
avaliação de funções matemáticas, que pode ou não, apresentar parâmetros bem como
um simples valor de retorno, que são os valores de entrada e o resultado da função,
respectivamente. A primeira linguagem representante da programação funcional foi o
LISP, responsável pela introdução da maioria das características encontradas hoje nas
linguagens de programação funcional. O Scheme representou uma tentativa de melhorar
e simplificar o LISP, e será a linguagem utilizada para demonstrar o desenvolvimento
de um programa utilizando programação funcional.
A realização deste trabalho visa demonstrar a utilização da programação lógica e
da programação funcional, aplicadas a um mesmo domínio de problema. Busca-se
analisar as implementações realizadas e as formas de desenvolvê-las, para que seja
possível identificar claramente as diferenças existentes entre as abordagens utilizadas.
Organização do Trabalho
No item 1 apresenta-se a definição do problema que será abordado, uma breve
descrição do domínio e das questões que serão consideradas no desenvolver do trabalho.
No item 2, realiza-se a especificação das implementações realizadas com a linguagem
lógica PROLOG, uma breve descrição da mesma e alguns outros pontos importantes
para o contexto do trabalho. O item 3 abrange as implementações realizadas com a
linguagem funcional Scheme, demonstrando alguns blocos de código e os resultados
gerados pelos mesmos. No item 4, apresentam-se as conclusões obtidas pela realização
das implementações realizadas.
7
1 - Definição do Problema
Com o intuito de estabelecer métricas para comparação entre paradigmas de
linguagens de programação lógica e funcional, utilizamos como domínio do problema,
um departamento que precisa realizar a consulta de diversas informações referentes
pesquisas, professores, disciplinas, carga horária, entre outros. Para tal, definimos um
esquema em Banco de Dados representado no Diagrama de Entidade e Relacionamento
(figura 1), utilizando o Sistema de Gerenciamento MySql e Microsoft Access.
As implementações realizadas em PROLOG, apresentaram êxito tanto com o
banco de dados MySql, quanto com o gerenciador Access. Os acessos a dados
realizados pela linguagem Scheme foram compatíveis somente com o Access, devido a
conflitos na conexão com o banco de dados MySql. Assim sendo, o mesmo não será
considerado para a analise do problema com a linguagem Scheme, mas trabalha
normalmente com as implementações realizadas em PROLOG descritas neste trabalho.
Figura 1 – Diagrama Entidade Relacionamento
As implementações desenvolvidas nas linguagens PROLOG e Scheme, possuem como
objetivo encontrar uma resposta para as seguintes perguntas:
1.
2.
3.
4.
5.
6.
7.
8.
Em quais horários um professor ministra aula?
Qual é o horário de uma disciplina?
Quais professores são pesquisadores?
Quais artigos um professor já escreveu?
Quais artigos um professor já publicou?
Em qual departamento um professor trabalha?
Em quais cursos um professor trabalha?
Em quais projetos um professor participa?
Nos próximos itens serão demonstradas e explanadas, as implementações realizadas
para se obter a resolução do problema. Inicialmente, consideraremos a solução do
problema em PROLOG, para em seguida, apresentá-lo em Scheme.
8
2 - PROLOG
A linguagem PROLOG foi utilizada para demonstrar a implementação da
solução, por meio da utilização de uma linguagem lógica. Descrevemos neste tópico,
alguns aspectos importantes quanto a conexão com o banco de dados, e quanto a
implementação da solução para a busca das respostas especificadas.
2.1 - Conexão com Banco de Dados MySql
Para realizar a conexão do PROLOG com o banco de dados MySql, após o
banco ter sido criado, o driver de comunicação deve ser instalado e o ODBC precisa ser
configurado (as figuras 2 e 3 ilustram esta configuração).
Figura 2 – Gerenciador de Fontes de Dados
Para criar uma nova fonte de dados, deve-se adicionar uma nova, e selecionar o driver
MySQL ODBC 3.5.1 Driver. A configuração do mesmo deve ser realizada na tela
seguinte.
9
Figura 3 – Configuração da Fonte de Dados do Sistema
Nesta janela devem ser especificados os parâmetros solicitados para a configuração, tais
como: banco de dados, servidor, usuário, senha, etc. O status da conexão pode ser
testado com o botão “Test”.
Após realizado o processo detalhado acima, as seguintes linhas de código em PROLOG,
possibilitam a comunicação do mesmo com o banco de dados configurado:
Para a conexão ser efetuada, são passados os parâmetros para o driver ODBC, de acordo
com o que se demonstra na tabela 1.
% Conexão do Prolog ao BD MySql através do ODBC-MS
connecta :- odbc_connect('bdprolog', _,
[user(root),password('root'),alias(bdprolog),open(once)]).
Tabela 1 – Conexão do Prolog ao BD Mysql
O predicado `conectado`, tabela 2, foi desenvolvida para retornar se já existe conexão
ativa ou não, com a base de dados especificada.
% Checagem se conexão do Prolog ao BD MySQL está ativa.
conectado(NmBD, DSN) :odbc_current_connection(NmBD, DSN).
Tabela 2 – Predicado Conectado
2.2 - Implementação.
Baseados no esquema SQL representado no item 1, onde foram especificados os
aspectos relacionados ao problema abordado neste estudo de caso, foram desenvolvidos
através de scripts de consulta SQL, os predicados necessários para obtermos as
10
respostas em consultas através da linguagem de programação lógica Prolog. Os
atributos identificadores são utilizados para compor os relacionamentos entre os
predicados. Na seqüência, estaremos detalhando cada predicado criado para retornar
acessar as informações no banco e possibilitar a realização de consultas e
conseqüentemente a busca das respostas para as perguntas anteriormente definidas.
O predicado departamento é utilizado para selecionar os atributos “nome do
departamento” (NmDepto) e o “identificador do departamento” (IdDepto).
depto(NmDepto, IdDepto) :odbc_query(bdprolog, 'Select nome_dpto, iddepartamento from
departamento order by nome_dpto', row(NmDepto, IdDepto)).
Tabela 3 – Predicado Departamento
O predicado curso seleciona os atributos “Nome do Curso” (NmCurso),
“Identificador do Curso” (IdCurso) e “Identificador do Departamento” (IdDepto).
curso(NmCurso, IdCurso, IdDepto) :odbc_query(bdprolog, 'Select nome_cur, idcurso,
iddepartamento from curso order by nome_cur',row(NmCurso,
IdCurso, IdDepto)).
Tabela 4 – Predicado Curso
O predicado professor seleciona os atributos “Nome do Professor” (NmProf),
“Identificador do Professor” (IdProf) e “Identificador do Departamento” (IdDepto).
professor(NmProf, IdProf, IdDepto) :odbc_query(bdprolog, 'Select nome_prof, idprofessor,
iddepartamento from professor order by nome_prof',
row(NmProf, IdProf, IdDepto)).
Tabela 5 – Predicado Professor
O predicado disciplina é necessário para selecionar os atributos “Nome da
Disciplina” (NmDisc), “Identificador do Curso” (IdCurso) e “Identificador da
Disciplina” (IdDisc).
disciplina(NmDisc, IdCurso, IdDisc) :odbc_query(bdprolog, 'Select nome_disc, iddisciplina, idcurso
from disciplina order by nome_disc, idcurso',
row(NmDisc, IdDisc, IdCurso)).
Tabela 6 – Predicado Disciplina
O predicado turno é utilizado para a seleção dos atributos “Nome do Turno”
(NmTur) e “Identificador do Turno” (IdTur).
turno(NmTur, IdTur) :odbc_query(bdprolog, 'Select turno, idturno from turno',
row(NmTur, IdTur)).
Tabela 7 – Predicado Turno
11
O predicado dia seleciona atributos “Dia da Semana” (DiaSem), “Identificador
do Turno” (IdTur) e “Identificador do Dia”(IdDia).
dia(DiaSem, IdTur, IdDia) :odbc_query(bdprolog, 'Select dia_sem, idturno, iddia from
dia', row(DiaSem, IdTur, IdDia)).
Tabela 8 – Predicado Dia
O predicado horario é necessário para selecionar os atributos “Hora” (Hora),
“Identificador do Dia” (IdDia) e “Identificador da Hora”(IdHora).
horario(Hora, IdDia, IdHora) :odbc_query(bdprolog, 'Select horario, iddia, idhorario from
horario', row(Hora, IdDia, IdHora)).
Tabela 9 – Predicado Horário
O predicado grupo_pesq é utilizado para selecionar os atributos referentes ao
grupo de pesquisa, sendo, “Nome do Grupo” (NmGrupo) e “Identificador do Grupo”
(IdGrupo).
grupo_pesq(NmGrupo, IdGrupo) :odbc_query(bdprolog, 'Select nome_grupo, idgrupo_pesq from
grupo_pesq', row(NmGrupo, IdGrupo)).
Tabela 10 – Predicado Grupo de Pesquisa
O predicado linha_pesq seleciona os atributos “Nome da Linha” (NmLinha),
“Área da Linha” (AreaL) e “Identificador da Linha” (IdLinha) utilizados nas consultas
referentes à “linha de pesquisa”.
linha_pesq(NmLinha, AreaL, IdLinha) :odbc_query(bdprolog, 'Select nome_lin, area_lin,
idlinha_pesquisa from linha_pesquisa', row(NmLinha, AreaL,
IdLinha)).
Tabela 11 – Predicado Linha de Pesquisa
O predicado aluno é utilizado na seleção do “Nome do Aluno” (NmAluno) e
“Identificados do Aluno” (IdAluno).
aluno(NmAluno, IdAluno) :odbc_query(bdprolog, 'Select nome_aluno, idaluno from aluno',
row(NmAluno, IdAluno)).
Tabela 12 – Predicado Aluno
O predicado projeto seleciona os atributos “Nome do Projeto” (NmProj), “Nome
do Tema” (NmTema), “Nome da Área” (NmArea) e “Identificados do projeto” (IdProj).
projeto(NmProj, NmTema, NmArea, IdProj) :odbc_query(bdprolog, 'Select nome_proj, tema_proj, area_proj,
idprojeto from projeto', row(NmProj, NmTema, NmArea,
IdProj)).
Tabela 13 – Predicado Projeto
12
O predicado artigo é necessário para selecionar os atributos “Título do Artigo”
(TitArt), “Resumo do Artigo” (resArt), “Ano do Artigo” (AnoArt), “Identificador da
Linha” (IdLinha) e “Identificados do Artigo” (IdArt).
artigo(TitArt, ResArt, AnoArt, IdLinha, IdArt) :odbc_query(bdprolog, 'Select titulo_art, resumo_art, ano_art,
idlinha_pesquisa, idartigo from artigo', row(TitArt,
ResArt, AnoArt, IdLinha, IdArt)).
Tabela 14 – Predicado Artigo
2.2.3 - Questões pré-determinadas para a resolução do problema.
Na seqüência, serão apresentadas as implementações construídas com base nos
predicados anteriormente especificados, de modo que seja possível responder às
questões definidas no inicio do projeto.
1. Qual professor ensina uma determinada disciplina?
Para encontrar os professores que ministram uma determinada disciplina,
utilizamos o predicado prof_disc, que é composto pelos atributos “Nome do
Professor”(NmProf), “Nome do Departamento” (NmDepto), “Nome do
Curso”(NmCurso) e “Nome da Disciplina” (NmDisc).
prof_disc( NmProf, IdProf, NmDisc, IdDisc, IdHora):odbc_query(bdprolog, 'Select idprofessor, iddisciplina,
idhorario from professor_disciplina', row(IdProf, IdDisc ,
IdHora)),
professor(NmProf, IdProf, IdDepto),
disciplina(NmDisc, IdCurso, IdDisc).
Tabela 15 – Predicado Professor x Disciplina
A consulta prof_disc seleciona o atributo “Nome do Professor” (NmProf), com
base no parâmetro de entrada “Nome da disciplina”. O objeto “_”, utilizado na consulta,
tem a finalidade de ocultar os atributos que não são necessários para esta questão.
1 ?- prof_disc(NmProf, _, 'Linguagem de Programação', _, _).
NmProf = 'Sérgio' ;
Yes
2 ?Tabela 16 – Resposta – Professor x Disciplina
No exemplo acima, o nome da disciplina foi passado como parâmetro, e o retorno
solicitado foi o nome do professor que a ministra.
2. Em quais horários um professor ministra aula?
Para esta questão, foi necessário utilizar o predicado prof_disc devido ao
modelo relacional armazenar o horário de aulas na tabela “professor_disciplina”,
estabelecendo assim um relacionamento ternário entre professor, disciplina e hora.
Foram utilizados ainda, os predicados dia, turno e horário. Os atributos mostrados
13
neste predicado são o “Nome do Professor” (NmProf), “Nome da Disciplina”
(NmDisc), “Dia da Semana” (DiaSem), “Turno” (Turno) e “Hora” (Hora).
hora_prof(NmProf, NmDisc, DiaSem, Turno, Hora) :prof_disc( NmProf, IdProf, NmDisc, IdHora),
dia(DiaSem, IdTur, IdDia),
turno(NmTur, IdTur),
horario(Hora, IdDia, IdHora).
Tabela 17 – Predicado Hora x Professor
A execução desta consulta permite que seja exibido todos os horários de todos os
professores, como segue o exemplo, ou passar por parâmetro qualquer um dos atributos
aplicando um filtro para a execução da consulta.
1 ?- hora_prof(NmProf, NmDisc, DiaSem, Turno, Hora).
NmProf
NmDisc
DiaSem
Hora =
= 'Sérgio'
= 'Linguagem de Programação'
= 'Seg'
'07:30 s 08:20' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Sérgio'
= 'Engenharia de Software'
= 'Seg'
'08:20 s 09:10' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Maria'
= 'Engenharia de Software'
= 'Seg'
'09:40 s 10:30' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Luiz'
= 'Algoritmo e Programação'
= 'Seg'
'10:30 s 11:20' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Antonio'
= 'Contabilidade'
= 'Seg'
'13:30 s 14:20' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Joaquim'
= 'Banco de Dados'
= 'Seg'
'14:20 s 15:10' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Gervásio'
= 'Banco de Dados'
= 'Seg'
'15:40 s 16:30' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Luiz'
= 'Banco de Dados'
= 'Seg'
'16:30 s 17:20' ;
NmProf = 'Antonio'
NmDisc = 'Banco de Dados'
DiaSem = 'Seg'
14
Hora = '19:20 s 20:10' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Luiz'
= 'História da Administração'
= 'Seg'
'20:10 s 21:00' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Gervásio'
= 'Direito Penal'
= 'Seg'
'21:20 s 22:10' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Maria'
= 'Direito Civil'
= 'Seg'
'22:10 s 23:00' ;
NmProf
NmDisc
DiaSem
Hora =
= 'Antonio'
= 'História'
= 'Ter'
'07:30 s 08:20' ;
Yes
2 ?Tabela 18 – Resposta – Hora x Professor
3. Qual é o horário de uma disciplina?
Para consultar o horário de uma disciplina, utilizamos o predicado hora_prof
ocultando o atributo “Nome do Professor” (NmProf) e passando como parâmetro a
disciplina específica no atributo “Nome da Disciplina” (NmDisc).
1 ?- hora_prof(_, 'Linguagem de Programação', DiaSem, Turno,
Hora).
DiaSem = 'Seg'
Hora = '07:30 s 08:20' ;
Yes
2 ?Tabela 19 – Resposta – Hora x Disciplina
No exemplo, o nome da disciplina foi passado como parâmetro, recebendo o dia da
semana e o horário da mesma.
4. Quais professores são pesquisadores?
O predicado professor_pesq permite consultar os Professores que estejam
classificados como pesquisadores, exibindo os atributos “Nome do Professor” (NmProf)
e “Pesquisador” (Pesq).
professor_pesq(NmProf, Pesq) :odbc_query(bdprolog, 'Select nome_prof, pesquisador from
professor order by nome_prof', row(NmProf, Pesq)).
Tabela 20 – Predicado Professor Pesquisador
15
Para encontrar os professores pesquisadores, realizamos a consulta passando o
parâmetro „S‟ no atributo “Pesquisador”.
1 ?- professor_pesq(NmProf,'S').
NmProf = 'Gervásio' ;
NmProf = 'Joaquim' ;
NmProf = 'Maria' ;
NmProf = 'Sérgio' ;
Yes
2 ?Tabela 21 – Resposta – Professor Pesquisador
Também é possível que seja passado determinado professor como parâmetro, para
consultar se o mesmo é pesquisador ou não.
5. Quais artigos um professor já escreveu?
O predicado prof_artigo realiza a consulta referente aos artigos que cada
professor escreveu, mostrando os atributos “Nome do Professor” (NmProf), “Título do
Artigo” (TitArt), “Resumo do Artigo” (ResArt), “Tipo de Autoria” (TpAutoria) e
“Identificador do Artigo” (IdArt).
prof_artigo(NmProf, TitArt, ResArt, TpAutoria, IdArt) :odbc_query(bdprolog, 'Select tipo_autoria, idartigo,
idprofessor from professor_artigo',
row(TpAutoria, IdArt, IdProf)),
professor(NmProf, IdProf, _),
artigo(TitArt, ResArt, _, _, IdArt).
Tabela 22 – Predicado Professor x Artigo
Consultando o predicado prof_artigo, estamos exibindo o “Nome do Professor”
(NmProf), o “Título do Artigo” (TitArt) e o “Resumo do Artigo” (ResArt). Para mostrar
apenas os Autores dos artigos, estamos passando o parâmetro “A”, que define o tipo de
autoria do artigo como Autor e assim, ocultamos os Co-autores.
1 ?- prof_artigo(NmProf, TitArt, ResArt, 'A', _).
NmProf = 'Sérgio'
TitArt = 'Titulo 4'
ResArt = 'Resumo do Titulo 4' ;
NmProf = 'Luiz'
TitArt = 'Titulo 6'
ResArt = 'Resumo do Titulo 6' ;
NmProf = 'Antonio'
TitArt = 'Titulo 5'
ResArt = 'Resumo do titulo 5' ;
NmProf = 'Gervásio'
TitArt = 'Titulo 2'
16
ResArt = 'Resumo do Titulo 2' ;
Yes
2 ?Tabela 23 – Resposta – Professor x Artigo
Caso não seja passado o parâmetro de autoria, são exibidas todas as autorias ou coautorias dos artigos, como segue o exemplo:
1 ?- prof_artigo(NmProf, TitArt, ResArt, TpAutoria, _).
NmProf = 'Sérgio'
TitArt = 'Titulo 4'
ResArt = 'Resumo do Titulo 4'
TpAutoria = 'A' ;
NmProf = 'Maria'
TitArt = 'Tittulo 3'
ResArt = 'Resumo do Titulo 3'
TpAutoria = 'C' ;
NmProf = 'Maria'
TitArt = 'Titulo 4'
ResArt = 'Resumo do Titulo 4'
TpAutoria = 'C' ;
NmProf = 'Luiz'
TitArt = 'Titulo 5'
ResArt = 'Resumo do titulo 5'
TpAutoria = 'C' ;
NmProf = 'Luiz'
TitArt = 'Titulo 6'
ResArt = 'Resumo do Titulo 6'
TpAutoria = 'A' ;
NmProf = 'Antonio'
TitArt = 'Titulo 5'
ResArt = 'Resumo do titulo 5'
TpAutoria = 'A' ;
NmProf = 'Joaquim'
TitArt = 'Titulo 1'
ResArt = 'Resumo do Titulo 1'
TpAutoria = 'C' ;
NmProf = 'Joaquim'
TitArt = 'Titulo 2'
ResArt = 'Resumo do Titulo 2'
TpAutoria = 'C' ;
NmProf = 'Gervásio'
TitArt = 'Titulo 2'
ResArt = 'Resumo do Titulo 2'
TpAutoria = 'A' ;
Yes
2 ?Tabela 24 – Resposta – Professor X Artigo Autoria
17
6. Quais artigos um professor já publicou?
Para encontrar os artigos publicados pelos professores, utilizamos dois
predicados, sendo eles:
O predicado artigo2 tem a finalidade de relacionar o artigo ao ano de submissão,
utilizando os atributos “Titulo do Artigo” (TitArt), “Resumo do Artigo” (ResArt), “Ano
de Submissão do Artigo” (AnoArt), “Nome da Linha de Pesquisa” (NmLinha), “Área
de Pesquisa” (AreaL), “Evento em que o artigo foi submetido” (Evento), “Aceitação do
Artigo” (Aceito), “Ano de Submissão” (AnoSub) e “Identificador do Artigo” (IdArt).
O segundo é o predicado artigo3 que estabelece o relacionamento entre o
predicado artigo2 e o predicado prof_artigo. O predicado artigo3 apresenta os atributos
“Nome do Professor” (NmProf), “Tipo de Autoria” (TpAutoria), “Título do Artigo”
(TitArt), “Resumo do Artigo” (ResArt), “Ano em que o artigo foi escrito” (AnoArt),
“Evento em que foi submetido” (Evento), “Aceite do Artigo” (Aceito) e “Ano de
submissão” (AnoSub).
artigo2(TitArt, ResArt, AnoArt, NmLinha, AreaL, Evento, Aceito,
AnoSub, IdArt) :odbc_query(bdprolog, 'Select titulo_art, resumo_art, ano_art,
idlinha_pesquisa, idartigo from artigo',
row(TitArt, ResArt, AnoArt, IdLinha, IdArt)),
odbc_query(bdprolog, 'Select evento, aceito, ano, idartigo
from submissao',row(Evento, Aceito, AnoSub, IdArt)),
linha_pesq(NmLinha, AreaL, IdLinha).
artigo3(NmProf, TpAutoria, TitArt, ResArt, AnoArt, Evento, Aceito,
AnoSub) :artigo2(TitArt, ResArt, AnoArt, _, _, Evento, Aceito, AnoSub,
IdArt),
prof_artigo(NmProf, _, _, TpAutoria, IdArt).
Tabela 25 – Predicado Artigo
Para encontrar os artigos publicados por um professor, utilizamos o predicado
artigo3 para realizar a consulta. Estamos passando como parâmetro o atributo “Aceito”
(Aceito) como „S‟, para que no resultado seja exibido apenas os artigos que foram
publicados, onde o professor seja autor ou co-autor.
1 ?- artigo3(NmProf, TpAutoria, TitArt, ResArt, AnoArt, Evento,
'S', AnoSub).
NmProf = 'Joaquim'
TpAutoria = 'C'
TitArt = 'Titulo 1'
ResArt = 'Resumo do Titulo 1'
AnoArt = '2005'
Evento = '3o Sei lá'
AnoSub = '2005' ;
NmProf = 'Joaquim'
TpAutoria = 'C'
TitArt = 'Titulo 2'
ResArt = 'Resumo do Titulo 2'
18
AnoArt = '2006'
Evento = 'Simpósio Nacional de Blá Blá Blá'
AnoSub = '2006' ;
NmProf = 'Gervásio'
TpAutoria = 'A'
TitArt = 'Titulo 2'
ResArt = 'Resumo do Titulo 2'
AnoArt = '2006'
Evento = 'Simpósio Nacional de Blá Blá Blá'
AnoSub = '2006' ;
NmProf = 'Maria'
TpAutoria = 'C'
TitArt = 'Tittulo 3'
ResArt = 'Resumo do Titulo 3'
AnoArt = '2004'
Evento = '4o Encontro de Blá Blá'
AnoSub = '2004' ;
NmProf = 'Sérgio'
TpAutoria = 'A'
TitArt = 'Titulo 4'
ResArt = 'Resumo do Titulo 4'
AnoArt = '2005'
Evento = 'Semana do Saco Cheio'
AnoSub = '2004' ;
NmProf = 'Maria'
TpAutoria = 'C'
TitArt = 'Titulo 4'
ResArt = 'Resumo do Titulo 4'
AnoArt = '2005'
Evento = 'Semana do Saco Cheio'
AnoSub = '2004' ;
NmProf = 'Luiz'
TpAutoria = 'C'
TitArt = 'Titulo 5'
ResArt = 'Resumo do titulo 5'
AnoArt = '2003'
Evento = 'Congresso de ETs'
AnoSub = '2003' ;
NmProf = 'Antonio'
TpAutoria = 'A'
TitArt = 'Titulo 5'
ResArt = 'Resumo do titulo 5'
AnoArt = '2003'
Evento = 'Congresso de ETs'
AnoSub = '2003' ;
Yes
2 ?Tabela 26 – Resposta Artigo Professor
Na execução abaixo, passamos também o parâmetro “Tipo de Autoria”
(TpAutoria) como „A‟ para limitar os resultados em apenas os artigos publicados dos
professores que foram autores destes artigos.
19
1 ?- artigo3(NmProf, 'A',TitArt,ResArt,AnoArt,Evento,'S',AnoSub).
NmProf
TitArt
ResArt
AnoArt
Evento
AnoSub
=
=
=
=
=
=
'Gervásio'
'Titulo 2'
'Resumo do Titulo 2'
'2006'
'Simpósio Nacional de Blá Blá Blá'
'2006' ;
NmProf
TitArt
ResArt
AnoArt
Evento
AnoSub
=
=
=
=
=
=
'Sérgio'
'Titulo 4'
'Resumo do Titulo 4'
'2005'
'Semana do Saco Cheio'
'2004' ;
NmProf
TitArt
ResArt
AnoArt
Evento
AnoSub
=
=
=
=
=
=
'Antonio'
'Titulo 5'
'Resumo do titulo 5'
'2003'
'Congresso de ETs'
'2003' ;
Yes
2 ?Tabela 27 – Resposta Artigo Professor Autoria
7. Em qual departamento um professor trabalha?
O predicado prof_depto é utilizado na consulta que resulta em qual
departamento um professor trabalha. Este predicado apresenta o atributo “Nome do
Professor” (NmProf) e “Nome do Departamento” (NmDepto).
prof_depto(NmProf, NmDepto) :professor(NmProf, _, IdDepto),
depto(NmDepto, IdDepto).
Tabela 28 – Predicado Professor x Departamento
Ao realizar a consulta com o predicado pro_depto, foram exibidos apenas os
atributos “Nome do Professor” (NmProf) e “Nome do Departamento” (NmDepto). No
caso de uma consulta específica, podemos passar como parâmetros tanto o Nome do
Professor como o Nome do Departamento, filtrando as informações de acordo com a
necessidade.
1 ?- prof_depto(NmProf, NmDepto).
NmProf = 'Antonio'
NmDepto = 'Departamento de Administração' ;
NmProf = 'Gervásio'
NmDepto = 'Departamento de Ciências Humanas' ;
NmProf = 'Joaquim'
NmDepto = 'Departamento de Ciências Humanas' ;
NmProf = 'Luiz'
NmDepto = 'Departamento de Administração' ;
20
NmProf = 'Maria'
NmDepto = 'Departamento de Informática' ;
NmProf = 'Sérgio'
NmDepto = 'Departamento de Informática' ;
Yes
2 ?Tabela 29 – Resposta – Professor x Departamento
8. Em quais cursos um professor trabalha?
Para o predicado prof_curso foi utilizados os predicados prof_disc, disciplina e
curso, estabelecendo os relacionamentos que são necessários. O predicado prof_curso
está exibindo os atributos “Nome do Professor”(NmProf) e “Nome do Curso”
(NmCurso).
prof_curso(NmCurso, NmProf) :prof_disc( NmProf, IdProf, NmDisc, IdDisc, IdHora),
disciplina(NmDisc, IdCurso, IdDisc),
curso(NmCurso, IdCurso, IdDepto).
Tabela 30 – Predicado Professor x Curso
Na execução da consulta no predicado prof_curso, estamos passando por
parâmetro o nome do professor para filtrar os cursos que o mesmo participa.
1 ?- prof_curso(NmCurso, 'Sérgio').
NmCurso = 'Ciência da Computação' ;
Yes
2 ?Tabela 31 – Resposta Professor x Curso
9. Em quais projetos um professor participa?
O predicado prof_projeto apresenta os atributos “Nome do Professor”
(NmProf), “Nome do Projeto” (NmProj), “Nome do Tema” (NmTema) e “Nome da
Área” (NmArea) e utiliza os predicados professor e projeto para obter o resultado quais
projetos um professor participa.
prof_projeto(NmProf, NmProj, NmTema, NmArea) :odbc_query(bdprolog, 'Select idprofessor, idprojeto from
professor_projeto', row(IdProf, IdProj)),
professor(NmProf, IdProf, _),
projeto(NmProj, NmTema, NmArea, IdProj).
Tabela 32 – Predicado Professor x Projeto
Podemos passar como parâmetro qualquer um dos atributos para estabelecer
algum filtro.
1 ?- prof_projeto(NmProf, NmProj, NmTema, NmArea).
NmProf = 'Sérgio'
21
NmProj = 'Projeto 1 - Grupo 1'
NmTema = 'Tema 1'
NmArea = 'Area 1' ;
NmProf
NmProj
NmTema
NmArea
=
=
=
=
'Maria'
'Projeto 1 - Grupo 1'
'Tema 1'
'Area 1' ;
Yes
2 ?Tabela 33 – Resposta Professor x Projeto
Pode-se verificar nos predicados e nas regras criadas, que o PROLOG é uma
linguagem eficiente e prática para a realização de consultas. Essa facilidade é uma das
causas que torna a linguagem muito utilizada na área de inteligência artificial entre
outras aplicações. Os predicados foram desenvolvidos e possibilitaram a realização de
todas as consultas. Em uma linguagem imperativa, tenderíamos a concentrar os esforços
diretamente nas cláusulas SQL, para que estas já retornassem os dados solicitados, de
acordo com os filtros repassados para a mesma. A linguagem lógica possibilita que os
predicados trabalhem para retornar a informação desejada, e se mostra muito eficiente
neste processo.
3 - Scheme
As implementações em uma linguagem funcional serão desenvolvidas em Scheme. Nos
próximos itens estaremos descrevendo como foi realizado o acesso ao banco de dados,
como foram obtidas algumas respostas para as questões mencionadas, e também
algumas limitações que não foram contornadas utilizando este linguagem.
3.1 - Conexão com Banco de Dados
Para a implementação utilizando a linguagem Scheme, utilizou-se um banco de
dados com a mesma estrutura do banco utilizado em MySql para o PROLOG (este
banco em Access também pode ser utilizado normalmente com os códigos PROLOG
detalhados no item anterior). A configuração da fonte de dados segue basicamente os
mesmos passos descritos na configuração para o PROLOG, no qual deve-se adicionar a
fonte desejada e especificar o banco a que ela deverá estar relacionada.
22
Figura 4 – Fonte de Dados para Access
Para a conexão do Scheme com o banco de dados, a seguinte cláusula deverá ser
incluída no código:
;; Carga do srpersist
(require (lib "srpersist.ss" "srpersist"))
Tabela 34 – Função de conexão
Este comando relaciona o arquivo srpersist.ss, que estará possibilitando a comunicação
com a base de dados utilizada. Sem o relacionamento com este arquivo, não é possível
realizar operações com acesso ao banco. Após isso, também exige-se a inclusão da
seguinte cláusula:
;; Antes de connectar-se a um banco, é necessário alocar um
'Environment Handle' e um 'Connection Handle'
(define henv (alloc-env))
(define hdbc (alloc-connect henv))
Tabela 35 – Alocação de 'Environment Handle' e um 'Connection Handle'
Por fim, deve-se incluir um comando que realizará uma chamada externa para que o
usuário esteja selecionando a fonte de dados à qual deseja se conectar (figura 5). Após
selecionada a fonte de dados, o programa encontra-se pronto para utilização.
23
Figura 5 – Seleção de Fonte de Dados
O comando que realiza esta chamada, é descrito abaixo:
; Chamada externa para identificar o drive ODBC
(driver-connect hdbc " " 'sql-driver-complete)
Tabela 36 – Chamada externa ao drive ODBC
3.3 - Implementação
Para a implementação com Scheme, também foi utilizado o esquema SQL
representado no item 1. Assim como em Prolog, as listas necessárias para a resolução
dos problemas vistos neste estudo de caso, foram criadas também através de scripts de
consulta SQL.
A função União, foi definida com a finalidade de auxiliar na construção das
listas a partir das consultas sql. A lista é criada a partir de uma varredura em todas as
tuplas resultantes da consulta, onde cada tupla, é criada uma nova lista, incluída na lista
ancestral. Na tabela abaixo, mostramos o código da função união.
(define (uniao a b)
(if (null? a)
b
(cons (car a) (uniao (cdr a) b))))
Tabela 37 – Função União
24
Para verificar quais os elementos que existem na lista, utilizamos a função
pertence?.
(define (pertence? x l)
(if (null? l)
#f
(if (equal? x (car l))
#t
(pertence? x (cdr l)))))
Tabela 38 – Função Pertence?
A função consul é utilizada em todas as questões para criar as listas de respostas. Esta
função trabalha de forma genérica, removendo todos os elementos que não fazem parte
da resposta.
(define consul
(lambda (chave tabela)
(cond
((null? tabela) '())
((pertence? chave (car tabela))
(cons (car tabela) (consul chave (cdr tabela))))
(else (consul chave (cdr tabela))) )))
Tabela 39 – Chamada e Execução do Script SQL
Para a realização de consultas em cada tabela criada em SQL, é utilizada a
função hstmt, exibida na tabela abaixo, que tem por objetivo retornar a conexão com o
banco para a execução da consulta. É repetida a definição desta função em cada
consulta realizada.
(define hstmt (alloc-stmt hdbc))
Tabela 40 – Função HSTMT
A chamada ao script SQL é realizada através da função prepare hstm, onde é
passada a consulta em SQL e é executada pela função sql-execute, conforme o exemplo
exibido na tabela 41.
(prepare hstmt "Select pesquisador, nome_prof from Professor order
by nome_prof")
(sql-execute hstmt)
Tabela 41 – Chamada e Execução do Script SQL
Para cada questão pré-definida, fizemos o uso de funções para a criação de
buffers para cada atributo resultante das consultas SQL, com seus respectivos tipos
associados. E também, utilizamos funções para a criação de indicadores para cada
atributo. E ainda, para a execução das rotinas fizemos uso de códigos semelhantes, onde
alterou apenas os buffers e os indicadores, criados para cada consulta, como poderá ser
visto nas especificações de cada questão.
25
3.3.1 - Questões pré-determinadas para a resolução do problema.
Na seqüência, são exibidos os códigos para geração impressão das listas criadas para
responder as perguntas definidas neste estudo de caso. Estas implementações fazem uso
das funções anteriormente especificadas.
1. Em quais horários um professor ministra aula?
Para criar a lista que responde a questão acima, a função prepare, para receber a
consulta SQL desta questão e a função sql-execute para executar esta consulta, como já
foi explicado. Estes códigos estão exibidos na tabela 42.
; Chamada para SQL
(prepare hstmt "SELECT p.nome_prof, h.horario, d.dia_sem
FROM professor AS p, professor_disciplina AS pd, horario AS h,
dia d WHERE (((p.idprofessor)=[pd].[idprofessor]) AND
((pd.idhorario)=[h].[idhorario]))and h.iddia=d.iddia
order by p.nome_prof")
(sql-execute hstmt)
Tabela 42 – Chamada e Execução do Script SQL – 1ª questão
Criação dos buffers e indicadores.
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmhora-buf (make-buffer 'sql-c-char 50))
(define nmdia-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmhora-ind (make-indicator))
(define nmdia-ind (make-indicator))
(define-struct r_prof (pesqui nmprof nmdia))
(define cria-lista (lambda (lista-i lista-c)
(cons lista-i (cria-lista ))))
(define resul_hora '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmhora-buf nmhora-ind)
(get-data hstmt 3 nmdia-buf nmdia-ind)
; Display dos atributos de professor em formatto de lista.
(display (list
(read-buffer nmprof-buf 0)
26
(read-buffer nmhora-buf 0)
(read-buffer nmdia-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmhora-buf 0)
(read-buffer nmdia-buf 0))
(set! resul_hora (uniao resul_hora (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmhora-buf 0)
(read-buffer nmdia-buf 0)))))
(free-buffer! nmprof-buf)
(free-buffer! nmhora-buf)
(free-buffer! nmdia-buf)
(loop)))
Tabela 43 – Buffers e Indicadores – 1ª questão.
Para obter a resposta a questão, executamos a função cônsul, onde são passados
os parâmetros o nome do professor “Sérgio” que será a chave para a consulta e a
função resul_hora que armazena, em formato de lista, todas as tuplas resultantes da
consulta SQL. A chamada a função e o resultado são exibidos na tabela 44.
> (consul "Sérgio" resul_hora)
(("Sérgio" "08:20 s 09:10" "Seg") ("Sérgio" "07:30 s 08:20" "Seg"))
>
Tabela 44 – Chamada da função cônsul e o resultado – 1ª questão.
2. Qual é o horário de uma disciplina?
Na tabela 45, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução.
; Chamada para SQL
(prepare hstmt "SELECT d.nome_disc, h.horario FROM disciplina AS d,
horario AS h, professor_disciplina AS pd WHERE
(((d.iddisciplina)=[d].[iddisciplina]) AND
((pd.idhorario)=[h].[idhorario])) ORDER BY d.nome_disc")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmdisc-buf (make-buffer 'sql-c-char 50))
(define nmhora-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmdisc-ind (make-indicator))
(define nmhora-ind (make-indicator))
(define resul_dischora '())
; Rotina de execução
(with-handlers
27
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmdisc-buf nmdisc-ind)
(get-data hstmt 2 nmhora-buf nmhora-ind)
; Display dos atributos de professor em formatto de lista.
(display (list
(read-buffer nmdisc-buf 0)
(read-buffer nmhora-buf 0)))
(newline)
(list
(read-buffer nmdisc-buf 0)
(read-buffer nmhora-buf 0))
(set! resul_dischora (uniao resul_dischora (list(list
(read-buffer nmdisc-buf 0)
(read-buffer nmhora-buf 0)))))
(free-buffer! nmdisc-buf)
(free-buffer! nmhora-buf)
(loop)))
Tabela 45 – Buffer, indicadores e rotinas de execução – 2ª questão.
Na execução da função consul, mostrada na tabela 46, passamos como
parâmetro “Linguagem” que faz a busca na lista resul_dischora resultante da
consulta SQL.
> (consul "Linguagem" resul_dischora)
(("Linguagem" "07:30 s 08:20")
("Linguagem" "20:10 s 21:00")
("Linguagem" "16:30 s 17:20")
("Linguagem" "07:30 s 08:20")
("Linguagem" "08:20 s 09:10")
("Linguagem" "22:10 s 23:00")
("Linguagem" "19:20 s 20:10")
("Linguagem" "10:30 s 11:20")
("Linguagem" "14:20 s 15:10")
("Linguagem" "09:40 s 10:30")
("Linguagem" "21:20 s 22:10 ")
("Linguagem" "13:30 s 14:20")
("Linguagem" "15:40 s 16:30"))
>
Tabela 46 – Chamada da função cônsul e o resultado – 2ª questão.
3. Quais professores são pesquisadores?
Função prepare e chamada a execução do SQL.
(prepare hstmt "Select pesquisador, nome_prof from Professor order
by nome_prof")
(sql-execute hstmt)
Tabela 47 – Chamada e Execução do Script SQL – 3ª questão
A tabela 48 mostra o código de criação do buffer e indicadores.
28
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define pesqui-buf (make-buffer 'sql-c-char 2))
(define nmprof-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define pesqui-ind (make-indicator))
(define nmprof-ind (make-indicator))
(define-struct r_prof (pesqui nmprof))
(define cria-lista (lambda (lista-i lista-c)
(cons lista-i (cria-lista ))))
(define resul_professor '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 pesqui-buf pesqui-ind)
(get-data hstmt 2 nmprof-buf nmprof-ind)
; Display dos atributos de professor em formatto de lista.
(display (list
(read-buffer pesqui-buf 0)
(read-buffer nmprof-buf 0)))
(newline)
(list
(read-buffer pesqui-buf 0)
(read-buffer nmprof-buf 0))
(set! resul_professor (uniao resul_professor (list(list
(read-buffer pesqui-buf 0)
(read-buffer nmprof-buf 0)))))
(free-buffer! pesqui-buf)
(free-buffer! nmprof-buf)
(loop)))
Tabela 48 – Buffers e Indicadores – 3ª questão.
Para obter a resposta a questão, executamos a função cônsul, onde são passados
os parâmetros “S”. A função resul_professor que é utilizada para guardar os armazenar
os valores durante a varredura em todas as tuplas da tabela. A chamada a função e o
resultado é exibido na tabela 49.
> (consul "S" resul_professor)
(("S" "Maria Conceição") ("S" "Sérgio"))
>
Tabela 49 – Chamada da função cônsul e o resultado de professor – 3ª questão.
29
4. Quais artigos um professor já escreveu?
Na tabela 50, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução.
; Chamada para SQL
(prepare hstmt "SELECT professor.nome_prof, artigo.titulo_art,
professor_artigo.tipo_autoria
FROM artigo, professor, professor_artigo
WHERE professor_artigo.idprofessor = professor.idprofessor and
professor_artigo.idartigo = artigo.idartigo and
professor_artigo.tipo_autoria='A' ORDER BY professor.nome_prof")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmarti-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmarti-ind (make-indicator))
(define-struct r_prof (pesqui nmprof))
(define cria-lista (lambda (lista-i lista-c)
(cons lista-i (cria-lista ))))
(define resul_artigo '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmarti-buf nmarti-ind)
; Display dos atributos de professor em formatto de lista.
(display (list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0))
(set! resul_artigo (uniao resul_artigo (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0)))))
(free-buffer! nmprof-buf)
30
(free-buffer! nmarti-buf)
(loop)))
Tabela 50– Buffer, indicadores e rotinas de execução – 4ª questão.
Na execução da função consul, mostrada na tabela 51, passamos como
parâmetro “Linguagem” que faz a busca na lista resul_artigo resultante da consulta
SQL.
> (consul "Sérgio" resul_artigo)
(("Sérgio" "Titulo 4"))
>
Tabela 51 – Chamada da função cônsul e o resultado – 4ª questão.
5. Quais artigos um professor já publicou?
Na tabela 52, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução.
; Chamada para SQL
(prepare hstmt "SELECT professor.nome_prof, artigo.titulo_art FROM
artigo, professor, professor_artigo WHERE
professor_artigo.idprofessor = professor.idprofessor and
professor_artigo.idartigo = artigo.idartigo ORDER BY
professor.nome_prof")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmarti-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmarti-ind (make-indicator))
(define-struct r_prof (pesqui nmprof))
(define cria-lista (lambda (lista-i lista-c)
(cons lista-i (cria-lista ))))
(define resul_artigo '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmarti-buf nmarti-ind)
31
; Display dos atributos de professor em formatto de lista.
(display (list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0))
(set! resul_artigo (uniao resul_artigo (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmarti-buf 0)))))
(free-buffer! nmprof-buf)
(free-buffer! nmarti-buf)
(loop)))
Tabela 52 – Buffer, indicadores e rotinas de execução – 5ª questão.
Na tabela 53 mostra a execução da função consul, passamos como parâmetro
“Sérgio” que faz a busca na lista resul_artigo resultante da consulta SQL.
> (consul "Sérgio" resul_artigo)
(("Sérgio" "Titulo 4"))
>
Tabela 53– Chamada da função cônsul e o resultado – 5ª questão.
6. Em qual departamento um professor trabalha?
Na tabela 54, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução.
; Chamada para SQL
(prepare hstmt "select p.nome_prof, d.nome_dpto from departamento
d, professor p where p.iddepartamento=d.iddepartamento order by
d.nome_dpto")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmdpto-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmdpto-ind (make-indicator))
(define resul_depto '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
32
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmdpto-buf nmdpto-ind)
; Display dos atributos de professor e departamento em formatto de
lista.
(display (list
(read-buffer nmprof-buf 0)
(read-buffer nmdpto-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmdpto-buf 0))
(set! resul_depto (uniao resul_depto (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmdpto-buf 0)))))
(free-buffer! nmprof-buf)
(free-buffer! nmdpto-buf)
(loop)))
Tabela 54 – Buffer, indicadores e rotinas de execução – 6ª questão.
Na tabela 55 mostra a execução da função consul, passamos como parâmetro
“Sérgio” que faz a busca na lista resul_depto resultante da consulta SQL.
> (consul "Sérgio" resul_depto)
(("Sérgio" "DepartamentoInformtica"))
>
Tabela 55– Chamada da função cônsul e o resultado – 6ª questão.
7. Em quais cursos um professor trabalha?
Na tabela 56, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução para a questão 7.
; Chamada para SQL
(prepare hstmt "select p.nome_prof, c.nome_cur from professor p,
curso c, disciplina d, professor_disciplina pd where
pd.iddisciplina=d.iddisciplina and pd.idprofessor=p.idprofessor and
d.idcurso=c.idcurso order by p.nome_prof")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmcurs-buf (make-buffer 'sql-c-char 50))
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmcurs-ind (make-indicator))
(define resul_curso '())
33
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmcurs-buf nmcurs-ind)
; Display dos atributos de professor e departamento em formatto de
lista.
(display (list
(read-buffer nmprof-buf 0)
(read-buffer nmcurs-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmcurs-buf 0))
(set! resul_curso (uniao resul_curso (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmcurs-buf 0)))))
(free-buffer! nmprof-buf)
(free-buffer! nmcurs-buf)
(loop)))
Tabela 56 – Buffer, indicadores e rotinas de execução – 7ª questão.
Na tabela 57 mostra a execução da função consul, passamos como parâmetro
“Sérgio” que faz a busca na lista resul_curso resultante da consulta SQL.
> (consul "Sérgio" resul_curso)
(("Sérgio" "CiênciaComputação") ("Sérgio" "CiênciaComputação"))
>
Tabela 57– Chamada da função cônsul e o resultado – 7ª questão.
8. Em quais projetos um professor participa?
Na tabela 58, mostramos as funções prepare, a criação dos buffers e indicadores,
e a rotina de execução.
; Chamada para SQL
(prepare hstmt "SELECT p.nome_prof, pj.nome_proj FROM professor AS
p, projeto AS pj, professor_projeto AS pp WHERE
p.idprofessor=pp.idprofessor and pj.idprojeto=pp.idprojeto ORDER BY
p.nome_prof")
(sql-execute hstmt)
; Informa o nro de colunas resultado do sql
(display (num-result-cols hstmt)) (newline)(newline)
; Criação de buffer para cada atributo do SQL com respectivo
formato (colocar na sequencia)
(define nmprof-buf (make-buffer 'sql-c-char 50))
(define nmproj-buf (make-buffer 'sql-c-char 50))
34
; --- comando obrigatório
; Criação de indicador para cada atributo do SQL
(define nmprof-ind (make-indicator))
(define nmproj-ind (make-indicator))
(define resul_proj '())
; Rotina de execução
(with-handlers
([(lambda (exn)
(exn-no-data? exn))
(lambda (exn)
(printf "~n*** Fim dos dados ***~n"))])
(let loop ()
(fetch hstmt)
(get-data hstmt 1 nmprof-buf nmprof-ind)
(get-data hstmt 2 nmproj-buf nmproj-ind)
; Display dos atributos de professor e do projeto.
(display (list
(read-buffer nmprof-buf 0)
(read-buffer nmproj-buf 0)))
(newline)
(list
(read-buffer nmprof-buf 0)
(read-buffer nmproj-buf 0))
(set! resul_proj (uniao resul_proj (list(list
(read-buffer nmprof-buf 0)
(read-buffer nmproj-buf 0)))))
(free-buffer! nmprof-buf)
(free-buffer! nmproj-buf)
(loop)))
Tabela 58 – Buffer, indicadores e rotinas de execução – 8ª questão.
Na tabela 59 mostra a execução da função consul, passamos como parâmetro
“Sérgio” que faz a busca na lista resul_ proj resultante da consulta SQL.
> (consul "Sérgio" resul_proj)
(("Sérgio" "Projeto1Grupo1"))
>
Tabela 59– Chamada da função cônsul e o resultado – 8ª questão.
35
4 - Conclusão
Trabalhar na busca de solução para um problema específico utilizando os
paradigmas lógico e funcional, permitiu pela prática, a inferência de muitos itens
que dizem respeito à importância, às diferenças, às dificuldades, facilidades e
características próprias de cada abordagem. No decorrer deste trabalho, percebemos
que mudar de paradigma é muito mais do que simplesmente aprender e
compreender uma nova linguagem de programação; a forma de pensar, de
raciocinar, de buscar a solução para um problema também tem de ser modificada.
Cada paradigma distinto, corresponde à uma forma particular de resolver e
representar um problema, e isto exige que a nossa capacidade de pensamento ajustese às formas de cada um.
Essa questão de „pensar diferente‟ contribui para que estejamos, não só
aprendendo a ver de várias formas a mesma solução para um problema, mas
também, a construir e elaborar estruturas de raciocínio, que nos permitam ver várias
soluções para um mesmo problema. Torna-se possível evoluir na forma como
costumamos abordar e propor soluções para os problemas de uma forma geral.
Nas experiências realizadas utilizando o paradigma funcional, a busca pela solução
ocasionou uma alteração radical em nossa forma „comum‟ de tratar um problema.
Foi necessária a definição de funções, a utilização de mecanismos de controle
recursivos ao invés de iterativos, e também, uma série de procedimentos
completamente diferentes dos métodos utilizados nas linguagens imperativas (como
a não utilização de variáveis e de comandos de atribuição). No contexto do
problema, a linguagem funcional Scheme apresentou-se mais complexa para se
aprender e implementar, porém, as respostas para as perguntas realizadas puderam
ser obtidas através da criação de uma única função, criada para trabalhar com uma
lista que disponibiliza as informações acessadas na base de dados.
Considerando-se as implementações efetuadas utilizando o paradigma da
programação em lógica, o seu desenvolvimento exigiu um meio totalmente diferente
de codificação, porém, menos conflitante com nossa capacidade e com nosso
costume de raciocinar sobre os problemas do mundo real. Na abordagem lógica, a
representação do problema a ser resolvido deve ser expressa na forma de lógica
simbólica, e um programa não é caracterizado por uma seqüência de operações
como é o caso das linguagens imperativas, e sim por uma „base de conhecimento‟
relacionada ao domínio do problema, juntamente com as perguntas realizadas para a
mesma. As implementações realizadas em Prolog foram mais facilmente elaboradas
e construídas que em Scheme, porém, exigiram um volume de codificação
significativamente maior, visto que não é possível definir perguntas tão genéricas,
numa mesma proporção em que é possível criar funções deste tipo em uma
linguagem funcional.
Uma avaliação sobre as duas abordagens, exigiria a análise de um complexo
conjunto de fatores como domínio do problema, propósito da implementação,
conhecimento e experiência dos programadores etc, para então ser possível optar
por qual delas utilizar. Uma linguagem lógica é mais prática para retornar respostas
às perguntas realizadas (o caso do nosso problema), enquanto que uma linguagem
funcional seria mais indicada para implementações que exigem cálculo e operações
matemáticas mais complexas. Assim, no contexto da realização do trabalho,
podemos mencionar que as principais representações de cada paradigma são: as
"funções" aplicadas aos argumentos e que retornam os valores no caso do paradigma
36
funcional, e as "proposições", aceitas como verdadeiras em um certo domínio no
caso do paradigma lógico.
37
5 – Referencias Bibliográficas
BARANAUSKAS, Maria Cecília Calani; Procedimento, Função, Objeto ou Lógica?
Linguagens de Programação Vistas Pelos Seus Paradigmas; NIED UNICAMP; 1998.
CASANOVA, Marco A; GIORNO, Fernando A. C.; FURTADO, Antonio L.;
Programação em Lógica e a Linguagem Prolog; São Paulo, Ed. Edgard Blücher Ltda;
1987.
GHEZZI, Carlo; JAZAYERI, Mehdi. Programminf Language Concepts. 3 ed –
USA;1997.
PUC-RJ; http://www.inf.puc-rio.br/~roberto/icc/texto/icc.html; acessado em
novembro/2006.
SEBESTA, Robert W; Conceitos de linguagens de programação; 5 ed. – Porto Alegre,
Bookman; 2003.
VICENTE, André Abe; Apostila Prolog; http://www.inf.unioeste.br/~abvicente;
acessado em outubro/2006.
Download

Programação Funcional e Programação Lógica Uma