-
Notifications
You must be signed in to change notification settings - Fork 0
/
MinTermSet.mojo
134 lines (112 loc) · 4.38 KB
/
MinTermSet.mojo
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
from bit import pop_count
from tools import get_bit, get_dk_mask
from to_string import PrintType, minterms_to_string, minterm_to_string
from MySet import MySet
struct MinTermSet[T: DType, N_BITS: Int](CollectionElement, Sized, Stringable):
alias Q = List[Scalar[T]]
alias n_sets = N_BITS + 1
var n_elements: Int
var max_bit_count: Int
var is_sorted: Bool
var data: List[Self.Q]
fn __init__(inout self):
self.n_elements = 0
self.max_bit_count = 0
self.is_sorted = True
self.data = List[Self.Q](capacity=Self.n_sets)
for i in range(Self.n_sets):
self.data.append(Self.Q())
fn __eq__(self, other: Self) -> Bool:
if not (self.is_sorted) or not (other.is_sorted):
print(
"WARNING performance: MinTermSet: __eq__: self or other is not"
" sorted!"
)
# return False
if len(self) != len(other):
# print("MinTermSet eq: returns False (A)")
return False
for i in range(Self.n_sets):
if self.data[i].size != other.data[i].size:
# print("MinTermSet eq: returns False (B)" + str(i))
return False
for i in range(Self.n_sets):
if not (Self.equal(self.data[i], other.data[i])):
# print("MinTermSet eq: returns False (C)" + str(i))
return False
# print("MinTermSet eq: returns True (D)")
return True
fn __ne__(self, other: Self) -> Bool:
return not (self == other)
@staticmethod
fn equal(v1: Self.Q, v2: Self.Q) -> Bool:
for i in range(v1.size):
if v1[i] != v2[i]:
return False
return True
# trait Sized
fn __len__(self) -> Int:
return self.n_elements
# trait Copyable
fn __copyinit__(inout self, existing: Self):
self.n_elements = existing.n_elements
self.max_bit_count = existing.max_bit_count
self.is_sorted = existing.is_sorted
self.data = existing.data
# trait Movable
fn __moveinit__(inout self, owned existing: Self):
self.n_elements = existing.n_elements
self.max_bit_count = existing.max_bit_count
self.is_sorted = existing.is_sorted
self.data = existing.data^
# trait Stringable
fn __str__(self) -> String:
return self.to_string[PrintType.VERBOSE](N_BITS)
fn to_string[P: PrintType](self, number_vars: Int) -> String:
var result: String = ""
for i in range(Self.n_sets):
result += minterms_to_string[T, P](self.data[i], number_vars)
return result
fn sort(inout self):
if self.is_sorted:
return
for i in range(Self.n_sets):
sort[T](self.data[i])
self.is_sorted = True
fn add[
CHECK_CONTAINS: Bool = True, SHOW_INFO: Bool = False
](inout self, value: Scalar[T]):
alias dk_mask: Scalar[T] = get_dk_mask[T]()
var n_bits_set = int(pop_count(value & dk_mask))
# @parameter
# if SHOW_INFO:
# print("INFO: 7bd7968f: adding value: check_duplicate=" +str(check_duplicate) +"; value=" + minterm_to_string[T, PrintType.VERBOSE](value, bit_width) + "; n_bits_set="+str(n_bits_set))
self.n_elements += 1
if self.max_bit_count < n_bits_set:
self.max_bit_count = n_bits_set
# @parameter
# if SHOW_INFO:
# print("INFO: currently present: n_bits_set=" + str(n_bits_set) + "; size=" + str(self.data[n_bits_set].size))
@parameter
if CHECK_CONTAINS:
var already_present = False
for i in range(self.data[n_bits_set].size):
if self.data[n_bits_set][i] == value:
already_present = True
break
if not already_present:
self.data[n_bits_set].append(value)
self.is_sorted = False
else:
self.data[n_bits_set].append(value)
self.is_sorted = False
fn get(self, n_bits_set: Int) -> Self.Q:
debug_assert(n_bits_set < Self.n_sets, "invalid idx")
return self.data[n_bits_set]
fn to_set(self) -> MySet[T]:
var result = MySet[T]()
for i in range(Self.n_sets):
var x = self.data[i]
for j in range(len(x)):
result.add[CHECK_CONTAINS=False](x[j])
return result^