30 lines
768 B
Go
30 lines
768 B
Go
package lambda
|
|
|
|
func Substitute(e *Expression, target string, replacement Expression) {
|
|
switch typed := (*e).(type) {
|
|
case *Variable:
|
|
if typed.Value == target {
|
|
*e = replacement
|
|
}
|
|
case *Abstraction:
|
|
if typed.Parameter == target {
|
|
return
|
|
}
|
|
|
|
replacement_free_vars := GetFreeVariables(replacement)
|
|
if !replacement_free_vars.Has(typed.Parameter) {
|
|
Substitute(&typed.Body, target, replacement)
|
|
return
|
|
}
|
|
|
|
used := GetFreeVariables(typed.Body)
|
|
used.Union(replacement_free_vars)
|
|
fresh_var := GenerateFreshName(used)
|
|
Rename(typed.Body, typed.Parameter, fresh_var)
|
|
Substitute(&typed.Body, target, replacement)
|
|
case *Application:
|
|
Substitute(&typed.Abstraction, target, replacement)
|
|
Substitute(&typed.Argument, target, replacement)
|
|
}
|
|
}
|