48 lines
2.1 KiB
Haskell
48 lines
2.1 KiB
Haskell
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"))
|