Skip to content

Commit 6229df2

Browse files
author
Pascual Martinez-Gomez
committed
Added more information to the snapshot of theorem proving failure.
1 parent be4d0a6 commit 6229df2

File tree

1 file changed

+69
-4
lines changed

1 file changed

+69
-4
lines changed

scripts/abduction_tools.py

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ def GetPremisesThatMatchConclusionArgs(premises, conclusion):
124124
candidate_premises.append(premise_line)
125125
return candidate_premises
126126

127-
def make_failure_log(conclusion_pred, premise_preds, conclusion, premises):
127+
def make_failure_log(conclusion_pred, premise_preds, conclusion, premises,
128+
coq_output_lines=None):
128129
"""
129130
Produces a dictionary with the following structure:
130131
{"unproved sub-goal" : "sub-goal_predicate",
@@ -144,17 +145,81 @@ def make_failure_log(conclusion_pred, premise_preds, conclusion, premises):
144145
failure_log["matching premises"] = premises_base
145146
failure_log["raw sub-goal"] = conclusion
146147
failure_log["raw premises"] = premises
148+
premise_preds = []
149+
for p in premises:
150+
try:
151+
pred = p.split()[2]
152+
except:
153+
continue
154+
if pred.startswith('_'):
155+
premise_preds.append(denormalize_token(pred))
156+
failure_log["all premises"] = premise_preds
157+
failure_log["other sub-goals"] = get_subgoals_from_coq_output(
158+
coq_output_lines, premises)
147159
return failure_log
148160

149-
def MakeAxiomsFromPremisesAndConclusion(premises, conclusion):
161+
def get_subgoals_from_coq_output(coq_output_lines, premises):
162+
"""
163+
When the proving is halted due to unprovable sub-goals,
164+
Coq produces an output similar to this:
165+
166+
2 subgoals
167+
168+
H1 : True
169+
H4 : True
170+
x1 : Event
171+
H6 : True
172+
H3 : _play x1
173+
H : _two (Subj x1)
174+
H2 : _man (Subj x1)
175+
H0 : _table (Acc x1)
176+
H5 : _tennis (Acc x1)
177+
============================
178+
_ping (Acc x1)
179+
180+
subgoal 2 is:
181+
_pong (Acc x1)
182+
183+
This function returns the remaining sub-goals ("_pong" in this example).
184+
"""
185+
subgoals = []
186+
subgoal_index = -1
187+
for line in coq_output_lines:
188+
if line.strip() == '':
189+
continue
190+
line_tokens = line.split()
191+
if subgoal_index > 0:
192+
subgoal_line = line
193+
subgoal_tokens = subgoal_line.split()
194+
subgoal_pred = subgoal_tokens[0]
195+
if subgoal_index in [s['index'] for s in subgoals]:
196+
# This sub-goal has already appeared and is recorded.
197+
subgoal_index = -1
198+
continue
199+
subgoal = {
200+
'predicate' : denormalize_token(line_tokens[0]),
201+
'index' : subgoal_index,
202+
'raw' : subgoal_line}
203+
matching_premises = GetPremisesThatMatchConclusionArgs(premises, subgoal_line)
204+
subgoal['matching raw premises'] = matching_premises
205+
premise_preds = [
206+
denormalize_token(premise.split()[2]) for premise in matching_premises]
207+
subgoal['matching premises'] = premise_preds
208+
subgoals.append(subgoal)
209+
subgoal_index = -1
210+
if len(line_tokens) >= 3 and line_tokens[0] == 'subgoal' and line_tokens[2] == 'is:':
211+
subgoal_index = int(line_tokens[1])
212+
return subgoals
213+
214+
def MakeAxiomsFromPremisesAndConclusion(premises, conclusion, coq_output_lines=None):
150215
matching_premises = GetPremisesThatMatchConclusionArgs(premises, conclusion)
151216
premise_preds = [premise.split()[2] for premise in matching_premises]
152217
conclusion_pred = conclusion.split()[0]
153218
pred_args = GetPredicateArguments(premises, conclusion)
154219
axioms = MakeAxiomsFromPreds(premise_preds, conclusion_pred, pred_args)
155220
if not axioms and 'False' not in conclusion_pred:
156221
failure_log = make_failure_log(
157-
conclusion_pred, premise_preds, conclusion, premises)
222+
conclusion_pred, premise_preds, conclusion, premises, coq_output_lines)
158223
print(json.dumps(failure_log), file=sys.stderr)
159224
return axioms
160225

@@ -319,7 +384,7 @@ def TryAbduction(coq_script, previous_axioms=set(), expected='yes'):
319384
if not premise_lines or not conclusion:
320385
return 'unknown', [], previous_axioms
321386
matching_premises = GetPremisesThatMatchConclusionArgs(premise_lines, conclusion)
322-
axioms = MakeAxiomsFromPremisesAndConclusion(premise_lines, conclusion)
387+
axioms = MakeAxiomsFromPremisesAndConclusion(premise_lines, conclusion, output_lines)
323388
axioms = filter_wrong_axioms(axioms, coq_script)
324389
axioms = axioms.union(previous_axioms)
325390
new_coq_script = InsertAxiomsInCoqScript(axioms, coq_script)

0 commit comments

Comments
 (0)