%mathpiper,def="CNF"


 // former LogicSimplify

/*
   Simplify a boolean expression. CNF is responsible
   for converting an expression to the following form:
        (p1  Or  p2  Or  ...)  And  (q1  Or  q2  Or  ...)  And ...
   That is, a conjunction of disjunctions.
*/


// Trivial simplifications
10  # CNF( Not  True)                  <-- False;
11  # CNF( Not  False)                 <-- True;
12  # CNF(True   And  (_x))            <-- CNF(x);
13  # CNF(False  And  (_x))            <-- False;
14  # CNF(_x   And  True)              <-- CNF(x);
15  # CNF(_x  And  False)              <-- False;
16  # CNF(True   Or  (_x))             <-- True;
17  # CNF(False  Or  (_x))             <-- CNF(x);
18  # CNF((_x)  Or  True )             <-- True;
19  # CNF((_x)  Or  False)             <-- CNF(x);

// A bit more complext
21  # CNF(_x  Or  _x)                  <-- CNF(x);
22  # CNF(_x  And  _x)                 <-- CNF(x);
23  # CNF(_x  Or Not (_x))             <-- True;
14  # CNF(Not (_x)  Or _x)             <-- True;
25  # CNF(_x  And Not (_x))            <-- False;
26  # CNF(Not (_x)  And _x)            <-- False;

// Simplifications that deal with (in)equalities
25  # CNF(((_x) == (_y))   Or  ((_x) !== (_y)))   <-- True;
25  # CNF(((_x) !== (_y))  Or  ((_x) == (_y)))    <-- True;
26  # CNF(((_x) == (_y))   And ((_x) !== (_y)))   <-- False;
26  # CNF(((_x) !== (_y))  And ((_x) == (_y)))    <-- False;

27  # CNF(((_x) >= (_y))   And ((_x) < (_y)))     <-- False;
27  # CNF(((_x) < (_y))    And ((_x) >= (_y)))    <-- False;
28  # CNF(((_x) >= (_y))   Or  ((_x) < (_y)))     <-- True;
28  # CNF(((_x) < (_y))    Or  ((_x) >= (_y)))    <-- True;


// some things that are more complex
120  # CNF((_x)  Or  (_y))            <-- LogOr(x, y, CNF(x), CNF(y));
10 # LogOr(_x,_y,_x,_y)               <-- x Or y;
20 # LogOr(_x,_y,_u,_v)               <-- CNF(u Or v);

130  # CNF( Not  (_x))                <-- LogNot(x, CNF(x));
10 # LogNot(_x, _x)                   <-- Not (x);
20 # LogNot(_x, _y)                   <-- CNF(Not (y));

40 # CNF( Not ( Not  (_x)))           <-- CNF(x);                           // eliminate double negation
45 # CNF((_x)=>(_y))                  <-- CNF((Not (x))  Or  (y));              // eliminate implication

50 # CNF( Not ((_x)  And  (_y)))      <-- CNF((Not x) Or (Not y));          // De Morgan's law
60 # CNF( Not ((_x)  Or  (_y)))       <-- CNF(Not (x)) And CNF(Not (y));        // De Morgan's law

/*
70 # CNF((_x) And ((_y)  Or  (_z)))   <-- CNF(x And y) Or CNF(x And z);
70 # CNF(((_x) Or (_y)) And (_z))     <-- CNF(x And z) Or CNF(y And z);

80 # CNF((_x)  Or  ((_y)  And  (_z))) <-- CNF(x Or y) And CNF(x Or z);
80 # CNF(((_x)  And  (_y)) Or (_z))   <-- CNF(x Or z) And CNF(y Or z);
*/

70 # CNF(((_x)  And  (_y))  Or  (_z)) <-- CNF(x Or z) And CNF(y Or z);      // Distributing Or over And
80 # CNF((_x)  Or  ((_y)  And  (_z))) <-- CNF(x Or y) And CNF(x Or z);

90 # CNF((_x)  And  (_y))             <-- CNF(x) And CNF(y);                // Transform subexpression

101 # CNF( (_x) < (_y) )              <-- Not CNFInEq(x >=  y);
102 # CNF( (_x) > (_y) )              <-- CNFInEq(x >   y);
103 # CNF( (_x) >= (_y) )             <-- CNFInEq(x >=  y);
104 # CNF( (_x) <= (_y) )             <-- Not CNFInEq(x >  y);
105 # CNF( (_x) == (_y) )             <-- CNFInEq(x ==  y);
106 # CNF( (_x) !== (_y) )            <-- Not CNFInEq(x == y);

111 # CNF( Not((_x) <  (_y)) )        <-- CNFInEq( x >= y );
113 # CNF( Not((_x) <= (_y)) )        <-- CNFInEq( x > y );
116 # CNF( Not((_x) !== (_y)) )       <-- CNFInEq( x == y );

/* Accept as fully simplified, fallthrough case */
200 # CNF(_x)                         <-- x;

20 # CNFInEq((_xex) == (_yex))        <-- (CNFInEqSimplify(xex-yex) ==  0);
20 # CNFInEq((_xex) > (_yex))         <-- (CNFInEqSimplify(xex-yex) >   0);
20 # CNFInEq((_xex) >= (_yex))        <-- (CNFInEqSimplify(xex-yex) >=  0);
30 # CNFInEq(_exp)                    <-- (CNFInEqSimplify(exp));

10 # CNFInEqSimplify((_x) - (_x))     <-- 0;        // strictly speaking, this is not always valid, i.e. 1/0 - 1/0 != 0...
100# CNFInEqSimplify(_x)              <-- [/*Echo({"Hit the bottom of CNFInEqSimplify with ", x, Nl()});*/ x;];
                                                    // former "Simplify";



%/mathpiper