(********************************************************************) (* *) (* The Why3 Verification Platform / The Why3 Development Team *) (* Copyright 2010-2017 -- INRIA - CNRS - Paris-Sud University *) (* *) (* This software is distributed under the terms of the GNU Lesser *) (* General Public License version 2.1, with the special exception *) (* on linking described in file LICENSE. *) (* *) (********************************************************************) open Format open Why3 open Why3session_lib module Hprover = Whyconf.Hprover module S = Session let output_dir = ref "" let opt_context = ref false type style = SimpleTree | Table let opt_style = ref Table let default_style = "table" let set_opt_style = function | "simpletree" -> opt_style := SimpleTree | "table" -> opt_style := Table | _ -> eprintf "Unknown html style, ignored@." let () = set_opt_style default_style let opt_pp = ref [] let set_opt_pp_in,set_opt_pp_cmd,set_opt_pp_out = let suf = ref "" in let cmd = ref "" in (fun s -> suf := s), (fun s -> cmd := s), (fun s -> opt_pp := (!suf,(!cmd,s))::!opt_pp) let spec = ("-o", Arg.Set_string output_dir, " output directory ('-' for stdout)") :: ("--context", Arg.Set opt_context, " add context around the generated HTML code") :: ("--style", Arg.Symbol (["simpletree";"table"], set_opt_style), " style to use, defaults to '" ^ default_style ^ "'." ) :: ("--add_pp", Arg.Tuple [Arg.String set_opt_pp_in; Arg.String set_opt_pp_cmd; Arg.String set_opt_pp_out], " declare a pretty-printer for edited proofs") :: ("--coqdoc", Arg.Unit (fun ()-> opt_pp := (".v",("coqdoc --no-index --html -o %o %i",".html"))::!opt_pp), " use coqdoc to print Coq proofs") :: common_options open Session type context = (string -> (formatter -> unit session -> unit) -> unit session -> unit, formatter, unit) format let run_file (context : context) print_session fname = let project_dir = Session.get_project_dir fname in let session,_use_shapes = Session.read_session project_dir in let output_dir = if !output_dir = "" then project_dir else !output_dir in let basename = Filename.basename project_dir in let cout = if output_dir = "-" then stdout else open_out (Filename.concat output_dir ("why3session.html")) in let fmt = formatter_of_out_channel cout in if !opt_context then fprintf fmt context basename (print_session basename) session else print_session basename fmt session; pp_print_flush fmt (); if output_dir <> "-" then close_out cout module Table = struct let rec transf_depth tr = List.fold_left (fun depth g -> max depth (goal_depth g)) 0 tr.S.transf_goals and goal_depth g = S.PHstr.fold (fun _st tr depth -> max depth (1 + transf_depth tr)) g.S.goal_transformations 1 let theory_depth t = List.fold_left (fun depth g -> max depth (goal_depth g)) 0 t.S.theory_goals let provers_stats provers theory = S.theory_iter_proof_attempt (fun a -> Hprover.replace provers a.S.proof_prover a.S.proof_prover) theory let print_prover = Whyconf.print_prover let color_of_status ?(dark=false) fmt b = fprintf fmt "%s" (if b then if dark then "008000" else "C0FFC0" else "FF0000") let print_results fmt provers proofs = List.iter (fun p -> fprintf fmt " begin match res.Call_provers.pr_answer with | Call_provers.Valid -> fprintf fmt "C0FFC0\">%.2f" res.Call_provers.pr_time | Call_provers.Invalid -> fprintf fmt "FF0000\">Invalid" | Call_provers.Timeout -> fprintf fmt "FF8000\">Timeout (%ds)" pr.S.proof_limit.Call_provers.limit_time | Call_provers.OutOfMemory -> fprintf fmt "FF8000\">Out Of Memory (%dM)" pr.S.proof_limit.Call_provers.limit_mem | Call_provers.StepLimitExceeded -> fprintf fmt "FF8000\">Step limit exceeded" | Call_provers.Unknown _ -> fprintf fmt "FF8000\">%.2f" res.Call_provers.pr_time | Call_provers.Failure _ -> fprintf fmt "FF8000\">Failure" | Call_provers.HighFailure -> fprintf fmt "FF8000\">High Failure" end | S.InternalFailure _ -> fprintf fmt "E0E0E0\">Internal Failure" | S.Interrupted -> fprintf fmt "E0E0E0\">Not yet run" | S.Unedited -> fprintf fmt "E0E0E0\">Not yet edited" | S.Scheduled | S.Running | S.JustEdited -> assert false end; if pr.S.proof_obsolete then fprintf fmt " (obsolete)" with Not_found -> fprintf fmt "E0E0E0\">---" end; fprintf fmt "") provers let rec num_lines acc tr = List.fold_left (fun acc g -> 1 + PHstr.fold (fun _ tr acc -> 1 + num_lines acc tr) g.goal_transformations acc) acc tr.transf_goals let rec print_transf fmt depth max_depth provers tr = fprintf fmt ""; for _i=1 to 0 (* depth-1 *) do fprintf fmt "" done; fprintf fmt "" (color_of_status ~dark:false) (Opt.inhabited tr.S.transf_verified) (max_depth - depth + 1); (* for i=1 to depth-1 do fprintf fmt "    " done; *) fprintf fmt "%s" tr.transf_name ; for _i=1 (* depth *) to (*max_depth - 1 + *) List.length provers do fprintf fmt "" done; fprintf fmt "@\n"; fprintf fmt "  " (num_lines 0 tr); let (_:bool) = List.fold_left (fun is_first g -> print_goal fmt is_first (depth+1) max_depth provers g; false) true tr.transf_goals in () and print_goal fmt is_first depth max_depth provers g = if not is_first then fprintf fmt ""; (* for i=1 to 0 (\* depth-1 *\) do fprintf fmt "" done; *) fprintf fmt "" (color_of_status ~dark:false) (Opt.inhabited g.S.goal_verified) (max_depth - depth + 1); (* for i=1 to depth-1 do fprintf fmt "    " done; *) fprintf fmt "%s" (S.goal_expl g); (* for i=depth to max_depth-1 do fprintf fmt "" done; *) print_results fmt provers g.goal_external_proofs; fprintf fmt "@\n"; PHstr.iter (fun _ tr -> print_transf fmt depth max_depth provers tr) g.goal_transformations let print_theory fn fmt th = let depth = theory_depth th in if depth > 0 then let provers = Hprover.create 9 in provers_stats provers th; let provers = Hprover.fold (fun _ pr acc -> pr :: acc) provers [] in let provers = List.sort Whyconf.Prover.compare provers in let name = try let (l,t,_) = Theory.restore_path th.theory_name in String.concat "." ([fn]@l@[t]) with Not_found -> fn ^ "." ^ th.theory_name.Ident.id_string in fprintf fmt "

Theory \"%s\": " (color_of_status ~dark:true) (Opt.inhabited th.S.theory_verified) name; begin match th.S.theory_verified with | Some t -> fprintf fmt "fully verified in %.02f s" t | None -> fprintf fmt "not fully verified" end; fprintf fmt "

@\n"; fprintf fmt "" depth; (* fprintf fmt "
Obligations
"; *) List.iter (fun pr -> fprintf fmt "" print_prover pr) provers; fprintf fmt "@\n"; List.iter (print_goal fmt true 1 depth provers) th.theory_goals; fprintf fmt "
Obligations%a
@\n" let print_file fmt f = (* fprintf fmt "

File %s

@\n" f.file_name; *) let fn = Filename.basename f.file_name in let fn = Filename.chop_extension fn in fprintf fmt "%a" (Pp.print_list Pp.newline (print_theory fn)) f.file_theories let print_session name fmt s = fprintf fmt "

Why3 Proof Results for Project \"%s\"

@\n" name; fprintf fmt "%a" (Pp.print_iter2 PHstr.iter Pp.newline Pp.nothing Pp.nothing print_file) s.session_files let context : context = "\ \ \ Why3 session of %s\ \ \ %a\ \ \ " let run_one = run_file context print_session end module Simple = struct let print_prover = Whyconf.print_prover let print_proof_status fmt = function | Interrupted -> fprintf fmt "Not yet run" | Unedited -> fprintf fmt "Not yet edited" | JustEdited | Scheduled | Running -> assert false | Done pr -> fprintf fmt "Done: %a" Call_provers.print_prover_result pr | InternalFailure exn -> fprintf fmt "Failure: %a"Exn_printer.exn_printer exn let print_proof_attempt fmt pa = fprintf fmt "
  • %a : %a
  • " print_prover pa.proof_prover print_proof_status pa.proof_state let rec print_transf fmt tr = fprintf fmt "
  • %s :
      %a
  • " tr.transf_name (Pp.print_list Pp.newline print_goal) tr.transf_goals and print_goal fmt g = fprintf fmt "
  • %s :
      %a%a
  • " g.goal_name.Ident.id_string (Pp.print_iter2 PHprover.iter Pp.newline Pp.nothing Pp.nothing print_proof_attempt) g.goal_external_proofs (Pp.print_iter2 PHstr.iter Pp.newline Pp.nothing Pp.nothing print_transf) g.goal_transformations let print_theory fmt th = fprintf fmt "
  • %s :
      %a
  • " th.theory_name.Ident.id_string (Pp.print_list Pp.newline print_goal) th.theory_goals let print_file fmt f = fprintf fmt "
  • %s :
      %a
  • " f.file_name (Pp.print_list Pp.newline print_theory) f.file_theories let print_session _name fmt s = fprintf fmt "
      %a
    " (Pp.print_iter2 PHstr.iter Pp.newline Pp.nothing Pp.nothing print_file) s.session_files let context : context = "\ \ \ Why3 session of %s\ \ \ %a\ \ \ " let run_one = run_file context print_session end let run () = let _,_,should_exit1 = read_env_spec () in if should_exit1 then exit 1; match !opt_style with | Table -> iter_files Table.run_one | SimpleTree -> iter_files Simple.run_one let cmd = { cmd_spec = spec; cmd_desc = "output session in HTML format"; cmd_name = "html"; cmd_run = run; } (* Local Variables: compile-command: "unset LANG; make -C ../.. bin/why3session.byte" End: *)