(* DPLL algorithm for SAT checking; after SAT-Micro (Conchon et al.) *)

module type LITERAL = sig
  type t
  val compare: t -> t -> int            (* multimile necesita ordonare *)
  val neg: t -> t                       (* negatia *)
end

module Sat(L: LITERAL) = struct
  module S = Set.Make(L)                (* multime de literali *)
  exception Sat of S.t
  exception Unsat

  let rec simplify ones =               (* arg: lit. adev. + lista de clauze *)
    let filter_clause ones =            (* arg: lit. adev. + clauza *)
      List.filter (fun lit ->           (* ones: multimea lit. adevarate *)
        if S.mem lit ones then raise Exit;      (* clauza e satisfacuta *)
        not (S.mem (L.neg lit) ones))   (* filtreaza lit. false *)
    in List.fold_left (fun (ones, cls) cl ->    (* ones, cls acumuleaza rez. *)
      try match filter_clause ones cl with      (* filtreaza cu ones *)
        [] -> raise Unsat                       (* clauza vida *)
      | [lit] -> simplify (S.add lit ones) cls  (* simplifica cu lit adevarat *)
      | cl -> (ones, cl :: cls)                 (* adauga clauza filtrata *)
      with Exit -> (ones, cls))         (* clauza satisf. -> nimic nou *)
    (ones, [])        (* incepe fold cu multimea data + nicio clauza *)

  let sat cls =
    let rec sat1 ones cls = 
      match simplify ones cls with      (* intai simplifica *)
        (ones, []) -> raise (Sat ones)  (* nicio clauza -> gata *)
      | (ones, cls) -> let l1 = List.hd (List.hd cls) and rcl = List.tl cls in (
        try sat1 (S.add l1 ones) rcl    (* incearca cu l1 adevarat *)
        with Unsat -> sat1 (S.add (L.neg l1) ones) cls) (* incearca fals *)
    in try sat1 S.empty cls             (* initial fara lit. atribuite *)
      with Sat ones -> S.elements ones  (* fa lista din multime *)
end

module StrLit = struct
  type t = P of string | N of string
  let compare = compare
  let neg = function P s -> N s | N s -> P s
end
module SatS = Sat(StrLit)
open StrLit;;

SatS.sat [[P "a"; P "b"; N "c"]; [N "a"; P "c"]; [P "a"; N "b"]];;


This document was generated using caml2html