Skip to content

Commit 260c629

Browse files
committed
Merge main comment cleanup and format NAE-SAT reduction test
2 parents 43fb5e0 + 35f40b4 commit 260c629

485 files changed

Lines changed: 171 additions & 1854 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎docs/paper/reductions.typ‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,7 +2228,7 @@ In all graph problems below, $G = (V, E)$ denotes an undirected graph with $|V|
22282228
import draw: *
22292229
let blue = graph-colors.at(0)
22302230
let gray = luma(185)
2231-
// Layout for issue #813: path 0–1–3–2–4–5 with clear bends so $v_0,v_1,v_3$ are not collinear
2231+
// Bend the path so $v_0,v_1,v_3$ are not collinear.
22322232
// (otherwise $(0,3)$ lies on the same geometric line as $0 arrow.r 1 arrow.r 3$).
22332233
let verts = (
22342234
(0, 0),
@@ -17156,7 +17156,7 @@ The following table shows concrete target-variable counts for example instances,
1715617156
_Solution extraction._ First $n$ variables (sign variables) give the source configuration.
1715717157
]
1715817158

17159-
// === Non-ILP reduction rules (issue #974) ===
17159+
// === Non-ILP reduction rules ===
1716017160

1716117161
#reduction-rule("ILP", "ILP")[
1716217162
ILP variants convert between binary and bounded integer variable domains and between exact-integer and floating-point coefficients. The independent bounds dimension defaults to general; the bounded integer variant requires finite lower and upper endpoints for every variable. Binary variables embed into bounded integer ILP, which embeds into general integer ILP while retaining all stored bounds. A bounded integer variable is encoded by binary variables with truncated positional weights. Integer coefficients are embedded only when every stored coefficient and right-hand side has an exact `f64` representation.

‎problemreductions-cli/src/bin/pred_sym.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ fn main() {
122122
})
123123
.collect();
124124

125-
// Check for unbound variables
126125
let expr_vars = parsed.variables();
127126
let bound_vars: std::collections::HashSet<&str> =
128127
bindings.iter().map(|(name, _)| name.as_str()).collect();

‎problemreductions-cli/src/commands/create.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,7 @@ pub fn create(args: &CreateArgs, out: &OutputConfig) -> Result<()> {
353353
return create_registered_random(args, canonical, &resolved_variant, out);
354354
}
355355

356-
// ILP and CircuitSAT have complex input structures
357-
// not suited for CLI flags. Check before the empty-flags help so they get a
358-
// clear message.
356+
// ILP and CircuitSAT have complex input structures not suited for CLI flags.
359357
if canonical == "ILP" || canonical == "CircuitSAT" {
360358
bail!(
361359
"CLI creation is not yet supported for {canonical}.\n\n\

‎problemreductions-cli/src/commands/create/tests.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,6 @@ fn test_create_staff_scheduling_reports_invalid_schedule_without_panic() {
778778
let result = std::panic::catch_unwind(|| create(&args, &out));
779779
assert!(result.is_ok(), "create should return an error, not panic");
780780
let err = result.unwrap().unwrap_err().to_string();
781-
// parse_bool_rows catches ragged rows before validate_staff_scheduling_args
782781
assert!(
783782
err.contains("All rows") || err.contains("schedule 1 has 6 periods, expected 7"),
784783
"expected row-length validation error, got: {err}"

‎problemreductions-cli/src/commands/graph.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,6 @@ pub fn neighbors(
12591259
TraversalFlow::Both => "both directions",
12601260
};
12611261

1262-
// Build tree structure via BFS with parent tracking
12631262
let tree = graph.k_neighbor_tree(&spec_name, &variant, max_hops, direction);
12641263

12651264
out.emit(

‎problemreductions-cli/src/commands/inspect.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ pub fn inspect(input: &Path, out: &OutputConfig) -> Result<()> {
1111
let content = read_input(input)?;
1212
let json: serde_json::Value = serde_json::from_str(&content)?;
1313

14-
// Detect if it's a bundle or a problem
1514
if json.get("source").is_some() && json.get("target").is_some() && json.get("path").is_some() {
1615
let bundle: ReductionBundle = serde_json::from_value(json)?;
1716
inspect_bundle(&bundle, out)

‎problemreductions-cli/src/mcp/tests.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ fn deterministic_solver_dispatch_mcp_output_is_repeatable_for_each_solver_class(
473473
fn test_solve_bundle() {
474474
let server = McpServer::new();
475475
let problem_json = create_test_mis(&server);
476-
// Reduce first, then solve the bundle
477476
let bundle_json = server
478477
.reduce_inner(
479478
&problem_json,

‎problemreductions-cli/src/mcp/tools.rs‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ impl McpServer {
314314
)
315315
})?;
316316

317-
// Check for random generation
318317
let is_random = params
319318
.get("random")
320319
.and_then(|v| v.as_bool())
@@ -363,7 +362,6 @@ impl McpServer {
363362
pub fn inspect_problem_inner(&self, problem_json: &str) -> anyhow::Result<String> {
364363
let json: serde_json::Value = serde_json::from_str(problem_json)?;
365364

366-
// Detect if it's a bundle or a problem
367365
if json.get("source").is_some()
368366
&& json.get("target").is_some()
369367
&& json.get("path").is_some()
@@ -442,7 +440,6 @@ impl McpServer {
442440
let timeout_secs = u64::try_from(timeout.unwrap_or(0))
443441
.map_err(|_| anyhow::anyhow!("timeout must be a nonnegative i64"))?;
444442

445-
// Detect if it's a bundle or a problem
446443
let is_bundle = json.get("source").is_some()
447444
&& json.get("target").is_some()
448445
&& json.get("path").is_some();

‎problemreductions-cli/src/output.rs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ pub fn format_table(
115115
rows: &[Vec<String>],
116116
color_fns: &[Option<CellFormatter>],
117117
) -> String {
118-
// Compute actual column widths (max of header width, specified width, and data width)
119118
let widths: Vec<usize> = columns
120119
.iter()
121120
.enumerate()
@@ -127,7 +126,6 @@ pub fn format_table(
127126

128127
let mut text = String::new();
129128

130-
// Header
131129
text.push_str(" ");
132130
for (i, (header, align, _)) in columns.iter().enumerate() {
133131
if i > 0 {
@@ -140,7 +138,6 @@ pub fn format_table(
140138
}
141139
text.push('\n');
142140

143-
// Separator
144141
text.push_str(" ");
145142
for (i, _) in columns.iter().enumerate() {
146143
if i > 0 {
@@ -150,7 +147,6 @@ pub fn format_table(
150147
}
151148
text.push('\n');
152149

153-
// Data rows
154150
for row in rows {
155151
text.push_str(" ");
156152
for (i, (_, align, _)) in columns.iter().enumerate() {

‎problemreductions-macros/src/lib.rs‎

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,6 @@ fn option_inner_type(ty: &Type) -> Option<&Type> {
206206
/// - `transform = { exact { ... }, upper_bound { ... }, unavailable { ... } }` — per-field relations
207207
/// - `transform = unavailable { field = "reason", ... }` — no symbolic parameter transform
208208
/// - `unavailable = { field = "reason", ... }` — fields that cannot be propagated
209-
///
210-
/// ## Syntax
211-
/// ```ignore
212-
/// #[reduction(transform = exact {
213-
/// num_vars = "num_vertices^2",
214-
/// num_constraints = num_edges,
215-
/// })]
216-
/// ```
217-
///
218209
#[proc_macro_attribute]
219210
pub fn reduction(attr: TokenStream, item: TokenStream) -> TokenStream {
220211
let attrs = parse_macro_input!(attr as ReductionAttrs);
@@ -598,28 +589,22 @@ fn generate_reduction_entry(
598589
attrs: &ReductionAttrs,
599590
impl_block: &ItemImpl,
600591
) -> syn::Result<TokenStream2> {
601-
// Extract the trait path (should be ReduceTo<Target>)
602592
let trait_path = impl_block
603593
.trait_
604594
.as_ref()
605595
.map(|(path, _)| path)
606596
.ok_or_else(|| syn::Error::new_spanned(impl_block, "Expected impl ReduceTo<T> for S"))?;
607597

608-
// Extract target type from ReduceTo<Target>
609598
let target_type = extract_target_from_trait(trait_path)?;
610599

611-
// Extract source type (Self type)
612600
let source_type = &impl_block.self_ty;
613601

614-
// Get type names
615602
let source_name = extract_type_name(source_type)
616603
.ok_or_else(|| syn::Error::new_spanned(source_type, "Cannot extract source type name"))?;
617604
let target_name = extract_type_name(&target_type)
618605
.ok_or_else(|| syn::Error::new_spanned(&target_type, "Cannot extract target type name"))?;
619-
// Collect generic parameter info from the impl block
620606
let type_generics = collect_type_generic_names(&impl_block.generics);
621607

622-
// Generate variant fn bodies
623608
let source_variant_body = make_variant_fn_body(source_type, &type_generics)?;
624609
let target_variant_body = make_variant_fn_body(&target_type, &type_generics)?;
625610

@@ -652,7 +637,6 @@ fn generate_reduction_entry(
652637
.iter()
653638
.map(|(field, reason)| quote! { crate::rules::registry::UnavailableParameterField { field: #field, reason: #reason } });
654639

655-
// Generate the combined output
656640
let output = quote! {
657641
#impl_block
658642

@@ -926,8 +910,6 @@ pub fn register_brute_force(input: TokenStream) -> TokenStream {
926910

927911
/// Generate code for all `declare_variants!` entries.
928912
fn generate_declare_variants(input: &DeclareVariantsInput) -> syn::Result<TokenStream2> {
929-
// Validate default markers per problem name.
930-
// Group entries by their base type name (e.g., "MaximumIndependentSet").
931913
let mut defaults_per_problem: HashMap<String, Vec<usize>> = HashMap::new();
932914
let mut problem_names = HashSet::new();
933915
for (i, entry) in input.entries.iter().enumerate() {
@@ -938,7 +920,6 @@ fn generate_declare_variants(input: &DeclareVariantsInput) -> syn::Result<TokenS
938920
}
939921
}
940922

941-
// Check for multiple defaults for the same problem
942923
for (name, indices) in &defaults_per_problem {
943924
if indices.len() > 1 {
944925
return Err(syn::Error::new(
@@ -973,15 +954,13 @@ fn generate_declare_variants(input: &DeclareVariantsInput) -> syn::Result<TokenS
973954
let is_default = entry.is_default;
974955
let alias_lits: Vec<_> = entry.aliases.iter().map(|s| s.value()).collect();
975956

976-
// Parse the complexity expression to validate syntax
977957
let parsed = problemreductions_expr::Expr::try_parse(&complexity_str).map_err(|e| {
978958
syn::Error::new(
979959
entry.complexity.span(),
980960
format!("invalid complexity expression \"{complexity_str}\": {e}"),
981961
)
982962
})?;
983963

984-
// Generate a compiled complexity evaluator over the problem-owned parameters.
985964
let complexity_eval_fn = generate_complexity_eval_fn(&parsed, ty)?;
986965

987966
let construction_fields = if let Some(create_spec) = create_spec {

0 commit comments

Comments
 (0)