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 Or(PathCond other) { if (this.EqualsNega(other)) { return(TRUE); } else if (other is Conj || other is Disj) { // TODO: This doesn't preserve order of disjuncts: return(other.Or(this)); } else { return(Disj.Make(this, other)); } }
public override PathCond Or(PathCond other) { if (other is CachedAtom && conds.Contains(((CachedAtom)other).Negate())) { // Reduce Or(OR(...,e,...), NOT(e)) and Or(OR(...,NOT(e),...), e) to TRUE return(TRUE); } else if (other is Disj) { HashList <PathCond> result = new HashList <PathCond>(); result.AddAll(conds); foreach (PathCond cond in ((Disj)other).conds) { if (cond is CachedAtom && conds.Contains((cond as CachedAtom).Negate())) { // Reduce Or(OR(...,e,...),OR(...,NOT(e),...)) to TRUE // and Or(OR(...,NOT(e),...),OR(...,e,...)) to TRUE return(TRUE); } result.Add(cond); } return(Disj.Make(result.ToArray())); } else if (other is Conj) { if (((Conj)other).conds.Contains(this)) { // Reduce (pi | (p1 & ... & pn)) to pi return(this); } else { if (((Conj)other).conds.Any(cond => conds.Contains(cond))) { return(this); } } return(Disj.Make(AddItem(this.conds, other))); } else { return(Disj.Make(AddItem(this.conds, other))); } }