main menu:
  » home
  » introduction
  » indigolog overview
      domain specification
      behaviour specification
  » oaa overview
  » interface model
  » developing agents
  » simple example
  » advanced example
  » other interface models
  » implementation details
  » tips
  » links

 

   

High-Level Constructs

 

Here is the list of the high-level IndiGolog constructs that are used in writing procedures. A and B denote programs. They can be single primitive actions or sequences of primitive actions/procedure calls. In IndiGolog sequences need to be included in square brackets. X denotes either a single variable or a list of variables (in square brackets).

  1. no_op - empty action

  2. A,B — sequence of actions

  3. ?(<condition>) - test whether the condition is true

  4. if(<condition>,A,B) — if <condition> is true execute A, otherwise execute B.
    Note: no_op can replace either A or B.

  5. while(<condition>,A) — while loop. While <condition> is true execute A.

  6. proc(<name of procedure>,<body of procedure>). — procedure definition. Procedures can be parametrized, so we can write something like proc(foo(a,b),[action1,action2]).

  7. <name of procedure>(<parameters>) or <name of procedure> — procedure call.

  8. ndet(A,B) — nondeterministic choice. Choose nondeterministically between program A and program B.

  9. pi(X,A) — nondeterministic choice of arguments. Nondeterministically choose a binding for the variable(s) in X and execute the program A for this binding.

  10. star(A) — nondeterministic iteration. Perform A zero or more times.

  11. conc(A,B) — concurrent execution. Execute programs A and B concurrently. Concurrent processes are modeled as interleavings of the primitive actions involved.

  12. pconc(A,B) — prioritized concurrency. Program A has higher priority than program B.

    Concurrency Note: A process may become blocked when it reaches a primitive action whose preconditions are false or test action ?(<cond>) whose condition <cond> is false. Then, execution of the program may continue provided another process executes next. In case of prioritized concurrency the lover-priority process can only be executed when the higher-priority one is done or blocked.

  13. iconc(A) — concurrent iteration. It is like nondeterministic iteration star(A), but the instances of A are executed concurrently rather than sequentially.

  14. interrupt(<condition>,<body>) — Interrupt. If the interrupt get control from higher priority process and the <condition> is true, the interrupt is triggered and its body is executed.

    interrupt(X,<condition>,<body>) — Interrupt. If the interrupt get control from higher priority process and the <condition> is true for some binding of the variables, the interrupt triggers and the body is executed with the variables taking these values.

    Once the body completes the execution, the interrupt may trigger again.

  15. prioritized_interrupts(<list of interrupts>) — Prioritized Interrupts. The interrupts are listed by their priority - the first interrupt has the highest one and so on.

    This construct is used quite commonly when writing controllers and reactive programs. You can think of this operator as an event loop: once prioritized_interrups gets control, it keeps executing. To start with, the fist interrupt clause is checked and executed if its condition evaluates to truth. Then the next interrupt is checked and possibly executed, and so on. The highest priority interrupts are the ones that require immediate response. The lower level interrupts can be checked or executed only when the higher priority ones do not fire. Of course, the condition can be set to 'true' so that the interrupt fires all the time.

  16. search(A) — By default IndiGolog programs are executed in on-line fashion: all the nondeterministic choices are treated as random ones and, and any action selected is executed immediately. On the other hand, a program in the search block is executed off-line. The interpreter must find a sequence of actions constituting a legal execution of the program A, before actually executing them.

    To illustrate the difference between on-line and off-line execution we give this example:

    ndet(a,b), A, ?(c)

    Here a and b are primitive actions, A is a program, c is some condition. The default way for IndiGolog interpreter to execute this program is to choose randomly either a or b, then execute A and then test whether c holds. It may happen that executing a and then A makes c false, thus making the program to fail. On the other hand if we put the above program inside a search block, the interpreter will search for a successful execution of the program first, and then execute it. This way we are guaranteed to find a successful execution if there is one.

    After the sequence of actions was found in the search block, it needs to be checked constantly to see if it is still valid. It is important since IndiGolog supports exogenous actions. If the previously found sequence of actions is no longer valid, replanning is done.

Conditions

IndiGolog supports quite complicated boolean conditions. Binary boolean operators such as and and or can be used, as well as unary negation operator neg. All the operators have to used in prefix notation.

In addition to the above operators IndiGolog also supports some construct, which is equivalent to existential quantification:

some(X,<boolean expression>) — X is a single variable or a list of variables. This is true if there exists a binding for the variables in X, that makes the boolean expression true.

Notes



Sensing Actions



Sensing actions are designed to get/update the value of certain fluent. The value can be calculated or received from other agent or sensor. Sensing actions are defined in the following way:

prim_action(<sensing action name>). — The usual action declaration.

poss(<sensing action name>,<condition>). — The usual precondition axiom.

execute(<sensing action name>, X) :- <sensing action body>. — Here X is a variable from the body of the action that is bound to the sensed result upon execution of the body.

senses(<sensing action name>,<name of the fluent this action updates>). — This statement links the sensing action with the fluent that it updates.

Note: Sensing actions cannot be used inside a search block.



Exogenous Actions


Agents coexist with other agents in a dynamic world. Other agents perform action that can change the environment, therefore agents must try to detect what exogenous actions have occurred in the world. IndiGolog provides a way to define monitoring routines for detecting exogenous events. The monitoring routines (provided their precondition axioms are satisfied) are tried before each primitive action. An exogenous action is considered taken place when its monitoring routine succeeds. In this case the successor state axioms for this particular exogenous action will tell the interpreter which fluents are to change their values.

exog_action(<name of exo action>). — Declare exogenous action.

exog_occurs(<name of exo action>) :- <body of exo action>.
— Define the monitoring routine. The body is written in Prolog.

poss(<name of exo action>,<condition>). — Precondition axiom. Normally the condition will be 'true', but in some cases it may be useful to suspend or cancel the execution of the exogenous event detection routines and the condition will be nontrivial.

causes_val(<name of exo action>,<fluent name>,<new value>, <condition>). — This specifies how the fluent <fluent name> changes its value after certain exogenous action occured.



 

 


 
© 2001 All Rights Reserved. See Legal Notice.