Skip to content

Commit 93cbd8d

Browse files
committed
Refactor generators.
1 parent d34ce59 commit 93cbd8d

File tree

5 files changed

+88
-27
lines changed

5 files changed

+88
-27
lines changed

popper/abs_generate.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import abc
2+
3+
4+
class Generator(abc.ABC):
5+
6+
# @profile
7+
def get_prog(self):
8+
pass
9+
10+
def gen_symbol(self, literal, backend):
11+
pass
12+
13+
def update_solver(self, size):
14+
pass
15+
self.update_number_of_literals(size)
16+
17+
def update_number_of_literals(self, size):
18+
pass
19+
20+
def update_number_of_vars(self, size):
21+
pass
22+
23+
def update_number_of_rules(self, size):
24+
pass
25+
26+
def prune_size(self, size):
27+
pass
28+
29+
# @profile
30+
def get_ground_rules(self, rule):
31+
pass
32+
33+
def parse_handles(self, new_handles):
34+
pass
35+
36+
def constrain(self, tmp_new_cons):
37+
pass

popper/gen2.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import pkg_resources
99
from clingo import Function, Number, Tuple_
1010

11-
from .util import Constraint, Literal
11+
from .util import Constraint, Literal, Settings
12+
from . abs_generate import Generator as AbstractGenerator
1213

1314

1415
def arg_to_symbol(arg):
@@ -20,7 +21,7 @@ def arg_to_symbol(arg):
2021
return Function(arg)
2122

2223

23-
def atom_to_symbol(pred, args):
24+
def atom_to_symbol(pred, args) -> Function:
2425
xs = tuple(arg_to_symbol(arg) for arg in args)
2526
return Function(name=pred, arguments=xs)
2627

@@ -35,9 +36,10 @@ def atom_to_symbol(pred, args):
3536
"""
3637

3738

38-
class Generator:
39+
class Generator(AbstractGenerator):
40+
settings: Settings
3941

40-
def __init__(self, settings, bkcons=[]):
42+
def __init__(self, settings: Settings, bkcons=[]):
4143
self.savings = 0
4244
self.settings = settings
4345
self.cached_clingo_atoms = {}
@@ -109,8 +111,8 @@ def __init__(self, settings, bkcons=[]):
109111

110112
encoding = '\n'.join(encoding)
111113

112-
# with open('ENCODING-GEN.pl', 'w') as f:
113-
# f.write(encoding)
114+
with open('/tmp/ENCODING-GEN.pro', 'w') as f:
115+
f.write(encoding)
114116

115117
if self.settings.single_solve:
116118
solver = clingo.Control(['--heuristic=Domain', '-Wnone'])

popper/gen3.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import pkg_resources
1111
from collections import defaultdict
1212
from . util import rule_is_recursive, Constraint, Literal
13+
from . abs_generate import Generator as AbstractGenerator
14+
1315
clingo.script.enable_python()
1416
from clingo import Function, Number, Tuple_
1517
from itertools import permutations
@@ -30,7 +32,7 @@ def atom_to_symbol(pred, args):
3032
xs = tuple(arg_to_symbol(arg) for arg in args)
3133
return Function(name = pred, arguments = xs)
3234

33-
class Generator:
35+
class Generator(AbstractGenerator):
3436

3537
def __init__(self, settings, bkcons=[]):
3638
self.settings = settings

popper/generate.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from clingo import Function, Number, Tuple_
1515
from itertools import permutations
1616
import dataclasses
17+
from . abs_generate import Generator as AbstractGenerator
1718

1819
@dataclasses.dataclass(frozen=True)
1920
class Var:
@@ -75,7 +76,7 @@ def build_rule_literals(rule, rule_var, pi=False):
7576
if rule_is_recursive(rule):
7677
yield gteq(rule_var, 1)
7778

78-
class Generator:
79+
class Generator(AbstractGenerator):
7980

8081
def __init__(self, settings, bkcons=[]):
8182
self.savings = 0

popper/loop.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
from collections import defaultdict
33
from functools import cache
44
from itertools import chain, combinations, permutations
5+
from typing import Any, List, Optional, Set, Tuple
56

67
from bitarray.util import any_and, ones, subset
78

89
from .bkcons import deduce_bk_cons, deduce_non_singletons, deduce_recalls, deduce_type_cons
910
from .combine import Combiner
1011
from .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

6973
class 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

Comments
 (0)