ciphercore_base/inline/
empty_state_iterate_inliner.rs

1use crate::data_types::{Type, UINT64};
2use crate::errors::Result;
3use crate::graphs::{Graph, Node};
4use crate::inline::inline_common::InlineState;
5use crate::ops::utils::constant_scalar;
6
7pub(super) fn inline_iterate_empty_state(
8    graph: Graph,
9    initial_state: Node,
10    inputs_node: Node,
11    inliner: &mut dyn InlineState,
12) -> Result<(Node, Vec<Node>)> {
13    let inputs_len = match inputs_node.get_type()? {
14        Type::Vector(len, _) => len,
15        _ => {
16            panic!("Inconsistency with type checker");
17        }
18    };
19    let mut outputs = vec![];
20    for i in 0..inputs_len {
21        let current_input =
22            inputs_node.vector_get(constant_scalar(&inliner.output_graph(), i, UINT64)?)?;
23        inliner.assign_input_nodes(
24            graph.clone(),
25            vec![initial_state.clone(), current_input.clone()],
26        )?;
27        let result = inliner.recursively_inline_graph(graph.clone())?;
28        inliner.unassign_nodes(graph.clone())?;
29        outputs.push(result.tuple_get(1)?.clone());
30    }
31    Ok((initial_state, outputs))
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37    use crate::graphs::create_context;
38    use crate::inline::inline_test_utils::{build_test_data, resolve_tuple_get, MockInlineState};
39
40    #[test]
41    fn test_empty_state_iterate() {
42        || -> Result<()> {
43            let c = create_context()?;
44            let (g, initial_state, inputs_node, input_vals) = build_test_data(c.clone(), UINT64)?;
45            let mut inliner = MockInlineState {
46                fake_graph: g.clone(),
47                inputs: vec![],
48                inline_graph_calls: vec![],
49                returned_nodes: vec![],
50            };
51            let res = inline_iterate_empty_state(
52                g.clone(),
53                initial_state.clone(),
54                inputs_node.clone(),
55                &mut inliner,
56            )?;
57            assert_eq!(inliner.inputs.len(), 5);
58            assert_eq!(inliner.inline_graph_calls.len(), 5);
59            assert_eq!(inliner.returned_nodes.len(), 5);
60            assert!(initial_state.clone() == inliner.inputs[0][0]);
61            for i in 0..input_vals.len() {
62                assert!(resolve_tuple_get(res.1[i].clone()) == inliner.returned_nodes[i][1]);
63            }
64            for i in 1..input_vals.len() {
65                // Inlinings should be independent.
66                assert!(
67                    inliner.returned_nodes[i - 1][0]
68                        != resolve_tuple_get(inliner.inputs[i][0].clone())
69                );
70                assert!(
71                    resolve_tuple_get(inliner.inputs[0][0].clone())
72                        == resolve_tuple_get(inliner.inputs[i][0].clone())
73                );
74            }
75            Ok(())
76        }()
77        .unwrap();
78    }
79}