(*
This file is part of the dpll(t) engine sammy
Copyright (C) 2004  The University of Iowa
Cesare Tinelli
George Hagen
Mike Decoster

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*)

(* pred_db.mli *)

(** Predicate database class *)

exception Pred_not_found of int

class pred_db :
 (* uses State.initial_state *)
object

  (** [add_abstract_pred id] 
  adds an abstract predicate with id [id] that the theory interprets to the 
  database. Duplicate ids are discarded.
  *)
  method add_abstract_pred : Global.pred_id -> unit

  (** [add_pred id formula]
  Adds a predicate that the theory interpretes to the database.
  [id] is the id for the new predicate, while
  [formula] is a string naming this predicate.
  If [id] already esists in the databse, nothing is done.
  *)
  method add_pred : Global.pred_id -> string -> unit

  (** [add_uninterpreted_abstract_pred id]
  Adds an abstract boolean predicate with id [id] to the database.
  If [id] already esists in the databse, nothing is done.
  *)
  method add_uninterpreted_abstract_pred : Global.pred_id -> unit

  (** [add_uninterpreted_pred id formula]
  Adds a boolean predicate to the database.
  [id] is the id for the new predicate, while
  [formula] is a string naming this predicate.
  If [id] already esists in the databse, nothing is done.
  *)
  method add_uninterpreted_pred : Global.pred_id -> string -> unit

  (** [add_quantified_abstraction_pred id]
  Adds a quantified abstraction predicate to the database.
  If [id] already esists in the databse, nothing is done.
  *)
  method add_quantified_abstraction_pred : Global.pred_id -> unit

  (** Retrieves a list of all predicates in the database *)
  method all_preds : Pred.pred list

  (** Retrieves a list of all literals in the database *)
  method all_lits : Pred.lit list

  (** Marks a backtrack point for clearing the pred_db. Should be called
    at the beginning of any backtrackable API call, prior to any parsing. *)
  method mark_point : unit

  (**  Returns the predicate associated with some id.
  Raises [Pred_db.Pred_not_found] if the predicate is 
  not present in the database.
  As predicates only have positive ids, a negative parameter will always 
  result in an exception.
  *)
  method get_pred : Global.pred_id -> Pred.pred

  (** Returns the literal associated with some (signed) pred id.
  Side effect: adds literals to database as they are referenced.
  Raises [Pred_db.Pred_not_found] if there is no associated 
  predicate for this literal.
  *)
  method get_lit : Global.pred_id -> Pred.lit

  (** [remove_pred f p] removes a predicate [p] from the database. 
   [f] is a function to clear references to the predicate from the theory. *)
  method remove_pred : (Pred.pred -> unit) -> Global.pred_id -> unit

  (** Prints some statistics for the database *)
  method print_stats : unit


  (** returns a list of all assigned quantified preds in the current model *)
  method quantified_partial_model: Global.pred_id list

  (** returns a lemma that requires a change in the assigned quantified preds 
   in the current model *)
  method quantified_lemma: Global.pred_id list

  (** returns & then clears a list of recently added predicates *)
  method recent_preds : Pred.pred list

  (** Removes all data added to the pred_db since the last [n] [mark_points] 
  the function [f] is one to remove references to predicates to the theory. *)
  method backtrack : (Pred.pred -> unit) -> int -> unit

  (** clears all entires from the pred table *)
  method clear : unit
 
(** {6 Debugging code} *)
                                                                                
  (** Prints a list of all predicates in the db *)
  method print_all : unit -> unit

  (** Checks the status of all predicates in the database against their 
  theory values. *) 
  method check_all : (Global.pred_id -> Global.status)-> (Pred.pred -> Global.status) -> unit

end

