mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-30 19:22:28 +00:00 
			
		
		
		
	overloading support for C# expressions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									e4b7ac37f3
								
							
						
					
					
						commit
						662e43d264
					
				
					 5 changed files with 225 additions and 29 deletions
				
			
		|  | @ -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()); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical divsion operator (over reals) </summary> | ||||
|         public static ArithExpr operator /(ArithExpr a, ArithExpr b) | ||||
|         { | ||||
|             return a.Context.MkDiv(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator -(ArithExpr a, ArithExpr b) | ||||
|         { | ||||
|             return a.Context.MkSub(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator -(ArithExpr a, int b) | ||||
|         { | ||||
|             return a.Context.MkSub(a, MkNum(a, b)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator -(ArithExpr a, double b) | ||||
|         { | ||||
|             return a.Context.MkSub(a, MkNum(a, b)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator -(int a, ArithExpr b) | ||||
|         { | ||||
|             return b.Context.MkSub(MkNum(b, a), b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator -(double a, ArithExpr b) | ||||
|         { | ||||
|             return b.Context.MkSub(MkNum(b, a), b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator +(ArithExpr a, ArithExpr b) | ||||
|         { | ||||
|             return a.Context.MkAdd(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator +(ArithExpr a, int b) | ||||
|         { | ||||
|             return a.Context.MkAdd(a, MkNum(a, b)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator +(ArithExpr a, double b) | ||||
|         { | ||||
|             return a.Context.MkAdd(a, MkNum(a, b)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator +(int a, ArithExpr b) | ||||
|         { | ||||
|             return b.Context.MkAdd(MkNum(b, a), b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator +(double a, ArithExpr b) | ||||
|         { | ||||
|             return b.Context.MkAdd(MkNum(b, a), b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static ArithExpr operator *(ArithExpr a, ArithExpr b) | ||||
|         { | ||||
|  | @ -60,25 +126,25 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         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)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         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)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         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); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         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); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|  | @ -90,25 +156,25 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <=(ArithExpr a, int b) | ||||
|         { | ||||
|             return a <= (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); | ||||
|             return a <= MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <=(ArithExpr a, double b) | ||||
|         { | ||||
|             return a <= (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); | ||||
|             return a <= MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <=(int a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) <= b; | ||||
|             return MkNum(b, a) <= b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <=(double a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) <= b; | ||||
|             return MkNum(b, a) <= b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|  | @ -120,25 +186,25 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <(ArithExpr a, int b) | ||||
|         { | ||||
|             return a < (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); | ||||
|             return a < MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <(ArithExpr a, double b) | ||||
|         { | ||||
|             return a < (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); | ||||
|             return a < MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <(int a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) < b; | ||||
|             return MkNum(b, a) < b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator <(double a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) < b; | ||||
|             return MkNum(b, a) < b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|  | @ -150,25 +216,25 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >=(ArithExpr a, int b) | ||||
|         { | ||||
|             return a >= (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); | ||||
|             return a >= MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >=(ArithExpr a, double b) | ||||
|         { | ||||
|             return a >= (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); | ||||
|             return a >= MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >=(int a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) >= b; | ||||
|             return MkNum(b, a) >= b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >=(double a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a.ToString(), b.Context.MkRealSort()) >= b; | ||||
|             return MkNum(b, a) >= b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|  | @ -180,25 +246,26 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >(ArithExpr a, int b) | ||||
|         { | ||||
|             return a > (ArithExpr)a.Context.MkNumeral(b, a.Context.MkIntSort()); | ||||
|             return a > MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >(ArithExpr a, double b) | ||||
|         { | ||||
|             return a > (ArithExpr)a.Context.MkNumeral(b.ToString(), a.Context.MkRealSort()); | ||||
|             return a > MkNum(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         public static BoolExpr operator >(int a, ArithExpr b) | ||||
|         { | ||||
|             return (ArithExpr)b.Context.MkNumeral(a, b.Context.MkIntSort()) > b; | ||||
|             return MkNum(b, a) > b; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Operator overloading for arithmetical operator </summary> | ||||
|         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 | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -34,5 +34,24 @@ namespace Microsoft.Z3 | |||
|         /// <summary> Constructor for BoolExpr </summary> | ||||
|         internal BoolExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } | ||||
|         #endregion | ||||
| 
 | ||||
|         #region Operators | ||||
|         /// <summary> | ||||
|         /// Disjunction of Boolean expressions | ||||
|         /// </summary> | ||||
|         public static BoolExpr operator|(BoolExpr a, BoolExpr b) | ||||
|         { | ||||
|             return a.Context.MkOr(a, b); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Conjunction of Boolean expressions | ||||
|         /// </summary> | ||||
|         public static BoolExpr operator &(BoolExpr a, BoolExpr b) | ||||
|         { | ||||
|             return a.Context.MkAnd(a, b); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create a new function application. | ||||
|         /// </summary> | ||||
|         public Expr MkApp(FuncDecl f, IEnumerable<Expr> args) | ||||
|         { | ||||
|             Contract.Requires(f != null); | ||||
|             Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); | ||||
|             Contract.Ensures(Contract.Result<Expr>() != null); | ||||
| 
 | ||||
|             CheckContextMatch(f); | ||||
|             CheckContextMatch(args); | ||||
|             return Expr.Create(this, f, args.ToArray()); | ||||
|         } | ||||
| 
 | ||||
|         #region Propositional | ||||
|         /// <summary> | ||||
|         /// 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))); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create an expression representing <c>t[0] and t[1] and ...</c>. | ||||
|         /// </summary> | ||||
|         public BoolExpr MkAnd(IEnumerable<BoolExpr> t) | ||||
|         { | ||||
|             Contract.Requires(t != null); | ||||
|             Contract.Requires(Contract.ForAll(t, a => a != null)); | ||||
|             Contract.Ensures(Contract.Result<BoolExpr>() != null); | ||||
|             CheckContextMatch(t); | ||||
|             return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.EnumToNative(t))); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create an expression representing <c>t[0] or t[1] or ...</c>. | ||||
|         /// </summary> | ||||
|  | @ -973,6 +1000,19 @@ namespace Microsoft.Z3 | |||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create an expression representing <c>t[0] or t[1] or ...</c>. | ||||
|         /// </summary> | ||||
|         public BoolExpr MkOr(IEnumerable<BoolExpr> t) | ||||
|         { | ||||
|             Contract.Requires(t != null); | ||||
|             Contract.Requires(Contract.ForAll(t, a => a != null)); | ||||
|             Contract.Ensures(Contract.Result<BoolExpr>() != 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))); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create an expression representing <c>t[0] + t[1] + ...</c>. | ||||
|         /// </summary> | ||||
|         public ArithExpr MkAdd(IEnumerable<ArithExpr> t) | ||||
|         { | ||||
|             Contract.Requires(t != null); | ||||
|             Contract.Requires(Contract.ForAll(t, a => a != null)); | ||||
|             Contract.Ensures(Contract.Result<ArithExpr>() != null); | ||||
| 
 | ||||
|             CheckContextMatch(t); | ||||
|             return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Count(), AST.EnumToNative(t))); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Create an expression representing <c>t[0] * t[1] * ...</c>. | ||||
|         /// </summary> | ||||
|  | @ -4743,6 +4796,21 @@ namespace Microsoft.Z3 | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [Pure] | ||||
|         internal void CheckContextMatch(IEnumerable<Z3Object> 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() | ||||
|         { | ||||
|  |  | |||
|  | @ -66,6 +66,38 @@ namespace Microsoft.Z3 | |||
|         /// Assert a constraint (or multiple) into the optimize solver. | ||||
|         /// </summary>         | ||||
|         public void Assert(params BoolExpr[] constraints) | ||||
|         { | ||||
|             AddConstraints(constraints); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Assert a constraint (or multiple) into the optimize solver. | ||||
|         /// </summary>         | ||||
|         public void Assert(IEnumerable<BoolExpr> constraints) | ||||
|         { | ||||
|             AddConstraints(constraints); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Alias for Assert. | ||||
|         /// </summary>         | ||||
|         public void Add(params BoolExpr[] constraints) | ||||
|         { | ||||
|             AddConstraints(constraints); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Alias for Assert. | ||||
|         /// </summary>         | ||||
|         public void Add(IEnumerable<BoolExpr> constraints) | ||||
|         { | ||||
|             AddConstraints(constraints); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Assert a constraint (or multiple) into the optimize solver. | ||||
|         /// </summary>    | ||||
|         private void AddConstraints(IEnumerable<BoolExpr> 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); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Alias for Assert. | ||||
|         /// </summary>         | ||||
|         public void Add(params BoolExpr[] constraints) | ||||
|         { | ||||
|             Assert(constraints); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Handle to objectives returned by objective functions. | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -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<Z3Object> a) | ||||
|         { | ||||
|             Contract.Ensures(a == null || Contract.Result<IntPtr[]>() != null); | ||||
|             Contract.Ensures(a == null || Contract.Result<IntPtr[]>().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) | ||||
|         { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue