Skip to content
This repository was archived by the owner on Nov 13, 2021. It is now read-only.

Commit 4281112

Browse files
author
herbelin
committed
- Implantation de la suggestion 1873 sur discriminate. Au final,
discriminate/injection/simplify_eq acceptent maintenant un terme comme argument. Les clauses "with" et les variantes "e" sont aussi acceptées. Aussi, discriminate sans argument essaie maintenant toutes les hyps quantifiées (au lieu de traiter seulement les buts t1<>t2). --This line, and those below, will be ignored-- M doc/refman/RefMan-tac.tex M CHANGES M pretyping/evd.ml M pretyping/termops.ml M pretyping/termops.mli M pretyping/clenv.ml M tactics/extratactics.ml4 M tactics/inv.ml M tactics/equality.ml M tactics/tactics.mli M tactics/equality.mli M tactics/tacticals.ml M tactics/eqdecide.ml4 M tactics/tacinterp.ml M tactics/tactics.ml M tactics/extratactics.mli M toplevel/auto_ind_decl.ml M contrib/funind/invfun.ml M test-suite/success/Discriminate.v M test-suite/success/Injection.v M proofs/clenvtac.mli M proofs/clenvtac.ml git-svn-id: svn://scm.gforge.inria.fr/svn/coq/trunk@11159 85f007b7-540e-0410-9357-904b9bb8a0f7
1 parent 9abd4a6 commit 4281112

22 files changed

+409
-176
lines changed

Diff for: CHANGES

+3
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ Tactics
202202
- Slight improvement of the hnf and simpl tactics when applied on
203203
expressions with explicit occurrences of match or fix.
204204
- New tactics "eapply in", "erewrite", "erewrite in".
205+
- New tactics "ediscriminate", "einjection", "esimplify_eq".
206+
- Tactics "discriminate", "injection", "simplify_eq" now support any
207+
term as argument. Clause "with" is also supported.
205208
- Unfoldable references can be given by notation's string rather than by name
206209
in unfold.
207210
- The "with" arguments are now typed using informations from the current goal:

Diff for: contrib/funind/invfun.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,9 @@ let rec reflexivity_with_destruct_cases g =
573573
match kind_of_term (pf_type_of g (mkVar id)) with
574574
| App(eq,[|_;t1;t2|]) when eq_constr eq eq_ind ->
575575
if Equality.discriminable (pf_env g) (project g) t1 t2
576-
then Equality.discr id g
576+
then Equality.discrHyp id g
577577
else if Equality.injectable (pf_env g) (project g) t1 t2
578-
then tclTHENSEQ [Equality.inj [] id;thin [id];intros_with_rewrite] g
578+
then tclTHENSEQ [Equality.injHyp id;thin [id];intros_with_rewrite] g
579579
else tclIDTAC g
580580
| _ -> tclIDTAC g
581581
)

Diff for: doc/refman/RefMan-tac.tex

+102-59
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ \subsection{\tt contradiction
993993
\tacindex{contradict}
994994

995995
This tactic allows to manipulate negated hypothesis and goals. The
996-
name \ident\ should correspond to an hypothesis. With
996+
name \ident\ should correspond to a hypothesis. With
997997
{\tt contradict H}, the current goal and context is transformed in
998998
the following way:
999999
\begin{itemize}
@@ -2395,17 +2395,20 @@ \subsection{\tt compare \term$_1$ \term$_2$
23952395
of \term$_1$ and \term$_2$ must satisfy the same restrictions as in the tactic
23962396
\texttt{decide equality}.
23972397

2398-
\subsection{\tt discriminate {\ident}
2398+
\subsection{\tt discriminate {\term}
23992399
\label{discriminate}
2400-
\tacindex{discriminate}}
2400+
\tacindex{discriminate}
2401+
\tacindex{ediscriminate}}
24012402

2402-
This tactic proves any goal from an absurd hypothesis stating that two
2403+
This tactic proves any goal from an assumption stating that two
24032404
structurally different terms of an inductive set are equal. For
2404-
example, from the hypothesis {\tt (S (S O))=(S O)} we can derive by
2405-
absurdity any proposition. Let {\ident} be a hypothesis of type
2406-
{\tt{\term$_1$} = {\term$_2$}} in the local context, {\term$_1$} and
2405+
example, from {\tt (S (S O))=(S O)} we can derive by absurdity any
2406+
proposition.
2407+
2408+
The argument {\term} is assumed to be a proof of a statement
2409+
of conclusion {\tt{\term$_1$} = {\term$_2$}} with {\term$_1$} and
24072410
{\term$_2$} being elements of an inductive set. To build the proof,
2408-
the tactic traverses the normal forms\footnote{Recall: opaque
2411+
the tactic traverses the normal forms\footnote{Reminder: opaque
24092412
constants will not be expanded by $\delta$ reductions} of
24102413
{\term$_1$} and {\term$_2$} looking for a couple of subterms {\tt u}
24112414
and {\tt w} ({\tt u} subterm of the normal form of {\term$_1$} and
@@ -2414,55 +2417,70 @@ \subsection{\tt discriminate {\ident}
24142417
such a couple of subterms exists, then the proof of the current goal
24152418
is completed, otherwise the tactic fails.
24162419

2417-
\Rem If {\ident} does not denote an hypothesis in the local context
2418-
but refers to an hypothesis quantified in the goal, then the
2419-
latter is first introduced in the local context using
2420-
\texttt{intros until \ident}.
2420+
\Rem The syntax {\tt discriminate {\ident}} can be used to refer to a
2421+
hypothesis quantified in the goal. In this case, the quantified
2422+
hypothesis whose name is {\ident} is first introduced in the local
2423+
context using \texttt{intros until \ident}.
24212424

24222425
\begin{ErrMsgs}
2423-
\item {\ident} \errindex{Not a discriminable equality} \\
2424-
occurs when the type of the specified hypothesis is not an equation.
2426+
\item \errindex{No primitive equality found}
2427+
\item \errindex{Not a discriminable equality}
24252428
\end{ErrMsgs}
24262429

24272430
\begin{Variants}
2428-
\item \texttt{discriminate} \num\\
2429-
This does the same thing as \texttt{intros until \num} then
2430-
\texttt{discriminate \ident} where {\ident} is the identifier for the last
2431-
introduced hypothesis.
2432-
\item {\tt discriminate}\\
2433-
It applies to a goal of the form {\tt
2434-
\verb=~={\term$_1$}={\term$_2$}} and it is equivalent to:
2435-
{\tt unfold not; intro {\ident}}; {\tt discriminate
2436-
{\ident}}.
2431+
\item \texttt{discriminate} \num
2432+
2433+
This does the same thing as \texttt{intros until \num} followed by
2434+
\texttt{discriminate \ident} where {\ident} is the identifier for
2435+
the last introduced hypothesis.
2436+
2437+
\item \texttt{discriminate} {\term} {\tt with} {\bindinglist}
2438+
2439+
This does the same thing as \texttt{discriminate {\term}} but using
2440+
the given bindings to instantiate parameters or hypotheses of {\term}.
2441+
2442+
\item \texttt{ediscriminate} \num\\
2443+
\texttt{ediscriminate} {\term} \zeroone{{\tt with} {\bindinglist}}
2444+
2445+
This works the same as {\tt discriminate} but if the type of {\term},
2446+
or the type of the hypothesis referred to by {\num}, has uninstantiated
2447+
parameters, these parameters are left as existential variables.
2448+
2449+
\item \texttt{discriminate}
2450+
2451+
This looks for a quantified or not quantified hypothesis {\ident} on
2452+
which {\tt discriminate {\ident}} is applicable.
24372453

24382454
\begin{ErrMsgs}
24392455
\item \errindex{No discriminable equalities} \\
24402456
occurs when the goal does not verify the expected preconditions.
24412457
\end{ErrMsgs}
24422458
\end{Variants}
24432459

2444-
\subsection{\tt injection {\ident}
2460+
\subsection{\tt injection {\term}
24452461
\label{injection}
2446-
\tacindex{injection}}
2462+
\tacindex{injection}
2463+
\tacindex{einjection}}
24472464

24482465
The {\tt injection} tactic is based on the fact that constructors of
24492466
inductive sets are injections. That means that if $c$ is a constructor
24502467
of an inductive set, and if $(c~\vec{t_1})$ and $(c~\vec{t_2})$ are two
24512468
terms that are equal then $~\vec{t_1}$ and $~\vec{t_2}$ are equal
24522469
too.
24532470

2454-
If {\ident} is an hypothesis of type {\tt {\term$_1$} = {\term$_2$}},
2455-
then {\tt injection} behaves as applying injection as deep as possible to
2471+
If {\term} is a proof of a statement of conclusion
2472+
{\tt {\term$_1$} = {\term$_2$}},
2473+
then {\tt injection} applies injectivity as deep as possible to
24562474
derive the equality of all the subterms of {\term$_1$} and {\term$_2$}
2457-
placed in the same positions. For example, from the hypothesis {\tt (S
2475+
placed in the same positions. For example, from {\tt (S
24582476
(S n))=(S (S (S m))} we may derive {\tt n=(S m)}. To use this
24592477
tactic {\term$_1$} and {\term$_2$} should be elements of an inductive
24602478
set and they should be neither explicitly equal, nor structurally
24612479
different. We mean by this that, if {\tt n$_1$} and {\tt n$_2$} are
24622480
their respective normal forms, then:
24632481
\begin{itemize}
24642482
\item {\tt n$_1$} and {\tt n$_2$} should not be syntactically equal,
2465-
\item there must not exist any couple of subterms {\tt u} and {\tt w},
2483+
\item there must not exist any pair of subterms {\tt u} and {\tt w},
24662484
{\tt u} subterm of {\tt n$_1$} and {\tt w} subterm of {\tt n$_2$} ,
24672485
placed in the same positions and having different constructors as
24682486
head symbols.
@@ -2501,69 +2519,94 @@ \subsection{\tt injection {\ident}
25012519
To define such an equality, you have to use the {\tt Scheme} command
25022520
(see \ref{Scheme}).
25032521

2504-
\Rem If {\ident} does not denote an hypothesis in the local context
2505-
but refers to an hypothesis quantified in the goal, then the
2506-
latter is first introduced in the local context using
2507-
\texttt{intros until \ident}.
2522+
\Rem If some quantified hypothesis of the goal is named {\ident}, then
2523+
{\tt injection {\ident}} first introduces the hypothesis in the local
2524+
context using \texttt{intros until \ident}.
25082525

25092526
\begin{ErrMsgs}
2510-
\item {\ident} \errindex{is not a projectable equality}
2511-
occurs when the type of
2512-
the hypothesis $id$ does not verify the preconditions.
2513-
\item \errindex{Not an equation} occurs when the type of the
2514-
hypothesis $id$ is not an equation.
2527+
\item \errindex{Not a projectable equality but a discriminable one}
2528+
\item \errindex{Nothing to do, it is an equality between convertible terms}
2529+
\item \errindex{Not a primitive equality}
25152530
\end{ErrMsgs}
25162531

25172532
\begin{Variants}
25182533
\item \texttt{injection} \num{}
25192534

2520-
This does the same thing as \texttt{intros until \num} then
2535+
This does the same thing as \texttt{intros until \num} followed by
25212536
\texttt{injection \ident} where {\ident} is the identifier for the last
25222537
introduced hypothesis.
25232538

2524-
\item{\tt injection}\tacindex{injection}
2539+
\item \texttt{injection} \term{} {\tt with} {\bindinglist}
2540+
2541+
This does the same as \texttt{injection {\term}} but using
2542+
the given bindings to instantiate parameters or hypotheses of {\term}.
2543+
2544+
\item \texttt{einjection} \num\\
2545+
\texttt{einjection} \term{} \zeroone{{\tt with} {\bindinglist}}
2546+
2547+
This works the same as {\tt injection} but if the type of {\term},
2548+
or the type of the hypothesis referred to by {\num}, has uninstantiated
2549+
parameters, these parameters are left as existential variables.
2550+
2551+
\item{\tt injection}
25252552

25262553
If the current goal is of the form {\term$_1$} {\tt <>} {\term$_2$},
2527-
the tactic computes the head normal form of the goal and then
2528-
behaves as the sequence: {\tt unfold not; intro {\ident}; injection
2529-
{\ident}}.
2554+
this behaves as {\tt intro {\ident}; injection {\ident}}.
25302555

25312556
\ErrMsg \errindex{goal does not satisfy the expected preconditions}
25322557

2533-
\item \texttt{injection} \ident{} \texttt{as} \nelist{\intropattern}{}\\
2558+
\item \texttt{injection} \term{} \zeroone{{\tt with} {\bindinglist}} \texttt{as} \nelist{\intropattern}{}\\
25342559
\texttt{injection} \num{} \texttt{as} {\intropattern} {\ldots} {\intropattern}\\
25352560
\texttt{injection} \texttt{as} {\intropattern} {\ldots} {\intropattern}\\
2561+
\texttt{einjection} \term{} \zeroone{{\tt with} {\bindinglist}} \texttt{as} \nelist{\intropattern}{}\\
2562+
\texttt{einjection} \num{} \texttt{as} {\intropattern} {\ldots} {\intropattern}\\
2563+
\texttt{einjection} \texttt{as} {\intropattern} {\ldots} {\intropattern}\\
25362564
\tacindex{injection \ldots{} as}
25372565

2538-
These variants apply \texttt{intros} \nelist{\intropattern}{} after the call to \texttt{injection}.
2566+
These variants apply \texttt{intros} \nelist{\intropattern}{} after
2567+
the call to \texttt{injection} or \texttt{einjection}.
25392568

25402569
\end{Variants}
25412570

2542-
\subsection{\tt simplify\_eq {\ident}
2571+
\subsection{\tt simplify\_eq {\term}
25432572
\tacindex{simplify\_eq}
2573+
\tacindex{esimplify\_eq}
25442574
\label{simplify-eq}}
25452575

2546-
Let {\ident} be the name of an hypothesis of type {\tt
2547-
{\term$_1$}={\term$_2$}} in the local context. If {\term$_1$} and
2576+
Let {\term} be the proof of a statement of conclusion {\tt
2577+
{\term$_1$}={\term$_2$}}. If {\term$_1$} and
25482578
{\term$_2$} are structurally different (in the sense described for the
25492579
tactic {\tt discriminate}), then the tactic {\tt simplify\_eq} behaves as {\tt
2550-
discriminate {\ident}} otherwise it behaves as {\tt injection
2551-
{\ident}}.
2580+
discriminate {\term}}, otherwise it behaves as {\tt injection
2581+
{\term}}.
25522582

2553-
\Rem If {\ident} does not denote an hypothesis in the local context
2554-
but refers to an hypothesis quantified in the goal, then the
2555-
latter is first introduced in the local context using
2556-
\texttt{intros until \ident}.
2583+
\Rem If some quantified hypothesis of the goal is named {\ident}, then
2584+
{\tt simplify\_eq {\ident}} first introduces the hypothesis in the local
2585+
context using \texttt{intros until \ident}.
25572586

25582587
\begin{Variants}
25592588
\item \texttt{simplify\_eq} \num
25602589

25612590
This does the same thing as \texttt{intros until \num} then
25622591
\texttt{simplify\_eq \ident} where {\ident} is the identifier for the last
25632592
introduced hypothesis.
2593+
2594+
\item \texttt{simplify\_eq} \term{} {\tt with} {\bindinglist}
2595+
2596+
This does the same as \texttt{simplify\_eq {\term}} but using
2597+
the given bindings to instantiate parameters or hypotheses of {\term}.
2598+
2599+
\item \texttt{esimplify\_eq} \num\\
2600+
\texttt{esimplify\_eq} \term{} \zeroone{{\tt with} {\bindinglist}}
2601+
2602+
This works the same as {\tt simplify\_eq} but if the type of {\term},
2603+
or the type of the hypothesis referred to by {\num}, has uninstantiated
2604+
parameters, these parameters are left as existential variables.
2605+
25642606
\item{\tt simplify\_eq}
2565-
If the current goal has form $\verb=~=t_1=t_2$, then this tactic does
2566-
\texttt{hnf; intro {\ident}; simplify\_eq {\ident}}.
2607+
2608+
If the current goal has form $t_1\verb=<>=t_2$, it behaves as
2609+
\texttt{intro {\ident}; simplify\_eq {\ident}}.
25672610
\end{Variants}
25682611

25692612
\subsection{\tt dependent rewrite -> {\ident}
@@ -2599,8 +2642,8 @@ \subsection{\tt inversion {\ident}
25992642
conditions that should hold for the instance $(I~\vec{t})$ to be
26002643
proved by $c_i$.
26012644

2602-
\Rem If {\ident} does not denote an hypothesis in the local context
2603-
but refers to an hypothesis quantified in the goal, then the
2645+
\Rem If {\ident} does not denote a hypothesis in the local context
2646+
but refers to a hypothesis quantified in the goal, then the
26042647
latter is first introduced in the local context using
26052648
\texttt{intros until \ident}.
26062649

@@ -3242,7 +3285,7 @@ \subsection{\tt congruence
32423285
(see \ref{injection} and \ref{discriminate}).
32433286
If the goal is a non-quantified equality, {\tt congruence} tries to
32443287
prove it with non-quantified equalities in the context. Otherwise it
3245-
tries to infer a discriminable equality from those in the context. Alternatively, congruence tries to prove that an hypothesis is equal to the goal or to the negation of another hypothesis.
3288+
tries to infer a discriminable equality from those in the context. Alternatively, congruence tries to prove that a hypothesis is equal to the goal or to the negation of another hypothesis.
32463289

32473290
{\tt congruence} is also able to take advantage of hypotheses stating quantified equalities, you have to provide a bound for the number of extra equalities generated that way. Please note that one of the members of the equality must contain all the quantified variables in order for {\tt congruence} to match against it.
32483291

Diff for: pretyping/clenv.ml

+13-2
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,24 @@ let dependent_metas clenv mvs conclmetas =
222222
Metaset.union deps (clenv_metavars clenv.evd mv))
223223
mvs conclmetas
224224

225+
let duplicated_metas c =
226+
let rec collrec (one,more as acc) c =
227+
match kind_of_term c with
228+
| Meta mv -> if List.mem mv one then (one,mv::more) else (mv::one,more)
229+
| _ -> fold_constr collrec acc c
230+
in
231+
snd (collrec ([],[]) c)
232+
225233
let clenv_dependent hyps_only clenv =
226234
let mvs = undefined_metas clenv.evd in
227235
let ctyp_mvs = (mk_freelisted (clenv_type clenv)).freemetas in
228236
let deps = dependent_metas clenv mvs ctyp_mvs in
237+
let nonlinear = duplicated_metas (clenv_value clenv) in
238+
(* Make the assumption that duplicated metas have internal dependencies *)
229239
List.filter
230-
(fun mv -> Metaset.mem mv deps &&
231-
not (hyps_only && Metaset.mem mv ctyp_mvs))
240+
(fun mv -> (Metaset.mem mv deps &&
241+
not (hyps_only && Metaset.mem mv ctyp_mvs))
242+
or List.mem mv nonlinear)
232243
mvs
233244

234245
let clenv_missing ce = clenv_dependent true ce

Diff for: pretyping/evd.ml

+16-2
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,20 @@ type unsolvability_explanation = SeveralInstancesFound of int
643643
(**********************************************************)
644644
(* Pretty-printing *)
645645

646+
let pr_instance_status (sc,typ) =
647+
begin match sc with
648+
| IsSubType -> str " [or a subtype of it]"
649+
| IsSuperType -> str " [or a supertype of it]"
650+
| ConvUpToEta 0 -> mt ()
651+
| UserGiven -> mt ()
652+
| ConvUpToEta n -> str" [or an eta-expansion up to " ++ int n ++ str" of it]"
653+
end ++
654+
begin match typ with
655+
| CoerceToType -> str " [up to coercion]"
656+
| TypeNotProcessed -> mt ()
657+
| TypeProcessed -> str " [type is checked]"
658+
end
659+
646660
let pr_meta_map mmap =
647661
let pr_name = function
648662
Name id -> str"[" ++ pr_id id ++ str"]"
@@ -652,10 +666,10 @@ let pr_meta_map mmap =
652666
hov 0
653667
(pr_meta mv ++ pr_name na ++ str " : " ++
654668
print_constr b.rebus ++ fnl ())
655-
| (mv,Clval(na,(b,_),_)) ->
669+
| (mv,Clval(na,(b,s),_)) ->
656670
hov 0
657671
(pr_meta mv ++ pr_name na ++ str " := " ++
658-
print_constr b.rebus ++ fnl ())
672+
print_constr b.rebus ++ spc () ++ pr_instance_status s ++ fnl ())
659673
in
660674
prlist pr_meta_binding (metamap_to_list mmap)
661675

Diff for: pretyping/termops.ml

+5
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ let rec strip_head_cast c = match kind_of_term c with
275275
| Cast (c,_,_) -> strip_head_cast c
276276
| _ -> c
277277

278+
(* Get the last arg of an application *)
279+
let last_arg c = match kind_of_term c with
280+
| App (f,cl) -> array_last cl
281+
| _ -> anomaly "last_arg"
282+
278283
(* [map_constr_with_named_binders g f l c] maps [f l] on the immediate
279284
subterms of [c]; it carries an extra data [l] (typically a name
280285
list) which is processed by [g na] (which typically cons [na] to

Diff for: pretyping/termops.mli

+3
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ val mkLambda_or_LetIn_name : env -> constr -> rel_declaration -> constr
185185
val it_mkProd_or_LetIn_name : env -> types -> rel_context -> types
186186
val it_mkLambda_or_LetIn_name : env -> constr -> rel_context -> constr
187187

188+
(* Get the last arg of a constr intended to be nn application *)
189+
val last_arg : constr -> constr
190+
188191
(* name contexts *)
189192
type names_context = name list
190193
val add_name : name -> names_context -> names_context

Diff for: proofs/clenvtac.ml

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ let clenv_cast_meta clenv =
6060
in
6161
crec
6262

63+
let clenv_value_cast_meta clenv =
64+
clenv_cast_meta clenv (clenv_value clenv)
65+
6366
let clenv_pose_dependent_evars with_evars clenv =
6467
let dep_mvs = clenv_dependent false clenv in
6568
if dep_mvs <> [] & not with_evars then

Diff for: proofs/clenvtac.mli

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ val res_pf : clausenv -> ?with_evars:evars_flag -> ?allow_K:bool -> ?flags:unify
2727
val elim_res_pf_THEN_i : clausenv -> (clausenv -> tactic array) -> tactic
2828

2929
val clenv_pose_dependent_evars : evars_flag -> clausenv -> clausenv
30+
val clenv_value_cast_meta : clausenv -> constr
3031

3132
(* Compatibility, use res_pf ?with_evars:true instead *)
3233
val e_res_pf : clausenv -> tactic

0 commit comments

Comments
 (0)