internal void Refine(PRED psi) { if (left == null && right == null) { #region leaf var phi_and_psi = solver.MkAnd(phi, psi); if (solver.IsSatisfiable(phi_and_psi)) { var phi_min_psi = solver.MkAnd(phi, solver.MkNot(psi)); if (solver.IsSatisfiable(phi_min_psi)) { left = new PartitonTree <PRED>(solver, nr + 1, this, phi_and_psi, null, null); right = new PartitonTree <PRED>(solver, nr + 1, this, phi_min_psi, null, null); } else // [[phi]] subset of [[psi]] { left = new PartitonTree <PRED>(solver, nr + 1, this, phi, null, null); //psi must true } } else // [[phi]] subset of [[not(psi)]] { right = new PartitonTree <PRED>(solver, nr + 1, this, phi, null, null); //psi must be false } #endregion } else if (left == null) { right.Refine(psi); } else if (right == null) { left.Refine(psi); } else { #region nonleaf var phi_and_psi = solver.MkAnd(phi, psi); if (solver.IsSatisfiable(phi_and_psi)) { var phi_min_psi = solver.MkAnd(phi, solver.MkNot(psi)); if (solver.IsSatisfiable(phi_min_psi)) { left.Refine(psi); right.Refine(psi); } else // [[phi]] subset of [[psi]] { left.ExtendLeft(); //psi is true right.ExtendLeft(); } } else // [[phi]] subset of [[not(psi)]] { left.ExtendRight(); right.ExtendRight(); //psi is false } #endregion } }
PartitonTree(IBooleanAlgebra <PRED> solver, int depth, PartitonTree <PRED> parent, PRED phi, PartitonTree <PRED> left, PartitonTree <PRED> right) { this.solver = solver; this.parent = parent; this.nr = depth; this.phi = phi; this.left = left; this.right = right; }
PartitonTree <PRED> right; //complement internal PartitonTree(IBooleanAlgebra <PRED> solver) { this.solver = solver; nr = -1; parent = null; this.phi = solver.True; this.left = null; this.right = null; }
private void ExtendLeft() { if (left == null && right == null) { left = new PartitonTree <PRED>(solver, nr + 1, this, phi, null, null); } else if (left == null) { right.ExtendLeft(); } else if (right == null) { left.ExtendLeft(); } else { left.ExtendLeft(); right.ExtendLeft(); } }
/// <summary> /// Given an array of predidates {p_1, p_2, ..., p_n} where n>=0. /// Enumerate all satisfiable Boolean combinations Tuple({b_1, b_2, ..., b_n}, p) /// where p is satisfiable and equivalent to p'_1 & p'_2 & ... & p'_n, /// where p'_i = p_i if b_i = true and p'_i is Not(p_i) otherwise. /// If n=0 return Tuple({},True). /// </summary> /// <param name="preds">array of predicates</param> /// <param name="useEquivalenceChecking">optimization flag: if true, uses equivalence checking to cluster equivalent predicates; otherwise does not use equivalence checking</param> /// <returns>all minterms of the given predicate sequence</returns> public IEnumerable <Tuple <bool[], PRED> > GenerateMinterms(bool useEquivalenceChecking, params PRED[] preds) { if (preds.Length == 0) { yield return(new Tuple <bool[], PRED>(new bool[] { }, ba.True)); } else { var count = preds.Length; List <PRED> nonequivalentSets = new List <PRED>(); //work only with nonequivalent sets as distinct elements var indexLookup = new Dictionary <int, int>(); var newIndexMap = new Dictionary <EquivClass, int>(); var equivs = new List <List <int> >(); for (int i = 0; i < count; i++) { int newIndex; EquivClass equiv = CreateEquivalenceClass(useEquivalenceChecking, preds[i]); if (!newIndexMap.TryGetValue(equiv, out newIndex)) { newIndex = newIndexMap.Count; newIndexMap[equiv] = newIndex; nonequivalentSets.Add(preds[i]); equivs.Add(new List <int>()); } indexLookup[i] = newIndex; equivs[newIndex].Add(i); } //var pairs = new List<Tuple<IntSet, PRED>>(GenerateMinterms1(nonequivalentSets.ToArray())); //foreach (var pair in pairs) //{ // var characteristic = new bool[preds.Length]; // for (int i = 0; i < count; i++) // if (pair.First.Contains(indexLookup[i])) // characteristic[i] = true; // yield return // new Tuple<bool[], PRED>(characteristic, pair.Second); //} var tree = new PartitonTree <PRED>(ba); foreach (var psi in nonequivalentSets) { tree.Refine(psi); } foreach (var leaf in tree.GetLeaves()) { var characteristic = new bool[preds.Length]; foreach (var k in leaf.GetPath()) { foreach (var n in equivs[k]) { characteristic[n] = true; } } yield return (new Tuple <bool[], PRED>(characteristic, leaf.phi)); } } }