%mathpiper,def="LogicRemoveTautologies"

 // not clear is this will stay, but it is eq. to LogicSimplify(expr, 2)

1 # SimpleNegate(Not (_x))  <-- x;
2 # SimpleNegate(_x)        <-- Not(x);

/* LogicRemoveTautologies scans a list representing e1 Or e2 Or ... to find
   if there are elements p and  Not p in the list. This signifies p Or Not p,
   which is always True. These pairs are removed. Another function that is used
   is RemoveDuplicates, which converts p Or p into p.
*/

/* this can be optimized to walk through the lists a bit more efficiently and also take
care of duplicates in one pass */
LocalCmp(_e1, _e2)                  <-- IsLessThan(PipeToString() Write(e1), PipeToString() Write(e2));

// we may want to add other expression simplifers for new expression types
100 # SimplifyExpression(_x)        <-- x;

// Return values:
//  {True} means True
//  {} means False
LogicRemoveTautologies(_e) <--
[
  Local(i, len, negationfound); Bind(len, Length(e));
  Bind(negationfound, False);

  //Echo(e);
  e := BubbleSort(e, "LocalCmp");

  For(Bind(i, 1), (i <= len) And (Not negationfound), i++)
  [
    Local(x, n, j);
    // we can register other simplification rules for expressions
    //e[i] := MathNth(e,i) /:: {gamma(_y) <- SimplifyExpression(gamma(y))};
    Bind(x, MathNth(e,i));
    Bind(n, SimpleNegate(x));                    /* this is all we have to do because of
                                                the kind of expressions we can have coming in */

    For(Bind(j, i+1), (j <= len) And (Not negationfound), j++) [
        Local(y);
        Bind(y, MathNth(e,j));

        If(IsEqual(y, n),
            [
                //Echo({"Deleting from ", e, " i=", i, ", j=", j, Nl()});

                Bind(negationfound, True);
                //Echo({"Removing clause ", i, Nl()});
            ],
        If(IsEqual(y, x),
            [
                //Echo({"Deleting from ", e, " j=", j, Nl()});
                DestructiveDelete(e, j);
                Bind(len,SubtractN(len,1));
            ])
        );
    ];
    Check(len = Length(e), "Math", "The length computation is incorrect");
  ];

  If(negationfound, {True}, e);            /* note that a list is returned */
];

%/mathpiper