///|
/// Translate one validated instruction into little-endian Boolean literals.
fn Encoder::blast(
  self : Encoder,
  node : Node,
  values : Array[Array[Int32]],
) -> Array[Int32] raise Failure {
  if node.op == "state" || node.op == "input" {
    return self.word(node.width)
  }
  if node.args.is_empty() {
    return constant_word(node.value, node.width)
  }
  let a = values[node.args[0]]
  let b = if node.args.length() > 1 { values[node.args[1]] } else { [] }
  match node.op {
    "not" => a.map(x => -x)
    "neg" => self.neg_word(a)
    "inc" => self.add_word(a, constant_word(1UL, a.length()), -1)
    "dec" => self.add_word(a, constant_word(mask(a.length()), a.length()), -1)
    "add" => self.add_word(a, b, -1)
    "sub" => self.add_word(a, b.map(x => -x), 1)
    "mul" => self.multiply(a, b)
    "ite" => self.mux_word(a[0], b, values[node.args[2]])
    "eq" | "iff" => [self.equal_word(a, b)]
    "neq" => [-self.equal_word(a, b)]
    "implies" => [self.or_gate(-a[0], b[0])]
    "ult" => [self.less_word(a, b)]
    "ulte" => [-self.less_word(b, a)]
    "ugt" => [self.less_word(b, a)]
    "ugte" => [-self.less_word(a, b)]
    "slt" => [self.signed_less(a, b)]
    "slte" => [-self.signed_less(b, a)]
    "sgt" => [self.signed_less(b, a)]
    "sgte" => [-self.signed_less(a, b)]
    "sll" | "srl" | "sra" => self.shift_word(a, b, node.op)
    "slice" => Array::makei(node.width, i => a[i + node.params[1]])
    "concat" => {
      let out = b.copy()
      for bit in a {
        out.push(bit)
      }
      out
    }
    "uext" | "sext" => {
      let out = a.copy()
      let fill = if node.op == "sext" { a[a.length() - 1] } else { -1 }
      for i = a.length(); i < node.width; i = i + 1 {
        out.push(fill)
      }
      out
    }
    "redand" | "redor" | "redxor" => {
      let mut result = if node.op == "redand" { 1 } else { -1 }
      for bit in a {
        result = match node.op {
          "redand" => self.and_gate(result, bit)
          "redor" => self.or_gate(result, bit)
          _ => self.xor_gate(result, bit)
        }
      }
      [result]
    }
    _ => {
      let out = []
      for i = 0; i < a.length(); i = i + 1 {
        let bit = match node.op {
          "and" => self.and_gate(a[i], b[i])
          "or" => self.or_gate(a[i], b[i])
          "xor" => self.xor_gate(a[i], b[i])
          "nand" => -self.and_gate(a[i], b[i])
          "nor" => -self.or_gate(a[i], b[i])
          "xnor" => -self.xor_gate(a[i], b[i])
          _ => {
            fail(0, "internal unsupported bit-blast instruction")
            -1
          }
        }
        out.push(bit)
      }
      out
    }
  }
}