sig
  type access_op = Ast.Expression.access_op = Dot | Arrow
  and assign_op =
    Ast.Expression.assign_op =
      Assign
    | AssignBitAnd
    | AssignBitOr
    | AssignDiv
    | AssignLShift
    | AssignMinus
    | AssignMul
    | AssignPlus
    | AssignRem
    | AssignRShift
    | AssignXor
  and unary_op =
    Ast.Expression.unary_op =
      UnaryMinus
    | Not
    | BitNot
    | Address
    | UnaryPlus
    | DestructorCall
    | Assume
    | Assert
    | PreInc
    | PreDec
    | PostInc
    | PostDec
  and binary_op =
    Ast.Expression.binary_op =
      BitAnd
    | BitOr
    | Div
    | LShift
    | Minus
    | Mul
    | Plus
    | Rem
    | RShift
    | Xor
    | Eq
    | Ge
    | Gt
    | Le
    | Lt
    | Ne
    | Index
    | And
    | Or
    | Comma
    | FieldOffset
  and lval =
    Ast.Expression.lval =
      Symbol of Ast.Symbol.symbol
    | Access of access_op * expression * Ast.Symbol.symbol
    | Dereference of expression
    | Indexed of expression * expression
  and expression =
    Ast.Expression.expression =
      Lval of lval
    | Chlval of lval * string
    | Assignment of assign_op * lval * expression
    | Binary of binary_op * expression * expression
    | Cast of Ast.ast_type * expression
    | Constant of Ast.Constant.constant
    | Constructor of Ast.Symbol.symbol * Ast.ast_type
    | FunctionCall of expression * expression list
    | Sizeof of int
    | Unary of unary_op * expression
  and t = expression
  val compare : t -> t -> int
  val unaryOpToString : unary_op -> string
  val unaryOpToVanillaString : unary_op -> string
  val assignOpToString : assign_op -> string
  val accessOpToString : access_op -> string
  val binaryOpToString : binary_op -> string
  val binaryOpToVanillaString : binary_op -> string
  val print : Format.formatter -> expression -> unit
  val print_lval : Format.formatter -> lval -> unit
  val toString : expression -> string
  val lvalToString : lval -> string
  val addressOf : expression -> expression
  val replaceChlvals : expression -> expression
  val isRelOp : binary_op -> bool
  val isDeref : expression -> bool
  val push_deref : lval -> lval
  val derefedVar : lval -> expression
  val getParents : lval list -> expression list
  val allVarExps : expression -> expression list
  val negateRel : expression -> expression
  val fresh_lval : lval -> expression
  val alpha_convert : (lval -> lval) -> expression -> expression
  val alpha_convert_lval : (lval -> lval) -> lval -> lval
  val deep_alpha_convert : (lval -> expression) -> expression -> expression
  val substituteExpression :
    (expression * expression) list -> expression -> expression
  val assignments_of_expression :
    expression -> (expression * expression) list
end