diff --git a/src/plugins/qed/export_coq.ml b/src/plugins/qed/export_coq.ml index 8e06fa9404c3431e141abaf3713952d73278804f..33756bcc50bc9d5d490734a66516cbbbb1c63793 100644 --- a/src/plugins/qed/export_coq.ml +++ b/src/plugins/qed/export_coq.ml @@ -362,7 +362,8 @@ struct begin self#declare_signature fmt f (List.map tau_of_var xs) t ; let fix = prefix ^ (link_name (self#link f)) in - self#declare_axiom fmt fix xs [] (e_eq (e_fun f (List.map e_var xs)) e) ; + self#declare_axiom fmt fix xs [] + (e_eq (e_fun ~result:t f (List.map e_var xs)) e) ; end method declare_axiom fmt lemma xs (_:trigger list list) p = diff --git a/src/plugins/qed/export_why3.ml b/src/plugins/qed/export_why3.ml index f940aa001d959d5df4e7367751dd1fa65bbde490..84aca8d411871ec01cdd4c1c072369011ca9d969 100644 --- a/src/plugins/qed/export_why3.ml +++ b/src/plugins/qed/export_why3.ml @@ -304,7 +304,8 @@ struct begin self#declare_signature fmt f (List.map tau_of_var xs) t ; let fix = prefix ^ (link_name (self#link f)) in - self#declare_axiom fmt fix xs [] (e_eq (e_fun f (List.map e_var xs)) e) ; + self#declare_axiom fmt fix xs [] + (e_eq (e_fun ~result:t f (List.map e_var xs)) e) ; end end diff --git a/src/plugins/qed/term.ml b/src/plugins/qed/term.ml index 7a2a8774a2879c799d600886d122348bdcbe1fcd..11f8e2cf2e24801ac3a03327b171a2a96da6365a 100644 --- a/src/plugins/qed/term.ml +++ b/src/plugins/qed/term.ml @@ -884,7 +884,7 @@ struct let c_record fxs = match fxs with - | [] | [_] -> insert(Rdef fxs) + | [] -> insert(Rdef fxs) | fx::gys -> try let base (f,v) = @@ -985,13 +985,13 @@ struct | x::[] as xs -> begin match x.repr with - | If(c,a,b) -> !extern_ite c (!extern_fun f [a]) (!extern_fun f [b]) + | If(c,a,b) -> !extern_ite c (!extern_fun f [a] tau) (!extern_fun f [b] tau) | _ -> operation (FUN(f,xs,tau)) end | a::b::[] as xs -> distribute_if_over_operation false (fun f xs -> operation (FUN(f,xs,tau))) f xs - (fun a b -> !extern_fun f [a;b]) a b + (fun a b -> !extern_fun f [a;b] tau) a b | xs -> operation (FUN(f,xs,tau)) let c_builtin_fun f xs tau = distribute f tau xs @@ -1101,12 +1101,12 @@ struct else modified,xs,ys in simpl false true xs ys - let rec element = function + let rec element tau = function | E_none -> assert false | E_int k -> e_int k | E_true -> e_true | E_false -> e_false - | E_fun (f,l) -> c_fun f (List.map element l) None + | E_fun (f,l) -> c_fun f (List.map (element tau) l) tau let rec is_element e x = match e , x.repr with | E_int k , Kint z -> Z.equal (Z.of_int k) z @@ -1144,7 +1144,7 @@ struct in if op.absorbant <> E_none && List.exists (is_element op.absorbant) xs - then element op.absorbant + then element tau op.absorbant else let xs = if op.neutral <> E_none @@ -1152,7 +1152,7 @@ struct else xs in let xs = if op.idempotent then op_idempotent xs else xs in match xs with - | [] when op.neutral <> E_none -> element op.neutral + | [] when op.neutral <> E_none -> element tau op.neutral | [x] when op.associative -> x | _ -> c_builtin_fun f xs tau @@ -1161,8 +1161,7 @@ struct | Logic.Operator op -> op_fun f op xs tau | _ -> c_builtin_fun f xs tau - let e_fun ?result f xs = e_fungen f xs result - let () = extern_fun := e_fun + let () = extern_fun := e_fungen (* -------------------------------------------------------------------------- *) (* --- Ground & Arithmetics --- *) @@ -1671,6 +1670,8 @@ struct (* --- Equality --- *) (* -------------------------------------------------------------------------- *) + let typeof2 x y = if x.tau = None then y.tau else x.tau + let rec e_eq x y = if x == y then e_true else relation eq_symb EQ x y @@ -1714,13 +1715,17 @@ struct and eq_invertible x y f xs ys = let modified,xs,ys = op_invertible ~ac:(is_ac f) xs ys in if modified - then eq_symb (e_fun f xs ?result:x.tau) (e_fun f ys ?result:y.tau) + then + let tr = typeof2 x y in + eq_symb (e_fungen f xs tr) (e_fungen f ys tr) else c_builtin_eq x y and eq_invertible_both x y f g xs ys = let modified,xs',ys' = op_invertible ~ac:(is_ac f) xs [y] in if modified - then eq_symb (e_fun f xs' ?result:x.tau) (e_fun f ys' ?result:y.tau) + then + let tr = typeof2 x y in + eq_symb (e_fungen f xs' tr) (e_fungen f ys' tr) else eq_invertible x y g [x] ys and eq_field (f,x) (g,y) = @@ -1775,13 +1780,17 @@ struct and neq_invertible x y f xs ys = let modified,xs,ys = op_invertible ~ac:(is_ac f) xs ys in if modified - then neq_symb (e_fun f xs) (e_fun f ys) + then + let tr = typeof2 x y in + neq_symb (e_fungen f xs tr) (e_fungen f ys tr) else c_builtin_neq x y and neq_invertible_both x y f g xs ys = let modified,xs',ys' = op_invertible ~ac:(is_ac f) xs [y] in if modified - then neq_symb (e_fun f xs') (e_fun f ys') + then + let tr = typeof2 x y in + neq_symb (e_fungen f xs' tr) (e_fungen f ys' tr) else neq_invertible x y g [x] ys and neq_field (f,x) (g,y) = @@ -2037,7 +2046,7 @@ struct | Times(z,t) -> e_times z (f t) | If(e,a,b) -> e_if (f e) (f a) (f b) | Imply(hs,p) -> e_imply (List.map f hs) (f p) - | Fun(g,xs) -> e_fun ?result:e0.tau g (List.map f xs) + | Fun(g,xs) -> e_fungen g (List.map f xs) e0.tau | Acst(t,v) -> e_const t v | Aget(x,y) -> e_get (f x) (f y) | Aset(x,y,z) -> e_set (f x) (f y) (f z) @@ -2072,7 +2081,6 @@ struct let validate fn e = if not (lc_closed e) then begin - Format.eprintf "Invalid %s: %a@." fn pretty e ; raise (Invalid_argument (fn ^ ": non lc-closed binding")) end @@ -2226,7 +2234,6 @@ struct List.iter (Subst.add_term sigma) es ; apply sigma Intmap.empty e es - (* -------------------------------------------------------------------------- *) (* --- convert between states --- *) (* -------------------------------------------------------------------------- *) @@ -2259,7 +2266,7 @@ struct | Times(z,t) -> times z (aux t) | If(e,a,b) -> e_if (aux e) (aux a) (aux b) | Imply(hs,p) -> e_imply (List.map aux hs) (aux p) - | Fun(g,xs) -> e_fun ?result:e.tau g (List.map aux xs) + | Fun(g,xs) -> e_fungen g (List.map aux xs) e.tau | Acst(t,v) -> e_const t (aux v) | Aget(x,y) -> e_get (aux x) (aux y) | Aset(x,y,z) -> e_set (aux x) (aux y) (aux z) @@ -2403,7 +2410,7 @@ struct | Leq(x,y) -> e_leq x y | If(e,a,b) -> e_if e a b | Imply(hs,p) -> e_imply hs p - | Fun(g,xs) -> e_fun ?result g xs + | Fun(g,xs) -> e_fungen g xs result | Acst(t,v) -> e_const t v | Aget(m,k) -> e_get m k | Aset(m,k,v) -> e_set m k v @@ -2433,6 +2440,8 @@ struct f a | _ -> repr_iter f e.repr + let e_fun ?result f xs = e_fungen f xs result + (* -------------------------------------------------------------------------- *) (* --- Sub-terms --- *) (* -------------------------------------------------------------------------- *) @@ -2506,7 +2515,7 @@ struct | Aset _ -> bad_position () | Rdef _ | Rget _ -> failwith "change in place for records not yet implemented" - | Fun (f,ops) -> e_fun ?result:e.tau f (change_in_list ops i l) + | Fun (f,ops) -> e_fungen f (change_in_list ops i l) e.tau | Bind(q,x,t) when i = 0 -> c_bind q x (aux t l) | Bind _ -> bad_position () | Apply(f,args) when i = 0 -> @@ -2550,7 +2559,8 @@ struct | _ -> true) fvs in - Some ( base , fothers ) + if fothers = [] then None (* suspiscious *) + else Some ( base , fothers ) (* ------------------------------------------------------------------------ *) (* --- Symbol --- *) diff --git a/src/plugins/wp/Definitions.ml b/src/plugins/wp/Definitions.ml index 2a40a79b124bb21ed5bd06a79c017168a3adf4eb..9acf448228ae8e33af9c797714522ca1addd52e3 100644 --- a/src/plugins/wp/Definitions.ml +++ b/src/plugins/wp/Definitions.ml @@ -353,14 +353,18 @@ class virtual visitor main = method vparam x = self#vtau (tau_of_var x) - method private repr ~bool x = - self#vtau (Lang.F.typeof x); - match F.repr x with + method private repr ~bool t = + begin + try self#vtau (Lang.F.typeof t); + with Not_found -> + Wp_parameters.debug ~level:2 "@[<hov 2>Untyped term: %a@]" F.pp_term t ; + end ; + match F.repr t with | Fun(f,_) -> self#vsymbol f | Rget(_,f) -> self#vfield f | Rdef fts -> List.iter (fun (f,_) -> self#vfield f) fts | Fvar x -> self#vparam x - | Bind(_,t,_) -> self#vtau t + | Bind(_,qt,_) -> self#vtau qt | True | False | Kint _ | Kreal _ | Bvar _ | Times _ | Add _ | Mul _ | Div _ | Mod _ | Aget _ | Aset _ | Apply _ -> () @@ -422,7 +426,7 @@ class virtual visitor main = match f with | Model { m_source = Extern e } -> self#vlibrary e.ext_library | Model { m_source = Generated _ } | ACSL _ -> self#vlfun f - | CTOR c -> self#vadt (Lang.atype c.ctor_type) + | CTOR c -> self#vadt (Lang.adt c.ctor_type) end method private vtrigger = function diff --git a/src/plugins/wp/GuiGoal.ml b/src/plugins/wp/GuiGoal.ml index 88258560f1f600fb7a8abddf69aae8a6ba3b2e02..407f98990d661247c025864069dd4497c6717e03 100644 --- a/src/plugins/wp/GuiGoal.ml +++ b/src/plugins/wp/GuiGoal.ml @@ -220,6 +220,7 @@ class pane (gprovers : GuiConfig.provers) = cancel proof ; Task.iter Task.cancel pool ; state <- Proof proof ; + ProofEngine.forward proof ; printer#reset ; self#update @@ -366,6 +367,7 @@ class pane (gprovers : GuiConfig.provers) = self#update_provers None ; self#update_tactics None ; state <- Proof pw ; + ProofEngine.forward pw ; self#update ; end @@ -586,6 +588,8 @@ class pane (gprovers : GuiConfig.provers) = printer#reset ; self#update ; end + else + Wutil.later self#commit method private schedule pool provers goal = Prover.spawn goal diff --git a/src/plugins/wp/GuiProof.ml b/src/plugins/wp/GuiProof.ml index d352290613b8d9a8e3a4553afd3d71f27b34aae3..1b984174b7b0f54bd374c223529e9ba6b22a773f 100644 --- a/src/plugins/wp/GuiProof.ml +++ b/src/plugins/wp/GuiProof.ml @@ -26,12 +26,10 @@ let rec rootchain node ns = | Some p -> rootchain p (p::ns) let pp_status fmt node = - match ProofEngine.state node with - | `Opened -> Format.fprintf fmt "@{<red>opened@}" - | `Proved | `Pending 0 -> Format.fprintf fmt "@{<green>proved@}" - | `Pending 1 -> Format.fprintf fmt "@{<orange>pending@}" - | `Pending n -> Format.fprintf fmt "@{<orange>pending %d@}" n - | `Script n -> Format.fprintf fmt "script with %d leaves" n + match ProofEngine.pending node with + | 0 -> Format.fprintf fmt "@{<green>proved@}" + | 1 -> Format.fprintf fmt "@{<orange>pending@}" + | n -> Format.fprintf fmt "@{<orange>pending %d@}" n class printer (text : Wtext.text) = let nodes : ProofEngine.position Wtext.marker = text#marker in @@ -66,36 +64,25 @@ class printer (text : Wtext.text) = VCS.pp_prover prv VCS.pp_result res ) (Wpo.get_results wpo) - method private pp_state fmt node = - match ProofEngine.state node with - | `Proved -> Format.pp_print_string fmt "proved" - | `Opened -> Format.pp_print_string fmt "opened" - | `Pending 0 -> Format.pp_print_string fmt "terminated" - | `Pending 1 -> Format.pp_print_string fmt "pending" - | `Pending n -> Format.fprintf fmt "pending(%d)" n - | `Script 0 -> Format.pp_print_string fmt "script" - | `Script n -> Format.fprintf fmt "script(%d)" n - method private tactic header node = + text#printf "@{<bf>Tactical@}@} %s:" header ; match ProofEngine.children node with | [] -> - text#printf "@{<bf>Tactical@}@} %s: @{<green>proved@} (Qed).@\n" header + text#printf "@{<green>proved@} (Qed).@\n" | [_,child] -> - text#printf "@{<bf>Tactical@} %a: %a.@\n" self#pp_node child self#pp_state child + text#printf "%a (%a).@\n" pp_status child self#pp_node child | children -> - begin match ProofEngine.pending node with - | 0 -> text#printf "@{<green>@{<bf>Tactical@}@} %s: @{<green>proved@}.@\n" header - | 1 -> text#printf "@{<bf>Tactical@} %s: @{<orange>pending@}.@\n" header ; - | n -> text#printf "@{<bf>Tactical@} %s: @{<orange>pending(%d)@}.@\n" header n ; - end ; - List.iter - (fun (part,child) -> text#printf "@{<bf>SubGoal@} %s : %a.@\n" - part self#pp_state child) - children + begin + text#printf " (%a)@\n@{<bf>Sub Goals:@}" pp_status node ; + List.iter + (fun (part,child) -> text#printf "@\n - %s : %a" part pp_status child) + children ; + text#printf "@." ; + end method private alternative g a = let open ProofScript in match a with - | Tactic(0,{ header },_) -> text#printf "@{<bf>Script@} %s: terminating.@\n" header + | Tactic(0,{ header },_) -> text#printf "@{<bf>Script@} %s: finished.@\n" header | Tactic(n,{ header },_) -> text#printf "@{<bf>Script@} %s: pending %d.@\n" header n | Error(msg,_) -> text#printf "@{<bf>Script@} Error (%S).@\n" msg | Prover(p,r) -> diff --git a/src/plugins/wp/Lang.ml b/src/plugins/wp/Lang.ml index a1cd8c082965e828251e992e1f7d4ec8990ea82c..cf1934d1e049824f31ae271281701a52a06300b0 100644 --- a/src/plugins/wp/Lang.ml +++ b/src/plugins/wp/Lang.ml @@ -196,9 +196,24 @@ let rec varpoly k x = function | [] -> Warning.error "Unbound type parameter <%s>" x | y::ys -> if x = y then k else varpoly (succ k) x ys +type t_builtin = E_mdt of mdt | E_poly of (tau list -> tau) + let builtins = Hashtbl.create 131 -let rec tau_of_ltype t = match Logic_utils.unroll_type ~unroll_typedef:false t with +let adt lt = + try match Hashtbl.find builtins lt.lt_name with + | E_mdt m -> Mtype m + | E_poly _ -> assert false + with Not_found -> Atype lt + +let atype lt ts = + try match Hashtbl.find builtins lt.lt_name with + | E_mdt m -> Logic.Data(Mtype m,ts) + | E_poly ftau -> ftau ts + with Not_found -> Logic.Data(Atype lt,ts) + +let rec tau_of_ltype t = + match Logic_utils.unroll_type ~unroll_typedef:false t with | Linteger -> Logic.Int | Lreal -> Logic.Real | Ctype typ -> tau_of_ctype typ @@ -207,14 +222,10 @@ let rec tau_of_ltype t = match Logic_utils.unroll_type ~unroll_typedef:false t w Warning.error "array type non-supported(%a)" Printer.pp_logic_type t | Ltype _ as b when Logic_const.is_boolean_type b -> Logic.Bool - | Ltype(lt,ps) -> - let tau = - (*TODO: check arity *) - try Mtype(Hashtbl.find builtins lt.lt_name) - with Not_found -> Atype lt - in Logic.Data(tau,List.map tau_of_ltype ps) - -let tau_of_return l = match l.l_type with + | Ltype(lt,lts) -> atype lt (List.map tau_of_ltype lts) + +let tau_of_return l = + match l.l_type with | None -> Logic.Prop | Some t -> tau_of_ltype t @@ -268,19 +279,20 @@ end (* --- Datatypes --- *) (* -------------------------------------------------------------------------- *) -let atype lt = - try Mtype(Hashtbl.find builtins lt.lt_name) - with Not_found -> Atype lt - let get_builtin_type ~name ~link ~library = - try Mtype (Hashtbl.find builtins name) + try match Hashtbl.find builtins name with + | E_mdt m -> Mtype m + | E_poly _ -> assert false with Not_found -> let m = new_extern ~link ~library ~debug:name in - Hashtbl.add builtins name m ; Mtype m + Hashtbl.add builtins name (E_mdt m) ; Mtype m let set_builtin_type ~name ~link ~library = let m = new_extern ~link ~library ~debug:name in - Hashtbl.add builtins name m + Hashtbl.add builtins name (E_mdt m) + +let set_builtin_poly ~name f = + Hashtbl.add builtins name (E_poly f) let mem_builtin_type ~name = Hashtbl.mem builtins name @@ -290,7 +302,9 @@ let is_builtin lt = Hashtbl.mem builtins lt.lt_name let is_builtin_type ~name = function | Data(Mtype m,_) -> begin - try m == Hashtbl.find builtins name + try match Hashtbl.find builtins name with + | E_mdt m0 -> m == m0 + | _ -> false with Not_found -> false end | _ -> false @@ -729,6 +743,20 @@ struct let is_pfalse = is_false let is_equal a b = is_true (e_eq a b) + let is_int e = + try typeof e = Qed.Logic.Int with Not_found -> false + + let is_real e = + try typeof e = Qed.Logic.Real with Not_found -> false + + let is_prop e = + try match typeof e with Qed.Logic.Prop | Qed.Logic.Bool -> true | _ -> false + with Not_found -> false + + let is_arith e = + try match typeof e with Qed.Logic.Int | Qed.Logic.Real -> true | _ -> false + with Not_found -> false + let p_equal = e_eq let p_equals = List.map (fun (x,y) -> p_equal x y) let p_neq = e_neq diff --git a/src/plugins/wp/Lang.mli b/src/plugins/wp/Lang.mli index 517f9857173e4c91d9fcb76e029d08d280b7ce11..f835b48962e18d8fe6e85d68af25aa8a6b4ecdbd 100644 --- a/src/plugins/wp/Lang.mli +++ b/src/plugins/wp/Lang.mli @@ -94,6 +94,7 @@ and source = | Extern of Engine.link extern val mem_builtin_type : name:string -> bool +val set_builtin_poly : name:string -> (tau list -> tau) -> unit val set_builtin_type : name:string -> link:string infoprover -> library:string -> unit val get_builtin_type : name:string -> link:string infoprover -> library:string -> adt val is_builtin : logic_type_info -> bool @@ -101,12 +102,13 @@ val is_builtin_type : name:string -> tau -> bool val datatype : library:string -> string -> adt val record : link:string infoprover -> library:string -> (string * tau) list -> adt -val atype : logic_type_info -> adt val comp : compinfo -> adt val field : adt -> string -> field val fields_of_adt : adt -> field list val fields_of_tau : tau -> field list val fields_of_field : field -> field list +val atype : logic_type_info -> tau list -> tau +val adt : logic_type_info -> adt (** Must not be a builtin *) type balance = Nary | Left | Right diff --git a/src/plugins/wp/LogicBuiltins.ml b/src/plugins/wp/LogicBuiltins.ml index 8fa7c5044b492f4ace85077d97fbcd48fa0213ee..8b72dbbf23638161d1ef492574243ce79d5b1a1e 100644 --- a/src/plugins/wp/LogicBuiltins.ml +++ b/src/plugins/wp/LogicBuiltins.ml @@ -235,6 +235,8 @@ let add_type ~source name ~library ?(link=Lang.infoprover name) () = Wp_parameters.warning ~source "Redefinition of type '%s'" name ; Lang.set_builtin_type ~name ~library ~link +let hack_type name poly = Lang.set_builtin_poly ~name poly + type sanitizer = driver_dir:string -> string -> string let sanitizers : ( string * string , sanitizer ) Hashtbl.t = Hashtbl.create 10 diff --git a/src/plugins/wp/LogicBuiltins.mli b/src/plugins/wp/LogicBuiltins.mli index 41a530ff77b0ece0f423052649aa5795b3dc7803..f54c67fd51308b702dc208aa412e2c63797a4eaa 100644 --- a/src/plugins/wp/LogicBuiltins.mli +++ b/src/plugins/wp/LogicBuiltins.mli @@ -115,4 +115,7 @@ val lookup : string -> kind list -> builtin of this symbol with the provided Qed function on terms. *) val hack : string -> (F.term list -> F.term) -> unit +(** Replace a logic type definition or predicate by a built-in type. *) +val hack_type : string -> (F.tau list -> F.tau) -> unit + val dump : unit -> unit diff --git a/src/plugins/wp/LogicCompiler.ml b/src/plugins/wp/LogicCompiler.ml index 69e3a0ea22a775b3f89247091212618447289c0e..27f13b6965a9a6129207f2f2d07d0533af2e2f95 100644 --- a/src/plugins/wp/LogicCompiler.ml +++ b/src/plugins/wp/LogicCompiler.ml @@ -840,6 +840,7 @@ struct ) sparam let call_fun env + (result:F.tau) (phi:logic_info) (labels:logic_label list) (parameters:F.term list) : F.term = @@ -847,7 +848,7 @@ struct | CST c -> e_zint c | SIG sparam -> let es = call_params env phi labels sparam parameters in - F.e_fun (ACSL phi) es + F.e_fun ~result (ACSL phi) es let call_pred env (phi:logic_info) @@ -871,11 +872,12 @@ struct of arity 0 are represented in the AST as a variable not as an application of the function with no arguments *) let cst = Logic_env.find_logic_cons x in + let result = Lang.tau_of_ltype x.lv_type in let v = match LogicBuiltins.logic cst with - | ACSLDEF -> call_fun env cst [] [] + | ACSLDEF -> call_fun env result cst [] [] | HACK phi -> phi [] - | LFUN phi -> e_fun phi [] ~result:(Lang.tau_of_ltype x.lv_type) + | LFUN phi -> e_fun ~result phi [] in Cvalues.plain x.lv_type v with Not_found -> if Logic_env.is_logic_function x.lv_name then diff --git a/src/plugins/wp/LogicCompiler.mli b/src/plugins/wp/LogicCompiler.mli index a34f3a35511f0f8ecd7a8f06270419e251ec7c9c..6f818870f67f5de55d733cf86722e415d099db5a 100644 --- a/src/plugins/wp/LogicCompiler.mli +++ b/src/plugins/wp/LogicCompiler.mli @@ -111,7 +111,9 @@ sig (** {3 Application} *) - val call_fun : env -> logic_info + val call_fun : env + -> tau + -> logic_info -> logic_label list -> F.term list -> F.term diff --git a/src/plugins/wp/LogicSemantics.ml b/src/plugins/wp/LogicSemantics.ml index 146dc9732866d70dadffce752605936ea23045af..1a84dcf2d3c491674e8b9d914c48f277182d5de3 100644 --- a/src/plugins/wp/LogicSemantics.ml +++ b/src/plugins/wp/LogicSemantics.ml @@ -673,10 +673,11 @@ struct | Tapp(f,ls,ts) -> let vs = List.map (val_of_term env) ts in + let result = Lang.tau_of_ltype t.term_type in let r = match LogicBuiltins.logic f with - | ACSLDEF -> C.call_fun env f ls vs + | ACSLDEF -> C.call_fun env result f ls vs | HACK phi -> phi vs - | LFUN f -> e_fun f vs ~result:(Lang.tau_of_ltype t.term_type) + | LFUN f -> e_fun ~result f vs in Vexp r | Tlambda _ -> diff --git a/src/plugins/wp/ProofEngine.ml b/src/plugins/wp/ProofEngine.ml index f86ec63be01681a38f4718160c28dc394a20ee52..d049b1ee2eb99347c69d567009050dac12b0217d 100644 --- a/src/plugins/wp/ProofEngine.ml +++ b/src/plugins/wp/ProofEngine.ml @@ -206,33 +206,15 @@ let children n = (* -------------------------------------------------------------------------- *) type status = [ `Main | `Proved | `Pending of int ] -type state = [ `Opened | `Proved | `Pending of int | `Script of int ] let status t : status = match t.root with | None -> if Wpo.is_proved t.main then `Proved else `Main | Some root -> - `Pending (pending root) - - -let opened n = not (Wpo.is_proved n.goal) - -let state n = - if Wpo.is_proved n.goal then `Proved else - match n.script with - | Opened -> `Opened - | Script s -> - begin - match List.partition ProofScript.is_prover s with - | [] , s -> `Script (ProofScript.status s) - | p , [] -> `Pending (ProofScript.status p) - | provers , scripts -> - let np = ProofScript.status provers in - let ns = ProofScript.status scripts in - `Script( min ns np ) - end - | Tactic _ -> `Pending (pending n) + match root.script with + | Opened | Script _ -> `Main + | Tactic _ -> `Pending (pending root) (* -------------------------------------------------------------------------- *) (* --- Navigation --- *) diff --git a/src/plugins/wp/ProofEngine.mli b/src/plugins/wp/ProofEngine.mli index b36f120911be60d77e3d0c21cd757aa0d5d138c1..2150cbae4c1ffbeae3e3a3dd88ecec4e186d2460 100644 --- a/src/plugins/wp/ProofEngine.mli +++ b/src/plugins/wp/ProofEngine.mli @@ -36,7 +36,6 @@ val validate : ?incomplete:bool -> tree -> unit (** Leaves are numbered from 0 to n-1 *) type status = [ `Main | `Proved | `Pending of int ] -type state = [ `Opened | `Proved | `Pending of int | `Script of int ] type current = [ `Main | `Internal of node | `Leaf of int * node ] type position = [ `Main | `Node of node | `Leaf of int ] @@ -53,13 +52,11 @@ val head : tree -> Wpo.t val goal : node -> Wpo.t val tree_context : tree -> WpContext.t val node_context : node -> WpContext.t -val opened : node -> bool (** not proved *) -val proved : node -> bool (** not opened *) val title : node -> string -val state : node -> state +val proved : node -> bool +val pending : node -> int (** 0 means proved *) val parent : node -> node option -val pending : node -> int val children : node -> (string * node) list val tactical : node -> ProofScript.jtactic option val get_strategies : node -> int * Strategy.t array (* current index *) diff --git a/src/plugins/wp/ProofScript.ml b/src/plugins/wp/ProofScript.ml index 35a027f61a35a1e10590516cd76d315596172eed..1c25e49dd9e0623ad45c792981b0f0363f56d5e9 100644 --- a/src/plugins/wp/ProofScript.ml +++ b/src/plugins/wp/ProofScript.ml @@ -369,16 +369,18 @@ let pending = function | Tactic(n,_,_) -> n | Error _ -> 1 -let rec status = function +let rec pending_any = function | [] -> 1 | [a] -> pending a | a::s -> let n = pending a in - if n = 0 then 0 else min n (status s) + if n = 0 then 0 else min n (pending_any s) let rec subgoals n = function | [] -> n - | (_,a)::s -> subgoals (n + status a) s + | (_,js)::s -> subgoals (n + pending_any js) s + +let has_proof = List.exists is_tactic let a_prover p r = Prover(p,r) let a_tactic tac children = Tactic(subgoals 0 children,tac,children) diff --git a/src/plugins/wp/ProofScript.mli b/src/plugins/wp/ProofScript.mli index aca4732eea85763555c4597783ed0c00ec910921..5f599ff49d1cb8f6630f5a36e4c4cb9bcc452ea2 100644 --- a/src/plugins/wp/ProofScript.mli +++ b/src/plugins/wp/ProofScript.mli @@ -43,7 +43,8 @@ val a_prover : VCS.prover -> VCS.result -> alternative val a_tactic : jtactic -> (string * jscript) list -> alternative val pending : alternative -> int (** pending goals *) -val status : jscript -> int (** minimum of pending goals *) +val pending_any : jscript -> int (** minimum of pending goals *) +val has_proof : jscript -> bool (** Has a tactical alternative *) val decode : Json.t -> jscript val encode : jscript -> Json.t diff --git a/src/plugins/wp/ProverCoq.ml b/src/plugins/wp/ProverCoq.ml index 946fc35b9cc5a266d7fff5b1ec0641b78ded0280..a9874efb94c2f35398c1d95826ef27f5e8d964d0 100644 --- a/src/plugins/wp/ProverCoq.ml +++ b/src/plugins/wp/ProverCoq.ml @@ -173,7 +173,7 @@ class visitor fmt c = method on_type lt def = begin self#lines ; - engine#declare_type fmt (Lang.atype lt) (List.length lt.lt_params) def ; + engine#declare_type fmt (Lang.adt lt) (List.length lt.lt_params) def ; end method on_comp c fts = diff --git a/src/plugins/wp/ProverErgo.ml b/src/plugins/wp/ProverErgo.ml index 19b82a4ef4163d4d2ac13019ba5a144082d7d442..9a6f0499405192fd22ea015b1b8496ca10027741 100644 --- a/src/plugins/wp/ProverErgo.ml +++ b/src/plugins/wp/ProverErgo.ml @@ -178,7 +178,7 @@ class visitor fmt c = method on_type lt def = begin self#lines ; - engine#declare_type fmt (Lang.atype lt) (List.length lt.lt_params) def ; + engine#declare_type fmt (Lang.adt lt) (List.length lt.lt_params) def ; end method on_comp c fts = diff --git a/src/plugins/wp/ProverScript.ml b/src/plugins/wp/ProverScript.ml index 7e2b91afb6f9eb66305c9baee77613b743034ab0..f0ba4bedf839e9865ba25f19b076a84736b63980 100644 --- a/src/plugins/wp/ProverScript.ml +++ b/src/plugins/wp/ProverScript.ml @@ -463,6 +463,7 @@ let search (* -------------------------------------------------------------------------- *) let proofs = Hashtbl.create 32 + let has_proof wpo = let wid = wpo.Wpo.po_gid in try Hashtbl.find proofs wid @@ -471,7 +472,7 @@ let has_proof wpo = let ok = try let script = ProofScript.decode (ProofSession.load wpo) in - ProofScript.status script = 0 + ProofScript.has_proof script with _ -> false in (Hashtbl.add proofs wid ok ; ok) else false diff --git a/src/plugins/wp/ProverWhy3.ml b/src/plugins/wp/ProverWhy3.ml index e3f3b6659e42f7391963d23be06e5b775cfcaaff..1284425bd9855e200a6e4541ffd78759b50e8e25 100644 --- a/src/plugins/wp/ProverWhy3.ml +++ b/src/plugins/wp/ProverWhy3.ml @@ -294,7 +294,11 @@ let rec of_term ~cnv expected t : Why3.Term.term = Wp_parameters.debug ~dkey:dkey_api "of_term %a %a@." Lang.F.Tau.pretty expected Lang.F.pp_term t; - let sort = Lang.F.typeof t in + let sort = + try Lang.F.typeof t + with Not_found -> + why3_failure "@[<hov 2>Untyped term: %a@]" Lang.F.pp_term t + in let ($) f x = f x in let r = try coerce ~cnv sort expected $ Lang.F.Tmap.find t cnv.subst @@ -1041,7 +1045,8 @@ type prover_call = { prover : Why3Provers.t ; call : Why3.Call_provers.prover_call ; steps : int option ; - timeover : float option ; + timeout : int ; + mutable timeover : float option ; mutable interrupted : bool ; mutable killed : bool ; } @@ -1051,7 +1056,9 @@ let ping_prover_call p = | NoUpdates | ProverStarted -> let () = match p.timeover with - | None -> () + | None -> + let started = Unix.time () in + p.timeover <- Some (started +. 2.0 +. float p.timeout) | Some timeout -> let time = Unix.time () in if time > timeout then @@ -1076,7 +1083,7 @@ let ping_prover_call p = | OutOfMemory -> VCS.failed "out of memory" | StepLimitExceeded -> VCS.result ?steps:p.steps VCS.Stepout | Unknown _ -> VCS.unknown - | _ when p.interrupted -> VCS.timeout (int_of_float pr.pr_time) + | _ when p.interrupted -> VCS.timeout p.timeout | Failure s -> VCS.failed s | HighFailure -> let alt_ergo_hack = @@ -1109,15 +1116,12 @@ let call_prover ~timeout ~steplimit drv prover prover_config task = Why3.Whyconf.print_prover prover (Why3.Opt.get_def (-1) timeout) (Why3.Opt.get_def (-1) steps); - let timeover = match timeout with - | None -> None | Some tlimit -> - let started = Unix.time () in - Some (started +. 2.0 +. float tlimit) in + let timeout = match timeout with None -> 0 | Some tlimit -> tlimit in let pcall = { call ; prover ; killed = false ; interrupted = false ; - steps ; timeover ; + steps ; timeout ; timeover = None ; } in let ping = function | Task.Kill -> diff --git a/src/plugins/wp/TacSplit.ml b/src/plugins/wp/TacSplit.ml index 91484aa918fd0494b496c942362a430880329c48..df18c879a4fa263f3ef91d51675738da444f4a10 100644 --- a/src/plugins/wp/TacSplit.ml +++ b/src/plugins/wp/TacSplit.ml @@ -192,7 +192,7 @@ class split = split_cmp "Split (eq.)" x y | Neq(x,y) when not (is_prop x || is_prop y) -> split_cmp "Split (neq.)" x y - | _ when F.is_prop e-> + | _ when F.is_prop e -> feedback#set_title "Split (true,false)" ; feedback#set_descr "Decompose between True and False values" ; let cases = ["True",F.p_bool e;"False",F.p_not (F.p_bool e)] in diff --git a/src/plugins/wp/Vlist.ml b/src/plugins/wp/Vlist.ml index 473cd6e4c7b3e2905dcb1d3c72a45fc48ed1d660..8784ed5bd1cc7048ff48f963219d229ec4ae412e 100644 --- a/src/plugins/wp/Vlist.ml +++ b/src/plugins/wp/Vlist.ml @@ -55,13 +55,10 @@ let l_repeat = Lang.(E.({ let a_list = Lang.get_builtin_type ~library ~name:t_list ~link:l_list -let _list_of t = L.Data(a_list,[t]) - let vlist_get_tau = function | None -> invalid_arg "a list operator without result type" | Some t -> t - let ty_nil = function _ -> invalid_arg "All nil must be typed" let ty_listelt = function