libreda-logic 0.0.3

Logic library for LibrEDA.
Documentation
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Logic networks.

pub mod aig;
pub mod generic_network;
pub mod klut;
pub mod mig;

/// Either a node or a node ID.
/// Used to make node simplification syntactically clean.
pub enum SimplifyResult<Node, NodeId> {
    /// Not fully simplified node with an optional inversion of the output.
    Node(Node, bool),
    /// Simplified down to an existing node ID with optional inversion of the output.
    Simplified(NodeId, bool),
}

impl<N, Id> SimplifyResult<N, Id> {
    /// If the result is not simplified yet, try to simplify the node further using the function `f`.
    pub fn and_then(self, f: impl Fn(N) -> SimplifyResult<N, Id>) -> SimplifyResult<N, Id> {
        match self {
            Self::Node(n, invert) => f(n).invert_conditional(invert), // Simplify using `f`.
            _ => self,                                                // Already simplified.
        }
    }

    /// Apply `f` to the node if it is not simplified yet.
    pub fn map_unsimplified(self, f: impl Fn(N) -> N) -> SimplifyResult<N, Id> {
        match self {
            Self::Node(n, invert) => Self::Node(f(n), invert),
            _ => self,
        }
    }

    /// Create from a node.
    pub fn new_node(node: N) -> Self {
        Self::Node(node, false)
    }

    /// Create from a node ID.
    pub fn new_id(id: Id) -> Self {
        Self::Simplified(id, false)
    }

    /// Invert the output value iff `invert` is `true`.
    pub fn invert_conditional(self, invert: bool) -> Self {
        match self {
            SimplifyResult::Node(n, i) => Self::Node(n, i ^ invert),
            SimplifyResult::Simplified(n, i) => Self::Simplified(n, i ^ invert),
        }
    }
}