1 % (c) 2009-2019 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(b_interpreter_eventb,
6 [ b_event/6
7 , b_event_with_change_set/7
8 , b_event_constraints/7
9 ]).
10
11 :- use_module(tools).
12 :- use_module(bsyntaxtree).
13 :- use_module(store).
14 :- use_module(bmachine).
15 :- use_module(kernel_objects).
16 :- use_module(error_manager).
17 :- use_module(kernel_waitflags).
18 :- use_module(b_enumerate).
19 :- use_module(state_space).
20
21 :- use_module(b_interpreter).
22
23 :- use_module(debug).
24
25 :- use_module(module_information,[module_info/2]).
26 :- module_info(group,interpreter).
27 :- module_info(description,'This is an Event-B specific part of the interpreter. It contains the interpreter rules for events (as opposed to operations in classical B.').
28
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30 % Event-B multilevel execution
31 %
32 % used shortcuts: IS=InState, OS=OutState, LS=LocalState
33
34 % execute an Event:
35 % difference with b_event_with_change_set : OutState already setup
36 b_event(TBody,Parameters,NormalisedParaValues,InState,OutState,Path) :-
37 get_texpr_expr(TBody,Event),
38 b_event_with_change_set_aux(Event,Parameters,NormalisedParaValues,InState,no_change_set_available,OutState,Path).
39
40
41 :- use_module(store,[copy_variable_store/4]).
42 % a version of b_event which gets the operation ChangeSet passed
43 b_event_with_change_set(TBody,Parameters,NormalisedParaValues,InState,ChangeSet,Updates,Path) :-
44 get_texpr_expr(TBody,Event),
45 b_event_with_change_set_aux(Event,Parameters,NormalisedParaValues,InState,ChangeSet,Updates,Path).
46
47 /* TO DO:
48 b_event_with_change_set_aux(lazy_let_subst(Id,IdExpr,TBody),Parameters,NormalisedParaValues,InState,ChangeSet,Updates,Path) :- !,
49 add_lazy_let_id_and_expression(Id,IdExpr,LocalState,InState,NewLocalState,WF),
50 b_event_with_change_set(TBody,Parameters,NormalisedParaValues,InState,ChangeSet,Updates,Path). */
51 b_event_with_change_set_aux(Event,Parameters,NormalisedParaValues,InState,ChangeSet,Updates,Path) :-
52 extract_event(Event,Name,Section,Guard),
53 setup_event_state(Parameters,ParaValues,NormalisedParaValues,ParamTypedVals,LS),
54 % evaluate the event's guard
55 evaluate_predicate_if_necessary(Guard,ParamTypedVals,LS,InState),
56 % execute the event
57 init_trace_of_event(Name,Section,Parameters,ParaValues,Guard,Path,RestPath,Desc),
58 (ChangeSet==no_change_set_available -> OutState=Updates
59 ; copy_variable_store(InState,ChangeSet,Updates,OutState)),
60 execute_event_body(Event,InState,LS,OutState,RestPath,Desc).
61
62 evaluate_predicate_if_necessary(Guard,ParamTypedVals,LS,InState) :-
63 (pge_algo: do_not_evaluate_guard, ParamTypedVals==[] ->
64 % if we already know that the event is enabled
65 % in the current state, we don't need to evaluate the guard here
66 debug_println(9,guard_will_not_be_evaluated_b_event)
67 ; otherwise ->
68 evaluate_predicate(Guard,ParamTypedVals,LS,InState)
69 ).
70
71 % TO DO: add support for lazy_let_subst by calling add_lazy_let_id_and_expression
72 :- use_module(error_manager,[add_error/2]).
73 extract_event(Event,Name,Section,FullGuard) :-
74 Event = rlevent(Name,Section,_Status,_Params,Guard,_Theorems,_Actions,_VWitnesses,_PWitnesses,_Unmod,_AbstractEvents),
75 !,
76 % check for user-defined additional guard
77 full_guard(Guard,FullGuard),
78 (Name='INITIALISATION',FullGuard \== Guard
79 % The guard is evaluated on the state before ! It should be executed on the state after ! %% TO DO
80 -> add_error(b_interpreter_eventb,'Additional guards not yet supported for Event-B INITIALISATION')
81 ; true).
82 extract_event(Event,Name,Section,FullGuard) :-
83 add_internal_error('Illegal Event-B Event: ',extract_event(Event,Name,Section,FullGuard)),fail.
84
85 setup_event_state(Parameters,ParaValues,NormalisedParaValues,ParamTypedVals,LS) :-
86 empty_state(EmptyState),
87 set_up_typed_localstate(Parameters,ParaValues,ParamTypedVals,EmptyState,LS,positive),
88 store:l_expand_and_normalise_values(ParaValues,NormalisedParaValues,Parameters).
89
90 init_trace_of_event(Name,Section,Parameters,ParaValues,FullGuard,[event(Path),eventtrace(Trace)],RestPath,D2) :-
91 Path = [event(Name,ParaValues)|RestPath],
92 eventtrace_init(Name,Desc,Trace),
93 eventtrace_add(event(Name,Section),Desc,D1),
94 eventtrace_add(true_guard(Parameters,ParaValues,FullGuard),D1,D2).
95
96 full_guard(Guard,FullGuard) :-
97 bmachine:b_machine_temp_predicate(TempPred),!,
98 conjunct_predicates([TempPred,Guard],FullGuard).
99 full_guard(Guard,Guard).
100
101 execute_event_body(Event,InState,LS,OutState,AbstractPath,D) :-
102 Event = rlevent(_Name,_Section,Status,_Params,_Guard,Theorems,Actions,VWitnesses,PWitnesses,Unmodifiables,AbstractEvents),
103 % for convergent/anticipated events: check if the variant is non-negative
104 check_event_entry_status(Status,InState,LS,VariantValue,D,D2),
105 % check if the theorems hold
106 check_event_theorems(Theorems,InState,LS,D2,D3),
107 % execute the actions
108 b_execute_eventb_actions(Actions,InState,LS,OutState,D3,D4),
109 % for convergent/anticipated events: check if the variant has decreased/not increased
110 check_event_exit_status(VariantValue,Status,OutState,LS,D4,D5),
111 check_if_invalid_vars_are_modified(Unmodifiables,InState,OutState,D5),
112 %print(go_for_abstract(AbstractEvents,VWitnesses,PWitnesses)),nl,
113 go_for_abstract_events(AbstractEvents,VWitnesses,PWitnesses,InState,LS,OutState,AbstractPath,D5).
114
115
116 go_for_abstract_events([],_VWit,_PWit,_IS,_LS,_OS,[],D) :-
117 % no more refined level exists, stop here
118 !, eventtrace_finalise(D,_).
119 go_for_abstract_events(AbstractEvents,[],[],IS,LS,OS,AbstractPath,Din) :-
120 !, % optimisation: If no witness has to be evaluated, do not copy primed variables
121 execute_abstract_events(AbstractEvents,[],[],IS,LS,OS,AbstractPath,Din).
122 go_for_abstract_events(AbstractEvents,VWitnesses,PWitnesses,IS,LS,OS,AbstractPath,Din) :-
123 % copy a primed version of all values in the outstate into the local state
124 copy_primed(OS,LS,NewLS),
125 % evaluate witnesses for dropped abstract vars
126 evaluate_witnesses_for_abstract_vars(VWitnesses,IS,NewLS,OS,Din,D1),
127 % evaluate witnesses for dropped parameters
128 evaluate_witnesses_for_abstract_parameters(PWitnesses,IS,NewLS,AbsLS,Params,PValues,D1,D2),
129 % continue with the next refinement level
130 execute_abstract_events(AbstractEvents,Params,PValues,IS,AbsLS,OS,AbstractPath,D2).
131
132 check_event_entry_status(TStatus,IS,LS,VariantValue,Din,Dout) :-
133 get_texpr_expr(TStatus,Status),
134 check_event_entry_status2(Status,IS,LS,VariantValue,Din,Dout).
135 check_event_entry_status2(ordinary,_IS,_LS,-,D,D).
136 check_event_entry_status2(anticipated(Variant),IS,LS,Val,Din,Dout) :-
137 variant_is_not_negative(Variant,anticipated,IS,LS,Val,Din,Dout).
138 check_event_entry_status2(convergent(Variant),IS,LS,Val,Din,Dout) :-
139 variant_is_not_negative(Variant,convergent,IS,LS,Val,Din,Dout).
140 variant_is_not_negative(Variant,_CType,IS,LS,Value,Din,Dout) :-
141 get_texpr_type(Variant, set(_)),!,
142 % if variant is of type set, it cannot be negative
143 % nevertheless, we compute its value here to check later if the set has been decreased
144 if( b_compute_expression_nowf(Variant,LS,IS,Value), % Daniel: why are LS & IS swapped ?
145 Din=Dout,
146 eventtrace_store_event_error(event_wd_error(Variant,variant),Din,Dout)).
147 variant_is_not_negative(Variant,CType,IS,LS,Value,Din,Dout) :-
148 % print_bt_message(computing_variant), print_bexpr(Variant),nl,
149 % print(local(LS)), nl, print(global(IS)),nl,
150 if( b_compute_expression_nowf(Variant,LS,IS,Value), % Daniel: why are LS & IS swapped ?
151 %print_bt_message(variant(Value)),
152 ( less_than(Value, int(0)) ->
153 eventtrace_store_event_error(variant_negative(CType,Variant,Value),Din,Dout)
154 ; otherwise -> eventtrace_add(variant_checked_pre(CType,Variant,Value),Din,Dout)),
155 eventtrace_store_event_error(event_wd_error(Variant,variant),Din,Dout)).
156
157
158 check_event_exit_status(-,_TStatus,_OS,_LS,D,D) :- !.
159 check_event_exit_status(EntryValue,TStatus,OS,LS,Din,Dout) :-
160 get_texpr_expr(TStatus,Status),
161 % Status is convergent(VariantExpr) or anticipated(VariantExpr)
162 functor(Status,CType,1),arg(1,Status,VariantExpr),
163 get_texpr_type(VariantExpr,Type),
164 if( b_compute_expression_nowf(VariantExpr,LS,OS,ExitValue),
165 ( variant_condition(CType,Type,EntryValue,ExitValue) ->
166 eventtrace_add(variant_checked_post(CType,VariantExpr,EntryValue,ExitValue),Din,Dout)
167 ; otherwise ->
168 eventtrace_store_event_error(invalid_variant(CType,VariantExpr,EntryValue,ExitValue),Din,Dout)),
169 eventtrace_store_event_error(event_wd_error(VariantExpr,variant_after_event),Din,Dout)).
170
171
172 variant_condition(anticipated, integer, Pre, Post) :- !, less_than_equal(Post,Pre).
173 variant_condition(anticipated, set(_), Pre, Post) :- !, check_subset_of(Post,Pre).
174 variant_condition(convergent, integer, Pre, Post) :- !, less_than(Post,Pre).
175 variant_condition(convergent, set(_), Pre, Post) :- !, strict_subset_of(Post,Pre).
176
177 check_event_theorems([],_State,_LState,D,D).
178 check_event_theorems([Theorem|Trest],State,LState,Din,Dout) :-
179 check_event_theorem(Theorem,State,LState,Din,Dinter),
180 check_event_theorems(Trest,State,LState,Dinter,Dout).
181 check_event_theorem(Theorem,State,LState,Din,Dout) :-
182 ( evaluate_predicate(Theorem,[],LState,State) ->
183 Din = Dout
184 %eventtrace_add(theorem_checked(Theorem),Din,Dout)
185 ; otherwise ->
186 eventtrace_store_event_error(invalid_theorem_in_guard(Theorem),Din,Dout)
187 ).
188
189 % check if variables that are not modified by an abstract event or newly introduced into
190 % the current refinement level are modified.
191 check_if_invalid_vars_are_modified([],_IS,_OS,_D).
192 check_if_invalid_vars_are_modified([Unmod|UnmodRest],IS,OS,D) :-
193 check_unmodifiable(Unmod,IS,OS,D),
194 check_if_invalid_vars_are_modified(UnmodRest,IS,OS,D).
195 check_unmodifiable(Var,IS,OS,D) :-
196 def_get_texpr_id(Var,Id),
197 lookup_value(Id,IS,Pre),!,
198 lookup_value(Id,OS,Post),!,
199 ( equal_object(Pre,Post) -> true
200 ; otherwise ->
201 eventtrace_failure(invalid_modification(Var,Pre,Post),D)).
202
203 evaluate_witnesses_for_abstract_parameters(Witnesses,IS,LS,AbsLS,Params,PValues,Din,Dout) :-
204 evaluate_witnesses_for_abstract_parameters2(Witnesses,IS,LS,LS,AbsLS,Params,PValues,Din,Dout).
205 evaluate_witnesses_for_abstract_parameters2([],_State,_OrigLS,LS,LS,[],[],D,D).
206 evaluate_witnesses_for_abstract_parameters2([Witness|WRest],State,OrigLS,LS,AbsLS,[TId|Params],[Value|PValues],Din,Dout) :-
207 witness_substate(Witness,OrigLS,LS,TId,Value,Predicate,TypedVals,WitnessLS,ExtLS),
208 if( evaluate_predicate(Predicate,TypedVals,WitnessLS,State),
209 ( eventtrace_add(eval_witness(parameter,TId,Value,Predicate),Din,D1),
210 evaluate_witnesses_for_abstract_parameters2(WRest,State,OrigLS,ExtLS,AbsLS,Params,PValues,D1,Dout)),
211 eventtrace_failure(no_witness_found(parameter,TId,Predicate), Din) ).
212
213 witness_substate(Witness,OrigLS,LS,TId,Value,Predicate,TypedVals,WitnessLS,ExtLS) :-
214 extract_witness(Witness,TId,Id,_Type,Predicate),
215 set_up_typed_localstate([TId],[Value],TypedVals,LS,ExtLS,positive),
216 add_var_to_localstate(Id,Value,OrigLS,WitnessLS).
217
218 extract_witness(Witness,TId,Id,Type,Predicate) :-
219 get_texpr_expr(Witness,witness(TId,Predicate)),
220 def_get_texpr_id(TId,Id),
221 get_texpr_type(TId,Type).
222
223 eventtrace_init(EventName, desc(EventName,D,D), D).
224 eventtrace_add( Entry, desc(EN,D,[Entry|L]), desc(EN,D,L) ).
225 eventtrace_name( desc(EN,_,_), EN).
226 eventtrace_finalise(desc(_EN,D,[]),D).
227 eventtrace_store_event_error(Error,Din,Dout) :-
228 eventtrace_name(Din, EventName),
229 copy_term(Din,Dcopy),
230 eventtrace_add(Error,Dcopy,Dc1),
231 eventtrace_finalise(Dc1,D),
232 store_error_for_context_state(eventerror(EventName,Error,D),Id),
233 eventtrace_add(error(Error,Id),Din,Dout).
234 eventtrace_failure(Error,Desc) :-
235 eventtrace_name(Desc,EventName),
236 eventtrace_add(Error,Desc,D1),
237 eventtrace_finalise(D1,D),
238 store_error_for_context_state(eventerror(EventName,Error,D),_Id),
239 fail.
240
241 evaluate_predicate(Predicate,TypedVals,LS,State) :-
242 init_wait_flags(WF),
243 enumerate_predicate(Predicate,TypedVals,LS,State,WF),
244 ground_wait_flags(WF).
245
246 enumerate_predicate(Predicate,TypedVals,LS,State,WF) :-
247 b_test_boolean_expression(Predicate,LS,State,WF),
248 b_tighter_enumerate_values(TypedVals,WF). % moved this later for performance, see PerformanceTests/ParameterEnumeration_mch.eventb
249
250 execute_abstract_events(Events,Params,PValues,IS,LS,OS,[event(Name,PValues)|Path],Din) :-
251 if( select_event(Events,Params,PValues,IS,LS,Event,Name,Din,D1),
252 execute_event_body(Event,IS,LS,OS,Path,D1),
253 ( generate_simulation_error(Events,Error), eventtrace_failure(Error,Din) )).
254
255 generate_simulation_error(Events,simulation_error(FailedEvents)) :-
256 generate_simulation_error2(Events,FailedEvents).
257 generate_simulation_error2([],[]).
258 generate_simulation_error2([TEvent|Erest],[event(Name,Section,Guard)|Srest]) :-
259 get_texpr_expr(TEvent,Event),
260 Event = rlevent(Name,Section,_Status,_Params,Guard,_Thms,_Actions,_VWitnesses,_PWitnesses,_Unmodifiables,_AbstractEvents),
261 generate_simulation_error2(Erest,Srest).
262
263 select_event(Events,Params,PValues,IS,LS,Event,Name,Din,Dout) :-
264 member(TEvent,Events),
265 get_texpr_expr(TEvent,Event),
266 Event = rlevent(Name,Section,_Status,_Params,Guard,_Thms,_Act,_VWit,_PWit,_Unmod,_Evt),
267 b_test_boolean_expression_wf(Guard,LS,IS),
268 eventtrace_add(event(Name,Section),Din,D1),
269 eventtrace_add(true_guard(Params,PValues,Guard),D1,Dout).
270
271 evaluate_witnesses_for_abstract_vars([],_IS,_LS,_OS,D,D).
272 evaluate_witnesses_for_abstract_vars([Witness|WRest],IS,LS,OS,Din,Dout) :-
273 extract_witness(Witness,TId,Id,Type,Predicate),
274 if( (init_wait_flags(WF),
275 b_enumerate_values_in_store([Id],[Type],[Value],LS,WF),
276 b_test_boolean_expression(Predicate,LS,IS,WF),
277 ground_wait_flags(WF)),
278 ( eventtrace_add(eval_witness(variable,TId,Value,Predicate),Din,D1),
279 evaluate_witnesses_for_abstract_vars(WRest,IS,LS,OS,D1,Dout)),
280 eventtrace_failure(no_witness_found(variable,TId,Predicate),Din) ).
281
282 b_execute_eventb_actions([],_IS,_LS,_OS,D,D).
283 b_execute_eventb_actions([TAction|ARest],IS,LS,OS,Din,Dout) :-
284 get_texpr_expr(TAction,Action),
285 if( ( init_wait_flags(WF),
286 b_execute_eventb_action(Action,IS,LS,OS,WF,Step),
287 ground_wait_flags(WF)),
288 ( eventtrace_add(Step,Din,D1),
289 b_execute_eventb_actions(ARest,IS,LS,OS,D1,Dout)),
290 eventtrace_failure(action_not_executable(TAction),Din)).
291 %get_assigned_vars(TAction,Assigned) :-
292 % get_texpr_info(TAction,Info),
293 % member(assigned_after(Assigned),Info),!.
294 b_execute_eventb_action(assign(Lhs,Exprs),IS,LS,OS,WF,Step) :- !,
295 b_interpreter:b_compute_expressions(Exprs,LS,IS,VALs,WF), % VALs - a list of computed values
296 b_interpreter:b_assign_values_or_functions(Lhs,VALs,LS,IS,NewValues,WF,output_required),
297 eventb_store_new_values(NewValues,OS),
298 Step = action(Lhs,Exprs,VALs).
299 b_execute_eventb_action(becomes_element_of(Lhs,Rhs),IS,LS,OS,WF,Step) :- !,
300 convert_pairs_into_list(Lhs,Val,ValList),
301 get_texpr_types(Lhs,Types),
302 b_compute_expression(Rhs,LS,IS,ValueSet,WF),
303 check_element_of_wf(Val,ValueSet,WF),
304 b_enumerate_typed_values(ValList,Types,WF),
305 % ground_det_wait_flag(WF),
306 b_interpreter:b_assign_values_or_functions(Lhs,ValList,LS,IS,NewValues,WF,output_required),
307 eventb_store_new_values(NewValues,OS),
308 Step = action_set(Lhs,Rhs,ValueSet,ValList).
309 b_execute_eventb_action(becomes_such(Ids,Pred),IS,LS,OS,WF,Step) :- !,
310 b_interpreter:b_execute_becomes_such(Ids,Pred,LS,IS,OutputValues,IdsValues,WF),
311 eventb_store_new_values(OutputValues,OS),
312 Step = action_pred(Ids,Pred,IdsValues).
313 b_execute_eventb_action(Action,IS,LS,OS,WF,Step) :-
314 add_internal_error('Unknown Event-B action: ',b_execute_eventb_action(Action,IS,LS,OS,WF,Step)),fail.
315 %b_execute_eventb_action(evb2_becomes_such(Ids,Pred),IS,LS,OS,WF,Step) :- % is now translated to becomes_such
316 % add_primed_vars(Ids,OS,LS,NewLS,TypedVals,Values),
317 % b_tighter_enumerate_values(TypedVals,WF),b_test_boolean_expression(Pred,NewLS,IS,WF),
318 % Step = action_pred(Ids,Pred,Values).
319
320 %primed vars always trigger an enum warning
321 %this might be split up depending on where they are introduced
322 %add_primed_vars([],_State,LS,LS,[],[]).
323 %add_primed_vars([TId|IRest],State,In,Out,[typedval(Value,Type,Id,trigger_true(Primed))|TypeValRest],[Value|Vrest]) :-
324 % def_get_texpr_id(TId,Id), get_texpr_type(TId,Type),
325 % lookup_value(Id,State,Value),
326 % atom_concat(Id,'\'',Primed),
327 % add_var_to_localstate(Primed,Value,In,Inter),
328 % add_primed_vars(IRest,State,Inter,Out,TypeValRest,Vrest).
329
330 eventb_store_new_values([],_Store).
331 eventb_store_new_values([bind(Id,Value)|IRest],Store) :-
332 (lookup_value(Id,Store,Res) -> StoreValue=Res
333 ; add_internal_error('Cannot find Event-B identifier:',Id:Store),fail),
334 equal_object(StoreValue,Value),
335 eventb_store_new_values(IRest,Store).
336
337
338 % copy_primed(+Store, +InStore, -OutStore)
339 % copies and primes all variables from Store
340 % TO DO: maybe only copy those that are really used as primed variables in witnesses,...
341 copy_primed([], InStore, InStore).
342 copy_primed([bind(OldVar,Value)|Srest], InStore, OutStore) :-
343 atom_concat(OldVar,'\'',NewVar), % is faster than caching this using a dynamic fact
344 copy_primed(Srest,[bind(NewVar,Value)|InStore], OutStore).
345
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 % Multilevel-animation: Version that is intended to set up constraints
348 % between two states and not to find errors in one event
349
350 % part below only used for cbc/state_model_check
351
352 b_event_constraints(TBody,Parameters,NormalisedParaValues,IS,OS,Path,WF) :-
353 get_texpr_expr(TBody,Event),
354 b_event_constraints_aux(Event,Parameters,NormalisedParaValues,IS,OS,Path,WF).
355
356 b_event_constraints_aux(Event,Parameters,NormalisedParaValues,IS,OS,Path,WF) :-
357 extract_event(Event,Name,Section,Guard),
358 setup_event_state(Parameters,ParaValues,NormalisedParaValues,ParamTypedVals,LS),
359 % evaluate guard
360 enumerate_predicate(Guard,ParamTypedVals,LS,IS,WF),
361 % execute the event
362 init_trace_of_event(Name,Section,Parameters,ParaValues,Guard,Path,RestPath,Desc),
363 event_body_constraints(Event,IS,LS,OS,RestPath,Desc,WF).
364
365 event_body_constraints(Event,IS,LS,OS,AbstractPath,D,WF) :-
366 Event = rlevent(_Name,_Section,_Status,_Params,_Guard,_Thms,Actions,VWitnesses,PWitnesses,_Unmodifiables,AbstractEvents),
367 % for convergent/anticipated events: check if the variant is non-negative
368 % check_event_entry_status(Status,IS,LS,VariantValue,D,D2),
369 eventb_actions_constraints(Actions,IS,LS,OS,D,D2,WF),
370 % for convergent/anticipated events: check if the variant has decreased/not increased
371 % check_event_exit_status(VariantValue,Status,OS,LS,D3,D4),
372 % check_if_invalid_vars_are_modified(Unmodifiables,IS,OS,D4),
373 abstract_event_constraints(AbstractEvents,VWitnesses,PWitnesses,IS,LS,OS,AbstractPath,D2,WF).
374
375 eventb_actions_constraints([],_IS,_LS,_OS,D,D,_WF).
376 eventb_actions_constraints([TAction|ARest],IS,LS,OS,Din,Dout,WF) :-
377 get_texpr_expr(TAction,Action),
378 b_execute_eventb_action(Action,IS,LS,OS,WF,Step),
379 eventtrace_add(Step,Din,D1),
380 eventb_actions_constraints(ARest,IS,LS,OS,D1,Dout,WF).
381
382 abstract_event_constraints([],_VWit,_PWit,_IS,_LS,_OS,[],D,_WF) :-
383 % no more refined level exists, stop here
384 !, eventtrace_finalise(D,_).
385 abstract_event_constraints(AbstractEvents,VWitnesses,PWitnesses,IS,LS,OS,AbstractPath,Din,WF) :-
386 % copy a primed version of all values in the outstate
387 % into the local state
388 copy_primed(OS,LS,NewLS),
389 % evaluate witnesses for dropped abstract vars
390 abstract_var_witnesses_constraints(VWitnesses,IS,NewLS,OS,Din,D1,WF),
391 % evaluate witnesses for dropped parameters
392 abstract_parameter_witnesses_constraints(PWitnesses,IS,NewLS,AbsLS,_Params,_PValues,D1,D2,WF),
393 % continue with the next refinement level
394 execute_abstract_events_with_constraints(AbstractEvents,IS,AbsLS,OS,AbstractPath,D2,WF).
395
396 abstract_var_witnesses_constraints([],_IS,_LS,_OS,D,D,_WF).
397 abstract_var_witnesses_constraints([Witness|WRest],IS,LS,OS,Din,Dout,WF) :-
398 extract_witness(Witness,TId,Id,Type,Predicate),
399 b_enumerate_values_in_store([Id],[Type],[Value],LS,WF),
400 b_test_boolean_expression(Predicate,LS,IS,WF),
401 eventtrace_add(eval_witness(variable,TId,Value,Predicate),Din,D1),
402 abstract_var_witnesses_constraints(WRest,IS,LS,OS,D1,Dout,WF).
403
404 abstract_parameter_witnesses_constraints(Witnesses,IS,LS,AbsLS,Params,PValues,Din,Dout,WF) :-
405 abstract_parameter_witnesses_constraints2(Witnesses,IS,LS,LS,AbsLS,Params,PValues,Din,Dout,WF).
406 abstract_parameter_witnesses_constraints2([],_State,_OrigLS,LS,LS,[],[],D,D,_WF).
407 abstract_parameter_witnesses_constraints2([Witness|WRest],State,OrigLS,LS,AbsLS,[TId|Params],[Value|PValues],Din,Dout,WF) :-
408 witness_substate(Witness,OrigLS,LS,TId,Value,Predicate,TypedVals,WitnessLS,ExtLS),
409 enumerate_predicate(Predicate,TypedVals,WitnessLS,State,WF),
410 eventtrace_add(eval_witness(parameter,TId,Value,Predicate),Din,D1),
411 abstract_parameter_witnesses_constraints2(WRest,State,OrigLS,ExtLS,AbsLS,Params,PValues,D1,Dout,WF).
412
413 execute_abstract_events_with_constraints(AbstractEvents,IS,LS,OS,Path,D,WF) :-
414 % This introduces a choicepoint when there are more than one abstract event.
415 % But the usual case is just one abstract event
416 member(TEvent,AbstractEvents),
417 get_texpr_expr(TEvent,Event),
418 event_body_constraints(Event,IS,LS,OS,Path,D,WF).