aboutsummaryrefslogtreecommitdiffhomepage
path: root/contrib/subtac/eterm.ml
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/subtac/eterm.ml')
-rw-r--r--contrib/subtac/eterm.ml118
1 files changed, 118 insertions, 0 deletions
diff --git a/contrib/subtac/eterm.ml b/contrib/subtac/eterm.ml
new file mode 100644
index 000000000..4f86af1e8
--- /dev/null
+++ b/contrib/subtac/eterm.ml
@@ -0,0 +1,118 @@
+(**
+ - Get types of existentials ;
+ - Flatten dependency tree (prefix order) ;
+ - Replace existentials by De Bruijn indices in term, applied to the right arguments ;
+ - Apply term prefixed by quantification on "existentials".
+*)
+
+open Term
+open Names
+open Sutils
+open Evd
+open List
+open Pp
+(** Substitute evar references in t using De Bruijn indices,
+ where n binders were passed through. *)
+let subst_evars evs n t =
+ let evar_index id =
+ let idx = list_assoc_index id evs in
+ idx + 1
+ in
+ let rec substrec depth c = match kind_of_term c with
+ | Evar (k, args) ->
+ (try
+ msgnl (str "Evar " ++ int k ++ str " found");
+ let ex =
+(* mkVar (id_of_string ("Evar" ^ string_of_int k));*)
+ mkRel (evar_index k + depth)
+ in
+ let args = Array.map (map_constr_with_binders succ substrec depth) args in
+ mkApp (ex, args)
+ with Not_found ->
+ msgnl (str "Evar " ++ int k ++ str " not found!!!");
+ c)
+ | _ -> map_constr_with_binders succ substrec depth c
+ in
+ substrec 0 t
+
+(** Substitute variable references in t using De Bruijn indices,
+ where n binders were passed through. *)
+let subst_vars acc n t =
+ let var_index id =
+ let idx = list_index id acc in
+ idx + 1
+ in
+ let rec substrec depth c = match kind_of_term c with
+ | Var v -> (try mkRel (depth + (var_index v)) with Not_found -> c)
+ | _ -> map_constr_with_binders succ substrec depth c
+ in
+ substrec 0 t
+
+(** Rewrite type of an evar ([ H1 : t1, ... Hn : tn |- concl ])
+ to a product : forall H1 : t1, ..., forall Hn : tn, concl.
+ Changes evars and hypothesis references to De Bruijn indices.
+*)
+let etype_of_evar evs ev =
+ let rec aux acc n = function
+ (id, copt, t) :: tl ->
+ let t' = subst_evars evs n t in
+ let t'' = subst_vars acc 0 t' in
+ mkNamedProd_or_LetIn (id, copt, t'') (aux (id :: acc) (succ n) tl)
+ | [] ->
+ let t' = subst_evars evs n ev.evar_concl in
+ subst_vars acc 0 t'
+ in aux [] 0 (rev ev.evar_hyps)
+
+
+open Tacticals
+
+let eterm evm t =
+ (* 'Serialize' the evars, we assume that the types of the existentials
+ refer to previous existentials in the list only *)
+ let evl = to_list evm in
+ let evts =
+ (* Remove existential variables in types and build the corresponding products *)
+ fold_left
+ (fun l (id, y) ->
+ let y' = (id, etype_of_evar l y) in
+ y' :: l)
+ [] evl
+ in
+ let t' = (* Substitute evar refs in the term to De Bruijn indices *)
+ subst_evars evts 0 t
+ in
+ let t'' =
+ (* Make the lambdas 'generalizing' the existential variables *)
+ fold_left
+ (fun acc (id, c) ->
+ mkLambda (Name (id_of_string ("Evar" ^ string_of_int id)),
+ c, acc))
+ t' evts
+
+
+ in
+ let declare_evar (id, c) =
+ let id = id_of_string ("Evar" ^ string_of_int id) in
+ ignore(Declare.declare_variable id (Names.empty_dirpath, Declare.SectionLocalAssum c,
+ Decl_kinds.IsAssumption Decl_kinds.Definitional))
+ in
+ let declare_assert acc (id, c) =
+ let id = id_of_string ("Evar" ^ string_of_int id) in
+ tclTHEN acc (Tactics.assert_tac false (Name id) c)
+ in
+ msgnl (str "Term constructed in Eterm" ++
+ Termops.print_constr_env (Global.env ()) t'');
+ Tactics.apply_term (Reduction.nf_betaiota t'') (map (fun _ -> Evarutil.mk_new_meta ()) evts)
+ (* t'' *)
+ (* Hack: push evars as assumptions in the global env *)
+(* iter declare_evar evts; *)
+(* Tactics.apply t' *)
+ (*tclTHEN (fold_left declare_assert tclIDTAC evts) (Tactics.apply t')*)
+
+open Tacmach
+
+let etermtac (evm, t) =
+ let t' = eterm evm t in
+ t'
+(* Tactics.apply (Reduction.nf_betaiota t')
+ Tactics.exact (Reduction.nf_betaiota t')*)