diff --git a/src/api/dotnet/UserPropagator.cs b/src/api/dotnet/UserPropagator.cs index af469ddff..68f2b0127 100644 --- a/src/api/dotnet/UserPropagator.cs +++ b/src/api/dotnet/UserPropagator.cs @@ -254,9 +254,19 @@ namespace Microsoft.Z3 /// Propagate consequence /// public void Propagate(IEnumerable terms, Expr conseq) + { + Propagate(terms, new EqualityPairs(), conseq); + } + + /// + /// Propagate consequence + /// + public void Propagate(IEnumerable terms, EqualityPairs equalities, Expr conseq) { var nTerms = Z3Object.ArrayToNative(terms.ToArray()); - Native.Z3_solver_propagate_consequence(ctx.nCtx, this.callback, (uint)nTerms.Length, nTerms, 0u, null, null, conseq.NativeObject); + var nLHS = Z3Object.ArrayToNative(equalities.LHS.ToArray()); + var nRHS = Z3Object.ArrayToNative(equalities.RHS.ToArray()); + Native.Z3_solver_propagate_consequence(ctx.nCtx, this.callback, (uint)nTerms.Length, nTerms, (uint)equalities.Count, nLHS, nRHS, conseq.NativeObject); } @@ -375,4 +385,72 @@ namespace Microsoft.Z3 } } } + + /// + /// A list of equalities used as justifications for propagation + /// + public class EqualityPairs { + + readonly List lhsList = new List(); + readonly List rhsList = new List(); + + /// + /// The left hand sides of the equalities + /// + public Expr[] LHS => lhsList.ToArray(); + + /// + /// The right hand sides of the equalities + /// + public Expr[] RHS => rhsList.ToArray(); + + /// + /// The number of equalities + /// + public int Count => lhsList.Count; + + /// + /// Adds an equality to the list. The sorts of the arguments have to be the same. + /// The left hand side of the equality + /// The right hand side of the equality + /// + public void Add(Expr lhs, Expr rhs) { + lhsList.Add(lhs); + rhsList.Add(rhs); + } + + /// + /// Checks if two equality lists are equal. + /// The function does not take symmetries, shuffling, or duplicates into account. + /// + public override bool Equals(object obj) { + if (ReferenceEquals(this, obj)) + return true; + if (!(obj is EqualityPairs other)) + return false; + if (lhsList.Count != other.lhsList.Count) + return false; + for (int i = 0; i < lhsList.Count; i++) { + if (!lhsList[i].Equals(other.lhsList[i])) + return false; + } + return true; + } + + /// + /// Gets a hash code for the list of equalities + /// + public override int GetHashCode() { + int hash = lhsList.Count; + unchecked { + for (int i = 0; i < lhsList.Count; i++) { + hash ^= lhsList[i].GetHashCode(); + hash *= 17; + hash ^= rhsList[i].GetHashCode(); + hash *= 29; + } + return hash; + } + } + } } diff --git a/src/api/java/NativeStatic.txt b/src/api/java/NativeStatic.txt index f076a817c..9507130fd 100644 --- a/src/api/java/NativeStatic.txt +++ b/src/api/java/NativeStatic.txt @@ -226,6 +226,7 @@ DLL_VIS JNIEXPORT void JNICALL Java_com_microsoft_z3_Native_propagateAdd(JNIEnv } } + DLL_VIS JNIEXPORT bool JNICALL Java_com_microsoft_z3_Native_propagateNextSplit(JNIEnv * jenv, jclass cls, jobject jobj, jlong ctx, jlong solver, jlong javainfo, jlong e, long idx, int phase) { JavaInfo *info = (JavaInfo*)javainfo; Z3_solver_callback cb = info->cb;