use crate::Operation;
fn bool_gate_to_bristol(gate: &Operation<bool>) -> String {
match gate {
Operation::Input(w) => {
format!("0 1 {} INPUT", w)
}
Operation::Random(_) => {
unimplemented!("Can't use random gates in Bristol")
}
Operation::Add(o, l, r) => {
format!("2 1 {} {} {} XOR", l, r, o)
}
Operation::AddConst(o, i, c) => {
if *c {
format!("1 1 {} {} INV", i, o)
} else {
format!("1 1 {} {} EQW", i, o) }
}
Operation::Sub(o, l, r) => {
format!("2 1 {} {} {} XOR", l, r, o) }
Operation::SubConst(o, i, c) => {
if *c {
format!("1 1 {} {} INV", i, o)
} else {
format!("1 1 {} {} EQW", i, o) }
}
Operation::Mul(o, l, r) => {
format!("2 1 {} {} {} AND", l, r, o)
}
Operation::MulConst(o, i, c) => {
if *c {
format!("1 1 {} {} EQW", i, o) } else {
format!("1 1 0 {} EQ", o)
}
}
Operation::AssertZero(w) => {
format!("0 1 {} OUTPUT", w)
}
Operation::Const(w, c) => {
format!("1 1 {} {} EQ", if *c { 1 } else { 0 }, w)
}
}
}
pub fn bool_circuit_to_bristol(gates: &[Operation<bool>], bool_witness: &[bool]) -> String {
let mut circuit: String = String::new();
let mut bool_iter = bool_witness.iter();
for gate in gates {
circuit.push_str(
format!(
"{}\n",
match gate {
Operation::Input(o) => {
bool_gate_to_bristol(&Operation::Const(*o, *bool_iter.next().unwrap()))
}
_ => {
bool_gate_to_bristol(gate)
}
}
)
.as_str(),
)
}
circuit
}
#[cfg(test)]
mod tests {
use crate::exporters::bristol::bool_circuit_to_bristol;
use crate::Operation;
#[test]
fn print_example() {
println!(
"{}",
bool_circuit_to_bristol(
&[
Operation::Input(1),
Operation::Input(2),
Operation::Input(3),
Operation::Add(4, 1, 3),
Operation::Add(5, 2, 3),
Operation::Mul(6, 5, 4),
Operation::AddConst(0, 6, true),
Operation::AssertZero(0)
],
&[false, false, true]
)
);
}
}