diff --git a/src/api/dotnet/ArithExpr.cs b/src/api/dotnet/ArithExpr.cs index 56aa48f26..ac1e9200e 100644 --- a/src/api/dotnet/ArithExpr.cs +++ b/src/api/dotnet/ArithExpr.cs @@ -39,18 +39,84 @@ namespace Microsoft.Z3 } #endregion + #region Operators + + private static ArithExpr MkNum(ArithExpr e, int i) + { + return (ArithExpr)e.Context.MkNumeral(i, e.Context.MkIntSort()); + } + + private static ArithExpr MkNum(ArithExpr e, double d) + { + return (ArithExpr)e.Context.MkNumeral(d.ToString(), e.Context.MkRealSort()); + } + + /// Operator overloading for arithmetical divsion operator (over reals) + public static ArithExpr operator /(ArithExpr a, ArithExpr b) + { + return a.Context.MkDiv(a, b); + } + /// Operator overloading for arithmetical operator public static ArithExpr operator -(ArithExpr a, ArithExpr b) { return a.Context.MkSub(a, b); } + /// Operator overloading for arithmetical operator + public static ArithExpr operator -(ArithExpr a, int b) + { + return a.Context.MkSub(a, MkNum(a, b)); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator -(ArithExpr a, double b) + { + return a.Context.MkSub(a, MkNum(a, b)); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator -(int a, ArithExpr b) + { + return b.Context.MkSub(MkNum(b, a), b); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator -(double a, ArithExpr b) + { + return b.Context.MkSub(MkNum(b, a), b); + } + /// Operator overloading for arithmetical operator public static ArithExpr operator +(ArithExpr a, ArithExpr b) { return a.Context.MkAdd(a, b); } + /// Operator overloading for arithmetical operator + public static ArithExpr operator +(ArithExpr a, int b) + { + return a.Context.MkAdd(a, MkNum(a, b)); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator +(ArithExpr a, double b) + { + return a.Context.MkAdd(a, MkNum(a, b)); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator +(int a, ArithExpr b) + { + return b.Context.MkAdd(MkNum(b, a), b); + } + + /// Operator overloading for arithmetical operator + public static ArithExpr operator +(double a, ArithExpr b) + { + return b.Context.MkAdd(MkNum(b, a), b); + } + /// Operator overloading for arithmetical operator public static ArithExpr operator *(ArithExpr a, ArithExpr b) { @@ -60,25 +126,25 @@ namespace Microsoft.Z3 /// Operator overloading for arithmetical operator public static ArithExpr operator *(ArithExpr a, int b) { - return a.Context.MkMul(a, (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort())); + return a.Context.MkMul(a, MkNum(a, b)); } /// Operator overloading for arithmetical operator public static ArithExpr operator *(ArithExpr a, double b) { - return a.Context.MkMul(a, (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort())); + return a.Context.MkMul(a, MkNum(a, b)); } /// Operator overloading for arithmetical operator public static ArithExpr operator *(int a, ArithExpr b) { - return b.Context.MkMul((ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()), b); + return b.Context.MkMul(MkNum(b, a), b); } /// Operator overloading for arithmetical operator public static ArithExpr operator *(double a, ArithExpr b) { - return b.Context.MkMul((ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()), b); + return b.Context.MkMul(MkNum(b, a), b); } /// Operator overloading for arithmetical operator @@ -90,25 +156,25 @@ namespace Microsoft.Z3 /// Operator overloading for arithmetical operator public static BoolExpr operator <=(ArithExpr a, int b) { - return a <= (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); + return a <= MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator <=(ArithExpr a, double b) { - return a <= (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); + return a <= MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator <=(int a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) <= b; + return MkNum(b, a) <= b; } /// Operator overloading for arithmetical operator public static BoolExpr operator <=(double a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) <= b; + return MkNum(b, a) <= b; } /// Operator overloading for arithmetical operator @@ -120,25 +186,25 @@ namespace Microsoft.Z3 /// Operator overloading for arithmetical operator public static BoolExpr operator <(ArithExpr a, int b) { - return a < (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); + return a < MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator <(ArithExpr a, double b) { - return a < (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); + return a < MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator <(int a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) < b; + return MkNum(b, a) < b; } /// Operator overloading for arithmetical operator public static BoolExpr operator <(double a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) < b; + return MkNum(b, a) < b; } /// Operator overloading for arithmetical operator @@ -150,25 +216,25 @@ namespace Microsoft.Z3 /// Operator overloading for arithmetical operator public static BoolExpr operator >=(ArithExpr a, int b) { - return a >= (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); + return a >= MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator >=(ArithExpr a, double b) { - return a >= (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); + return a >= MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator >=(int a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) >= b; + return MkNum(b, a) >= b; } /// Operator overloading for arithmetical operator public static BoolExpr operator >=(double a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) >= b; + return MkNum(b, a) >= b; } /// Operator overloading for arithmetical operator @@ -180,25 +246,26 @@ namespace Microsoft.Z3 /// Operator overloading for arithmetical operator public static BoolExpr operator >(ArithExpr a, int b) { - return a > (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); + return a > MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator >(ArithExpr a, double b) { - return a > (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); + return a > MkNum(a, b); } /// Operator overloading for arithmetical operator public static BoolExpr operator >(int a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) > b; + return MkNum(b, a) > b; } /// Operator overloading for arithmetical operator public static BoolExpr operator >(double a, ArithExpr b) { - return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) > b; + return MkNum(b, a) > b; } + #endregion } } diff --git a/src/api/dotnet/BoolExpr.cs b/src/api/dotnet/BoolExpr.cs index a9a15e4dc..4d5a43074 100644 --- a/src/api/dotnet/BoolExpr.cs +++ b/src/api/dotnet/BoolExpr.cs @@ -34,5 +34,24 @@ namespace Microsoft.Z3 /// Constructor for BoolExpr internal BoolExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } #endregion + + #region Operators + /// + /// Disjunction of Boolean expressions + /// + public static BoolExpr operator|(BoolExpr a, BoolExpr b) + { + return a.Context.MkOr(a, b); + } + + /// + /// Conjunction of Boolean expressions + /// + public static BoolExpr operator &(BoolExpr a, BoolExpr b) + { + return a.Context.MkAnd(a, b); + } + + #endregion } } diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index a97036897..5bff8960a 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; +using System.Linq; namespace Microsoft.Z3 { @@ -814,6 +815,20 @@ namespace Microsoft.Z3 return Expr.Create(this, f, args); } + /// + /// Create a new function application. + /// + public Expr MkApp(FuncDecl f, IEnumerable args) + { + Contract.Requires(f != null); + Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(f); + CheckContextMatch(args); + return Expr.Create(this, f, args.ToArray()); + } + #region Propositional /// /// The true Term. @@ -959,6 +974,18 @@ namespace Microsoft.Z3 return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); } + /// + /// Create an expression representing t[0] and t[1] and .... + /// + public BoolExpr MkAnd(IEnumerable t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.EnumToNative(t))); + } + /// /// Create an expression representing t[0] or t[1] or .... /// @@ -973,6 +1000,19 @@ namespace Microsoft.Z3 } + /// + /// Create an expression representing t[0] or t[1] or .... + /// + public BoolExpr MkOr(IEnumerable t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Count(), AST.EnumToNative(t))); + } + #endregion #region Arithmetic @@ -989,6 +1029,19 @@ namespace Microsoft.Z3 return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); } + /// + /// Create an expression representing t[0] + t[1] + .... + /// + public ArithExpr MkAdd(IEnumerable t) + { + Contract.Requires(t != null); + Contract.Requires(Contract.ForAll(t, a => a != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Count(), AST.EnumToNative(t))); + } + /// /// Create an expression representing t[0] * t[1] * .... /// @@ -4743,6 +4796,21 @@ namespace Microsoft.Z3 } } + [Pure] + internal void CheckContextMatch(IEnumerable arr) + { + Contract.Requires(arr == null || Contract.ForAll(arr, a => a != null)); + + if (arr != null) + { + foreach (Z3Object a in arr) + { + Contract.Assert(a != null); // It was an assume, now we added the precondition, and we made it into an assert + CheckContextMatch(a); + } + } + } + [ContractInvariantMethod] private void ObjectInvariant() { diff --git a/src/api/dotnet/Optimize.cs b/src/api/dotnet/Optimize.cs index 501603668..304e3e86f 100644 --- a/src/api/dotnet/Optimize.cs +++ b/src/api/dotnet/Optimize.cs @@ -66,6 +66,38 @@ namespace Microsoft.Z3 /// Assert a constraint (or multiple) into the optimize solver. /// public void Assert(params BoolExpr[] constraints) + { + AddConstraints(constraints); + } + + /// + /// Assert a constraint (or multiple) into the optimize solver. + /// + public void Assert(IEnumerable constraints) + { + AddConstraints(constraints); + } + + /// + /// Alias for Assert. + /// + public void Add(params BoolExpr[] constraints) + { + AddConstraints(constraints); + } + + /// + /// Alias for Assert. + /// + public void Add(IEnumerable constraints) + { + AddConstraints(constraints); + } + + /// + /// Assert a constraint (or multiple) into the optimize solver. + /// + private void AddConstraints(IEnumerable constraints) { Contract.Requires(constraints != null); Contract.Requires(Contract.ForAll(constraints, c => c != null)); @@ -76,15 +108,6 @@ namespace Microsoft.Z3 Native.Z3_optimize_assert(Context.nCtx, NativeObject, a.NativeObject); } } - - /// - /// Alias for Assert. - /// - public void Add(params BoolExpr[] constraints) - { - Assert(constraints); - } - /// /// Handle to objectives returned by objective functions. /// diff --git a/src/api/dotnet/Z3Object.cs b/src/api/dotnet/Z3Object.cs index 8e474041a..cd6803341 100644 --- a/src/api/dotnet/Z3Object.cs +++ b/src/api/dotnet/Z3Object.cs @@ -20,6 +20,8 @@ Notes: using System; using System.Diagnostics.Contracts; using System.Threading; +using System.Collections.Generic; +using System.Linq; namespace Microsoft.Z3 { @@ -135,6 +137,23 @@ namespace Microsoft.Z3 return an; } + [Pure] + internal static IntPtr[] EnumToNative(IEnumerable a) + { + Contract.Ensures(a == null || Contract.Result() != null); + Contract.Ensures(a == null || Contract.Result().Length == a.Count()); + + if (a == null) return null; + IntPtr[] an = new IntPtr[a.Count()]; + int i = 0; + foreach (var ai in a) + { + if (ai != null) an[i] = ai.NativeObject; + ++i; + } + return an; + } + [Pure] internal static uint ArrayLength(Z3Object[] a) {