(*
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.
*)
                                                                                


(** Global data structures including the predicate database, constraint store, and "meta-states" used in backtracking assertions *)

exception Incorrect_backtrack

let pred_db = new Pred_db.pred_db
let cstore = new Cstore.cstore (pred_db)

let base_states = ref ([]:(Pred.pred list * int * State.state) list)

(* theory callback functions *)

let theory_reasons x = cstore#theory#implicants x;;
Callback.register "theory_reasons" theory_reasons;;

(* create a new base state *)
let add_base_state pred_list clause_num = 
(*  State.advance_state ();*)
  base_states := (pred_list,clause_num,State.current_state())::(!base_states)

(* add preds/clauses to the current base state *)
let augment_base_state pl cn =
  match !base_states with
    (pl',cn',s)::t -> 
       base_states := 
         ((List.rev_append pl pl'),(cn'+cn),s)::t
  

let get_top_base_state () = 
  match !base_states with
      h::t -> h
    | [] -> raise Incorrect_backtrack

let rec backtrack_base_state n =
  if n > 0 then
    begin
      match !base_states with
          (pl,cl,s)::t -> base_states := t;
                  State.backtrack_to_level (State.level s);
                  (* remove all new preds/clauses for this state *)
                  (* remove preds? *)
(*                  Satbox.retract_user_lemmas cl;*)
                  backtrack_base_state (n-1)
        | [] -> raise Incorrect_backtrack
    end

let rec backtrack_base_state_to_level n =
      match !base_states with
          (pl,cl,s)::t -> 
              if State.level s > n then
                begin
                  base_states := t;
                  State.backtrack_to_level (State.level s);
                  (* remove all new preds/clauses for this state *)
                  (* remove preds? *)
(*                  Satbox.retract_user_lemmas cl;*)
                  backtrack_base_state_to_level (n)
                end
        | [] -> ()



let clear_base_states () =
  backtrack_base_state_to_level 0;
  base_states := []
