Seguinte: Tipos Abstractos de Informação Acima: Dados Anterior: Combinações de Dados
Índice remissivo

Abstracção de Dados

A abstração de dados é uma forma de aumentar a modularidade. Se decidirmos implementar números racionais, teremos de pensar em combinar dois números--o numerador e o denominador, e de os tratar como um todo. Se não fosse possível considerar aquela combinação de números como uma abstração (um racional), toda a sua utilização seria extremamente difícil. Por exemplo, para se somar dois números racionais, seria necessário usar uma operação para o cálculo do númerador, e outra operação para o cálculo do denominador, em vez de se pensar numa operação genérica, soma-racional, que receberia dois argumentos-- dois racionais--e calcularia um terceiro número--um racional.

Para nos abstrairmos da complexidade de um número racional, devemos definir funções que os manipulam internamente. Podemos começar por definir uma função que constroi um número racional a partir do numerador e do denominador.

(defun racional (numerador denominador)
   (cons numerador denominador))

Para sabermos qual é o numerador ou o denominador de um dado número racional podemos definir:

(defun numerador (racional)
  (car racional))

(defun denominador (racional) (cdr racional))

Assim, já já podemos escrever a função que calcula a soma de dois racionais, usando a fórmula tex2html_wrap_inline3402 .

(defun +racional (r1 r2)
  (racional (+ (* (numerador r1) (denominador r2))
               (* (numerador r2) (denominador r1)))
            (* (denominador r1) (denominador r2))))

Para simplificar a escrita de racionais, podemos definir uma função que escreve um racional de acordo com uma convenção qualquer.

(defun escreve-racional (racional)
  (format t " a/ a" (numerador racional)
                    (denominador racional)))

Agora, já podemos calcular a seguinte expressão:

> (escreve-racional (+racional (racional 1 2) 
                               (racional 1 3)))
5/6

Exercício 34

Defina as restantes funções do tipo abstracto de informação racional: -racional, *racional, e /racional.

Resposta

Como se vê, tratamos um número racional como um só objecto, e separamos a parte do programa que usa racionais da parte que os implementa como pares de inteiros. Esta técnica designa-se por abstração de dados.

A abstração é a melhor maneira de lidar com a complexidade. A abstração de dados permite-nos isolar a utilização dos dados do modo como eles estão implementados, através da utilização de barreiras de abstração. Essas barreiras consistem em limitar a utilização dos dados a um pequeno conjunto de funções (racional, numerador e denominador) que escondem a maneira como eles estão implementados. Ao utilizador de um dado tipo de dados, apenas se diz quais as funções que ele pode usar para os manipular, e não qual o funcionamento das funções que implementam aquele tipo de dados.

Seguindo esta metodologia, se precisarmos de testar a igualdade de racionais, devemos escrever uma função que o faça usando apenas as funções de manipulação de racionais, i.e., racional, numerador e denominador:

(defun =racional (r1 r2)
  (and (= (numerador r1) (numerador r2))
       (= (denominador r1) (denominador r2))))

Exercício 35

A função que compara dois racionais não funciona correctamente para todos os casos. Assim,

> (=racional (racional 4 6) (racional 4 6))
t
> (=racional (racional 4 6) (racional 2 3))
nil

Qual é o problema? Como é que se pode resolver?

Resposta

Exercício 36

Escreva uma função que calcule o maior divisor comum entre dois números. Para isso, use o algoritmo de Euclides que diz que se r é o resto da divisão de a por b, então o maior divisor comum entre a e b é também o maior divisor comum entre b e r: mdc(a,b)=mdc(b,r). Como é natural, quando o resto é zero, o maior divisor comum é o próprio b.

Resposta

Exercício 37

Empregue o método de Euclides para reescrever a função racional de modo a só construir números na forma reduzida.

Resposta


Seguinte: Tipos Abstractos de Informação Acima: Dados Anterior: Combinações de Dados
Índice remissivo

Copyright António Leitão, 1995