SSoelvsten / adiar

An I/O-efficient implementation of (Binary) Decision Diagrams
https://ssoelvsten.github.io/adiar/
MIT License
24 stars 13 forks source link

Add `bdd_compose` #148

Open SSoelvsten opened 3 years ago

SSoelvsten commented 3 years ago

The Composition of two BDDs f and g for some label i ∊ [n] is f i = g is to be interpreted as f(x1, ..., xi-1, g(x1, ..., xn), xi+1, ..., xn), i.e. g dictates the value of the ith input variable. This function is used in some model checking algorithms.

Based on BuDDy, the declarations in adiar/bdd.h should be

  //////////////////////////////////////////////////////////////////////////////
  /// \brief Functional composition.
  ///
  /// \param f   Outer function
  ///
  /// \param g   Inner function
  ///
  /// \param var The variable that \c g replaces in the input of \c f
  /// 
  /// \returns \f$ f|_{x_{\mathit{var}} = g} \f$
  //////////////////////////////////////////////////////////////////////////////
  __bdd bdd_compose(const bdd &f, const bdd &g, label_t var);

  inline __bdd bdd_compose(const bdd &f, const bdd &g, const bdd &var)
  { bdd_compose(f, g, min_label(v)); }

Implementation

This can be implemented with a single sweep through f and g by reusing the ideas in the Quantification and the If-Then-Else algorithms. A priority queue contains requests on triples t1, t2, t3 where t2 and t3 are nodes from f and t1 is from g. Here, similar to If-Then-Else, t2 represents the true (high) branch on variable i and t3 the false branch (low).

For level i we deal with it somewhat similar to Quantify where a single node of f is turned into two. To this end, we need to introduce the same idea as we did for the product construction etc. with the std::variant<skipto, output> and the policy::may_skip optimisation, where we use skipto if g is not on level i.

The pruning of the If-Then-Else still apply. Ideas from Quantification also somewhat applies here.

All of this should be possible to do with the policy pattern on the algorithm in the adiar/bdd/if_then_else.cpp.

When this is done, then slowly add enough hooks in the policy of prod3 to vary the behaviour between the two algorithms.

SSoelvsten commented 1 year ago

We also somehow should make the prod3 algorithm as to whether there truly are three or only two BDDs for the input (to not open a stream for the same input twice). This is important for #485 .