mirror of
https://github.com/Z3Prover/z3
synced 2025-04-11 19:53:34 +00:00
258 lines
9.3 KiB
C#
258 lines
9.3 KiB
C#
/*++
|
|
Copyright (c) 2012 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Quantifier.cs
|
|
|
|
Abstract:
|
|
|
|
Z3 Managed API: Quantifiers
|
|
|
|
Author:
|
|
|
|
Christoph Wintersteiger (cwinter) 2012-03-19
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
using System;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
namespace Microsoft.Z3
|
|
{
|
|
/// <summary>
|
|
/// Quantifier expressions.
|
|
/// </summary>
|
|
[ContractVerification(true)]
|
|
public class Quantifier : BoolExpr
|
|
{
|
|
/// <summary>
|
|
/// Indicates whether the quantifier is universal.
|
|
/// </summary>
|
|
public bool IsUniversal
|
|
{
|
|
get { return Native.Z3_is_quantifier_forall(Context.nCtx, NativeObject) != 0; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether the quantifier is existential.
|
|
/// </summary>
|
|
public bool IsExistential
|
|
{
|
|
get { return !IsUniversal; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The weight of the quantifier.
|
|
/// </summary>
|
|
public uint Weight
|
|
{
|
|
get { return Native.Z3_get_quantifier_weight(Context.nCtx, NativeObject); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The number of patterns.
|
|
/// </summary>
|
|
public uint NumPatterns
|
|
{
|
|
get { return Native.Z3_get_quantifier_num_patterns(Context.nCtx, NativeObject); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The patterns.
|
|
/// </summary>
|
|
public Pattern[] Patterns
|
|
{
|
|
get
|
|
{
|
|
Contract.Ensures(Contract.Result<Pattern[]>() != null);
|
|
|
|
uint n = NumPatterns;
|
|
Pattern[] res = new Pattern[n];
|
|
for (uint i = 0; i < n; i++)
|
|
res[i] = new Pattern(Context, Native.Z3_get_quantifier_pattern_ast(Context.nCtx, NativeObject, i));
|
|
return res;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The number of no-patterns.
|
|
/// </summary>
|
|
public uint NumNoPatterns
|
|
{
|
|
get { return Native.Z3_get_quantifier_num_no_patterns(Context.nCtx, NativeObject); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The no-patterns.
|
|
/// </summary>
|
|
public Pattern[] NoPatterns
|
|
{
|
|
get
|
|
{
|
|
Contract.Ensures(Contract.Result<Pattern[]>() != null);
|
|
|
|
uint n = NumNoPatterns;
|
|
Pattern[] res = new Pattern[n];
|
|
for (uint i = 0; i < n; i++)
|
|
res[i] = new Pattern(Context, Native.Z3_get_quantifier_no_pattern_ast(Context.nCtx, NativeObject, i));
|
|
return res;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The number of bound variables.
|
|
/// </summary>
|
|
public uint NumBound
|
|
{
|
|
get { return Native.Z3_get_quantifier_num_bound(Context.nCtx, NativeObject); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The symbols for the bound variables.
|
|
/// </summary>
|
|
public Symbol[] BoundVariableNames
|
|
{
|
|
get
|
|
{
|
|
Contract.Ensures(Contract.Result<Symbol[]>() != null);
|
|
|
|
uint n = NumBound;
|
|
Symbol[] res = new Symbol[n];
|
|
for (uint i = 0; i < n; i++)
|
|
res[i] = Symbol.Create(Context, Native.Z3_get_quantifier_bound_name(Context.nCtx, NativeObject, i));
|
|
return res;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The sorts of the bound variables.
|
|
/// </summary>
|
|
public Sort[] BoundVariableSorts
|
|
{
|
|
get
|
|
{
|
|
Contract.Ensures(Contract.Result<Sort[]>() != null);
|
|
|
|
uint n = NumBound;
|
|
Sort[] res = new Sort[n];
|
|
for (uint i = 0; i < n; i++)
|
|
res[i] = Sort.Create(Context, Native.Z3_get_quantifier_bound_sort(Context.nCtx, NativeObject, i));
|
|
return res;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The body of the quantifier.
|
|
/// </summary>
|
|
public BoolExpr Body
|
|
{
|
|
get {
|
|
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
|
|
|
return new BoolExpr(Context, Native.Z3_get_quantifier_body(Context.nCtx, NativeObject)); }
|
|
}
|
|
|
|
#region Internal
|
|
[ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug
|
|
internal Quantifier(Context ctx, bool isForall, Sort[] sorts, Symbol[] names, Expr body,
|
|
uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null,
|
|
Symbol quantifierID = null, Symbol skolemID = null
|
|
)
|
|
: base(ctx)
|
|
{
|
|
Contract.Requires(ctx != null);
|
|
Contract.Requires(sorts != null);
|
|
Contract.Requires(names != null);
|
|
Contract.Requires(body != null);
|
|
Contract.Requires(sorts.Length == names.Length);
|
|
Contract.Requires(Contract.ForAll(sorts, s => s != null));
|
|
Contract.Requires(Contract.ForAll(names, n => n != null));
|
|
Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null));
|
|
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
|
|
|
Context.CheckContextMatch(patterns);
|
|
Context.CheckContextMatch(noPatterns);
|
|
Context.CheckContextMatch(sorts);
|
|
Context.CheckContextMatch(names);
|
|
Context.CheckContextMatch(body);
|
|
|
|
if (sorts.Length != names.Length)
|
|
throw new Z3Exception("Number of sorts does not match number of names");
|
|
|
|
IntPtr[] _patterns = AST.ArrayToNative(patterns);
|
|
|
|
if (noPatterns == null && quantifierID == null && skolemID == null)
|
|
{
|
|
NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (isForall) ? 1 : 0, weight,
|
|
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
|
|
AST.ArrayLength(sorts), AST.ArrayToNative(sorts),
|
|
Symbol.ArrayToNative(names),
|
|
body.NativeObject);
|
|
}
|
|
else
|
|
{
|
|
NativeObject = Native.Z3_mk_quantifier_ex(ctx.nCtx, (isForall) ? 1 : 0, weight,
|
|
AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID),
|
|
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
|
|
AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns),
|
|
AST.ArrayLength(sorts), AST.ArrayToNative(sorts),
|
|
Symbol.ArrayToNative(names),
|
|
body.NativeObject);
|
|
}
|
|
}
|
|
|
|
[ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug
|
|
internal Quantifier(Context ctx, bool isForall, Expr[] bound, Expr body,
|
|
uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null,
|
|
Symbol quantifierID = null, Symbol skolemID = null
|
|
)
|
|
: base(ctx)
|
|
{
|
|
Contract.Requires(ctx != null);
|
|
Contract.Requires(body != null);
|
|
|
|
Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null));
|
|
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
|
Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null));
|
|
|
|
Context.CheckContextMatch(noPatterns);
|
|
Context.CheckContextMatch(patterns);
|
|
//Context.CheckContextMatch(bound);
|
|
Context.CheckContextMatch(body);
|
|
|
|
if (noPatterns == null && quantifierID == null && skolemID == null)
|
|
{
|
|
NativeObject = Native.Z3_mk_quantifier_const(ctx.nCtx, (isForall) ? 1 : 0, weight,
|
|
AST.ArrayLength(bound), AST.ArrayToNative(bound),
|
|
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
|
|
body.NativeObject);
|
|
}
|
|
else
|
|
{
|
|
NativeObject = Native.Z3_mk_quantifier_const_ex(ctx.nCtx, (isForall) ? 1 : 0, weight,
|
|
AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID),
|
|
AST.ArrayLength(bound), AST.ArrayToNative(bound),
|
|
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
|
|
AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns),
|
|
body.NativeObject);
|
|
}
|
|
}
|
|
|
|
|
|
internal Quantifier(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
|
|
|
|
#if DEBUG
|
|
internal override void CheckNativeObject(IntPtr obj)
|
|
{
|
|
if ((Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST)
|
|
throw new Z3Exception("Underlying object is not a quantifier");
|
|
base.CheckNativeObject(obj);
|
|
}
|
|
#endif
|
|
#endregion
|
|
}
|
|
}
|