Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
a {{boolExp}} is either:
   *  a boolean value {{true}} and {{false}};
   *  a symbol {{s}} representing a boolean variable;
   *  {{(make-Not M)}} where {{M}} is a {{boolExp}};
   *  {{(make-And M N)}} where {{M}} and {{N}} are {{boolExps}};
   *  {{(make-Or M N)}} where {{M}} and {{N}} are {{boolExps}};
   *  {{(make-Implies M N)}} where {{M}} and {{N}} are {{boolExps=; or
   *  {{(make-If M N P)}} where {{M}}, {{N}}, and {{P}} are {{boolExp}}s.

The provided function {{parse: input -> boolExp}} takes a Scheme expression and returns the corresponding {{boolExp}}.

----+h1. Normalization

An ={{ifExp=}} is _normalized_ iff every sub-expression in =test= position is either
 a variable (symbol) or a constant (={{true=}} or ={{false=}}).  We call this type ={{norm-ifExp=}}    .

For example, the =ifExp=

(make-If (make-If X Y Z) U V))

Code Block
is not a ={{norm-ifExp=}} because it has an ={{If=}} construction in test
 position.
  In contrast, the equivalent ={{ifExp=}}

(make-If X (make-If Y U V) (make-If Z U V))

Code Block
is normalized and hence is an ={{norm-ifExp=}}.

The normalization process, implemented by the function
=normalize: ifExp -> norm-ifExp= eliminates all =if= constructions that
appear in the _test_ position of other =if= constructions.
We perform this transformation by
repeatedly applying the following rewrite rule
(to any portion of the expression) until it is inapplicable:

...

Code Block
This transformation always terminates and yields a unique answer
independent of the order in which rewrites are performed.
The proof of this fact is left as an optional exercise.

In the ={{normalize=}} function, it is critically important not to duplicate any work, so
the order in which reductions are made really matters.  Do *NOT* apply
the normalization rule above unless ={{U=}} and ={{V=}} are already
normalized, because the rule duplicates both ={{U=}} and ={{V=}}.  If you
reduce the _consequent_ and the _alternative_ (=U= and =V= in the left
hand side of the rule above) before reducing the _test_, =normalize=
runs in linear time (in the number of nodes in the input); if done in
the wrong order it runs in exponential time in the worst case.  (And
some of our test cases will exhibit this worst case behavior.)

Hint: define a sub-function head-normalize that takes three =norm-ifExp=s =X=, =Y=, and =Z=
and constructs a =norm-ifExp= equivalent to =(makeIf X Y Z)=.  This help function processes
=X= because the =test= position must be a variable or a constant, yet =X= can be an
arbitrary =norm-ifExp=. In contrast, =(head-normalize X Y Z)= never even inspects =Y=
and =Z= because they are already normalized and the normalizing transformations performed
in =head-normalize= never place these expressions in =test= position.

The following examples illustrate how the =normalize= and =head-normalize= functions behave:

...