use rayon::prelude::*;
use crate::cost::scorer::profile_tasm;
use crate::cost::stack_verifier::verify_equivalent;
use crate::neural::model::vocab::Vocab;
pub struct RankedResult {
pub tasm_lines: Vec<String>,
pub cost: u64,
pub valid_count: usize,
pub total_count: usize,
}
pub fn validate_and_rank(
candidates: &[Vec<u32>],
vocab: &Vocab,
baseline_tasm: &[String],
seed: u64,
) -> Option<RankedResult> {
if candidates.is_empty() || baseline_tasm.is_empty() {
return None;
}
let results: Vec<Option<(Vec<String>, u64)>> = candidates
.par_iter()
.map(|token_ids| {
let tasm_lines = vocab.decode_sequence(token_ids);
if tasm_lines.is_empty() {
return None;
}
if !verify_equivalent(baseline_tasm, &tasm_lines, seed) {
return None;
}
let line_refs: Vec<&str> = tasm_lines.iter().map(|s| s.as_str()).collect();
let profile = profile_tasm(&line_refs);
Some((tasm_lines, profile.cost()))
})
.collect();
let valid_count = results.iter().filter(|r| r.is_some()).count();
let total_count = candidates.len();
let best = results
.into_iter()
.flatten()
.min_by_key(|(_, cost)| *cost)?;
Some(RankedResult {
tasm_lines: best.0,
cost: best.1,
valid_count,
total_count,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn validate_empty_candidates() {
let vocab = Vocab::new();
let result = validate_and_rank(&[], &vocab, &["push 1".into()], 42);
assert!(result.is_none());
}
#[test]
fn validate_empty_baseline() {
let vocab = Vocab::new();
let result = validate_and_rank(&[vec![3, 0]], &vocab, &[], 42);
assert!(result.is_none());
}
#[test]
fn validate_equivalent_candidate() {
let vocab = Vocab::new();
let baseline: Vec<String> = vec!["push 1".into(), "push 2".into(), "add".into()];
let candidates = vec![vec![5]]; let result = validate_and_rank(&candidates, &vocab, &baseline, 42);
assert!(result.is_some());
let r = result.unwrap();
assert_eq!(r.valid_count, 1);
assert_eq!(r.tasm_lines, vec!["push 3"]);
}
#[test]
fn validate_picks_cheapest() {
let vocab = Vocab::new();
let baseline: Vec<String> = vec!["push 3".into()];
let candidates = vec![
vec![5, 96], vec![5], ];
let result = validate_and_rank(&candidates, &vocab, &baseline, 42);
assert!(result.is_some());
let r = result.unwrap();
assert_eq!(r.valid_count, 2);
assert_eq!(r.tasm_lines, vec!["push 3"]);
}
#[test]
fn validate_rejects_invalid() {
let vocab = Vocab::new();
let baseline: Vec<String> = vec!["push 1".into(), "push 2".into(), "add".into()];
let candidates = vec![vec![6]]; let result = validate_and_rank(&candidates, &vocab, &baseline, 42);
assert!(result.is_none());
}
}