====== Beating HeaRT ====== ===== Docs ===== More docs available upon request from the author: wojnicki@agh.edu.pl. ===== Concept ===== The main concept is to provide a runtime environment for the [[:hekate:hml1| Hekate Markup Language Mark 1]] supported with I/O primitives complying with the ideas emerged form [[hekatedev:hekate_case_io]] and implemented in Prolog (based on [[hekatedev:hekate_prolog_io]]) or Java. The runtime is coded in Prolog (guess why ;-)). ==== Starting inference process ==== The inference process must be explicitly started from an indicated XTT table by using ''run_xtt_single/1'' predicate: run_xtt_single(xtt_0). - The engine triggers appropriate I/O routines to provide attribute values (for ''ro'' or ''rw'' class attributes present in the conditions), - it comes up with a conflict set (a set of rules for particular XTT which conditions are met), - resolves it (see below) and - fires appropriate rules in turn, - triggers appropriate I/O routines (for all ''wo'' or ''rw'' class attributes present in the decisions), - switches to the next XTT associated with the fired rules. The inference process ends if there are no rules to fire (fails), or if the last fired rule has no outgoing links (succeeds). For future releases it might be desired to have an algorithm which finds which XTT should the inference process start with. It could be an XTT without incoming links, however it is still subject to further research. ==== Conflict set resolution ==== The conflict set is built with rules which conditions are met. It is resolved in the following way: - if the rule has no outgoing links add it to the resolved set, - if there is a rule with an outgoing link/links add it to the resolved set and stop the conflict set resolution. ==== I/O ==== Appropriate trigger routines are called for ''ro'', ''rw'', ''wo'' class attributes. To define a routine a predicate ''io/3'' is used: io(att_12,ro_trigger,get_character). io(att_10,wo_trigger,write_chars_to_file). The above defines that an attribute with unique identifier ''att_12'' has a routine ''get_character/1'' defined which will be spawned before reading attribute value (the attribute is ''ro'' or ''rw'' class). Furthermore ''att_10'' has ''write_chars_to_file/2'' which will be spawned after the rule, with such an attribute in the condition part, is fired. :!: Comparing to the original idea ([[hekatedev:hekate_prolog_io]]) there is a slight adjustment. Attribute values are passed to/for the trigger routines as list. Attribute values are passed as lists, single element list for single valued attributes, multiple element list for multiple valued attribute. See example below. :!: ==== Avaliable operators ==== The following operators are defined in ''operators.pl'' file. The implementation is far from being complete, just a few operators are defined at present to cover the editor case FIXME. These operators are used in ''editor-model.xttml''. === Evaluative === * add -- evaluates to a sum of 1st and 2nd argument * sub -- evaluates to a difference of 1st and 2nd argument * insert -- inserts a value into a multivalued attribute at given index * remove -- removes a value from a multivalued attribute at a given index === Logical === * eq -- checks for equality * neq -- checks for inequality * in -- checks if 1st argument is within a set * nin -- checks if 1st argument is not within a set * gt -- geater than (available from release-2) * lt -- less than (available from release-2) === Modification === * assign -- assigns a value to an attribute ===== Availability ===== Current development vresion: cvs -d :ext:charon.ia.agh.edu.pl/mnt/cvs/cvs-hades co bheart Releases: * Second release, thermostat case added, more logical operators (to make the thermostat case work) {{:hekate:bheart-rel-2.tar.gz}} cvs -d :ext:charon.ia.agh.edu.pl/mnt/cvs/cvs-hades co -r rel-2 bheart * First realase, the test case (editor) works fine: {{:hekate:bheart-rel-1.tar.gz|}} cvs -d :ext:charon.ia.agh.edu.pl/mnt/cvs/cvs-hades co -r rel-1 bheart ===== Modules ===== The inference engine is highly modularized. It consists of the following modules: * hml.pl - Hekate Markup Language ([[HML1]]) support * infeng.pl - inference engine * operators.pl - available operators * prolog-runtime.pl - prolog i/o predicates * runtime.pl - auxiliary runtime predicates * hml-view.pl - HML visualization support (markup independent), not mandatory for run-time execution; spawns graphviz and generates XTT diagrams (yet to be released, avaliable through CVS only) This way the Beating HeaRT can be extended easily. ===== I/O Modules ===== There are two I/O modules currently available for the Inference Engine. They allow to call apropriate trigger routines for non-state attributes which are implemented as Prolog predicates or Java methods. ===== Examples ===== ==== Editor ==== The following example is included in the Beating Heart in a file: ''test-bheart.pl''. It provides logic for a simple text editor. The editor is capable of reading in characters into a buffer (''chars'') which contents is displayed at any change (''chars'' is ''wo'' class) along with the value of ''cursor'' attribute, which represents cursor position. There are following key sequences covered by the rules: * ^o -- open a file, currently it resets the buffer (implemented by ''read_chars_from_file/1'' predicate), * ^s -- save -- displays current contents of the buffer (implemented by ''write_chars_to_file/2''), * backspace -- obvious, * ^j -- moves the cursor left, * ^k -- moves the cursor right, * ^q -- quits. The XTT editor model is given below (click to enlarge). The model is generated by the Beating HeaRT visualization plugin. {{:hekate:editor-xtt-bh.png?800|}} The following code, loads up The Beating HeaRT, reads in logic, defines all I/O routines for apropriate attributes and launches the inference process. :- [bheart]. % consulting the Beating Heart %:-assert(bheart(debug)). % to enable b heart debugging :-hml_load('editor-model.xttml'). % loading up model. % defining i/o routines % general i/o % inkey io(att_12,ro_trigger,get_character). % inchar io(att_8,ro_trigger,read_chars_from_file). % outchar io(att_10,wo_trigger,write_chars_to_file). % editor content output % chars: io(att_3,wo_trigger,display_chars). % cursor io(att_4,wo_trigger,display_cursor). % single character input get_character([Char]):- get_single_char(C), resolve_character(C,Char),!. resolve_character(15,"^o"). resolve_character(19,"^s"). resolve_character(17,"^q"). resolve_character(10,"left"). resolve_character(11,"right"). resolve_character(127,"backspace"). resolve_character(C,[C]). % editor content output display_chars(X,X) :- write('on screen->>>:'),maplist(putvalues,X),nl. display_cursor([X],[X]):- write('cursor at->>>:'), write(X),nl. % file i/o read_chars_from_file(["T","h","i","s"," ","i","s"," ","r","e","a","d"," ","i","n","."]). write_chars_to_file(X,X):- write('file output->>>:'),maplist(putvalues,X),nl. putvalues([]):- put(' '). putvalues([13]):- nl. putvalues([X]):- put(X). % starting the inference process :-run_xtt_single(xtt_0). ==== Thermostat ==== The following example is included in the Beating Heart in a file: ''test-therm.pl''. It is a famous [[hekate_case_thermostat|thermostat example]]. The actual XTT differs slightly from the one presented in [[hekate_case_thermostat]]. The original thermostat XTT model is given below: {{:hekate:thermostat-xtt.png?800}} There is a question to be asked: which rules should be interpreted first, these from table id 1, or these from table id 2 ? To eliminate such an ambiguity an alteration is performed which results in the following XTTs: {{:hekatedev:thermostat-xtt-bh.png?800}} Now it is easy to assume that the inference process hsould start with Table id 1. The following visualization is generated by the Beating HeaRT visualization module. {{:hekate:therm-xtt-bh.png?800|}} The following code, loads up The Beating HeaRT, reads in logic, defines all I/O routines for appropriate attributes and launches the inference process. Since input has to be delivered to the inference engine, it spawns appropriate I/O routines to get actual month, hour, and day of week. :- [bheart]. % consulting the Beating Heart %:-assert(bheart(debug)). % to enable b heart debugging :-hml_load('therm-model.hml'). % loading up model. % defining i/o routines % day io(att_7,ro_trigger,get_day). % month io(att_8,ro_trigger,get_month). % hour io(att_10,ro_trigger,get_hour). % thermostat_settings io(att_11,wo_trigger,set_temperature). get_day([Day]):- write('Day of week (in double quotes, ending with period: "tue".):'), read(Day). get_month([Month]):- write('Month (numeric):'), read(Month). get_hour([Hour]):- write('Hour (numeric):'), read(Hour). set_temperature(X,X) :- write('temperature->>>:'),write(X),nl. % starting the inference process :-run_xtt_single(xtt_0).