(* This is a pattern to collect terms from the Coq memory of valid terms andproofs.Thispatternextendsallthewaytothedefinitionoffunction
c_U *) let collect_constants () = if (!constants = []) then letopen Names in letopen EConstr in letopen UnivGen in let find_reference path id = let path = DirPath.make (List.rev_map Id.of_string path) in let fp = Libnames.make_path path (Id.of_string id) in
Nametab.global_of_path fp in let gr_H = find_reference ["Tuto3"; "Data"] "pack"in let gr_M = find_reference ["Tuto3"; "Data"] "packer"in let gr_R = find_reference ["Corelib"; "Init"; "Datatypes"] "pair"in let gr_P = find_reference ["Corelib"; "Init"; "Datatypes"] "prod"in let gr_U = find_reference ["Tuto3"; "Data"] "uncover"in
constants := List.map (fun x -> of_constr (constr_of_monomorphic_global (Global.env ()) x))
[gr_H; gr_M; gr_R; gr_P; gr_U];
!constants else
!constants
let c_H () = match collect_constants () with
it :: _ -> it
| _ -> failwith "could not obtain an internal representation of pack"
let c_M () = match collect_constants () with
_ :: it :: _ -> it
| _ -> failwith "could not obtain an internal representation of pack_marker"
let c_R () = match collect_constants () with
_ :: _ :: it :: _ -> it
| _ -> failwith "could not obtain an internal representation of pair"
let c_P () = match collect_constants () with
_ :: _ :: _ :: it :: _ -> it
| _ -> failwith "could not obtain an internal representation of prod"
let c_U () = match collect_constants () with
_ :: _ :: _ :: _ :: it :: _ -> it
| _ -> failwith "could not obtain an internal representation of prod"
(* The following tactic is meant to pack an hypothesis when no other dataisalreadypacked.
Themaindifficultyindefiningthistacticistounderstandhowto
construct the input expected by apply_in. *) let package i = Goal.enter beginfun gl ->
Tactics.apply_in truefalse i
[(* this means that the applied theorem is not to be cleared. *)
None, (CAst.make (c_M (), (* we don't specialize the theorem with extra values. *)
Tactypes.NoBindings))] (* we don't destruct the result according to any intro_pattern *)
None end
(* This function is meant to observe a type of shape (f a)
and return the value a. *)
(* Remark by Maxime: look for destApp combinator. *) let unpack_type sigma term = let report () =
CErrors.user_err (Pp.str "expecting a packed type") in match EConstr.kind sigma term with
| Constr.App (_, [| ty |]) -> ty
| _ -> report ()
(* This function is meant to observe a type of shape A->packB->CandreturnA,B,C butitisnotusedinthecurrentversionofourtactic.
It is kept as an example. *) let two_lambda_pattern sigma term = let report () =
CErrors.user_err (Pp.str "expecting two nested implications") in (* Note that pattern-matching is always done through the EConstr.kind function,
which only provides one-level deep patterns. *) match EConstr.kind sigma term with (* Here we recognize the outer implication *)
| Constr.Prod (_, ty1, l1) -> (* Here we recognize the inner implication *)
(match EConstr.kind sigma l1 with
| Constr.Prod (n2, packed_ty2, deep_conclusion) -> (* Here we recognized that the second type is an application *)
ty1, unpack_type sigma packed_ty2, deep_conclusion
| _ -> report ())
| _ -> report ()
(* In the environment of the goal, we can get the type of an assumption directlybyalookup.Theothersolutionistocallalow-costretyping
function like *) let get_type_of_hyp env id = match EConstr.lookup_named id env with
| Context.Named.Declaration.LocalAssum (_, ty) -> ty
| _ -> CErrors.user_err (letopen Pp in
str (Names.Id.to_string id) ++
str " is not a plain hypothesis")
let repackage i h_hyps_id = Goal.enter beginfun gl -> let env = Goal.env gl in let sigma = Tacmach.project gl in let concl = Tacmach.pf_concl gl in let (ty1 : EConstr.t) = get_type_of_hyp env i in let (packed_ty2 : EConstr.t) = get_type_of_hyp env h_hyps_id in let ty2 = unpack_type sigma packed_ty2 in let new_packed_type = EConstr.mkApp (c_P (), [| ty1; ty2 |]) in letopen EConstr in let new_packed_value =
mkApp (c_R (), [| ty1; ty2; mkVar i;
mkApp (c_U (), [| ty2; mkVar h_hyps_id|]) |]) in
Refine.refine ~typecheck:truebeginfun sigma -> let sigma, new_goal = Evarutil.new_evar env sigma
(mkArrowR (mkApp(c_H (), [| new_packed_type |]))
(Vars.lift 1 concl)) in
sigma, mkApp (new_goal,
[|mkApp(c_M (), [|new_packed_type; new_packed_value |]) |]) end end
let pack_tactic i = let h_hyps_id = (Names.Id.of_string "packed_hyps") in
Proofview.Goal.enter beginfun gl -> let hyps = Environ.named_context_val (Proofview.Goal.env gl) in ifnot (Termops.mem_named_context_val i hyps) then
(CErrors.user_err
(Pp.str ("no hypothesis named" ^ (Names.Id.to_string i)))) else if Termops.mem_named_context_val h_hyps_id hyps then
tclTHEN (repackage i h_hyps_id)
(tclTHEN (Tactics.clear [h_hyps_id; i])
(Tactics.introduction h_hyps_id)) else
tclTHEN (package i)
(tclTHEN (Tactics.rename_hyp [i, h_hyps_id])
(Tactics.move_hyp h_hyps_id Logic.MoveLast)) end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-06-17)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.