## FORWARD-CHAINING

make a rule to forward chain when a certain trigger arises
```Major Section:  RULE-CLASSES
```

See rule-classes for a general discussion of rule classes and how they are used to build rules from formulas. An example `:``corollary` formula from which a `:forward-chaining` rule might be built is:

```Example:
(implies (and (p x) (r x))        when (p a) appears in a formula to be
(q (f x)))               simplified, try to establish (r a) and
if successful, add (q (f a)) to the
known assumptions
```
To specify the triggering terms provide a non-empty list of terms as the value of the `:trigger-terms` field of the rule class object.

```General Form:
Any theorem, provided an acceptable triggering term exists.
```
Forward chaining rules are generated from the corollary term as follows. First, every `let` expression is expanded away (hence, so is every `let*` and `lambda` expression), as is every call of a so-called ``guard holder'' (`must-be-equal`, `prog2\$`, `ec-call`, `mv-list`, `the`). If the resulting term has the form `(implies hyp concl)`, then `concl` is treated as a conjunction, with one forward chaining rule with hypothesis `hyp` created for each conjunct. In the other case, where the corollary term is not an `implies`, we process it as we process the conclusion in the first case.

The `:trigger-terms` field of a `:forward-chaining` rule class object should be a non-empty list of terms, if provided, and should have certain properties described below. If the `:trigger-terms` field is not provided, it defaults to the singleton list containing the ``atom'' of the first hypothesis of the formula. (The atom of `(not x)` is `x`; the atom of any other term is the term itself.) If there are no hypotheses and no `:trigger-terms` were provided, an error is caused.

A triggering term is acceptable if it is not a variable, a quoted constant, a lambda application, a `let`- (or `let*`-) expression, or a `not`-expression, and every variable symbol in the conclusion of the theorem either occurs in the hypotheses or occurs in the trigger.

`:Forward-chaining` rules are used by the simplifier before it begins to rewrite the literals of the goal. (Forward chaining is thus carried out from scratch for each goal.) If any term in the goal is an instance of a trigger of some forward chaining rule, we try to establish the hypotheses of that forward chaining theorem (from the negation of the goal). To relieve a hypothesis we only use type reasoning, evaluation of ground terms, and presence among our known assumptions. We do not use rewriting. So-called free variables in hypotheses are treated specially; see free-variables. If all hypotheses are relieved, we add the instantiated conclusion to our known assumptions.

Caution. Forward chaining does not actually add terms to the goals displayed during proof attempts. Instead, it extends an associated context, called ``assumptions'' in the preceding paragraph, that ACL2 builds from the goal currently being proved. The context starts out with ``obvious'' consequences of the negation of the goal. For example, if the goal is

```(implies (and (p x) (q (f x)))
(c x))
```
then the context notes that `(p x)` and `(q (f x))` are non-`nil` and `(c x)` is `nil`. Forward chaining is then used to expand the context. For example, if a forward chaining rule has `(f x)` as a trigger term and has body `(implies (p x) (r (f x)))`, then the context is extended by binding `(r (f x))` to non-`nil`. Note however that since `(r (f x))` is put into the context, not the goal, it is not further simplified. If `f` is an enabled nonrecursive function symbol then this forward chaining rule may well be useless, since calls of `f` may be expanded away.

However, forward-chaining does support the linear arithmetic reasoning package. For example, suppose that forward-chaining puts `(< (f x) (g x))` into the context. Then this inequality also goes into the linear arithmetic data base, together with suitable instances of linear lemmas whose trigger term is a call of `g`. See linear.