1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2% FILE : Interpreters/indigolog.pl 3% 4% IndiGolog Top Level Executor (Version 5) 5% 6% AUTHOR : Sebastian Sardina (prev. Hector Levesque & Maurice Pagnucco) 7% EMAIL : ssardina@cs.toronto.edu 8% WWW : www.cs.toronto.edu/~ssardina www.cs.toronto.edu/cogrobo 9% TYPE : system independent code 10% TESTED : SWI Prolog 5.0.10 http://www.swi-prolog.org 11% ECLIPSE 5.4 http://www.icparc.ic.ac.uk/eclipse/ 12% 13% This file provides the implementation for the top-level part of 14% the online IndiGolog executor. 15% 16% The main tool provided in this file is the following predicate: 17% 18% -- indigolog(E): E is an IndiGolog program 19% 20% For more information on Golog and some of its variants, see: 21% http://www.cs.toronto.edu/~cogrobo/ 22% 23%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24% 25% 26% September, 2002 27% 28% This software was developed by the Cognitive Robotics Group under the 29% direction of Hector Levesque and Ray Reiter. 30% 31% Do not distribute without permission. 32% Include this notice in any copy made. 33% 34% 35% Copyright (c) 2002-2005 by The University of Toronto, 36% Toronto, Ontario, Canada. 37% 38% All Rights Reserved 39% 40% Permission to use, copy, and modify, this software and its 41% documentation for non-commercial research purpose is hereby granted 42% without fee, provided that the above copyright notice appears in all 43% copies and that both the copyright notice and this permission notice 44% appear in supporting documentation, and that the name of The University 45% of Toronto not be used in advertising or publicity pertaining to 46% distribution of the software without specific, written prior 47% permission. The University of Toronto makes no representations about 48% the suitability of this software for any purpose. It is provided "as 49% is" without express or implied warranty. 50% THE UNIVERSITY OF TORONTO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 51% SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 52% FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TORONTO BE LIABLE FOR ANY 53% SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 54% RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 55% CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 56% CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 57% 58%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59% 60% This files provides: 61% 62% -- indigolog(+E) 63% run IndiGolog program E in the main cycle 64% -- now(-H) 65% H is the current history 66% -- pasthist(?H) 67% H is a past situation w.r.t. the current one 68% -- doingStep 69% the main cycle is computing a step 70% -- exog_action_occurred(LExoAction) 71% to report a list of exog. actions LExogAction to the top-level 72% 73% -- exists_pending_exog 74% there are exogenous events pending to be dealt 75% -- set_option(+O, +V) 76% set option O to value V. Current options are: 77% 78% + wait_step number of seconds to wait between steps 79% + debug_level level for debug messages 80% + type_manager define the type of the environment manager (thread/signal) 81% 82% -- error(+M) 83% an error has occurred with message M 84% -- warn(+M) 85% warn the user of event M 86% 87% 88% 89% The following should be provided for this file: 90% 91% LANGUAGE CONSTRUCTS IMPLEMENTATION (transition system): 92% 93% -- trans(+P,+H,-P2,-H2) 94% configuration (P,H) can perform a single step to configuration (P2,H2) 95% -- final(+P,+H) 96% configuration (P,H) is terminating 97% 98% FROM ENVIRONMENT MANAGER (eng_man.pl): 99% 100% -- execute_action(+A, +H, +T, -Id, -S) 101% execute action A of type T at history H and resturn sens. 102% S is the sensing outcome, or "failed" if the execution failed 103% Id is the identification for the action from the EM 104% -- exog_occurs(-L) 105% return a list L of exog. actions that have occurred (sync) 106% -- initializeEM/0 107% environment initialization 108% -- finalizeEM/0 109% environment finalization 110% -- set_type_manager(+T) 111% set the implementation type of the env manager 112% 113% 114% FROM TEMPORAL PROJECTOR (evalxxx.pl): 115% 116% -- debug(+A, +H, -S) 117% debug routine 118% -- pause_or_roll(+H1,-H2) 119% check if the DB CAN roll forward 120% -- can_roll(+H1) 121% check if the DB CAN roll forward 122% -- must_roll(+H1) 123% check if the DB MUST roll forward 124% -- roll_DB(+H1) 125% check if the DB MUST roll forward 126% -- initializeDB/0 127% initialize projector 128% -- finalizeDB/0 129% finalize projector 130% -- handle_sensing(+A,+H,+Sr,-H2) 131% change history H to H2 when action A is executed in history 132% H with Sr as returning sensing value 133% -- sensing(+A,-SL) : 134% action A is a sensing action with possible sensing outcome list SL 135% -- system_action(+A) : 136% action A is an action used by the system 137% e.g., the projector may use action e(_,_) to store sensing outcomes 138% 139% FROM THE SPECIFIC DOMAIN OR APPLICATION: 140% 141% -- simulateSensing(+A) 142% sensing outcome for action A is simulated 143% -- type_prolog(+P) 144% name of prolog being used (ecl, swi, vanilla, etc) 145% 146% OTHERS TOOLS (PROLOG OR LIBRARIES): 147% 148% -- sleep(Sec) : wait for Sec seconds 149% -- turn_on_gc : turns on the automatic garbage collector 150% -- turn_off_gc : turns off the automatic garbage collector 151% -- garbage_collect : perform garbage collection (now) 152% -- report_message(+T, +M) : report message M of type T 153% -- set_debug_level(+N) : set debug level to N 154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 155:- dynamic sensing/2, % There may be no sensing action 156 indi_exog/1, % Stores exogenous events not managed yet 157 now/1, % Used to store the actual history 158 rollednow/1, % Part of now/1 that was already rolled fwd 159 wait_at_action/1, % Wait some seconds after each action 160 doing_step/0, % A step is being calculated 161 pause_step/0. % Pause the step being calculated 162 163% Predicates that they have definitions here but they can defined elsewhere 164:- multifile(set_option/1), 165 multifile(set_option/2), 166 multifile(exog_action/1), % Many modules can register exog. actions 167 multifile(system_action/1). % Many modules can register system actions 168 169 170:- style_check(-discontiguous). 171% :- style_check(-singleton). 172% :- style_check(-atom). 173 174 175:- ensure_loaded(transfinal). % Load the TRANS and FINAL definitions 176 177 178 179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 180% CONFIGURATION SECTION 181% 182% This tools allow the user to tune different global options 183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 184% set_option/1/2 are used to define parameters the user can set 185% set_option/1 is used for the help tool set_option/0 186% set_option/2 is the actual definition of the parameter configuration 187 188set_option :- 189 writeln('set_option(Option, V): 190 sets Option to value V, where Options may be:'), 191 nl, 192 set_option(X), 193 tab(1), 194 writeln(X), 195 fail. 196set_option. 197 198% Set the wait-at-action to pause after the execution of each prim action 199set_option('wait_step : pause V seconds after each prim. action execution.'). 200set_option(wait_step, N) :- wait_step(N). 201 202wait_step(S) :- 203 S==0, 204 report_message(system(0), '** Wait-at-action disabled'), 205 retractall(wait_at_action(_)). 206wait_step(S) :- 207 number(S), 208 report_message(system(0), ['** Wait-at-action enable to ',S, ' seconds.']), 209 retractall(wait_at_action(_)), 210 assert(wait_at_action(S)). 211wait_step(_) :- 212 report_message(warning, 'Wait-at-action cannot be set!'). 213 214 215set_option('debug_level : set debug level to V.'). 216set_option(debug_level, N) :- 217 set_debug_level(N), 218 report_message(system(0), ['** System debug level set to ',N]). 219 220 221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 222% SOME SYSTEM BUILT-IN EXOGENOUS ACTIONS 223%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 224 225% BUILT-IN exogenous actions that will be mapped to system actions for the cycle 226exog_action(debug). % Show debugging information 227exog_action(halt). % Terminate program execution by jumping to the empty program 228exog_action(abort). % Abort program execution by jumping to ?(false) program 229exog_action(break). % Pause the execution of the program 230exog_action(reset). % Reset agent execution from scratch 231exog_action(start). % Start the execution of the program 232 233exog_action(debug_exec). % Show debugging information 234exog_action(halt_exec). % Terminate program execution by jumping to the empty program 235exog_action(abort_exec). % Abort program execution by jumping to ?(false) program 236exog_action(break_exec). % Pause the execution of the program 237exog_action(reset_exec). % Reset agent execution from scratch 238exog_action(start_exec). % Start the execution of the program 239 240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 241% MAIN LOOP 242% 243% The top level call is indigolog(E), where E is a program 244% The history H is a list of actions (prim or exog), initially [] 245% Sensing reports are inserted as actions of the form e(fluent,value) 246% 247% indigo/2, indigo2/3, indigo3/3 implement the main architecture by 248% defyining a 3-phase main cycle 249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 250init :- 251% set_option(debug_level,3), 252 report_message(system(0),'Starting ENVIRONMENT MANAGER...'), 253 initializeEM, % Initialization of environment 254 report_message(system(0),'ENVIRONMENT MANAGER was started successfully.'), 255 report_message(system(0),'Starting PROJECTOR...'), 256 initializeDB, % Initialization of projector 257 report_message(system(0),'PROJECTOR was started successfully.'), 258 reset_indigolog_dbs. % Reset the DB wrt the controller 259 260fin :- 261 report_message(system(0),'Finalizing PROJECTOR...'), 262 finalizeDB, % Finalization of projector 263 report_message(system(0),'PROJECTOR was finalized successfully.'), 264 report_message(system(0),'Finalizing ENVIRONMENT MANAGER...'), 265 finalizeEM, % Finalization of environment 266 report_message(system(0),'ENVIRONMENT MANAGER was finalized successfully.'). 267 268 269% Clean all exogenous actions and set the initial now/1 situation 270reset_indigolog_dbs :- 271 retractall(doing_step), 272 retractall(indi_exog(_)), 273 retractall(rollednow(_)), 274 retractall(now(_)), 275 update_now([]), 276 assert(rollednow([])), 277 assert((indi_exog(_) :- fail)), 278 fail. 279reset_indigolog_dbs.
285indigolog :- indigolog(none). 286indigolog(_) :- % Used to require a program, now we start proc. main always (March 06) 287 init, !, 288 (proc(main, E) -> % obtain main agent program 289 report_message(system(0),'Starting to execute the main program'), 290 indigo(E,[]), ! 291 ; 292 report_message(system(0),'No main program to execute') 293 ), 294 report_message(system(0),'Program execution finished. Closing modules...'), 295 fin, !, 296 report_message(system(0),'Everything finished - HALTING TOP-LEVEL CONTROLLER').
301indigo(E,H) :-
302 handle_rolling(H,H2), !, % Must roll forward?
303 handle_exog(H2,H3), !, % Handle pending exog. events
304 prepare_for_step, % Prepare for step
305 mayEvolve(E,H3,E4,H4,S), !, % Compute next configuration evolution
306 wrap_up_step, % Finish step
307 (S=trans -> indigo2(H3,E4,H4) ;
308 S=final -> report_message(program, 'Success.') ;
309 S=exog -> (report_message(program, 'Restarting step.'), indigo(E,H3)) ;
310 S=failed-> report_message(program, 'Program fails.')
311 ).
320indigo2(H,E,H) :- 321 indigo(E,H). % The case of Trans for tests 322indigo2(H,E,[sim(_)|H]) :- !, 323 indigo(E,H). % Drop simulated actions 324indigo2(H,E,[wait|H]) :- !, 325 pause_or_roll(H,H1), 326 doWaitForExog(H1,H2), 327 indigo(E,H2). 328indigo2(_,E,[debug_exec|H]) :- !, 329 report_message(system(0), 'Request for DEBUGGING'), 330 debug(debug, H, null), !, 331 delete(H,debug,H2), 332 indigo(E,H2). 333indigo2(_,_,[halt_exec|H]) :- !, 334 report_message(system(0), 'Request for TERMINATION of the program'), 335 indigo([], H). 336indigo2(_,_,[abort_exec|H]) :- !, 337 report_message(system(0), 'Request for ABORTION of the program'), 338 indigo([?(false)], H). 339indigo2(_,E,[break_exec|H]) :- !, 340 report_message(system(0), 'Request for PAUSE of the program'), 341 writeln(E), 342 break, % BREAK POINT (CTRL+D to continue execution) 343 delete(H,pause,H2), 344 indigo(E,H2). 345indigo2(_,_,[reset_exec|_]) :- !, 346 report_message(system(0), 'Request for RESETING agent execution'), 347 finalizeDB, 348 initializeDB, 349 proc(main, E), % obtain main agent program 350 indigo(E,[]). % restart main with empty history 351indigo2(H,E,[stop_interrupts|H]) :- !, 352 indigo(E,[stop_interrupts|H]). 353indigo2(H,E,[A|H]) :- 354 indixeq(A, H, H1), 355 indigo(E, H1). % DOMAIN ACTION 356 357% This are special actions that if they are in the current history 358% they are interpreted by the interpreter in a particular way 359% This should be seen as meta-actions that deal with the interpreter itself 360system_action(debug_exec). % Special action to force debugging 361system_action(halt_exec). % Action to force clean termination 362system_action(abort_exec). % Action to force sudden nonclean termination 363system_action(start_exec). % Action to start execution 364system_action(break_exec). % Action to break the agent execution to top-level Prolog 365system_action(reset_exec). % Reset agent execution from scratch 366 367% Wait continously until an exogenous action occurrs 368doWaitForExog(H1,H2):- 369 report_message(system(2), 'Waiting for exogenous action to happen'), 370 repeat, 371 handle_exog(H1,H2), 372 (H2=H1 -> fail ; true). 373 374% Predicates to prepare everthing for the computation of the next 375% single step. Up to now, we just disable the GC to speed up the execution 376prepare_for_step :- turn_off_gc. % Before computing a step 377wrap_up_step :- retractall(doing_step), % After computing a step 378 turn_on_gc, 379 garbage_collect. 380 381 382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 383% mayEvolve(E1,H1,E2,H2,S): perform transition from (E1,S1) to (E2,H2) with 384% result S: 385% 386% trans = (E1,H1) performs a step to (E2,H2) 387% final = (E1,H1) is a terminating configuration 388% exog = an exogenous actions occurred 389% failed= (E1,H1) is a dead-end configuration 390% system= system action transition 391% 392% There are two different implementations: 393% 394% * for Prolog's providing event handling (e.g., ECLIPSE, SWI) 395% * any vanilla Prolog 396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 397 398% If the step is a system-action, then just propagate it 399%mayEvolve(E1,[A|H1],E1,[A|H1], system):- type_action(A, system), !. 400 401mayEvolve(E1,H1,E2,H2,S):- 402 type_prolog(T) -> mayEvolve(E1,H1,E2,H2,S,T) ; 403 mayEvolve(E1,H1,E2,H2,S,van). 404abortStep :- 405 type_prolog(T) -> abortStep(T) ; abortStep(van). 406 407 408%%%%%%%%%%%%%%%%%%%%%%%%%% 409% (1) - for Prologs with ISO exception handling. (e.g., ECLIPSE and SWI) 410% 411% Notice that if a catch/3 is left via an throw/1 call, all current 412% computations and bindings are lost (e.g., the bindings on E1,H1,S,E2,H2) 413% 414mayEvolve(E1,H1,E2,H2,S,T):- (T=ecl ; T=swi), 415 catch( (assert(doing_step), % Assert flag doing_step 416 (exists_pending_exog_event -> abortStep(T) ; true), 417 (final(E1,H1,T) -> S=final ; 418 trans(E1,H1,E2,H2,T) -> S=trans ; 419 S=failed), 420 retract(doing_step) % Retract flag doing_step 421% (repeat, \+ pause_step) 422 ), exog_action, (retractall(doing_step), S=exog) ). 423 424% Abort mechanism for ECLIPSE: just throw exception 425abortStep(ecl) :- throw(exog_action). 426 427% Abort mechanism for SWI: throw exception to main thread only 428% OBS: abortStep(swi) is running in the env. manager thread 429% so by the time throw(exog_action) is executed, it could 430% be the case that thread main already retracted doing_step/0 431% from the DB and that mayEvolve/6 is already finished. In that 432% case the event should not be raised 433abortStep(swi) :- thread_signal(main, (doing_step -> throw(exog_action) ; true)). 434 435/* OBS: As it is, it is not working 100% because sometimes the execution 436is aborted and the following message is written: 437 ERROR: Unhandled exception: exog_action 438 439 This happens because the "exog_action" event was rised 440 outside the catch/3 clause!!! 441*/ 442 443 444%%%%%%%%%%%%%%%%%%%%%%%%%% 445% (2) - for "vanilla" Prolog 446% 447mayEvolve(E1,H1,E2,H2,S,van):- 448 final(E1,H1) -> S=final ; 449 trans(E1,H1,E2,H2) -> S=trans ; S=failed. 450 451abortStep(van) :- true. % No way of aborting a step in the vanilla version 452 453 454 455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 456% trans/5 and final/3 wrappers for the real trans/4 and final/3 457% 458% The last argument of trans/4 and final/3 is used to distinghuish 459% trans and final under different plataforms: ECLPSE, SWI or vanilla Prolog 460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 461 462% ECLIPSE: execute trans/4 (final/2) and, then, grounds 463% all remaining free variables using the provided fix_term/2 464final(E,H,ecl) :- mfinal(E,H), 465 (fix_term((E,H)) -> true ; true). 466trans(E,H,E1,H1,ecl):- mtrans(E,H,E1,H1), 467 (fix_term((E1,H1)) -> true ; true). 468 469% SWI: final/3 and trans/5 just reduce to final/2 and trans/4 470final(E,H,swi) :- mfinal(E,H). 471trans(E,H,E1,H1,swi):- mtrans(E,H,E1,H1). 472 473% vanilla Prolog: final/3 and trans/5 just reduce to final/2 and trans/4 474final(E,H,van) :- mfinal(E,H). 475trans(E,H,E1,H1,van):- mtrans(E,H,E1,H1). 476 477 478%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 479% EXECUTION OF ACTIONS 480% 481% indixeq(+Act,+H,-H2) is called when action Act should be executed at 482% history H. H2 is the new history after the execution of Act in H 483%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 484 485% type_action(Action, Type) : finds out the type of an action 486type_action(Act, sensing) :- sensing(Act, _), !. 487type_action(Act, system) :- system_action(Act), !. 488type_action(_, nonsensing). 489 490indixeq(Act, H, H2) :- % EXECUTION OF SYSTEM ACTIONS: just add it to history 491 type_action(Act, system), !, 492 H2 = [Act|H], 493 update_now(H2). 494indixeq(Act, H, H2) :- % EXECUTION OF SENSING ACTIONS 495 type_action(Act, sensing), !, 496 report_message(system(1), ['Sending sensing Action *',Act,'* for execution']), 497 execute_action(Act, H, sensing, IdAct, S), !, 498 (S=failed -> 499 report_message(error, ['Action *', Act, '* FAILED to execute at history: ',H]), 500 H2 = [abort,failed(Act)|H], % Request abortion of program 501 update_now(H2) 502 ; 503 report_message(action, 504 ['Action *', (Act, IdAct),'* EXECUTED SUCCESSFULLY with sensing outcome: ', S]), 505 wait_if_neccessary, 506 handle_sensing(Act, [Act|H], S, H2), % ADD SENSING OUTCOME! 507 update_now(H2) 508 ). 509indixeq(Act, H, H2) :- % EXECUTION OF NON-SENSING ACTIONS 510 type_action(Act, nonsensing), !, 511 report_message(system(1), ['Sending nonsensing action *',Act,'* for execution']), 512 execute_action(Act, H, nonsensing, IdAct, S), !, 513 (S=failed -> 514 report_message(error, ['Action *', Act, '* could not be executed at history: ',H]), 515 H2 = [abort,failed(Act)|H], 516 update_now(H2) 517 ; 518 report_message(action, ['Action *',(Act, IdAct),'* COMPLETED SUCCESSFULLY']), 519 wait_if_neccessary, 520 H2 = [Act|H], 521 update_now(H2) 522 ). 523 524% Simulated pause between execution of actions if requested by user 525wait_if_neccessary :- 526 wait_at_action(Sec), !, % Wait Sec numbers of seconds 527 report_message(system(2),['Waiting at step ',Sec,' seconds']), 528 sleep(Sec). 529wait_if_neccessary. 530 531% Updates the current history to H 532update_now(H):- 533 retract(now(_)) -> assert(now(H)) ; assert(now(H)). 534 535action_failed(Action, H) :- 536 report_message(error,['Action *', Action, '* could not be executed', 537 ' at history: ',H]), 538 halt. 539 540 541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 542% EXOGENOUS ACTIONS 543% 544% Exogenous actions are stored in the local predicate indi_exog(Act) 545% until they are ready to be incorporated into the history 546% History H2 is H1 with all pending exog actions placed at the front 547%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 548handle_exog(H1, H2) :- 549 save_exog, % Collect on-demand exogenous actions 550 exists_pending_exog_event, % Any indi_exog/1 in the database? 551 % 1 - Collect SYSTEM exogenous actions (e.g., debug) 552 findall(A, (indi_exog(A), type_action(A, system)), LSysExog), 553 % 2 - Collect NON-SYSTEM exogenous actions (e.g., domain actions) 554 findall(A, (indi_exog(A), \+ type_action(A, system)), LNormal), 555 % 3 - Append the lists to the current hitory (system list on front) 556 append(LSysExog, LNormal, LTotal), 557 append(LTotal, H1, H2), 558 update_now(H2), 559 % 4 - Remove all indi_exog/1 clauses 560 retractall(indi_exog(_)). 561handle_exog(H1, H1). % No exogenous actions, keep same history 562 563 564% Collect on-demand exogenous actions: reported by exog_occurs/1 565save_exog :- exog_occurs(L) -> store_exog(L) ; true. 566 567store_exog([]). 568store_exog([A|L]) :- assertz(indi_exog(A)), store_exog(L). 569 570% Is there any pending exogenous event? 571exists_pending_exog_event :- indi_exog(_). 572 573 574% exog_action_occurred(L) : called to report the occurrence of a list L of 575% exogenous actions (called from env. manager) 576% 577% First we add each exogenous event to the clause indi_exog/1 and 578% in the end, if we are performing an evolution step, we abort the step. 579exog_action_occurred([]) :- doing_step -> abortStep ; true. 580exog_action_occurred([ExoAction|LExoAction]) :- 581 assert(indi_exog(ExoAction)), 582 report_message(exogaction, ['Exog. Action *',ExoAction,'* occurred']), 583 exog_action_occurred(LExoAction). 584 585 586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 587% HANDLING OF ROLLING FORWARD 588% 589% handle_rolling/2: mandatory rolling forward 590% pause_or_roll/2: optional rolling forward 591% 592% Based on the following tools provided by the evaluator used: 593% 594% must_roll(H): we MUST roll at H 595% can_roll(H) : we COULD roll at H (if there is time) 596% roll_db(H1,H2): roll from H1 to H2 597%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 598handle_rolling(H1,H2) :- must_roll(H1), !, roll(H1, H2). 599handle_rolling(H1,H1). 600 601pause_or_roll(H1,H2) :- can_roll(H1), !, roll(H1, H2). 602pause_or_roll(H1,H1). 603 604roll(H1, H2) :- 605 report_message(system(0),'Rolling down the river (progressing the database).......'), 606 roll_db(H1, H2), 607 report_message(system(0), 'done progressing the database!'), 608 report_message(system(3), ['New History: ', H2]), 609 update_now(H2), % Update the current history 610 retract(rollednow(HO)), % Update the rollednow/1 predicate 611 append(H1,HO,HN), % rollednow(H): H is the full system history 612 assert(rollednow(HN)), 613 save_exog. % Collect all exogenous actions 614 615 616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 617% OTHER PREDICATES PROVIDED 618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 619 620% H is a past situation w.r.t. the actual situation (stored in clause now/1) 621pasthist(H):- now(ActualH), before(H,ActualH). 622 623% Deal with an unknown configuration (P,H) 624error(M):- 625 report_message(error, M), 626 report_message(error,'Execution will be aborted!'), abort. 627 628warn(M):- 629 report_message(warning, M). 630 631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 632% EOF: Interpreters/indigolog.pl 633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%