use aufbau::typing::{Context, Type};
pub fn stlc_chain(n: usize) -> (String, Context) {
let type_names: Vec<_> = (0..=n).map(|i| format!("T{i}")).collect();
let mut f_ty = type_names[n].clone();
for i in (0..n).rev() {
f_ty = format!("{}->{}", type_names[i], f_ty);
}
let mut ctx = Context::new();
ctx.add("f".to_string(), Type::raw(&f_ty));
for (i, name) in (0..n).map(|i| (i, format!("x{i}"))) {
ctx.add(name, Type::raw(&type_names[i]));
}
let input = std::iter::once("f".to_string())
.chain((0..n).map(|i| format!("x{i}")))
.collect::<Vec<_>>()
.join(" ");
(input, ctx)
}
pub fn imp_block(n: usize) -> String {
let mut parts = vec!["{".to_string()];
for i in 0..n {
parts.extend([
"let".to_string(),
format!("v{i}"),
":".to_string(),
"Int".to_string(),
"=".to_string(),
(i + 1).to_string(),
";".to_string(),
]);
}
parts.push("}".to_string());
parts.join(" ")
}
pub fn arith_flat(n: usize) -> String {
(1..=n.max(1))
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join(" + ")
}
pub fn arith_nested(n: usize) -> String {
format!("{}{}{}", "(".repeat(n), 1, ")".repeat(n))
}