• No results found

The Limits of Airpower

In document Luftmakt 1996 (sider 48-52)

Na programação funcional a função desejada é definida recorrendo à eventual definição de outras funções por abstracção funcional e à aplicação dessas funções e de outras funções predefinidas, eventualmente sobre listas ou mesmo outras funções.

Ao programarmos funcionalmente não utilizaremos a composição sequencial, comandos iterativos While e a memorização de valores em variáveis através de atribuições. As funções são utilizadas como argumento de outras funções (funcionais ou operadores). Para o conseguirmos recorremos aos funcionais Apply e Map.

Nesta secção optamos por nos referirmos em primeiro lugar ao Mathematica uma vez que consideramos que este apresenta melhores argumentos para abordar a programação funcional.

Mathematica:

O funcional Apply substitui a cabeça da expressão apresentada no segundo argumento pela função que consta no primeiro. Esta substituição é feita desde que a expressão seja não atómica.

Vejamos um exemplo da aplicação do funcional Apply.

Recorde-se que a lista {1,2,3,4} é representada em Mathematica por

List[1,2,3,4].

FullForm

@8

1, 2, 3, 4

<D

List

@

1, 2, 3, 4

D

Ao pretender obter a soma dos elementos que compõem a lista bastar-nos-ia substituir a cabeça List por Plus. Conseguimos fazê-lo facilmente aplicando o funcional

Apply.

Apply

@

Plus,

8

1, 2, 3, 4

<D

10

Ao pretender obter a definição de uma função que nos dê o factorial de um dado número inteiro não negativo teremos de utilizar um raciocínio semelhante ao anterior utilizando a multiplicação que em Mathematica se designa por Times.

Para calcular n! temos de construir uma lista com os números 1, 2, 3, ..., n. Ora podemos consegui-la utilizando a função Table.

Table

@

i,

8

i, 4

<D

8

1, 2, 3, 4

<

Assim somos levados à seguinte definição de fact.

fact=Function

@

n, Apply

@

Times, Table

@

i,

8

i, n

<DDD

;

fact

@

0

D

fact

@

5

D

120

Quanto ao funcional Map este faz com que uma dada função seja aplicada a todos os elementos de uma lista.

Map

@

g,

8

3, 5, 11

<D

8

g

@

3

D

, g

@

5

D

, g

@

11

D<

Posto isto podemos passar à definição funcional da função pertence.

A ideia subjacente a esta função é percorrer a lista e comparar um a um todos os elementos da lista com o elemento que queremos encontrar. Temos portanto de definir uma função que compare cada elemento da lista com o elemento que queremos pesquisar.

Depois obteremos uma lista composta por elementos que serão True ou False. A função pertence deverá dar True nos casos em que existe pelo menos um True na lista anterior. Daqui surge como imediata a aplicação da função Or.

Assim a definição para a função pertence poderá ser a seguinte.

pertence= Function

@8

w, x

<

,

Apply

@

Or, Map

@

Function

@

y, yŠ x

D

, w

DDD

; pertence

@8

1, 2, 3, 4

<

, 3

D

True pertence

@8

1, 2, 3, 4

<

, 0

D

False pertence

@8

1, 2, 3, 4

<

, 4

D

True pertence

@8

1, 2, 3, 4

<

, 7

D

False

Derive:

No Derive podemos utilizar a função MAP_LIST para distribuir a aplicação de uma função pelos elementos de listas e conjuntos.

Nos casos em que u é uma expressão envolvendo a variável x e c é um conjunto ou uma lista, MAP_LIST(u,x,c) avalia u(x) quando x é igual a cada um dos elementos de c e retorna um conjunto ou uma lista.

Podemos ainda aplicar a função MAP_LIST com mais do que três argumentos. Nesses casos é possível indicar onde deve começar a aplicação da função, onde deve terminar e qual o tamanho dos passos a dar.

PRODUCT. Tendo em conta esse facto podemos definir a função factorial como fact(n) :=PRODUCT(x, x, 1, n). Carregando em ENTER a nossa função fica registada

na nossa zona de trabalho como se segue.

Na definição da função pertence já sentimos a necessidade de utilizar a função

MAP_LIST à qual já fizemos referência. Neste caso particular a função anterior tem

por objectivo verificar se alguma das entradas da lista coincide com o elemento introduzido. Na definição da função pertence criamos uma função auxiliar de nome

ou_lista que permite o cálculo da disjunção dos elementos de uma lista composta pelas

constantes booleanas true ou false. Tal foi feito mediante a utilização de uma expressão condicional em que nos casos em que o elemento da lista era true era transformado em

1 e 0 nos restantes casos. Depois, somando os valores, e tendo em conta que a disjunção

de condições é verdadeira desde que exista pelo menos uma das condições que seja verdadeira, bastou impor que caso a soma fosse maior que 0 a função ou_lista desse

true. A definição para a função encontrada foi a seguinte: ou_lista(w) := IF( ΣΣΣΣ ( IF (y, 1, 0), y, w) > 0, true, false).

Para concluirmos a definição da nossa função temos de garantir que o argumento que é fornecido à função anterior lá chega nas condições pretendidas. Conseguimos isso pela comparação de cada entrada da lista original com o elemento do qual pretendemos saber se está ou não na lista para o que utilizamos o funcional MAP_LIST.

Maple:

Para conseguir definir funcionalmente a função factorial sentimos necessidade de definir localmente uma função a que chamamos sequencia cuja finalidade é a de simplesmente nos gerar o conjunto vazio quando o argumento da nossa função for zero. Isto fica a dever-se ao facto de seq( j, j =1 .. 0) não ser avaliado.

Caso não nos interessasse o caso do factorial de zero a nossa definição não necessitaria da função sequencia.

Vejamos que realmente nestas condições a função está de acordo com o que pretendíamos.

Para conseguir definir funcionalmente a função pertence seguimos aqui um raciocínio semelhante ao utilizado no Derive. Tal como lá, utilizamos uma função f que permite a comparação de cada elemento da lista com aquele que pretendemos saber se faz parte desta. Ao invocarmos a função pertence(w,x) onde w é a lista e x é o elemento, caso a função f encontre em w algum elemento que coincida com x este é transformado em 1 e nos restantes casos é alterado para 0. Posteriormente esses uns e zeros são adicionados permitindo que se obtenha true nos casos em que existia um (ou mais) elemento(s) iguais a x. Este é um método muito parecido com aquele que usamos para o Derive.

In document Luftmakt 1996 (sider 48-52)