A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Elsa Carvalho 112 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Existe também.

Apresentações semelhantes


Apresentação em tema: "Elsa Carvalho 112 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Existe também."— Transcrição da apresentação:

1 Elsa Carvalho 112 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Existe também a função flatten que retorna a lista de valores que estão nos nós da árvores. A ordem pela qual este valores são compostos é, usualmente chamada, de inorder. Ou seja, o valor do nó de topo é colocado entre as listas correspondentes aos valores dos nós das sub-árvores esquerda e direita, que são ordenadas de forma similar. fun flatten Empty = [ ] | flatten (Tr (t1, a, t2)) = flatten t1 @ [a] @ flatten t2 Árvores com valores em todos os nós

2 Elsa Carvalho 113 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Se pretendermos uma ordem diferente para os valores da lista podemos definir as funções: fun preorder Empty = [ ] | preorder (Tr (t1, a, t2)) = [a] @ preorder t1 @ preorder t2 fun postorder Empty = [ ] | postorder (Tr (t1, a, t2)) = postorder t1 @ postorder t2 @ [a] Árvores com valores em todos os nós

3 Elsa Carvalho 114 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Podemos introduzir ainda uma função genérica sobre árvores (análoga a btreeop). Esta função recebe como argumento um valor constante, uma função g e uma árvore. A constante é retornada no caso da árvore ser Empty, caso contrário, a função g é usada para combinar os resultados do processamento recursivo das sub-árvores esquerda e direita: fun treeop c g Empty = c | treeop c g (Tr (t1, a, t2)) = g (treeop c g t1, a, treeop c g t2) Ao contrário da função btreeop, neste caso decidiu-se que a função g não está na forma curried, recebendo assim um triplo de argumentos. Árvores com valores em todos os nós

4 Elsa Carvalho 115 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Usualmente estas árvores são usadas quando se pretende manter uma colecção de items ordenados e o uso de uma lista torna as inserções muito caras e consequentemente ineficientes. Podemos comprovar este facto pela análise da implementação de um algoritmo de ordenação de árvores, que é usado para ordenar listas. O algoritmo é semelhante a uma mistura do quicksort com o insert sort, onde é usada uma árvore para organizar o posicionamento dos elementos. À medida que a árvore é percorrida, os elementos são inseridos na posição correcta e assim, quando a árvore é achatada (flatten) a lista resultante está ordenada. Árvores com valores em todos os nós

5 Elsa Carvalho 116 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) fun treeinsert Empty m = leaf m | treeinsert (Tr (t1, n, t2)) m = if (lessthan n) m(i.e. m<n) then Tr (treeinsert t1 m, n, t2) else Tr (t1, n, treeinsert t2 m) fun treesort x = flatten (accumulate treeinsert Empty x) A ordenação funciona da seguinte forma: começa por receber uma árvore vazia vai acumulando os elementos na árvore, através da função treeinsert, com cada elemento da lista recebida como argumento, de cada vez. Árvores com valores em todos os nós

6 Elsa Carvalho 117 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) As árvores intermédias estão sempre ordenadas porque se começa a partir da lista vazia, usando apenas a função treeinsert que preserva a ordem. A lista final é obtida simplesmente por achatamento da árvore assim obtida. Árvores com valores em todos os nós

7 Elsa Carvalho 118 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Introduz-se agora uma notação para listas que não é standard ML. Essa notação é chamada ZF e permite denotar de forma sucinta aquelas listas que resultam da aplicação encadeada das funções map, link e filter, embora tenha correspondência na notação standard. Um caso em que esta notação se torna muito conveniente é o da função permutations que será apresentada como exemplo.

8 Elsa Carvalho 119 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas A forma mais simples que a notação ZF pode assumir é: [E | V 1 E 1 ] em que E 1 é uma expressão do tipo lista onde a variável V 1 toma valores. Por sua vez E é uma expressão em que V 1 pode ocorrer. Para cada valor possível para V 1 tem-se o valor correspondente para E. Ao componente da forma V 1 E 1 dá-se o nome de gerador uma vez que este é usado para gerar a lista de valores para V 1 a partir da lista denotada por E 1. A expressão completa é chamada de lista em compreensão, mas a notação é também conhecida por notação ZF, que vem do nome Zermelo-Fraenkel.

9 Elsa Carvalho 120 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Um exemplo da notação ZF será: [2*x | x 1 upto 5] que denota a lista [2*1, 2*2, 2*3, 2*4, 2*5] = [2, 4, 6, 8, 10] Podemos também definir a função sum usando a notação ZF. A função sum recebe uma função g e soma os valores g(y), em que y varia de 0 a x. fun sum g x = sumlist [g y | y 0 upto x]

10 Elsa Carvalho 121 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas A notação ZF pode ser generalizada da seguinte forma: [E | V 1 E 1 ; V 2 E 2 ;...; V n E n ] Aqui cada uma das variáveis locais Vi toma valores na lista que lhe corresponde E i e E pode envolver ocorrências de todos os V i s. Além disso cada E i pode envolver ocorrências dos V j s precedentes (1 j < i). Assim, o verdadeiro significado é que E i pode depender dos valores tomados por V 1, V 2,..., V i-1. Por exemplo [x* y | x 1 upto 20; y 1 upto x] denota a lista [1*1, 2*1, 2*2,..., 20*1,..., 20*20]

11 Elsa Carvalho 122 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Para encontrar a lista denotada por expressões do tipo indicado basta fixar uma a uma as variáveis V 1, V 2,... fazendo variar as de índice mais elevado. Eis um exemplo que se torna muito difícil de expressar se não usarmos a notação ZF. A função permutations calcula todas as permutações dos elementos de uma lista, retornando uma lista de listas. Faz-se ainda uso de uma função infixa - - que remove a primeira ocorrência de um dado elemento de uma lista.

12 Elsa Carvalho 123 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas fun permutations [] = [[]] | permutations x = [a::y | a x, y permutations (x - - a)] infix - - fun [] - - a = [] | (a::x) - - a = x | (b::x) - - a = b::(x - - a) - - : = list X = = list permutations: = list ( = list) list

13 Elsa Carvalho 124 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas permutations: = list ( = list) list - - : = list X = = list A lista de permutações de uma lista vazia é [[]], uma vez que [] é uma permutação da lista vazia. Para uma lista não vazia x, as permutações são calculadas como todas as listas da forma a::y onde a é um elemento de x e y é uma permutação de x tendo sido removido o elemento a.

14 Elsa Carvalho 125 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Outra extensão útil da notação ZF é permitir condições para qualificar um gerador para que os elementos da lista gerada que não satisfaçam a condição sejam filtrados. Assim um gerador pode ter a forma V i E i ; B onde a condição B será uma expressão booleana, envolvendo algumas variáveis dos geradores precedentes (V 1,..., V i ). Por exemplo fun ordcart x y = [(a,b) | a x; b y; a < b] ordcart: int list int list (int x int) list define a lista de pares da forma (a, b), tal que a vem de x, b vem de y e a < b.

15 Elsa Carvalho 126 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Para traduzir (expandir) listas na notação ZF para ML, basta compreender o significado da referida notação. Assim, uma possível correspondente em ML da expressão [E | V 1 E 1 ] é dada por map (fn V 1 E) E 1 que não é mais do que a lista de possíveis valores que E toma quando o parâmetro da função anónima, V 1, é substituído pelos valores da lista E 1 via map.

16 Elsa Carvalho 127 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas Generalizando, para encontrar a correspondente em ML da expressão [E | V 1 E 1 ; V 2 E 2 ;...; V n E n ] basta notar que esta expressão é quase equivalente a (fixando V 1 ) [[E | V 2 E 2 ;...; V n E n ] | V 1 E 1 ] mas como esta expressão forma uma lista de listas, se utilizarmos a função link obtemos uma expressão exactamente equivalente à primeira: link [[E | V 2 E 2 ;...; V n E n ] | V 1 E 1 ]

17 Elsa Carvalho 128 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas E, fazendo uso da primeira regra enunciada tem-se link (map (fn V 1 [E | V 2 E 2 ;...; V n E n ]) E 1 ) Por último, a tradução de [E | V 1 E 1 ; V 2 E 2 ;...; V n E n ; B] é dada, naturalmente por filter B [E | V 1 E 1 ; V 2 E 2 ;...; V n E n ] em que B representa o predicado contido em B.

18 Elsa Carvalho 129 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Notação ZF para listas No caso do exemplo apresentado [(a,b) | a x; b y; a < b] em que B é a < b, B será o predicado par_ordenado definido da seguinte forma fun par_ordenado (x, y) = x < y e teremos a seguinte correspondência filter par_ordenado [(a,b) | a x; b y]


Carregar ppt "Elsa Carvalho 112 Universidade da Madeira Departamento de Matemática Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Existe também."

Apresentações semelhantes


Anúncios Google