mod codegen;
mod collector;
mod error;
pub use error::ExtractError;
use logicaffeine_kernel::Context;
use codegen::CodeGen;
use collector::collect_dependencies;
use std::collections::HashSet;
pub fn extract_program(ctx: &Context, entry: &str) -> Result<String, ExtractError> {
if !ctx.is_inductive(entry) && !ctx.is_definition(entry) && !ctx.is_constructor(entry) {
return Err(ExtractError::NotFound(entry.to_string()));
}
let deps = collect_dependencies(ctx, entry);
let sorted = topological_sort(ctx, &deps);
let mut codegen = CodeGen::new(ctx);
for name in &sorted {
if ctx.is_inductive(name) {
codegen.emit_inductive(name)?;
} else if ctx.is_definition(name) {
codegen.emit_definition(name)?;
}
}
Ok(codegen.finish())
}
fn topological_sort(ctx: &Context, deps: &HashSet<String>) -> Vec<String> {
let mut inductives = Vec::new();
let mut definitions = Vec::new();
for name in deps {
if ctx.is_inductive(name) {
inductives.push(name.clone());
} else if ctx.is_definition(name) {
definitions.push(name.clone());
}
}
inductives.extend(definitions);
inductives
}