diff options
Diffstat (limited to 'pretyping/evd.ml')
-rw-r--r-- | pretyping/evd.ml | 559 |
1 files changed, 333 insertions, 226 deletions
diff --git a/pretyping/evd.ml b/pretyping/evd.ml index af070d7e..21753d3a 100644 --- a/pretyping/evd.ml +++ b/pretyping/evd.ml @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(* $Id: evd.ml 11865 2009-01-28 17:34:30Z herbelin $ *) +(* $Id$ *) open Pp open Util @@ -19,12 +19,30 @@ open Environ open Libnames open Mod_subst +(* The kinds of existential variable *) + +type obligation_definition_status = Define of bool | Expand + +type hole_kind = + | ImplicitArg of global_reference * (int * identifier option) * bool + | BinderType of name + | QuestionMark of obligation_definition_status + | CasesType + | InternalHole + | TomatchTypeParameter of inductive * int + | GoalEvar + | ImpossibleCase + | MatchingVar of bool * identifier + (* The type of mappings for existential variables *) type evar = existential_key +let string_of_existential evk = "?" ^ string_of_int evk +let existential_of_int evk = evk + type evar_body = - | Evar_empty + | Evar_empty | Evar_defined of constr type evar_info = { @@ -32,6 +50,7 @@ type evar_info = { evar_hyps : named_context_val; evar_body : evar_body; evar_filter : bool list; + evar_source : hole_kind located; evar_extra : Dyn.t option} let make_evar hyps ccl = { @@ -39,6 +58,7 @@ let make_evar hyps ccl = { evar_hyps = hyps; evar_body = Evar_empty; evar_filter = List.map (fun _ -> true) (named_context_of_val hyps); + evar_source = (dummy_loc,InternalHole); evar_extra = None } @@ -48,109 +68,121 @@ let evar_context evi = named_context_of_val evi.evar_hyps let evar_body evi = evi.evar_body let evar_filter evi = evi.evar_filter let evar_unfiltered_env evi = Global.env_of_context evi.evar_hyps -let evar_filtered_context evi = +let evar_filtered_context evi = snd (list_filter2 (fun b c -> b) (evar_filter evi,evar_context evi)) -let evar_env evi = +let evar_env evi = List.fold_right push_named (evar_filtered_context evi) (reset_context (Global.env())) let eq_evar_info ei1 ei2 = - ei1 == ei2 || - eq_constr ei1.evar_concl ei2.evar_concl && + ei1 == ei2 || + eq_constr ei1.evar_concl ei2.evar_concl && eq_named_context_val (ei1.evar_hyps) (ei2.evar_hyps) && ei1.evar_body = ei2.evar_body -module Evarmap = Intmap - -type evar_map1 = evar_info Evarmap.t - -let empty = Evarmap.empty - -let to_list evc = (* Workaround for change in Map.fold behavior *) - let l = ref [] in - Evarmap.iter (fun evk x -> l := (evk,x)::!l) evc; - !l - -let dom evc = Evarmap.fold (fun evk _ acc -> evk::acc) evc [] -let find evc k = Evarmap.find k evc -let remove evc k = Evarmap.remove k evc -let mem evc k = Evarmap.mem k evc -let fold = Evarmap.fold - -let add evd evk newinfo = Evarmap.add evk newinfo evd - -let define evd evk body = - let oldinfo = - try find evd evk - with Not_found -> error "Evd.define: cannot define undeclared evar" in - let newinfo = - { oldinfo with - evar_body = Evar_defined body } in - match oldinfo.evar_body with - | Evar_empty -> Evarmap.add evk newinfo evd - | _ -> anomaly "Evd.define: cannot define an evar twice" - -let is_evar sigma evk = mem sigma evk - -let is_defined sigma evk = - let info = find sigma evk in - not (info.evar_body = Evar_empty) - -let string_of_existential evk = "?" ^ string_of_int evk - -let existential_of_int evk = evk - -(*******************************************************************) -(* Formerly Instantiate module *) - -let is_id_inst inst = - let is_id (id,c) = match kind_of_term c with - | Var id' -> id = id' - | _ -> false - in - List.for_all is_id inst - -(* Vérifier que les instances des let-in sont compatibles ?? *) -let instantiate_sign_including_let sign args = - let rec instrec = function - | ((id,b,_) :: sign, c::args) -> (id,c) :: (instrec (sign,args)) - | ([],[]) -> [] - | ([],_) | (_,[]) -> - anomaly "Signature and its instance do not match" - in - instrec (sign,args) - -let instantiate_evar sign c args = - let inst = instantiate_sign_including_let sign args in - if is_id_inst inst then - c - else - replace_vars inst c - -(* Existentials. *) +(* spiwack: Revised hierarchy : + - ExistentialMap ( Maps of existential_keys ) + - EvarInfoMap ( .t = evar_info ExistentialMap.t ) + - EvarMap ( .t = EvarInfoMap.t * sort_constraints ) + - evar_map (exported) +*) -let existential_type sigma (n,args) = - let info = - try find sigma n - with Not_found -> - anomaly ("Evar "^(string_of_existential n)^" was not declared") in - let hyps = evar_filtered_context info in - instantiate_evar hyps info.evar_concl (Array.to_list args) +module ExistentialMap = Intmap +module ExistentialSet = Intset +(* This exception is raised by *.existential_value *) exception NotInstantiatedEvar -let existential_value sigma (n,args) = - let info = find sigma n in - let hyps = evar_filtered_context info in - match evar_body info with - | Evar_defined c -> - instantiate_evar hyps c (Array.to_list args) - | Evar_empty -> - raise NotInstantiatedEvar +module EvarInfoMap = struct + type t = evar_info ExistentialMap.t + + let empty = ExistentialMap.empty + + let to_list evc = (* Workaround for change in Map.fold behavior *) + let l = ref [] in + ExistentialMap.iter (fun evk x -> l := (evk,x)::!l) evc; + !l + + let dom evc = ExistentialMap.fold (fun evk _ acc -> evk::acc) evc [] + let find evc k = ExistentialMap.find k evc + let remove evc k = ExistentialMap.remove k evc + let mem evc k = ExistentialMap.mem k evc + let fold = ExistentialMap.fold + let exists evc f = ExistentialMap.fold (fun k v b -> b || f k v) evc false + + let add evd evk newinfo = ExistentialMap.add evk newinfo evd + + let equal = ExistentialMap.equal + + let define evd evk body = + let oldinfo = + try find evd evk + with Not_found -> error "Evd.define: cannot define undeclared evar" in + let newinfo = + { oldinfo with + evar_body = Evar_defined body } in + match oldinfo.evar_body with + | Evar_empty -> ExistentialMap.add evk newinfo evd + | _ -> anomaly "Evd.define: cannot define an evar twice" + + let is_evar sigma evk = mem sigma evk + + let is_defined sigma evk = + let info = find sigma evk in + not (info.evar_body = Evar_empty) + + + (*******************************************************************) + (* Formerly Instantiate module *) + + let is_id_inst inst = + let is_id (id,c) = match kind_of_term c with + | Var id' -> id = id' + | _ -> false + in + List.for_all is_id inst + + (* Vérifier que les instances des let-in sont compatibles ?? *) + let instantiate_sign_including_let sign args = + let rec instrec = function + | ((id,b,_) :: sign, c::args) -> (id,c) :: (instrec (sign,args)) + | ([],[]) -> [] + | ([],_) | (_,[]) -> + anomaly "Signature and its instance do not match" + in + instrec (sign,args) + + let instantiate_evar sign c args = + let inst = instantiate_sign_including_let sign args in + if is_id_inst inst then + c + else + replace_vars inst c + + (* Existentials. *) + + let existential_type sigma (n,args) = + let info = + try find sigma n + with Not_found -> + anomaly ("Evar "^(string_of_existential n)^" was not declared") in + let hyps = evar_filtered_context info in + instantiate_evar hyps info.evar_concl (Array.to_list args) + + let existential_value sigma (n,args) = + let info = find sigma n in + let hyps = evar_filtered_context info in + match evar_body info with + | Evar_defined c -> + instantiate_evar hyps c (Array.to_list args) + | Evar_empty -> + raise NotInstantiatedEvar + + let existential_opt_value sigma ev = + try Some (existential_value sigma ev) + with NotInstantiatedEvar -> None -let existential_opt_value sigma ev = - try Some (existential_value sigma ev) - with NotInstantiatedEvar -> None +end (*******************************************************************) (* Constraints for sort variables *) @@ -163,11 +195,8 @@ type sort_constraint = | SortVar of sort_var list * sort_var list (* (leq,geq) *) | EqSort of sort_var -module UniverseOrdered = struct - type t = Univ.universe - let compare = Pervasives.compare -end -module UniverseMap = Map.Make(UniverseOrdered) +module UniverseMap = + Map.Make (struct type t = Univ.universe let compare = compare end) type sort_constraints = sort_constraint UniverseMap.t @@ -236,7 +265,7 @@ let set_leq_sort (u1,(leq1,geq1)) (u2,(leq2,geq2)) scstr = match UniverseMap.find u1 scstr with EqSort u1' -> search_rec (is_b,betw,not_betw) u1' | SortVar(leq,_) -> - let (is_b',betw',not_betw') = + let (is_b',betw',not_betw') = List.fold_left search_rec (false,betw,not_betw) leq in if is_b' then (true, u1::betw', not_betw') else (false, betw', not_betw') @@ -285,41 +314,33 @@ let pr_sort_cstrs g = hov 0 (prlist_with_sep spc Univ.pr_uni leq) ++ str"]") l -type evar_map = evar_map1 * sort_constraints -let empty = empty, UniverseMap.empty -let add (sigma,sm) k v = (add sigma k v, sm) -let dom (sigma,_) = dom sigma -let find (sigma,_) = find sigma -let remove (sigma,sm) k = (remove sigma k, sm) -let mem (sigma,_) = mem sigma -let to_list (sigma,_) = to_list sigma -let fold f (sigma,_) = fold f sigma -let define (sigma,sm) k v = (define sigma k v, sm) -let is_evar (sigma,_) = is_evar sigma -let is_defined (sigma,_) = is_defined sigma -let existential_value (sigma,_) = existential_value sigma -let existential_type (sigma,_) = existential_type sigma -let existential_opt_value (sigma,_) = existential_opt_value sigma -let eq_evar_map x y = x == y || - (Evarmap.equal eq_evar_info (fst x) (fst y) && - UniverseMap.equal (=) (snd x) (snd y)) - -let merge e e' = fold (fun n v sigma -> add sigma n v) e' e +module EvarMap = struct + type t = EvarInfoMap.t * sort_constraints + let empty = EvarInfoMap.empty, UniverseMap.empty + let add (sigma,sm) k v = (EvarInfoMap.add sigma k v, sm) + let dom (sigma,_) = EvarInfoMap.dom sigma + let find (sigma,_) = EvarInfoMap.find sigma + let remove (sigma,sm) k = (EvarInfoMap.remove sigma k, sm) + let mem (sigma,_) = EvarInfoMap.mem sigma + let to_list (sigma,_) = EvarInfoMap.to_list sigma + let fold f (sigma,_) = EvarInfoMap.fold f sigma + let define (sigma,sm) k v = (EvarInfoMap.define sigma k v, sm) + let is_evar (sigma,_) = EvarInfoMap.is_evar sigma + let is_defined (sigma,_) = EvarInfoMap.is_defined sigma + let existential_value (sigma,_) = EvarInfoMap.existential_value sigma + let existential_type (sigma,_) = EvarInfoMap.existential_type sigma + let existential_opt_value (sigma,_) = EvarInfoMap.existential_opt_value sigma + let progress_evar_map (sigma1,sm1 as x) (sigma2,sm2 as y) = not (x == y) && + (EvarInfoMap.exists sigma1 + (fun k v -> v.evar_body = Evar_empty && + (EvarInfoMap.find sigma2 k).evar_body <> Evar_empty) + || not (UniverseMap.equal (=) sm1 sm2)) + + let merge e e' = fold (fun n v sigma -> add sigma n v) e' e -(*******************************************************************) -type open_constr = evar_map * constr +end (*******************************************************************) -(* The type constructor ['a sigma] adds an evar map to an object of - type ['a] *) -type 'a sigma = { - it : 'a ; - sigma : evar_map} - -let sig_it x = x.it -let sig_sig x = x.sigma - -(*******************************************************************) (* Metamaps *) (*******************************************************************) @@ -390,65 +411,113 @@ let clb_name = function | Clval (na,_,_) -> (na,true) (***********************) - + module Metaset = Intset - + let meta_exists p s = Metaset.fold (fun x b -> b || (p x)) s false module Metamap = Intmap let metamap_to_list m = Metamap.fold (fun n v l -> (n,v)::l) m [] - + (*************************) (* Unification state *) -type obligation_definition_status = Define of bool | Expand - -type hole_kind = - | ImplicitArg of global_reference * (int * identifier option) - | BinderType of name - | QuestionMark of obligation_definition_status - | CasesType - | InternalHole - | TomatchTypeParameter of inductive * int - | GoalEvar - | ImpossibleCase - type conv_pb = Reduction.conv_pb type evar_constraint = conv_pb * Environ.env * constr * constr -type evar_defs = - { evars : evar_map; +type evar_map = + { evars : EvarMap.t; conv_pbs : evar_constraint list; - last_mods : existential_key list; - history : (existential_key * (loc * hole_kind)) list; + last_mods : ExistentialSet.t; metas : clbinding Metamap.t } +(*** Lifting primitive from EvarMap. ***) + +(* HH: The progress tactical now uses this function. *) +let progress_evar_map d1 d2 = + EvarMap.progress_evar_map d1.evars d2.evars + +(* spiwack: tentative. It might very well not be the semantics we want + for merging evar_map *) +let merge d1 d2 = { +(* d1 with evars = EvarMap.merge d1.evars d2.evars*) + evars = EvarMap.merge d1.evars d2.evars ; + conv_pbs = List.rev_append d1.conv_pbs d2.conv_pbs ; + last_mods = ExistentialSet.union d1.last_mods d2.last_mods ; + metas = Metamap.fold (fun k m r -> Metamap.add k m r) d2.metas d1.metas +} +let add d e i = { d with evars=EvarMap.add d.evars e i } +let remove d e = { d with evars=EvarMap.remove d.evars e } +let dom d = EvarMap.dom d.evars +let find d e = EvarMap.find d.evars e +let mem d e = EvarMap.mem d.evars e +(* spiwack: this function loses information from the original evar_map + it might be an idea not to export it. *) +let to_list d = EvarMap.to_list d.evars +(* spiwack: not clear what folding over an evar_map, for now we shall + simply fold over the inner evar_map. *) +let fold f d a = EvarMap.fold f d.evars a +let is_evar d e = EvarMap.is_evar d.evars e +let is_defined d e = EvarMap.is_defined d.evars e + +let existential_value d e = EvarMap.existential_value d.evars e +let existential_type d e = EvarMap.existential_type d.evars e +let existential_opt_value d e = EvarMap.existential_opt_value d.evars e + +(*** /Lifting... ***) + +(* evar_map are considered empty disregarding histories *) +let is_empty d = + d.evars = EvarMap.empty && + d.conv_pbs = [] && + Metamap.is_empty d.metas + +let subst_named_context_val s = map_named_val (subst_mps s) + +let subst_evar_info s evi = + let subst_evb = function Evar_empty -> Evar_empty + | Evar_defined c -> Evar_defined (subst_mps s c) in + { evi with + evar_concl = subst_mps s evi.evar_concl; + evar_hyps = subst_named_context_val s evi.evar_hyps; + evar_body = subst_evb evi.evar_body } + let subst_evar_defs_light sub evd = - assert (evd.evars = (Evarmap.empty,UniverseMap.empty)); + assert (UniverseMap.is_empty (snd evd.evars)); assert (evd.conv_pbs = []); { evd with - metas = Metamap.map (map_clb (subst_mps sub)) evd.metas } - -let create_evar_defs sigma = - { evars=sigma; conv_pbs=[]; last_mods = []; history=[]; metas=Metamap.empty } -let create_goal_evar_defs sigma = - let h = fold (fun mv _ l -> (mv,(dummy_loc,GoalEvar))::l) sigma [] in - { evars=sigma; conv_pbs=[]; last_mods = []; history=h; metas=Metamap.empty } -let empty_evar_defs = create_evar_defs empty -let evars_of d = d.evars -let evars_reset_evd evd d = {d with evars = evd} -let reset_evd (sigma,mmap) d = {d with evars = sigma; metas=mmap} + metas = Metamap.map (map_clb (subst_mps sub)) evd.metas; + evars = ExistentialMap.map (subst_evar_info sub) (fst evd.evars), snd evd.evars + } + +let subst_evar_map = subst_evar_defs_light + +(* spiwack: deprecated *) +let create_evar_defs sigma = { sigma with + conv_pbs=[]; last_mods=ExistentialSet.empty; metas=Metamap.empty } +(* spiwack: tentatively deprecated *) +let create_goal_evar_defs sigma = { sigma with + conv_pbs=[]; last_mods=ExistentialSet.empty; metas=Metamap.empty } +let empty = { + evars=EvarMap.empty; + conv_pbs=[]; + last_mods = ExistentialSet.empty; + metas=Metamap.empty +} + +let evars_reset_evd evd d = {d with evars = evd.evars} let add_conv_pb pb d = {d with conv_pbs = pb::d.conv_pbs} -let evar_source evk d = - try List.assoc evk d.history - with Not_found -> (dummy_loc, InternalHole) +let evar_source evk d = (EvarMap.find d.evars evk).evar_source (* define the existential of section path sp as the constr body *) -let evar_define evk body evd = +let define evk body evd = { evd with - evars = define evd.evars evk body; - last_mods = evk :: evd.last_mods } + evars = EvarMap.define evd.evars evk body; + last_mods = + match evd.conv_pbs with + | [] -> evd.last_mods + | _ -> ExistentialSet.add evk evd.last_mods } let evar_declare hyps evk ty ?(src=(dummy_loc,InternalHole)) ?filter evd = let filter = @@ -460,43 +529,43 @@ let evar_declare hyps evk ty ?(src=(dummy_loc,InternalHole)) ?filter evd = filter) in { evd with - evars = add evd.evars evk + evars = EvarMap.add evd.evars evk {evar_hyps = hyps; evar_concl = ty; evar_body = Evar_empty; evar_filter = filter; - evar_extra = None}; - history = (evk,src)::evd.history } + evar_source = src; + evar_extra = None} } -let is_defined_evar evd (evk,_) = is_defined evd.evars evk +let is_defined_evar evd (evk,_) = EvarMap.is_defined evd.evars evk (* Does k corresponds to an (un)defined existential ? *) let is_undefined_evar evd c = match kind_of_term c with | Evar ev -> not (is_defined_evar evd ev) | _ -> false -let undefined_evars evd = - let evars = - fold (fun evk evi sigma -> if evi.evar_body = Evar_empty then - add sigma evk evi else sigma) - evd.evars empty - in +let undefined_evars evd = + let evars = + EvarMap.fold (fun evk evi sigma -> if evi.evar_body = Evar_empty then + EvarMap.add sigma evk evi else sigma) + evd.evars EvarMap.empty + in { evd with evars = evars } (* extracts conversion problems that satisfy predicate p *) (* Note: conv_pbs not satisying p are stored back in reverse order *) let extract_conv_pbs evd p = - let (pbs,pbs1) = + let (pbs,pbs1) = List.fold_left (fun (pbs,pbs1) pb -> - if p pb then + if p pb then (pb::pbs,pbs1) - else + else (pbs,pb::pbs1)) ([],[]) evd.conv_pbs in - {evd with conv_pbs = pbs1; last_mods = []}, + {evd with conv_pbs = pbs1; last_mods = ExistentialSet.empty}, pbs let extract_changed_conv_pbs evd p = @@ -505,23 +574,31 @@ let extract_changed_conv_pbs evd p = let extract_all_conv_pbs evd = extract_conv_pbs evd (fun _ -> true) +(* spiwack: should it be replaced by Evd.merge? *) let evar_merge evd evars = - { evd with evars = merge evd.evars evars } + { evd with evars = EvarMap.merge evd.evars evars.evars } + +let evar_list evd c = + let rec evrec acc c = + match kind_of_term c with + | Evar (evk, _ as ev) when mem evd evk -> ev :: acc + | _ -> fold_constr evrec acc c in + evrec [] c (**********************************************************) (* Sort variables *) -let new_sort_variable (sigma,sm) = +let new_sort_variable ({ evars = (sigma,sm) } as d)= let (u,scstr) = new_sort_var sm in - (Type u,(sigma,scstr)) -let is_sort_variable (_,sm) s = + (Type u,{ d with evars = (sigma,scstr) } ) +let is_sort_variable {evars=(_,sm)} s = is_sort_var s sm -let whd_sort_variable (_,sm) t = whd_sort_var sm t -let set_leq_sort_variable (sigma,sm) u1 u2 = - (sigma, set_leq u1 u2 sm) -let define_sort_variable (sigma,sm) u s = - (sigma, set_sort_variable u s sm) -let pr_sort_constraints (_,sm) = pr_sort_cstrs sm +let whd_sort_variable {evars=(_,sm)} t = whd_sort_var sm t +let set_leq_sort_variable ({evars=(sigma,sm)}as d) u1 u2 = + { d with evars = (sigma, set_leq u1 u2 sm) } +let define_sort_variable ({evars=(sigma,sm)}as d) u s = + { d with evars = (sigma, set_sort_variable u s sm) } +let pr_sort_constraints {evars=(_,sm)} = pr_sort_cstrs sm (**********************************************************) (* Accessing metas *) @@ -536,7 +613,7 @@ let undefined_metas evd = | (n,Cltyp (_,typ)) -> n) (meta_list evd)) -let metas_of evd = +let metas_of evd = List.map (function | (n,Clval(_,_,typ)) -> (n,typ.rebus) | (n,Cltyp (_,typ)) -> (n,typ.rebus)) @@ -544,8 +621,8 @@ let metas_of evd = let map_metas_fvalue f evd = { evd with metas = - Metamap.map - (function + Metamap.map + (function | Clval(id,(c,s),typ) -> Clval(id,(mk_freelisted (f c.rebus),s),typ) | x -> x) evd.metas } @@ -559,19 +636,28 @@ let meta_defined evd mv = | Clval _ -> true | Cltyp _ -> false -let meta_fvalue evd mv = +let try_meta_fvalue evd mv = match Metamap.find mv evd.metas with | Clval(_,b,_) -> b - | Cltyp _ -> anomaly "meta_fvalue: meta has no value" - + | Cltyp _ -> raise Not_found + +let meta_fvalue evd mv = + try try_meta_fvalue evd mv + with Not_found -> anomaly "meta_fvalue: meta has no value" + +let meta_value evd mv = + (fst (try_meta_fvalue evd mv)).rebus + let meta_ftype evd mv = match Metamap.find mv evd.metas with | Cltyp (_,b) -> b | Clval(_,_,b) -> b - + +let meta_type evd mv = (meta_ftype evd mv).rebus + let meta_declare mv v ?(name=Anonymous) evd = { evd with metas = Metamap.add mv (Cltyp(name,mk_freelisted v)) evd.metas } - + let meta_assign mv (v,pb) evd = match Metamap.find mv evd.metas with | Cltyp(na,ty) -> @@ -588,10 +674,7 @@ let meta_reassign mv (v,pb) evd = (* If the meta is defined then forget its name *) let meta_name evd mv = - try - let (na,def) = clb_name (Metamap.find mv evd.metas) in - if def then Anonymous else na - with Not_found -> Anonymous + try fst (clb_name (Metamap.find mv evd.metas)) with Not_found -> Anonymous let meta_with_name evd id = let na = Name id in @@ -603,27 +686,28 @@ let meta_with_name evd id = else l) evd.metas ([],[]) in match mvnodef, mvl with - | _,[] -> + | _,[] -> errorlabstrm "Evd.meta_with_name" (str"No such bound variable " ++ pr_id id ++ str".") - | ([n],_|_,[n]) -> + | ([n],_|_,[n]) -> n - | _ -> + | _ -> errorlabstrm "Evd.meta_with_name" (str "Binder name \"" ++ pr_id id ++ strbrk "\" occurs more than once in clause.") +(* spiwack: we should try and replace this List.fold_left by a Metamap.fold. *) let meta_merge evd1 evd2 = {evd2 with - metas = List.fold_left (fun m (n,v) -> Metamap.add n v m) + metas = List.fold_left (fun m (n,v) -> Metamap.add n v m) evd2.metas (metamap_to_list evd1.metas) } type metabinding = metavariable * constr * instance_status let retract_coercible_metas evd = - let mc,ml = - Metamap.fold (fun n v (mc,ml) -> + let mc,ml = + Metamap.fold (fun n v (mc,ml) -> match v with | Clval (na,(b,(UserGiven,CoerceToType as s)),typ) -> (n,b.rebus,s)::mc, Metamap.add n (Cltyp (na,typ)) ml @@ -636,12 +720,25 @@ let rec list_assoc_in_triple x = function [] -> raise Not_found | (a,b,_)::l -> if compare a x = 0 then b else list_assoc_in_triple x l -let subst_defined_metas bl c = +let subst_defined_metas bl c = let rec substrec c = match kind_of_term c with | Meta i -> substrec (list_assoc_in_triple i bl) | _ -> map_constr substrec c in try Some (substrec c) with Not_found -> None +(*******************************************************************) +type open_constr = evar_map * constr + +(*******************************************************************) +(* The type constructor ['a sigma] adds an evar map to an object of + type ['a] *) +type 'a sigma = { + it : 'a ; + sigma : evar_map} + +let sig_it x = x.it +let sig_sig x = x.sigma + (**********************************************************) (* Failure explanation *) @@ -670,20 +767,22 @@ let pr_meta_map mmap = | _ -> mt() in let pr_meta_binding = function | (mv,Cltyp (na,b)) -> - hov 0 + hov 0 (pr_meta mv ++ pr_name na ++ str " : " ++ print_constr b.rebus ++ fnl ()) - | (mv,Clval(na,(b,s),_)) -> - hov 0 + | (mv,Clval(na,(b,s),t)) -> + hov 0 (pr_meta mv ++ pr_name na ++ str " := " ++ - print_constr b.rebus ++ spc () ++ pr_instance_status s ++ fnl ()) + print_constr b.rebus ++ + str " : " ++ print_constr t.rebus ++ + spc () ++ pr_instance_status s ++ fnl ()) in prlist pr_meta_binding (metamap_to_list mmap) let pr_decl ((id,b,_),ok) = match b with | None -> if ok then pr_id id else (str "{" ++ pr_id id ++ str "}") - | Some c -> str (if ok then "(" else "{") ++ pr_id id ++ str ":=" ++ + | Some c -> str (if ok then "(" else "{") ++ pr_id id ++ str ":=" ++ print_constr c ++ str (if ok then ")" else "}") let pr_evar_info evi = @@ -697,12 +796,19 @@ let pr_evar_info evi = in hov 2 (str"[" ++ phyps ++ spc () ++ str"|- " ++ pty ++ pb ++ str"]") -let pr_evar_map sigma = - h 0 - (prlist_with_sep pr_fnl - (fun (ev,evi) -> - h 0 (str(string_of_existential ev)++str"=="++ pr_evar_info evi)) - (to_list sigma)) +let pr_evar_map_t (evars,cstrs as sigma) = + let evs = + if evars = EvarInfoMap.empty then mt () + else + str"EVARS:"++brk(0,1)++ + h 0 (prlist_with_sep pr_fnl + (fun (ev,evi) -> + h 0 (str(string_of_existential ev)++str"=="++ pr_evar_info evi)) + (EvarMap.to_list sigma))++fnl() + and cs = + if cstrs = UniverseMap.empty then mt () + else pr_sort_cstrs cstrs++fnl() + in evs ++ cs let pr_constraints pbs = h 0 @@ -710,19 +816,20 @@ let pr_constraints pbs = print_constr t1 ++ spc() ++ str (match pbty with | Reduction.CONV -> "==" - | Reduction.CUMUL -> "<=") ++ + | Reduction.CUMUL -> "<=") ++ spc() ++ print_constr t2) pbs) -let pr_evar_defs evd = +let pr_evar_map evd = let pp_evm = - if evd.evars = empty then mt() else - str"EVARS:"++brk(0,1)++pr_evar_map evd.evars++fnl() in + if evd.evars = EvarMap.empty then mt() else + pr_evar_map_t evd.evars++fnl() in let cstrs = + if evd.conv_pbs = [] then mt() else str"CONSTRAINTS:"++brk(0,1)++pr_constraints evd.conv_pbs++fnl() in let pp_met = if evd.metas = Metamap.empty then mt() else str"METAS:"++brk(0,1)++pr_meta_map evd.metas in v 0 (pp_evm ++ cstrs ++ pp_met) -let pr_metaset metas = +let pr_metaset metas = str "[" ++ prlist_with_sep spc pr_meta (Metaset.elements metas) ++ str "]" |