diff --git a/src/plugins/wp/Cache.ml b/src/plugins/wp/Cache.ml index 65da7ca4b528daae67654b0f7d37fdcc9eb24103..74e6c3b7ea8a2dfa30c8537266425371c8b77926 100644 --- a/src/plugins/wp/Cache.ml +++ b/src/plugins/wp/Cache.ml @@ -141,22 +141,6 @@ let is_updating () = | NoCache | Replay | Offline -> false | Update | Rebuild | Cleanup -> true -let task_hash wpo drv prover task = - lazy - begin - let file = Wpo.DISK.file_goal - ~pid:wpo.Wpo.po_pid - ~model:wpo.Wpo.po_model - ~prover:(VCS.Why3 prover) in - let _ = Command.print_file file - begin fun fmt -> - Format.fprintf fmt "(* WP Task for Prover %s *)@\n" - (Why3Provers.print_why3 prover) ; - Why3.Driver.print_task_prepared drv fmt task ; - end - in Digest.file file |> Digest.to_hex - end - let time_fits time = function | None | Some 0 -> true | Some limit -> time <= float limit @@ -256,23 +240,24 @@ let cleanup_cache () = Wp_parameters.warning ~current:false "Cannot cleanup cache" -type runner = - timeout:int option -> steplimit:int option -> - Why3.Driver.driver -> Why3Provers.t -> Why3.Task.task -> +type 'a digest = + Why3Provers.t -> 'a -> string + +type 'a runner = + timeout:int option -> steplimit:int option -> Why3Provers.t -> 'a -> VCS.result Task.task -let get_result wpo runner ~timeout ~steplimit drv prover task = +let get_result ~digest ~runner ~timeout ~steplimit prover goal = let mode = get_mode () in match mode with - | NoCache -> - runner ~timeout ~steplimit drv prover task + | NoCache -> runner ~timeout ~steplimit prover goal | Offline -> - let hash = task_hash wpo drv prover task in + let hash = lazy (digest prover goal) in let result = get_cache_result ~mode hash |> VCS.cached in if VCS.is_verdict result then incr hits else incr miss ; Task.return result | Update | Replay | Rebuild | Cleanup -> - let hash = task_hash wpo drv prover task in + let hash = lazy (digest prover goal) in let result = get_cache_result ~mode hash |> promote ~timeout ~steplimit |> VCS.cached in @@ -284,10 +269,12 @@ let get_result wpo runner ~timeout ~steplimit drv prover task = end else Task.finally - (runner ~timeout ~steplimit drv prover task) + (runner ~timeout ~steplimit prover goal) begin function | Task.Result result when VCS.is_verdict result -> incr miss ; set_cache_result ~mode hash prover result | _ -> () end + +(* -------------------------------------------------------------------------- *) diff --git a/src/plugins/wp/Cache.mli b/src/plugins/wp/Cache.mli index 85130ef5bbf06c648b9bd4bd09b4dd50ed1735c9..7197a8dc22207aa1aec096a1a61735d3e43b4bc8 100644 --- a/src/plugins/wp/Cache.mli +++ b/src/plugins/wp/Cache.mli @@ -34,9 +34,12 @@ val is_updating : unit -> bool val cleanup_cache : unit -> unit -type runner = - timeout:int option -> steplimit:int option -> - Why3.Driver.driver -> Why3Provers.t -> Why3.Task.task -> +type 'a digest = Why3Provers.t -> 'a -> string + +type 'a runner = + timeout:int option -> steplimit:int option -> Why3Provers.t -> 'a -> VCS.result Task.task -val get_result: Wpo.t -> runner -> runner +val get_result: digest:('a digest) -> runner:('a runner) -> 'a runner + +(**************************************************************************) diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index d19bacb5bd4c9800a65005833298362e9fdc30fd..17a55fcf05e666baabab4a36fb712cdfedfea96a 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -1198,34 +1198,11 @@ let ping_prover_call p = VCS.pp_result r; Task.Return (Task.Result r) -let call_prover prover_config ~timeout ~steplimit drv prover task = - let steps = match steplimit with Some 0 -> None | _ -> steplimit in - let limit = - let def = Why3.Call_provers.empty_limit in - { def with - Why3.Call_provers.limit_time = Why3.Opt.get_def def.limit_time timeout; - Why3.Call_provers.limit_steps = Why3.Opt.get_def def.limit_time steps; - } in - let with_steps = match steps, prover_config.Why3.Whyconf.command_steps with - | None, _ -> false - | Some _, Some _ -> true - | Some _, None -> - Wp_parameters.warning ~once:true ~current:false - "%a does not support steps limit (ignored option)" - Why3.Whyconf.print_prover prover ; - false - in - let command = Why3.Whyconf.get_complete_command prover_config ~with_steps in - let call = - Why3.Driver.prove_task_prepared ~command ~limit drv task in - let pp_steps fmt s = - if with_steps then Format.fprintf fmt "%i steps" (Why3.Opt.get_def (-1) s) - else Format.fprintf fmt "" - in - Wp_parameters.debug ~dkey "Why3 run prover %a with %i timeout %a@." +let call_prover_task ~timeout ~steps prover call = + Wp_parameters.debug ~dkey "Why3 run prover %a with timeout %d, steps %d@." Why3.Whyconf.print_prover prover (Why3.Opt.get_def (-1) timeout) - pp_steps steps ; + (Why3.Opt.get_def (-1) steps) ; let timeout = match timeout with None -> 0 | Some tlimit -> tlimit in let pcall = { call ; prover ; @@ -1242,14 +1219,48 @@ let call_prover prover_config ~timeout ~steplimit drv prover task = in Task.async ping -let is_trivial (t : Why3.Task.task) = - let goal = Why3.Task.task_goal_fmla t in - Why3.Term.t_equal goal Why3.Term.t_true +(* -------------------------------------------------------------------------- *) +(* --- Batch Prover --- *) +(* -------------------------------------------------------------------------- *) + +let digest wpo drv prover task = + let file = Wpo.DISK.file_goal + ~pid:wpo.Wpo.po_pid + ~model:wpo.Wpo.po_model + ~prover:(VCS.Why3 prover) in + let _ = Command.print_file file + begin fun fmt -> + Format.fprintf fmt "(* WP Task for Prover %s *)@\n" + (Why3Provers.print_why3 prover) ; + Why3.Driver.print_task_prepared drv fmt task ; + end + in Digest.file file |> Digest.to_hex + +let batch pconf driver ~timeout ~steplimit prover task = + let steps = match steplimit with Some 0 -> None | _ -> steplimit in + let limit = + let def = Why3.Call_provers.empty_limit in + { def with + Why3.Call_provers.limit_time = Why3.Opt.get_def def.limit_time timeout; + Why3.Call_provers.limit_steps = Why3.Opt.get_def def.limit_time steps; + } in + let with_steps = match steps, pconf.Why3.Whyconf.command_steps with + | None, _ -> false + | Some _, Some _ -> true + | Some _, None -> false + in + let command = Why3.Whyconf.get_complete_command pconf ~with_steps in + let call = Why3.Driver.prove_task_prepared ~command ~limit driver task in + call_prover_task ~timeout ~steps prover call (* -------------------------------------------------------------------------- *) (* --- Prove WPO --- *) (* -------------------------------------------------------------------------- *) +let is_trivial (t : Why3.Task.task) = + let goal = Why3.Task.task_goal_fmla t in + Why3.Term.t_equal goal Why3.Term.t_true + let build_proof_task ?timeout ?steplimit ~prover wpo () = try (* Always generate common task *) @@ -1259,12 +1270,14 @@ let build_proof_task ?timeout ?steplimit ~prover wpo () = then Task.return VCS.no_result (* Only generate *) else let env = WpContext.on_context context get_why3_env () in - let drv , config , task = prover_task env prover task in + let drv , pconf , task = prover_task env prover task in if is_trivial task then Task.return VCS.valid else - Cache.get_result wpo (call_prover config) - ~timeout ~steplimit drv prover task + Cache.get_result + ~digest:(digest wpo drv) + ~runner:(batch pconf drv) + ~timeout ~steplimit prover task with exn -> if Wp_parameters.has_dkey dkey_api then Wp_parameters.fatal "[Why3 Error] %a@\n%s" diff --git a/src/plugins/wp/Why3Provers.ml b/src/plugins/wp/Why3Provers.ml index ab50c9858b2de0a3fec9d8adc147994a3e0db981..46a1f714ab5902d7b9356ede7a3a0f879af75a54 100644 --- a/src/plugins/wp/Why3Provers.ml +++ b/src/plugins/wp/Why3Provers.ml @@ -109,3 +109,5 @@ let has_shortcut p s = (Why3.Whyconf.get_prover_shortcuts (config ())) with | None -> false | Some p' -> Why3.Whyconf.Prover.equal p p' + +(* -------------------------------------------------------------------------- *)