use std::fmt::Write as _;
use std::sync::OnceLock;
use crate::self_source_graph::{
owned_file_count, owned_manifest_content_id, owned_source_files, owned_total_bytes, SourceGraph,
};
pub const SOURCE_GRAPH_PATH: &str = "self-source-graph.lino";
const SLICE_SIZE: usize = 6;
pub const SOURCE_GRAPH_TASK: &str =
"Translate the entire source code of our system to the links / meta language and \
back to source, and record the whole-repository source-to-links projection in \
Links Notation so we can recompile ourselves.";
const SOURCE_GRAPH_KEYWORDS: [&str; 3] = ["source graph", "source-graph", "recompile"];
#[must_use]
pub fn is_source_graph_task(prompt: &str) -> bool {
let lower = prompt.to_lowercase();
if SOURCE_GRAPH_KEYWORDS
.iter()
.any(|keyword| lower.contains(keyword))
{
return true;
}
let whole_source =
(lower.contains("entire") || lower.contains("whole") || lower.contains("all"))
&& lower.contains("source");
let to_links_and_back = lower.contains("links") && lower.contains("back");
whole_source && to_links_and_back
}
fn representative_slice() -> Vec<(&'static str, &'static str)> {
let files = owned_source_files();
let total = files.len();
let want = SLICE_SIZE.min(total);
if want == 0 {
return Vec::new();
}
let stride = (total / want).max(1);
(0..want)
.map(|index| files[(index * stride).min(total - 1)])
.collect()
}
fn cached_slice() -> &'static SourceGraph {
static SLICE: OnceLock<SourceGraph> = OnceLock::new();
SLICE.get_or_init(|| SourceGraph::compile(&representative_slice()))
}
#[must_use]
pub fn render_document() -> String {
let slice = cached_slice();
let mut out = String::from("self_source_graph\n");
let _ = writeln!(out, " engine meta_language");
let _ = writeln!(out, " language rust");
let _ = writeln!(out, " task translate_entire_source_to_links_and_back");
let _ = writeln!(out, " entire_source");
let _ = writeln!(out, " file_count {}", owned_file_count());
let _ = writeln!(out, " total_bytes {}", owned_total_bytes());
let _ = writeln!(
out,
" manifest_content_id \"{}\"",
owned_manifest_content_id()
);
let _ = writeln!(out, " round_trip_proof");
let _ = writeln!(out, " slice_size {}", slice.module_count());
let _ = writeln!(out, " slice_faithful_count {}", slice.faithful_count());
let _ = writeln!(
out,
" slice_fully_faithful {}",
slice.is_fully_faithful()
);
for line in slice.links_notation().lines() {
if line.is_empty() {
out.push('\n');
} else {
let _ = writeln!(out, " {line}");
}
}
format!("{}\n", out.trim_end())
}
#[must_use]
pub fn slice() -> SourceGraph {
cached_slice().clone()
}
#[must_use]
pub fn final_answer(document: &str) -> String {
let slice = cached_slice();
format!(
"Translated the entire source code of our system to the links / meta language and back: \
content-addressed all {files} owned source files under one manifest id, and verified a \
representative slice of {slice} modules round-trips byte-for-byte through the meta-language \
links network (the sole CST/AST engine here). The exhaustive whole-repository round-trip is \
the library invariant (SourceGraph::owned) — a real step toward recompiling ourselves. \
Nothing was written back; the projection is a read-only, auditable artifact.\n\n\
Generated document ({SOURCE_GRAPH_PATH}):\n\n{document}",
files = owned_file_count(),
slice = slice.module_count(),
document = document.trim_end(),
)
}