import { test, expect, describe } from "bun:test"; import { abs1, abs2, app1, app2, arr, convertToDebruijn, evaluate, infer, parseExpr, parseTy, unitTy, var1, var2, } from "."; const kCombinator = `lam (x : ()) . lam (y : ()) . x`; const kCombinatorTy = `() -> (() -> ())`; const sCombinator = `lam (x : () -> (() -> ())) . lam (y : () -> ()) . lam (z : ()) . (x z) (y z)`; describe("parser", () => { test("K combinator", () => { const parsed = parseExpr(kCombinator); const expr = abs1("x", unitTy(), abs1("y", unitTy(), var1("x"))); expect(parsed).toEqual(expr); }); test("S combinator", () => { const parsed = parseExpr(sCombinator); const expr = abs1( "x", arr(unitTy(), arr(unitTy(), unitTy())), abs1( "y", arr(unitTy(), unitTy()), abs1( "z", unitTy(), app1(app1(var1("x"), var1("z")), app1(var1("y"), var1("z"))), ), ), ); expect(parsed).toEqual(expr); }); }); describe("convertToDeBruijn", () => { test("K combinator", () => { const expr = parseExpr(kCombinator); const expr2 = abs2(unitTy(), abs2(unitTy(), var2(1))); expect(convertToDebruijn(expr)).toEqual(expr2); }); test("S combinator", () => { const expr = abs1( "x", arr(unitTy(), arr(unitTy(), unitTy())), abs1( "y", arr(unitTy(), unitTy()), abs1( "z", unitTy(), app1(app1(var1("x"), var1("z")), app1(var1("y"), var1("z"))), ), ), ); const expr2 = abs2( arr(unitTy(), arr(unitTy(), unitTy())), abs2( arr(unitTy(), unitTy()), abs2(unitTy(), app2(app2(var2(2), var2(0)), app2(var2(1), var2(0)))), ), ); expect(convertToDebruijn(expr)).toEqual(expr2); }); }); describe("infer", () => { test("K combinator", () => { const expr = parseExpr(kCombinator); const expr2 = convertToDebruijn(expr); const ty = parseTy(kCombinatorTy); expect(infer(expr2)).toEqual(ty); }); test("K combinator negative", () => { const expr = parseExpr(kCombinator); const expr2 = convertToDebruijn(expr); const ty = parseTy(`() -> (() -> (() -> ()))`); expect(infer(expr2)).not.toEqual(ty); }); }); describe("evaluate", () => { test("simple", () => { const expr = parseExpr(`(lam (x : ()) . x) ()`); const expr2 = parseExpr(`()`); expect(evaluate(convertToDebruijn(expr))).toEqual(convertToDebruijn(expr2)); }); });