1 | % (c) 2013-2024 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
2 | % Heinrich Heine Universitaet Duesseldorf | |
3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
4 | ||
5 | :- module(disprover, [disprove/5, disprove_with_opts/6, get_disprover_default_opts/1, | |
6 | print_prover_result_stats/0]). | |
7 | ||
8 | :- use_module(probsrc(module_information)). | |
9 | :- module_info(group,cbc). | |
10 | :- module_info(description,'Rodin Prover / Disprover'). | |
11 | ||
12 | % provide access to the Disprover algorithm with all hypotheses, selected hypotheses and goal | |
13 | ||
14 | :- use_module(extension('user_signal/user_signal'), [user_interruptable_call_det/2]). | |
15 | ||
16 | :- use_module(probsrc(solver_interface), [solve_predicate/5,type_check_in_machine_context/2]). | |
17 | :- use_module(probsrc(preferences), [temporary_set_preference/3, reset_temporary_preference/2, | |
18 | get_preference/2]). | |
19 | :- use_module(probsrc(bsyntaxtree), [conjunct_predicates/2, create_negation/2, | |
20 | find_typed_identifier_uses/3, | |
21 | find_typed_identifier_uses_l/3, | |
22 | get_texpr_types/2]). | |
23 | :- use_module(probsrc(error_manager), [reset_errors/0, add_message/3, | |
24 | add_warning/3, add_internal_error/2, add_error_and_fail/2]). | |
25 | :- use_module(library(lists)). | |
26 | :- use_module(probsrc(tools),[start_ms_timer/1, stop_ms_timer/1,stop_ms_timer_with_debug_msg/2, | |
27 | get_elapsed_timer/2, combiner_timer/3]). | |
28 | :- use_module(probsrc(debug), [debug_println/2,debug_mode/1, debug_format/3]). | |
29 | :- use_module(probsrc(b_global_sets),[contains_unfixed_deferred_set/1]). | |
30 | :- use_module(probsrc(external_functions),[observe_state/1]). | |
31 | :- use_module(extrasrc(unsat_cores),[unsat_core/2]). | |
32 | :- use_module(probsrc(pathes_lib), [unavailable_extension/2]). | |
33 | ||
34 | disprove(Goal,AllHypotheses,SelectedHypotheses,Timeout,OutResult) :- | |
35 | get_disprover_default_opts(Opts), | |
36 | % Note: disprover_mode is always set to true | |
37 | disprove_with_opts(Goal,AllHypotheses,SelectedHypotheses,Timeout,Opts,OutResult). | |
38 | ||
39 | get_disprover_default_opts(Opts) :- | |
40 | (unavailable_extension(chr_extension,_Reason) | |
41 | -> CHR=false, format('Disabling CHR in disprover as extension not available~n',[]) ; CHR=true), | |
42 | % default options: | |
43 | Opts = [use_smt_mode/true,use_clpfd_solver/true,use_chr_solver/CHR]. | |
44 | ||
45 | % ---------- | |
46 | ||
47 | disprove_with_opts(Goal,AllHypotheses,SelectedHypotheses,Timeout,Opts,OutResult) :- | |
48 | check_options(Opts), | |
49 | temporary_set_preference(disprover_mode,true,DC), | |
50 | temporary_set_preference(time_out,Timeout,TC), | |
51 | start_ms_timer(Timer), | |
52 | user_interruptable_call_det(disprove1(Goal,AllHypotheses,SelectedHypotheses,Opts,Result),InterruptResult), | |
53 | %write(ir(InterruptResult)), nl, | |
54 | (InterruptResult = interrupted -> OutResult = interrupted ; OutResult = Result), | |
55 | %catch_internal_timeout(InterruptResult,Result,OutResult), | |
56 | (debug_mode(on) -> write(disprove_result(OutResult)),nl,stop_ms_timer(Timer),nl ; true), | |
57 | reset_temporary_preference(disprover_mode,DC), | |
58 | reset_temporary_preference(time_out,TC). | |
59 | ||
60 | check_options([]) :- !. | |
61 | check_options([O|T]) :- !, (valid_option(O) -> true ; add_warning(disprover,'Illegal disprover option: ',O)), | |
62 | check_options(T). | |
63 | check_options(O) :- add_internal_error('Illegal disprover options: ',check_options(O)). | |
64 | ||
65 | :- use_module(probsrc(solver_interface), [valid_solver_option/1]). | |
66 | % Valid options | |
67 | valid_option(disprover_option(X)) :- !,valid_disprover_option(X). | |
68 | valid_option(X) :- valid_solver_option(X). | |
69 | ||
70 | valid_disprover_option(observe_state). | |
71 | valid_disprover_option(unsat_core). | |
72 | valid_disprover_option(unsat_core_as_machine). | |
73 | valid_disprover_option(export_po_as_machine(_)). | |
74 | valid_disprover_option(setlog_prover_timeout(_)). | |
75 | valid_disprover_option(wd_prover_timeout(_)). | |
76 | valid_disprover_option(po_label(_)). | |
77 | ||
78 | % ---------- | |
79 | ||
80 | :- use_module(probsrc(error_manager),[add_all_perrors/3]). | |
81 | disprove1(Goal,AllHypotheses,SelectedHypotheses,Opts,Result) :- | |
82 | catch( | |
83 | (disprove2(Goal,AllHypotheses,SelectedHypotheses,Opts,Result) -> true | |
84 | ; add_internal_error('Disprover failed on goal:',Goal), | |
85 | fail), | |
86 | type_errors(E), | |
87 | (add_all_perrors(E,[],disprover), Result=type_error)). | |
88 | ||
89 | %catch_internal_timeout(ok,contradiction_found,Out) :- | |
90 | % error_manager:check_warning_occured(warning(_X),Y), | |
91 | % is_time_out_message(Y), % Sebastian: why do we catch this ?? This is not necessarily a problem ?? | |
92 | % !, % Might be a problem for proofs, invalidate only if Result = contradiction_found | |
93 | % Out = time_out. % However, this might be old code that is superseded by the enum warnings | |
94 | %catch_internal_timeout(ok,Result,Result). | |
95 | ||
96 | % is_time_out_message(Y) :- atom(Y), atom_codes(Y,Codes), | |
97 | % append("TIME-OUT occurred while ProB was expanding", _, Codes). | |
98 | ||
99 | % ProverContext: just a name for statistics | |
100 | solve_disprover_predicate(ProverContext,Predicate,Opts,CBCResult) :- | |
101 | TimeoutFactor = 1, | |
102 | exclude(disprover_option,Opts,SOpts), | |
103 | (member(disprover_option(observe_state),Opts) -> observe_state(State) ; true), | |
104 | start_ms_timer(Timer), | |
105 | (solve_predicate(Predicate,State,TimeoutFactor,SOpts,CBCResult) | |
106 | -> register_prover_result(ProverContext,CBCResult,Timer) | |
107 | ; register_prover_result(ProverContext,failed,Timer), | |
108 | fail | |
109 | ). | |
110 | disprover_option(disprover_option(_)). | |
111 | ||
112 | ||
113 | :- use_module(wdsrc(well_def_analyser),[prove_sequent/4]). | |
114 | :- use_module(probsrc(tools_meta),[safe_time_out/3]). | |
115 | :- use_module(extrasrc(b2setlog),[prove_using_setlog/5]). | |
116 | prove_using_alternative_prover(setlog_prover,Goal,Hypotheses,Opts,TimeOutMs,Res) :- | |
117 | start_ms_timer(Timer), | |
118 | (prove_using_setlog(Goal,Hypotheses,Opts,TimeOutMs,Res) | |
119 | -> (Res = contradiction_found | |
120 | -> register_prover_result(setlog_prover,contradiction_found,Timer) | |
121 | ; register_prover_result(setlog_prover,Res,Timer), | |
122 | fail | |
123 | ) | |
124 | ; register_prover_result(setlog_prover,failed,Timer), | |
125 | fail | |
126 | ). | |
127 | prove_using_alternative_prover(wd_prover,Goal,Hypotheses,Opts,TimeOutMs,contradiction_found) :- | |
128 | % quite often 0 or 1 ms are enough for TimeOutMs | |
129 | (member(disprover_option(po_label(Label)),Opts) -> WDOpts=[po_label(Label)] ; WDOpts=[]), | |
130 | debug_format(19,'Starting WD Prover (timeout ~w ms) for \'~w\' ~n',[TimeOutMs,Label]), | |
131 | start_ms_timer(Timer), | |
132 | (safe_time_out(prove_sequent(proving,Goal,Hypotheses,WDOpts),TimeOutMs,TimeOutRes) | |
133 | -> (TimeOutRes=time_out | |
134 | -> format('Timeout in WD Prover (~w ms)~n',[TimeOutMs]), | |
135 | register_prover_result(wd_prover,time_out,Timer), fail | |
136 | ; register_prover_result(wd_prover,contradiction_found,Timer)) | |
137 | ; register_prover_result(wd_prover,failed,Timer), | |
138 | fail | |
139 | ). | |
140 | ||
141 | ||
142 | :- dynamic prover_stats/4. | |
143 | ||
144 | % register the result of a prover for statistics / user feedback | |
145 | register_prover_result(Prover,Result,Timer) :- | |
146 | functor(Result,RF,_), | |
147 | (retract(prover_stats(Prover,RF,PrevNr,PrevTime)) -> true ; PrevNr=0, PrevTime=0), | |
148 | NewNr is PrevNr+1, | |
149 | get_elapsed_timer(Timer,DeltaTimer), | |
150 | combiner_timer(PrevTime,DeltaTimer,NewTimer), | |
151 | assert(prover_stats(Prover,RF,NewNr,NewTimer)), | |
152 | stop_ms_timer_with_debug_msg(Timer,prover_result(Prover,RF)). | |
153 | ||
154 | print_prover_result_stats :- | |
155 | \+ \+ prover_stats(_,_,_,_), % at least one call made | |
156 | format('* Disprover statistics about individual prover calls and results:~n',[]), | |
157 | format('~w,~w,~w,~w,~w,~w~n',['Prover','Result','Calls','Runtime','TotRuntime','Walltime']), | |
158 | prover_stats(Prover,Result,Nr,timer(Runtime,TotRuntime,Walltime)), | |
159 | format('~w,~w,~w,~w,~w,~w~n',[Prover,Result,Nr,Runtime,TotRuntime,Walltime]), | |
160 | fail. | |
161 | print_prover_result_stats. | |
162 | ||
163 | :- public disprove2/5. % it is called by user_interruptable_call_det above; we should also add a meta_predicate annotation | |
164 | :- use_module(probsrc(bsyntaxtree), [predicate_identifiers/2]). | |
165 | disprove2(Goal,AllHypotheses,SelectedHypotheses,Opts,ResultOut) :- | |
166 | (type_check_in_machine_context([Goal|AllHypotheses],[TGoal|TAllHypotheses]) -> true | |
167 | ; add_error_and_fail(disprover,'Disprover typechecking goal failed')), | |
168 | (type_check_in_machine_context(SelectedHypotheses,TSelectedHypotheses) -> true | |
169 | ; add_error_and_fail(disprover,'Disprover typechecking selected hyps failed')), | |
170 | disprove3(TGoal,TAllHypotheses,TSelectedHypotheses,Opts,ResultOut). | |
171 | ||
172 | ||
173 | disprove3(TGoal,TAllHypotheses,TSelectedHypotheses,Opts,ResultOut) :- | |
174 | % build predicate H1 & H2 .... & not Goal | |
175 | create_negation(TGoal,NegatedGoal), | |
176 | %(debug_mode(on) -> write(NegatedGoal), nl ; true), | |
177 | (debug_mode(on) -> nl,write('Negated Goal:'), nl, | |
178 | translate:nested_print_bexpr_as_classicalb(NegatedGoal), | |
179 | write_hypothesis(TAllHypotheses) | |
180 | ; true), | |
181 | conjunct_predicates([NegatedGoal|TAllHypotheses],Predicate), | |
182 | %tools:print_bt_message(solving), | |
183 | ProofInfos = [disprover_result(final,all_and_selected,ResultOut),options(Opts)|PI1], | |
184 | ( get_alternate_prover_timeout(Opts,Prover,Timeout), | |
185 | Timeout>0, | |
186 | prove_using_alternative_prover(Prover,TGoal,TAllHypotheses,Opts,Timeout,ResultWithAll) | |
187 | % adds 5 extra PO proven in test 1800, and 4 more in test 1447 | |
188 | -> % DISCHARGED by WD Prover | |
189 | (debug_mode(on) -> add_message(disprover,'Discharged by alternate prover: ',Prover:Timeout) ; true), | |
190 | PI1 = [disprover_result(Prover,all,ResultWithAll)|PI2] | |
191 | ; solve_disprover_predicate(prob_all_hyps,Predicate,Opts,ResultWithAll), | |
192 | PI1 = [disprover_result(prob,all,ResultWithAll)|PI2] | |
193 | ), | |
194 | %tools:print_bt_message(solver_result(CBCResult)), | |
195 | debug_println(10,disprover_result_with_all_hypotheses(ResultWithAll)), | |
196 | disprove_double_check(ResultWithAll,NegatedGoal,TAllHypotheses,TSelectedHypotheses,Predicate,Opts,ResultOut,PI2), | |
197 | (member(disprover_option(export_po_as_machine(File)),Opts) | |
198 | -> export_po_as_machine(File,TAllHypotheses,TSelectedHypotheses,TGoal,ProofInfos) | |
199 | ; true). | |
200 | ||
201 | get_alternate_prover_timeout(Opts,Prover,Timeout) :- | |
202 | member(disprover_option(setlog_prover_timeout(TO)),Opts),!, | |
203 | (Prover=wd_prover,member(disprover_option(wd_prover_timeout(Timeout)),Opts) % try WD prover first | |
204 | ; | |
205 | Prover=setlog_prover, TO=Timeout). | |
206 | get_alternate_prover_timeout(Opts,wd_prover,Timeout) :- | |
207 | member(disprover_option(wd_prover_timeout(Timeout)),Opts),!. | |
208 | get_alternate_prover_timeout(_,wd_prover,WDTimeout) :- | |
209 | get_preference(time_out,GlobalTO), | |
210 | WDTimeout is 20 + GlobalTO // 100. | |
211 | ||
212 | % res <— solve( All Hyp & not G ) | |
213 | % if res = solution then | |
214 | % return CounterExample Found, Goal definitely not provable | |
215 | % else if unfixed deferred set used in selected Hypotheses or Goal then | |
216 | % return Unknown // WE COULD TRY and find counter example here in case there was a time-out? | |
217 | % else if res = fail (without time-out & without enumeration warning & no unfixed deferred set in All Hypotheses) then | |
218 | % return Proof Found, Goal proven | |
219 | % else | |
220 | % res <— solve (Selected Hyp & not G) /* maybe use smaller time-out here ?? */ | |
221 | % if res = fail (without time-out & without enumeration warning) then | |
222 | % return Proof Found, Goal proven | |
223 | % else if res = solution then | |
224 | % return CounterExample for selected Hypotheses found, Goal not provable from selected Hypotheses (but may be provable with all Hyp) | |
225 | % else | |
226 | % return Unknown | |
227 | % fi | |
228 | % fi | |
229 | ||
230 | % we found a solution / counter example to all hyps no need to double check here. | |
231 | % just clear up the resulting state, keeping only variables occuring in the goal. | |
232 | % although: sometimes it is useful to have other IDs as well, at least in the same component as the Goal ! | |
233 | disprove_double_check(solution(X),NegatedGoal,_Hypotheses,_SelectedHypotheses,_,_,ResultOut,ProofInfos) :- | |
234 | predicate_identifiers(NegatedGoal,GoalIdentifiers), | |
235 | findall(binding(Id,Value,PP), get_binding_from_solution(X,GoalIdentifiers,0,Id,Value,PP), FilteredState), | |
236 | ResultOut = solution(FilteredState), | |
237 | ProofInfos = ['Counter example to all hypotheses found']. | |
238 | % check if the unfixed deferred sets occur in selected hyps or goal | |
239 | disprove_double_check(no_solution_found(unfixed_deferred_sets),NegatedGoal,_Hypotheses,SelectedHypotheses,_,_, | |
240 | no_solution_found(unfixed_deferred_sets),ProofInfos) :- | |
241 | find_typed_identifier_uses(NegatedGoal,[],GoalIdentifiers), | |
242 | get_texpr_types(GoalIdentifiers,GoalTypes), | |
243 | find_typed_identifier_uses_l(SelectedHypotheses,[],HypIdentifiers), | |
244 | get_texpr_types(HypIdentifiers,HypTypes), | |
245 | append(GoalTypes,HypTypes,Types), | |
246 | % exclude all types that are not unfixed | |
247 | include(contains_unfixed_deferred_set,Types,UnfixedTypes), | |
248 | % see if an unfixed type is left | |
249 | UnfixedTypes = [_|_], | |
250 | !, | |
251 | ProofInfos = ['Goal or selected hypotheses contain unfixed deferred sets', unfixed(UnfixedTypes)], | |
252 | !. | |
253 | % contradiction was found, i.e. there was neither a timeout nor an enumeration warning | |
254 | disprove_double_check(contradiction_found,NegatedGoal,Hypotheses,SelectedHypotheses,FullPredicate,Opts, | |
255 | FinalResult,ProofInfos) :- | |
256 | ProofInfos = ['PO is proven using all hypotheses, no timeout or enumeration warning occured'], | |
257 | %add_hit(po_discharged,prob_all), | |
258 | (get_preference(double_evaluation_when_analysing,true) | |
259 | -> check_negated(NegatedGoal,Hypotheses,SelectedHypotheses,FullPredicate,Opts,FinalResult) | |
260 | ; FinalResult = contradiction_found). | |
261 | disprove_double_check(Result,_NegatedGoal,Hypotheses,SelectedHypotheses,_,_Opts,ResultOut,ProofInfos) :- | |
262 | same_conjunction_list(Hypotheses,SelectedHypotheses),!, | |
263 | ProofInfos = ['Selected hypotheses identical to all hypotheses'], | |
264 | Result=ResultOut. | |
265 | % see what solving only selected hypotheses & not G gives us | |
266 | disprove_double_check(_OldResult,NegatedGoal,Hypotheses,SelectedHypotheses,_,Opts,ResultOut,ProofInfos) :- | |
267 | % No proof found with all hypotheses, now try selected ones only | |
268 | % reset existing enumeration warnings, | |
269 | % that might have been generated in a previous run | |
270 | reset_errors, | |
271 | (debug_mode(on) | |
272 | -> nl,write('Trying to use only selected hypotheses.\nNegated Goal:'), nl, | |
273 | translate:nested_print_bexpr_as_classicalb(NegatedGoal), | |
274 | write_hypothesis(SelectedHypotheses) | |
275 | ; true), | |
276 | conjunct_predicates([NegatedGoal|SelectedHypotheses],Predicate), | |
277 | %external_functions:observe_state(State), | |
278 | solve_disprover_predicate(prob_selected_hyps,Predicate,Opts,Result), | |
279 | ProofInfos = [disprover_result(prob,selected,Result)], | |
280 | !, | |
281 | disprove_triple_check(Result,NegatedGoal,Hypotheses,SelectedHypotheses,Predicate,Opts,ResultOut). | |
282 | ||
283 | ||
284 | % we still have a contradiction -> double check it if preference set | |
285 | disprove_triple_check(contradiction_found,NegatedGoal,Hypotheses,SelectedHypotheses,FullPredicate,Opts,FinalResult) :- | |
286 | %add_hit(po_discharged,prob_selected), | |
287 | (get_preference(double_evaluation_when_analysing,true) % preference set by Rodin Disprover | |
288 | -> check_negated(NegatedGoal,Hypotheses,SelectedHypotheses,FullPredicate,Opts,FinalResult) | |
289 | ; FinalResult = contradiction_found, | |
290 | compute_unsat_core_if_requested(FullPredicate,Opts) | |
291 | ). | |
292 | disprove_triple_check(solution(X),NegatedGoal,_,_,_FullPredicate,_,ResultOut) :- | |
293 | % Counter-Example to Goal for selected Hypotheses found | |
294 | predicate_identifiers(NegatedGoal,GoalIdentifiers), | |
295 | findall(binding(Id,Value,PP), get_binding_from_solution(X,GoalIdentifiers,10,Id,Value,PP), FilteredState), | |
296 | ResultOut = solution_on_selected_hypotheses(FilteredState). | |
297 | disprove_triple_check(time_out,_,_,_,_,_,time_out). % TODO: We could try Kodkod here! | |
298 | disprove_triple_check(no_solution_found(X),_,_,_,_,_,no_solution_found(X)). % Or here? | |
299 | ||
300 | :- use_module(library(ordsets),[ord_member/2]). | |
301 | % get bindings from solution; showing all identifiers from goal and a few others as indicated by MaxIndexNonGoal | |
302 | get_binding_from_solution(Solution,GoalIdentifiers,MaxIndexNonGoal,Id,Value,PP) :- MaxIndexNonGoal>=0, | |
303 | sort(GoalIdentifiers,SG), | |
304 | nth1(Nr,Solution,binding(Id,Value,PP)), | |
305 | (Nr =< MaxIndexNonGoal -> true ; ord_member(Id,SG)). | |
306 | % TO DO: rather than limiting this way, we could analyse the variables which are in the same component | |
307 | % either by calling predicate_components or by storing component info in | |
308 | ||
309 | check_negated(NegatedGoal,Hypotheses,_,FullOrigPredicate,Opts,ResultOut) :- | |
310 | create_negation(NegatedGoal,Goal), | |
311 | conjunct_predicates([Goal|Hypotheses],Predicate), | |
312 | %tools:print_bt_message(check_negated), | |
313 | debug_println(20,'Check whether we can also prove negation of goal'), | |
314 | solve_disprover_predicate(prob_check_negated_goal,Predicate,Opts,Result), | |
315 | %% tools:print_bt_message(solver_double_check_result(Result)), | |
316 | !, | |
317 | (Result = contradiction_found % proven both (H & not G) and (H & G) | |
318 | -> ResultOut = contradiction_in_hypotheses, | |
319 | translate:translate_bexpression_with_limit(NegatedGoal,GS), | |
320 | add_warning(disprover_inconsistent_hypotheses, | |
321 | 'Disprover double check result: Contradiction in hypotheses (or Bug) detected for goal: ', | |
322 | GS), %% check_negated(NegatedGoal,Hypotheses)) | |
323 | % translate:nested_print_bexpr_as_classicalb(Hypotheses),nl,nl, | |
324 | compute_unsat_core_if_requested(Predicate,Opts) | |
325 | % ; Result=solution(Bindings), format('Solution for negated goal:~n',[]), member(B,Bindings), print_binding(B),fail | |
326 | ; ResultOut = contradiction_found, | |
327 | compute_unsat_core_if_requested(FullOrigPredicate,Opts) | |
328 | ). | |
329 | ||
330 | %print_binding(binding(Var,_,PPV)) :- format(' ~w = ~w~n',[Var,PPV]). | |
331 | ||
332 | compute_unsat_core_if_requested(Predicate,Opts) :- | |
333 | (member(disprover_option(unsat_core),Opts) -> compute_unsat_core(Opts,Predicate) ; true). | |
334 | :- use_module(probsrc(preferences),[call_with_preference/3]). | |
335 | :- use_module(probsrc(translate),[translate_predicate_into_machine/3,nested_print_bexpr_as_classicalb/1]). | |
336 | compute_unsat_core(Opts,Predicate) :- | |
337 | (member(unsat_core_algorithm/P,Opts) | |
338 | -> call_with_preference(compute_unsat_core_aux(Predicate,CorePredicate),unsat_core_algorithm,P) | |
339 | ; compute_unsat_core_aux(Predicate,CorePredicate)), | |
340 | !, | |
341 | print('UNSAT CORE: '),nl,print('--------'),nl, | |
342 | (member(disprover_option(unsat_core_as_machine),Opts) | |
343 | -> translate_predicate_into_machine(CorePredicate,'UnsatCore',ResultAtom), | |
344 | write(ResultAtom),nl | |
345 | ; nested_print_bexpr_as_classicalb(CorePredicate)), | |
346 | nl, print('--------'),nl. | |
347 | ||
348 | compute_unsat_core_aux(Predicate,CorePredicate) :- | |
349 | print('Computing UNSAT CORE'),nl, | |
350 | unsat_core(Predicate,CorePredicate). % from unsat_cores | |
351 | ||
352 | :- use_module(probsrc(bsyntaxtree),[same_texpr/2]). | |
353 | % check if two lists of conjuncts represent the same conjunction (modulo info fields) | |
354 | same_conjunction_list(List1,List2) :- | |
355 | same_length(List1,List2,_), % avoid possibly expensive comparisons if lists clearly different | |
356 | % we could strip info field and the sort; but here we just want to catch the obvious case where the disprover is called with SelectedHyp = AllHyp | |
357 | maplist(same_texpr,List1,List2). | |
358 | ||
359 | :- use_module(probsrc(translate),[nested_print_sequent_as_classicalb/6,nested_print_bexpr_as_classicalb/1]). | |
360 | write_hypothesis([]). | |
361 | write_hypothesis([Hyp|Hyps]) :- | |
362 | write(' & /* Hypothesis: */ '), nl, | |
363 | %(debug_mode(on) -> write(Hyp), nl ; true), | |
364 | nested_print_bexpr_as_classicalb(Hyp), | |
365 | write_hypothesis(Hyps). | |
366 | ||
367 | :- use_module(probsrc(tools_io),[safe_intelligent_open_file/3]). | |
368 | export_po_as_machine(Filename,THypothesesList,TSelectedHypothesesList,TGoal,Infos) :- | |
369 | %nested_print_sequent_as_classicalb(Stream,THypothesesList,TGoal,'ProofObligation_AllHyps',Infos), | |
370 | format(user_output,'Exporting selected hypotheses to B machine: ~w~n',[Filename]), | |
371 | safe_intelligent_open_file(Filename,write,Stream), | |
372 | nested_print_sequent_as_classicalb(Stream,TSelectedHypothesesList,TGoal, | |
373 | THypothesesList,'ProofObligation_SelectedHyps',Infos), | |
374 | close(Stream). | |
375 |