import("util.lua") local f, g, a, b, c, d = Consts("f, g, a, b, c, d") local x = Var(0) local y = Var(1) assert(f(a):closed()) local F = f(g(x, a), f(b, f(x, c))) assert(F:has_free_vars()) assert(F:lift_free_vars(1) == f(g(y, a), f(b, f(y, c)))) print(F) print(F:instantiate{c, g(b)}) assert(F:instantiate{c, g(b)} == f(g(g(b), a), f(b, f(g(b), c)))) assert(F:instantiate(g(b)) == f(g(g(b), a), f(b, f(g(b), c)))) assert(F:lift_free_vars(1):instantiate{c, g(b)} == f(g(c, a), f(b, f(c, c)))) print(F:lift_free_vars(1):abstract(a)) assert(F:lift_free_vars(1):abstract(a) == f(g(y, x), f(b, f(y, c)))) assert(F:lift_free_vars(1):abstract(a):instantiate{c, d} == f(g(c, d), f(b, f(c, c)))) assert(F:lift_free_vars(1):abstract(a):instantiate{c, d}:abstract{c, b} == f(g(y, d), f(x, f(y, y)))) assert(F:lift_free_vars(1):lower_free_vars(1) == F) assert(F:lift_free_vars(0, 1):lower_free_vars(1, 1) == F)