# 7 User-defined Actions

Actions for the Explorer can be user-defined. They must be provided as procedures to the `Explorer.object`.

## 7.1 Information Actions

`add`

  > > `{Explorer.object add(information` `+PA``
  > > label:` `+V``<= _
  > > type:` `+A``<= root`

  If PA is the atom separator, a separator entry is added as last entry of the Information Action sub menu.

  Otherwise, an entry with label V (a virtual string) is added to the Information Action sub menu, from which PA can be selected. If the `label` feature is missing, the printname of PA is taken as label instead. PA must be either a binary or ternary procedure.

  When the information action is invoked, PA is applied with the integer tagging the current node as first actual argument. The second actual argument depends on A. If A is `root` (the default) the argument is the root variable of the space attached to the current node. If A is `space` the argument is the space itself. If A is `procedure` the argument is a unary procedure P. On application, P returns the root variable of a copy of the space.

  If PA is a ternary procedure, it must return either a nullary procedure P or a pair O`#`M of an object O and a message M. When the Explorer is cleared, reset, or closed, a new thread is created that runs either `{`P`}` or `{`O`` M`}` is executed.

  For example, the default information action can be defined as follows:

  > `{Explorer.object add(information proc {$ I X}
  > {Inspector.inspect I#X}
  > end
  > label: 'Inspect')}`

`delete`

  > > `{Explorer.object delete(information` `+PA``)}`

  Deletes the information action PA from the Information Action submenu. If PA is the atom `all`, all but the default information actions are deleted from the submenu.

  For example, after adding an information action P by

  > `{Explorer add(information` P`)}`

  it can be deleted by

  > `{Explorer delete(information` P`)}`

## 7.2 Compare Actions

`add`

  > > `{Explorer.object add(compare` `+PA``
  > > label:` `+V``<= _
  > > type:` `+A``<= root`

  If PA is the atom `separator`, a separator entry is added to the bottom of the Compare Action submenu.

  Otherwise, an entry with label V (a virtual string) is added to the Compare Action submenu, from which PA can be selected. If the `label` feature is missing, the printname of PA is taken as label instead. PA must be either a $4$-ary or $5$-ary procedure. When the compare action is invoked, PA is applied with the integer tagging the compare (current) node as first (third) actual argument. The second (fourth) actual argument is the computation space attached to the compare (current) node. These arguments depend on A as explained for adding information actions.

  If PA is a $5$-ary procedure, it must return either a nullary procedure P or a pair O`#`M of an object O and a message M. When the Explorer is cleared, reset, or closed, a new thread is created that runs either `{`P`}` or `{`O`` M`}` is executed.

  For example, the default compare action can be defined as follows:

  > `{Explorer.object add(compare proc {$ I1 X1 I2 X2}
  > {Inspector.inspect I1#I2#X1#X2}
  > end
  > label: 'Inspect')}`

`delete`

  > > `{Explorer.object delete(compare` `+PA``)}`

  Deletes the compare action P from the Compare Action submenu. If PA is the atom `all`, all but the default compare actions are deleted from the submenu.

## 7.3 Statistics Actions

`add`

  > > `{Explorer.object add(statistics` `+PA``
  > > label:` `+V``<= _)`

  If PA is the atom `separator`, a separator entry is added to the bottom of the Statistics Action sub menu.

  Otherwise, an entry with label V (a virtual string) is added to the Statistics Action sub menu, from which PA can be selected. If the `label` feature is missing, the printname of PA is taken as label instead. PA must be either a binary or ternary procedure. When the information action is invoked, PA is applied with the integer tagging the current node as first actual argument. The second actual argument is a record as follows:

  > `stat(c:` ...`% number of choice nodes
  > s:` ...`% number of solved nodes
  > f:` ...`% number of failed nodes
  > b:` ...`% number of suspended nodes
  > start:` ...`% depth of current node
  > depth:` ...`% depth of current subtree
  > shape:` ...`% describes current subtree
  > )`

  The value for the feature `shape` is either `s`, `f`, or `b` with the meaning from above or a unary tuple with label `c`. The argument of the tuple is a list where the elements recursively describe the shapes of the choice node's subtrees.

  For example, invoking a statistics action on the following subtree;

  the second actual argument is as follows:

  > `stat(c:4 s:1 f:1 b:1
  > start:1
  > depth:4
  > shape: c([c([s f])
  > c([c([b])])])
  > )`

  If PA is a ternary procedure, it must return either a nullary procedure P or a pair O`#`M of an object O and a message M. When the Explorer is cleared, reset, or closed, a new thread is created that runs either `{`P`}` or `{`O`` M`}` is executed.

  For example, the default statistics action can be defined as follows:

  > `{Explorer.object add(statistics
  > proc {$ I R}
  > {Inspector.inspect I#{Record.subtract R shape}}
  > end
  > label: 'Inspect')`

`delete`

  > > `{Explorer.object delete(statistics` `+PA``)}`

  Deletes the statistics action P from the Statistics Action submenu. If PA is the atom `all`, all but the default statistics actions are deleted from the submenu.