|COGENT Version 2.2 Help|
See also: Built-in Conditions
A (rule-based) process is a box whose behaviour is defined in terms of a set or rules. A rule is just a condition/action pair. The conditions of a rule evaluate to true or false. In doing so they may also bind or instantiate variables within the rule. The actions are a list of messages that should be sent to specified destinations if the rule's conditions are true. Variables contained in a rule's actions will be bound to the values they were given in the evaluation of the rule's conditions.
In general a process will produce output, e.g., by scanning and acting on information in one or more buffers, or by reacting to an input message (or by a combination of the two). The rules which define a process' behaviour are of two basic sorts: autonomous (or active) rules, and triggered (or passive) rules. Autonomous rules test their conditions on every processing cycle and fire when their conditions are met. Triggered rules only test their conditions when they are triggered by the arrival of an appropriate message. Autonomous and triggered rules may be mixed freely within a single process.
The precise behaviour of processes is determined by the rules they contain and three properties:
Initialise (possible values: Each Trial/Each Block/Each Subject/Each Experiment/Each Session;
default: Each Trial)
This property determines the timing of process initialisation. When the value is Each Trial, the process will automatically initialise itself at the beginning of each trial. When the value is Each Block, initialisation will only occur at the beginning of each block. Analogous comments apply when the initialisation level is set at each subject, experiment or session. Initialisation of a process controls the scope of refractory checking within that process. Thus, each instantiation of a refracted rule within a process that is initialised on each block may fire once per block. If initialisation is set to each trial, however, the same instantiation may fire once each trial (and hence on multiple occasions throughout a block of trials).
Recurrent (possible values: Yes/No; default: Yes)
Recurrent processes are able to send messages to themselves. Non-recurrent processes just take in information, process it, and send it on, but recurrent processes are able to feed their output back into themselves.
Firing Rate (possible values: 0.0 -- 1.0; default: 1.0)
This property gives the probability of a process' rules firing when their conditions are satisfied. Normally a rule will fire whenever its conditions hold (and, in the case of triggered rules, it receives a triggering message), but by setting a process' firing rate to (for example) 0.5, we can specify that rules should only fire on half of the occasions that firing is possible. This property is primarily intended to allow investigation of the effects of partial damage to a model, corresponding, for example, to neural damage.
The rule editor is the most complex part of COGENT, since it permits the user to create rules of arbitrary complexity, using a full-featured programming language based on the logic programming language Prolog. A full description of Prolog is beyond the scope of this help system; however, the rule editor makes the process considerably easier than standard Prolog programming, since it handles much of the syntax checking and provides many functions through a series of pull-down menus, so non-programmers should find it fairly easy to use.
The rule editor is invoked from a process' Rules & Condition Definitions page by either inserting a rule into a process (by right-clicking on the canvas) or by double-clicking on an existing rule (on the canvas). Figure 1 shows an example rule editor opened on a rule of moderate complexity.
Three Boolean options are displayed at the top of the rule editor window (immediately under the Comment field and the Apply and Done buttons). These options control the firing properties of the rule. By default, rules will attempt to fire as many times as they can on each cycle; basically, they fire only if their conditions are satisfied. Each option further constrains the default firing behaviour of the rule:
Rule is triggered
If this box is checked, the rule will not attempt to fire unless it receives a message which matches its Triggering pattern. The Triggering pattern field is only active if the Rule is triggered box is checked, otherwise it is greyed out. If Rule is triggered is not checked, the rule will attempt to fire on each cycle.
Rule is refracted
A refracted rule will fire only once with each pattern of instantiations of its variables during a given period, where the period is determined by the process' Initialise property.
Rule fires once per cycle
In general, each time a rule fires it generates a new set of bindings for its variables. By default, if multiple different solutions are possible the rule will fire once for each possibility, and moreover, if more than one possibility exists on a given cycle, the rule will fire as many times as are possible on that cycle. If this option is checked, however, the rule will fire a maximum of once on any given cycle. If Rule is refracted is also checked, different solutions will always be produced on different cycles.
The remainder of the rule editor is concerned with defining the conditions and actions of the rule. New conditions may be added by clicking on the Add condition button. This pops up a menu of condition types. The type of condition selected by the user will then be added to the bottom of the condition list. Similarly, actions may be added by clicking on the Add action button and selecting the appropriate type of action. Again the new action will be added to the bottom of the list of already defined actions.
A pull-down menu at the left-hand side of each condition permits a variety of modifications to the condition, such as changing the type of the condition, deleting it, qualifying it or inserting a new condition above or below it. The Change condition type, Insert before condition and Insert after condition commands each have a system of sub-menus which permit a large range of built-in condition types to be selected, including conditions dealing with list processing, term comparison, arithmetic and general Prolog. It is possible, therefore, to create compound conditions of arbitrary complexity and power.
The Add qualifier option permits control over the precise operation of the condition, for example by negation or quantification. By default, conditions are universally quantified, that is, they will re-satisfy as many times as they can, but they can be forced to satisfy only once in the present invocation of the rule by using the once qualifier. Using the not qualifier makes the compound condition satisfy only if the sub-condition is not met. It is possible to add sub-conditions within the scope of a qualifier, by using the pull-down menu directly to the right of the qualifier. As with top-level conditions, this menu permits inserting sub-conditions above or below, adding (or deleting) further qualifiers, or changing or deleting the sub-condition.
Finally, the rule editor permits the user to specify the actions which are to be carried out if the rule's conditions are met. The specification of a rule's actions follows exactly the specification of messages within a data source. This is possible because the actions of a rule are just a list of messages.
The condition editor is invoked whenever the user attempts to create or modify a condition. Conditions should only be found within processes, and may be edited by following the general procedure for editing all box elements (i.e., double clicking on the condition, or selecting Edit... from the menu that appears after right-clicking on the condition).
New conditions may be created within a process by either left-clicking on the condition icon on the palette associated with the process' Rules & Condition Definition page and the left-clicking again on the Rules & Condition Definition canvas or copying existing ones (by selecting Duplicate from the menu that appears after right-clicking on the condition).
Conditions are basically raw Prolog. Some of their more advanced uses, especially those involving recursion, definitely require a reasonable understanding of Prolog. However, it is worth noting that if several rules have the same sequence of sub-conditions in common, then the process of rule writing can be made easier, and the rules themselves made simpler and clearer, by defining a condition separately from the rules and then calling the defined condition in each rule.
The condition editor is designed to simplify the process of writing Prolog conditions by forcing the appropriate structure on those conditions and preventing common syntax errors. Figure 2 shows the condition definition editor.
Each condition consists of one or more clauses, and each clause is composed of a head, which is a Prolog structure, with a functor and zero or more arguments, and optionally a body, composed of sub-conditions. The Functor field in the condition editor allows the user to modify the functor name, and changes here are reflected in all clauses of the condition. Similarly, the number of arguments is controlled by the No. of args widget; changing this value will change the number of argument fields available in the head of each clause.
As well as a head, each clause may have a body, which is composed of sub-conditions. A pull-down menu at the left of the clause allows the user to add, delete, change or qualify sub-conditions in a manner already familiar from the Rule Editor, and this menu makes the same built-in conditions available.
Any conditions which the user defines become available for selection through the pull-down condition-editing menus in both the Rule Editor and Condition Definition Editor.
COGENT supports a small number of special triggers for the control of execution. These are system_end(Level) and stop.
This trigger is sent to any rule which responds to it, on execution of a corresponding end(Level) script command. Level may be one of trial, block, subject, experiment or session. This trigger is intended for use by processes which control experiments, for example to trigger statistical processes at the end of a trial, block, subject or experiment.
Note that system_end(trial) replaces the system_quiescent trigger used to detect the end of a trial in very early versions of COGENT. All old-style system_quiescent triggers are automatically converted to system_end(trial) internally, for backward compatibility.
If a stop message is sent to any box, the box will be completely halted until the next initialisation. If the box is a compound then all child boxes will be stopped. stop takes effect immediately, overriding any other messages sent on the same cycle to that box.
|COGENT Version 2.2 Help|