diff options
Diffstat (limited to 'proofs/refiner.ml')
-rw-r--r-- | proofs/refiner.ml | 477 |
1 files changed, 174 insertions, 303 deletions
diff --git a/proofs/refiner.ml b/proofs/refiner.ml index 785e6dd4..a1d7e011 100644 --- a/proofs/refiner.ml +++ b/proofs/refiner.ml @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(* $Id: refiner.ml,v 1.67.2.3 2005/11/04 08:59:30 herbelin Exp $ *) +(* $Id: refiner.ml 9573 2007-01-31 20:18:18Z notin $ *) open Pp open Util @@ -17,12 +17,10 @@ open Evd open Sign open Environ open Reductionops -open Instantiate open Type_errors open Proof_trees open Proof_type open Logic -open Printer type transformation_tactic = proof_tree -> (goal list * validation) @@ -30,10 +28,7 @@ let hypotheses gl = gl.evar_hyps let conclusion gl = gl.evar_concl let sig_it x = x.it -let sig_sig x = x.sigma - - -let project_with_focus gls = rc_of_gc (gls.sigma) (gls.it) +let project x = x.sigma let pf_status pf = pf.open_subgoals @@ -43,21 +38,35 @@ let on_open_proofs f pf = if is_complete pf then pf else f pf let and_status = List.fold_left (+) 0 -(* Normalizing evars in a goal. Called by tactic Local_constraints - (i.e. when the sigma of the proof tree changes). Detect if the - goal is unchanged *) -let norm_goal sigma gl = - let red_fun = Evarutil.nf_evar sigma in - let ncl = red_fun gl.evar_concl in - let ngl = - { evar_concl = ncl; - evar_hyps = - Sign.fold_named_context - (fun (d,b,ty) sign -> - add_named_decl (d, option_app red_fun b, red_fun ty) sign) - gl.evar_hyps ~init:empty_named_context; - evar_body = gl.evar_body} in - if ngl = gl then None else Some ngl +(* Getting env *) + +let pf_env gls = Global.env_of_context (sig_it gls).evar_hyps +let pf_hyps gls = named_context_of_val (sig_it gls).evar_hyps + + +let descend n p = + match p.ref with + | None -> error "It is a leaf." + | Some(r,pfl) -> + if List.length pfl >= n then + (match list_chop (n-1) pfl with + | left,(wanted::right) -> + (wanted, + (fun pfl' -> + if (List.length pfl' = 1) + & (List.hd pfl').goal = wanted.goal + then + let pf' = List.hd pfl' in + let spfl = left@(pf'::right) in + let newstatus = and_status (List.map pf_status spfl) in + { p with + open_subgoals = newstatus; + ref = Some(r,spfl) } + else + error "descend: validation")) + | _ -> assert false) + else + error "Too few subproofs" (* [mapshape [ l1 ; ... ; lk ] [ v1 ; ... ; vk ] [ p_1 ; .... ; p_(l1+...+lk) ]] @@ -85,7 +94,7 @@ let rec frontier p = ([p.goal], (fun lp' -> let p' = List.hd lp' in - if p'.goal = p.goal then + if Evd.eq_evar_info p'.goal p.goal then p' else errorlabstrm "Refiner.frontier" @@ -95,9 +104,9 @@ let rec frontier p = (List.flatten gll, (fun retpfl -> let pfl' = mapshape (List.map List.length gll) vl retpfl in - { open_subgoals = and_status (List.map pf_status pfl'); - goal = p.goal; - ref = Some(r,pfl')})) + { p with + open_subgoals = and_status (List.map pf_status pfl'); + ref = Some(r,pfl')})) let rec frontier_map_rec f n p = @@ -105,7 +114,7 @@ let rec frontier_map_rec f n p = match p.ref with | None -> let p' = f p in - if p'.goal == p.goal || p'.goal = p.goal then p' + if Evd.eq_evar_info p'.goal p.goal then p' else errorlabstrm "Refiner.frontier_map" (str"frontier_map was handed back a ill-formed proof.") @@ -115,9 +124,9 @@ let rec frontier_map_rec f n p = (fun (n,acc) p -> (n-p.open_subgoals,frontier_map_rec f n p::acc)) (n,[]) pfl in let pfl' = List.rev rpfl' in - { open_subgoals = and_status (List.map pf_status pfl'); - goal = p.goal; - ref = Some(r,pfl')} + { p with + open_subgoals = and_status (List.map pf_status pfl'); + ref = Some(r,pfl')} let frontier_map f n p = let nmax = p.open_subgoals in @@ -131,7 +140,7 @@ let rec frontier_mapi_rec f i p = match p.ref with | None -> let p' = f i p in - if p'.goal == p.goal || p'.goal = p.goal then p' + if Evd.eq_evar_info p'.goal p.goal then p' else errorlabstrm "Refiner.frontier_mapi" (str"frontier_mapi was handed back a ill-formed proof.") @@ -141,9 +150,9 @@ let rec frontier_mapi_rec f i p = (fun (n,acc) p -> (n+p.open_subgoals,frontier_mapi_rec f n p::acc)) (i,[]) pfl in let pfl' = List.rev rpfl' in - { open_subgoals = and_status (List.map pf_status pfl'); - goal = p.goal; - ref = Some(r,pfl')} + { p with + open_subgoals = and_status (List.map pf_status pfl'); + ref = Some(r,pfl')} let frontier_mapi f p = frontier_mapi_rec f 1 p @@ -156,124 +165,87 @@ let rec nb_unsolved_goals pf = pf.open_subgoals (* leaf g is the canonical incomplete proof of a goal g *) -let leaf g = { - open_subgoals = 1; - goal = g; - ref = None } +let leaf g = + { open_subgoals = 1; + goal = g; + ref = None } -(* Tactics table. *) +(* refiner r is a tactic applying the rule r *) -let tac_tab = Hashtbl.create 17 +let check_subproof_connection gl spfl = + list_for_all2eq (fun g pf -> Evd.eq_evar_info g pf.goal) gl spfl -let add_tactic s t = - if Hashtbl.mem tac_tab s then - errorlabstrm ("Refiner.add_tactic: ") - (str ("Cannot redeclare tactic "^s)); - Hashtbl.add tac_tab s t -let overwriting_add_tactic s t = - if Hashtbl.mem tac_tab s then begin - Hashtbl.remove tac_tab s; - warning ("Overwriting definition of tactic "^s) - end; - Hashtbl.add tac_tab s t +let abstract_operation syntax semantics gls = + let (sgl_sigma,validation) = semantics gls in + let hidden_proof = validation (List.map leaf sgl_sigma.it) in + (sgl_sigma, + fun spfl -> + assert (check_subproof_connection sgl_sigma.it spfl); + { open_subgoals = and_status (List.map pf_status spfl); + goal = gls.it; + ref = Some(Nested(syntax,hidden_proof),spfl)}) -let lookup_tactic s = - try - Hashtbl.find tac_tab s - with Not_found -> - errorlabstrm "Refiner.lookup_tactic" - (str"The tactic " ++ str s ++ str" is not installed") +let abstract_tactic_expr ?(dflt=false) te tacfun gls = + abstract_operation (Tactic(te,dflt)) tacfun gls +let abstract_tactic ?(dflt=false) te = + abstract_tactic_expr ~dflt (Tacexpr.TacAtom (dummy_loc,te)) -(* refiner r is a tactic applying the rule r *) - -let check_subproof_connection gl spfl = - list_for_all2eq (fun g pf -> g=pf.goal) gl spfl - -let abstract_tactic_expr te tacfun gls = - let (sgl_sigma,v) = tacfun gls in - let hidden_proof = v (List.map leaf sgl_sigma.it) in - (sgl_sigma, - fun spfl -> - assert (check_subproof_connection sgl_sigma.it spfl); - { open_subgoals = and_status (List.map pf_status spfl); - goal = gls.it; - ref = Some(Tactic(te,hidden_proof),spfl) }) +let abstract_extended_tactic ?(dflt=false) s args = + abstract_tactic ~dflt (Tacexpr.TacExtend (dummy_loc, s, args)) let refiner = function | Prim pr as r -> let prim_fun = prim_refiner pr in - (fun goal_sigma -> - let sgl = prim_fun goal_sigma.sigma goal_sigma.it in - ({it=sgl; sigma = goal_sigma.sigma}, - (fun spfl -> - assert (check_subproof_connection sgl spfl); - { open_subgoals = and_status (List.map pf_status spfl); - goal = goal_sigma.it; - ref = Some(r,spfl) }))) - - | Tactic _ -> failwith "Refiner: should not occur" + (fun goal_sigma -> + let (sgl,sigma') = prim_fun goal_sigma.sigma goal_sigma.it in + ({it=sgl; sigma = sigma'}, + (fun spfl -> + assert (check_subproof_connection sgl spfl); + { open_subgoals = and_status (List.map pf_status spfl); + goal = goal_sigma.it; + ref = Some(r,spfl) }))) + + + | Nested (_,_) | Decl_proof _ -> + failwith "Refiner: should not occur" - (* [Local_constraints lc] makes the local constraints be [lc] and - normalizes evars *) - - | Change_evars as r -> - (fun goal_sigma -> - let gl = goal_sigma.it in - (match norm_goal goal_sigma.sigma gl with - Some ngl -> - ({it=[ngl];sigma=goal_sigma.sigma}, - (fun spfl -> - assert (check_subproof_connection [ngl] spfl); - { open_subgoals = (List.hd spfl).open_subgoals; - goal = gl; - ref = Some(r,spfl) })) - (* if the evar change does not affect the goal, leave the - proof tree unchanged *) - | None -> ({it=[gl];sigma=goal_sigma.sigma}, - (fun spfl -> - assert (List.length spfl = 1); - List.hd spfl)))) - - -let local_Constraints gl = refiner Change_evars gl - -let norm_evar_tac = local_Constraints + (* Daimon is a canonical unfinished proof *) -(* -let vernac_tactic (s,args) = - let tacfun = lookup_tactic s args in - abstract_extra_tactic s args tacfun -*) -let abstract_tactic te = abstract_tactic_expr (Tacexpr.TacAtom (dummy_loc,te)) + | Daimon -> + fun gls -> + ({it=[];sigma=gls.sigma}, + fun spfl -> + assert (spfl=[]); + { open_subgoals = 0; + goal = gls.it; + ref = Some(Daimon,[])}) -let abstract_extended_tactic s args = - abstract_tactic (Tacexpr.TacExtend (dummy_loc, s, args)) -let vernac_tactic (s,args) = - let tacfun = lookup_tactic s args in - abstract_extended_tactic s args tacfun +let local_Constraints gl = refiner (Prim Change_evars) gl -(* [rc_of_pfsigma : proof sigma -> readable_constraints] *) -let rc_of_pfsigma sigma = rc_of_gc sigma.sigma sigma.it.goal +let norm_evar_tac = local_Constraints -(* [rc_of_glsigma : proof sigma -> readable_constraints] *) -let rc_of_glsigma sigma = rc_of_gc sigma.sigma sigma.it +let norm_evar_proof sigma pf = + let nf_subgoal i sgl = + let (gll,v) = norm_evar_tac {it=sgl.goal;sigma=sigma} in + v (List.map leaf gll.it) in + frontier_mapi nf_subgoal pf (* [extract_open_proof : proof_tree -> constr * (int * constr) list] - takes a (not necessarly complete) proof and gives a pair (pfterm,obl) - where pfterm is the constr corresponding to the proof - and [obl] is an [int*constr list] [ (m1,c1) ; ... ; (mn,cn)] - where the mi are metavariables numbers, and ci are their types. - Their proof should be completed in order to complete the initial proof *) + takes a (not necessarly complete) proof and gives a pair (pfterm,obl) + where pfterm is the constr corresponding to the proof + and [obl] is an [int*constr list] [ (m1,c1) ; ... ; (mn,cn)] + where the mi are metavariables numbers, and ci are their types. + Their proof should be completed in order to complete the initial proof *) let extract_open_proof sigma pf = let next_meta = let meta_cnt = ref 0 in let rec f () = incr meta_cnt; - if in_dom sigma (existential_of_int !meta_cnt) then f () + if Evd.mem sigma (existential_of_int !meta_cnt) then f () else !meta_cnt in f in @@ -281,24 +253,24 @@ let extract_open_proof sigma pf = let rec proof_extractor vl = function | {ref=Some(Prim _,_)} as pf -> prim_extractor proof_extractor vl pf - | {ref=Some(Tactic (_,hidden_proof),spfl)} -> + | {ref=Some(Nested(_,hidden_proof),spfl)} -> let sgl,v = frontier hidden_proof in let flat_proof = v spfl in proof_extractor vl flat_proof + + | {ref=Some(Decl_proof _,[pf])} -> (proof_extractor vl) pf - | {ref=Some(Change_evars,[pf])} -> (proof_extractor vl) pf - - | {ref=None;goal=goal} -> + | {ref=(None|Some(Daimon,[]));goal=goal} -> let visible_rels = map_succeed (fun id -> - try let n = list_index id vl in (n,id) + try let n = proof_variable_index id vl in (n,id) with Not_found -> failwith "caught") - (ids_of_named_context goal.evar_hyps) in + (ids_of_named_context (named_context_of_val goal.evar_hyps)) in let sorted_rels = Sort.list (fun (n1,_) (n2,_) -> n1 > n2 ) visible_rels in let sorted_env = - List.map (fun (n,id) -> (n,Sign.lookup_named id goal.evar_hyps)) + List.map (fun (n,id) -> (n,lookup_named_val id goal.evar_hyps)) sorted_rels in let abs_concl = List.fold_right (fun (_,decl) c -> mkNamedProd_or_LetIn decl c) @@ -308,7 +280,7 @@ let extract_open_proof sigma pf = open_obligations := (meta,abs_concl):: !open_obligations; applist (mkMeta meta, List.map (fun (n,_) -> mkRel n) inst) - | _ -> anomaly "Bug : a case has been forgotten in proof_extractor" + | _ -> anomaly "Bug: a case has been forgotten in proof_extractor" in let pfterm = proof_extractor [] pf in (pfterm, List.rev !open_obligations) @@ -345,17 +317,13 @@ let tclIDTAC gls = (goal_goal_list gls, idtac_valid) (* the message printing identity tactic *) let tclIDTAC_MESSAGE s gls = - if s = "" then tclIDTAC gls - else - begin - msgnl (str ("Idtac says : "^s)); tclIDTAC gls - end + msg (hov 0 s); tclIDTAC gls (* General failure tactic *) let tclFAIL_s s gls = errorlabstrm "Refiner.tclFAIL_s" (str s) (* A special exception for levels for the Fail tactic *) -exception FailError of int * string +exception FailError of int * std_ppcmds (* The Fail tactic *) let tclFAIL lvl s g = raise (FailError (lvl,s)) @@ -469,7 +437,7 @@ let rec tclTHENLIST = function (* various progress criterions *) let same_goal gl subgoal = - (hypotheses subgoal) = (hypotheses gl) & + eq_named_context_val (hypotheses subgoal) (hypotheses gl) && eq_constr (conclusion subgoal) (conclusion gl) @@ -569,6 +537,8 @@ let tclIFTHENSELSE=ite_gen tclTHENS let tclIFTHENSVELSE=ite_gen tclTHENSV +let tclIFTHENTRYELSEMUST tac1 tac2 gl = + tclIFTHENELSE tac1 (tclTRY tac2) tac2 gl (* Fails if a tactic did not solve the goal *) let tclCOMPLETE tac = tclTHEN tac (tclFAIL_s "Proof is not complete.") @@ -647,7 +617,6 @@ let tactic_list_tactic tac gls = - (* The type of proof-trees state and a few utilities A proof-tree state is built from a proof-tree, a set of global constraints, and a stack which allows to navigate inside the @@ -679,41 +648,19 @@ let nth_goal_of_pftreestate n pts = try {it = List.nth goals (n-1); sigma = pts.tpfsigma } with Invalid_argument _ | Failure _ -> non_existent_goal n -let descend n p = - match p.ref with - | None -> error "It is a leaf." - | Some(r,pfl) -> - if List.length pfl >= n then - (match list_chop (n-1) pfl with - | left,(wanted::right) -> - (wanted, - (fun pfl' -> - if (List.length pfl' = 1) - & (List.hd pfl').goal = wanted.goal - then - let pf' = List.hd pfl' in - let spfl = left@(pf'::right) in - let newstatus = and_status (List.map pf_status spfl) in - { open_subgoals = newstatus; - goal = p.goal; - ref = Some(r,spfl) } - else - error "descend: validation")) - | _ -> assert false) - else - error "Too few subproofs" - let traverse n pts = match n with | 0 -> (* go to the parent *) (match pts.tstack with | [] -> error "traverse: no ancestors" | (_,v)::tl -> - { tpf = v [pts.tpf]; + let pf = v [pts.tpf] in + let pf = norm_evar_proof pts.tpfsigma pf in + { tpf = pf; tstack = tl; tpfsigma = pts.tpfsigma }) | -1 -> (* go to the hidden tactic-proof, if any, otherwise fail *) (match pts.tpf.ref with - | Some (Tactic (_,spf),_) -> + | Some (Nested (_,spf),_) -> let v = (fun pfl -> pts.tpf) in { tpf = spf; tstack = (-1,v)::pts.tstack; @@ -732,17 +679,23 @@ let app_tac sigr tac p = sigr := gll.sigma; v (List.map leaf gll.it) -(* solve the nth subgoal with tactic tac *) -let solve_nth_pftreestate n tac pts = +(* modify proof state at current position *) + +let map_pftreestate f pts = let sigr = ref pts.tpfsigma in - let tpf' = frontier_map (app_tac sigr tac) n pts.tpf in + let tpf' = f sigr pts.tpf in let tpf'' = - if !sigr == pts.tpfsigma then tpf' - else frontier_mapi (fun _ g -> app_tac sigr norm_evar_tac g) tpf' in + if !sigr == pts.tpfsigma then tpf' else norm_evar_proof !sigr tpf' in { tpf = tpf''; tpfsigma = !sigr; tstack = pts.tstack } +(* solve the nth subgoal with tactic tac *) + +let solve_nth_pftreestate n tac = + map_pftreestate + (fun sigr pt -> frontier_map (app_tac sigr tac) n pt) + let solve_pftreestate = solve_nth_pftreestate 1 (* This function implements a poor man's undo at the current goal. @@ -774,15 +727,16 @@ let extract_pftreestate pts = (str"Cannot extract from a proof-tree in which we have descended;" ++ spc () ++ str"Please ascend to the root"); let pfterm,subgoals = extract_open_pftreestate pts in - let exl = Evd.non_instantiated pts.tpfsigma in + let exl = Evarutil.non_instantiated pts.tpfsigma in if subgoals <> [] or exl <> [] then - errorlabstrm "extract_proof" - (if subgoals <> [] then - str "Attempt to save an incomplete proof" - else - str "Attempt to save a proof with existential variables still non-instantiated"); + errorlabstrm "extract_proof" + (if subgoals <> [] then + str "Attempt to save an incomplete proof" + else + str "Attempt to save a proof with existential variables still non-instantiated"); let env = Global.env_of_context pts.tpf.goal.evar_hyps in - strong whd_betaiotaevar env pts.tpfsigma pfterm + nf_betaiotaevar_preserving_vm_cast env pts.tpfsigma pfterm + (* strong whd_betaiotaevar env pts.tpfsigma pfterm *) (*** local_strong (Evarutil.whd_ise (ts_it pts.tpfsigma)) pfterm ***) @@ -893,137 +847,54 @@ let prev_unproven pts = let rec top_of_tree pts = if is_top_pftreestate pts then pts else top_of_tree(traverse 0 pts) +let change_rule f pts = + let mark_top _ pt = + match pt.ref with + Some (oldrule,l) -> + {pt with ref=Some (f oldrule,l)} + | _ -> invalid_arg "change_rule" in + map_pftreestate mark_top pts + +let match_rule p pts = + match (proof_of_pftreestate pts).ref with + Some (r,_) -> p r + | None -> false + +let rec up_until_matching_rule p pts = + if is_top_pftreestate pts then + raise Not_found + else + let one_up = traverse 0 pts in + if match_rule p one_up then + pts + else + up_until_matching_rule p one_up -(* Pretty-printers. *) +let rec up_to_matching_rule p pts = + if match_rule p pts then + pts + else + if is_top_pftreestate pts then + raise Not_found + else + let one_up = traverse 0 pts in + up_to_matching_rule p one_up -open Pp +(* Change evars *) +let tclEVARS sigma gls = tclIDTAC {gls with sigma=sigma} -let pr_tactic = function - | Tacexpr.TacArg (Tacexpr.Tacexp t) -> - if !Options.v7 then - Pptactic.pr_glob_tactic t (*top tactic from tacinterp*) - else - Pptacticnew.pr_glob_tactic (Global.env()) t - | t -> - if !Options.v7 then - Pptactic.pr_tactic t - else - Pptacticnew.pr_tactic (Global.env()) t - -let pr_rule = function - | Prim r -> hov 0 (pr_prim_rule r) - | Tactic (texp,_) -> hov 0 (pr_tactic texp) - | Change_evars -> - (* This is internal tactic and cannot be replayed at user-level. - Function pr_rule_dot below is used when we want to hide - Change_evars *) - str "Evar change" - -(* Does not print change of evars *) -let pr_rule_dot = function - | Change_evars -> mt () - | r -> pr_rule r ++ str"." - -exception Different - -(* We remove from the var context of env what is already in osign *) -let thin_sign osign sign = - Sign.fold_named_context - (fun (id,c,ty as d) sign -> - try - if Sign.lookup_named id osign = (id,c,ty) then sign - else raise Different - with Not_found | Different -> add_named_decl d sign) - sign ~init:empty_named_context - -let rec print_proof sigma osign pf = - let {evar_hyps=hyps; evar_concl=cl; - evar_body=body} = pf.goal in - let hyps' = thin_sign osign hyps in - match pf.ref with - | None -> - hov 0 (pr_seq {evar_hyps=hyps'; evar_concl=cl; evar_body=body}) - | Some(r,spfl) -> - hov 0 - (hov 0 (pr_seq {evar_hyps=hyps'; evar_concl=cl; evar_body=body}) ++ - spc () ++ str" BY " ++ - hov 0 (pr_rule r) ++ fnl () ++ - str" " ++ - hov 0 (prlist_with_sep pr_fnl (print_proof sigma hyps) spfl) -) - -let pr_change gl = - (str"Change " ++ prterm_env (Global.env()) gl.evar_concl ++ str".") - -let rec print_script nochange sigma osign pf = - let {evar_hyps=sign; evar_concl=cl} = pf.goal in - match pf.ref with - | None -> - (if nochange then - (str"<Your Tactic Text here>") - else - pr_change pf.goal) - ++ fnl () - | Some(r,spfl) -> - ((if nochange then (mt ()) else (pr_change pf.goal ++ fnl ())) ++ - pr_rule_dot r ++ fnl () ++ - prlist_with_sep pr_fnl - (print_script nochange sigma sign) spfl) - -let print_treescript nochange sigma _osign pf = - let rec aux top pf = - let {evar_hyps=sign; evar_concl=cl} = pf.goal in - match pf.ref with - | None -> - if nochange then - (str"<Your Tactic Text here>") - else - (pr_change pf.goal) - | Some(r,spfl) -> - (if nochange then mt () else (pr_change pf.goal ++ fnl ())) ++ - pr_rule_dot r ++ - match spfl with - | [] -> mt () - | [spf] -> fnl () ++ (if top then mt () else str " ") ++ aux top spf - | _ -> fnl () ++ str " " ++ - hov 0 (prlist_with_sep fnl (aux false) spfl) - in hov 0 (aux true pf) - -let rec print_info_script sigma osign pf = - let {evar_hyps=sign; evar_concl=cl} = pf.goal in - match pf.ref with - | None -> (mt ()) - | Some(Change_evars,[spf]) -> - print_info_script sigma osign spf - | Some(r,spfl) -> - (pr_rule r ++ - match spfl with - | [pf1] -> - if pf1.ref = None then - (str "." ++ fnl ()) - else - (str";" ++ brk(1,3) ++ - print_info_script sigma sign pf1) - | _ -> (str"." ++ fnl () ++ - prlist_with_sep pr_fnl - (print_info_script sigma sign) spfl)) - -let format_print_info_script sigma osign pf = - hov 0 (print_info_script sigma osign pf) - -let print_subscript sigma sign pf = - if is_tactic_proof pf then - format_print_info_script sigma sign (subproof_of_proof pf) - else - format_print_info_script sigma sign pf +(* Pretty-printers. *) + +let pp_info = ref (fun _ _ _ -> assert false) +let set_info_printer f = pp_info := f let tclINFO (tac : tactic) gls = let (sgl,v) as res = tac gls in begin try let pf = v (List.map leaf (sig_it sgl)) in - let sign = (sig_it gls).evar_hyps in + let sign = named_context_of_val (sig_it gls).evar_hyps in msgnl (hov 0 (str" == " ++ - print_subscript (sig_sig gls) sign pf)) + !pp_info (project gls) sign pf)) with e when catchable_exception e -> msgnl (hov 0 (str "Info failed to apply validation")) end; |