/ GENTLE PRIMER
/ Describing Computations
Conditions and Actions
Predicates of the category 'condition' and 'action'
are evaluated by shallow backtracking, i.e. the rules are evaluated
until one succeeds, in which case the predicate succeeds.
Should all rules fail, the behavior is different for conditions and actions.
In the case of conditions, the predicate fails. Predicates that are supposed to fail for certain arguments are used as guards in rules: if they fail, then at the place of invocation the next rule will be considered. By way of an example, consider
'condition' IsJimsColor(Color) 'rule' IsJimsColor(red)This predicate is intended to succeed for red and to fail for all other colors.
In contrast, consider the predicate length declared above. The predicate is intended to work for all arguments. It is not used to signal failure. Such predicates are declared with the keyword 'action'. If for an action no rule is applicable, this does not indicate failure but an error in the specification. Hence, in this case an error message is issued that indicates the incomplete predicate, and the program is terminated.
For example, if we had omitted the rule dealing with the case nil, the specification of length would have be incomplete. If length had been declared as a condition, this error would not have been detected at the earliest possible point, but would simply result in failure of the rule that invoked length with an empty list. This again could propagate the failure to even wider contexts, making it hard to locate the error.
If a program is correct, all actions could be declared as conditions without changing the behavior. But if the program contains incompletely specified predicates, these can be detected much easier when using actions.
In addition, declaring a predicate as an action indicates to the human reader that this predicate is not intended to test its arguments for a certain condition, but to compute ouput values for all input values.
It turns out that the majority of predicates are actions. The reason is that, in Gentle, the program flow is controlled by pattern matching, i.e. the structure of the data being processed.