feat: only compute all free variables during a-conversion

This commit is contained in:
2025-12-28 02:07:14 -05:00
parent 4d81aca0b2
commit 0945cedf51
10 changed files with 36 additions and 3 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.gitignore vendored
View File

@@ -26,3 +26,5 @@ go.work.sum
.env
*.log
profile/

View File

@@ -13,5 +13,13 @@ thunk: it
saccharine: it
@ ./lambda.exe - < ./samples/saccharine.txt
prof:
@ go tool pprof -top profile/cpu.prof
graph:
@ go tool pprof -raw -output=profile/cpu.raw profile/cpu.prof
@ go tool pprof -svg profile/cpu.prof > profile/cpu.svg
@ open profile/cpu.svg
saccharineX: it
@ ./lambda.exe -x - < ./samples/saccharine.txt > saccharine.out

BIN
cmd/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"runtime/pprof"
"time"
"git.maximhutz.com/max/lambda/internal/cli"
@@ -14,6 +15,14 @@ import (
// Run main application.
func main() {
f, err := os.Create("profile/cpu.prof")
cli.HandleError(err)
defer f.Close()
err = pprof.StartCPUProfile(f)
cli.HandleError(err)
defer pprof.StopCPUProfile()
options, err := config.FromArgs()
cli.HandleError(err)

BIN
internal/.DS_Store vendored Normal file

Binary file not shown.

BIN
pkg/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,14 @@
package lambda
func IsFreeVariable(n string, e Expression) bool {
switch e := e.(type) {
case *Variable:
return e.Value == n
case *Abstraction:
return e.Parameter != n && IsFreeVariable(n, e.Body)
case *Application:
return IsFreeVariable(n, e.Abstraction) || IsFreeVariable(n, e.Argument)
default:
return false
}
}

View File

@@ -11,12 +11,12 @@ func Substitute(e *Expression, target string, replacement Expression) {
return
}
replacementFreeVars := GetFreeVariables(replacement)
if !replacementFreeVars.Has(typed.Parameter) {
if !IsFreeVariable(typed.Parameter, replacement) {
Substitute(&typed.Body, target, replacement)
return
}
replacementFreeVars := GetFreeVariables(replacement)
used := GetFreeVariables(typed.Body)
used.Merge(replacementFreeVars)
freshVar := GenerateFreshName(used)

BIN
pkg/saccharine/.DS_Store vendored Normal file

Binary file not shown.