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:
2026-01-16 19:36:05 -05:00
parent 1974ad582f
commit 528956b033
12 changed files with 621 additions and 9 deletions

View File

@@ -14,8 +14,20 @@ func FromArgs() (*Config, error) {
profile := flag.String("p", "", "CPU profiling. If an output file is defined, the program will profile its execution and dump its results into it.")
file := flag.String("f", "", "File. If set, read source from the specified file.")
output := flag.String("o", "", "Output. If set, write result to the specified file. Use '-' for stdout (default).")
interpreter := flag.String("i", "lambda", "Interpreter. The reduction engine to use: 'lambda' or 'debruijn'.")
flag.Parse()
// Validate interpreter flag.
var interpType Interpreter
switch *interpreter {
case "lambda":
interpType = LambdaInterpreter
case "debruijn":
interpType = DeBruijnInterpreter
default:
return nil, fmt.Errorf("invalid interpreter: %s (must be 'lambda' or 'debruijn')", *interpreter)
}
// Parse source type.
var source Source
if *file != "" {
@@ -52,5 +64,6 @@ func FromArgs() (*Config, error) {
Explanation: *explanation,
Profile: *profile,
Statistics: *statistics,
Interpreter: interpType,
}, nil
}