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 | % This module provides a plugin mechanism for ProB | |
6 | % Each plugin has an unique ID. It should be registered in the module | |
7 | % plugin_registry | |
8 | ||
9 | :- module(plugins, [initialise_plugins/0 | |
10 | ,is_registered_plugin/1,is_registered_plugin/2 | |
11 | ,active_plugin/1,tcl_plugin_syntax_colouring/2 | |
12 | ,plugin_file_extensions/1 | |
13 | ,available_plugins_for_mode/1,plugin_is_available_for_mode/0 | |
14 | ,plugin_has_preferences/0,plugins_with_preferences/1 | |
15 | ,plugin_has_output/1 | |
16 | ,plugin_get_output/2 | |
17 | ,is_plugin_file_extension/2 | |
18 | ,load_plugin_file/2 | |
19 | ,setup_transition_skeleton/2 | |
20 | ,plugin_transition/5 | |
21 | ,plugin_state_property/3 | |
22 | ,plugin_parse/7 | |
23 | ,plugin_compute_expression/4 | |
24 | ,plugin_evaluate_predicate/3 | |
25 | ,plugin_evaluate_transition_predicate/3 | |
26 | ,notify_new_transition_to_plugin/4 ,notify_new_transition_to_plugin/5 | |
27 | ,plugin_is_initialised_state/2 | |
28 | ,start_plugin_for_current_mode/1,stop_plugin/0 | |
29 | ,plugin_prettyprint_transition/3 | |
30 | ,plugin_prettyprint_property/3 | |
31 | ,plugin_prettyprint_value/3 | |
32 | % ,plugin_advanced_eclipse_preference/2 % TO DO: not used nor defined at the moment | |
33 | ,plugin_preference_default_value/2 | |
34 | ,plugin_preference_description/2 | |
35 | ,plugin_preference_val_type/2 | |
36 | ,plugin_preference_category/2 | |
37 | ,plugin_check_invariantKO/3 | |
38 | ,plugin_get_internal/2 | |
39 | ,compiletime_init_plugins/0 | |
40 | ]). | |
41 | ||
42 | :- use_module(library(lists)). | |
43 | :- use_module(library(codesio)). | |
44 | :- use_module(library(file_systems)). | |
45 | ||
46 | :- use_module(tools_strings,[ajoin/2]). | |
47 | :- use_module(module_information,[module_info/2]). | |
48 | ||
49 | :- use_module(specfile,[animation_mode/1,animation_minor_mode/1,set_animation_mode/1,set_animation_minor_mode/1]). | |
50 | ||
51 | :- use_module(error_manager,[add_error/2]). | |
52 | :- use_module(preferences,[get_preference/2]). | |
53 | ||
54 | :- module_info(group,infrastructure). | |
55 | :- module_info(description,'A plugin mechanism for ProB.'). | |
56 | ||
57 | :- public author/2. % for Spider | |
58 | :- dynamic | |
59 | plugin/2, | |
60 | pname/2, | |
61 | status/2, | |
62 | author/2, | |
63 | file_extensions/2, | |
64 | file_loader/2, | |
65 | transition_skeleton/2, | |
66 | transition_pred/2, | |
67 | initialisation_pred/2, | |
68 | state_property_pred/2, | |
69 | parser_pred/2, | |
70 | compute_expression_pred/2, | |
71 | evaluate_predicate_pred/2, | |
72 | evaluate_transition_pred/2, | |
73 | is_initialised_state_pred/2, | |
74 | prettyprint_transition_pred/2, | |
75 | prettyprint_property_pred/2, | |
76 | prettyprint_value_pred/2, | |
77 | syntax_colouring/2, | |
78 | plugin_for_modes/2, | |
79 | plugin_init_pred/2, | |
80 | plugin_new_transition_pred/2, | |
81 | plugin_preferences_pred/2, | |
82 | plugin_check_invariant_pred/2, | |
83 | plugin_output_pred/2, | |
84 | plugin_internal_representation_pred/2. | |
85 | ||
86 | % TODO: deactivated plugin mechanism for next release -- keeping the number of | |
87 | % modules smaller until the report is better structured | |
88 | % load_compiletime_plugins :- !. | |
89 | load_compiletime_plugins :- print(load_compiletime_plugins),nl, | |
90 | findall(Module, | |
91 | ( directory_member_of_directory(plugins('.'),Dir,Fullname), | |
92 | atom_concat(Dir,'.pl',PrologFilename), | |
93 | file_member_of_directory(Fullname,PrologFilename,_), | |
94 | ajoin([Dir,'/',PrologFilename], Modulename), | |
95 | Module = plugins(Modulename) ), | |
96 | Plugins), | |
97 | %print(loading_plugins(Plugins)),nl, | |
98 | load_plugins2(Plugins). | |
99 | ||
100 | % these plug-ins are not stable enough to load for the normal user: | |
101 | do_not_load_plugin(plugins('probvm/probvm.pl')). | |
102 | ||
103 | load_plugins2([]). | |
104 | load_plugins2([Module|Prest]) :- do_not_load_plugin(Module),!, load_plugins2(Prest). | |
105 | load_plugins2([Module|Prest]) :- | |
106 | load_plugin(Module,Id), | |
107 | (nonvar(Id) -> assert(plugin(Id,Module)); true), | |
108 | load_plugins2(Prest). | |
109 | ||
110 | load_plugin(Module,Id) :- | |
111 | catch( ( load_plugin2(Module,Id) -> | |
112 | ajoin(['Loaded plugin ', Id], Msg), | |
113 | print_message(informational, Msg) | |
114 | ; otherwise -> | |
115 | ajoin(['Loading of module ', Module, ' failed: '], Msg), | |
116 | print_message(error, Msg)), | |
117 | E, | |
118 | ( ajoin(['Loading of module ', Module, ' raised an exception: ', E], Msg), | |
119 | print_message(error, Msg))). | |
120 | ||
121 | load_plugin2(Module,Id) :- | |
122 | use_module(IdVar,Module,[]), % SICStus 4.3.3 now keeps IdVar a variable ! | |
123 | (var(IdVar) -> get_plugin_module_name(Module,Id) | |
124 | ; IdVar = Id), | |
125 | %print(used_module(Id,Module)),nl, | |
126 | ( plugin(Id,_) -> | |
127 | ajoin(['Plugin ID ',Id,' used twice'],Msg), | |
128 | print_message(error,Msg), | |
129 | fail | |
130 | ; otherwise -> | |
131 | true). | |
132 | ||
133 | :- use_module(tools,[get_modulename_filename/2]). | |
134 | get_plugin_module_name(plugins(F),ModuleName) :- !, tools:get_modulename_filename(F,ModuleName). | |
135 | get_plugin_module_name(F,ModuleName) :- tools:get_modulename_filename(F,ModuleName). | |
136 | ||
137 | %:- load_compiletime_plugins. % now done here : compiletime_init_plugins | |
138 | ||
139 | :- use_module(eventhandling,[register_event_listener/3]). | |
140 | :- register_event_listener(compile_prob,compiletime_init_plugins, | |
141 | 'Load compile time plugins and initialise them.'). | |
142 | compiletime_init_plugins :- load_compiletime_plugins,initialise_plugins. | |
143 | ||
144 | ||
145 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
146 | ||
147 | initialise_plugins :- | |
148 | reset_plugin_db, | |
149 | fail. | |
150 | initialise_plugins :- | |
151 | ? | plugin(Id,_Module), |
152 | initialise_plugin(Id), | |
153 | fail. | |
154 | initialise_plugins. | |
155 | ||
156 | reset_plugin_db :- | |
157 | retractpred(pname/2), | |
158 | retractpred(status/2), | |
159 | retractpred(author/2), | |
160 | retractpred(file_extensions/2), | |
161 | retractpred(file_loader/2), | |
162 | retractpred(transition_skeleton/2), | |
163 | retractpred(transition_pred/2), | |
164 | retractpred(initialisation_pred/2), | |
165 | retractpred(state_property_pred/2), | |
166 | retractpred(parser_pred/2), | |
167 | retractpred(compute_expression_pred/2), | |
168 | retractpred(evaluate_predicate_pred/2), | |
169 | retractpred(evaluate_transition_pred/2), | |
170 | retractpred(is_initialised_state_pred/2), | |
171 | retractpred(prettyprint_transition_pred/2), | |
172 | retractpred(prettyprint_property_pred/2), | |
173 | retractpred(prettyprint_value_pred/2), | |
174 | retractpred(syntax_colouring/2), | |
175 | retractpred(plugin_for_modes/2), | |
176 | retractpred(plugin_init_pred/2), | |
177 | retractpred(plugin_new_transition_pred/2), | |
178 | retractpred(plugin_preferences_pred/2), | |
179 | retractpred(plugin_check_invariant_pred/2), | |
180 | retractpred(plugin_output_pred/2), | |
181 | retractpred(plugin_internal_representation_pred/2). | |
182 | ||
183 | retractpred(F/A) :- | |
184 | functor(Fact,F,A), retractall(Fact). | |
185 | ||
186 | initialise_plugin(Id) :- | |
187 | plugin(Id,_Module), | |
188 | call(Id:plugin_info(Info)), | |
189 | %print(init_plugin(Id,Info)),nl, | |
190 | initialise_plugin2(Id,Info), | |
191 | !. | |
192 | ||
193 | initialise_plugin2(Id,Info) :- | |
194 | %check_options(Info,Id), | |
195 | register_infos(Info,Id,_Used). | |
196 | register_infos([],_Id,[]). | |
197 | register_infos([Info|IRest],Id,Used) :- | |
198 | register_info(Info,Id,U), | |
199 | append(U,RUsed,Used), | |
200 | register_infos(IRest,Id,RUsed). | |
201 | register_info(Info,Id,Used) :- | |
202 | ( Info = (Name=Value) -> | |
203 | ( register_info2(Name,Value,Id) -> | |
204 | Used = [Name] | |
205 | ; otherwise -> | |
206 | ajoin(['Failed analysing plugin info for plugin ', Id, | |
207 | ': ', Name, ' = ', Value], Msg), | |
208 | print_message(error, Msg), | |
209 | Used = []) | |
210 | ; otherwise -> | |
211 | ajoin(['Invalid plugin info for plugin ', Id, | |
212 | ': ', Info], Msg), | |
213 | print_message(error, Msg), | |
214 | Used = []). | |
215 | ||
216 | :- public check_options/2. | |
217 | check_options(Info,Id) :- | |
218 | findall(O,mandatory_option(O),Mandatory), | |
219 | check_options2(Mandatory,Info,Id,_). | |
220 | check_options2([],_Info,_Id,true). | |
221 | check_options2([Mandatory1|Mrest],Info,Id,Verdict) :- | |
222 | ( is_list(Mandatory1) -> Mandatory = Mandatory1 | |
223 | ; otherwise -> Mandatory = [Mandatory1]), | |
224 | check_option(Mandatory,Info,Id,Verdict), | |
225 | check_options2(Mrest,Info,Id,Verdict). | |
226 | ||
227 | check_option(Mandatory,Info,_Id,_Verdict) :- | |
228 | member(M,Mandatory), | |
229 | memberchk( (M=_), Info),!. | |
230 | check_option(Mandatory,_Info,Id,false) :- | |
231 | ( Mandatory = [M] -> | |
232 | Msg = ['Missing plugin info ', M] | |
233 | ; otherwise -> | |
234 | Msg = ['Missing one plugin info of ', Mandatory]), | |
235 | ajoin(['Plugin ',Id,': '|Msg], Msg1), | |
236 | print_message(error,Msg1), | |
237 | fail. | |
238 | ||
239 | mandatory_option(name). | |
240 | mandatory_option(load_file). | |
241 | mandatory_option([file_extensions,plugin_for_modes]). | |
242 | mandatory_option(transition). | |
243 | mandatory_option(initialisation). | |
244 | ||
245 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
246 | % handling options | |
247 | ||
248 | register_info2(name,Name,Id) :- | |
249 | regassert(Id,name,pname(Name)). | |
250 | register_info2(status,Status,Id) :- | |
251 | ( memberchk(Status,[stable,unstable]) -> | |
252 | regassert(Id,name,status(Status)) | |
253 | ; otherwise -> | |
254 | ajoin(['Plugin ',Id,': Invalid status, ignoring'],Msg), | |
255 | print_message(warning,Msg)). | |
256 | register_info2(load_file,Proc,Id) :- | |
257 | reg_proc_assert(Id,load_file,file_loader,Proc,1). | |
258 | register_info2(author,Author,Id) :- | |
259 | regassert(Id,author,author(Author)). | |
260 | register_info2(file_extensions,Ext,Id) :- | |
261 | regassert(Id,file_extensions,file_extensions(Ext)). | |
262 | register_info2(transition_skeleton,Proc,Id) :- | |
263 | reg_proc_assert(Id,transition_skeleton,transition_skeleton,Proc,1). | |
264 | register_info2(transition,Proc,Id) :- | |
265 | reg_proc_assert(Id,transition,transition_pred,Proc,4). | |
266 | register_info2(initialisation,Proc,Id) :- | |
267 | reg_proc_assert(Id,initialisation,initialisation_pred,Proc,3). | |
268 | register_info2(state_property,Proc,Id) :- | |
269 | reg_proc_assert(Id,state_property,state_property_pred,Proc,2). | |
270 | register_info2(parser,Proc,Id) :- | |
271 | reg_proc_assert(Id,parser,parser_pred,Proc,6). | |
272 | register_info2(compute_expression,Proc,Id) :- | |
273 | reg_proc_assert(Id,compute_expression,compute_expression_pred,Proc,3). | |
274 | register_info2(evaluate_predicate,Proc,Id) :- | |
275 | reg_proc_assert(Id,evaluate_predicate,evaluate_predicate_pred,Proc,2). | |
276 | register_info2(evaluate_transition,Proc,Id) :- | |
277 | reg_proc_assert(Id,evaluate_transition,evaluate_transition_pred,Proc,2). | |
278 | register_info2(is_initialised_state,Proc,Id) :- | |
279 | reg_proc_assert(Id,is_initialised_state,is_initialised_state_pred,Proc,1). | |
280 | register_info2(prettyprint_transition,Proc,Id) :- | |
281 | reg_proc_assert(Id,prettyprint_transition,prettyprint_transition_pred,Proc,2). | |
282 | register_info2(prettyprint_property,Proc,Id) :- | |
283 | reg_proc_assert(Id,prettyprint_property,prettyprint_property_pred,Proc,2). | |
284 | register_info2(prettyprint_value,Proc,Id) :- | |
285 | reg_proc_assert(Id,prettyprint_value,prettyprint_value_pred,Proc,2). | |
286 | register_info2(syntax_colouring,Rules,Id) :- | |
287 | check_syntax_colouring(Rules,Id), | |
288 | regassert(Id,syntax_colouring,syntax_colouring(Rules)). | |
289 | register_info2(plugin_for_modes,Modes,Id) :- | |
290 | regassert(Id,syntax_colouring,plugin_for_modes(Modes)). | |
291 | register_info2(plugin_init,Proc,Id) :- | |
292 | reg_proc_assert(Id,plugin_init,plugin_init_pred,Proc,0). | |
293 | register_info2(new_transition_notification,Proc,Id) :- | |
294 | reg_proc_assert(Id,new_transition_notification,plugin_new_transition_pred,Proc,4). | |
295 | register_info2(preferences,Proc,Id) :- | |
296 | reg_proc_assert(Id,preferences,plugin_preferences_pred,Proc,4). | |
297 | register_info2(check_invariant,Proc,Id) :- | |
298 | reg_proc_assert(Id,check_invariant,plugin_check_invariant_pred,Proc,2). | |
299 | register_info2(output,Proc,Id) :- | |
300 | reg_proc_assert(Id,output,plugin_output_pred,Proc,3). | |
301 | register_info2(internal_representation,Proc,Id) :- | |
302 | reg_proc_assert(Id,internal_representation,plugin_internal_representation_pred,Proc,1). | |
303 | ||
304 | % helper predicates | |
305 | ||
306 | regassert(Id,Name,Fact) :- | |
307 | functor(Fact,F,Arity), | |
308 | NArity is Arity+1, | |
309 | functor(Check,F,NArity), arg(1,Check,Id), | |
310 | ( call(Check) -> | |
311 | ajoin(['Plugin ', Id, ': multiple occurence of info ', | |
312 | Name, ', ignoring'],Msg), | |
313 | print_message(warning,Msg) | |
314 | ; otherwise -> | |
315 | Fact=..[F|Args], | |
316 | NFact=..[F,Id|Args], | |
317 | assert(NFact)). | |
318 | ||
319 | reg_proc_assert(Id,Name,Fact,Proc,Arity) :- | |
320 | ( Proc = M:P/Arity -> true | |
321 | ; Proc = P/Arity -> M:P/Arity = Id:Proc | |
322 | ; otherwise -> | |
323 | ajoin(['Predicate in info ',Name,' of plugin ', | |
324 | Id,' is not valid: ',Proc],Msg), | |
325 | print_message(error, Msg),fail), | |
326 | Fact =.. [F|Args], append(Args,[M:P/Arity],AllArgs), | |
327 | NFact =.. [F|AllArgs], | |
328 | regassert(Id,Name,NFact). | |
329 | ||
330 | check_syntax_colouring(Rules,Id) :- | |
331 | ( syntax_colouring_error(Rules,Error) -> | |
332 | ajoin(['Error in syntax colouring rules for plugin ',Id, | |
333 | ': ', Error],Msg), | |
334 | print_message(warning,Msg), | |
335 | fail | |
336 | ; otherwise -> | |
337 | true). | |
338 | syntax_colouring_error([],_) :- !,fail. | |
339 | syntax_colouring_error([Rule|_],Error) :- | |
340 | syntax_colouring_error2(Rule,Error),!. | |
341 | syntax_colouring_error([_|Rest],Error) :- !, | |
342 | syntax_colouring_error(Rest,Error). | |
343 | syntax_colouring_error(_,'list expected'). | |
344 | ||
345 | syntax_colouring_error2(expression(_Regex,Type),Error) :- !, | |
346 | check_syntax_colouring_type(Type,Error). | |
347 | syntax_colouring_error2(pair(_RegexA,_RegexB,Type),Error) :- !, | |
348 | check_syntax_colouring_type(Type,Error). | |
349 | syntax_colouring_error2(_,'expected expression(Regex,Type) or pair(Begin,End,Type)'). | |
350 | ||
351 | check_syntax_colouring_type(Type,Error) :- | |
352 | Keys = [syntax_comment,syntax_keyword,syntax_type, | |
353 | syntax_assignment, syntax_operator, syntax_logical, | |
354 | syntax_unsupported], | |
355 | ( memberchk(Type,Keys) -> fail | |
356 | ; otherwise -> | |
357 | ajoin(['unexpected colouring type ',Type],Error)). | |
358 | ||
359 | % :- initialise_plugins. now done in compiletime_init_plugins | |
360 | ||
361 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
362 | ||
363 | active_plugin(Id) :- | |
364 | animation_mode(Id), | |
365 | is_registered_plugin(Id). | |
366 | ||
367 | is_registered_plugin(Id) :- | |
368 | ? | pname(Id,_Name). |
369 | ||
370 | is_registered_plugin(Id,Name) :- | |
371 | pname(Id,Name). | |
372 | ||
373 | plugin_is_stable(Id) :- | |
374 | ( status(Id,Status) -> Status==stable | |
375 | ; otherwise -> true). | |
376 | ||
377 | plugin_file_extensions(list(Ext)) :- | |
378 | get_preference(user_is_an_expert_with_accessto_source_distribution,Expert), | |
379 | findall( list([Description, list(Suffixes)]), | |
380 | ( file_extensions(Id,Ext), | |
381 | ( Expert==true -> true ; plugin_is_stable(Id) ), | |
382 | member( (Description,Suffixes), Ext)), | |
383 | Ext). | |
384 | ||
385 | available_plugins_for_mode(list(Plugins)) :- | |
386 | get_preference(user_is_an_expert_with_accessto_source_distribution,Expert), | |
387 | animation_mode(Mode), | |
388 | findall( list([Pl,Name]), | |
389 | ( plugin_for_modes(Pl,Modes), | |
390 | ( Expert==true -> true ; plugin_is_stable(Pl) ), | |
391 | member(Mode,Modes), | |
392 | pname(Pl,Name)), | |
393 | Plugins). | |
394 | ||
395 | plugin_is_available_for_mode :- | |
396 | available_plugins_for_mode(list([_|_])),!. | |
397 | ||
398 | plugins_with_preferences(list(Plugins)) :- | |
399 | get_preference(user_is_an_expert_with_accessto_source_distribution,Expert), | |
400 | findall( list([Pl,Name]), | |
401 | ( is_registered_plugin(Pl), | |
402 | ( Expert==true -> true ; plugin_is_stable(Pl) ), | |
403 | plugin_preferences_pred(Pl,_), | |
404 | pname(Pl,Name)), | |
405 | Plugins). | |
406 | ||
407 | plugin_has_preferences :- | |
408 | plugins_with_preferences(list([_|_])),!. | |
409 | ||
410 | plugin_get_output(list(Outputs),SortOfOutput) :- | |
411 | active_plugin(Id), | |
412 | plugin_output_pred(Id,Module:Pred/3), | |
413 | findall(list([Name,Output]), | |
414 | (call(Module:Pred,Name,Output,Sorts),member(SortOfOutput,Sorts)), | |
415 | Outputs). | |
416 | ||
417 | plugin_get_output(Name,Output) :- | |
418 | active_plugin(Id), | |
419 | plugin_output_pred(Id,Module:Pred/3), | |
420 | call(Module:Pred,Name,Output,_). | |
421 | ||
422 | plugin_has_output(SortOfOutput) :- | |
423 | plugin_get_output(list([_|_]),SortOfOutput). | |
424 | ||
425 | start_plugin_for_current_mode(Id) :- | |
426 | animation_mode(Mode), | |
427 | is_registered_plugin(Id), | |
428 | set_animation_mode(Id), | |
429 | set_animation_minor_mode(Mode), | |
430 | ( plugin_init_pred(Id,Module:Pred/0) -> | |
431 | call(Module:Pred) | |
432 | ; otherwise -> true). | |
433 | ||
434 | stop_plugin :- | |
435 | animation_minor_mode(Mode), | |
436 | set_animation_mode(Mode). | |
437 | stop_plugin :- | |
438 | set_animation_mode(b). | |
439 | ||
440 | tcl_plugin_syntax_colouring(Id,list(Rules)) :- | |
441 | findall(L, tcl_syntax_colouring2(Id,L), Rules). | |
442 | tcl_syntax_colouring2(Id,TclRule) :- | |
443 | syntax_colouring(Id,Rules), | |
444 | member(PRule,Rules), | |
445 | tcl_syntax_colouring3(PRule,TclRule). | |
446 | tcl_syntax_colouring3(expression(Pattern,Type), list([expression,Pattern,Type])). | |
447 | tcl_syntax_colouring3(pair(Begin,End,Type), list([pair,Begin,End,Type])). | |
448 | ||
449 | is_plugin_file_extension(Ext,Id) :- | |
450 | file_extensions(Id,AllExtensions), | |
451 | member( (_,Extensions), AllExtensions), | |
452 | member(Ext,Extensions), !. | |
453 | ||
454 | load_plugin_file(Id,Filename) :- | |
455 | user:tcltk_clear_machine, | |
456 | ( plugin_init_pred(Id,Module:Pred/0) -> | |
457 | call(Module:Pred) | |
458 | ; otherwise -> true), | |
459 | file_loader(Id,Module:Pred/1), | |
460 | call(Module:Pred,Filename),!, | |
461 | set_animation_mode(Id). | |
462 | ||
463 | setup_transition_skeleton(Id,Skeleton) :- | |
464 | transition_skeleton(Id,Module:Pred/1),!, | |
465 | call(Module:Pred,Skeleton). | |
466 | setup_transition_skeleton(_Id,_Skeleton). | |
467 | ||
468 | plugin_transition(Id,Org,Trans,Dst,Infos) :- | |
469 | ( Org==root -> | |
470 | initialisation_pred(Id,Module:Pred/3), | |
471 | call(Module:Pred,Trans,Dst,Infos) | |
472 | ; otherwise -> | |
473 | transition_pred(Id,Module:Pred/4), | |
474 | call(Module:Pred,Org,Trans,Dst,Infos)). | |
475 | ||
476 | plugin_state_property(Id,State,Property) :- | |
477 | State \== root, | |
478 | ( state_property_pred(Id,Module:Pred/2) -> | |
479 | call(Module:Pred,State,Property) | |
480 | ; otherwise -> | |
481 | Property = State). | |
482 | ||
483 | plugin_parse(Id,ExprStrings,PredStrings,TransPredStrings,Exprs,Preds,Trans) :- | |
484 | parser_pred(Id,Module:Pred/6), | |
485 | call(Module:Pred,ExprStrings,PredStrings,TransPredStrings,Exprs,Preds,Trans). | |
486 | ||
487 | plugin_compute_expression(Id,Expression,State,Result) :- | |
488 | compute_expression_pred(Id,Module:Pred/3), | |
489 | call(Module:Pred,Expression,State,Result). | |
490 | ||
491 | plugin_evaluate_predicate(Id,Predicate,State) :- | |
492 | evaluate_predicate_pred(Id,Module:Pred/3), | |
493 | call(Module:Pred,Predicate,State). | |
494 | ||
495 | plugin_evaluate_transition_predicate(Id,Predicate,Transition) :- | |
496 | evaluate_transition_pred(Id,Module:Pred/2), | |
497 | call(Module:Pred,Predicate,Transition). | |
498 | ||
499 | plugin_is_initialised_state(Id,State) :- | |
500 | ( is_initialised_state_pred(Id,Module:Pred/1) -> | |
501 | call(Module:Pred,State) | |
502 | ; otherwise -> true). | |
503 | ||
504 | plugin_get_internal(Id,InternalRepresentation) :- | |
505 | active_plugin(Id), | |
506 | plugin_internal_representation_pred(Id,Module:Pred/1), | |
507 | call(Module:Pred,InternalRepresentation). | |
508 | ||
509 | plugin_prettyprint_transition(Id,Transition,Atom) :- | |
510 | ( prettyprint_transition_pred(Id,Module:Pred/2) -> | |
511 | call(Module:Pred,Transition,Codes) | |
512 | ; otherwise -> | |
513 | write_to_codes(Transition,Codes)), | |
514 | ( atomic(Codes) -> Atom=Codes | |
515 | ; otherwise -> atom_codes(Atom,Codes)). | |
516 | ||
517 | plugin_prettyprint_property(Id,Property,Atom) :- | |
518 | ( prettyprint_property_pred(Id,Module:Pred/2) -> | |
519 | call(Module:Pred,Property,Codes) | |
520 | ; otherwise -> | |
521 | write_to_codes(Property,Codes)), | |
522 | ( atomic(Codes) -> Atom=Codes | |
523 | ; otherwise -> atom_codes(Atom,Codes)). | |
524 | ||
525 | plugin_prettyprint_value(Id,Property,Codes) :- | |
526 | ( prettyprint_value_pred(Id,Module:Pred/2) -> | |
527 | call(Module:Pred,Property,Codes) | |
528 | ; otherwise -> | |
529 | write_to_codes(Property,Codes)). | |
530 | ||
531 | notify_new_transition_to_plugin(FromId,TransId,DstId,Exists) :- | |
532 | animation_mode(Mode), | |
533 | notify_new_transition_to_plugin(Mode,FromId,TransId,DstId,Exists). | |
534 | ||
535 | notify_new_transition_to_plugin(ModeId,FromId,TransId,DstId,Exists) :- | |
536 | plugin_new_transition_pred(ModeId,Module:Pred/4), | |
537 | !, | |
538 | ( call(Module:Pred,FromId,TransId,DstId,Exists) -> | |
539 | true | |
540 | ; otherwise -> | |
541 | ajoin(['Notification of new transition failed for plugin ',ModeId,', ',call(Pred,FromId,TransId,DstId,Exists)],Msg), | |
542 | add_error(plugins,Msg)). | |
543 | notify_new_transition_to_plugin(_Id,_FromId,_TransId,_DstId,_Exists). | |
544 | ||
545 | plugin_preference_default_value(plugin(Id,Key),Value) :- | |
546 | is_registered_plugin(Id), | |
547 | plugin_preferences_pred(Id,Module:Pred/4), | |
548 | call(Module:Pred,Key,Value,_,_). | |
549 | ||
550 | plugin_preference_description(plugin(Id,Key),Description) :- | |
551 | ? | is_registered_plugin(Id), |
552 | ? | plugin_preferences_pred(Id,Module:Pred/4), |
553 | ? | call(Module:Pred,Key,_,Description,_). |
554 | ||
555 | plugin_preference_val_type(plugin(Id,Key),Type) :- | |
556 | ? | is_registered_plugin(Id), |
557 | ? | plugin_preferences_pred(Id,Module:Pred/4), |
558 | ? | call(Module:Pred,Key,_,_,Type). |
559 | ||
560 | plugin_preference_category(plugin(Id,Key), plugin(Id)) :- | |
561 | ? | is_registered_plugin(Id), |
562 | ? | plugin_preferences_pred(Id,Module:Pred/4), |
563 | ? | call(Module:Pred,Key,_,_,_). |
564 | ||
565 | plugin_check_invariantKO(IdPlugin,IdProB,State) :- | |
566 | plugin_check_invariant_pred(IdPlugin,Module:Pred/2), | |
567 | call(Module:Pred,IdProB,State). | |
568 | ||
569 |