A matching clause is a form of a clause where the determinacy and input/output unifications are denoted explicitly. The compiler translates matching clauses into matching trees and generates indexes for all input arguments. The compilation of matching clauses is much simpler than that of normal Prolog clauses because no complex program analysis or specialization is necessary; and the generated code tends to be more compact and faster.
A determinate matching clause takes the following form:
H, G => B
where H is an atomic formula, G and B are two sequences of atomic formulas. H is called the head, G the guard, and B the body of the clause. No call in G can bind variables in H and all calls in G must be in-line tests. In other words, the guard must be flat.
For a call C, matching rather than unification is used to select a matching clause in its predicate. The matching clause 'H, G => B' is applicable to C if C matches H (i.e., C and H become identical after a substitution is applied to H) and G succeeds. When applying the matching clause to C, the system rewrites C determininately into B. In other words, when execution backtracks to C, no alternative clauses will be tried.
A non-determinate matching clause takes the following form:
H, G ?=> B
It differs from the determinate matching clause 'H, G => B' in that the rewriting from H into B is non-determinate. In other words, the alternative clause will be tried on backtracking.
The following types of predicates can occur in G:
- Type checking
- integer(X), real(X), float(X), number(X), var(X), nonvar(X), atom(X), atomic(X): X must be a variable that occurs before in either the head or some other call in the guard.
- Matching
- X=Y: One of the arguments must be a non-variable term and the other must be a variable that occurs before. The non-variable term serves as a pattern and the variable refers to an object to be matched against the pattern. This call succeeds when the pattern and the object become identical after a substitution is applied to the pattern. For instance, the call f(X)=Y in a guard succeeds when Y is a structure whose functor is f/1.
- Term inspection
- functor(T,F,N): T must be a variable that occurs before. The call succeeds if the T's functor is F/N. F can be either an atom or a variable. If F is not a first-occurrence variable, then the call is equivalent to functor(T,F1,N),F1==F. Similarly, N can be either an integer or a variable. If N is not a first-occurrence variable, then the call is equivalent to
functor(T,F,N1),N1==N.
- arg(N,T,A): T must be a variable that occurs before and N must be an integer that is in the range of 1 and the arity of T, inclusive. If A is a first-occurrence variable, the call succeeds and binds A to the Nth argument of T. If A is a variable that occurs before, the call is equivalent to arg(N,T,A1),A1==A. If A is a non-variable term, then the call is equivalent to arg(N,T,A1),A1=A where A is a pattern and A1 is an object to be matched against A.
- T1 == T2: T1 and T2 are identical terms.
T1 \== T2: T1 and T2 are not identical terms.
- Arithmetic comparisons
- E1 =:= E2,
E1 =\= E2, E1 > E2, E1 >= E2, E1 < E2, E1 =< E2: E1 and E2 must be ground expressions.
Subsections
Neng-Fa Zhou
2012-01-03