(*
This file is part of the dpll(t) engine sammy
Copyright (C) 2004  The University of Iowa
George Hagen
                                                                                
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.
*)

(** Internal API using ocaml data structures. *)                                                                                

type command_type =
  ASSERT_CMD | QUERY_CMD | SIGNATURE_CMD | AXIOM_CMD | OTHER_CMD | NON_CMD
(** Indicates the type of command to give the system. *)

exception Incorrect_state
(** Indicates that the user attempted a command at the wrong time. *)

exception Backtrack_error
(** Indicates that the user attempted to retract more assertions than 
he had made. *)

val start_solver : unit -> unit
(** Used to initially prime the solver; should only be called initially or
after [Api_native.stop_solver ()].  Raises [Api_native.Incorrect_state] if
called at any other time. *)
  
val set_flag : Global.paramtype -> unit
(** Sets the indicated flag to the indicated value.  Raises [Api_native.Incorrect_state] if called while there are assertions on the stack. *) 

val declarations : Formula.exprtype option -> Skolemizer.skolemizer -> unit
(** Adds the indicated definition formula (explicitly, may be None) and the 
[Pred_db.pred_db]'s new predicates (implicitly) to the solver.  Raises 
[Api_native.Incorrect_state] if called before ths solver is started.
Raises [Convert.Conversion_error] on a conversion error.
Raises [Theory.Incons] if the constraint set is 
discovered to be inconsistent during this process.
If an exception is raised, no new clauses will be added to the system state,
but it will be advanced on a [Conversion_error] or [Incons].
Note: call [pred_db#mark_point] before parsing the input formula *)

val add_assertion : Formula.exprtype -> Skolemizer.skolemizer -> unit
(** Adds the indicated definition formula (explicitly) and the 
[Pred_db.pred_db]'s new predicates (implicitly) to the solver.  Raises 
[Api_native.Incorrect_state] if called before ths solver is started.
Raises [Convert.Conversion_error] on a conversion error.
Raises [Theory.Incons] if the constraint set is 
discovered to be inconsistent during this process. 
If an exception is raised, no new clauses will be added to the system state,
but it will be advanced on a [Conversion_error] or [Incons].
Note: call [pred_db#mark_point] before parsing the input formula *)

val add_axiom : Formula.exprtype -> Skolemizer.skolemizer -> unit
(** In the current implementation, this is an alias for
[Api_native.add_assertion]. *)

val backtrack : int -> unit
(** Undoes the last [n] assertions to the system.
This retracts the system state n steps and removes any clauses (& predicates?)
added during those steps.
Raises [Api_native.Backtrack_error] if [n] < 0 or [n] > the net number 
of assertions made since the solver was started.
Raises [Api_native.Incorrect_state] if you attempt to backtrack prior to
having made any assertions. *)

val query : Formula.exprtype -> Skolemizer.skolemizer -> bool
(** Returns true if the expression is valid in the current context
(its negation is unsatisfiable), false otherwise.
Raises [Dpllt.Timeout] if the check times out.
Raises [Api_native.Incorrect_state] if called before ths solver is started.
Raises [Convert.Conversion_error] on a conversion error. 
If an exception is raised, no new clauses will be added to the system state,
but it will be advanced on a [Conversion_error] or [Incons].
Note: call [pred_db#mark_point] before parsing the input formula *)

val stop_solver : unit -> unit
(** Returns the solver to the initial state (needs to be re-started). *)

val call_dpllt : Pred.pred list -> int -> Skolemizer.skolemizer -> bool
(** [call_dpllt new_preds new_clauses skolemizer] makes a call to dpllt.satisfiable on the current set of clauses. *)
