Can't traverse an iterator more than once

BTW. I’m pretty happy with the current state of the code once it has been debugged. Especially how I was finally able to express generating a Bdd from randomly selected truth table (genRandomBdd) vs generating a Bdd from the k’th truth table (genKthBdd) without having to generate a random 2^n bit integer, which may be larger than Long.MaxVal.


  def clauseToBdd(clause: Clause, ident: BddTerm, op: BinaryOperation): Bdd = {
    // interpreting clause as an OR so that clause is CNF rather than DNF
    def conv(i: Int): Bdd = Bdd(i)

    treeReduce(clause, ident: Bdd, conv, (acc: Bdd, b: Bdd) => op(acc, b))
  }

  def cnfClauseToBdd(cnfClause: Clause): Bdd = clauseToBdd(cnfClause, BddFalse, Or)

  def dnfClauseToBdd(dnfClause: Clause): Bdd = clauseToBdd(dnfClause, BddTrue, And)

  // Interpret a list of Clauses as an And of Ors where each clause is a disjunction
  def cnfToBdd(cnf: TraversableOnce[Clause]): Bdd = {
    treeReduce(cnf, BddTrue, cnfClauseToBdd, { (acc: Bdd, b: Bdd) => And(acc, b) })
  }

  // Interpret a list of Clauses as an Or of Ands where each clause is a conjunction
  def dnfToBdd(dnf: TraversableOnce[Clause]): Bdd = {
    treeReduce(dnf, BddFalse, dnfClauseToBdd, { (acc: Bdd, b: Bdd) => Or(acc, b) })
  }

  def genBddFromBitMask(n: Int, f: Int => Boolean): Bdd = {
    val dnf = for {
      truthTableRow <- (0 until (1 << n)).iterator
      if f(truthTableRow)
    } yield minTerm(n, truthTableRow)
    dnfToBdd(dnf)
  }

  val prng = scala.util.Random

  // Generate randomly selected BDD of n variables.
  // In terms of truth table, this is equivalent to choosing a number between 0 and 2^n-1 where
  // each 1 in k'th position of the binary representation indicates a T in the k'th row
  // of the truth table, but we don't really generate such an integer as it may be larger
  // than Long.MaxValue
  def genRandomBdd(n: Int): Bdd = {
    genBddFromBitMask(n, _ => (0 == prng.nextInt(2)))
  }

  // if the 1 bits of the binary representation of k denote the True
  // rows in the truth table, with the least significant bit representing
  // variable x1. (there is no x0)
  // k is interpreted as a 2^n-bit binary number. 0 <= k < 2^(2^n)
  def genKthBdd(n: Int, k: Long): Bdd = {
    // we interpret k as a 'function' mapping the range 0<=i<2^n to Boolean
    //   whose value is true if there is a 1 in the ith position of k,
    //   considering the 0'th position as the least significant bit.
    genBddFromBitMask(n, truthTableRow => (k & (1 << truthTableRow)) != 0)
  }