This utility uses arithmetic and logical identities to simplify forms. Forms that can be simplified may be present in user-level code. They may also be created during the process of compilation. This function is run twice. In principle, the first pass may be unnecessary. However, it makes intermediate output easier to understand when debugging the compiler.

This is not an exhaustive list of simplifications that might be done. Our goal was to handle the easy cases, particularly forms which look really stupid in output code and impede readability.

Arithmetic identities should be applied after pre-type rewriting (so guard clauses have been generated). They do not require type markings, nor do they preserve them.

These identities are applied to the inputs of a form before the form itself is analyzed.

Forms headed by arithmetic tests (< > = <= >=) cannot receive missing inputs, because identities are applied after generation of run-time errors for missing inputs to such forms (pre-type-rewriting in step 4).

If the inputs to such a form are all numbers, the form is evaluated at compile time.

If a form headed by an arithmetic operator has any inputs that are literal make-missing (or make-missing-real or make-missing-integer) forms, simplify to (make-missing-integer). This will be converted to (make-missing-real) when appropriate by a later real contagion step.

Forms headed by any of the operations in the following list are evaluated if their inputs are all numbers.

* / + - remainder quotient modulo abs floor ceiling round truncate log exp expt sin cos tan asin acos unary-atan binary-atan bitwise-not bitwise-and bitwise-ior min max guaranteed-divide bitwise-xor arithmetic-shift

This evaluation first checks for conditions which will trigger an error and returns missing value.

- divide by a very small number (/ quotient modulo guaranteed-divide guaranteed-/)
- both inputs to binary-atan very small
- very small input to log
- negative input to sqrt
- input to asin or acos outside the range [-1, 1]
- first input smaller than second in random-real
- first input to expt very small and second input negative
- first input to expt negative and second input not an integer

Forms headed by / are simplified if the second input is 1.

Forms headed by +, *, and - are simplified if either input is the relevant identity.

A form (and expr1 expr2) is converted to #f if expr1 is false and expr1 if expr2 is false. The asymmetry expansion is due to the fact that scheme defines the order of evaluation for such forms and expr1 might trigger side-effects. If both expr1 and expr2 are booleans, the form is evaluated.

Similar rules are applied to forms headed by OR.

Forms headed by NOT are simplified if the input is a literal boolean, or if the input is also headed by NOT.

Forms headed by BINARY-IF and UNARY-IF are rewritten if their test input is a literal boolean.

The following forms are simplified:

- (inexact->exact (make-missing-real)) becomes (make-missing-integer)
- (exact->inexact (make-missing-integer)) becomes (make-missing-real)
- (inexact->exact (exact->inexact expr1)) becomes expr1
- (exact->inexact (inexact->exact expr1)) becomes expr1
- (missing? expr1) becomes #t if expr1 is (make-missing-real) or (make-missing-integer)

The case of missing? applied to pure (never missing) inputs is handled by step 4.

Ownership, Maintenance and Disclaimers

Last modified