Paradigma de Programação: o que é? A maioria das linguagens de programação são extensas e complexas e normalmente integram várias ideias. No entanto, cada linguagem baseia-se, usualmente, numa ideia central, ou paradigma. Um paradigma de programação é uma abordagem à tarefa de programar: - o que é um programa; - como são desenhados e escritos; - o que é que significam; - como é que atingem os objectivos a que se propõem. Um paradigma é uma ideia na sua forma pura; é materializada numa linguagem através de um conjunto de construções e de metodologias que as utilizam. As linguagens de programação podem, por vezes, combinar vários paradigmas. Universidade da Madeira Departamento de Matemática Elsa Carvalho 130 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Qual o objectivo de estudar vários paradigmas? O programador sabe escolher o paradigma cuja ideia base modele adequadamente o domínio do problema em questão. Facilita o processo de aprendizagem de novas linguagens e a forma de como, realmente, as utilizar. Paradigmas de Programação Imperativo Orientado a Objectos Funcional Lógico Universidade da Madeira Departamento de Matemática Elsa Carvalho 131 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Paradigma Imperativo (Manipula Memória) comandos e procedimentos que actuam sobre o estado da máquina as variáveis referem directamente células de memória um programa é um comando Linguagens de Programação C Pascal FORTRAN Cobol Universidade da Madeira Departamento de Matemática Elsa Carvalho 132 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Paradigma Orientado a Objectos (Manipula Memória) extensão do paradigma imperativo objectos enviam mensagens uns aos outros o envio de mensagens actua sobre o estado da máquina Linguagens de Programação C++ Java Smalltalk Universidade da Madeira Departamento de Matemática Elsa Carvalho 133 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Paradigma Funcional (Não Manipula Memória - Declarativo) teoria das funções matemáticas funções são aplicadas aos parâmetros e retornam um valor as variáveis são os parâmetros formais das funções um programa é uma função execução do programa = avaliar funções/expressões Linguagens de Programação Lisp ML Scheme Haskell Universidade da Madeira Departamento de Matemática Elsa Carvalho 134 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Paradigma Lógico (Não Manipula Memória - Declarativo) usa lógica de predicados como linguagem de programação um programa em lógica é formado por axiomas que indicam alguns factos sobre o mundo uma computação significa inferir consequências lógicas a partir dos factos expressos no programa as variáveis envolvidas são variáveis lógicas Linguagens de Programação PROLOG Godel Universidade da Madeira Departamento de Matemática Elsa Carvalho 135 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Paradigma Imperativo vs. Paradigma Declarativo Os paradigmas imperativos requerem a produção de programas que especifiquem COMO resolver o problema directa ou indirectamente através da execução de transições entre estados. Nos paradigmas declarativos um programa deve especificar: ou qual é a resposta para o problema (funcional) ou quais as relações que definem o problema (lógico) Universidade da Madeira Departamento de Matemática Elsa Carvalho 136 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Exemplo O seguinte exemplo ilustra a diferença entre o paradigma imperativo e o paradigma declarativo. Queremos escrever um programa que indique qual o comprimento de uma dada lista. Podemos dar uma especificação abstracta: SE lista é vazia SE lista não é vazia Universidade da Madeira Departamento de Matemática Elsa Carvalho ENTÃO comprimento = 0 ENTÃO comprimento = comprimento resto da lista + 1 137 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Exemplo (cont.) Com o paradigma imperativo: int length(List x) { int n = 0; while(!isEmpty(x)) { n = n + 1; x = tail(x); } return n; } Embora este algoritmo seja razoavelmente fiel à especificação, há dois pontos a salientar: O uso de estado O programa altera continuamente o estado de ‘x’ e ‘n’ para conseguir o resultado. Sequência Existe uma sequência clara de passos Universidade da Madeira Departamento de Matemática Elsa Carvalho 138 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Exemplo (cont.) Com o paradigma declarativo/funcional: int length(List x) { if(isEmpty(x)) return 0; else return length(tail(x)) + 1; } Declarativo significa que conseguimos obter o programa declarando unicamente a especificação de comprimento. Funcional significa uma função matemática pura, i.e., uma que recebe os argumentos e retorna um resultado – não existem efeitos secundários tais como a alteração do estado (conteúdo da memória). Universidade da Madeira Departamento de Matemática Elsa Carvalho 139 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Programação em Lógica: o que é ? A programação em lógica é um formalismo computacional que combina dois princípios centrais: usa lógica para expressar conhecimento usa inferência para manipular o conhecimento No contexto da resolução de problemas o primeiro princípio serve para representar suposições e conclusões, enquanto o segundo serve para estabelecer as conecções lógicas entre suposições e conclusões. Universidade da Madeira Departamento de Matemática Elsa Carvalho 140 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Programação em Lógica Axiomas (suposições) + Regras de Inferência Derivação de Teoremas (conclusões) Universidade da Madeira Departamento de Matemática Elsa Carvalho 141 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Programação em Lógica Ao descrevermos um estado de coisas no mundo real usamos, na maioria das vezes, frases declarativas como: (i) “Todas as mães gostam dos seus filhos” (ii) “A Maria é mãe e o Tiago é o seu filho” Aplicando algumas regras gerais de raciocínio, estas declarações podem ser usadas para tirar novas conclusões. Por exemplo, sabendo (i) e (ii) é possível concluir: (iii) “A Maria gosta do Tiago“ Universidade da Madeira Departamento de Matemática Elsa Carvalho 142 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Programação em Lógica As frases utilizadas descrevem algum universo de pessoas e algumas relações/propriedades dessas pessoas – como “ ... é mãe”, “... é filho de ...”, “... gosta de ...” – que podem ou não ocorrer com essas pessoas. Este exemplo reflecte a ideia principal da programação em lógica: descrever relações, possivelmente infinitas, entre objectos e aplicar o sistema de programação de maneira a chegar a conclusões como (iii). Universidade da Madeira Departamento de Matemática Elsa Carvalho 143 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Programação em Lógica No entanto, para que um computador trate de frases como as (i) (iii) a sintaxe dessas frases tem que ser definida com precisão! E ainda mais importante, as regras de raciocínio (ou inferência) – como a que permite inferir (iii) a partir de (i) e (ii) – têm de ser cuidadosamente formalizadas. Vamos proceder à definição da sintaxe!!! Universidade da Madeira Departamento de Matemática Elsa Carvalho 144 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão A linguagem de lógica de 1ª ordem é o conjunto de todas as frases que se conseguem construir de acordo com a seguinte gramática informal: Alfabeto constantes – maria, tiago, ... variáveis – X, Y, Z, ... funções – f, g, h, ... predicados – mae, filho_de, gosta, ... De notar que as constantes, funções e predicados começam com letra minúscula e as variáveis com maiúscula. Universidade da Madeira Departamento de Matemática Elsa Carvalho 145 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Termo Constantes e variáveis são termos; Um termo composto é uma função aplicada a uma sequência de um ou mais termos Termos compostos também são termos. Uma função é caracterizada pelo seu nome e pela sua aridade (nº de argumentos). f(t1, t2, …, tn) onde a função tem o nome f , a sua aridade é n e os ti’s são os seus argumentos. Universidade da Madeira Departamento de Matemática Elsa Carvalho 146 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Fórmula atómica é um predicado aplicado a um ou mais termos. filho_de(X, Y) empresta(brinquedo,tiago,anita) Um predicado que seja aplicado a n termos diz-se que tem aridade n. Nos exemplos acima filho_de tem aridade 2 e empresta tem aridade 3. Quantificadores universal - X (para todo o X) existencial - X (existe um X) onde X é uma qualquer variável. Universidade da Madeira Departamento de Matemática Elsa Carvalho 147 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Fórmula bem formada uma fórmula atómica é uma fórmula bem formada se W, W1 e W2 são fórmulas bem formadas as seguintes formas são fórmulas bem formadas W - a própria fórmula W - a sua negação W1 W2 - conjunção W1 W2 - disjunção (QX) W - onde Q é um quantificador W1 W2 - (W1 se W2) W1 W2 - (W1 se e só se W2) Universidade da Madeira Departamento de Matemática Elsa Carvalho 148 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Âmbito de um Quantificador Numa fórmula bem formada (QX)W o âmbito do quantificador (QX) é definido como sendo W. Diz-se que (QX) quantifica todas as ocorrências de X em W que não ocorram nem em nenhum quantificador em W nem dentro do âmbito de nenhum desses quantificadores Por exemplo, na fórmula (X)((X) A(X) B(X)) W Existem 3 ocorrências de X em W, mas o quantificador (X) apenas quantifica a que se encontra em B(X). Universidade da Madeira Departamento de Matemática Elsa Carvalho 149 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Âmbito de um Quantificador Diz-se que a ocorrência de uma variável X numa fórmula bem formada é ligada (ou muda) se e só se acontecer um dos seguintes casos: está dentro do âmbito de um quantificador (QX) que ocorre em W está num quantificador (QX) que ocorre em W Numa fórmula bem formada uma variável que não está ligada dizse livre. Universidade da Madeira Departamento de Matemática Elsa Carvalho 150 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão (Y)pai(Y, X) criança(X) Neste caso ambas as ocorrências de X ocorrem livres. Indique o âmbito de cada quantificador para a fórmula (X)(((X) p(X) (Y)p(Y) q(X)) (p(X) q(Y))) e diga quais os quantificadores que quantificam cada variável ligada, bem como as variáveis livres Universidade da Madeira Departamento de Matemática Elsa Carvalho 151 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Frase lógica (ou fórmula fechada) Fórmula bem formada em que todas as ocorrências de todas as variáveis são ligadas (X)((Y)pai(Y, X) criança(X)) “Todas as crianças têm um pai” Para a fórmula W = gosta(ana, X) gosta(X,Z) diz-se que gosta(ana,X) é o consequente de W, gosta(X,Z) é o antecedente de W Universidade da Madeira Departamento de Matemática Elsa Carvalho 152 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Literal Ou é uma fórmula atómica (literal positivo) ou uma fórmula atómica negada (literal negativo). gosta(ana, luis) gosta(ana, luis) Termo chão Termo que não contém variáveis. Fórmula chã Fórmula que não contém variáveis. Universidade da Madeira Departamento de Matemática Elsa Carvalho 153 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Lógica de 1ª Ordem - Revisão Uma instância de uma fórmula W é o resultado de substituir qualquer variável livre X1, X2,... por qualquer termo t1, t2,... A instância é representada por W{X1/t1, X2/t2,...} gosta(ana, luis) gosta(luis, pai(ana)) é uma instância de W, para a substituição W{X/luis, Z/pai(ana)} Instância chã da fórmula W é uma instância de W que não contém variáveis, como no exemplo acima. Universidade da Madeira Departamento de Matemática Elsa Carvalho 154 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal A forma clausal é uma das muitas formas normais da lógica de 1ª ordem e é a sub-linguagem em que os programas lógicos são escritos. As formas normais têm a característica de tornar a estrutura das frases mais regulares. Quaisquer frases que se possam inicialmente construir em lógica de 1ª ordem aquando da formulação de um problema, podem sempre ser convertidas em forma clausal sem qualquer perda de expressividade. Rescrever frases lógicas em forma clausal preserva modelos e consequências lógicas. Universidade da Madeira Departamento de Matemática Elsa Carvalho 155 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal Uma frase encontra-se na forma clausal se e só se tem a seguinte forma: <prefixo universal><matriz> O prefixo universal é um conjunto de quantificadores universais. A matriz é uma conjunção de fórmulas, livre de quantificadores, em que cada fórmula é uma disjunção de um ou mais literais. Universidade da Madeira Departamento de Matemática Elsa Carvalho 156 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal A seguinte frase encontra-se na forma clausal (XY)( (gosta(ana,X) gosta(X, pai(ana))) (gosta(ana, pai(ana))) (gosta(luis, pai(ana))) (gosta(X,Y) namora(X,Y)) ) Uma vez que temos a equivalência (X)(A B) (X)A (X)B pode-se rescrever a frase acima como um conjunto de frases implicitamente conjuntas, chamadas cláusulas. Universidade da Madeira Departamento de Matemática Elsa Carvalho 157 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal Assim temos { (X)( gosta(ana,X) gosta(X, pai(ana)) gosta(ana, pai(ana)) gosta(luis, pai(ana)) (X)(Y)( gosta(X,Y) namora(X,Y)) } Cada cláusula continua a ser uma frase na forma clausal. É habitual organizar os programas em lógica como um conjunto de cláusulas e apresentá-los no estilo simplificado (formato condicional): os quantificadores são omitidos e, em cada cláusula, a ocorrência de ‘ ’ é substituída pelo equivalente , de forma a que no consequente fiquem 0 ou 1 literais positivos e no antecedente fique a conjunção de 0 ou mais literais. Universidade da Madeira Departamento de Matemática Elsa Carvalho 158 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal Teremos a seguinte forma convencional gosta(ana,X) gosta(X, pai(ana)) gosta(ana, pai(ana)) gosta(luis, pai(ana)) gosta(X,Y) namora(X,Y) que é muito semelhante à forma como um programa é escrito na notação do Prolog. Universidade da Madeira Departamento de Matemática Elsa Carvalho 159 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Forma Clausal Cláusula definida: contém exactamente um literal positivo e zero ou mais literais negativos. Cláusula unitária positiva: cláusula definida com exactamente zero literais negativos. Cláusula negativa: contém zero ou mais literais negativos e nenhum literal positivo. Cláusula unitária negativa: cláusula negativa com exactamente um literal negativo. Cláusula vazia: cláusula negativa sem literais e é representada graficamente pelo símbolo . Cláusula indefinida: contém pelo menos dois literais positivos. Todas as cláusulas, excepto as indefinidas, são chamadas cláusulas de Horn. Universidade da Madeira Departamento de Matemática Elsa Carvalho 160 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Conversão para a Forma Clausal 1. Rescrever cada subfórmula W1 W2 como: (W1 W2) (W2 W1) 2. Rescrever cada subfórmula W1 W2 como: W1 W2 3. Distribuir todas as ocorrências de rescrevendo: (X)W como (X) W (X)W como (X) W (W1 W2) como W1 W2 (W1 W2) como W1 W2 W como W 4. Distribuir todas as ocorrências de rescrevendo: W (W1 W2) W1 (X)W2 W1 (X)W2 Universidade da Madeira Departamento de Matemática Elsa Carvalho como como como 161 (W W1) (W W2) (X)(W1 W2) (X)(W1 W2) Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05) Conversão para a Forma Clausal 5.Distribuir todas as ocorrências de rescrevendo: (X)(W1 W2) como (X)W1 (X)W2 6.Skolemização - eliminar todas as ocorrências de rescrevendo: (X1)...(Xn)(Y)W(Y)como (Y)W(Y) (X1)...(Xn)W(f(X1...Xn)) como W(c) O processo de Skolemização introduz novos símbolos de funções e constantes para fazer referência ao nome do Y que existe. 7.Se for possível voltar a aplicar o passo 5. A frase será uma conjunção de cláusulas. Para as apresentar como um conjunto de cláusulas implicitamente quantificadas (formato condicional) omitem-se todos os quantificadores universais e todas as ocorrências de e, em cada cláusula, substitue-se a ocorrência de ‘ ’ por , de forma a que no consequente fiquem 0 ou 1 literais positivos e no antecedente fique a conjunção de 0 ou mais literais. Universidade da Madeira Departamento de Matemática Elsa Carvalho 162 Programação em Lógica e Funcional (2000/01) (Actualizado em 2004/05)