/*******************************************************************\

Module: Theory of Arrays

Author: Daniel Kroening, kroening@cs.cmu.edu

\*******************************************************************/

#ifndef CPROVER_ARRAYS_H
#define CPROVER_ARRAYS_H

#include <union_find.h>

#include "functions.h"

class arrayst:public functionst
{
public:
  arrayst(propt &_prop):functionst(_prop) { }

  virtual void post_process()
  {
    add_array_constraints();
    SUB::post_process();
  }
  
  typedef functionst SUB;
  
  virtual literalt record_array_equality(const exprt &expr);
                 
protected:
  virtual void add_array_constraints();

  struct array_equalityt
  {
    literalt l;
    exprt f1, f2;
  };

  typedef std::list<array_equalityt> array_equalitiest;
  array_equalitiest array_equalities;
  
  union_find<exprt> arrays;

  virtual void add_array_constraints(
    const array_equalityt &array_equality);

  void add_array_constraints(const exprt &expr);
  void add_array_constraints_if(const exprt &expr);
  void add_array_constraints_with(const exprt &expr);
  void add_array_constraints_array_of(const exprt &expr);

  typedef std::set<exprt> index_sett;
  typedef std::map<exprt, index_sett> index_mapt;
  index_mapt index_map;

  void get_index_map();
  void collect_arrays(const exprt &a);
};

#endif
