Skip to content

Consider optimizing variable order to reduce BDD size #18

@Ravenslofty

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