Closes #26 - Added -i flag to select interpreter (lambda or debruijn) - Created debruijn package with Expression interface - Variable contains index and optional label - Abstraction contains only body (no parameter) - Application structure remains similar - Implemented De Bruijn reduction without variable renaming - Shift operation handles index adjustments - Substitute replaces by index instead of name - Abstracted Engine into interface with two implementations - LambdaEngine: original named variable engine - DeBruijnEngine: new index-based engine - Added conversion functions between representations - LambdaToDeBruijn: converts named to indexed - DeBruijnToLambda: converts indexed back to named - SaccharineToDeBruijn: direct saccharine to De Bruijn - Updated main to switch engines based on -i flag - All test samples pass with both engines Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
package debruijn
|
|
|
|
type Expression interface {
|
|
Accept(Visitor)
|
|
}
|
|
|
|
/** ------------------------------------------------------------------------- */
|
|
|
|
type Abstraction struct {
|
|
body Expression
|
|
}
|
|
|
|
func (a *Abstraction) Body() Expression {
|
|
return a.body
|
|
}
|
|
|
|
func (a *Abstraction) Accept(v Visitor) {
|
|
v.VisitAbstraction(a)
|
|
}
|
|
|
|
func NewAbstraction(body Expression) *Abstraction {
|
|
return &Abstraction{body: body}
|
|
}
|
|
|
|
/** ------------------------------------------------------------------------- */
|
|
|
|
type Application struct {
|
|
abstraction Expression
|
|
argument Expression
|
|
}
|
|
|
|
func (a *Application) Abstraction() Expression {
|
|
return a.abstraction
|
|
}
|
|
|
|
func (a *Application) Argument() Expression {
|
|
return a.argument
|
|
}
|
|
|
|
func (a *Application) Accept(v Visitor) {
|
|
v.VisitApplication(a)
|
|
}
|
|
|
|
func NewApplication(abstraction Expression, argument Expression) *Application {
|
|
return &Application{abstraction: abstraction, argument: argument}
|
|
}
|
|
|
|
/** ------------------------------------------------------------------------- */
|
|
|
|
type Variable struct {
|
|
index int
|
|
label string
|
|
}
|
|
|
|
func (v *Variable) Index() int {
|
|
return v.index
|
|
}
|
|
|
|
func (v *Variable) Label() string {
|
|
return v.label
|
|
}
|
|
|
|
func (v *Variable) Accept(visitor Visitor) {
|
|
visitor.VisitVariable(v)
|
|
}
|
|
|
|
func NewVariable(index int, label string) *Variable {
|
|
return &Variable{index: index, label: label}
|
|
}
|
|
|
|
/** ------------------------------------------------------------------------- */
|
|
|
|
type Visitor interface {
|
|
VisitAbstraction(*Abstraction)
|
|
VisitApplication(*Application)
|
|
VisitVariable(*Variable)
|
|
}
|