@@ -68,10 +68,15 @@ def signed_masking(n: int, mask: int = MAXI) -> int:
6868
6969
7070def comp_by_enum (grammars : list , tr : str , max_size : int ):
71- enums : list [Enumerator ] = []
71+ """
72+ args = [g1, g2]
73+ check g1 == g2 (exactly in this order)
74+ """
75+ enums : list [tuple [Enumerator , Evaluator ]] = []
7276 for g in grammars :
77+ evaluator = Evaluator (dsl , inputs , {}, set ())
7378 e = Enumerator (g )
74- gen = e .enumerate_until_size (max_size )
79+ gen = e .enumerate_until_size (max_size + 1 )
7580 p = next (gen )
7681 evaluator .eval (p , tr )
7782 should_keep = True
@@ -81,13 +86,31 @@ def comp_by_enum(grammars: list, tr: str, max_size: int):
8186 should_keep = evaluator .eval (p , tr ) is None
8287 except StopIteration :
8388 pass
84- enums .append (e )
85- std = enums .pop ()
86- for other in enums :
87- for size in range (max_size ):
88- assert other .count_programs_at_size (size ) == std .count_programs_at_size (
89- size
90- )
89+ enums .append ((e , evaluator ))
90+
91+ std , evalstd = enums .pop ()
92+ for other , evalother in enums :
93+ for size in range (max_size + 1 ):
94+ a = other .count_programs_at_size (size )
95+ b = std .count_programs_at_size (size )
96+ if a != b :
97+ programs = []
98+ for state in other .states :
99+ programs += other .memory [state ][size ]
100+ p2 = []
101+ for state in std .states :
102+ p2 += std .memory [state ][size ]
103+ diff = set (p2 ).symmetric_difference (programs )
104+ true_diffL = set ()
105+ true_diffR = set ()
106+ for p in diff :
107+ pp = evalstd .eval (p , tr ) or evalother .eval (p , tr )
108+ if pp is None or pp not in diff :
109+ true_diff = true_diffL if p in programs else true_diffR
110+ true_diff .add (p )
111+ assert true_diffL == true_diffR , (
112+ f"size={ size } count(g1)-count(g2)={ b - a } "
113+ )
91114
92115
93116def test_prune ():
@@ -96,7 +119,7 @@ def test_prune():
96119 tr = "int->int"
97120 g = grammar_by_saturation (dsl , tr )
98121 spec_out = specialize (out , tr , dsl )
99- comp_by_enum ([spec_out , g ], tr , max_size + 1 )
122+ comp_by_enum ([spec_out , g ], tr , max_size )
100123
101124
102125def test_incremental_same_size ():
@@ -131,17 +154,19 @@ def test_incremental_same_size_with_loops():
131154
132155def test_incremental_next_size ():
133156 manager = EquivalenceClassManager ()
134- out , tr = prune (dsl , evaluator , manager , max_size = max_size , rtype = "int" )
157+ evaluator = Evaluator (dsl , inputs , {}, set ())
158+ out , _ = prune (dsl , evaluator , manager , max_size = max_size , rtype = "int" )
135159 out = add_loops (
136160 out ,
137161 dsl ,
138162 )
139- incremental , tr = prune (
163+ evaluator .free_memory ()
164+ incremental , _ = prune (
140165 dsl , evaluator , manager , max_size = max_size + 1 , rtype = "int" , base_grammar = out
141166 )
142- direct , tr = prune ( dsl , evaluator , manager , max_size = max_size + 1 , rtype = "int" )
143- assert direct . rules == incremental . rules
144- assert direct . finals == incremental . finals
167+ evaluator . free_memory ( )
168+ direct , _ = prune ( dsl , evaluator , manager , max_size = max_size + 1 , rtype = "int" )
169+ comp_by_enum ([ incremental , direct ], "int->int" , max_size + 1 )
145170
146171
147172def test_is_superset ():
0 commit comments