lamb/test/BruijnSpec.hs

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"))