aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorEnrico Tassi2018-05-31 16:12:33 +0200
committerErik Martin-Dorel2019-04-02 22:02:27 +0200
commit717f77bbaf479ae1e8335ce226ad71c2c88df644 (patch)
treedfa33fc400fa1d07c8eeab44a1372add576ccf2f /plugins
parent2b2b70d2f0487994db7effc7ced89a658c0cf4f3 (diff)
[ssr] implement "under i: ext_lemma" by rewrite rule
Still to do: renaming the bound variables afterwards
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ssr/ssrfwd.ml63
-rw-r--r--plugins/ssr/ssrfwd.mli3
-rw-r--r--plugins/ssr/ssrparser.mlg5
3 files changed, 71 insertions, 0 deletions
diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml
index 3cadc92bcc..ff7b891319 100644
--- a/plugins/ssr/ssrfwd.ml
+++ b/plugins/ssr/ssrfwd.ml
@@ -319,3 +319,66 @@ let sufftac ist ((((clr, pats),binders),simpl), ((_, c), hint)) =
let _,ty,_,uc = pf_interp_ty ist gl c in let gl = pf_merge_uc uc gl in
basecuttac "ssr_suff" ty gl in
Tacticals.tclTHENS ctac [htac; Tacticals.tclTHEN (old_cleartac clr) (introstac (binders@simpl))]
+
+open Proofview.Notations
+
+let is_app_evar sigma t =
+ match EConstr.kind sigma t with
+ | Constr.Evar _ -> true
+ | Constr.App(t,_) ->
+ begin match EConstr.kind sigma t with
+ | Constr.Evar _ -> true
+ | _ -> false end
+ | _ -> false
+
+let tmp = ref 0
+
+let rec intro_lock names = Proofview.Goal.enter begin fun gl ->
+ let c = Proofview.Goal.concl gl in
+ let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
+ let rec aux c =
+ match EConstr.kind_of_type sigma c with
+ | Term.SortType _ -> Proofview.tclUNIT ()
+ | ( Term.ProdType ({ Context.binder_name = name },_,t)
+ | Term.LetInType ({ Context.binder_name = name },_,_,t) ) ->
+ begin match names with
+ | n :: names -> Ssripats.(tclIPAT @@ [Ssripats.IOpId n]) <*> intro_lock names
+ | [] ->
+ (* after quell intro patterns, use IpatTemp *)
+ let id =
+ match name with
+ | Name.Anonymous -> Id.of_string (Printf.sprintf "_under_%d_" !tmp)
+ | Name.Name n -> n in
+ incr tmp;
+ Ssripats.tclIPAT [
+ Ssripats.IOpId id;
+ Ssripats.IOpEqGen (intro_lock names);
+ Ssripats.IOpEqGen (Tactics.revert [id])]
+ end
+ | Term.CastType (t,_) -> aux t
+ | Term.AtomicType _ ->
+ let t = Reductionops.whd_all env sigma c in
+ match EConstr.kind_of_type sigma t with
+ | Term.AtomicType(hd, args) when
+ Ssrcommon.is_ind_ref sigma hd (Coqlib.lib_ref "core.eq.type") &&
+ Array.length args = 3 && is_app_evar sigma args.(2) ->
+ Tactics.New.refine ~typecheck:true (fun sigma ->
+ let sigma, under =
+ Ssrcommon.mkSsrConst "Under" env sigma in
+ let sigma, under_from_eq =
+ Ssrcommon.mkSsrConst "Under_from_eq" env sigma in
+ let ty = EConstr.mkApp (under,args) in
+ let sigma, t = Evarutil.new_evar env sigma ty in
+ sigma, EConstr.mkApp(under_from_eq,Array.append args [|t|]))
+ | _ -> Proofview.tclUNIT ()
+ in
+ aux c
+
+end
+
+let undertac ist varnames ((dir,mult),_ as rule) =
+ if mult <> Ssrequality.nomult then
+ Ssrcommon.errorstrm Pp.(str"Multiplicity not supported");
+ Proofview.V82.tactic (Ssrequality.ssrrewritetac ~under:true ist [rule]) <*>
+ intro_lock varnames
diff --git a/plugins/ssr/ssrfwd.mli b/plugins/ssr/ssrfwd.mli
index 35e89dbcea..fe7d84871e 100644
--- a/plugins/ssr/ssrfwd.mli
+++ b/plugins/ssr/ssrfwd.mli
@@ -57,3 +57,6 @@ val sufftac :
(bool * Tacinterp.Value.t option list)) ->
Tacmach.tactic
+val undertac :
+ Ltac_plugin.Tacinterp.interp_sign ->
+ Names.Id.t list -> Ssrequality.ssrrwarg -> unit Proofview.tactic
diff --git a/plugins/ssr/ssrparser.mlg b/plugins/ssr/ssrparser.mlg
index 0ec5f1673a..e63d1e5562 100644
--- a/plugins/ssr/ssrparser.mlg
+++ b/plugins/ssr/ssrparser.mlg
@@ -2650,6 +2650,11 @@ TACTIC EXTEND ssrgenhave2
V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) }
END
+TACTIC EXTEND under
+ | [ "under" ne_ident_list(names) ":" ssrrwarg(r) ] ->
+ { Ssrfwd.undertac ist names r }
+END
+
{
(* We wipe out all the keywords generated by the grammar rules we defined. *)