use miden_core::{Felt, field::QuadFelt};
use miden_crypto::field::{Field, PrimeCharacteristicRing};
use crate::{
AceCircuit, InputCounts, InputKey, InputLayout, circuit::emit_circuit, dag::DagBuilder,
};
fn minimal_layout(num_public: usize) -> InputLayout {
let counts = InputCounts {
width: 0,
aux_width: 0,
num_aux_boundary: 0,
num_public,
num_vlpi: 0,
num_randomness: 2,
num_periodic: 0,
num_quotient_chunks: 1,
};
InputLayout::new(counts)
}
fn build_inputs(layout: &InputLayout, values: &[(InputKey, QuadFelt)]) -> Vec<QuadFelt> {
let mut inputs = vec![QuadFelt::ZERO; layout.total_inputs];
for (key, value) in values {
let idx = layout.index(*key).expect("input key in layout");
inputs[idx] = *value;
}
inputs
}
#[test]
fn ace_simple_circuit_matches_hand_eval() {
let layout = minimal_layout(3);
let mut builder = DagBuilder::<QuadFelt>::new();
let a = builder.input(InputKey::Public(0));
let b = builder.input(InputKey::Public(1));
let c = builder.input(InputKey::Public(2));
let sum = builder.add(a, b);
let prod = builder.mul(sum, a);
let root = builder.sub(prod, c);
let dag = builder.build(root);
let circuit: AceCircuit<QuadFelt> = emit_circuit(&dag, layout.clone()).expect("emit circuit");
let a_val = QuadFelt::from(Felt::new_unchecked(3));
let b_val = QuadFelt::from(Felt::new_unchecked(5));
let c_val = (a_val + b_val) * a_val;
let inputs = build_inputs(
&layout,
&[
(InputKey::Public(0), a_val),
(InputKey::Public(1), b_val),
(InputKey::Public(2), c_val),
],
);
let result = circuit.eval(&inputs).expect("circuit eval");
assert!(result.is_zero());
}
#[test]
fn ace_simple_circuit_with_shared_terms() {
let layout = minimal_layout(3);
let mut builder = DagBuilder::<QuadFelt>::new();
let a = builder.input(InputKey::Public(0));
let b = builder.input(InputKey::Public(1));
let c = builder.input(InputKey::Public(2));
let sum = builder.add(a, b);
let lhs = builder.mul(sum, c);
let ac = builder.mul(a, c);
let bc = builder.mul(b, c);
let rhs = builder.add(ac, bc);
let root = builder.sub(lhs, rhs);
let dag = builder.build(root);
let circuit: AceCircuit<QuadFelt> = emit_circuit(&dag, layout.clone()).expect("emit circuit");
let a_val = QuadFelt::from(Felt::new_unchecked(7));
let b_val = QuadFelt::from(Felt::new_unchecked(2));
let c_val = QuadFelt::from(Felt::new_unchecked(11));
let inputs = build_inputs(
&layout,
&[
(InputKey::Public(0), a_val),
(InputKey::Public(1), b_val),
(InputKey::Public(2), c_val),
],
);
let result = circuit.eval(&inputs).expect("circuit eval");
assert!(result.is_zero());
}