Gramáticas e tipos sensíveis ao contexto

25

1) Qual é a relação entre tipagem estática e gramáticas formais?

2) Em particular, seria possível para um autômato limitado linear verificar se, digamos, um programa C ++ ou SML foi bem digitado? Um autômato de pilha aninhado?

3) Existe uma maneira natural de expressar regras de digitação estática em termos gramaticais formais?

Andrew Cone
fonte

Respostas:

20

Não é possível para os autômatos limitados lineares verificar se os programas C ++ e é improvável que o LBA verifique se os programas SML estão bem digitados. O C ++ possui um sistema de tipo Turing-completo, pois você pode codificar programas arbitrários como metaprogramas de modelo.

SML é mais interessante. Possui verificação de tipo decidível, mas o problema está EXPTIME-complete. Portanto, é improvável que um LBA possa verificá-lo, a menos que haja um colapso muito surpreendente na hierarquia de complexidade. A razão para isso é que o SML requer inferência de tipo e há famílias de programas cujo tamanho cresce muito mais rápido que o tamanho do programa. Como exemplo, considere o seguinte programa:

fun delta x = (x, x)        (* this has type 'a -> ('a * 'a), so its return value
                               has a type double the size of its argument *)

fun f1 x = delta (delta x)  (* Now we use functions to iterate this process *)
fun f2 x = f1 (f1 x)        
fun f3 x = f2 (f2 x)        (* This function has a HUGE type *)

Para sistemas do tipo mais simples, como C ou Pascal, acredito que é possível para um LBA verificá-lo.

Nos primeiros dias da pesquisa em linguagens de programação, as pessoas às vezes usavam gramáticas de van Wingaarden (também conhecidas como gramáticas de dois níveis) para especificar sistemas de tipos para linguagens de programação. Acredito que Algol 68 tenha sido especificado dessa maneira. No entanto, me disseram que essa técnica foi abandonada por razões essencialmente pragmáticas: tornou-se bastante difícil para as pessoas escreverem gramáticas que especificavam o que pensavam estar especificando! (Normalmente, as gramáticas que as pessoas escrevem geram idiomas maiores do que pretendiam.)

Atualmente, as pessoas usam regras de inferência esquemática para especificar sistemas de tipos, que é essencialmente uma maneira de especificar predicados como o ponto menos fixo de uma coleção de cláusulas de Horn. A satisfação das teorias de Horn de primeira ordem é indecidível em geral; portanto, se você deseja capturar tudo o que os teóricos do tipo fazem, o formalismo gramatical escolhido será mais forte do que é realmente conveniente.

Eu sei que tem havido algum trabalho no uso de gramáticas de atributos para implementar sistemas de tipos. Eles alegam que existem alguns benefícios de engenharia de software para essa escolha: a saber, gramáticas de atributo controlam o fluxo de informações muito estritamente, e me disseram que isso facilita a compreensão do programa.

Neel Krishnaswami
fonte
4

Até onde eu sei, a correção de tipos tende a ser indecidível para casos interessantes, de modo que gramáticas claramente formais não podem capturar todos os sistemas de tipos que você pode imaginar.

Eu sei que os principais geradores de compiladores permitem predicados arbitrários para regras que impedem que uma regra seja executada se o predicado não avaliar true, por exemplo { type(e1) == type(e2) } (expression e1) '+' (expression e2). Esse conceito pode ser facilmente formalizado; restrições apropriadas sobre os predicados permitidos podem gerar decidibilidade pelos LBAs.

kk+1

Rafael
fonte