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}