public static BooleanExpression FindMininalExpressionInBasis(int n, BooleanOperation[] ops,
			BooleanVariable[] vars, ExpressionSearchMode mode = ExpressionSearchMode.CountOps)
        {
            var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
            var knownTruthTables = new HashSet<byte>();
            var knownExpressions = new HashSet<BooleanExpression>();

            foreach(var variable in vars) {
                queue.TryEnqueue(new VarExpression(variable), 1);
            }

            while(queue.Count != 0) {
                var curExperession = queue.Dequeue();

                byte truthTable = curExperession.Eval();

                if(knownTruthTables.Contains(truthTable)) {
                    continue;
                }

                if(curExperession.Eval() == n) {
                    return curExperession;
                }

                knownExpressions.Add(curExperession);
                knownTruthTables.Add(truthTable);

                foreach(var anotherExpression in knownExpressions) {
                    foreach(var neighbourExpression in curExperession.CombineWith(anotherExpression, ops)) {
                        queue.TryEnqueue(neighbourExpression, mode == ExpressionSearchMode.CountBlocks
                            ? neighbourExpression.CountBlocks() : neighbourExpression.CountOps());
                    }
                }
            }

            throw new CouldntFindExpressionException();
        }
        public static BooleanExpression FindMininalExpressionForBinary(BooleanExpression targetBinary, BooleanFunction f,
			List<BooleanExpression> availableExpressions)
        {
            var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
            var knownTruthTables = new HashSet<byte>();
            var knownExpressions = new HashSet<BooleanExpression>();

            foreach(var expression in availableExpressions) {
                queue.TryEnqueue(expression, 1);
            }

            while(queue.Count != 0) {
                var curExperession = queue.Dequeue();

                byte truthTable = curExperession.Eval();

                if(knownTruthTables.Contains(truthTable)) {
                    continue;
                }

                if((curExperession.Eval() & 0xAA) == (targetBinary.Eval() & 0xAA)) {
                    return curExperession;
                }

                knownExpressions.Add(curExperession);
                knownTruthTables.Add(truthTable);

                foreach(var anotherExpression in knownExpressions) {
                    foreach(var thirdExpression in knownExpressions) {
                        foreach(var neighbourExpression in CombineTertiary(f, curExperession, anotherExpression, thirdExpression)) {
                            queue.TryEnqueue(neighbourExpression, neighbourExpression.CountOps());
                        }
                    }
                }
            }

            throw new CouldntFindExpressionException();
        }