@@ -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