internal void Refine(IBooleanAlgebra <S> solver, S newSet) { var set_cap_newSet = solver.MkAnd(set, newSet); if (!solver.IsSatisfiable(set_cap_newSet)) { return; //set is disjoint from newSet } if (solver.AreEquivalent(set, set_cap_newSet)) { return; //set is a subset of newSet } var set_minus_newSet = solver.MkAnd(set, solver.MkNot(newSet)); if (left == null) //leaf { left = new PartTree(set_cap_newSet, null, null); right = new PartTree(set_minus_newSet, null, null); } else { left.Refine(solver, newSet); right.Refine(solver, newSet); } }
/// <summary> /// Refines the current partition with respect to the given set. /// The given set is not required be a subset of the initial set. /// </summary> /// <param name="B">given set</param> public void Refine(S B) { var A = partitions.set; if (!solver.AreEquivalent(A, B)) { var B_minus_A = solver.MkAnd(B, solver.MkNot(A)); if (solver.IsSatisfiable(B_minus_A)) //new elements are added to the total set { var A_union_B = solver.MkOr(A, B); var A_intersect_B = solver.MkAnd(A, B); var A_minus_B = solver.MkAnd(A, solver.MkNot(B)); var left = new PartTree(B_minus_A, null, null); this.partitions = new PartTree(A_union_B, left, this.partitions); if (solver.IsSatisfiable(A_intersect_B) && solver.IsSatisfiable(A_minus_B)) { this.partitions.right.Refine(solver, A_minus_B); } } else // B is a subset of A { partitions.Refine(solver, B); } } }
internal PartTree(S set, PartTree left, PartTree right) { this.set = set; this.left = left; this.right = right; }
/// <summary> /// Construct a symbolic partition refinement for a given Boolean algebra over S and initial set of elements. /// </summary> /// <param name="solver">given Boolean algebra</param> /// <param name="initialSet">initial set of elements will be one part</param> public SymbolicPartitionRefinement(IBooleanAlgebra <S> solver, S initialSet) { this.solver = solver; this.partitions = new PartTree(initialSet, null, null); }