From f8ae9475f825c82ec44498846822e1ab6b8d3b8f Mon Sep 17 00:00:00 2001 From: Alex Ivliev Date: Mon, 24 Nov 2025 14:43:23 +0100 Subject: [PATCH] do not apply constant operations to factors --- .../planning/operations/join_cartesian.rs | 24 ++++++++----------- .../planning/strategy/forward/body.rs | 8 +------ 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/nemo/src/execution/planning/operations/join_cartesian.rs b/nemo/src/execution/planning/operations/join_cartesian.rs index fd5954484..358a94da3 100644 --- a/nemo/src/execution/planning/operations/join_cartesian.rs +++ b/nemo/src/execution/planning/operations/join_cartesian.rs @@ -21,6 +21,7 @@ use crate::{ /// The rule body is divided into multiple independent factors. /// Those can either be [BodyAtom]s /// or [Operation]s assigning constants to a variable. +#[derive(Debug)] enum Factor { /// Factor consisting of body atoms Atoms(Vec), @@ -107,7 +108,7 @@ impl GeneratorJoinCartesian { /// atoms: [a(x, y), b(y, z), c(z), r(w), t(w)] /// operations: [q = 3, s = 7] /// result: [[a(x, y), b(y, z), c(z)], [r(w), t(w)], [q = 3, s = 7]] - fn partition_atoms(atoms: &[BodyAtom], operations: &[Operation]) -> Vec { + fn partition_atoms(atoms: &[BodyAtom], operations: &mut Vec) -> Vec { #[derive(Clone)] struct Partition { pub variables: HashSet, @@ -207,26 +208,26 @@ impl GeneratorJoinCartesian { .flat_map(|atom| atom.terms()) .collect::>(); - let mut constant_operations = HashSet::::default(); + let mut constant_operations = Vec::::default(); let mut constant_operations_len = constant_operations.len(); let mut constant_operations_variables = HashSet::::default(); loop { - for (index, operation) in operations.iter().enumerate() { - if constant_operations.contains(&index) { - continue; - } - + operations.retain(|operation| { if let Some((left, right)) = operation.variable_assignment() && !body_variables.contains(left) && right .variables() .all(|variable| constant_operations_variables.contains(variable)) { - constant_operations.insert(index); + constant_operations.push(operation.clone()); constant_operations_variables.insert(left.clone()); + + return false; } - } + + true + }); if constant_operations_len == constant_operations.len() { break; @@ -235,11 +236,6 @@ impl GeneratorJoinCartesian { constant_operations_len = constant_operations.len(); } - let constant_operations = constant_operations - .iter() - .map(|&index| operations[index].clone()) - .collect::>(); - if !constant_operations.is_empty() { result.push(Factor::Operations(constant_operations)); } diff --git a/nemo/src/execution/planning/strategy/forward/body.rs b/nemo/src/execution/planning/strategy/forward/body.rs index 4fb939355..9bb1094df 100644 --- a/nemo/src/execution/planning/strategy/forward/body.rs +++ b/nemo/src/execution/planning/strategy/forward/body.rs @@ -60,20 +60,14 @@ impl StrategyBody { Self::Plain { join, filter } } else { - let mut merge_operations = &mut operations.clone(); + let merge_operations = &mut operations.clone(); let mut merge_negative = negative.clone(); let join = GeneratorJoinCartesian::new(&order, &positive, operations, &mut negative); let variables_join = join.output_variables(); - let single_factor = join.is_single_join(); let import = GeneratorImport::new(variables_join, &imports); - if single_factor { - merge_operations = operations; - merge_negative = negative; - } - let merge = GeneratorJoinImports::new( &order, positive,