feat: add De Bruijn indexed reduction engine
Add a new interpreter option (-i debruijn) that uses De Bruijn indices for variable representation, eliminating the need for variable renaming during substitution. - Add -i flag to select interpreter (lambda or debruijn) - Create debruijn package with Expression types (Variable with index, Abstraction without parameter, Application) - Implement shift and substitute operations for De Bruijn indices - Add conversion functions between lambda and De Bruijn representations - Update CLI to support switching between interpreters - Add De Bruijn tests to verify all samples pass Closes #26
This commit is contained in:
44
pkg/convert/lambda_to_debruijn.go
Normal file
44
pkg/convert/lambda_to_debruijn.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"git.maximhutz.com/max/lambda/pkg/debruijn"
|
||||
"git.maximhutz.com/max/lambda/pkg/lambda"
|
||||
)
|
||||
|
||||
// LambdaToDeBruijn converts a lambda calculus expression to De Bruijn indexed form.
|
||||
// The context parameter tracks bound variables from outer abstractions.
|
||||
func LambdaToDeBruijn(expr lambda.Expression) debruijn.Expression {
|
||||
return lambdaToDeBruijnWithContext(expr, []string{})
|
||||
}
|
||||
|
||||
func lambdaToDeBruijnWithContext(expr lambda.Expression, context []string) debruijn.Expression {
|
||||
switch e := expr.(type) {
|
||||
case *lambda.Variable:
|
||||
name := e.Value()
|
||||
// Search for the variable in the context (innermost to outermost).
|
||||
for i := len(context) - 1; i >= 0; i-- {
|
||||
if context[i] == name {
|
||||
index := len(context) - 1 - i
|
||||
return debruijn.NewVariable(index, name)
|
||||
}
|
||||
}
|
||||
// Free variable: use a negative index to mark it.
|
||||
// We encode free variables with index = len(context) + position.
|
||||
// For simplicity, we use a large index that won't conflict.
|
||||
return debruijn.NewVariable(len(context), name)
|
||||
|
||||
case *lambda.Abstraction:
|
||||
// Add the parameter to the context.
|
||||
newContext := append(context, e.Parameter())
|
||||
body := lambdaToDeBruijnWithContext(e.Body(), newContext)
|
||||
return debruijn.NewAbstraction(body)
|
||||
|
||||
case *lambda.Application:
|
||||
abs := lambdaToDeBruijnWithContext(e.Abstraction(), context)
|
||||
arg := lambdaToDeBruijnWithContext(e.Argument(), context)
|
||||
return debruijn.NewApplication(abs, arg)
|
||||
|
||||
default:
|
||||
panic("unknown expression type")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user