diff --git a/problemreductions-cli/src/commands/graph.rs b/problemreductions-cli/src/commands/graph.rs index e27caaaa..5468a9ae 100644 --- a/problemreductions-cli/src/commands/graph.rs +++ b/problemreductions-cli/src/commands/graph.rs @@ -375,6 +375,24 @@ pub(crate) fn variant_to_full_slash(variant: &BTreeMap) -> Strin } } +/// Build a hint string listing available variants for a problem name. +/// Returns an empty string if there is only one variant (nothing to disambiguate). +pub(crate) fn variant_hint_for(graph: &ReductionGraph, name: &str) -> String { + let variants = graph.variants_for(name); + if variants.len() <= 1 { + return String::new(); + } + let list: Vec = variants + .iter() + .map(|v| format!("{}{}", name, variant_to_full_slash(v))) + .collect(); + format!( + "\nTip: try specifying a variant. Available variants for {}:\n {}\n", + name, + list.join(", "), + ) +} + /// Format a problem node as **bold name/variant** in slash notation. /// This is the single source of truth for "name/variant" display. fn fmt_node(_graph: &ReductionGraph, name: &str, variant: &BTreeMap) -> String { @@ -550,8 +568,10 @@ pub fn path( out.emit_with_default_name("", &text, &json) } None => { + let variant_hint = variant_hint_for(&graph, &dst_spec.name); anyhow::bail!( - "No reduction path from {} to {}\n\n\ + "No reduction path from {} to {}\n\ + {variant_hint}\n\ Usage: pred path \n\ Example: pred path MIS QUBO\n\n\ Run `pred show {}` and `pred show {}` to check available reductions.", @@ -578,8 +598,10 @@ fn path_all( graph.find_paths_up_to(src_name, src_variant, dst_name, dst_variant, max_paths + 1); if all_paths.is_empty() { + let variant_hint = variant_hint_for(graph, dst_name); anyhow::bail!( - "No reduction path from {} to {}\n\n\ + "No reduction path from {} to {}\n\ + {variant_hint}\n\ Usage: pred path --all\n\ Example: pred path MIS QUBO --all\n\n\ Run `pred show {}` and `pred show {}` to check available reductions.", diff --git a/problemreductions-cli/src/commands/reduce.rs b/problemreductions-cli/src/commands/reduce.rs index 7e579ed6..f0a083d4 100644 --- a/problemreductions-cli/src/commands/reduce.rs +++ b/problemreductions-cli/src/commands/reduce.rs @@ -125,8 +125,10 @@ pub fn reduce( ); best_path.ok_or_else(|| { + let variant_hint = variant_hint_for(&graph, &dst_ref.name); anyhow::anyhow!( - "No witness-capable reduction path from {} to {}\n\n\ + "No witness-capable reduction path from {} to {}\n\ + {variant_hint}\n\ Hint: generate a path file first, then pass it with --via:\n\ pred path {} {} -o path.json\n\ pred reduce {} --via path.json -o reduced.json", @@ -196,4 +198,4 @@ pub fn reduce( Ok(()) } -use super::graph::variant_to_full_slash; +use super::graph::{variant_hint_for, variant_to_full_slash}; diff --git a/src/models/graph/isomorphic_spanning_tree.rs b/src/models/graph/isomorphic_spanning_tree.rs index ecf69e41..b624280e 100644 --- a/src/models/graph/isomorphic_spanning_tree.rs +++ b/src/models/graph/isomorphic_spanning_tree.rs @@ -195,7 +195,7 @@ pub(crate) fn canonical_model_example_specs() -> Vec => "num_vertices^num_vertices", + default IsomorphicSpanningTree => "2^num_vertices", } #[cfg(test)]