Suponha que você estenda o Cálculo de construções com "furos" - ou seja, trechos incompletos de código que você ainda não preencheu. Gostaria de saber se existe um algoritmo para preencher essas funções automaticamente. Por exemplo (usando a sintaxe de Morte ):
Caso A:
λ (pred : ?)
-> λ (Nat : *)
-> λ (Succ : Nat -> Nat)
-> λ (Zero : Nat)
-> (Succ (pred Nat Succ Zero))
Nesta situação, um algoritmo de inferência de tipos pode identificar que ?
, obviamente, pode ser apenas ∀ (Nat : *) -> (Nat -> Nat) -> Nat -> Nat
porque pred
recebe Nat : *
, Succ : Nat -> Nat
, Zero : Nat
, e deve retornar Nat
, porque é o primeiro argumento Succ
.
Caso B:
(Id ? 4)
Onde 4 é codificado em λ e Id
é a função de identidade (ou seja, ∀ (t:*) -> λ (x:t) -> x
). Nessa situação, '?' É novamente claro ∀ (N:*) -> (N -> N) -> N -> N
, porque esse é o tipo de 4
.
Caso C:
(Id (Equals Nat 7 (add 3 ?)) (Refl 7))
Aqui, Equals
e Refl
são definidos de maneira semelhante a Idris. ?
obviamente só pode ser 4
, mas como você descobre isso? Uma maneira seria usar o fato de que ? : Nat
, e Nat
é um tipo que sabemos enumerar, para que possamos tentar tudo Nats
até verificar o tipo. Isso pode ser feito para qualquer tipo enumerável.
Caso D:
(Id (Equal Nat 10 (MulPair ?)) 10)
Aqui, ?
só pode ser do tipo Pair Nat
; ele tem apenas mais de uma resposta válida, porém: ele pode ser (Pair 10 1)
, (Pair 2 5)
, (Pair 5 2)
e (Pair 1 10)
.
Caso E:
(Id (Equal Nat 7 (Mul 2 ?)) 7)
Aqui, não há resposta válida, pois 7
não é um múltiplo de 2
.
Todos esses exemplos me fizeram perceber que podemos criar um algoritmo geral que identifica alguns padrões conhecidos e dá uma resposta escolhendo um algoritmo específico (inferência de tipo, força bruta etc.), como Wolfram Alpha descobre a estratégia certa para resolver um integral. Mas isso soa como uma abordagem de engenharia / codificada. Existe uma maneira básica de resolver esse problema? Existe algum estudo / área de pesquisa?