22from collections import defaultdict
33from functools import cache
44from itertools import chain , combinations , permutations
5+ from typing import Any , List , Optional , Set , Tuple
56
67from bitarray .util import any_and , ones , subset
78
89from .bkcons import deduce_bk_cons , deduce_non_singletons , deduce_recalls , deduce_type_cons
910from .combine import Combiner
1011from .tester import Tester
11- from .util import Constraint , Literal , calc_prog_size , format_literal , format_prog , format_rule , get_raw_prog , \
12+ from .util import Constraint , Literal , Settings , calc_prog_size , format_literal , format_prog , format_rule , get_raw_prog , \
1213 mdl_score , order_prog , prog_has_invention , prog_is_recursive , remap_variables , rule_is_recursive , timeout
14+ from .abs_generate import Generator
15+ from .generate import Generator as Generator1
16+ from .gen2 import Generator as Generator2
17+ from .gen3 import Generator as Generator3
1318
14-
15- def load_solver (settings , tester , coverage_pos , coverage_neg , prog_lookup ):
19+ def load_solver (settings : Settings , tester : Tester , coverage_pos , coverage_neg , prog_lookup ):
1620 if settings .debug :
1721 settings .logger .debug (f'Load exact solver: { settings .solver } ' )
1822
@@ -67,7 +71,12 @@ def load_solver(settings, tester, coverage_pos, coverage_neg, prog_lookup):
6771
6872
6973class Popper ():
70- def __init__ (self , settings , tester ):
74+ settings : Settings
75+ tester : Tester
76+ # the following 2 type hints are conjectural -- rpg
77+ num_pos : int
78+ num_neg : int
79+ def __init__ (self , settings : Settings , tester : Tester ):
7180 self .settings = settings
7281 self .tester = tester
7382 self .pruned2 = set ()
@@ -78,6 +87,21 @@ def __init__(self, settings, tester):
7887 self .tmp = {}
7988 self .seen_allsat = set ()
8089
90+ def select_generator (self , bkcons ):
91+ settings = self .settings
92+ gen : type [Generator ]
93+ if settings .single_solve :
94+ gen = Generator2
95+ settings .logger .debug ("using generator 2" )
96+
97+ elif settings .max_rules == 2 and not settings .pi_enabled :
98+ gen = Generator3
99+ settings .logger .debug ("using generator 3" )
100+ else :
101+ gen = Generator1
102+ settings .logger .debug ("using generate" )
103+ return gen (settings , bkcons )
104+
81105 def run (self , bkcons ):
82106
83107 settings , tester = self .settings , self .tester
@@ -102,16 +126,7 @@ def run(self, bkcons):
102126 # generator that builds programs
103127 # AC: all very hacky until the refactoring is complete
104128 with settings .stats .duration ('init' ):
105- if settings .single_solve :
106- from .gen2 import Generator
107- print ("using generator 2" )
108- elif settings .max_rules == 2 and not settings .pi_enabled :
109- from .gen3 import Generator
110- print ("using generator 3" )
111- else :
112- from .generate import Generator
113- print ("using generate" )
114- generator = self .generator = Generator (settings , bkcons )
129+ generator = self .generator = self .select_generator (bkcons )
115130
116131 # track the success sets of tested hypotheses
117132
@@ -173,7 +188,6 @@ def run(self, bkcons):
173188 # generate a program
174189 with settings .stats .duration ('generate' ):
175190 prog = generator .get_prog ()
176- print ("Generated prog: {}" .format (prog ))
177191 settings .logger .info ("Generated prog: {}" .format (prog ))
178192 if prog is None :
179193 break
@@ -203,7 +217,7 @@ def run(self, bkcons):
203217 prog_size )
204218 else :
205219 pos_covered , inconsistent = tester .test_prog (prog )
206- print (f"pos_covered: { pos_covered } , inconsistent: { inconsistent } " )
220+ settings . logger . debug (f"pos_covered: { pos_covered } , inconsistent: { inconsistent } " )
207221 # @CH: can you explain these?
208222 skipped , skip_early_neg = False , False
209223
@@ -258,7 +272,8 @@ def run(self, bkcons):
258272 if tp == num_pos :
259273 add_gen = True
260274
261- # if the program does not cover any positive examples, check whether it is has an unsat core
275+ # if the program does not cover any positive examples, check whether
276+ # it has an unsat core
262277 if not has_invention :
263278 if tp < min_coverage or (settings .noisy and tp <= prog_size ):
264279 with settings .stats .duration ('find mucs' ):
@@ -1560,8 +1575,10 @@ def popper(settings, tester, bkcons):
15601575 Popper (settings , tester ).run (bkcons )
15611576
15621577
1563- def get_bk_cons (settings , tester ):
1578+ def get_bk_cons (settings : Settings , tester : Tester ):
15641579 bkcons = []
1580+ recalls : Optional [List [str ]]
1581+ pointless : Set [Tuple [str , Any ]]
15651582
15661583 with settings .stats .duration ('find_pointless_relations' ):
15671584 pointless = settings .pointless = tester .find_pointless_relations ()
@@ -1576,9 +1593,11 @@ def get_bk_cons(settings, tester):
15761593 with settings .stats .duration ('recalls' ):
15771594 recalls = deduce_recalls (settings )
15781595
1579- if recalls == None :
1596+ if recalls is None :
1597+ settings .logger .debug ('No recalls; datalog is False' )
15801598 settings .datalog = False
15811599 else :
1600+ settings .logger .debug ('Non-empty recalls: datalog is True' )
15821601 settings .datalog = True
15831602 if settings .showcons :
15841603 for x in recalls :
0 commit comments