style: moved isViable to reducer

This commit is contained in:
2026-01-16 19:09:27 -05:00
parent cb4f42c91d
commit d9639ecc2b
2 changed files with 14 additions and 32 deletions

View File

@@ -1,30 +0,0 @@
package lambda
func IsViable(e *Expression) (*Abstraction, Expression, bool) {
if e == nil {
return nil, nil, false
} else if app, appOk := (*e).(*Application); !appOk {
return nil, nil, false
} else if fn, fnOk := app.abstraction.(*Abstraction); !fnOk {
return nil, nil, false
} else {
return fn, app.argument, true
}
}
func ReduceAll(e *Expression, step func()) {
it := NewIterator(e)
for !it.Done() {
if fn, arg, ok := IsViable(it.Current()); !ok {
it.Next()
} else {
it.Swap(Substitute(fn.body, fn.parameter, arg))
step()
if _, _, ok := IsViable(it.Parent()); ok {
it.Back()
}
}
}
}

View File

@@ -26,6 +26,18 @@ func (r *NormalOrderReducer) Expression() expr.Expression {
return r.expression return r.expression
} }
func isViable(e *Expression) (*Abstraction, Expression, bool) {
if e == nil {
return nil, nil, false
} else if app, appOk := (*e).(*Application); !appOk {
return nil, nil, false
} else if fn, fnOk := app.abstraction.(*Abstraction); !fnOk {
return nil, nil, false
} else {
return fn, app.argument, true
}
}
// Reduce performs normal order reduction on a lambda expression. // Reduce performs normal order reduction on a lambda expression.
// The expression must be a lambda.Expression; other types are returned unchanged. // The expression must be a lambda.Expression; other types are returned unchanged.
func (r *NormalOrderReducer) Reduce() { func (r *NormalOrderReducer) Reduce() {
@@ -33,13 +45,13 @@ func (r *NormalOrderReducer) Reduce() {
it := NewIterator(&r.expression) it := NewIterator(&r.expression)
for !it.Done() { for !it.Done() {
if fn, arg, ok := IsViable(it.Current()); !ok { if fn, arg, ok := isViable(it.Current()); !ok {
it.Next() it.Next()
} else { } else {
it.Swap(Substitute(fn.body, fn.parameter, arg)) it.Swap(Substitute(fn.body, fn.parameter, arg))
r.Emit(reducer.StepEvent) r.Emit(reducer.StepEvent)
if _, _, ok := IsViable(it.Parent()); ok { if _, _, ok := isViable(it.Parent()); ok {
it.Back() it.Back()
} }
} }