/*
  Kommutativgesetze 	  => a and b = b and a
                        => a or b = b or a

  Assoziativgesetze 	  => (a and b) and c = a and (b and c)
                        => (a or b) or c = a or (b or c)

  [OK] Idempotenzgesetze 	  => a and a=a
                            => a or a=a

  [OK] Distributivgesetze   => a and (b or c) = (a and b)  or (a  and c)
                             => a or (b and c) = (a or b)  and (a  or c)

  [OK] Neutralitätsgesetze   => a and 1 = a
                             => a or 0 = a

  [OK] Extremalgesetze 	   => a and 0=0
                             => a or 1=1

  [OK] Doppelnegationsgesetz => not( not a)=a

  [OK] De Morgansche Gesetze => not(a and b)= not a or not b
                             => not(a or b)= not a and not b

  [OK] Komplementärgesetze   => a and not a=0
                             => a or not a=1

  [OK] Dualitätsgesetze 	   => not 0 = 1
                             => not 1 = 0

  [OK] Absorptionsgesetze    => a or(a and b)=a
                             => a and(a or b)=a
       */
  public ASTNode simplify(ASTNode term, final IExpressionContext context) {
    if (term instanceof BooleanExpression) {
      final BooleanExpression expr = (BooleanExpression) term;
      ASTNode left = simplifyTerm(expr.getLHS(), context);
      ASTNode right = simplifyTerm(expr.getRHS(), context);
      return new BooleanExpression(left, right);
    }
    return simplifyTerm(term, context);
  }
 /**
  * Tries to reduce a term by replacing expressions that evaluate to a literal value (true or
  * false) with the corresponding value.
  *
  * @param term
  * @param context
  * @return
  */
 public ASTNode reduce(ASTNode term, final IExpressionContext context) {
   if (term instanceof BooleanExpression) {
     final BooleanExpression expr = (BooleanExpression) term;
     ASTNode left = internalReduce(expr.getLHS(), context);
     ASTNode right = internalReduce(expr.getRHS(), context);
     return new BooleanExpression(left, right);
   }
   return internalReduce(term, context);
 }
  public Boolean isTrue(BooleanExpression expr, IExpressionContext context) {

    ASTNode lhs = expr.getLHS();
    ASTNode rhs = expr.getRHS();

    ASTNode value1 = lhs.evaluate(context);
    ASTNode value2 = rhs.evaluate(context);
    if (value1 != null && value2 != null) {
      return value1.isEquivalent(value2, context);
    }
    return null;
  }