-
Notifications
You must be signed in to change notification settings - Fork 90
/
bool_result.py
201 lines (151 loc) · 4.89 KB
/
bool_result.py
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
from ..backend_object import BackendObject
class BoolResult(BackendObject):
def __init__(self, op=None, args=None):
self._op = op
self._args = args
def value(self):
raise NotImplementedError()
def __len__(self):
return BackendError()
def __eq__(self, other):
raise NotImplementedError()
def __and__(self, other):
raise NotImplementedError()
def __invert__(self):
raise NotImplementedError()
def __or__(self, other):
raise NotImplementedError()
def identical(self, other):
if self.value != other.value:
return False
if self._op != other._op:
return False
if self._args != other._args:
return False
return True
def union(self, other):
raise NotImplementedError()
def size(self): #pylint:disable=no-self-use
return None
@staticmethod
def is_maybe(o):
if isinstance(o, Base):
raise ClaripyValueError("BoolResult can't handle AST objects directly")
return isinstance(o, MaybeResult)
@staticmethod
def has_true(o):
if isinstance(o, Base):
raise ClaripyValueError("BoolResult can't handle AST objects directly")
return o is True or (isinstance(o, BoolResult) and True in o.value)
@staticmethod
def has_false(o):
if isinstance(o, Base):
raise ClaripyValueError("BoolResult can't handle AST objects directly")
return o is False or (isinstance(o, BoolResult) and False in o.value)
@staticmethod
def is_true(o):
if isinstance(o, Base):
raise ClaripyValueError("BoolResult can't handle AST objects directly")
return o is True or (isinstance(o, TrueResult))
@staticmethod
def is_false(o):
if isinstance(o, Base):
raise ClaripyValueError("BoolResult can't handle AST objects directly")
return o is False or (isinstance(o, FalseResult))
class TrueResult(BoolResult):
cardinality = 1
@property
def value(self):
return (True, )
def identical(self, other):
return isinstance(other, TrueResult)
def __eq__(self, other):
if isinstance(other, FalseResult):
return FalseResult()
elif isinstance(other, TrueResult):
return TrueResult()
else:
return MaybeResult()
def __invert__(self):
return FalseResult()
def __or__(self, other):
return TrueResult()
def __and__(self, other):
if BoolResult.is_maybe(other):
return MaybeResult()
elif BoolResult.is_false(other):
return FalseResult()
else:
return TrueResult()
def union(self, other):
if other is True or type(other) is TrueResult:
return TrueResult()
elif other is False or type(other) is FalseResult:
return MaybeResult()
elif type(other) is MaybeResult:
return MaybeResult()
else:
return NotImplemented
def __repr__(self):
return '<True>'
class FalseResult(BoolResult):
cardinality = 1
@property
def value(self):
return (False, )
def identical(self, other):
return isinstance(other, FalseResult)
def __eq__(self, other):
if isinstance(other, FalseResult):
return TrueResult()
elif isinstance(other, TrueResult):
return FalseResult()
else:
return MaybeResult()
def __invert__(self):
return TrueResult()
def __and__(self, other):
return FalseResult()
def __or__(self, other):
return other
def __repr__(self):
return '<False>'
def union(self, other):
if other is True or type(other) is TrueResult:
return MaybeResult()
elif other is False or type(other) is FalseResult:
return FalseResult()
elif type(other) is MaybeResult:
return MaybeResult()
else:
return NotImplemented
class MaybeResult(BoolResult):
cardinality = 2
@property
def value(self):
return (True, False)
def identical(self, other):
return isinstance(other, MaybeResult)
def __eq__(self, other):
return MaybeResult()
def __invert__(self):
return MaybeResult()
def __and__(self, other):
if BoolResult.is_false(other):
return FalseResult()
else:
return MaybeResult()
def union(self, other):
return MaybeResult()
def __or__(self, other):
if BoolResult.is_true(other):
return TrueResult()
else:
return self
def __repr__(self):
if self._op is None:
return '<Maybe>'
else:
return '<Maybe(%s, %s)>' % (self._op, self._args)
from ..errors import BackendError, ClaripyValueError
from ..ast.base import Base