Beispiel #1
0
        private static BoundQuery ToDisjunctiveNormalForm(BoundQuery node)
        {
            if (node is BoundNegatedQuery negated)
            {
                return(ToDisjunctiveNormalForm(Negate(negated.Query)));
            }

            if (node is BoundOrQuery or)
            {
                var left  = ToDisjunctiveNormalForm(or.Left);
                var right = ToDisjunctiveNormalForm(or.Right);
                if (ReferenceEquals(left, or.Left) &&
                    ReferenceEquals(right, or.Right))
                {
                    return(node);
                }

                return(new BoundOrQuery(left, right));
            }

            if (node is BoundAndQuery and)
            {
                var left  = ToDisjunctiveNormalForm(and.Left);
                var right = ToDisjunctiveNormalForm(and.Right);

                // (A OR B) AND C      ->    (A AND C) OR (B AND C)

                if (left is BoundOrQuery leftOr)
                {
                    var a = leftOr.Left;
                    var b = leftOr.Right;
                    var c = right;
                    return(new BoundOrQuery(
                               ToDisjunctiveNormalForm(new BoundAndQuery(a, c)),
                               ToDisjunctiveNormalForm(new BoundAndQuery(b, c))
                               ));
                }

                // A AND (B OR C)      ->    (A AND B) OR (A AND C)

                if (right is BoundOrQuery rightOr)
                {
                    var a = left;
                    var b = rightOr.Left;
                    var c = rightOr.Right;
                    return(new BoundOrQuery(
                               ToDisjunctiveNormalForm(new BoundAndQuery(a, b)),
                               ToDisjunctiveNormalForm(new BoundAndQuery(a, c))
                               ));
                }

                return(new BoundAndQuery(left, right));
            }

            return(node);
        }
Beispiel #2
0
            static void Walk(IndentedTextWriter writer, BoundQuery node)
            {
                switch (node)
                {
                case BoundKevValueQuery kevValue:
                    writer.WriteLine($"{(kevValue.IsNegated ? "-" : "")}{kevValue.Key}:{kevValue.Value}");
                    break;

                case BoundTextQuery text:
                    writer.WriteLine($"{(text.IsNegated ? "-" : "")}{text.Text}");
                    break;

                case BoundNegatedQuery negated:
                    writer.WriteLine("NOT");
                    writer.Indent++;
                    Walk(writer, negated.Query);
                    writer.Indent--;
                    break;

                case BoundAndQuery and:
                    writer.WriteLine("AND");
                    writer.Indent++;
                    Walk(writer, and.Left);
                    Walk(writer, and.Right);
                    writer.Indent--;
                    break;

                case BoundOrQuery or:
                    writer.WriteLine("OR");
                    writer.Indent++;
                    Walk(writer, or.Left);
                    Walk(writer, or.Right);
                    writer.Indent--;
                    break;

                default:
                    throw new Exception($"Unexpected node {node.GetType()}");
                }
            }
Beispiel #3
0
        private static BoundQuery Negate(BoundQuery node)
        {
            switch (node)
            {
            case BoundKevValueQuery kevValue:
                return(NegateKevValueExpression(kevValue));

            case BoundTextQuery text:
                return(NegateTextExpression(text));

            case BoundNegatedQuery negated:
                return(NegateNegatedExpression(negated));

            case BoundAndQuery and:
                return(NegateAndExpression(and));

            case BoundOrQuery or:
                return(NegateOrExpression(or));

            default:
                throw new Exception($"Unexpected node {node.GetType()}");
            }
        }