/* Apply Disjunctive Normal Form. Convert ANDs of ORs to ORs of ANDs. For example: (A OR B) AND C => (A AND C) OR (B AND C) Also apply constant folding. Remove any constant terms. */ func (this *DNF) VisitAnd(expr *expression.And) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } // Constant folding var terms expression.Expressions for _, term := range expr.Operands() { val := term.Value() if val == nil { if terms == nil { terms = make(expression.Expressions, 0, len(expr.Operands())) } terms = append(terms, term) continue } if !val.Truth() { return expression.FALSE_EXPR, nil } } if len(terms) == 0 { return expression.TRUE_EXPR, nil } if len(terms) < len(expr.Operands()) { expr = expression.NewAnd(terms...) } // DNF if dnfComplexity(expr, 16) >= 16 { return expr, nil } else { return applyDNF(expr, 0), nil } }