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 Markup Language Mark 1 supported with I/O primitives complying with the ideas emerged form hekate_case_io and implemented in Prolog (based on 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).
  1. The engine triggers appropriate I/O routines to provide attribute values (for ro or rw class attributes present in the conditions),
  2. it comes up with a conflict set (a set of rules for particular XTT which conditions are met),
  3. resolves it (see below) and
  4. fires appropriate rules in turn,
  5. triggers appropriate I/O routines (for all wo or rw class attributes present in the decisions),
  6. 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:

  1. if the rule has no outgoing links add it to the resolved set,
  2. 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 (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) bheart-rel-2.tar.gz
cvs -d :ext:charon.ia.agh.edu.pl/mnt/cvs/cvs-hades co -r rel-2 bheart 
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.

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 thermostat example. The actual XTT differs slightly from the one presented in hekate_case_thermostat.

The original thermostat XTT model is given below:

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:

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.

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).
hekate/beating_heart.txt · Last modified: 2019/06/27 15:49 (external edit)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0