/// <summary> /// Checks the equality of objects. /// </summary> /// <param name="obj">Object to be checked.</param> /// <returns>True if the objects are equal, false otherwise.</returns> public override bool Equals(object obj) { OrExpression other = obj as OrExpression; if (other == null) { return(false); } return(CollectionsEquality.Equals(Children, other.Children)); }
/// <summary> /// Visits and transforms the expression. /// </summary> /// <param name="expression">Source expression.</param> /// <returns>Transformed expression.</returns> public override IExpression Visit(OrExpression expression) { List <IExpression> children = new List <IExpression>(); foreach (var child in expression.Children) { children.Add(child.Accept(this)); } HashSet <IExpression> primitives = new HashSet <IExpression>(); HashSet <AndExpression> andExpressions = new HashSet <AndExpression>(); foreach (var element in children) { AndExpression andExpression = element as AndExpression; if (andExpression != null) { andExpressions.Add(andExpression); continue; } OrExpression orExpression = element as OrExpression; if (orExpression != null) { foreach (var orChild in orExpression.Children) { primitives.Add(orChild); } } else { // predicate, equals, numericCompare, forall, exists primitives.Add(element); } } OrExpression primitivesClause = new OrExpression(new List <IExpression>(primitives)); if (andExpressions.Count == 0) { return(primitivesClause); } List <OrExpression> clauses = new List <OrExpression>(); if (primitives.Count != 0) { clauses.Add(primitivesClause); } return(new AndExpression(DistributeDisjunctions(new List <AndExpression>(andExpressions), clauses))); }
/// <summary> /// Visits and performs a property count on predicate expression. /// </summary> /// <param name="expression">Predicate expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <double, double> Visit(OrExpression expression) { double positiveValue = 0.0; double negativeValue = 0.0; foreach (var child in expression.Children) { var childPropertyCounts = child.Accept(this); positiveValue = Math.Max(positiveValue, childPropertyCounts.Item1); negativeValue = Math.Max(negativeValue, childPropertyCounts.Item2); } return(Tuple.Create(positiveValue, negativeValue)); }
/// <summary> /// Visits and performs a property count on predicate expression. /// </summary> /// <param name="expression">Predicate expression.</param> /// <returns>Tuple (property satisfied count, property not satisfied count).</returns> public Tuple <int, int> Visit(OrExpression expression) { int minFulfilled = int.MaxValue; int minNotFulfilled = int.MaxValue; foreach (var child in expression.Children) { var childPropertyCounts = child.Accept(this); minFulfilled = Math.Min(minFulfilled, childPropertyCounts.Item1); minNotFulfilled = Math.Min(minNotFulfilled, childPropertyCounts.Item2); } return(Tuple.Create(minFulfilled, minNotFulfilled)); }
/// <summary> /// Visits and transforms the expression. /// </summary> /// <param name="expression">Source expression.</param> /// <returns>Transformed expression.</returns> public override IExpression Visit(OrExpression expression) { List <IExpression> arguments = new List <IExpression>(); foreach (var child in expression.Children) { arguments.Add(child.Accept(this)); } if (IsNegating) { return(new AndExpression(arguments)); } return(new OrExpression(arguments)); }
/// <summary> /// Distributes disjunctions deeper into the expression (by deMorgan laws) - i.e. we need to push ORs inside the expression and pull ANDs /// outside the expression to get the CNF representation. We also filter out duplicates in the clauses and conjunctions (indepotence property). /// </summary> /// <param name="andExpressions">Conjunctions on the given level.</param> /// <param name="clauses">Disjunctions on the given level.</param> /// <returns>List of clauses or literals.</returns> private static List <IExpression> DistributeDisjunctions(List <AndExpression> andExpressions, List <OrExpression> clauses) { foreach (var andExpr in andExpressions) { List <OrExpression> newClauses = new List <OrExpression>(); foreach (var andElem in andExpr.Children) { HashSet <IExpression> andElemItems = new HashSet <IExpression>(); OrExpression orExpr = andElem as OrExpression; if (orExpr != null) { orExpr.Children.ForEach(child => andElemItems.Add(child)); } else { andElemItems.Add(andElem); } if (clauses.Count == 0) { newClauses.Add(new OrExpression(new List <IExpression>(andElemItems))); } else { foreach (var clause in clauses) { HashSet <IExpression> newOrChildren = new HashSet <IExpression>(); clause.Children.ForEach(child => newOrChildren.Add(child)); newOrChildren.UnionWith(andElemItems); newClauses.Add(new OrExpression(new List <IExpression>(newOrChildren))); } } } clauses = newClauses; } HashSet <IExpression> clausesList = new HashSet <IExpression>(); clauses.ForEach(clause => clausesList.Add(clause)); return(new List <IExpression>(clausesList)); }
/// <summary> /// Visits the expression. /// </summary> /// <param name="expression">Expression.</param> public override void Visit(OrExpression expression) { expression.Children.ForEach(child => child.Accept(this)); ClauseCNF clause = new ClauseCNF(); for (int i = 0; i < expression.Children.Count; ++i) { LiteralCNF literal = Stack.Pop() as LiteralCNF; if (literal != null) { clause.Add(literal); } else { Debug.Assert(false, "Source expression not in CNF!"); } } Stack.Push(clause); }