Skip to content

Commit e8c319f

Browse files
committed
add a generic mechanism for rewriting with any equality satisfying J
1 parent bbc0645 commit e8c319f

36 files changed

+520
-192
lines changed

tactics/equality.ml

Lines changed: 177 additions & 110 deletions
Large diffs are not rendered by default.

tactics/tactics.ml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ let index_of_ind_arg sigma t =
12651265
*)
12661266

12671267
type eliminator =
1268-
| ElimConstant of (Constant.t * EInstance.t)
1268+
| ElimConstant of EConstr.constr * int option
12691269
(* Constant generated by a scheme function *)
12701270
| ElimClause of EConstr.constr with_bindings
12711271
(* Arbitrary expression provided by the user *)
@@ -1275,10 +1275,13 @@ let general_elim_clause0 with_evars flags (submetas, c, ty) elim =
12751275
let env = Proofview.Goal.env gl in
12761276
let sigma = Proofview.Goal.sigma gl in
12771277
let clause, bindings, index = match elim with
1278-
| ElimConstant cst ->
1279-
let elimc = mkConstU cst in
1278+
| ElimConstant (elimc, i) ->
12801279
let elimt = Retyping.get_type_of env sigma elimc in
1281-
let i = index_of_ind_arg sigma elimt in
1280+
let elimt = Reductionops.whd_all env sigma elimt in
1281+
let i = match i with
1282+
| Some i -> i
1283+
| None -> index_of_ind_arg sigma elimt
1284+
in
12821285
(elimc, elimt), NoBindings, Some i
12831286
| ElimClause (elimc, lbindelimc) ->
12841287
let elimt = Retyping.get_type_of env sigma elimc in
@@ -1293,13 +1296,18 @@ let general_elim_clause0 with_evars flags (submetas, c, ty) elim =
12931296
Clenv.res_pf elimclause ~with_evars ~with_classes:true ~flags
12941297
end
12951298

1296-
let general_elim_clause_in0 with_evars flags id (submetas, c, ty) elim =
1299+
let dbg = CDebug.create ~name:"general_elim" ()
1300+
1301+
let general_elim_clause_in0 with_evars flags id (submetas, c, ty) elimc indarg =
12971302
Proofview.Goal.enter begin fun gl ->
12981303
let env = Proofview.Goal.env gl in
12991304
let sigma = Tacmach.project gl in
1300-
let elimc = mkConstU elim in
13011305
let elimt = Retyping.get_type_of env sigma elimc in
1302-
let i = index_of_ind_arg sigma elimt in
1306+
let elimt = Reductionops.whd_all env sigma elimt in
1307+
let i = match indarg with
1308+
| Some i -> i
1309+
| None -> index_of_ind_arg sigma elimt
1310+
in
13031311
let elimclause = mk_clenv_from env sigma (elimc, elimt) in
13041312
let indmv =
13051313
try nth_arg (Some i) (clenv_arguments elimclause)
@@ -1314,6 +1322,8 @@ let general_elim_clause_in0 with_evars flags id (submetas, c, ty) elim =
13141322
let elimclause = clenv_instantiate ~flags ~submetas indmv elimclause (c, ty) in
13151323
let hyp = mkVar id in
13161324
let hyp_typ = Retyping.get_type_of env sigma hyp in
1325+
let _ = dbg (fun () -> Printer.pr_etype_env env sigma elimc) in
1326+
let _ = dbg (fun () -> Printer.pr_etype_env env sigma elimt) in
13171327
let elimclause =
13181328
try clenv_instantiate ~flags hypmv elimclause (hyp, hyp_typ)
13191329
with PretypeError (env,evd,NoOccurrenceFound (op,_)) ->
@@ -1343,14 +1353,10 @@ let general_elim with_evars clear_flag (c, lbindc) elim =
13431353
(apply_clear_request clear_flag (use_clear_hyp_by_default ()) id)
13441354
end
13451355

1346-
let general_elim_clause with_evars flags where arg elim =
1347-
Proofview.tclENV >>= fun env ->
1348-
Proofview.tclEVARMAP >>= fun sigma ->
1349-
let (sigma, (elim, u)) = Evd.fresh_constant_instance env sigma elim in
1350-
Proofview.Unsafe.tclEVARS sigma <*>
1356+
let general_elim_clause with_evars flags where arg elimc indarg =
13511357
match where with
1352-
| None -> general_elim_clause0 with_evars flags arg (ElimConstant (elim, EInstance.make u))
1353-
| Some id -> general_elim_clause_in0 with_evars flags id arg (elim, EInstance.make u)
1358+
| None -> general_elim_clause0 with_evars flags arg (ElimConstant (elimc, indarg))
1359+
| Some id -> general_elim_clause_in0 with_evars flags id arg elimc indarg
13541360

13551361
(* Case analysis tactics *)
13561362

@@ -1425,7 +1431,7 @@ let default_elim with_evars clear_flag (c,_ as cx) =
14251431
let sigma, elim = find_ind_eliminator env sigma ind
14261432
(Retyping.get_sort_quality_of env sigma concl) in
14271433
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
1428-
(general_elim with_evars clear_flag cx (ElimConstant elim))
1434+
(general_elim with_evars clear_flag cx (ElimConstant (mkConstU elim, None)))
14291435
end)
14301436
begin function (e, info) -> match e with
14311437
| IsNonrec ->
@@ -2126,7 +2132,7 @@ let intro_decomp_eq ?loc l thin tac id =
21262132
| Some (eq,u,eq_args) ->
21272133
!intro_decomp_eq_function
21282134
(fun n -> tac ((CAst.make id)::thin) (Some n) l)
2129-
(eq,t,eq_args) (c, t)
2135+
(eq,u,t,eq_args) (c, t)
21302136
| None ->
21312137
let info = Exninfo.reify () in
21322138
Tacticals.tclZEROMSG ~info (str "Not a primitive equality here.")

tactics/tactics.mli

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ val default_elim : evars_flag -> clear_flag -> constr with_bindings ->
455455
unit Proofview.tactic
456456

457457
val general_elim_clause : evars_flag -> unify_flags -> Id.t option ->
458-
((metavariable list * Unification.Meta.t) * EConstr.t * EConstr.types) -> Constant.t -> unit Proofview.tactic
458+
((metavariable list * Unification.Meta.t) * EConstr.t * EConstr.types) -> EConstr.t -> int option -> unit Proofview.tactic
459459

460460
(** [general_case_analysis with_evars clear (t, bindings)] performs case analysis on [t].
461461
If [t] is a variable which is not in the context, we attempt to perform introductions
@@ -677,7 +677,7 @@ val subst_one :
677677
(bool -> Id.t -> Id.t * constr * bool -> unit Proofview.tactic) Hook.t
678678

679679
val declare_intro_decomp_eq :
680-
((int -> unit Proofview.tactic) -> Rocqlib.rocq_eq_data * types *
680+
((int -> unit Proofview.tactic) -> Rocqlib.rocq_eq_data * EInstance.t * types *
681681
(types * constr * constr) ->
682682
constr * types -> unit Proofview.tactic) -> unit
683683

test-suite/bugs/bug_19203.v

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ Definition nand@{q; |} (a b : bool@{q;}) : bool@{q;} :=
1111
Inductive seq@{q;u|} {A : Type@{q;u}} (a : A) : A -> Type@{q;u} := | srefl : seq a a.
1212
Arguments srefl {_ _}.
1313

14-
Definition seq_elim@{q;u v|} :=
15-
fun (A : Type@{q;u}) (x : A) (P : A -> Type@{q;v}) (f : P x) (a : A) (e : seq x a) =>
16-
match e in (seq _ a0) return (P a0) with
17-
| srefl => f
18-
end.
14+
#[universes(polymorphic=yes)]
15+
Instance seq_Has_Leibniz_elim@{s; l l' l''} : Has_Leibniz@{s s s;l l' l''} (@seq) :=
16+
fun A x P t y e => match e with srefl => t end.
1917

2018
Register seq as core.eq.type.
2119
Register srefl as core.eq.refl.
22-
Register seq_elim as core.eq.rect.
2320

2421
Lemma foo@{q; |} (f : bool@{q;} -> bool@{q;}) (x : bool@{q;}) : seq (f true) (f true).
2522
Proof.

test-suite/bugs/bug_19215.v

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ Register eq_elim as core.eq.rect.
100100

101101
End equality.
102102

103-
Inductive comparison : Set :=
103+
Instance eq_Has_Leibniz_elim@{s s'; l l' l''} : Has_Leibniz@{s s' s' ; l l' l''} (@eq@{s s' ; l l'}) :=
104+
fun A x P t y e => match e with eq_refl => t end.
105+
106+
Inductive comparison : Set :=
104107
| Eq : comparison
105108
| Lt : comparison
106109
| Gt : comparison.

test-suite/bugs/bug_20397_1.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ End Nat.
1818

1919
Notation eq_nat_dec := Nat.eq_dec (only parsing).
2020

21+
#[universes(polymorphic=yes)]
2122
Theorem eq_rect_nat_double : forall T (a b c : nat) x ab bc,
22-
eq_rect b T (eq_rect a T x b ab) c bc = eq_rect a T x c (eq_trans ab bc).
23+
@eq_Has_Leibniz_r_elim _ b T (eq_rect a T x b ab) c bc = eq_rect a T x c (eq_trans ab (eq_sym bc)).
2324
Admitted.
2425

2526
Ltac eq_rect_simpl :=

test-suite/bugs/bug_3125.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ Goal
2727
Proof.
2828
intros a b H.
2929
inversion H.
30-
Fail reflexivity.
30+
reflexivity.
3131
Abort.

test-suite/bugs/bug_3132.v

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Register eq_refl as core.eq.refl.
2222
Register eq_ind as core.eq.ind.
2323
Register eq_rect as core.eq.rect.
2424

25+
#[universes(polymorphic=yes)]
26+
Instance eq_Has_Leibniz_elim@{s ; l l'} : Has_Leibniz@{Type Prop s;l Set l'} (@eq) :=
27+
fun A x P t y e => match e with eq_refl => t end.
28+
2529
Lemma foo (H : true = false) : False.
2630
Proof.
2731
discriminate.
@@ -31,6 +35,6 @@ Print foo.
3135
Goal False.
3236
let c := eval cbv delta [foo] in foo in
3337
match c with
34-
context[eq_ind] => idtac
38+
context[eq_Has_Leibniz_elim] => idtac
3539
end.
3640
Abort.

test-suite/coqdoc/bug11353.html.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
<div class="code">
2222
<span class="id" title="keyword">Definition</span> <a id="a" class="idref" href="#a"><span class="id" title="definition">a</span></a> := 0. #[ <span class="id" title="var">universes</span>( <span class="id" title="var">template</span>) ]<br/>
2323
<span class="id" title="keyword">Inductive</span> <a id="mysum" class="idref" href="#mysum"><span class="id" title="definition, inductive"><span id="mysum_rect" class="id"><span id="mysum_ind" class="id"><span id="mysum_rec" class="id"><span id="mysum_sind" class="id">mysum</span></span></span></span></span></a> (<a id="A:1" class="idref" href="#A:1"><span class="id" title="binder">A</span></a> <a id="B:2" class="idref" href="#B:2"><span class="id" title="binder">B</span></a>:<span class="id" title="keyword">Type</span>) : <span class="id" title="keyword">Type</span> :=<br/>
24-
&nbsp;&nbsp;| <a id="myinl" class="idref" href="#myinl"><span class="id" title="constructor">myinl</span></a> : <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Corelib.Init.Logic.html#::type_scope:x_'-&gt;'_x"><span class="id" title="notation">→</span></a> <a class="idref" href="Coqdoc.bug11353.html#mysum:3"><span class="id" title="inductive">mysum</span></a> <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a><br/>
25-
&nbsp;&nbsp;| <a id="myinr" class="idref" href="#myinr"><span class="id" title="constructor">myinr</span></a> : <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Corelib.Init.Logic.html#::type_scope:x_'-&gt;'_x"><span class="id" title="notation">→</span></a> <a class="idref" href="Coqdoc.bug11353.html#mysum:3"><span class="id" title="inductive">mysum</span></a> <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a>.<br/>
24+
&nbsp;&nbsp;| <a id="myinl" class="idref" href="#myinl"><span class="id" title="constructor">myinl</span></a> : <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Corelib.Init.Equality.html#::type_scope:x_'-&gt;'_x"><span class="id" title="notation">→</span></a> <a class="idref" href="Coqdoc.bug11353.html#mysum:3"><span class="id" title="inductive">mysum</span></a> <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a><br/>
25+
&nbsp;&nbsp;| <a id="myinr" class="idref" href="#myinr"><span class="id" title="constructor">myinr</span></a> : <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Corelib.Init.Equality.html#::type_scope:x_'-&gt;'_x"><span class="id" title="notation">→</span></a> <a class="idref" href="Coqdoc.bug11353.html#mysum:3"><span class="id" title="inductive">mysum</span></a> <a class="idref" href="Coqdoc.bug11353.html#A:1"><span class="id" title="variable">A</span></a> <a class="idref" href="Coqdoc.bug11353.html#B:2"><span class="id" title="variable">B</span></a>.<br/>
2626

2727
<br/>
2828
#[<span class="id" title="var">local</span>]<span class="id" title="keyword">Definition</span> <a id="b" class="idref" href="#b"><span class="id" title="definition">b</span></a> := 1.<br/>

test-suite/coqdoc/bug11353.tex.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
\coqdocnoindent
2525
\coqdockw{Inductive} \coqdef{Coqdoc.bug11353.mysum}{mysum}{\coqdocinductive{mysum}} (\coqdef{Coqdoc.bug11353.A:1}{A}{\coqdocbinder{A}} \coqdef{Coqdoc.bug11353.B:2}{B}{\coqdocbinder{B}}:\coqdockw{Type}) : \coqdockw{Type} :=\coqdoceol
2626
\coqdocindent{1.00em}
27-
\ensuremath{|} \coqdef{Coqdoc.bug11353.myinl}{myinl}{\coqdocconstructor{myinl}} : \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqexternalref{::type scope:x '->' x}{http://coq.inria.fr/stdlib/Corelib.Init.Logic}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqref{Coqdoc.bug11353.mysum:3}{\coqdocinductive{mysum}} \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}}\coqdoceol
27+
\ensuremath{|} \coqdef{Coqdoc.bug11353.myinl}{myinl}{\coqdocconstructor{myinl}} : \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqexternalref{::type scope:x '->' x}{http://coq.inria.fr/stdlib/Corelib.Init.Equality}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqref{Coqdoc.bug11353.mysum:3}{\coqdocinductive{mysum}} \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}}\coqdoceol
2828
\coqdocindent{1.00em}
29-
\ensuremath{|} \coqdef{Coqdoc.bug11353.myinr}{myinr}{\coqdocconstructor{myinr}} : \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}} \coqexternalref{::type scope:x '->' x}{http://coq.inria.fr/stdlib/Corelib.Init.Logic}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqref{Coqdoc.bug11353.mysum:3}{\coqdocinductive{mysum}} \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}}.\coqdoceol
29+
\ensuremath{|} \coqdef{Coqdoc.bug11353.myinr}{myinr}{\coqdocconstructor{myinr}} : \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}} \coqexternalref{::type scope:x '->' x}{http://coq.inria.fr/stdlib/Corelib.Init.Equality}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqref{Coqdoc.bug11353.mysum:3}{\coqdocinductive{mysum}} \coqref{Coqdoc.bug11353.A:1}{\coqdocvariable{A}} \coqref{Coqdoc.bug11353.B:2}{\coqdocvariable{B}}.\coqdoceol
3030
\coqdocemptyline
3131
\coqdocnoindent
3232
\#[\coqdocvar{local}]\coqdockw{Definition} \coqdef{Coqdoc.bug11353.b}{b}{\coqdocdefinition{b}} := 1.\coqdoceol

0 commit comments

Comments
 (0)