package jazz.circuit.expr;

//////////////////////////////////////////////////////////////////////////////
//
//                           Boolean Expressions
//
// Boolean expressions can be used to build circuits algorithmically and
// imperatively. Boolean expressions represent "meta-circuits" that can be
// instanciated on any boolean algebra, provided a function to generate
// constants, and a register function.
//
//                   Author: Francois.Bourdoncle@ensmp.fr
//
//////////////////////////////////////////////////////////////////////////////

public final class BoolExpr implements BooleanAlgebra {
  // Creation of input variable number "n"
  public static newInput(n: int): BoolExpr;

  // Creation of a new local node
  public static newLocal(): BoolExpr;

  // Defines the value of the boolean expression variable "this" by the
  // equation "this = e". Since this method destructively replaces any
  // previous definition of the boolean expression variable, calls to this
  // method must be explicitly serialized.
  public setEq(e: BoolExpr): BoolExpr;

  // Defines the value of the boolean expression variable "this". If the
  // variable has no previous definition, simply defines the variable by the
  // equation "this = e". If the variable was already defined by the equation
  // "this = e0", then the variable is redefined by the new equation
  // "this = (e0 | e)". Since this method destructively replaces any previous 
  // definition of the boolean expression variable, calls to this method must
  // be explicitly serialized.
  public setOr(e: BoolExpr): BoolExpr;

  // Same as above, but redefines the variables by "this = (e0 & e)".
  public setAnd(e: BoolExpr): BoolExpr;

  // Same as above, but redefines the variables by "this = (e0 ^ e)".
  public setXor(e: BoolExpr): BoolExpr;

  // Definition of a boolean variable
  public getDefinition(): BoolExpr;

  // Instanciate each variable the array of specified output boolean
  // expressions over a given boolean algebra A, given:
  //
  // - the mapping of input variable to input values (e.g., input nets)
  // - the register function of the boolean algebra (e.g., "reg")
  // - the instanciation function for constants (e.g., "Net.constant")
  //
  public static instanciate<T: BooleanAlgebra>(outputs: BoolExpr[])
                                              (inputs: T[],
                                               reg: fun(T): T,
                                               constant: fun(per): T): T[];

  // The delay operator
  public static reg(e: BoolExpr): BoolExpr;

  // Creation of a new constant
  public static constant(v: per): BoolExpr;

  // Private implementation
  e: _BoolExpr;
}