Z3
NativeModel.cs
Go to the documentation of this file.
1/*++
2Copyright (c) 2012 Microsoft Corporation
3
4Module Name:
5
6 NativeModel.cs
7
8Abstract:
9
10 Z3 Managed API: Models
11 Native interface to model objects.
12
13Author:
14
15 Christoph Wintersteiger (cwinter) 2012-03-21
16 Nikolaj Bjorner (nbjorner) 2022-03-01
17
18Notes:
19
20--*/
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Diagnostics;
26
27namespace Microsoft.Z3
28{
29 using Z3_ast = System.IntPtr;
30 using Z3_func_decl = System.IntPtr;
31 using Z3_sort = System.IntPtr;
32
36 public class NativeModel : IDisposable
37 {
38
44 public Z3_ast ConstInterp(Z3_ast a) => ConstFuncInterp(Native.Z3_get_app_decl(ntvContext.nCtx, a));
45
52 {
53 if (Native.Z3_get_arity(ntvContext.nCtx, f) != 0)
54 throw new Z3Exception("Non-zero arity functions have FunctionInterpretations as a model. Use FuncInterp.");
55
56 return Native.Z3_model_get_const_interp(ntvContext.nCtx, NativeObject, f);
57 }
58
65 {
66 Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(ntvContext.nCtx, Native.Z3_get_range(ntvContext.nCtx, f));
67
68 if (Native.Z3_get_arity(ntvContext.nCtx, f) == 0)
69 {
70 IntPtr n = Native.Z3_model_get_const_interp(ntvContext.nCtx, NativeObject, f);
71
72 if (sk == Z3_sort_kind.Z3_ARRAY_SORT)
73 {
74 if (n == IntPtr.Zero)
75 return null;
76 else
77 {
78 if (Native.Z3_is_as_array(ntvContext.nCtx, n) == 0)
79 throw new Z3Exception("Argument was not an array constant");
80 var fd = Native.Z3_get_as_array_func_decl(ntvContext.nCtx, n);
81 return new NativeFuncInterp(ntvContext, this, f, fd);
82 }
83 }
84 else
85 {
86 throw new Z3Exception("Constant functions do not have a function interpretation; use ConstInterp");
87 }
88 }
89 else
90 {
91 IntPtr n = Native.Z3_model_get_func_interp(ntvContext.nCtx, NativeObject, f);
92 if (n == IntPtr.Zero)
93 return null;
94 else
95 return new NativeFuncInterp(ntvContext, this, f, n);
96 }
97 }
98
99
100
104 public uint NumConsts
105 {
106 get { return Native.Z3_model_get_num_consts(ntvContext.nCtx, NativeObject); }
107 }
108
109
114 {
115 get
116 {
117
118 uint n = NumConsts;
119 Z3_func_decl[] res = new Z3_func_decl[n];
120 for (uint i = 0; i < n; i++)
121 res[i] = Native.Z3_model_get_const_decl(ntvContext.nCtx, NativeObject, i);
122 return res;
123 }
124 }
125
126
130 public IEnumerable<KeyValuePair<Z3_func_decl, Z3_ast>> Consts
131 {
132 get
133 {
134 uint nc = NumConsts;
135 for (uint i = 0; i < nc; ++i)
136 {
137 var f = Native.Z3_model_get_const_decl(ntvContext.nCtx, NativeObject, i);
138 IntPtr n = Native.Z3_model_get_const_interp(ntvContext.nCtx, NativeObject, f);
139 if (n == IntPtr.Zero) continue;
140 yield return new KeyValuePair<Z3_func_decl, Z3_ast>(f, n);
141 }
142 }
143 }
144
148 public uint NumFuncs
149 {
150 get { return Native.Z3_model_get_num_funcs(ntvContext.nCtx, NativeObject); }
151 }
152
157 {
158 get
159 {
160
161 uint n = NumFuncs;
162 Z3_func_decl[] res = new Z3_func_decl[n];
163 for (uint i = 0; i < n; i++)
164 res[i] = Native.Z3_model_get_func_decl(ntvContext.nCtx, NativeObject, i);
165 return res;
166 }
167 }
168
173 {
174 get
175 {
176
177 uint nFuncs = NumFuncs;
178 uint nConsts = NumConsts;
179 uint n = nFuncs + nConsts;
180 Z3_func_decl[] res = new Z3_func_decl[n];
181 for (uint i = 0; i < nConsts; i++)
182 res[i] = Native.Z3_model_get_const_decl(ntvContext.nCtx, NativeObject, i);
183 for (uint i = 0; i < nFuncs; i++)
184 res[nConsts + i] = Native.Z3_model_get_func_decl(ntvContext.nCtx, NativeObject, i);
185 return res;
186 }
187 }
188
193 {
197 public ModelEvaluationFailedException() : base() { }
198 }
199
214 public Z3_ast Eval(Z3_ast t, bool completion = false)
215 {
216
217 IntPtr v = IntPtr.Zero;
218 if (Native.Z3_model_eval(ntvContext.nCtx, NativeObject, t, (byte)(completion ? 1 : 0), ref v) == (byte)0)
220 else
221 return v;
222 }
223
227 public Z3_ast Evaluate(Z3_ast t, bool completion = false) => Eval(t, completion);
228
232 public double Double(Z3_ast t)
233 {
234 var r = Eval(t, true);
235 return Native.Z3_get_numeral_double(ntvContext.nCtx, r);
236 }
237
241 public class ArrayValue
242 {
246 public KeyValuePair<Z3_ast, Z3_ast>[] Updates;
247
251 public Z3_ast Else;
252
257 public Z3_ast[] Domain;
258
263 public Z3_ast[] Range;
264 }
265
272 public bool TryGetArrayValue(Z3_ast t, out ArrayValue result)
273 {
274 var r = Eval(t, true);
275 // check that r is a sequence of store over a constant default array.
276 var updates = new Dictionary<Z3_ast, Z3_ast>();
277 result = null;
278 while (true)
279 {
280 if (ntvContext.GetAstKind(r) != Z3_ast_kind.Z3_APP_AST)
281 return false;
282 Z3_func_decl f = ntvContext.GetAppDecl(r);
283 var kind = ntvContext.GetDeclKind(f);
284 if (kind == Z3_decl_kind.Z3_OP_CONST_ARRAY)
285 {
286 result = new ArrayValue();
287 result.Else = ntvContext.GetAppArg(r, 0);
288 result.Updates = updates.ToArray();
289 result.Domain = updates.Keys.ToArray();
290 result.Range = updates.Values.ToArray();
291 return true;
292 }
293 else if (kind == Z3_decl_kind.Z3_OP_STORE)
294 {
295 Debug.Assert(ntvContext.GetNumArgs(r) == 3);
296 updates[ntvContext.GetAppArg(r, 1)] = ntvContext.GetAppArg(r, 2);
297 r = ntvContext.GetAppArg(r, 0);
298 }
299 else
300 {
301 return false;
302 }
303 }
304 }
305
309 public uint NumSorts { get { return Native.Z3_model_get_num_sorts(ntvContext.nCtx, NativeObject); } }
310
311
321 public Z3_sort[] Sorts
322 {
323 get
324 {
325
326 uint n = NumSorts;
327 Z3_sort[] res = new Z3_sort[n];
328 for (uint i = 0; i < n; i++)
329 res[i] = Native.Z3_model_get_sort(ntvContext.nCtx, NativeObject, i);
330 return res;
331 }
332 }
333
334
339 public override string ToString()
340 {
341 return Native.Z3_model_to_string(ntvContext.nCtx, NativeObject);
342 }
343
344
345 IntPtr NativeObject;
346 NativeContext ntvContext;
347
348 internal NativeModel(NativeContext ctx, IntPtr obj)
349 {
350 ntvContext = ctx;
351 NativeObject = obj;
352 Debug.Assert(ctx != null);
353 Native.Z3_model_inc_ref(ctx.nCtx, obj);
354 }
355
356
360 ~NativeModel()
361 {
362 Dispose();
363 }
364
368 public void Dispose()
369 {
370 if (NativeObject != IntPtr.Zero)
371 {
372 Native.Z3_model_dec_ref(ntvContext.nCtx, NativeObject);
373 NativeObject = IntPtr.Zero;
374 }
375 GC.SuppressFinalize(this);
376 }
377
378
379 }
380}
381
382
383
The main interaction with Z3 happens via the Context. NativeContext allows for efficient wrapper-redu...
Z3_ast_kind GetAstKind(Z3_ast ast)
Get the AST kind from IntPtr
uint GetNumArgs(Z3_app app)
Return number of arguments for app
Z3_decl_kind GetDeclKind(Z3_func_decl decl)
Get the Decl kind from IntPtr
Z3_func_decl GetAppDecl(Z3_ast ast)
Get App Decl from IntPtr
A function interpretation is represented as a finite map and an 'else' value. Each entry in the finit...
An array value obtained by untangling a model assignment.
Definition: NativeModel.cs:242
Z3_ast[] Range
Range for array Updates.Values
Definition: NativeModel.cs:263
Z3_ast[] Domain
Domain for array Updates.Keys
Definition: NativeModel.cs:257
Z3_ast Else
default Else case
Definition: NativeModel.cs:251
KeyValuePair< Z3_ast, Z3_ast >[] Updates
One dimensional array of indices where the array is updated
Definition: NativeModel.cs:246
A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model.
Definition: NativeModel.cs:193
ModelEvaluationFailedException()
An exception that is thrown when model evaluation fails.
Definition: NativeModel.cs:197
A Model contains interpretations (assignments) of constants and functions.
Definition: NativeModel.cs:37
Z3_ast ConstInterp(Z3_ast a)
Retrieves the interpretation (the assignment) of a in the model.
bool TryGetArrayValue(Z3_ast t, out ArrayValue result)
Convert the interpretation of t into a sequence of array updates
Definition: NativeModel.cs:272
Z3_sort[] Sorts
The uninterpreted sorts that the model has an interpretation for.
Definition: NativeModel.cs:322
Z3_func_decl[] FuncDecls
The function declarations of the function interpretations in the model.
Definition: NativeModel.cs:157
double Double(Z3_ast t)
Evaluate expression to a double, assuming it is a numeral already.
Definition: NativeModel.cs:232
void Dispose()
Disposes of the underlying native Z3 object.
Definition: NativeModel.cs:368
IEnumerable< KeyValuePair< Z3_func_decl, Z3_ast > > Consts
Enumerate constants in model.
Definition: NativeModel.cs:131
NativeFuncInterp FuncInterp(Z3_func_decl f)
Retrieves the interpretation (the assignment) of a non-constant f in the model.
Definition: NativeModel.cs:64
Z3_ast Eval(Z3_ast t, bool completion=false)
Evaluates the expression t in the current model.
Definition: NativeModel.cs:214
Z3_func_decl[] Decls
All symbols that have an interpretation in the model.
Definition: NativeModel.cs:173
override string ToString()
Conversion of models to strings.
Definition: NativeModel.cs:339
Z3_ast Evaluate(Z3_ast t, bool completion=false)
Alias for Eval.
Z3_ast ConstFuncInterp(Z3_func_decl f)
Retrieves the interpretation (the assignment) of f in the model.
Definition: NativeModel.cs:51
Z3_func_decl[] ConstDecls
The function declarations of the constants in the model.
Definition: NativeModel.cs:114
uint NumFuncs
The number of function interpretations in the model.
Definition: NativeModel.cs:149
uint NumConsts
The number of constants that have an interpretation in the model.
Definition: NativeModel.cs:105
uint NumSorts
The number of uninterpreted sorts that the model has an interpretation for.
Definition: NativeModel.cs:309
The exception base class for error reporting from Z3
Definition: Z3Exception.cs:32
Z3_ast_kind
The different kinds of Z3 AST (abstract syntax trees). That is, terms, formulas and types.
Definition: z3_api.h:139
Z3_decl_kind
The different kinds of interpreted function kinds.
Definition: z3_api.h:961
Z3_sort_kind
The different kinds of Z3 types (See Z3_get_sort_kind).
Definition: z3_api.h:108
System.IntPtr Z3_func_decl
System.IntPtr Z3_ast
System.IntPtr Z3_sort