Skip to content

Commit da5b8c0

Browse files
committed
new way to reduce solving time as explained in https://arxiv.org/pdf/2508.06263 and changed print statements to show time elapsed rather than actual time
1 parent 32a592e commit da5b8c0

File tree

2 files changed

+79
-6
lines changed

2 files changed

+79
-6
lines changed

popper/gen2.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ def __init__(self, settings, bkcons=[]):
4848
bias_text = re.sub(r'max_body\(\d*\).','', bias_text)
4949
bias_text = re.sub(r'max_clauses\(\d*\).','', bias_text)
5050

51-
# AC: NEED TO COMPLETELY REFACTOR THIS CODE
5251
for p,a in settings.pointless:
5352
bias_text = re.sub(rf'body_pred\({p},\s*{a}\)\.', '', bias_text)
5453
bias_text = re.sub(rf'constant\({p},.*?\).*', '', bias_text, flags=re.MULTILINE)
@@ -68,6 +67,62 @@ def __init__(self, settings, bkcons=[]):
6867
encoding.append(f'vars({arity}, {tuple(xs)}).')
6968
for i, x in enumerate(xs):
7069
encoding.append(f'var_pos({x}, {tuple(xs)}, {i}).')
70+
encoding.append(f'ordered_vars({tuple(xs)},{tuple(sorted(xs))}).')
71+
72+
73+
74+
# ORDERING THINGY
75+
# %% appears((0,0,V0)):- body_literal(_, _, _, (V0,)), not head_var(_,V0).
76+
# appears((0,V0,V1)):- body_literal(_, _, _, (A,B)), ordered_vars((A,B), (V0,V1)).
77+
# appears((V0,V1,V2)):- body_literal(_, _, _, (A,B,C)), ordered_vars((A,B,C), (V0,V1,V2)).
78+
order_cons = []
79+
max_arity = max(arities)
80+
for arity in range(2, max_arity+1):
81+
xs1 = ','.join(f'V{i}' for i in range(arity)) # Vs
82+
xs2 = ','.join(f'X{i}' for i in range(arity)) # Xs
83+
84+
if arity < max_arity:
85+
prefix = ','.join(str(0) for i in range(arity, max_arity)) + ',' + xs1
86+
else:
87+
prefix = xs1
88+
89+
90+
order_cons.append(f'appears(({prefix})):- body_literal(_,_,_,({xs2})), ordered_vars(({xs2}), ({xs1})).')
91+
92+
order_cons.append(f'var_tuple(({prefix})):- body_pred(P,{arity}), vars({arity},Vars), not bad_body(P,Vars), not type_mismatch(P,Vars), ordered_vars(Vars,OrderedVars), OrderedVars=({xs1}).')
93+
94+
95+
if arity == 1:
96+
order_cons.append(f'var_member(V,(0,0,0,V)):-var(V).')
97+
else:
98+
order_cons.append(f'var_member(V,({prefix})):-vars(_, Vars), Vars=({xs1}), var_member(V,Vars).')
99+
# print(f)
100+
# var_member(V,(0,0,V0,V1)):-vars(_, Vars), Vars=(V0,V1), var_member(V,Vars).
101+
# var_member(V,(0,V0,V1,V2)):-vars(_, Vars), Vars=(V0,V1,V2), var_member(V,Vars).
102+
103+
xs1 = ','.join(f'V{i}' for i in range(max_arity)) # Vs
104+
for k in range(max_arity):
105+
xs2 = ','.join(f'V{i}' for i in range(k)) # Vs
106+
if k > 0 and k < max_arity:
107+
xs2 += ','
108+
xs2 += ','.join(f'X{i}' for i in range(k, max_arity))
109+
order_cons.append(f'lower(({xs1}),({xs2})):- var_tuple(({xs1})), var_tuple(({xs2})), X{k} < V{k}.')
110+
111+
for k in range(max_arity-1):
112+
# A,B,C,D
113+
v0 = f'V{k}'
114+
v1 = f'V{k+1}'
115+
order_cons.append(f'seen_lower(Vars1, V):- V={v1}-1, Vars1 = ({xs1}), {v0} < V < {v1}, lower(Vars1, Vars2), var_tuple(Vars1), appears(Vars2), var_member(V, Vars2), not head_var(_,V).')
116+
order_cons.append(f'gap_(({xs1}),{v1}-1):- var_tuple(({xs1})), {v0} < V < {v1}, var(V).')
117+
118+
119+
order_cons.append(f'gap(({xs1}),V):- gap_(({xs1}), _), #max' + '{X :gap_((' + xs1 + '), X)} == V.')
120+
121+
order_cons.append(f':- appears(({xs1})), gap(({xs1}), V), not seen_lower(({xs1}),V), not head_var(_,V).')
122+
123+
# print('\n'.join(order_cons))
124+
encoding.extend(order_cons)
125+
71126

72127
type_encoding = set()
73128
if self.settings.head_types:
@@ -105,7 +160,7 @@ def __init__(self, settings, bkcons=[]):
105160
encoding = '\n'.join(encoding)
106161

107162
# with open('ENCODING-GEN.pl', 'w') as f:
108-
# f.write(encoding)
163+
# f.write(encoding)
109164

110165
if self.settings.single_solve:
111166
solver = clingo.Control(['--heuristic=Domain','-Wnone'])
@@ -157,6 +212,7 @@ def constrain(self, tmp_new_cons):
157212
con_size = None
158213
if self.settings.noisy and len(xs)>2:
159214
con_size = xs[2]
215+
# print('gen', con_type)
160216
ground_rules2 = tuple(self.build_generalisation_constraint3(con_prog, con_size))
161217
new_ground_cons.update(ground_rules2)
162218
elif con_type == Constraint.SPECIALISATION:
@@ -173,6 +229,8 @@ def constrain(self, tmp_new_cons):
173229
cached_clingo_atoms = self.cached_clingo_atoms
174230

175231
for ground_body in new_ground_cons:
232+
233+
# print(', '.join(sorted(map(str,ground_body))))
176234
nogood = []
177235
for sign, pred, args in ground_body:
178236
k = hash((sign, pred, args))

popper/util.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,18 +257,33 @@ def __init__(self, cmd_line=False, info=True, debug=False, show_stats=True, max_
257257
self.bk_file = bk_file
258258
self.bias_file = bias_file
259259

260-
self.tmp_cache = set()
260+
# self.tmp_cache = set()
261261
self.logger = logging.getLogger("popper")
262262

263+
class SecondsFormatter(logging.Formatter):
264+
def format(self, record):
265+
record.elapsed_secs = record.relativeCreated / 1000.0
266+
return super().format(record)
267+
268+
formatter = SecondsFormatter(
269+
"%(elapsed_secs).1f s %(levelname)s: %(message)s"
270+
)
271+
272+
handler = logging.StreamHandler()
273+
handler.setFormatter(formatter)
274+
275+
self.logger = logging.getLogger("popper")
276+
self.logger.addHandler(handler)
277+
278+
263279
if quiet:
264280
pass
265281
elif debug:
266282
log_level = logging.DEBUG
267-
# logging.basicConfig(format='%(asctime)s %(message)s', level=log_level, datefmt='%H:%M:%S')
268-
logging.basicConfig(format='%(message)s', level=log_level, datefmt='%H:%M:%S')
283+
self.logger.setLevel(logging.DEBUG)
269284
elif info:
270285
log_level = logging.INFO
271-
logging.basicConfig(format='%(asctime)s %(message)s', level=log_level, datefmt='%H:%M:%S')
286+
self.logger.setLevel(logging.INFO)
272287

273288
self.info = info
274289
self.debug = debug

0 commit comments

Comments
 (0)