use open_hypergraphs::lax::var;
use std::hash::Hash;
#[derive(PartialEq, Clone, Debug, Hash)]
pub struct Bit;
#[derive(PartialEq, Clone, Debug, Hash)]
pub enum Gate {
Not,
Xor,
Zero, Or,
And,
One,
Copy, }
impl var::HasVar for Gate {
fn var() -> Gate {
Gate::Copy
}
}
impl var::HasBitXor<Bit, Gate> for Gate {
fn bitxor(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::Xor)
}
}
impl var::HasBitAnd<Bit, Gate> for Gate {
fn bitand(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::And)
}
}
impl var::HasBitOr<Bit, Gate> for Gate {
fn bitor(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::Or)
}
}
use hypersyn::def_arrow;
#[def_arrow(Bit, Gate, full_adder_arrow)]
fn full_adder(a: var!(Bit), b: var!(Bit), cin: var!(Bit)) -> (var!(Bit), var!(Bit)) {
let a_xor_b = a.clone() ^ b.clone();
let sum = a_xor_b.clone() ^ cin.clone();
let cout = (a & b) | (cin & a_xor_b.clone());
(sum, cout)
}
use graphviz_rust::{
cmd::{CommandArg, Format},
exec,
printer::PrinterContext,
};
use open_hypergraphs_dot::{dark_theme, generate_dot};
fn main() -> std::io::Result<()> {
let open_hypergraph = full_adder_arrow();
let dot_graph = generate_dot(&open_hypergraph, &dark_theme());
let png_bytes = exec(
dot_graph,
&mut PrinterContext::default(),
vec![CommandArg::Format(Format::Png)],
)?;
std::fs::write("images/adder.png", png_bytes)?;
Ok(())
}