/// <summary> /// Invariant: algebra.IsSatisfiable(context), assumes that bag1 has no dead branches /// </summary> private IteBag <T> OpInContext(BagOpertion op, T context, IteBag <T> bag1, IteBag <T> bag2) { IteBag <T> bag; var key = new Tuple <BagOpertion, T, IteBag <T>, IteBag <T> >(op, context, bag1, bag2); if (opCache.TryGetValue(key, out bag)) { return(bag); } if (bag1.IsLeaf) { return(OpInContext2(op, context, bag1, bag2)); } var context1 = algebra.MkAnd(context, bag1.Predicate); var context2 = algebra.MkAnd(context, algebra.MkNot(bag1.Predicate)); var t = OpInContext(op, context1, bag1.TrueCase, bag2); var f = OpInContext(op, context2, bag1.FalseCase, bag2); bag = MkNode(bag1.Predicate, t, f); opCache[key] = bag; return(bag); }
public bool IntersectsWith(IteBag <T> bag) { if (bag.builder != builder) { throw new AutomataException(AutomataExceptionKind.IteBagError); } return(builder.IsNonemptyIntersection(this, bag)); }
public IteBag <T> Min(IteBag <T> bag) { if (bag.builder != builder) { throw new AutomataException(AutomataExceptionKind.IteBagError); } return(builder.Op(BagOpertion.MIN, this, bag)); }
internal IteBag(IteBagBuilder <T> builder, int count, T predicate, IteBag <T> trueCase, IteBag <T> falseCase) { this.builder = builder; this.Count = count; this.Predicate = predicate; this.TrueCase = trueCase; this.FalseCase = falseCase; }
private bool IsNonemptyIntersection_2(T context, IteBag <T> leaf, IteBag <T> bag2) { bool res; var key = new Tuple <T, IteBag <T>, IteBag <T> >(context, leaf, bag2); if (intersectionEmptinessTestCache.TryGetValue(key, out res)) { return(res); } else { if (bag2.IsLeaf) { if (leaf.Count > 0 && bag2.Count > 0) { res = true; } else { res = false; } } else { var context_t = algebra.MkAnd(context, bag2.Predicate); if (algebra.IsSatisfiable(context_t)) { var context_f = algebra.MkAnd(context, algebra.MkNot(bag2.Predicate)); if (algebra.IsSatisfiable(context_f)) { if (IsNonemptyIntersection_2(context_t, leaf, bag2.TrueCase)) { res = true; } else if (IsNonemptyIntersection_2(context_f, leaf, bag2.FalseCase)) { res = true; } else { res = false; } } else //~IsSat(context & ~ bag2.Predicate) ---> IsValid(context ==> bag2.Predicate) { res = IsNonemptyIntersection_2(context, leaf, bag2.TrueCase); } } else //~IsSat(context & bag2.Predicate) ---> IsValid(context ==> ~ bag2.Predicate) { res = IsNonemptyIntersection_2(context, leaf, bag2.FalseCase); } } intersectionEmptinessTestCache[key] = res; return(res); } }
internal bool IsNonemptyIntersection(IteBag <T> bag1, IteBag <T> bag2) { count[BagOpertion.ISNONEMPTYINTERSECTION] += 1; stopwatch[BagOpertion.ISNONEMPTYINTERSECTION].Start(); var res = IsNonemptyIntersection_1(algebra.True, bag1, bag2); stopwatch[BagOpertion.ISNONEMPTYINTERSECTION].Stop(); return(res); }
internal IteBag <T> Op(BagOpertion op, IteBag <T> bag1, IteBag <T> bag2) { count[op] += 1; stopwatch[op].Start(); var res = OpInContext(op, algebra.True, bag1, bag2); stopwatch[op].Stop(); return(res); }
public IteBagBuilder(IBooleanAlgebra <T> algebra) { this.algebra = algebra; leafCache[0] = new IteBag <T>(this, 0, default(T), null, null); leafCache[1] = new IteBag <T>(this, 1, default(T), null, null); foreach (BagOpertion op in Enum.GetValues(typeof(BagOpertion))) { count[op] = 0; stopwatch[op] = new System.Diagnostics.Stopwatch(); } }
IteBag <T> MkLeaf(int count) { IteBag <T> leaf; if (leafCache.TryGetValue(count, out leaf)) { return(leaf); } leaf = new IteBag <T>(this, count, default(T), null, null); leafCache[count] = leaf; return(leaf); }
IteBag <T> MkNode(T predicate, IteBag <T> t, IteBag <T> f) { if (t == f) { return(t); } IteBag <T> bag; var key = new Tuple <T, IteBag <T>, IteBag <T> >(predicate, t, f); if (nodeCache.TryGetValue(key, out bag)) { return(bag); } bag = new IteBag <T>(this, -1, predicate, t, f); nodeCache[key] = bag; return(bag); }
private bool IsNonemptyIntersection_1(T context, IteBag <T> bag1, IteBag <T> bag2) { bool res; var key = new Tuple <T, IteBag <T>, IteBag <T> >(context, bag1, bag2); if (intersectionEmptinessTestCache.TryGetValue(key, out res)) { return(res); } else { if (bag1.IsLeaf) { res = IsNonemptyIntersection_2(context, bag1, bag2); } else { var context1 = algebra.MkAnd(context, bag1.Predicate); if (IsNonemptyIntersection_1(context1, bag1.TrueCase, bag2)) { res = true; } else { var context2 = algebra.MkAnd(context, algebra.MkNot(bag1.Predicate)); if (IsNonemptyIntersection_1(context2, bag1.FalseCase, bag2)) { res = true; } else { res = false; } } } intersectionEmptinessTestCache[key] = res; return(res); } }
private IteBag <T> OpInContext2(BagOpertion op, T context, IteBag <T> leaf, IteBag <T> bag2) { if (bag2.IsLeaf) { var newleaf = MkLeaf(ApplyOp(op, leaf.Count, bag2.Count)); return(newleaf); } IteBag <T> bag; var key = new Tuple <BagOpertion, T, IteBag <T>, IteBag <T> >(op, context, leaf, bag2); if (opCache.TryGetValue(key, out bag)) { return(bag); } var context_t = algebra.MkAnd(context, bag2.Predicate); if (algebra.IsSatisfiable(context_t)) { var context_f = algebra.MkAnd(context, algebra.MkNot(bag2.Predicate)); if (algebra.IsSatisfiable(context_f)) { bag = MkNode(bag2.Predicate, OpInContext2(op, context_t, leaf, bag2.TrueCase), OpInContext2(op, context_f, leaf, bag2.FalseCase)); } else //~IsSat(context & ~ bag2.Predicate) ---> IsValid(context ==> bag2.Predicate) { bag = OpInContext2(op, context, leaf, bag2.TrueCase); } } else //~IsSat(context & bag2.Predicate) ---> IsValid(context ==> ~ bag2.Predicate) { bag = OpInContext2(op, context, leaf, bag2.FalseCase); } opCache[key] = bag; return(bag); }