/*****************************************************************************/
/*!
 *\file expr_transform.h
 *\brief Generally Useful Expression Transformations
 *
 * Author: Clark Barrett
 *
 * Created: Fri Aug  5 16:11:51 2005
 *
 * <hr>
 * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
 * Junior University and by New York University. 
 *
 * License to use, copy, modify, sell and/or distribute this software
 * and its documentation for any purpose is hereby granted without
 * royalty, subject to the terms and conditions defined in the \ref
 * LICENSE file provided with this distribution.  In particular:
 *
 * - The above copyright notice and this permission notice must appear
 * in all copies of the software and related documentation.
 *
 * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
 * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
 * 
 * <hr>
 * 
 */
/*****************************************************************************/

#ifndef _cvcl__include__expr_transform_h_
#define _cvcl__include__expr_transform_h_

#include "expr.h"

namespace CVCL {

  class VCL;
  class TheoryCore;
  class CommonProofRules;
  class CoreProofRules;

class ExprTransform {

  TheoryCore* d_core;
  CommonProofRules* d_commonRules;
  CoreProofRules* d_rules;

  //! Cache for pushNegation()
  ExprMap<Theorem> d_pushNegCache;

public:
  ExprTransform(TheoryCore* core);
  ~ExprTransform() {}

  /*************************************************************************/
  /*!
   *\name Preprocessor methods
   * FIXME: please document these functions
   *@{
   */
  /*************************************************************************/
  Theorem preprocess(const Expr& e);
  Theorem preprocess(const Theorem& thm);
  //! Push all negations down to the leaves
  Theorem pushNegation(const Expr& e);
  //! Auxiliary recursive function for pushNegation().
  Theorem pushNegationRec(const Expr& e, bool neg);
  //! Its version for transitivity
  Theorem pushNegationRec(const Theorem& e, bool neg);
  //! Push negation one level down.  Takes 'e' which is 'NOT e[0]'
  Theorem pushNegation1(const Expr& e);
  Theorem substitute(Expr e, ExprMap<Theorem> *init_st=NULL);
  Theorem ite_simplify(Expr e);
  Theorem ite_convert(const Expr& e);
  Expr ite_reorder(const Expr& e);
  Expr getNeg(const Expr& e);
  /*@}*/ // end of preprocessor stuff

};

}

#endif
