@@ -236,6 +236,12 @@ def representative():
236
236
assert BV_Dont_Care_Grouping .representatives .is_consistent ()
237
237
return BV_Dont_Care_Grouping .representatives
238
238
239
+ def downsample (self ):
240
+ if self .is_downsample_cached ():
241
+ return self .get_cached_downsample ()
242
+
243
+ return BV_No_Distinction_Proto .downsample (self )
244
+
239
245
def pair_product (self , g2 , inorder = True ):
240
246
assert isinstance (g2 , BV_Grouping )
241
247
@@ -311,8 +317,8 @@ class BV_Fork_Grouping(BV_Grouping):
311
317
312
318
def __init__ (self , level , swap_level , fork_level , number_of_exits , bvdd ):
313
319
super ().__init__ (level , number_of_exits )
314
- assert 0 <= swap_level <= level
315
- assert 0 <= fork_level <= level
320
+ assert 0 <= swap_level
321
+ assert 0 <= fork_level
316
322
self .swap_level = swap_level
317
323
self .fork_level = fork_level
318
324
self .bvdd = bvdd
@@ -364,11 +370,10 @@ def representative(self):
364
370
BV_Fork_Grouping .representatives [self ] = self
365
371
return BV_Fork_Grouping .representatives [self ]
366
372
367
- def projection_proto (level , input_i ):
368
- # TODO: assert level == 0 and input_i == 0
369
- assert 0 <= input_i < 2 ** level
370
- bvdd = BVDD .BVDD .projection_proto (input_i )
371
- return BV_Fork_Grouping (level , level , level ,
373
+ def projection_proto (level , swap_level , fork_level ):
374
+ assert level == 0
375
+ bvdd = BVDD .BVDD .projection_proto (0 )
376
+ return BV_Fork_Grouping (level , swap_level , fork_level ,
372
377
bvdd .number_of_exits (), bvdd ).representative ()
373
378
374
379
def upsample (self ):
@@ -377,14 +382,18 @@ def upsample(self):
377
382
if self .is_upsample_cached ():
378
383
return self .get_cached_upsample ()
379
384
380
- g_a_bvdd , g_b_bvdds , g_b_return_tuples , _ = self .bvdd .upsample (2 ** ( self .level - 1 ) - 1 )
385
+ g_a_bvdd , _ , g_b_bvdds , g_b_return_tuples = self .bvdd .upsample (self .level )
381
386
382
387
# TODO: enable different input orderings
383
388
g = BV_Internal_Grouping (self .level , self .swap_level , self .fork_level , True ,
384
389
len (g_b_return_tuples ))
385
390
386
- g .a_connection = BV_Fork_Grouping (self .level - 1 , self .swap_level , self .fork_level ,
387
- g_a_bvdd .number_of_exits (), g_a_bvdd ).representative ()
391
+ if g_a_bvdd .is_constant ():
392
+ g .a_connection = BV_No_Distinction_Proto .representative (self .level - 1 ,
393
+ self .swap_level , self .fork_level )
394
+ else :
395
+ g .a_connection = BV_Fork_Grouping (self .level - 1 , self .swap_level , self .fork_level ,
396
+ g_a_bvdd .number_of_exits (), g_a_bvdd ).representative ()
388
397
389
398
assert g .a_connection .number_of_exits == len (g_b_bvdds )
390
399
@@ -393,15 +402,28 @@ def upsample(self):
393
402
g .b_connections = {}
394
403
395
404
for g_b_i in g_b_bvdds :
396
- g_b = BV_Fork_Grouping (self .level - 1 , self .swap_level , self .fork_level ,
397
- g_b_bvdds [g_b_i ].number_of_exits (), g_b_bvdds [g_b_i ]).representative ()
405
+ if g_b_bvdds [g_b_i ].is_constant ():
406
+ g_b = BV_No_Distinction_Proto .representative (self .level - 1 ,
407
+ self .swap_level , self .fork_level )
408
+ else :
409
+ g_b = BV_Fork_Grouping (self .level - 1 , self .swap_level , self .fork_level ,
410
+ g_b_bvdds [g_b_i ].number_of_exits (), g_b_bvdds [g_b_i ]).representative ()
398
411
g .b_connections [g_b_i ] = g_b
399
412
400
413
assert g_b .number_of_exits == len (g_b_return_tuples [g_b_i ])
401
414
402
415
g .b_return_tuples = g_b_return_tuples
403
416
404
- return self .cache_upsample (g .representative ())
417
+ if g .a_connection .is_no_distinction_proto ():
418
+ print (self )
419
+
420
+ if (g .a_connection .is_no_distinction_proto () and
421
+ g .number_of_b_connections == 1 and
422
+ g .b_connections [1 ].is_no_distinction_proto ()):
423
+ return self .cache_upsample (BV_No_Distinction_Proto .representative (self .level ,
424
+ self .swap_level , self .fork_level ))
425
+ else :
426
+ return self .cache_upsample (g .representative ())
405
427
406
428
def downsample (self ):
407
429
assert self .level <= self .fork_level
@@ -502,7 +524,8 @@ def reduce(self, reduction_tuple):
502
524
assert self .level == self .fork_level
503
525
504
526
if bvdd .is_constant ():
505
- g = No_Distinction_Proto .representative (self .level , self .swap_level , self .fork_level )
527
+ g = No_Distinction_Proto .representative (self .level ,
528
+ self .swap_level , self .fork_level )
506
529
else :
507
530
g = BV_Fork_Grouping (self .level , self .swap_level , self .fork_level ,
508
531
reduction_length , bvdd ).representative ()
@@ -540,7 +563,8 @@ class BV_Internal_Grouping(BV_Grouping):
540
563
def __init__ (self , level , swap_level , fork_level , a2b , number_of_exits = 0 ):
541
564
assert level > 0
542
565
super ().__init__ (level , number_of_exits )
543
- assert 0 <= fork_level <= swap_level <= level
566
+ assert 0 <= swap_level
567
+ assert 0 <= fork_level
544
568
self .swap_level = swap_level
545
569
self .fork_level = fork_level
546
570
self .a2b = a2b
@@ -668,8 +692,8 @@ def representative(self):
668
692
def projection_proto (level , swap_level , fork_level , input_i ):
669
693
# generalizing CFLOBDD projection to generational CFLOBVDD projection
670
694
assert 0 <= input_i < 2 ** level
671
- if level == fork_level :
672
- return BV_Fork_Grouping .projection_proto (level , input_i )
695
+ if level == 0 :
696
+ return BV_Fork_Grouping .projection_proto (level , swap_level , fork_level )
673
697
else :
674
698
g = BV_Internal_Grouping (level , swap_level , fork_level , True )
675
699
@@ -836,10 +860,8 @@ def pair_product(self, g2):
836
860
837
861
if g1 .level <= g1 .fork_level :
838
862
# g1 and g2 are downsampled in original order (decompressing)
839
- pass
840
- # TODO:
841
- #g, pt_ans = g1.downsample().pair_product(g2.downsample())
842
- #return g1_orig.cache_pair_product(g2_orig, g, pt_ans)
863
+ g , pt_ans = g1 .downsample ().pair_product (g2 .downsample ())
864
+ return g1_orig .cache_pair_product (g2_orig , g , pt_ans )
843
865
844
866
g = BV_Internal_Grouping (g1 .level , g1 .swap_level , g1 .fork_level , g1 .a2b )
845
867
@@ -957,10 +979,8 @@ def triple_product(self, g2, g3):
957
979
958
980
if g1 .level <= g1 .fork_level :
959
981
# g1, g2, g3 are downsampled in original order (decompressing)
960
- pass
961
- # TODO:
962
- #g, tt_ans = g1.downsample().triple_product(g2.downsample(), g3.downsample())
963
- #return g1_orig.cache_triple_product(g2_orig, g3_orig, g, tt_ans)
982
+ g , tt_ans = g1 .downsample ().triple_product (g2 .downsample (), g3 .downsample ())
983
+ return g1_orig .cache_triple_product (g2_orig , g3_orig , g , tt_ans )
964
984
965
985
g = BV_Internal_Grouping (g1 .level , g1 .swap_level , g1 .fork_level , g1 .a2b )
966
986
@@ -1099,7 +1119,8 @@ class BV_No_Distinction_Proto(BV_Internal_Grouping):
1099
1119
1100
1120
def __init__ (self , level , swap_level , fork_level ):
1101
1121
assert level > 0
1102
- assert 0 <= fork_level <= swap_level <= level
1122
+ assert 0 <= swap_level
1123
+ assert 0 <= fork_level
1103
1124
super ().__init__ (level , swap_level , fork_level , True , 1 )
1104
1125
1105
1126
def representative (level , swap_level , fork_level ):
@@ -1130,6 +1151,16 @@ def swap(self):
1130
1151
assert self .level > self .swap_level
1131
1152
return self
1132
1153
1154
+ def downsample (self ):
1155
+ assert self .level <= self .fork_level
1156
+
1157
+ if self .is_downsample_cached ():
1158
+ return self .get_cached_downsample ()
1159
+
1160
+ return self .cache_downsample (BV_Fork_Grouping (self .level ,
1161
+ self .swap_level , self .fork_level ,
1162
+ 1 , BVDD .BVDD .constant (1 )).representative ())
1163
+
1133
1164
def pair_product (self , g2 , inorder = True ):
1134
1165
assert isinstance (g2 , BV_Grouping )
1135
1166
@@ -1320,6 +1351,8 @@ def is_always_true(self):
1320
1351
return self .number_of_distinct_outputs () == 1 and True in self .outputs .values ()
1321
1352
1322
1353
def constant (level , swap_level , fork_level , output = 0 ):
1354
+ assert 0 <= swap_level <= level
1355
+ assert 0 <= fork_level <= level
1323
1356
with CFLOBVDD .max_level_lock :
1324
1357
CFLOBVDD .max_level = max (CFLOBVDD .max_level , level )
1325
1358
return CFLOBVDD .representative (
@@ -1358,7 +1391,8 @@ def unary_apply_and_reduce(self, op, number_of_output_bits):
1358
1391
number_of_output_bits )
1359
1392
1360
1393
def projection (level , swap_level , fork_level , input_i , reorder = False ):
1361
- assert 0 <= fork_level <= swap_level <= level
1394
+ assert 0 <= swap_level <= level
1395
+ assert 0 <= fork_level <= level
1362
1396
assert 0 <= input_i < 2 ** level
1363
1397
with CFLOBVDD .max_level_lock :
1364
1398
CFLOBVDD .max_level = max (CFLOBVDD .max_level , level )
0 commit comments