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