/** * Flattens this circuit with respect to the given operator into the provided set. Specifically, * the method modifies the set so that it contains the elements f_0, ..., f_k' where k' <= k * elements and [[this]] = op(f_0, ..., f_k'). The default implementation simply adds this to the * set. * * @requires k > 0 * @effects 1 <= k' <= k && some f_0,..., f_k' : flat.elts' | [[this]] = op([[f_0]], ..., * [[f_k']]) */ @Override void flatten(Operator op, Set<BooleanFormula> flat, int k) { assert k > 0; if (this.op == op && k > 1) { final int oldsize = flat.size(); low.flatten(op, flat, k - 1); high.flatten(op, flat, k - (flat.size() - oldsize)); } else { flat.add(this); } }
/** * Returns an integer k' such that 0 < |k'| < k and |k'| is the number of flattening steps that * need to be taken to determine that this circuit has (or does not have) an input with the given * label. A positive k' indicates that f is found to be an input to this circuit in k' steps. A * negative k' indicates that f is not an input to this circuit, when it is flattened using at * most k steps. * * @requires k > 0 * @return the number of flattening steps that need to be taken to determine that f is (not) an * input to this circuit */ @Override int contains(Operator op, int f, int k) { assert k > 0; if (f == label()) return 1; else if (this.op != op || k < 2 || f > label() || -f > label()) return -1; else { final int l = low.contains(op, f, k - 1); if (l > 0) return l; else { final int h = high.contains(op, f, k - l); return h > 0 ? h - l : h + l; } } }
/** * Constructs a new binary gate with the given operator, label, and inputs. * * @requires components.h = components.l && l.label < h.label * @effects this.op' = op && this.inputs' = l + h && this.label' = label */ BinaryGate(Operator.Nary op, int label, int hashcode, BooleanFormula l, BooleanFormula h) { super(op, label, hashcode); assert l.label() < h.label(); this.low = l; this.high = h; }