Picat is a pragmatic mix of several programming paradigms, and it supports both directional and non-directional computing.
Pattern-matching is directional. Consider the following predicate definitions:
p([a,b|_]) => true.
q([X,X]) => true.
A call p(L) succeeds only when L has at least two elements and the first two elements are a and b, respectively. A call q(L) succeeds only when L has exactly two identical elements.
Functions are directional. In Prolog, the length(L,N) predicate can be used to compute the length of L and can also be used to create a list of a given length N. In Picat, you need to use function new_list(N) to create a list, and use function len(L) to compute the length of L.
Loops are directional. Unlike in ECLiPSe-CLP where it is possible to iterate over a list that is to be created, in Picat the collection of every iterator must be fixed.
Unification is non-directional. A call X = Y is like an equality constraint over terms. Built-ins predicates, such as member(X,L) and append(L1,L2,L3), are defined by using unification, and can be used in the same way as in Prolog.
Constraints are non-directional. While a unification X = Y has a unique solution when it succeeds, a system of constraints may have multiple solutions. Picat provides a built-in, called solve, that calls the imported solver to search for a satisfactory or an optimal solution.