mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
feat: basic proof production for QF_UF (wip)
This commit is contained in:
parent
fbc3ec7ed6
commit
57bf44dfb9
7 changed files with 63 additions and 29 deletions
|
|
@ -373,14 +373,14 @@ module Make (A: CC_ARG)
|
||||||
n.n_expl <- FL_none;
|
n.n_expl <- FL_none;
|
||||||
end
|
end
|
||||||
|
|
||||||
let raise_conflict (cc:t) ~th (acts:actions) (e:lit list) : _ =
|
let raise_conflict_ (cc:t) ~th (acts:actions) (e:lit list) p : _ =
|
||||||
Profile.instant "cc.conflict";
|
Profile.instant "cc.conflict";
|
||||||
(* clear tasks queue *)
|
(* clear tasks queue *)
|
||||||
Vec.clear cc.pending;
|
Vec.clear cc.pending;
|
||||||
Vec.clear cc.combine;
|
Vec.clear cc.combine;
|
||||||
List.iter (fun f -> f cc ~th e) cc.on_conflict;
|
List.iter (fun f -> f cc ~th e) cc.on_conflict;
|
||||||
Stat.incr cc.count_conflict;
|
Stat.incr cc.count_conflict;
|
||||||
Actions.raise_conflict acts e P.default
|
Actions.raise_conflict acts e p
|
||||||
|
|
||||||
let[@inline] all_classes cc : repr Iter.t =
|
let[@inline] all_classes cc : repr Iter.t =
|
||||||
T_tbl.values cc.tbl
|
T_tbl.values cc.tbl
|
||||||
|
|
@ -652,7 +652,14 @@ module Make (A: CC_ARG)
|
||||||
let lits = explain_decompose cc ~th [] e_ab in
|
let lits = explain_decompose cc ~th [] e_ab in
|
||||||
let lits = explain_pair cc ~th lits a ra in
|
let lits = explain_pair cc ~th lits a ra in
|
||||||
let lits = explain_pair cc ~th lits b rb in
|
let lits = explain_pair cc ~th lits b rb in
|
||||||
raise_conflict cc ~th:!th acts (List.rev_map Lit.neg lits)
|
let proof =
|
||||||
|
let lits =
|
||||||
|
Iter.of_list lits
|
||||||
|
|> Iter.map (fun lit -> Lit.term lit, Lit.sign lit)
|
||||||
|
in
|
||||||
|
P.make_cc lits
|
||||||
|
in
|
||||||
|
raise_conflict_ cc ~th:!th acts (List.rev_map Lit.neg lits) proof
|
||||||
);
|
);
|
||||||
(* We will merge [r_from] into [r_into].
|
(* We will merge [r_from] into [r_into].
|
||||||
we try to ensure that [size ra <= size rb] in general, but always
|
we try to ensure that [size ra <= size rb] in general, but always
|
||||||
|
|
@ -833,7 +840,14 @@ module Make (A: CC_ARG)
|
||||||
let th = ref true in
|
let th = ref true in
|
||||||
let lits = explain_decompose cc ~th [] expl in
|
let lits = explain_decompose cc ~th [] expl in
|
||||||
let lits = List.rev_map Lit.neg lits in
|
let lits = List.rev_map Lit.neg lits in
|
||||||
raise_conflict cc ~th:!th acts lits
|
let proof =
|
||||||
|
let lits =
|
||||||
|
Iter.of_list lits
|
||||||
|
|> Iter.map (fun lit -> Lit.term lit, Lit.sign lit)
|
||||||
|
in
|
||||||
|
P.make_cc lits
|
||||||
|
in
|
||||||
|
raise_conflict_ cc ~th:!th acts lits proof
|
||||||
|
|
||||||
let merge cc n1 n2 expl =
|
let merge cc n1 n2 expl =
|
||||||
Log.debugf 5
|
Log.debugf 5
|
||||||
|
|
|
||||||
|
|
@ -146,10 +146,11 @@ module type TERM = sig
|
||||||
end
|
end
|
||||||
|
|
||||||
module type PROOF = sig
|
module type PROOF = sig
|
||||||
|
type term
|
||||||
type t
|
type t
|
||||||
val pp : t Fmt.printer
|
val pp : t Fmt.printer
|
||||||
|
|
||||||
val default : t
|
val default : t
|
||||||
|
val make_cc : (term*bool) Iter.t -> t
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Literals
|
(** Literals
|
||||||
|
|
@ -192,9 +193,10 @@ end
|
||||||
is inconsistent *)
|
is inconsistent *)
|
||||||
module type CC_ACTIONS = sig
|
module type CC_ACTIONS = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
|
|
||||||
|
module P : PROOF with type term = T.Term.t
|
||||||
|
|
||||||
type t
|
type t
|
||||||
(** An action handle. It is used by the congruence closure
|
(** An action handle. It is used by the congruence closure
|
||||||
to perform the actions below. How it performs the actions
|
to perform the actions below. How it performs the actions
|
||||||
|
|
@ -220,7 +222,7 @@ end
|
||||||
(** Arguments to a congruence closure's implementation *)
|
(** Arguments to a congruence closure's implementation *)
|
||||||
module type CC_ARG = sig
|
module type CC_ARG = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
module P : PROOF with type term = T.Term.t
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
module Actions : CC_ACTIONS with module T=T and module P = P and module Lit = Lit
|
module Actions : CC_ACTIONS with module T=T and module P = P and module Lit = Lit
|
||||||
|
|
||||||
|
|
@ -231,7 +233,7 @@ end
|
||||||
(** Signature of the congruence closure *)
|
(** Signature of the congruence closure *)
|
||||||
module type CC_S = sig
|
module type CC_S = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
module P : PROOF with type term = T.Term.t
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P
|
module Actions : CC_ACTIONS with module T = T and module Lit = Lit and module P = P
|
||||||
type term_state = T.Term.state
|
type term_state = T.Term.state
|
||||||
|
|
@ -491,7 +493,7 @@ end
|
||||||
new lemmas, propagate literals, access the congruence closure, etc. *)
|
new lemmas, propagate literals, access the congruence closure, etc. *)
|
||||||
module type SOLVER_INTERNAL = sig
|
module type SOLVER_INTERNAL = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
module P : PROOF with type term = T.Term.t
|
||||||
|
|
||||||
type ty = T.Ty.t
|
type ty = T.Ty.t
|
||||||
type term = T.Term.t
|
type term = T.Term.t
|
||||||
|
|
@ -728,7 +730,8 @@ end
|
||||||
Theory implementors will mostly interact with {!SOLVER_INTERNAL}. *)
|
Theory implementors will mostly interact with {!SOLVER_INTERNAL}. *)
|
||||||
module type SOLVER = sig
|
module type SOLVER = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
module P : PROOF with type term = T.Term.t
|
||||||
|
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
|
|
||||||
module Solver_internal
|
module Solver_internal
|
||||||
|
|
@ -854,6 +857,7 @@ module type SOLVER = sig
|
||||||
type t
|
type t
|
||||||
val check : t -> unit
|
val check : t -> unit
|
||||||
val pp_dot : t Fmt.printer
|
val pp_dot : t Fmt.printer
|
||||||
|
val pp : t Fmt.printer
|
||||||
end
|
end
|
||||||
type proof = Proof.t
|
type proof = Proof.t
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ exception Out_of_space
|
||||||
let file = ref ""
|
let file = ref ""
|
||||||
let p_cnf = ref false
|
let p_cnf = ref false
|
||||||
let p_dot_proof = ref ""
|
let p_dot_proof = ref ""
|
||||||
let p_proof_print = ref false
|
let p_proof = ref false
|
||||||
let p_model = ref false
|
let p_model = ref false
|
||||||
let check = ref false
|
let check = ref false
|
||||||
let time_limit = ref 300.
|
let time_limit = ref 300.
|
||||||
|
|
@ -71,6 +71,8 @@ let argspec = Arg.align [
|
||||||
"--no-restarts", Arg.Clear restarts, " disable restarts";
|
"--no-restarts", Arg.Clear restarts, " disable restarts";
|
||||||
"--dot", Arg.Set_string p_dot_proof, " if provided, print the dot proof in the given file";
|
"--dot", Arg.Set_string p_dot_proof, " if provided, print the dot proof in the given file";
|
||||||
"--stat", Arg.Set p_stat, " print statistics";
|
"--stat", Arg.Set p_stat, " print statistics";
|
||||||
|
"--proof", Arg.Set p_proof, " print proof";
|
||||||
|
"--no-proof", Arg.Clear p_proof, " do not print proof";
|
||||||
"--model", Arg.Set p_model, " print model";
|
"--model", Arg.Set p_model, " print model";
|
||||||
"--no-model", Arg.Clear p_model, " do not print model";
|
"--no-model", Arg.Clear p_model, " do not print model";
|
||||||
"--gc-stat", Arg.Set p_gc_stat, " outputs statistics about the GC";
|
"--gc-stat", Arg.Set p_gc_stat, " outputs statistics about the GC";
|
||||||
|
|
@ -151,7 +153,8 @@ let main () =
|
||||||
Process.th_lra;
|
Process.th_lra;
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
Process.Solver.create ~store_proof:!check ~theories tst () ()
|
let store_proof = !check || !p_proof in
|
||||||
|
Process.Solver.create ~store_proof ~theories tst () ()
|
||||||
in
|
in
|
||||||
if !check then (
|
if !check then (
|
||||||
(* might have to check conflicts *)
|
(* might have to check conflicts *)
|
||||||
|
|
@ -171,7 +174,8 @@ let main () =
|
||||||
Process.process_stmt
|
Process.process_stmt
|
||||||
~hyps ~gc:!gc ~restarts:!restarts ~pp_cnf:!p_cnf
|
~hyps ~gc:!gc ~restarts:!restarts ~pp_cnf:!p_cnf
|
||||||
~time:!time_limit ~memory:!size_limit
|
~time:!time_limit ~memory:!size_limit
|
||||||
?dot_proof ~pp_model:!p_model ~check:!check ~progress:!p_progress
|
?dot_proof ~pp_proof:!p_proof ~pp_model:!p_model
|
||||||
|
~check:!check ~progress:!p_progress
|
||||||
solver)
|
solver)
|
||||||
() input
|
() input
|
||||||
with Exit ->
|
with Exit ->
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ module Log = Msat.Log
|
||||||
module type ARG = sig
|
module type ARG = sig
|
||||||
open Sidekick_core
|
open Sidekick_core
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module P : PROOF
|
module P : PROOF with type term = T.Term.t
|
||||||
|
|
||||||
val cc_view : T.Term.t -> (T.Fun.t, T.Term.t, T.Term.t Iter.t) CC_view.t
|
val cc_view : T.Term.t -> (T.Fun.t, T.Term.t, T.Term.t Iter.t) CC_view.t
|
||||||
|
|
||||||
|
|
@ -435,6 +435,7 @@ module Make(A : ARG)
|
||||||
include Sat_solver.Proof
|
include Sat_solver.Proof
|
||||||
module Dot = Msat_backend.Dot.Make(Sat_solver)(Msat_backend.Dot.Default(Sat_solver))
|
module Dot = Msat_backend.Dot.Make(Sat_solver)(Msat_backend.Dot.Default(Sat_solver))
|
||||||
let pp_dot = Dot.pp
|
let pp_dot = Dot.pp
|
||||||
|
let pp out (_self:t) = Fmt.string out "<Proof>" (* TODO *)
|
||||||
end
|
end
|
||||||
|
|
||||||
type proof = Proof.t
|
type proof = Proof.t
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,7 @@ module Solver_arg = struct
|
||||||
|
|
||||||
let cc_view = Term.cc_view
|
let cc_view = Term.cc_view
|
||||||
let is_valid_literal _ = true
|
let is_valid_literal _ = true
|
||||||
module P = struct
|
module P = Proof
|
||||||
type t = Default
|
|
||||||
let default=Default
|
|
||||||
let pp out _ = Fmt.string out "default"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
module Solver = Sidekick_msat_solver.Make(Solver_arg)
|
module Solver = Sidekick_msat_solver.Make(Solver_arg)
|
||||||
|
|
||||||
|
|
@ -147,6 +143,7 @@ let solve
|
||||||
?gc:_
|
?gc:_
|
||||||
?restarts:_
|
?restarts:_
|
||||||
?dot_proof
|
?dot_proof
|
||||||
|
?(pp_proof=false)
|
||||||
?(pp_model=false)
|
?(pp_model=false)
|
||||||
?(check=false)
|
?(check=false)
|
||||||
?time:_ ?memory:_ ?(progress=false)
|
?time:_ ?memory:_ ?(progress=false)
|
||||||
|
|
@ -179,12 +176,19 @@ let solve
|
||||||
let t3 = Sys.time () -. t2 in
|
let t3 = Sys.time () -. t2 in
|
||||||
Format.printf "Sat (%.3f/%.3f/%.3f)@." t1 (t2-.t1) t3;
|
Format.printf "Sat (%.3f/%.3f/%.3f)@." t1 (t2-.t1) t3;
|
||||||
| Solver.Unsat {proof;_} ->
|
| Solver.Unsat {proof;_} ->
|
||||||
|
|
||||||
|
let proof_opt =
|
||||||
|
if check||pp_proof then Lazy.force proof
|
||||||
|
else None
|
||||||
|
in
|
||||||
|
|
||||||
if check then (
|
if check then (
|
||||||
match proof with
|
match proof_opt with
|
||||||
| lazy (Some p) ->
|
| Some p ->
|
||||||
Profile.with_ "unsat.check" (fun () -> Solver.Proof.check p);
|
Profile.with_ "unsat.check" (fun () -> Solver.Proof.check p);
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
);
|
);
|
||||||
|
|
||||||
begin match dot_proof, proof with
|
begin match dot_proof, proof with
|
||||||
| None, _ -> ()
|
| None, _ -> ()
|
||||||
| Some file, lazy (Some p) ->
|
| Some file, lazy (Some p) ->
|
||||||
|
|
@ -197,8 +201,18 @@ let solve
|
||||||
Format.pp_print_flush fmt (); flush oc)
|
Format.pp_print_flush fmt (); flush oc)
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
end;
|
end;
|
||||||
|
|
||||||
let t3 = Sys.time () -. t2 in
|
let t3 = Sys.time () -. t2 in
|
||||||
Format.printf "Unsat (%.3f/%.3f/%.3f)@." t1 (t2-.t1) t3;
|
Format.printf "Unsat (%.3f/%.3f/%.3f)@." t1 (t2-.t1) t3;
|
||||||
|
|
||||||
|
(* TODO: allow to print proof into a file, more realistic for checking *)
|
||||||
|
if pp_proof then (
|
||||||
|
match proof_opt with
|
||||||
|
| None -> Error.errorf "cannot print proof, none was generated"
|
||||||
|
| Some p ->
|
||||||
|
Fmt.printf "(@[proof@ %a@])@." Solver.Proof.pp p;
|
||||||
|
);
|
||||||
|
|
||||||
| Solver.Unknown reas ->
|
| Solver.Unknown reas ->
|
||||||
Format.printf "Unknown (:reason %a)" Solver.Unknown.pp reas
|
Format.printf "Unknown (:reason %a)" Solver.Unknown.pp reas
|
||||||
end
|
end
|
||||||
|
|
@ -206,7 +220,7 @@ let solve
|
||||||
(* process a single statement *)
|
(* process a single statement *)
|
||||||
let process_stmt
|
let process_stmt
|
||||||
?hyps
|
?hyps
|
||||||
?gc ?restarts ?(pp_cnf=false) ?dot_proof ?pp_model ?(check=false)
|
?gc ?restarts ?(pp_cnf=false) ?dot_proof ?pp_proof ?pp_model ?(check=false)
|
||||||
?time ?memory ?progress
|
?time ?memory ?progress
|
||||||
(solver:Solver.t)
|
(solver:Solver.t)
|
||||||
(stmt:Statement.t) : unit or_error =
|
(stmt:Statement.t) : unit or_error =
|
||||||
|
|
@ -240,7 +254,8 @@ let process_stmt
|
||||||
List.map (fun (sign,t) -> Solver.mk_atom_t solver ~sign t) l
|
List.map (fun (sign,t) -> Solver.mk_atom_t solver ~sign t) l
|
||||||
in
|
in
|
||||||
solve
|
solve
|
||||||
?gc ?restarts ?dot_proof ~check ?pp_model ?time ?memory ?progress
|
?gc ?restarts ?dot_proof ~check ?pp_proof ?pp_model
|
||||||
|
?time ?memory ?progress
|
||||||
~assumptions ?hyps
|
~assumptions ?hyps
|
||||||
solver;
|
solver;
|
||||||
E.return()
|
E.return()
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ val process_stmt :
|
||||||
?restarts:bool ->
|
?restarts:bool ->
|
||||||
?pp_cnf:bool ->
|
?pp_cnf:bool ->
|
||||||
?dot_proof:string ->
|
?dot_proof:string ->
|
||||||
|
?pp_proof:bool ->
|
||||||
?pp_model:bool ->
|
?pp_model:bool ->
|
||||||
?check:bool ->
|
?check:bool ->
|
||||||
?time:float ->
|
?time:float ->
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
(** {1 Process Statements} *)
|
(** {1 Process Statements} *)
|
||||||
|
|
||||||
module ID = Sidekick_base_term.ID
|
module ID = Sidekick_base_term.ID
|
||||||
module Fmt = CCFormat
|
|
||||||
module E = CCResult
|
module E = CCResult
|
||||||
module Loc = Smtlib_utils.V_2_6.Loc
|
module Loc = Smtlib_utils.V_2_6.Loc
|
||||||
module Parse_ast = Smtlib_utils.V_2_6.Ast
|
module Parse_ast = Smtlib_utils.V_2_6.Ast
|
||||||
|
|
@ -9,11 +8,7 @@ module Process = Process
|
||||||
module Solver = Process.Solver
|
module Solver = Process.Solver
|
||||||
module Term = Sidekick_base_term.Term
|
module Term = Sidekick_base_term.Term
|
||||||
module Stmt = Sidekick_base_term.Statement
|
module Stmt = Sidekick_base_term.Statement
|
||||||
|
module Proof = Proof
|
||||||
module Proof = struct
|
|
||||||
type t = Proof_default
|
|
||||||
let default = Proof_default
|
|
||||||
end
|
|
||||||
|
|
||||||
type 'a or_error = ('a, string) CCResult.t
|
type 'a or_error = ('a, string) CCResult.t
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue