let lambda f =
fun ~var_count ->
let var_name = sprintf "Var_%d" var_count in
(*
Here is the hack that makes nodes containing variables “semi-unique.”
[var_repr_fake] is a first version of the variable representation,
that we feed to the the function [f] a first time.
This resulting tree is used to create the real variable representation,
the first argument [applied_once] will be hashed to create a
unique-for-this-subtree identifier.
Finally get the normal [applied] subtree and feed it to [Tree.lambda].
*)
let var_repr_fake = fun ~var_count -> Tree.string var_name in
let applied_once = f var_repr_fake ~var_count:(var_count + 1) in
let var_repr = fun ~var_count -> Tree.variable applied_once var_name in
let applied = f var_repr ~var_count:(var_count + 1) in
Tree.lambda var_name applied