1
- """This module contains the Variable abstract class, as well as its concrete extensions: Input, Output and Meta. The
2
- function z3_types and the private function _coerce are also in this module."""
1
+ """This module contains the Variable abstract class, as well as its concrete extensions: Input, Output and Meta."""
3
2
4
3
from __future__ import annotations
5
4
from abc import ABC
6
5
from collections .abc import Callable
7
- from enum import Enum
8
6
from typing import Any , TypeVar
9
7
10
8
import lhsmdu
11
9
from pandas import DataFrame
12
10
from scipy .stats ._distn_infrastructure import rv_generic
13
- from z3 import Bool , BoolRef , Const , EnumSort , Int , RatNumRef , Real , String
14
11
15
12
# Declare type variable
16
13
T = TypeVar ("T" )
17
- z3 = TypeVar ("Z3" )
18
-
19
-
20
- def z3_types (datatype : T ) -> z3 :
21
- """Cast datatype to Z3 datatype
22
- :param datatype: python datatype to be cast
23
- :return: Type name compatible with Z3 library
24
- """
25
- types = {int : Int , str : String , float : Real , bool : Bool }
26
- if datatype in types :
27
- return types [datatype ]
28
- if issubclass (datatype , Enum ):
29
- dtype , _ = EnumSort (datatype .__name__ , [str (x .value ) for x in datatype ])
30
- return lambda x : Const (x , dtype )
31
- if hasattr (datatype , "to_z3" ):
32
- return datatype .to_z3 ()
33
- raise ValueError (
34
- f"Cannot convert type { datatype } to Z3."
35
- + " Please use a native type, an Enum, or implement a conversion manually."
36
- )
37
-
38
-
39
- def _coerce (val : Any ) -> Any :
40
- """Coerce Variables to their Z3 equivalents if appropriate to do so,
41
- otherwise assume literal constants.
42
-
43
- :param any val: A value, possibly a Variable.
44
- :return: Either a Z3 ExprRef representing the variable or the original value.
45
- :rtype: Any
46
-
47
- """
48
- if isinstance (val , Variable ):
49
- return val .z3
50
- return val
51
14
52
15
53
16
class Variable (ABC ):
@@ -56,7 +19,6 @@ class Variable(ABC):
56
19
:param str name: The name of the variable.
57
20
:param T datatype: The datatype of the variable.
58
21
:param rv_generic distribution: The expected distribution of the variable values.
59
- :attr type z3: The Z3 mirror of the variable.
60
22
:attr name:
61
23
:attr datatype:
62
24
:attr distribution:
@@ -70,125 +32,12 @@ class Variable(ABC):
70
32
def __init__ (self , name : str , datatype : T , distribution : rv_generic = None , hidden : bool = False ):
71
33
self .name = name
72
34
self .datatype = datatype
73
- self .z3 = z3_types (datatype )(name )
74
35
self .distribution = distribution
75
36
self .hidden = hidden
76
37
77
38
def __repr__ (self ):
78
39
return f"{ self .typestring ()} : { self .name } ::{ self .datatype .__name__ } "
79
40
80
- # Thin wrapper for Z1 functions
81
-
82
- def __add__ (self , other : Any ) -> BoolRef :
83
- """Create the Z3 expression `self + other`.
84
-
85
- :param any other: The object to compare against.
86
- :return: The Z3 expression `self + other`.
87
- :rtype: BoolRef
88
- """
89
- return self .z3 .__add__ (_coerce (other ))
90
-
91
- def __ge__ (self , other : Any ) -> BoolRef :
92
- """Create the Z3 expression `self >= other`.
93
-
94
- :param any other: The object to compare against.
95
- :return: The Z3 expression `self >= other`.
96
- :rtype: BoolRef
97
- """
98
- return self .z3 .__ge__ (_coerce (other ))
99
-
100
- def __gt__ (self , other : Any ) -> BoolRef :
101
- """Create the Z3 expression `self > other`.
102
-
103
- :param any other: The object to compare against.
104
- :return: The Z3 expression `self > other`.
105
- :rtype: BoolRef
106
- """
107
- return self .z3 .__gt__ (_coerce (other ))
108
-
109
- def __le__ (self , other : Any ) -> BoolRef :
110
- """Create the Z3 expression `self <= other`.
111
-
112
- :param any other: The object to compare against.
113
- :return: The Z3 expression `self <= other`.
114
- :rtype: BoolRef
115
- """
116
- return self .z3 .__le__ (_coerce (other ))
117
-
118
- def __lt__ (self , other : Any ) -> BoolRef :
119
- """Create the Z3 expression `self < other`.
120
-
121
- :param any other: The object to compare against.
122
- :return: The Z3 expression `self < other`.
123
- :rtype: BoolRef
124
- """
125
- return self .z3 .__lt__ (_coerce (other ))
126
-
127
- def __mod__ (self , other : Any ) -> BoolRef :
128
- """Create the Z3 expression `self % other`.
129
-
130
- :param any other: The object to compare against.
131
- :return: The Z3 expression `self % other`.
132
- :rtype: BoolRef
133
- """
134
- return self .z3 .__mod__ (_coerce (other ))
135
-
136
- def __mul__ (self , other : Any ) -> BoolRef :
137
- """Create the Z3 expression `self * other`.
138
-
139
- :param any other: The object to compare against.
140
- :return: The Z3 expression `self * other`.
141
- :rtype: BoolRef
142
- """
143
- return self .z3 .__mul__ (_coerce (other ))
144
-
145
- def __ne__ (self , other : Any ) -> BoolRef :
146
- """Create the Z3 expression `self != other`.
147
-
148
- :param any other: The object to compare against.
149
- :return: The Z3 expression `self != other`.
150
- :rtype: BoolRef
151
- """
152
- return self .z3 .__ne__ (_coerce (other ))
153
-
154
- def __neg__ (self ) -> BoolRef :
155
- """Create the Z3 expression `-self`.
156
-
157
- :param any other: The object to compare against.
158
- :return: The Z3 expression `-self`.
159
- :rtype: BoolRef
160
- """
161
- return self .z3 .__neg__ ()
162
-
163
- def __pow__ (self , other : Any ) -> BoolRef :
164
- """Create the Z3 expression `self ^ other`.
165
-
166
- :param any other: The object to compare against.
167
- :return: The Z3 expression `self ^ other`.
168
- :rtype: BoolRef
169
- """
170
- return self .z3 .__pow__ (_coerce (other ))
171
-
172
- def __sub__ (self , other : Any ) -> BoolRef :
173
- """Create the Z3 expression `self - other`.
174
-
175
- :param any other: The object to compare against.
176
- :return: The Z3 expression `self - other`.
177
- :rtype: BoolRef
178
- """
179
- return self .z3 .__sub__ (_coerce (other ))
180
-
181
- def __truediv__ (self , other : Any ) -> BoolRef :
182
- """Create the Z3 expression `self / other`.
183
-
184
- :param any other: The object to compare against.
185
- :return: The Z3 expression `self / other`.
186
- :rtype: BoolRef
187
- """
188
- return self .z3 .__truediv__ (_coerce (other ))
189
-
190
- # End thin wrapper
191
-
192
41
def cast (self , val : Any ) -> T :
193
42
"""Cast the supplied value to the datatype T of the variable.
194
43
@@ -209,16 +58,6 @@ def cast(self, val: Any) -> T:
209
58
return self .datatype (val )
210
59
return self .datatype (str (val ))
211
60
212
- def z3_val (self , z3_var , val : Any ) -> T :
213
- """Cast value to Z3 value"""
214
- native_val = self .cast (val )
215
- if isinstance (native_val , Enum ):
216
- values = [z3_var .sort ().constructor (c )() for c in range (z3_var .sort ().num_constructors ())]
217
- values = [v for v in values if val .__class__ (str (v )) == val ]
218
- assert len (values ) == 1 , f"Expected { values } to be length 1"
219
- return values [0 ]
220
- return native_val
221
-
222
61
def sample (self , n_samples : int ) -> [T ]:
223
62
"""Generate a Latin Hypercube Sample of size n_samples according to the
224
63
Variable's distribution.
0 commit comments