libreda_logic/networks/mod.rs
1// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5//! Logic networks.
6
7pub mod aig;
8pub mod generic_network;
9pub mod klut;
10pub mod mig;
11
12/// Either a node or a node ID.
13/// Used to make node simplification syntactically clean.
14pub enum SimplifyResult<Node, NodeId> {
15 /// Not fully simplified node with an optional inversion of the output.
16 Node(Node, bool),
17 /// Simplified down to an existing node ID with optional inversion of the output.
18 Simplified(NodeId, bool),
19}
20
21impl<N, Id> SimplifyResult<N, Id> {
22 /// If the result is not simplified yet, try to simplify the node further using the function `f`.
23 pub fn and_then(self, f: impl Fn(N) -> SimplifyResult<N, Id>) -> SimplifyResult<N, Id> {
24 match self {
25 Self::Node(n, invert) => f(n).invert_conditional(invert), // Simplify using `f`.
26 _ => self, // Already simplified.
27 }
28 }
29
30 /// Apply `f` to the node if it is not simplified yet.
31 pub fn map_unsimplified(self, f: impl Fn(N) -> N) -> SimplifyResult<N, Id> {
32 match self {
33 Self::Node(n, invert) => Self::Node(f(n), invert),
34 _ => self,
35 }
36 }
37
38 /// Create from a node.
39 pub fn new_node(node: N) -> Self {
40 Self::Node(node, false)
41 }
42
43 /// Create from a node ID.
44 pub fn new_id(id: Id) -> Self {
45 Self::Simplified(id, false)
46 }
47
48 /// Invert the output value iff `invert` is `true`.
49 pub fn invert_conditional(self, invert: bool) -> Self {
50 match self {
51 SimplifyResult::Node(n, i) => Self::Node(n, i ^ invert),
52 SimplifyResult::Simplified(n, i) => Self::Simplified(n, i ^ invert),
53 }
54 }
55}