5
5
Test random lists.
6
6
'''
7
7
8
- from random import Random
8
+ from enum import auto , IntEnum
9
+ from typing import Any , Dict , List
9
10
10
11
from constrainedrandom import RandObj
11
12
from constrainedrandom .utils import unique
@@ -339,6 +340,26 @@ def not_7(x):
339
340
r .add_rand_var ('listvar' , bits = 5 , constraints = [not_7 ], rand_length = 'length' )
340
341
return r
341
342
343
+ def get_tmp_constraints (self ):
344
+ tmp_constrs = []
345
+ def not_6 (x ):
346
+ return x != 6
347
+ tmp_constrs .append ((not_6 , ('listvar' ,)))
348
+ tmp_constrs .append ((not_6 , ('length' ,)))
349
+ def mul_3 (x ):
350
+ return x % 3 == 0
351
+ tmp_constrs .append ((mul_3 , ('length' ,)))
352
+ return tmp_constrs
353
+
354
+ def tmp_check (self , results ):
355
+ self .check (results )
356
+ for result in results :
357
+ length = result ['length' ]
358
+ listvar = result ['listvar' ]
359
+ self .assertNotEqual (length , 6 , "Temp constraint not respected" )
360
+ self .assertNotEqual (listvar , 6 , "Temp constraint not respected" )
361
+ self .assertEqual (length % 3 , 0 , "Temp constraint not respected" )
362
+
342
363
def check (self , results ):
343
364
nonzero_seen = False
344
365
for result in results :
@@ -355,13 +376,22 @@ def check(self, results):
355
376
self .assertTrue (nonzero_seen , "All values were zero" )
356
377
357
378
379
+ class RandSizeListValue (RandSizeList ):
380
+ '''
381
+ Test a random sized list with temporary values.
382
+ '''
383
+
384
+ def get_tmp_values (self ):
385
+ return {'length' : 12 }
386
+
387
+
358
388
class RandSizeListConstrained (RandSizeList ):
359
389
'''
360
390
Test a randomized list, with a random size.
361
391
Add constriants between the length and another variable.
362
392
'''
363
393
364
- ITERATIONS = 1000
394
+ ITERATIONS = 500
365
395
366
396
def get_randobj (self , * args ):
367
397
r = super ().get_randobj (* args )
@@ -385,6 +415,12 @@ def check(self, results):
385
415
self .assertEqual (length % 2 , 1 , "Length was even, should be odd" )
386
416
387
417
418
+ class RandSizeListConstrainedValue (RandSizeListValue , RandSizeListConstrained ):
419
+ '''
420
+ Test a random sized list, with constraints, and with temporary values.
421
+ '''
422
+
423
+
388
424
class RandSizeListConstrainedMore (RandSizeListConstrained ):
389
425
'''
390
426
Test a randomized list, with a random size.
@@ -407,3 +443,234 @@ def check(self, results):
407
443
length = result ['length' ]
408
444
listvar = result ['listvar' ]
409
445
self .assertNotIn (length , listvar , "Length should not appear in list" )
446
+
447
+
448
+ class RandSizeListConstrainedMoreValue (RandSizeListValue , RandSizeListConstrained ):
449
+ '''
450
+ Test a randomized list, with a random size.
451
+ Add constriants between the length and other variables,
452
+ and the length and the list.
453
+ Test with temporary values.
454
+ '''
455
+
456
+
457
+ class RandSizeListConstrainedSparse (RandSizeListConstrained ):
458
+ '''
459
+ Test a constrained randomized list with a random length,
460
+ exercising the sparse solver.
461
+ '''
462
+
463
+ def get_randobj (self , * args ):
464
+ r = super ().get_randobj (* args )
465
+ r .set_solver_mode (naive = False , sparse = True , thorough = False )
466
+ return r
467
+
468
+
469
+ class RandSizeListConstrainedSparseValue (RandSizeListValue , RandSizeListConstrainedSparse ):
470
+ '''
471
+ Test a constrained randomized list with a random length,
472
+ exercising the sparse solver, with temporary values.
473
+ '''
474
+
475
+
476
+ class RandSizeListConstrainedMoreSparse (RandSizeListConstrainedMore ):
477
+ '''
478
+ Test a further constrained randomized list with a random length,
479
+ exercising the sparse solver.
480
+ '''
481
+
482
+ def get_randobj (self , * args ):
483
+ r = super ().get_randobj (* args )
484
+ r .set_solver_mode (naive = False , sparse = True , thorough = False )
485
+ return r
486
+
487
+
488
+ class RandSizeListConstrainedMoreSparseValue (RandSizeListValue , RandSizeListConstrainedMoreSparse ):
489
+ '''
490
+ Test a further constrained randomized list with a random length,
491
+ exercising the sparse solver, with temporary values.
492
+ '''
493
+
494
+
495
+ class RandSizeListConstrainedThorough (RandSizeListConstrained ):
496
+ '''
497
+ Test a constrained randomized list with a random length,
498
+ exercising the thorough solver.
499
+ '''
500
+
501
+ ITERATIONS = 5
502
+
503
+ def get_randobj (self , * args ):
504
+ r = super ().get_randobj (* args )
505
+ r .set_solver_mode (naive = False , sparse = False , thorough = True )
506
+ return r
507
+
508
+
509
+ class RandSizeListConstrainedThoroughValue (RandSizeListValue , RandSizeListConstrainedThorough ):
510
+ '''
511
+ Test a constrained randomized list with a random length,
512
+ exercising the thorough solver, with temporary values.
513
+ '''
514
+
515
+
516
+ class RandSizeListConstrainedMoreThorough (RandSizeListConstrainedMore ):
517
+ '''
518
+ Test a constrained randomized list with a random length,
519
+ exercising the thorough solver.
520
+ '''
521
+
522
+ ITERATIONS = 2
523
+
524
+ def get_randobj (self , * args ):
525
+ r = super ().get_randobj (* args )
526
+ r .set_solver_mode (naive = False , sparse = False , thorough = True )
527
+ return r
528
+
529
+
530
+ class RandSizeListConstrainedMoreThoroughValue (RandSizeListValue , RandSizeListConstrainedMoreThorough ):
531
+ '''
532
+ Test a constrained randomized list with a random length,
533
+ exercising the thorough solver.
534
+ '''
535
+
536
+
537
+ class RandSizeListHard (testutils .RandObjTestBase ):
538
+ '''
539
+ Test a much more difficult problem with randomized-length lists.
540
+ '''
541
+
542
+ ITERATIONS = 100
543
+
544
+ class RegEnum (IntEnum ):
545
+
546
+ REG0 = 0
547
+ REG1 = auto ()
548
+ REG2 = auto ()
549
+ REG3 = auto ()
550
+ REG4 = auto ()
551
+ REG5 = auto ()
552
+ REG6 = auto ()
553
+ REG7 = auto ()
554
+
555
+ def get_randobj (self , * args ):
556
+ r = RandObj (* args )
557
+ r .add_rand_var ('shared_length' , domain = range (8 ))
558
+ def not_reg0 (x ):
559
+ return x != self .RegEnum .REG0
560
+ r .add_rand_var (
561
+ 'list1' ,
562
+ domain = self .RegEnum ,
563
+ rand_length = 'shared_length' ,
564
+ constraints = [not_reg0 ],
565
+ list_constraints = [unique ],
566
+ )
567
+ r .add_rand_var ('list2' , domain = range (32 ), rand_length = 'shared_length' )
568
+ def lists_dont_intersect (list1 , list2 ):
569
+ for x in list1 :
570
+ if x in list2 :
571
+ return False
572
+ return True
573
+ r .add_constraint (lists_dont_intersect , ('list1' , 'list2' ))
574
+ return r
575
+
576
+ def get_tmp_constraints (self ):
577
+ return super ().get_tmp_constraints ()
578
+
579
+ def check (self , results ):
580
+ for idx , result in enumerate (results ):
581
+ list1 = result ['list1' ]
582
+ list2 = result ['list2' ]
583
+ shared_length = result ['shared_length' ]
584
+ self .assertIn (shared_length , range (8 ))
585
+ self .assertEqual (len (list1 ), shared_length , f"{ idx } List length was wrong" )
586
+ self .assertEqual (len (list2 ), shared_length , "List length was wrong" )
587
+ for idx , item in enumerate (list1 ):
588
+ self .assertIn (item , self .RegEnum )
589
+ other_elems = list1 [0 :idx ] + list1 [idx + 1 :]
590
+ self .assertNotIn (item , other_elems , "List had repeated elements" )
591
+ for item in list2 :
592
+ self .assertNotIn (item , list1 , "Lists were not disjoint" )
593
+
594
+
595
+ class RandSizeListVeryHard (RandSizeListHard ):
596
+ '''
597
+ Test an extremely difficult problem with randomized-length lists.
598
+ '''
599
+
600
+ ITERATIONS = 2
601
+
602
+ def get_randobj (self , * args ):
603
+ r = super ().get_randobj (* args )
604
+ def double_length (length , length2 ):
605
+ return length2 == length * 2
606
+ r .add_rand_var ('other_length' , domain = range (16 ))
607
+ r .add_constraint (double_length , ('shared_length' , 'other_length' ))
608
+ r .add_rand_var ('list3' , domain = range (32 ), rand_length = 'other_length' , order = 2 )
609
+ def composed_from_others (list1 , list2 , list3 ):
610
+ for x in list3 :
611
+ if x not in list1 and x not in list2 :
612
+ return False
613
+ return True
614
+ r .add_constraint (composed_from_others , ('list1' , 'list2' , 'list3' ))
615
+ return r
616
+
617
+ def check (self , results ):
618
+ super ().check (results )
619
+ for result in results :
620
+ list1 = result ['list1' ]
621
+ list2 = result ['list2' ]
622
+ list3 = result ['list3' ]
623
+ shared_length = result ['shared_length' ]
624
+ other_length = result ['other_length' ]
625
+ self .assertEqual (len (list3 ), shared_length * 2 , "List length was wrong" )
626
+ self .assertEqual (other_length , shared_length * 2 , "List length was wrong" )
627
+ for item in list3 :
628
+ self .assertIn (item , list1 + list2 , "Item was not in other lists" )
629
+
630
+
631
+ class RandSizeListShort (testutils .RandObjTestBase ):
632
+ '''
633
+ Test random lists and lengths with small domains, to
634
+ use CSP.
635
+ '''
636
+
637
+ def get_randobj (self , * args ):
638
+ r = RandObj (* args )
639
+ r .add_rand_var ('length1' , domain = range (1 , 4 ))
640
+ r .add_rand_var ('list1' , domain = range (1 , 4 ), rand_length = 'length1' )
641
+ def in_list (x , y ):
642
+ return x in y
643
+ r .add_rand_var ('length2' , domain = range (1 , 4 ))
644
+ r .add_constraint (in_list , ('length2' , 'list1' ))
645
+ r .add_rand_var ('list2' , domain = range (1 , 4 ), rand_length = 'length2' )
646
+ return r
647
+
648
+ def check (self , results ):
649
+ for result in results :
650
+ length1 = result ['length1' ]
651
+ list1 = result ['list1' ]
652
+ length2 = result ['length2' ]
653
+ list2 = result ['list2' ]
654
+ self .assertEqual (len (list1 ), length1 , "List length was wrong" )
655
+ self .assertIn (length2 , list1 , "Length 2 must be in list 1" )
656
+ self .assertEqual (len (list2 ), length2 , "List length was wrong" )
657
+
658
+
659
+ class RandSizeListShortSparse (RandSizeListShort ):
660
+
661
+ ITERATIONS = 200
662
+
663
+ def get_randobj (self , * args ):
664
+ r = super ().get_randobj (* args )
665
+ r .set_solver_mode (naive = False , sparse = True , thorough = False )
666
+ return r
667
+
668
+
669
+ class RandSizeListShortThorough (RandSizeListShort ):
670
+
671
+ ITERATIONS = 50
672
+
673
+ def get_randobj (self , * args ):
674
+ r = super ().get_randobj (* args )
675
+ r .set_solver_mode (naive = False , sparse = False , thorough = True )
676
+ return r
0 commit comments