3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

overloading support for C# expressions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-04-23 15:50:30 -07:00
parent e4b7ac37f3
commit 662e43d264
5 changed files with 225 additions and 29 deletions

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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()
{

View file

@ -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>

View file

@ -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)
{