public override PathCond Or(PathCond other) { if (this.Is(true) || other.Is(true)) { return(TRUE); } else if (this.Is(false)) { return(other); } else if (other.Is(false)) { return(this); } else if (conds.Contains(other)) { // Reduce ((p1 & ... & pn)) | pi to pi return(other); } else if (other is Disj) { // TODO: This doesn't preserve order of disjuncts: return(other.Or(this)); } else if (other is Conj) { if ((other as Conj).conds.Contains(this)) { // Reduce (pi | (p1 & ... & pn)) to pi return(this); } else { HashList <PathCond> intersect = HashList <PathCond> .Intersection(this.conds, (other as Conj).conds); if (intersect.Count > 0) { // Reduce (p1 & ... & pn & q1 & ... & qm) | (p1 & ... & pn & r1 & ... & rk) // to (p1 & ... & pn & (q1 & ... & qm | r1 & ... & rk). // The pi go in intersect, qi in thisRest, and ri in otherRest. HashList <PathCond> thisRest = HashList <PathCond> .Difference(this.conds, intersect); HashList <PathCond> otherRest = HashList <PathCond> .Difference((other as Conj).conds, intersect); // This recursion terminates because thisRest is smaller than this.conds intersect.Add(Conj.Make(thisRest.ToArray()).Or(Conj.Make(otherRest.ToArray()))); return(Conj.Make(intersect.ToArray())); } else { return(Disj.Make(AddItem(this.conds, other))); } } } else { return(Disj.Make(this, other)); } }
public override PathCond AndNot(CachedAtom cond) { if (this.Equals(cond)) { return(FALSE); } else { return(Conj.Make(this, cond.Negate())); } }
public override PathCond And(CachedAtom cond) { return(Conj.Make(this, cond)); // Alternatively, weed out disjuncts inconsistent with the condition, // using an order-preserving version of this code: // HashSet<PathCond> result = new HashSet<PathCond>(); // result.AddAll(conds); // result.Filter(disj => !(disj is NegAtom && (disj as NegAtom).cond.Equals(cond) // || disj is Conj && (disj as Conj).conds.Contains(new NegAtom(cond)))); // return Conj.Make(Make(result.ToArray(), new Atom(cond)); }
public override PathCond AndNot(CachedAtom cond) { return(Conj.Make(this, cond.Negate())); }