Semântica Denotacional Uma introdução ISBN 0-321-19362-8 Semântica denotacional • é um método formal para definir a semântica de linguagens de programação. • Interessa a: – projetista de linguagens, – quem escreve compiladores e – programadores. • Estes indivíduos têm critérios diferentes para julgar um método). Requisitos para método • deve ser conciso, não ambíguo, aberto à análise matemática, verificável mecanicamente, executável e legível dependendo do seu ponto de vista. • A semântica denotacional é uma tentativa de satisfazer a estes objetivos diversos. • É um método formal pois é baseado em fundamentos matemáticos bem entendidos e usa uma notação rigorosamente definida (meta-linguagem) Problema do programador • escrever um programa que irá transformar dados satisfazendo algumas propriedades ou asserções ´P´ em resultados satisfazendo ´Q´. • {P} programa {Q} Semântica Denotacional • A semântica denotacional reconhece a sutil diferença entre uma função – um conjunto de pares ordenados possivelmente infinito {<entradai, saidai>}- e um algoritmo como uma descrição finita de uma função. Semântica Denotacional • Um programa é o algoritmo escrito em uma linguagem particular de programação. • Um programa define, ou denota, uma função. • Uma semântica denotacional de uma linguagem dá o mapeamento de programas na linguagem para a função denotada Exemplo: Fatorial = {<0,1>,<1,1>,<2,2>,<3,6>,<4,24>,...} Fat = if n =0 then 1 else n * fat(n-1) Uma boa semântica deve confirmar que o programa denota a função fatorial. Descrição da Semântica denotacional • é escrita em λ-notação que é o cálculo λ de Church com tipos de dados. • O método é conciso e poderoso o suficiente para descrever as características das linguagens de programação atuais. • Definições formais só são legíveis com prática, sendo a notação equivalente a uma linguagem de programação poderosa mas difícil de ler. • É mais adequada ao projetista e implementador de uma linguagem de programação que ao programador. Vantagens da Semântica denotacional • Pode ser mecanizada • Mosses desenvolveu um interpretador para semântica denotacional que permite que uma definição seja executada. • Algumas linguagens funcionais tais como ML são muito próximas da notação λ com tipo, e podem ser usadas para escrever e executar definições denotacionais Exemplo • de números decimais é apresentado. Os números decimais formam uma linguagem, Num, sobre o alfabeto {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. Ela pode ser definida pela gramática ν ::= ν δ|δ δ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 Exemplo • O símbolo ::= pode ser lido como “é” ou “pode ser substituído por”. • O “|” pode ser lido como “ou”. • Um dígito δ é um 0, ou um 1, ou um 2, e assim por diante. • Um numeral é simples dígito ou um numeral seguido de um dígito. • As letras gregas ν e δ são variáveis sintáticas sobre partes da linguagem Num. números decimais • são normalmente tomados por significarem, ou denotarem, inteiros que são objetos abstratos. Esta interpretação convencional pode ser feita formalmente pela definição de uma função de valoração V Função de valoração V V: Num → Int V [ν δ] = 10 x V[ν] + V[δ] • V[0] =0 • V[1] =1 • V[2] =3 • V[3] =3 • V[4] =4 • V[5] =5 • • • • V[6] =6 V[7] =7 V[8] =8 V[9] =9 • V é uma função das sentenças da linguagem Num para os inteiros Int. V é definido por uma análise caso a caso das alternativas da gramática para Num. • Elementos da linguagem estão dentro de chaves para distingui-los da meta linguagem fora. • Dentro das chaves estão seqüências de caracteres (strings). • Os inteiros fora das chaves estão em itálico. – 7 é um caracter que denota o inteiro 7. valor de um numeral em particular pode agora ser calculado V[123] = 10 x V[12] + 3 = 10 x (10x V[1]+2)+3 = 123 E daí? Não é óbvio? • devemos estar satisfeitos pela definição formal concordar com a intuição em casos simples. • Esta é uma característica de boas teorias. O • formalismo é necessário quando a intuição não é forte o suficiente. • O leitor que não percebe que 7 = ‘7’ não apenas não é verdadeiro mas é um erro em diversas LP (ex Pascal), pode ter perdido o sentido. • Note que V capturou a essência da notação posicional, e que V[123] = V[0123] e assim por diante. Exemplo de uso (uso em compiladores) If ch in [‘0’..’9’] then Begin n:= ord(ch) – ord(‘0’); Ch:= nextch {retorna o próximo char e avança a entrada} While ch in [‘0’..’9’] do Begin n:= n*10 + ord[ch()- ord(‘0’); Ch := nextch; End End Exercício • • • • Se a definição de V é alterada para V [ν δ] = - 10 x V[ν] + V[δ] Quais são as novas características de V? Qual vantagem esta nova interpretação de Num tem?