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)); } }
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { for (int i = 0; i < es.Length; i++) { es[i].EvalCond(evalCond, evalConds, caches); } }
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { PathCond old; if (evalConds.TryGetValue(cellAddr, out old)) { evalConds[cellAddr] = old.Or(evalCond); } else { evalConds[cellAddr] = evalCond; } }
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 void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { for (int i = 0; i < es.Length; i++) { es[i].EvalCond(evalCond, evalConds, caches); if (SHORTCIRCUIT_EVALCONDS && i != es.Length - 1) { // Take short-circuit evaluation into account for precision CachedAtom atom = new CachedAtom(es[i], caches); evalCond = evalCond.AndNot(atom); es[i] = atom.cachedExpr; } } }
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { if (es.Length >= 1) { CachedAtom atom = new CachedAtom(es[0], caches); CGCachedExpr cached = atom.cachedExpr; es[0].EvalCond(evalCond, evalConds, caches); es[0] = cached; for (int i = 1; i < es.Length; i++) { CGExpr iConst = CGConst.Make(i); CGExpr cond = new CGEqual(new CGExpr[] {cached, iConst}); es[i].EvalCond(evalCond.And(new CachedAtom(cond, caches)), evalConds, caches); } } }
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 void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { if (es.Length == 3) { CachedAtom atom = new CachedAtom(es[0], caches); es[0].EvalCond(evalCond, evalConds, caches); es[0] = atom.cachedExpr; es[1].EvalCond(evalCond.And(atom), evalConds, caches); es[2].EvalCond(evalCond.AndNot(atom), evalConds, caches); } }
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) {}
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { throw new ImpossibleException("CGCachedExpr.EvalCond"); }
public override bool Equals(PathCond other) { return other is Conj && conds.UnsequencedEquals((other as Conj).conds); }
public override bool Equals(PathCond other) { return other is Disj && conds.UnsequencedEquals(((Disj)other).conds); }
public bool EqualsNega(PathCond other) { CachedAtom atom = other as CachedAtom; return atom != null && cachedExpr.Equals(atom.cachedExpr) && negated != atom.negated; }
public override bool Equals(PathCond other) { CachedAtom atom = other as CachedAtom; return atom != null && cachedExpr.Equals(atom.cachedExpr) && negated == atom.negated; }
/// <summary> /// Update the evaluation conditions (in the evalConds dictionary) for every cell /// referenced from this expression, assuming that this expression itself /// has evaluation condition evalCond. /// </summary> /// <param name="evalCond"></param> /// <param name="evalConds"></param> public abstract void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches);