pub fn compute_outcome_combinations(
    oracle_digits_infos: &[usize],
    main_outcome_prefix: &[usize],
    max_error_exp: usize,
    min_support_exp: usize,
    maximize_coverage: bool,
) -> Vec<Vec<Vec<usize>>> {
    let nb_oracles = oracle_digits_infos.len();
    assert!(nb_oracles > 1 && max_error_exp > min_support_exp);

    let min_num_digits = oracle_digits_infos[0];
    let (min_num_digits, max_num, main_outcome_prefix) = if oracle_digits_infos
        .iter()
        .skip(1)
        .all(|x| x == &min_num_digits)
    {
        (
            min_num_digits,
            (1 << min_num_digits) - 1,
            main_outcome_prefix.to_vec(),
        )
    } else {
        let mut new_main_outcome_prefix = vec![0];
        new_main_outcome_prefix.extend_from_slice(main_outcome_prefix);
        (
            min_num_digits + 1,
            (1 << (min_num_digits + 1)) - 1,
            new_main_outcome_prefix,
        )
    };
    let max_error: usize = 1 << max_error_exp;
    let half_max_error: usize = max_error >> 1;
    let min_support: usize = 1 << min_support_exp;
    let suffix_len = min_num_digits - main_outcome_prefix.len();

    let (start, end) = compute_interval_from_prefix(&main_outcome_prefix, min_num_digits, 2);

    // interval length is strictly smaller than max_error
    if suffix_len < max_error_exp {
        let start_max_error_suffix = start & ((1 << max_error_exp) - 1);
        let left_bound = (start >> max_error_exp) << max_error_exp;
        let right_bound = left_bound | (max_error - 1);
        let error_interval_prefix = num_to_vec(left_bound, min_num_digits, max_error_exp, 2);

        // interval length is less than or equal to min_support
        if start_max_error_suffix >= min_support && end <= right_bound - min_support {
            let support_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_min_support_covering_prefix(start, end, min_support, min_num_digits)
            };

            return vec![single_covering_prefix_combinations(
                &main_outcome_prefix,
                &support_interval_prefix,
                oracle_digits_infos,
                suffix_len,
            )];
        } else if start_max_error_suffix < min_support {
            let right_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_right_covering_prefix(end, max_error_exp, min_support, min_num_digits)
            };

            return if left_bound == 0 {
                vec![single_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &right_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )]
            } else {
                let left_interval_prefix = if maximize_coverage {
                    num_to_vec(
                        left_bound - half_max_error,
                        min_num_digits,
                        max_error_exp - 1,
                        2,
                    )
                } else {
                    compute_left_covering_prefix(start, max_error_exp, min_support, min_num_digits)
                };
                double_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &right_interval_prefix,
                    &left_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )
            };
        } else if end > right_bound - min_support {
            let left_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_left_covering_prefix(start, max_error_exp, min_support, min_num_digits)
            };

            return if right_bound == max_num {
                vec![single_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &left_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )]
            } else {
                let right_interval_prefix = if maximize_coverage {
                    num_to_vec(right_bound + 1, min_num_digits, max_error_exp - 1, 2)
                } else {
                    compute_right_covering_prefix(end, max_error_exp, min_support, min_num_digits)
                };

                double_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &left_interval_prefix,
                    &right_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )
            };
        } else {
            unreachable!();
        }
    }

    let mut res = Vec::new();

    if start != 0 {
        let right_interval_prefix = if maximize_coverage {
            num_to_vec(start, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(start, min_num_digits, min_support_exp, 2)
        };

        let left_interval_prefix = if maximize_coverage {
            num_to_vec(start - half_max_error, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(start - min_support, min_num_digits, min_support_exp, 2)
        };

        let mut combination = double_covering_restricted_prefix_combinations(
            &right_interval_prefix,
            &left_interval_prefix,
            oracle_digits_infos,
            min_num_digits - right_interval_prefix.len(),
        );

        res.append(&mut combination);
    }

    res.push(single_covering_prefix_combinations(
        &main_outcome_prefix,
        &main_outcome_prefix,
        oracle_digits_infos,
        suffix_len,
    ));

    if end != max_num {
        let right_interval_prefix = if maximize_coverage {
            num_to_vec(
                end - half_max_error + 1,
                min_num_digits,
                max_error_exp - 1,
                2,
            )
        } else {
            num_to_vec(end - min_support + 1, min_num_digits, min_support_exp, 2)
        };

        let left_interval_prefix = if maximize_coverage {
            num_to_vec(end + 1, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(end + 1, min_num_digits, min_support_exp, 2)
        };

        let mut combination = double_covering_restricted_prefix_combinations(
            &right_interval_prefix,
            &left_interval_prefix,
            oracle_digits_infos,
            min_num_digits - right_interval_prefix.len(),
        );
        res.append(&mut combination);
    }

    res
}
/// Compute the outcome combinations required to cover intervals that will
/// satisfy the specified min support and max error parameters.
/// Expect that the first element of oracle_numeric_infos is the one with smallest
/// `num_digits`.
/// Throws if oracle_numeric_infos has less than 2 elements or max_error_exp is
/// not greater than min_support_exp.
Compute the outcome combinations required to cover intervals that will
satisfy the specified min support and max error parameters.
Expect that the first element of oracle_numeric_infos is the one with smallest
`num_digits`.
Throws if oracle_numeric_infos has less than 2 elements or max_error_exp is
not greater than min_support_exp.
Compute the outcome combinations required to cover intervals that will satisfy the specified min support and max error parameters . Expect that the first element of oracle_numeric_infos is the one with smallest ` num_digits ` . Throws if oracle_numeric_infos has less than 2 elements or max_error_exp is not greater than min_support_exp .
pub fn compute_outcome_combinations(
    oracle_digits_infos: &[usize],
    main_outcome_prefix: &[usize],
    max_error_exp: usize,
    min_support_exp: usize,
    maximize_coverage: bool,
) -> Vec<Vec<Vec<usize>>> {
    let nb_oracles = oracle_digits_infos.len();
    assert!(nb_oracles > 1 && max_error_exp > min_support_exp);
    let min_num_digits = oracle_digits_infos[0];
    let (min_num_digits, max_num, main_outcome_prefix) = if oracle_digits_infos
        .iter()
        .skip(1)
        .all(|x| x == &min_num_digits)
    {
        (
            min_num_digits,
            (1 << min_num_digits) - 1,
            main_outcome_prefix.to_vec(),
        )
    } else {
        let mut new_main_outcome_prefix = vec![0];
        new_main_outcome_prefix.extend_from_slice(main_outcome_prefix);
        (
            min_num_digits + 1,
            (1 << (min_num_digits + 1)) - 1,
            new_main_outcome_prefix,
        )
    };
    let max_error: usize = 1 << max_error_exp;
    let half_max_error: usize = max_error >> 1;
    let min_support: usize = 1 << min_support_exp;
    let suffix_len = min_num_digits - main_outcome_prefix.len();
    let (start, end) = compute_interval_from_prefix(&main_outcome_prefix, min_num_digits, 2);
    // interval length is strictly smaller than max_error
    if suffix_len < max_error_exp {
        let start_max_error_suffix = start & ((1 << max_error_exp) - 1);
        let left_bound = (start >> max_error_exp) << max_error_exp;
        let right_bound = left_bound | (max_error - 1);
        let error_interval_prefix = num_to_vec(left_bound, min_num_digits, max_error_exp, 2);
        // interval length is less than or equal to min_support
        if start_max_error_suffix >= min_support && end <= right_bound - min_support {
            let support_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_min_support_covering_prefix(start, end, min_support, min_num_digits)
            };
            return vec![single_covering_prefix_combinations(
                &main_outcome_prefix,
                &support_interval_prefix,
                oracle_digits_infos,
                suffix_len,
            )];
        } else if start_max_error_suffix < min_support {
            let right_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_right_covering_prefix(end, max_error_exp, min_support, min_num_digits)
            };
            return if left_bound == 0 {
                vec![single_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &right_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )]
            } else {
                let left_interval_prefix = if maximize_coverage {
                    num_to_vec(
                        left_bound - half_max_error,
                        min_num_digits,
                        max_error_exp - 1,
                        2,
                    )
                } else {
                    compute_left_covering_prefix(start, max_error_exp, min_support, min_num_digits)
                };
                double_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &right_interval_prefix,
                    &left_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )
            };
        } else if end > right_bound - min_support {
            let left_interval_prefix = if maximize_coverage {
                error_interval_prefix
            } else {
                compute_left_covering_prefix(start, max_error_exp, min_support, min_num_digits)
            };
            return if right_bound == max_num {
                vec![single_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &left_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )]
            } else {
                let right_interval_prefix = if maximize_coverage {
                    num_to_vec(right_bound + 1, min_num_digits, max_error_exp - 1, 2)
                } else {
                    compute_right_covering_prefix(end, max_error_exp, min_support, min_num_digits)
                };
                double_covering_prefix_combinations(
                    &main_outcome_prefix,
                    &left_interval_prefix,
                    &right_interval_prefix,
                    oracle_digits_infos,
                    suffix_len,
                )
            };
        } else {
            unreachable!();
        }
    }
    let mut res = Vec::new();
    if start != 0 {
        let right_interval_prefix = if maximize_coverage {
            num_to_vec(start, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(start, min_num_digits, min_support_exp, 2)
        };
        let left_interval_prefix = if maximize_coverage {
            num_to_vec(start - half_max_error, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(start - min_support, min_num_digits, min_support_exp, 2)
        };
        let mut combination = double_covering_restricted_prefix_combinations(
            &right_interval_prefix,
            &left_interval_prefix,
            oracle_digits_infos,
            min_num_digits - right_interval_prefix.len(),
        );
        res.append(&mut combination);
    }
    res.push(single_covering_prefix_combinations(
        &main_outcome_prefix,
        &main_outcome_prefix,
        oracle_digits_infos,
        suffix_len,
    ));
    if end != max_num {
        let right_interval_prefix = if maximize_coverage {
            num_to_vec(
                end - half_max_error + 1,
                min_num_digits,
                max_error_exp - 1,
                2,
            )
        } else {
            num_to_vec(end - min_support + 1, min_num_digits, min_support_exp, 2)
        };
        let left_interval_prefix = if maximize_coverage {
            num_to_vec(end + 1, min_num_digits, max_error_exp - 1, 2)
        } else {
            num_to_vec(end + 1, min_num_digits, min_support_exp, 2)
        };
        let mut combination = double_covering_restricted_prefix_combinations(
            &right_interval_prefix,
            &left_interval_prefix,
            oracle_digits_infos,
            min_num_digits - right_interval_prefix.len(),
        );
        res.append(&mut combination);
    }
    res
}
pub fn compute_outcome_combinations ( oracle_digits_infos : & [ usize ] , main_outcome_prefix : & [ usize ] , max_error_exp : usize , min_support_exp : usize , maximize_coverage : bool , ) -> Vec < Vec < Vec < usize > > > { let nb_oracles = oracle_digits_infos . len ( ) ; assert ! ( nb_oracles 1 max_error_exp min_support_exp ) ; let min_num_digits = oracle_digits_infos [ 0 ] ; let ( min_num_digits , max_num , main_outcome_prefix ) = if oracle_digits_infos . iter ( ) . skip ( 1 ) . all ( | x | x == & min_num_digits ) { ( min_num_digits , ( 1 << min_num_digits ) - 1 , main_outcome_prefix . to_vec ( ) , ) } else { let mut new_main_outcome_prefix = vec ! [ 0 ] ; new_main_outcome_prefix . extend_from_slice ( main_outcome_prefix ) ; ( min_num_digits + 1 , ( 1 << ( min_num_digits + 1 ) ) - 1 , new_main_outcome_prefix , ) } ; let max_error : usize = 1 << max_error_exp ; let half_max_error : usize = max_error >> 1 ; let min_support : usize = 1 << min_support_exp ; let suffix_len = min_num_digits - main_outcome_prefix . len ( ) ; let ( start , end ) = compute_interval_from_prefix ( & main_outcome_prefix , min_num_digits , 2 ) ; // interval length is strictly smaller than max_error if suffix_len < max_error_exp { let start_max_error_suffix = start & ( ( 1 << max_error_exp ) - 1 ) ; let left_bound = ( start >> max_error_exp ) << max_error_exp ; let right_bound = left_bound | ( max_error - 1 ) ; let error_interval_prefix = num_to_vec ( left_bound , min_num_digits , max_error_exp , 2 ) ; // interval length is less than or equal to min_support if start_max_error_suffix >= min_support && end <= right_bound - min_support { let support_interval_prefix = if maximize_coverage { error_interval_prefix } else { compute_min_support_covering_prefix ( start , end , min_support , min_num_digits ) } ; return vec ! [ single_covering_prefix_combinations ( main_outcome_prefix support_interval_prefix oracle_digits_infos suffix_len ) ] ; } else if start_max_error_suffix < min_support { let right_interval_prefix = if maximize_coverage { error_interval_prefix } else { compute_right_covering_prefix ( end , max_error_exp , min_support , min_num_digits ) } ; return if left_bound == 0 { vec ! [ single_covering_prefix_combinations ( main_outcome_prefix right_interval_prefix oracle_digits_infos suffix_len ) ] } else { let left_interval_prefix = if maximize_coverage { num_to_vec ( left_bound - half_max_error , min_num_digits , max_error_exp - 1 , 2 , ) } else { compute_left_covering_prefix ( start , max_error_exp , min_support , min_num_digits ) } ; double_covering_prefix_combinations ( & main_outcome_prefix , & right_interval_prefix , & left_interval_prefix , oracle_digits_infos , suffix_len , ) } ; } else if end > right_bound - min_support { let left_interval_prefix = if maximize_coverage { error_interval_prefix } else { compute_left_covering_prefix ( start , max_error_exp , min_support , min_num_digits ) } ; return if right_bound == max_num { vec ! [ single_covering_prefix_combinations ( main_outcome_prefix left_interval_prefix oracle_digits_infos suffix_len ) ] } else { let right_interval_prefix = if maximize_coverage { num_to_vec ( right_bound + 1 , min_num_digits , max_error_exp - 1 , 2 ) } else { compute_right_covering_prefix ( end , max_error_exp , min_support , min_num_digits ) } ; double_covering_prefix_combinations ( & main_outcome_prefix , & left_interval_prefix , & right_interval_prefix , oracle_digits_infos , suffix_len , ) } ; } else { unreachable ! ( ) ; } } let mut res = Vec :: new ( ) ; if start != 0 { let right_interval_prefix = if maximize_coverage { num_to_vec ( start , min_num_digits , max_error_exp - 1 , 2 ) } else { num_to_vec ( start , min_num_digits , min_support_exp , 2 ) } ; let left_interval_prefix = if maximize_coverage { num_to_vec ( start - half_max_error , min_num_digits , max_error_exp - 1 , 2 ) } else { num_to_vec ( start - min_support , min_num_digits , min_support_exp , 2 ) } ; let mut combination = double_covering_restricted_prefix_combinations ( & right_interval_prefix , & left_interval_prefix , oracle_digits_infos , min_num_digits - right_interval_prefix . len ( ) , ) ; res . append ( & mut combination ) ; } res . push ( single_covering_prefix_combinations ( & main_outcome_prefix , & main_outcome_prefix , oracle_digits_infos , suffix_len , ) ) ; if end != max_num { let right_interval_prefix = if maximize_coverage { num_to_vec ( end - half_max_error + 1 , min_num_digits , max_error_exp - 1 , 2 , ) } else { num_to_vec ( end - min_support + 1 , min_num_digits , min_support_exp , 2 ) } ; let left_interval_prefix = if maximize_coverage { num_to_vec ( end + 1 , min_num_digits , max_error_exp - 1 , 2 ) } else { num_to_vec ( end + 1 , min_num_digits , min_support_exp , 2 ) } ; let mut combination = double_covering_restricted_prefix_combinations ( & right_interval_prefix , & left_interval_prefix , oracle_digits_infos , min_num_digits - right_interval_prefix . len ( ) , ) ; res . append ( & mut combination ) ; } res }
Compute the outcome combinations required to cover intervals that will
satisfy the specified min support and max error parameters.
Compute the outcome combinations required to cover intervals that will satisfy the specified min support and max error parameters .
oracle_digits_infos
&[usize]
main_outcome_prefix
&[usize]
max_error_exp
usize
min_support_exp
usize
maximize_coverage
bool