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

(* reduce.ml *)
(* performs BCP and det. literal elimination on a list of Pred.lit lists *)

exception Valid
exception Incons

(*
let debug = Global.debug

(* cstore -> pred list -> pred list*)
let set_preds cstore pred_db x =
Printf.printf "Reference to Reduce.set_preds\n"; flush stdout;
()
(*
  List.iter (fun pred ->
                      try
                         match cstore#t_status pred with
                             Global.Undet -> ()
                           | Global.Valid ->
                              let lit = pred_db#get_lit (Pred.id pred) in
                              cstore#reduce_assert lit
                           | Global.Unsat ->
                              let lit = 
                                pred_db#get_lit (Global.compl (Pred.id pred))
                              in
                              cstore#reduce_assert lit
                      with Theory.Incons -> raise Incons
            )
*)

(* lit list -> lit list *)
let reduce_clause =
  List.fold_left (fun acc lit ->
                    match Pred.lit_status lit with
                        Global.Valid -> raise Valid
                      | Global.Unsat -> acc
                      | Global.Undet -> lit::acc
                 ) []

let rec check_existing_clauses cstore lit =
  let simplify_clause _ c =
    match Pred.simplify_clause c with
        Some lit -> cstore#reduce_assert lit;
                    check_existing_clauses cstore lit
      | _ -> ()
  in
  let pred = Pred.pred lit in
  let clist = 
    if Pred.is_positive lit then
      Pred.n_set pred
    else
      Pred.p_set pred
  in
  try Hashtbl.iter simplify_clause clist
  with Pred.Empty_clause -> raise Incons


let rec reduce cstore (cs:Pred.lit list list) (cs':Pred.lit list list) =
  Satbox.init ();
  match cs with
      [] -> Satbox.initial_bcp ()
    | c::cs1 -> Satbox.insert_clause
try
                  let c' = reduce_clause c in
                  match c' with
                      [] -> raise Incons
                    | [lit] ->
                                 cstore#reduce_assert lit;
                                 (* at this point, check the clauses of pred *)
                                 check_existing_clauses cstore lit;
                                 reduce cstore cs1 (reduce cstore cs' [])
                    | _ -> reduce cstore cs1 (c'::cs')
                with Valid -> 
                  reduce cstore cs1 cs'
                | Theory.Incons -> raise Incons


*)
