diff options
Diffstat (limited to 'contrib/funind/tacinvutils.ml')
-rw-r--r-- | contrib/funind/tacinvutils.ml | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/contrib/funind/tacinvutils.ml b/contrib/funind/tacinvutils.ml new file mode 100644 index 00000000..758071ba --- /dev/null +++ b/contrib/funind/tacinvutils.ml @@ -0,0 +1,277 @@ +(* tacinvutils.ml *) +(*s utilities *) + +(*i*) +open Names +open Util +open Term +open Termops +open Coqlib +open Pp +open Printer +open Inductiveops +open Environ +open Declarations +open Nameops +open Evd +open Sign +open Reductionops +(*i*) + +(*s printing of constr -- debugging *) + +let msg x = () ;; let prterm c = str "" (* comment this to see debug msgs *) + (* uncomment this to see debugging *) +let prconstr c = msg (str" " ++ prterm c ++ str"\n") +let prlistconstr lc = List.iter prconstr lc +let prstr s = msg(str s) + +let prchr () = msg (str" (ret) \n") +let prNamedConstr s c = + begin + msg(str ""); + msg(str(s^"==>\n ") ++ prterm c ++ str "\n<==\n"); + msg(str ""); + end + +let prNamedLConstr_aux lc = + List.iter (prNamedConstr "#>") lc + +let prNamedLConstr s lc = + begin + prstr s; + prNamedLConstr_aux lc + end + + +(* FIXME: ref 1, pas bon, si? *) +let evarcpt = ref 0 +let metacpt = ref 0 +let mknewexist ()= + begin + evarcpt := !evarcpt+1; + !evarcpt,[||] + end + +let resetexist ()= evarcpt := 0 + +let mknewmeta ()= + begin + metacpt := !metacpt+1; + mkMeta (!metacpt) + end + +let resetmeta () = metacpt := 0 + +let rec mkevarmap_from_listex lex = + match lex with + | [] -> Evd.empty + | ((ex,_),typ)::lex' -> + let info ={ + evar_concl = typ; + evar_hyps = empty_named_context; + evar_body = Evar_empty} in + Evd.add (mkevarmap_from_listex lex') ex info + +let mkEq typ c1 c2 = + mkApp (build_coq_eq(),[| typ; c1; c2|]) + +let mkRefl typ c1 = + mkApp ((build_coq_eq_data()).refl, [| typ; c1|]) + +let rec popn i c = if i<=0 then c else pop (popn (i-1) c) + + +(* Operations on names *) +let id_of_name = function + Anonymous -> id_of_string "H" + | Name id -> id;; +let string_of_name nme = string_of_id (id_of_name nme) +let name_of_string str = Name (id_of_string str) +let newname_append nme str = + Name(id_of_string ((string_of_id (id_of_name nme))^str)) + +(* Substitutions in constr *) + +let compare_constr_nosub t1 t2 = + if compare_constr (fun _ _ -> false) t1 t2 + then true + else false + +let rec compare_constr' t1 t2 = + if compare_constr_nosub t1 t2 + then true + else (compare_constr (compare_constr') t1 t2) + +let rec substitterm prof t by_t in_u = + if (compare_constr' (lift prof t) in_u) + then (lift prof by_t) + else map_constr_with_binders succ + (fun i -> substitterm i t by_t) prof in_u + + +let apply_eqtrpl eq t = + let r,(tb,b,by_t) = eq in + substitterm 0 b by_t t + +let apply_eqtrpl_lt lt eq = List.map (apply_eqtrpl eq) lt + +let apply_leqtrpl_t t leq = + List.fold_left (fun x y -> apply_eqtrpl y x) t leq + + +let apply_refl_term eq t = + let _,arr = destApplication eq in + let reli= (Array.get arr 1) in + let by_t= (Array.get arr 2) in + substitterm 0 reli by_t t + +let apply_eq_leqtrpl leq eq = + List.map + (function (r,(tb,b,t)) -> + r,(tb, + (if isRel b then b else (apply_refl_term eq b)), apply_refl_term eq t)) + leq + + + +(* [(a b c) a] -> true *) +let constr_head_match u t= + if isApp u + then + let uhd,args= destApplication u in + uhd=t + else false + +(* My operations on constr *) +let lift1L l = (List.map (lift 1) l) +let mkArrow_lift t1 t2 = mkArrow t1 (lift 1 t2) +let mkProd_liftc nme c1 c2 = mkProd (nme,c1,(lift 1 c2)) +(* prod_it_lift x [a1 a2 ...] *) +let prod_it_lift ini lcpl = + List.fold_right (function a,b -> (fun c -> mkProd_liftc a b c)) ini lcpl;; + +let prod_it_anonym_lift trm lst = List.fold_right mkArrow_lift lst trm + +let lam_it_anonymous trm lst = + List.fold_right + (fun elt res -> mkLambda(Name(id_of_string "Hrec"),elt,res)) lst trm + +let lambda_id id typeofid cstr = + let cstr' = mkNamedLambda (id_of_string "FUNX") typeofid cstr in + substitterm 0 id (mkRel 0) cstr' + +let prod_id id typeofid cstr = + let cstr' = mkNamedProd (id_of_string "FUNX") typeofid cstr in + substitterm 0 id (mkRel 0) cstr' + + + + + +let nth_dep_constructor indtype n = + let sigma = Evd.empty and env = Global.env() in + let indtypedef = find_rectype env sigma indtype in + let indfam,_ = dest_ind_type indtypedef in + let arr_cstr_summary = get_constructors env indfam in + let cstr_sum = Array.get arr_cstr_summary n in + build_dependent_constructor cstr_sum, cstr_sum.cs_nargs + + +let rec buildrefl_from_eqs eqs = + match eqs with + | [] -> [] + | cstr::eqs' -> + let eq,args = destApplication cstr in + (mkRefl (Array.get args 0) (Array.get args 2)) + :: (buildrefl_from_eqs eqs') + + + + +(* list of occurrences of a term inside another, no imbricated + occurrence are considered (ie we stop looking inside a termthat is + an occurrence). *) +let rec hdMatchSub u t= + if constr_head_match u t then + u::(fold_constr (fun l cstr -> l@(hdMatchSub cstr t)) + [] + u) + else + fold_constr (fun l cstr -> l@(hdMatchSub cstr t)) + [] + u + +(* let hdMatchSub_list u lt = List.flatten (List.map (hdMatchSub u) lt) *) +let hdMatchSub_cpl u (d,f) = + let res = ref [] in + begin + for i = d to f do res := (hdMatchSub u (mkRel i)) @ !res done; + !res + end + + +(* destApplication raises an exception if [t] is not an application *) +let exchange_hd_prod subst_hd t = + let (hd,args)= destApplication t in mkApp (subst_hd,args) + +(* substitute t by by_t in head of products inside in_u, reduces each + product found *) +let rec substit_red prof t by_t in_u = + if constr_head_match in_u (lift prof t) + then + let _ = prNamedConstr "in_u" in_u in + let x = whd_beta (exchange_hd_prod (lift prof by_t) in_u) in + let _ = prNamedConstr "xx " x in + let _ = prstr "\n\n" in + x + else + map_constr_with_binders succ (fun i u -> substit_red i t by_t u) + prof in_u + +(* [exchange_reli_arrayi t=(reli x y ...) tarr (d,f)] exchange each + reli by tarr.(f-i). *) +let exchange_reli_arrayi tarr (d,f) t = + let hd,args= destApplication t in + let i = destRel hd in + whd_beta (mkApp (tarr.(f-i) ,args)) + +let exchange_reli_arrayi_L tarr (d,f) = + List.map (exchange_reli_arrayi tarr (d,f)) + + +(* expand all letins in a term, before building the principle. *) +let rec expand_letins mimick = + match kind_of_term mimick with + | LetIn(nme,cstr1, typ, cstr) -> + let cstr' = substitterm 0 (mkRel 1) (lift 1 cstr1) cstr in + expand_letins (pop cstr') + | x -> map_constr expand_letins mimick + + +(* Valeur d'une constante, or identity *) +let def_of_const t = + match kind_of_term t with + | Const sp -> + (try + match Global.lookup_constant sp with + {const_body=Some c} -> force c + |_ -> assert false + with _ -> assert false) + | _ -> t + +(* nom d'une constante. Must be a constante. x*) +let name_of_const t = + match (kind_of_term t) with + Const cst -> Names.string_of_label (Names.label cst) + |_ -> assert false + ;; + + +(*i +*** Local Variables: +*** compile-command: "make -k tacinvutils.cmo" +*** test-tactic: "../../bin/coqtop -translate -q -batch -load-vernac-source ../../test-suite/success/Funind.v" +*** End: +i*) + |