add (custom) de bruijn-y conversion and alpha equivalence check

This commit is contained in:
jackjohn7 2026-05-16 17:49:12 -05:00
parent 99a18df155
commit dde7cfc7a4
5 changed files with 164 additions and 3 deletions

48
test/BruijnSpec.hs Normal file
View file

@ -0,0 +1,48 @@
module BruijnSpec (spec) where
import Bruijn (toDeBruijn)
import Parser (Expr (Abstraction, Application, Variable))
import Test.Hspec
spec :: Spec
spec = do
describe "toDeBruijn" $ do
-- Free variables
it "leaves a lone free variable unchanged" $
toDeBruijn (Variable "x") `shouldBe` Variable "x"
it "leaves free variables in abstraction body unchanged" $
toDeBruijn (Abstraction "x" (Variable "y"))
`shouldBe` Abstraction "0" (Variable "y")
-- Single abstraction
it "converts bound variable in identity" $
toDeBruijn (Abstraction "x" (Variable "x"))
`shouldBe` Abstraction "0" (Variable "0")
it "leaves free variable in abstraction body unchanged" $
toDeBruijn (Abstraction "x" (Variable "z"))
`shouldBe` Abstraction "0" (Variable "z")
-- Nested abstractions
it "inner binder resolves to depth 1" $
toDeBruijn (Abstraction "x" (Abstraction "y" (Variable "y")))
`shouldBe` Abstraction "0" (Abstraction "1" (Variable "1"))
it "outer binder resolves to depth 0 from within nested scope" $
toDeBruijn (Abstraction "x" (Abstraction "y" (Variable "x")))
`shouldBe` Abstraction "0" (Abstraction "1" (Variable "0"))
it "outermost of three binders resolves correctly" $
toDeBruijn (Abstraction "x" (Abstraction "y" (Abstraction "z" (Variable "x"))))
`shouldBe` Abstraction "0" (Abstraction "1" (Abstraction "2" (Variable "0")))
-- Application
it "converts self-application" $
toDeBruijn (Abstraction "x" (Application (Variable "x") (Variable "x")))
`shouldBe` Abstraction "0" (Application (Variable "0") (Variable "0"))
it "converts independent scopes in application" $
toDeBruijn (Application (Abstraction "x" (Variable "x")) (Abstraction "y" (Variable "y")))
`shouldBe` Application (Abstraction "0" (Variable "0")) (Abstraction "0" (Variable "0"))
-- Alpha equivalence
it "alpha-equivalent terms produce identical output" $
toDeBruijn (Abstraction "x" (Variable "x"))
`shouldBe` toDeBruijn (Abstraction "y" (Variable "y"))