This repository has been archived by the owner on Jun 30, 2022. It is now read-only.
forked from mitchellh/go-z3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.go
127 lines (109 loc) · 3.51 KB
/
model.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package z3
// #include "go-z3.h"
/*
int _Z3_model_eval(Z3_context c, Z3_model m, Z3_ast t, int model_completion, Z3_ast * v) {
return Z3_model_eval(c, m, t, (bool) model_completion, v);
}
*/
import "C"
// Model represents a model from a solver.
//
// Memory management for this is manual and based on reference counting.
// When a model is initialized (via Solver.Model for example), it always has
// a reference count of 1. You must call Close when you're done.
type Model struct {
rawCtx C.Z3_context
rawModel C.Z3_model
}
// String returns a human-friendly string version of the model.
func (m *Model) String() string {
return C.GoString(C.Z3_model_to_string(m.rawCtx, m.rawModel))
}
//-------------------------------------------------------------------
// Assignments
//-------------------------------------------------------------------
// Eval evaluates the given AST within the model. This can be used to get
// the assignment of an AST. This will return nil if evaluation failed.
//
// For example:
//
// x := ctx.Const(ctx.Symbol("x"), ctx.IntSort())
// // ... further solving
// m.Eval(x) => x's value
//
// Maps: Z3_model_eval
func (m *Model) Eval(c *AST) *AST {
var result C.Z3_ast
if C._Z3_model_eval(m.rawCtx, m.rawModel, c.rawAST, 1, &result) == 0 {
return nil
}
return &AST{
rawCtx: m.rawCtx,
rawAST: result,
}
}
// Assignments returns a map of all the assignments for all the constants
// within the model. The key of the map will be the String value of the
// symbol.
//
// This doesn't map to any specific Z3 API. This is a higher-level function
// provided by go-z3 to make the Z3 API easier to consume in Go.
func (m *Model) Assignments() map[string]*AST {
result := make(map[string]*AST)
for i := uint(0); i < m.NumConsts(); i++ {
// Get the declaration
decl := m.ConstDecl(i)
// Get the name of it, i.e. "x"
name := decl.DeclName()
// Get the assignment for this
ast := C.Z3_model_get_const_interp(
m.rawCtx, m.rawModel, C.Z3_to_func_decl(decl.rawCtx, decl.rawAST))
// Map it
result[name.String()] = &AST{
rawCtx: m.rawCtx,
rawAST: ast,
}
}
return result
}
// NumConsts returns the number of constant assignments.
//
// Maps: Z3_model_get_num_consts
func (m *Model) NumConsts() uint {
return uint(C.Z3_model_get_num_consts(m.rawCtx, m.rawModel))
}
// ConstDecl returns the const declaration for the given index. idx must
// be less than NumConsts.
//
// Maps: Z3_model_get_const_decl
func (m *Model) ConstDecl(idx uint) *AST {
return &AST{
rawCtx: m.rawCtx,
rawAST: C.Z3_func_decl_to_ast(
m.rawCtx,
C.Z3_model_get_const_decl(m.rawCtx, m.rawModel, C.uint(idx))),
}
}
//-------------------------------------------------------------------
// Memory Management
//-------------------------------------------------------------------
// Close decreases the reference count for this model. If nothing else
// has manually increased the reference count, this will free the memory
// associated with it.
func (m *Model) Close() error {
C.Z3_model_dec_ref(m.rawCtx, m.rawModel)
return nil
}
// IncRef increases the reference count of this model. This is advanced,
// you probably don't need to use this.
func (m *Model) IncRef() {
C.Z3_model_inc_ref(m.rawCtx, m.rawModel)
}
// DecRef decreases the reference count of this model. This is advanced,
// you probably don't need to use this.
//
// Close will decrease it automatically from the initial 1, so this should
// only be called with exact matching calls to IncRef.
func (m *Model) DecRef() {
C.Z3_model_dec_ref(m.rawCtx, m.rawModel)
}