A matching clause is a form of a clause in which the determinacy and input/output unifications are explicitly denoted. The compiler translates matching clauses into matching trees, and generates indices for all of the 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 because the generated code tends to be faster and more compact.
A determinate matching clause takes the following form:
H, G => B
where H is an atomic formula, and G and B are two sequences of atomic formulas. H is called the head, G is called the guard, and B is called the body of the clause. Calls in G cannot 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 is used instead of unification in order 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 upon 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 has already occurred, either in the head, or in 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 has already occurred. The non-variable term serves as a pattern, and the variable refers to an object that is to be matched against the pattern. This call succeeds when the pattern and the object become identical once a substitution is applied to the pattern. For instance, in a guard, the call f(X)=Y succeeds when Y is a structure whose functor is f/1.
- Term inspection
- functor(T,F,N): T must be a variable that has already occurred. The call succeeds if T's functor is F/N. F can either be 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 either be 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 has already occurred, 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 has already occurred, 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 that is 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
2013-01-25