Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
Context.cs
Abstract:
Z3 Managed API: Context
Author:
Christoph Wintersteiger (cwinter) 2012-03-15
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
namespace Microsoft.Z3
{
using Z3_context = System.IntPtr;
///
/// The main interaction with Z3 happens via the Context.
///
public class Context : IDisposable
{
#region Constructors
///
/// Constructor.
///
public Context()
: base()
{
lock (creation_lock)
{
m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero);
Native.Z3_enable_concurrent_dec_ref(m_ctx);
InitContext();
}
}
///
/// Constructor.
///
///
/// The following parameters can be set:
/// - proof (Boolean) Enable proof generation
/// - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting
/// - trace (Boolean) Tracing support for VCC
/// - trace_file_name (String) Trace out file for VCC traces
/// - timeout (unsigned) default timeout (in milliseconds) used for solvers
/// - well_sorted_check type checker
/// - auto_config use heuristics to automatically select solver and configure it
/// - model model generation for solvers, this parameter can be overwritten when creating a solver
/// - model_validate validate models produced by solvers
/// - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver
/// Note that in previous versions of Z3, this constructor was also used to set global and module parameters.
/// For this purpose we should now use
///
public Context(Dictionary settings)
: base()
{
Debug.Assert(settings != null);
lock (creation_lock)
{
IntPtr cfg = Native.Z3_mk_config();
foreach (KeyValuePair kv in settings)
Native.Z3_set_param_value(cfg, kv.Key, kv.Value);
m_ctx = Native.Z3_mk_context_rc(cfg);
Native.Z3_enable_concurrent_dec_ref(m_ctx);
Native.Z3_del_config(cfg);
InitContext();
}
}
///
/// Internal Constructor. It is used from UserPropagator
///
internal Context(Z3_context ctx)
: base()
{
lock (creation_lock)
{
is_external = true;
m_ctx = ctx;
InitContext();
}
}
bool is_external = false;
#endregion
#region Symbols
///
/// Creates a new symbol using an integer.
///
///
/// Not all integers can be passed to this function.
/// The legal range of unsigned integers is 0 to 2^30-1.
///
public IntSymbol MkSymbol(int i)
{
return new IntSymbol(this, i);
}
///
/// Create a symbol using a string.
///
public StringSymbol MkSymbol(string name)
{
return new StringSymbol(this, name);
}
///
/// Create an array of symbols.
///
internal Symbol[] MkSymbols(string[] names)
{
if (names == null) return new Symbol[0];
Symbol[] result = new Symbol[names.Length];
for (int i = 0; i < names.Length; ++i) result[i] = MkSymbol(names[i]);
return result;
}
#endregion
#region Sorts
private BoolSort m_boolSort = null;
private IntSort m_intSort = null;
private RealSort m_realSort = null;
private SeqSort m_stringSort = null;
private CharSort m_charSort = null;
///
/// Retrieves the Boolean sort of the context.
///
public BoolSort BoolSort
{
get
{
if (m_boolSort == null) m_boolSort = new BoolSort(this); return m_boolSort;
}
}
///
/// Retrieves the Integer sort of the context.
///
public IntSort IntSort
{
get
{
if (m_intSort == null) m_intSort = new IntSort(this); return m_intSort;
}
}
///
/// Retrieves the Real sort of the context.
///
public RealSort RealSort
{
get
{
if (m_realSort == null) m_realSort = new RealSort(this); return m_realSort;
}
}
///
/// Retrieves the String sort of the context.
///
public CharSort CharSort
{
get
{
if (m_charSort == null) m_charSort = new CharSort(this); return m_charSort;
}
}
///
/// Retrieves the String sort of the context.
///
public SeqSort StringSort
{
get
{
if (m_stringSort == null) m_stringSort = new SeqSort(this, Native.Z3_mk_string_sort(nCtx));
return m_stringSort;
}
}
///
/// Create a new Boolean sort.
///
public BoolSort MkBoolSort()
{
return new BoolSort(this);
}
///
/// Create a new uninterpreted sort.
///
public UninterpretedSort MkUninterpretedSort(Symbol s)
{
Debug.Assert(s != null);
CheckContextMatch(s);
return new UninterpretedSort(this, s);
}
///
/// Create a new uninterpreted sort.
///
public UninterpretedSort MkUninterpretedSort(string str)
{
using var sym = MkSymbol(str);
return MkUninterpretedSort(sym);
}
///
/// Create a new integer sort.
///
public IntSort MkIntSort()
{
return new IntSort(this);
}
///
/// Create a real sort.
///
public RealSort MkRealSort()
{
return new RealSort(this);
}
///
/// Create a new bit-vector sort.
///
public BitVecSort MkBitVecSort(uint size)
{
return new BitVecSort(this, Native.Z3_mk_bv_sort(nCtx, size));
}
///
/// Create a new sequence sort.
///
public SeqSort MkSeqSort(Sort s)
{
Debug.Assert(s != null);
return new SeqSort(this, Native.Z3_mk_seq_sort(nCtx, s.NativeObject));
}
///
/// Create a new regular expression sort.
///
public ReSort MkReSort(SeqSort s)
{
Debug.Assert(s != null);
return new ReSort(this, Native.Z3_mk_re_sort(nCtx, s.NativeObject));
}
///
/// Create a new array sort.
///
public ArraySort MkArraySort(Sort domain, Sort range)
{
Debug.Assert(domain != null);
Debug.Assert(range != null);
CheckContextMatch(domain);
CheckContextMatch(range);
return new ArraySort(this, domain, range);
}
///
/// Create a new n-ary array sort.
///
public ArraySort MkArraySort(Sort[] domain, Sort range)
{
Debug.Assert(domain != null);
Debug.Assert(range != null);
CheckContextMatch(domain);
CheckContextMatch(range);
return new ArraySort(this, domain, range);
}
///
/// Create a new tuple sort.
///
public TupleSort MkTupleSort(Symbol name, Symbol[] fieldNames, Sort[] fieldSorts)
{
Debug.Assert(name != null);
Debug.Assert(fieldNames != null);
Debug.Assert(fieldNames.All(fn => fn != null));
Debug.Assert(fieldSorts == null || fieldSorts.All(fs => fs != null));
CheckContextMatch(name);
CheckContextMatch(fieldNames);
CheckContextMatch(fieldSorts);
return new TupleSort(this, name, (uint)fieldNames.Length, fieldNames, fieldSorts);
}
///
/// Create a new enumeration sort.
///
public EnumSort MkEnumSort(Symbol name, params Symbol[] enumNames)
{
Debug.Assert(name != null);
Debug.Assert(enumNames != null);
Debug.Assert(enumNames.All(f => f != null));
CheckContextMatch(name);
CheckContextMatch(enumNames);
return new EnumSort(this, name, enumNames);
}
///
/// Create a new enumeration sort.
///
public EnumSort MkEnumSort(string name, params string[] enumNames)
{
Debug.Assert(enumNames != null);
var enumSymbols = MkSymbols(enumNames);
try
{
using var symbol = MkSymbol(name);
return new EnumSort(this, symbol, enumSymbols);
}
finally
{
foreach (var enumSymbol in enumSymbols)
enumSymbol.Dispose();
}
}
///
/// Create a new list sort.
///
public ListSort MkListSort(Symbol name, Sort elemSort)
{
Debug.Assert(name != null);
Debug.Assert(elemSort != null);
CheckContextMatch(name);
CheckContextMatch(elemSort);
return new ListSort(this, name, elemSort);
}
///
/// Create a new list sort.
///
public ListSort MkListSort(string name, Sort elemSort)
{
Debug.Assert(elemSort != null);
CheckContextMatch(elemSort);
using var symbol = MkSymbol(name);
return new ListSort(this, symbol, elemSort);
}
///
/// Create a new finite domain sort.
/// The result is a sort
///
/// The name used to identify the sort
/// The size of the sort
public FiniteDomainSort MkFiniteDomainSort(Symbol name, ulong size)
{
Debug.Assert(name != null);
CheckContextMatch(name);
return new FiniteDomainSort(this, name, size);
}
///
/// Create a new finite domain sort.
/// The result is a sort
/// Elements of the sort are created using ,
/// and the elements range from 0 to size-1.
///
/// The name used to identify the sort
/// The size of the sort
public FiniteDomainSort MkFiniteDomainSort(string name, ulong size)
{
using var symbol = MkSymbol(name);
return new FiniteDomainSort(this, symbol, size);
}
#region Datatypes
///
/// Create a datatype constructor.
///
/// constructor name
/// name of recognizer function.
/// names of the constructor fields.
/// field sorts, 0 if the field sort refers to a recursive sort.
/// reference to datatype sort that is an argument to the constructor;
/// if the corresponding sort reference is 0, then the value in sort_refs should be an index
/// referring to one of the recursive datatypes that is declared.
public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null)
{
Debug.Assert(name != null);
Debug.Assert(recognizer != null);
return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs);
}
///
/// Create a datatype constructor.
///
///
///
///
///
///
///
public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null)
{
using var nameSymbol = MkSymbol(name);
using var recognizerSymbol = MkSymbol(recognizer);
var fieldSymbols = MkSymbols(fieldNames);
try
{
return new Constructor(this, nameSymbol, recognizerSymbol, fieldSymbols, sorts, sortRefs);
}
finally
{
foreach (var fieldSymbol in fieldSymbols)
fieldSymbol.Dispose();
}
}
///
/// Create a new datatype sort.
///
public DatatypeSort MkDatatypeSort(Symbol name, Constructor[] constructors)
{
Debug.Assert(name != null);
Debug.Assert(constructors != null);
Debug.Assert(constructors.All(c => c != null));
CheckContextMatch(name);
CheckContextMatch(constructors);
return new DatatypeSort(this, name, constructors);
}
///
/// Create a new datatype sort.
///
public DatatypeSort MkDatatypeSort(string name, Constructor[] constructors)
{
Debug.Assert(constructors != null);
Debug.Assert(constructors.All(c => c != null));
CheckContextMatch(constructors);
using var symbol = MkSymbol(name);
return new DatatypeSort(this, symbol, constructors);
}
///
/// Create mutually recursive datatypes.
///
/// names of datatype sorts
/// list of constructors, one list per sort.
public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c)
{
Debug.Assert(names != null);
Debug.Assert(c != null);
Debug.Assert(names.Length == c.Length);
//Debug.Assert(Contract.ForAll(0, c.Length, j => c[j] != null));
Debug.Assert(names.All(name => name != null));
CheckContextMatch(names);
uint n = (uint)names.Length;
ConstructorList[] cla = new ConstructorList[n];
IntPtr[] n_constr = new IntPtr[n];
for (uint i = 0; i < n; i++)
{
Constructor[] constructor = c[i];
CheckContextMatch(constructor);
cla[i] = new ConstructorList(this, constructor);
n_constr[i] = cla[i].NativeObject;
}
IntPtr[] n_res = new IntPtr[n];
Native.Z3_mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr);
DatatypeSort[] res = new DatatypeSort[n];
for (uint i = 0; i < n; i++)
res[i] = new DatatypeSort(this, n_res[i]);
return res;
}
///
/// Create mutually recursive data-types.
///
///
///
///
public DatatypeSort[] MkDatatypeSorts(string[] names, Constructor[][] c)
{
Debug.Assert(names != null);
Debug.Assert(c != null);
Debug.Assert(names.Length == c.Length);
//Debug.Assert(Contract.ForAll(0, c.Length, j => c[j] != null));
//Debug.Assert(names.All(name => name != null));
var symbols = MkSymbols(names);
try
{
return MkDatatypeSorts(symbols, c);
}
finally
{
foreach (var symbol in symbols)
symbol.Dispose();
}
}
///
/// Update a datatype field at expression t with value v.
/// The function performs a record update at t. The field
/// that is passed in as argument is updated with value v,
/// the remaining fields of t are unchanged.
///
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
{
return Expr.Create(this, Native.Z3_datatype_update_field(
nCtx, field.NativeObject,
t.NativeObject, v.NativeObject));
}
#endregion
#endregion
#region Function Declarations
///
/// Creates a new function declaration.
///
public FuncDecl MkFuncDecl(Symbol name, Sort[] domain, Sort range)
{
Debug.Assert(name != null);
Debug.Assert(range != null);
Debug.Assert(domain.All(d => d != null));
CheckContextMatch(name);
CheckContextMatch(domain);
CheckContextMatch(range);
return new FuncDecl(this, name, domain, range);
}
///
/// Creates a new function declaration.
///
public FuncDecl MkFuncDecl(Symbol name, Sort domain, Sort range)
{
Debug.Assert(name != null);
Debug.Assert(domain != null);
Debug.Assert(range != null);
CheckContextMatch(name);
CheckContextMatch(domain);
CheckContextMatch(range);
Sort[] q = new Sort[] { domain };
return new FuncDecl(this, name, q, range);
}
///
/// Creates a new function declaration.
///
public FuncDecl MkFuncDecl(string name, Sort[] domain, Sort range)
{
Debug.Assert(range != null);
Debug.Assert(domain.All(d => d != null));
CheckContextMatch(domain);
CheckContextMatch(range);
using var symbol = MkSymbol(name);
return new FuncDecl(this, symbol, domain, range);
}
///
/// Creates a new recursive function declaration.
///
public FuncDecl MkRecFuncDecl(string name, Sort[] domain, Sort range)
{
Debug.Assert(range != null);
Debug.Assert(domain.All(d => d != null));
CheckContextMatch(domain);
CheckContextMatch(range);
using var symbol = MkSymbol(name);
return new FuncDecl(this, symbol, domain, range, true);
}
///
/// Bind a definition to a recursive function declaration.
/// The function must have previously been created using
/// MkRecFuncDecl. The body may contain recursive uses of the function or
/// other mutually recursive functions.
///
public void AddRecDef(FuncDecl f, Expr[] args, Expr body)
{
CheckContextMatch(f);
CheckContextMatch(args);
CheckContextMatch(body);
IntPtr[] argsNative = AST.ArrayToNative(args);
Native.Z3_add_rec_def(nCtx, f.NativeObject, (uint)args.Length, argsNative, body.NativeObject);
}
///
/// Creates a new function declaration.
///
public FuncDecl MkFuncDecl(string name, Sort domain, Sort range)
{
Debug.Assert(range != null);
Debug.Assert(domain != null);
CheckContextMatch(domain);
CheckContextMatch(range);
using var symbol = MkSymbol(name);
Sort[] q = new Sort[] { domain };
return new FuncDecl(this, symbol, q, range);
}
///
/// Creates a fresh function declaration with a name prefixed with .
///
///
///
public FuncDecl MkFreshFuncDecl(string prefix, Sort[] domain, Sort range)
{
Debug.Assert(range != null);
Debug.Assert(domain.All(d => d != null));
CheckContextMatch(domain);
CheckContextMatch(range);
return new FuncDecl(this, prefix, domain, range);
}
///
/// Creates a new constant function declaration.
///
public FuncDecl MkConstDecl(Symbol name, Sort range)
{
Debug.Assert(name != null);
Debug.Assert(range != null);
CheckContextMatch(name);
CheckContextMatch(range);
return new FuncDecl(this, name, null, range);
}
///
/// Creates a new constant function declaration.
///
public FuncDecl MkConstDecl(string name, Sort range)
{
Debug.Assert(range != null);
CheckContextMatch(range);
using var symbol = MkSymbol(name);
return new FuncDecl(this, symbol, null, range);
}
///
/// Creates a fresh constant function declaration with a name prefixed with .
///
///
///
public FuncDecl MkFreshConstDecl(string prefix, Sort range)
{
Debug.Assert(range != null);
CheckContextMatch(range);
return new FuncDecl(this, prefix, null, range);
}
///
/// Declare a function to be processed by the user propagator plugin.
///
public FuncDecl MkUserPropagatorFuncDecl(string name, Sort[] domain, Sort range)
{
using var _name = MkSymbol(name);
var fn = Native.Z3_solver_propagate_declare(nCtx, _name.NativeObject, AST.ArrayLength(domain), AST.ArrayToNative(domain), range.NativeObject);
return new FuncDecl(this, fn);
}
#endregion
#region Bound Variables
///
/// Creates a new bound variable.
///
/// The de-Bruijn index of the variable
/// The sort of the variable
public Expr MkBound(uint index, Sort ty)
{
Debug.Assert(ty != null);
return Expr.Create(this, Native.Z3_mk_bound(nCtx, index, ty.NativeObject));
}
#endregion
#region Quantifier Patterns
///
/// Create a quantifier pattern.
///
public Pattern MkPattern(params Expr[] terms)
{
Debug.Assert(terms != null);
if (terms.Length == 0)
throw new Z3Exception("Cannot create a pattern from zero terms");
IntPtr[] termsNative = AST.ArrayToNative(terms);
return new Pattern(this, Native.Z3_mk_pattern(nCtx, (uint)terms.Length, termsNative));
}
#endregion
#region Constants
///
/// Creates a new Constant of sort and named .
///
public Expr MkConst(Symbol name, Sort range)
{
Debug.Assert(name != null);
Debug.Assert(range != null);
CheckContextMatch(name);
CheckContextMatch(range);
return Expr.Create(this, Native.Z3_mk_const(nCtx, name.NativeObject, range.NativeObject));
}
///
/// Creates a new Constant of sort and named .
///
public Expr MkConst(string name, Sort range)
{
Debug.Assert(range != null);
using var symbol = MkSymbol(name);
return MkConst(symbol, range);
}
///
/// Creates a fresh Constant of sort and a
/// name prefixed with .
///
public Expr MkFreshConst(string prefix, Sort range)
{
Debug.Assert(range != null);
CheckContextMatch(range);
return Expr.Create(this, Native.Z3_mk_fresh_const(nCtx, prefix, range.NativeObject));
}
///
/// Creates a fresh constant from the FuncDecl .
///
/// A decl of a 0-arity function
public Expr MkConst(FuncDecl f)
{
Debug.Assert(f != null);
return MkApp(f);
}
///
/// Create a Boolean constant.
///
public BoolExpr MkBoolConst(Symbol name)
{
Debug.Assert(name != null);
return (BoolExpr)MkConst(name, BoolSort);
}
///
/// Create a Boolean constant.
///
public BoolExpr MkBoolConst(string name)
{
using var symbol = MkSymbol(name);
return (BoolExpr)MkConst(symbol, BoolSort);
}
///
/// Creates an integer constant.
///
public IntExpr MkIntConst(Symbol name)
{
Debug.Assert(name != null);
return (IntExpr)MkConst(name, IntSort);
}
///
/// Creates an integer constant.
///
public IntExpr MkIntConst(string name)
{
Debug.Assert(name != null);
return (IntExpr)MkConst(name, IntSort);
}
///
/// Creates a real constant.
///
public RealExpr MkRealConst(Symbol name)
{
Debug.Assert(name != null);
return (RealExpr)MkConst(name, RealSort);
}
///
/// Creates a real constant.
///
public RealExpr MkRealConst(string name)
{
return (RealExpr)MkConst(name, RealSort);
}
///
/// Creates a bit-vector constant.
///
public BitVecExpr MkBVConst(Symbol name, uint size)
{
Debug.Assert(name != null);
using var sort = MkBitVecSort(size);
return (BitVecExpr)MkConst(name, sort);
}
///
/// Creates a bit-vector constant.
///
public BitVecExpr MkBVConst(string name, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecExpr)MkConst(name, sort);
}
#endregion
#region Terms
///
/// Create a new function application.
///
public Expr MkApp(FuncDecl f, params Expr[] args)
{
Debug.Assert(f != null);
Debug.Assert(args == null || args.All(a => a != null));
CheckContextMatch(f);
CheckContextMatch(args);
return Expr.Create(this, f, args);
}
///
/// Create a new function application.
///
public Expr MkApp(FuncDecl f, IEnumerable args)
{
Debug.Assert(f != null);
Debug.Assert(args == null || args.All(a => a != null));
CheckContextMatch(f);
CheckContextMatch(args);
return Expr.Create(this, f, args.ToArray());
}
#region Propositional
///
/// The true Term.
///
public BoolExpr MkTrue()
{
return new BoolExpr(this, Native.Z3_mk_true(nCtx));
}
///
/// The false Term.
///
public BoolExpr MkFalse()
{
return new BoolExpr(this, Native.Z3_mk_false(nCtx));
}
///
/// Creates a Boolean value.
///
public BoolExpr MkBool(bool value)
{
return value ? MkTrue() : MkFalse();
}
///
/// Creates the equality = .
///
public BoolExpr MkEq(Expr x, Expr y)
{
Debug.Assert(x != null);
Debug.Assert(y != null);
CheckContextMatch(x);
CheckContextMatch(y);
return new BoolExpr(this, Native.Z3_mk_eq(nCtx, x.NativeObject, y.NativeObject));
}
///
/// Creates a distinct term.
///
public BoolExpr MkDistinct(params Expr[] args)
{
Debug.Assert(args != null);
Debug.Assert(args.All(a => a != null));
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
}
///
/// Creates a distinct term.
///
public BoolExpr MkDistinct(IEnumerable args)
{
Debug.Assert(args != null);
return MkDistinct(args.ToArray());
}
///
/// Mk an expression representing not(a).
///
public BoolExpr MkNot(BoolExpr a)
{
Debug.Assert(a != null);
CheckContextMatch(a);
return new BoolExpr(this, Native.Z3_mk_not(nCtx, a.NativeObject));
}
///
/// Create an expression representing an if-then-else: ite(t1, t2, t3).
///
/// An expression with Boolean sort
/// An expression
/// An expression with the same sort as
public Expr MkITE(BoolExpr t1, Expr t2, Expr t3)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
Debug.Assert(t3 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
CheckContextMatch(t3);
return Expr.Create(this, Native.Z3_mk_ite(nCtx, t1.NativeObject, t2.NativeObject, t3.NativeObject));
}
///
/// Create an expression representing t1 iff t2.
///
public BoolExpr MkIff(BoolExpr t1, BoolExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_iff(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 -> t2.
///
public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_implies(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 xor t2.
///
public BoolExpr MkXor(BoolExpr t1, BoolExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_xor(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 xor t2 xor t3 ... .
///
public BoolExpr MkXor(IEnumerable ts)
{
Debug.Assert(ts != null);
Debug.Assert(ts.All(a => a != null));
CheckContextMatch(ts);
return ts.Aggregate(MkFalse(), (r, t) =>
{
using (r)
return MkXor(r, t);
});
}
///
/// Create an expression representing t[0] and t[1] and ....
///
public BoolExpr MkAnd(params BoolExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
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)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
var ands = t.ToArray();
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.ArrayToNative(ands)));
}
///
/// Create an expression representing t[0] or t[1] or ....
///
public BoolExpr MkOr(params BoolExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Create an expression representing t[0] or t[1] or ....
///
public BoolExpr MkOr(IEnumerable t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
var ts = t.ToArray();
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)ts.Length, AST.ArrayToNative(ts)));
}
#endregion
#region Arithmetic
///
/// Create an expression representing t[0] + t[1] + ....
///
public ArithExpr MkAdd(params ArithExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
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)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
var ts = t.ToArray();
return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)ts.Length, AST.ArrayToNative(ts)));
}
///
/// Create an expression representing t[0] * t[1] * ....
///
public ArithExpr MkMul(params ArithExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
var ts = t.ToArray();
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)ts.Length, AST.ArrayToNative(ts)));
}
///
/// Create an expression representing t[0] * t[1] * ....
///
public ArithExpr MkMul(IEnumerable t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
var ts = t.ToArray();
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)ts.Length, AST.ArrayToNative(ts)));
}
///
/// Create an expression representing t[0] - t[1] - ....
///
public ArithExpr MkSub(params ArithExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return (ArithExpr)Expr.Create(this, Native.Z3_mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Create an expression representing -t.
///
public ArithExpr MkUnaryMinus(ArithExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return (ArithExpr)Expr.Create(this, Native.Z3_mk_unary_minus(nCtx, t.NativeObject));
}
///
/// Create an expression representing t1 / t2.
///
public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return (ArithExpr)Expr.Create(this, Native.Z3_mk_div(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 mod t2.
///
/// The arguments must have int type.
public IntExpr MkMod(IntExpr t1, IntExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new IntExpr(this, Native.Z3_mk_mod(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 rem t2.
///
/// The arguments must have int type.
public IntExpr MkRem(IntExpr t1, IntExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new IntExpr(this, Native.Z3_mk_rem(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 ^ t2.
///
public ArithExpr MkPower(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return (ArithExpr)Expr.Create(this, Native.Z3_mk_power(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 < t2
///
public BoolExpr MkLt(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_lt(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 <= t2
///
public BoolExpr MkLe(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_le(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 > t2
///
public BoolExpr MkGt(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_gt(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an expression representing t1 >= t2
///
public BoolExpr MkGe(ArithExpr t1, ArithExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_ge(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Coerce an integer to a real.
///
///
/// There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard.
///
/// You can take the floor of a real by creating an auxiliary integer Term k and
/// and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1.
/// The argument must be of integer sort.
///
public RealExpr MkInt2Real(IntExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new RealExpr(this, Native.Z3_mk_int2real(nCtx, t.NativeObject));
}
///
/// Coerce a real to an integer.
///
///
/// The semantics of this function follows the SMT-LIB standard for the function to_int.
/// The argument must be of real sort.
///
public IntExpr MkReal2Int(RealExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new IntExpr(this, Native.Z3_mk_real2int(nCtx, t.NativeObject));
}
///
/// Creates an expression that checks whether a real number is an integer.
///
public BoolExpr MkIsInteger(RealExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BoolExpr(this, Native.Z3_mk_is_int(nCtx, t.NativeObject));
}
#endregion
#region Bit-vectors
///
/// Bitwise negation.
///
/// The argument must have a bit-vector sort.
public BitVecExpr MkBVNot(BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_bvnot(nCtx, t.NativeObject));
}
///
/// Take conjunction of bits in a vector, return vector of length 1.
///
/// The argument must have a bit-vector sort.
public BitVecExpr MkBVRedAND(BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_bvredand(nCtx, t.NativeObject));
}
///
/// Take disjunction of bits in a vector, return vector of length 1.
///
/// The argument must have a bit-vector sort.
public BitVecExpr MkBVRedOR(BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_bvredor(nCtx, t.NativeObject));
}
///
/// Bitwise conjunction.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVAND(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvand(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bitwise disjunction.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVOR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvor(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bitwise XOR.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVXOR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvxor(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bitwise NAND.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVNAND(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvnand(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bitwise NOR.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVNOR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvnor(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bitwise XNOR.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVXNOR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvxnor(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Standard two's complement unary minus.
///
/// The arguments must have a bit-vector sort.
public BitVecExpr MkBVNeg(BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_bvneg(nCtx, t.NativeObject));
}
///
/// Two's complement addition.
///
/// The arguments must have the same bit-vector sort.
public BitVecExpr MkBVAdd(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvadd(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement subtraction.
///
/// The arguments must have the same bit-vector sort.
public BitVecExpr MkBVSub(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvsub(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement multiplication.
///
/// The arguments must have the same bit-vector sort.
public BitVecExpr MkBVMul(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvmul(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned division.
///
///
/// It is defined as the floor of t1/t2 if \c t2 is
/// different from zero. If t2 is zero, then the result
/// is undefined.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVUDiv(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvudiv(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Signed division.
///
///
/// It is defined in the following way:
///
/// - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0.
///
/// - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0.
///
/// If t2 is zero, then the result is undefined.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVSDiv(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvsdiv(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned remainder.
///
///
/// It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division.
/// If t2 is zero, then the result is undefined.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVURem(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvurem(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Signed remainder.
///
///
/// It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division.
/// The most significant bit (sign) of the result is equal to the most significant bit of \c t1.
///
/// If t2 is zero, then the result is undefined.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVSRem(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvsrem(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement signed remainder (sign follows divisor).
///
///
/// If t2 is zero, then the result is undefined.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVSMod(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvsmod(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned less-than
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVULT(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvult(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement signed less-than
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVSLT(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvslt(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned less-than or equal to.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVULE(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvule(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement signed less-than or equal to.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVSLE(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsle(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned greater than or equal to.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVUGE(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvuge(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement signed greater than or equal to.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVSGE(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsge(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Unsigned greater-than.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVUGT(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvugt(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Two's complement signed greater-than.
///
///
/// The arguments must have the same bit-vector sort.
///
public BoolExpr MkBVSGT(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsgt(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bit-vector concatenation.
///
///
/// The arguments must have a bit-vector sort.
///
///
/// The result is a bit-vector of size n1+n2, where n1 (n2)
/// is the size of t1 (t2).
///
public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_concat(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Bit-vector extraction.
///
///
/// Extract the bits down to from a bitvector of
/// size m to yield a new bitvector of size n, where
/// n = high - low + 1.
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_extract(nCtx, high, low, t.NativeObject));
}
///
/// Bit-vector sign extension.
///
///
/// Sign-extends the given bit-vector to the (signed) equivalent bitvector of
/// size m+i, where \c m is the size of the given bit-vector.
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkSignExt(uint i, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_sign_ext(nCtx, i, t.NativeObject));
}
///
/// Bit-vector zero extension.
///
///
/// Extend the given bit-vector with zeros to the (unsigned) equivalent
/// bitvector of size m+i, where \c m is the size of the
/// given bit-vector.
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkZeroExt(uint i, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_zero_ext(nCtx, i, t.NativeObject));
}
///
/// Bit-vector repetition.
///
///
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkRepeat(uint i, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_repeat(nCtx, i, t.NativeObject));
}
///
/// Shift left.
///
///
/// It is equivalent to multiplication by 2^x where \c x is the value of .
///
/// NB. The semantics of shift operations varies between environments. This
/// definition does not necessarily capture directly the semantics of the
/// programming language or assembly architecture you are modeling.
///
/// The arguments must have a bit-vector sort.
///
public BitVecExpr MkBVSHL(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvshl(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Logical shift right
///
///
/// It is equivalent to unsigned division by 2^x where \c x is the value of .
///
/// NB. The semantics of shift operations varies between environments. This
/// definition does not necessarily capture directly the semantics of the
/// programming language or assembly architecture you are modeling.
///
/// The arguments must have a bit-vector sort.
///
public BitVecExpr MkBVLSHR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvlshr(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Arithmetic shift right
///
///
/// It is like logical shift right except that the most significant
/// bits of the result always copy the most significant bit of the
/// second argument.
///
/// NB. The semantics of shift operations varies between environments. This
/// definition does not necessarily capture directly the semantics of the
/// programming language or assembly architecture you are modeling.
///
/// The arguments must have a bit-vector sort.
///
public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_bvashr(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Rotate Left.
///
///
/// Rotate bits of \c t to the left \c i times.
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkBVRotateLeft(uint i, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_rotate_left(nCtx, i, t.NativeObject));
}
///
/// Rotate Right.
///
///
/// Rotate bits of \c t to the right \c i times.
/// The argument must have a bit-vector sort.
///
public BitVecExpr MkBVRotateRight(uint i, BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_rotate_right(nCtx, i, t.NativeObject));
}
///
/// Rotate Left.
///
///
/// Rotate bits of to the left times.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVRotateLeft(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_ext_rotate_left(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Rotate Right.
///
///
/// Rotate bits of to the right times.
/// The arguments must have the same bit-vector sort.
///
public BitVecExpr MkBVRotateRight(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BitVecExpr(this, Native.Z3_mk_ext_rotate_right(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create an bit bit-vector from the integer argument .
///
///
/// NB. This function is essentially treated as uninterpreted.
/// So you cannot expect Z3 to precisely reflect the semantics of this function
/// when solving constraints with this function.
///
/// The argument must be of integer sort.
///
public BitVecExpr MkInt2BV(uint n, IntExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BitVecExpr(this, Native.Z3_mk_int2bv(nCtx, n, t.NativeObject));
}
///
/// Create an integer from the bit-vector argument .
///
///
/// If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned.
/// So the result is non-negative and in the range [0..2^N-1], where
/// N are the number of bits in .
/// If \c is_signed is true, \c t1 is treated as a signed bit-vector.
///
/// NB. This function is essentially treated as uninterpreted.
/// So you cannot expect Z3 to precisely reflect the semantics of this function
/// when solving constraints with this function.
///
/// The argument must be of bit-vector sort.
///
public IntExpr MkBV2Int(BitVecExpr t, bool signed)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new IntExpr(this, Native.Z3_mk_bv2int(nCtx, t.NativeObject, (byte)(signed ? 1 : 0)));
}
///
/// Create a predicate that checks that the bit-wise addition does not overflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvadd_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
///
/// Create a predicate that checks that the bit-wise addition does not underflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvadd_no_underflow(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a predicate that checks that the bit-wise subtraction does not overflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsub_no_overflow(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a predicate that checks that the bit-wise subtraction does not underflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsub_no_underflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
///
/// Create a predicate that checks that the bit-wise signed division does not overflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsdiv_no_overflow(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a predicate that checks that the bit-wise negation does not overflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVNegNoOverflow(BitVecExpr t)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new BoolExpr(this, Native.Z3_mk_bvneg_no_overflow(nCtx, t.NativeObject));
}
///
/// Create a predicate that checks that the bit-wise multiplication does not overflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvmul_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
///
/// Create a predicate that checks that the bit-wise multiplication does not underflow.
///
///
/// The arguments must be of bit-vector sort.
///
public BoolExpr MkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvmul_no_underflow(nCtx, t1.NativeObject, t2.NativeObject));
}
#endregion
#region Arrays
///
/// Create an array constant.
///
public ArrayExpr MkArrayConst(Symbol name, Sort domain, Sort range)
{
Debug.Assert(name != null);
Debug.Assert(domain != null);
Debug.Assert(range != null);
using var sort = MkArraySort(domain, range);
return (ArrayExpr)MkConst(name, sort);
}
///
/// Create an array constant.
///
public ArrayExpr MkArrayConst(string name, Sort domain, Sort range)
{
Debug.Assert(domain != null);
Debug.Assert(range != null);
using var symbol = MkSymbol(name);
using var sort = MkArraySort(domain, range);
return (ArrayExpr)MkConst(symbol, sort);
}
///
/// Array read.
///
///
/// The argument a is the array and i is the index
/// of the array that gets read.
///
/// The node a must have an array sort [domain -> range],
/// and i must have the sort domain.
/// The sort of the result is range.
///
///
///
public Expr MkSelect(ArrayExpr a, Expr i)
{
Debug.Assert(a != null);
Debug.Assert(i != null);
CheckContextMatch(a);
CheckContextMatch(i);
return Expr.Create(this, Native.Z3_mk_select(nCtx, a.NativeObject, i.NativeObject));
}
///
/// Array read.
///
///
/// The argument a is the array and args are the indices
/// of the array that gets read.
///
/// The node a must have an array sort [domain1,..,domaink -> range],
/// and args must have the sort domain1,..,domaink.
/// The sort of the result is range.
///
///
///
public Expr MkSelect(ArrayExpr a, params Expr[] args)
{
Debug.Assert(a != null);
Debug.Assert(args != null && args.All(n => n != null));
CheckContextMatch(a);
CheckContextMatch(args);
return Expr.Create(this, Native.Z3_mk_select_n(nCtx, a.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args)));
}
///
/// Array update.
///
///
/// The node a must have an array sort [domain -> range],
/// i must have sort domain,
/// v must have sort range. The sort of the result is [domain -> range].
/// The semantics of this function is given by the theory of arrays described in the SMT-LIB
/// standard. See http://smtlib.org for more details.
/// The result of this function is an array that is equal to a
/// (with respect to select)
/// on all indices except for i, where it maps to v
/// (and the select of a with
/// respect to i may be a different value).
///
///
///
///
public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v)
{
Debug.Assert(a != null);
Debug.Assert(i != null);
Debug.Assert(v != null);
CheckContextMatch(a);
CheckContextMatch(i);
CheckContextMatch(v);
return new ArrayExpr(this, Native.Z3_mk_store(nCtx, a.NativeObject, i.NativeObject, v.NativeObject));
}
///
/// Array update.
///
///
/// The node a must have an array sort [domain1,..,domaink -> range],
/// args must have sort domain1,..,domaink,
/// v must have sort range. The sort of the result is [domain -> range].
/// The semantics of this function is given by the theory of arrays described in the SMT-LIB
/// standard. See http://smtlib.org for more details.
/// The result of this function is an array that is equal to a
/// (with respect to select)
/// on all indices except for args, where it maps to v
/// (and the select of a with
/// respect to args may be a different value).
///
///
///
///
public ArrayExpr MkStore(ArrayExpr a, Expr[] args, Expr v)
{
Debug.Assert(a != null);
Debug.Assert(args != null);
Debug.Assert(v != null);
CheckContextMatch(args);
CheckContextMatch(a);
CheckContextMatch(v);
return new ArrayExpr(this, Native.Z3_mk_store_n(nCtx, a.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args), v.NativeObject));
}
///
/// Create a constant array.
///
///
/// The resulting term is an array, such that a selecton an arbitrary index
/// produces the value v.
///
///
///
public ArrayExpr MkConstArray(Sort domain, Expr v)
{
Debug.Assert(domain != null);
Debug.Assert(v != null);
CheckContextMatch(domain);
CheckContextMatch(v);
return new ArrayExpr(this, Native.Z3_mk_const_array(nCtx, domain.NativeObject, v.NativeObject));
}
///
/// Maps f on the argument arrays.
///
///
/// Each element of args must be of an array sort [domain_i -> range_i].
/// The function declaration f must have type range_1 .. range_n -> range.
/// v must have sort range. The sort of the result is [domain_i -> range].
///
///
///
///
public ArrayExpr MkMap(FuncDecl f, params ArrayExpr[] args)
{
Debug.Assert(f != null);
Debug.Assert(args == null || args.All(a => a != null));
CheckContextMatch(f);
CheckContextMatch(args);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args)));
}
///
/// Access the array default value.
///
///
/// Produces the default range value, for arrays that can be represented as
/// finite maps with a default range value.
///
public Expr MkTermArray(ArrayExpr array)
{
Debug.Assert(array != null);
CheckContextMatch(array);
return Expr.Create(this, Native.Z3_mk_array_default(nCtx, array.NativeObject));
}
///
/// Create Extentionality index. Two arrays are equal if and only if they are equal on the index returned by MkArrayExt.
///
public Expr MkArrayExt(ArrayExpr arg1, ArrayExpr arg2)
{
Debug.Assert(arg1 != null);
Debug.Assert(arg2 != null);
CheckContextMatch(arg1);
CheckContextMatch(arg2);
return Expr.Create(this, Native.Z3_mk_array_ext(nCtx, arg1.NativeObject, arg2.NativeObject));
}
#endregion
#region Sets
///
/// Create a set type.
///
public SetSort MkSetSort(Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return new SetSort(this, ty);
}
///
/// Create an empty set.
///
public ArrayExpr MkEmptySet(Sort domain)
{
Debug.Assert(domain != null);
CheckContextMatch(domain);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_empty_set(nCtx, domain.NativeObject));
}
///
/// Create the full set.
///
public ArrayExpr MkFullSet(Sort domain)
{
Debug.Assert(domain != null);
CheckContextMatch(domain);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_full_set(nCtx, domain.NativeObject));
}
///
/// Add an element to the set.
///
public ArrayExpr MkSetAdd(ArrayExpr set, Expr element)
{
Debug.Assert(set != null);
Debug.Assert(element != null);
CheckContextMatch(set);
CheckContextMatch(element);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_add(nCtx, set.NativeObject, element.NativeObject));
}
///
/// Remove an element from a set.
///
public ArrayExpr MkSetDel(ArrayExpr set, Expr element)
{
Debug.Assert(set != null);
Debug.Assert(element != null);
CheckContextMatch(set);
CheckContextMatch(element);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_del(nCtx, set.NativeObject, element.NativeObject));
}
///
/// Take the union of a list of sets.
///
public ArrayExpr MkSetUnion(params ArrayExpr[] args)
{
Debug.Assert(args != null);
Debug.Assert(args.All(a => a != null));
CheckContextMatch(args);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
}
///
/// Take the intersection of a list of sets.
///
public ArrayExpr MkSetIntersection(params ArrayExpr[] args)
{
Debug.Assert(args != null);
Debug.Assert(args.All(a => a != null));
CheckContextMatch(args);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
}
///
/// Take the difference between two sets.
///
public ArrayExpr MkSetDifference(ArrayExpr arg1, ArrayExpr arg2)
{
Debug.Assert(arg1 != null);
Debug.Assert(arg2 != null);
CheckContextMatch(arg1);
CheckContextMatch(arg2);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_difference(nCtx, arg1.NativeObject, arg2.NativeObject));
}
///
/// Take the complement of a set.
///
public ArrayExpr MkSetComplement(ArrayExpr arg)
{
Debug.Assert(arg != null);
CheckContextMatch(arg);
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_complement(nCtx, arg.NativeObject));
}
///
/// Check for set membership.
///
public BoolExpr MkSetMembership(Expr elem, ArrayExpr set)
{
Debug.Assert(elem != null);
Debug.Assert(set != null);
CheckContextMatch(elem);
CheckContextMatch(set);
return (BoolExpr)Expr.Create(this, Native.Z3_mk_set_member(nCtx, elem.NativeObject, set.NativeObject));
}
///
/// Check for subsetness of sets.
///
public BoolExpr MkSetSubset(ArrayExpr arg1, ArrayExpr arg2)
{
Debug.Assert(arg1 != null);
Debug.Assert(arg2 != null);
CheckContextMatch(arg1);
CheckContextMatch(arg2);
return (BoolExpr)Expr.Create(this, Native.Z3_mk_set_subset(nCtx, arg1.NativeObject, arg2.NativeObject));
}
#endregion
#region Sequence, string and regular expressions
///
/// Create the empty sequence.
///
public SeqExpr MkEmptySeq(Sort s)
{
Debug.Assert(s != null);
return new SeqExpr(this, Native.Z3_mk_seq_empty(nCtx, s.NativeObject));
}
///
/// Create the singleton sequence.
///
public SeqExpr MkUnit(Expr elem)
{
Debug.Assert(elem != null);
return new SeqExpr(this, Native.Z3_mk_seq_unit(nCtx, elem.NativeObject));
}
///
/// Create a string constant.
///
public SeqExpr MkString(string s)
{
Debug.Assert(s != null);
return new SeqExpr(this, Native.Z3_mk_string(nCtx, s));
}
///
/// Convert an integer expression to a string.
///
public SeqExpr IntToString(Expr e)
{
Debug.Assert(e != null);
Debug.Assert(e is ArithExpr);
return new SeqExpr(this, Native.Z3_mk_int_to_str(nCtx, e.NativeObject));
}
///
/// Convert a bit-vector expression, represented as an unsigned number, to a string.
///
public SeqExpr UbvToString(Expr e)
{
Debug.Assert(e != null);
Debug.Assert(e is ArithExpr);
return new SeqExpr(this, Native.Z3_mk_ubv_to_str(nCtx, e.NativeObject));
}
///
/// Convert a bit-vector expression, represented as an signed number, to a string.
///
public SeqExpr SbvToString(Expr e)
{
Debug.Assert(e != null);
Debug.Assert(e is ArithExpr);
return new SeqExpr(this, Native.Z3_mk_sbv_to_str(nCtx, e.NativeObject));
}
///
/// Convert an integer expression to a string.
///
public IntExpr StringToInt(Expr e)
{
Debug.Assert(e != null);
Debug.Assert(e is SeqExpr);
return new IntExpr(this, Native.Z3_mk_str_to_int(nCtx, e.NativeObject));
}
///
/// Concatenate sequences.
///
public SeqExpr MkConcat(params SeqExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return new SeqExpr(this, Native.Z3_mk_seq_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Retrieve the length of a given sequence.
///
public IntExpr MkLength(SeqExpr s)
{
Debug.Assert(s != null);
return (IntExpr)Expr.Create(this, Native.Z3_mk_seq_length(nCtx, s.NativeObject));
}
///
/// Check for sequence prefix.
///
public BoolExpr MkPrefixOf(SeqExpr s1, SeqExpr s2)
{
Debug.Assert(s1 != null);
Debug.Assert(s2 != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_prefix(nCtx, s1.NativeObject, s2.NativeObject));
}
///
/// Check for sequence suffix.
///
public BoolExpr MkSuffixOf(SeqExpr s1, SeqExpr s2)
{
Debug.Assert(s1 != null);
Debug.Assert(s2 != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_suffix(nCtx, s1.NativeObject, s2.NativeObject));
}
///
/// Check for sequence containment of s2 in s1.
///
public BoolExpr MkContains(SeqExpr s1, SeqExpr s2)
{
Debug.Assert(s1 != null);
Debug.Assert(s2 != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_contains(nCtx, s1.NativeObject, s2.NativeObject));
}
///
/// Check if the string s1 is lexicographically strictly less than s2.
///
public BoolExpr MkStringLt(SeqExpr s1, SeqExpr s2)
{
Debug.Assert(s1 != null);
Debug.Assert(s2 != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_str_lt(nCtx, s1.NativeObject, s2.NativeObject));
}
///
/// Check if the string s1 is lexicographically less or equal to s2.
///
public BoolExpr MkStringLe(SeqExpr s1, SeqExpr s2)
{
Debug.Assert(s1 != null);
Debug.Assert(s2 != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_str_le(nCtx, s1.NativeObject, s2.NativeObject));
}
///
/// Retrieve sequence of length one at index.
///
public SeqExpr MkAt(SeqExpr s, Expr index)
{
Debug.Assert(s != null);
Debug.Assert(index != null);
CheckContextMatch(s, index);
return new SeqExpr(this, Native.Z3_mk_seq_at(nCtx, s.NativeObject, index.NativeObject));
}
///
/// Retrieve element at index.
///
public Expr MkNth(SeqExpr s, Expr index)
{
Debug.Assert(s != null);
Debug.Assert(index != null);
CheckContextMatch(s, index);
return Expr.Create(this, Native.Z3_mk_seq_nth(nCtx, s.NativeObject, index.NativeObject));
}
///
/// Extract subsequence.
///
public SeqExpr MkExtract(SeqExpr s, IntExpr offset, IntExpr length)
{
Debug.Assert(s != null);
Debug.Assert(offset != null);
Debug.Assert(length != null);
CheckContextMatch(s, offset, length);
return new SeqExpr(this, Native.Z3_mk_seq_extract(nCtx, s.NativeObject, offset.NativeObject, length.NativeObject));
}
///
/// Extract index of sub-string starting at offset.
///
public IntExpr MkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset)
{
Debug.Assert(s != null);
Debug.Assert(offset != null);
Debug.Assert(substr != null);
CheckContextMatch(s, substr, offset);
return new IntExpr(this, Native.Z3_mk_seq_index(nCtx, s.NativeObject, substr.NativeObject, offset.NativeObject));
}
///
/// Replace the first occurrence of src by dst in s.
///
public SeqExpr MkReplace(SeqExpr s, SeqExpr src, SeqExpr dst)
{
Debug.Assert(s != null);
Debug.Assert(src != null);
Debug.Assert(dst != null);
CheckContextMatch(s, src, dst);
return new SeqExpr(this, Native.Z3_mk_seq_replace(nCtx, s.NativeObject, src.NativeObject, dst.NativeObject));
}
///
/// Convert a regular expression that accepts sequence s.
///
public ReExpr MkToRe(SeqExpr s)
{
Debug.Assert(s != null);
return new ReExpr(this, Native.Z3_mk_seq_to_re(nCtx, s.NativeObject));
}
///
/// Check for regular expression membership.
///
public BoolExpr MkInRe(SeqExpr s, ReExpr re)
{
Debug.Assert(s != null);
Debug.Assert(re != null);
CheckContextMatch(s, re);
return new BoolExpr(this, Native.Z3_mk_seq_in_re(nCtx, s.NativeObject, re.NativeObject));
}
///
/// Take the Kleene star of a regular expression.
///
public ReExpr MkStar(ReExpr re)
{
Debug.Assert(re != null);
return new ReExpr(this, Native.Z3_mk_re_star(nCtx, re.NativeObject));
}
///
/// Take the bounded Kleene star of a regular expression.
///
public ReExpr MkLoop(ReExpr re, uint lo, uint hi = 0)
{
Debug.Assert(re != null);
return new ReExpr(this, Native.Z3_mk_re_loop(nCtx, re.NativeObject, lo, hi));
}
///
/// Take the Kleene plus of a regular expression.
///
public ReExpr MkPlus(ReExpr re)
{
Debug.Assert(re != null);
return new ReExpr(this, Native.Z3_mk_re_plus(nCtx, re.NativeObject));
}
///
/// Create the optional regular expression.
///
public ReExpr MkOption(ReExpr re)
{
Debug.Assert(re != null);
return new ReExpr(this, Native.Z3_mk_re_option(nCtx, re.NativeObject));
}
///
/// Create the complement regular expression.
///
public ReExpr MkComplement(ReExpr re)
{
Debug.Assert(re != null);
return new ReExpr(this, Native.Z3_mk_re_complement(nCtx, re.NativeObject));
}
///
/// Create the concatenation of regular languages.
///
public ReExpr MkConcat(params ReExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return new ReExpr(this, Native.Z3_mk_re_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Create the union of regular languages.
///
public ReExpr MkUnion(params ReExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return new ReExpr(this, Native.Z3_mk_re_union(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Create the intersection of regular languages.
///
public ReExpr MkIntersect(params ReExpr[] t)
{
Debug.Assert(t != null);
Debug.Assert(t.All(a => a != null));
CheckContextMatch(t);
return new ReExpr(this, Native.Z3_mk_re_intersect(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
///
/// Create a difference regular expression.
///
public ReExpr MkDiff(ReExpr a, ReExpr b)
{
Debug.Assert(a != null);
Debug.Assert(b != null);
CheckContextMatch(a, b);
return new ReExpr(this, Native.Z3_mk_re_diff(nCtx, a.NativeObject, b.NativeObject));
}
///
/// Create the empty regular expression.
/// The sort s should be a regular expression.
///
public ReExpr MkEmptyRe(Sort s)
{
Debug.Assert(s != null);
return new ReExpr(this, Native.Z3_mk_re_empty(nCtx, s.NativeObject));
}
///
/// Create the full regular expression.
/// The sort s should be a regular expression.
///
public ReExpr MkFullRe(Sort s)
{
Debug.Assert(s != null);
return new ReExpr(this, Native.Z3_mk_re_full(nCtx, s.NativeObject));
}
///
/// Create a range expression.
///
public ReExpr MkRange(SeqExpr lo, SeqExpr hi)
{
Debug.Assert(lo != null);
Debug.Assert(hi != null);
CheckContextMatch(lo, hi);
return new ReExpr(this, Native.Z3_mk_re_range(nCtx, lo.NativeObject, hi.NativeObject));
}
///
/// Create less than or equal to between two characters.
///
public BoolExpr MkCharLe(Expr ch1, Expr ch2)
{
Debug.Assert(ch1 != null);
Debug.Assert(ch2 != null);
return new BoolExpr(this, Native.Z3_mk_char_le(nCtx, ch1.NativeObject, ch2.NativeObject));
}
///
/// Create an integer (code point) from character.
///
public IntExpr CharToInt(Expr ch)
{
Debug.Assert(ch != null);
return new IntExpr(this, Native.Z3_mk_char_to_int(nCtx, ch.NativeObject));
}
///
/// Create a bit-vector (code point) from character.
///
public BitVecExpr CharToBV(Expr ch)
{
Debug.Assert(ch != null);
return new BitVecExpr(this, Native.Z3_mk_char_to_bv(nCtx, ch.NativeObject));
}
///
/// Create a character from a bit-vector (code point).
///
public Expr CharFromBV(BitVecExpr bv)
{
Debug.Assert(bv != null);
return new Expr(this, Native.Z3_mk_char_from_bv(nCtx, bv.NativeObject));
}
///
/// Create a check if the character is a digit.
///
public BoolExpr MkIsDigit(Expr ch)
{
Debug.Assert(ch != null);
return new BoolExpr(this, Native.Z3_mk_char_is_digit(nCtx, ch.NativeObject));
}
#endregion
#region Pseudo-Boolean constraints
///
/// Create an at-most-k constraint.
///
public BoolExpr MkAtMost(IEnumerable args, uint k)
{
Debug.Assert(args != null);
CheckContextMatch(args);
var ts = args.ToArray();
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint)ts.Length,
AST.ArrayToNative(ts), k));
}
///
/// Create an at-least-k constraint.
///
public BoolExpr MkAtLeast(IEnumerable args, uint k)
{
Debug.Assert(args != null);
CheckContextMatch(args);
var ts = args.ToArray();
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint)ts.Length,
AST.ArrayToNative(ts), k));
}
///
/// Create a pseudo-Boolean less-or-equal constraint.
///
public BoolExpr MkPBLe(int[] coeffs, BoolExpr[] args, int k)
{
Debug.Assert(args != null);
Debug.Assert(coeffs != null);
Debug.Assert(args.Length == coeffs.Length);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint)args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
///
/// Create a pseudo-Boolean greater-or-equal constraint.
///
public BoolExpr MkPBGe(int[] coeffs, BoolExpr[] args, int k)
{
Debug.Assert(args != null);
Debug.Assert(coeffs != null);
Debug.Assert(args.Length == coeffs.Length);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_pbge(nCtx, (uint)args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
///
/// Create a pseudo-Boolean equal constraint.
///
public BoolExpr MkPBEq(int[] coeffs, BoolExpr[] args, int k)
{
Debug.Assert(args != null);
Debug.Assert(coeffs != null);
Debug.Assert(args.Length == coeffs.Length);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_pbeq(nCtx, (uint)args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
#endregion
#region Numerals
#region General Numerals
///
/// Create a Term of a given sort.
///
/// A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*.
/// The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size.
/// A Term with value and sort
public Expr MkNumeral(string v, Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return Expr.Create(this, Native.Z3_mk_numeral(nCtx, v, ty.NativeObject));
}
///
/// Create a Term of a given sort. This function can be used to create numerals that fit in a machine integer.
/// It is slightly faster than MakeNumeral since it is not necessary to parse a string.
///
/// Value of the numeral
/// Sort of the numeral
/// A Term with value and type
public Expr MkNumeral(int v, Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return Expr.Create(this, Native.Z3_mk_int(nCtx, v, ty.NativeObject));
}
///
/// Create a Term of a given sort. This function can be used to create numerals that fit in a machine integer.
/// It is slightly faster than MakeNumeral since it is not necessary to parse a string.
///
/// Value of the numeral
/// Sort of the numeral
/// A Term with value and type
public Expr MkNumeral(uint v, Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return Expr.Create(this, Native.Z3_mk_unsigned_int(nCtx, v, ty.NativeObject));
}
///
/// Create a Term of a given sort. This function can be used to create numerals that fit in a machine integer.
/// It is slightly faster than MakeNumeral since it is not necessary to parse a string.
///
/// Value of the numeral
/// Sort of the numeral
/// A Term with value and type
public Expr MkNumeral(long v, Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return Expr.Create(this, Native.Z3_mk_int64(nCtx, v, ty.NativeObject));
}
///
/// Create a Term of a given sort. This function can be used to create numerals that fit in a machine integer.
/// It is slightly faster than MakeNumeral since it is not necessary to parse a string.
///
/// Value of the numeral
/// Sort of the numeral
/// A Term with value and type
public Expr MkNumeral(ulong v, Sort ty)
{
Debug.Assert(ty != null);
CheckContextMatch(ty);
return Expr.Create(this, Native.Z3_mk_unsigned_int64(nCtx, v, ty.NativeObject));
}
#endregion
#region Reals
///
/// Create a real from a fraction.
///
/// numerator of rational.
/// denominator of rational.
/// A Term with value / and sort Real
///
public RatNum MkReal(int num, int den)
{
if (den == 0)
throw new Z3Exception("Denominator is zero");
return new RatNum(this, Native.Z3_mk_real(nCtx, num, den));
}
///
/// Create a real numeral.
///
/// A string representing the Term value in decimal notation.
/// A Term with value and sort Real
public RatNum MkReal(string v)
{
return new RatNum(this, Native.Z3_mk_numeral(nCtx, v, RealSort.NativeObject));
}
///
/// Create a real numeral.
///
/// value of the numeral.
/// A Term with value and sort Real
public RatNum MkReal(int v)
{
return new RatNum(this, Native.Z3_mk_int(nCtx, v, RealSort.NativeObject));
}
///
/// Create a real numeral.
///
/// value of the numeral.
/// A Term with value and sort Real
public RatNum MkReal(uint v)
{
return new RatNum(this, Native.Z3_mk_unsigned_int(nCtx, v, RealSort.NativeObject));
}
///
/// Create a real numeral.
///
/// value of the numeral.
/// A Term with value and sort Real
public RatNum MkReal(long v)
{
return new RatNum(this, Native.Z3_mk_int64(nCtx, v, RealSort.NativeObject));
}
///
/// Create a real numeral.
///
/// value of the numeral.
/// A Term with value and sort Real
public RatNum MkReal(ulong v)
{
return new RatNum(this, Native.Z3_mk_unsigned_int64(nCtx, v, RealSort.NativeObject));
}
#endregion
#region Integers
///
/// Create an integer numeral.
///
/// A string representing the Term value in decimal notation.
public IntNum MkInt(string v)
{
return new IntNum(this, Native.Z3_mk_numeral(nCtx, v, IntSort.NativeObject));
}
///
/// Create an integer numeral.
///
/// value of the numeral.
/// A Term with value and sort Integer
public IntNum MkInt(int v)
{
return new IntNum(this, Native.Z3_mk_int(nCtx, v, IntSort.NativeObject));
}
///
/// Create an integer numeral.
///
/// value of the numeral.
/// A Term with value and sort Integer
public IntNum MkInt(uint v)
{
return new IntNum(this, Native.Z3_mk_unsigned_int(nCtx, v, IntSort.NativeObject));
}
///
/// Create an integer numeral.
///
/// value of the numeral.
/// A Term with value and sort Integer
public IntNum MkInt(long v)
{
return new IntNum(this, Native.Z3_mk_int64(nCtx, v, IntSort.NativeObject));
}
///
/// Create an integer numeral.
///
/// value of the numeral.
/// A Term with value and sort Integer
public IntNum MkInt(ulong v)
{
return new IntNum(this, Native.Z3_mk_unsigned_int64(nCtx, v, IntSort.NativeObject));
}
#endregion
#region Bit-vectors
///
/// Create a bit-vector numeral.
///
/// A string representing the value in decimal notation.
/// the size of the bit-vector
public BitVecNum MkBV(string v, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecNum)MkNumeral(v, sort);
}
///
/// Create a bit-vector numeral.
///
/// value of the numeral.
/// the size of the bit-vector
public BitVecNum MkBV(int v, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecNum)MkNumeral(v, sort);
}
///
/// Create a bit-vector numeral.
///
/// value of the numeral.
/// the size of the bit-vector
public BitVecNum MkBV(uint v, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecNum)MkNumeral(v, sort);
}
///
/// Create a bit-vector numeral.
///
/// value of the numeral.
/// the size of the bit-vector
public BitVecNum MkBV(long v, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecNum)MkNumeral(v, sort);
}
///
/// Create a bit-vector numeral.
///
/// value of the numeral.
/// the size of the bit-vector
public BitVecNum MkBV(ulong v, uint size)
{
using var sort = MkBitVecSort(size);
return (BitVecNum)MkNumeral(v, sort);
}
///
/// Create a bit-vector numeral.
///
/// An array of bits representing the bit-vector. Least significant bit is at position 0.
public BitVecNum MkBV(bool[] bits)
{
byte[] _bits = new byte[bits.Length];
for (int i = 0; i < bits.Length; ++i) _bits[i] = (byte)(bits[i] ? 1 : 0);
return (BitVecNum)Expr.Create(this, Native.Z3_mk_bv_numeral(nCtx, (uint)bits.Length, _bits));
}
#endregion
#endregion // Numerals
#region Quantifiers
///
/// Create a universal Quantifier.
///
///
/// Creates a forall formula, where is the weight,
/// is an array of patterns, is an array
/// with the sorts of the bound variables, is an array with the
/// 'names' of the bound variables, and is the body of the
/// quantifier. Quantifiers are associated with weights indicating the importance of
/// using the quantifier during instantiation.
/// Note that the bound variables are de-Bruijn indices created using .
/// Z3 applies the convention that the last element in and
/// refers to the variable with index 0, the second to last element
/// of and refers to the variable
/// with index 1, etc.
///
/// the sorts of the bound variables.
/// names of the bound variables
/// the body of the quantifier.
/// quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0.
/// array containing the patterns created using MkPattern.
/// array containing the anti-patterns created using MkPattern.
/// optional symbol to track quantifier.
/// optional symbol to track skolem constants.
public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(sorts != null);
Debug.Assert(names != null);
Debug.Assert(body != null);
Debug.Assert(sorts.Length == names.Length);
Debug.Assert(sorts.All(s => s != null));
Debug.Assert(names.All(n => n != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create a universal Quantifier.
///
///
/// Creates a universal quantifier using a list of constants that will
/// form the set of bound variables.
///
///
public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(body != null);
Debug.Assert(boundConstants == null || boundConstants.All(b => b != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create an existential Quantifier.
///
///
/// Creates an existential quantifier using de-Bruijn indexed variables.
/// ().
///
public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(sorts != null);
Debug.Assert(names != null);
Debug.Assert(body != null);
Debug.Assert(sorts.Length == names.Length);
Debug.Assert(sorts.All(s => s != null));
Debug.Assert(names.All(n => n != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create an existential Quantifier.
///
///
/// Creates an existential quantifier using a list of constants that will
/// form the set of bound variables.
///
///
public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(body != null);
Debug.Assert(boundConstants == null || boundConstants.All(n => n != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create a Quantifier.
///
///
public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(body != null);
Debug.Assert(names != null);
Debug.Assert(sorts != null);
Debug.Assert(sorts.Length == names.Length);
Debug.Assert(sorts.All(s => s != null));
Debug.Assert(names.All(n => n != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
if (universal)
return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID);
else
return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create a Quantifier.
///
///
public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)
{
Debug.Assert(body != null);
Debug.Assert(boundConstants == null || boundConstants.All(n => n != null));
Debug.Assert(patterns == null || patterns.All(p => p != null));
Debug.Assert(noPatterns == null || noPatterns.All(np => np != null));
if (universal)
return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID);
else
return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
///
/// Create a lambda expression.
///
///
/// Creates a lambda expression.
/// is an array
/// with the sorts of the bound variables, is an array with the
/// 'names' of the bound variables, and is the body of the
/// lambda.
/// Note that the bound variables are de-Bruijn indices created using .
/// Z3 applies the convention that the last element in and
/// refers to the variable with index 0, the second to last element
/// of and refers to the variable
/// with index 1, etc.
///
/// the sorts of the bound variables.
/// names of the bound variables
/// the body of the quantifier.
public Lambda MkLambda(Sort[] sorts, Symbol[] names, Expr body)
{
Debug.Assert(sorts != null);
Debug.Assert(names != null);
Debug.Assert(body != null);
Debug.Assert(sorts.Length == names.Length);
Debug.Assert(sorts.All(s => s != null));
Debug.Assert(names.All(n => n != null));
return new Lambda(this, sorts, names, body);
}
///
/// Create a lambda expression.
///
///
/// Creates a lambda expression using a list of constants that will
/// form the set of bound variables.
///
///
public Lambda MkLambda(Expr[] boundConstants, Expr body)
{
Debug.Assert(body != null);
Debug.Assert(boundConstants != null && boundConstants.All(b => b != null));
return new Lambda(this, boundConstants, body);
}
#endregion
#endregion // Expr
#region Options
///
/// Selects the format used for pretty-printing expressions.
///
///
/// The default mode for pretty printing expressions is to produce
/// SMT-LIB style output where common subexpressions are printed
/// at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL.
/// To print shared common subexpressions only once,
/// use the Z3_PRINT_LOW_LEVEL mode.
/// To print in way that conforms to SMT-LIB standards and uses let
/// expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT.
///
///
///
///
///
public Z3_ast_print_mode PrintMode
{
set { Native.Z3_set_ast_print_mode(nCtx, (uint)value); }
}
#endregion
#region SMT Files & Strings
///
/// Parse the given string using the SMT-LIB2 parser.
///
/// A conjunction of assertions in the scope (up to push/pop) at the end of the string.
public BoolExpr[] ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null)
{
uint csn = Symbol.ArrayLength(sortNames);
uint cs = Sort.ArrayLength(sorts);
uint cdn = Symbol.ArrayLength(declNames);
uint cd = AST.ArrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
using ASTVector assertions = new ASTVector(this, Native.Z3_parse_smtlib2_string(nCtx, str,
AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts),
AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)));
return assertions.ToBoolExprArray();
}
///
/// Parse the given file using the SMT-LIB2 parser.
///
///
public BoolExpr[] ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null)
{
uint csn = Symbol.ArrayLength(sortNames);
uint cs = Sort.ArrayLength(sorts);
uint cdn = Symbol.ArrayLength(declNames);
uint cd = AST.ArrayLength(decls);
if (csn != cs || cdn != cd)
throw new Z3Exception("Argument size mismatch");
using ASTVector assertions = new ASTVector(this, Native.Z3_parse_smtlib2_file(nCtx, fileName,
AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts),
AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)));
return assertions.ToBoolExprArray();
}
#endregion
#region Goals
///
/// Creates a new Goal.
///
///
/// Note that the Context must have been created with proof generation support if
/// is set to true here.
///
/// Indicates whether model generation should be enabled.
/// Indicates whether unsat core generation should be enabled.
/// Indicates whether proof generation should be enabled.
public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false)
{
return new Goal(this, models, unsatCores, proofs);
}
#endregion
#region ParameterSets
///
/// Creates a new ParameterSet.
///
public Params MkParams()
{
return new Params(this);
}
#endregion
#region Tactics
///
/// The number of supported tactics.
///
public uint NumTactics
{
get { return Native.Z3_get_num_tactics(nCtx); }
}
///
/// The names of all supported tactics.
///
public string[] TacticNames
{
get
{
uint n = NumTactics;
string[] res = new string[n];
for (uint i = 0; i < n; i++)
res[i] = Native.Z3_get_tactic_name(nCtx, i);
return res;
}
}
///
/// Returns a string containing a description of the tactic with the given name.
///
public string TacticDescription(string name)
{
return Native.Z3_tactic_get_descr(nCtx, name);
}
///
/// Creates a new Tactic.
///
public Tactic MkTactic(string name)
{
return new Tactic(this, name);
}
///
/// Create a tactic that applies to a Goal and
/// then to every subgoal produced by .
///
public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
// Debug.Assert(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null));
CheckContextMatch(t1);
CheckContextMatch(t2);
CheckContextMatch(ts);
IntPtr last = IntPtr.Zero;
if (ts != null && ts.Length > 0)
{
last = ts[ts.Length - 1].NativeObject;
for (int i = ts.Length - 2; i >= 0; i--)
last = Native.Z3_tactic_and_then(nCtx, ts[i].NativeObject, last);
}
if (last != IntPtr.Zero)
{
last = Native.Z3_tactic_and_then(nCtx, t2.NativeObject, last);
return new Tactic(this, Native.Z3_tactic_and_then(nCtx, t1.NativeObject, last));
}
else
return new Tactic(this, Native.Z3_tactic_and_then(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a tactic that applies to a Goal and
/// then to every subgoal produced by .
///
///
/// Shorthand for AndThen.
///
public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
// Debug.Assert(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null));
return AndThen(t1, t2, ts);
}
///
/// Create a tactic that first applies to a Goal and
/// if it fails then returns the result of applied to the Goal.
///
public Tactic OrElse(Tactic t1, Tactic t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new Tactic(this, Native.Z3_tactic_or_else(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a tactic that applies to a goal for milliseconds.
///
///
/// If does not terminate within milliseconds, then it fails.
///
public Tactic TryFor(Tactic t, uint ms)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new Tactic(this, Native.Z3_tactic_try_for(nCtx, t.NativeObject, ms));
}
///
/// Create a tactic that applies to a given goal if the probe
/// evaluates to true.
///
///
/// If evaluates to false, then the new tactic behaves like the skip tactic.
///
public Tactic When(Probe p, Tactic t)
{
Debug.Assert(p != null);
Debug.Assert(t != null);
CheckContextMatch(t);
CheckContextMatch(p);
return new Tactic(this, Native.Z3_tactic_when(nCtx, p.NativeObject, t.NativeObject));
}
///
/// Create a tactic that applies to a given goal if the probe
/// evaluates to true and otherwise.
///
public Tactic Cond(Probe p, Tactic t1, Tactic t2)
{
Debug.Assert(p != null);
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(p);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new Tactic(this, Native.Z3_tactic_cond(nCtx, p.NativeObject, t1.NativeObject, t2.NativeObject));
}
///
/// Create a tactic that keeps applying until the goal is not
/// modified anymore or the maximum number of iterations is reached.
///
public Tactic Repeat(Tactic t, uint max = uint.MaxValue)
{
Debug.Assert(t != null);
CheckContextMatch(t);
return new Tactic(this, Native.Z3_tactic_repeat(nCtx, t.NativeObject, max));
}
///
/// Create a tactic that just returns the given goal.
///
public Tactic Skip()
{
return new Tactic(this, Native.Z3_tactic_skip(nCtx));
}
///
/// Create a tactic always fails.
///
public Tactic Fail()
{
return new Tactic(this, Native.Z3_tactic_fail(nCtx));
}
///
/// Create a tactic that fails if the probe evaluates to false.
///
public Tactic FailIf(Probe p)
{
Debug.Assert(p != null);
CheckContextMatch(p);
return new Tactic(this, Native.Z3_tactic_fail_if(nCtx, p.NativeObject));
}
///
/// Create a tactic that fails if the goal is not trivially satisfiable (i.e., empty)
/// or trivially unsatisfiable (i.e., contains `false').
///
public Tactic FailIfNotDecided()
{
return new Tactic(this, Native.Z3_tactic_fail_if_not_decided(nCtx));
}
///
/// Create a tactic that applies using the given set of parameters .
///
public Tactic UsingParams(Tactic t, Params p)
{
Debug.Assert(t != null);
Debug.Assert(p != null);
CheckContextMatch(t);
CheckContextMatch(p);
return new Tactic(this, Native.Z3_tactic_using_params(nCtx, t.NativeObject, p.NativeObject));
}
///
/// Create a tactic that applies using the given set of parameters .
///
/// Alias for UsingParams
public Tactic With(Tactic t, Params p)
{
Debug.Assert(t != null);
Debug.Assert(p != null);
return UsingParams(t, p);
}
///
/// Create a tactic that applies the given tactics in parallel until one of them succeeds (i.e., the first that doesn't fail).
///
public Tactic ParOr(params Tactic[] t)
{
Debug.Assert(t == null || t.All(tactic => tactic != null));
CheckContextMatch(t);
return new Tactic(this, Native.Z3_tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t)));
}
///
/// Create a tactic that applies to a given goal and then
/// to every subgoal produced by . The subgoals are processed in parallel.
///
public Tactic ParAndThen(Tactic t1, Tactic t2)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
CheckContextMatch(t1);
CheckContextMatch(t2);
return new Tactic(this, Native.Z3_tactic_par_and_then(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Interrupt the execution of a Z3 procedure.
///
/// This procedure can be used to interrupt: solvers, simplifiers and tactics.
public void Interrupt()
{
Native.Z3_interrupt(nCtx);
}
#endregion
#region Simplifiers
///
/// The number of supported simplifiers.
///
public uint NumSimplifiers
{
get { return Native.Z3_get_num_simplifiers(nCtx); }
}
///
/// The names of all supported tactics.
///
public string[] SimplifierNames
{
get
{
uint n = NumSimplifiers;
string[] res = new string[n];
for (uint i = 0; i < n; i++)
res[i] = Native.Z3_get_simplifier_name(nCtx, i);
return res;
}
}
///
/// Returns a string containing a description of the simplifier with the given name.
///
public string SimplifierDescription(string name)
{
return Native.Z3_simplifier_get_descr(nCtx, name);
}
///
/// Creates a new Tactic.
///
public Simplifier MkSimplifier(string name)
{
return new Simplifier(this, name);
}
///
/// Create a simplifier that applies and
/// then .
///
public Simplifier AndThen(Simplifier t1, Simplifier t2, params Simplifier[] ts)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
// Debug.Assert(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null));
CheckContextMatch(t1);
CheckContextMatch(t2);
CheckContextMatch(ts);
IntPtr last = IntPtr.Zero;
if (ts != null && ts.Length > 0)
{
last = ts[ts.Length - 1].NativeObject;
for (int i = ts.Length - 2; i >= 0; i--)
last = Native.Z3_simplifier_and_then(nCtx, ts[i].NativeObject, last);
}
if (last != IntPtr.Zero)
{
last = Native.Z3_simplifier_and_then(nCtx, t2.NativeObject, last);
return new Simplifier(this, Native.Z3_simplifier_and_then(nCtx, t1.NativeObject, last));
}
else
return new Simplifier(this, Native.Z3_simplifier_and_then(nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Create a simplifier that applies and then
/// then .
///
///
/// Shorthand for AndThen.
///
public Simplifier Then(Simplifier t1, Simplifier t2, params Simplifier[] ts)
{
Debug.Assert(t1 != null);
Debug.Assert(t2 != null);
// Debug.Assert(ts == null || Contract.ForAll(0, ts.Length, j => ts[j] != null));
return AndThen(t1, t2, ts);
}
///
/// Create a tactic that applies using the given set of parameters .
///
public Simplifier UsingParams(Simplifier t, Params p)
{
Debug.Assert(t != null);
Debug.Assert(p != null);
CheckContextMatch(t);
CheckContextMatch(p);
return new Simplifier(this, Native.Z3_simplifier_using_params(nCtx, t.NativeObject, p.NativeObject));
}
#endregion
#region Probes
///
/// The number of supported Probes.
///
public uint NumProbes
{
get { return Native.Z3_get_num_probes(nCtx); }
}
///
/// The names of all supported Probes.
///
public string[] ProbeNames
{
get
{
uint n = NumProbes;
string[] res = new string[n];
for (uint i = 0; i < n; i++)
res[i] = Native.Z3_get_probe_name(nCtx, i);
return res;
}
}
///
/// Returns a string containing a description of the probe with the given name.
///
public string ProbeDescription(string name)
{
return Native.Z3_probe_get_descr(nCtx, name);
}
///
/// Creates a new Probe.
///
public Probe MkProbe(string name)
{
return new Probe(this, name);
}
///
/// Create a probe that always evaluates to .
///
public Probe ConstProbe(double val)
{
return new Probe(this, Native.Z3_probe_const(nCtx, val));
}
///
/// Create a probe that evaluates to "true" when the value returned by
/// is less than the value returned by
///
public Probe Lt(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_lt(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value returned by
/// is greater than the value returned by
///
public Probe Gt(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_gt(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value returned by
/// is less than or equal the value returned by
///
public Probe Le(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_le(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value returned by
/// is greater than or equal the value returned by
///
public Probe Ge(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_ge(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value returned by
/// is equal to the value returned by
///
public Probe Eq(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_eq(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value
/// and evaluate to "true".
///
public Probe And(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_and(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value
/// or evaluate to "true".
///
public Probe Or(Probe p1, Probe p2)
{
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
CheckContextMatch(p1);
CheckContextMatch(p2);
return new Probe(this, Native.Z3_probe_or(nCtx, p1.NativeObject, p2.NativeObject));
}
///
/// Create a probe that evaluates to "true" when the value
/// does not evaluate to "true".
///
public Probe Not(Probe p)
{
Debug.Assert(p != null);
CheckContextMatch(p);
return new Probe(this, Native.Z3_probe_not(nCtx, p.NativeObject));
}
#endregion
#region Solvers
///
/// Creates a new (incremental) solver.
///
///
/// This solver also uses a set of builtin tactics for handling the first
/// check-sat command, and check-sat commands that take more than a given
/// number of milliseconds to be solved.
///
public Solver MkSolver(Symbol logic = null)
{
if (logic == null)
return new Solver(this, Native.Z3_mk_solver(nCtx));
else
return new Solver(this, Native.Z3_mk_solver_for_logic(nCtx, logic.NativeObject));
}
///
/// Creates a new (incremental) solver.
///
///
public Solver MkSolver(string logic)
{
using var symbol = MkSymbol(logic);
return MkSolver(symbol);
}
///
/// Creates a new (incremental) solver.
///
public Solver MkSimpleSolver()
{
return new Solver(this, Native.Z3_mk_simple_solver(nCtx));
}
///
/// Creates a solver that uses an incremental simplifier.
///
public Solver MkSolver(Solver s, Simplifier t)
{
Debug.Assert(t != null);
Debug.Assert(s != null);
return new Solver(this, Native.Z3_solver_add_simplifier(nCtx, s.NativeObject, t.NativeObject));
}
///
/// Creates a solver that is implemented using the given tactic.
///
///
/// The solver supports the commands Push and Pop, but it
/// will always solve each check from scratch.
///
public Solver MkSolver(Tactic t)
{
Debug.Assert(t != null);
return new Solver(this, Native.Z3_mk_solver_from_tactic(nCtx, t.NativeObject));
}
#endregion
#region Fixedpoints
///
/// Create a Fixedpoint context.
///
public Fixedpoint MkFixedpoint()
{
return new Fixedpoint(this);
}
#endregion
#region Optimization
///
/// Create an Optimization context.
///
public Optimize MkOptimize()
{
return new Optimize(this);
}
#endregion
#region Floating-Point Arithmetic
#region Rounding Modes
#region RoundingMode Sort
///
/// Create the floating-point RoundingMode sort.
///
public FPRMSort MkFPRoundingModeSort()
{
return new FPRMSort(this);
}
#endregion
#region Numerals
///
/// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode.
///
public FPRMExpr MkFPRoundNearestTiesToEven()
{
return new FPRMExpr(this, Native.Z3_mk_fpa_round_nearest_ties_to_even(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode.
///
public FPRMNum MkFPRNE()
{
return new FPRMNum(this, Native.Z3_mk_fpa_rne(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode.
///
public FPRMNum MkFPRoundNearestTiesToAway()
{
return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode.
///
public FPRMNum MkFPRNA()
{
return new FPRMNum(this, Native.Z3_mk_fpa_rna(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode.
///
public FPRMNum MkFPRoundTowardPositive()
{
return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_positive(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode.
///
public FPRMNum MkFPRTP()
{
return new FPRMNum(this, Native.Z3_mk_fpa_rtp(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode.
///
public FPRMNum MkFPRoundTowardNegative()
{
return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_negative(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode.
///
public FPRMNum MkFPRTN()
{
return new FPRMNum(this, Native.Z3_mk_fpa_rtn(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode.
///
public FPRMNum MkFPRoundTowardZero()
{
return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_zero(nCtx));
}
///
/// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode.
///
public FPRMNum MkFPRTZ()
{
return new FPRMNum(this, Native.Z3_mk_fpa_rtz(nCtx));
}
#endregion
#endregion
#region FloatingPoint Sorts
///
/// Create a FloatingPoint sort.
///
/// exponent bits in the FloatingPoint sort.
/// significand bits in the FloatingPoint sort.
public FPSort MkFPSort(uint ebits, uint sbits)
{
return new FPSort(this, ebits, sbits);
}
///
/// Create the half-precision (16-bit) FloatingPoint sort.
///
public FPSort MkFPSortHalf()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_half(nCtx));
}
///
/// Create the half-precision (16-bit) FloatingPoint sort.
///
public FPSort MkFPSort16()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_16(nCtx));
}
///
/// Create the single-precision (32-bit) FloatingPoint sort.
///
public FPSort MkFPSortSingle()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_single(nCtx));
}
///
/// Create the single-precision (32-bit) FloatingPoint sort.
///
public FPSort MkFPSort32()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_32(nCtx));
}
///
/// Create the double-precision (64-bit) FloatingPoint sort.
///
public FPSort MkFPSortDouble()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_double(nCtx));
}
///
/// Create the double-precision (64-bit) FloatingPoint sort.
///
public FPSort MkFPSort64()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_64(nCtx));
}
///
/// Create the quadruple-precision (128-bit) FloatingPoint sort.
///
public FPSort MkFPSortQuadruple()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_quadruple(nCtx));
}
///
/// Create the quadruple-precision (128-bit) FloatingPoint sort.
///
public FPSort MkFPSort128()
{
return new FPSort(this, Native.Z3_mk_fpa_sort_128(nCtx));
}
#endregion
#region Numerals
///
/// Create a NaN of sort s.
///
/// FloatingPoint sort.
public FPNum MkFPNaN(FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_nan(nCtx, s.NativeObject));
}
///
/// Create a floating-point infinity of sort s.
///
/// FloatingPoint sort.
/// indicates whether the result should be negative.
public FPNum MkFPInf(FPSort s, bool negative)
{
return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, (byte)(negative ? 1 : 0)));
}
///
/// Create a floating-point zero of sort s.
///
/// FloatingPoint sort.
/// indicates whether the result should be negative.
public FPNum MkFPZero(FPSort s, bool negative)
{
return new FPNum(this, Native.Z3_mk_fpa_zero(nCtx, s.NativeObject, (byte)(negative ? 1 : 0)));
}
///
/// Create a numeral of FloatingPoint sort from a float.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFPNumeral(float v, FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_numeral_float(nCtx, v, s.NativeObject));
}
///
/// Create a numeral of FloatingPoint sort from a float.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFPNumeral(double v, FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_numeral_double(nCtx, v, s.NativeObject));
}
///
/// Create a numeral of FloatingPoint sort from an int.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFPNumeral(int v, FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_numeral_int(nCtx, v, s.NativeObject));
}
///
/// Create a numeral of FloatingPoint sort from a sign bit and two integers.
///
/// the sign.
/// the significand.
/// the exponent.
/// FloatingPoint sort.
public FPNum MkFPNumeral(bool sgn, uint sig, int exp, FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_numeral_int_uint(nCtx, (byte)(sgn ? 1 : 0), exp, sig, s.NativeObject));
}
///
/// Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers.
///
/// the sign.
/// the significand.
/// the exponent.
/// FloatingPoint sort.
public FPNum MkFPNumeral(bool sgn, Int64 exp, UInt64 sig, FPSort s)
{
return new FPNum(this, Native.Z3_mk_fpa_numeral_int64_uint64(nCtx, (byte)(sgn ? 1 : 0), exp, sig, s.NativeObject));
}
///
/// Create a numeral of FloatingPoint sort from a float.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFP(float v, FPSort s)
{
return MkFPNumeral(v, s);
}
///
/// Create a numeral of FloatingPoint sort from a float.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFP(double v, FPSort s)
{
return MkFPNumeral(v, s);
}
///
/// Create a numeral of FloatingPoint sort from an int.
///
/// numeral value.
/// FloatingPoint sort.
public FPNum MkFP(int v, FPSort s)
{
return MkFPNumeral(v, s);
}
///
/// Create a numeral of FloatingPoint sort from a sign bit and two integers.
///
/// the sign.
/// the exponent.
/// the significand.
/// FloatingPoint sort.
public FPNum MkFP(bool sgn, int exp, uint sig, FPSort s)
{
return MkFPNumeral(sgn, exp, sig, s);
}
///
/// Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers.
///
/// the sign.
/// the exponent.
/// the significand.
/// FloatingPoint sort.
public FPNum MkFP(bool sgn, Int64 exp, UInt64 sig, FPSort s)
{
return MkFPNumeral(sgn, exp, sig, s);
}
#endregion
#region Operators
///
/// Floating-point absolute value
///
/// floating-point term
public FPExpr MkFPAbs(FPExpr t)
{
return new FPExpr(this, Native.Z3_mk_fpa_abs(this.nCtx, t.NativeObject));
}
///
/// Floating-point negation
///
/// floating-point term
public FPExpr MkFPNeg(FPExpr t)
{
return new FPExpr(this, Native.Z3_mk_fpa_neg(this.nCtx, t.NativeObject));
}
///
/// Floating-point addition
///
/// rounding mode term
/// floating-point term
/// floating-point term
public FPExpr MkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_add(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point subtraction
///
/// rounding mode term
/// floating-point term
/// floating-point term
public FPExpr MkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_sub(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point multiplication
///
/// rounding mode term
/// floating-point term
/// floating-point term
public FPExpr MkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_mul(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point division
///
/// rounding mode term
/// floating-point term
/// floating-point term
public FPExpr MkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_div(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point fused multiply-add
///
///
/// The result is round((t1 * t2) + t3)
///
/// rounding mode term
/// floating-point term
/// floating-point term
/// floating-point term
public FPExpr MkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3)
{
return new FPExpr(this, Native.Z3_mk_fpa_fma(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject, t3.NativeObject));
}
///
/// Floating-point square root
///
/// rounding mode term
/// floating-point term
public FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t)
{
return new FPExpr(this, Native.Z3_mk_fpa_sqrt(this.nCtx, rm.NativeObject, t.NativeObject));
}
///
/// Floating-point remainder
///
/// floating-point term
/// floating-point term
public FPExpr MkFPRem(FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_rem(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point roundToIntegral. Rounds a floating-point number to
/// the closest integer, again represented as a floating-point number.
///
/// term of RoundingMode sort
/// floating-point term
public FPExpr MkFPRoundToIntegral(FPRMExpr rm, FPExpr t)
{
return new FPExpr(this, Native.Z3_mk_fpa_round_to_integral(this.nCtx, rm.NativeObject, t.NativeObject));
}
///
/// Minimum of floating-point numbers.
///
/// floating-point term
/// floating-point term
public FPExpr MkFPMin(FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_min(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Maximum of floating-point numbers.
///
/// floating-point term
/// floating-point term
public FPExpr MkFPMax(FPExpr t1, FPExpr t2)
{
return new FPExpr(this, Native.Z3_mk_fpa_max(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point less than or equal.
///
/// floating-point term
/// floating-point term
public BoolExpr MkFPLEq(FPExpr t1, FPExpr t2)
{
return new BoolExpr(this, Native.Z3_mk_fpa_leq(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point less than.
///
/// floating-point term
/// floating-point term
public BoolExpr MkFPLt(FPExpr t1, FPExpr t2)
{
return new BoolExpr(this, Native.Z3_mk_fpa_lt(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point greater than or equal.
///
/// floating-point term
/// floating-point term
public BoolExpr MkFPGEq(FPExpr t1, FPExpr t2)
{
return new BoolExpr(this, Native.Z3_mk_fpa_geq(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point greater than.
///
/// floating-point term
/// floating-point term
public BoolExpr MkFPGt(FPExpr t1, FPExpr t2)
{
return new BoolExpr(this, Native.Z3_mk_fpa_gt(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Floating-point equality.
///
///
/// Note that this is IEEE 754 equality (as opposed to standard =).
///
/// floating-point term
/// floating-point term
public BoolExpr MkFPEq(FPExpr t1, FPExpr t2)
{
return new BoolExpr(this, Native.Z3_mk_fpa_eq(this.nCtx, t1.NativeObject, t2.NativeObject));
}
///
/// Predicate indicating whether t is a normal floating-point number.
///
/// floating-point term
public BoolExpr MkFPIsNormal(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_normal(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a subnormal floating-point number.
///
/// floating-point term
public BoolExpr MkFPIsSubnormal(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_subnormal(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a floating-point number with zero value, i.e., +0 or -0.
///
/// floating-point term
public BoolExpr MkFPIsZero(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_zero(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a floating-point number representing +oo or -oo.
///
/// floating-point term
public BoolExpr MkFPIsInfinite(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_infinite(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a NaN.
///
/// floating-point term
public BoolExpr MkFPIsNaN(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_nan(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a negative floating-point number.
///
/// floating-point term
public BoolExpr MkFPIsNegative(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_negative(this.nCtx, t.NativeObject));
}
///
/// Predicate indicating whether t is a positive floating-point number.
///
/// floating-point term
public BoolExpr MkFPIsPositive(FPExpr t)
{
return new BoolExpr(this, Native.Z3_mk_fpa_is_positive(this.nCtx, t.NativeObject));
}
#endregion
#region Conversions to FloatingPoint terms
///
/// Create an expression of FloatingPoint sort from three bit-vector expressions.
///
///
/// This is the operator named `fp' in the SMT FP theory definition.
/// Note that sgn is required to be a bit-vector of size 1. Significand and exponent
/// are required to be greater than 1 and 2 respectively. The FloatingPoint sort
/// of the resulting expression is automatically determined from the bit-vector sizes
/// of the arguments.
///
/// bit-vector term (of size 1) representing the sign.
/// bit-vector term representing the significand.
/// bit-vector term representing the exponent.
public FPExpr MkFP(BitVecExpr sgn, BitVecExpr sig, BitVecExpr exp)
{
return new FPExpr(this, Native.Z3_mk_fpa_fp(this.nCtx, sgn.NativeObject, sig.NativeObject, exp.NativeObject));
}
///
/// Conversion of a single IEEE 754-2008 bit-vector into a floating-point number.
///
///
/// Produces a term that represents the conversion of a bit-vector term bv to a
/// floating-point term of sort s. The bit-vector size of bv (m) must be equal
/// to ebits+sbits of s. The format of the bit-vector is as defined by the
/// IEEE 754-2008 interchange format.
///
/// bit-vector value (of size m).
/// FloatingPoint sort (ebits+sbits == m)
public FPExpr MkFPToFP(BitVecExpr bv, FPSort s)
{
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_bv(this.nCtx, bv.NativeObject, s.NativeObject));
}
///
/// Conversion of a FloatingPoint term into another term of different FloatingPoint sort.
///
///
/// Produces a term that represents the conversion of a floating-point term t to a
/// floating-point term of sort s. If necessary, the result will be rounded according
/// to rounding mode rm.
///
/// RoundingMode term.
/// FloatingPoint term.
/// FloatingPoint sort.
public FPExpr MkFPToFP(FPRMExpr rm, FPExpr t, FPSort s)
{
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
}
///
/// Conversion of a term of real sort into a term of FloatingPoint sort.
///
///
/// Produces a term that represents the conversion of term t of real sort into a
/// floating-point term of sort s. If necessary, the result will be rounded according
/// to rounding mode rm.
///
/// RoundingMode term.
/// term of Real sort.
/// FloatingPoint sort.
public FPExpr MkFPToFP(FPRMExpr rm, RealExpr t, FPSort s)
{
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_real(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
}
///
/// Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort.
///
///
/// Produces a term that represents the conversion of the bit-vector term t into a
/// floating-point term of sort s. The bit-vector t is taken to be in signed
/// 2's complement format (when signed==true, otherwise unsigned). If necessary, the
/// result will be rounded according to rounding mode rm.
///
/// RoundingMode term.
/// term of bit-vector sort.
/// FloatingPoint sort.
/// flag indicating whether t is interpreted as signed or unsigned bit-vector.
public FPExpr MkFPToFP(FPRMExpr rm, BitVecExpr t, FPSort s, bool signed)
{
if (signed)
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_signed(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
else
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_unsigned(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject));
}
///
/// Conversion of a floating-point number to another FloatingPoint sort s.
///
///
/// Produces a term that represents the conversion of a floating-point term t to a different
/// FloatingPoint sort s. If necessary, rounding according to rm is applied.
///
/// FloatingPoint sort
/// floating-point rounding mode term
/// floating-point term
public FPExpr MkFPToFP(FPSort s, FPRMExpr rm, FPExpr t)
{
return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject));
}
#endregion
#region Conversions from FloatingPoint terms
///
/// Conversion of a floating-point term into a bit-vector.
///
///
/// Produces a term that represents the conversion of the floating-point term t into a
/// bit-vector term of size sz in 2's complement format (signed when sign==true). If necessary,
/// the result will be rounded according to rounding mode rm.
///
/// RoundingMode term.
/// FloatingPoint term
/// Size of the resulting bit-vector.
/// Indicates whether the result is a signed or unsigned bit-vector.
public BitVecExpr MkFPToBV(FPRMExpr rm, FPExpr t, uint sz, bool sign)
{
if (sign)
return new BitVecExpr(this, Native.Z3_mk_fpa_to_sbv(this.nCtx, rm.NativeObject, t.NativeObject, sz));
else
return new BitVecExpr(this, Native.Z3_mk_fpa_to_ubv(this.nCtx, rm.NativeObject, t.NativeObject, sz));
}
///
/// Conversion of a floating-point term into a real-numbered term.
///
///
/// Produces a term that represents the conversion of the floating-point term t into a
/// real number. Note that this type of conversion will often result in non-linear
/// constraints over real terms.
///
/// FloatingPoint term
public RealExpr MkFPToReal(FPExpr t)
{
return new RealExpr(this, Native.Z3_mk_fpa_to_real(this.nCtx, t.NativeObject));
}
#endregion
#region Z3-specific extensions
///
/// Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format.
///
///
/// The size of the resulting bit-vector is automatically determined. Note that
/// IEEE 754-2008 allows multiple different representations of NaN. This conversion
/// knows only one NaN and it will always produce the same bit-vector representation of
/// that NaN.
///
/// FloatingPoint term.
public BitVecExpr MkFPToIEEEBV(FPExpr t)
{
return new BitVecExpr(this, Native.Z3_mk_fpa_to_ieee_bv(this.nCtx, t.NativeObject));
}
///
/// Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort.
///
///
/// Produces a term that represents the conversion of sig * 2^exp into a
/// floating-point term of sort s. If necessary, the result will be rounded
/// according to rounding mode rm.
///
/// RoundingMode term.
/// Exponent term of Int sort.
/// Significand term of Real sort.
/// FloatingPoint sort.
public BitVecExpr MkFPToFP(FPRMExpr rm, IntExpr exp, RealExpr sig, FPSort s)
{
return new BitVecExpr(this, Native.Z3_mk_fpa_to_fp_int_real(this.nCtx, rm.NativeObject, exp.NativeObject, sig.NativeObject, s.NativeObject));
}
#endregion
#endregion // Floating-point Arithmetic
#region Miscellaneous
///
/// Wraps an AST.
///
/// This function is used for transitions between native and
/// managed objects. Note that must be a
/// native object obtained from Z3 (e.g., through )
/// and that it must have a correct reference count (see e.g.,
/// .
///
/// The native pointer to wrap.
public AST WrapAST(IntPtr nativeObject)
{
return AST.Create(this, nativeObject);
}
///
/// Unwraps an AST.
///
/// This function is used for transitions between native and
/// managed objects. It returns the native pointer to the AST. Note that
/// AST objects are reference counted and unwrapping an AST disables automatic
/// reference counting, i.e., all references to the IntPtr that is returned
/// must be handled externally and through native calls (see e.g.,
/// ).
///
/// The AST to unwrap.
public IntPtr UnwrapAST(AST a)
{
return a.NativeObject;
}
///
/// Return a string describing all available parameters to Expr.Simplify.
///
public string SimplifyHelp()
{
return Native.Z3_simplify_get_help(nCtx);
}
///
/// Retrieves parameter descriptions for simplifier.
///
public ParamDescrs SimplifyParameterDescriptions
{
get { return new ParamDescrs(this, Native.Z3_simplify_get_param_descrs(nCtx)); }
}
#endregion
#region Error Handling
/////
///// A delegate which is executed when an error is raised.
/////
/////
///// Note that it is possible for memory leaks to occur if error handlers
///// throw exceptions.
/////
//public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString);
/////
///// The OnError event.
/////
//public event ErrorHandler OnError = null;
#endregion
#region Parameters
///
/// Update a mutable configuration parameter.
///
///
/// The list of all configuration parameters can be obtained using the Z3 executable:
/// z3.exe -p
/// Only a few configuration parameters are mutable once the context is created.
/// An exception is thrown when trying to modify an immutable parameter.
///
public void UpdateParamValue(string id, string value)
{
Native.Z3_update_param_value(nCtx, id, value);
}
#endregion
#region Internal
internal IntPtr m_ctx = IntPtr.Zero;
internal Native.Z3_error_handler m_n_err_handler = null;
internal static Object creation_lock = new Object();
internal IntPtr nCtx { get { return m_ctx; } }
internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode)
{
// Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors.
}
internal void InitContext()
{
PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT;
m_n_err_handler = new Native.Z3_error_handler(NativeErrorHandler); // keep reference so it doesn't get collected.
Native.Z3_set_error_handler(m_ctx, m_n_err_handler);
}
internal void CheckContextMatch(Z3Object other)
{
Debug.Assert(other != null);
if (!ReferenceEquals(this, other.Context))
throw new Z3Exception("Context mismatch");
}
internal void CheckContextMatch(Z3Object other1, Z3Object other2)
{
Debug.Assert(other1 != null);
Debug.Assert(other2 != null);
CheckContextMatch(other1);
CheckContextMatch(other2);
}
internal void CheckContextMatch(Z3Object other1, Z3Object other2, Z3Object other3)
{
Debug.Assert(other1 != null);
Debug.Assert(other2 != null);
Debug.Assert(other3 != null);
CheckContextMatch(other1);
CheckContextMatch(other2);
CheckContextMatch(other3);
}
internal void CheckContextMatch(Z3Object[] arr)
{
Debug.Assert(arr == null || arr.All(a => a != null));
if (arr != null)
{
foreach (Z3Object a in arr)
{
Debug.Assert(a != null); // It was an assume, now we added the precondition, and we made it into an assert
CheckContextMatch(a);
}
}
}
internal void CheckContextMatch(IEnumerable arr) where T : Z3Object
{
Debug.Assert(arr == null || arr.All(a => a != null));
if (arr != null)
{
foreach (Z3Object a in arr)
{
Debug.Assert(a != null); // It was an assume, now we added the precondition, and we made it into an assert
CheckContextMatch(a);
}
}
}
private void ObjectInvariant()
{
// none
}
///
/// Finalizer.
///
~Context()
{
// Console.WriteLine("Context Finalizer from " + System.Threading.Thread.CurrentThread.ManagedThreadId);
Dispose();
}
///
/// Disposes of the context.
///
public void Dispose()
{
// Console.WriteLine("Context Dispose from " + System.Threading.Thread.CurrentThread.ManagedThreadId);
if (m_boolSort != null) m_boolSort.Dispose();
if (m_intSort != null) m_intSort.Dispose();
if (m_realSort != null) m_realSort.Dispose();
if (m_stringSort != null) m_stringSort.Dispose();
if (m_charSort != null) m_charSort.Dispose();
m_boolSort = null;
m_intSort = null;
m_realSort = null;
m_stringSort = null;
m_charSort = null;
if (m_ctx != IntPtr.Zero)
{
IntPtr ctx = m_ctx;
lock (this)
{
m_n_err_handler = null;
m_ctx = IntPtr.Zero;
}
if (!is_external)
Native.Z3_del_context(ctx);
}
GC.SuppressFinalize(this);
}
#endregion
}
}