+(** select metasenv conjecture pattern
+* select all subterms of [conjecture] matching [pattern].
+* It returns the set of matched terms (that can be compared using physical
+* equality to the subterms of [conjecture]) together with their contexts.
+* The representation of the set mimics the ProofEngineTypes.pattern type:
+* a list of hypothesis (names of) together with the list of its matched
+* subterms (and their contexts) + the list of matched subterms of the
+* with their context conclusion. Note: in the result the list of hypothesis
+* has an entry for each entry in the context and in the same order.
+* Of course the list of terms (with their context) associated to the
+* hypothesis name may be empty. *)
+let select ~metasenv ~conjecture:(_,context,ty) ~pattern:(what,hyp_patterns,goal_pattern) =
+ let find_pattern_for name =
+ try Some (snd (List.find (fun (n, pat) -> Cic.Name n = name) hyp_patterns))
+ with Not_found -> None in
+ let ty_terms = select_in_term ~context ~term:ty ~pattern:(what,goal_pattern) in
+ let context_len = List.length context in
+ let context_terms =
+ fst
+ (List.fold_right
+ (fun entry (res,context) ->
+ match entry with
+ None -> (None::res),(None::context)
+ | Some (name,Cic.Decl term) ->
+ (match find_pattern_for name with
+ | None -> ((Some (`Decl []))::res),(entry::context)
+ | Some pat ->
+ try
+ let what =
+ match what with
+ None -> None
+ | Some what ->
+ let what,subst',metasenv' =
+ CicMetaSubst.delift_rels [] metasenv
+ (context_len - List.length context) what
+ in
+ assert (subst' = []);
+ assert (metasenv' = metasenv);
+ Some what in
+ let terms = select_in_term ~context ~term ~pattern:(what,pat) in
+ ((Some (`Decl terms))::res),(entry::context)
+ with
+ CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
+ raise
+ (Fail
+ ("The term the user wants to convert is not closed " ^
+ "in the context of the position of the substitution.")))
+ | Some (name,Cic.Def (bo, ty)) ->
+ (match find_pattern_for name with
+ | None ->
+ let selected_ty= match ty with None -> None | Some _ -> Some [] in
+ ((Some (`Def ([],selected_ty)))::res),(entry::context)
+ | Some pat ->
+ try
+ let what =
+ match what with
+ None -> None
+ | Some what ->
+ let what,subst',metasenv' =
+ CicMetaSubst.delift_rels [] metasenv
+ (context_len - List.length context) what
+ in
+ assert (subst' = []);
+ assert (metasenv' = metasenv);
+ Some what in
+ let terms_bo =
+ select_in_term ~context ~term:bo ~pattern:(what,pat) in
+ let terms_ty =
+ match ty with
+ None -> None
+ | Some ty ->
+ Some (select_in_term ~context ~term:ty ~pattern:(what,pat))
+ in
+ ((Some (`Def (terms_bo,terms_ty)))::res),(entry::context)
+ with
+ CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
+ raise
+ (Fail
+ ("The term the user wants to convert is not closed " ^
+ "in the context of the position of the substitution.")))
+ ) context ([],[]))
+ in
+ context_terms, ty_terms