# The And, Or, and Not Objects for PatternMatching

There are two sets of **And**, **Or**, and **Not** objects defined. The first
set represent the conventional **Boolean** objects. The second set is in the **Code**
namespace and are used with pattern matching. These objects can take objects of type
**Boolean** or **PatternMatch** as parameters. When the **And**, **Or**, and
**Not** in the **Code** namespace contain multiple match objects, they build the
appropriate cumulative binding list as the match expressions are executed.

## The And Object

The **And** object in the **Code** namespace provides a convenient way to express a
requirement that multiple expressions each match to a corresponding pattern. For
example:

A **Boolean** expression is a subtype of a **PatternMatch**, so an **And** term
can contain a combination of match objects and conventional boolean expressions. For
example:

An **And** expression can also contain only **Boolean** expressions. In this case,
there is no pattern matching and the behavior of the **Code.And** object is the same as
the conventional **Boolean**
**And**.

Note that an **Assert** expression containing an **And** term in the pattern match
can be expressed in terms of nested **Assert** expressions. For example, these two
clauses are equivalent:

And[ { a -> b }, { c -> d }] => expr

{ a -> b } => { c -> d } => expr

This means that varibles bound in a pattern match in the first term of and And expression can be used in a later pattern match in the And expression.

## The Or Object

The **Or** object in the **Code** namespace provides a convenient way to express a
requirement that at least one of several pattern match expressions must succeed. For
example:

Like the **And** object, the **Or** object can also contain conventional
**Boolean** expressions and behaves like the **Boolean Or** in this case.

Note that an **Assert** expression containing an **Or** term in the pattern match can
be expressed as an **ElseList** of clauses. For example, these two clauses are
equivalent:

Since each of the pattern match terms in the **Or** expression are evaluated separately,
any variable bound in the first term of an **Or** expression are not carried over into
later terms the way they are in an **And** expression.

## The Not Object

The **Not** object succeeds if the **PatternMatch** in its parameter would fail to
generate a match. The **Not** object always returns an empty binding list. The **Not**
object is implemented by evaluating the **PatternMatch** object passed into its
parameter. If that match returns one or more valid lists of bindings, then the **Not**
fails. If the **PatternMatch** doesn't return any binding lists, then the **Not**
succeeds. The following two clauses are equivalent and illustrate how the **Not** object
is implemented:

A **Not** expression never generates any additional bindings to variables. For example,
in the match expression:

Not[Match[x + y, a + b/c]]

the match succeeds, but it does not generate a binding between the variable "*a*" and
"*x*".

The **And**, **Or**, and **Not** objects can be nested in a match expression when
needed.