#[macro_export]
macro_rules! impl_get_matches_nary {
(bi: $self:expr, $solution:expr) => {{
use std::collections::HashMap;
use $crate::api::analysis::{ConstraintJustification, DetailedConstraintMatch, EntityRef};
let entities = $crate::stream::collection_extract::CollectionExtract::extract(
&$self.extractor,
$solution,
);
let cref = $self.constraint_ref.clone();
let mut temp_index: HashMap<_, Vec<usize>> = HashMap::new();
for (i, entity) in entities.iter().enumerate() {
let key = $crate::stream::key_extract::KeyExtract::extract(
&$self.key_extractor,
$solution,
entity,
i,
);
temp_index.entry(key).or_default().push(i);
}
let mut matches = Vec::new();
for indices in temp_index.values() {
for i in 0..indices.len() {
for j in (i + 1)..indices.len() {
let idx_a = indices[i];
let idx_b = indices[j];
let a = &entities[idx_a];
let b = &entities[idx_b];
if ($self.filter)($solution, a, b, idx_a, idx_b) {
let justification = ConstraintJustification::new(vec![
EntityRef::new(a),
EntityRef::new(b),
]);
let score = $self.compute_score($solution, idx_a, idx_b);
matches.push(DetailedConstraintMatch::new(
cref.clone(),
score,
justification,
));
}
}
}
}
matches
}};
(tri: $self:expr, $solution:expr) => {{
use std::collections::HashMap;
use $crate::api::analysis::{ConstraintJustification, DetailedConstraintMatch, EntityRef};
let entities = $crate::stream::collection_extract::CollectionExtract::extract(
&$self.extractor,
$solution,
);
let cref = $self.constraint_ref.clone();
let mut temp_index: HashMap<_, Vec<usize>> = HashMap::new();
for (i, entity) in entities.iter().enumerate() {
let key = $crate::stream::key_extract::KeyExtract::extract(
&$self.key_extractor,
$solution,
entity,
i,
);
temp_index.entry(key).or_default().push(i);
}
let mut matches = Vec::new();
for indices in temp_index.values() {
for pos_i in 0..indices.len() {
for pos_j in (pos_i + 1)..indices.len() {
for pos_k in (pos_j + 1)..indices.len() {
let i = indices[pos_i];
let j = indices[pos_j];
let k = indices[pos_k];
let a = &entities[i];
let b = &entities[j];
let c = &entities[k];
if ($self.filter)($solution, a, b, c) {
let justification = ConstraintJustification::new(vec![
EntityRef::new(a),
EntityRef::new(b),
EntityRef::new(c),
]);
let score = $self.compute_score($solution, i, j, k);
matches.push(DetailedConstraintMatch::new(
cref.clone(),
score,
justification,
));
}
}
}
}
}
matches
}};
(quad: $self:expr, $solution:expr) => {{
use std::collections::HashMap;
use $crate::api::analysis::{ConstraintJustification, DetailedConstraintMatch, EntityRef};
let entities = $crate::stream::collection_extract::CollectionExtract::extract(
&$self.extractor,
$solution,
);
let cref = $self.constraint_ref.clone();
let mut temp_index: HashMap<_, Vec<usize>> = HashMap::new();
for (i, entity) in entities.iter().enumerate() {
let key = $crate::stream::key_extract::KeyExtract::extract(
&$self.key_extractor,
$solution,
entity,
i,
);
temp_index.entry(key).or_default().push(i);
}
let mut matches = Vec::new();
for indices in temp_index.values() {
for pos_i in 0..indices.len() {
for pos_j in (pos_i + 1)..indices.len() {
for pos_k in (pos_j + 1)..indices.len() {
for pos_l in (pos_k + 1)..indices.len() {
let i = indices[pos_i];
let j = indices[pos_j];
let k = indices[pos_k];
let l = indices[pos_l];
let a = &entities[i];
let b = &entities[j];
let c = &entities[k];
let d = &entities[l];
if ($self.filter)($solution, a, b, c, d) {
let justification = ConstraintJustification::new(vec![
EntityRef::new(a),
EntityRef::new(b),
EntityRef::new(c),
EntityRef::new(d),
]);
let score = $self.compute_score($solution, i, j, k, l);
matches.push(DetailedConstraintMatch::new(
cref.clone(),
score,
justification,
));
}
}
}
}
}
}
matches
}};
(penta: $self:expr, $solution:expr) => {{
use std::collections::HashMap;
use $crate::api::analysis::{ConstraintJustification, DetailedConstraintMatch, EntityRef};
let entities = $crate::stream::collection_extract::CollectionExtract::extract(
&$self.extractor,
$solution,
);
let cref = $self.constraint_ref.clone();
let mut temp_index: HashMap<_, Vec<usize>> = HashMap::new();
for (i, entity) in entities.iter().enumerate() {
let key = $crate::stream::key_extract::KeyExtract::extract(
&$self.key_extractor,
$solution,
entity,
i,
);
temp_index.entry(key).or_default().push(i);
}
let mut matches = Vec::new();
for indices in temp_index.values() {
for pos_i in 0..indices.len() {
for pos_j in (pos_i + 1)..indices.len() {
for pos_k in (pos_j + 1)..indices.len() {
for pos_l in (pos_k + 1)..indices.len() {
for pos_m in (pos_l + 1)..indices.len() {
let i = indices[pos_i];
let j = indices[pos_j];
let k = indices[pos_k];
let l = indices[pos_l];
let m = indices[pos_m];
let a = &entities[i];
let b = &entities[j];
let c = &entities[k];
let d = &entities[l];
let e = &entities[m];
if ($self.filter)($solution, a, b, c, d, e) {
let justification = ConstraintJustification::new(vec![
EntityRef::new(a),
EntityRef::new(b),
EntityRef::new(c),
EntityRef::new(d),
EntityRef::new(e),
]);
let score = $self.compute_score($solution, i, j, k, l, m);
matches.push(DetailedConstraintMatch::new(
cref.clone(),
score,
justification,
));
}
}
}
}
}
}
}
matches
}};
}
pub use impl_get_matches_nary;