1.2 What is TeleoR?

TeleoR is a syntactic extension of QuLog inspired by Nilsson’s Teleo-Reactive procedures robotic programming language

(https://www.jair.org/index.php/jair/article/view/10112)

It adds another form of action rules:

Robotic action rule: Guard ~> RAct ++ QAct

sequenced inside named parameterised procedures. Here RAct is a robotic action for devices external to the agent. It could be a program defined action, i.e. a TeleoR procedure call. It could even be a recursive call to the procedure in which the rule appears. QAct is an optional QuLog action. If absent the ++ is dropped. QAct is typically used to send messages to other agents, and/or to update the agent’s Belief Store.

The Guard of a TeleoR rule, which is not optional, is a QuLog direct or indirect query to the agent’s Belief Store, or the logical constant true. true is typically used as the guard of the last rule inside a procedure when we want the last rule to cover all the cases not covered by earlier rules.

The Belief Store will be being frequently updated by percept facts recording external sensor readings, as well as facts that the agent has remembered or been told by other agents. A percept handling thread atomically updates the Belief Store each time new sense data arrives, and a separate message handling thread likewise atomically updates the Belief Store when a revision of beliefs is needed as a result of a received message. These handling threads are programmed in QuLog.

Below is an example of two mutually recursive TeleoR procedure for controlling a robot arm manipulating blocks. pickup(block) and put_on_table() are primitive arm actions. The second rule of move_to_table will normally be used to put the Block being moved to the table onto the table. But the rule has guard holding(AnyBlock) in case the procedure is called when the robot arm happens to be holding another block.

tel make_clear(block)  
make_clear(Block){
    clear(Block)  ~> ()   % The goal of the procedure is achieved
    
    on(OnBlock, Block) ~>  move_to_table(OnBlock)
    % Otherwise move OnBlock, immediately above Block, to the table
    }
    
tel move_to_table(block)
move_to_table(Block){
    on_table(Block) ~> ()  
    % Goal is achieved, do nothing
    
    holding(AnyBlock) ~> put_on_table()
    % This rule puts any held block (which is typically Block) 
    % onto the table
    
    clear(Block) ~> pickup(Block)
    
    true ~> make_clear(Block)
    % Block needs to be made clear 
    }

On This Site