Author image Christophe IVORRA
and 1 contributors


Chorus::Frame - A short implementation of frames from knowledge representation.


Version 1.04


  use Chorus::Frame;
  my $f1 = Chorus::Frame->new(
     b => {
             _DEFAULT => 'inherited default for b'

  my $f2 = Chorus::Frame->new(
    a => { 
           b1 => sub { $SELF->get('a b2') }, # procedural attachment using context $SELF
           b2 => {
                   _ISA    => $f1->{b},
                   _NEEDED => 'needed for b  # needs mode Z to precede inherited _DEFAULT
  Chorus::Frame::setMode(GET => 'N');
  print $f2->get('a b1') . "\n";       # print 'inherited default for b'

  Chorus::Frame::setMode(GET => 'Z');
  print $f2->get('a b1') . "\n";       # print 'needed for b'


  - A frame is a generic object structure described by slots (properties).
  - A frame can inherit slots from other frames.
  - A frame can have specific slots describing :
    * how it can be associated to a target information, 
    * how he reacts when its target information changes
    * what it can try when a missing property is requested.
  - The slots _VALUE,_DEFAULT,_NEEDED are tested in this order to obtain the target information 
    of a given frame (can be inherited).
  - Two other special slots _BEFORE & _AFTER can define what a frame has to do before or after 
    one of its properties changes.
  - The slot _ISA is used to define the inheritance. 

  Two modes 'N' (default) or 'Z' are used to define the priority between a frame and its inherited 
  frames in order to process its target information
  The globale variable $SELF returns the current CONTEXT which is the most recent frame called for the method get().
  A slot defined by a function sub { .. } can refer to the current context $SELF in its body.
  All frames are automaticaly referenced in a repository used to optimise the selection of frames for a given action.
  The function fmatch() can be used to quicly select all the frames responding to a given test on their properties.  



 Defines the inheritance mode of methods get() for the special slots _VALUE,_DEFAULT,_NEEDED
 the default mode is 'N'.
    'N' : ex. a single slot from the sequence _VALUE,_DEFAULT,_NEEDED will be tested in all inherited
              frames before trying the next one.
    'Z' : the whole sequence _VALUE,_DEFAULT,_NEEDED will be tested from the frame before being 
          tested from the inherited frames
    ex. Chorus::Frame::setMode(GET => 'Z');



  my @k = $f->_keys;
  same as CORE::keys but excludes the special slot '_KEY' specific to all frames


  push new elements to a given slot (becomes an array if necessary)


  add inherited new frame(s) outside constructor
  ex. $f->_inherits($F1,$F2);


  Constructor : Converts a hashtable definition into a Chorus::Frame object.
  Important - All nested hashtables are recursively converted to Chorus::Frame,  
              except those providing a slot _NO_FRAME
  All frames are associated to a unique key and registered in an internal repository (see fmatch)
  Ex. $f = Chorus::Frame->new(
                       slotA1 => {
                              _ISA   => [ $f2->slotA, $f3->slotA ] # multiple inheritance
                              slotA2 => sub { $SELF };             # procedural attachements
                              slotA3 => 'value for A3'
                       slotB => {
                              _NEEDED => sub { .. }


This method provides the information associated to a sequence of slots. This sequence is given in a string composed with slot names separated by spaces. The last slot is tested for the target information with the sequence _VALUE,_DEFAULT,_NEEDED. If a frame doesn't provide any of those slots, the target information is the frame itself.

A frame called with the method get() becomes the current context wich can be referred with the variable $SELF.

Note - The short form $f->SLOTNAME() can by used instead of $f->get('SLOTNAME');

Ex. $f->foo; # equiv to $f->get('foo'); $f->foo(@args); # equiv to $f->get('foo')(@args);

    $f->get('foo bar');        # $SELF (context) is $f while processing 'bar'

    $f->get('foo')->get('bar') # $SELF (context) is $f->foo while processing 'bar'
    $f->foo->bar;              # short form


   All Frames properties are registered in a single table, especially to optimize the method fmatch().
   This why frames have to use the form $f->delete($slotname) instead of delete($f->{$slotname})
   otherwise a frame will be considered by fmatch() as providing a slot even after this one have been removed.


   This method tells a frame to associated target information to a sequence of slots
   A frame called for this method becomes the new context.

    Ex. $f1 = Chorus::Frame->new(
          a => {
                  b => { 
                        c => 'C'
    $f1->set('a b', 'B');  # 'B' becomes the target _VALUE for $f1->get('a b')
    $f1->get('a b');       # returns 'B'

    $f1->get('a b c');     # still returns 'C'
    $f1->delete('a b c');
    $f1->get('a b c');     # undef

    $f2 = Chorus::Frame->new(
          _ISA => $1,

    $f2->get('a b c');     # returns 'C'
    $f2->set('a b', 'AB'); # cancel inheritance for first slot 'a'
    $f2->get('a b');       # returns 'AB'

    $f2->get('a b c');     # undefined


 This function returns the list of the frames providing all the slots given as argument.
 The result can contains the frames providing these the slots by inheritance.
 This function can be used to minimise the list of frames that should be candidate for a given process.
 An optional argument 'from' can provide a list of frames as search space
 ex. @l = grep { $_->score > 5 } fmatch(
                                         slot => ['foo', 'score'],
                                         from => \@framelist       # optional : limit search scope
     # all frames, optionnaly from @framelist, providing both slots 'foo' and 'score' (possible 
     # inheritance) and on which the method get('score') returns a value > 5


Christophe Ivorra, <ch.ivorra at>


Please report any bugs or feature requests to bug-chorus-frame at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


You can find documentation for this module with the perldoc command.

    perldoc Chorus::Frame

You can also look for information at:



Copyright 2013 Christophe Ivorra.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.