Skip to main content

native/egglog_nif/src/run.rs

use std::time::Instant;

use egglog::{EGraph, ast::Command};

use crate::report::{add_output_report_stats, collect_reports, output_kind};
use crate::snapshot::{NativeSnapshot, build_snapshot};

pub type NativeRun = (
    Vec<(String, String)>,
    Vec<(String, i64)>,
    Vec<(String, String)>,
    NativeSnapshot,
    Vec<(String, Vec<(String, i64)>)>,
);

pub fn execute_program(
    egraph: &mut EGraph,
    program: &str,
    started: Instant,
    snapshot_format: &str,
    snapshot_max_functions: i64,
    snapshot_max_calls_per_function: i64,
    snapshot_inline_leaves: i64,
    snapshot_split_primitive_outputs: bool,
) -> Result<NativeRun, String> {
    let commands = if program.trim().is_empty() {
        Vec::new()
    } else {
        egraph
            .parse_program(None, program)
            .map_err(|err| err.to_string())?
    };

    execute_commands(
        egraph,
        commands,
        started,
        snapshot_format,
        snapshot_max_functions,
        snapshot_max_calls_per_function,
        snapshot_inline_leaves,
        snapshot_split_primitive_outputs,
    )
}

pub fn execute_commands(
    egraph: &mut EGraph,
    commands: Vec<Command>,
    started: Instant,
    snapshot_format: &str,
    snapshot_max_functions: i64,
    snapshot_max_calls_per_function: i64,
    snapshot_inline_leaves: i64,
    snapshot_split_primitive_outputs: bool,
) -> Result<NativeRun, String> {
    let outputs = if commands.is_empty() {
        Vec::new()
    } else {
        egraph
            .run_program(commands)
            .map_err(|err| err.to_string())?
    };

    let mut numeric_stats = vec![
        (
            "elapsed_native_us".to_string(),
            started.elapsed().as_micros() as i64,
        ),
        ("num_tuples".to_string(), egraph.num_tuples() as i64),
        ("output_count".to_string(), outputs.len() as i64),
    ];

    add_output_report_stats(&outputs, &mut numeric_stats);
    let report = collect_reports(&outputs);

    let encoded_outputs = outputs
        .iter()
        .map(|output| (output_kind(output).to_string(), output.to_string()))
        .collect();

    let snapshot = build_snapshot(
        egraph,
        snapshot_format,
        snapshot_max_functions,
        snapshot_max_calls_per_function,
        snapshot_inline_leaves,
        snapshot_split_primitive_outputs,
    )?;

    Ok((encoded_outputs, numeric_stats, Vec::new(), snapshot, report))
}