Gentle has a predefined predicate where that merely copies its input to its output. It is defined for each type T
'action' where(T -> T) 'rule' where(X -> X)This can be used to define variables. For example,
where(red -> Col)defines Col as red
Consider the predicate max with rules
'rule' max(X, Y -> X): ge(X, Y) 'rule' max(X, Y -> Y): lt(X, Y)If we want to replace an invocation
max(A, B -> C)we can write
(| ge(A, B) where(A -> C) || lt(A, B) where(B -> C) |)Here, C is defined as the maximum of A and B.
In the example, an alternative was selected by giving a condition such as ge as a guard. If we wish to replace a predicate inline, the rules of which are selected by pattern matching, we have to use a different device.
Again, we can use the predefined predicate where. If we supply a pattern as the output value the input value is matched against this pattern. The pattern may contain variables, which are defined if matching succeeds. For examples,
where(Col -> red)succeeds if Col is red.
Consider the predicate MapType(Type -> Rep) with rules
'rule' MapType(array(N,Type) -> Rep): ArrayType(N,Type -> Rep) 'rule' MapType(int -> Rep): IntType(-> Rep)An invocation
MapType(Type -> Rep)can be replaced by
(| where(Type -> array(N, Type)) ArrayType(N, Type -> Rep) || where(Type -> int) IntType(-> Rep) |)Here, Rep is defined in both alternatives, and therefore by the whole alternative statement. N and Type are variables that are local to the first alternative.