H:-G : B. (1)or
H:-G ? B. (2)where H is an atomic formula, G and B are two sequences of atomic formulas, the : is called a determinate choice operator, and the ? is called a nondeterminate choice operator. H is called the head, G is called the guard and B is called the body of the clause. Matching clauses must be flat. In other words, all the predicate calls occuring in guards must be in-line.
Semantically, clause (1) has the meaning that when a selected subgoal matches H (H and the subgoal become identical after some variables in H are substituted with some other terms) and the guard G succeeds, then the subgoal is rewritten into B determinately. By determinately, I mean that all the remaining clauses in the same predicate as H will never be considered. Clause (2) has the meaning that when a subgoal matching H and G succeeds, then the subgoal is rewritten into B nondeterminately. By nondeterminately, I mean that when a failure occurs in B, execution will backtrack to the next clause defining the same predicate as H.
In a guard, the one directional matching predicate X<=Y, which succeeds if Y matches X (i.e., X becomes identical to Y after some variables in X are substituted by some other terms), can be used. In a body, the assignment predicate X:=Y, which binds the variable X to Y, can be used.
For example, the following predicate
membchk(X,[X|_]):-true : true. membchk(X,[_|T]):- true : membchk(X,T).checks whether or not an element appears in a given list. It can not be used to select an element from a list. To do this, one may use the following predicate:
member(X,[Y|_]):-true ? X=Y. member(X,[_|T]):- true : member(X,T).This predicate is nondeterminate. It is possible to use this predicate to select all the elements in a given list by failure-driven backtracking.