package coq-core
The Coq Proof Assistant -- Core Binaries and Tools
Install
Dune Dependency
Authors
Maintainers
Sources
coq-8.19.2.tar.gz
md5=5d1187d5e44ed0163f76fb12dabf012e
sha512=91bc81530fa4f6498961583ad51eac5001f139881788b88e360a866ad8e2a6e2c5bce86d1a580ab4cd4782bf49d48318767df82471ce33ba3ac143e5569ad33c
doc/src/tuto3_plugin/tuto_tactic.ml.html
Source file tuto_tactic.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
open Proofview let constants = ref ([] : EConstr.t list) (* This is a pattern to collect terms from the Coq memory of valid terms and proofs. This pattern extends all the way to the definition of function c_U *) let collect_constants () = if (!constants = []) then let open EConstr in let open UnivGen in let find_reference = Coqlib.find_reference [@ocaml.warning "-3"] in let gr_H = find_reference "Tuto3" ["Tuto3"; "Data"] "pack" in let gr_M = find_reference "Tuto3" ["Tuto3"; "Data"] "packer" in let gr_R = find_reference "Tuto3" ["Coq"; "Init"; "Datatypes"] "pair" in let gr_P = find_reference "Tuto3" ["Coq"; "Init"; "Datatypes"] "prod" in let gr_U = find_reference "Tuto3" ["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 data is already packed. The main difficulty in defining this tactic is to understand how to construct the input expected by apply_in. *) let package i = Goal.enter begin fun gl -> Tactics.apply_in true false 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 -> pack B -> C and return A, B, C but it is not used in the current version of our tactic. 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 directly by a lookup. The other solution is to call a low-cost retyping 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 (let open Pp in str (Names.Id.to_string id) ++ str " is not a plain hypothesis") let repackage i h_hyps_id = Goal.enter begin fun 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 let open 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:true begin fun 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 begin fun gl -> let hyps = Environ.named_context_val (Proofview.Goal.env gl) in if not (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
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>