2024-11-26 01:49:47 +00:00
|
|
|
import { test, expect, describe } from "bun:test";
|
|
|
|
import {
|
|
|
|
abs1,
|
|
|
|
abs2,
|
|
|
|
app1,
|
|
|
|
app2,
|
|
|
|
arr,
|
|
|
|
convertToDebruijn,
|
2024-11-26 03:12:03 +00:00
|
|
|
evaluate,
|
2024-11-26 01:49:47 +00:00
|
|
|
infer,
|
2024-11-26 03:06:20 +00:00
|
|
|
parseExpr,
|
|
|
|
parseTy,
|
2024-11-26 01:49:47 +00:00
|
|
|
unitTy,
|
|
|
|
var1,
|
|
|
|
var2,
|
|
|
|
} from ".";
|
|
|
|
|
2024-11-26 03:06:20 +00:00
|
|
|
const kCombinator = `lam (x : ()) . lam (y : ()) . x`;
|
|
|
|
const kCombinatorTy = `() -> (() -> ())`;
|
|
|
|
|
|
|
|
const sCombinator = `lam (x : () -> (() -> ())) . lam (y : () -> ()) . lam (z : ()) . (x z) (y z)`;
|
|
|
|
|
|
|
|
describe("parser", () => {
|
2024-11-26 01:49:47 +00:00
|
|
|
test("K combinator", () => {
|
2024-11-26 03:06:20 +00:00
|
|
|
const parsed = parseExpr(kCombinator);
|
2024-11-26 01:49:47 +00:00
|
|
|
const expr = abs1("x", unitTy(), abs1("y", unitTy(), var1("x")));
|
2024-11-26 03:06:20 +00:00
|
|
|
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);
|
2024-11-26 01:49:47 +00:00
|
|
|
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", () => {
|
2024-11-26 03:06:20 +00:00
|
|
|
const expr = parseExpr(kCombinator);
|
2024-11-26 01:49:47 +00:00
|
|
|
const expr2 = convertToDebruijn(expr);
|
2024-11-26 03:06:20 +00:00
|
|
|
const ty = parseTy(kCombinatorTy);
|
2024-11-26 01:49:47 +00:00
|
|
|
|
|
|
|
expect(infer(expr2)).toEqual(ty);
|
|
|
|
});
|
|
|
|
|
2024-11-26 03:06:20 +00:00
|
|
|
test("K combinator negative", () => {
|
|
|
|
const expr = parseExpr(kCombinator);
|
2024-11-26 01:49:47 +00:00
|
|
|
const expr2 = convertToDebruijn(expr);
|
2024-11-26 03:06:20 +00:00
|
|
|
const ty = parseTy(`() -> (() -> (() -> ()))`);
|
2024-11-26 01:49:47 +00:00
|
|
|
|
|
|
|
expect(infer(expr2)).not.toEqual(ty);
|
|
|
|
});
|
|
|
|
});
|
2024-11-26 03:12:03 +00:00
|
|
|
|
|
|
|
describe("evaluate", () => {
|
|
|
|
test("simple", () => {
|
|
|
|
const expr = parseExpr(`(lam (x : ()) . x) ()`);
|
|
|
|
const expr2 = parseExpr(`()`);
|
|
|
|
|
|
|
|
expect(evaluate(convertToDebruijn(expr))).toEqual(convertToDebruijn(expr2));
|
|
|
|
});
|
|
|
|
});
|