Ciência da Computação Teoria da Computação (ENG10395) Profa. Juliana Pinheiro Campos E-mail: [email protected] TEORIA DA COMPUTAÇÃO Funções recursivas Os formalismos usados para especificar algoritmos podem ser classificados nos seguintes tipos: • Operacional: define-se uma máquina abstrata baseada em estados, em instruções primitivas e na especificação de como cada instrução modifica cada estado. Ex: MT. • Axiomático: Associam-se regras às componentes da linguagem. As regras permitem afirmar o que será verdadeiro após a ocorrência de cada cláusula, considerando-se o que era verdadeiro antes da ocorrência. Ex: gramática. TEORIA DA COMPUTAÇÃO Funções recursivas • Denotacional ou funcional: Trata-se de uma função construída a partir de funções elementares de forma composicional, no sentido em que o algoritmo denotado pela função pode ser determinado em termos de suas funções componentes. Ex: funções recursivas parciais (de Stephen C. Kleene) e cálculo lambda (de Alonzo Church) TEORIA DA COMPUTAÇÃO Funções recursivas de Kleene (ou funções recursivas parciais) São funções construídas sobre 3 funções naturais básicas (funções recursivas primitivas): • natural zero visto como uma função • sucessor (de um número natural) • projeção (na realidade, uma família de funções, pois depende do n° de componentes, bem como de qual componente deseja-se projetar) juntamente com as seguintes operações: • substituição composicional (generaliza o conceito usual de composição de funções) TEORIA DA COMPUTAÇÃO Funções recursivas de Kleene (ou funções recursivas parciais) • recursão (definição de uma função em termos dela mesma) • minimização (busca, em um tempo finito, o menor valor para o qual uma certa condição ocorre) constituindo uma forma compacta e natural para definir muitas funções e suficientemente poderosa para descrever toda função intuitivamente computável. TEORIA DA COMPUTAÇÃO Definição por indução de funções recursivas Quando você aprendeu a operação de exponenciação pela primeira vez provavelmente foi da forma: xn= x . x . … . x (n vezes) Essa forma é bem simples de entender. Mais tarde você aprendeu uma definição própria por indução: x0= 1 xn+1= xn . x TEORIA DA COMPUTAÇÃO Definição por indução de funções recursivas Na sua forma mais simples, a definição de uma função f por indução a partir de uma outra função g é da forma f(0) = m f(n + 1) = g(f(n)) Para Associe 0 f(0) = m 1 f(1) = g(m) 2 f(2) = g(f(1)) ... A partir de agora, consideramos funções que podem ser obtidas usando a indução e a composição, começando por algumas que são obviamente computáveis. TEORIA DA COMPUTAÇÃO Definição das funções recursivas primitivas As funções primitivas são incontestavelmente computáveis. São elas: • Função constante zero fzero: N → N tal que, ∀ x Є N, fzero(x) = 0 • Sucessor sucessor: N → N tal que, ∀ x Є N, sucessor(x) = x + 1 • Projeção proj ki: Nk → N tal que ∀ (x1, …, xk) Є Nk, proj ki (x1, …, xk) = xi para 1 <= i <=k (retorna o i-esimo elemento de uma sequencia de k valores) Ex: proj33: N3→ N (projeção da 3ª componente de uma tripla) proj33(x, y, z) = z TEORIA DA COMPUTAÇÃO Definição das funções recursivas primitivas Elas são usadas para definir todas as outras funções recursivas parciais. Todas as funções tratadas serão sempre entre números naturais. Algumas vezes as projeções são chamadas funções de seleção. Proj11 é chamada de função identidade e escrita como id(x) = x. TEORIA DA COMPUTAÇÃO Operações básicas Composição (substituição composicional): Sejam as funções parciais: g: Nk → N e f1, f2, ..., fk: Nn →N. A função parcial: h: Nn → N é a substituição composicional de funções, ou simplesmente substituição de funções, definida a partir de g, f1, f2, ... fk como segue: h(x1, x2, ..., xn) = g(f1(x1, x2, ..., xn), f2(x1, x2, ..., xn), ... fk(x1, x2, ..., xn)) h é dita definida para (x1, x2, ..., xn) se, e somente se: fi(x1, x2, ..., xn) é definida para todo i Є {1,2,..., k} g(f1(x1, x2, ..., xn), f2(x1, x2, ..., xn), ... fk(x1, x2, ..., xn)) é definida TEORIA DA COMPUTAÇÃO Operações básicas Composição (substituição composicional): Exemplos: fum: sucessor(fzero) fdois: sucessor(fum) ftres: adição(fum, fdois) função constante um função constante dois função constante três OBS: Para qualquer número natural n a função constante pode ser definida como a aplicação de n vezes a função sucessor. TEORIA DA COMPUTAÇÃO Operações básicas Recursão primitiva Sejam as funções parciais: f: Nn →N e g: Nn+2 → N. A função parcial: h: Nn+1 → N é definida por recursão primitiva a partir de f e g como segue: h(x1, x2, ..., xn, 0 ) = f (x1, x2, ..., xn) h(x1, x2, ..., xn, y + 1) = g(x1, x2, ..., xn, y, h(x1, x2, ..., xn, y) A função parcial h é dita definida para (x1, x2, ..., xn, ) se, e somente se: f (x1, x2, ..., xn) é definida g(x1, x2, ..., xn, i, h(x1, x2, ..., xn, i) é definida para todo i Є {1,2,..., y} TEORIA DA COMPUTAÇÃO Operações básicas Recursão primitiva Exemplo: A adição é definida usando recursão primitiva: adição(x, 0) = id(x) adição(x, y+1) = proj33(x, y, sucessor(adição(x, y))) adição(3,2) = proj33(3, 1, sucessor(adição(3, 1))) = sucessor(adição(3, 1)) = sucessor(proj33(3, 0, sucessor(adição(3, 0)))) = sucessor(sucessor(adição(3, 0))) = sucessor(sucessor(3)) = sucessor(4) = 5 TEORIA DA COMPUTAÇÃO Operações básicas Minimização Seja f:Nn+1→N uma função parcial. A função parcial: h: Nn→N é fita definida por minimização de f e é tal que, ∀(x1, x2, ..., xn, y) Є Nn+1: h(x1, x2, ..., xn) = min{y | f(x1, x2, ..., xn, y) = 0 e, ∀z tal que z < f(x1, x2, ..., xn, z) é definida} y, A função h, para o valor (x1, x2, ..., xn) é definida como o menor natural y tal que f(x1, x2, ..., xn, y) = 0. Adicionalmente, a condição “∀z tal que z < y, f(x1, x2, ..., xn, z) é definida” garante que é possível determinar, em um tempo finito, se, para qualquer valor z menor do que y, f(x1, x2, ..., xn, z) é diferente de zero TEORIA DA COMPUTAÇÃO Operações básicas Minimização Exemplo: função número zero. Suponha a função constante fzero. Seja constZero o nº 0 nos naturais (não confundir com a função constante zero): constZero: 1 → N (função número zero constZero(*)= 0) Podemos representar também como constZero: → N Podemos definí-la por minimização da seguinte forma: constZero = min{y | fzero(y) = 0}. De fato, o menor natural y tal que fzero(y) = 0 é o 0. TEORIA DA COMPUTAÇÃO Funções recursivas Função recursiva total Como o próprio nome indica, função recursiva total nada mais é que uma função recursiva parcial que é total, ou seja, definida para todos os elementos do domínio. Como podemos ver, as seguintes classes de funções são equivalentes: funções recursivas parciais e funções turingcomputáveis; funções recursivas totais e funções turing-computáveis totais. TEORIA DA COMPUTAÇÃO Funções recursivas Operações limitadas Uma vez que estamos limitados aos números naturais, não podemos ter algumas operações convencionais como as operações de subtração e divisão. A subtração realizada em sala de aula é a subtração limitada m – n = máx{m – n, 0} A função divisão div(m, n):divisão inteira de m por n pode ser realizada convencionando que o resultado é nulo quando n = 0. TEORIA DA COMPUTAÇÃO Funções recursivas Predicado recursivo primitivo: é uma função recursiva parcial que assume somente os valores 0 e 1. Exemplo: função ezero: retorna 1 para o argumento 0 e 0, caso contrário. e_zero(0) = fum e_zero(n+1) = constZero TEORIA DA COMPUTAÇÃO Funções recursivas Predicado recursivo primitivo: Ex: função maior_ou_igual: maior_ou_igual(m,n) = 1 quando m >= n; e 0 caso contrário. maior_ou_igual (m, n) = e_zero(sub(n, m) Ex: E a função menor_que(m,n) como seria? menor_que(m, n) = fum – maior_ou_igual(m, n) OBS: A negação de qualquer predicado recursivo também é um predicado recursivo. TEORIA DA COMPUTAÇÃO Funções recursivas Predicado recursivo primitivo: Resumindo, se f e g são funções recursivas e p é um predicado recursivo, todos os três com o mesmo número de argumentos k, então a função definida por casos f(n1, …, nk) = g(n1, …, nk), se p(n1, …, nk); f(n1, …, nk) = h(n1, …, nk), caso contrário; também é recursiva primitiva, uma vez que pode ser reescrita como: f(n1, …, nk) = p(n1, …, nk) x g(n1, …, nk) + (1 - p(n1, …, nk)) x h(n1, …, nk) ; TEORIA DA COMPUTAÇÃO Referências Diverio, T. A.; Menezes, P. B.. Teoria da Computação: Máquinas Universais e Computabilidade. Porto Alegre: Sagra Luzzato, 2000. Carnielli, W. A.; Epstein, R. L.; Computabilidade, funções computáveis, lógica e os fundamentos da matemática. 2.ed. São Paulo: Editora UNESP, 2009.