use std::collections::HashMap;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_relocatable_from_var_name;
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
use cairo_vm::serde::deserialize_program::ApTracking;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::errors::hint_errors::HintError;
use cairo_vm::vm::vm_core::VirtualMachine;
pub fn divide_queries_ind_by_coset_size_to_fp_offset(
vm: &mut VirtualMachine,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let queries_base = get_relocatable_from_var_name("queries", vm, ids_data, ap_tracking)?;
let params_base = get_relocatable_from_var_name("params", vm, ids_data, ap_tracking)?;
let first_query_addr = vm.get_relocatable(queries_base).map_err(|_| {
HintError::CustomHint("Failed to retrieve `first_query_addr` as relocatable.".into())
})?;
let first_params_addr = vm.get_relocatable(params_base).map_err(|_| {
HintError::CustomHint("Failed to retrieve `first_params_addr` as relocatable.".into())
})?;
let index = vm
.get_integer(first_query_addr)
.map_err(|_| {
HintError::CustomHint("Failed to retrieve `queries.index` as integer.".into())
})?
.to_biguint();
let coset_size = vm
.get_integer(first_params_addr)
.map_err(|_| {
HintError::CustomHint("Failed to retrieve `params.coset_size` as integer.".into())
})?
.to_biguint();
let result = MaybeRelocatable::Int((index / coset_size).into());
let dest = (vm.get_fp() + 1)?;
Ok(vm.insert_value(dest, result)?)
}
#[cfg(test)]
mod test {
use super::*;
use crate::test_utils::fill_ids_data_for_test;
use cairo_vm::types::relocatable::Relocatable;
use cairo_vm::Felt252;
use rstest::rstest;
#[rstest]
#[case(42, 7, 6)]
#[case(100, 25, 4)]
#[case(0, 5, 0)]
fn test_divide_queries_ind_by_coset_size_to_fp_offset(
#[case] index: u64,
#[case] coset_size: u64,
#[case] expected: u64,
) {
let mut vm = VirtualMachine::new(false, false);
let ids_data = fill_ids_data_for_test(&["queries", "params"]);
let ap_tracking = ApTracking::default();
vm.add_memory_segment();
vm.add_memory_segment();
vm.add_memory_segment();
vm.set_ap(2);
vm.set_fp(2);
let queries_addr = Relocatable::from((2, 0));
let params_addr = Relocatable::from((2, 3));
let fp = vm.get_fp();
vm.insert_value(
Relocatable::from((fp.segment_index, fp.offset - 2)),
MaybeRelocatable::from(queries_addr),
)
.expect("Failed to insert queries pointer");
vm.insert_value(
Relocatable::from((fp.segment_index, fp.offset - 1)),
MaybeRelocatable::from(params_addr),
)
.expect("Failed to insert params pointer");
let _ = vm.segments.load_data(
queries_addr,
&[
MaybeRelocatable::from(Felt252::from(index)), MaybeRelocatable::from(100), MaybeRelocatable::from(200), ],
);
let _ = vm.segments.load_data(
params_addr,
&[
MaybeRelocatable::from(Felt252::from(coset_size)), MaybeRelocatable::from(300),
MaybeRelocatable::from(400), ],
);
divide_queries_ind_by_coset_size_to_fp_offset(&mut vm, &ids_data, &ap_tracking)
.expect("Failed to run hint");
let fp = vm.get_fp();
let result_addr = Relocatable::from((fp.segment_index, fp.offset + 1));
let result = vm.get_integer(result_addr).expect("Failed to get result");
assert_eq!(*result.as_ref(), Felt252::from(expected));
}
}