boolean_circuit/
builder.rs1use crate::Gate;
2
3pub fn eq(x: &Gate, y: &Gate) -> Gate {
6 !(x ^ y)
7}
8
9pub fn reduce_conjunction(i: impl IntoIterator<Item = Gate>) -> Gate {
14 reduce_associative(i.into_iter().collect::<Vec<_>>().as_slice(), |x, y| x & y)
15 .unwrap_or_else(|| true.into())
16}
17
18pub fn reduce_disjunction(i: impl IntoIterator<Item = Gate>) -> Gate {
23 reduce_associative(i.into_iter().collect::<Vec<_>>().as_slice(), |x, y| x | y)
24 .unwrap_or_else(|| false.into())
25}
26
27pub fn reduce_xor(i: impl IntoIterator<Item = Gate>) -> Gate {
32 reduce_associative(i.into_iter().collect::<Vec<_>>().as_slice(), |x, y| x ^ y).unwrap()
33}
34
35fn reduce_associative<T: Clone>(i: &[T], op: fn(&T, &T) -> T) -> Option<T> {
36 match i.len() {
37 0 => None,
38 1 => Some(i[0].clone()),
39 _ => {
40 let mid = i.len() / 2;
41 Some(op(
42 &reduce_associative(&i[..mid], op).unwrap(),
43 &reduce_associative(&i[mid..], op).unwrap(),
44 ))
45 }
46 }
47}