private IEnumerable <EnumerationItem> EnumerableBinary(int minSize, int maxSize, byte[] prefix, int prefixSize, byte[] operations, Operation op, int unusedOpsToSpend, int unusedSpent, int usedOps) { var totalArgsSize = maxSize - op.size; var minLeftTree = (minSize - op.size) / 2; foreach (var arg0 in EnumerateSubtrees(minLeftTree, totalArgsSize - 1, prefix, prefixSize + 1, operations, unusedOpsToSpend, usedOps)) { var withFirstArgMask = prefix.GetMask(arg0.subtree.First - 1, arg0.subtree.Last); var singleSecond = withFirstArgMask.IsConstant(); var leftMaxSize = maxSize - op.size - arg0.subtree.Size; var leftMinSize = minSize - op.size - arg0.subtree.Size; Debug.Assert(leftMaxSize >= 1); //TODO: symm optimization foreach (var arg1 in EnumerateSubtrees(leftMinSize, leftMaxSize, prefix, prefixSize + arg0.subtree.Len + 1, operations, unusedOpsToSpend - arg0.unusedSpent, arg0.usedOps)) { var enumerationItem = new EnumerationItem(new Subtree(prefix, prefixSize, arg1.subtree.Last), unusedSpent + arg0.unusedSpent + arg1.unusedSpent, arg1.usedOps); Mask mask = enumerationItem.subtree.GetMask(); if (!mask.IsZero() && !mask.IsOne()) { yield return(enumerationItem); } if (singleSecond) { break; } } } }
private IEnumerable <EnumerationItem> EnumerationIfBranches(int minSize, int maxSize, byte[] prefix, int prefixSize, byte[] operations, EnumerationItem cond, int unusedOpsToSpend, int unusedSpent, bool singleElse, bool singleZero) { foreach (var zeroExp in EnumerateSubtrees(1, maxSize - 1, prefix, prefixSize + 1 + cond.subtree.Len, operations, unusedOpsToSpend - cond.unusedSpent, cond.usedOps)) { var elseMaxSize = maxSize - zeroExp.subtree.Size; var elseMinSize = minSize - zeroExp.subtree.Size; Debug.Assert(elseMaxSize >= 1); var spent = cond.unusedSpent + zeroExp.unusedSpent; bool something = false; foreach (var elseExp in EnumerateSubtrees(elseMinSize, elseMaxSize, prefix, prefixSize + 1 + cond.subtree.Len + zeroExp.subtree.Len, operations, unusedOpsToSpend - spent, zeroExp.usedOps)) { yield return(new EnumerationItem(new Subtree(prefix, prefixSize, elseExp.subtree.Last), unusedSpent + spent + elseExp.unusedSpent, elseExp.usedOps)); something = true; if (singleElse) { break; // yield break; } } if (something && singleZero) { yield break; // yield break; } } }