Skip to content

Consider optimizing variable order to reduce BDD size #18

Description

@Ravenslofty

Here's my example program:

use boolean_expression::{BDD, Expr};

fn main() {
    let node = |name: &str| Expr::Terminal(name.to_string());

    let a_select = (node("as0") & node("ai0")) | (node("as1") & node("ai1")) | (node("as2") & node("ai2")) | (node("as3") & node("ai3")) | (node("as4") & node("ai4")) | (node("as5") & node("ai5")) | (node("as6") & node("ai6"));
    let b_select = (node("bs0") & node("bi0")) | (node("bs1") & node("bi1")) | (node("bs2") & node("bi2")) | (node("bs3") & node("bi3")) | (node("bs4") & node("bi4")) | (node("bs5") & node("bi5")) | (node("bs6") & node("bi6"));

    let a_inverted = a_select ^ node("ainv");
    let b_inverted = b_select ^ node("binv");

    let andxor = (!node("andxor") & a_inverted.clone() & b_inverted.clone()) | (node("andxor") & (a_inverted.clone() ^ b_inverted.clone()));
    let muxout = (!node("muxsel") & a_inverted) | (node("muxsel") & b_inverted);

    let output = (!node("usemux") & andxor) | (node("usemux") & muxout);

    let mut bdd = BDD::new();
    let top = bdd.from_expr(&output);

    println!("{}", bdd.to_dot(top));
}

If you look at the output dot, there's a lot of duplication of things like the a_select and b_select muxes, much of which I would argue is unnecessary.

vcxsrv_2021-03-20_15-07-08
From this snippet of the output, it seems to me that all the "b_inv is true" nodes can be merged and all the "b_inv is false" nodes can be merged. If you then recursively follow this upwards, this would remove a lot of redundancy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions