diff --git a/nemo/src/execution/planning/operations/negation.rs b/nemo/src/execution/planning/operations/negation.rs index 9ac3d6de2..62475e715 100644 --- a/nemo/src/execution/planning/operations/negation.rs +++ b/nemo/src/execution/planning/operations/negation.rs @@ -28,6 +28,7 @@ pub(crate) fn node_negation( .iter() .map(|atom| { let subtract_markers = variable_translation.operation_table(atom.terms().iter()); + let node = subplan_union( plan, table_manager, @@ -36,9 +37,22 @@ pub(crate) fn node_negation( subtract_markers.clone(), ); - // We simply apply all constraints to this node - // Constraints which do not reference this atom will be filtered in the physical layer - let node_filtered = node_filter(plan, variable_translation, node, subtracted_filters); + // We only keep those constraints that can be evaluated within the current atom + let filters = subtracted_filters + .iter() + .filter(|filter| { + filter.variables().all(|variable| { + subtract_markers.contains( + variable_translation + .get(variable) + .expect("variable translation must know every variable"), + ) + }) + }) + .cloned() + .collect::>(); + + let node_filtered = node_filter(plan, variable_translation, node, &filters); // The tables may contain columns that are not part of `node_main`. // These need to be projected away. diff --git a/nemo/src/execution/planning/plan_head_restricted.rs b/nemo/src/execution/planning/plan_head_restricted.rs index ff1ae3306..7b799aeb6 100644 --- a/nemo/src/execution/planning/plan_head_restricted.rs +++ b/nemo/src/execution/planning/plan_head_restricted.rs @@ -80,8 +80,6 @@ impl RestrictedChaseStrategy { let head_join_atoms = analysis.existential_aux_rule.positive_body().clone(); let head_join_constraints = analysis.existential_aux_rule.positive_constraints().clone(); - println!("{:?}, {:?}", head_join_atoms, head_join_constraints); - let aux_head = &analysis.existential_aux_rule.head()[0]; let mut aux_head_order = VariableOrder::new(); let mut used_join_head_variables = HashSet::::new(); diff --git a/resources/testcases/regression/planning_engine/constants_negation/run.rls b/resources/testcases/regression/planning_engine/constants_negation/run.rls new file mode 100644 index 000000000..f7737ed7f --- /dev/null +++ b/resources/testcases/regression/planning_engine/constants_negation/run.rls @@ -0,0 +1,21 @@ +%%% Test related to +%%% https://github.com/knowsys/nemo/issues/452 +%%% +%%% Previously, an incorrect plan was produced, which lead to a crash. + +S(a, b, c). +S(r, r, r). +T(a, b). +T(a, c). + +R(?x, ?y, ?z) :- + S(?x, ?y, ?z), + ~ T(?x, ?y), + ~ T(a, ?z). + +R(?x, ?y, ?z) :- + S(?x, ?y, ?z), + ~ T(a, ?y), + ~ T(a, ?z). + +@export R :- csv {} . \ No newline at end of file diff --git a/resources/testcases/regression/planning_engine/constants_negation/run/R.csv b/resources/testcases/regression/planning_engine/constants_negation/run/R.csv new file mode 100644 index 000000000..1f382fb6c --- /dev/null +++ b/resources/testcases/regression/planning_engine/constants_negation/run/R.csv @@ -0,0 +1 @@ +r,r,r \ No newline at end of file