feat: inner DRUP proof checking for pure-sat-solver

This commit is contained in:
Simon Cruanes 2021-08-19 00:15:00 -04:00
parent 9f01b98cde
commit 8bc1f1c864
8 changed files with 90 additions and 10 deletions

View file

@ -1,6 +1,6 @@
{ {
type token = EOF | ZERO | LIT of int | D type token = EOF | ZERO | LIT of int | D | R | I
} }
let number = ['1' - '9'] ['0' - '9']* let number = ['1' - '9'] ['0' - '9']*
@ -10,6 +10,8 @@ rule token = parse
| "c" { comment lexbuf } | "c" { comment lexbuf }
| [' ' '\t' '\r'] { token lexbuf } | [' ' '\t' '\r'] { token lexbuf }
| "d" { D } | "d" { D }
| "r" { R }
| "i" { I }
| '\n' { Lexing.new_line lexbuf; token lexbuf } | '\n' { Lexing.new_line lexbuf; token lexbuf }
| '0' { ZERO } | '0' { ZERO }
| '-'? number { LIT (int_of_string (Lexing.lexeme lexbuf)) } | '-'? number { LIT (int_of_string (Lexing.lexeme lexbuf)) }

View file

@ -2,6 +2,7 @@
module L = Drup_lexer module L = Drup_lexer
type event = type event =
| Input of int list
| Add of int list | Add of int list
| Delete of int list | Delete of int list
@ -9,9 +10,10 @@ type t = {
buf: Lexing.lexbuf; buf: Lexing.lexbuf;
} }
let create (ic:in_channel) : t = let create_string s : t =
let buf = Lexing.from_channel ic in { buf=Lexing.from_string s }
{buf; } let create_chan (ic:in_channel) : t =
{ buf = Lexing.from_channel ic }
let next self : _ option = let next self : _ option =
let rec get_clause acc = match L.token self.buf with let rec get_clause acc = match L.token self.buf with
@ -22,9 +24,15 @@ let next self : _ option =
in in
begin match L.token self.buf with begin match L.token self.buf with
| L.EOF -> None | L.EOF -> None
| L.I ->
let c = get_clause [] in
Some (Input c)
| L.D -> | L.D ->
let c = get_clause [] in let c = get_clause [] in
Some (Delete c) Some (Delete c)
| L.R ->
let c = get_clause [] in
Some (Add c)
| L.ZERO -> Some (Add []) | L.ZERO -> Some (Add [])
| L.LIT i -> | L.LIT i ->
let c = get_clause [i] in let c = get_clause [i] in

View file

@ -4,10 +4,12 @@
type t type t
type event = type event =
| Input of int list
| Add of int list | Add of int list
| Delete of int list | Delete of int list
val create : in_channel -> t val create_chan : in_channel -> t
val create_string : string -> t
val next : t -> event option val next : t -> event option

View file

@ -34,9 +34,12 @@ let check ?pb proof : bool =
Profile.with_ "parse-proof.drup" @@ fun() -> Profile.with_ "parse-proof.drup" @@ fun() ->
CCIO.with_in f CCIO.with_in f
(fun ic -> (fun ic ->
let p = BL.Drup_parser.create ic in let p = BL.Drup_parser.create_chan ic in
BL.Drup_parser.iter p BL.Drup_parser.iter p
(function (function
| BL.Drup_parser.Input c ->
let c = clause_of_int_l cstore c in
Drup_check.Trace.add_input_clause trace c
| BL.Drup_parser.Add c -> | BL.Drup_parser.Add c ->
let c = clause_of_int_l cstore c in let c = clause_of_int_l cstore c in
Drup_check.Trace.add_clause trace c Drup_check.Trace.add_clause trace c

View file

@ -7,6 +7,7 @@
(modes native) (modes native)
(libraries containers iter result sidekick.sat sidekick.core sidekick-base (libraries containers iter result sidekick.sat sidekick.core sidekick-base
sidekick.smt-solver sidekick-bin.smtlib sidekick.tef sidekick.smt-solver sidekick-bin.smtlib sidekick.tef
sidekick.drup
sidekick.memtrace sidekick-bin.lib) sidekick.memtrace sidekick-bin.lib)
(flags :standard -safe-string -color always -open Sidekick_util)) (flags :standard -safe-string -color always -open Sidekick_util))

View file

@ -15,9 +15,20 @@ module Formula = struct
let pp = Fmt.int let pp = Fmt.int
end end
module Proof (* TODO: on the fly compression *)
: Sidekick_sat.PROOF with type lit = Formula.t module Proof : sig
= struct include Sidekick_sat.PROOF with type lit = Formula.t
val dummy : t
val create : unit -> t
val to_string : t -> string
val to_chan : out_channel -> t -> unit
type event = Sidekick_bin_lib.Drup_parser.event =
| Input of int list
| Add of int list
| Delete of int list
val iter_events : t -> event Iter.t
end = struct
let bpf = Printf.bprintf let bpf = Printf.bprintf
type lit = Formula.t type lit = Formula.t
type t = type t =
@ -64,6 +75,21 @@ module Proof
let to_chan oc = function let to_chan oc = function
| Dummy -> () | Dummy -> ()
| Inner {buf} -> Buffer.output_buffer oc buf; flush oc | Inner {buf} -> Buffer.output_buffer oc buf; flush oc
module DP = Sidekick_bin_lib.Drup_parser
type event = DP.event =
| Input of int list
| Add of int list
| Delete of int list
(* parse the proof back *)
let iter_events (self:t) : DP.event Iter.t =
match self with
| Dummy -> Iter.empty
| Inner {buf} ->
let dp = DP.create_string (to_string self) in
DP.iter dp
end end
module Arg = struct module Arg = struct
@ -96,6 +122,37 @@ module Dimacs = struct
E.of_exn_trace e E.of_exn_trace e
end end
let check_proof proof : bool =
Profile.with_ "pure-sat.check-proof" @@ fun () ->
let module SDRUP = Sidekick_drup.Make() in
let store = SDRUP.Clause.create() in
let checker = SDRUP.Checker.create store in
let ok = ref true in
let tr_clause c =
let c = List.rev_map SDRUP.Atom.of_int_dimacs c in
SDRUP.Clause.of_list store c
in
Proof.iter_events proof
(function
| Proof.Input c ->
let c = tr_clause c in
SDRUP.Checker.add_clause checker c
| Proof.Add c ->
let c = tr_clause c in
if not (SDRUP.Checker.is_valid_drup checker c) then (
ok := false;
);
SDRUP.Checker.add_clause checker c;
| Proof.Delete c ->
let c = tr_clause c in
SDRUP.Checker.del_clause checker c;
);
!ok
let solve ?(check=false) (solver:SAT.t) : (unit, string) result = let solve ?(check=false) (solver:SAT.t) : (unit, string) result =
let res = let res =
Profile.with_ "solve" (fun () -> SAT.solve solver) Profile.with_ "solve" (fun () -> SAT.solve solver)
@ -110,7 +167,10 @@ let solve ?(check=false) (solver:SAT.t) : (unit, string) result =
if check then ( if check then (
let proof = SAT.proof solver in let proof = SAT.proof solver in
Proof.check proof; let ok = check_proof proof in
if not ok then (
Error.errorf "Proof validation failed"
);
); );
let t3 = Sys.time () -. t2 in let t3 = Sys.time () -. t2 in

View file

@ -1830,6 +1830,7 @@ module Make(Plugin : PLUGIN)
let[@inline] theory st = st.th let[@inline] theory st = st.th
let[@inline] store st = st.store let[@inline] store st = st.store
let[@inline] proof st = st.proof
(* Result type *) (* Result type *)
type res = type res =

View file

@ -299,6 +299,9 @@ module type S = sig
val store : t -> store val store : t -> store
(** Store for the solver *) (** Store for the solver *)
val proof : t -> proof
(** Access the inner proof *)
(** {2 Types} *) (** {2 Types} *)
(** Result type for the solver *) (** Result type for the solver *)