pub(crate) fn split_state_id_groups( states: &Vec, state_ids_by_group_id: &mut Vec>, group_ids_by_state_id: &mut Vec, start_group_id: usize, mut f: impl FnMut(&S, &S, &Vec) -> bool, ) -> bool { let mut result = false; let mut group_id = start_group_id; while group_id < state_ids_by_group_id.len() { let state_ids = &state_ids_by_group_id[group_id]; let mut split_state_ids = Vec::new(); let mut i = 0; while i < state_ids.len() { let left_state_id = state_ids[i]; if split_state_ids.contains(&left_state_id) { i += 1; continue; } let left_state = &states[left_state_id]; // Identify all of the other states in the group that are incompatible with // this state. let mut j = i + 1; while j < state_ids.len() { let right_state_id = state_ids[j]; if split_state_ids.contains(&right_state_id) { j += 1; continue; } let right_state = &states[right_state_id]; if f(left_state, right_state, &group_ids_by_state_id) { split_state_ids.push(right_state_id); } j += 1; } i += 1; } // If any states were removed from the group, add them all as a new group. if split_state_ids.len() > 0 { result = true; state_ids_by_group_id[group_id].retain(|i| !split_state_ids.contains(&i)); let new_group_id = state_ids_by_group_id.len(); for id in &split_state_ids { group_ids_by_state_id[*id] = new_group_id; } state_ids_by_group_id.push(split_state_ids); } group_id += 1; } result }