V8.2 © INRIA 2008-2011
V8.3 © INRIA 2010-2011
V8.4 © INRIA 2012-2014
- V8.5 © INRIA 2015
+ V8.5 © INRIA 2015-2016
This research was partly supported by IST
diff --git a/doc/common/styles/html/simple/cover.html b/doc/common/styles/html/simple/cover.html
index 1641a1ed37..328bd68daf 100644
--- a/doc/common/styles/html/simple/cover.html
+++ b/doc/common/styles/html/simple/cover.html
@@ -38,7 +38,7 @@
V8.2 © INRIA 2008-2011
V8.3 © INRIA 2010-2011
V8.4 © INRIA 2012-2014
- V8.5 © INRIA 2015
+ V8.5 © INRIA 2015-2016
This research was partly supported by IST
diff --git a/doc/common/title.tex b/doc/common/title.tex
index 4716c3156a..0e072b6b65 100644
--- a/doc/common/title.tex
+++ b/doc/common/title.tex
@@ -45,7 +45,7 @@ V\coqversion, \today
%END LATEX
\copyright INRIA 1999-2004 ({\Coq} versions 7.x)
-\copyright INRIA 2004-2015 ({\Coq} versions 8.x)
+\copyright INRIA 2004-2016 ({\Coq} versions 8.x)
#3
\end{flushleft}
diff --git a/grammar/argextend.ml4 b/grammar/argextend.ml4
index fe0959ddbc..8def9537cb 100644
--- a/grammar/argextend.ml4
+++ b/grammar/argextend.ml4
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* CFBundleGetInfoString
Coq_vVERSION
NSHumanReadableCopyright
- Copyright 1999-2015, The Coq Development Team INRIA - CNRS - LIX - LRI - PPS
+ Copyright 1999-2016, The Coq Development Team INRIA - CNRS - LIX - LRI - PPS
CFBundleHelpBookFolder
share/doc/coq/html/
CFAppleHelpAnchor
diff --git a/ide/config_lexer.mll b/ide/config_lexer.mll
index 3671535680..ac9cc57bc0 100644
--- a/ide/config_lexer.mll
+++ b/ide/config_lexer.mll
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* .
- reflexivity.
- exact I.
Qed.
+
+(* Fixing a bug when destructing a type with let-ins in the constructor *)
+
+Inductive I := C : let x:=1 in x=1 -> I.
+Goal I -> True.
+intros [x H]. (* Was failing in 8.5 *)
+Abort.
--
cgit v1.2.3
From 3ad653b53ccbf2feb7807b4618dc9a455e9df877 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Wed, 20 Jan 2016 22:41:43 +0100
Subject: Code simplification in elim.ml.
---
tactics/elim.ml | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/tactics/elim.ml b/tactics/elim.ml
index 182240b554..0954f3ddf2 100644
--- a/tactics/elim.ml
+++ b/tactics/elim.ml
@@ -17,28 +17,19 @@ open Tacticals.New
open Tactics
open Proofview.Notations
+(* Supposed to be called without as clause *)
let introElimAssumsThen tac ba =
- let nassums =
- List.fold_left
- (fun acc b -> if b then acc+2 else acc+1)
- 0 ba.Tacticals.branchsign
- in
- let introElimAssums = tclDO nassums intro in
+ assert (ba.Tacticals.branchnames == []);
+ let introElimAssums = tclDO ba.Tacticals.nassums intro in
(tclTHEN introElimAssums (elim_on_ba tac ba))
+(* Supposed to be called with a non-recursive scheme *)
let introCaseAssumsThen tac ba =
- let case_thin_sign =
- List.flatten
- (List.map (function b -> if b then [false;true] else [false])
- ba.Tacticals.branchsign)
- in
- let n1 = List.length case_thin_sign in
+ let n1 = List.length ba.Tacticals.branchsign in
let n2 = List.length ba.Tacticals.branchnames in
let (l1,l2),l3 =
if n1 < n2 then List.chop n1 ba.Tacticals.branchnames, []
- else
- (ba.Tacticals.branchnames, []),
- if n1 > n2 then snd (List.chop n2 case_thin_sign) else [] in
+ else (ba.Tacticals.branchnames, []), List.make (n1-n2) false in
let introCaseAssums =
tclTHEN (intro_patterns l1) (intros_clearing l3) in
(tclTHEN introCaseAssums (case_on_ba (tac l2) ba))
--
cgit v1.2.3
From 4b075af747f65bcd73ff1c78417cf77edf6fbd76 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Thu, 21 Jan 2016 01:13:56 +0100
Subject: Fixing some problems with double induction.
Basically, the hypotheses were treated in an incorrect order, with a
hack for sometimes put them again in the right order, resulting in
failures and redundant hypotheses.
Status unclear, because this new version is incompatible except in
simple cases like a double induction on two "nat".
Fixing the bug incidentally simplify the code, relying on the
deprecation since 8.4 to allow not to ensure a compatibility (beyond
the simple situation of a double induction on simple datatypes).
See file induct.v for effect of changes.
---
CHANGES | 4 ++++
tactics/elim.ml | 3 +--
tactics/tacticals.ml | 48 +++++----------------------------------------
test-suite/success/induct.v | 43 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 53 insertions(+), 45 deletions(-)
diff --git a/CHANGES b/CHANGES
index a9fbfe29d0..cda16d3804 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@ Tactics
- Flag "Bracketing Last Introduction Pattern" is now on by default.
- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
tactical w.r.t. variables appearing in the body of the proof.
+- Serious bugs are fixed in tactic "double induction" (source of
+ incompatibilities as soon as the inductive types have dependencies in
+ the type of their constructors; "double induction" remains however
+ deprecated).
Program
diff --git a/tactics/elim.ml b/tactics/elim.ml
index 0954f3ddf2..99236e7707 100644
--- a/tactics/elim.ml
+++ b/tactics/elim.ml
@@ -145,8 +145,7 @@ let induction_trailer abs_i abs_j bargs =
in
let ids = List.rev (ids_of_named_context hyps) in
(tclTHENLIST
- [bring_hyps hyps; tclTRY (Proofview.V82.tactic (clear ids));
- simple_elimination (mkVar id)])
+ [revert ids; simple_elimination (mkVar id)])
end }
))
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index 750ec8fb1e..061c05b9b2 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -239,52 +239,14 @@ let gl_make_case_nodep ind gl =
(Sigma.to_evar_map sigma, r)
let make_elim_branch_assumptions ba gl =
- let rec makerec (assums,cargs,constargs,recargs,indargs) lb lc =
- match lb,lc with
- | ([], _) ->
- { ba = ba;
- assums = assums}
- | ((true::tl), ((idrec,_,_ as recarg)::(idind,_,_ as indarg)::idtl)) ->
- makerec (recarg::indarg::assums,
- idrec::cargs,
- idrec::recargs,
- constargs,
- idind::indargs) tl idtl
- | ((false::tl), ((id,_,_ as constarg)::idtl)) ->
- makerec (constarg::assums,
- id::cargs,
- id::constargs,
- recargs,
- indargs) tl idtl
- | (_, _) -> anomaly (Pp.str "make_elim_branch_assumptions")
- in
- makerec ([],[],[],[],[]) ba.branchsign
- (try List.firstn ba.nassums (pf_hyps gl)
- with Failure _ -> anomaly (Pp.str "make_elim_branch_assumptions"))
+ let assums =
+ try List.rev (List.firstn ba.nassums (pf_hyps gl))
+ with Failure _ -> anomaly (Pp.str "make_elim_branch_assumptions") in
+ { ba = ba; assums = assums }
let elim_on_ba tac ba gl = tac (make_elim_branch_assumptions ba gl) gl
-let make_case_branch_assumptions ba gl =
- let rec makerec (assums,cargs,constargs,recargs) p_0 p_1 =
- match p_0,p_1 with
- | ([], _) ->
- { ba = ba;
- assums = assums}
- | ((true::tl), ((idrec,_,_ as recarg)::idtl)) ->
- makerec (recarg::assums,
- idrec::cargs,
- idrec::recargs,
- constargs) tl idtl
- | ((false::tl), ((id,_,_ as constarg)::idtl)) ->
- makerec (constarg::assums,
- id::cargs,
- recargs,
- id::constargs) tl idtl
- | (_, _) -> anomaly (Pp.str "make_case_branch_assumptions")
- in
- makerec ([],[],[],[]) ba.branchsign
- (try List.firstn ba.nassums (pf_hyps gl)
- with Failure _ -> anomaly (Pp.str "make_case_branch_assumptions"))
+let make_case_branch_assumptions = make_elim_branch_assumptions
let case_on_ba tac ba gl = tac (make_case_branch_assumptions ba gl) gl
diff --git a/test-suite/success/induct.v b/test-suite/success/induct.v
index 7ae60d9892..9413b8dae9 100644
--- a/test-suite/success/induct.v
+++ b/test-suite/success/induct.v
@@ -151,3 +151,46 @@ intros x H1 H.
induction H.
change (0 = z -> True) in IHrepr''.
Abort.
+
+(* Test double induction *)
+
+(* This was failing in 8.5 and before because of a bug in the order of
+ hypotheses *)
+
+Inductive I2 : Type :=
+ C2 : forall x:nat, x=x -> I2.
+Goal forall a b:I2, a = b.
+double induction a b.
+Abort.
+
+(* This was leaving useless hypotheses in 8.5 and before because of
+ the same bug. This is a change of compatibility. *)
+
+Inductive I3 : Prop :=
+ C3 : forall x:nat, x=x -> I3.
+Goal forall a b:I3, a = b.
+double induction a b.
+Fail clear H. (* H should have been erased *)
+Abort.
+
+(* This one had quantification in reverse order in 8.5 and before *)
+(* This is a change of compatibility. *)
+
+Goal forall m n, le m n -> le n m -> n=m.
+intros m n. double induction 1 2.
+3:destruct 1. (* Should be "S m0 <= m0" *)
+Abort.
+
+(* Idem *)
+
+Goal forall m n p q, le m n -> le p q -> n+p=m+q.
+intros *. double induction 1 2.
+3:clear H2. (* H2 should have been erased *)
+Abort.
+
+(* This is unchanged *)
+
+Goal forall m n:nat, n=m.
+double induction m n.
+Abort.
+
--
cgit v1.2.3
From 9c2662eecc398f38be3b6280a8f760cc439bc31c Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Thu, 21 Jan 2016 01:43:10 +0100
Subject: Stronger invariants on the use of the introduction pattern
(pat1,...,patn).
The length of the pattern should now be exactly the number of
assumptions and definitions introduced by the destruction or induction,
including the induction hypotheses in case of an induction.
Like for pattern-matching, the local definitions in the argument of
the constructor can be skipped in which case a name is automatically
created for these.
---
CHANGES | 3 +
intf/misctypes.mli | 5 +-
lib/cList.ml | 7 ++
lib/cList.mli | 3 +
parsing/g_tactic.ml4 | 15 ++--
printing/miscprint.ml | 4 +-
tactics/inv.ml | 8 +-
tactics/tacintern.ml | 7 +-
tactics/tacinterp.ml | 13 +++-
tactics/tacsubst.ml | 8 +-
tactics/tacticals.ml | 89 +++++++++++++++-------
tactics/tacticals.mli | 18 +++--
tactics/tactics.ml | 41 +++++-----
test-suite/success/intros.v | 23 ++++++
theories/Sorting/Permutation.v | 2 +-
.../Wellfounded/Lexicographic_Exponentiation.v | 6 +-
toplevel/auto_ind_decl.ml | 6 +-
17 files changed, 177 insertions(+), 81 deletions(-)
diff --git a/CHANGES b/CHANGES
index cda16d3804..e80a3b4547 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,9 @@ Tactics
incompatibilities as soon as the inductive types have dependencies in
the type of their constructors; "double induction" remains however
deprecated).
+- In introduction patterns of the form (pat1,...,patn), n should match
+ the exact number of hypotheses introduced (except for local definitions
+ for which pattern can be omitted, as in regular pattern-matching).
Program
diff --git a/intf/misctypes.mli b/intf/misctypes.mli
index 65c7dccf2a..889dc54448 100644
--- a/intf/misctypes.mli
+++ b/intf/misctypes.mli
@@ -16,6 +16,8 @@ type patvar = Id.t
(** Introduction patterns *)
+type tuple_flag = bool (* tells pattern list should be list of fixed length *)
+
type 'constr intro_pattern_expr =
| IntroForthcoming of bool
| IntroNaming of intro_pattern_naming_expr
@@ -31,7 +33,8 @@ and 'constr intro_pattern_action_expr =
| IntroApplyOn of 'constr * (Loc.t * 'constr intro_pattern_expr)
| IntroRewrite of bool
and 'constr or_and_intro_pattern_expr =
- (Loc.t * 'constr intro_pattern_expr) list list
+ | IntroOrPattern of (Loc.t * 'constr intro_pattern_expr) list list
+ | IntroAndPattern of (Loc.t * 'constr intro_pattern_expr) list
(** Move destination for hypothesis *)
diff --git a/lib/cList.ml b/lib/cList.ml
index bd3e09b5b2..ba592d13f3 100644
--- a/lib/cList.ml
+++ b/lib/cList.ml
@@ -48,6 +48,7 @@ sig
val filteri :
(int -> 'a -> bool) -> 'a list -> 'a list
val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ val extend : bool list -> 'a -> 'a list -> 'a list
val count : ('a -> bool) -> 'a list -> int
val index : 'a eq -> 'a -> 'a list -> int
val index0 : 'a eq -> 'a -> 'a list -> int
@@ -376,6 +377,12 @@ let rec smartfilter f l = match l with
else h :: tl'
else tl'
+let rec extend l a l' = match l,l' with
+ | true::l, b::l' -> b :: extend l a l'
+ | false::l, l' -> a :: extend l a l'
+ | [], [] -> []
+ | _ -> invalid_arg "extend"
+
let count f l =
let rec aux acc = function
| [] -> acc
diff --git a/lib/cList.mli b/lib/cList.mli
index 1487f67a37..9c7b815c15 100644
--- a/lib/cList.mli
+++ b/lib/cList.mli
@@ -94,6 +94,9 @@ sig
(** [smartfilter f [a1...an] = List.filter f [a1...an]] but if for all i
[f ai = true], then [smartfilter f l == l] *)
+ val extend : bool list -> 'a -> 'a list -> 'a list
+(** [extend l a [a1..an]] assumes that the number of [true] in [l] is [n];
+ it extends [a1..an] by inserting [a] at the position of [false] in [l] *)
val count : ('a -> bool) -> 'a list -> int
val index : 'a eq -> 'a -> 'a list -> int
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index a7b05dd5eb..77d74892d0 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -285,18 +285,19 @@ GEXTEND Gram
[ [ l = LIST1 nonsimple_intropattern -> l ]]
;
or_and_intropattern:
- [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> tc
- | "()" -> [[]]
- | "("; si = simple_intropattern; ")" -> [[si]]
+ [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> IntroOrPattern tc
+ | "()" -> IntroAndPattern []
+ | "("; si = simple_intropattern; ")" -> IntroAndPattern [si]
| "("; si = simple_intropattern; ",";
- tc = LIST1 simple_intropattern SEP "," ; ")" -> [si::tc]
+ tc = LIST1 simple_intropattern SEP "," ; ")" ->
+ IntroAndPattern (si::tc)
| "("; si = simple_intropattern; "&";
tc = LIST1 simple_intropattern SEP "&" ; ")" ->
(* (A & B & C) is translated into (A,(B,C)) *)
let rec pairify = function
- | ([]|[_]|[_;_]) as l -> [l]
- | t::q -> [[t;(loc_of_ne_list q,IntroAction (IntroOrAndPattern (pairify q)))]]
- in pairify (si::tc) ] ]
+ | ([]|[_]|[_;_]) as l -> l
+ | t::q -> [t;(loc_of_ne_list q,IntroAction (IntroOrAndPattern (IntroAndPattern (pairify q))))]
+ in IntroAndPattern (pairify (si::tc)) ] ]
;
equality_intropattern:
[ [ "->" -> IntroRewrite true
diff --git a/printing/miscprint.ml b/printing/miscprint.ml
index d09af6d2ac..be3e62574a 100644
--- a/printing/miscprint.ml
+++ b/printing/miscprint.ml
@@ -33,9 +33,9 @@ and pr_intro_pattern_action prc = function
| IntroRewrite false -> str "<-"
and pr_or_and_intro_pattern prc = function
- | [pl] ->
+ | IntroAndPattern pl ->
str "(" ++ hv 0 (prlist_with_sep pr_comma (pr_intro_pattern prc) pl) ++ str ")"
- | pll ->
+ | IntroOrPattern pll ->
str "[" ++
hv 0 (prlist_with_sep pr_bar (prlist_with_sep spc (pr_intro_pattern prc)) pll)
++ str "]"
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 3574990f6c..01124e867c 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -296,17 +296,17 @@ let get_names (allow_conj,issimple) (loc, pat as x) = match pat with
error "Discarding pattern not allowed for inversion equations."
| IntroAction (IntroRewrite _) ->
error "Rewriting pattern not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern [[]]) when allow_conj -> (None, [])
- | IntroAction (IntroOrAndPattern [(_,IntroNaming (IntroIdentifier id)) :: _ as l])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern [])) when allow_conj -> (None, [])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l)))
when allow_conj -> (Some id,l)
- | IntroAction (IntroOrAndPattern [_]) ->
+ | IntroAction (IntroOrAndPattern (IntroAndPattern _)) ->
if issimple then
error"Conjunctive patterns not allowed for simple inversion equations."
else
error"Nested conjunctive patterns not allowed for inversion equations."
| IntroAction (IntroInjection l) ->
error "Injection patterns not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern l) ->
+ | IntroAction (IntroOrAndPattern (IntroOrPattern _)) ->
error "Disjunctive patterns not allowed for inversion equations."
| IntroAction (IntroApplyOn (c,pat)) ->
error "Apply patterns not allowed for inversion equations."
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index 14e0fed31d..f92213da81 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -258,8 +258,11 @@ and intern_intro_pattern_action lf ist = function
| IntroApplyOn (c,pat) ->
IntroApplyOn (intern_constr ist c, intern_intro_pattern lf ist pat)
-and intern_or_and_intro_pattern lf ist =
- List.map (List.map (intern_intro_pattern lf ist))
+and intern_or_and_intro_pattern lf ist = function
+ | IntroAndPattern l ->
+ IntroAndPattern (List.map (intern_intro_pattern lf ist) l)
+ | IntroOrPattern ll ->
+ IntroOrPattern (List.map (List.map (intern_intro_pattern lf ist)) ll)
let intern_or_and_intro_pattern_loc lf ist = function
| ArgVar (_,id) as x ->
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 8db91c07f6..a6991691fb 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -511,7 +511,9 @@ let extract_ltac_constr_values ist env =
(* Extract the identifier list from lfun: join all branches (what to do else?)*)
let rec intropattern_ids (loc,pat) = match pat with
| IntroNaming (IntroIdentifier id) -> [id]
- | IntroAction (IntroOrAndPattern ll) ->
+ | IntroAction (IntroOrAndPattern (IntroAndPattern l)) ->
+ List.flatten (List.map intropattern_ids l)
+ | IntroAction (IntroOrAndPattern (IntroOrPattern ll)) ->
List.flatten (List.map intropattern_ids (List.flatten ll))
| IntroAction (IntroInjection l) ->
List.flatten (List.map intropattern_ids l)
@@ -940,8 +942,13 @@ and interp_intro_pattern_action ist env sigma = function
sigma, IntroApplyOn (c,ipat)
| IntroWildcard | IntroRewrite _ as x -> sigma, x
-and interp_or_and_intro_pattern ist env sigma =
- List.fold_map (interp_intro_pattern_list_as_list ist env) sigma
+and interp_or_and_intro_pattern ist env sigma = function
+ | IntroAndPattern l ->
+ let sigma, l = List.fold_map (interp_intro_pattern ist env) sigma l in
+ sigma, IntroAndPattern l
+ | IntroOrPattern ll ->
+ let sigma, ll = List.fold_map (interp_intro_pattern_list_as_list ist env) sigma ll in
+ sigma, IntroOrPattern ll
and interp_intro_pattern_list_as_list ist env sigma = function
| [loc,IntroNaming (IntroIdentifier id)] as l ->
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index c74f6093a2..e09360a6a6 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -54,10 +54,16 @@ and subst_intro_pattern_action subst = function
| IntroApplyOn (t,pat) ->
IntroApplyOn (subst_glob_constr subst t,subst_intro_pattern subst pat)
| IntroOrAndPattern l ->
- IntroOrAndPattern (List.map (List.map (subst_intro_pattern subst)) l)
+ IntroOrAndPattern (subst_intro_or_and_pattern subst l)
| IntroInjection l -> IntroInjection (List.map (subst_intro_pattern subst) l)
| IntroWildcard | IntroRewrite _ as x -> x
+and subst_intro_or_and_pattern subst = function
+ | IntroAndPattern l ->
+ IntroAndPattern (List.map (subst_intro_pattern subst) l)
+ | IntroOrPattern ll ->
+ IntroOrPattern (List.map (List.map (subst_intro_pattern subst)) ll)
+
let subst_induction_arg subst = function
| clear,ElimOnConstr c -> clear,ElimOnConstr (subst_glob_with_bindings subst c)
| clear,ElimOnAnonHyp n as x -> x
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index 061c05b9b2..4029d1fcca 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -147,51 +147,85 @@ type branch_args = {
largs : constr list; (* its arguments *)
branchnum : int; (* the branch number *)
pred : constr; (* the predicate we used *)
- nassums : int; (* the number of assumptions to be introduced *)
+ nassums : int; (* number of assumptions/letin to be introduced *)
branchsign : bool list; (* the signature of the branch.
- true=recursive argument, false=constant *)
+ true=assumption, false=let-in *)
branchnames : Tacexpr.intro_patterns}
type branch_assumptions = {
ba : branch_args; (* the branch args *)
assums : Context.Named.t} (* the list of assumptions introduced *)
+open Misctypes
+
let fix_empty_or_and_pattern nv l =
(* 1- The syntax does not distinguish between "[ ]" for one clause with no
names and "[ ]" for no clause at all *)
(* 2- More generally, we admit "[ ]" for any disjunctive pattern of
arbitrary length *)
match l with
- | [[]] -> List.make nv []
+ | IntroOrPattern [[]] -> IntroOrPattern (List.make nv [])
| _ -> l
-let check_or_and_pattern_size loc names n =
- if not (Int.equal (List.length names) n) then
- if Int.equal n 1 then
- user_err_loc (loc,"",str "Expects a conjunctive pattern.")
- else
- user_err_loc (loc,"",str "Expects a disjunctive pattern with " ++ int n
- ++ str " branches.")
-
-let compute_induction_names n = function
+let check_or_and_pattern_size loc names branchsigns =
+ let n = Array.length branchsigns in
+ let msg p1 p2 = strbrk "a conjunctive pattern made of " ++ int p1 ++ (if p1 == p2 then mt () else str " or " ++ int p2) ++ str " patterns" in
+ let err1 p1 p2 =
+ user_err_loc (loc,"",str "Expects " ++ msg p1 p2 ++ str ".") in
+ let errn n =
+ user_err_loc (loc,"",str "Expects a disjunctive pattern with " ++ int n
+ ++ str " branches.") in
+ let err1' p1 p2 =
+ user_err_loc (loc,"",strbrk "Expects a disjunctive pattern with 1 branch or " ++ msg p1 p2 ++ str ".") in
+ match names with
+ | IntroAndPattern l ->
+ if not (Int.equal n 1) then errn n;
+ let p1 = List.count (fun x -> x) branchsigns.(0) in
+ let p2 = List.length branchsigns.(0) in
+ let p = List.length l in
+ if not (Int.equal p p1 || Int.equal p p2) ||
+ not (List.for_all (function _,IntroNaming _ | _,IntroAction _ -> true | _,IntroForthcoming _ -> false) l) then err1 p1 p2;
+ if Int.equal p p1 then
+ IntroAndPattern
+ (List.extend branchsigns.(0) (Loc.ghost,IntroNaming IntroAnonymous) l)
+ else
+ names
+ | IntroOrPattern ll ->
+ if not (Int.equal n (List.length ll)) then
+ if Int.equal n 1 then
+ let p1 = List.count (fun x -> x) branchsigns.(0) in
+ let p2 = List.length branchsigns.(0) in
+ err1' p1 p2 else errn n;
+ names
+
+let get_and_check_or_and_pattern loc names branchsigns =
+ let names = check_or_and_pattern_size loc names branchsigns in
+ match names with
+ | IntroAndPattern l -> [|l|]
+ | IntroOrPattern l -> Array.of_list l
+
+let compute_induction_names branchletsigns = function
| None ->
- Array.make n []
+ Array.make (Array.length branchletsigns) []
| Some (loc,names) ->
- let names = fix_empty_or_and_pattern n names in
- check_or_and_pattern_size loc names n;
- Array.of_list names
+ let names = fix_empty_or_and_pattern (Array.length branchletsigns) names in
+ get_and_check_or_and_pattern loc names branchletsigns
-let compute_construtor_signatures isrec ((_,k as ity),u) =
+(* Compute the let-in signature of case analysis or standard induction scheme *)
+let compute_constructor_signatures isrec ((_,k as ity),u) =
let rec analrec c recargs =
match kind_of_term c, recargs with
| Prod (_,_,c), recarg::rest ->
- let b = match Declareops.dest_recarg recarg with
- | Norec | Imbr _ -> false
- | Mrec (_,j) -> isrec && Int.equal j k
- in b :: (analrec c rest)
- | LetIn (_,_,_,c), rest -> false :: (analrec c rest)
+ let rest = analrec c rest in
+ begin match Declareops.dest_recarg recarg with
+ | Norec | Imbr _ -> true :: rest
+ | Mrec (_,j) ->
+ if isrec && Int.equal j k then true :: true :: rest
+ else true :: rest
+ end
+ | LetIn (_,_,_,c), rest -> false :: analrec c rest
| _, [] -> []
- | _ -> anomaly (Pp.str "compute_construtor_signatures")
+ | _ -> anomaly (Pp.str "compute_constructor_signatures")
in
let (mib,mip) = Global.lookup_inductive ity in
let n = mib.mind_nparams in
@@ -596,8 +630,8 @@ module New = struct
(str "The elimination combinator " ++ str name_elim ++ str " is unknown.")
in
let elimclause' = clenv_fchain ~with_univs:false indmv elimclause indclause in
- let branchsigns = compute_construtor_signatures isrec ind in
- let brnames = compute_induction_names (Array.length branchsigns) allnames in
+ let branchsigns = compute_constructor_signatures isrec ind in
+ let brnames = compute_induction_names branchsigns allnames in
let flags = Unification.elim_flags () in
let elimclause' =
match predicate with
@@ -609,10 +643,7 @@ module New = struct
let (hd,largs) = decompose_app clenv'.templtyp.Evd.rebus in
let ba = { branchsign = branchsigns.(i);
branchnames = brnames.(i);
- nassums =
- List.fold_left
- (fun acc b -> if b then acc+2 else acc+1)
- 0 branchsigns.(i);
+ nassums = List.length branchsigns.(i);
branchnum = i+1;
ity = ind;
largs = List.map (clenv_nf_meta clenv') largs;
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index 147f1f0f20..4f6f87f698 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -102,28 +102,32 @@ type branch_args = {
largs : constr list; (** its arguments *)
branchnum : int; (** the branch number *)
pred : constr; (** the predicate we used *)
- nassums : int; (** the number of assumptions to be introduced *)
+ nassums : int; (** number of assumptions/letin to be introduced *)
branchsign : bool list; (** the signature of the branch.
- true=recursive argument, false=constant *)
+ true=assumption, false=let-in *)
branchnames : intro_patterns}
type branch_assumptions = {
ba : branch_args; (** the branch args *)
assums : Context.Named.t} (** the list of assumptions introduced *)
-(** [check_disjunctive_pattern_size loc pats n] returns an appropriate
- error message if |pats| <> n *)
-val check_or_and_pattern_size :
- Loc.t -> delayed_open_constr or_and_intro_pattern_expr -> int -> unit
+(** [check_disjunctive_pattern_size loc pats n] returns an appropriate
+ error message if |pats| <> n; extends them if no pattern is given
+ for let-ins in the case of a conjunctive pattern *)
+val get_and_check_or_and_pattern :
+ Loc.t -> delayed_open_constr or_and_intro_pattern_expr ->
+ bool list array -> intro_patterns array
(** Tolerate "[]" to mean a disjunctive pattern of any length *)
val fix_empty_or_and_pattern : int ->
delayed_open_constr or_and_intro_pattern_expr ->
delayed_open_constr or_and_intro_pattern_expr
+val compute_constructor_signatures : rec_flag -> pinductive -> bool list array
+
(** Useful for [as intro_pattern] modifier *)
val compute_induction_names :
- int -> or_and_intro_pattern option -> intro_patterns array
+ bool list array -> or_and_intro_pattern option -> intro_patterns array
val elimination_sort_of_goal : goal sigma -> sorts_family
val elimination_sort_of_hyp : Id.t -> goal sigma -> sorts_family
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index f0f46c14db..796cea98f8 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -2089,14 +2089,15 @@ let intro_or_and_pattern loc bracketed ll thin tac id =
Proofview.Goal.enter { enter = begin fun gl ->
let c = mkVar id in
let t = Tacmach.New.pf_unsafe_type_of gl c in
- let ((ind,u),t) = Tacmach.New.pf_reduce_to_quantified_ind gl t in
- let nv = constructors_nrealdecls ind in
- let ll = fix_empty_or_and_pattern (Array.length nv) ll in
- check_or_and_pattern_size loc ll (Array.length nv);
+ let (ind,t) = Tacmach.New.pf_reduce_to_quantified_ind gl t in
+ let branchsigns = compute_constructor_signatures false ind in
+ let nv_with_let = Array.map List.length branchsigns in
+ let ll = fix_empty_or_and_pattern (Array.length branchsigns) ll in
+ let ll = get_and_check_or_and_pattern loc ll branchsigns in
Tacticals.New.tclTHENLASTn
(Tacticals.New.tclTHEN (simplest_case c) (Proofview.V82.tactic (clear [id])))
(Array.map2 (fun n l -> tac thin (Some (bracketed,n)) l)
- nv (Array.of_list ll))
+ nv_with_let ll)
end }
let rewrite_hyp assert_style l2r id =
@@ -2137,7 +2138,8 @@ let prepare_naming loc = function
let rec explicit_intro_names = function
| (_, IntroForthcoming _) :: l -> explicit_intro_names l
| (_, IntroNaming (IntroIdentifier id)) :: l -> id :: explicit_intro_names l
-| (_, IntroAction (IntroOrAndPattern ll)) :: l' ->
+| (_, IntroAction (IntroOrAndPattern l)) :: l' ->
+ let ll = match l with IntroAndPattern l -> [l] | IntroOrPattern ll -> ll in
List.flatten (List.map (fun l -> explicit_intro_names (l@l')) ll)
| (_, IntroAction (IntroInjection l)) :: l' ->
explicit_intro_names (l@l')
@@ -2842,8 +2844,8 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
let avoid = avoid @ avoid' in
let rec peel_tac ra dests names thin =
match ra with
- | (RecArg,deprec,recvarname) ::
- (IndArg,depind,hyprecname) :: ra' ->
+ | (RecArg,_,deprec,recvarname) ::
+ (IndArg,_,depind,hyprecname) :: ra' ->
Proofview.Goal.enter { enter = begin fun gl ->
let (recpat,names) = match names with
| [loc,IntroNaming (IntroIdentifier id) as pat] ->
@@ -2860,7 +2862,7 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
peel_tac ra' (update_dest dests ids') names thin)
end })
end }
- | (IndArg,dep,hyprecname) :: ra' ->
+ | (IndArg,_,dep,hyprecname) :: ra' ->
Proofview.Goal.enter { enter = begin fun gl ->
(* Rem: does not happen in Coq schemes, only in user-defined schemes *)
let pat,names =
@@ -2868,7 +2870,7 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
dest_intro_patterns avoid thin MoveLast [pat] (fun ids thin ->
peel_tac ra' (update_dest dests ids) names thin)
end }
- | (RecArg,dep,recvarname) :: ra' ->
+ | (RecArg,_,dep,recvarname) :: ra' ->
Proofview.Goal.enter { enter = begin fun gl ->
let (pat,names) =
consume_pattern avoid (Name recvarname) dep gl names in
@@ -2876,7 +2878,7 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
dest_intro_patterns avoid thin dest [pat] (fun ids thin ->
peel_tac ra' dests names thin)
end }
- | (OtherArg,dep,_) :: ra' ->
+ | (OtherArg,_,dep,_) :: ra' ->
Proofview.Goal.enter { enter = begin fun gl ->
let (pat,names) = consume_pattern avoid Anonymous dep gl names in
let dest = get_recarg_dest dests in
@@ -3682,9 +3684,9 @@ let compute_scheme_signature scheme names_info ind_type_guess =
let rec check_branch p c =
match kind_of_term c with
| Prod (_,t,c) ->
- (is_pred p t, dependent (mkRel 1) c) :: check_branch (p+1) c
+ (is_pred p t, true, dependent (mkRel 1) c) :: check_branch (p+1) c
| LetIn (_,_,_,c) ->
- (OtherArg, dependent (mkRel 1) c) :: check_branch (p+1) c
+ (OtherArg, false, dependent (mkRel 1) c) :: check_branch (p+1) c
| _ when is_pred p c == IndArg -> []
| _ -> raise Exit
in
@@ -3694,12 +3696,12 @@ let compute_scheme_signature scheme names_info ind_type_guess =
(try
let lchck_brch = check_branch p t in
let n = List.fold_left
- (fun n (b,_) -> if b == RecArg then n+1 else n) 0 lchck_brch in
+ (fun n (b,_,_) -> if b == RecArg then n+1 else n) 0 lchck_brch in
let recvarname, hyprecname, avoid =
make_up_names n scheme.indref names_info in
let namesign =
- List.map (fun (b,dep) ->
- (b, dep, if b == IndArg then hyprecname else recvarname))
+ List.map (fun (b,is_assum,dep) ->
+ (b,is_assum,dep,if b == IndArg then hyprecname else recvarname))
lchck_brch in
(avoid,namesign) :: find_branches (p+1) brs
with Exit-> error_ind_scheme "the branches of")
@@ -3744,7 +3746,7 @@ let given_elim hyp0 (elimc,lbind as e) gl =
Tacmach.New.project gl, (e, Tacmach.New.pf_unsafe_type_of gl elimc), ind_type_guess
type scheme_signature =
- (Id.t list * (elim_arg_kind * bool * Id.t) list) array
+ (Id.t list * (elim_arg_kind * bool * bool * Id.t) list) array
type eliminator_source =
| ElimUsing of (eliminator * types) * scheme_signature
@@ -3865,7 +3867,10 @@ let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
List.fold_left
(fun a (id,b,_) -> if Option.is_empty b then (mkVar id)::a else a) [] deps in
let (sigma, isrec, elim, indsign) = get_eliminator elim dep s (Proofview.Goal.assume gl) in
- let names = compute_induction_names (Array.length indsign) names in
+ let branchletsigns =
+ let f (_,is_not_let,_,_) = is_not_let in
+ Array.map (fun (_,l) -> List.map f l) indsign in
+ let names = compute_induction_names branchletsigns names in
let tac =
(if isrec then Tacticals.New.tclTHENFIRSTn else Tacticals.New.tclTHENLASTn)
(Tacticals.New.tclTHENLIST [
diff --git a/test-suite/success/intros.v b/test-suite/success/intros.v
index af5f994010..ee69df9774 100644
--- a/test-suite/success/intros.v
+++ b/test-suite/success/intros.v
@@ -105,3 +105,26 @@ Inductive I := C : let x:=1 in x=1 -> I.
Goal I -> True.
intros [x H]. (* Was failing in 8.5 *)
Abort.
+
+(* Ensuring that the (pat1,...,patn) intropatterns has the expected size, up
+ to skipping let-ins *)
+
+Goal I -> 1=1.
+intros (H). (* This skips x *)
+exact H.
+Qed.
+
+Goal I -> 1=1.
+Fail intros (x,H,H').
+Fail intros [|].
+intros (x,H).
+exact H.
+Qed.
+
+Goal Acc le 0 -> True.
+Fail induction 1 as (n,H). (* Induction hypothesis is missing *)
+induction 1 as (n,H,IH).
+exact Logic.I.
+Qed.
+
+
diff --git a/theories/Sorting/Permutation.v b/theories/Sorting/Permutation.v
index fcb4e7876d..ba7da256dc 100644
--- a/theories/Sorting/Permutation.v
+++ b/theories/Sorting/Permutation.v
@@ -321,7 +321,7 @@ Proof.
induction H; intros; try (injection Heqm; intros; subst; clear Heqm);
discriminate || (try tauto).
apply Permutation_length_1_inv in H as ->; left; auto.
- apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as ();
+ apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as [];
auto.
Qed.
diff --git a/theories/Wellfounded/Lexicographic_Exponentiation.v b/theories/Wellfounded/Lexicographic_Exponentiation.v
index b8b9e929c2..e05dab7a4a 100644
--- a/theories/Wellfounded/Lexicographic_Exponentiation.v
+++ b/theories/Wellfounded/Lexicographic_Exponentiation.v
@@ -75,7 +75,7 @@ Section Wf_Lexicographic_Exponentiation.
Proof.
intros.
inversion H.
- - apply app_cons_not_nil in H1 as ().
+ - apply app_cons_not_nil in H1 as [].
- assert (x ++ [a] = [x0]) by auto with sets.
apply app_eq_unit in H0 as [(->, _)| (_, [=])].
auto using d_nil.
@@ -98,7 +98,7 @@ Section Wf_Lexicographic_Exponentiation.
destruct (app_inj_tail (l ++ [y]) ([] ++ [b]) _ _ H0) as ((?, <-)%app_inj_tail, <-).
inversion H1; subst; [ apply rt_step; assumption | apply rt_refl ].
- inversion H0.
- + apply app_cons_not_nil in H3 as ().
+ + apply app_cons_not_nil in H3 as [].
+ rewrite app_comm_cons in H0, H1. apply desc_prefix in H0.
pose proof (H x0 b H0).
apply rt_trans with (y := x0); auto with sets.
@@ -145,7 +145,7 @@ Section Wf_Lexicographic_Exponentiation.
pose proof H0 as H0'.
apply app_inj_tail in H0' as (_, ->).
rewrite app_assoc_reverse in H0.
- apply Hind in H0 as ().
+ apply Hind in H0 as [].
split.
assumption.
apply d_conc; auto with sets.
diff --git a/toplevel/auto_ind_decl.ml b/toplevel/auto_ind_decl.ml
index 56106928e5..2f206bfc84 100644
--- a/toplevel/auto_ind_decl.ml
+++ b/toplevel/auto_ind_decl.ml
@@ -85,7 +85,7 @@ let destruct_on c = destruct false None c None None
let destruct_on_using c id =
destruct false None c
- (Some (dl,[[dl,IntroNaming IntroAnonymous];
+ (Some (dl,IntroOrPattern [[dl,IntroNaming IntroAnonymous];
[dl,IntroNaming (IntroIdentifier id)]]))
None
@@ -589,8 +589,8 @@ repeat ( apply andb_prop in z;let z1:= fresh "Z" in destruct z as [z1 z]).
Simple.apply_in freshz (andb_prop());
Proofview.Goal.nf_enter { enter = begin fun gl ->
let fresht = fresh_id (Id.of_string "Z") gl in
- (destruct_on_as (mkVar freshz)
- [[dl,IntroNaming (IntroIdentifier fresht);
+ destruct_on_as (mkVar freshz)
+ (IntroOrPattern [[dl,IntroNaming (IntroIdentifier fresht);
dl,IntroNaming (IntroIdentifier freshz)]])
end }
]);
--
cgit v1.2.3
From aa1913411547eeed464b024f1cf54113be26e929 Mon Sep 17 00:00:00 2001
From: Maxime Dénès
Date: Thu, 21 Jan 2016 22:17:36 +0100
Subject: Compile OS X binaries without native_compute support.
---
dev/make-macos-dmg.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dev/make-macos-dmg.sh b/dev/make-macos-dmg.sh
index 70889badc1..20b7b5b531 100755
--- a/dev/make-macos-dmg.sh
+++ b/dev/make-macos-dmg.sh
@@ -8,7 +8,7 @@ eval `opam config env`
make distclean
OUTDIR=$PWD/_install
DMGDIR=$PWD/_dmg
-./configure -debug -prefix $OUTDIR
+./configure -debug -prefix $OUTDIR -native-compiler no
VERSION=$(sed -n -e '/^let coq_version/ s/^[^"]*"\([^"]*\)"$/\1/p' configure.ml)
APP=bin/CoqIDE_${VERSION}.app
--
cgit v1.2.3
From 176d8e004153e65688dc8ef4f22f7939fd6101b1 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Thu, 21 Jan 2016 18:45:36 +0100
Subject: New step on recent 9c2662eecc398f3 (strong invariants on tuple
pattern).
- Fixing dead code, doc.
- Relaxing constraints on using an as-tuple in inversion.
---
intf/misctypes.mli | 2 --
tactics/inv.ml | 4 ++--
tactics/tacticals.ml | 38 ++++++++++++++++++++++++--------------
tactics/tacticals.mli | 6 +++---
4 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/intf/misctypes.mli b/intf/misctypes.mli
index 3c6d59ff0c..1452bbc347 100644
--- a/intf/misctypes.mli
+++ b/intf/misctypes.mli
@@ -16,8 +16,6 @@ type patvar = Id.t
(** Introduction patterns *)
-type tuple_flag = bool (* tells pattern list should be list of fixed length *)
-
type 'constr intro_pattern_expr =
| IntroForthcoming of bool
| IntroNaming of intro_pattern_naming_expr
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 8030fc32ee..ded1e8076d 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -296,8 +296,8 @@ let get_names (allow_conj,issimple) (loc, pat as x) = match pat with
error "Discarding pattern not allowed for inversion equations."
| IntroAction (IntroRewrite _) ->
error "Rewriting pattern not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern (IntroAndPattern [])) when allow_conj -> (None, [])
- | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l)))
+ | IntroAction (IntroOrAndPattern (IntroAndPattern [] | IntroOrPattern [[]])) when allow_conj -> (None, [])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l) | IntroOrPattern [(_,IntroNaming (IntroIdentifier id)) :: _ as l ]))
when allow_conj -> (Some id,l)
| IntroAction (IntroOrAndPattern (IntroAndPattern _)) ->
if issimple then
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index bacd8a607a..d79de4913c 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -167,7 +167,7 @@ let fix_empty_or_and_pattern nv l =
| IntroOrPattern [[]] -> IntroOrPattern (List.make nv [])
| _ -> l
-let check_or_and_pattern_size loc names branchsigns =
+let check_or_and_pattern_size check_and loc names branchsigns =
let n = Array.length branchsigns in
let msg p1 p2 = strbrk "a conjunctive pattern made of " ++ int p1 ++ (if p1 == p2 then mt () else str " or " ++ int p2) ++ str " patterns" in
let err1 p1 p2 =
@@ -177,17 +177,23 @@ let check_or_and_pattern_size loc names branchsigns =
++ str " branches.") in
let err1' p1 p2 =
user_err_loc (loc,"",strbrk "Expects a disjunctive pattern with 1 branch or " ++ msg p1 p2 ++ str ".") in
+ let errforthcoming loc =
+ user_err_loc (loc,"",strbrk "Unexpected non atomic pattern.") in
match names with
| IntroAndPattern l ->
if not (Int.equal n 1) then errn n;
- let p1 = List.count (fun x -> x) branchsigns.(0) in
- let p2 = List.length branchsigns.(0) in
- let p = List.length l in
- if not (Int.equal p p1 || Int.equal p p2) ||
- not (List.for_all (function _,IntroNaming _ | _,IntroAction _ -> true | _,IntroForthcoming _ -> false) l) then err1 p1 p2;
- if Int.equal p p1 then
- IntroAndPattern
- (List.extend branchsigns.(0) (Loc.ghost,IntroNaming IntroAnonymous) l)
+ let l' = List.filter (function _,IntroForthcoming _ -> true | _,IntroNaming _ | _,IntroAction _ -> false) l in
+ if l' != [] then errforthcoming (fst (List.hd l'));
+ if check_and then
+ let p1 = List.count (fun x -> x) branchsigns.(0) in
+ let p2 = List.length branchsigns.(0) in
+ let p = List.length l in
+ if not (Int.equal p p1 || Int.equal p p2) then err1 p1 p2;
+ if Int.equal p p1 then
+ IntroAndPattern
+ (List.extend branchsigns.(0) (Loc.ghost,IntroNaming IntroAnonymous) l)
+ else
+ names
else
names
| IntroOrPattern ll ->
@@ -198,18 +204,22 @@ let check_or_and_pattern_size loc names branchsigns =
err1' p1 p2 else errn n;
names
-let get_and_check_or_and_pattern loc names branchsigns =
- let names = check_or_and_pattern_size loc names branchsigns in
+let get_and_check_or_and_pattern_gen check_and loc names branchsigns =
+ let names = check_or_and_pattern_size check_and loc names branchsigns in
match names with
| IntroAndPattern l -> [|l|]
| IntroOrPattern l -> Array.of_list l
-let compute_induction_names branchletsigns = function
+let get_and_check_or_and_pattern = get_and_check_or_and_pattern_gen true
+
+let compute_induction_names_gen check_and branchletsigns = function
| None ->
Array.make (Array.length branchletsigns) []
| Some (loc,names) ->
let names = fix_empty_or_and_pattern (Array.length branchletsigns) names in
- get_and_check_or_and_pattern loc names branchletsigns
+ get_and_check_or_and_pattern_gen check_and loc names branchletsigns
+
+let compute_induction_names = compute_induction_names_gen true
(* Compute the let-in signature of case analysis or standard induction scheme *)
let compute_constructor_signatures isrec ((_,k as ity),u) =
@@ -631,7 +641,7 @@ module New = struct
in
let elimclause' = clenv_fchain ~with_univs:false indmv elimclause indclause in
let branchsigns = compute_constructor_signatures isrec ind in
- let brnames = compute_induction_names branchsigns allnames in
+ let brnames = compute_induction_names_gen false branchsigns allnames in
let flags = Unification.elim_flags () in
let elimclause' =
match predicate with
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index 4b70536113..ffcc71b458 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -111,10 +111,10 @@ type branch_assumptions = {
ba : branch_args; (** the branch args *)
assums : Context.Named.t} (** the list of assumptions introduced *)
-(** [check_disjunctive_pattern_size loc pats n] returns an appropriate
- error message if |pats| <> n; extends them if no pattern is given
+(** [get_and_check_or_and_pattern loc pats branchsign] returns an appropriate
+ error message if |pats| <> |branchsign|; extends them if no pattern is given
for let-ins in the case of a conjunctive pattern *)
-val get_and_check_or_and_pattern :
+val get_and_check_or_and_pattern :
Loc.t -> delayed_open_constr or_and_intro_pattern_expr ->
bool list array -> intro_patterns array
--
cgit v1.2.3
From f65f8d5a4d9ba437fa2d8af03e2781d841e53007 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Thu, 21 Jan 2016 09:21:23 +0100
Subject: Restore warnings produced by the interpretation of the command line
(e.g. with deprecated options such as -byte, etc.) since I guess this is what
we expect.
Was probably lost in 81eb133d64ac81cb.
---
lib/flags.mli | 1 +
toplevel/coqtop.ml | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/flags.mli b/lib/flags.mli
index ab06eda306..69caad5b62 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -90,6 +90,7 @@ val is_universe_polymorphism : unit -> bool
val make_polymorphic_flag : bool -> unit
val use_polymorphic_flag : unit -> bool
+val warn : bool ref
val make_warn : bool -> unit
val if_warn : ('a -> unit) -> 'a -> unit
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index afd4ef40e8..cfedff0809 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -35,7 +35,7 @@ let print_header () =
ppnl (str "Welcome to Coq " ++ str ver ++ str " (" ++ str rev ++ str ")");
pp_flush ()
-let warning s = msg_warning (strbrk s)
+let warning s = with_option Flags.warn msg_warning (strbrk s)
let toploop = ref None
--
cgit v1.2.3
From 4953a129858a231e64dec636a3bc15a54a0e771c Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Fri, 22 Jan 2016 01:36:43 +0100
Subject: Fixing a use of "clear" on an non-existing hypothesis in
intro-patterns.
It was not detected because of a "bug" in clear checking the existence
of the hypothesis only at interpretation time (not at execution time).
---
tactics/tactics.ml | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index b88ec69e62..aeb3726a0c 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -2103,34 +2103,45 @@ let intro_or_and_pattern loc bracketed ll thin tac id =
nv_with_let ll)
end }
-let rewrite_hyp assert_style l2r id =
+let rewrite_hyp_then assert_style thin l2r id tac =
let rew_on l2r =
Hook.get forward_general_rewrite_clause l2r false (mkVar id,NoBindings) in
let subst_on l2r x rhs =
Hook.get forward_subst_one true x (id,rhs,l2r) in
- let clear_var_and_eq c = tclTHEN (clear [id]) (clear [destVar c]) in
+ let clear_var_and_eq id' = clear [id';id] in
+ let early_clear id' thin =
+ List.filter (fun (_,id) -> not (Id.equal id id')) thin in
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let type_of = Tacmach.New.pf_unsafe_type_of gl in
let whd_betadeltaiota = Tacmach.New.pf_apply whd_betadeltaiota gl in
let t = whd_betadeltaiota (type_of (mkVar id)) in
- match match_with_equality_type t with
+ let eqtac, thin = match match_with_equality_type t with
| Some (hdcncl,[_;lhs;rhs]) ->
if l2r && isVar lhs && not (occur_var env (destVar lhs) rhs) then
- subst_on l2r (destVar lhs) rhs
+ let id' = destVar lhs in
+ subst_on l2r id' rhs, early_clear id' thin
else if not l2r && isVar rhs && not (occur_var env (destVar rhs) lhs) then
- subst_on l2r (destVar rhs) lhs
+ let id' = destVar rhs in
+ subst_on l2r id' lhs, early_clear id' thin
else
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id]))
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ thin
| Some (hdcncl,[c]) ->
let l2r = not l2r in (* equality of the form eq_true *)
if isVar c then
+ let id' = destVar c in
Tacticals.New.tclTHEN (rew_on l2r allHypsAndConcl)
- (Proofview.V82.tactic (clear_var_and_eq c))
+ (Proofview.V82.tactic (clear_var_and_eq id')),
+ early_clear id' thin
else
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id]))
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ thin
| _ ->
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id]))
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ thin in
+ (* Skip the side conditions of the rewriting step *)
+ Tacticals.New.tclTHENFIRST eqtac (tac thin)
end }
let prepare_naming loc = function
@@ -2256,10 +2267,7 @@ and intro_pattern_action loc b style pat thin destopt tac id = match pat with
| IntroInjection l' ->
intro_decomp_eq loc l' thin tac id
| IntroRewrite l2r ->
- Tacticals.New.tclTHENFIRST
- (* Skip the side conditions of the rewriting step *)
- (rewrite_hyp style l2r id)
- (tac thin None [])
+ rewrite_hyp_then style thin l2r id (fun thin -> tac thin None [])
| IntroApplyOn (f,(loc,pat)) ->
let naming,tac_ipat =
prepare_intros_loc loc (IntroIdentifier id) destopt pat in
--
cgit v1.2.3
From ccdc62a6b4722c38f2b37cbf21b14e5094255390 Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Thu, 21 Jan 2016 18:05:55 -0500
Subject: Fix bug #4506. Using betadeltaiota_nolet might produce terms of the
form (let x := t in u) a that should be reduced. Maybe a different
decomposition/reduction primitive should be used instead.
---
pretyping/indrec.ml | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index d5f6e9b301..0588dcc87f 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -155,7 +155,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
| Prod (n,t,c) ->
let d = (n,None,t) in
make_prod env (n,t,prec (push_rel d env) (i+1) (d::sign) c)
- | LetIn (n,b,t,c) ->
+ | LetIn (n,b,t,c) when List.is_empty largs ->
let d = (n,Some b,t) in
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::sign) c)
| Ind (_,_) ->
@@ -166,7 +166,10 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
base [|applist (mkRel (i+1), Termops.extended_rel_list 0 sign)|]
else
base
- | _ -> assert false
+ | _ ->
+ let t' = whd_betadeltaiota env sigma p in
+ if Term.eq_constr p' t' then assert false
+ else prec env i sign t'
in
prec env 0 []
in
@@ -230,14 +233,17 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
| Prod (n,t,c) ->
let d = (n,None,t) in
mkLambda_name env (n,t,prec (push_rel d env) (i+1) (d::hyps) c)
- | LetIn (n,b,t,c) ->
+ | LetIn (n,b,t,c) when List.is_empty largs ->
let d = (n,Some b,t) in
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::hyps) c)
| Ind _ ->
let realargs = List.skipn nparrec largs
and arg = appvect (mkRel (i+1), Termops.extended_rel_vect 0 hyps) in
applist(lift i fk,realargs@[arg])
- | _ -> assert false
+ | _ ->
+ let t' = whd_betadeltaiota env sigma p in
+ if Term.eq_constr t' p' then assert false
+ else prec env i hyps t'
in
prec env 0 []
in
--
cgit v1.2.3
From 5cbcc8fd761df0779f6202fef935f07cfef8a228 Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Sat, 23 Jan 2016 15:17:29 -0500
Subject: Implement support for universe binder lists in Instance and Program
Fixpoint/Definition.
---
interp/dumpglob.ml | 2 +-
intf/constrexpr.mli | 2 +-
parsing/g_vernac.ml4 | 8 ++++----
parsing/pcoq.ml4 | 1 +
parsing/pcoq.mli | 1 +
printing/ppvernac.ml | 5 +++--
tactics/rewrite.ml | 4 ++--
toplevel/classes.ml | 29 +++++++++++++++++------------
toplevel/classes.mli | 3 ++-
toplevel/command.ml | 29 ++++++++++++++++-------------
toplevel/obligations.ml | 26 +++++++++++++++++---------
toplevel/obligations.mli | 2 ++
12 files changed, 67 insertions(+), 45 deletions(-)
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index 0d9d021c68..44a62ef379 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -248,7 +248,7 @@ let dump_def ty loc secpath id =
let dump_definition (loc, id) sec s =
dump_def s loc (Names.DirPath.to_string (Lib.current_dirpath sec)) (Names.Id.to_string id)
-let dump_constraint ((loc, n), _, _) sec ty =
+let dump_constraint (((loc, n),_), _, _) sec ty =
match n with
| Names.Name id -> dump_definition (loc, id) sec ty
| Names.Anonymous -> ()
diff --git a/intf/constrexpr.mli b/intf/constrexpr.mli
index dcdbd47f68..a53238dfd8 100644
--- a/intf/constrexpr.mli
+++ b/intf/constrexpr.mli
@@ -121,7 +121,7 @@ and constr_notation_substitution =
constr_expr list list * (** for recursive notations *)
local_binder list list (** for binders subexpressions *)
-type typeclass_constraint = Name.t located * binding_kind * constr_expr
+type typeclass_constraint = (Name.t located * Id.t located list option) * binding_kind * constr_expr
and typeclass_context = typeclass_constraint list
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 839f768b98..f3766a7d79 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -192,7 +192,7 @@ let test_plurial_form_types = function
(* Gallina declarations *)
GEXTEND Gram
GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
- record_field decl_notation rec_definition;
+ record_field decl_notation rec_definition pidentref;
gallina:
(* Definition, Theorem, Variable, Axiom, ... *)
@@ -783,10 +783,10 @@ GEXTEND Gram
| IDENT "transparent" -> Conv_oracle.transparent ] ]
;
instance_name:
- [ [ name = identref; sup = OPT binders ->
- (let (loc,id) = name in (loc, Name id)),
+ [ [ name = pidentref; sup = OPT binders ->
+ (let ((loc,id),l) = name in ((loc, Name id),l)),
(Option.default [] sup)
- | -> (!@loc, Anonymous), [] ] ]
+ | -> ((!@loc, Anonymous), None), [] ] ]
;
reserv_list:
[ [ bl = LIST1 reserv_tuple -> bl | b = simple_reserv -> [b] ] ]
diff --git a/parsing/pcoq.ml4 b/parsing/pcoq.ml4
index 32dbeaa4dd..28dc74e81b 100644
--- a/parsing/pcoq.ml4
+++ b/parsing/pcoq.ml4
@@ -315,6 +315,7 @@ module Prim =
let name = Gram.entry_create "Prim.name"
let identref = Gram.entry_create "Prim.identref"
+ let pidentref = Gram.entry_create "Prim.pidentref"
let pattern_ident = Gram.entry_create "pattern_ident"
let pattern_identref = Gram.entry_create "pattern_identref"
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 24b58775a2..54e6423877 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -163,6 +163,7 @@ module Prim :
val ident : Id.t Gram.entry
val name : Name.t located Gram.entry
val identref : Id.t located Gram.entry
+ val pidentref : (Id.t located * (Id.t located list) option) Gram.entry
val pattern_ident : Id.t Gram.entry
val pattern_identref : Id.t located Gram.entry
val base_ident : Id.t Gram.entry
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index d2f59e7b8d..38add9d2c8 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -925,8 +925,9 @@ module Make
hov 1 (
(if abst then keyword "Declare" ++ spc () else mt ()) ++
keyword "Instance" ++
- (match snd instid with Name id -> spc () ++ pr_lident (fst instid, id) ++ spc () |
- Anonymous -> mt ()) ++
+ (match instid with
+ | (loc, Name id), l -> spc () ++ pr_plident ((loc, id),l) ++ spc ()
+ | (_, Anonymous), _ -> mt ()) ++
pr_and_type_binders_arg sup ++
str":" ++ spc () ++
pr_constr cl ++ pr_priority pri ++
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 74bb6d5976..83742bfbdd 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -1703,7 +1703,7 @@ let rec strategy_of_ast = function
let mkappc s l = CAppExpl (Loc.ghost,(None,(Libnames.Ident (Loc.ghost,Id.of_string s)),None),l)
let declare_an_instance n s args =
- ((Loc.ghost,Name n), Explicit,
+ (((Loc.ghost,Name n),None), Explicit,
CAppExpl (Loc.ghost, (None, Qualid (Loc.ghost, qualid_of_string s),None),
args))
@@ -1919,7 +1919,7 @@ let add_morphism glob binders m s n =
let poly = Flags.is_universe_polymorphism () in
let instance_id = add_suffix n "_Proper" in
let instance =
- ((Loc.ghost,Name instance_id), Explicit,
+ (((Loc.ghost,Name instance_id),None), Explicit,
CAppExpl (Loc.ghost,
(None, Qualid (Loc.ghost, Libnames.qualid_of_string "Coq.Classes.Morphisms.Proper"),None),
[cHole; s; m]))
diff --git a/toplevel/classes.ml b/toplevel/classes.ml
index 3a0b5f24f7..f73dd5a2e6 100644
--- a/toplevel/classes.ml
+++ b/toplevel/classes.ml
@@ -101,19 +101,21 @@ let instance_hook k pri global imps ?hook cst =
Typeclasses.declare_instance pri (not global) cst;
(match hook with Some h -> h cst | None -> ())
-let declare_instance_constant k pri global imps ?hook id poly uctx term termtype =
+let declare_instance_constant k pri global imps ?hook id pl poly evm term termtype =
let kind = IsDefinition Instance in
- let uctx =
+ let evm =
let levels = Univ.LSet.union (Universes.universes_of_constr termtype)
(Universes.universes_of_constr term) in
- Universes.restrict_universe_context uctx levels
+ Evd.restrict_universe_context evm levels
in
+ let pl, uctx = Evd.universe_context ?names:pl evm in
let entry =
- Declare.definition_entry ~types:termtype ~poly ~univs:(Univ.ContextSet.to_context uctx) term
+ Declare.definition_entry ~types:termtype ~poly ~univs:uctx term
in
let cdecl = (DefinitionEntry entry, kind) in
let kn = Declare.declare_constant id cdecl in
Declare.definition_message id;
+ Universes.register_universe_binders (ConstRef kn) pl;
instance_hook k pri global imps ?hook (ConstRef kn);
id
@@ -121,7 +123,9 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
?(generalize=true)
?(tac:unit Proofview.tactic option) ?hook pri =
let env = Global.env() in
- let evars = ref (Evd.from_env env) in
+ let ((loc, instid), pl) = instid in
+ let uctx = Evd.make_evar_universe_context env pl in
+ let evars = ref (Evd.from_ctx uctx) in
let tclass, ids =
match bk with
| Implicit ->
@@ -158,7 +162,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
cl, u, c', ctx', ctx, len, imps, args
in
let id =
- match snd instid with
+ match instid with
Name id ->
let sp = Lib.make_path id in
if Nametab.exists_cci sp then
@@ -185,11 +189,13 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
nf t
in
Evarutil.check_evars env Evd.empty !evars termtype;
- let pl, ctx = Evd.universe_context !evars in
+ let pl, ctx = Evd.universe_context ?names:pl !evars in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
(ParameterEntry
(None,poly,(termtype,ctx),None), Decl_kinds.IsAssumption Decl_kinds.Logical)
- in instance_hook k None global imps ?hook (ConstRef cst); id
+ in
+ Universes.register_universe_binders (ConstRef cst) pl;
+ instance_hook k None global imps ?hook (ConstRef cst); id
end
else (
let props =
@@ -282,9 +288,8 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
in
let term = Option.map nf term in
if not (Evd.has_undefined evm) && not (Option.is_empty term) then
- let ctx = Evd.universe_context_set evm in
- declare_instance_constant k pri global imps ?hook id
- poly ctx (Option.get term) termtype
+ declare_instance_constant k pri global imps ?hook id pl
+ poly evm (Option.get term) termtype
else if !refine_instance || Option.is_empty term then begin
let kind = Decl_kinds.Global, poly, Decl_kinds.DefinitionBody Decl_kinds.Instance in
if Flags.is_program_mode () then
@@ -304,7 +309,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
let hook = Lemmas.mk_hook hook in
let ctx = Evd.evar_universe_context evm in
ignore (Obligations.add_definition id ?term:constr
- typ ctx ~kind:(Global,poly,Instance) ~hook obls);
+ ?pl typ ctx ~kind:(Global,poly,Instance) ~hook obls);
id
else
(Flags.silently
diff --git a/toplevel/classes.mli b/toplevel/classes.mli
index 24c51b31a3..d600b3104f 100644
--- a/toplevel/classes.mli
+++ b/toplevel/classes.mli
@@ -31,8 +31,9 @@ val declare_instance_constant :
Impargs.manual_explicitation list -> (** implicits *)
?hook:(Globnames.global_reference -> unit) ->
Id.t -> (** name *)
+ Id.t Loc.located list option ->
bool -> (* polymorphic *)
- Univ.universe_context_set -> (* Universes *)
+ Evd.evar_map -> (* Universes *)
Constr.t -> (** body *)
Term.types -> (** type *)
Names.Id.t
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 5d2a7638a0..8f7c389975 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -177,7 +177,9 @@ let _ = Obligations.declare_definition_ref :=
(fun i k c imps hook -> declare_definition i k c [] imps hook)
let do_definition ident k pl bl red_option c ctypopt hook =
- let (ce, evd, pl, imps as def) = interp_definition pl bl (pi2 k) red_option c ctypopt in
+ let (ce, evd, pl', imps as def) =
+ interp_definition pl bl (pi2 k) red_option c ctypopt
+ in
if Flags.is_program_mode () then
let env = Global.env () in
let (c,ctx), sideff = Future.force ce.const_entry_body in
@@ -194,9 +196,9 @@ let do_definition ident k pl bl red_option c ctypopt hook =
let ctx = Evd.evar_universe_context evd in
let hook = Lemmas.mk_hook (fun l r _ -> Lemmas.call_hook (fun exn -> exn) hook l r) in
ignore(Obligations.add_definition
- ident ~term:c cty ctx ~implicits:imps ~kind:k ~hook obls)
+ ident ~term:c cty ctx ?pl ~implicits:imps ~kind:k ~hook obls)
else let ce = check_definition def in
- ignore(declare_definition ident k ce pl imps
+ ignore(declare_definition ident k ce pl' imps
(Lemmas.mk_hook
(fun l r -> Lemmas.call_hook (fun exn -> exn) hook l r;r)))
@@ -905,10 +907,11 @@ let nf_evar_context sigma ctx =
List.map (fun (n, b, t) ->
(n, Option.map (Evarutil.nf_evar sigma) b, Evarutil.nf_evar sigma t)) ctx
-let build_wellfounded (recname,n,bl,arityc,body) r measure notation =
+let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
Coqlib.check_required_library ["Coq";"Program";"Wf"];
let env = Global.env() in
- let evdref = ref (Evd.from_env env) in
+ let ctx = Evd.make_evar_universe_context env pl in
+ let evdref = ref (Evd.from_ctx ctx) in
let _, ((env', binders_rel), impls) = interp_context_evars env evdref bl in
let len = List.length binders_rel in
let top_env = push_rel_context binders_rel env in
@@ -1014,9 +1017,9 @@ let build_wellfounded (recname,n,bl,arityc,body) r measure notation =
let hook l gr _ =
let body = it_mkLambda_or_LetIn (mkApp (Universes.constr_of_global gr, [|make|])) binders_rel in
let ty = it_mkProd_or_LetIn top_arity binders_rel in
- let pl, univs = Evd.universe_context !evdref in
+ let pl, univs = Evd.universe_context ?names:pl !evdref in
(*FIXME poly? *)
- let ce = definition_entry ~types:ty ~univs (Evarutil.nf_evar !evdref body) in
+ let ce = definition_entry ~poly ~types:ty ~univs (Evarutil.nf_evar !evdref body) in
(** FIXME: include locality *)
let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
let gr = ConstRef c in
@@ -1040,7 +1043,7 @@ let build_wellfounded (recname,n,bl,arityc,body) r measure notation =
Obligations.eterm_obligations env recname !evdref 0 fullcoqc fullctyp
in
let ctx = Evd.evar_universe_context !evdref in
- ignore(Obligations.add_definition recname ~term:evars_def
+ ignore(Obligations.add_definition recname ~term:evars_def ?pl
evars_typ ctx evars ~hook)
let interp_recursive isfix fixl notations =
@@ -1261,22 +1264,22 @@ let do_program_recursive local p fixkind fixl ntns =
| Obligations.IsFixpoint _ -> (local, p, Fixpoint)
| Obligations.IsCoFixpoint -> (local, p, CoFixpoint)
in
- Obligations.add_mutual_definitions defs ~kind ctx ntns fixkind
+ Obligations.add_mutual_definitions defs ~kind ?pl ctx ntns fixkind
let do_program_fixpoint local poly l =
let g = List.map (fun ((_,wf,_,_,_),_) -> wf) l in
match g, l with
- | [(n, CWfRec r)], [((((_,id),_),_,bl,typ,def),ntn)] ->
+ | [(n, CWfRec r)], [((((_,id),pl),_,bl,typ,def),ntn)] ->
let recarg =
match n with
| Some n -> mkIdentC (snd n)
| None ->
errorlabstrm "do_program_fixpoint"
(str "Recursive argument required for well-founded fixpoints")
- in build_wellfounded (id, n, bl, typ, out_def def) r recarg ntn
+ in build_wellfounded (id, pl, n, bl, typ, out_def def) poly r recarg ntn
- | [(n, CMeasureRec (m, r))], [((((_,id),_),_,bl,typ,def),ntn)] ->
- build_wellfounded (id, n, bl, typ, out_def def)
+ | [(n, CMeasureRec (m, r))], [((((_,id),pl),_,bl,typ,def),ntn)] ->
+ build_wellfounded (id, pl, n, bl, typ, out_def def) poly
(Option.default (CRef (lt_ref,None)) r) m ntn
| _, _ when List.for_all (fun (n, ro) -> ro == CStructRec) g ->
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index 314789ced6..7e0d30a63e 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -311,6 +311,7 @@ type program_info_aux = {
prg_body: constr;
prg_type: constr;
prg_ctx: Evd.evar_universe_context;
+ prg_pl: Id.t Loc.located list option;
prg_obligations: obligations;
prg_deps : Id.t list;
prg_fixkind : fixpoint_kind option ;
@@ -510,15 +511,21 @@ let declare_definition prg =
(Evd.evar_universe_context_subst prg.prg_ctx) in
let opaque = prg.prg_opaque in
let fix_exn = Stm.get_fix_exn () in
+ let pl, ctx =
+ Evd.universe_context ?names:prg.prg_pl (Evd.from_ctx prg.prg_ctx) in
let ce =
definition_entry ~fix_exn
~opaque ~types:(nf typ) ~poly:(pi2 prg.prg_kind)
~univs:(Evd.evar_context_universe_context prg.prg_ctx) (nf body)
in
- progmap_remove prg;
+ let () = progmap_remove prg in
+ let cst =
!declare_definition_ref prg.prg_name
- prg.prg_kind ce prg.prg_implicits
- (Lemmas.mk_hook (fun l r -> Lemmas.call_hook fix_exn prg.prg_hook l r prg.prg_ctx; r))
+ prg.prg_kind ce prg.prg_implicits
+ (Lemmas.mk_hook (fun l r -> Lemmas.call_hook fix_exn prg.prg_hook l r prg.prg_ctx; r))
+ in
+ Universes.register_universe_binders cst pl;
+ cst
open Pp
@@ -644,7 +651,8 @@ let declare_obligation prg obl body ty uctx =
else
Some (TermObl (it_mkLambda_or_LetIn (mkApp (mkConst constant, args)) ctx)) }
-let init_prog_info ?(opaque = false) sign n b t ctx deps fixkind notations obls impls kind reduce hook =
+let init_prog_info ?(opaque = false) sign n pl b t ctx deps fixkind
+ notations obls impls kind reduce hook =
let obls', b =
match b with
| None ->
@@ -664,7 +672,7 @@ let init_prog_info ?(opaque = false) sign n b t ctx deps fixkind notations obls
obls, b
in
{ prg_name = n ; prg_body = b; prg_type = reduce t;
- prg_ctx = ctx;
+ prg_ctx = ctx; prg_pl = pl;
prg_obligations = (obls', Array.length obls');
prg_deps = deps; prg_fixkind = fixkind ; prg_notations = notations ;
prg_implicits = impls; prg_kind = kind; prg_reduce = reduce;
@@ -995,11 +1003,11 @@ let show_term n =
Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_type ++ spc () ++ str ":=" ++ fnl ()
++ Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_body)
-let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition) ?tactic
+let add_definition n ?term t ctx ?pl ?(implicits=[]) ?(kind=Global,false,Definition) ?tactic
?(reduce=reduce) ?(hook=Lemmas.mk_hook (fun _ _ _ -> ())) ?(opaque = false) obls =
let sign = Decls.initialize_named_context_for_proof () in
let info = str (Id.to_string n) ++ str " has type-checked" in
- let prg = init_prog_info sign ~opaque n term t ctx [] None [] obls implicits kind reduce hook in
+ let prg = init_prog_info sign ~opaque n pl term t ctx [] None [] obls implicits kind reduce hook in
let obls,_ = prg.prg_obligations in
if Int.equal (Array.length obls) 0 then (
Flags.if_verbose msg_info (info ++ str ".");
@@ -1014,13 +1022,13 @@ let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition)
| Remain rem -> Flags.if_verbose (fun () -> show_obligations ~msg:false (Some n)) (); res
| _ -> res)
-let add_mutual_definitions l ctx ?tactic ?(kind=Global,false,Definition) ?(reduce=reduce)
+let add_mutual_definitions l ctx ?pl ?tactic ?(kind=Global,false,Definition) ?(reduce=reduce)
?(hook=Lemmas.mk_hook (fun _ _ _ -> ())) ?(opaque = false) notations fixkind =
let sign = Decls.initialize_named_context_for_proof () in
let deps = List.map (fun (n, b, t, imps, obls) -> n) l in
List.iter
(fun (n, b, t, imps, obls) ->
- let prg = init_prog_info sign ~opaque n (Some b) t ctx deps (Some fixkind)
+ let prg = init_prog_info sign ~opaque n pl (Some b) t ctx deps (Some fixkind)
notations obls imps kind reduce hook
in progmap_add n (Ephemeron.create prg)) l;
let _defined =
diff --git a/toplevel/obligations.mli b/toplevel/obligations.mli
index b2320a578a..e257da0161 100644
--- a/toplevel/obligations.mli
+++ b/toplevel/obligations.mli
@@ -64,6 +64,7 @@ val get_proofs_transparency : unit -> bool
val add_definition : Names.Id.t -> ?term:Term.constr -> Term.types ->
Evd.evar_universe_context ->
+ ?pl:(Id.t Loc.located list) -> (* Universe binders *)
?implicits:(Constrexpr.explicitation * (bool * bool * bool)) list ->
?kind:Decl_kinds.definition_kind ->
?tactic:unit Proofview.tactic ->
@@ -81,6 +82,7 @@ val add_mutual_definitions :
(Names.Id.t * Term.constr * Term.types *
(Constrexpr.explicitation * (bool * bool * bool)) list * obligation_info) list ->
Evd.evar_universe_context ->
+ ?pl:(Id.t Loc.located list) -> (* Universe binders *)
?tactic:unit Proofview.tactic ->
?kind:Decl_kinds.definition_kind ->
?reduce:(Term.constr -> Term.constr) ->
--
cgit v1.2.3
From 6a046f8d3e33701d70e2a391741e65564cc0554d Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Sat, 23 Jan 2016 15:55:43 -0500
Subject: Fix bug #4519: oops, global shadowed local universe level bindings.
---
pretyping/pretyping.ml | 10 +++++-----
test-suite/bugs/closed/4519.v | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+), 5 deletions(-)
create mode 100644 test-suite/bugs/closed/4519.v
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index ac0104d9f8..b33084a423 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -138,12 +138,12 @@ let interp_universe_level_name evd (loc,s) =
in evd, level
else
try
- let id =
- try Id.of_string s with _ -> raise Not_found in
- evd, Idmap.find id names
+ let level = Evd.universe_of_name evd s in
+ evd, level
with Not_found ->
- try let level = Evd.universe_of_name evd s in
- evd, level
+ try
+ let id = try Id.of_string s with _ -> raise Not_found in
+ evd, Idmap.find id names
with Not_found ->
if not (is_strict_universe_declarations ()) then
new_univ_level_variable ~name:s univ_rigid evd
diff --git a/test-suite/bugs/closed/4519.v b/test-suite/bugs/closed/4519.v
new file mode 100644
index 0000000000..ccbc47d20f
--- /dev/null
+++ b/test-suite/bugs/closed/4519.v
@@ -0,0 +1,21 @@
+Set Universe Polymorphism.
+Section foo.
+ Universe i.
+ Context (foo : Type@{i}) (bar : Type@{i}).
+ Definition qux@{i} (baz : Type@{i}) := foo -> bar.
+End foo.
+Set Printing Universes.
+Print qux. (* qux@{Top.42 Top.43} =
+fun foo bar _ : Type@{Top.42} => foo -> bar
+ : Type@{Top.42} -> Type@{Top.42} -> Type@{Top.42} -> Type@{Top.42}
+(* Top.42 Top.43 |= *)
+(* This is wrong; the first two types are equal, but the last one is not *)
+
+qux is universe polymorphic
+Argument scopes are [type_scope type_scope type_scope]
+ *)
+Check qux nat nat nat : Set.
+Check qux nat nat Set : Set. (* Error:
+The term "qux@{Top.50 Top.51} ?T ?T0 Set" has type "Type@{Top.50}" while it is
+expected to have type "Set"
+(universe inconsistency: Cannot enforce Top.50 = Set because Set < Top.50). *)
\ No newline at end of file
--
cgit v1.2.3
From b582db2ecbb3f7f1315fedc50b0009f62f5c59ad Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Sat, 23 Jan 2016 17:28:34 -0500
Subject: Fix bug #4503: mixing universe polymorphic and monomorphic variables
and definitions in sections is unsupported.
---
library/declare.ml | 4 ++--
library/lib.ml | 22 ++++++++++++++-------
library/lib.mli | 5 +++--
test-suite/bugs/closed/4503.v | 37 +++++++++++++++++++++++++++++++++++
test-suite/bugs/closed/HoTT_coq_002.v | 2 +-
test-suite/bugs/closed/HoTT_coq_020.v | 4 ++--
theories/Logic/Hurkens.v | 3 ++-
7 files changed, 62 insertions(+), 15 deletions(-)
create mode 100644 test-suite/bugs/closed/4503.v
diff --git a/library/declare.ml b/library/declare.ml
index 5f6f0fe45e..c9d5fdbe2f 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -158,7 +158,7 @@ let cache_constant ((sp,kn), obj) =
assert (eq_constant kn' (constant_of_kn kn));
Nametab.push (Nametab.Until 1) sp (ConstRef (constant_of_kn kn));
let cst = Global.lookup_constant kn' in
- add_section_constant (cst.const_proj <> None) kn' cst.const_hyps;
+ add_section_constant cst.const_polymorphic kn' cst.const_hyps;
Dischargedhypsmap.set_discharged_hyps sp obj.cst_hyps;
add_constant_kind (constant_of_kn kn) obj.cst_kind
@@ -325,7 +325,7 @@ let cache_inductive ((sp,kn),(dhyps,mie)) =
let kn' = Global.add_mind dir id mie in
assert (eq_mind kn' (mind_of_kn kn));
let mind = Global.lookup_mind kn' in
- add_section_kn kn' mind.mind_hyps;
+ add_section_kn mind.mind_polymorphic kn' mind.mind_hyps;
Dischargedhypsmap.set_discharged_hyps sp dhyps;
List.iter (fun (sp, ref) -> Nametab.push (Nametab.Until 1) sp ref) names
diff --git a/library/lib.ml b/library/lib.ml
index ff89291679..e4617cafb6 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -408,17 +408,24 @@ let add_section () =
sectab := ([],(Names.Cmap.empty,Names.Mindmap.empty),
(Names.Cmap.empty,Names.Mindmap.empty)) :: !sectab
+let check_same_poly p vars =
+ let pred = function Context _ -> p = false | Variable (_, _, poly, _) -> p != poly in
+ if List.exists pred vars then
+ error "Cannot mix universe polymorphic and monomorphic declarations in sections."
+
let add_section_variable id impl poly ctx =
match !sectab with
| [] -> () (* because (Co-)Fixpoint temporarily uses local vars *)
| (vars,repl,abs)::sl ->
- sectab := (Variable (id,impl,poly,ctx)::vars,repl,abs)::sl
+ check_same_poly poly vars;
+ sectab := (Variable (id,impl,poly,ctx)::vars,repl,abs)::sl
let add_section_context ctx =
match !sectab with
| [] -> () (* because (Co-)Fixpoint temporarily uses local vars *)
| (vars,repl,abs)::sl ->
- sectab := (Context ctx :: vars,repl,abs)::sl
+ check_same_poly true vars;
+ sectab := (Context ctx :: vars,repl,abs)::sl
let extract_hyps (secs,ohyps) =
let rec aux = function
@@ -443,10 +450,11 @@ let instance_from_variable_context sign =
let named_of_variable_context ctx = List.map (fun (id,_,b,t) -> (id,b,t)) ctx
-let add_section_replacement f g hyps =
+let add_section_replacement f g poly hyps =
match !sectab with
| [] -> ()
| (vars,exps,abs)::sl ->
+ let () = check_same_poly poly vars in
let sechyps,ctx = extract_hyps (vars,hyps) in
let ctx = Univ.ContextSet.to_context ctx in
let subst, ctx = Univ.abstract_universes true ctx in
@@ -454,13 +462,13 @@ let add_section_replacement f g hyps =
sectab := (vars,f (Univ.UContext.instance ctx,args) exps,
g (sechyps,subst,ctx) abs)::sl
-let add_section_kn kn =
+let add_section_kn poly kn =
let f x (l1,l2) = (l1,Names.Mindmap.add kn x l2) in
- add_section_replacement f f
+ add_section_replacement f f poly
-let add_section_constant is_projection kn =
+let add_section_constant poly kn =
let f x (l1,l2) = (Names.Cmap.add kn x l1,l2) in
- add_section_replacement f f
+ add_section_replacement f f poly
let replacement_context () = pi2 (List.hd !sectab)
diff --git a/library/lib.mli b/library/lib.mli
index 29fc7cd24b..513c48549e 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -178,9 +178,10 @@ val is_in_section : Globnames.global_reference -> bool
val add_section_variable : Names.Id.t -> Decl_kinds.binding_kind -> Decl_kinds.polymorphic -> Univ.universe_context_set -> unit
val add_section_context : Univ.universe_context_set -> unit
-val add_section_constant : bool (* is_projection *) ->
+val add_section_constant : Decl_kinds.polymorphic ->
Names.constant -> Context.named_context -> unit
-val add_section_kn : Names.mutual_inductive -> Context.named_context -> unit
+val add_section_kn : Decl_kinds.polymorphic ->
+ Names.mutual_inductive -> Context.named_context -> unit
val replacement_context : unit -> Opaqueproof.work_list
(** {6 Discharge: decrease the section level if in the current section } *)
diff --git a/test-suite/bugs/closed/4503.v b/test-suite/bugs/closed/4503.v
new file mode 100644
index 0000000000..f54d6433d8
--- /dev/null
+++ b/test-suite/bugs/closed/4503.v
@@ -0,0 +1,37 @@
+Require Coq.Classes.RelationClasses.
+
+Class PreOrder (A : Type) (r : A -> A -> Type) : Type :=
+{ refl : forall x, r x x }.
+
+(* FAILURE 1 *)
+
+Section foo.
+ Polymorphic Universes A.
+ Polymorphic Context {A : Type@{A}} {rA : A -> A -> Prop} {PO : PreOrder A rA}.
+
+ Fail Definition foo := PO.
+End foo.
+
+
+Module ILogic.
+
+Set Universe Polymorphism.
+
+(* Logical connectives *)
+Class ILogic@{L} (A : Type@{L}) : Type := mkILogic
+{
+ lentails: A -> A -> Prop;
+ lentailsPre:> RelationClasses.PreOrder lentails
+}.
+
+
+End ILogic.
+
+Set Printing Universes.
+
+(* There is stil a problem if the class is universe polymorphic *)
+Section Embed_ILogic_Pre.
+ Polymorphic Universes A T.
+ Fail Context {A : Type@{A}} {ILA: ILogic.ILogic@{A} A}.
+
+End Embed_ILogic_Pre.
\ No newline at end of file
diff --git a/test-suite/bugs/closed/HoTT_coq_002.v b/test-suite/bugs/closed/HoTT_coq_002.v
index ba69f6b158..dba4d5998f 100644
--- a/test-suite/bugs/closed/HoTT_coq_002.v
+++ b/test-suite/bugs/closed/HoTT_coq_002.v
@@ -9,7 +9,7 @@ Section SpecializedFunctor.
(* Variable objC : Type. *)
Context `(C : SpecializedCategory objC).
- Polymorphic Record SpecializedFunctor := {
+ Record SpecializedFunctor := {
ObjectOf' : objC -> Type;
ObjectC : Object C
}.
diff --git a/test-suite/bugs/closed/HoTT_coq_020.v b/test-suite/bugs/closed/HoTT_coq_020.v
index 4938b80f9b..008fb72c4e 100644
--- a/test-suite/bugs/closed/HoTT_coq_020.v
+++ b/test-suite/bugs/closed/HoTT_coq_020.v
@@ -59,8 +59,8 @@ Polymorphic Definition FunctorFrom0 objC (C : Category objC) : Functor Cat0 C
:= Build_Functor Cat0 C (fun x => match x with end).
Section Law0.
- Variable objC : Type.
- Variable C : Category objC.
+ Polymorphic Variable objC : Type.
+ Polymorphic Variable C : Category objC.
Set Printing All.
Set Printing Universes.
diff --git a/theories/Logic/Hurkens.v b/theories/Logic/Hurkens.v
index 8ded74763e..841f843c07 100644
--- a/theories/Logic/Hurkens.v
+++ b/theories/Logic/Hurkens.v
@@ -631,6 +631,8 @@ End NoRetractFromTypeToProp.
Module TypeNeqSmallType.
+Unset Universe Polymorphism.
+
Section Paradox.
(** ** Universe [U] is equal to one of its elements. *)
@@ -655,7 +657,6 @@ Proof.
reflexivity.
Qed.
-
Theorem paradox : False.
Proof.
Generic.paradox p.
--
cgit v1.2.3
From 4b1103dc38754917e12bf04feca446e02cf55f07 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 12:17:21 +0100
Subject: Fixing bug #4511: evar tactic can create non-typed evars.
---
tactics/evar_tactics.ml | 3 +++
test-suite/bugs/closed/4511.v | 3 +++
2 files changed, 6 insertions(+)
create mode 100644 test-suite/bugs/closed/4511.v
diff --git a/tactics/evar_tactics.ml b/tactics/evar_tactics.ml
index 202aca0de1..2887fc2284 100644
--- a/tactics/evar_tactics.ml
+++ b/tactics/evar_tactics.ml
@@ -71,6 +71,9 @@ let let_evar name typ =
Proofview.Goal.enter begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let env = Proofview.Goal.env gl in
+ let sigma = ref sigma in
+ let _ = Typing.sort_of env sigma typ in
+ let sigma = !sigma in
let id = match name with
| Names.Anonymous ->
let id = Namegen.id_of_name_using_hdchar env typ name in
diff --git a/test-suite/bugs/closed/4511.v b/test-suite/bugs/closed/4511.v
new file mode 100644
index 0000000000..0cdb3aee4f
--- /dev/null
+++ b/test-suite/bugs/closed/4511.v
@@ -0,0 +1,3 @@
+Goal True.
+Fail evar I.
+
--
cgit v1.2.3
From cb30837323aa462df24ad6668790f67b9bf20b5d Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 12:35:49 +0100
Subject: Fixing bug #4495: Failed assertion in metasyntax.ml.
We simply handle the "break" in error messages. Not sure it is the
proper bugfix though, we may want to be able to add breaks in such
recursive notations.
---
test-suite/bugs/closed/4495.v | 1 +
toplevel/metasyntax.ml | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
create mode 100644 test-suite/bugs/closed/4495.v
diff --git a/test-suite/bugs/closed/4495.v b/test-suite/bugs/closed/4495.v
new file mode 100644
index 0000000000..8b032db5f5
--- /dev/null
+++ b/test-suite/bugs/closed/4495.v
@@ -0,0 +1 @@
+Fail Notation "'forall' x .. y ',' P " := (forall x, .. (forall y, P) ..) (at level 200, x binder, y binder).
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index ae82b64e87..231b22e255 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -540,10 +540,15 @@ let add_break_if_none n = function
| l -> UnpCut (PpBrk(n,0)) :: l
let check_open_binder isopen sl m =
+ let pr_token = function
+ | Terminal s -> str s
+ | Break n -> str "␣"
+ | _ -> assert false
+ in
if isopen && not (List.is_empty sl) then
errorlabstrm "" (str "as " ++ pr_id m ++
str " is a non-closed binder, no such \"" ++
- prlist_with_sep spc (function Terminal s -> str s | _ -> assert false) sl
+ prlist_with_sep spc pr_token sl
++ strbrk "\" is allowed to occur.")
(* Heuristics for building default printing rules *)
--
cgit v1.2.3
From e7852396a452f446135183ec3e1743b731d781c0 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 14:18:40 +0100
Subject: Adding a test for bug #4378.
---
test-suite/bugs/closed/4378.v | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 test-suite/bugs/closed/4378.v
diff --git a/test-suite/bugs/closed/4378.v b/test-suite/bugs/closed/4378.v
new file mode 100644
index 0000000000..9d59165562
--- /dev/null
+++ b/test-suite/bugs/closed/4378.v
@@ -0,0 +1,9 @@
+Tactic Notation "epose" open_constr(a) :=
+ let a' := fresh in
+ pose a as a'.
+Tactic Notation "epose2" open_constr(a) tactic3(tac) :=
+ let a' := fresh in
+ pose a as a'.
+Goal True.
+ epose _. Undo.
+ epose2 _ idtac.
--
cgit v1.2.3
From 030ef2f015e5c592ea7599f0f98a715873c1e4d0 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 15:15:16 +0100
Subject: Fixing bug #3826: "Incompatible module types" is uninformative.
---
toplevel/himsg.ml | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index 7ddfd46cd1..89c33cb6fe 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -890,7 +890,17 @@ let explain_is_a_functor () =
str "Illegal use of a functor."
let explain_incompatible_module_types mexpr1 mexpr2 =
- str "Incompatible module types."
+ let open Declarations in
+ let rec get_arg = function
+ | NoFunctor _ -> 0
+ | MoreFunctor (_, _, ty) -> succ (get_arg ty)
+ in
+ let len1 = get_arg mexpr1.mod_type in
+ let len2 = get_arg mexpr2.mod_type in
+ if len1 <> len2 then
+ str "Incompatible module types: module expects " ++ int len2 ++
+ str " arguments, found " ++ int len1 ++ str "."
+ else str "Incompatible module types."
let explain_not_equal_module_paths mp1 mp2 =
str "Non equal modules."
--
cgit v1.2.3
From f17096fa9eff103f40e6d381ebeb4313002fa378 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 16:25:38 +0100
Subject: Fixing bug #4373: coqdep does not know about .vio files.
---
tools/coqdep_common.ml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/coqdep_common.ml b/tools/coqdep_common.ml
index 58c8e884cc..a90264e261 100644
--- a/tools/coqdep_common.ml
+++ b/tools/coqdep_common.ml
@@ -504,15 +504,15 @@ let add_caml_known phys_dir _ f =
| _ -> ()
let add_coqlib_known recur phys_dir log_dir f =
- match get_extension f [".vo"] with
- | (basename,".vo") ->
+ match get_extension f [".vo"; ".vio"] with
+ | (basename, (".vo" | ".vio")) ->
let name = log_dir@[basename] in
let paths = if recur then suffixes name else [name] in
List.iter (fun f -> Hashtbl.add coqlibKnown f ()) paths
| _ -> ()
let add_known recur phys_dir log_dir f =
- match get_extension f [".v";".vo"] with
+ match get_extension f [".v"; ".vo"; ".vio"] with
| (basename,".v") ->
let name = log_dir@[basename] in
let file = phys_dir//basename in
@@ -521,7 +521,7 @@ let add_known recur phys_dir log_dir f =
let paths = List.tl (suffixes name) in
let iter n = safe_hash_add compare_file clash_v vKnown (n, (file, false)) in
List.iter iter paths
- | (basename,".vo") when not(!option_boot) ->
+ | (basename, (".vo" | ".vio")) when not(!option_boot) ->
let name = log_dir@[basename] in
let paths = if recur then suffixes name else [name] in
List.iter (fun f -> Hashtbl.add coqlibKnown f ()) paths
--
cgit v1.2.3
From 5361b02a96704a226b713b6040b67ca01de808fa Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 24 Jan 2016 18:00:34 +0100
Subject: Tentative fix for bug #4522: Incorrect "Warning..." on windows.
---
tools/coq_makefile.ml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 478cf8875a..c4b7618270 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -99,7 +99,13 @@ let string_prefix a b =
let is_prefix dir1 dir2 =
let l1 = String.length dir1 in
let l2 = String.length dir2 in
- dir1 = dir2 || (l1 < l2 && String.sub dir2 0 l1 = dir1 && dir2.[l1] = '/')
+ let sep = Filename.dir_sep in
+ if dir1 = dir2 then true
+ else if l1 + String.length sep <= l2 then
+ let dir1' = String.sub dir2 0 l1 in
+ let sep' = String.sub dir2 l1 (String.length sep) in
+ dir1' = dir1 && sep' = sep
+ else false
let physical_dir_of_logical_dir ldir =
let le = String.length ldir - 1 in
--
cgit v1.2.3
From 40cc1067dc5353d43ea2f6643cd8ca954e3e8afa Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Tue, 26 Jan 2016 17:22:08 +0100
Subject: Fixing bde12b70 about reporting ill-formed constructor.
For instance, in
Inductive I : nat -> nat -> Prop := C : forall z, let '(x,y) := z in x + y = 0.
the computation of the number of arguments to I was made wrong in bde12b70.
---
kernel/indtypes.ml | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index f9c2a7b0d5..49e8583158 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -336,7 +336,7 @@ let typecheck_inductive env mie =
type ill_formed_ind =
| LocalNonPos of int
| LocalNotEnoughArgs of int
- | LocalNotConstructor of rel_context * constr list
+ | LocalNotConstructor of rel_context * int
| LocalNonPar of int * int * int
exception IllFormedInd of ill_formed_ind
@@ -355,11 +355,10 @@ let explain_ind_err id ntyp env nbpar c err =
| LocalNotEnoughArgs kt ->
raise (InductiveError
(NotEnoughArgs (env,c',mkRel (kt+nbpar))))
- | LocalNotConstructor (paramsctxt,args)->
+ | LocalNotConstructor (paramsctxt,nargs)->
let nparams = rel_context_nhyps paramsctxt in
raise (InductiveError
- (NotConstructor (env,id,c',mkRel (ntyp+nbpar),nparams,
- List.length args - nparams)))
+ (NotConstructor (env,id,c',mkRel (ntyp+nbpar),nparams,nargs)))
| LocalNonPar (n,i,l) ->
raise (InductiveError
(NonPar (env,c',n,mkRel i, mkRel (l+nbpar))))
@@ -548,7 +547,7 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
begin match hd with
| Rel j when Int.equal j (n + ntypes - i - 1) ->
check_correct_par ienv hyps (ntypes - i) largs
- | _ -> raise (IllFormedInd (LocalNotConstructor(hyps,largs)))
+ | _ -> raise (IllFormedInd (LocalNotConstructor(hyps,nargs)))
end
else
if not (List.for_all (noccur_between n ntypes) largs)
--
cgit v1.2.3
From 22a2cc1897f0d9f568ebfb807673e84f6ada491a Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 27 Jan 2016 09:36:47 +0100
Subject: Fix bug #4537: Coq 8.5 is slower in typeclass resolution.
The performance enhancement introduced by a895b2c0 for non-polymorphic hints
was actually causing a huge regression in the polymorphic case (and was marked
as such). We fix this by only substituting the metas from the evarmap instead
of the whole evarmap.
---
pretyping/evd.ml | 4 ++++
pretyping/evd.mli | 1 +
tactics/auto.ml | 13 ++++++++-----
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/pretyping/evd.ml b/pretyping/evd.ml
index 01083142b7..5441145189 100644
--- a/pretyping/evd.ml
+++ b/pretyping/evd.ml
@@ -1467,6 +1467,10 @@ let map_metas_fvalue f evd =
in
set_metas evd (Metamap.smartmap map evd.metas)
+let map_metas f evd =
+ let map cl = map_clb f cl in
+ set_metas evd (Metamap.smartmap map evd.metas)
+
let meta_opt_fvalue evd mv =
match Metamap.find mv evd.metas with
| Clval(_,b,_) -> Some b
diff --git a/pretyping/evd.mli b/pretyping/evd.mli
index 0b4f185368..9cfca02ed8 100644
--- a/pretyping/evd.mli
+++ b/pretyping/evd.mli
@@ -455,6 +455,7 @@ val meta_merge : ?with_univs:bool -> evar_map -> evar_map -> evar_map
val undefined_metas : evar_map -> metavariable list
val map_metas_fvalue : (constr -> constr) -> evar_map -> evar_map
+val map_metas : (constr -> constr) -> evar_map -> evar_map
type metabinding = metavariable * constr * instance_status
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 2d92387c03..647ff97148 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -85,11 +85,14 @@ let connect_hint_clenv poly (c, _, ctx) clenv gl =
let (subst, ctx) = Universes.fresh_universe_context_set_instance ctx in
let map c = Vars.subst_univs_level_constr subst c in
let evd = Evd.merge_context_set Evd.univ_flexible evd ctx in
- let clenv = { clenv with evd = evd ; env = Proofview.Goal.env gl } in
- (** FIXME: We're being inefficient here because we substitute the whole
- evar map instead of just its metas, which are the only ones
- mentioning the old universes. *)
- Clenv.map_clenv map clenv, map c
+ (** Only metas are mentioning the old universes. *)
+ let clenv = {
+ templval = Evd.map_fl map clenv.templval;
+ templtyp = Evd.map_fl map clenv.templtyp;
+ evd = Evd.map_metas map evd;
+ env = Proofview.Goal.env gl;
+ } in
+ clenv, map c
else
let evd = Evd.merge_context_set Evd.univ_flexible evd ctx in
{ clenv with evd = evd ; env = Proofview.Goal.env gl }, c
--
cgit v1.2.3
From e93b9402823cbb9d4713974c51b89d77a7f83b95 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 1 Feb 2016 18:34:48 +0100
Subject: Infering atomic ML entries from their grammar.
---
grammar/tacextend.ml4 | 48 +------------------------------------------
toplevel/metasyntax.ml | 54 +++++++++++++++++++++++++++++++++++++++++++------
toplevel/metasyntax.mli | 4 +---
3 files changed, 50 insertions(+), 56 deletions(-)
diff --git a/grammar/tacextend.ml4 b/grammar/tacextend.ml4
index cca734720f..ef7cdbfa3a 100644
--- a/grammar/tacextend.ml4
+++ b/grammar/tacextend.ml4
@@ -86,14 +86,6 @@ let make_prod_item = function
let mlexpr_of_clause cl =
mlexpr_of_list (fun (a,_,_) -> mlexpr_of_list make_prod_item a) cl
-let rec make_tags loc = function
- | [] -> <:expr< [] >>
- | ExtNonTerminal (t, _, p) :: l ->
- let l = make_tags loc l in
- let t = mlexpr_of_argtype loc t in
- <:expr< [ $t$ :: $l$ ] >>
- | _::l -> make_tags loc l
-
let make_one_printing_rule (pt,_,e) =
let level = mlexpr_of_int 0 in (* only level 0 supported here *)
let loc = MLast.loc_of_expr e in
@@ -103,41 +95,6 @@ let make_one_printing_rule (pt,_,e) =
let make_printing_rule r = mlexpr_of_list make_one_printing_rule r
-let make_empty_check = function
-| ExtNonTerminal (t, e, _)->
- let is_extra = match t with ExtraArgType _ -> true | _ -> false in
- if is_possibly_empty e || is_extra then
- (* This possibly parses epsilon *)
- let wit = make_wit loc t in
- let rawwit = make_rawwit loc t in
- <:expr<
- match Genarg.default_empty_value $wit$ with
- [ None -> raise Exit
- | Some v ->
- Tacintern.intern_genarg Tacintern.fully_empty_glob_sign
- (Genarg.in_gen $rawwit$ v) ] >>
- else
- (* This does not parse epsilon (this Exit is static time) *)
- raise Exit
-| ExtTerminal _ ->
- (* Idem *)
- raise Exit
-
-let rec possibly_atomic loc = function
-| [] -> []
-| ((ExtNonTerminal _ :: _ | []), _, _) :: rem ->
- (** This is not parsed by the TACTIC EXTEND rules *)
- assert false
-| (ExtTerminal s :: prods, _, _) :: rem ->
- let entry =
- try
- let l = List.map make_empty_check prods in
- let l = mlexpr_of_list (fun x -> x) l in
- (s, <:expr< try Some $l$ with [ Exit -> None ] >>)
- with Exit -> (s, <:expr< None >>)
- in
- entry :: possibly_atomic loc rem
-
(** Special treatment of constr entries *)
let is_constr_gram = function
| ExtTerminal _ -> false
@@ -193,10 +150,7 @@ let declare_tactic loc s c cl = match cl with
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
let pp = make_printing_rule cl in
let gl = mlexpr_of_clause cl in
- let atom =
- mlexpr_of_list (mlexpr_of_pair mlexpr_of_string (fun x -> x))
- (possibly_atomic loc cl) in
- let obj = <:expr< fun () -> Metasyntax.add_ml_tactic_notation $se$ $gl$ $atom$ >> in
+ let obj = <:expr< fun () -> Metasyntax.add_ml_tactic_notation $se$ $gl$ >> in
declare_str_items loc
[ <:str_item< do {
try do {
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index 5a47fc0ea1..0d002aa8e9 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -149,8 +149,6 @@ let add_tactic_notation (local,n,prods,e) =
(**********************************************************************)
(* ML Tactic entries *)
-type atomic_entry = string * Genarg.glob_generic_argument list option
-
type ml_tactic_grammar_obj = {
mltacobj_name : Tacexpr.ml_tactic_name;
(** ML-side unique name *)
@@ -158,12 +156,56 @@ type ml_tactic_grammar_obj = {
(** Grammar rules generating the ML tactic. *)
}
+exception NonEmptyArgument
+
+let default_empty_value wit = match Genarg.default_empty_value wit with
+| None -> raise NonEmptyArgument
+| Some v -> v
+
+let rec empty_value : type a b c s. (a, b, c) Genarg.genarg_type -> (s, a) entry_key -> a =
+fun wit key -> match key with
+| Alist1 key ->
+ begin match wit with
+ | Genarg.ListArg wit -> [empty_value wit key]
+ | Genarg.ExtraArg _ -> default_empty_value wit
+ end
+| Alist1sep (key, _) ->
+ begin match wit with
+ | Genarg.ListArg wit -> [empty_value wit key]
+ | Genarg.ExtraArg _ -> default_empty_value wit
+ end
+| Alist0 _ -> []
+| Alist0sep (_, _) -> []
+| Amodifiers _ -> []
+| Aopt _ -> None
+| Aentry _ -> default_empty_value wit
+| Aentryl (_, _) -> default_empty_value wit
+
+| Atoken _ -> raise NonEmptyArgument
+| Aself -> raise NonEmptyArgument
+| Anext -> raise NonEmptyArgument
+
(** ML tactic notations whose use can be restricted to an identifier are added
as true Ltac entries. *)
let extend_atomic_tactic name entries =
- let add_atomic i (id, args) = match args with
+ let map_prod prods =
+ let (hd, rem) = match prods with
+ | GramTerminal s :: rem -> (s, rem)
+ | _ -> assert false (** Not handled by the ML extension syntax *)
+ in
+ let empty_value = function
+ | GramTerminal s -> raise NonEmptyArgument
+ | GramNonTerminal (_, typ, e) ->
+ let Genarg.Rawwit wit = typ in
+ let def = Genarg.in_gen typ (empty_value wit e) in
+ Tacintern.intern_genarg Tacintern.fully_empty_glob_sign def
+ in
+ try Some (hd, List.map empty_value rem) with NonEmptyArgument -> None
+ in
+ let entries = List.map map_prod entries in
+ let add_atomic i args = match args with
| None -> ()
- | Some args ->
+ | Some (id, args) ->
let open Tacexpr in
let args = List.map (fun a -> TacGeneric a) args in
let entry = { mltac_name = name; mltac_index = i } in
@@ -186,13 +228,13 @@ let inMLTacticGrammar : ml_tactic_grammar_obj -> obj =
subst_function = (fun (_, o) -> o);
}
-let add_ml_tactic_notation name prods atomic =
+let add_ml_tactic_notation name prods =
let obj = {
mltacobj_name = name;
mltacobj_prod = prods;
} in
Lib.add_anonymous_leaf (inMLTacticGrammar obj);
- extend_atomic_tactic name atomic
+ extend_atomic_tactic name prods
(**********************************************************************)
(* Printing grammar entries *)
diff --git a/toplevel/metasyntax.mli b/toplevel/metasyntax.mli
index 826886f678..5d01405b27 100644
--- a/toplevel/metasyntax.mli
+++ b/toplevel/metasyntax.mli
@@ -21,10 +21,8 @@ val add_tactic_notation :
locality_flag * int * grammar_tactic_prod_item_expr list * raw_tactic_expr ->
unit
-type atomic_entry = string * Genarg.glob_generic_argument list option
-
val add_ml_tactic_notation : ml_tactic_name ->
- Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list list -> atomic_entry list -> unit
+ Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list list -> unit
(** Adding a (constr) notation in the environment*)
--
cgit v1.2.3
From 292e205138ca11c3dce37d48cb34ef4172f6fa06 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Tue, 2 Feb 2016 10:28:16 +0100
Subject: Removing a source of type-unsafeness in Pcoq.
---
parsing/egramcoq.ml | 18 +++++++++---------
parsing/pcoq.mli | 3 ---
2 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/parsing/egramcoq.ml b/parsing/egramcoq.ml
index e9c3a7073d..465073b7aa 100644
--- a/parsing/egramcoq.ml
+++ b/parsing/egramcoq.ml
@@ -387,16 +387,16 @@ let create_ltac_quotation name cast wit e =
let () = ltac_quotations := String.Set.add name !ltac_quotations in
(* let level = Some "1" in *)
let level = None in
- let assoc = Some (of_coq_assoc Extend.RightA) in
- let rule = [
- gram_token_of_string name;
- gram_token_of_string ":";
- symbol_of_prod_entry_key (Aentry (name_of_entry e));
- ] in
+ let assoc = Some Extend.RightA in
+ let rule =
+ Next (Next (Next (Stop,
+ Atoken (Lexer.terminal name)),
+ Atoken (Lexer.terminal ":")),
+ Aentry (name_of_entry e))
+ in
let action v _ _ loc =
- let loc = !@loc in
let arg = TacGeneric (Genarg.in_gen (Genarg.rawwit wit) (cast (loc, v))) in
TacArg (loc, arg)
in
- let gram = (level, assoc, [rule, Gram.action action]) in
- maybe_uncurry (Gram.extend Tactic.tactic_expr) (None, [gram])
+ let gram = (level, assoc, [Rule (rule, action)]) in
+ Pcoq.grammar_extend Tactic.tactic_expr None (None, [gram])
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 9b3a96975f..b26c3044bd 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -274,9 +274,6 @@ val name_of_entry : 'a Gram.entry -> 'a Entry.t
(** Binding general entry keys to symbols *)
-val symbol_of_prod_entry_key :
- ('self, 'a) entry_key -> Gram.symbol
-
type 's entry_name = EntryName :
'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's entry_name
--
cgit v1.2.3
From 7eeec8f82d96a71929289b0b9401a1b96e1d3dda Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 10:26:28 +0100
Subject: More compact representation for evar resolvability flag.
This patch was proposed by JH in bug report #4547.
---
pretyping/typeclasses.ml | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 3be98a1ae2..bb475cc554 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -495,15 +495,18 @@ let is_instance = function
let resolvable = Store.field ()
let set_resolvable s b =
- Store.set s resolvable b
+ if b then Store.remove s resolvable
+ else Store.set s resolvable ()
let is_resolvable evi =
assert (match evi.evar_body with Evar_empty -> true | _ -> false);
- Option.default true (Store.get evi.evar_extra resolvable)
+ Option.is_empty (Store.get evi.evar_extra resolvable)
let mark_resolvability_undef b evi =
- let t = Store.set evi.evar_extra resolvable b in
- { evi with evar_extra = t }
+ if is_resolvable evi = b then evi
+ else
+ let t = set_resolvable evi.evar_extra b in
+ { evi with evar_extra = t }
let mark_resolvability b evi =
assert (match evi.evar_body with Evar_empty -> true | _ -> false);
--
cgit v1.2.3
From 0ee0b7d2f2365da6e63bc2e94d66f9c5fe1ebe6a Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 11:28:34 +0100
Subject: Opacifying the type of evar naming structure in Evd.
---
pretyping/evd.ml | 124 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 74 insertions(+), 50 deletions(-)
diff --git a/pretyping/evd.ml b/pretyping/evd.ml
index 5441145189..8be09a7821 100644
--- a/pretyping/evd.ml
+++ b/pretyping/evd.ml
@@ -575,34 +575,28 @@ type evar_constraint = conv_pb * Environ.env * constr * constr
module EvMap = Evar.Map
-type evar_map = {
- (** Existential variables *)
- defn_evars : evar_info EvMap.t;
- undf_evars : evar_info EvMap.t;
- evar_names : Id.t EvMap.t * existential_key Idmap.t;
- (** Universes *)
- universes : evar_universe_context;
- (** Conversion problems *)
- conv_pbs : evar_constraint list;
- last_mods : Evar.Set.t;
- (** Metas *)
- metas : clbinding Metamap.t;
- (** Interactive proofs *)
- effects : Safe_typing.private_constants;
- future_goals : Evar.t list; (** list of newly created evars, to be
- eventually turned into goals if not solved.*)
- principal_future_goal : Evar.t option; (** if [Some e], [e] must be
- contained
- [future_goals]. The evar
- [e] will inherit
- properties (now: the
- name) of the evar which
- will be instantiated with
- a term containing [e]. *)
- extras : Store.t;
-}
+module EvNames :
+sig
-(*** Lifting primitive from Evar.Map. ***)
+open Misctypes
+
+type t
+
+val empty : t
+val add_name_newly_undefined : intro_pattern_naming_expr -> Evar.t -> evar_info -> t -> t
+val add_name_undefined : intro_pattern_naming_expr -> Evar.t -> evar_info -> t -> t
+val remove_name_defined : Evar.t -> t -> t
+val rename : Evar.t -> Id.t -> t -> t
+val reassign_name_defined : Evar.t -> Evar.t -> t -> t
+val ident : Evar.t -> t -> Id.t
+val key : Id.t -> t -> Evar.t
+
+end =
+struct
+
+type t = Id.t EvMap.t * existential_key Idmap.t
+
+let empty = (EvMap.empty, Idmap.empty)
let add_name_newly_undefined naming evk evi (evtoid,idtoev) =
let id = match naming with
@@ -630,29 +624,65 @@ let remove_name_defined evk (evtoid,idtoev) =
let id = EvMap.find evk evtoid in
(EvMap.remove evk evtoid, Idmap.remove id idtoev)
-let remove_name_possibly_already_defined evk evar_names =
- try remove_name_defined evk evar_names
- with Not_found -> evar_names
-
-let rename evk id evd =
- let (evtoid,idtoev) = evd.evar_names in
+let rename evk id (evtoid, idtoev) =
let id' = EvMap.find evk evtoid in
if Idmap.mem id idtoev then anomaly (str "Evar name already in use");
- { evd with evar_names =
- (EvMap.add evk id evtoid (* overwrite old name *),
- Idmap.add id evk (Idmap.remove id' idtoev)) }
+ (EvMap.add evk id evtoid (* overwrite old name *), Idmap.add id evk (Idmap.remove id' idtoev))
let reassign_name_defined evk evk' (evtoid,idtoev) =
let id = EvMap.find evk evtoid in
(EvMap.add evk' id (EvMap.remove evk evtoid),
Idmap.add id evk' (Idmap.remove id idtoev))
+let ident evk (evtoid, _) =
+ try EvMap.find evk evtoid
+ with Not_found ->
+ (* Unnamed (non-dependent) evar *)
+ add_suffix (Id.of_string "X") (string_of_int (Evar.repr evk))
+
+let key id (_, idtoev) =
+ Idmap.find id idtoev
+
+end
+
+type evar_map = {
+ (** Existential variables *)
+ defn_evars : evar_info EvMap.t;
+ undf_evars : evar_info EvMap.t;
+ evar_names : EvNames.t;
+ (** Universes *)
+ universes : evar_universe_context;
+ (** Conversion problems *)
+ conv_pbs : evar_constraint list;
+ last_mods : Evar.Set.t;
+ (** Metas *)
+ metas : clbinding Metamap.t;
+ (** Interactive proofs *)
+ effects : Safe_typing.private_constants;
+ future_goals : Evar.t list; (** list of newly created evars, to be
+ eventually turned into goals if not solved.*)
+ principal_future_goal : Evar.t option; (** if [Some e], [e] must be
+ contained
+ [future_goals]. The evar
+ [e] will inherit
+ properties (now: the
+ name) of the evar which
+ will be instantiated with
+ a term containing [e]. *)
+ extras : Store.t;
+}
+
+(*** Lifting primitive from Evar.Map. ***)
+
+let rename evk id evd =
+ { evd with evar_names = EvNames.rename evk id evd.evar_names }
+
let add d e i = match i.evar_body with
| Evar_empty ->
- let evar_names = add_name_undefined Misctypes.IntroAnonymous e i d.evar_names in
+ let evar_names = EvNames.add_name_undefined Misctypes.IntroAnonymous e i d.evar_names in
{ d with undf_evars = EvMap.add e i d.undf_evars; evar_names }
| Evar_defined _ ->
- let evar_names = remove_name_possibly_already_defined e d.evar_names in
+ let evar_names = try EvNames.remove_name_defined e d.evar_names with Not_found -> d.evar_names in
{ d with defn_evars = EvMap.add e i d.defn_evars; evar_names }
let remove d e =
@@ -783,7 +813,7 @@ let empty = {
last_mods = Evar.Set.empty;
metas = Metamap.empty;
effects = Safe_typing.empty_private_constants;
- evar_names = (EvMap.empty,Idmap.empty); (* id<->key for undefined evars *)
+ evar_names = EvNames.empty; (* id<->key for undefined evars *)
future_goals = [];
principal_future_goal = None;
extras = Store.empty;
@@ -819,14 +849,8 @@ let add_conv_pb ?(tail=false) pb d =
let evar_source evk d = (find d evk).evar_source
-let evar_ident evk evd =
- try EvMap.find evk (fst evd.evar_names)
- with Not_found ->
- (* Unnamed (non-dependent) evar *)
- add_suffix (Id.of_string "X") (string_of_int (Evar.repr evk))
-
-let evar_key id evd =
- Idmap.find id (snd evd.evar_names)
+let evar_ident evk evd = EvNames.ident evk evd.evar_names
+let evar_key id evd = EvNames.key id evd.evar_names
let define_aux def undef evk body =
let oldinfo =
@@ -848,7 +872,7 @@ let define evk body evd =
| [] -> evd.last_mods
| _ -> Evar.Set.add evk evd.last_mods
in
- let evar_names = remove_name_defined evk evd.evar_names in
+ let evar_names = EvNames.remove_name_defined evk evd.evar_names in
{ evd with defn_evars; undf_evars; last_mods; evar_names }
let evar_declare hyps evk ty ?(src=(Loc.ghost,Evar_kinds.InternalHole))
@@ -868,7 +892,7 @@ let evar_declare hyps evk ty ?(src=(Loc.ghost,Evar_kinds.InternalHole))
evar_candidates = candidates;
evar_extra = store; }
in
- let evar_names = add_name_newly_undefined naming evk evar_info evd.evar_names in
+ let evar_names = EvNames.add_name_newly_undefined naming evk evar_info evd.evar_names in
{ evd with undf_evars = EvMap.add evk evar_info evd.undf_evars; evar_names }
let restrict evk evk' filter ?candidates evd =
@@ -877,7 +901,7 @@ let restrict evk evk' filter ?candidates evd =
{ evar_info with evar_filter = filter;
evar_candidates = candidates;
evar_extra = Store.empty } in
- let evar_names = reassign_name_defined evk evk' evd.evar_names in
+ let evar_names = EvNames.reassign_name_defined evk evk' evd.evar_names in
let ctxt = Filter.filter_list filter (evar_context evar_info) in
let id_inst = Array.map_of_list (fun (id,_,_) -> mkVar id) ctxt in
let body = mkEvar(evk',id_inst) in
--
cgit v1.2.3
From e9675e068f9e0e92bab05c030fb4722b146123b8 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 16:20:46 +0100
Subject: Adding a "get" primitive to map signature.
It is similar to find but raises an assertion failure instead of a Not_found
when the element is not encountered. Using it will give stronger invariants.
---
lib/cMap.ml | 2 ++
lib/cMap.mli | 3 +++
lib/hMap.ml | 2 ++
3 files changed, 7 insertions(+)
diff --git a/lib/cMap.ml b/lib/cMap.ml
index d1a32b7aa5..4b058380c6 100644
--- a/lib/cMap.ml
+++ b/lib/cMap.ml
@@ -25,6 +25,7 @@ module type ExtS =
sig
include CSig.MapS
module Set : CSig.SetS with type elt = key
+ val get : key -> 'a t -> 'a
val update : key -> 'a -> 'a t -> 'a t
val modify : key -> (key -> 'a -> 'a) -> 'a t -> 'a t
val domain : 'a t -> Set.t
@@ -207,4 +208,5 @@ module Make(M : Map.OrderedType) =
struct
include Map.Make(M)
include MapExt(M)
+ let get k m = try find k m with Not_found -> assert false
end
diff --git a/lib/cMap.mli b/lib/cMap.mli
index 464dc503be..3ef7fa2c8a 100644
--- a/lib/cMap.mli
+++ b/lib/cMap.mli
@@ -31,6 +31,9 @@ sig
module Set : CSig.SetS with type elt = key
(** Sets used by the domain function *)
+ val get : key -> 'a t -> 'a
+ (** Same as {!find} but fails an assertion instead of raising [Not_found] *)
+
val update : key -> 'a -> 'a t -> 'a t
(** Same as [add], but expects the key to be present, and thus faster.
@raise Not_found when the key is unbound in the map. *)
diff --git a/lib/hMap.ml b/lib/hMap.ml
index 220adc28f3..778c366fd5 100644
--- a/lib/hMap.ml
+++ b/lib/hMap.ml
@@ -286,6 +286,8 @@ struct
let m = Int.Map.find h s in
Map.find k m
+ let get k s = try find k s with Not_found -> assert false
+
let split k s = assert false (** Cannot be implemented efficiently *)
let map f s =
--
cgit v1.2.3
From 62c141be71dd3c542824c19429eac0fdd686c9cb Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 18:39:15 +0100
Subject: Optimizing the computation of frozen evars.
---
pretyping/unification.ml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index f97f6fbc57..6cb1bc7028 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -1450,9 +1450,7 @@ let default_matching_core_flags sigma =
check_applied_meta_types = true;
use_pattern_unification = false;
use_meta_bound_pattern_unification = false;
- frozen_evars =
- fold_undefined (fun evk _ evars -> Evar.Set.add evk evars)
- sigma Evar.Set.empty;
+ frozen_evars = Evar.Map.domain (Evd.undefined_map sigma);
restrict_conv_on_strict_subterms = false;
modulo_betaiota = false;
modulo_eta = false;
--
cgit v1.2.3
From 5d9eaa378277ed96456fec5a2037a8da4f38c8e0 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 20:07:33 +0100
Subject: Optimizing the universes_of_constr_function.
Instead of relying on a costly set union, we take advantage of the fact
that instances are small compared to the set of universes.
---
library/universes.ml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/library/universes.ml b/library/universes.ml
index 7972c478ad..3bebdafc78 100644
--- a/library/universes.ml
+++ b/library/universes.ml
@@ -959,10 +959,10 @@ let universes_of_constr c =
let rec aux s c =
match kind_of_term c with
| Const (_, u) | Ind (_, u) | Construct (_, u) ->
- LSet.union (Instance.levels u) s
+ LSet.fold LSet.add (Instance.levels u) s
| Sort u when not (Sorts.is_small u) ->
let u = univ_of_sort u in
- LSet.union (Universe.levels u) s
+ LSet.fold LSet.add (Universe.levels u) s
| _ -> fold_constr aux s c
in aux LSet.empty c
--
cgit v1.2.3
From 68db732f12980e592c610085192d93457f312607 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Mon, 8 Feb 2016 11:19:09 +0100
Subject: Improving error message with missing patterns in the presence of
multiple patterns.
---
toplevel/himsg.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index 89c33cb6fe..c0a99fe75c 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -1207,7 +1207,7 @@ let explain_unused_clause env pats =
let explain_non_exhaustive env pats =
str "Non exhaustive pattern-matching: no clause found for " ++
str (String.plural (List.length pats) "pattern") ++
- spc () ++ hov 0 (pr_sequence pr_cases_pattern pats)
+ spc () ++ hov 0 (prlist_with_sep pr_comma pr_cases_pattern pats)
let explain_cannot_infer_predicate env sigma typs =
let env = make_all_name_different env in
--
cgit v1.2.3
From 34ef02fac1110673ae74c41c185c228ff7876de2 Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Fri, 29 Jan 2016 10:13:12 +0100
Subject: CLEANUP: Context.{Rel,Named}.Declaration.t
Originally, rel-context was represented as:
Context.rel_context = Names.Name.t * Constr.t option * Constr.t
Now it is represented as:
Context.Rel.t = LocalAssum of Names.Name.t * Constr.t
| LocalDef of Names.Name.t * Constr.t * Constr.t
Originally, named-context was represented as:
Context.named_context = Names.Id.t * Constr.t option * Constr.t
Now it is represented as:
Context.Named.t = LocalAssum of Names.Id.t * Constr.t
| LocalDef of Names.Id.t * Constr.t * Constr.t
Motivation:
(1) In "tactics/hipattern.ml4" file we define "test_strict_disjunction"
function which looked like this:
let test_strict_disjunction n lc =
Array.for_all_i (fun i c ->
match (prod_assum (snd (decompose_prod_n_assum n c))) with
| [_,None,c] -> isRel c && Int.equal (destRel c) (n - i)
| _ -> false) 0 lc
Suppose that you do not know about rel-context and named-context.
(that is the case of people who just started to read the source code)
Merlin would tell you that the type of the value you are destructing
by "match" is:
'a * 'b option * Constr.t (* worst-case scenario *)
or
Named.Name.t * Constr.t option * Constr.t (* best-case scenario (?) *)
To me, this is akin to wearing an opaque veil.
It is hard to figure out the meaning of the values you are looking at.
In particular, it is hard to discover the connection between the value
we are destructing above and the datatypes and functions defined
in the "kernel/context.ml" file.
In this case, the connection is there, but it is not visible
(between the function above and the "Context" module).
------------------------------------------------------------------------
Now consider, what happens when the reader see the same function
presented in the following form:
let test_strict_disjunction n lc =
Array.for_all_i (fun i c ->
match (prod_assum (snd (decompose_prod_n_assum n c))) with
| [LocalAssum (_,c)] -> isRel c && Int.equal (destRel c) (n - i)
| _ -> false) 0 lc
If the reader haven't seen "LocalAssum" before, (s)he can use Merlin
to jump to the corresponding definition and learn more.
In this case, the connection is there, and it is directly visible
(between the function above and the "Context" module).
(2) Also, if we already have the concepts such as:
- local declaration
- local assumption
- local definition
and we describe these notions meticulously in the Reference Manual,
then it is a real pity not to reinforce the connection
of the actual code with the abstract description we published.
---
checker/cic.mli | 3 +-
checker/closure.ml | 8 +-
checker/declarations.ml | 13 +-
checker/environ.ml | 2 +-
checker/indtypes.ml | 20 +-
checker/inductive.ml | 48 ++--
checker/reduction.ml | 10 +-
checker/term.ml | 47 ++--
checker/term.mli | 2 +-
checker/typeops.ml | 16 +-
checker/values.ml | 6 +-
dev/doc/changes.txt | 31 ++-
engine/evd.ml | 27 +-
engine/namegen.ml | 15 +-
engine/termops.ml | 199 ++++++++------
engine/termops.mli | 2 +-
ide/ide_slave.ml | 11 +-
interp/constrextern.ml | 4 +-
interp/constrintern.ml | 9 +-
interp/implicit_quantifiers.ml | 19 +-
interp/implicit_quantifiers.mli | 4 +-
kernel/closure.ml | 10 +-
kernel/context.ml | 364 ++++++++++++++++++-------
kernel/context.mli | 151 +++++++---
kernel/cooking.ml | 7 +-
kernel/csymtable.ml | 10 +-
kernel/declareops.ml | 35 ++-
kernel/environ.ml | 64 ++---
kernel/fast_typeops.ml | 17 +-
kernel/indtypes.ml | 35 +--
kernel/inductive.ml | 50 ++--
kernel/nativecode.ml | 17 +-
kernel/nativelambda.ml | 3 +-
kernel/pre_env.ml | 7 +-
kernel/reduction.ml | 11 +-
kernel/safe_typing.ml | 8 +-
kernel/term.ml | 111 ++++----
kernel/term_typing.ml | 24 +-
kernel/typeops.ml | 39 +--
kernel/vars.ml | 11 +-
lib/util.ml | 1 +
lib/util.mli | 1 +
library/decls.ml | 10 +-
library/heads.ml | 11 +-
library/impargs.ml | 15 +-
library/lib.ml | 9 +-
plugins/cc/ccalgo.ml | 2 +-
plugins/cc/cctac.ml | 8 +-
plugins/decl_mode/decl_interp.ml | 2 +-
plugins/decl_mode/decl_mode.ml | 2 +-
plugins/decl_mode/decl_proof_instr.ml | 25 +-
plugins/derive/derive.ml | 4 +-
plugins/extraction/extraction.ml | 9 +-
plugins/firstorder/formula.ml | 11 +-
plugins/firstorder/instances.ml | 3 +-
plugins/firstorder/rules.ml | 6 +-
plugins/fourier/fourierR.ml | 6 +-
plugins/funind/functional_principles_proofs.ml | 60 ++--
plugins/funind/functional_principles_types.ml | 39 +--
plugins/funind/glob_term_to_relation.ml | 52 ++--
plugins/funind/indfun.ml | 8 +-
plugins/funind/invfun.ml | 40 +--
plugins/funind/merge.ml | 24 +-
plugins/funind/recdef.ml | 18 +-
plugins/omega/coq_omega.ml | 37 ++-
plugins/rtauto/refl_tauto.ml | 5 +-
plugins/rtauto/refl_tauto.mli | 2 +-
pretyping/cases.ml | 196 +++++++------
pretyping/coercion.ml | 11 +-
pretyping/constr_matching.ml | 15 +-
pretyping/detyping.ml | 36 ++-
pretyping/evarconv.ml | 34 ++-
pretyping/evarsolve.ml | 131 +++++----
pretyping/evarutil.ml | 94 ++++---
pretyping/find_subterm.ml | 23 +-
pretyping/indrec.ml | 48 ++--
pretyping/inductiveops.ml | 11 +-
pretyping/nativenorm.ml | 21 +-
pretyping/patternops.ml | 7 +-
pretyping/pretyping.ml | 62 ++---
pretyping/reductionops.ml | 36 +--
pretyping/retyping.ml | 22 +-
pretyping/tacred.ml | 54 ++--
pretyping/typeclasses.ml | 37 ++-
pretyping/typing.ml | 13 +-
pretyping/unification.ml | 27 +-
pretyping/vnorm.ml | 14 +-
printing/prettyp.ml | 31 ++-
printing/prettyp.mli | 2 +-
printing/printer.ml | 18 +-
proofs/goal.ml | 5 +-
proofs/logic.ml | 51 ++--
proofs/proof_global.ml | 7 +-
proofs/proof_using.ml | 8 +-
proofs/proofview.ml | 22 +-
proofs/refiner.ml | 6 +-
proofs/tacmach.ml | 17 +-
stm/lemmas.ml | 11 +-
stm/stm.ml | 6 +-
tactics/auto.ml | 2 +-
tactics/autorewrite.ml | 5 +-
tactics/class_tactics.ml | 11 +-
tactics/contradiction.ml | 8 +-
tactics/elim.ml | 4 +-
tactics/eqschemes.ml | 29 +-
tactics/equality.ml | 36 +--
tactics/evar_tactics.ml | 7 +-
tactics/hints.ml | 8 +-
tactics/hipattern.ml4 | 10 +-
tactics/inv.ml | 21 +-
tactics/leminv.ml | 18 +-
tactics/rewrite.ml | 40 +--
tactics/tacinterp.ml | 6 +-
tactics/tactic_matching.ml | 14 +-
tactics/tacticals.ml | 12 +-
tactics/tactics.ml | 327 +++++++++++++---------
toplevel/assumptions.ml | 7 +-
toplevel/auto_ind_decl.ml | 43 +--
toplevel/classes.ml | 44 +--
toplevel/command.ml | 78 +++---
toplevel/discharge.ml | 12 +-
toplevel/himsg.ml | 24 +-
toplevel/indschemes.ml | 3 +-
toplevel/obligations.ml | 33 ++-
toplevel/record.ml | 74 ++---
toplevel/search.ml | 9 +-
toplevel/vernacentries.ml | 14 +-
127 files changed, 2283 insertions(+), 1572 deletions(-)
diff --git a/checker/cic.mli b/checker/cic.mli
index 041394d466..00ac2f56c3 100644
--- a/checker/cic.mli
+++ b/checker/cic.mli
@@ -111,7 +111,8 @@ type cofixpoint = constr pcofixpoint
(** {6 Type of assumptions and contexts} *)
-type rel_declaration = Name.t * constr option * constr
+type rel_declaration = LocalAssum of Name.t * constr (* name, type *)
+ | LocalDef of Name.t * constr * constr (* name, value, type *)
type rel_context = rel_declaration list
(** The declarations below in .vo should be outside sections,
diff --git a/checker/closure.ml b/checker/closure.ml
index 400a535cf2..c2708e97d2 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -217,10 +217,10 @@ let ref_value_cache info ref =
let defined_rels flags env =
(* if red_local_const (snd flags) then*)
fold_rel_context
- (fun (id,b,t) (i,subs) ->
- match b with
- | None -> (i+1, subs)
- | Some body -> (i+1, (i,body) :: subs))
+ (fun decl (i,subs) ->
+ match decl with
+ | LocalAssum _ -> (i+1, subs)
+ | LocalDef (_,body,_) -> (i+1, (i,body) :: subs))
(rel_context env) ~init:(0,[])
(* else (0,[])*)
diff --git a/checker/declarations.ml b/checker/declarations.ml
index 32d1713a88..2f6eeba1d9 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -517,11 +517,14 @@ let map_decl_arity f g = function
| RegularArity a -> RegularArity (f a)
| TemplateArity a -> TemplateArity (g a)
-
-let subst_rel_declaration sub (id,copt,t as x) =
- let copt' = Option.smartmap (subst_mps sub) copt in
- let t' = subst_mps sub t in
- if copt == copt' && t == t' then x else (id,copt',t')
+let subst_rel_declaration sub = function
+ | LocalAssum (id,t) as x ->
+ let t' = subst_mps sub t in
+ if t == t' then x else LocalAssum (id,t')
+ | LocalDef (id,c,t) as x ->
+ let c' = subst_mps sub c in
+ let t' = subst_mps sub t in
+ if c == c' && t == t' then x else LocalDef (id,c',t')
let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
diff --git a/checker/environ.ml b/checker/environ.ml
index f8f5c29b79..7040fdda46 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -80,7 +80,7 @@ let push_rel d env =
let push_rel_context ctxt x = fold_rel_context push_rel ctxt ~init:x
let push_rec_types (lna,typarray,_) env =
- let ctxt = Array.map2_i (fun i na t -> (na, None, lift i t)) lna typarray in
+ let ctxt = Array.map2_i (fun i na t -> LocalAssum (na, lift i t)) lna typarray in
Array.fold_left (fun e assum -> push_rel assum e) env ctxt
(* Universe constraints *)
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index 2865f5bd4a..f11fa5a7ad 100644
--- a/checker/indtypes.ml
+++ b/checker/indtypes.ml
@@ -56,10 +56,10 @@ let is_constructor_head t =
let conv_ctxt_prefix env (ctx1:rel_context) ctx2 =
let rec chk env rctx1 rctx2 =
match rctx1, rctx2 with
- (_,None,ty1 as d1)::rctx1', (_,None,ty2)::rctx2' ->
+ (LocalAssum (_,ty1) as d1)::rctx1', LocalAssum (_,ty2)::rctx2' ->
conv env ty1 ty2;
chk (push_rel d1 env) rctx1' rctx2'
- | (_,Some bd1,ty1 as d1)::rctx1', (_,Some bd2,ty2)::rctx2' ->
+ | (LocalDef (_,bd1,ty1) as d1)::rctx1', LocalDef (_,bd2,ty2)::rctx2' ->
conv env ty1 ty2;
conv env bd1 bd2;
chk (push_rel d1 env) rctx1' rctx2'
@@ -94,10 +94,10 @@ let rec sorts_of_constr_args env t =
match t with
| Prod (name,c1,c2) ->
let varj = infer_type env c1 in
- let env1 = push_rel (name,None,c1) env in
+ let env1 = push_rel (LocalAssum (name,c1)) env in
varj :: sorts_of_constr_args env1 c2
| LetIn (name,def,ty,c) ->
- let env1 = push_rel (name,Some def,ty) env in
+ let env1 = push_rel (LocalDef (name,def,ty)) env in
sorts_of_constr_args env1 c
| _ when is_constructor_head t -> []
| _ -> anomaly ~label:"infos_and_sort" (Pp.str "not a positive constructor")
@@ -167,7 +167,7 @@ let typecheck_arity env params inds =
full_arity is used as argument or subject to cast, an
upper universe will be generated *)
let id = ind.mind_typename in
- let env_ar' = push_rel (Name id, None, arity) env_ar in
+ let env_ar' = push_rel (LocalAssum (Name id, arity)) env_ar in
env_ar')
env
inds in
@@ -319,7 +319,7 @@ let check_correct_par (env,n,ntypes,_) hyps l largs =
let nhyps = List.length hyps in
let rec check k index = function
| [] -> ()
- | (_,Some _,_)::hyps -> check k (index+1) hyps
+ | LocalDef (_,_,_) :: hyps -> check k (index+1) hyps
| _::hyps ->
match whd_betadeltaiota env lpar.(k) with
| Rel w when w = index -> check (k-1) (index+1) hyps
@@ -340,7 +340,7 @@ let check_rec_par (env,n,_,_) hyps nrecp largs =
| ([],_) -> ()
| (_,[]) ->
failwith "number of recursive parameters cannot be greater than the number of parameters."
- | (lp,(_,Some _,_)::hyps) -> find (index-1) (lp,hyps)
+ | (lp,LocalDef _ :: hyps) -> find (index-1) (lp,hyps)
| (p::lp,_::hyps) ->
(match whd_betadeltaiota env p with
| Rel w when w = index -> find (index-1) (lp,hyps)
@@ -370,14 +370,14 @@ let abstract_mind_lc env ntyps npars lc =
[lra] is the list of recursive tree of each variable
*)
let ienv_push_var (env, n, ntypes, lra) (x,a,ra) =
- (push_rel (x,None,a) env, n+1, ntypes, (Norec,ra)::lra)
+ (push_rel (LocalAssum (x,a)) env, n+1, ntypes, (Norec,ra)::lra)
let ienv_push_inductive (env, n, ntypes, ra_env) ((mi,u),lpar) =
let auxntyp = 1 in
let specif = lookup_mind_specif env mi in
let env' =
- push_rel (Anonymous,None,
- hnf_prod_applist env (type_of_inductive env (specif,u)) lpar) env in
+ push_rel (LocalAssum (Anonymous,
+ hnf_prod_applist env (type_of_inductive env (specif,u)) lpar)) env in
let ra_env' =
(Imbr mi,(Rtree.mk_rec_calls 1).(0)) ::
List.map (fun (r,t) -> (r,Rtree.lift 1 t)) ra_env in
diff --git a/checker/inductive.ml b/checker/inductive.ml
index 79dba4fac5..9480124211 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -88,10 +88,10 @@ let instantiate_params full t u args sign =
anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch") in
let (rem_args, subs, ty) =
fold_rel_context
- (fun (_,copt,_) (largs,subs,ty) ->
- match (copt, largs, ty) with
- | (None, a::args, Prod(_,_,t)) -> (args, a::subs, t)
- | (Some b,_,LetIn(_,_,_,t)) ->
+ (fun decl (largs,subs,ty) ->
+ match (decl, largs, ty) with
+ | (LocalAssum _, a::args, Prod(_,_,t)) -> (args, a::subs, t)
+ | (LocalDef (_,b,_),_,LetIn(_,_,_,t)) ->
(largs, (substl subs (subst_instance_constr u b))::subs, t)
| (_,[],_) -> if full then fail() else ([], subs, ty)
| _ -> fail ())
@@ -161,7 +161,7 @@ let remember_subst u subst =
(* Propagate the new levels in the signature *)
let rec make_subst env =
let rec make subst = function
- | (_,Some _,_)::sign, exp, args ->
+ | LocalDef _ :: sign, exp, args ->
make subst (sign, exp, args)
| d::sign, None::exp, args ->
let args = match args with _::args -> args | [] -> [] in
@@ -174,7 +174,7 @@ let rec make_subst env =
(* a useless extra constraint *)
let s = sort_as_univ (snd (dest_arity env a)) in
make (cons_subst u s subst) (sign, exp, args)
- | (na,None,t)::sign, Some u::exp, [] ->
+ | LocalAssum (na,t) :: sign, Some u::exp, [] ->
(* No more argument here: we add the remaining universes to the *)
(* substitution (when [u] is distinct from all other universes in the *)
(* template, it is identity substitution otherwise (ie. when u is *)
@@ -319,8 +319,8 @@ let elim_sorts (_,mip) = mip.mind_kelim
let extended_rel_list n hyps =
let rec reln l p = function
- | (_,None,_) :: hyps -> reln (Rel (n+p) :: l) (p+1) hyps
- | (_,Some _,_) :: hyps -> reln l (p+1) hyps
+ | LocalAssum _ :: hyps -> reln (Rel (n+p) :: l) (p+1) hyps
+ | LocalDef _ :: hyps -> reln l (p+1) hyps
| [] -> l
in
reln [] 1 hyps
@@ -345,12 +345,12 @@ let is_correct_arity env c (p,pj) ind specif params =
let rec srec env pt ar =
let pt' = whd_betadeltaiota env pt in
match pt', ar with
- | Prod (na1,a1,t), (_,None,a1')::ar' ->
+ | Prod (na1,a1,t), LocalAssum (_,a1')::ar' ->
(try conv env a1 a1'
with NotConvertible -> raise (LocalArity None));
- srec (push_rel (na1,None,a1) env) t ar'
+ srec (push_rel (LocalAssum (na1,a1)) env) t ar'
| Prod (na1,a1,a2), [] -> (* whnf of t was not needed here! *)
- let env' = push_rel (na1,None,a1) env in
+ let env' = push_rel (LocalAssum (na1,a1)) env in
let ksort = match (whd_betadeltaiota env' a2) with
| Sort s -> family_of_sort s
| _ -> raise (LocalArity None) in
@@ -362,8 +362,8 @@ let is_correct_arity env c (p,pj) ind specif params =
| Sort s', [] ->
check_allowed_sort (family_of_sort s') specif;
false
- | _, (_,Some _,_ as d)::ar' ->
- srec (push_rel d env) (lift 1 pt') ar'
+ | _, (LocalDef _ as d)::ar' ->
+ srec (push_rel d env) (lift 1 pt') ar'
| _ ->
raise (LocalArity None)
in
@@ -530,7 +530,7 @@ let make_renv env recarg tree =
genv = [Lazy.lazy_from_val(Subterm(Large,tree))] }
let push_var renv (x,ty,spec) =
- { env = push_rel (x,None,ty) renv.env;
+ { env = push_rel (LocalAssum (x,ty)) renv.env;
rel_min = renv.rel_min+1;
genv = spec:: renv.genv }
@@ -628,14 +628,14 @@ let check_inductive_codomain env p =
(* The following functions are almost duplicated from indtypes.ml, except
that they carry here a poorer environment (containing less information). *)
let ienv_push_var (env, lra) (x,a,ra) =
-(push_rel (x,None,a) env, (Norec,ra)::lra)
+(push_rel (LocalAssum (x,a)) env, (Norec,ra)::lra)
let ienv_push_inductive (env, ra_env) ((mind,u),lpar) =
let mib = Environ.lookup_mind mind env in
let ntypes = mib.mind_ntypes in
let push_ind specif env =
- push_rel (Anonymous,None,
- hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar) env
+ push_rel (LocalAssum (Anonymous,
+ hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar)) env
in
let env = Array.fold_right push_ind mib.mind_packets env in
let rc = Array.mapi (fun j t -> (Imbr (mind,j),t)) (Rtree.mk_rec_calls ntypes) in
@@ -902,7 +902,7 @@ let filter_stack_domain env ci p stack =
let t = whd_betadeltaiota env ar in
match stack, t with
| elt :: stack', Prod (n,a,c0) ->
- let d = (n,None,a) in
+ let d = LocalAssum (n,a) in
let ty, args = decompose_app (whd_betadeltaiota env a) in
let elt = match ty with
| Ind ind ->
@@ -956,10 +956,10 @@ let check_one_fix renv recpos trees def =
end
else
begin
- match pi2 (lookup_rel p renv.env) with
- | None ->
+ match lookup_rel p renv.env with
+ | LocalAssum _ ->
List.iter (check_rec_call renv []) l
- | Some c ->
+ | LocalDef (_,c,_) ->
try List.iter (check_rec_call renv []) l
with FixGuardError _ ->
check_rec_call renv stack (applist(lift p c,l))
@@ -1078,7 +1078,7 @@ let inductive_of_mutfix env ((nvect,bodynum),(names,types,bodies as recdef)) =
match (whd_betadeltaiota env def) with
| Lambda (x,a,b) ->
if noccur_with_meta n nbfix a then
- let env' = push_rel (x, None, a) env in
+ let env' = push_rel (LocalAssum (x,a)) env in
if n = k+1 then
(* get the inductive type of the fixpoint *)
let (mind, _) =
@@ -1127,7 +1127,7 @@ let rec codomain_is_coind env c =
let b = whd_betadeltaiota env c in
match b with
| Prod (x,a,b) ->
- codomain_is_coind (push_rel (x, None, a) env) b
+ codomain_is_coind (push_rel (LocalAssum (x,a)) env) b
| _ ->
(try find_coinductive env b
with Not_found ->
@@ -1168,7 +1168,7 @@ let check_one_cofix env nbfix def deftype =
| Lambda (x,a,b) ->
assert (args = []);
if noccur_with_meta n nbfix a then
- let env' = push_rel (x, None, a) env in
+ let env' = push_rel (LocalAssum (x,a)) env in
check_rec_call env' alreadygrd (n+1) tree vlra b
else
raise (CoFixGuardError (env,RecCallInTypeOfAbstraction a))
diff --git a/checker/reduction.ml b/checker/reduction.ml
index 3a666a60a4..f1aa5d9194 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -490,7 +490,7 @@ let dest_prod env =
let t = whd_betadeltaiota env c in
match t with
| Prod (n,a,c0) ->
- let d = (n,None,a) in
+ let d = LocalAssum (n,a) in
decrec (push_rel d env) (d::m) c0
| _ -> m,t
in
@@ -502,10 +502,10 @@ let dest_prod_assum env =
let rty = whd_betadeltaiota_nolet env ty in
match rty with
| Prod (x,t,c) ->
- let d = (x,None,t) in
+ let d = LocalAssum (x,t) in
prodec_rec (push_rel d env) (d::l) c
| LetIn (x,b,t,c) ->
- let d = (x,Some b,t) in
+ let d = LocalDef (x,b,t) in
prodec_rec (push_rel d env) (d::l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
@@ -520,10 +520,10 @@ let dest_lam_assum env =
let rty = whd_betadeltaiota_nolet env ty in
match rty with
| Lambda (x,t,c) ->
- let d = (x,None,t) in
+ let d = LocalAssum (x,t) in
lamec_rec (push_rel d env) (d::l) c
| LetIn (x,b,t,c) ->
- let d = (x,Some b,t) in
+ let d = LocalDef (x,b,t) in
lamec_rec (push_rel d env) (d::l) c
| Cast (c,_,_) -> lamec_rec env l c
| _ -> l,rty
diff --git a/checker/term.ml b/checker/term.ml
index 6487d1a152..181d292ad4 100644
--- a/checker/term.ml
+++ b/checker/term.ml
@@ -222,24 +222,29 @@ let rel_context_length = List.length
let rel_context_nhyps hyps =
let rec nhyps acc = function
| [] -> acc
- | (_,None,_)::hyps -> nhyps (1+acc) hyps
- | (_,Some _,_)::hyps -> nhyps acc hyps in
+ | LocalAssum _ :: hyps -> nhyps (1+acc) hyps
+ | LocalDef _ :: hyps -> nhyps acc hyps in
nhyps 0 hyps
let fold_rel_context f l ~init = List.fold_right f l init
let map_rel_context f l =
- let map_decl (n, body_o, typ as decl) =
- let body_o' = Option.smartmap f body_o in
- let typ' = f typ in
- if body_o' == body_o && typ' == typ then decl else
- (n, body_o', typ')
+ let map_decl = function
+ | LocalAssum (n, typ) as decl ->
+ let typ' = f typ in
+ if typ' == typ then decl else
+ LocalAssum (n, typ')
+ | LocalDef (n, body, typ) as decl ->
+ let body' = f body in
+ let typ' = f typ in
+ if body' == body && typ' == typ then decl else
+ LocalDef (n, body', typ')
in
List.smartmap map_decl l
let extended_rel_list n hyps =
let rec reln l p = function
- | (_,None,_) :: hyps -> reln (Rel (n+p) :: l) (p+1) hyps
- | (_,Some _,_) :: hyps -> reln l (p+1) hyps
+ | LocalAssum _ :: hyps -> reln (Rel (n+p) :: l) (p+1) hyps
+ | LocalDef _ :: hyps -> reln l (p+1) hyps
| [] -> l
in
reln [] 1 hyps
@@ -272,8 +277,8 @@ let decompose_lam_n_assum n =
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
else match c with
- | Lambda (x,t,c) -> lamdec_rec ((x,None,t) :: l) (n-1) c
- | LetIn (x,b,t,c) -> lamdec_rec ((x,Some b,t) :: l) n c
+ | Lambda (x,t,c) -> lamdec_rec (LocalAssum (x,t) :: l) (n-1) c
+ | LetIn (x,b,t,c) -> lamdec_rec (LocalDef (x,b,t) :: l) n c
| Cast (c,_,_) -> lamdec_rec l n c
| c -> error "decompose_lam_n_assum: not enough abstractions"
in
@@ -282,18 +287,18 @@ let decompose_lam_n_assum n =
(* Iterate products, with or without lets *)
(* Constructs either [(x:t)c] or [[x=b:t]c] *)
-let mkProd_or_LetIn (na,body,t) c =
- match body with
- | None -> Prod (na, t, c)
- | Some b -> LetIn (na, b, t, c)
+let mkProd_or_LetIn decl c =
+ match decl with
+ | LocalAssum (na,t) -> Prod (na, t, c)
+ | LocalDef (na,b,t) -> LetIn (na, b, t, c)
let it_mkProd_or_LetIn = List.fold_left (fun c d -> mkProd_or_LetIn d c)
let decompose_prod_assum =
let rec prodec_rec l c =
match c with
- | Prod (x,t,c) -> prodec_rec ((x,None,t) :: l) c
- | LetIn (x,b,t,c) -> prodec_rec ((x,Some b,t) :: l) c
+ | Prod (x,t,c) -> prodec_rec (LocalAssum (x,t) :: l) c
+ | LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t) :: l) c
| Cast (c,_,_) -> prodec_rec l c
| _ -> l,c
in
@@ -305,8 +310,8 @@ let decompose_prod_n_assum n =
let rec prodec_rec l n c =
if Int.equal n 0 then l,c
else match c with
- | Prod (x,t,c) -> prodec_rec ((x,None,t) :: l) (n-1) c
- | LetIn (x,b,t,c) -> prodec_rec ((x,Some b,t) :: l) (n-1) c
+ | Prod (x,t,c) -> prodec_rec (LocalAssum (x,t) :: l) (n-1) c
+ | LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t) :: l) (n-1) c
| Cast (c,_,_) -> prodec_rec l n c
| c -> error "decompose_prod_n_assum: not enough assumptions"
in
@@ -324,8 +329,8 @@ let mkArity (sign,s) = it_mkProd_or_LetIn (Sort s) sign
let destArity =
let rec prodec_rec l c =
match c with
- | Prod (x,t,c) -> prodec_rec ((x,None,t)::l) c
- | LetIn (x,b,t,c) -> prodec_rec ((x,Some b,t)::l) c
+ | Prod (x,t,c) -> prodec_rec (LocalAssum (x,t)::l) c
+ | LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t)::l) c
| Cast (c,_,_) -> prodec_rec l c
| Sort s -> l,s
| _ -> anomaly ~label:"destArity" (Pp.str "not an arity")
diff --git a/checker/term.mli b/checker/term.mli
index ab488b2b7c..d6455e23f4 100644
--- a/checker/term.mli
+++ b/checker/term.mli
@@ -40,7 +40,7 @@ val extended_rel_list : int -> rel_context -> constr list
val compose_lam : (name * constr) list -> constr -> constr
val decompose_lam : constr -> (name * constr) list * constr
val decompose_lam_n_assum : int -> constr -> rel_context * constr
-val mkProd_or_LetIn : name * constr option * constr -> constr -> constr
+val mkProd_or_LetIn : rel_declaration -> constr -> constr
val it_mkProd_or_LetIn : constr -> rel_context -> constr
val decompose_prod_assum : constr -> rel_context * constr
val decompose_prod_n_assum : int -> constr -> rel_context * constr
diff --git a/checker/typeops.ml b/checker/typeops.ml
index d49c40a8bd..64afd21b2a 100644
--- a/checker/typeops.ml
+++ b/checker/typeops.ml
@@ -62,7 +62,7 @@ let judge_of_type u = Sort (Type (Univ.super u))
let judge_of_relative env n =
try
- let (_,_,typ) = lookup_rel n env in
+ let LocalAssum (_,typ) | LocalDef (_,_,typ) = lookup_rel n env in
lift n typ
with Not_found ->
error_unbound_rel env n
@@ -296,13 +296,13 @@ let rec execute env cstr =
| Lambda (name,c1,c2) ->
let _ = execute_type env c1 in
- let env1 = push_rel (name,None,c1) env in
+ let env1 = push_rel (LocalAssum (name,c1)) env in
let j' = execute env1 c2 in
Prod(name,c1,j')
| Prod (name,c1,c2) ->
let varj = execute_type env c1 in
- let env1 = push_rel (name,None,c1) env in
+ let env1 = push_rel (LocalAssum (name,c1)) env in
let varj' = execute_type env1 c2 in
Sort (sort_of_product env varj varj')
@@ -314,7 +314,7 @@ let rec execute env cstr =
let env',c2' = (* refresh_arity env *) env, c2 in
let _ = execute_type env' c2' in
judge_of_cast env' (c1,j1) DEFAULTcast c2' in
- let env1 = push_rel (name,Some c1,c2) env in
+ let env1 = push_rel (LocalDef (name,c1,c2)) env in
let j' = execute env1 c3 in
subst1 c1 j'
@@ -378,10 +378,10 @@ let infer_type env constr = execute_type env constr
let check_ctxt env rels =
fold_rel_context (fun d env ->
match d with
- (_,None,ty) ->
+ | LocalAssum (_,ty) ->
let _ = infer_type env ty in
push_rel d env
- | (_,Some bd,ty) ->
+ | LocalDef (_,bd,ty) ->
let j1 = infer env bd in
let _ = infer env ty in
conv_leq env j1 ty;
@@ -399,9 +399,9 @@ let check_polymorphic_arity env params par =
let pl = par.template_param_levels in
let rec check_p env pl params =
match pl, params with
- Some u::pl, (na,None,ty)::params ->
+ Some u::pl, LocalAssum (na,ty)::params ->
check_kind env ty u;
- check_p (push_rel (na,None,ty) env) pl params
+ check_p (push_rel (LocalAssum (na,ty)) env) pl params
| None::pl,d::params -> check_p (push_rel d env) pl params
| [], _ -> ()
| _ -> failwith "check_poly: not the right number of params" in
diff --git a/checker/values.ml b/checker/values.ml
index c14e9223da..19cbb50606 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -13,7 +13,7 @@
To ensure this file is up-to-date, 'make' now compares the md5 of cic.mli
with a copy we maintain here:
-MD5 7c050ff1db22f14ee3a4c44aae533082 checker/cic.mli
+MD5 9f7fd499f812b6548a55f7067e6a9d06 checker/cic.mli
*)
@@ -154,8 +154,8 @@ and v_prec = Tuple ("prec_declaration",
and v_fix = Tuple ("pfixpoint", [|Tuple ("fix2",[|Array Int;Int|]);v_prec|])
and v_cofix = Tuple ("pcofixpoint",[|Int;v_prec|])
-
-let v_rdecl = v_tuple "rel_declaration" [|v_name;Opt v_constr;v_constr|]
+let v_rdecl = v_sum "rel_declaration" 0 [| [|v_name; v_constr|]; (* LocalAssum *)
+ [|v_name; v_constr; v_constr|] |] (* LocalDef *)
let v_rctxt = List v_rdecl
let v_section_ctxt = v_enum "emptylist" 1
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index c143afd374..0581a5f850 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -1,5 +1,5 @@
=========================================
-= CHANGES BETWEEN COQ V8.5 AND CQQ V8.6 =
+= CHANGES BETWEEN COQ V8.5 AND COQ V8.6 =
=========================================
- The interface of the Context module was changed.
@@ -9,9 +9,9 @@
Context.named_declaration ---> Context.Named.Declaration.t
Context.named_list_declaration ---> Context.NamedList.Declaration.t
Context.rel_declaration ---> Context.Rel.Declaration.t
- Context.map_named_declaration ---> Context.Named.Declaration.map
+ Context.map_named_declaration ---> Context.Named.Declaration.map_constr
Context.map_named_list_declaration ---> Context.NamedList.Declaration.map
- Context.map_rel_declaration ---> Context.Rel.Declaration.map
+ Context.map_rel_declaration ---> Context.Rel.Declaration.map_constr
Context.fold_named_declaration ---> Context.Named.Declaration.fold
Context.fold_rel_declaration ---> Context.Rel.Declaration.fold
Context.exists_named_declaration ---> Context.Named.Declaration.exists
@@ -37,8 +37,8 @@
Context.extended_rel_vect ---> Context.Rel.to_extended_vect
Context.fold_rel_context ---> Context.Rel.fold_outside
Context.fold_rel_context_reverse ---> Context.Rel.fold_inside
- Context.map_rel_context ---> Context.Rel.map
- Context.map_named_context ---> Context.Named.map
+ Context.map_rel_context ---> Context.Rel.map_constr
+ Context.map_named_context ---> Context.Named.map_constr
Context.iter_rel_context ---> Context.Rel.iter
Context.iter_named_context ---> Context.Named.iter
Context.empty_rel_context ---> Context.Rel.empty
@@ -48,8 +48,27 @@
Context.rel_context_nhyps ---> Context.Rel.nhyps
Context.rel_context_tags ---> Context.Rel.to_tags
+- Originally, rel-context was represented as:
+
+ Context.rel_context = Names.Name.t * Constr.t option * Constr.t
+
+ Now it is represented as:
+
+ Context.Rel.t = LocalAssum of Names.Name.t * Constr.t
+ | LocalDef of Names.Name.t * Constr.t * Constr.t
+
+- Originally, named-context was represented as:
+
+ Context.named_context = Names.Id.t * Constr.t option * Constr.t
+
+ Now it is represented as:
+
+ Context.Named.t = LocalAssum of Names.Id.t * Constr.t
+ | LocalDef of Names.Id.t * Constr.t * Constr.t
+
+
=========================================
-= CHANGES BETWEEN COQ V8.4 AND CQQ V8.5 =
+= CHANGES BETWEEN COQ V8.4 AND COQ V8.5 =
=========================================
** Refactoring : more mli interfaces and simpler grammar.cma **
diff --git a/engine/evd.ml b/engine/evd.ml
index 8f8b29d106..f1f65bd8af 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -16,6 +16,7 @@ open Vars
open Termops
open Environ
open Globnames
+open Context.Named.Declaration
(** Generic filters *)
module Filter :
@@ -230,20 +231,20 @@ let evar_instance_array test_id info args =
else instance_mismatch ()
| false :: filter, _ :: ctxt ->
instrec filter ctxt i
- | true :: filter, (id,_,_ as d) :: ctxt ->
+ | true :: filter, d :: ctxt ->
if i < len then
let c = Array.unsafe_get args i in
if test_id d c then instrec filter ctxt (succ i)
- else (id, c) :: instrec filter ctxt (succ i)
+ else (get_id d, c) :: instrec filter ctxt (succ i)
else instance_mismatch ()
| _ -> instance_mismatch ()
in
match Filter.repr (evar_filter info) with
| None ->
- let map i (id,_,_ as d) =
+ let map i d =
if (i < len) then
let c = Array.unsafe_get args i in
- if test_id d c then None else Some (id,c)
+ if test_id d c then None else Some (get_id d, c)
else instance_mismatch ()
in
List.map_filter_i map (evar_context info)
@@ -251,7 +252,7 @@ let evar_instance_array test_id info args =
instrec filter (evar_context info) 0
let make_evar_instance_array info args =
- evar_instance_array (fun (id,_,_) -> isVarId id) info args
+ evar_instance_array (isVarId % get_id) info args
let instantiate_evar_array info c args =
let inst = make_evar_instance_array info args in
@@ -660,7 +661,7 @@ let restrict evk filter ?candidates evd =
evar_extra = Store.empty } in
let evar_names = reassign_name_defined evk evk' evd.evar_names in
let ctxt = Filter.filter_list filter (evar_context evar_info) in
- let id_inst = Array.map_of_list (fun (id,_,_) -> mkVar id) ctxt in
+ let id_inst = Array.map_of_list (mkVar % get_id) ctxt in
let body = mkEvar(evk',id_inst) in
let (defn_evars, undf_evars) = define_aux evd.defn_evars evd.undf_evars evk body in
{ evd with undf_evars = EvMap.add evk' evar_info' undf_evars;
@@ -722,10 +723,10 @@ let evars_of_term c =
evrec Evar.Set.empty c
let evars_of_named_context nc =
- List.fold_right (fun (_, b, t) s ->
+ List.fold_right (fun decl s ->
Option.fold_left (fun s t ->
Evar.Set.union s (evars_of_term t))
- (Evar.Set.union s (evars_of_term t)) b)
+ (Evar.Set.union s (evars_of_term (get_type decl))) (get_value decl))
nc Evar.Set.empty
let evars_of_filtered_evar_info evi =
@@ -1228,8 +1229,9 @@ let pr_meta_map mmap =
in
prlist pr_meta_binding (metamap_to_list mmap)
-let pr_decl ((id,b,_),ok) =
- match b with
+let pr_decl (decl,ok) =
+ let id = get_id decl in
+ match get_value decl with
| None -> if ok then pr_id id else (str "{" ++ pr_id id ++ str "}")
| Some c -> str (if ok then "(" else "{") ++ pr_id id ++ str ":=" ++
print_constr c ++ str (if ok then ")" else "}")
@@ -1346,8 +1348,9 @@ let print_env_short env =
let pr_body n = function
| None -> pr_name n
| Some b -> str "(" ++ pr_name n ++ str " := " ++ print_constr b ++ str ")" in
- let pr_named_decl (n, b, _) = pr_body (Name n) b in
- let pr_rel_decl (n, b, _) = pr_body n b in
+ let pr_named_decl decl = pr_body (Name (get_id decl)) (get_value decl) in
+ let pr_rel_decl decl = let open Context.Rel.Declaration in
+ pr_body (get_name decl) (get_value decl) in
let nc = List.rev (named_context env) in
let rc = List.rev (rel_context env) in
str "[" ++ pr_sequence pr_named_decl nc ++ str "]" ++ spc () ++
diff --git a/engine/namegen.ml b/engine/namegen.ml
index fc3f0cc75b..6b2b585316 100644
--- a/engine/namegen.ml
+++ b/engine/namegen.ml
@@ -22,6 +22,7 @@ open Libnames
open Globnames
open Environ
open Termops
+open Context.Rel.Declaration
(**********************************************************************)
(* Conventional names *)
@@ -113,7 +114,7 @@ let hdchar env c =
| Rel n ->
(if n<=k then "p" (* the initial term is flexible product/function *)
else
- try match Environ.lookup_rel (n-k) env with
+ try match Environ.lookup_rel (n-k) env |> to_tuple with
| (Name id,_,_) -> lowercase_first_char id
| (Anonymous,_,t) -> hdrec 0 (lift (n-k) t)
with Not_found -> "y")
@@ -142,10 +143,9 @@ let prod_name = mkProd_name
let prod_create env (a,b) = mkProd (named_hd env a Anonymous, a, b)
let lambda_create env (a,b) = mkLambda (named_hd env a Anonymous, a, b)
-let name_assumption env (na,c,t) =
- match c with
- | None -> (named_hd env t na, None, t)
- | Some body -> (named_hd env body na, c, t)
+let name_assumption env = function
+ | LocalAssum (na,t) -> LocalAssum (named_hd env t na, t)
+ | LocalDef (na,c,t) -> LocalDef (named_hd env c na, c, t)
let name_context env hyps =
snd
@@ -277,11 +277,12 @@ let next_name_away = next_name_away_with_default default_non_dependent_string
let make_all_name_different env =
let avoid = ref (ids_of_named_context (named_context env)) in
process_rel_context
- (fun (na,c,t) newenv ->
+ (fun decl newenv ->
+ let (na,_,t) = to_tuple decl in
let na = named_hd newenv t na in
let id = next_name_away na !avoid in
avoid := id::!avoid;
- push_rel (Name id,c,t) newenv)
+ push_rel (set_name (Name id) decl) newenv)
env
(* 5- Looks for next fresh name outside a list; avoids also to use names that
diff --git a/engine/termops.ml b/engine/termops.ml
index b7d89ba7b1..f698f81513 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -15,6 +15,9 @@ open Term
open Vars
open Environ
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
(* Sorts and sort family *)
let print_sort = function
@@ -98,26 +101,28 @@ let print_constr_env t = !term_printer t
let print_constr t = !term_printer (Global.env()) t
let set_print_constr f = term_printer := f
-let pr_var_decl env (id,c,typ) =
- let pbody = match c with
- | None -> (mt ())
- | Some c ->
+let pr_var_decl env decl =
+ let open NamedDecl in
+ let pbody = match decl with
+ | LocalAssum _ -> mt ()
+ | LocalDef (_,c,_) ->
(* Force evaluation *)
let pb = print_constr_env env c in
(str" := " ++ pb ++ cut () ) in
- let pt = print_constr_env env typ in
+ let pt = print_constr_env env (get_type decl) in
let ptyp = (str" : " ++ pt) in
- (pr_id id ++ hov 0 (pbody ++ ptyp))
+ (pr_id (get_id decl) ++ hov 0 (pbody ++ ptyp))
-let pr_rel_decl env (na,c,typ) =
- let pbody = match c with
- | None -> mt ()
- | Some c ->
+let pr_rel_decl env decl =
+ let open RelDecl in
+ let pbody = match decl with
+ | LocalAssum _ -> mt ()
+ | LocalDef (_,c,_) ->
(* Force evaluation *)
let pb = print_constr_env env c in
(str":=" ++ spc () ++ pb ++ spc ()) in
- let ptyp = print_constr_env env typ in
- match na with
+ let ptyp = print_constr_env env (get_type decl) in
+ match get_name decl with
| Anonymous -> hov 0 (str"<>" ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
| Name id -> hov 0 (pr_id id ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
@@ -157,42 +162,53 @@ let rel_list n m =
in
reln [] 1
-let push_rel_assum (x,t) env = push_rel (x,None,t) env
+let push_rel_assum (x,t) env =
+ let open RelDecl in
+ push_rel (LocalAssum (x,t)) env
let push_rels_assum assums =
- push_rel_context (List.map (fun (x,t) -> (x,None,t)) assums)
+ let open RelDecl in
+ push_rel_context (List.map (fun (x,t) -> LocalAssum (x,t)) assums)
let push_named_rec_types (lna,typarray,_) env =
+ let open NamedDecl in
let ctxt =
Array.map2_i
(fun i na t ->
match na with
- | Name id -> (id, None, lift i t)
+ | Name id -> LocalAssum (id, lift i t)
| Anonymous -> anomaly (Pp.str "Fix declarations must be named"))
lna typarray in
Array.fold_left
(fun e assum -> push_named assum e) env ctxt
let lookup_rel_id id sign =
+ let open RelDecl in
let rec lookrec n = function
- | [] -> raise Not_found
- | (Anonymous, _, _) :: l -> lookrec (n + 1) l
- | (Name id', b, t) :: l ->
- if Names.Id.equal id' id then (n, b, t) else lookrec (n + 1) l
+ | [] ->
+ raise Not_found
+ | (LocalAssum (Anonymous, _) | LocalDef (Anonymous,_,_)) :: l ->
+ lookrec (n + 1) l
+ | LocalAssum (Name id', t) :: l ->
+ if Names.Id.equal id' id then (n,None,t) else lookrec (n + 1) l
+ | LocalDef (Name id', b, t) :: l ->
+ if Names.Id.equal id' id then (n,Some b,t) else lookrec (n + 1) l
in
lookrec 1 sign
(* Constructs either [forall x:t, c] or [let x:=b:t in c] *)
-let mkProd_or_LetIn (na,body,t) c =
- match body with
- | None -> mkProd (na, t, c)
- | Some b -> mkLetIn (na, b, t, c)
+let mkProd_or_LetIn decl c =
+ let open RelDecl in
+ match decl with
+ | LocalAssum (na,t) -> mkProd (na, t, c)
+ | LocalDef (na,b,t) -> mkLetIn (na, b, t, c)
(* Constructs either [forall x:t, c] or [c] in which [x] is replaced by [b] *)
-let mkProd_wo_LetIn (na,body,t) c =
- match body with
- | None -> mkProd (na, t, c)
- | Some b -> subst1 b c
+let mkProd_wo_LetIn decl c =
+ let open RelDecl in
+ match decl with
+ | LocalAssum (na,t) -> mkProd (na, t, c)
+ | LocalDef (_,b,_) -> subst1 b c
let it_mkProd init = List.fold_left (fun c (n,t) -> mkProd (n, t, c)) init
let it_mkLambda init = List.fold_left (fun c (n,t) -> mkLambda (n, t, c)) init
@@ -208,10 +224,11 @@ let it_mkNamedProd_wo_LetIn init = it_named_context_quantifier mkNamedProd_wo_Le
let it_mkNamedLambda_or_LetIn init = it_named_context_quantifier mkNamedLambda_or_LetIn ~init
let it_mkLambda_or_LetIn_from_no_LetIn c decls =
+ let open RelDecl in
let rec aux k decls c = match decls with
| [] -> c
- | (na,Some b,t)::decls -> mkLetIn (na,b,t,aux (k-1) decls (liftn 1 k c))
- | (na,None,t)::decls -> mkLambda (na,t,aux (k-1) decls c)
+ | LocalDef (na,b,t) :: decls -> mkLetIn (na,b,t,aux (k-1) decls (liftn 1 k c))
+ | LocalAssum (na,t) :: decls -> mkLambda (na,t,aux (k-1) decls c)
in aux (List.length decls) (List.rev decls) c
(* *)
@@ -302,7 +319,7 @@ let map_constr_with_named_binders g f l c = match kind_of_term c with
(co-)fixpoint) *)
let fold_rec_types g (lna,typarray,_) e =
- let ctxt = Array.map2_i (fun i na t -> (na, None, lift i t)) lna typarray in
+ let ctxt = Array.map2_i (fun i na t -> RelDecl.LocalAssum (na, lift i t)) lna typarray in
Array.fold_left (fun e assum -> g assum e) e ctxt
let map_left2 f a g b =
@@ -317,7 +334,9 @@ let map_left2 f a g b =
r, s
end
-let map_constr_with_binders_left_to_right g f l c = match kind_of_term c with
+let map_constr_with_binders_left_to_right g f l c =
+ let open RelDecl in
+ match kind_of_term c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> c
| Cast (b,k,t) ->
@@ -327,18 +346,18 @@ let map_constr_with_binders_left_to_right g f l c = match kind_of_term c with
else mkCast (b',k,t')
| Prod (na,t,b) ->
let t' = f l t in
- let b' = f (g (na,None,t) l) b in
+ let b' = f (g (LocalAssum (na,t)) l) b in
if t' == t && b' == b then c
else mkProd (na, t', b')
| Lambda (na,t,b) ->
let t' = f l t in
- let b' = f (g (na,None,t) l) b in
+ let b' = f (g (LocalAssum (na,t)) l) b in
if t' == t && b' == b then c
else mkLambda (na, t', b')
| LetIn (na,bo,t,b) ->
let bo' = f l bo in
let t' = f l t in
- let b' = f (g (na,Some bo,t) l) b in
+ let b' = f (g (LocalDef (na,bo,t)) l) b in
if bo' == bo && t' == t && b' == b then c
else mkLetIn (na, bo', t', b')
| App (c,[||]) -> assert false
@@ -379,7 +398,9 @@ let map_constr_with_binders_left_to_right g f l c = match kind_of_term c with
else mkCoFix (ln,(lna,tl',bl'))
(* strong *)
-let map_constr_with_full_binders g f l cstr = match kind_of_term cstr with
+let map_constr_with_full_binders g f l cstr =
+ let open RelDecl in
+ match kind_of_term cstr with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> cstr
| Cast (c,k, t) ->
@@ -388,16 +409,16 @@ let map_constr_with_full_binders g f l cstr = match kind_of_term cstr with
if c==c' && t==t' then cstr else mkCast (c', k, t')
| Prod (na,t,c) ->
let t' = f l t in
- let c' = f (g (na,None,t) l) c in
+ let c' = f (g (LocalAssum (na,t)) l) c in
if t==t' && c==c' then cstr else mkProd (na, t', c')
| Lambda (na,t,c) ->
let t' = f l t in
- let c' = f (g (na,None,t) l) c in
+ let c' = f (g (LocalAssum (na,t)) l) c in
if t==t' && c==c' then cstr else mkLambda (na, t', c')
| LetIn (na,b,t,c) ->
let b' = f l b in
let t' = f l t in
- let c' = f (g (na,Some b,t) l) c in
+ let c' = f (g (LocalDef (na,b,t)) l) c in
if b==b' && t==t' && c==c' then cstr else mkLetIn (na, b', t', c')
| App (c,al) ->
let c' = f l c in
@@ -418,7 +439,7 @@ let map_constr_with_full_binders g f l cstr = match kind_of_term cstr with
| Fix (ln,(lna,tl,bl)) ->
let tl' = Array.map (f l) tl in
let l' =
- Array.fold_left2 (fun l na t -> g (na,None,t) l) l lna tl in
+ Array.fold_left2 (fun l na t -> g (LocalAssum (na,t)) l) l lna tl in
let bl' = Array.map (f l') bl in
if Array.for_all2 (==) tl tl' && Array.for_all2 (==) bl bl'
then cstr
@@ -426,7 +447,7 @@ let map_constr_with_full_binders g f l cstr = match kind_of_term cstr with
| CoFix(ln,(lna,tl,bl)) ->
let tl' = Array.map (f l) tl in
let l' =
- Array.fold_left2 (fun l na t -> g (na,None,t) l) l lna tl in
+ Array.fold_left2 (fun l na t -> g (LocalAssum (na,t)) l) l lna tl in
let bl' = Array.map (f l') bl in
if Array.for_all2 (==) tl tl' && Array.for_all2 (==) bl bl'
then cstr
@@ -439,23 +460,25 @@ let map_constr_with_full_binders g f l cstr = match kind_of_term cstr with
index) which is processed by [g] (which typically add 1 to [n]) at
each binder traversal; it is not recursive *)
-let fold_constr_with_full_binders g f n acc c = match kind_of_term c with
+let fold_constr_with_full_binders g f n acc c =
+ let open RelDecl in
+ match kind_of_term c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> acc
| Cast (c,_, t) -> f n (f n acc c) t
- | Prod (na,t,c) -> f (g (na,None,t) n) (f n acc t) c
- | Lambda (na,t,c) -> f (g (na,None,t) n) (f n acc t) c
- | LetIn (na,b,t,c) -> f (g (na,Some b,t) n) (f n (f n acc b) t) c
+ | Prod (na,t,c) -> f (g (LocalAssum (na,t)) n) (f n acc t) c
+ | Lambda (na,t,c) -> f (g (LocalAssum (na,t)) n) (f n acc t) c
+ | LetIn (na,b,t,c) -> f (g (LocalDef (na,b,t)) n) (f n (f n acc b) t) c
| App (c,l) -> Array.fold_left (f n) (f n acc c) l
| Proj (p,c) -> f n acc c
| Evar (_,l) -> Array.fold_left (f n) acc l
| Case (_,p,c,bl) -> Array.fold_left (f n) (f n (f n acc p) c) bl
| Fix (_,(lna,tl,bl)) ->
- let n' = CArray.fold_left2 (fun c n t -> g (n,None,t) c) n lna tl in
+ let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n,t)) c) n lna tl in
let fd = Array.map2 (fun t b -> (t,b)) tl bl in
Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
| CoFix (_,(lna,tl,bl)) ->
- let n' = CArray.fold_left2 (fun c n t -> g (n,None,t) c) n lna tl in
+ let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n,t)) c) n lna tl in
let fd = Array.map2 (fun t b -> (t,b)) tl bl in
Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
@@ -467,23 +490,25 @@ let fold_constr_with_binders g f n acc c =
each binder traversal; it is not recursive and the order with which
subterms are processed is not specified *)
-let iter_constr_with_full_binders g f l c = match kind_of_term c with
+let iter_constr_with_full_binders g f l c =
+ let open RelDecl in
+ match kind_of_term c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> ()
| Cast (c,_, t) -> f l c; f l t
- | Prod (na,t,c) -> f l t; f (g (na,None,t) l) c
- | Lambda (na,t,c) -> f l t; f (g (na,None,t) l) c
- | LetIn (na,b,t,c) -> f l b; f l t; f (g (na,Some b,t) l) c
+ | Prod (na,t,c) -> f l t; f (g (LocalAssum (na,t)) l) c
+ | Lambda (na,t,c) -> f l t; f (g (LocalAssum (na,t)) l) c
+ | LetIn (na,b,t,c) -> f l b; f l t; f (g (LocalDef (na,b,t)) l) c
| App (c,args) -> f l c; Array.iter (f l) args
| Proj (p,c) -> f l c
| Evar (_,args) -> Array.iter (f l) args
| Case (_,p,c,bl) -> f l p; f l c; Array.iter (f l) bl
| Fix (_,(lna,tl,bl)) ->
- let l' = Array.fold_left2 (fun l na t -> g (na,None,t) l) l lna tl in
+ let l' = Array.fold_left2 (fun l na t -> g (LocalAssum (na,t)) l) l lna tl in
Array.iter (f l) tl;
Array.iter (f l') bl
| CoFix (_,(lna,tl,bl)) ->
- let l' = Array.fold_left2 (fun l na t -> g (na,None,t) l) l lna tl in
+ let l' = Array.fold_left2 (fun l na t -> g (LocalAssum (na,t)) l) l lna tl in
Array.iter (f l) tl;
Array.iter (f l') bl
@@ -531,10 +556,11 @@ let occur_var env id c =
in
try occur_rec c; false with Occur -> true
-let occur_var_in_decl env hyp (_,c,typ) =
- match c with
- | None -> occur_var env hyp typ
- | Some body ->
+let occur_var_in_decl env hyp decl =
+ let open NamedDecl in
+ match decl with
+ | LocalAssum (_,typ) -> occur_var env hyp typ
+ | LocalDef (_, body, typ) ->
occur_var env hyp typ ||
occur_var env hyp body
@@ -593,10 +619,11 @@ let dependent_no_evar = dependent_main true false
let dependent_univs = dependent_main false true
let dependent_univs_no_evar = dependent_main true true
-let dependent_in_decl a (_,c,t) =
- match c with
- | None -> dependent a t
- | Some body -> dependent a body || dependent a t
+let dependent_in_decl a decl =
+ let open NamedDecl in
+ match decl with
+ | LocalAssum (_,t) -> dependent a t
+ | LocalDef (_, body, t) -> dependent a body || dependent a t
let count_occurrences m t =
let n = ref 0 in
@@ -699,10 +726,10 @@ let replace_term = replace_term_gen eq_constr
let vars_of_env env =
let s =
- Context.Named.fold_outside (fun (id,_,_) s -> Id.Set.add id s)
+ Context.Named.fold_outside (fun decl s -> Id.Set.add (NamedDecl.get_id decl) s)
(named_context env) ~init:Id.Set.empty in
Context.Rel.fold_outside
- (fun (na,_,_) s -> match na with Name id -> Id.Set.add id s | _ -> s)
+ (fun decl s -> match RelDecl.get_name decl with Name id -> Id.Set.add id s | _ -> s)
(rel_context env) ~init:s
let add_vname vars = function
@@ -728,11 +755,11 @@ let empty_names_context = []
let ids_of_rel_context sign =
Context.Rel.fold_outside
- (fun (na,_,_) l -> match na with Name id -> id::l | Anonymous -> l)
+ (fun decl l -> match RelDecl.get_name decl with Name id -> id::l | Anonymous -> l)
sign ~init:[]
let ids_of_named_context sign =
- Context.Named.fold_outside (fun (id,_,_) idl -> id::idl) sign ~init:[]
+ Context.Named.fold_outside (fun decl idl -> NamedDecl.get_id decl :: idl) sign ~init:[]
let ids_of_context env =
(ids_of_rel_context (rel_context env))
@@ -740,7 +767,7 @@ let ids_of_context env =
let names_of_rel_context env =
- List.map (fun (na,_,_) -> na) (rel_context env)
+ List.map RelDecl.get_name (rel_context env)
let is_section_variable id =
try let _ = Global.lookup_named id in true
@@ -813,7 +840,7 @@ let filtering env cv_pb c1 c2 =
end
| Prod (n,t1,c1), Prod (_,t2,c2) ->
aux env cv_pb t1 t2;
- aux ((n,None,t1)::env) cv_pb c1 c2
+ aux (RelDecl.LocalAssum (n,t1) :: env) cv_pb c1 c2
| _, Evar (ev,_) -> define cv_pb env ev c1
| Evar (ev,_), _ -> define cv_pb env ev c2
| _ ->
@@ -826,8 +853,8 @@ let filtering env cv_pb c1 c2 =
let decompose_prod_letin : constr -> int * Context.Rel.t * constr =
let rec prodec_rec i l c = match kind_of_term c with
- | Prod (n,t,c) -> prodec_rec (succ i) ((n,None,t)::l) c
- | LetIn (n,d,t,c) -> prodec_rec (succ i) ((n,Some d,t)::l) c
+ | Prod (n,t,c) -> prodec_rec (succ i) (RelDecl.LocalAssum (n,t)::l) c
+ | LetIn (n,d,t,c) -> prodec_rec (succ i) (RelDecl.LocalDef (n,d,t)::l) c
| Cast (c,_,_) -> prodec_rec i l c
| _ -> i,l,c in
prodec_rec 0 []
@@ -902,16 +929,16 @@ let process_rel_context f env =
let assums_of_rel_context sign =
Context.Rel.fold_outside
- (fun (na,c,t) l ->
- match c with
- Some _ -> l
- | None -> (na, t)::l)
+ (fun decl l ->
+ match decl with
+ | RelDecl.LocalDef _ -> l
+ | RelDecl.LocalAssum (na,t) -> (na, t)::l)
sign ~init:[]
let map_rel_context_in_env f env sign =
let rec aux env acc = function
| d::sign ->
- aux (push_rel d env) (Context.Rel.Declaration.map (f env) d :: acc) sign
+ aux (push_rel d env) (RelDecl.map_constr (f env) d :: acc) sign
| [] ->
acc
in
@@ -919,7 +946,7 @@ let map_rel_context_in_env f env sign =
let map_rel_context_with_binders f sign =
let rec aux k = function
- | d::sign -> Context.Rel.Declaration.map (f k) d :: aux (k-1) sign
+ | d::sign -> RelDecl.map_constr (f k) d :: aux (k-1) sign
| [] -> []
in
aux (Context.Rel.length sign) sign
@@ -933,21 +960,23 @@ let lift_rel_context n =
let smash_rel_context sign =
let rec aux acc = function
| [] -> acc
- | (_,None,_ as d) :: l -> aux (d::acc) l
- | (_,Some b,_) :: l ->
+ | (RelDecl.LocalAssum _ as d) :: l -> aux (d::acc) l
+ | RelDecl.LocalDef (_,b,_) :: l ->
(* Quadratic in the number of let but there are probably a few of them *)
aux (List.rev (substl_rel_context [b] (List.rev acc))) l
in List.rev (aux [] sign)
let fold_named_context_both_sides f l ~init = List.fold_right_and_left f l init
-let rec mem_named_context id = function
- | (id',_,_) :: _ when Id.equal id id' -> true
+let rec mem_named_context id ctxt =
+ match ctxt with
+ | decl :: _ when Id.equal id (NamedDecl.get_id decl) -> true
| _ :: sign -> mem_named_context id sign
| [] -> false
let compact_named_context_reverse sign =
- let compact l (i1,c1,t1) =
+ let compact l decl =
+ let (i1,c1,t1) = NamedDecl.to_tuple decl in
match l with
| [] -> [[i1],c1,t1]
| (l2,c2,t2)::q ->
@@ -959,16 +988,17 @@ let compact_named_context_reverse sign =
let compact_named_context sign = List.rev (compact_named_context_reverse sign)
let clear_named_body id env =
+ let open NamedDecl in
let aux _ = function
- | (id',Some c,t) when Id.equal id id' -> push_named (id,None,t)
+ | LocalDef (id',c,t) when Id.equal id id' -> push_named (LocalAssum (id,t))
| d -> push_named d in
fold_named_context aux env ~init:(reset_context env)
let global_vars env ids = Id.Set.elements (global_vars_set env ids)
let global_vars_set_of_decl env = function
- | (_,None,t) -> global_vars_set env t
- | (_,Some c,t) ->
+ | NamedDecl.LocalAssum (_,t) -> global_vars_set env t
+ | NamedDecl.LocalDef (_,c,t) ->
Id.Set.union (global_vars_set env t)
(global_vars_set env c)
@@ -976,7 +1006,8 @@ let dependency_closure env sign hyps =
if Id.Set.is_empty hyps then [] else
let (_,lh) =
Context.Named.fold_inside
- (fun (hs,hl) (x,_,_ as d) ->
+ (fun (hs,hl) d ->
+ let x = NamedDecl.get_id d in
if Id.Set.mem x hs then
(Id.Set.union (global_vars_set_of_decl env d) (Id.Set.remove x hs),
x::hl)
@@ -996,7 +1027,7 @@ let on_judgment_type f j = { j with uj_type = f j.uj_type }
let context_chop k ctx =
let rec chop_aux acc = function
| (0, l2) -> (List.rev acc, l2)
- | (n, ((_,Some _,_ as h)::t)) -> chop_aux (h::acc) (n, t)
+ | (n, (RelDecl.LocalDef _ as h)::t) -> chop_aux (h::acc) (n, t)
| (n, (h::t)) -> chop_aux (h::acc) (pred n, t)
| (_, []) -> anomaly (Pp.str "context_chop")
in chop_aux [] (k,ctx)
diff --git a/engine/termops.mli b/engine/termops.mli
index 720ed3bd67..c2a4f33235 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -101,7 +101,7 @@ val occur_evar : existential_key -> types -> bool
val occur_var : env -> Id.t -> types -> bool
val occur_var_in_decl :
env ->
- Id.t -> 'a * types option * types -> bool
+ Id.t -> Context.Named.Declaration.t -> bool
val free_rels : constr -> Int.Set.t
(** [dependent m t] tests whether [m] is a subterm of [t] *)
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index 20cf48d7f8..12ef0e0751 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -130,7 +130,8 @@ let annotate phrase =
(** Goal display *)
-let hyp_next_tac sigma env (id,_,ast) =
+let hyp_next_tac sigma env decl =
+ let (id,_,ast) = Context.Named.Declaration.to_tuple decl in
let id_s = Names.Id.to_string id in
let type_s = string_of_ppcmds (pr_ltype_env env sigma ast) in
[
@@ -187,8 +188,12 @@ let process_goal sigma g =
Richpp.richpp_of_pp (pr_goal_concl_style_env env sigma norm_constr)
in
let process_hyp d (env,l) =
- let d = Context.NamedList.Declaration.map (Reductionops.nf_evar sigma) d in
- let d' = List.map (fun x -> (x, pi2 d, pi3 d)) (pi1 d) in
+ let d = Context.NamedList.Declaration.map_constr (Reductionops.nf_evar sigma) d in
+ let d' = List.map (fun name -> let open Context.Named.Declaration in
+ match pi2 d with
+ | None -> LocalAssum (name, pi3 d)
+ | Some value -> LocalDef (name, value, pi3 d))
+ (pi1 d) in
(List.fold_right Environ.push_named d' env,
(Richpp.richpp_of_pp (pr_var_list_decl env sigma d)) :: l) in
let (_env, hyps) =
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 70a35c6132..3a8c506cba 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -29,6 +29,8 @@ open Notation
open Detyping
open Misctypes
open Decl_kinds
+
+module NamedDecl = Context.Named.Declaration
(*i*)
(* Translation from glob_constr to front constr *)
@@ -980,7 +982,7 @@ let rec glob_of_pat env sigma = function
| PRef ref -> GRef (loc,ref,None)
| PVar id -> GVar (loc,id)
| PEvar (evk,l) ->
- let test (id,_,_) = function PVar id' -> Id.equal id id' | _ -> false in
+ let test decl = function PVar id' -> Id.equal (NamedDecl.get_id decl) id' | _ -> false in
let l = Evd.evar_instance_array test (Evd.find sigma evk) l in
let id = Evd.evar_ident evk sigma in
GEvar (loc,id,List.map (on_snd (glob_of_pat env sigma)) l)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 964ed05140..70802d5cba 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -29,6 +29,7 @@ open Nametab
open Notation
open Inductiveops
open Decl_kinds
+open Context.Rel.Declaration
(** constr_expr -> glob_constr translation:
- it adds holes for implicit arguments
@@ -1645,14 +1646,14 @@ let internalize globalenv env allow_patvar lvar c =
|loc,(Name y as x) -> (y,PatVar(loc,x)) :: l in
match case_rel_ctxt,arg_pats with
(* LetIn in the rel_context *)
- |(_,Some _,_)::t, l when not with_letin ->
+ | LocalDef _ :: t, l when not with_letin ->
canonize_args t l forbidden_names match_acc ((Loc.ghost,Anonymous)::var_acc)
|[],[] ->
(add_name match_acc na, var_acc)
|_::t,PatVar (loc,x)::tt ->
canonize_args t tt forbidden_names
(add_name match_acc (loc,x)) ((loc,x)::var_acc)
- |(cano_name,_,ty)::t,c::tt ->
+ | (LocalAssum (cano_name,ty) | LocalDef (cano_name,_,ty)) :: t, c::tt ->
let fresh =
Namegen.next_name_away_with_default_using_types "iV" cano_name forbidden_names ty in
canonize_args t tt (fresh::forbidden_names)
@@ -1894,7 +1895,7 @@ let interp_rawcontext_evars env evdref k bl =
let t' = locate_if_hole (loc_of_glob_constr t) na t in
let t =
understand_tcc_evars env evdref ~expected_type:IsType t' in
- let d = (na,None,t) in
+ let d = LocalAssum (na,t) in
let impls =
if k == Implicit then
let na = match na with Name n -> Some n | Anonymous -> None in
@@ -1904,7 +1905,7 @@ let interp_rawcontext_evars env evdref k bl =
(push_rel d env, d::params, succ n, impls)
| Some b ->
let c = understand_judgment_tcc env evdref b in
- let d = (na, Some c.uj_val, c.uj_type) in
+ let d = LocalDef (na, c.uj_val, c.uj_type) in
(push_rel d env, d::params, n, impls))
(env,[],k+1,[]) (List.rev bl)
in (env, par), impls
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index 391c600ed2..751b03a4a8 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -20,6 +20,7 @@ open Pp
open Libobject
open Nameops
open Misctypes
+open Context.Rel.Declaration
(*i*)
let generalizable_table = Summary.ref Id.Pred.empty ~name:"generalizable-ident"
@@ -196,7 +197,7 @@ let combine_params avoid fn applied needed =
List.partition
(function
(t, Some (loc, ExplByName id)) ->
- let is_id (_, (na, _, _)) = match na with
+ let is_id (_, decl) = match get_name decl with
| Name id' -> Id.equal id id'
| Anonymous -> false
in
@@ -209,22 +210,22 @@ let combine_params avoid fn applied needed =
(fun x -> match x with (t, Some (loc, ExplByName id)) -> id, t | _ -> assert false)
named
in
- let is_unset (_, (_, b, _)) = match b with
- | None -> true
- | Some _ -> false
+ let is_unset (_, decl) = match decl with
+ | LocalAssum _ -> true
+ | LocalDef _ -> false
in
let needed = List.filter is_unset needed in
let rec aux ids avoid app need =
match app, need with
[], [] -> List.rev ids, avoid
- | app, (_, (Name id, _, _)) :: need when Id.List.mem_assoc id named ->
+ | app, (_, (LocalAssum (Name id, _) | LocalDef (Name id, _, _))) :: need when Id.List.mem_assoc id named ->
aux (Id.List.assoc id named :: ids) avoid app need
- | (x, None) :: app, (None, (Name id, _, _)) :: need ->
+ | (x, None) :: app, (None, (LocalAssum (Name id, _) | LocalDef (Name id, _, _))) :: need ->
aux (x :: ids) avoid app need
- | _, (Some cl, (_, _, _) as d) :: need ->
+ | _, (Some cl, _ as d) :: need ->
let t', avoid' = fn avoid d in
aux (t' :: ids) avoid' app need
@@ -239,8 +240,8 @@ let combine_params avoid fn applied needed =
in aux [] avoid applied needed
let combine_params_freevar =
- fun avoid (_, (na, _, _)) ->
- let id' = next_name_away_from na avoid in
+ fun avoid (_, decl) ->
+ let id' = next_name_away_from (get_name decl) avoid in
(CRef (Ident (Loc.ghost, id'),None), Id.Set.add id' avoid)
let destClassApp cl =
diff --git a/interp/implicit_quantifiers.mli b/interp/implicit_quantifiers.mli
index b226bfa0af..d0327e5068 100644
--- a/interp/implicit_quantifiers.mli
+++ b/interp/implicit_quantifiers.mli
@@ -38,10 +38,10 @@ val make_fresh : Id.Set.t -> Environ.env -> Id.t -> Id.t
val implicits_of_glob_constr : ?with_products:bool -> Glob_term.glob_constr -> Impargs.manual_implicits
val combine_params_freevar :
- Id.Set.t -> (global_reference * bool) option * (Name.t * Term.constr option * Term.types) ->
+ Id.Set.t -> (global_reference * bool) option * Context.Rel.Declaration.t ->
Constrexpr.constr_expr * Id.Set.t
val implicit_application : Id.Set.t -> ?allow_partial:bool ->
- (Id.Set.t -> (global_reference * bool) option * (Name.t * Term.constr option * Term.types) ->
+ (Id.Set.t -> (global_reference * bool) option * Context.Rel.Declaration.t ->
Constrexpr.constr_expr * Id.Set.t) ->
constr_expr -> constr_expr * Id.Set.t
diff --git a/kernel/closure.ml b/kernel/closure.ml
index 9bc67b5adb..dc98cc65d0 100644
--- a/kernel/closure.ml
+++ b/kernel/closure.ml
@@ -247,8 +247,8 @@ let info_env info = info.i_cache.i_env
let rec assoc_defined id = function
| [] -> raise Not_found
-| (_, None, _) :: ctxt -> assoc_defined id ctxt
-| (id', Some c, _) :: ctxt ->
+| Context.Named.Declaration.LocalAssum _ :: ctxt -> assoc_defined id ctxt
+| Context.Named.Declaration.LocalDef (id', c, _) :: ctxt ->
if Id.equal id id' then c else assoc_defined id ctxt
let ref_value_cache ({i_cache = cache} as infos) ref =
@@ -285,9 +285,9 @@ let defined_rels flags env =
let ctx = rel_context env in
let len = List.length ctx in
let ans = Array.make len None in
- let iter i (_, b, _) = match b with
- | None -> ()
- | Some _ -> Array.unsafe_set ans i b
+ let iter i = function
+ | Context.Rel.Declaration.LocalAssum _ -> ()
+ | Context.Rel.Declaration.LocalDef (_,b,_) -> Array.unsafe_set ans i (Some b)
in
let () = List.iteri iter ctx in
ans
diff --git a/kernel/context.ml b/kernel/context.ml
index 3be1e83230..cc1e6f1762 100644
--- a/kernel/context.ml
+++ b/kernel/context.ml
@@ -33,33 +33,122 @@ open Names
Individual declarations are then designated by de Bruijn indexes. *)
module Rel =
struct
- (** Representation of {e local declarations}.
-
- [(name, None, typ)] represents a {e local assumption}.
- In the Reference Manual we denote them as [(name:typ)].
-
- [(name, Some value, typ)] represents a {e local definition}.
- In the Reference Manual we denote them as [(name := value : typ)].
- *)
+ (** Representation of {e local declarations}. *)
module Declaration =
struct
- type t = Name.t * Constr.t option * Constr.t
-
- (** Map all terms in a given declaration. *)
- let map f (n, v, ty) = (n, Option.map f v, f ty)
-
- (** Reduce all terms in a given declaration to a single value. *)
- let fold f (_, v, ty) a = f ty (Option.fold_right f v a)
+ (* local declaration *)
+ type t = LocalAssum of Name.t * Constr.t (* local assumption *)
+ | LocalDef of Name.t * Constr.t * Constr.t (* local definition *)
+
+ (** Return the name bound by a given declaration. *)
+ let get_name = function
+ | LocalAssum (na,_)
+ | LocalDef (na,_,_) -> na
+
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ let get_value = function
+ | LocalAssum _ -> None
+ | LocalDef (_,v,_) -> Some v
+
+ (** Return the type of the name bound by a given declaration. *)
+ let get_type = function
+ | LocalAssum (_,ty)
+ | LocalDef (_,_,ty) -> ty
+
+ (** Set the name that is bound by a given declaration. *)
+ let set_name na = function
+ | LocalAssum (_,ty) -> LocalAssum (na, ty)
+ | LocalDef (_,v,ty) -> LocalDef (na, v, ty)
+
+ (** Set the type of the bound variable in a given declaration. *)
+ let set_type ty = function
+ | LocalAssum (na,_) -> LocalAssum (na, ty)
+ | LocalDef (na,v,_) -> LocalDef (na, v, ty)
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ let is_local_assum = function
+ | LocalAssum _ -> true
+ | LocalDef _ -> false
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ let is_local_def = function
+ | LocalAssum _ -> false
+ | LocalDef _ -> true
(** Check whether any term in a given declaration satisfies a given predicate. *)
- let exists f (_, v, ty) = Option.cata f false v || f ty
+ let exists f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v || f ty
(** Check whether all terms in a given declaration satisfy a given predicate. *)
- let for_all f (_, v, ty) = Option.cata f true v && f ty
+ let for_all f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v && f ty
(** Check whether the two given declarations are equal. *)
- let equal (n1, v1, ty1) (n2, v2, ty2) =
- Name.equal n1 n2 && Option.equal Constr.equal v1 v2 && Constr.equal ty1 ty2
+ let equal decl1 decl2 =
+ match decl1, decl2 with
+ | LocalAssum (n1,ty1), LocalAssum (n2, ty2) ->
+ Name.equal n1 n2 && Constr.equal ty1 ty2
+ | LocalDef (n1,v1,ty1), LocalDef (n2,v2,ty2) ->
+ Name.equal n1 n2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
+ | _ ->
+ false
+
+ (** Map the name bound by a given declaration. *)
+ let map_name f = function
+ | LocalAssum (na, ty) as decl ->
+ let na' = f na in
+ if na == na' then decl else LocalAssum (na', ty)
+ | LocalDef (na, v, ty) as decl ->
+ let na' = f na in
+ if na == na' then decl else LocalDef (na', v, ty)
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ let map_value f = function
+ | LocalAssum _ as decl -> decl
+ | LocalDef (na, v, t) as decl ->
+ let v' = f v in
+ if v == v' then decl else LocalDef (na, v', t)
+
+ (** Map the type of the name bound by a given declaration. *)
+ let map_type f = function
+ | LocalAssum (na, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (na, ty')
+ | LocalDef (na, v, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalDef (na, v, ty')
+
+ (** Map all terms in a given declaration. *)
+ let map_constr f = function
+ | LocalAssum (na, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (na, ty')
+ | LocalDef (na, v, ty) as decl ->
+ let v' = f v in
+ let ty' = f ty in
+ if v == v' && ty == ty' then decl else LocalDef (na, v', ty')
+
+ (** Perform a given action on all terms in a given declaration. *)
+ let iter_constr f = function
+ | LocalAssum (_,ty) -> f ty
+ | LocalDef (_,v,ty) -> f v; f ty
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f decl acc =
+ match decl with
+ | LocalAssum (n,ty) -> f ty acc
+ | LocalDef (n,v,ty) -> f ty (f v acc)
+
+ let to_tuple = function
+ | LocalAssum (na, ty) -> na, None, ty
+ | LocalDef (na, v, ty) -> na, Some v, ty
+
+ let of_tuple = function
+ | n, None, ty -> LocalAssum (n,ty)
+ | n, Some v, ty -> LocalDef (n,v,ty)
end
(** Rel-context is represented as a list of declarations.
@@ -73,6 +162,21 @@ module Rel =
(** Return a new rel-context enriched by with a given inner-most declaration. *)
let add d ctx = d :: ctx
+ (** Return the number of {e local declarations} in a given context. *)
+ let length = List.length
+
+ (** [extended_rel_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the local definitions of [Γ] skipped in
+ [args]. Example: for [x:T,y:=c,z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ let nhyps =
+ let open Declaration in
+ let rec nhyps acc = function
+ | [] -> acc
+ | LocalAssum _ :: hyps -> nhyps (succ acc) hyps
+ | LocalDef _ :: hyps -> nhyps acc hyps
+ in
+ nhyps 0
+
(** Return a declaration designated by a given de Bruijn index.
@raise Not_found if the designated de Bruijn index is not present in the designated rel-context. *)
let rec lookup n ctx =
@@ -81,15 +185,14 @@ module Rel =
| n, _ :: sign -> lookup (n-1) sign
| _, [] -> raise Not_found
+ (** Check whether given two rel-contexts are equal. *)
+ let equal = List.equal Declaration.equal
+
(** Map all terms in a given rel-context. *)
- let map f =
- let map_decl (n, body_o, typ as decl) =
- let body_o' = Option.smartmap f body_o in
- let typ' = f typ in
- if body_o' == body_o && typ' == typ then decl else
- (n, body_o', typ')
- in
- List.smartmap map_decl
+ let map f = List.smartmap (Declaration.map_constr f)
+
+ (** Perform a given action on every declaration in a given rel-context. *)
+ let iter f = List.iter (Declaration.iter_constr f)
(** Reduce all terms in a given rel-context to a single value.
Innermost declarations are processed first. *)
@@ -99,29 +202,13 @@ module Rel =
Outermost declarations are processed first. *)
let fold_outside f l ~init = List.fold_right f l init
- (** Perform a given action on every declaration in a given rel-context. *)
- let iter f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
-
- (** Return the number of {e local declarations} in a given context. *)
- let length = List.length
-
- (** [extended_rel_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
- with n = |Δ| and with the local definitions of [Γ] skipped in
- [args]. Example: for [x:T,y:=c,z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
- let nhyps =
- let rec nhyps acc = function
- | [] -> acc
- | (_,None,_)::hyps -> nhyps (1+acc) hyps
- | (_,Some _,_)::hyps -> nhyps acc hyps in
- nhyps 0
-
(** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
and each {e local definition} is mapped to [false]. *)
let to_tags =
let rec aux l = function
| [] -> l
- | (_,Some _,_)::ctx -> aux (true::l) ctx
- | (_,None,_)::ctx -> aux (false::l) ctx
+ | Declaration.LocalDef _ :: ctx -> aux (true::l) ctx
+ | Declaration.LocalAssum _ :: ctx -> aux (false::l) ctx
in aux []
(** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
@@ -129,8 +216,8 @@ module Rel =
[args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
let to_extended_list n =
let rec reln l p = function
- | (_, None, _) :: hyps -> reln (Constr.mkRel (n+p) :: l) (p+1) hyps
- | (_, Some _, _) :: hyps -> reln l (p+1) hyps
+ | Declaration.LocalAssum _ :: hyps -> reln (Constr.mkRel (n+p) :: l) (p+1) hyps
+ | Declaration.LocalDef _ :: hyps -> reln l (p+1) hyps
| [] -> l
in
reln [] 1
@@ -143,38 +230,127 @@ module Rel =
Individual declarations are then designated by the identifiers they bind. *)
module Named =
struct
- (** Representation of {e local declarations}.
-
- [(id, None, typ)] represents a {e local assumption}.
- In the Reference Manual we denote them as [(name:typ)].
-
- [(id, Some value, typ)] represents a {e local definition}.
- In the Reference Manual we denote them as [(name := value : typ)].
- *)
+ (** Representation of {e local declarations}. *)
module Declaration =
struct
- (** Named-context is represented as a list of declarations.
- Inner-most declarations are at the beginning of the list.
- Outer-most declarations are at the end of the list. *)
- type t = Id.t * Constr.t option * Constr.t
-
- (** Map all terms in a given declaration. *)
- let map = Rel.Declaration.map
-
- (** Reduce all terms in a given declaration to a single value. *)
- let fold f (_, v, ty) a = f ty (Option.fold_right f v a)
+ (** local declaration *)
+ type t = LocalAssum of Id.t * Constr.t
+ | LocalDef of Id.t * Constr.t * Constr.t
+
+ (** Return the identifier bound by a given declaration. *)
+ let get_id = function
+ | LocalAssum (id,_) -> id
+ | LocalDef (id,_,_) -> id
+
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ let get_value = function
+ | LocalAssum _ -> None
+ | LocalDef (_,v,_) -> Some v
+
+ (** Return the type of the name bound by a given declaration. *)
+ let get_type = function
+ | LocalAssum (_,ty)
+ | LocalDef (_,_,ty) -> ty
+
+ (** Set the identifier that is bound by a given declaration. *)
+ let set_id id = function
+ | LocalAssum (_,ty) -> LocalAssum (id, ty)
+ | LocalDef (_, v, ty) -> LocalDef (id, v, ty)
+
+ (** Set the type of the bound variable in a given declaration. *)
+ let set_type ty = function
+ | LocalAssum (id,_) -> LocalAssum (id, ty)
+ | LocalDef (id,v,_) -> LocalDef (id, v, ty)
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ let is_local_assum = function
+ | LocalAssum _ -> true
+ | LocalDef _ -> false
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ let is_local_def = function
+ | LocalDef _ -> true
+ | LocalAssum _ -> false
(** Check whether any term in a given declaration satisfies a given predicate. *)
- let exists f (_, v, ty) = Option.cata f false v || f ty
+ let exists f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v || f ty
(** Check whether all terms in a given declaration satisfy a given predicate. *)
- let for_all f (_, v, ty) = Option.cata f true v && f ty
+ let for_all f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v && f ty
(** Check whether the two given declarations are equal. *)
- let equal (i1, v1, ty1) (i2, v2, ty2) =
- Id.equal i1 i2 && Option.equal Constr.equal v1 v2 && Constr.equal ty1 ty2
+ let equal decl1 decl2 =
+ match decl1, decl2 with
+ | LocalAssum (id1, ty1), LocalAssum (id2, ty2) ->
+ Id.equal id1 id2 && Constr.equal ty1 ty2
+ | LocalDef (id1, v1, ty1), LocalDef (id2, v2, ty2) ->
+ Id.equal id1 id2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
+ | _ ->
+ false
+
+ (** Map the identifier bound by a given declaration. *)
+ let map_id f = function
+ | LocalAssum (id, ty) as decl ->
+ let id' = f id in
+ if id == id' then decl else LocalAssum (id', ty)
+ | LocalDef (id, v, ty) as decl ->
+ let id' = f id in
+ if id == id' then decl else LocalDef (id', v, ty)
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ let map_value f = function
+ | LocalAssum _ as decl -> decl
+ | LocalDef (na, v, t) as decl ->
+ let v' = f v in
+ if v == v' then decl else LocalDef (na, v', t)
+
+ (** Map the type of the name bound by a given declaration. *)
+ let map_type f = function
+ | LocalAssum (id, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (id, ty')
+ | LocalDef (id, v, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalDef (id, v, ty')
+
+ (** Map all terms in a given declaration. *)
+ let map_constr f = function
+ | LocalAssum (id, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (id, ty')
+ | LocalDef (id, v, ty) as decl ->
+ let v' = f v in
+ let ty' = f ty in
+ if v == v' && ty == ty' then decl else LocalDef (id, v', ty')
+
+ (** Perform a given action on all terms in a given declaration. *)
+ let iter_constr f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v; f ty
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f decl a =
+ match decl with
+ | LocalAssum (_, ty) -> f ty a
+ | LocalDef (_, v, ty) -> a |> f v |> f ty
+
+ let to_tuple = function
+ | LocalAssum (id, ty) -> id, None, ty
+ | LocalDef (id, v, ty) -> id, Some v, ty
+
+ let of_tuple = function
+ | id, None, ty -> LocalAssum (id, ty)
+ | id, Some v, ty -> LocalDef (id, v, ty)
end
+ (** Named-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
type t = Declaration.t list
(** empty named-context *)
@@ -183,22 +359,23 @@ module Named =
(** empty named-context *)
let add d ctx = d :: ctx
+ (** Return the number of {e local declarations} in a given named-context. *)
+ let length = List.length
+
(** Return a declaration designated by a given de Bruijn index.
- @raise Not_found if the designated identifier is not present in the designated named-context. *)
- let rec lookup id = function
- | (id',_,_ as decl) :: _ when Id.equal id id' -> decl
- | _ :: sign -> lookup id sign
- | [] -> raise Not_found
+ @raise Not_found if the designated identifier is not present in the designated named-context. *) let rec lookup id = function
+ | decl :: _ when Id.equal id (Declaration.get_id decl) -> decl
+ | _ :: sign -> lookup id sign
+ | [] -> raise Not_found
+
+ (** Check whether given two named-contexts are equal. *)
+ let equal = List.equal Declaration.equal
(** Map all terms in a given named-context. *)
- let map f =
- let map_decl (n, body_o, typ as decl) =
- let body_o' = Option.smartmap f body_o in
- let typ' = f typ in
- if body_o' == body_o && typ' == typ then decl else
- (n, body_o', typ')
- in
- List.smartmap map_decl
+ let map f = List.smartmap (Declaration.map_constr f)
+
+ (** Perform a given action on every declaration in a given named-context. *)
+ let iter f = List.iter (Declaration.iter_constr f)
(** Reduce all terms in a given named-context to a single value.
Innermost declarations are processed first. *)
@@ -208,18 +385,9 @@ module Named =
Outermost declarations are processed first. *)
let fold_outside f l ~init = List.fold_right f l init
- (** Perform a given action on every declaration in a given named-context. *)
- let iter f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
-
- (** Return the number of {e local declarations} in a given named-context. *)
- let length = List.length
-
- (** Check whether given two named-contexts are equal. *)
- let equal = List.equal Declaration.equal
-
(** Return the set of all identifiers bound in a given named-context. *)
let to_vars =
- List.fold_left (fun accu (id, _, _) -> Id.Set.add id accu) Id.Set.empty
+ List.fold_left (fun accu decl -> Id.Set.add (Declaration.get_id decl) accu) Id.Set.empty
(** [instance_from_named_context Ω] builds an instance [args] such
that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
@@ -227,8 +395,8 @@ module Named =
gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
let to_instance =
let filter = function
- | (id, None, _) -> Some (Constr.mkVar id)
- | (_, Some _, _) -> None
+ | Declaration.LocalAssum (id, _) -> Some (Constr.mkVar id)
+ | _ -> None
in
List.map_filter filter
end
@@ -238,9 +406,15 @@ module NamedList =
module Declaration =
struct
type t = Id.t list * Constr.t option * Constr.t
- let map = Named.Declaration.map
+
+ let map_constr f (ids, copt, ty as decl) =
+ let copt' = Option.map f copt in
+ let ty' = f ty in
+ if copt == copt' && ty == ty' then decl else (ids, copt', ty')
end
+
type t = Declaration.t list
+
let fold f l ~init = List.fold_right f l init
end
diff --git a/kernel/context.mli b/kernel/context.mli
index 1976e46d33..a69754cc29 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -26,21 +26,32 @@ open Names
Individual declarations are then designated by de Bruijn indexes. *)
module Rel :
sig
- (** Representation of {e local declarations}.
-
- [(name, None, typ)] represents a {e local assumption}.
-
- [(name, Some value, typ)] represents a {e local definition}.
- *)
module Declaration :
sig
- type t = Name.t * Constr.t option * Constr.t
+ (* local declaration *)
+ type t = LocalAssum of Name.t * Constr.t (* local assumption *)
+ | LocalDef of Name.t * Constr.t * Constr.t (* local definition *)
- (** Map all terms in a given declaration. *)
- val map : (Constr.t -> Constr.t) -> t -> t
+ (** Return the name bound by a given declaration. *)
+ val get_name : t -> Name.t
- (** Reduce all terms in a given declaration to a single value. *)
- val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ val get_value : t -> Constr.t option
+
+ (** Return the type of the name bound by a given declaration. *)
+ val get_type : t -> Constr.t
+
+ (** Set the name that is bound by a given declaration. *)
+ val set_name : Name.t -> t -> t
+
+ (** Set the type of the bound variable in a given declaration. *)
+ val set_type : Constr.t -> t -> t
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ val is_local_assum : t -> bool
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ val is_local_def : t -> bool
(** Check whether any term in a given declaration satisfies a given predicate. *)
val exists : (Constr.t -> bool) -> t -> bool
@@ -50,6 +61,28 @@ sig
(** Check whether the two given declarations are equal. *)
val equal : t -> t -> bool
+
+ (** Map the name bound by a given declaration. *)
+ val map_name : (Name.t -> Name.t) -> t -> t
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ val map_value : (Constr.t -> Constr.t) -> t -> t
+
+ (** Map the type of the name bound by a given declaration. *)
+ val map_type : (Constr.t -> Constr.t) -> t -> t
+
+ (** Map all terms in a given declaration. *)
+ val map_constr : (Constr.t -> Constr.t) -> t -> t
+
+ (** Perform a given action on all terms in a given declaration. *)
+ val iter_constr : (Constr.t -> unit) -> t -> unit
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
+
+ val to_tuple : t -> Name.t * Constr.t option * Constr.t
+ val of_tuple : Name.t * Constr.t option * Constr.t -> t
end
(** Rel-context is represented as a list of declarations.
@@ -63,6 +96,15 @@ sig
(** Return a new rel-context enriched by with a given inner-most declaration. *)
val add : Declaration.t -> t -> t
+ (** Return the number of {e local declarations} in a given context. *)
+ val length : t -> int
+
+ (** Check whether given two rel-contexts are equal. *)
+ val equal : t -> t -> bool
+
+ (** Return the number of {e local assumptions} in a given rel-context. *)
+ val nhyps : t -> int
+
(** Return a declaration designated by a given de Bruijn index.
@raise Not_found if the designated de Bruijn index outside the range. *)
val lookup : int -> t -> Declaration.t
@@ -70,6 +112,9 @@ sig
(** Map all terms in a given rel-context. *)
val map : (Constr.t -> Constr.t) -> t -> t
+ (** Perform a given action on every declaration in a given rel-context. *)
+ val iter : (Constr.t -> unit) -> t -> unit
+
(** Reduce all terms in a given rel-context to a single value.
Innermost declarations are processed first. *)
val fold_inside : ('a -> Declaration.t -> 'a) -> init:'a -> t -> 'a
@@ -78,15 +123,6 @@ sig
Outermost declarations are processed first. *)
val fold_outside : (Declaration.t -> 'a -> 'a) -> t -> init:'a -> 'a
- (** Perform a given action on every declaration in a given rel-context. *)
- val iter : (Constr.t -> unit) -> t -> unit
-
- (** Return the number of {e local declarations} in a given context. *)
- val length : t -> int
-
- (** Return the number of {e local assumptions} in a given rel-context. *)
- val nhyps : t -> int
-
(** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
and each {e local definition} is mapped to [false]. *)
val to_tags : t -> bool list
@@ -104,21 +140,32 @@ end
Individual declarations are then designated by the identifiers they bind. *)
module Named :
sig
- (** Representation of {e local declarations}.
-
- [(id, None, typ)] represents a {e local assumption}.
-
- [(id, Some value, typ)] represents a {e local definition}.
- *)
+ (** Representation of {e local declarations}. *)
module Declaration :
sig
- type t = Id.t * Constr.t option * Constr.t
+ type t = LocalAssum of Id.t * Constr.t
+ | LocalDef of Id.t * Constr.t * Constr.t
- (** Map all terms in a given declaration. *)
- val map : (Constr.t -> Constr.t) -> t -> t
+ (** Return the identifier bound by a given declaration. *)
+ val get_id : t -> Id.t
- (** Reduce all terms in a given declaration to a single value. *)
- val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ val get_value : t -> Constr.t option
+
+ (** Return the type of the name bound by a given declaration. *)
+ val get_type : t -> Constr.t
+
+ (** Set the identifier that is bound by a given declaration. *)
+ val set_id : Id.t -> t -> t
+
+ (** Set the type of the bound variable in a given declaration. *)
+ val set_type : Constr.t -> t -> t
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ val is_local_assum : t -> bool
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ val is_local_def : t -> bool
(** Check whether any term in a given declaration satisfies a given predicate. *)
val exists : (Constr.t -> bool) -> t -> bool
@@ -128,6 +175,28 @@ sig
(** Check whether the two given declarations are equal. *)
val equal : t -> t -> bool
+
+ (** Map the identifier bound by a given declaration. *)
+ val map_id : (Id.t -> Id.t) -> t -> t
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ val map_value : (Constr.t -> Constr.t) -> t -> t
+
+ (** Map the type of the name bound by a given declaration. *)
+ val map_type : (Constr.t -> Constr.t) -> t -> t
+
+ (** Map all terms in a given declaration. *)
+ val map_constr : (Constr.t -> Constr.t) -> t -> t
+
+ (** Perform a given action on all terms in a given declaration. *)
+ val iter_constr : (Constr.t -> unit) -> t -> unit
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
+
+ val to_tuple : t -> Id.t * Constr.t option * Constr.t
+ val of_tuple : Id.t * Constr.t option * Constr.t -> t
end
(** Rel-context is represented as a list of declarations.
@@ -141,13 +210,22 @@ sig
(** Return a new rel-context enriched by with a given inner-most declaration. *)
val add : Declaration.t -> t -> t
+ (** Return the number of {e local declarations} in a given named-context. *)
+ val length : t -> int
+
(** Return a declaration designated by an identifier of the variable bound in that declaration.
@raise Not_found if the designated identifier is not bound in a given named-context. *)
val lookup : Id.t -> t -> Declaration.t
+ (** Check whether given two rel-contexts are equal. *)
+ val equal : t -> t -> bool
+
(** Map all terms in a given named-context. *)
val map : (Constr.t -> Constr.t) -> t -> t
+ (** Perform a given action on every declaration in a given named-context. *)
+ val iter : (Constr.t -> unit) -> t -> unit
+
(** Reduce all terms in a given named-context to a single value.
Innermost declarations are processed first. *)
val fold_inside : ('a -> Declaration.t -> 'a) -> init:'a -> t -> 'a
@@ -156,15 +234,6 @@ sig
Outermost declarations are processed first. *)
val fold_outside : (Declaration.t -> 'a -> 'a) -> t -> init:'a -> 'a
- (** Perform a given action on every declaration in a given named-context. *)
- val iter : (Constr.t -> unit) -> t -> unit
-
- (** Return the number of {e local declarations} in a given named-context. *)
- val length : t -> int
-
- (** Check whether given two named-contexts are equal. *)
- val equal : t -> t -> bool
-
(** Return the set of all identifiers bound in a given named-context. *)
val to_vars : t -> Id.Set.t
@@ -180,7 +249,7 @@ sig
module Declaration :
sig
type t = Id.t list * Constr.t option * Constr.t
- val map : (Constr.t -> Constr.t) -> t -> t
+ val map_constr : (Constr.t -> Constr.t) -> t -> t
end
type t = Declaration.t list
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 3ab6983d8a..d2106f8609 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -201,8 +201,11 @@ let cook_constant env { from = cb; info } =
cb.const_body
in
let const_hyps =
- Context.Named.fold_outside (fun (h,_,_) hyps ->
- List.filter (fun (id,_,_) -> not (Id.equal id h)) hyps)
+ Context.Named.fold_outside (fun decl hyps ->
+ let open Context.Named.Declaration in
+ let h = get_id decl in
+ List.filter (fun decl -> let id = get_id decl in
+ not (Id.equal id h)) hyps)
hyps ~init:cb.const_hyps in
let typ = match cb.const_type with
| RegularArity t ->
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index 8f60216afa..cfbb89f06c 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -189,16 +189,18 @@ and slot_for_fv env fv =
let nv = Pre_env.lookup_named_val id env in
begin match force_lazy_val nv with
| None ->
- let _, b, _ = Context.Named.lookup id env.env_named_context in
- fill_fv_cache nv id val_of_named idfun b
+ let open Context.Named in
+ let open Context.Named.Declaration in
+ fill_fv_cache nv id val_of_named idfun (lookup id env.env_named_context |> get_value)
| Some (v, _) -> v
end
| FVrel i ->
let rv = Pre_env.lookup_rel_val i env in
begin match force_lazy_val rv with
| None ->
- let _, b, _ = Context.Rel.lookup i env.env_rel_context in
- fill_fv_cache rv i val_of_rel env_of_rel b
+ let open Context.Rel in
+ let open Context.Rel.Declaration in
+ fill_fv_cache rv i val_of_rel env_of_rel (lookup i env.env_rel_context |> get_value)
| Some (v, _) -> v
end
| FVuniv_var idu ->
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index f73eea030f..cb67135ad4 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -87,10 +87,18 @@ let is_opaque cb = match cb.const_body with
(** {7 Constant substitutions } *)
-let subst_rel_declaration sub (id,copt,t as x) =
- let copt' = Option.smartmap (subst_mps sub) copt in
- let t' = subst_mps sub t in
- if copt == copt' && t == t' then x else (id,copt',t')
+let subst_rel_declaration sub x =
+ let open Context.Rel.Declaration in
+ match x with
+ | LocalAssum (id,t) ->
+ let t' = subst_mps sub t in
+ if t == t' then x
+ else LocalAssum (id,t')
+ | LocalDef (id,v,t) ->
+ let v' = subst_mps sub v in
+ let t' = subst_mps sub t in
+ if v == v' && t == t' then x
+ else LocalDef (id,v',t')
let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
@@ -140,11 +148,20 @@ let subst_const_body sub cb =
share internal fields (e.g. constr), and not the records
themselves. But would it really bring substantial gains ? *)
-let hcons_rel_decl ((n,oc,t) as d) =
- let n' = Names.Name.hcons n
- and oc' = Option.smartmap Term.hcons_constr oc
- and t' = Term.hcons_types t
- in if n' == n && oc' == oc && t' == t then d else (n',oc',t')
+let hcons_rel_decl d =
+ let open Context.Rel.Declaration in
+ match d with
+ | LocalAssum (n,t) ->
+ let n' = Names.Name.hcons n
+ and t' = Term.hcons_types t in
+ if n' == n && t' == t then d
+ else LocalAssum (n',t')
+ | LocalDef (n,v,t) ->
+ let n' = Names.Name.hcons n
+ and v' = Term.hcons_constr v
+ and t' = Term.hcons_types t in
+ if n' == n && v' == v && t' == t then d
+ else LocalDef (n',v',t')
let hcons_rel_context l = List.smartmap hcons_rel_decl l
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 847e1d08f9..1089dff92c 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -72,9 +72,8 @@ let lookup_rel n env =
Context.Rel.lookup n env.env_rel_context
let evaluable_rel n env =
- match lookup_rel n env with
- | (_,Some _,_) -> true
- | _ -> false
+ let open Context.Rel.Declaration in
+ lookup_rel n env |> is_local_def
let nb_rel env = env.env_nb_rel
@@ -83,7 +82,8 @@ let push_rel = push_rel
let push_rel_context ctxt x = Context.Rel.fold_outside push_rel ctxt ~init:x
let push_rec_types (lna,typarray,_) env =
- let ctxt = Array.map2_i (fun i na t -> (na, None, lift i t)) lna typarray in
+ let open Context.Rel.Declaration in
+ let ctxt = Array.map2_i (fun i na t -> LocalAssum (na, lift i t)) lna typarray in
Array.fold_left (fun e assum -> push_rel assum e) env ctxt
let fold_rel_context f env ~init =
@@ -107,17 +107,8 @@ let named_vals_of_val = snd
(* [map_named_val f ctxt] apply [f] to the body and the type of
each declarations.
*** /!\ *** [f t] should be convertible with t *)
-let map_named_val f (ctxt,ctxtv) =
- let rec map ctx = match ctx with
- | [] -> []
- | (id, body, typ) :: rem ->
- let body' = Option.smartmap f body in
- let typ' = f typ in
- let rem' = map rem in
- if body' == body && typ' == typ && rem' == rem then ctx
- else (id, body', typ') :: rem'
- in
- (map ctxt, ctxtv)
+let map_named_val f =
+ on_fst (Context.Named.map f)
let empty_named_context = Context.Named.empty
@@ -138,10 +129,10 @@ let eq_named_context_val c1 c2 =
(* A local const is evaluable if it is defined *)
let named_type id env =
- let (_,_,t) = lookup_named id env in t
+ lookup_named id env |> Context.Named.Declaration.get_type
let named_body id env =
- let (_,b,_) = lookup_named id env in b
+ lookup_named id env |> Context.Named.Declaration.get_value
let evaluable_named id env =
match named_body id env with
@@ -426,15 +417,16 @@ let global_vars_set env constr =
contained in the types of the needed variables. *)
let really_needed env needed =
+ let open Context.Named.Declaration in
Context.Named.fold_inside
- (fun need (id,copt,t) ->
- if Id.Set.mem id need then
+ (fun need decl ->
+ if Id.Set.mem (get_id decl) need then
let globc =
- match copt with
- | None -> Id.Set.empty
- | Some c -> global_vars_set env c in
+ match decl with
+ | LocalAssum _ -> Id.Set.empty
+ | LocalDef (_,c,_) -> global_vars_set env c in
Id.Set.union
- (global_vars_set env t)
+ (global_vars_set env (get_type decl))
(Id.Set.union globc need)
else need)
~init:needed
@@ -443,8 +435,9 @@ let really_needed env needed =
let keep_hyps env needed =
let really_needed = really_needed env needed in
Context.Named.fold_outside
- (fun (id,_,_ as d) nsign ->
- if Id.Set.mem id really_needed then Context.Named.add d nsign
+ (fun d nsign ->
+ let open Context.Named.Declaration in
+ if Id.Set.mem (get_id d) really_needed then Context.Named.add d nsign
else nsign)
(named_context env)
~init:empty_named_context
@@ -494,11 +487,12 @@ let compile_constant_body = Cbytegen.compile_constant_body false
exception Hyp_not_found
let apply_to_hyp (ctxt,vals) id f =
+ let open Context.Named.Declaration in
let rec aux rtail ctxt vals =
match ctxt, vals with
- | (idc,c,ct as d)::ctxt, v::vals ->
- if Id.equal idc id then
- (f ctxt d rtail)::ctxt, v::vals
+ | d::ctxt, v::vals ->
+ if Id.equal (get_id d) id then
+ (f ctxt d rtail)::ctxt, v::vals
else
let ctxt',vals' = aux (d::rtail) ctxt vals in
d::ctxt', v::vals'
@@ -507,10 +501,11 @@ let apply_to_hyp (ctxt,vals) id f =
in aux [] ctxt vals
let apply_to_hyp_and_dependent_on (ctxt,vals) id f g =
+ let open Context.Named.Declaration in
let rec aux ctxt vals =
match ctxt,vals with
- | (idc,c,ct as d)::ctxt, v::vals ->
- if Id.equal idc id then
+ | d::ctxt, v::vals ->
+ if Id.equal (get_id d) id then
let sign = ctxt,vals in
push_named_context_val (f d sign) sign
else
@@ -521,10 +516,11 @@ let apply_to_hyp_and_dependent_on (ctxt,vals) id f g =
in aux ctxt vals
let insert_after_hyp (ctxt,vals) id d check =
+ let open Context.Named.Declaration in
let rec aux ctxt vals =
match ctxt, vals with
- | (idc,c,ct)::ctxt', v::vals' ->
- if Id.equal idc id then begin
+ | decl::ctxt', v::vals' ->
+ if Id.equal (get_id decl) id then begin
check ctxt;
push_named_context_val d (ctxt,vals)
end else
@@ -537,12 +533,12 @@ let insert_after_hyp (ctxt,vals) id d check =
(* To be used in Logic.clear_hyps *)
let remove_hyps ids check_context check_value (ctxt, vals) =
+ let open Context.Named.Declaration in
let rec remove_hyps ctxt vals = match ctxt, vals with
| [], [] -> [], []
| d :: rctxt, (nid, v) :: rvals ->
- let (id, _, _) = d in
let ans = remove_hyps rctxt rvals in
- if Id.Set.mem id ids then ans
+ if Id.Set.mem (get_id d) ids then ans
else
let (rctxt', rvals') = ans in
let d' = check_context d in
diff --git a/kernel/fast_typeops.ml b/kernel/fast_typeops.ml
index ebc1853d93..df95c93dc5 100644
--- a/kernel/fast_typeops.ml
+++ b/kernel/fast_typeops.ml
@@ -73,8 +73,9 @@ let judge_of_type u =
let judge_of_relative env n =
try
- let (_,_,typ) = lookup_rel n env in
- lift n typ
+ let open Context.Rel.Declaration in
+ let typ = get_type (lookup_rel n env) in
+ lift n typ
with Not_found ->
error_unbound_rel env n
@@ -91,7 +92,10 @@ let judge_of_variable env id =
(* TODO: check order? *)
let check_hyps_inclusion env f c sign =
Context.Named.fold_outside
- (fun (id,_,ty1) () ->
+ (fun decl () ->
+ let open Context.Named.Declaration in
+ let id = get_id decl in
+ let ty1 = get_type decl in
try
let ty2 = named_type id env in
if not (eq_constr ty2 ty1) then raise Exit
@@ -325,6 +329,7 @@ let type_fixpoint env lna lar vdef vdeft =
Ind et Constructsi un jour cela devient des constructions
arbitraires et non plus des variables *)
let rec execute env cstr =
+ let open Context.Rel.Declaration in
match kind_of_term cstr with
(* Atomic terms *)
| Sort (Prop c) ->
@@ -368,13 +373,13 @@ let rec execute env cstr =
| Lambda (name,c1,c2) ->
let _ = execute_is_type env c1 in
- let env1 = push_rel (name,None,c1) env in
+ let env1 = push_rel (LocalAssum (name,c1)) env in
let c2t = execute env1 c2 in
judge_of_abstraction env name c1 c2t
| Prod (name,c1,c2) ->
let vars = execute_is_type env c1 in
- let env1 = push_rel (name,None,c1) env in
+ let env1 = push_rel (LocalAssum (name,c1)) env in
let vars' = execute_is_type env1 c2 in
judge_of_product env name vars vars'
@@ -382,7 +387,7 @@ let rec execute env cstr =
let c1t = execute env c1 in
let _c2s = execute_is_type env c2 in
let _ = judge_of_cast env c1 c1t DEFAULTcast c2 in
- let env1 = push_rel (name,Some c1,c2) env in
+ let env1 = push_rel (LocalDef (name,c1,c2)) env in
let c3t = execute env1 c3 in
subst1 c1 c3t
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index a8625009ce..4834f95d15 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -20,6 +20,7 @@ open Reduction
open Typeops
open Entries
open Pp
+open Context.Rel.Declaration
(* Tell if indices (aka real arguments) contribute to size of inductive type *)
(* If yes, this is compatible with the univalent model *)
@@ -122,7 +123,7 @@ let infos_and_sort env t =
match kind_of_term t with
| Prod (name,c1,c2) ->
let varj = infer_type env c1 in
- let env1 = Environ.push_rel (name,None,varj.utj_val) env in
+ let env1 = Environ.push_rel (LocalAssum (name,varj.utj_val)) env in
let max = Universe.sup max (univ_of_sort varj.utj_type) in
aux env1 c2 max
| _ when is_constructor_head t -> max
@@ -168,12 +169,14 @@ let infer_constructor_packet env_ar_par params lc =
(* If indices matter *)
let cumulate_arity_large_levels env sign =
fst (List.fold_right
- (fun (_,b,t as d) (lev,env) ->
- if Option.is_empty b then
+ (fun d (lev,env) ->
+ match d with
+ | LocalAssum (_,t) ->
let tj = infer_type env t in
let u = univ_of_sort tj.utj_type in
(Universe.sup u lev, push_rel d env)
- else lev, push_rel d env)
+ | LocalDef _ ->
+ lev, push_rel d env)
sign (Universe.type0m,env))
let is_impredicative env u =
@@ -184,12 +187,12 @@ let is_impredicative env u =
from the most recent and ignoring let-definitions) is not contributing
or is Some u_k if its level is u_k and is contributing. *)
let param_ccls params =
- let fold acc = function (_, None, p) ->
+ let fold acc = function (LocalAssum (_, p)) ->
(let c = strip_prod_assum p in
match kind_of_term c with
| Sort (Type u) -> Univ.Universe.level u
| _ -> None) :: acc
- | _ -> acc
+ | LocalDef _ -> acc
in
List.fold_left fold [] params
@@ -249,7 +252,7 @@ let typecheck_inductive env mie =
let full_arity = it_mkProd_or_LetIn arity params in
let id = ind.mind_entry_typename in
let env_ar' =
- push_rel (Name id, None, full_arity) env_ar in
+ push_rel (LocalAssum (Name id, full_arity)) env_ar in
(* (add_constraints cst2 env_ar) in *)
(env_ar', (id,full_arity,sign @ params,expltype,deflev,inflev)::l))
(env',[])
@@ -390,7 +393,7 @@ let check_correct_par (env,n,ntypes,_) hyps l largs =
let nhyps = List.length hyps in
let rec check k index = function
| [] -> ()
- | (_,Some _,_)::hyps -> check k (index+1) hyps
+ | LocalDef _ :: hyps -> check k (index+1) hyps
| _::hyps ->
match kind_of_term (whd_betadeltaiota env lpar.(k)) with
| Rel w when Int.equal w index -> check (k-1) (index+1) hyps
@@ -412,7 +415,7 @@ if Int.equal nmr 0 then 0 else
function
([],_) -> nmr
| (_,[]) -> assert false (* |hyps|>=nmr *)
- | (lp,(_,Some _,_)::hyps) -> find k (index-1) (lp,hyps)
+ | (lp, LocalDef _ :: hyps) -> find k (index-1) (lp,hyps)
| (p::lp,_::hyps) ->
( match kind_of_term (whd_betadeltaiota env p) with
| Rel w when Int.equal w index -> find (k+1) (index-1) (lp,hyps)
@@ -426,15 +429,15 @@ if Int.equal nmr 0 then 0 else
[lra] is the list of recursive tree of each variable
*)
let ienv_push_var (env, n, ntypes, lra) (x,a,ra) =
- (push_rel (x,None,a) env, n+1, ntypes, (Norec,ra)::lra)
+ (push_rel (LocalAssum (x,a)) env, n+1, ntypes, (Norec,ra)::lra)
let ienv_push_inductive (env, n, ntypes, ra_env) ((mi,u),lpar) =
let auxntyp = 1 in
let specif = (lookup_mind_specif env mi, u) in
let ty = type_of_inductive env specif in
let env' =
- push_rel (Anonymous,None,
- hnf_prod_applist env ty lpar) env in
+ let decl = LocalAssum (Anonymous, hnf_prod_applist env ty lpar) in
+ push_rel decl env in
let ra_env' =
(Imbr mi,(Rtree.mk_rec_calls 1).(0)) ::
List.map (fun (r,t) -> (r,Rtree.lift 1 t)) ra_env in
@@ -726,9 +729,9 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
let body = mkCase (ci, p, mkRel 1, [|lift 1 branch|]) in
it_mkLambda_or_LetIn (mkLambda (x,indty,body)) params
in
- let projections (na, b, t) (i, j, kns, pbs, subst, letsubst) =
- match b with
- | Some c ->
+ let projections decl (i, j, kns, pbs, subst, letsubst) =
+ match decl with
+ | LocalDef (na,c,t) ->
(* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)
let c = liftn 1 j c in
@@ -746,7 +749,7 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
to [params-wo-let, x:I |- subst:(params, x:I, field1,..,fieldj+1)] *)
let letsubst = c2 :: letsubst in
(i, j+1, kns, pbs, subst, letsubst)
- | None ->
+ | LocalAssum (na,t) ->
match na with
| Name id ->
let kn = Constant.make1 (KerName.make mp dp (Label.of_id id)) in
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index dd49c4a1b7..ca29d83f6a 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -17,6 +17,7 @@ open Declareops
open Environ
open Reduction
open Type_errors
+open Context.Rel.Declaration
type mind_specif = mutual_inductive_body * one_inductive_body
@@ -77,10 +78,10 @@ let instantiate_params full t u args sign =
anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch") in
let (rem_args, subs, ty) =
Context.Rel.fold_outside
- (fun (_,copt,_) (largs,subs,ty) ->
- match (copt, largs, kind_of_term ty) with
- | (None, a::args, Prod(_,_,t)) -> (args, a::subs, t)
- | (Some b,_,LetIn(_,_,_,t)) ->
+ (fun decl (largs,subs,ty) ->
+ match (decl, largs, kind_of_term ty) with
+ | (LocalAssum _, a::args, Prod(_,_,t)) -> (args, a::subs, t)
+ | (LocalDef (_,b,_), _, LetIn(_,_,_,t)) ->
(largs, (substl subs (subst_instance_constr u b))::subs, t)
| (_,[],_) -> if full then fail() else ([], subs, ty)
| _ -> fail ())
@@ -152,7 +153,7 @@ let remember_subst u subst =
(* Propagate the new levels in the signature *)
let make_subst env =
let rec make subst = function
- | (_,Some _,_)::sign, exp, args ->
+ | LocalDef _ :: sign, exp, args ->
make subst (sign, exp, args)
| d::sign, None::exp, args ->
let args = match args with _::args -> args | [] -> [] in
@@ -165,7 +166,7 @@ let make_subst env =
(* a useless extra constraint *)
let s = sort_as_univ (snd (dest_arity env (Lazy.force a))) in
make (cons_subst u s subst) (sign, exp, args)
- | (na,None,t)::sign, Some u::exp, [] ->
+ | LocalAssum (na,t) :: sign, Some u::exp, [] ->
(* No more argument here: we add the remaining universes to the *)
(* substitution (when [u] is distinct from all other universes in the *)
(* template, it is identity substitution otherwise (ie. when u is *)
@@ -314,14 +315,14 @@ let is_correct_arity env c pj ind specif params =
let rec srec env pt ar =
let pt' = whd_betadeltaiota env pt in
match kind_of_term pt', ar with
- | Prod (na1,a1,t), (_,None,a1')::ar' ->
+ | Prod (na1,a1,t), (LocalAssum (_,a1'))::ar' ->
let () =
try conv env a1 a1'
with NotConvertible -> raise (LocalArity None) in
- srec (push_rel (na1,None,a1) env) t ar'
+ srec (push_rel (LocalAssum (na1,a1)) env) t ar'
(* The last Prod domain is the type of the scrutinee *)
| Prod (na1,a1,a2), [] -> (* whnf of t was not needed here! *)
- let env' = push_rel (na1,None,a1) env in
+ let env' = push_rel (LocalAssum (na1,a1)) env in
let ksort = match kind_of_term (whd_betadeltaiota env' a2) with
| Sort s -> family_of_sort s
| _ -> raise (LocalArity None) in
@@ -330,7 +331,7 @@ let is_correct_arity env c pj ind specif params =
try conv env a1 dep_ind
with NotConvertible -> raise (LocalArity None) in
check_allowed_sort ksort specif
- | _, (_,Some _,_ as d)::ar' ->
+ | _, (LocalDef _ as d)::ar' ->
srec (push_rel d env) (lift 1 pt') ar'
| _ ->
raise (LocalArity None)
@@ -482,7 +483,7 @@ let make_renv env recarg tree =
genv = [Lazy.lazy_from_val(Subterm(Large,tree))] }
let push_var renv (x,ty,spec) =
- { env = push_rel (x,None,ty) renv.env;
+ { env = push_rel (LocalAssum (x,ty)) renv.env;
rel_min = renv.rel_min+1;
genv = spec:: renv.genv }
@@ -568,14 +569,14 @@ let check_inductive_codomain env p =
(* The following functions are almost duplicated from indtypes.ml, except
that they carry here a poorer environment (containing less information). *)
let ienv_push_var (env, lra) (x,a,ra) =
- (push_rel (x,None,a) env, (Norec,ra)::lra)
+ (push_rel (LocalAssum (x,a)) env, (Norec,ra)::lra)
let ienv_push_inductive (env, ra_env) ((mind,u),lpar) =
let mib = Environ.lookup_mind mind env in
let ntypes = mib.mind_ntypes in
let push_ind specif env =
- push_rel (Anonymous,None,
- hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar) env
+ let decl = LocalAssum (Anonymous, hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar) in
+ push_rel decl env
in
let env = Array.fold_right push_ind mib.mind_packets env in
let rc = Array.mapi (fun j t -> (Imbr (mind,j),t)) (Rtree.mk_rec_calls ntypes) in
@@ -848,7 +849,7 @@ let filter_stack_domain env ci p stack =
let t = whd_betadeltaiota env ar in
match stack, kind_of_term t with
| elt :: stack', Prod (n,a,c0) ->
- let d = (n,None,a) in
+ let d = LocalAssum (n,a) in
let ty, args = decompose_app (whd_betadeltaiota env a) in
let elt = match kind_of_term ty with
| Ind ind ->
@@ -905,10 +906,10 @@ let check_one_fix renv recpos trees def =
end
else
begin
- match pi2 (lookup_rel p renv.env) with
- | None ->
+ match lookup_rel p renv.env with
+ | LocalAssum _ ->
List.iter (check_rec_call renv []) l
- | Some c ->
+ | LocalDef (_,c,_) ->
try List.iter (check_rec_call renv []) l
with FixGuardError _ ->
check_rec_call renv stack (applist(lift p c,l))
@@ -983,10 +984,11 @@ let check_one_fix renv recpos trees def =
| Var id ->
begin
- match pi2 (lookup_named id renv.env) with
- | None ->
+ let open Context.Named.Declaration in
+ match lookup_named id renv.env with
+ | LocalAssum _ ->
List.iter (check_rec_call renv []) l
- | Some c ->
+ | LocalDef (_,c,_) ->
try List.iter (check_rec_call renv []) l
with (FixGuardError _) ->
check_rec_call renv stack (applist(c,l))
@@ -1040,7 +1042,7 @@ let inductive_of_mutfix env ((nvect,bodynum),(names,types,bodies as recdef)) =
match kind_of_term (whd_betadeltaiota env def) with
| Lambda (x,a,b) ->
if noccur_with_meta n nbfix a then
- let env' = push_rel (x, None, a) env in
+ let env' = push_rel (LocalAssum (x,a)) env in
if Int.equal n (k + 1) then
(* get the inductive type of the fixpoint *)
let (mind, _) =
@@ -1090,7 +1092,7 @@ let rec codomain_is_coind env c =
let b = whd_betadeltaiota env c in
match kind_of_term b with
| Prod (x,a,b) ->
- codomain_is_coind (push_rel (x, None, a) env) b
+ codomain_is_coind (push_rel (LocalAssum (x,a)) env) b
| _ ->
(try find_coinductive env b
with Not_found ->
@@ -1131,7 +1133,7 @@ let check_one_cofix env nbfix def deftype =
| Lambda (x,a,b) ->
let () = assert (List.is_empty args) in
if noccur_with_meta n nbfix a then
- let env' = push_rel (x, None, a) env in
+ let env' = push_rel (LocalAssum (x,a)) env in
check_rec_call env' alreadygrd (n+1) tree vlra b
else
raise (CoFixGuardError (env,RecCallInTypeOfAbstraction a))
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 711096b2b1..47274a5cd5 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -1832,24 +1832,25 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
auxdefs, MLlet(aux_name, ml, mkMLapp (MLlocal aux_name) (Array.of_list (fv_rel@fv_named)))
and compile_rel env sigma univ auxdefs n =
- let (_,body,_) = Context.Rel.lookup n env.env_rel_context in
+ let decl = Context.Rel.lookup n env.env_rel_context in
let n = Context.Rel.length env.env_rel_context - n in
- match body with
- | Some t ->
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalDef (_,t,_) ->
let code = lambda_of_constr env sigma t in
let auxdefs,code = compile_with_fv env sigma univ auxdefs None code in
Glet(Grel n, code)::auxdefs
- | None ->
+ | LocalAssum _ ->
Glet(Grel n, MLprimitive (Mk_rel n))::auxdefs
and compile_named env sigma univ auxdefs id =
- let (_,body,_) = Context.Named.lookup id env.env_named_context in
- match body with
- | Some t ->
+ let open Context.Named.Declaration in
+ match Context.Named.lookup id env.env_named_context with
+ | LocalDef (_,t,_) ->
let code = lambda_of_constr env sigma t in
let auxdefs,code = compile_with_fv env sigma univ auxdefs None code in
Glet(Gnamed id, code)::auxdefs
- | None ->
+ | LocalAssum _ ->
Glet(Gnamed id, MLprimitive (Mk_var id))::auxdefs
let compile_constant env sigma prefix ~interactive con cb =
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index 01f59df15a..91b40be7e9 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -727,7 +727,8 @@ let optimize lam =
let lambda_of_constr env sigma c =
set_global_env env;
let env = Renv.make () in
- let ids = List.rev_map (fun (id, _, _) -> id) !global_env.env_rel_context in
+ let open Context.Rel.Declaration in
+ let ids = List.rev_map get_name !global_env.env_rel_context in
Renv.push_rels env (Array.of_list ids);
let lam = lambda_of_constr env sigma c in
(* if Flags.vm_draw_opt () then begin
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index 4c1b2c5a64..99d99e6940 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -18,6 +18,7 @@ open Names
open Univ
open Term
open Declarations
+open Context.Named.Declaration
(* The type of environments. *)
@@ -124,18 +125,16 @@ let env_of_rel n env =
(* Named context *)
let push_named_context_val d (ctxt,vals) =
- let id,_,_ = d in
let rval = ref VKnone in
- Context.Named.add d ctxt, (id,rval)::vals
+ Context.Named.add d ctxt, (get_id d,rval)::vals
let push_named d env =
(* if not (env.env_rel_context = []) then raise (ASSERT env.env_rel_context);
assert (env.env_rel_context = []); *)
- let id,body,_ = d in
let rval = ref VKnone in
{ env_globals = env.env_globals;
env_named_context = Context.Named.add d env.env_named_context;
- env_named_vals = (id, rval) :: env.env_named_vals;
+ env_named_vals = (get_id d, rval) :: env.env_named_vals;
env_rel_context = env.env_rel_context;
env_rel_val = env.env_rel_val;
env_nb_rel = env.env_nb_rel;
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 40b80cc5e9..cfc286135d 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -24,6 +24,7 @@ open Univ
open Environ
open Closure
open Esubst
+open Context.Rel.Declaration
let rec is_empty_stack = function
[] -> true
@@ -739,7 +740,7 @@ let dest_prod env =
let t = whd_betadeltaiota env c in
match kind_of_term t with
| Prod (n,a,c0) ->
- let d = (n,None,a) in
+ let d = LocalAssum (n,a) in
decrec (push_rel d env) (Context.Rel.add d m) c0
| _ -> m,t
in
@@ -751,10 +752,10 @@ let dest_prod_assum env =
let rty = whd_betadeltaiota_nolet env ty in
match kind_of_term rty with
| Prod (x,t,c) ->
- let d = (x,None,t) in
+ let d = LocalAssum (x,t) in
prodec_rec (push_rel d env) (Context.Rel.add d l) c
| LetIn (x,b,t,c) ->
- let d = (x,Some b,t) in
+ let d = LocalDef (x,b,t) in
prodec_rec (push_rel d env) (Context.Rel.add d l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
@@ -769,10 +770,10 @@ let dest_lam_assum env =
let rty = whd_betadeltaiota_nolet env ty in
match kind_of_term rty with
| Lambda (x,t,c) ->
- let d = (x,None,t) in
+ let d = LocalAssum (x,t) in
lamec_rec (push_rel d env) (Context.Rel.add d l) c
| LetIn (x,b,t,c) ->
- let d = (x,Some b,t) in
+ let d = LocalDef (x,b,t) in
lamec_rec (push_rel d env) (Context.Rel.add d l) c
| Cast (c,_,_) -> lamec_rec env l c
| _ -> l,rty
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index e56a6e0999..8a402322f0 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -60,6 +60,7 @@
open Util
open Names
open Declarations
+open Context.Named.Declaration
(** {6 Safe environments }
@@ -362,7 +363,8 @@ let check_required current_libs needed =
hypothesis many many times, and the check performed here would
cost too much. *)
-let safe_push_named (id,_,_ as d) env =
+let safe_push_named d env =
+ let id = get_id d in
let _ =
try
let _ = Environ.lookup_named id env in
@@ -383,13 +385,13 @@ let push_named_def (id,de) senv =
(Opaqueproof.force_constraints (Environ.opaque_tables senv.env) o)
| _ -> assert false in
let senv' = push_context_set poly univs senv in
- let env'' = safe_push_named (id,Some c,typ) senv'.env in
+ let env'' = safe_push_named (LocalDef (id,c,typ)) senv'.env in
univs, {senv' with env=env''}
let push_named_assum ((id,t,poly),ctx) senv =
let senv' = push_context_set poly ctx senv in
let t = Term_typing.translate_local_assum senv'.env t in
- let env'' = safe_push_named (id,None,t) senv'.env in
+ let env'' = safe_push_named (LocalAssum (id,t)) senv'.env in
{senv' with env=env''}
diff --git a/kernel/term.ml b/kernel/term.ml
index 9ba45f5403..4416770fe4 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -383,40 +383,46 @@ let mkNamedLambda id typ c = mkLambda (Name id, typ, subst_var id c)
let mkNamedLetIn id c1 t c2 = mkLetIn (Name id, c1, t, subst_var id c2)
(* Constructs either [(x:t)c] or [[x=b:t]c] *)
-let mkProd_or_LetIn (na,body,t) c =
- match body with
- | None -> mkProd (na, t, c)
- | Some b -> mkLetIn (na, b, t, c)
-
-let mkNamedProd_or_LetIn (id,body,t) c =
- match body with
- | None -> mkNamedProd id t c
- | Some b -> mkNamedLetIn id b t c
+let mkProd_or_LetIn decl c =
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalAssum (na,t) -> mkProd (na, t, c)
+ | LocalDef (na,b,t) -> mkLetIn (na, b, t, c)
+
+let mkNamedProd_or_LetIn decl c =
+ let open Context.Named.Declaration in
+ match decl with
+ | LocalAssum (id,t) -> mkNamedProd id t c
+ | LocalDef (id,b,t) -> mkNamedLetIn id b t c
(* Constructs either [(x:t)c] or [c] where [x] is replaced by [b] *)
-let mkProd_wo_LetIn (na,body,t) c =
- match body with
- | None -> mkProd (na, t, c)
- | Some b -> subst1 b c
-
-let mkNamedProd_wo_LetIn (id,body,t) c =
- match body with
- | None -> mkNamedProd id t c
- | Some b -> subst1 b (subst_var id c)
+let mkProd_wo_LetIn decl c =
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalAssum (na,t) -> mkProd (na, t, c)
+ | LocalDef (na,b,t) -> subst1 b c
+
+let mkNamedProd_wo_LetIn decl c =
+ let open Context.Named.Declaration in
+ match decl with
+ | LocalAssum (id,t) -> mkNamedProd id t c
+ | LocalDef (id,b,t) -> subst1 b (subst_var id c)
(* non-dependent product t1 -> t2 *)
let mkArrow t1 t2 = mkProd (Anonymous, t1, t2)
(* Constructs either [[x:t]c] or [[x=b:t]c] *)
-let mkLambda_or_LetIn (na,body,t) c =
- match body with
- | None -> mkLambda (na, t, c)
- | Some b -> mkLetIn (na, b, t, c)
-
-let mkNamedLambda_or_LetIn (id,body,t) c =
- match body with
- | None -> mkNamedLambda id t c
- | Some b -> mkNamedLetIn id b t c
+let mkLambda_or_LetIn decl c =
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalAssum (na,t) -> mkLambda (na, t, c)
+ | LocalDef (na,b,t) -> mkLetIn (na, b, t, c)
+
+let mkNamedLambda_or_LetIn decl c =
+ let open Context.Named.Declaration in
+ match decl with
+ | LocalAssum (id,t) -> mkNamedLambda id t c
+ | LocalDef (id,b,t) -> mkNamedLetIn id b t c
(* prodn n [xn:Tn;..;x1:T1;Gamma] b = (x1:T1)..(xn:Tn)b *)
let prodn n env b =
@@ -576,10 +582,11 @@ let decompose_lam_n n =
(* Transforms a product term (x1:T1)..(xn:Tn)T into the pair
([(xn,Tn);...;(x1,T1)],T), where T is not a product *)
let decompose_prod_assum =
+ let open Context.Rel.Declaration in
let rec prodec_rec l c =
match kind_of_term c with
- | Prod (x,t,c) -> prodec_rec (Context.Rel.add (x,None,t) l) c
- | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (x,Some b,t) l) c
+ | Prod (x,t,c) -> prodec_rec (Context.Rel.add (LocalAssum (x,t)) l) c
+ | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> prodec_rec l c
| _ -> l,c
in
@@ -589,9 +596,10 @@ let decompose_prod_assum =
([(xn,Tn);...;(x1,T1)],T), where T is not a lambda *)
let decompose_lam_assum =
let rec lamdec_rec l c =
+ let open Context.Rel.Declaration in
match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) c
- | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) c
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> lamdec_rec l c
| _ -> l,c
in
@@ -606,11 +614,13 @@ let decompose_prod_n_assum n =
error "decompose_prod_n_assum: integer parameter must be positive";
let rec prodec_rec l n c =
if Int.equal n 0 then l,c
- else match kind_of_term c with
- | Prod (x,t,c) -> prodec_rec (Context.Rel.add (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (x,Some b,t) l) (n-1) c
- | Cast (c,_,_) -> prodec_rec l n c
- | c -> error "decompose_prod_n_assum: not enough assumptions"
+ else
+ let open Context.Rel.Declaration in
+ match kind_of_term c with
+ | Prod (x,t,c) -> prodec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
+ | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (LocalDef (x,b,t)) l) (n-1) c
+ | Cast (c,_,_) -> prodec_rec l n c
+ | c -> error "decompose_prod_n_assum: not enough assumptions"
in
prodec_rec Context.Rel.empty n
@@ -625,11 +635,13 @@ let decompose_lam_n_assum n =
error "decompose_lam_n_assum: integer parameter must be positive";
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
- else match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) n c
- | Cast (c,_,_) -> lamdec_rec l n c
- | c -> error "decompose_lam_n_assum: not enough abstractions"
+ else
+ let open Context.Rel.Declaration in
+ match kind_of_term c with
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) n c
+ | Cast (c,_,_) -> lamdec_rec l n c
+ | c -> error "decompose_lam_n_assum: not enough abstractions"
in
lamdec_rec Context.Rel.empty n
@@ -639,11 +651,13 @@ let decompose_lam_n_decls n =
error "decompose_lam_n_decls: integer parameter must be positive";
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
- else match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) (n-1) c
- | Cast (c,_,_) -> lamdec_rec l n c
- | c -> error "decompose_lam_n_decls: not enough abstractions"
+ else
+ let open Context.Rel.Declaration in
+ match kind_of_term c with
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) (n-1) c
+ | Cast (c,_,_) -> lamdec_rec l n c
+ | c -> error "decompose_lam_n_decls: not enough abstractions"
in
lamdec_rec Context.Rel.empty n
@@ -669,10 +683,11 @@ let strip_lam_n n t = snd (decompose_lam_n n t)
type arity = Context.Rel.t * sorts
let destArity =
+ let open Context.Rel.Declaration in
let rec prodec_rec l c =
match kind_of_term c with
- | Prod (x,t,c) -> prodec_rec ((x,None,t)::l) c
- | LetIn (x,b,t,c) -> prodec_rec ((x,Some b,t)::l) c
+ | Prod (x,t,c) -> prodec_rec (LocalAssum (x,t) :: l) c
+ | LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t) :: l) c
| Cast (c,_,_) -> prodec_rec l c
| Sort s -> l,s
| _ -> anomaly ~label:"destArity" (Pp.str "not an arity")
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 979165e49c..2a3ac957fb 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -138,16 +138,17 @@ let check_signatures curmb sl =
let skip_trusted_seff sl b e =
let rec aux sl b e acc =
+ let open Context.Rel.Declaration in
match sl, kind_of_term b with
| (None|Some 0), _ -> b, e, acc
| Some sl, LetIn (n,c,ty,bo) ->
aux (Some (sl-1)) bo
- (Environ.push_rel (n,Some c,ty) e) (`Let(n,c,ty)::acc)
+ (Environ.push_rel (LocalDef (n,c,ty)) e) (`Let(n,c,ty)::acc)
| Some sl, App(hd,arg) ->
begin match kind_of_term hd with
| Lambda (n,ty,bo) ->
aux (Some (sl-1)) bo
- (Environ.push_rel (n,None,ty) e) (`Cut(n,ty,arg)::acc)
+ (Environ.push_rel (LocalAssum (n,ty)) e) (`Cut(n,ty,arg)::acc)
| _ -> assert false
end
| _ -> assert false
@@ -251,11 +252,13 @@ let global_vars_set_constant_type env = function
ctx ~init:Id.Set.empty
let record_aux env s_ty s_bo suggested_expr =
+ let open Context.Named.Declaration in
let in_ty = keep_hyps env s_ty in
let v =
String.concat " "
- (CList.map_filter (fun (id, _,_) ->
- if List.exists (fun (id',_,_) -> Id.equal id id') in_ty then None
+ (CList.map_filter (fun decl ->
+ let id = get_id decl in
+ if List.exists (Id.equal id % get_id) in_ty then None
else Some (Id.to_string id))
(keep_hyps env s_bo)) in
Aux_file.record_in_aux "context_used" (v ^ ";" ^ suggested_expr)
@@ -264,8 +267,9 @@ let suggest_proof_using = ref (fun _ _ _ _ _ -> "")
let set_suggest_proof_using f = suggest_proof_using := f
let build_constant_declaration kn env (def,typ,proj,poly,univs,inline_code,ctx) =
+ let open Context.Named.Declaration in
let check declared inferred =
- let mk_set l = List.fold_right Id.Set.add (List.map pi1 l) Id.Set.empty in
+ let mk_set l = List.fold_right Id.Set.add (List.map get_id l) Id.Set.empty in
let inferred_set, declared_set = mk_set inferred, mk_set declared in
if not (Id.Set.subset inferred_set declared_set) then
let l = Id.Set.elements (Idset.diff inferred_set declared_set) in
@@ -276,12 +280,13 @@ let build_constant_declaration kn env (def,typ,proj,poly,univs,inline_code,ctx)
str " used but not declared:" ++
fnl () ++ pr_sequence Id.print (List.rev l) ++ str ".")) in
let sort evn l =
- List.filter (fun (id,_,_) ->
- List.exists (fun (id',_,_) -> Names.Id.equal id id') l)
+ List.filter (fun decl ->
+ let id = get_id decl in
+ List.exists (Names.Id.equal id % get_id) l)
(named_context env) in
(* We try to postpone the computation of used section variables *)
let hyps, def =
- let context_ids = List.map pi1 (named_context env) in
+ let context_ids = List.map get_id (named_context env) in
match ctx with
| None when not (List.is_empty context_ids) ->
(* No declared section vars, and non-empty section context:
@@ -472,7 +477,8 @@ let translate_local_def mb env id centry =
| Undef _ -> ()
| Def _ -> ()
| OpaqueDef lc ->
- let context_ids = List.map pi1 (named_context env) in
+ let open Context.Named.Declaration in
+ let context_ids = List.map get_id (named_context env) in
let ids_typ = global_vars_set env typ in
let ids_def = global_vars_set env
(Opaqueproof.force_proof (opaque_tables env) lc) in
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index f31cba0a8a..eeb12a2b49 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -77,8 +77,9 @@ let judge_of_type u =
(*s Type of a de Bruijn index. *)
let judge_of_relative env n =
+ let open Context.Rel.Declaration in
try
- let (_,_,typ) = lookup_rel n env in
+ let typ = get_type (lookup_rel n env) in
{ uj_val = mkRel n;
uj_type = lift n typ }
with Not_found ->
@@ -98,18 +99,20 @@ let judge_of_variable env id =
variables of the current env.
Order does not have to be checked assuming that all names are distinct *)
let check_hyps_inclusion env c sign =
+ let open Context.Named.Declaration in
Context.Named.fold_outside
- (fun (id,b1,ty1) () ->
+ (fun d1 () ->
+ let id = get_id d1 in
try
- let (_,b2,ty2) = lookup_named id env in
- conv env ty2 ty1;
- (match b2,b1 with
- | None, None -> ()
- | None, Some _ ->
+ let d2 = lookup_named id env in
+ conv env (get_type d2) (get_type d1);
+ (match d2,d1 with
+ | LocalAssum _, LocalAssum _ -> ()
+ | LocalAssum _, LocalDef _ ->
(* This is wrong, because we don't know if the body is
needed or not for typechecking: *) ()
- | Some _, None -> raise NotConvertible
- | Some b2, Some b1 -> conv env b2 b1);
+ | LocalDef _, LocalAssum _ -> raise NotConvertible
+ | LocalDef (_,b2,_), LocalDef (_,b1,_) -> conv env b2 b1);
with Not_found | NotConvertible | Option.Heterogeneous ->
error_reference_variables env id c)
sign
@@ -124,9 +127,10 @@ let extract_level env p =
match kind_of_term c with Sort (Type u) -> Univ.Universe.level u | _ -> None
let extract_context_levels env l =
- let fold l (_, b, p) = match b with
- | None -> extract_level env p :: l
- | _ -> l
+ let open Context.Rel.Declaration in
+ let fold l = function
+ | LocalAssum (_,p) -> extract_level env p :: l
+ | LocalDef _ -> l
in
List.fold_left fold [] l
@@ -416,6 +420,7 @@ let type_fixpoint env lna lar vdefj =
Ind et Constructsi un jour cela devient des constructions
arbitraires et non plus des variables *)
let rec execute env cstr =
+ let open Context.Rel.Declaration in
match kind_of_term cstr with
(* Atomic terms *)
| Sort (Prop c) ->
@@ -458,13 +463,13 @@ let rec execute env cstr =
| Lambda (name,c1,c2) ->
let varj = execute_type env c1 in
- let env1 = push_rel (name,None,varj.utj_val) env in
+ let env1 = push_rel (LocalAssum (name,varj.utj_val)) env in
let j' = execute env1 c2 in
judge_of_abstraction env name varj j'
| Prod (name,c1,c2) ->
let varj = execute_type env c1 in
- let env1 = push_rel (name,None,varj.utj_val) env in
+ let env1 = push_rel (LocalAssum (name,varj.utj_val)) env in
let varj' = execute_type env1 c2 in
judge_of_product env name varj varj'
@@ -472,7 +477,7 @@ let rec execute env cstr =
let j1 = execute env c1 in
let j2 = execute_type env c2 in
let _ = judge_of_cast env j1 DEFAULTcast j2 in
- let env1 = push_rel (name,Some j1.uj_val,j2.utj_val) env in
+ let env1 = push_rel (LocalDef (name,j1.uj_val,j2.utj_val)) env in
let j' = execute env1 c3 in
judge_of_letin env name j1 j2 j'
@@ -550,10 +555,10 @@ let infer_v env cv =
let infer_local_decl env id = function
| LocalDef c ->
let j = infer env c in
- (Name id, Some j.uj_val, j.uj_type)
+ Context.Rel.Declaration.LocalDef (Name id, j.uj_val, j.uj_type)
| LocalAssum c ->
let j = infer env c in
- (Name id, None, assumption_of_judgment env j)
+ Context.Rel.Declaration.LocalAssum (Name id, assumption_of_judgment env j)
let infer_local_decls env decls =
let rec inferec env = function
diff --git a/kernel/vars.ml b/kernel/vars.ml
index 4554c6be17..b935ab6b91 100644
--- a/kernel/vars.ml
+++ b/kernel/vars.ml
@@ -8,6 +8,7 @@
open Names
open Esubst
+open Context.Rel.Declaration
(*********************)
(* Occurring *)
@@ -159,17 +160,17 @@ let substnl laml n c = substn_many (make_subst laml) n c
let substl laml c = substn_many (make_subst laml) 0 c
let subst1 lam c = substn_many [|make_substituend lam|] 0 c
-let substnl_decl laml k r = Context.Rel.Declaration.map (fun c -> substnl laml k c) r
-let substl_decl laml r = Context.Rel.Declaration.map (fun c -> substnl laml 0 c) r
-let subst1_decl lam r = Context.Rel.Declaration.map (fun c -> subst1 lam c) r
+let substnl_decl laml k r = map_constr (fun c -> substnl laml k c) r
+let substl_decl laml r = map_constr (fun c -> substnl laml 0 c) r
+let subst1_decl lam r = map_constr (fun c -> subst1 lam c) r
(* Build a substitution from an instance, inserting missing let-ins *)
let subst_of_rel_context_instance sign l =
let rec aux subst sign l =
match sign, l with
- | (_,None,_)::sign', a::args' -> aux (a::subst) sign' args'
- | (_,Some c,_)::sign', args' ->
+ | LocalAssum _ :: sign', a::args' -> aux (a::subst) sign' args'
+ | LocalDef (_,c,_)::sign', args' ->
aux (substl subst c :: subst) sign' args'
| [], [] -> subst
| _ -> Errors.anomaly (Pp.str "Instance and signature do not match")
diff --git a/lib/util.ml b/lib/util.ml
index b67539918d..6e22d6be57 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -88,6 +88,7 @@ let matrix_transpose mat =
let identity x = x
let compose f g x = f (g x)
+let (%) = compose
let const x _ = x
diff --git a/lib/util.mli b/lib/util.mli
index 7923c65a3b..bf342c1e66 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -84,6 +84,7 @@ val matrix_transpose : 'a list list -> 'a list list
val identity : 'a -> 'a
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
+val (%) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
val const : 'a -> 'b -> 'a
val iterate : ('a -> 'a) -> int -> 'a -> 'a
val repeat : int -> ('a -> unit) -> 'a -> unit
diff --git a/library/decls.ml b/library/decls.ml
index cafdcd0abd..6e21880f1f 100644
--- a/library/decls.ml
+++ b/library/decls.ml
@@ -46,16 +46,20 @@ let constant_kind kn = Cmap.find kn !csttab
(** Miscellaneous functions. *)
+open Context.Named.Declaration
+
let initialize_named_context_for_proof () =
let sign = Global.named_context () in
List.fold_right
- (fun (id,c,t as d) signv ->
- let d = if variable_opacity id then (id,None,t) else d in
+ (fun d signv ->
+ let id = get_id d in
+ let d = if variable_opacity id then LocalAssum (id, get_type d) else d in
Environ.push_named_context_val d signv) sign Environ.empty_named_context_val
let last_section_hyps dir =
Context.Named.fold_outside
- (fun (id,_,_) sec_ids ->
+ (fun d sec_ids ->
+ let id = get_id d in
try if DirPath.equal dir (variable_path id) then id::sec_ids else sec_ids
with Not_found -> sec_ids)
(Environ.named_context (Global.env()))
diff --git a/library/heads.ml b/library/heads.ml
index 8124d3474f..4c9b789769 100644
--- a/library/heads.ml
+++ b/library/heads.ml
@@ -15,6 +15,7 @@ open Environ
open Globnames
open Libobject
open Lib
+open Context.Named.Declaration
(** Characterization of the head of a term *)
@@ -63,9 +64,9 @@ let kind_of_head env t =
(try on_subterm k l b (variable_head id)
with Not_found ->
(* a goal variable *)
- match pi2 (lookup_named id env) with
- | Some c -> aux k l c b
- | None -> NotImmediatelyComputableHead)
+ match lookup_named id env with
+ | LocalDef (_,c,_) -> aux k l c b
+ | LocalAssum _ -> NotImmediatelyComputableHead)
| Const (cst,_) ->
(try on_subterm k l b (constant_head cst)
with Not_found ->
@@ -132,8 +133,8 @@ let compute_head = function
| None -> RigidHead (RigidParameter cst)
| Some c -> kind_of_head env c)
| EvalVarRef id ->
- (match pi2 (Global.lookup_named id) with
- | Some c when not (Decls.variable_opacity id) ->
+ (match Global.lookup_named id with
+ | LocalDef (_,c,_) when not (Decls.variable_opacity id) ->
kind_of_head (Global.env()) c
| _ ->
RigidHead (RigidVar id))
diff --git a/library/impargs.ml b/library/impargs.ml
index f5f6a3eba7..4e344a9543 100644
--- a/library/impargs.ml
+++ b/library/impargs.ml
@@ -165,6 +165,7 @@ let update pos rig (na,st) =
(* modified is_rigid_reference with a truncated env *)
let is_flexible_reference env bound depth f =
+ let open Context.Named.Declaration in
match kind_of_term f with
| Rel n when n >= bound+depth -> (* inductive type *) false
| Rel n when n >= depth -> (* previous argument *) true
@@ -173,8 +174,7 @@ let is_flexible_reference env bound depth f =
let cb = Environ.lookup_constant kn env in
(match cb.const_body with Def _ -> true | _ -> false)
| Var id ->
- let (_, value, _) = Environ.lookup_named id env in
- begin match value with None -> false | _ -> true end
+ Environ.lookup_named id env |> is_local_def
| Ind _ | Construct _ -> false
| _ -> true
@@ -234,13 +234,14 @@ let find_displayed_name_in all avoid na (_,b as envnames_b) =
let compute_implicits_gen strict strongly_strict revpat contextual all env t =
let rigid = ref true in
+ let open Context.Rel.Declaration in
let rec aux env avoid n names t =
let t = whd_betadeltaiota env t in
match kind_of_term t with
| Prod (na,a,b) ->
let na',avoid' = find_displayed_name_in all avoid na (names,b) in
add_free_rels_until strict strongly_strict revpat n env a (Hyp (n+1))
- (aux (push_rel (na',None,a) env) avoid' (n+1) (na'::names) b)
+ (aux (push_rel (LocalAssum (na',a)) env) avoid' (n+1) (na'::names) b)
| _ ->
rigid := is_rigid_head t;
let names = List.rev names in
@@ -252,7 +253,7 @@ let compute_implicits_gen strict strongly_strict revpat contextual all env t =
match kind_of_term (whd_betadeltaiota env t) with
| Prod (na,a,b) ->
let na',avoid = find_displayed_name_in all [] na ([],b) in
- let v = aux (push_rel (na',None,a) env) avoid 1 [na'] b in
+ let v = aux (push_rel (LocalAssum (na',a)) env) avoid 1 [na'] b in
!rigid, Array.to_list v
| _ -> true, []
@@ -427,7 +428,7 @@ let compute_mib_implicits flags manual kn =
(Array.mapi (* No need to lift, arities contain no de Bruijn *)
(fun i mip ->
(** No need to care about constraints here *)
- (Name mip.mind_typename, None, Global.type_of_global_unsafe (IndRef (kn,i))))
+ Context.Rel.Declaration.LocalAssum (Name mip.mind_typename, Global.type_of_global_unsafe (IndRef (kn,i))))
mib.mind_packets) in
let env_ar = push_rel_context ar env in
let imps_one_inductive i mip =
@@ -449,8 +450,8 @@ let compute_all_mib_implicits flags manual kn =
let compute_var_implicits flags manual id =
let env = Global.env () in
- let (_,_,ty) = lookup_named id env in
- compute_semi_auto_implicits env flags manual ty
+ let open Context.Named.Declaration in
+ compute_semi_auto_implicits env flags manual (get_type (lookup_named id env))
(* Implicits of a global reference. *)
diff --git a/library/lib.ml b/library/lib.ml
index e4617cafb6..f8bb6bac59 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -428,8 +428,10 @@ let add_section_context ctx =
sectab := (Context ctx :: vars,repl,abs)::sl
let extract_hyps (secs,ohyps) =
+ let open Context.Named.Declaration in
let rec aux = function
- | (Variable (id,impl,poly,ctx)::idl,(id',b,t)::hyps) when Names.Id.equal id id' ->
+ | (Variable (id,impl,poly,ctx)::idl, decl::hyps) when Names.Id.equal id (get_id decl) ->
+ let (id',b,t) = to_tuple decl in
let l, r = aux (idl,hyps) in
(id',impl,b,t) :: l, if poly then Univ.ContextSet.union r ctx else r
| (Variable (_,_,poly,ctx)::idl,hyps) ->
@@ -448,7 +450,10 @@ let instance_from_variable_context sign =
| [] -> [] in
Array.of_list (inst_rec sign)
-let named_of_variable_context ctx = List.map (fun (id,_,b,t) -> (id,b,t)) ctx
+let named_of_variable_context ctx = let open Context.Named.Declaration in
+ List.map (function id,_,None,t -> LocalAssum (id,t)
+ | id,_,Some b,t -> LocalDef (id,b,t))
+ ctx
let add_section_replacement f g poly hyps =
match !sectab with
diff --git a/plugins/cc/ccalgo.ml b/plugins/cc/ccalgo.ml
index bc3d9ed560..359157a4c1 100644
--- a/plugins/cc/ccalgo.ml
+++ b/plugins/cc/ccalgo.ml
@@ -824,7 +824,7 @@ let __eps__ = Id.of_string "_eps_"
let new_state_var typ state =
let id = pf_get_new_id __eps__ state.gls in
let {it=gl ; sigma=sigma} = state.gls in
- let gls = Goal.V82.new_goal_with sigma gl [id,None,typ] in
+ let gls = Goal.V82.new_goal_with sigma gl [Context.Named.Declaration.LocalAssum (id,typ)] in
state.gls<- gls;
id
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index 09d9cf0195..e5b68af8e8 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -23,6 +23,7 @@ open Pp
open Errors
open Util
open Proofview.Notations
+open Context.Rel.Declaration
let reference dir s = lazy (Coqlib.gen_reference "CC" dir s)
@@ -152,7 +153,7 @@ let rec quantified_atom_of_constr env sigma nrels term =
let patts=patterns_of_constr env sigma nrels atom in
`Nrule patts
else
- quantified_atom_of_constr (Environ.push_rel (id,None,atom) env) sigma (succ nrels) ff
+ quantified_atom_of_constr (Environ.push_rel (LocalAssum (id,atom)) env) sigma (succ nrels) ff
| _ ->
let patts=patterns_of_constr env sigma nrels term in
`Rule patts
@@ -167,7 +168,7 @@ let litteral_of_constr env sigma term=
else
begin
try
- quantified_atom_of_constr (Environ.push_rel (id,None,atom) env) sigma 1 ff
+ quantified_atom_of_constr (Environ.push_rel (LocalAssum (id,atom)) env) sigma 1 ff
with Not_found ->
`Other (decompose_term env sigma term)
end
@@ -188,7 +189,8 @@ let make_prb gls depth additionnal_terms =
let t = decompose_term env sigma c in
ignore (add_term state t)) additionnal_terms;
List.iter
- (fun (id,_,e) ->
+ (fun decl ->
+ let (id,_,e) = Context.Named.Declaration.to_tuple decl in
begin
let cid=mkVar id in
match litteral_of_constr env sigma e with
diff --git a/plugins/decl_mode/decl_interp.ml b/plugins/decl_mode/decl_interp.ml
index 2a44dca219..7cfca53c50 100644
--- a/plugins/decl_mode/decl_interp.ml
+++ b/plugins/decl_mode/decl_interp.ml
@@ -403,7 +403,7 @@ let interp_suffices_clause env sigma (hyps,cot)=
match hyp with
(Hprop st | Hvar st) ->
match st.st_label with
- Name id -> Environ.push_named (id,None,st.st_it) env0
+ Name id -> Environ.push_named (Context.Named.Declaration.LocalAssum (id,st.st_it)) env0
| _ -> env in
let nenv = List.fold_right push_one locvars env in
nenv,res
diff --git a/plugins/decl_mode/decl_mode.ml b/plugins/decl_mode/decl_mode.ml
index acee3d6c21..f9399d6824 100644
--- a/plugins/decl_mode/decl_mode.ml
+++ b/plugins/decl_mode/decl_mode.ml
@@ -116,7 +116,7 @@ let get_top_stack pts =
let get_stack pts = Proof.get_at_focus proof_focus pts
let get_last env = match Environ.named_context env with
- | (id,_,_)::_ -> id
+ | decl :: _ -> Context.Named.Declaration.get_id decl
| [] -> error "no previous statement to use"
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index f47b355417..22a646b3f8 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -30,6 +30,7 @@ open Namegen
open Goptions
open Misctypes
open Sigma.Notations
+open Context.Named.Declaration
(* Strictness option *)
@@ -229,7 +230,8 @@ let close_previous_case pts =
(* automation *)
let filter_hyps f gls =
- let filter_aux (id,_,_) =
+ let filter_aux id =
+ let id = get_id id in
if f id then
tclIDTAC
else
@@ -331,11 +333,12 @@ let enstack_subsubgoals env se stack gls=
let rc,_ = Reduction.dest_prod env apptype in
let rec meta_aux last lenv = function
[] -> (last,lenv,[])
- | (nam,_,typ)::q ->
+ | decl::q ->
let nlast=succ last in
let (llast,holes,metas) =
meta_aux nlast (mkMeta nlast :: lenv) q in
- (llast,holes,(nlast,special_nf gls (substl lenv typ))::metas) in
+ let open Context.Rel.Declaration in
+ (llast,holes,(nlast,special_nf gls (substl lenv (get_type decl)))::metas) in
let (nlast,holes,nmetas) =
meta_aux se.se_last_meta [] (List.rev rc) in
let refiner = applist (appterm,List.rev holes) in
@@ -411,7 +414,7 @@ let concl_refiner metas body gls =
let _A = subst_meta subst typ in
let x = id_of_name_using_hdchar env _A Anonymous in
let _x = fresh_id avoid x gls in
- let nenv = Environ.push_named (_x,None,_A) env in
+ let nenv = Environ.push_named (LocalAssum (_x,_A)) env in
let asort = family_of_sort (Typing.sort_of nenv (ref evd) _A) in
let nsubst = (n,mkVar _x)::subst in
if List.is_empty rest then
@@ -606,7 +609,7 @@ let assume_tac hyps gls =
tclTHEN
(push_intro_tac
(fun id ->
- Proofview.V82.of_tactic (convert_hyp (id,None,st.st_it))) st.st_label))
+ Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it)))) st.st_label))
hyps tclIDTAC gls
let assume_hyps_or_theses hyps gls =
@@ -616,7 +619,7 @@ let assume_hyps_or_theses hyps gls =
tclTHEN
(push_intro_tac
(fun id ->
- Proofview.V82.of_tactic (convert_hyp (id,None,c))) nam)
+ Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,c)))) nam)
| Hprop {st_label=nam;st_it=Thesis (tk)} ->
tclTHEN
(push_intro_tac
@@ -628,7 +631,7 @@ let assume_st hyps gls =
(fun st ->
tclTHEN
(push_intro_tac
- (fun id -> Proofview.V82.of_tactic (convert_hyp (id,None,st.st_it))) st.st_label))
+ (fun id -> Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it)))) st.st_label))
hyps tclIDTAC gls
let assume_st_letin hyps gls =
@@ -637,7 +640,7 @@ let assume_st_letin hyps gls =
tclTHEN
(push_intro_tac
(fun id ->
- Proofview.V82.of_tactic (convert_hyp (id,Some (fst st.st_it),snd st.st_it))) st.st_label))
+ Proofview.V82.of_tactic (convert_hyp (LocalDef (id, fst st.st_it, snd st.st_it)))) st.st_label))
hyps tclIDTAC gls
(* suffices *)
@@ -731,7 +734,7 @@ let rec consider_match may_intro introduced available expected gls =
error "Not enough sub-hypotheses to match statements."
(* should tell which ones *)
| id::rest_ids,(Hvar st | Hprop st)::rest ->
- tclIFTHENELSE (Proofview.V82.of_tactic (convert_hyp (id,None,st.st_it)))
+ tclIFTHENELSE (Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it))))
begin
match st.st_label with
Anonymous ->
@@ -799,8 +802,8 @@ let define_tac id args body gls =
let cast_tac id_or_thesis typ gls =
match id_or_thesis with
This id ->
- let (_,body,_) = pf_get_hyp gls id in
- Proofview.V82.of_tactic (convert_hyp (id,body,typ)) gls
+ let body = pf_get_hyp gls id |> get_value in
+ Proofview.V82.of_tactic (convert_hyp (of_tuple (id,body,typ))) gls
| Thesis (For _ ) ->
error "\"thesis for ...\" is not applicable here."
| Thesis Plain ->
diff --git a/plugins/derive/derive.ml b/plugins/derive/derive.ml
index a47dc5b2fa..5d1551106f 100644
--- a/plugins/derive/derive.ml
+++ b/plugins/derive/derive.ml
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Context.Named.Declaration
+
let map_const_entry_body (f:Term.constr->Term.constr) (x:Safe_typing.private_constants Entries.const_entry_body)
: Safe_typing.private_constants Entries.const_entry_body =
Future.chain ~pure:true x begin fun ((b,ctx),fx) ->
@@ -32,7 +34,7 @@ let start_deriving f suchthat lemma =
let open Proofview in
TCons ( env , sigma , f_type_type , (fun sigma f_type ->
TCons ( env , sigma , f_type , (fun sigma ef ->
- let env' = Environ.push_named (f , (Some ef) , f_type) env in
+ let env' = Environ.push_named (LocalDef (f, ef, f_type)) env in
let evdref = ref sigma in
let suchthat = Constrintern.interp_type_evars env' evdref suchthat in
TCons ( env' , !evdref , suchthat , (fun sigma _ ->
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index 38aef62e1e..6c57bc2bbd 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -25,6 +25,7 @@ open Globnames
open Miniml
open Table
open Mlutil
+open Context.Rel.Declaration
(*i*)
exception I of inductive_kind
@@ -74,7 +75,7 @@ type flag = info * scheme
let rec flag_of_type env t : flag =
let t = whd_betadeltaiota env none t in
match kind_of_term t with
- | Prod (x,t,c) -> flag_of_type (push_rel (x,None,t) env) c
+ | Prod (x,t,c) -> flag_of_type (push_rel (LocalAssum (x,t)) env) c
| Sort s when Sorts.is_prop s -> (Logic,TypeScheme)
| Sort _ -> (Info,TypeScheme)
| _ -> if (sort_of env t) == InProp then (Logic,Default) else (Info,Default)
@@ -247,7 +248,7 @@ let rec extract_type env db j c args =
| _ when sort_of env (applist (c, args)) == InProp -> Tdummy Kprop
| Rel n ->
(match lookup_rel n env with
- | (_,Some t,_) -> extract_type env db j (lift n t) args
+ | LocalDef (_,t,_) -> extract_type env db j (lift n t) args
| _ ->
(* Asks [db] a translation for [n]. *)
if n > List.length db then Tunknown
@@ -560,7 +561,7 @@ let rec extract_term env mle mlt c args =
put_magic_if magic (MLlam (id, d')))
| LetIn (n, c1, t1, c2) ->
let id = id_of_name n in
- let env' = push_rel (Name id, Some c1, t1) env in
+ let env' = push_rel (LocalDef (Name id, c1, t1)) env in
(* We directly push the args inside the [LetIn].
TODO: the opt_let_app flag is supposed to prevent that *)
let args' = List.map (lift 1) args in
@@ -835,7 +836,7 @@ and extract_fix env mle i (fi,ti,ci as recd) mlt =
let decomp_lams_eta_n n m env c t =
let rels = fst (splay_prod_n env none n t) in
- let rels = List.map (fun (id,_,c) -> (id,c)) rels in
+ let rels = List.map (fun (LocalAssum (id,c) | LocalDef (id,_,c)) -> (id,c)) rels in
let rels',c = decompose_lam c in
let d = n - m in
(* we'd better keep rels' as long as possible. *)
diff --git a/plugins/firstorder/formula.ml b/plugins/firstorder/formula.ml
index ae2d059fa2..2ed436c6bf 100644
--- a/plugins/firstorder/formula.ml
+++ b/plugins/firstorder/formula.ml
@@ -15,6 +15,7 @@ open Tacmach
open Util
open Declarations
open Globnames
+open Context.Rel.Declaration
let qflag=ref true
@@ -139,8 +140,8 @@ let build_atoms gl metagen side cciterm =
negative:= unsigned :: !negative
end;
let v = ind_hyps 0 i l gl in
- let g i _ (_,_,t) =
- build_rec env polarity (lift i t) in
+ let g i _ decl =
+ build_rec env polarity (lift i (get_type decl)) in
let f l =
List.fold_left_i g (1-(List.length l)) () l in
if polarity && (* we have a constant constructor *)
@@ -150,8 +151,8 @@ let build_atoms gl metagen side cciterm =
| Exists(i,l)->
let var=mkMeta (metagen true) in
let v =(ind_hyps 1 i l gl).(0) in
- let g i _ (_,_,t) =
- build_rec (var::env) polarity (lift i t) in
+ let g i _ decl =
+ build_rec (var::env) polarity (lift i (get_type decl)) in
List.fold_left_i g (2-(List.length l)) () v
| Forall(_,b)->
let var=mkMeta (metagen true) in
@@ -224,7 +225,7 @@ let build_formula side nam typ gl metagen=
| And(_,_,_) -> Rand
| Or(_,_,_) -> Ror
| Exists (i,l) ->
- let (_,_,d)=List.last (ind_hyps 0 i l gl).(0) in
+ let d = get_type (List.last (ind_hyps 0 i l gl).(0)) in
Rexists(m,d,trivial)
| Forall (_,a) -> Rforall
| Arrow (a,b) -> Rarrow in
diff --git a/plugins/firstorder/instances.ml b/plugins/firstorder/instances.ml
index a717cc91ea..797f43f2a0 100644
--- a/plugins/firstorder/instances.ml
+++ b/plugins/firstorder/instances.ml
@@ -22,6 +22,7 @@ open Formula
open Sequent
open Names
open Misctypes
+open Context.Rel.Declaration
let compare_instance inst1 inst2=
match inst1,inst2 with
@@ -117,7 +118,7 @@ let mk_open_instance id idc gl m t=
if Int.equal n 0 then evmap, decls else
let nid=(fresh_id avoid var_id gl) in
let evmap, (c, _) = Evarutil.new_type_evar env evmap Evd.univ_flexible in
- let decl = (Name nid,None,c) in
+ let decl = LocalAssum (Name nid,c) in
aux (n-1) (nid::avoid) (Environ.push_rel decl env) evmap (decl::decls) in
let evmap, decls = aux m [] env evmap [] in
evmap, decls, revt
diff --git a/plugins/firstorder/rules.ml b/plugins/firstorder/rules.ml
index e676a8a936..b0e8f7d25c 100644
--- a/plugins/firstorder/rules.ml
+++ b/plugins/firstorder/rules.ml
@@ -19,6 +19,7 @@ open Formula
open Sequent
open Globnames
open Locus
+open Context.Named.Declaration
type seqtac= (Sequent.t -> tactic) -> Sequent.t -> tactic
@@ -34,12 +35,13 @@ let wrap n b continue seq gls=
if i<=0 then seq else
match nc with
[]->anomaly (Pp.str "Not the expected number of hyps")
- | ((id,_,typ) as nd)::q->
+ | nd::q->
+ let id = get_id nd in
if occur_var env id (pf_concl gls) ||
List.exists (occur_var_in_decl env id) ctx then
(aux (i-1) q (nd::ctx))
else
- add_formula Hyp (VarRef id) typ (aux (i-1) q (nd::ctx)) gls in
+ add_formula Hyp (VarRef id) (get_type nd) (aux (i-1) q (nd::ctx)) gls in
let seq1=aux n nc [] in
let seq2=if b then
add_formula Concl dummy_id (pf_concl gls) seq1 gls else seq1 in
diff --git a/plugins/fourier/fourierR.ml b/plugins/fourier/fourierR.ml
index 4c0aa6c759..8bc84608e6 100644
--- a/plugins/fourier/fourierR.ml
+++ b/plugins/fourier/fourierR.ml
@@ -445,7 +445,11 @@ let is_ineq (h,t) =
;;
*)
-let list_of_sign s = List.map (fun (x,_,z)->(x,z)) s;;
+let list_of_sign s =
+ let open Context.Named.Declaration in
+ List.map (function LocalAssum (name, typ) -> name, typ
+ | LocalDef (name, _, typ) -> name, typ)
+ s;;
let mkAppL a =
let l = Array.to_list a in
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 4eab5f9126..28982c37fe 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -15,6 +15,7 @@ open Tactics
open Indfun_common
open Libnames
open Globnames
+open Context.Rel.Declaration
(* let msgnl = Pp.msgnl *)
@@ -304,11 +305,11 @@ let change_eq env sigma hyp_id (context:Context.Rel.t) x t end_of_type =
in
let new_type_of_hyp,ctxt_size,witness_fun =
List.fold_left_i
- (fun i (end_of_type,ctxt_size,witness_fun) ((x',b',t') as decl) ->
+ (fun i (end_of_type,ctxt_size,witness_fun) decl ->
try
let witness = Int.Map.find i sub in
- if not (Option.is_empty b') then anomaly (Pp.str "can not redefine a rel!");
- (Termops.pop end_of_type,ctxt_size,mkLetIn(x',witness,t',witness_fun))
+ if is_local_def decl then anomaly (Pp.str "can not redefine a rel!");
+ (Termops.pop end_of_type,ctxt_size,mkLetIn (get_name decl, witness, get_type decl, witness_fun))
with Not_found ->
(mkProd_or_LetIn decl end_of_type, ctxt_size + 1, mkLambda_or_LetIn decl witness_fun)
)
@@ -536,7 +537,7 @@ let clean_hyp_with_heq ptes_infos eq_hyps hyp_id env sigma =
(scan_type new_context new_t')
with Failure "NoChange" ->
(* Last thing todo : push the rel in the context and continue *)
- scan_type ((x,None,t_x)::context) t'
+ scan_type (LocalAssum (x,t_x) :: context) t'
end
end
else
@@ -736,7 +737,8 @@ let build_proof
tclTHEN
(Proofview.V82.of_tactic intro)
(fun g' ->
- let (id,_,_) = pf_last_hyp g' in
+ let open Context.Named.Declaration in
+ let id = pf_last_hyp g' |> get_id in
let new_term =
pf_nf_betaiota g'
(mkApp(dyn_infos.info,[|mkVar id|]))
@@ -921,7 +923,9 @@ let generalize_non_dep hyp g =
let env = Global.env () in
let hyp_typ = pf_unsafe_type_of g (mkVar hyp) in
let to_revert,_ =
- Environ.fold_named_context_reverse (fun (clear,keep) (hyp,_,_ as decl) ->
+ let open Context.Named.Declaration in
+ Environ.fold_named_context_reverse (fun (clear,keep) decl ->
+ let hyp = get_id decl in
if Id.List.mem hyp hyps
|| List.exists (Termops.occur_var_in_decl env hyp) keep
|| Termops.occur_var env hyp hyp_typ
@@ -936,7 +940,7 @@ let generalize_non_dep hyp g =
((* observe_tac "thin" *) (thin to_revert))
g
-let id_of_decl (na,_,_) = (Nameops.out_name na)
+let id_of_decl decl = Nameops.out_name (get_name decl)
let var_of_decl decl = mkVar (id_of_decl decl)
let revert idl =
tclTHEN
@@ -1044,7 +1048,8 @@ let do_replace (evd:Evd.evar_map ref) params rec_arg_num rev_args_id f fun_num a
(
fun g' ->
let just_introduced = nLastDecls nb_intro_to_do g' in
- let just_introduced_id = List.map (fun (id,_,_) -> id) just_introduced in
+ let open Context.Named.Declaration in
+ let just_introduced_id = List.map get_id just_introduced in
tclTHEN (Proofview.V82.of_tactic (Equality.rewriteLR equation_lemma))
(revert just_introduced_id) g'
)
@@ -1069,11 +1074,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
(Name new_id)
)
in
- let fresh_decl =
- (fun (na,b,t) ->
- (fresh_id na,b,t)
- )
- in
+ let fresh_decl = map_name fresh_id in
let princ_info : elim_scheme =
{ princ_info with
params = List.map fresh_decl princ_info.params;
@@ -1120,11 +1121,11 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
)
in
observe (str "full_params := " ++
- prlist_with_sep spc (fun (na,_,_) -> Ppconstr.pr_id (Nameops.out_name na))
+ prlist_with_sep spc (fun decl -> Ppconstr.pr_id (Nameops.out_name (get_name decl)))
full_params
);
observe (str "princ_params := " ++
- prlist_with_sep spc (fun (na,_,_) -> Ppconstr.pr_id (Nameops.out_name na))
+ prlist_with_sep spc (fun decl -> Ppconstr.pr_id (Nameops.out_name (get_name decl)))
princ_params
);
observe (str "fbody_with_full_params := " ++
@@ -1165,7 +1166,8 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
in
let pte_to_fix,rev_info =
List.fold_left_i
- (fun i (acc_map,acc_info) (pte,_,_) ->
+ (fun i (acc_map,acc_info) decl ->
+ let pte = get_name decl in
let infos = info_array.(i) in
let type_args,_ = decompose_prod infos.types in
let nargs = List.length type_args in
@@ -1259,7 +1261,8 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let args = nLastDecls nb_args g in
let fix_body = fix_info.body_with_param in
(* observe (str "fix_body := "++ pr_lconstr_env (pf_env gl) fix_body); *)
- let args_id = List.map (fun (id,_,_) -> id) args in
+ let open Context.Named.Declaration in
+ let args_id = List.map get_id args in
let dyn_infos =
{
nb_rec_hyps = -100;
@@ -1276,7 +1279,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
(do_replace evd
full_params
(fix_info.idx + List.length princ_params)
- (args_id@(List.map (fun (id,_,_) -> Nameops.out_name id ) princ_params))
+ (args_id@(List.map (fun decl -> Nameops.out_name (get_name decl)) princ_params))
(all_funs.(fix_info.num_in_block))
fix_info.num_in_block
all_funs
@@ -1317,8 +1320,9 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
[
tclDO nb_args (Proofview.V82.of_tactic intro);
(fun g -> (* replacement of the function by its body *)
- let args = nLastDecls nb_args g in
- let args_id = List.map (fun (id,_,_) -> id) args in
+ let args = nLastDecls nb_args g in
+ let open Context.Named.Declaration in
+ let args_id = List.map get_id args in
let dyn_infos =
{
nb_rec_hyps = -100;
@@ -1520,7 +1524,7 @@ let prove_principle_for_gen
avoid := new_id :: !avoid;
Name new_id
in
- let fresh_decl (na,b,t) = (fresh_id na,b,t) in
+ let fresh_decl = map_name fresh_id in
let princ_info : elim_scheme =
{ princ_info with
params = List.map fresh_decl princ_info.params;
@@ -1550,11 +1554,11 @@ let prove_principle_for_gen
in
let rec_arg_id =
match List.rev post_rec_arg with
- | (Name id,_,_)::_ -> id
+ | (LocalAssum (Name id,_) | LocalDef (Name id,_,_)) :: _ -> id
| _ -> assert false
in
(* observe (str "rec_arg_id := " ++ pr_lconstr (mkVar rec_arg_id)); *)
- let subst_constrs = List.map (fun (na,_,_) -> mkVar (Nameops.out_name na)) (pre_rec_arg@princ_info.params) in
+ let subst_constrs = List.map (fun decl -> mkVar (Nameops.out_name (get_name decl))) (pre_rec_arg@princ_info.params) in
let relation = substl subst_constrs relation in
let input_type = substl subst_constrs rec_arg_type in
let wf_thm_id = Nameops.out_name (fresh_id (Name (Id.of_string "wf_R"))) in
@@ -1582,7 +1586,7 @@ let prove_principle_for_gen
)
g
in
- let args_ids = List.map (fun (na,_,_) -> Nameops.out_name na) princ_info.args in
+ let args_ids = List.map (fun decl -> Nameops.out_name (get_name decl)) princ_info.args in
let lemma =
match !tcc_lemma_ref with
| None -> error "No tcc proof !!"
@@ -1629,7 +1633,7 @@ let prove_principle_for_gen
[
observe_tac "start_tac" start_tac;
h_intros
- (List.rev_map (fun (na,_,_) -> Nameops.out_name na)
+ (List.rev_map (fun decl -> Nameops.out_name (get_name decl))
(princ_info.args@princ_info.branches@princ_info.predicates@princ_info.params)
);
(* observe_tac "" *) Proofview.V82.of_tactic (assert_by
@@ -1667,7 +1671,7 @@ let prove_principle_for_gen
in
let acc_inv = lazy (mkApp(Lazy.force acc_inv, [|mkVar acc_rec_arg_id|])) in
let predicates_names =
- List.map (fun (na,_,_) -> Nameops.out_name na) princ_info.predicates
+ List.map (fun decl -> Nameops.out_name (get_name decl)) princ_info.predicates
in
let pte_info =
{ proving_tac =
@@ -1683,7 +1687,7 @@ let prove_principle_for_gen
is_mes acc_inv fix_id
(!tcc_list@(List.map
- (fun (na,_,_) -> (Nameops.out_name na))
+ (fun decl -> (Nameops.out_name (get_name decl)))
(princ_info.args@princ_info.params)
)@ ([acc_rec_arg_id])) eqs
)
@@ -1712,7 +1716,7 @@ let prove_principle_for_gen
(* observe_tac "instanciate_hyps_with_args" *)
(instanciate_hyps_with_args
make_proof
- (List.map (fun (na,_,_) -> Nameops.out_name na) princ_info.branches)
+ (List.map (fun decl -> Nameops.out_name (get_name decl)) princ_info.branches)
(List.rev args_ids)
)
gl'
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index e2c3bbb978..7a933c04b2 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -8,6 +8,7 @@ open Names
open Pp
open Entries
open Tactics
+open Context.Rel.Declaration
open Indfun_common
open Functional_principles_proofs
open Misctypes
@@ -32,11 +33,13 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
let rec change_predicates_names (avoid:Id.t list) (predicates:Context.Rel.t) : Context.Rel.t =
match predicates with
| [] -> []
- |(Name x,v,t)::predicates ->
- let id = Namegen.next_ident_away x avoid in
- Hashtbl.add tbl id x;
- (Name id,v,t)::(change_predicates_names (id::avoid) predicates)
- | (Anonymous,_,_)::_ -> anomaly (Pp.str "Anonymous property binder ")
+ | decl :: predicates ->
+ (match Context.Rel.Declaration.get_name decl with
+ | Name x ->
+ let id = Namegen.next_ident_away x avoid in
+ Hashtbl.add tbl id x;
+ set_name (Name id) decl :: change_predicates_names (id::avoid) predicates
+ | Anonymous -> anomaly (Pp.str "Anonymous property binder "))
in
let avoid = (Termops.ids_of_context env_with_params ) in
let princ_type_info =
@@ -46,15 +49,16 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
in
(* observe (str "starting princ_type := " ++ pr_lconstr_env env princ_type); *)
(* observe (str "princ_infos : " ++ pr_elim_scheme princ_type_info); *)
- let change_predicate_sort i (x,_,t) =
+ let change_predicate_sort i decl =
let new_sort = sorts.(i) in
- let args,_ = decompose_prod t in
+ let args,_ = decompose_prod (get_type decl) in
let real_args =
if princ_type_info.indarg_in_concl
then List.tl args
else args
in
- Nameops.out_name x,None,compose_prod real_args (mkSort new_sort)
+ Context.Named.Declaration.LocalAssum (Nameops.out_name (Context.Rel.Declaration.get_name decl),
+ compose_prod real_args (mkSort new_sort))
in
let new_predicates =
List.map_i
@@ -69,7 +73,7 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
| _ -> error "Not a valid predicate"
)
in
- let ptes_vars = List.map (fun (id,_,_) -> id) new_predicates in
+ let ptes_vars = List.map Context.Named.Declaration.get_id new_predicates in
let is_pte =
let set = List.fold_right Id.Set.add ptes_vars Id.Set.empty in
fun t ->
@@ -114,7 +118,7 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
| Rel n ->
begin
try match Environ.lookup_rel n env with
- | _,_,t when is_dom t -> raise Toberemoved
+ | LocalAssum (_,t) | LocalDef (_,_,t) when is_dom t -> raise Toberemoved
| _ -> pre_princ,[]
with Not_found -> assert false
end
@@ -159,7 +163,7 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
try
let new_t,binders_to_remove_from_t = compute_new_princ_type remove env t in
let new_x : Name.t = get_name (Termops.ids_of_context env) x in
- let new_env = Environ.push_rel (x,None,t) env in
+ let new_env = Environ.push_rel (LocalAssum (x,t)) env in
let new_b,binders_to_remove_from_b = compute_new_princ_type remove new_env b in
if List.exists (eq_constr (mkRel 1)) binders_to_remove_from_b
then (Termops.pop new_b), filter_map (eq_constr (mkRel 1)) Termops.pop binders_to_remove_from_b
@@ -188,7 +192,7 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
let new_t,binders_to_remove_from_t = compute_new_princ_type remove env t in
let new_v,binders_to_remove_from_v = compute_new_princ_type remove env v in
let new_x : Name.t = get_name (Termops.ids_of_context env) x in
- let new_env = Environ.push_rel (x,Some v,t) env in
+ let new_env = Environ.push_rel (LocalDef (x,v,t)) env in
let new_b,binders_to_remove_from_b = compute_new_princ_type remove new_env b in
if List.exists (eq_constr (mkRel 1)) binders_to_remove_from_b
then (Termops.pop new_b),filter_map (eq_constr (mkRel 1)) Termops.pop binders_to_remove_from_b
@@ -227,7 +231,8 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
in
it_mkProd_or_LetIn
(it_mkProd_or_LetIn
- pre_res (List.map (fun (id,t,b) -> Name(Hashtbl.find tbl id), t,b)
+ pre_res (List.map (function Context.Named.Declaration.LocalAssum (id,b) -> LocalAssum (Name (Hashtbl.find tbl id), b)
+ | Context.Named.Declaration.LocalDef (id,t,b) -> LocalDef (Name (Hashtbl.find tbl id), t, b))
new_predicates)
)
princ_type_info.params
@@ -235,10 +240,12 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
let change_property_sort evd toSort princ princName =
+ let open Context.Rel.Declaration in
let princ_info = compute_elim_sig princ in
- let change_sort_in_predicate (x,v,t) =
- (x,None,
- let args,ty = decompose_prod t in
+ let change_sort_in_predicate decl =
+ LocalAssum
+ (get_name decl,
+ let args,ty = decompose_prod (get_type decl) in
let s = destSort ty in
Global.add_constraints (Univ.enforce_leq (univ_of_sort toSort) (univ_of_sort s) Univ.Constraint.empty);
compose_prod args (mkSort toSort)
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 80de8e764d..8a0a1a064d 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -335,15 +335,17 @@ let raw_push_named (na,raw_value,raw_typ) env =
| Name id ->
let value = Option.map (fun x-> fst (Pretyping.understand env (Evd.from_env env) x)) raw_value in
let typ,ctx = Pretyping.understand env (Evd.from_env env) ~expected_type:Pretyping.IsType raw_typ in
- Environ.push_named (id,value,typ) env
+ let open Context.Named.Declaration in
+ Environ.push_named (of_tuple (id,value,typ)) env
let add_pat_variables pat typ env : Environ.env =
let rec add_pat_variables env pat typ : Environ.env =
+ let open Context.Rel.Declaration in
observe (str "new rel env := " ++ Printer.pr_rel_context_of env (Evd.from_env env));
match pat with
- | PatVar(_,na) -> Environ.push_rel (na,None,typ) env
+ | PatVar(_,na) -> Environ.push_rel (LocalAssum (na,typ)) env
| PatCstr(_,c,patl,na) ->
let Inductiveops.IndType(indf,indargs) =
try Inductiveops.find_rectype env (Evd.from_env env) typ
@@ -351,15 +353,16 @@ let add_pat_variables pat typ env : Environ.env =
in
let constructors = Inductiveops.get_constructors env indf in
let constructor : Inductiveops.constructor_summary = List.find (fun cs -> eq_constructor c (fst cs.Inductiveops.cs_cstr)) (Array.to_list constructors) in
- let cs_args_types :types list = List.map (fun (_,_,t) -> t) constructor.Inductiveops.cs_args in
+ let cs_args_types :types list = List.map get_type constructor.Inductiveops.cs_args in
List.fold_left2 add_pat_variables env patl (List.rev cs_args_types)
in
let new_env = add_pat_variables env pat typ in
let res =
fst (
Context.Rel.fold_outside
- (fun (na,v,t) (env,ctxt) ->
- match na with
+ (fun decl (env,ctxt) ->
+ let _,v,t = Context.Rel.Declaration.to_tuple decl in
+ match Context.Rel.Declaration.get_name decl with
| Anonymous -> assert false
| Name id ->
let new_t = substl ctxt t in
@@ -370,7 +373,8 @@ let add_pat_variables pat typ env : Environ.env =
Option.fold_right (fun v _ -> str "old value := " ++ Printer.pr_lconstr v ++ fnl ()) v (mt ()) ++
Option.fold_right (fun v _ -> str "new value := " ++ Printer.pr_lconstr v ++ fnl ()) new_v (mt ())
);
- (Environ.push_named (id,new_v,new_t) env,mkVar id::ctxt)
+ let open Context.Named.Declaration in
+ (Environ.push_named (of_tuple (id,new_v,new_t)) env,mkVar id::ctxt)
)
(Environ.rel_context new_env)
~init:(env,[])
@@ -398,7 +402,8 @@ let rec pattern_to_term_and_type env typ = function
in
let constructors = Inductiveops.get_constructors env indf in
let constructor = List.find (fun cs -> eq_constructor (fst cs.Inductiveops.cs_cstr) constr) (Array.to_list constructors) in
- let cs_args_types :types list = List.map (fun (_,_,t) -> t) constructor.Inductiveops.cs_args in
+ let open Context.Rel.Declaration in
+ let cs_args_types :types list = List.map get_type constructor.Inductiveops.cs_args in
let _,cstl = Inductiveops.dest_ind_family indf in
let csta = Array.of_list cstl in
let implicit_args =
@@ -597,9 +602,10 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
let v_as_constr,ctx = Pretyping.understand env (Evd.from_env env) v in
let v_type = Typing.unsafe_type_of env (Evd.from_env env) v_as_constr in
let new_env =
+ let open Context.Named.Declaration in
match n with
Anonymous -> env
- | Name id -> Environ.push_named (id,Some v_as_constr,v_type) env
+ | Name id -> Environ.push_named (of_tuple (id,Some v_as_constr,v_type)) env
in
let b_res = build_entry_lc new_env funnames avoid b in
combine_results (combine_letin n) v_res b_res
@@ -875,7 +881,7 @@ exception Continue
*)
let rec rebuild_cons env nb_args relname args crossed_types depth rt =
observe (str "rebuilding : " ++ pr_glob_constr rt);
-
+ let open Context.Rel.Declaration in
match rt with
| GProd(_,n,k,t,b) ->
let not_free_in_t id = not (is_free_in id t) in
@@ -895,7 +901,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
mkGApp(mkGVar(mk_rel_id this_relname),args'@[res_rt])
in
let t',ctx = Pretyping.understand env (Evd.from_env env) new_t in
- let new_env = Environ.push_rel (n,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (n,t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -926,7 +932,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
let subst_b =
if is_in_b then b else replace_var_by_term id rt b
in
- let new_env = Environ.push_rel (n,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (n,t')) env in
let new_b,id_to_exclude =
rebuild_cons
new_env
@@ -970,9 +976,8 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
(fun acc var_as_constr arg ->
if isRel var_as_constr
then
- let (na,_,_) =
- Environ.lookup_rel (destRel var_as_constr) env
- in
+ let open Context.Rel.Declaration in
+ let na = get_name (Environ.lookup_rel (destRel var_as_constr) env) in
match na with
| Anonymous -> acc
| Name id' ->
@@ -1010,7 +1015,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
in
let new_env =
let t',ctx = Pretyping.understand env (Evd.from_env env) eq' in
- Environ.push_rel (n,None,t') env
+ Environ.push_rel (LocalAssum (n,t')) env
in
let new_b,id_to_exclude =
rebuild_cons
@@ -1048,7 +1053,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
with Continue ->
observe (str "computing new type for prod : " ++ pr_glob_constr rt);
let t',ctx = Pretyping.understand env (Evd.from_env env) t in
- let new_env = Environ.push_rel (n,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (n,t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -1064,7 +1069,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
| _ ->
observe (str "computing new type for prod : " ++ pr_glob_constr rt);
let t',ctx = Pretyping.understand env (Evd.from_env env) t in
- let new_env = Environ.push_rel (n,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (n,t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -1085,7 +1090,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
let t',ctx = Pretyping.understand env (Evd.from_env env) t in
match n with
| Name id ->
- let new_env = Environ.push_rel (n,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (n,t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -1108,7 +1113,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
let t',ctx = Pretyping.understand env evd t in
let evd = Evd.from_ctx ctx in
let type_t' = Typing.unsafe_type_of env evd t' in
- let new_env = Environ.push_rel (n,Some t',type_t') env in
+ let new_env = Environ.push_rel (LocalDef (n,t',type_t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -1132,7 +1137,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
depth t
in
let t',ctx = Pretyping.understand env (Evd.from_env env) new_t in
- let new_env = Environ.push_rel (na,None,t') env in
+ let new_env = Environ.push_rel (LocalAssum (na,t')) env in
let new_b,id_to_exclude =
rebuild_cons new_env
nb_args relname
@@ -1254,12 +1259,13 @@ let do_build_inductive
let relnames = Array.map mk_rel_id funnames in
let relnames_as_set = Array.fold_right Id.Set.add relnames Id.Set.empty in
(* Construction of the pseudo constructors *)
+ let open Context.Named.Declaration in
let evd,env =
Array.fold_right2
(fun id c (evd,env) ->
let evd,t = Typing.type_of env evd (mkConstU c) in
evd,
- Environ.push_named (id,None,t)
+ Environ.push_named (LocalAssum (id,t))
(* try *)
(* Typing.e_type_of env evd (mkConstU c) *)
(* with Not_found -> *)
@@ -1298,8 +1304,8 @@ let do_build_inductive
*)
let rel_arities = Array.mapi rel_arity funsargs in
Util.Array.fold_left2 (fun env rel_name rel_ar ->
- Environ.push_named (rel_name,None,
- fst (with_full_print (Constrintern.interp_constr env evd) rel_ar)) env) env relnames rel_arities
+ Environ.push_named (LocalAssum (rel_name,
+ fst (with_full_print (Constrintern.interp_constr env evd) rel_ar))) env) env relnames rel_arities
in
(* and of the real constructors*)
let constr i res =
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index d1e1098259..86abf9e2ef 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -1,3 +1,4 @@
+open Context.Rel.Declaration
open Errors
open Util
open Names
@@ -13,10 +14,10 @@ open Decl_kinds
open Sigma.Notations
let is_rec_info scheme_info =
- let test_branche min acc (_,_,br) =
+ let test_branche min acc decl =
acc || (
let new_branche =
- it_mkProd_or_LetIn mkProp (fst (decompose_prod_assum br)) in
+ it_mkProd_or_LetIn mkProp (fst (decompose_prod_assum (get_type decl))) in
let free_rels_in_br = Termops.free_rels new_branche in
let max = min + scheme_info.Tactics.npredicates in
Int.Set.exists (fun i -> i >= min && i< max) free_rels_in_br
@@ -153,7 +154,8 @@ let build_newrecursive
let evdref = ref (Evd.from_env env0) in
let _, (_, impls') = Constrintern.interp_context_evars env evdref bl in
let impl = Constrintern.compute_internalization_data env0 Constrintern.Recursive arity impls' in
- (Environ.push_named (recname,None,arity) env, Id.Map.add recname impl impls))
+ let open Context.Named.Declaration in
+ (Environ.push_named (LocalAssum (recname,arity)) env, Id.Map.add recname impl impls))
(env0,Constrintern.empty_internalization_env) lnameargsardef in
let recdef =
(* Declare local notations *)
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index 0c9d3bb819..56bc4328d1 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -5,6 +5,7 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+
open Tacexpr
open Declarations
open Errors
@@ -20,6 +21,7 @@ open Indfun_common
open Tacmach
open Misctypes
open Termops
+open Context.Rel.Declaration
(* Some pretty printing function for debugging purpose *)
@@ -134,18 +136,21 @@ let generate_type evd g_to_f f graph i =
let fun_ctxt,res_type =
match ctxt with
| [] | [_] -> anomaly (Pp.str "Not a valid context")
- | (_,_,res_type)::fun_ctxt -> fun_ctxt,res_type
+ | decl :: fun_ctxt -> fun_ctxt, get_type decl
in
let rec args_from_decl i accu = function
| [] -> accu
- | (_, Some _, _) :: l ->
+ | LocalDef _ :: l ->
args_from_decl (succ i) accu l
| _ :: l ->
let t = mkRel i in
args_from_decl (succ i) (t :: accu) l
in
(*i We need to name the vars [res] and [fv] i*)
- let filter = function (Name id,_,_) -> Some id | (Anonymous,_,_) -> None in
+ let filter = fun decl -> match get_name decl with
+ | Name id -> Some id
+ | Anonymous -> None
+ in
let named_ctxt = List.map_filter filter fun_ctxt in
let res_id = Namegen.next_ident_away_in_goal (Id.of_string "_res") named_ctxt in
let fv_id = Namegen.next_ident_away_in_goal (Id.of_string "fv") (res_id :: named_ctxt) in
@@ -171,12 +176,12 @@ let generate_type evd g_to_f f graph i =
\[\forall (x_1:t_1)\ldots(x_n:t_n), let fv := f x_1\ldots x_n in, forall res, \]
i*)
let pre_ctxt =
- (Name res_id,None,lift 1 res_type)::(Name fv_id,Some (mkApp(f,args_as_rels)),res_type)::fun_ctxt
+ LocalAssum (Name res_id, lift 1 res_type) :: LocalDef (Name fv_id, mkApp (f,args_as_rels), res_type) :: fun_ctxt
in
(*i and we can return the solution depending on which lemma type we are defining i*)
if g_to_f
- then (Anonymous,None,graph_applied)::pre_ctxt,(lift 1 res_eq_f_of_args),graph
- else (Anonymous,None,res_eq_f_of_args)::pre_ctxt,(lift 1 graph_applied),graph
+ then LocalAssum (Anonymous,graph_applied)::pre_ctxt,(lift 1 res_eq_f_of_args),graph
+ else LocalAssum (Anonymous,res_eq_f_of_args)::pre_ctxt,(lift 1 graph_applied),graph
(*
@@ -260,10 +265,10 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
(* and built the intro pattern for each of them *)
let intro_pats =
List.map
- (fun (_,_,br_type) ->
+ (fun decl ->
List.map
(fun id -> Loc.ghost, IntroNaming (IntroIdentifier id))
- (generate_fresh_id (Id.of_string "y") ids (List.length (fst (decompose_prod_assum br_type))))
+ (generate_fresh_id (Id.of_string "y") ids (List.length (fst (decompose_prod_assum (get_type decl)))))
)
branches
in
@@ -390,10 +395,10 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
(fun ((_,(ctxt,concl))) ->
match ctxt with
| [] | [_] | [_;_] -> anomaly (Pp.str "bad context")
- | hres::res::(x,_,t)::ctxt ->
+ | hres::res::decl::ctxt ->
let res = Termops.it_mkLambda_or_LetIn
(Termops.it_mkProd_or_LetIn concl [hres;res])
- ((x,None,t)::ctxt)
+ (LocalAssum (get_name decl, get_type decl) :: ctxt)
in
res
)
@@ -408,8 +413,8 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
let bindings =
let params_bindings,avoid =
List.fold_left2
- (fun (bindings,avoid) (x,_,_) p ->
- let id = Namegen.next_ident_away (Nameops.out_name x) avoid in
+ (fun (bindings,avoid) decl p ->
+ let id = Namegen.next_ident_away (Nameops.out_name (get_name decl)) avoid in
p::bindings,id::avoid
)
([],pf_ids_of_hyps g)
@@ -418,8 +423,8 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
in
let lemmas_bindings =
List.rev (fst (List.fold_left2
- (fun (bindings,avoid) (x,_,_) p ->
- let id = Namegen.next_ident_away (Nameops.out_name x) avoid in
+ (fun (bindings,avoid) decl p ->
+ let id = Namegen.next_ident_away (Nameops.out_name (get_name decl)) avoid in
(nf_zeta p)::bindings,id::avoid)
([],avoid)
princ_infos.predicates
@@ -455,9 +460,10 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
generalize every hypothesis which depends of [x] but [hyp]
*)
let generalize_dependent_of x hyp g =
+ let open Context.Named.Declaration in
tclMAP
(function
- | (id,None,t) when not (Id.equal id hyp) &&
+ | LocalAssum (id,t) when not (Id.equal id hyp) &&
(Termops.occur_var (pf_env g) x t) -> tclTHEN (Tactics.generalize [mkVar id]) (thin [id])
| _ -> tclIDTAC
)
@@ -663,10 +669,10 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
let branches = List.rev princ_infos.branches in
let intro_pats =
List.map
- (fun (_,_,br_type) ->
+ (fun decl ->
List.map
(fun id -> id)
- (generate_fresh_id (Id.of_string "y") ids (nb_prod br_type))
+ (generate_fresh_id (Id.of_string "y") ids (nb_prod (get_type decl)))
)
branches
in
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
index 57782dd71f..c71d9a9ca4 100644
--- a/plugins/funind/merge.ml
+++ b/plugins/funind/merge.ml
@@ -24,6 +24,7 @@ open Declarations
open Glob_term
open Glob_termops
open Decl_kinds
+open Context.Rel.Declaration
(** {1 Utilities} *)
@@ -134,9 +135,9 @@ let showind (id:Id.t) =
let cstrid = Constrintern.global_reference id in
let ind1,cstrlist = Inductiveops.find_inductive (Global.env()) Evd.empty cstrid in
let mib1,ib1 = Inductive.lookup_mind_specif (Global.env()) (fst ind1) in
- List.iter (fun (nm, optcstr, tp) ->
- print_string (string_of_name nm^":");
- prconstr tp; print_string "\n")
+ List.iter (fun decl ->
+ print_string (string_of_name (Context.Rel.Declaration.get_name decl) ^ ":");
+ prconstr (get_type decl); print_string "\n")
ib1.mind_arity_ctxt;
Printf.printf "arity :"; prconstr (Inductiveops.type_of_inductive (Global.env ()) ind1);
Array.iteri
@@ -459,11 +460,12 @@ let shift_linked_params mib1 mib2 (lnk1:linked_var array) (lnk2:linked_var array
let recprms2,otherprms2,args2,funresprms2 = bldprms (List.rev oib2.mind_arity_ctxt) mlnk2 in
let _ = prstr "\notherprms1:\n" in
let _ =
- List.iter (fun (x,_,y) -> prstr (string_of_name x^" : ");prconstr y;prstr "\n")
+ List.iter (fun decl -> prstr (string_of_name (get_name decl) ^ " : ");
+ prconstr (get_type decl); prstr "\n")
otherprms1 in
let _ = prstr "\notherprms2:\n" in
let _ =
- List.iter (fun (x,_,y) -> prstr (string_of_name x^" : ");prconstr y;prstr "\n")
+ List.iter (fun decl -> prstr (string_of_name (get_name decl) ^ " : "); prconstr (get_type decl); prstr "\n")
otherprms2 in
{
ident=id;
@@ -823,9 +825,11 @@ let merge_rec_params_and_arity prms1 prms2 shift (concl:constr) =
let concl = Constrextern.extern_constr false (Global.env()) Evd.empty concl in
let arity,_ =
List.fold_left
- (fun (acc,env) (nm,_,c) ->
+ (fun (acc,env) decl ->
+ let nm = Context.Rel.Declaration.get_name decl in
+ let c = get_type decl in
let typ = Constrextern.extern_constr false env Evd.empty c in
- let newenv = Environ.push_rel (nm,None,c) env in
+ let newenv = Environ.push_rel (LocalAssum (nm,c)) env in
CProdN (Loc.ghost, [[(Loc.ghost,nm)],Constrexpr_ops.default_binder_kind,typ] , acc) , newenv)
(concl,Global.env())
(shift.funresprms2 @ shift.funresprms1
@@ -852,10 +856,10 @@ let glob_constr_list_to_inductive_expr prms1 prms2 mib1 mib2 shift
let mkProd_reldecl (rdecl:Context.Rel.Declaration.t) (t2:glob_constr) =
match rdecl with
- | (nme,None,t) ->
+ | LocalAssum (nme,t) ->
let traw = Detyping.detype false [] (Global.env()) Evd.empty t in
GProd (Loc.ghost,nme,Explicit,traw,t2)
- | (_,Some _,_) -> assert false
+ | LocalDef _ -> assert false
(** [merge_inductive ind1 ind2 lnk] merges two graphs, linking
@@ -969,7 +973,7 @@ let funify_branches relinfo nfuns branch =
| Rel i -> let reali = i-shift in (reali>=0 && reali false in
(* FIXME: *)
- (Anonymous,Some mkProp,mkProp)
+ LocalDef (Anonymous,mkProp,mkProp)
let relprinctype_to_funprinctype relprinctype nfuns =
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index b096783412..09c5aa5673 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -40,7 +40,7 @@ open Eauto
open Indfun_common
open Sigma.Notations
-
+open Context.Rel.Declaration
(* Ugly things which should not be here *)
@@ -181,7 +181,7 @@ let (value_f:constr list -> global_reference -> constr) =
)
in
let context = List.map
- (fun (x, c) -> Name x, None, c) (List.combine rev_x_id_l (List.rev al))
+ (fun (x, c) -> LocalAssum (Name x, c)) (List.combine rev_x_id_l (List.rev al))
in
let env = Environ.push_rel_context context (Global.env ()) in
let glob_body =
@@ -678,8 +678,10 @@ let mkDestructEq :
let hyps = pf_hyps g in
let to_revert =
Util.List.map_filter
- (fun (id, _, t) ->
- if Id.List.mem id not_on_hyp || not (Termops.occur_term expr t)
+ (fun decl ->
+ let open Context.Named.Declaration in
+ let id = get_id decl in
+ if Id.List.mem id not_on_hyp || not (Termops.occur_term expr (get_type decl))
then None else Some id) hyps in
let to_revert_constr = List.rev_map mkVar to_revert in
let type_of_expr = pf_unsafe_type_of g expr in
@@ -1253,7 +1255,7 @@ let clear_goals =
then Termops.pop b'
else if b' == b then t
else mkProd(na,t',b')
- | _ -> map_constr clear_goal t
+ | _ -> Term.map_constr clear_goal t
in
List.map clear_goal
@@ -1489,7 +1491,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let env = Global.env() in
let evd = ref (Evd.from_env env) in
let function_type = interp_type_evars env evd type_of_f in
- let env = push_named (function_name,None,function_type) env in
+ let env = push_named (Context.Named.Declaration.LocalAssum (function_name,function_type)) env in
(* Pp.msgnl (str "function type := " ++ Printer.pr_lconstr function_type); *)
let ty = interp_type_evars env evd ~impls:rec_impls eq in
let evm, nf = Evarutil.nf_evars_and_universes !evd in
@@ -1497,7 +1499,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let function_type = nf function_type in
(* Pp.msgnl (str "lemma type := " ++ Printer.pr_lconstr equation_lemma_type ++ fnl ()); *)
let res_vars,eq' = decompose_prod equation_lemma_type in
- let env_eq' = Environ.push_rel_context (List.map (fun (x,y) -> (x,None,y)) res_vars) env in
+ let env_eq' = Environ.push_rel_context (List.map (fun (x,y) -> LocalAssum (x,y)) res_vars) env in
let eq' = nf_zeta env_eq' eq' in
let res =
(* Pp.msgnl (str "res_var :=" ++ Printer.pr_lconstr_env (push_rel_context (List.map (function (x,t) -> (x,None,t)) res_vars) env) eq'); *)
@@ -1515,7 +1517,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let functional_id = add_suffix function_name "_F" in
let term_id = add_suffix function_name "_terminate" in
let functional_ref = declare_fun functional_id (IsDefinition Decl_kinds.Definition) ~ctx:(snd (Evd.universe_context evm)) res in
- let env_with_pre_rec_args = push_rel_context(List.map (function (x,t) -> (x,None,t)) pre_rec_args) env in
+ let env_with_pre_rec_args = push_rel_context(List.map (function (x,t) -> LocalAssum (x,t)) pre_rec_args) env in
let relation =
fst (*FIXME*)(interp_constr
env_with_pre_rec_args
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 7e38109d67..b740649e98 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -28,6 +28,7 @@ open Nametab
open Contradiction
open Misctypes
open Proofview.Notations
+open Context.Named.Declaration
module OmegaSolver = Omega.MakeOmegaSolver (Bigint)
open OmegaSolver
@@ -1695,25 +1696,26 @@ let destructure_hyps =
let pf_nf = Tacmach.New.of_old pf_nf gl in
let rec loop = function
| [] -> (Tacticals.New.tclTHEN nat_inject coq_omega)
- | (i,body,t)::lit ->
+ | decl::lit ->
+ let (i,_,t) = to_tuple decl in
begin try match destructurate_prop t with
| Kapp(False,[]) -> elim_id i
| Kapp((Zle|Zge|Zgt|Zlt|Zne),[t1;t2]) -> loop lit
| Kapp(Or,[t1;t2]) ->
(Tacticals.New.tclTHENS
(elim_id i)
- [ onClearedName i (fun i -> (loop ((i,None,t1)::lit)));
- onClearedName i (fun i -> (loop ((i,None,t2)::lit))) ])
+ [ onClearedName i (fun i -> (loop (LocalAssum (i,t1)::lit)));
+ onClearedName i (fun i -> (loop (LocalAssum (i,t2)::lit))) ])
| Kapp(And,[t1;t2]) ->
Tacticals.New.tclTHEN
(elim_id i)
(onClearedName2 i (fun i1 i2 ->
- loop ((i1,None,t1)::(i2,None,t2)::lit)))
+ loop (LocalAssum (i1,t1) :: LocalAssum (i2,t2) :: lit)))
| Kapp(Iff,[t1;t2]) ->
Tacticals.New.tclTHEN
(elim_id i)
(onClearedName2 i (fun i1 i2 ->
- loop ((i1,None,mkArrow t1 t2)::(i2,None,mkArrow t2 t1)::lit)))
+ loop (LocalAssum (i1,mkArrow t1 t2) :: LocalAssum (i2,mkArrow t2 t1) :: lit)))
| Kimp(t1,t2) ->
(* t1 and t2 might be in Type rather than Prop.
For t1, the decidability check will ensure being Prop. *)
@@ -1724,7 +1726,7 @@ let destructure_hyps =
Proofview.V82.tactic (generalize_tac [mkApp (Lazy.force coq_imp_simp,
[| t1; t2; d1; mkVar i|])]);
(onClearedName i (fun i ->
- (loop ((i,None,mk_or (mk_not t1) t2)::lit))))
+ (loop (LocalAssum (i,mk_or (mk_not t1) t2) :: lit))))
]
else
loop lit
@@ -1735,7 +1737,7 @@ let destructure_hyps =
Proofview.V82.tactic (generalize_tac
[mkApp (Lazy.force coq_not_or,[| t1; t2; mkVar i |])]);
(onClearedName i (fun i ->
- (loop ((i,None,mk_and (mk_not t1) (mk_not t2)):: lit))))
+ (loop (LocalAssum (i,mk_and (mk_not t1) (mk_not t2)) :: lit))))
]
| Kapp(And,[t1;t2]) ->
let d1 = decidability t1 in
@@ -1744,7 +1746,7 @@ let destructure_hyps =
[mkApp (Lazy.force coq_not_and,
[| t1; t2; d1; mkVar i |])]);
(onClearedName i (fun i ->
- (loop ((i,None,mk_or (mk_not t1) (mk_not t2))::lit))))
+ (loop (LocalAssum (i,mk_or (mk_not t1) (mk_not t2)) :: lit))))
]
| Kapp(Iff,[t1;t2]) ->
let d1 = decidability t1 in
@@ -1754,9 +1756,8 @@ let destructure_hyps =
[mkApp (Lazy.force coq_not_iff,
[| t1; t2; d1; d2; mkVar i |])]);
(onClearedName i (fun i ->
- (loop ((i,None,
- mk_or (mk_and t1 (mk_not t2))
- (mk_and (mk_not t1) t2))::lit))))
+ (loop (LocalAssum (i, mk_or (mk_and t1 (mk_not t2))
+ (mk_and (mk_not t1) t2)) :: lit))))
]
| Kimp(t1,t2) ->
(* t2 must be in Prop otherwise ~(t1->t2) wouldn't be ok.
@@ -1767,14 +1768,14 @@ let destructure_hyps =
[mkApp (Lazy.force coq_not_imp,
[| t1; t2; d1; mkVar i |])]);
(onClearedName i (fun i ->
- (loop ((i,None,mk_and t1 (mk_not t2)) :: lit))))
+ (loop (LocalAssum (i,mk_and t1 (mk_not t2)) :: lit))))
]
| Kapp(Not,[t]) ->
let d = decidability t in
Tacticals.New.tclTHENLIST [
Proofview.V82.tactic (generalize_tac
[mkApp (Lazy.force coq_not_not, [| t; d; mkVar i |])]);
- (onClearedName i (fun i -> (loop ((i,None,t)::lit))))
+ (onClearedName i (fun i -> (loop (LocalAssum (i,t) :: lit))))
]
| Kapp(op,[t1;t2]) ->
(try
@@ -1807,15 +1808,13 @@ let destructure_hyps =
match destructurate_type (pf_nf typ) with
| Kapp(Nat,_) ->
(Tacticals.New.tclTHEN
- (convert_hyp_no_check
- (i,body,
- (mkApp (Lazy.force coq_neq, [| t1;t2|]))))
+ (convert_hyp_no_check (set_type (mkApp (Lazy.force coq_neq, [| t1;t2|]))
+ decl))
(loop lit))
| Kapp(Z,_) ->
(Tacticals.New.tclTHEN
- (convert_hyp_no_check
- (i,body,
- (mkApp (Lazy.force coq_Zne, [| t1;t2|]))))
+ (convert_hyp_no_check (set_type (mkApp (Lazy.force coq_Zne, [| t1;t2|]))
+ decl))
(loop lit))
| _ -> loop lit
end
diff --git a/plugins/rtauto/refl_tauto.ml b/plugins/rtauto/refl_tauto.ml
index 9c22b5adb3..2f3a3e5514 100644
--- a/plugins/rtauto/refl_tauto.ml
+++ b/plugins/rtauto/refl_tauto.ml
@@ -13,6 +13,7 @@ open Util
open Term
open Tacmach
open Proof_search
+open Context.Named.Declaration
let force count lazc = incr count;Lazy.force lazc
@@ -128,9 +129,9 @@ let rec make_form atom_env gls term =
let rec make_hyps atom_env gls lenv = function
[] -> []
- | (_,Some body,typ)::rest ->
+ | LocalDef (_,body,typ)::rest ->
make_hyps atom_env gls (typ::body::lenv) rest
- | (id,None,typ)::rest ->
+ | LocalAssum (id,typ)::rest ->
let hrec=
make_hyps atom_env gls (typ::lenv) rest in
if List.exists (Termops.dependent (mkVar id)) lenv ||
diff --git a/plugins/rtauto/refl_tauto.mli b/plugins/rtauto/refl_tauto.mli
index c9e591bbdf..9a14ac6c79 100644
--- a/plugins/rtauto/refl_tauto.mli
+++ b/plugins/rtauto/refl_tauto.mli
@@ -18,7 +18,7 @@ val make_hyps :
atom_env ->
Proof_type.goal Tacmach.sigma ->
Term.types list ->
- (Names.Id.t * Term.types option * Term.types) list ->
+ Context.Named.t ->
(Names.Id.t * Proof_search.form) list
val rtauto_tac : Proof_type.tactic
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 2cbf3a2650..dd58590923 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -28,6 +28,7 @@ open Evarutil
open Evarsolve
open Evarconv
open Evd
+open Context.Rel.Declaration
(* Pattern-matching errors *)
@@ -272,13 +273,13 @@ let inductive_template evdref env tmloc ind =
| None -> fun _ -> (Loc.ghost, Evar_kinds.InternalHole) in
let (_,evarl,_) =
List.fold_right
- (fun (na,b,ty) (subst,evarl,n) ->
- match b with
- | None ->
+ (fun decl (subst,evarl,n) ->
+ match decl with
+ | LocalAssum (na,ty) ->
let ty' = substl subst ty in
let e = e_new_evar env evdref ~src:(hole_source n) ty' in
(e::subst,e::evarl,n+1)
- | Some b ->
+ | LocalDef (na,b,ty) ->
(substl subst b::subst,evarl,n+1))
arsign ([],[],1) in
applist (mkIndU indu,List.rev evarl)
@@ -306,15 +307,15 @@ let binding_vars_of_inductive = function
| NotInd _ -> []
| IsInd (_,IndType(_,realargs),_) -> List.filter isRel realargs
-let extract_inductive_data env sigma (_,b,t) =
- match b with
- | None ->
+let extract_inductive_data env sigma decl =
+ match decl with
+ | LocalAssum (_,t) ->
let tmtyp =
try try_find_ind env sigma t None
with Not_found -> NotInd (None,t) in
let tmtypvars = binding_vars_of_inductive tmtyp in
(tmtyp,tmtypvars)
- | Some _ ->
+ | LocalDef (_,_,t) ->
(NotInd (None, t), [])
let unify_tomatch_with_patterns evdref env loc typ pats realnames =
@@ -427,7 +428,7 @@ let remove_current_pattern eqn =
let push_current_pattern (cur,ty) eqn =
match eqn.patterns with
| pat::pats ->
- let rhs_env = push_rel (alias_of_pat pat,Some cur,ty) eqn.rhs.rhs_env in
+ let rhs_env = push_rel (LocalDef (alias_of_pat pat,cur,ty)) eqn.rhs.rhs_env in
{ eqn with
rhs = { eqn.rhs with rhs_env = rhs_env };
patterns = pats }
@@ -454,9 +455,9 @@ let prepend_pattern tms eqn = {eqn with patterns = tms@eqn.patterns }
exception NotAdjustable
let rec adjust_local_defs loc = function
- | (pat :: pats, (_,None,_) :: decls) ->
+ | (pat :: pats, LocalAssum _ :: decls) ->
pat :: adjust_local_defs loc (pats,decls)
- | (pats, (_,Some _,_) :: decls) ->
+ | (pats, LocalDef _ :: decls) ->
PatVar (loc, Anonymous) :: adjust_local_defs loc (pats,decls)
| [], [] -> []
| _ -> raise NotAdjustable
@@ -528,9 +529,10 @@ let dependencies_in_pure_rhs nargs eqns =
let deps_columns = matrix_transpose deps_rows in
List.map (List.exists (fun x -> x)) deps_columns
-let dependent_decl a = function
- | (na,None,t) -> dependent a t
- | (na,Some c,t) -> dependent a t || dependent a c
+let dependent_decl a =
+ function
+ | LocalAssum (na,t) -> dependent a t
+ | LocalDef (na,c,t) -> dependent a t || dependent a c
let rec dep_in_tomatch n = function
| (Pushed _ | Alias _ | NonDepAlias) :: l -> dep_in_tomatch n l
@@ -601,7 +603,7 @@ let relocate_index_tomatch n1 n2 =
NonDepAlias :: genrec depth rest
| Abstract (i,d) :: rest ->
let i = relocate_rel n1 n2 depth i in
- Abstract (i, Context.Rel.Declaration.map (relocate_index n1 n2 depth) d)
+ Abstract (i, map_constr (relocate_index n1 n2 depth) d)
:: genrec (depth+1) rest in
genrec 0
@@ -634,7 +636,7 @@ let replace_tomatch n c =
| NonDepAlias :: rest ->
NonDepAlias :: replrec depth rest
| Abstract (i,d) :: rest ->
- Abstract (i, Context.Rel.Declaration.map (replace_term n c depth) d)
+ Abstract (i, map_constr (replace_term n c depth) d)
:: replrec (depth+1) rest in
replrec 0
@@ -659,7 +661,7 @@ let rec liftn_tomatch_stack n depth = function
NonDepAlias :: liftn_tomatch_stack n depth rest
| Abstract (i,d)::rest ->
let i = if i
let na =
merge_name
- (fun (na,_,t) -> Name (next_name_away (named_hd env t na) avoid))
+ (fun (LocalAssum (na,t) | LocalDef (na,_,t)) -> Name (next_name_away (named_hd env t na) avoid))
d na
in
(na::l,(out_name na)::avoid))
@@ -727,18 +729,16 @@ let get_names env sign eqns =
(* We now replace the names y1 .. yn y by the actual names *)
(* xi1 .. xin xi to be found in the i-th clause of the matrix *)
-let set_declaration_name x (_,c,t) = (x,c,t)
-
-let recover_initial_subpattern_names = List.map2 set_declaration_name
+let recover_initial_subpattern_names = List.map2 set_name
let recover_and_adjust_alias_names names sign =
let rec aux = function
| [],[] ->
[]
- | x::names, (_,None,t)::sign ->
- (x,(alias_of_pat x,None,t)) :: aux (names,sign)
- | names, (na,(Some _ as c),t)::sign ->
- (PatVar (Loc.ghost,na),(na,c,t)) :: aux (names,sign)
+ | x::names, LocalAssum (_,t)::sign ->
+ (x, LocalAssum (alias_of_pat x,t)) :: aux (names,sign)
+ | names, (LocalDef (na,_,_) as decl)::sign ->
+ (PatVar (Loc.ghost,na), decl) :: aux (names,sign)
| _ -> assert false
in
List.split (aux (names,sign))
@@ -753,11 +753,12 @@ let push_rels_eqn_with_names sign eqn =
let sign = recover_initial_subpattern_names subpatnames sign in
push_rels_eqn sign eqn
-let push_generalized_decl_eqn env n (na,c,t) eqn =
- let na = match na with
- | Anonymous -> Anonymous
- | Name id -> pi1 (Environ.lookup_rel n eqn.rhs.rhs_env) in
- push_rels_eqn [(na,c,t)] eqn
+let push_generalized_decl_eqn env n decl eqn =
+ match get_name decl with
+ | Anonymous ->
+ push_rels_eqn [decl] eqn
+ | Name _ ->
+ push_rels_eqn [set_name (get_name (Environ.lookup_rel n eqn.rhs.rhs_env)) decl] eqn
let drop_alias_eqn eqn =
{ eqn with alias_stack = List.tl eqn.alias_stack }
@@ -765,7 +766,7 @@ let drop_alias_eqn eqn =
let push_alias_eqn alias eqn =
let aliasname = List.hd eqn.alias_stack in
let eqn = drop_alias_eqn eqn in
- let alias = set_declaration_name aliasname alias in
+ let alias = set_name aliasname alias in
push_rels_eqn [alias] eqn
(**********************************************************************)
@@ -931,7 +932,7 @@ let abstract_predicate env sigma indf cur realargs (names,na) tms ccl =
in
let pred = extract_predicate ccl tms in
(* Build the predicate properly speaking *)
- let sign = List.map2 set_declaration_name (na::names) sign in
+ let sign = List.map2 set_name (na::names) sign in
it_mkLambda_or_LetIn_name env pred sign
(* [expand_arg] is used by [specialize_predicate]
@@ -1117,14 +1118,14 @@ let postprocess_dependencies evd tocheck brs tomatch pred deps cs =
let rec aux k brs tomatch pred tocheck deps = match deps, tomatch with
| [], _ -> brs,tomatch,pred,[]
| n::deps, Abstract (i,d) :: tomatch ->
- let d = Context.Rel.Declaration.map (nf_evar evd) d in
- let is_d = match d with (_, None, _) -> false | _ -> true in
+ let d = map_constr (nf_evar evd) d in
+ let is_d = match d with LocalAssum _ -> false | LocalDef _ -> true in
if is_d || List.exists (fun c -> dependent_decl (lift k c) d) tocheck
&& Array.exists (is_dependent_branch k) brs then
(* Dependency in the current term to match and its dependencies is real *)
let brs,tomatch,pred,inst = aux (k+1) brs tomatch pred (mkRel n::tocheck) deps in
let inst = match d with
- | (_, None, _) -> mkRel n :: inst
+ | LocalAssum _ -> mkRel n :: inst
| _ -> inst
in
brs, Abstract (i,d) :: tomatch, pred, inst
@@ -1186,12 +1187,13 @@ let group_equations pb ind current cstrs mat =
let rec generalize_problem names pb = function
| [] -> pb, []
| i::l ->
- let (na,b,t as d) = Context.Rel.Declaration.map (lift i) (Environ.lookup_rel i pb.env) in
let pb',deps = generalize_problem names pb l in
- begin match (na, b) with
- | Anonymous, Some _ -> pb', deps
+ let d = map_constr (lift i) (Environ.lookup_rel i pb.env) in
+ begin match d with
+ | LocalDef (Anonymous,_,_) -> pb', deps
| _ ->
- let d = on_pi3 (whd_betaiota !(pb.evdref)) d in (* for better rendering *)
+ (* for better rendering *)
+ let d = map_type (whd_betaiota !(pb.evdref)) d in
let tomatch = lift_tomatch_stack 1 pb'.tomatch in
let tomatch = relocate_index_tomatch (i+1) 1 tomatch in
{ pb' with
@@ -1219,7 +1221,8 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
(* that had matched constructor C *)
let cs_args = const_info.cs_args in
let names,aliasname = get_names pb.env cs_args eqns in
- let typs = List.map2 (fun (_,c,t) na -> (na,c,t)) cs_args names in
+ let typs = List.map2 set_name names cs_args
+ in
(* We build the matrix obtained by expanding the matching on *)
(* "C x1..xn as x" followed by a residual matching on eqn into *)
@@ -1229,7 +1232,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
(* We adjust the terms to match in the context they will be once the *)
(* context [x1:T1,..,xn:Tn] will have been pushed on the current env *)
let typs' =
- List.map_i (fun i d -> (mkRel i, Context.Rel.Declaration.map (lift i) d)) 1 typs in
+ List.map_i (fun i d -> (mkRel i, map_constr (lift i) d)) 1 typs in
let extenv = push_rel_context typs pb.env in
@@ -1267,7 +1270,8 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
let typs' =
List.map2
- (fun (tm,(tmtyp,_),(na,_,_)) deps ->
+ (fun (tm, (tmtyp,_), decl) deps ->
+ let na = get_name decl in
let na = match curname, na with
| Name _, Anonymous -> curname
| Name _, Name _ -> na
@@ -1391,7 +1395,7 @@ and shift_problem ((current,t),_,na) pb =
let pred = specialize_predicate_var (current,t,na) pb.tomatch pb.pred in
let pb =
{ pb with
- env = push_rel (na,Some current,ty) pb.env;
+ env = push_rel (LocalDef (na,current,ty)) pb.env;
tomatch = tomatch;
pred = lift_predicate 1 pred tomatch;
history = pop_history pb.history;
@@ -1439,7 +1443,7 @@ and compile_generalization pb i d rest =
([false]). *)
and compile_alias initial pb (na,orig,(expanded,expanded_typ)) rest =
let f c t =
- let alias = (na,Some c,t) in
+ let alias = LocalDef (na,c,t) in
let pb =
{ pb with
env = push_rel alias pb.env;
@@ -1575,9 +1579,9 @@ let adjust_to_extended_env_and_remove_deps env extenv subst t =
(* \--------------extenv------------/ *)
let (p, _, _) = lookup_rel_id x (rel_context extenv) in
let rec traverse_local_defs p =
- match pi2 (lookup_rel p extenv) with
- | Some c -> assert (isRel c); traverse_local_defs (p + destRel c)
- | None -> p in
+ match lookup_rel p extenv with
+ | LocalDef (_,c,_) -> assert (isRel c); traverse_local_defs (p + destRel c)
+ | LocalAssum _ -> p in
let p = traverse_local_defs p in
let u = lift (n' - n) u in
try Some (p, u, expand_vars_in_term extenv u)
@@ -1622,7 +1626,7 @@ let abstract_tycon loc env evdref subst tycon extenv t =
convertible subterms of the substitution *)
let rec aux (k,env,subst as x) t =
let t = whd_evar !evdref t in match kind_of_term t with
- | Rel n when pi2 (lookup_rel n env) != None -> t
+ | Rel n when is_local_def (lookup_rel n env) -> t
| Evar ev ->
let ty = get_type_of env !evdref t in
let ty = Evarutil.evd_comb1 (refresh_universes (Some false) env) evdref ty in
@@ -1658,7 +1662,8 @@ let abstract_tycon loc env evdref subst tycon extenv t =
List.map (fun a -> not (isRel a) || dependent a u
|| Int.Set.mem (destRel a) depvl) inst in
let named_filter =
- List.map (fun (id,_,_) -> dependent (mkVar id) u)
+ let open Context.Named.Declaration in
+ List.map (fun d -> dependent (mkVar (get_id d)) u)
(named_context extenv) in
let filter = Filter.make (rel_filter @ named_filter) in
let candidates = u :: List.map mkRel vl in
@@ -1726,7 +1731,7 @@ let build_inversion_problem loc env sigma tms t =
List.rev_append patl patl',acc_sign,acc
| (t, NotInd (bo,typ)) :: tms ->
let pat,acc = make_patvar t acc in
- let d = (alias_of_pat pat,None,typ) in
+ let d = LocalAssum (alias_of_pat pat,typ) in
let patl,acc_sign,acc = aux (n+1) (push_rel d env) (d::acc_sign) tms acc in
pat::patl,acc_sign,acc in
let avoid0 = ids_of_context env in
@@ -1743,7 +1748,7 @@ let build_inversion_problem loc env sigma tms t =
let n = List.length sign in
let decls =
- List.map_i (fun i d -> (mkRel i, Context.Rel.Declaration.map (lift i) d)) 1 sign in
+ List.map_i (fun i d -> (mkRel i, map_constr (lift i) d)) 1 sign in
let pb_env = push_rel_context sign env in
let decls =
@@ -1753,8 +1758,8 @@ let build_inversion_problem loc env sigma tms t =
let dep_sign = find_dependencies_signature (List.make n true) decls in
let sub_tms =
- List.map2 (fun deps (tm,(tmtyp,_),(na,b,t)) ->
- let na = if List.is_empty deps then Anonymous else force_name na in
+ List.map2 (fun deps (tm, (tmtyp,_), decl) ->
+ let na = if List.is_empty deps then Anonymous else force_name (get_name decl) in
Pushed (true,((tm,tmtyp),deps,na)))
dep_sign decls in
let subst = List.map (fun (na,t) -> (na,lift n t)) subst in
@@ -1815,7 +1820,8 @@ let build_inversion_problem loc env sigma tms t =
let build_initial_predicate arsign pred =
let rec buildrec n pred tmnames = function
| [] -> List.rev tmnames,pred
- | ((na,c,t)::realdecls)::lnames ->
+ | (decl::realdecls)::lnames ->
+ let na = get_name decl in
let n' = n + List.length realdecls in
buildrec (n'+1) pred (force_name na::tmnames) lnames
| _ -> assert false
@@ -1827,7 +1833,9 @@ let extract_arity_signature ?(dolift=true) env0 tomatchl tmsign =
match tm with
| NotInd (bo,typ) ->
(match t with
- | None -> [na,Option.map (lift n) bo,lift n typ]
+ | None -> (match bo with
+ | None -> [LocalAssum (na, lift n typ)]
+ | Some b -> [LocalDef (na, lift n b, lift n typ)])
| Some (loc,_,_) ->
user_err_loc (loc,"",
str"Unexpected type annotation for a term of non inductive type."))
@@ -1845,8 +1853,8 @@ let extract_arity_signature ?(dolift=true) env0 tomatchl tmsign =
anomaly (Pp.str "Ill-formed 'in' clause in cases");
List.rev realnal
| None -> List.make nrealargs_ctxt Anonymous in
- (na,None,build_dependent_inductive env0 indf')
- ::(List.map2 (fun x (_,c,t) ->(x,c,t)) realnal arsign) in
+ LocalAssum (na, build_dependent_inductive env0 indf')
+ ::(List.map2 set_name realnal arsign) in
let rec buildrec n = function
| [],[] -> []
| (_,tm)::ltm, (_,x)::tmsign ->
@@ -2027,7 +2035,7 @@ let constr_of_pat env evdref arsign pat avoid =
let previd, id = prime avoid (Name (Id.of_string "wildcard")) in
Name id, id :: avoid
in
- (PatVar (l, name), [name, None, ty] @ realargs, mkRel 1, ty,
+ (PatVar (l, name), [LocalAssum (name, ty)] @ realargs, mkRel 1, ty,
(List.map (fun x -> mkRel 1) realargs), 1, avoid)
| PatCstr (l,((_, i) as cstr),args,alias) ->
let cind = inductive_of_constructor cstr in
@@ -2044,7 +2052,8 @@ let constr_of_pat env evdref arsign pat avoid =
assert (Int.equal nb_args_constr (List.length args));
let patargs, args, sign, env, n, m, avoid =
List.fold_right2
- (fun (na, c, t) ua (patargs, args, sign, env, n, m, avoid) ->
+ (fun decl ua (patargs, args, sign, env, n, m, avoid) ->
+ let t = get_type decl in
let pat', sign', arg', typ', argtypargs, n', avoid =
let liftt = liftn (List.length sign) (succ (List.length args)) t in
typ env (substl args liftt, []) ua avoid
@@ -2066,7 +2075,7 @@ let constr_of_pat env evdref arsign pat avoid =
Anonymous ->
pat', sign, app, apptype, realargs, n, avoid
| Name id ->
- let sign = (alias, None, lift m ty) :: sign in
+ let sign = LocalAssum (alias, lift m ty) :: sign in
let avoid = id :: avoid in
let sign, i, avoid =
try
@@ -2078,14 +2087,14 @@ let constr_of_pat env evdref arsign pat avoid =
(lift 1 app) (* aliased term *)
in
let neq = eq_id avoid id in
- (Name neq, Some (mkRel 0), eq_t) :: sign, 2, neq :: avoid
+ LocalDef (Name neq, mkRel 0, eq_t) :: sign, 2, neq :: avoid
with Reduction.NotConvertible -> sign, 1, avoid
in
(* Mark the equality as a hole *)
pat', sign, lift i app, lift i apptype, realargs, n + i, avoid
in
- let pat', sign, patc, patty, args, z, avoid = typ env (pi3 (List.hd arsign), List.tl arsign) pat avoid in
- pat', (sign, patc, (pi3 (List.hd arsign), args), pat'), avoid
+ let pat', sign, patc, patty, args, z, avoid = typ env (get_type (List.hd arsign), List.tl arsign) pat avoid in
+ pat', (sign, patc, (get_type (List.hd arsign), args), pat'), avoid
(* shadows functional version *)
@@ -2100,23 +2109,23 @@ match kind_of_term t with
| Rel 0 -> true
| _ -> false
-let rels_of_patsign l =
- List.map (fun ((na, b, t) as x) ->
- match b with
- | Some t' when is_topvar t' -> (na, None, t)
- | _ -> x) l
+let rels_of_patsign =
+ List.map (fun decl ->
+ match decl with
+ | LocalDef (na,t',t) when is_topvar t' -> LocalAssum (na,t)
+ | _ -> decl)
let vars_of_ctx ctx =
let _, y =
- List.fold_right (fun (na, b, t) (prev, vars) ->
- match b with
- | Some t' when is_topvar t' ->
+ List.fold_right (fun decl (prev, vars) ->
+ match decl with
+ | LocalDef (na,t',t) when is_topvar t' ->
prev,
(GApp (Loc.ghost,
(GRef (Loc.ghost, delayed_force coq_eq_refl_ref, None)),
[hole; GVar (Loc.ghost, prev)])) :: vars
| _ ->
- match na with
+ match get_name decl with
Anonymous -> invalid_arg "vars_of_ctx"
| Name n -> n, GVar (Loc.ghost, n) :: vars)
ctx (Id.of_string "vars_of_ctx_error", [])
@@ -2225,7 +2234,7 @@ let constrs_of_pats typing_fun env evdref eqns tomatchs sign neqs arity =
match ineqs with
| None -> [], arity
| Some ineqs ->
- [Anonymous, None, ineqs], lift 1 arity
+ [LocalAssum (Anonymous, ineqs)], lift 1 arity
in
let eqs_rels, arity = decompose_prod_n_assum neqs arity in
eqs_rels @ neqs_rels @ rhs_rels', arity
@@ -2236,7 +2245,7 @@ let constrs_of_pats typing_fun env evdref eqns tomatchs sign neqs arity =
and btype = it_mkProd_or_LetIn j.uj_type rhs_rels' in
let _btype = evd_comb1 (Typing.type_of env) evdref bbody in
let branch_name = Id.of_string ("program_branch_" ^ (string_of_int !i)) in
- let branch_decl = (Name branch_name, Some (lift !i bbody), (lift !i btype)) in
+ let branch_decl = LocalDef (Name branch_name, lift !i bbody, lift !i btype) in
let branch =
let bref = GVar (Loc.ghost, branch_name) in
match vars_of_ctx rhs_rels with
@@ -2285,7 +2294,7 @@ let abstract_tomatch env tomatchs tycon =
(fun t -> subst_term (lift 1 c) (lift 1 t)) tycon in
let name = next_ident_away (Id.of_string "filtered_var") names in
(mkRel 1, lift_tomatch_type (succ lenctx) t) :: lift_ctx 1 prev,
- (Name name, Some (lift lenctx c), lift lenctx $ type_of_tomatch t) :: ctx,
+ LocalDef (Name name, lift lenctx c, lift lenctx $ type_of_tomatch t) :: ctx,
name :: names, tycon)
([], [], [], tycon) tomatchs
in List.rev prev, ctx, tycon
@@ -2293,7 +2302,7 @@ let abstract_tomatch env tomatchs tycon =
let build_dependent_signature env evdref avoid tomatchs arsign =
let avoid = ref avoid in
let arsign = List.rev arsign in
- let allnames = List.rev_map (List.map pi1) arsign in
+ let allnames = List.rev_map (List.map get_name) arsign in
let nar = List.fold_left (fun n names -> List.length names + n) 0 allnames in
let eqs, neqs, refls, slift, arsign' =
List.fold_left2
@@ -2309,11 +2318,15 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
(* Build the arity signature following the names in matched terms
as much as possible *)
let argsign = List.tl arsign in (* arguments in inverse application order *)
- let (appn, appb, appt) as _appsign = List.hd arsign in (* The matched argument *)
+ let app_decl = List.hd arsign in (* The matched argument *)
+ let appn = get_name app_decl in
+ let appt = get_type app_decl in
let argsign = List.rev argsign in (* arguments in application order *)
let env', nargeqs, argeqs, refl_args, slift, argsign' =
List.fold_left2
- (fun (env, nargeqs, argeqs, refl_args, slift, argsign') arg (name, b, t) ->
+ (fun (env, nargeqs, argeqs, refl_args, slift, argsign') arg decl ->
+ let name = get_name decl in
+ let t = get_type decl in
let argt = Retyping.get_type_of env !evdref arg in
let eq, refl_arg =
if Reductionops.is_conv env !evdref argt t then
@@ -2331,16 +2344,16 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
let previd, id =
let name =
match kind_of_term arg with
- Rel n -> pi1 (lookup_rel n env)
+ Rel n -> get_name (lookup_rel n env)
| _ -> name
in
make_prime avoid name
in
(env, succ nargeqs,
- (Name (eq_id avoid previd), None, eq) :: argeqs,
+ (LocalAssum (Name (eq_id avoid previd), eq)) :: argeqs,
refl_arg :: refl_args,
pred slift,
- (Name id, b, t) :: argsign'))
+ set_name (Name id) decl :: argsign'))
(env, neqs, [], [], slift, []) args argsign
in
let eq = mk_JMeq evdref
@@ -2351,22 +2364,23 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
in
let refl_eq = mk_JMeq_refl evdref ty tm in
let previd, id = make_prime avoid appn in
- (((Name (eq_id avoid previd), None, eq) :: argeqs) :: eqs,
+ ((LocalAssum (Name (eq_id avoid previd), eq) :: argeqs) :: eqs,
succ nargeqs,
refl_eq :: refl_args,
pred slift,
- (((Name id, appb, appt) :: argsign') :: arsigns))
+ ((set_name (Name id) app_decl :: argsign') :: arsigns))
| _ -> (* Non dependent inductive or not inductive, just use a regular equality *)
- let (name, b, typ) = match arsign with [x] -> x | _ -> assert(false) in
+ let decl = match arsign with [x] -> x | _ -> assert(false) in
+ let name = get_name decl in
let previd, id = make_prime avoid name in
- let arsign' = (Name id, b, typ) in
+ let arsign' = set_name (Name id) decl in
let tomatch_ty = type_of_tomatch ty in
let eq =
mk_eq evdref (lift nar tomatch_ty)
(mkRel slift) (lift nar tm)
in
- ([(Name (eq_id avoid previd), None, eq)] :: eqs, succ neqs,
+ ([LocalAssum (Name (eq_id avoid previd), eq)] :: eqs, succ neqs,
(mk_eq_refl evdref tomatch_ty tm) :: refl_args,
pred slift, (arsign' :: []) :: arsigns))
([], 0, [], nar, []) tomatchs arsign
@@ -2440,7 +2454,9 @@ let compile_program_cases loc style (typing_function, evdref) tycon env
(* We push the initial terms to match and push their alias to rhs' envs *)
(* names of aliases will be recovered from patterns (hence Anonymous here) *)
- let out_tmt na = function NotInd (c,t) -> (na,c,t) | IsInd (typ,_,_) -> (na,None,typ) in
+ let out_tmt na = function NotInd (None,t) -> LocalAssum (na,t)
+ | NotInd (Some b, t) -> LocalDef (na,b,t)
+ | IsInd (typ,_,_) -> LocalAssum (na,typ) in
let typs = List.map2 (fun na (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in
let typs =
@@ -2513,7 +2529,9 @@ let compile_cases loc style (typing_fun, evdref) tycon env (predopt, tomatchl, e
(* names of aliases will be recovered from patterns (hence Anonymous *)
(* here) *)
- let out_tmt na = function NotInd (c,t) -> (na,c,t) | IsInd (typ,_,_) -> (na,None,typ) in
+ let out_tmt na = function NotInd (None,t) -> LocalAssum (na,t)
+ | NotInd (Some b,t) -> LocalDef (na,b,t)
+ | IsInd (typ,_,_) -> LocalAssum (na,typ) in
let typs = List.map2 (fun na (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in
let typs =
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 489a311bc6..9d5a6006de 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -142,6 +142,7 @@ let mu env evdref t =
and coerce loc env evdref (x : Term.constr) (y : Term.constr)
: (Term.constr -> Term.constr) option
=
+ let open Context.Rel.Declaration in
let rec coerce_unify env x y =
let x = hnf env !evdref x and y = hnf env !evdref y in
try
@@ -151,8 +152,9 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
and coerce' env x y : (Term.constr -> Term.constr) option =
let subco () = subset_coerce env evdref x y in
let dest_prod c =
+ let open Context.Rel.Declaration in
match Reductionops.splay_prod_n env ( !evdref) 1 c with
- | [(na,b,t)], c -> (na,t), c
+ | [LocalAssum (na,t) | LocalDef (na,_,t)], c -> (na,t), c
| _ -> raise NoSubtacCoercion
in
let coerce_application typ typ' c c' l l' =
@@ -205,7 +207,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
let name' =
Name (Namegen.next_ident_away Namegen.default_dependent_ident (Termops.ids_of_context env))
in
- let env' = push_rel (name', None, a') env in
+ let env' = push_rel (LocalAssum (name', a')) env in
let c1 = coerce_unify env' (lift 1 a') (lift 1 a) in
(* env, x : a' |- c1 : lift 1 a' > lift 1 a *)
let coec1 = app_opt env' evdref c1 (mkRel 1) in
@@ -255,7 +257,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
| _ -> raise NoSubtacCoercion
in
let (pb, b), (pb', b') = remove_head a pb, remove_head a' pb' in
- let env' = push_rel (Name Namegen.default_dependent_ident, None, a) env in
+ let env' = push_rel (LocalAssum (Name Namegen.default_dependent_ident, a)) env in
let c2 = coerce_unify env' b b' in
match c1, c2 with
| None, None -> None
@@ -475,7 +477,8 @@ let rec inh_conv_coerce_to_fail loc env evd rigidonly v t c1 =
let name = match name with
| Anonymous -> Name Namegen.default_dependent_ident
| _ -> name in
- let env1 = push_rel (name,None,u1) env in
+ let open Context.Rel.Declaration in
+ let env1 = push_rel (LocalAssum (name,u1)) env in
let (evd', v1) =
inh_conv_coerce_to_fail loc env1 evd rigidonly
(Some (mkRel 1)) (lift 1 u1) (lift 1 t1) in
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 69c1dfb47a..4fb4112022 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -20,6 +20,7 @@ open Vars
open Pattern
open Patternops
open Misctypes
+open Context.Rel.Declaration
(*i*)
(* Given a term with second-order variables in it,
@@ -254,15 +255,15 @@ let matches_core env sigma convert allow_partial_app allow_bound_rels
sorec ctx env subst c1 c2
| PProd (na1,c1,d1), Prod(na2,c2,d2) ->
- sorec ((na1,na2,c2)::ctx) (Environ.push_rel (na2,None,c2) env)
+ sorec ((na1,na2,c2)::ctx) (Environ.push_rel (LocalAssum (na2,c2)) env)
(add_binders na1 na2 binding_vars (sorec ctx env subst c1 c2)) d1 d2
| PLambda (na1,c1,d1), Lambda(na2,c2,d2) ->
- sorec ((na1,na2,c2)::ctx) (Environ.push_rel (na2,None,c2) env)
+ sorec ((na1,na2,c2)::ctx) (Environ.push_rel (LocalAssum (na2,c2)) env)
(add_binders na1 na2 binding_vars (sorec ctx env subst c1 c2)) d1 d2
| PLetIn (na1,c1,d1), LetIn(na2,c2,t2,d2) ->
- sorec ((na1,na2,t2)::ctx) (Environ.push_rel (na2,Some c2,t2) env)
+ sorec ((na1,na2,t2)::ctx) (Environ.push_rel (LocalDef (na2,c2,t2)) env)
(add_binders na1 na2 binding_vars (sorec ctx env subst c1 c2)) d1 d2
| PIf (a1,b1,b1'), Case (ci,_,a2,[|b2;b2'|]) ->
@@ -271,7 +272,7 @@ let matches_core env sigma convert allow_partial_app allow_bound_rels
let n = Context.Rel.length ctx_b2 in
let n' = Context.Rel.length ctx_b2' in
if noccur_between 1 n b2 && noccur_between 1 n' b2' then
- let f l (na,_,t) = (Anonymous,na,t)::l in
+ let f l (LocalAssum (na,t) | LocalDef (na,_,t)) = (Anonymous,na,t)::l in
let ctx_br = List.fold_left f ctx ctx_b2 in
let ctx_br' = List.fold_left f ctx ctx_b2' in
let b1 = lift_pattern n b1 and b1' = lift_pattern n' b1' in
@@ -367,21 +368,21 @@ let sub_match ?(partial_app=false) ?(closed=true) env sigma pat c =
| [c1; c2] -> mk_ctx (mkLambda (x, c1, c2))
| _ -> assert false
in
- let env' = Environ.push_rel (x,None,c1) env in
+ let env' = Environ.push_rel (LocalAssum (x,c1)) env in
try_aux [(env, c1); (env', c2)] next_mk_ctx next
| Prod (x,c1,c2) ->
let next_mk_ctx = function
| [c1; c2] -> mk_ctx (mkProd (x, c1, c2))
| _ -> assert false
in
- let env' = Environ.push_rel (x,None,c1) env in
+ let env' = Environ.push_rel (LocalAssum (x,c1)) env in
try_aux [(env, c1); (env', c2)] next_mk_ctx next
| LetIn (x,c1,t,c2) ->
let next_mk_ctx = function
| [c1; c2] -> mk_ctx (mkLetIn (x, c1, t, c2))
| _ -> assert false
in
- let env' = Environ.push_rel (x,Some c1,t) env in
+ let env' = Environ.push_rel (LocalDef (x,c1,t)) env in
try_aux [(env, c1); (env', c2)] next_mk_ctx next
| App (c1,lc) ->
let topdown = true in
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index c8ecf91d33..67a8f01aa4 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -24,6 +24,7 @@ open Nametab
open Mod_subst
open Misctypes
open Decl_kinds
+open Context.Named.Declaration
let dl = Loc.ghost
@@ -33,8 +34,15 @@ let print_universes = Flags.univ_print
(** If true, prints local context of evars, whatever print_arguments *)
let print_evar_arguments = ref false
-let add_name na b t (nenv, env) = add_name na nenv, push_rel (na, b, t) env
-let add_name_opt na b t (nenv, env) =
+let add_name na b t (nenv, env) =
+ let open Context.Rel.Declaration in
+ add_name na nenv, push_rel (match b with
+ | None -> LocalAssum (na,t)
+ | Some b -> LocalDef (na,b,t)
+ )
+ env
+
+let add_name_opt na b t (nenv, env) =
match t with
| None -> Termops.add_name na nenv, env
| Some t -> add_name na b t (nenv, env)
@@ -510,11 +518,14 @@ let rec detype flags avoid env sigma t =
else noparams ()
| Evar (evk,cl) ->
- let bound_to_itself_or_letin (id,b,_) c =
- b != None ||
- try let n = List.index Name.equal (Name id) (fst env) in
- isRelN n c
- with Not_found -> isVarId id c in
+ let bound_to_itself_or_letin decl c =
+ match decl with
+ | LocalDef _ -> true
+ | LocalAssum (id,_) ->
+ try let n = List.index Name.equal (Name id) (fst env) in
+ isRelN n c
+ with Not_found -> isVarId id c
+ in
let id,l =
try
let id = Evd.evar_ident evk sigma in
@@ -684,17 +695,24 @@ let detype_rel_context ?(lax=false) where avoid env sigma sign =
let where = Option.map (fun c -> it_mkLambda_or_LetIn c sign) where in
let rec aux avoid env = function
| [] -> []
- | (na,b,t)::rest ->
+ | decl::rest ->
+ let open Context.Rel.Declaration in
+ let na = get_name decl in
+ let t = get_type decl in
let na',avoid' =
match where with
| None -> na,avoid
| Some c ->
- if b != None then
+ if is_local_def decl then
compute_displayed_let_name_in
(RenamingElsewhereFor (fst env,c)) avoid na c
else
compute_displayed_name_in
(RenamingElsewhereFor (fst env,c)) avoid na c in
+ let b = match decl with
+ | LocalAssum _ -> None
+ | LocalDef (_,b,_) -> Some b
+ in
let b' = Option.map (detype (lax,false) avoid env sigma) b in
let t' = detype (lax,false) avoid env sigma t in
(na',Explicit,b',t') :: aux avoid' (add_name na' b t env) rest
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 99e51330ef..020f998aa7 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -23,6 +23,7 @@ open Globnames
open Evd
open Pretype_errors
open Sigma.Notations
+open Context.Rel.Declaration
type unify_fun = transparent_state ->
env -> evar_map -> conv_pb -> constr -> constr -> Evarsolve.unification_result
@@ -55,12 +56,15 @@ let eval_flexible_term ts env evd c =
then constant_opt_value_in env cu
else None
| Rel n ->
- (try let (_,v,_) = lookup_rel n env in Option.map (lift n) v
- with Not_found -> None)
+ (try match lookup_rel n env with
+ | LocalAssum _ -> None
+ | LocalDef (_,v,_) -> Some (lift n v)
+ with Not_found -> None)
| Var id ->
(try
if is_transparent_variable ts id then
- let (_,v,_) = lookup_named id env in v
+ let open Context.Named.Declaration in
+ lookup_named id env |> get_value
else None
with Not_found -> None)
| LetIn (_,b,_,c) -> Some (subst1 b c)
@@ -394,7 +398,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
assert (match sk with [] -> true | _ -> false);
let (na,c1,c'1) = destLambda term in
let c = nf_evar evd c1 in
- let env' = push_rel (na,None,c) env in
+ let env' = push_rel (LocalAssum (na,c)) env in
let out1 = whd_betaiota_deltazeta_for_iota_state
(fst ts) env' evd Cst_stack.empty (c'1, Stack.empty) in
let out2 = whd_nored_state evd
@@ -561,7 +565,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let b = nf_evar i b1 in
let t = nf_evar i t1 in
let na = Nameops.name_max na1 na2 in
- evar_conv_x ts (push_rel (na,Some b,t) env) i pbty c'1 c'2);
+ evar_conv_x ts (push_rel (LocalDef (na,b,t)) env) i pbty c'1 c'2);
(fun i -> exact_ise_stack2 env i (evar_conv_x ts) sk1 sk2)]
and f2 i =
let out1 = whd_betaiota_deltazeta_for_iota_state (fst ts) env i csts1 (v1,sk1)
@@ -676,7 +680,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(fun i ->
let c = nf_evar i c1 in
let na = Nameops.name_max na1 na2 in
- evar_conv_x ts (push_rel (na,None,c) env) i CONV c'1 c'2)]
+ evar_conv_x ts (push_rel (LocalAssum (na,c)) env) i CONV c'1 c'2)]
| Flexible ev1, Rigid -> flex_rigid true ev1 appr1 appr2
| Rigid, Flexible ev2 -> flex_rigid false ev2 appr2 appr1
@@ -735,7 +739,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(fun i ->
let c = nf_evar i c1 in
let na = Nameops.name_max n1 n2 in
- evar_conv_x ts (push_rel (na,None,c) env) i pbty c'1 c'2)]
+ evar_conv_x ts (push_rel (LocalAssum (na,c)) env) i pbty c'1 c'2)]
| Rel x1, Rel x2 ->
if Int.equal x1 x2 then
@@ -912,6 +916,7 @@ let choose_less_dependent_instance evk evd term args =
| [] -> None
| (id, _) :: _ -> Some (Evd.define evk (mkVar id) evd)
+open Context.Named.Declaration
let apply_on_subterm env evdref f c t =
let rec applyrec (env,(k,c) as acc) t =
(* By using eq_constr, we make an approximation, for instance, we *)
@@ -922,7 +927,7 @@ let apply_on_subterm env evdref f c t =
match kind_of_term t with
| Evar (evk,args) when Evd.is_undefined !evdref evk ->
let ctx = evar_filtered_context (Evd.find_undefined !evdref evk) in
- let g (_,b,_) a = if Option.is_empty b then applyrec acc a else a in
+ let g decl a = if is_local_assum decl then applyrec acc a else a in
mkEvar (evk, Array.of_list (List.map2 g ctx (Array.to_list args)))
| _ ->
map_constr_with_binders_left_to_right
@@ -939,17 +944,17 @@ let filter_possible_projections c ty ctxt args =
let fv2 = collect_vars (mkApp (c,args)) in
let len = Array.length args in
let tyvars = collect_vars ty in
- List.map_i (fun i (id,b,_) ->
+ List.map_i (fun i decl ->
let () = assert (i < len) in
let a = Array.unsafe_get args i in
- (match b with None -> false | Some c -> not (isRel c || isVar c)) ||
+ (match decl with LocalAssum _ -> false | LocalDef (_,c,_) -> not (isRel c || isVar c)) ||
a == c ||
(* Here we make an approximation, for instance, we could also be *)
(* interested in finding a term u convertible to c such that a occurs *)
(* in u *)
isRel a && Int.Set.mem (destRel a) fv1 ||
isVar a && Id.Set.mem (destVar a) fv2 ||
- Id.Set.mem id tyvars)
+ Id.Set.mem (get_id decl) tyvars)
0 ctxt
let solve_evars = ref (fun _ -> failwith "solve_evars not installed")
@@ -980,17 +985,18 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
let env_evar = evar_filtered_env evi in
let sign = named_context_val env_evar in
let ctxt = evar_filtered_context evi in
- let instance = List.map mkVar (List.map pi1 ctxt) in
+ let instance = List.map mkVar (List.map get_id ctxt) in
let rec make_subst = function
- | (id,_,t)::ctxt', c::l, occs::occsl when isVarId id c ->
+ | decl'::ctxt', c::l, occs::occsl when isVarId (get_id decl') c ->
begin match occs with
| Some _ ->
error "Cannot force abstraction on identity instance."
| None ->
make_subst (ctxt',l,occsl)
end
- | (id,_,t)::ctxt', c::l, occs::occsl ->
+ | decl'::ctxt', c::l, occs::occsl ->
+ let (id,_,t) = to_tuple decl' in
let evs = ref [] in
let ty = Retyping.get_type_of env_rhs evd c in
let filter' = filter_possible_projections c ty ctxt args in
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 0dd0ad2e08..a65394e17b 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -19,6 +19,7 @@ open Retyping
open Reductionops
open Evarutil
open Pretype_errors
+open Context.Rel.Declaration
let normalize_evar evd ev =
match kind_of_term (whd_evar evd (mkEvar ev)) with
@@ -79,7 +80,7 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) pbty env evd t =
if !modified then
evdref := Evd.add !evdref ev {evi with evar_concl = ty'}
else ()
- | _ -> iter_constr (refresh_term_evars onevars false) t
+ | _ -> Constr.iter (refresh_term_evars onevars false) t
and refresh_polymorphic_positions args pos =
let rec aux i = function
| Some l :: ls ->
@@ -162,7 +163,8 @@ type 'a update =
| UpdateWith of 'a
| NoUpdate
-let inst_of_vars sign = Array.map_of_list (fun (id,_,_) -> mkVar id) sign
+open Context.Named.Declaration
+let inst_of_vars sign = Array.map_of_list (mkVar % get_id) sign
let restrict_evar_key evd evk filter candidates =
match filter, candidates with
@@ -205,6 +207,7 @@ let restrict_instance evd evk filter argsv =
let evi = Evd.find evd evk in
Filter.filter_array (Filter.compose (evar_filter evi) filter) argsv
+open Context.Rel.Declaration
let noccur_evar env evd evk c =
let cache = ref Int.Set.empty (* cache for let-ins *) in
let rec occur_rec (k, env as acc) c =
@@ -217,9 +220,9 @@ let noccur_evar env evd evk c =
else Array.iter (occur_rec acc) args')
| Rel i when i > k ->
if not (Int.Set.mem (i-k) !cache) then
- (match pi2 (Environ.lookup_rel i env) with
- | None -> ()
- | Some b -> cache := Int.Set.add (i-k) !cache; occur_rec acc (lift i b))
+ (match Environ.lookup_rel i env with
+ | LocalAssum _ -> ()
+ | LocalDef (_,b,_) -> cache := Int.Set.add (i-k) !cache; occur_rec acc (lift i b))
| Proj (p,c) ->
let c =
try Retyping.expand_projection env evd p c []
@@ -241,9 +244,11 @@ let noccur_evar env evd evk c =
variable in its family of aliased variables *)
let compute_var_aliases sign =
- List.fold_right (fun (id,b,c) aliases ->
- match b with
- | Some t ->
+ let open Context.Named.Declaration in
+ List.fold_right (fun decl aliases ->
+ let id = get_id decl in
+ match decl with
+ | LocalDef (_,t,_) ->
(match kind_of_term t with
| Var id' ->
let aliases_of_id =
@@ -251,27 +256,30 @@ let compute_var_aliases sign =
Id.Map.add id (aliases_of_id@[t]) aliases
| _ ->
Id.Map.add id [t] aliases)
- | None -> aliases)
+ | LocalAssum _ -> aliases)
sign Id.Map.empty
let compute_rel_aliases var_aliases rels =
- snd (List.fold_right (fun (_,b,u) (n,aliases) ->
- (n-1,
- match b with
- | Some t ->
- (match kind_of_term t with
- | Var id' ->
- let aliases_of_n =
- try Id.Map.find id' var_aliases with Not_found -> [] in
- Int.Map.add n (aliases_of_n@[t]) aliases
- | Rel p ->
- let aliases_of_n =
- try Int.Map.find (p+n) aliases with Not_found -> [] in
- Int.Map.add n (aliases_of_n@[mkRel (p+n)]) aliases
- | _ ->
- Int.Map.add n [lift n (mkCast(t,DEFAULTcast,u))] aliases)
- | None -> aliases))
- rels (List.length rels,Int.Map.empty))
+ snd (List.fold_right
+ (fun decl (n,aliases) ->
+ (n-1,
+ match decl with
+ | LocalDef (_,t,u) ->
+ (match kind_of_term t with
+ | Var id' ->
+ let aliases_of_n =
+ try Id.Map.find id' var_aliases with Not_found -> [] in
+ Int.Map.add n (aliases_of_n@[t]) aliases
+ | Rel p ->
+ let aliases_of_n =
+ try Int.Map.find (p+n) aliases with Not_found -> [] in
+ Int.Map.add n (aliases_of_n@[mkRel (p+n)]) aliases
+ | _ ->
+ Int.Map.add n [lift n (mkCast(t,DEFAULTcast,u))] aliases)
+ | LocalAssum _ -> aliases)
+ )
+ rels
+ (List.length rels,Int.Map.empty))
let make_alias_map env =
(* We compute the chain of aliases for each var and rel *)
@@ -305,13 +313,13 @@ let normalize_alias aliases x =
let normalize_alias_var var_aliases id =
destVar (normalize_alias (var_aliases,Int.Map.empty) (mkVar id))
-let extend_alias (_,b,_) (var_aliases,rel_aliases) =
+let extend_alias decl (var_aliases,rel_aliases) =
let rel_aliases =
Int.Map.fold (fun n l -> Int.Map.add (n+1) (List.map (lift 1) l))
rel_aliases Int.Map.empty in
let rel_aliases =
- match b with
- | Some t ->
+ match decl with
+ | LocalDef(_,t,_) ->
(match kind_of_term t with
| Var id' ->
let aliases_of_binder =
@@ -323,7 +331,7 @@ let extend_alias (_,b,_) (var_aliases,rel_aliases) =
Int.Map.add 1 (aliases_of_binder@[mkRel (p+1)]) rel_aliases
| _ ->
Int.Map.add 1 [lift 1 t] rel_aliases)
- | None -> rel_aliases in
+ | LocalAssum _ -> rel_aliases in
(var_aliases, rel_aliases)
let expand_alias_once aliases x =
@@ -429,16 +437,17 @@ let get_actual_deps aliases l t =
| Rel n -> Int.Set.mem n fv_rels
| _ -> assert false) l
+open Context.Named.Declaration
let remove_instance_local_defs evd evk args =
let evi = Evd.find evd evk in
let len = Array.length args in
let rec aux sign i = match sign with
| [] ->
let () = assert (i = len) in []
- | (_, None, _) :: sign ->
+ | LocalAssum _ :: sign ->
let () = assert (i < len) in
(Array.unsafe_get args i) :: aux sign (succ i)
- | (_, Some _, _) :: sign ->
+ | LocalDef _ :: sign ->
aux sign (succ i)
in
aux (evar_filtered_context evi) 0
@@ -500,7 +509,8 @@ let solve_pattern_eqn env l c =
match kind_of_term a with
(* Rem: if [a] links to a let-in, do as if it were an assumption *)
| Rel n ->
- let d = Context.Rel.Declaration.map (lift n) (lookup_rel n env) in
+ let open Context.Rel.Declaration in
+ let d = map_constr (lift n) (lookup_rel n env) in
mkLambda_or_LetIn d c'
| Var id ->
let d = lookup_named id env in mkNamedLambda_or_LetIn d c'
@@ -529,9 +539,9 @@ let make_projectable_subst aliases sigma evi args =
let evar_aliases = compute_var_aliases sign in
let (_,full_subst,cstr_subst) =
List.fold_right
- (fun (id,b,c) (args,all,cstrs) ->
- match b,args with
- | None, a::rest ->
+ (fun decl (args,all,cstrs) ->
+ match decl,args with
+ | LocalAssum (id,c), a::rest ->
let a = whd_evar sigma a in
let cstrs =
let a',args = decompose_app_vect a in
@@ -541,7 +551,7 @@ let make_projectable_subst aliases sigma evi args =
Constrmap.add (fst cstr) ((args,id)::l) cstrs
| _ -> cstrs in
(rest,Id.Map.add id [a,normalize_alias_opt aliases a,id] all,cstrs)
- | Some c, a::rest ->
+ | LocalDef (id,c,_), a::rest ->
let a = whd_evar sigma a in
(match kind_of_term c with
| Var id' ->
@@ -601,10 +611,12 @@ let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
let sign1 = evar_hyps evi1 in
let filter1 = evar_filter evi1 in
let src = subterm_source evk1 evi1.evar_source in
- let ids1 = List.map pi1 (named_context_of_val sign1) in
+ let ids1 = List.map get_id (named_context_of_val sign1) in
let inst_in_sign = List.map mkVar (Filter.filter_list filter1 ids1) in
+ let open Context.Rel.Declaration in
let (sign2,filter2,inst2_in_env,inst2_in_sign,_,evd,_) =
- List.fold_right (fun (na,b,t_in_env as d) (sign,filter,inst_in_env,inst_in_sign,env,evd,avoid) ->
+ List.fold_right (fun d (sign,filter,inst_in_env,inst_in_sign,env,evd,avoid) ->
+ let LocalAssum (na,t_in_env) | LocalDef (na,_,t_in_env) = d in
let id = next_name_away na avoid in
let evd,t_in_sign =
let s = Retyping.get_sort_of env evd t_in_env in
@@ -612,13 +624,13 @@ let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
~status:univ_flexible (Some false) env evd (mkSort s) in
define_evar_from_virtual_equation define_fun env evd src t_in_env
ty_t_in_sign sign filter inst_in_env in
- let evd,b_in_sign = match b with
- | None -> evd,None
- | Some b ->
+ let evd,b_in_sign = match d with
+ | LocalAssum _ -> evd,None
+ | LocalDef (_,b,_) ->
let evd,b = define_evar_from_virtual_equation define_fun env evd src b
t_in_sign sign filter inst_in_env in
evd,Some b in
- (push_named_context_val (id,b_in_sign,t_in_sign) sign, Filter.extend 1 filter,
+ (push_named_context_val (Context.Named.Declaration.of_tuple (id,b_in_sign,t_in_sign)) sign, Filter.extend 1 filter,
(mkRel 1)::(List.map (lift 1) inst_in_env),
(mkRel 1)::(List.map (lift 1) inst_in_sign),
push_rel d env,evd,id::avoid))
@@ -756,9 +768,10 @@ let project_with_effects aliases sigma effects t subst =
effects := p :: !effects;
c
+open Context.Named.Declaration
let rec find_solution_type evarenv = function
- | (id,ProjectVar)::l -> pi3 (lookup_named id evarenv)
- | [id,ProjectEvar _] -> (* bugged *) pi3 (lookup_named id evarenv)
+ | (id,ProjectVar)::l -> get_type (lookup_named id evarenv)
+ | [id,ProjectEvar _] -> (* bugged *) get_type (lookup_named id evarenv)
| (id,ProjectEvar _)::l -> find_solution_type evarenv l
| [] -> assert false
@@ -892,7 +905,7 @@ let invert_invertible_arg fullenv evd aliases k (evk,argsv) args' =
*)
let set_of_evctx l =
- List.fold_left (fun s (id,_,_) -> Id.Set.add id s) Id.Set.empty l
+ List.fold_left (fun s decl -> Id.Set.add (get_id decl) s) Id.Set.empty l
let filter_effective_candidates evi filter candidates =
match filter with
@@ -924,7 +937,13 @@ let closure_of_filter evd evk = function
| Some filter ->
let evi = Evd.find_undefined evd evk in
let vars = collect_vars (Evarutil.nf_evar evd (evar_concl evi)) in
- let test b (id,c,_) = b || Idset.mem id vars || match c with None -> false | Some c -> not (isRel c || isVar c) in
+ let test b decl = b || Idset.mem (get_id decl) vars ||
+ match decl with
+ | LocalAssum _ ->
+ false
+ | LocalDef (_,c,_) ->
+ not (isRel c || isVar c)
+ in
let newfilter = Filter.map_along test filter (evar_context evi) in
(* Now ensure that restriction is at least what is was originally *)
let newfilter = Option.cata (Filter.map_along (&&) newfilter) newfilter (Filter.repr (evar_filter evi)) in
@@ -1280,7 +1299,7 @@ let occur_evar_upto_types sigma n c =
seen := Evar.Set.add sp !seen;
Option.iter occur_rec (existential_opt_value sigma e);
occur_rec (existential_type sigma e))
- | _ -> iter_constr occur_rec c
+ | _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
@@ -1365,15 +1384,16 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
let t = whd_evar !evdref t in
match kind_of_term t with
| Rel i when i>k ->
- (match pi2 (Environ.lookup_rel (i-k) env') with
- | None -> project_variable (mkRel (i-k))
- | Some b ->
+ let open Context.Rel.Declaration in
+ (match Environ.lookup_rel (i-k) env' with
+ | LocalAssum _ -> project_variable (mkRel (i-k))
+ | LocalDef (_,b,_) ->
try project_variable (mkRel (i-k))
with NotInvertibleUsingOurAlgorithm _ -> imitate envk (lift i b))
| Var id ->
- (match pi2 (Environ.lookup_named id env') with
- | None -> project_variable t
- | Some b ->
+ (match Environ.lookup_named id env' with
+ | LocalAssum _ -> project_variable t
+ | LocalDef (_,b,_) ->
try project_variable t
with NotInvertibleUsingOurAlgorithm _ -> imitate envk b)
| LetIn (na,b,u,c) ->
@@ -1453,7 +1473,8 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
let names = ref Idset.empty in
let rec is_id_subst ctxt s =
match ctxt, s with
- | ((id, _, _) :: ctxt'), (c :: s') ->
+ | (decl :: ctxt'), (c :: s') ->
+ let id = get_id decl in
names := Idset.add id !names;
isVarId id c && is_id_subst ctxt' s'
| [], [] -> true
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index 8c210e2833..343d3ef903 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -76,13 +76,15 @@ let tj_nf_evar sigma {utj_val=v;utj_type=t} =
{utj_val=nf_evar sigma v;utj_type=t}
let env_nf_evar sigma env =
+ let open Context.Rel.Declaration in
process_rel_context
- (fun d e -> push_rel (Context.Rel.Declaration.map (nf_evar sigma) d) e) env
+ (fun d e -> push_rel (map_constr (nf_evar sigma) d) e) env
let env_nf_betaiotaevar sigma env =
+ let open Context.Rel.Declaration in
process_rel_context
(fun d e ->
- push_rel (Context.Rel.Declaration.map (Reductionops.nf_betaiota sigma) d) e) env
+ push_rel (map_constr (Reductionops.nf_betaiota sigma) d) e) env
let nf_evars_universes evm =
Universes.nf_evars_and_universes_opt_subst (Reductionops.safe_evar_value evm)
@@ -149,11 +151,16 @@ let is_ground_term evd t =
not (has_undefined_evars evd t)
let is_ground_env evd env =
- let is_ground_decl = function
- (_,Some b,_) -> is_ground_term evd b
+ let open Context.Rel.Declaration in
+ let is_ground_rel_decl = function
+ | LocalDef (_,b,_) -> is_ground_term evd b
| _ -> true in
- List.for_all is_ground_decl (rel_context env) &&
- List.for_all is_ground_decl (named_context env)
+ let open Context.Named.Declaration in
+ let is_ground_named_decl = function
+ | LocalDef (_,b,_) -> is_ground_term evd b
+ | _ -> true in
+ List.for_all is_ground_rel_decl (rel_context env) &&
+ List.for_all is_ground_named_decl (named_context env)
(* Memoization is safe since evar_map and environ are applicative
structures *)
@@ -231,10 +238,11 @@ let non_instantiated sigma =
(************************)
let make_pure_subst evi args =
+ let open Context.Named.Declaration in
snd (List.fold_right
- (fun (id,b,c) (args,l) ->
+ (fun decl (args,l) ->
match args with
- | a::rest -> (rest, (id,a)::l)
+ | a::rest -> (rest, (get_id decl, a)::l)
| _ -> anomaly (Pp.str "Instance does not match its signature"))
(evar_filtered_context evi) (Array.rev_to_list args,[]))
@@ -276,17 +284,15 @@ let subst2 subst vsubst c =
let push_rel_context_to_named_context env typ =
(* compute the instances relative to the named context and rel_context *)
- let ids = List.map pi1 (named_context env) in
+ let open Context.Named.Declaration in
+ let ids = List.map get_id (named_context env) in
let inst_vars = List.map mkVar ids in
let inst_rels = List.rev (rel_list 0 (nb_rel env)) in
- let replace_var_named_declaration id0 id (id',b,t) =
+ let replace_var_named_declaration id0 id decl =
+ let id' = get_id decl in
let id' = if Id.equal id0 id' then id else id' in
let vsubst = [id0 , mkVar id] in
- let b = match b with
- | None -> None
- | Some c -> Some (replace_vars vsubst c)
- in
- id', b, replace_vars vsubst t
+ decl |> set_id id' |> map_constr (replace_vars vsubst)
in
let replace_var_named_context id0 id env =
let nc = Environ.named_context env in
@@ -303,7 +309,12 @@ let push_rel_context_to_named_context env typ =
(* We do keep the instances corresponding to local definition (see above) *)
let (subst, vsubst, _, env) =
Context.Rel.fold_outside
- (fun (na,c,t) (subst, vsubst, avoid, env) ->
+ (fun decl (subst, vsubst, avoid, env) ->
+ let open Context.Rel.Declaration in
+ let na = get_name decl in
+ let c = get_value decl in
+ let t = get_type decl in
+ let open Context.Named.Declaration in
let id =
(* ppedrot: we want to infer nicer names for the refine tactic, but
keeping at the same time backward compatibility in other code
@@ -321,7 +332,10 @@ let push_rel_context_to_named_context env typ =
context. Unless [id] is a section variable. *)
let subst = List.map (replace_vars [id0,mkVar id]) subst in
let vsubst = (id0,mkVar id)::vsubst in
- let d = (id0, Option.map (subst2 subst vsubst) c, subst2 subst vsubst t) in
+ let d = match c with
+ | None -> LocalAssum (id0, subst2 subst vsubst t)
+ | Some c -> LocalDef (id0, subst2 subst vsubst c, subst2 subst vsubst t)
+ in
let env = replace_var_named_context id0 id env in
(mkVar id0 :: subst, vsubst, id::avoid, push_named d env)
| _ ->
@@ -329,7 +343,10 @@ let push_rel_context_to_named_context env typ =
incorrect. We revert to a less robust behaviour where
the new binder has name [id]. Which amounts to the same
behaviour than when [id=id0]. *)
- let d = (id,Option.map (subst2 subst vsubst) c,subst2 subst vsubst t) in
+ let d = match c with
+ | None -> LocalAssum (id, subst2 subst vsubst t)
+ | Some c -> LocalDef (id, subst2 subst vsubst c, subst2 subst vsubst t)
+ in
(mkVar id :: subst, vsubst, id::avoid, push_named d env)
)
(rel_context env) ~init:([], [], ids, env) in
@@ -477,7 +494,7 @@ let rec check_and_clear_in_constr env evdref err ids c =
let ctxt = Evd.evar_filtered_context evi in
let (rids,filter) =
List.fold_right2
- (fun (rid, ob,c as h) a (ri,filter) ->
+ (fun h a (ri,filter) ->
try
(* Check if some id to clear occurs in the instance
a of rid in ev and remember the dependency *)
@@ -493,7 +510,8 @@ let rec check_and_clear_in_constr env evdref err ids c =
let () = Id.Map.iter check ri in
(* No dependency at all, we can keep this ev's context hyp *)
(ri, true::filter)
- with Depends id -> (Id.Map.add rid id ri, false::filter))
+ with Depends id -> let open Context.Named.Declaration in
+ (Id.Map.add (get_id h) id ri, false::filter))
ctxt (Array.to_list l) (Id.Map.empty,[]) in
(* Check if some rid to clear in the context of ev has dependencies
in the type of ev and adjust the source of the dependency *)
@@ -528,11 +546,10 @@ let clear_hyps_in_evi_main env evdref hyps terms ids =
let terms =
List.map (check_and_clear_in_constr env evdref (OccurHypInSimpleClause None) ids) terms in
let nhyps =
- let check_context ((id,ob,c) as decl) =
- let err = OccurHypInSimpleClause (Some id) in
- let ob' = Option.smartmap (fun c -> check_and_clear_in_constr env evdref err ids c) ob in
- let c' = check_and_clear_in_constr env evdref err ids c in
- if ob == ob' && c == c' then decl else (id, ob', c')
+ let open Context.Named.Declaration in
+ let check_context decl =
+ let err = OccurHypInSimpleClause (Some (get_id decl)) in
+ map_constr (check_and_clear_in_constr env evdref err ids) decl
in
let check_value vk = match force_lazy_val vk with
| None -> vk
@@ -570,11 +587,12 @@ let process_dependent_evar q acc evm is_dependent e =
(* Queues evars appearing in the types of the goal (conclusion, then
hypotheses), they are all dependent. *)
queue_term q true evi.evar_concl;
- List.iter begin fun (_,b,t) ->
- queue_term q true t;
- match b with
- | None -> ()
- | Some b -> queue_term q true b
+ List.iter begin fun decl ->
+ let open Context.Named.Declaration in
+ queue_term q true (get_type decl);
+ match decl with
+ | LocalAssum _ -> ()
+ | LocalDef (_,b,_) -> queue_term q true b
end (Environ.named_context_of_val evi.evar_hyps);
match evi.evar_body with
| Evar_empty ->
@@ -625,11 +643,11 @@ let undefined_evars_of_term evd t =
evrec Evar.Set.empty t
let undefined_evars_of_named_context evd nc =
- List.fold_right (fun (_, b, t) s ->
- Option.fold_left (fun s t ->
- Evar.Set.union s (undefined_evars_of_term evd t))
- (Evar.Set.union s (undefined_evars_of_term evd t)) b)
- nc Evar.Set.empty
+ let open Context.Named.Declaration in
+ Context.Named.fold_outside
+ (fold (fun c s -> Evar.Set.union s (undefined_evars_of_term evd c)))
+ nc
+ ~init:Evar.Set.empty
let undefined_evars_of_evar_info evd evi =
Evar.Set.union (undefined_evars_of_term evd evi.evar_concl)
@@ -709,6 +727,7 @@ let idx = Namegen.default_dependent_ident
(* Refining an evar to a product *)
let define_pure_evar_as_product evd evk =
+ let open Context.Named.Declaration in
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
let id = next_ident_away idx (ids_of_named_context (evar_context evi)) in
@@ -717,7 +736,7 @@ let define_pure_evar_as_product evd evk =
let evd1,(dom,u1) =
new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi) in
let evd2,rng =
- let newenv = push_named (id, None, dom) evenv in
+ let newenv = push_named (LocalAssum (id, dom)) evenv in
let src = evar_source evk evd1 in
let filter = Filter.extend 1 (evar_filter evi) in
if is_prop_sort s then
@@ -756,6 +775,7 @@ let define_evar_as_product evd (evk,args) =
*)
let define_pure_evar_as_lambda env evd evk =
+ let open Context.Named.Declaration in
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
let typ = whd_betadeltaiota evenv evd (evar_concl evi) in
@@ -766,7 +786,7 @@ let define_pure_evar_as_lambda env evd evk =
let avoid = ids_of_named_context (evar_context evi) in
let id =
next_name_away_with_default_using_types "x" na avoid (whd_evar evd dom) in
- let newenv = push_named (id, None, dom) evenv in
+ let newenv = push_named (LocalAssum (id, dom)) evenv in
let filter = Filter.extend 1 (evar_filter evi) in
let src = evar_source evk evd1 in
let evd2,body = new_evar_unsafe newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
diff --git a/pretyping/find_subterm.ml b/pretyping/find_subterm.ml
index 6733b7fca0..ae8b91c346 100644
--- a/pretyping/find_subterm.ml
+++ b/pretyping/find_subterm.ml
@@ -59,19 +59,22 @@ let proceed_with_occurrences f occs x =
(** Applying a function over a named_declaration with an hypothesis
location request *)
-let map_named_declaration_with_hyploc f hyploc acc (id,bodyopt,typ) =
- let f = f (Some (id,hyploc)) in
- match bodyopt,hyploc with
- | None, InHypValueOnly ->
+let map_named_declaration_with_hyploc f hyploc acc decl =
+ let open Context.Named.Declaration in
+ let f = f (Some (get_id decl, hyploc)) in
+ match decl,hyploc with
+ | LocalAssum (id,_), InHypValueOnly ->
error_occurrences_error (IncorrectInValueOccurrence id)
- | None, _ | Some _, InHypTypeOnly ->
- let acc,typ = f acc typ in acc,(id,bodyopt,typ)
- | Some body, InHypValueOnly ->
- let acc,body = f acc body in acc,(id,Some body,typ)
- | Some body, InHyp ->
+ | LocalAssum (id,typ), _ ->
+ let acc,typ = f acc typ in acc, LocalAssum (id,typ)
+ | LocalDef (id,body,typ), InHypTypeOnly ->
+ let acc,typ = f acc typ in acc, LocalDef (id,body,typ)
+ | LocalDef (id,body,typ), InHypValueOnly ->
+ let acc,body = f acc body in acc, LocalDef (id,body,typ)
+ | LocalDef (id,body,typ), InHyp ->
let acc,body = f acc body in
let acc,typ = f acc typ in
- acc,(id,Some body,typ)
+ acc, LocalDef (id,body,typ)
(** Finding a subterm up to some testing function *)
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index fb45be6635..713c99597a 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -28,6 +28,7 @@ open Environ
open Reductionops
open Nametab
open Sigma.Notations
+open Context.Rel.Declaration
type dep_flag = bool
@@ -77,7 +78,6 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
(* mais pas très joli ... (mais manque get_sort_of à ce niveau) *)
let env' = push_rel_context lnamespar env in
-
let rec add_branch env k =
if Int.equal k (Array.length mip.mind_consnames) then
let nbprod = k+1 in
@@ -85,7 +85,7 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
let indf' = lift_inductive_family nbprod indf in
let arsign,_ = get_arity env indf' in
let depind = build_dependent_inductive env indf' in
- let deparsign = (Anonymous,None,depind)::arsign in
+ let deparsign = LocalAssum (Anonymous,depind)::arsign in
let ci = make_case_info env (fst pind) RegularStyle in
let pbody =
@@ -118,14 +118,14 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
let cs = lift_constructor (k+1) constrs.(k) in
let t = build_branch_type env dep (mkRel (k+1)) cs in
mkLambda_string "f" t
- (add_branch (push_rel (Anonymous, None, t) env) (k+1))
+ (add_branch (push_rel (LocalAssum (Anonymous, t)) env) (k+1))
in
let Sigma (s, sigma, p) = Sigma.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env sigma kind in
let typP = make_arity env' dep indf s in
let c =
it_mkLambda_or_LetIn_name env
(mkLambda_string "P" typP
- (add_branch (push_rel (Anonymous,None,typP) env') 0)) lnamespar
+ (add_branch (push_rel (LocalAssum (Anonymous,typP)) env') 0)) lnamespar
in
Sigma (c, sigma, p)
@@ -154,10 +154,10 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
let p',largs = whd_betadeltaiota_nolet_stack env sigma p in
match kind_of_term p' with
| Prod (n,t,c) ->
- let d = (n,None,t) in
+ let d = LocalAssum (n,t) in
make_prod env (n,t,prec (push_rel d env) (i+1) (d::sign) c)
| LetIn (n,b,t,c) when List.is_empty largs ->
- let d = (n,Some b,t) in
+ let d = LocalDef (n,b,t) in
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::sign) c)
| Ind (_,_) ->
let realargs = List.skipn nparams largs in
@@ -192,22 +192,22 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
| None ->
make_prod env
(n,t,
- process_constr (push_rel (n,None,t) env) (i+1) c_0 rest
+ process_constr (push_rel (LocalAssum (n,t)) env) (i+1) c_0 rest
(nhyps-1) (i::li))
| Some(dep',p) ->
let nP = lift (i+1+decP) p in
- let env' = push_rel (n,None,t) env in
+ let env' = push_rel (LocalAssum (n,t)) env in
let t_0 = process_pos env' dep' nP (lift 1 t) in
make_prod_dep (dep || dep') env
(n,t,
mkArrow t_0
(process_constr
- (push_rel (Anonymous,None,t_0) env')
+ (push_rel (LocalAssum (Anonymous,t_0)) env')
(i+2) (lift 1 c_0) rest (nhyps-1) (i::li))))
| LetIn (n,b,t,c_0) ->
mkLetIn (n,b,t,
process_constr
- (push_rel (n,Some b,t) env)
+ (push_rel (LocalDef (n,b,t)) env)
(i+1) c_0 recargs (nhyps-1) li)
| _ -> assert false
else
@@ -232,10 +232,10 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
let p',largs = whd_betadeltaiota_nolet_stack env sigma p in
match kind_of_term p' with
| Prod (n,t,c) ->
- let d = (n,None,t) in
+ let d = LocalAssum (n,t) in
mkLambda_name env (n,t,prec (push_rel d env) (i+1) (d::hyps) c)
| LetIn (n,b,t,c) when List.is_empty largs ->
- let d = (n,Some b,t) in
+ let d = LocalDef (n,b,t) in
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::hyps) c)
| Ind _ ->
let realargs = List.skipn nparrec largs
@@ -250,7 +250,7 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
in
(* ici, cstrprods est la liste des produits du constructeur instantié *)
let rec process_constr env i f = function
- | (n,None,t as d)::cprest, recarg::rest ->
+ | (LocalAssum (n,t) as d)::cprest, recarg::rest ->
let optionpos =
match dest_recarg recarg with
| Norec -> None
@@ -271,7 +271,7 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
(n,t,process_constr env' (i+1)
(whd_beta Evd.empty (applist (lift 1 f, [(mkRel 1); arg])))
(cprest,rest)))
- | (n,Some c,t as d)::cprest, rest ->
+ | (LocalDef (n,c,t) as d)::cprest, rest ->
mkLetIn
(n,c,t,
process_constr (push_rel d env) (i+1) (lift 1 f)
@@ -322,7 +322,7 @@ let mis_make_indrec env sigma listdepkind mib u =
let arsign,_ = get_arity env indf in
let depind = build_dependent_inductive env indf in
- let deparsign = (Anonymous,None,depind)::arsign in
+ let deparsign = LocalAssum (Anonymous,depind)::arsign in
let nonrecpar = Context.Rel.length lnonparrec in
let larsign = Context.Rel.length deparsign in
@@ -357,7 +357,7 @@ let mis_make_indrec env sigma listdepkind mib u =
let depind' = build_dependent_inductive env indf' in
let arsign',_ = get_arity env indf' in
- let deparsign' = (Anonymous,None,depind')::arsign' in
+ let deparsign' = LocalAssum (Anonymous,depind')::arsign' in
let pargs =
let nrpar = Context.Rel.to_extended_list (2*ndepar) lnonparrec
@@ -387,11 +387,13 @@ let mis_make_indrec env sigma listdepkind mib u =
let branch = branches.(0) in
let ctx, br = decompose_lam_assum branch in
let n, subst =
- List.fold_right (fun (na,b,t) (i, subst) ->
- if b == None then
- let t = mkProj (Projection.make ps.(i) true, mkRel 1) in
- (i + 1, t :: subst)
- else (i, mkRel 0 :: subst))
+ List.fold_right (fun decl (i, subst) ->
+ match decl with
+ | LocalAssum (na,t) ->
+ let t = mkProj (Projection.make ps.(i) true, mkRel 1) in
+ i + 1, t :: subst
+ | LocalDef (na,b,t) ->
+ i, mkRel 0 :: subst)
ctx (0, [])
in
let term = substl subst br in
@@ -440,7 +442,7 @@ let mis_make_indrec env sigma listdepkind mib u =
true dep env !evdref (vargs,depPvec,i+j) tyi cs recarg
in
mkLambda_string "f" p_0
- (onerec (push_rel (Anonymous,None,p_0) env) (j+1))
+ (onerec (push_rel (LocalAssum (Anonymous,p_0)) env) (j+1))
in onerec env 0
| [] ->
makefix i listdepkind
@@ -454,7 +456,7 @@ let mis_make_indrec env sigma listdepkind mib u =
in
let typP = make_arity env dep indf s in
mkLambda_string "P" typP
- (put_arity (push_rel (Anonymous,None,typP) env) (i+1) rest)
+ (put_arity (push_rel (LocalAssum (Anonymous,typP)) env) (i+1) rest)
| [] ->
make_branch env 0 listdepkind
in
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index bb38c72f25..80f1988a97 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -17,6 +17,7 @@ open Declarations
open Declareops
open Environ
open Reductionops
+open Context.Rel.Declaration
(* The following three functions are similar to the ones defined in
Inductive, but they expect an env *)
@@ -389,7 +390,7 @@ let make_arity_signature env dep indf =
if dep then
(* We need names everywhere *)
Namegen.name_context env
- ((Anonymous,None,build_dependent_inductive env indf)::arsign)
+ ((LocalAssum (Anonymous,build_dependent_inductive env indf))::arsign)
(* Costly: would be better to name once for all at definition time *)
else
(* No need to enforce names *)
@@ -459,7 +460,7 @@ let is_predicate_explicitly_dep env pred arsign =
let rec srec env pval arsign =
let pv' = whd_betadeltaiota env Evd.empty pval in
match kind_of_term pv', arsign with
- | Lambda (na,t,b), (_,None,_)::arsign ->
+ | Lambda (na,t,b), (LocalAssum _)::arsign ->
srec (push_rel_assum (na,t) env) b arsign
| Lambda (na,_,t), _ ->
@@ -539,11 +540,11 @@ let arity_of_case_predicate env (ind,params) dep k =
that appear in the type of the inductive by the sort of the
conclusion, and the other ones by fresh universes. *)
let rec instantiate_universes env evdref scl is = function
- | (_,Some _,_ as d)::sign, exp ->
+ | (LocalDef _ as d)::sign, exp ->
d :: instantiate_universes env evdref scl is (sign, exp)
| d::sign, None::exp ->
d :: instantiate_universes env evdref scl is (sign, exp)
- | (na,None,ty)::sign, Some l::exp ->
+ | (LocalAssum (na,ty))::sign, Some l::exp ->
let ctx,_ = Reduction.dest_arity env ty in
let u = Univ.Universe.make l in
let s =
@@ -557,7 +558,7 @@ let rec instantiate_universes env evdref scl is = function
let evm = Evd.set_leq_sort env evm s (Sorts.sort_of_univ u) in
evdref := evm; s
in
- (na,None,mkArity(ctx,s)):: instantiate_universes env evdref scl is (sign, exp)
+ (LocalAssum (na,mkArity(ctx,s))) :: instantiate_universes env evdref scl is (sign, exp)
| sign, [] -> sign (* Uniform parameters are exhausted *)
| [], _ -> assert false
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 6d09d56985..8ddfeaf2f0 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -19,6 +19,7 @@ open Util
open Nativecode
open Nativevalues
open Nativelambda
+open Context.Rel.Declaration
(** This module implements normalization by evaluation to OCaml code *)
@@ -121,9 +122,8 @@ let build_case_type dep p realargs c =
else mkApp(p, realargs)
(* TODO move this function *)
-let type_of_rel env n =
- let (_,_,ty) = lookup_rel n env in
- lift n ty
+let type_of_rel env n =
+ lookup_rel n env |> get_type |> lift n
let type_of_prop = mkSort type1_sort
@@ -132,8 +132,9 @@ let type_of_sort s =
| Prop _ -> type_of_prop
| Type u -> mkType (Univ.super u)
-let type_of_var env id =
- try let (_,_,ty) = lookup_named id env in ty
+let type_of_var env id =
+ let open Context.Named.Declaration in
+ try lookup_named id env |> get_type
with Not_found ->
anomaly ~label:"type_of_var" (str "variable " ++ Id.print id ++ str " unbound")
@@ -181,7 +182,7 @@ let rec nf_val env v typ =
Errors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
- let env = push_rel (name,None,dom) env in
+ let env = push_rel (LocalAssum (name,dom)) env in
let body = nf_val env (f (mk_rel_accu lvl)) codom in
mkLambda(name,dom,body)
| Vconst n -> construct_of_constr_const env n typ
@@ -257,7 +258,7 @@ and nf_atom env atom =
| Aprod(n,dom,codom) ->
let dom = nf_type env dom in
let vn = mk_rel_accu (nb_rel env) in
- let env = push_rel (n,None,dom) env in
+ let env = push_rel (LocalAssum (n,dom)) env in
let codom = nf_type env (codom vn) in
mkProd(n,dom,codom)
| Ameta (mv,_) -> mkMeta mv
@@ -328,7 +329,7 @@ and nf_atom_type env atom =
| Aprod(n,dom,codom) ->
let dom,s1 = nf_type_sort env dom in
let vn = mk_rel_accu (nb_rel env) in
- let env = push_rel (n,None,dom) env in
+ let env = push_rel (LocalAssum (n,dom)) env in
let codom,s2 = nf_type_sort env (codom vn) in
mkProd(n,dom,codom), mkSort (sort_of_product env s1 s2)
| Aevar(ev,ty) ->
@@ -356,7 +357,7 @@ and nf_predicate env ind mip params v pT =
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let dep,body =
- nf_predicate (push_rel (name,None,dom) env) ind mip params vb codom in
+ nf_predicate (push_rel (LocalAssum (name,dom)) env) ind mip params vb codom in
dep, mkLambda(name,dom,body)
| Vfun f, _ ->
let k = nb_rel env in
@@ -366,7 +367,7 @@ and nf_predicate env ind mip params v pT =
let rargs = Array.init n (fun i -> mkRel (n-i)) in
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
- let body = nf_type (push_rel (name,None,dom) env) vb in
+ let body = nf_type (push_rel (LocalAssum (name,dom)) env) vb in
true, mkLambda(name,dom,body)
| _, _ -> false, nf_type env v
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index af46c390a6..827071054a 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -123,6 +123,7 @@ let head_of_constr_reference c = match kind_of_term c with
let pattern_of_constr env sigma t =
let rec pattern_of_constr env t =
+ let open Context.Rel.Declaration in
match kind_of_term t with
| Rel n -> PRel n
| Meta n -> PMeta (Some (Id.of_string ("META" ^ string_of_int n)))
@@ -132,11 +133,11 @@ let pattern_of_constr env sigma t =
| Sort (Type _) -> PSort (GType [])
| Cast (c,_,_) -> pattern_of_constr env c
| LetIn (na,c,t,b) -> PLetIn (na,pattern_of_constr env c,
- pattern_of_constr (push_rel (na,Some c,t) env) b)
+ pattern_of_constr (push_rel (LocalDef (na,c,t)) env) b)
| Prod (na,c,b) -> PProd (na,pattern_of_constr env c,
- pattern_of_constr (push_rel (na, None, c) env) b)
+ pattern_of_constr (push_rel (LocalAssum (na, c)) env) b)
| Lambda (na,c,b) -> PLambda (na,pattern_of_constr env c,
- pattern_of_constr (push_rel (na, None, c) env) b)
+ pattern_of_constr (push_rel (LocalAssum (na, c)) env) b)
| App (f,a) ->
(match
match kind_of_term f with
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 11fba7b941..7c91b1a934 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -42,6 +42,7 @@ open Glob_ops
open Evarconv
open Pattern
open Misctypes
+open Context.Named.Declaration
type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = constr_under_binders Id.Map.t
@@ -319,7 +320,7 @@ let ltac_interp_name_env k0 lvar env =
let n = Context.Rel.length (rel_context env) - k0 in
let ctxt,_ = List.chop n (rel_context env) in
let env = pop_rel_context n env in
- let ctxt = List.map (fun (na,c,t) -> ltac_interp_name lvar na,c,t) ctxt in
+ let ctxt = List.map (Context.Rel.Declaration.map_name (ltac_interp_name lvar)) ctxt in
push_rel_context ctxt env
let invert_ltac_bound_name lvar env id0 id =
@@ -372,8 +373,7 @@ let pretype_id pretype k0 loc env evdref lvar id =
str "Variable " ++ pr_id id ++ str " should be bound to a term.");
(* Check if [id] is a section or goal variable *)
try
- let (_,_,typ) = lookup_named id env in
- { uj_val = mkVar id; uj_type = typ }
+ { uj_val = mkVar id; uj_type = (get_type (lookup_named id env)) }
with Not_found ->
(* [id] not found, standard error message *)
error_var_not_found_loc loc id
@@ -418,8 +418,7 @@ let pretype_ref loc evdref env ref us =
match ref with
| VarRef id ->
(* Section variable *)
- (try let (_,_,ty) = lookup_named id env in
- make_judge (mkVar id) ty
+ (try make_judge (mkVar id) (get_type (lookup_named id env))
with Not_found ->
(* This may happen if env is a goal env and section variables have
been cleared - section variables should be different from goal
@@ -459,6 +458,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let inh_conv_coerce_to_tycon = inh_conv_coerce_to_tycon resolve_tc in
let pretype_type = pretype_type k0 resolve_tc in
let pretype = pretype k0 resolve_tc in
+ let open Context.Rel.Declaration in
match t with
| GRef (loc,ref,u) ->
inh_conv_coerce_to_tycon loc env evdref
@@ -518,14 +518,14 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
[] -> ctxt
| (na,bk,None,ty)::bl ->
let ty' = pretype_type empty_valcon env evdref lvar ty in
- let dcl = (na,None,ty'.utj_val) in
- let dcl' = (ltac_interp_name lvar na,None,ty'.utj_val) in
+ let dcl = LocalAssum (na, ty'.utj_val) in
+ let dcl' = LocalAssum (ltac_interp_name lvar na,ty'.utj_val) in
type_bl (push_rel dcl env) (Context.Rel.add dcl' ctxt) bl
| (na,bk,Some bd,ty)::bl ->
let ty' = pretype_type empty_valcon env evdref lvar ty in
let bd' = pretype (mk_tycon ty'.utj_val) env evdref lvar bd in
- let dcl = (na,Some bd'.uj_val,ty'.utj_val) in
- let dcl' = (ltac_interp_name lvar na,Some bd'.uj_val,ty'.utj_val) in
+ let dcl = LocalDef (na, bd'.uj_val, ty'.utj_val) in
+ let dcl' = LocalDef (ltac_interp_name lvar na, bd'.uj_val, ty'.utj_val) in
type_bl (push_rel dcl env) (Context.Rel.add dcl' ctxt) bl in
let ctxtv = Array.map (type_bl env Context.Rel.empty) bl in
let larj =
@@ -694,7 +694,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
(* The name specified by ltac is used also to create bindings. So
the substitution must also be applied on variables before they are
looked up in the rel context. *)
- let var = (name,None,j.utj_val) in
+ let var = LocalAssum (name, j.utj_val) in
let j' = pretype rng (push_rel var env) evdref lvar c2 in
let name = ltac_interp_name lvar name in
let resj = judge_of_abstraction env (orelse_name name name') j j' in
@@ -738,7 +738,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
(* The name specified by ltac is used also to create bindings. So
the substitution must also be applied on variables before they are
looked up in the rel context. *)
- let var = (name,Some j.uj_val,t) in
+ let var = LocalDef (name, j.uj_val, t) in
let tycon = lift_tycon 1 tycon in
let j' = pretype tycon (push_rel var env) evdref lvar c2 in
let name = ltac_interp_name lvar name in
@@ -763,17 +763,17 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
int cs.cs_nargs ++ str " variables.");
let fsign, record =
match get_projections env indf with
- | None -> List.map2 (fun na (_,c,t) -> (na,c,t))
- (List.rev nal) cs.cs_args, false
+ | None ->
+ List.map2 set_name (List.rev nal) cs.cs_args, false
| Some ps ->
let rec aux n k names l =
match names, l with
- | na :: names, ((_, None, t) :: l) ->
+ | na :: names, (LocalAssum (_,t) :: l) ->
let proj = Projection.make ps.(cs.cs_nargs - k) true in
- (na, Some (lift (cs.cs_nargs - n) (mkProj (proj, cj.uj_val))), t)
+ LocalDef (na, lift (cs.cs_nargs - n) (mkProj (proj, cj.uj_val)), t)
:: aux (n+1) (k + 1) names l
- | na :: names, ((_, c, t) :: l) ->
- (na, c, t) :: aux (n+1) k names l
+ | na :: names, (decl :: l) ->
+ set_name na decl :: aux (n+1) k names l
| [], [] -> []
| _ -> assert false
in aux 1 1 (List.rev nal) cs.cs_args, true in
@@ -781,7 +781,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
if not record then
let nal = List.map (fun na -> ltac_interp_name lvar na) nal in
let nal = List.rev nal in
- let fsign = List.map2 (fun na (_,b,t) -> (na,b,t)) nal fsign in
+ let fsign = List.map2 set_name nal fsign in
let f = it_mkLambda_or_LetIn f fsign in
let ci = make_case_info env (fst ind) LetStyle in
mkCase (ci, p, cj.uj_val,[|f|])
@@ -792,10 +792,10 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let arsgn =
let arsgn,_ = get_arity env indf in
if not !allow_anonymous_refs then
- List.map (fun (_,b,t) -> (Anonymous,b,t)) arsgn
+ List.map (set_name Anonymous) arsgn
else arsgn
in
- let psign = (na,None,build_dependent_inductive env indf)::arsgn in
+ let psign = LocalAssum (na, build_dependent_inductive env indf) :: arsgn in
let nar = List.length arsgn in
(match po with
| Some p ->
@@ -851,11 +851,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let arsgn,_ = get_arity env indf in
if not !allow_anonymous_refs then
(* Make dependencies from arity signature impossible *)
- List.map (fun (_,b,t) -> (Anonymous,b,t)) arsgn
+ List.map (set_name Anonymous) arsgn
else arsgn
in
let nar = List.length arsgn in
- let psign = (na,None,build_dependent_inductive env indf)::arsgn in
+ let psign = LocalAssum (na, build_dependent_inductive env indf) :: arsgn in
let pred,p = match po with
| Some p ->
let env_p = push_rel_context psign env in
@@ -880,14 +880,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let pi = beta_applist (pi, [build_dependent_constructor cs]) in
let csgn =
if not !allow_anonymous_refs then
- List.map (fun (_,b,t) -> (Anonymous,b,t)) cs.cs_args
+ List.map (set_name Anonymous) cs.cs_args
else
- List.map
- (fun (n, b, t) ->
- match n with
- Name _ -> (n, b, t)
- | Anonymous -> (Name Namegen.default_non_dependent_ident, b, t))
- cs.cs_args
+ List.map (map_name (function Name _ as n -> n
+ | Anonymous -> Name Namegen.default_non_dependent_ident))
+ cs.cs_args
in
let env_c = push_rel_context csgn env in
let bj = pretype (mk_tycon pi) env_c evdref lvar b in
@@ -949,8 +946,9 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
in inh_conv_coerce_to_tycon loc env evdref cj tycon
and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
- let f (id,_,t) (subst,update) =
- let t = replace_vars subst t in
+ let f decl (subst,update) =
+ let id = get_id decl in
+ let t = replace_vars subst (get_type decl) in
let c, update =
try
let c = List.assoc id update in
@@ -962,7 +960,7 @@ and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
if is_conv env !evdref t t' then mkRel n, update else raise Not_found
with Not_found ->
try
- let (_,_,t') = lookup_named id env in
+ let t' = lookup_named id env |> get_type in
if is_conv env !evdref t t' then mkVar id, update else raise Not_found
with Not_found ->
user_err_loc (loc,"",str "Cannot interpret " ++
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 5e21154a67..d7637d1c27 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -15,6 +15,7 @@ open Termops
open Univ
open Evd
open Environ
+open Context.Rel.Declaration
exception Elimconst
@@ -607,7 +608,7 @@ let strong whdfun env sigma t =
strongrec env t
let local_strong whdfun sigma =
- let rec strongrec t = map_constr strongrec (whdfun sigma t) in
+ let rec strongrec t = Constr.map strongrec (whdfun sigma t) in
strongrec
let rec strong_prodspine redfun sigma c =
@@ -799,6 +800,7 @@ let equal_stacks (x, l) (y, l') =
| Some (lft1,lft2) -> f_equal (x, lft1) (y, lft2)
let rec whd_state_gen ?csts tactic_mode flags env sigma =
+ let open Context.Named.Declaration in
let rec whrec cst_l (x, stack as s) =
let () = if !debug_RAKAM then
let open Pp in
@@ -815,11 +817,11 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
match kind_of_term x with
| Rel n when Closure.RedFlags.red_set flags Closure.RedFlags.fDELTA ->
(match lookup_rel n env with
- | (_,Some body,_) -> whrec Cst_stack.empty (lift n body, stack)
+ | LocalDef (_,body,_) -> whrec Cst_stack.empty (lift n body, stack)
| _ -> fold ())
| Var id when Closure.RedFlags.red_set flags (Closure.RedFlags.fVAR id) ->
(match lookup_named id env with
- | (_,Some body,_) -> whrec (Cst_stack.add_cst (mkVar id) cst_l) (body, stack)
+ | LocalDef (_,body,_) -> whrec (Cst_stack.add_cst (mkVar id) cst_l) (body, stack)
| _ -> fold ())
| Evar ev ->
(match safe_evar_value sigma ev with
@@ -922,7 +924,7 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
| Some _ when Closure.RedFlags.red_set flags Closure.RedFlags.fBETA ->
apply_subst whrec [] cst_l x stack
| None when Closure.RedFlags.red_set flags Closure.RedFlags.fETA ->
- let env' = push_rel (na,None,t) env in
+ let env' = push_rel (LocalAssum (na,t)) env in
let whrec' = whd_state_gen tactic_mode flags env' sigma in
(match kind_of_term (Stack.zip ~refold:true (fst (whrec' (c, Stack.empty)))) with
| App (f,cl) ->
@@ -1442,7 +1444,7 @@ let splay_prod env sigma =
let t = whd_betadeltaiota env sigma c in
match kind_of_term t with
| Prod (n,a,c0) ->
- decrec (push_rel (n,None,a) env)
+ decrec (push_rel (LocalAssum (n,a)) env)
((n,a)::m) c0
| _ -> m,t
in
@@ -1453,7 +1455,7 @@ let splay_lam env sigma =
let t = whd_betadeltaiota env sigma c in
match kind_of_term t with
| Lambda (n,a,c0) ->
- decrec (push_rel (n,None,a) env)
+ decrec (push_rel (LocalAssum (n,a)) env)
((n,a)::m) c0
| _ -> m,t
in
@@ -1464,11 +1466,11 @@ let splay_prod_assum env sigma =
let t = whd_betadeltaiota_nolet env sigma c in
match kind_of_term t with
| Prod (x,t,c) ->
- prodec_rec (push_rel (x,None,t) env)
- (Context.Rel.add (x, None, t) l) c
+ prodec_rec (push_rel (LocalAssum (x,t)) env)
+ (Context.Rel.add (LocalAssum (x,t)) l) c
| LetIn (x,b,t,c) ->
- prodec_rec (push_rel (x, Some b, t) env)
- (Context.Rel.add (x, Some b, t) l) c
+ prodec_rec (push_rel (LocalDef (x,b,t)) env)
+ (Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
let t' = whd_betadeltaiota env sigma t in
@@ -1489,8 +1491,8 @@ let splay_prod_n env sigma n =
let rec decrec env m ln c = if Int.equal m 0 then (ln,c) else
match kind_of_term (whd_betadeltaiota env sigma c) with
| Prod (n,a,c0) ->
- decrec (push_rel (n,None,a) env)
- (m-1) (Context.Rel.add (n,None,a) ln) c0
+ decrec (push_rel (LocalAssum (n,a)) env)
+ (m-1) (Context.Rel.add (LocalAssum (n,a)) ln) c0
| _ -> invalid_arg "splay_prod_n"
in
decrec env n Context.Rel.empty
@@ -1499,8 +1501,8 @@ let splay_lam_n env sigma n =
let rec decrec env m ln c = if Int.equal m 0 then (ln,c) else
match kind_of_term (whd_betadeltaiota env sigma c) with
| Lambda (n,a,c0) ->
- decrec (push_rel (n,None,a) env)
- (m-1) (Context.Rel.add (n,None,a) ln) c0
+ decrec (push_rel (LocalAssum (n,a)) env)
+ (m-1) (Context.Rel.add (LocalAssum (n,a)) ln) c0
| _ -> invalid_arg "splay_lam_n"
in
decrec env n Context.Rel.empty
@@ -1538,8 +1540,8 @@ let find_conclusion env sigma =
let rec decrec env c =
let t = whd_betadeltaiota env sigma c in
match kind_of_term t with
- | Prod (x,t,c0) -> decrec (push_rel (x,None,t) env) c0
- | Lambda (x,t,c0) -> decrec (push_rel (x,None,t) env) c0
+ | Prod (x,t,c0) -> decrec (push_rel (LocalAssum (x,t)) env) c0
+ | Lambda (x,t,c0) -> decrec (push_rel (LocalAssum (x,t)) env) c0
| t -> t
in
decrec env
@@ -1623,7 +1625,7 @@ let meta_reducible_instance evd b =
with
| Some g -> irec (mkProj (p,g))
| None -> mkProj (p,c))
- | _ -> map_constr irec u
+ | _ -> Constr.map irec u
in
if Metaset.is_empty fm then (* nf_betaiota? *) b.rebus
else irec b.rebus
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index cb4e588eea..1a6f7832aa 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -18,6 +18,7 @@ open Reductionops
open Environ
open Termops
open Arguments_renaming
+open Context.Rel.Declaration
type retype_error =
| NotASort
@@ -71,13 +72,14 @@ let rec subst_type env sigma typ = function
let sort_of_atomic_type env sigma ft args =
let rec concl_of_arity env n ar args =
match kind_of_term (whd_betadeltaiota env sigma ar), args with
- | Prod (na, t, b), h::l -> concl_of_arity (push_rel (na,Some (lift n h),t) env) (n + 1) b l
+ | Prod (na, t, b), h::l -> concl_of_arity (push_rel (LocalDef (na, lift n h, t)) env) (n + 1) b l
| Sort s, [] -> s
| _ -> retype_error NotASort
in concl_of_arity env 0 ft (Array.to_list args)
let type_of_var env id =
- try let (_,_,ty) = lookup_named id env in ty
+ let open Context.Named.Declaration in
+ try get_type (lookup_named id env)
with Not_found -> retype_error (BadVariable id)
let decomp_sort env sigma t =
@@ -86,13 +88,13 @@ let decomp_sort env sigma t =
| _ -> retype_error NotASort
let retype ?(polyprop=true) sigma =
- let rec type_of env cstr=
+ let rec type_of env cstr =
match kind_of_term cstr with
| Meta n ->
(try strip_outer_cast (Evd.meta_ftype sigma n).Evd.rebus
with Not_found -> retype_error (BadMeta n))
| Rel n ->
- let (_,_,ty) = lookup_rel n env in
+ let ty = get_type (lookup_rel n env) in
lift n ty
| Var id -> type_of_var env id
| Const cst -> rename_type_of_constant env cst
@@ -115,9 +117,9 @@ let retype ?(polyprop=true) sigma =
| Prod _ -> whd_beta sigma (applist (t, [c]))
| _ -> t)
| Lambda (name,c1,c2) ->
- mkProd (name, c1, type_of (push_rel (name,None,c1) env) c2)
+ mkProd (name, c1, type_of (push_rel (LocalAssum (name,c1)) env) c2)
| LetIn (name,b,c1,c2) ->
- subst1 b (type_of (push_rel (name,Some b,c1) env) c2)
+ subst1 b (type_of (push_rel (LocalDef (name,b,c1)) env) c2)
| Fix ((_,i),(_,tys,_)) -> tys.(i)
| CoFix (i,(_,tys,_)) -> tys.(i)
| App(f,args) when is_template_polymorphic env f ->
@@ -140,7 +142,7 @@ let retype ?(polyprop=true) sigma =
| Sort (Prop c) -> type1_sort
| Sort (Type u) -> Type (Univ.super u)
| Prod (name,t,c2) ->
- (match (sort_of env t, sort_of (push_rel (name,None,t) env) c2) with
+ (match (sort_of env t, sort_of (push_rel (LocalAssum (name,t)) env) c2) with
| _, (Prop Null as s) -> s
| Prop _, (Prop Pos as s) -> s
| Type _, (Prop Pos as s) when is_impredicative_set env -> s
@@ -161,7 +163,7 @@ let retype ?(polyprop=true) sigma =
| Sort (Prop c) -> InType
| Sort (Type u) -> InType
| Prod (name,t,c2) ->
- let s2 = sort_family_of (push_rel (name,None,t) env) c2 in
+ let s2 = sort_family_of (push_rel (LocalAssum (name,t)) env) c2 in
if not (is_impredicative_set env) &&
s2 == InSet && sort_family_of env t == InType then InType else s2
| App(f,args) when is_template_polymorphic env f ->
@@ -235,9 +237,9 @@ let get_judgment_of env evc c = { uj_val = c; uj_type = get_type_of env evc c }
let sorts_of_context env evc ctxt =
let rec aux = function
| [] -> env,[]
- | (_,_,t as d)::ctxt ->
+ | d :: ctxt ->
let env,sorts = aux ctxt in
- let s = get_sort_of env evc t in
+ let s = get_sort_of env evc (get_type d) in
(push_rel d env,s::sorts) in
snd (aux ctxt)
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index bd46911c92..ae224cf0d4 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -53,12 +53,13 @@ let is_evaluable env = function
| EvalVarRef id -> is_evaluable_var env id
let value_of_evaluable_ref env evref u =
+ let open Context.Named.Declaration in
match evref with
| EvalConstRef con ->
(try constant_value_in env (con,u)
with NotEvaluableConst IsProj ->
raise (Invalid_argument "value_of_evaluable_ref"))
- | EvalVarRef id -> Option.get (pi2 (lookup_named id env))
+ | EvalVarRef id -> lookup_named id env |> get_value |> Option.get
let evaluable_of_global_reference env = function
| ConstRef cst when is_evaluable_const env cst -> EvalConstRef cst
@@ -103,29 +104,29 @@ let destEvalRefU c = match kind_of_term c with
| Evar ev -> (EvalEvar ev, Univ.Instance.empty)
| _ -> anomaly (Pp.str "Not an unfoldable reference")
-let unsafe_reference_opt_value env sigma eval =
+let unsafe_reference_opt_value env sigma eval =
match eval with
| EvalConst cst ->
(match (lookup_constant cst env).Declarations.const_body with
| Declarations.Def c -> Some (Mod_subst.force_constr c)
| _ -> None)
| EvalVar id ->
- let (_,v,_) = lookup_named id env in
- v
+ let open Context.Named.Declaration in
+ lookup_named id env |> get_value
| EvalRel n ->
- let (_,v,_) = lookup_rel n env in
- Option.map (lift n) v
+ let open Context.Rel.Declaration in
+ lookup_rel n env |> map_value (lift n) |> get_value
| EvalEvar ev -> Evd.existential_opt_value sigma ev
let reference_opt_value env sigma eval u =
match eval with
| EvalConst cst -> constant_opt_value_in env (cst,u)
| EvalVar id ->
- let (_,v,_) = lookup_named id env in
- v
+ let open Context.Named.Declaration in
+ lookup_named id env |> get_value
| EvalRel n ->
- let (_,v,_) = lookup_rel n env in
- Option.map (lift n) v
+ let open Context.Rel.Declaration in
+ lookup_rel n env |> map_value (lift n) |> get_value
| EvalEvar ev -> Evd.existential_opt_value sigma ev
exception NotEvaluable
@@ -258,7 +259,8 @@ let compute_consteval_direct env sigma ref =
let c',l = whd_betadelta_stack env sigma c in
match kind_of_term c' with
| Lambda (id,t,g) when List.is_empty l && not onlyproj ->
- srec (push_rel (id,None,t) env) (n+1) (t::labs) onlyproj g
+ let open Context.Rel.Declaration in
+ srec (push_rel (LocalAssum (id,t)) env) (n+1) (t::labs) onlyproj g
| Fix fix when not onlyproj ->
(try check_fix_reversibility labs l fix
with Elimconst -> NotAnElimination)
@@ -277,7 +279,8 @@ let compute_consteval_mutual_fix env sigma ref =
let nargs = List.length l in
match kind_of_term c' with
| Lambda (na,t,g) when List.is_empty l ->
- srec (push_rel (na,None,t) env) (minarg+1) (t::labs) ref g
+ let open Context.Rel.Declaration in
+ srec (push_rel (LocalAssum (na,t)) env) (minarg+1) (t::labs) ref g
| Fix ((lv,i),(names,_,_)) ->
(* Last known constant wrapping Fix is ref = [labs](Fix l) *)
(match compute_consteval_direct env sigma ref with
@@ -371,7 +374,8 @@ let make_elim_fun (names,(nbfix,lv,n)) u largs =
let dummy = mkProp
let vfx = Id.of_string "_expanded_fix_"
let vfun = Id.of_string "_eliminator_function_"
-let venv = val_of_named_context [(vfx, None, dummy); (vfun, None, dummy)]
+let venv = let open Context.Named.Declaration in
+ val_of_named_context [LocalAssum (vfx, dummy); LocalAssum (vfun, dummy)]
(* Mark every occurrence of substituted vars (associated to a function)
as a problem variable: an evar that can be instantiated either by
@@ -534,9 +538,11 @@ let match_eval_ref_value env sigma constr =
| Const (sp, u) when is_evaluable env (EvalConstRef sp) ->
Some (constant_value_in env (sp, u))
| Var id when is_evaluable env (EvalVarRef id) ->
- let (_,v,_) = lookup_named id env in v
- | Rel n -> let (_,v,_) = lookup_rel n env in
- Option.map (lift n) v
+ let open Context.Named.Declaration in
+ lookup_named id env |> get_value
+ | Rel n ->
+ let open Context.Rel.Declaration in
+ lookup_rel n env |> map_value (lift n) |> get_value
| Evar ev -> Evd.existential_opt_value sigma ev
| _ -> None
@@ -601,12 +607,14 @@ let whd_nothing_for_iota env sigma s =
let rec whrec (x, stack as s) =
match kind_of_term x with
| Rel n ->
+ let open Context.Rel.Declaration in
(match lookup_rel n env with
- | (_,Some body,_) -> whrec (lift n body, stack)
+ | LocalDef (_,body,_) -> whrec (lift n body, stack)
| _ -> s)
| Var id ->
+ let open Context.Named.Declaration in
(match lookup_named id env with
- | (_,Some body,_) -> whrec (body, stack)
+ | LocalDef (_,body,_) -> whrec (body, stack)
| _ -> s)
| Evar ev ->
(try whrec (Evd.existential_value sigma ev, stack)
@@ -809,7 +817,9 @@ let try_red_product env sigma c =
simpfun (Stack.zip (f,stack')))
| _ -> simpfun (appvect (redrec env f, l)))
| Cast (c,_,_) -> redrec env c
- | Prod (x,a,b) -> mkProd (x, a, redrec (push_rel (x,None,a) env) b)
+ | Prod (x,a,b) ->
+ let open Context.Rel.Declaration in
+ mkProd (x, a, redrec (push_rel (LocalAssum (x,a)) env) b)
| LetIn (x,a,b,t) -> redrec env (subst1 a t)
| Case (ci,p,d,lf) -> simpfun (mkCase (ci,p,redrec env d,lf))
| Proj (p, c) ->
@@ -1157,8 +1167,9 @@ let reduce_to_ind_gen allow_product env sigma t =
match kind_of_term (fst (decompose_app t)) with
| Ind ind-> (check_privacy env ind, it_mkProd_or_LetIn t l)
| Prod (n,ty,t') ->
+ let open Context.Rel.Declaration in
if allow_product then
- elimrec (push_rel (n,None,ty) env) t' ((n,None,ty)::l)
+ elimrec (push_rel (LocalAssum (n,ty)) env) t' ((LocalAssum (n,ty))::l)
else
errorlabstrm "" (str"Not an inductive definition.")
| _ ->
@@ -1235,7 +1246,8 @@ let reduce_to_ref_gen allow_product env sigma ref t =
match kind_of_term c with
| Prod (n,ty,t') ->
if allow_product then
- elimrec (push_rel (n,None,t) env) t' ((n,None,ty)::l)
+ let open Context.Rel.Declaration in
+ elimrec (push_rel (LocalAssum (n,t)) env) t' ((LocalAssum (n,ty))::l)
else
error_cannot_recognize ref
| _ ->
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 3d6196c352..6c62bd08fc 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -16,6 +16,7 @@ open Evd
open Util
open Typeclasses_errors
open Libobject
+open Context.Rel.Declaration
(*i*)
let typeclasses_unique_solutions = ref false
@@ -180,9 +181,7 @@ let subst_class (subst,cl) =
let do_subst_con c = Mod_subst.subst_constant subst c
and do_subst c = Mod_subst.subst_mps subst c
and do_subst_gr gr = fst (subst_global subst gr) in
- let do_subst_ctx ctx = List.smartmap
- (fun (na, b, t) -> (na, Option.smartmap do_subst b, do_subst t))
- ctx in
+ let do_subst_ctx = List.smartmap (map_constr do_subst) in
let do_subst_context (grs,ctx) =
List.smartmap (Option.smartmap (fun (gr,b) -> do_subst_gr gr, b)) grs,
do_subst_ctx ctx in
@@ -199,15 +198,19 @@ let discharge_class (_,cl) =
let repl = Lib.replacement_context () in
let rel_of_variable_context ctx = List.fold_right
( fun (n,_,b,t) (ctx', subst) ->
- let decl = (Name n, Option.map (substn_vars 1 subst) b, substn_vars 1 subst t) in
+ let decl = match b with
+ | None -> LocalAssum (Name n, substn_vars 1 subst t)
+ | Some b -> LocalDef (Name n, substn_vars 1 subst b, substn_vars 1 subst t)
+ in
(decl :: ctx', n :: subst)
) ctx ([], []) in
let discharge_rel_context subst n rel =
let rel = Context.Rel.map (Cooking.expmod_constr repl) rel in
let ctx, _ =
List.fold_right
- (fun (id, b, t) (ctx, k) ->
- (id, Option.smartmap (substn_vars k subst) b, substn_vars k subst t) :: ctx, succ k)
+ (fun decl (ctx, k) ->
+ map_constr (substn_vars k subst) decl :: ctx, succ k
+ )
rel ([], n)
in ctx
in
@@ -217,15 +220,15 @@ let discharge_class (_,cl) =
| ConstRef cst -> Lib.section_segment_of_constant cst
| IndRef (ind,_) -> Lib.section_segment_of_mutual_inductive ind in
let discharge_context ctx' subst (grs, ctx) =
- let grs' =
- let newgrs = List.map (fun (_, _, t) ->
- match class_of_constr t with
- | None -> None
- | Some (_, ((tc,_), _)) -> Some (tc.cl_impl, true))
- ctx'
+ let grs' =
+ let newgrs = List.map (fun decl ->
+ match decl |> get_type |> class_of_constr with
+ | None -> None
+ | Some (_, ((tc,_), _)) -> Some (tc.cl_impl, true))
+ ctx'
in
- List.smartmap (Option.smartmap (fun (gr, b) -> Lib.discharge_global gr, b)) grs
- @ newgrs
+ List.smartmap (Option.smartmap (fun (gr, b) -> Lib.discharge_global gr, b)) grs
+ @ newgrs
in grs', discharge_rel_context subst 1 ctx @ ctx' in
let cl_impl' = Lib.discharge_global cl.cl_impl in
if cl_impl' == cl.cl_impl then cl else
@@ -431,11 +434,7 @@ let add_class cl =
*)
let instance_constructor (cl,u) args =
- let filter (_, b, _) = match b with
- | None -> true
- | Some _ -> false
- in
- let lenpars = List.count filter (snd cl.cl_context) in
+ let lenpars = List.count is_local_assum (snd cl.cl_context) in
let pars = fst (List.chop lenpars args) in
match cl.cl_impl with
| IndRef ind ->
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index fb0c49320f..8be28a6202 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -18,6 +18,7 @@ open Inductive
open Inductiveops
open Typeops
open Arguments_renaming
+open Context.Rel.Declaration
let meta_type evd mv =
let ty =
@@ -88,16 +89,16 @@ let e_is_correct_arity env evdref c pj ind specif params =
let rec srec env pt ar =
let pt' = whd_betadeltaiota env !evdref pt in
match kind_of_term pt', ar with
- | Prod (na1,a1,t), (_,None,a1')::ar' ->
+ | Prod (na1,a1,t), (LocalAssum (_,a1'))::ar' ->
if not (Evarconv.e_cumul env evdref a1 a1') then error ();
- srec (push_rel (na1,None,a1) env) t ar'
+ srec (push_rel (LocalAssum (na1,a1)) env) t ar'
| Sort s, [] ->
if not (Sorts.List.mem (Sorts.family s) allowed_sorts)
then error ()
| Evar (ev,_), [] ->
let evd, s = Evd.fresh_sort_in_family env !evdref (max_sort allowed_sorts) in
evdref := Evd.define ev (mkSort s) evd
- | _, (_,Some _,_ as d)::ar' ->
+ | _, (LocalDef _ as d)::ar' ->
srec (push_rel d env) (lift 1 pt') ar'
| _ ->
error ()
@@ -229,14 +230,14 @@ let rec execute env evdref cstr =
| Lambda (name,c1,c2) ->
let j = execute env evdref c1 in
let var = e_type_judgment env evdref j in
- let env1 = push_rel (name,None,var.utj_val) env in
+ let env1 = push_rel (LocalAssum (name, var.utj_val)) env in
let j' = execute env1 evdref c2 in
judge_of_abstraction env1 name var j'
| Prod (name,c1,c2) ->
let j = execute env evdref c1 in
let varj = e_type_judgment env evdref j in
- let env1 = push_rel (name,None,varj.utj_val) env in
+ let env1 = push_rel (LocalAssum (name, varj.utj_val)) env in
let j' = execute env1 evdref c2 in
let varj' = e_type_judgment env1 evdref j' in
judge_of_product env name varj varj'
@@ -246,7 +247,7 @@ let rec execute env evdref cstr =
let j2 = execute env evdref c2 in
let j2 = e_type_judgment env evdref j2 in
let _ = e_judge_of_cast env evdref j1 DEFAULTcast j2 in
- let env1 = push_rel (name,Some j1.uj_val,j2.utj_val) env in
+ let env1 = push_rel (LocalDef (name, j1.uj_val, j2.utj_val)) env in
let j3 = execute env1 evdref c3 in
judge_of_letin env name j1 j2 j3
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index b5e882bc4b..6614749d08 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -28,6 +28,7 @@ open Locus
open Locusops
open Find_subterm
open Sigma.Notations
+open Context.Named.Declaration
let keyed_unification = ref (false)
let _ = Goptions.declare_bool_option {
@@ -58,7 +59,7 @@ let occur_meta_or_undefined_evar evd c =
| Evar_defined c ->
occrec c; Array.iter occrec args
| Evar_empty -> raise Occur)
- | _ -> iter_constr occrec c
+ | _ -> Constr.iter occrec c
in try occrec c; false with Occur | Not_found -> true
let occur_meta_evd sigma mv c =
@@ -67,7 +68,7 @@ let occur_meta_evd sigma mv c =
let c = whd_evar sigma (whd_meta sigma c) in
match kind_of_term c with
| Meta mv' when Int.equal mv mv' -> raise Occur
- | _ -> iter_constr occrec c
+ | _ -> Constr.iter occrec c
in try occrec c; false with Occur -> true
(* if lname_typ is [xn,An;..;x1,A1] and l is a list of terms,
@@ -75,7 +76,10 @@ let occur_meta_evd sigma mv c =
let abstract_scheme env evd c l lname_typ =
List.fold_left2
- (fun (t,evd) (locc,a) (na,_,ta) ->
+ (fun (t,evd) (locc,a) decl ->
+ let open Context.Rel.Declaration in
+ let na = get_name decl in
+ let ta = get_type decl in
let na = match kind_of_term a with Var id -> Name id | _ -> na in
(* [occur_meta ta] test removed for support of eelim/ecase but consequences
are unclear...
@@ -146,7 +150,7 @@ let rec subst_meta_instances bl c =
| Meta i ->
let select (j,_,_) = Int.equal i j in
(try pi2 (List.find select bl) with Not_found -> c)
- | _ -> map_constr (subst_meta_instances bl) c
+ | _ -> Constr.map (subst_meta_instances bl) c
(** [env] should be the context in which the metas live *)
@@ -164,7 +168,7 @@ let pose_all_metas_as_evars env evd t =
evdref := meta_assign mv (ev,(Conv,TypeNotProcessed)) !evdref;
ev)
| _ ->
- map_constr aux t in
+ Constr.map aux t in
let c = aux t in
(* side-effect *)
(!evdref, c)
@@ -568,8 +572,8 @@ let subst_defined_metas_evars (bl,el) c =
| Evar (evk,args) ->
let select (_,(evk',args'),_) = Evar.equal evk evk' && Array.equal Constr.equal args args' in
(try substrec (pi3 (List.find select el))
- with Not_found -> map_constr substrec c)
- | _ -> map_constr substrec c
+ with Not_found -> Constr.map substrec c)
+ | _ -> Constr.map substrec c
in try Some (substrec c) with Not_found -> None
let check_compatibility env pbty flags (sigma,metasubst,evarsubst) tyM tyN =
@@ -1448,10 +1452,10 @@ let indirectly_dependent c d decls =
it is needed otherwise, as e.g. when abstracting over "2" in
"forall H:0=2, H=H:>(0=1+1) -> 0=2." where there is now obvious
way to see that the second hypothesis depends indirectly over 2 *)
- List.exists (fun (id,_,_) -> dependent_in_decl (mkVar id) d) decls
+ List.exists (fun d' -> dependent_in_decl (mkVar (get_id d')) d) decls
let indirect_dependency d decls =
- pi1 (List.hd (List.filter (fun (id,_,_) -> dependent_in_decl (mkVar id) d) decls))
+ decls |> List.filter (fun d' -> dependent_in_decl (mkVar (get_id d')) d) |> List.hd |> get_id
let finish_evar_resolution ?(flags=Pretyping.all_and_fail_flags) env current_sigma (pending,c) =
let current_sigma = Sigma.to_evar_map current_sigma in
@@ -1570,7 +1574,8 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
in
let likefirst = clause_with_generic_occurrences occs in
let mkvarid () = mkVar id in
- let compute_dependency _ (hyp,_,_ as d) (sign,depdecls) =
+ let compute_dependency _ d (sign,depdecls) =
+ let hyp = get_id d in
match occurrences_of_hyp hyp occs with
| NoOccurrences, InHyp ->
if indirectly_dependent c d depdecls then
@@ -1607,7 +1612,7 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
replace_term_occ_modulo occ test mkvarid concl
in
let lastlhyp =
- if List.is_empty depdecls then None else Some (pi1(List.last depdecls)) in
+ if List.is_empty depdecls then None else Some (get_id (List.last depdecls)) in
let res = match out test with
| None -> None
| Some (sigma, c) -> Some (Sigma.Unsafe.of_pair (c, sigma))
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 8b9c2d6c92..7ea9b90635 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -15,6 +15,7 @@ open Environ
open Inductive
open Reduction
open Vm
+open Context.Rel.Declaration
(*******************************************)
(* Calcul de la forme normal d'un terme *)
@@ -134,7 +135,7 @@ and nf_whd env whd typ =
let dom = nf_vtype env (dom p) in
let name = Name (Id.of_string "x") in
let vc = body_of_vfun (nb_rel env) (codom p) in
- let codom = nf_vtype (push_rel (name,None,dom) env) vc in
+ let codom = nf_vtype (push_rel (LocalAssum (name,dom)) env) vc in
mkProd(name,dom,codom)
| Vfun f -> nf_fun env f typ
| Vfix(f,None) -> nf_fix env f
@@ -202,11 +203,12 @@ and constr_type_of_idkey env (idkey : Vars.id_key) stk =
in
nf_univ_args ~nb_univs mk env stk
| VarKey id ->
- let (_,_,ty) = lookup_named id env in
+ let open Context.Named.Declaration in
+ let ty = get_type (lookup_named id env) in
nf_stk env (mkVar id) ty stk
| RelKey i ->
let n = (nb_rel env - i) in
- let (_,_,ty) = lookup_rel n env in
+ let ty = get_type (lookup_rel n env) in
nf_stk env (mkRel n) (lift n ty) stk
and nf_stk ?from:(from=0) env c t stk =
@@ -260,7 +262,7 @@ and nf_predicate env ind mip params v pT =
let vb = body_of_vfun k f in
let name,dom,codom = decompose_prod env pT in
let dep,body =
- nf_predicate (push_rel (name,None,dom) env) ind mip params vb codom in
+ nf_predicate (push_rel (LocalAssum (name,dom)) env) ind mip params vb codom in
dep, mkLambda(name,dom,body)
| Vfun f, _ ->
let k = nb_rel env in
@@ -270,7 +272,7 @@ and nf_predicate env ind mip params v pT =
let rargs = Array.init n (fun i -> mkRel (n-i)) in
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
- let body = nf_vtype (push_rel (name,None,dom) env) vb in
+ let body = nf_vtype (push_rel (LocalAssum (name,dom)) env) vb in
true, mkLambda(name,dom,body)
| _, _ -> false, nf_val env v crazy_type
@@ -306,7 +308,7 @@ and nf_fun env f typ =
Errors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
- let body = nf_val (push_rel (name,None,dom) env) vb codom in
+ let body = nf_val (push_rel (LocalAssum (name,dom)) env) vb codom in
mkLambda(name,dom,body)
and nf_fix env f =
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index b448df3375..b7b1d67f03 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -35,7 +35,7 @@ type object_pr = {
print_syntactic_def : kernel_name -> std_ppcmds;
print_module : bool -> Names.module_path -> std_ppcmds;
print_modtype : module_path -> std_ppcmds;
- print_named_decl : Id.t * constr option * types -> std_ppcmds;
+ print_named_decl : Context.Named.Declaration.t -> std_ppcmds;
print_library_entry : bool -> (object_name * Lib.node) -> std_ppcmds option;
print_context : bool -> int option -> Lib.library_segment -> std_ppcmds;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> Term.constr * Term.types -> Pp.std_ppcmds;
@@ -132,7 +132,8 @@ let print_renames_list prefix l =
let need_expansion impl ref =
let typ = Global.type_of_global_unsafe ref in
let ctx = prod_assum typ in
- let nprods = List.count (fun (_,b,_) -> Option.is_empty b) ctx in
+ let open Context.Rel.Declaration in
+ let nprods = List.count is_local_assum ctx in
not (List.is_empty impl) && List.length impl >= nprods &&
let _,lastimpl = List.chop nprods impl in
List.exists is_status_implicit lastimpl
@@ -168,8 +169,10 @@ type opacity =
| FullyOpaque
| TransparentMaybeOpacified of Conv_oracle.level
-let opacity env = function
- | VarRef v when not (Option.is_empty (pi2 (Environ.lookup_named v env))) ->
+let opacity env =
+ let open Context.Named.Declaration in
+ function
+ | VarRef v when is_local_def (Environ.lookup_named v env) ->
Some(TransparentMaybeOpacified
(Conv_oracle.get_strategy (Environ.oracle env) (VarKey v)))
| ConstRef cst ->
@@ -440,11 +443,13 @@ let print_named_def name body typ =
let print_named_assum name typ =
str "*** [" ++ str name ++ str " : " ++ pr_ltype typ ++ str "]"
-let gallina_print_named_decl (id,c,typ) =
- let s = Id.to_string id in
- match c with
- | Some body -> print_named_def s body typ
- | None -> print_named_assum s typ
+let gallina_print_named_decl =
+ let open Context.Named.Declaration in
+ function
+ | LocalAssum (id, typ) ->
+ print_named_assum (Id.to_string id) typ
+ | LocalDef (id, body, typ) ->
+ print_named_def (Id.to_string id) body typ
let assumptions_for_print lna =
List.fold_right (fun na env -> add_name na env) lna empty_names_context
@@ -721,8 +726,8 @@ let print_any_name = function
try (* Var locale de but, pas var de section... donc pas d'implicits *)
let dir,str = repr_qualid qid in
if not (DirPath.is_empty dir) then raise Not_found;
- let (_,c,typ) = Global.lookup_named str in
- (print_named_decl (str,c,typ))
+ let open Context.Named.Declaration in
+ str |> Global.lookup_named |> set_id str |> print_named_decl
with Not_found ->
errorlabstrm
"print_name" (pr_qualid qid ++ spc () ++ str "not a defined object.")
@@ -750,8 +755,8 @@ let print_opaque_name qid =
let ty = Universes.unsafe_type_of_global gr in
print_typed_value (mkConstruct cstr, ty)
| VarRef id ->
- let (_,c,ty) = lookup_named id env in
- print_named_decl (id,c,ty)
+ let open Context.Named.Declaration in
+ lookup_named id env |> set_id id |> print_named_decl
let print_about_any loc k =
match k with
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 6f3556adba..0eab155796 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -66,7 +66,7 @@ type object_pr = {
print_syntactic_def : kernel_name -> std_ppcmds;
print_module : bool -> Names.module_path -> std_ppcmds;
print_modtype : module_path -> std_ppcmds;
- print_named_decl : Id.t * constr option * types -> std_ppcmds;
+ print_named_decl : Context.Named.Declaration.t -> std_ppcmds;
print_library_entry : bool -> (object_name * Lib.node) -> std_ppcmds option;
print_context : bool -> int option -> Lib.library_segment -> std_ppcmds;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> Term.constr * Term.types -> Pp.std_ppcmds;
diff --git a/printing/printer.ml b/printing/printer.ml
index 93850e41fa..5f4371f2d0 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -262,16 +262,19 @@ let pr_var_decl_skel pr_id env sigma (id,c,typ) =
let ptyp = (str" : " ++ pt) in
(pr_id id ++ hov 0 (pbody ++ ptyp))
-let pr_var_decl env sigma (id,c,typ) =
- pr_var_decl_skel pr_id env sigma (id,c,typ)
+let pr_var_decl env sigma d =
+ pr_var_decl_skel pr_id env sigma (Context.Named.Declaration.to_tuple d)
let pr_var_list_decl env sigma (l,c,typ) =
hov 0 (pr_var_decl_skel (fun ids -> prlist_with_sep pr_comma pr_id ids) env sigma (l,c,typ))
-let pr_rel_decl env sigma (na,c,typ) =
- let pbody = match c with
- | None -> mt ()
- | Some c ->
+let pr_rel_decl env sigma decl =
+ let open Context.Rel.Declaration in
+ let na = get_name decl in
+ let typ = get_type decl in
+ let pbody = match decl with
+ | LocalAssum _ -> mt ()
+ | LocalDef (_,c,_) ->
(* Force evaluation *)
let pb = pr_lconstr_env env sigma c in
let pb = if isCast c then surround pb else pb in
@@ -420,7 +423,8 @@ let pr_evgl_sign sigma evi =
| None -> [], []
| Some f -> List.filter2 (fun b c -> not b) f (evar_context evi)
in
- let ids = List.rev_map pi1 l in
+ let open Context.Named.Declaration in
+ let ids = List.rev_map get_id l in
let warn =
if List.is_empty ids then mt () else
(str "(" ++ prlist_with_sep pr_comma pr_id ids ++ str " cannot be used)")
diff --git a/proofs/goal.ml b/proofs/goal.ml
index 1dd5be0e71..84ffee23c1 100644
--- a/proofs/goal.ml
+++ b/proofs/goal.ml
@@ -9,6 +9,7 @@
open Util
open Pp
open Term
+open Context.Named.Declaration
(* This module implements the abstract interface to goals *)
(* A general invariant of the module, is that a goal whose associated
@@ -73,7 +74,7 @@ module V82 = struct
let (evars, evk) = Evarutil.new_pure_evar_full evars evi in
let evars = Evd.restore_future_goals evars prev_future_goals prev_principal_goal in
let ctxt = Environ.named_context_of_val hyps in
- let inst = Array.map_of_list (fun (id, _, _) -> mkVar id) ctxt in
+ let inst = Array.map_of_list (mkVar % get_id) ctxt in
let ev = Term.mkEvar (evk,inst) in
(evk, ev, evars)
@@ -139,7 +140,7 @@ module V82 = struct
let env = env sigma gl in
let genv = Global.env () in
let is_proof_var decl =
- try ignore (Environ.lookup_named (Util.pi1 decl) genv); false
+ try ignore (Environ.lookup_named (get_id decl) genv); false
with Not_found -> true in
Environ.fold_named_context_reverse (fun t decl ->
if is_proof_var decl then
diff --git a/proofs/logic.ml b/proofs/logic.ml
index 99e32db046..09f308abef 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -22,6 +22,7 @@ open Proof_type
open Type_errors
open Retyping
open Misctypes
+open Context.Named.Declaration
type refiner_error =
@@ -160,7 +161,8 @@ let reorder_context env sign ord =
| _ ->
(match ctxt_head with
| [] -> error_no_such_hypothesis (List.hd ord)
- | (x,_,_ as d) :: ctxt ->
+ | d :: ctxt ->
+ let x = get_id d in
if Id.Set.mem x expected then
step ord (Id.Set.remove x expected)
ctxt (push_item x d moved_hyps) ctxt_tail
@@ -175,7 +177,8 @@ let reorder_val_context env sign ord =
-let check_decl_position env sign (x,_,_ as d) =
+let check_decl_position env sign d =
+ let x = get_id d in
let needed = global_vars_set_of_decl env d in
let deps = dependency_closure env (named_context_of_val sign) needed in
if Id.List.mem x deps then
@@ -200,16 +203,17 @@ let move_location_eq m1 m2 = match m1, m2 with
let rec get_hyp_after h = function
| [] -> error_no_such_hypothesis h
- | (hyp,_,_) :: right ->
- if Id.equal hyp h then
- match right with (id,_,_)::_ -> MoveBefore id | [] -> MoveFirst
+ | d :: right ->
+ if Id.equal (get_id d) h then
+ match right with d' ::_ -> MoveBefore (get_id d') | [] -> MoveFirst
else
get_hyp_after h right
let split_sign hfrom hto l =
let rec splitrec left toleft = function
| [] -> error_no_such_hypothesis hfrom
- | (hyp,c,typ) as d :: right ->
+ | d :: right ->
+ let hyp,_,typ = to_tuple d in
if Id.equal hyp hfrom then
(left,right,d, toleft || move_location_eq hto MoveLast)
else
@@ -227,27 +231,28 @@ let hyp_of_move_location = function
| MoveBefore id -> id
| _ -> assert false
-let move_hyp toleft (left,(idfrom,_,_ as declfrom),right) hto =
+let move_hyp toleft (left,declfrom,right) hto =
let env = Global.env() in
- let test_dep (hyp,c,typ as d) (hyp2,c,typ2 as d2) =
+ let test_dep d d2 =
if toleft
- then occur_var_in_decl env hyp2 d
- else occur_var_in_decl env hyp d2
+ then occur_var_in_decl env (get_id d2) d
+ else occur_var_in_decl env (get_id d) d2
in
let rec moverec first middle = function
| [] ->
if match hto with MoveFirst | MoveLast -> false | _ -> true then
error_no_such_hypothesis (hyp_of_move_location hto);
List.rev first @ List.rev middle
- | (hyp,_,_) :: _ as right when move_location_eq hto (MoveBefore hyp) ->
+ | d :: _ as right when move_location_eq hto (MoveBefore (get_id d)) ->
List.rev first @ List.rev middle @ right
- | (hyp,_,_) as d :: right ->
+ | d :: right ->
+ let hyp = get_id d in
let (first',middle') =
if List.exists (test_dep d) middle then
if not (move_location_eq hto (MoveAfter hyp)) then
(first, d::middle)
else
- errorlabstrm "move_hyp" (str "Cannot move " ++ pr_id idfrom ++
+ errorlabstrm "move_hyp" (str "Cannot move " ++ pr_id (get_id declfrom) ++
Miscprint.pr_move_location pr_id hto ++
str (if toleft then ": it occurs in " else ": it depends on ")
++ pr_id hyp ++ str ".")
@@ -483,12 +488,14 @@ and mk_casegoals sigma goal goalacc p c =
(acc'',lbrty,conclty,sigma,p',c')
-let convert_hyp check sign sigma (id,b,bt as d) =
+let convert_hyp check sign sigma d =
+ let id,b,bt = to_tuple d in
let env = Global.env() in
let reorder = ref [] in
let sign' =
apply_to_hyp sign id
- (fun _ (_,c,ct) _ ->
+ (fun _ d' _ ->
+ let _,c,ct = to_tuple d' in
let env = Global.env_of_context sign in
if check && not (is_conv env sigma bt ct) then
errorlabstrm "Logic.convert_hyp"
@@ -522,14 +529,14 @@ let prim_refiner r sigma goal =
if replace then
let nexthyp = get_hyp_after id (named_context_of_val sign) in
let sign,t,cl,sigma = clear_hyps2 env sigma (Id.Set.singleton id) sign t cl in
- move_hyp false ([],(id,None,t),named_context_of_val sign)
+ move_hyp false ([], LocalAssum (id,t),named_context_of_val sign)
nexthyp,
t,cl,sigma
else
(if !check && mem_named_context id (named_context_of_val sign) then
errorlabstrm "Logic.prim_refiner"
(str "Variable " ++ pr_id id ++ str " is already declared.");
- push_named_context_val (id,None,t) sign,t,cl,sigma) in
+ push_named_context_val (LocalAssum (id,t)) sign,t,cl,sigma) in
let (sg2,ev2,sigma) =
Goal.V82.mk_goal sigma sign cl (Goal.V82.extra sigma goal) in
let oterm = Term.mkNamedLetIn id ev1 t ev2 in
@@ -546,7 +553,8 @@ let prim_refiner r sigma goal =
with Not_found ->
error "Cannot do a fixpoint on a non inductive type."
else
- check_ind (push_rel (na,None,c1) env) (k-1) b
+ let open Context.Rel.Declaration in
+ check_ind (push_rel (LocalAssum (na,c1)) env) (k-1) b
| _ -> error "Not enough products."
in
let ((sp,_),u) = check_ind env n cl in
@@ -560,7 +568,7 @@ let prim_refiner r sigma goal =
if !check && mem_named_context f (named_context_of_val sign) then
errorlabstrm "Logic.prim_refiner"
(str "Name " ++ pr_id f ++ str " already used in the environment");
- mk_sign (push_named_context_val (f,None,ar) sign) oth
+ mk_sign (push_named_context_val (LocalAssum (f,ar)) sign) oth
| [] ->
Evd.Monad.List.map (fun (_,_,c) sigma ->
let gl,ev,sig' =
@@ -584,7 +592,8 @@ let prim_refiner r sigma goal =
let rec check_is_coind env cl =
let b = whd_betadeltaiota env sigma cl in
match kind_of_term b with
- | Prod (na,c1,b) -> check_is_coind (push_rel (na,None,c1) env) b
+ | Prod (na,c1,b) -> let open Context.Rel.Declaration in
+ check_is_coind (push_rel (LocalAssum (na,c1)) env) b
| _ ->
try
let _ = find_coinductive env sigma b in ()
@@ -601,7 +610,7 @@ let prim_refiner r sigma goal =
error "Name already used in the environment.")
with
| Not_found ->
- mk_sign (push_named_context_val (f,None,ar) sign) oth)
+ mk_sign (push_named_context_val (LocalAssum (f,ar)) sign) oth)
| [] ->
Evd.Monad.List.map (fun (_,c) sigma ->
let gl,ev,sigma =
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index fc33e9a657..403a36141f 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -267,18 +267,19 @@ let _ = Goptions.declare_bool_option
Goptions.optwrite = (fun b -> proof_using_auto_clear := b) }
let set_used_variables l =
+ let open Context.Named.Declaration in
let env = Global.env () in
let ids = List.fold_right Id.Set.add l Id.Set.empty in
let ctx = Environ.keep_hyps env ids in
let ctx_set =
- List.fold_right Id.Set.add (List.map pi1 ctx) Id.Set.empty in
+ List.fold_right Id.Set.add (List.map get_id ctx) Id.Set.empty in
let vars_of = Environ.global_vars_set in
let aux env entry (ctx, all_safe, to_clear as orig) =
match entry with
- | (x,None,_) ->
+ | LocalAssum (x,_) ->
if Id.Set.mem x all_safe then orig
else (ctx, all_safe, (Loc.ghost,x)::to_clear)
- | (x,Some bo, ty) as decl ->
+ | LocalDef (x,bo, ty) as decl ->
if Id.Set.mem x all_safe then orig else
let vars = Id.Set.union (vars_of env bo) (vars_of env ty) in
if Id.Set.subset vars all_safe
diff --git a/proofs/proof_using.ml b/proofs/proof_using.ml
index a69645b116..681a7fa1ad 100644
--- a/proofs/proof_using.ml
+++ b/proofs/proof_using.ml
@@ -10,6 +10,7 @@ open Names
open Environ
open Util
open Vernacexpr
+open Context.Named.Declaration
let to_string e =
let rec aux = function
@@ -33,7 +34,8 @@ let in_nameset =
let rec close_fwd e s =
let s' =
- List.fold_left (fun s (id,b,ty) ->
+ List.fold_left (fun s decl ->
+ let (id,b,ty) = Context.Named.Declaration.to_tuple decl in
let vb = Option.(default Id.Set.empty (map (global_vars_set e) b)) in
let vty = global_vars_set e ty in
let vbty = Id.Set.union vb vty in
@@ -61,13 +63,13 @@ and set_of_id env ty id =
Id.Set.union (global_vars_set env ty) acc)
Id.Set.empty ty
else if Id.to_string id = "All" then
- List.fold_right Id.Set.add (List.map pi1 (named_context env)) Id.Set.empty
+ List.fold_right Id.Set.add (List.map get_id (named_context env)) Id.Set.empty
else if CList.mem_assoc_f Id.equal id !known_names then
process_expr env (CList.assoc_f Id.equal id !known_names) []
else Id.Set.singleton id
and full_set env =
- List.fold_right Id.Set.add (List.map pi1 (named_context env)) Id.Set.empty
+ List.fold_right Id.Set.add (List.map get_id (named_context env)) Id.Set.empty
let process_expr env e ty =
let ty_expr = SsSingl(Loc.ghost, Id.of_string "Type") in
diff --git a/proofs/proofview.ml b/proofs/proofview.ml
index ff8effcda4..ebce25d293 100644
--- a/proofs/proofview.ml
+++ b/proofs/proofview.ml
@@ -17,6 +17,7 @@ open Pp
open Util
open Proofview_monad
open Sigma.Notations
+open Context.Named.Declaration
(** Main state of tactics *)
type proofview = Proofview_monad.proofview
@@ -750,9 +751,15 @@ module Progress = struct
let eq_named_context_val sigma1 sigma2 ctx1 ctx2 =
let open Environ in
let c1 = named_context_of_val ctx1 and c2 = named_context_of_val ctx2 in
- let eq_named_declaration (i1, c1, t1) (i2, c2, t2) =
- Names.Id.equal i1 i2 && Option.equal (eq_constr sigma1 sigma2) c1 c2
- && (eq_constr sigma1 sigma2) t1 t2
+ let eq_named_declaration d1 d2 =
+ match d1, d2 with
+ | LocalAssum (i1,t1), LocalAssum (i2,t2) ->
+ Names.Id.equal i1 i2 && eq_constr sigma1 sigma2 t1 t2
+ | LocalDef (i1,c1,t1), LocalDef (i2,c2,t2) ->
+ Names.Id.equal i1 i2 && eq_constr sigma1 sigma2 c1 c2
+ && eq_constr sigma1 sigma2 t1 t2
+ | _ ->
+ false
in List.equal eq_named_declaration c1 c2
let eq_evar_body sigma1 sigma2 b1 b2 =
@@ -1075,12 +1082,13 @@ struct
let typecheck_evar ev env sigma =
let info = Evd.find sigma ev in
(** Typecheck the hypotheses. *)
- let type_hyp (sigma, env) (na, body, t as decl) =
+ let type_hyp (sigma, env) decl =
+ let t = get_type decl in
let evdref = ref sigma in
let _ = Typing.sort_of env evdref t in
- let () = match body with
- | None -> ()
- | Some body -> Typing.check env evdref body t
+ let () = match decl with
+ | LocalAssum _ -> ()
+ | LocalDef (_,body,_) -> Typing.check env evdref body t
in
(!evdref, Environ.push_named decl env)
in
diff --git a/proofs/refiner.ml b/proofs/refiner.ml
index 8d6bdf6aec..186525e159 100644
--- a/proofs/refiner.ml
+++ b/proofs/refiner.ml
@@ -13,7 +13,7 @@ open Evd
open Environ
open Proof_type
open Logic
-
+open Context.Named.Declaration
let sig_it x = x.it
let project x = x.sigma
@@ -202,7 +202,7 @@ let tclSHOWHYPS (tac : tactic) (goal: Goal.goal Evd.sigma)
let { it = gls; sigma = sigma; } = rslt in
let hyps:Context.Named.t list =
List.map (fun gl -> pf_hyps { it = gl; sigma=sigma; }) gls in
- let cmp (i1, c1, t1) (i2, c2, t2) = Names.Id.equal i1 i2 in
+ let cmp d1 d2 = Names.Id.equal (get_id d1) (get_id d2) in
let newhyps =
List.map
(fun hypl -> List.subtract cmp hypl oldhyps)
@@ -215,7 +215,7 @@ let tclSHOWHYPS (tac : tactic) (goal: Goal.goal Evd.sigma)
List.fold_left
(fun acc lh -> acc ^ (if !frst then (frst:=false;"") else " | ")
^ (List.fold_left
- (fun acc (nm,_,_) -> (Names.Id.to_string nm) ^ " " ^ acc)
+ (fun acc d -> (Names.Id.to_string (get_id d)) ^ " " ^ acc)
"" lh))
"" newhyps in
pp (str (emacs_str "")
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index a1ebacea84..429bd27742 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -18,6 +18,7 @@ open Tacred
open Proof_type
open Logic
open Refiner
+open Context.Named.Declaration
let re_sig it gc = { it = it; sigma = gc; }
@@ -40,9 +41,11 @@ let pf_hyps = Refiner.pf_hyps
let pf_concl gls = Goal.V82.concl (project gls) (sig_it gls)
let pf_hyps_types gls =
let sign = Environ.named_context (pf_env gls) in
- List.map (fun (id,_,x) -> (id, x)) sign
+ List.map (function LocalAssum (id,x)
+ | LocalDef (id,_,x) -> id, x)
+ sign
-let pf_nth_hyp_id gls n = let (id,c,t) = List.nth (pf_hyps gls) (n-1) in id
+let pf_nth_hyp_id gls n = List.nth (pf_hyps gls) (n-1) |> get_id
let pf_last_hyp gl = List.hd (pf_hyps gl)
@@ -53,8 +56,7 @@ let pf_get_hyp gls id =
raise (RefinerError (NoSuchHyp id))
let pf_get_hyp_typ gls id =
- let (_,_,ty)= (pf_get_hyp gls id) in
- ty
+ pf_get_hyp gls id |> get_type
let pf_ids_of_hyps gls = ids_of_named_context (pf_hyps gls)
@@ -204,13 +206,14 @@ module New = struct
sign
let pf_get_hyp_typ id gl =
- let (_,_,ty) = pf_get_hyp id gl in
- ty
+ pf_get_hyp id gl |> get_type
let pf_hyps_types gl =
let env = Proofview.Goal.env gl in
let sign = Environ.named_context env in
- List.map (fun (id,_,x) -> (id, x)) sign
+ List.map (function LocalAssum (id,x)
+ | LocalDef (id,_,x) -> id, x)
+ sign
let pf_last_hyp gl =
let hyps = Proofview.Goal.hyps gl in
diff --git a/stm/lemmas.ml b/stm/lemmas.ml
index 845f83a401..ac54028eb7 100644
--- a/stm/lemmas.ml
+++ b/stm/lemmas.ml
@@ -31,6 +31,7 @@ open Reductionops
open Constrexpr
open Constrintern
open Impargs
+open Context.Rel.Declaration
type 'a declaration_hook = Decl_kinds.locality -> Globnames.global_reference -> 'a
let mk_hook hook = hook
@@ -44,7 +45,8 @@ let call_hook fix_exn hook l c =
let retrieve_first_recthm = function
| VarRef id ->
- (pi2 (Global.lookup_named id),variable_opacity id)
+ let open Context.Named.Declaration in
+ (get_value (Global.lookup_named id),variable_opacity id)
| ConstRef cst ->
let cb = Global.lookup_constant cst in
(Global.body_of_constant_body cb, is_opaque cb)
@@ -107,11 +109,12 @@ let find_mutually_recursive_statements thms =
(fun env c -> fst (whd_betadeltaiota_stack env Evd.empty c))
(Global.env()) hyps in
let ind_hyps =
- List.flatten (List.map_i (fun i (_,b,t) ->
+ List.flatten (List.map_i (fun i decl ->
+ let t = get_type decl in
match kind_of_term t with
| Ind ((kn,_ as ind),u) when
let mind = Global.lookup_mind kn in
- mind.mind_finite <> Decl_kinds.CoFinite && Option.is_empty b ->
+ mind.mind_finite <> Decl_kinds.CoFinite && is_local_assum decl ->
[ind,x,i]
| _ ->
[]) 0 (List.rev whnf_hyp_hds)) in
@@ -450,7 +453,7 @@ let start_proof_com kind thms hook =
let impls, ((env, ctx), imps) = interp_context_evars env0 evdref bl in
let t', imps' = interp_type_evars_impls ~impls env evdref t in
evdref := solve_remaining_evars all_and_fail_flags env !evdref (Evd.empty,!evdref);
- let ids = List.map pi1 ctx in
+ let ids = List.map get_name ctx in
(compute_proof_name (pi1 kind) sopt,
(nf_evar !evdref (it_mkProd_or_LetIn t' ctx),
(ids, imps @ lift_implicits (List.length ids) imps'),
diff --git a/stm/stm.ml b/stm/stm.ml
index e8b500a620..1503c0f8ab 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -1477,10 +1477,8 @@ end = struct (* {{{ *)
let g = Evd.find sigma0 r_goal in
if not (
Evarutil.is_ground_term sigma0 Evd.(evar_concl g) &&
- List.for_all (fun (_,bo,ty) ->
- Evarutil.is_ground_term sigma0 ty &&
- Option.cata (Evarutil.is_ground_term sigma0) true bo)
- Evd.(evar_context g))
+ List.for_all (Context.Named.Declaration.for_all (Evarutil.is_ground_term sigma0))
+ Evd.(evar_context g))
then
Errors.errorlabstrm "Stm" (strbrk("the par: goal selector supports ground "^
"goals only"))
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 6caebf6c4f..86b71999b1 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -324,7 +324,7 @@ let rec trivial_fail_db dbg mod_delta db_list local_db =
let env = Proofview.Goal.env gl in
let nf c = Evarutil.nf_evar sigma c in
let decl = Tacmach.New.pf_last_hyp (Proofview.Goal.assume gl) in
- let hyp = Context.Named.Declaration.map nf decl in
+ let hyp = Context.Named.Declaration.map_constr nf decl in
let hintl = make_resolve_hyp env sigma hyp
in trivial_fail_db dbg mod_delta db_list
(Hint_db.add_list env sigma hintl local_db)
diff --git a/tactics/autorewrite.ml b/tactics/autorewrite.ml
index 40c0f7f9b0..ea598b61ca 100644
--- a/tactics/autorewrite.ml
+++ b/tactics/autorewrite.ml
@@ -133,7 +133,7 @@ let autorewrite_multi_in ?(conds=Naive) idl tac_main lbas =
fun dir cstr tac gl ->
let last_hyp_id =
match Tacmach.pf_hyps gl with
- (last_hyp_id,_,_)::_ -> last_hyp_id
+ d :: _ -> Context.Named.Declaration.get_id d
| _ -> (* even the hypothesis id is missing *)
raise (Logic.RefinerError (Logic.NoSuchHyp !id))
in
@@ -142,7 +142,8 @@ let autorewrite_multi_in ?(conds=Naive) idl tac_main lbas =
match gls with
g::_ ->
(match Environ.named_context_of_val (Goal.V82.hyps gl'.Evd.sigma g) with
- (lastid,_,_)::_ ->
+ d ::_ ->
+ let lastid = Context.Named.Declaration.get_id d in
if not (Id.equal last_hyp_id lastid) then
begin
let gl'' =
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index c9b2c7cfde..7c05befddd 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -302,8 +302,10 @@ type ('a,'b) optionk2 =
| Nonek2 of failure
| Somek2 of 'a * 'b * ('a,'b) optionk2 fk
-let make_resolve_hyp env sigma st flags only_classes pri (id, _, cty) =
- let cty = Evarutil.nf_evar sigma cty in
+let make_resolve_hyp env sigma st flags only_classes pri decl =
+ let open Context.Named.Declaration in
+ let id = get_id decl in
+ let cty = Evarutil.nf_evar sigma (get_type decl) in
let rec iscl env ty =
let ctx, ar = decompose_prod_assum ty in
match kind_of_term (fst (decompose_app ar)) with
@@ -345,9 +347,10 @@ let make_hints g st only_classes sign =
List.fold_left
(fun (paths, hints) hyp ->
let consider =
- try let (_, b, t) = Global.lookup_named (pi1 hyp) in
+ let open Context.Named.Declaration in
+ try let t = Global.lookup_named (get_id hyp) |> get_type in
(* Section variable, reindex only if the type changed *)
- not (Term.eq_constr t (pi3 hyp))
+ not (Term.eq_constr t (get_type hyp))
with Not_found -> true
in
if consider then
diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml
index c4a23f6862..ab6fb37fd1 100644
--- a/tactics/contradiction.ml
+++ b/tactics/contradiction.ml
@@ -15,6 +15,7 @@ open Reductionops
open Misctypes
open Sigma.Notations
open Proofview.Notations
+open Context.Named.Declaration
(* Absurd *)
@@ -47,7 +48,7 @@ let absurd c = absurd c
let filter_hyp f tac =
let rec seek = function
| [] -> Proofview.tclZERO Not_found
- | (id,_,t)::rest when f t -> tac id
+ | d::rest when f (get_type d) -> tac (get_id d)
| _::rest -> seek rest in
Proofview.Goal.enter { enter = begin fun gl ->
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
@@ -60,8 +61,9 @@ let contradiction_context =
let env = Proofview.Goal.env gl in
let rec seek_neg l = match l with
| [] -> Tacticals.New.tclZEROMSG (Pp.str"No such contradiction")
- | (id,_,typ)::rest ->
- let typ = nf_evar sigma typ in
+ | d :: rest ->
+ let id = get_id d in
+ let typ = nf_evar sigma (get_type d) in
let typ = whd_betadeltaiota env sigma typ in
if is_empty_type typ then
simplest_elim (mkVar id)
diff --git a/tactics/elim.ml b/tactics/elim.ml
index 7767affccc..d441074f6a 100644
--- a/tactics/elim.ml
+++ b/tactics/elim.ml
@@ -16,6 +16,7 @@ open Tacmach.New
open Tacticals.New
open Tactics
open Proofview.Notations
+open Context.Named.Declaration
(* Supposed to be called without as clause *)
let introElimAssumsThen tac ba =
@@ -137,7 +138,8 @@ let induction_trailer abs_i abs_j bargs =
in
let (hyps,_) =
List.fold_left
- (fun (bring_ids,leave_ids) (cid,_,_ as d) ->
+ (fun (bring_ids,leave_ids) d ->
+ let cid = get_id d in
if not (List.mem cid leave_ids)
then (d::bring_ids,leave_ids)
else (bring_ids,cid::leave_ids))
diff --git a/tactics/eqschemes.ml b/tactics/eqschemes.ml
index e0bea77703..a03489c805 100644
--- a/tactics/eqschemes.ml
+++ b/tactics/eqschemes.ml
@@ -58,6 +58,7 @@ open Inductiveops
open Ind_tables
open Indrec
open Sigma.Notations
+open Context.Rel.Declaration
let hid = Id.of_string "H"
let xid = Id.of_string "X"
@@ -104,7 +105,7 @@ let get_sym_eq_data env (ind,u) =
error "Not an inductive type with a single constructor.";
let arityctxt = Vars.subst_instance_context u mip.mind_arity_ctxt in
let realsign,_ = List.chop mip.mind_nrealdecls arityctxt in
- if List.exists (fun (_,b,_) -> not (Option.is_empty b)) realsign then
+ if List.exists is_local_def realsign then
error "Inductive equalities with local definitions in arity not supported.";
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
@@ -139,7 +140,7 @@ let get_non_sym_eq_data env (ind,u) =
error "Not an inductive type with a single constructor.";
let arityctxt = Vars.subst_instance_context u mip.mind_arity_ctxt in
let realsign,_ = List.chop mip.mind_nrealdecls arityctxt in
- if List.exists (fun (_,b,_) -> not (Option.is_empty b)) realsign then
+ if List.exists is_local_def realsign then
error "Inductive equalities with local definitions in arity not supported";
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
@@ -173,7 +174,7 @@ let build_sym_scheme env ind =
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let applied_ind = build_dependent_inductive indu specif in
let realsign_ind =
- name_context env ((Name varH,None,applied_ind)::realsign) in
+ name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let ci = make_case_info (Global.env()) ind RegularStyle in
let c =
(my_it_mkLambda_or_LetIn paramsctxt
@@ -232,7 +233,7 @@ let build_sym_involutive_scheme env ind =
(Context.Rel.to_extended_vect (nrealargs+1) mib.mind_params_ctxt)
(rel_vect (nrealargs+1) nrealargs)) in
let realsign_ind =
- name_context env ((Name varH,None,applied_ind)::realsign) in
+ name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let ci = make_case_info (Global.env()) ind RegularStyle in
let c =
(my_it_mkLambda_or_LetIn paramsctxt
@@ -352,9 +353,9 @@ let build_l2r_rew_scheme dep env ind kind =
rel_vect 0 nrealargs]) in
let realsign_P = lift_rel_context nrealargs realsign in
let realsign_ind_P =
- name_context env ((Name varH,None,applied_ind_P)::realsign_P) in
+ name_context env ((LocalAssum (Name varH,applied_ind_P))::realsign_P) in
let realsign_ind_G =
- name_context env ((Name varH,None,applied_ind_G)::
+ name_context env ((LocalAssum (Name varH,applied_ind_G))::
lift_rel_context (nrealargs+3) realsign) in
let applied_sym_C n =
mkApp(sym,
@@ -465,9 +466,9 @@ let build_l2r_forward_rew_scheme dep env ind kind =
rel_vect (2*nrealargs+1) nrealargs]) in
let realsign_P n = lift_rel_context (nrealargs*n+n) realsign in
let realsign_ind =
- name_context env ((Name varH,None,applied_ind)::realsign) in
+ name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let realsign_ind_P n aP =
- name_context env ((Name varH,None,aP)::realsign_P n) in
+ name_context env ((LocalAssum (Name varH,aP))::realsign_P n) in
let s, ctx' = Universes.fresh_sort_in_family (Global.env ()) kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
@@ -545,7 +546,7 @@ let build_r2l_forward_rew_scheme dep env ind kind =
let varP = fresh env (Id.of_string "P") in
let applied_ind = build_dependent_inductive indu specif in
let realsign_ind =
- name_context env ((Name varH,None,applied_ind)::realsign) in
+ name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let s, ctx' = Universes.fresh_sort_in_family (Global.env ()) kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
@@ -599,9 +600,9 @@ let fix_r2l_forward_rew_scheme (c, ctx') =
| hp :: p :: ind :: indargs ->
let c' =
my_it_mkLambda_or_LetIn indargs
- (mkLambda_or_LetIn (Context.Rel.Declaration.map (liftn (-1) 1) p)
- (mkLambda_or_LetIn (Context.Rel.Declaration.map (liftn (-1) 2) hp)
- (mkLambda_or_LetIn (Context.Rel.Declaration.map (lift 2) ind)
+ (mkLambda_or_LetIn (map_constr (liftn (-1) 1) p)
+ (mkLambda_or_LetIn (map_constr (liftn (-1) 2) hp)
+ (mkLambda_or_LetIn (map_constr (lift 2) ind)
(Reductionops.whd_beta Evd.empty
(applist (c,
Context.Rel.to_extended_list 3 indargs @ [mkRel 1;mkRel 3;mkRel 2]))))))
@@ -737,10 +738,10 @@ let build_congr env (eq,refl,ctx) ind =
let arityctxt = Vars.subst_instance_context u mip.mind_arity_ctxt in
let paramsctxt = Vars.subst_instance_context u mib.mind_params_ctxt in
let realsign,_ = List.chop mip.mind_nrealdecls arityctxt in
- if List.exists (fun (_,b,_) -> not (Option.is_empty b)) realsign then
+ if List.exists is_local_def realsign then
error "Inductive equalities with local definitions in arity not supported.";
let env_with_arity = push_rel_context arityctxt env in
- let (_,_,ty) = lookup_rel (mip.mind_nrealargs - i + 1) env_with_arity in
+ let ty = get_type (lookup_rel (mip.mind_nrealargs - i + 1) env_with_arity) in
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
if Int.equal (Context.Rel.length constrsign) (Context.Rel.length mib.mind_params_ctxt) then
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 1e814e861c..d27dcd82a1 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -43,6 +43,7 @@ open Misctypes
open Sigma.Notations
open Proofview.Notations
open Unification
+open Context.Named.Declaration
(* Options *)
@@ -960,7 +961,7 @@ let apply_on_clause (f,t) clause =
let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
let e = next_ident_away eq_baseid (ids_of_context env) in
- let e_env = push_named (e,None,t) env in
+ let e_env = push_named (Context.Named.Declaration.LocalAssum (e,t)) env in
let discriminator =
build_discriminator e_env sigma dirn (mkVar e) sort cpath in
let sigma,(pf, absurd_term), eff =
@@ -1064,7 +1065,7 @@ let make_tuple env sigma (rterm,rty) lind =
assert (dependent (mkRel lind) rty);
let sigdata = find_sigma_data env (get_sort_of env sigma rty) in
let sigma, a = type_of ~refresh:true env sigma (mkRel lind) in
- let (na,_,_) = lookup_rel lind env in
+ let na = Context.Rel.Declaration.get_name (lookup_rel lind env) in
(* We move [lind] to [1] and lift other rels > [lind] by 1 *)
let rty = lift (1-lind) (liftn lind (lind+1) rty) in
(* Now [lind] is [mkRel 1] and we abstract on (na:a) *)
@@ -1335,7 +1336,7 @@ let simplify_args env sigma t =
let inject_at_positions env sigma l2r (eq,_,(t,t1,t2)) eq_clause posns tac =
let e = next_ident_away eq_baseid (ids_of_context env) in
- let e_env = push_named (e, None,t) env in
+ let e_env = push_named (LocalAssum (e,t)) env in
let evdref = ref sigma in
let filter (cpath, t1', t2') =
try
@@ -1612,14 +1613,14 @@ let unfold_body x =
Proofview.Goal.enter { enter = begin fun gl ->
(** We normalize the given hypothesis immediately. *)
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let (_, xval, _) = Context.Named.lookup x hyps in
+ let xval = Context.Named.lookup x hyps |> get_value in
let xval = match xval with
| None -> errorlabstrm "unfold_body"
(pr_id x ++ str" is not a defined hypothesis.")
| Some xval -> pf_nf_evar gl xval
in
afterHyp x begin fun aft ->
- let hl = List.fold_right (fun (y,yval,_) cl -> (y,InHyp) :: cl) aft [] in
+ let hl = List.fold_right (fun d cl -> (get_id d, InHyp) :: cl) aft [] in
let xvar = mkVar x in
let rfun _ _ c = replace_term xvar xval c in
let reducth h = Proofview.V82.tactic (fun gl -> reduct_in_hyp rfun h gl) in
@@ -1636,9 +1637,10 @@ let restrict_to_eq_and_identity eq = (* compatibility *)
exception FoundHyp of (Id.t * constr * bool)
(* tests whether hyp [c] is [x = t] or [t = x], [x] not occurring in [t] *)
-let is_eq_x gl x (id,_,c) =
+let is_eq_x gl x d =
+ let id = get_id d in
try
- let c = pf_nf_evar gl c in
+ let c = pf_nf_evar gl (get_type d) in
let (_,lhs,rhs) = pi3 (find_eq_data_decompose gl c) in
if (Term.eq_constr x lhs) && not (occur_term x rhs) then raise (FoundHyp (id,rhs,true));
if (Term.eq_constr x rhs) && not (occur_term x lhs) then raise (FoundHyp (id,lhs,false))
@@ -1655,11 +1657,12 @@ let subst_one dep_proof_ok x (hyp,rhs,dir) =
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
(* The set of hypotheses using x *)
let dephyps =
- List.rev (snd (List.fold_right (fun (id,b,_ as dcl) (deps,allhyps) ->
+ List.rev (snd (List.fold_right (fun dcl (deps,allhyps) ->
+ let id = get_id dcl in
if not (Id.equal id hyp)
&& List.exists (fun y -> occur_var_in_decl env y dcl) deps
then
- ((if b = None then deps else id::deps), id::allhyps)
+ ((if is_local_assum dcl then deps else id::deps), id::allhyps)
else
(deps,allhyps))
hyps
@@ -1683,7 +1686,7 @@ let subst_one dep_proof_ok x (hyp,rhs,dir) =
let subst_one_var dep_proof_ok x =
Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
- let (_,xval,_) = pf_get_hyp x gl in
+ let xval = pf_get_hyp x gl |> get_value in
(* If x has a body, simply replace x with body and clear x *)
if not (Option.is_empty xval) then tclTHEN (unfold_body x) (clear [x]) else
(* x is a variable: *)
@@ -1742,14 +1745,14 @@ let subst_all ?(flags=default_subst_tactic_flags ()) () =
let gl = Proofview.Goal.assume gl in
let env = Proofview.Goal.env gl in
let find_eq_data_decompose = find_eq_data_decompose gl in
- let test (hyp,_,c) =
+ let test decl =
try
- let lbeq,u,(_,x,y) = find_eq_data_decompose c in
+ let lbeq,u,(_,x,y) = find_eq_data_decompose (get_type decl) in
let eq = Universes.constr_of_global_univ (lbeq.eq,u) in
if flags.only_leibniz then restrict_to_eq_and_identity eq;
match kind_of_term x, kind_of_term y with
| Var z, _ | _, Var z when not (is_evaluable env (EvalVarRef z)) ->
- Some hyp
+ Some (get_id decl)
| _ ->
None
with Constr_matching.PatternMatchingFailure -> None
@@ -1763,7 +1766,7 @@ let subst_all ?(flags=default_subst_tactic_flags ()) () =
Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let find_eq_data_decompose = find_eq_data_decompose gl in
- let (_,_,c) = pf_get_hyp hyp gl in
+ let c = pf_get_hyp hyp gl |> get_type in
let _,_,(_,x,y) = find_eq_data_decompose c in
(* J.F.: added to prevent failure on goal containing x=x as an hyp *)
if Term.eq_constr x y then Proofview.tclUNIT () else
@@ -1831,10 +1834,11 @@ let cond_eq_term c t gl =
let rewrite_assumption_cond cond_eq_term cl =
let rec arec hyps gl = match hyps with
| [] -> error "No such assumption."
- | (id,_,t) ::rest ->
+ | hyp ::rest ->
+ let id = get_id hyp in
begin
try
- let dir = cond_eq_term t gl in
+ let dir = cond_eq_term (get_type hyp) gl in
general_rewrite_clause dir false (mkVar id,NoBindings) cl
with | Failure _ | UserError _ -> arec rest gl
end
diff --git a/tactics/evar_tactics.ml b/tactics/evar_tactics.ml
index 97b5ba0cc5..f443837a41 100644
--- a/tactics/evar_tactics.ml
+++ b/tactics/evar_tactics.ml
@@ -16,6 +16,7 @@ open Evd
open Locus
open Sigma.Notations
open Proofview.Notations
+open Context.Named.Declaration
(* The instantiate tactic *)
@@ -43,14 +44,14 @@ let instantiate_tac n c ido =
match hloc with
InHyp ->
(match decl with
- (_,None,typ) -> evar_list typ
+ | LocalAssum (_,typ) -> evar_list typ
| _ -> error
"Please be more specific: in type or value?")
| InHypTypeOnly ->
- let (_, _, typ) = decl in evar_list typ
+ evar_list (get_type decl)
| InHypValueOnly ->
(match decl with
- (_,Some body,_) -> evar_list body
+ | LocalDef (_,body,_) -> evar_list body
| _ -> error "Not a defined hypothesis.") in
if List.length evl < n then
error "Not enough uninstantiated existential variables.";
diff --git a/tactics/hints.ml b/tactics/hints.ml
index c99e591fe6..730da147af 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -34,6 +34,7 @@ open Tacred
open Printer
open Vernacexpr
open Sigma.Notations
+open Context.Named.Declaration
(****************************************)
(* General functions *)
@@ -727,11 +728,12 @@ let make_resolves env sigma flags pri poly ?name cr =
ents
(* used to add an hypothesis to the local hint database *)
-let make_resolve_hyp env sigma (hname,_,htyp) =
+let make_resolve_hyp env sigma decl =
+ let hname = get_id decl in
try
[make_apply_entry env sigma (true, true, false) None false
~name:(PathHints [VarRef hname])
- (mkVar hname, htyp, Univ.ContextSet.empty)]
+ (mkVar hname, get_type decl, Univ.ContextSet.empty)]
with
| Failure _ -> []
| e when Logic.catchable_exception e -> anomaly (Pp.str "make_resolve_hyp")
@@ -1061,7 +1063,7 @@ let prepare_hint check (poly,local) env init (sigma,c) =
(* Not clever enough to construct dependency graph of evars *)
error "Not clever enough to deal with evars dependent in other evars.";
raise (Found (c,t))
- | _ -> iter_constr find_next_evar c in
+ | _ -> Constr.iter find_next_evar c in
let rec iter c =
try find_next_evar c; c
with Found (evar,t) ->
diff --git a/tactics/hipattern.ml4 b/tactics/hipattern.ml4
index 29d848ca13..bcec90f803 100644
--- a/tactics/hipattern.ml4
+++ b/tactics/hipattern.ml4
@@ -19,6 +19,7 @@ open Constr_matching
open Coqlib
open Declarations
open Tacmach.New
+open Context.Rel.Declaration
(* I implemented the following functions which test whether a term t
is an inductive but non-recursive type, a general conjuction, a
@@ -101,13 +102,16 @@ let match_with_one_constructor style onlybinary allow_rec t =
(decompose_prod_n_assum mib.mind_nparams mip.mind_nf_lc.(0)))) in
if
List.for_all
- (fun (_,b,c) -> Option.is_empty b && isRel c && Int.equal (destRel c) mib.mind_nparams) ctx
+ (fun decl -> let c = get_type decl in
+ is_local_assum decl &&
+ isRel c &&
+ Int.equal (destRel c) mib.mind_nparams) ctx
then
Some (hdapp,args)
else None
else
let ctyp = prod_applist mip.mind_nf_lc.(0) args in
- let cargs = List.map pi3 ((prod_assum ctyp)) in
+ let cargs = List.map get_type (prod_assum ctyp) in
if not (is_lax_conjunction style) || has_nodep_prod ctyp then
(* Record or non strict conjunction *)
Some (hdapp,List.rev cargs)
@@ -152,7 +156,7 @@ let is_tuple t =
let test_strict_disjunction n lc =
Array.for_all_i (fun i c ->
match (prod_assum (snd (decompose_prod_n_assum n c))) with
- | [_,None,c] -> isRel c && Int.equal (destRel c) (n - i)
+ | [LocalAssum (_,c)] -> isRel c && Int.equal (destRel c) (n - i)
| _ -> false) 0 lc
let match_with_disjunction ?(strict=false) ?(onlybinary=false) t =
diff --git a/tactics/inv.ml b/tactics/inv.ml
index ded1e8076d..9bfbbc41b7 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -28,6 +28,7 @@ open Misctypes
open Tacexpr
open Sigma.Notations
open Proofview.Notations
+open Context.Named.Declaration
let clear hyps = Proofview.V82.tactic (clear hyps)
@@ -181,9 +182,9 @@ let make_inv_predicate env evd indf realargs id status concl =
let dependent_hyps env id idlist gl =
let rec dep_rec =function
| [] -> []
- | (id1,_,_)::l ->
+ | d::l ->
(* Update the type of id1: it may have been subject to rewriting *)
- let d = pf_get_hyp id1 gl in
+ let d = pf_get_hyp (get_id d) gl in
if occur_var_in_decl env id d
then d :: dep_rec l
else dep_rec l
@@ -192,8 +193,8 @@ let dependent_hyps env id idlist gl =
let split_dep_and_nodep hyps gl =
List.fold_right
- (fun (id,_,_ as d) (l1,l2) ->
- if var_occurs_in_pf gl id then (d::l1,l2) else (l1,d::l2))
+ (fun d (l1,l2) ->
+ if var_occurs_in_pf gl (get_id d) then (d::l1,l2) else (l1,d::l2))
hyps ([],[])
(* Computation of dids is late; must have been done in rewrite_equations*)
@@ -296,8 +297,8 @@ let get_names (allow_conj,issimple) (loc, pat as x) = match pat with
error "Discarding pattern not allowed for inversion equations."
| IntroAction (IntroRewrite _) ->
error "Rewriting pattern not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern (IntroAndPattern [] | IntroOrPattern [[]])) when allow_conj -> (None, [])
- | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l) | IntroOrPattern [(_,IntroNaming (IntroIdentifier id)) :: _ as l ]))
+ | IntroAction (IntroOrAndPattern (IntroAndPattern [])) when allow_conj -> (None, [])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l)))
when allow_conj -> (Some id,l)
| IntroAction (IntroOrAndPattern (IntroAndPattern _)) ->
if issimple then
@@ -384,7 +385,7 @@ let rewrite_equations as_mode othin neqns names ba =
Proofview.Goal.nf_enter { enter = begin fun gl ->
let (depids,nodepids) = split_dep_and_nodep ba.Tacticals.assums gl in
let first_eq = ref MoveLast in
- let avoid = if as_mode then List.map pi1 nodepids else [] in
+ let avoid = if as_mode then List.map get_id nodepids else [] in
match othin with
| Some thin ->
tclTHENLIST
@@ -399,11 +400,11 @@ let rewrite_equations as_mode othin neqns names ba =
(onLastHypId (fun id ->
tclTRY (projectAndApply as_mode thin avoid id first_eq names depids)))))
names;
- tclMAP (fun (id,_,_) -> tclIDTAC >>= fun () -> (* delay for [first_eq]. *)
- let idopt = if as_mode then Some id else None in
+ tclMAP (fun d -> tclIDTAC >>= fun () -> (* delay for [first_eq]. *)
+ let idopt = if as_mode then Some (get_id d) else None in
intro_move idopt (if thin then MoveLast else !first_eq))
nodepids;
- (tclMAP (fun (id,_,_) -> tclTRY (clear [id])) depids)]
+ (tclMAP (fun d -> tclTRY (clear [get_id d])) depids)]
| None ->
(* simple inversion *)
if as_mode then
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index cdf38ae46a..70782ec648 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -27,6 +27,7 @@ open Tacticals.New
open Tactics
open Decl_kinds
open Proofview.Notations
+open Context.Named.Declaration
let no_inductive_inconstr env sigma constr =
(str "Cannot recognize an inductive predicate in " ++
@@ -117,11 +118,11 @@ let rec add_prods_sign env sigma t =
| Prod (na,c1,b) ->
let id = id_of_name_using_hdchar env t na in
let b'= subst1 (mkVar id) b in
- add_prods_sign (push_named (id,None,c1) env) sigma b'
+ add_prods_sign (push_named (LocalAssum (id,c1)) env) sigma b'
| LetIn (na,c1,t1,b) ->
let id = id_of_name_using_hdchar env t na in
let b'= subst1 (mkVar id) b in
- add_prods_sign (push_named (id,Some c1,t1) env) sigma b'
+ add_prods_sign (push_named (LocalDef (id,c1,t1)) env) sigma b'
| _ -> (env,t)
(* [dep_option] indicates whether the inversion lemma is dependent or not.
@@ -154,7 +155,8 @@ let compute_first_inversion_scheme env sigma ind sort dep_option =
let ivars = global_vars env i in
let revargs,ownsign =
fold_named_context
- (fun env (id,_,_ as d) (revargs,hyps) ->
+ (fun env d (revargs,hyps) ->
+ let id = get_id d in
if Id.List.mem id ivars then
((mkVar id)::revargs, Context.Named.add d hyps)
else
@@ -166,7 +168,7 @@ let compute_first_inversion_scheme env sigma ind sort dep_option =
(pty,goal)
in
let npty = nf_betadeltaiota env sigma pty in
- let extenv = push_named (p,None,npty) env in
+ let extenv = push_named (LocalAssum (p,npty)) env in
extenv, goal
(* [inversion_scheme sign I]
@@ -203,8 +205,8 @@ let inversion_scheme env sigma t sort dep_option inv_op =
let global_named_context = Global.named_context () in
let ownSign = ref begin
fold_named_context
- (fun env (id,_,_ as d) sign ->
- if mem_named_context id global_named_context then sign
+ (fun env d sign ->
+ if mem_named_context (get_id d) global_named_context then sign
else Context.Named.add d sign)
invEnv ~init:Context.Named.empty
end in
@@ -217,9 +219,9 @@ let inversion_scheme env sigma t sort dep_option inv_op =
let h = next_ident_away (Id.of_string "H") !avoid in
let ty,inst = Evarutil.generalize_evar_over_rels sigma (e,args) in
avoid := h::!avoid;
- ownSign := Context.Named.add (h,None,ty) !ownSign;
+ ownSign := Context.Named.add (LocalAssum (h,ty)) !ownSign;
applist (mkVar h, inst)
- | _ -> map_constr fill_holes c
+ | _ -> Constr.map fill_holes c
in
let c = fill_holes pfterm in
(* warning: side-effect on ownSign *)
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 29002af9e0..b39e34fc1b 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -36,6 +36,7 @@ open Termops
open Libnames
open Sigma.Notations
open Proofview.Notations
+open Context.Named.Declaration
(** Typeclass-based generalized rewriting. *)
@@ -134,6 +135,7 @@ module GlobalBindings (M : sig
val arrow : evars -> evars * constr
end) = struct
open M
+ open Context.Rel.Declaration
let relation : evars -> evars * constr = find_global (fst relation) (snd relation)
let reflexive_type = find_global relation_classes "Reflexive"
@@ -219,8 +221,8 @@ end) = struct
let evars, newarg = app_poly env evars respectful [| ty ; b' ; relty ; arg |] in
evars, mkProd(na, ty, b), newarg, (ty, Some relty) :: cstrs
else
- let (evars, b, arg, cstrs) =
- aux (Environ.push_rel (na, None, ty) env) evars b cstrs
+ let (evars, b, arg, cstrs) =
+ aux (Environ.push_rel (LocalAssum (na, ty)) env) evars b cstrs
in
let ty = Reductionops.nf_betaiota (goalevars evars) ty in
let pred = mkLambda (na, ty, b) in
@@ -318,7 +320,7 @@ end) = struct
let evars, rb = aux evars env b' (pred n) in
app_poly env evars pointwise_relation [| ty; b'; rb |]
else
- let evars, rb = aux evars (Environ.push_rel (na, None, ty) env) b (pred n) in
+ let evars, rb = aux evars (Environ.push_rel (LocalAssum (na, ty)) env) b (pred n) in
app_poly env evars forall_relation
[| ty; mkLambda (na, ty, b); mkLambda (na, ty, rb) |]
| _ -> raise Not_found
@@ -469,6 +471,7 @@ let rec decompose_app_rel env evd t =
| _ -> error "Cannot find a relation to rewrite."
let decompose_applied_relation env sigma (c,l) =
+ let open Context.Rel.Declaration in
let ctype = Retyping.get_type_of env sigma c in
let find_rel ty =
let sigma, cl = Clenv.make_evar_clause env sigma ty in
@@ -491,7 +494,7 @@ let decompose_applied_relation env sigma (c,l) =
| Some c -> c
| None ->
let ctx,t' = Reductionops.splay_prod env sigma ctype in (* Search for underlying eq *)
- match find_rel (it_mkProd_or_LetIn t' (List.map (fun (n,t) -> n, None, t) ctx)) with
+ match find_rel (it_mkProd_or_LetIn t' (List.map (fun (n,t) -> LocalAssum (n, t)) ctx)) with
| Some c -> c
| None -> error "Cannot find an homogeneous relation to rewrite."
@@ -766,9 +769,9 @@ let resolve_morphism env avoid oldt m ?(fnewt=fun x -> x) args args' (b,cstr) ev
else TypeGlobal.do_subrelation, TypeGlobal.apply_subrelation
in
Environ.push_named
- (Id.of_string "do_subrelation",
- Some (snd (app_poly_sort b env evars dosub [||])),
- snd (app_poly_nocheck env evars appsub [||]))
+ (LocalDef (Id.of_string "do_subrelation",
+ snd (app_poly_sort b env evars dosub [||]),
+ snd (app_poly_nocheck env evars appsub [||])))
env
in
let evars, morph = new_cstr_evar evars env' app in
@@ -1110,8 +1113,9 @@ let subterm all flags (s : 'a pure_strategy) : 'a pure_strategy =
(* | _ -> b') *)
| Lambda (n, t, b) when flags.under_lambdas ->
- let n' = name_app (fun id -> Tactics.fresh_id_in_env unfresh id env) n in
- let env' = Environ.push_rel (n', None, t) env in
+ let n' = name_app (fun id -> Tactics.fresh_id_in_env unfresh id env) n in
+ let open Context.Rel.Declaration in
+ let env' = Environ.push_rel (LocalAssum (n', t)) env in
let bty = Retyping.get_type_of env' (goalevars evars) b in
let unlift = if prop then PropGlobal.unlift_cstr else TypeGlobal.unlift_cstr in
let state, b' = s.strategy { state ; env = env' ; unfresh ;
@@ -1495,8 +1499,8 @@ let cl_rewrite_clause_aux ?(abs=None) strat env avoid sigma concl is_hyp : resul
(** Insert a declaration after the last declaration it depends on *)
let rec insert_dependent env decl accu hyps = match hyps with
| [] -> List.rev_append accu [decl]
-| (id, _, _ as ndecl) :: rem ->
- if occur_var_in_decl env id decl then
+| ndecl :: rem ->
+ if occur_var_in_decl env (get_id ndecl) decl then
List.rev_append accu (decl :: hyps)
else
insert_dependent env decl (ndecl :: accu) rem
@@ -1506,16 +1510,19 @@ let assert_replacing id newt tac =
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
let ctx = Environ.named_context env in
- let after, before = List.split_when (fun (n, b, t) -> Id.equal n id) ctx in
+ let after, before = List.split_when (Id.equal id % get_id) ctx in
let nc = match before with
| [] -> assert false
- | (id, b, _) :: rem -> insert_dependent env (id, None, newt) [] after @ rem
+ | d :: rem -> insert_dependent env (LocalAssum (get_id d, newt)) [] after @ rem
in
let env' = Environ.reset_with_named_context (val_of_named_context nc) env in
Proofview.Refine.refine ~unsafe:false { run = begin fun sigma ->
let Sigma (ev, sigma, p) = Evarutil.new_evar env' sigma concl in
let Sigma (ev', sigma, q) = Evarutil.new_evar env sigma newt in
- let map (n, _, _) = if Id.equal n id then ev' else mkVar n in
+ let map d =
+ let n = get_id d in
+ if Id.equal n id then ev' else mkVar n
+ in
let (e, _) = destEvar ev in
Sigma (mkEvar (e, Array.map_of_list map nc), sigma, p +> q)
end }
@@ -1543,7 +1550,7 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
assert_replacing id newt tac
| Some id, None ->
Proofview.Unsafe.tclEVARS undef <*>
- convert_hyp_no_check (id, None, newt)
+ convert_hyp_no_check (LocalAssum (id, newt))
| None, Some p ->
Proofview.Unsafe.tclEVARS undef <*>
Proofview.Goal.enter { enter = begin fun gl ->
@@ -2053,7 +2060,8 @@ let setoid_proof ty fn fallback =
try
let rel, _, _ = decompose_app_rel env sigma concl in
let evm = sigma in
- let car = pi3 (List.hd (fst (Reduction.dest_prod env (Typing.unsafe_type_of env evm rel)))) in
+ let open Context.Rel.Declaration in
+ let car = get_type (List.hd (fst (Reduction.dest_prod env (Typing.unsafe_type_of env evm rel)))) in
(try init_setoid () with _ -> raise Not_found);
fn env sigma car rel
with e -> Proofview.tclZERO e
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 1112da4a0d..30a9071fda 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -42,6 +42,7 @@ open Tacintern
open Taccoerce
open Sigma.Notations
open Proofview.Notations
+open Context.Named.Declaration
let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
let Val.Dyn (t, _) = v in
@@ -444,14 +445,13 @@ let interp_reference ist env sigma = function
try try_interp_ltac_var (coerce_to_reference env) ist (Some (env,sigma)) (loc, id)
with Not_found ->
try
- let (v, _, _) = Environ.lookup_named id env in
- VarRef v
+ VarRef (get_id (Environ.lookup_named id env))
with Not_found -> error_global_not_found_loc loc (qualid_of_ident id)
let try_interp_evaluable env (loc, id) =
let v = Environ.lookup_named id env in
match v with
- | (_, Some _, _) -> EvalVarRef id
+ | LocalDef _ -> EvalVarRef id
| _ -> error_not_evaluable (VarRef id)
let interp_evaluable ist env sigma = function
diff --git a/tactics/tactic_matching.ml b/tactics/tactic_matching.ml
index 80786058d9..2144b75e74 100644
--- a/tactics/tactic_matching.ml
+++ b/tactics/tactic_matching.ml
@@ -11,6 +11,7 @@
open Names
open Tacexpr
+open Context.Named.Declaration
(** [t] is the type of matching successes. It ultimately contains a
{!Tacexpr.glob_tactic_expr} representing the left-hand side of the
@@ -278,9 +279,10 @@ module PatternMatching (E:StaticEnvironment) = struct
[hyps]. Tries the hypotheses in order. For each success returns
the name of the matched hypothesis. *)
let hyp_match_type hypname pat hyps =
- pick hyps >>= fun (id,b,hyp) ->
- let refresh = not (Option.is_empty b) in
- pattern_match_term refresh pat hyp () <*>
+ pick hyps >>= fun decl ->
+ let id = get_id decl in
+ let refresh = is_local_def decl in
+ pattern_match_term refresh pat (get_type decl) () <*>
put_terms (id_map_try_add_name hypname (Term.mkVar id) empty_term_subst) <*>
return id
@@ -290,12 +292,12 @@ module PatternMatching (E:StaticEnvironment) = struct
success returns the name of the matched hypothesis. *)
let hyp_match_body_and_type hypname bodypat typepat hyps =
pick hyps >>= function
- | (id,Some body,hyp) ->
+ | LocalDef (id,body,hyp) ->
pattern_match_term false bodypat body () <*>
pattern_match_term true typepat hyp () <*>
put_terms (id_map_try_add_name hypname (Term.mkVar id) empty_term_subst) <*>
return id
- | (id,None,hyp) -> fail
+ | LocalAssum (id,hyp) -> fail
(** [hyp_match pat hyps] dispatches to
{!hyp_match_type} or {!hyp_match_body_and_type} depending on whether
@@ -317,7 +319,7 @@ module PatternMatching (E:StaticEnvironment) = struct
(* spiwack: alternatively it is possible to return the list
with the matched hypothesis removed directly in
[hyp_match]. *)
- let select_matched_hyp (id,_,_) = Id.equal id matched_hyp in
+ let select_matched_hyp decl = Id.equal (get_id decl) matched_hyp in
let hyps = CList.remove_first select_matched_hyp hyps in
hyp_pattern_list_match pats hyps lhs
| [] -> return lhs
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index d79de4913c..7f904a561d 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -16,6 +16,7 @@ open Declarations
open Tacmach
open Clenv
open Sigma.Notations
+open Context.Named.Declaration
(************************************************************************)
(* Tacticals re-exported from the Refiner module *)
@@ -69,7 +70,7 @@ let nthDecl m gl =
try List.nth (pf_hyps gl) (m-1)
with Failure _ -> error "No such assumption."
-let nthHypId m gl = pi1 (nthDecl m gl)
+let nthHypId m gl = nthDecl m gl |> get_id
let nthHyp m gl = mkVar (nthHypId m gl)
let lastDecl gl = nthDecl 1 gl
@@ -80,7 +81,7 @@ let nLastDecls n gl =
try List.firstn n (pf_hyps gl)
with Failure _ -> error "Not enough hypotheses in the goal."
-let nLastHypsId n gl = List.map pi1 (nLastDecls n gl)
+let nLastHypsId n gl = List.map get_id (nLastDecls n gl)
let nLastHyps n gl = List.map mkVar (nLastHypsId n gl)
let onNthDecl m tac gl = tac (nthDecl m gl) gl
@@ -98,7 +99,7 @@ let onNLastHypsId n tac = onHyps (nLastHypsId n) tac
let onNLastHyps n tac = onHyps (nLastHyps n) tac
let afterHyp id gl =
- fst (List.split_when (fun (hyp,_,_) -> Id.equal hyp id) (pf_hyps gl))
+ fst (List.split_when (Id.equal id % get_id) (pf_hyps gl))
(***************************************)
(* Clause Tacticals *)
@@ -552,8 +553,7 @@ module New = struct
let nthHypId m gl =
(** We only use [id] *)
let gl = Proofview.Goal.assume gl in
- let (id,_,_) = nthDecl m gl in
- id
+ nthDecl m gl |> get_id
let nthHyp m gl =
mkVar (nthHypId m gl)
@@ -585,7 +585,7 @@ module New = struct
let afterHyp id tac =
Proofview.Goal.nf_enter { enter = begin fun gl ->
let hyps = Proofview.Goal.hyps gl in
- let rem, _ = List.split_when (fun (hyp,_,_) -> Id.equal hyp id) hyps in
+ let rem, _ = List.split_when (Id.equal id % get_id) hyps in
tac rem
end }
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index aeb3726a0c..8f30df5c04 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -161,19 +161,21 @@ let _ =
(** This tactic creates a partial proof realizing the introduction rule, but
does not check anything. *)
-let unsafe_intro env store (id, c, t) b =
+let unsafe_intro env store decl b =
+ let open Context.Named.Declaration in
Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
let sigma = Sigma.to_evar_map sigma in
let ctx = named_context_val env in
- let nctx = push_named_context_val (id, c, t) ctx in
- let inst = List.map (fun (id, _, _) -> mkVar id) (named_context env) in
+ let nctx = push_named_context_val decl ctx in
+ let inst = List.map (mkVar % get_id) (named_context env) in
let ninst = mkRel 1 :: inst in
- let nb = subst1 (mkVar id) b in
+ let nb = subst1 (mkVar (get_id decl)) b in
let sigma, ev = new_evar_instance nctx sigma nb ~principal:true ~store ninst in
- Sigma.Unsafe.of_pair (mkNamedLambda_or_LetIn (id, c, t) ev, sigma)
+ Sigma.Unsafe.of_pair (mkNamedLambda_or_LetIn decl ev, sigma)
end }
let introduction ?(check=true) id =
+ let open Context.Named.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let concl = Proofview.Goal.concl gl in
@@ -186,8 +188,8 @@ let introduction ?(check=true) id =
(str "Variable " ++ pr_id id ++ str " is already declared.")
in
match kind_of_term (whd_evar sigma concl) with
- | Prod (_, t, b) -> unsafe_intro env store (id, None, t) b
- | LetIn (_, c, t, b) -> unsafe_intro env store (id, Some c, t) b
+ | Prod (_, t, b) -> unsafe_intro env store (LocalAssum (id, t)) b
+ | LetIn (_, c, t, b) -> unsafe_intro env store (LocalDef (id, c, t)) b
| _ -> raise (RefinerError IntroNeedsProduct)
end }
@@ -296,6 +298,7 @@ let move_hyp id dest gl = Tacmach.move_hyp id dest gl
(* Renaming hypotheses *)
let rename_hyp repl =
+ let open Context.Named.Declaration in
let fold accu (src, dst) = match accu with
| None -> None
| Some (srcs, dsts) ->
@@ -317,7 +320,7 @@ let rename_hyp repl =
let concl = Proofview.Goal.concl gl in
let store = Proofview.Goal.extra gl in
(** Check that we do not mess variables *)
- let fold accu (id, _, _) = Id.Set.add id accu in
+ let fold accu decl = Id.Set.add (get_id decl) accu in
let vars = List.fold_left fold Id.Set.empty hyps in
let () =
if not (Id.Set.subset src vars) then
@@ -335,14 +338,14 @@ let rename_hyp repl =
let make_subst (src, dst) = (src, mkVar dst) in
let subst = List.map make_subst repl in
let subst c = Vars.replace_vars subst c in
- let map (id, body, t) =
- let id = try List.assoc_f Id.equal id repl with Not_found -> id in
- (id, Option.map subst body, subst t)
+ let map decl =
+ decl |> map_id (fun id -> try List.assoc_f Id.equal id repl with Not_found -> id)
+ |> map_constr subst
in
let nhyps = List.map map hyps in
let nconcl = subst concl in
let nctx = Environ.val_of_named_context nhyps in
- let instance = List.map (fun (id, _, _) -> mkVar id) hyps in
+ let instance = List.map (mkVar % get_id) hyps in
Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
let sigma = Sigma.to_evar_map sigma in
let (sigma, c) = Evarutil.new_evar_instance nctx sigma nconcl ~store instance in
@@ -370,11 +373,13 @@ let id_of_name_with_default id = function
let default_id_of_sort s =
if Sorts.is_small s then default_small_ident else default_type_ident
-let default_id env sigma = function
- | (name,None,t) ->
+let default_id env sigma decl =
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalAssum (name,t) ->
let dft = default_id_of_sort (Retyping.get_sort_of env sigma t) in
id_of_name_with_default dft name
- | (name,Some b,_) -> id_of_name_using_hdchar env b name
+ | LocalDef (name,b,_) -> id_of_name_using_hdchar env b name
(* Non primitive introduction tactics are treated by intro_then_gen
There is possibly renaming, with possibly names to avoid and
@@ -409,8 +414,9 @@ let find_name mayrepl decl naming gl = match naming with
(**************************************************************)
let assert_before_then_gen b naming t tac =
+ let open Context.Rel.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
- let id = find_name b (Anonymous,None,t) naming gl in
+ let id = find_name b (LocalAssum (Anonymous,t)) naming gl in
Tacticals.New.tclTHENLAST
(Proofview.V82.tactic
(fun gl ->
@@ -427,8 +433,9 @@ let assert_before na = assert_before_gen false (naming_of_name na)
let assert_before_replacing id = assert_before_gen true (NamingMustBe (dloc,id))
let assert_after_then_gen b naming t tac =
+ let open Context.Rel.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
- let id = find_name b (Anonymous,None,t) naming gl in
+ let id = find_name b (LocalAssum (Anonymous,t)) naming gl in
Tacticals.New.tclTHENFIRST
(Proofview.V82.tactic
(fun gl ->
@@ -472,17 +479,18 @@ let cofix ido gl = match ido with
type tactic_reduction = env -> evar_map -> constr -> constr
-let pf_reduce_decl redfun where (id,c,ty) gl =
+let pf_reduce_decl redfun where decl gl =
+ let open Context.Named.Declaration in
let redfun' = Tacmach.pf_reduce redfun gl in
- match c with
- | None ->
+ match decl with
+ | LocalAssum (id,ty) ->
if where == InHypValueOnly then
errorlabstrm "" (pr_id id ++ str " has no value.");
- (id,None,redfun' ty)
- | Some b ->
+ LocalAssum (id,redfun' ty)
+ | LocalDef (id,b,ty) ->
let b' = if where != InHypTypeOnly then redfun' b else b in
let ty' = if where != InHypValueOnly then redfun' ty else ty in
- (id,Some b',ty')
+ LocalDef (id,b',ty')
(* Possibly equip a reduction with the occurrences mentioned in an
occurrence clause *)
@@ -568,19 +576,20 @@ let reduct_option ?(check=false) redfun = function
(** Tactic reduction modulo evars (for universes essentially) *)
-let pf_e_reduce_decl redfun where (id,c,ty) gl =
+let pf_e_reduce_decl redfun where decl gl =
+ let open Context.Named.Declaration in
let sigma = project gl in
let redfun = redfun (pf_env gl) in
- match c with
- | None ->
+ match decl with
+ | LocalAssum (id,ty) ->
if where == InHypValueOnly then
errorlabstrm "" (pr_id id ++ str " has no value.");
let sigma, ty' = redfun sigma ty in
- sigma, (id,None,ty')
- | Some b ->
+ sigma, LocalAssum (id,ty')
+ | LocalDef (id,b,ty) ->
let sigma, b' = if where != InHypTypeOnly then redfun sigma b else sigma, b in
let sigma, ty' = if where != InHypValueOnly then redfun sigma ty else sigma, ty in
- sigma, (id,Some b',ty')
+ sigma, LocalDef (id,b',ty')
let e_reduct_in_concl (redfun,sty) gl =
Proofview.V82.of_tactic
@@ -609,21 +618,22 @@ let e_change_in_concl (redfun,sty) =
Sigma.Unsafe.of_pair (convert_concl_no_check c sty, sigma)
end }
-let e_pf_change_decl (redfun : bool -> e_reduction_function) where (id,c,ty) env sigma =
- match c with
- | None ->
+let e_pf_change_decl (redfun : bool -> e_reduction_function) where decl env sigma =
+ let open Context.Named.Declaration in
+ match decl with
+ | LocalAssum (id,ty) ->
if where == InHypValueOnly then
errorlabstrm "" (pr_id id ++ str " has no value.");
let sigma',ty' = redfun false env sigma ty in
- sigma', (id,None,ty')
- | Some b ->
+ sigma', LocalAssum (id,ty')
+ | LocalDef (id,b,ty) ->
let sigma',b' =
if where != InHypTypeOnly then redfun true env sigma b else sigma, b
in
let sigma',ty' =
if where != InHypValueOnly then redfun false env sigma' ty else sigma', ty
in
- sigma', (id,Some b',ty')
+ sigma', LocalDef (id,b',ty')
let e_change_in_hyp redfun (id,where) =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
@@ -767,10 +777,9 @@ let unfold_constr = function
let find_intro_names ctxt gl =
let _, res = List.fold_right
(fun decl acc ->
- let wantedname,x,typdecl = decl in
let env,idl = acc in
let name = fresh_id idl (default_id env gl.sigma decl) gl in
- let newenv = push_rel (wantedname,x,typdecl) env in
+ let newenv = push_rel decl env in
(newenv,(name::idl)))
ctxt (pf_env gl , []) in
List.rev res
@@ -782,15 +791,16 @@ let build_intro_tac id dest tac = match dest with
Proofview.V82.tactic (move_hyp id dest); tac id]
let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
+ let open Context.Rel.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
let concl = nf_evar (Tacmach.New.project gl) concl in
match kind_of_term concl with
| Prod (name,t,u) when not dep_flag || (dependent (mkRel 1) u) ->
- let name = find_name false (name,None,t) name_flag gl in
+ let name = find_name false (LocalAssum (name,t)) name_flag gl in
build_intro_tac name move_flag tac
| LetIn (name,b,t,u) when not dep_flag || (dependent (mkRel 1) u) ->
- let name = find_name false (name,Some b,t) name_flag gl in
+ let name = find_name false (LocalDef (name,b,t)) name_flag gl in
build_intro_tac name move_flag tac
| _ ->
begin if not force_flag then Proofview.tclZERO (RefinerError IntroNeedsProduct)
@@ -853,21 +863,24 @@ let intro_forthcoming_then_gen name_flag move_flag dep_flag n bound tac =
aux n []
let get_next_hyp_position id gl =
+ let open Context.Named.Declaration in
let rec aux = function
| [] -> raise (RefinerError (NoSuchHyp id))
- | (hyp,_,_) :: right ->
- if Id.equal hyp id then
- match right with (id,_,_)::_ -> MoveBefore id | [] -> MoveLast
+ | decl :: right ->
+ if Id.equal (get_id decl) id then
+ match right with decl::_ -> MoveBefore (get_id decl) | [] -> MoveLast
else
aux right
in
aux (Proofview.Goal.hyps (Proofview.Goal.assume gl))
let get_previous_hyp_position id gl =
+ let open Context.Named.Declaration in
let rec aux dest = function
| [] -> raise (RefinerError (NoSuchHyp id))
- | (hyp,_,_) :: right ->
- if Id.equal hyp id then dest else aux (MoveAfter hyp) right
+ | decl :: right ->
+ let hyp = get_id decl in
+ if Id.equal hyp id then dest else aux (MoveAfter hyp) right
in
aux MoveLast (Proofview.Goal.hyps (Proofview.Goal.assume gl))
@@ -1146,6 +1159,7 @@ let index_of_ind_arg t =
in aux None 0 t
let enforce_prop_bound_names rename tac =
+ let open Context.Rel.Declaration in
match rename with
| Some (isrec,nn) when Namegen.use_h_based_elimination_names () ->
(* Rename dependent arguments in Prop with name "H" *)
@@ -1165,11 +1179,11 @@ let enforce_prop_bound_names rename tac =
Name (add_suffix Namegen.default_prop_ident s)
else
na in
- mkProd (na,t,aux (push_rel (na,None,t) env) sigma (i-1) t')
+ mkProd (na,t,aux (push_rel (LocalAssum (na,t)) env) sigma (i-1) t')
| Prod (Anonymous,t,t') ->
- mkProd (Anonymous,t,aux (push_rel (Anonymous,None,t) env) sigma (i-1) t')
+ mkProd (Anonymous,t,aux (push_rel (LocalAssum (Anonymous,t)) env) sigma (i-1) t')
| LetIn (na,c,t,t') ->
- mkLetIn (na,c,t,aux (push_rel (na,Some c,t) env) sigma (i-1) t')
+ mkLetIn (na,c,t,aux (push_rel (LocalDef (na,c,t)) env) sigma (i-1) t')
| _ -> print_int i; Pp.msg (print_constr t); assert false in
let rename_branch i =
Proofview.Goal.nf_enter { enter = begin fun gl ->
@@ -1391,11 +1405,13 @@ type conjunction_status =
| NotADefinedRecordUseScheme of constr
let make_projection env sigma params cstr sign elim i n c u =
+ let open Context.Rel.Declaration in
let elim = match elim with
| NotADefinedRecordUseScheme elim ->
(* bugs: goes from right to left when i increases! *)
- let (na,b,t) = List.nth cstr.cs_args i in
- let b = match b with None -> mkRel (i+1) | Some b -> b in
+ let decl = List.nth cstr.cs_args i in
+ let t = get_type decl in
+ let b = match decl with LocalAssum _ -> mkRel (i+1) | LocalDef (_,b,_) -> b in
let branch = it_mkLambda_or_LetIn b cstr.cs_args in
if
(* excludes dependent projection types *)
@@ -1651,6 +1667,7 @@ let apply_in_once_main flags innerclause env sigma (d,lbind) =
let apply_in_once sidecond_first with_delta with_destruct with_evars naming
id (clear_flag,(loc,(d,lbind))) tac =
+ let open Context.Rel.Declaration in
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
@@ -1658,7 +1675,7 @@ let apply_in_once sidecond_first with_delta with_destruct with_evars naming
if with_delta then default_unify_flags () else default_no_delta_unify_flags () in
let t' = Tacmach.New.pf_get_hyp_typ id gl in
let innerclause = mk_clenv_from_env env sigma (Some 0) (mkVar id,t') in
- let targetid = find_name true (Anonymous,None,t') naming gl in
+ let targetid = find_name true (LocalAssum (Anonymous,t')) naming gl in
let rec aux idstoclear with_destruct c =
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
@@ -1770,13 +1787,15 @@ let exact_proof c gl =
in tclTHEN (tclEVARUNIVCONTEXT ctx) (Tacmach.refine_no_check c) gl
let assumption =
+ let open Context.Named.Declaration in
let rec arec gl only_eq = function
| [] ->
if only_eq then
let hyps = Proofview.Goal.hyps gl in
arec gl false hyps
else Tacticals.New.tclZEROMSG (str "No such assumption.")
- | (id, c, t)::rest ->
+ | decl::rest ->
+ let t = get_type decl in
let concl = Proofview.Goal.concl gl in
let sigma = Tacmach.New.project gl in
let (sigma, is_same_type) =
@@ -1787,7 +1806,7 @@ let assumption =
in
if is_same_type then
(Proofview.Unsafe.tclEVARS sigma) <*>
- Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here (mkVar id) h }
+ Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here (mkVar (get_id decl)) h }
else arec gl only_eq rest
in
let assumption_tac = { enter = begin fun gl ->
@@ -1822,40 +1841,43 @@ let check_is_type env ty msg =
with e when Errors.noncritical e ->
msg e
-let check_decl env (_, c, ty) msg =
+let check_decl env decl msg =
+ let open Context.Named.Declaration in
+ let ty = get_type decl in
Proofview.tclEVARMAP >>= fun sigma ->
let evdref = ref sigma in
try
let _ = Typing.sort_of env evdref ty in
- let _ = match c with
- | None -> ()
- | Some c -> Typing.check env evdref c ty
+ let _ = match decl with
+ | LocalAssum _ -> ()
+ | LocalDef (_,c,_) -> Typing.check env evdref c ty
in
Proofview.Unsafe.tclEVARS !evdref
with e when Errors.noncritical e ->
msg e
let clear_body ids =
+ let open Context.Named.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
let ctx = named_context env in
- let map (id, body, t as decl) = match body with
- | None ->
+ let map = function
+ | LocalAssum (id,t) as decl ->
let () = if List.mem_f Id.equal id ids then
errorlabstrm "" (str "Hypothesis " ++ pr_id id ++ str " is not a local definition")
in
decl
- | Some _ ->
- if List.mem_f Id.equal id ids then (id, None, t) else decl
+ | LocalDef (id,_,t) as decl ->
+ if List.mem_f Id.equal id ids then LocalAssum (id, t) else decl
in
let ctx = List.map map ctx in
let base_env = reset_context env in
let env = push_named_context ctx base_env in
let check_hyps =
- let check env (id, _, _ as decl) =
+ let check env decl =
let msg _ = Tacticals.New.tclZEROMSG
- (str "Hypothesis " ++ pr_id id ++ on_the_bodies ids)
+ (str "Hypothesis " ++ pr_id (get_id decl) ++ on_the_bodies ids)
in
check_decl env decl msg <*> Proofview.tclUNIT (push_named decl env)
in
@@ -1897,11 +1919,13 @@ let rec intros_clearing = function
(* Keeping only a few hypotheses *)
let keep hyps =
+ let open Context.Named.Declaration in
Proofview.Goal.nf_enter { enter = begin fun gl ->
Proofview.tclENV >>= fun env ->
let ccl = Proofview.Goal.concl gl in
let cl,_ =
- fold_named_context_reverse (fun (clear,keep) (hyp,_,_ as decl) ->
+ fold_named_context_reverse (fun (clear,keep) decl ->
+ let hyp = get_id decl in
if Id.List.mem hyp hyps
|| List.exists (occur_var_in_decl env hyp) keep
|| occur_var env hyp ccl
@@ -2442,20 +2466,24 @@ let letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty =
end }
let insert_before decls lasthyp env =
+ let open Context.Named.Declaration in
match lasthyp with
| None -> push_named_context decls env
| Some id ->
Environ.fold_named_context
- (fun _ (id',_,_ as d) env ->
- let env = if Id.equal id id' then push_named_context decls env else env in
+ (fun _ d env ->
+ let env = if Id.equal id (get_id d) then push_named_context decls env else env in
push_named d env)
~init:(reset_context env) env
(* unsafe *)
let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
- let body = if dep then Some c else None in
+ let open Context.Named.Declaration in
let t = match ty with Some t -> t | _ -> typ_of env sigma c in
+ let decl = if dep then LocalDef (id,c,t)
+ else LocalAssum (id,t)
+ in
match with_eq with
| Some (lr,(loc,ido)) ->
let heq = match ido with
@@ -2471,11 +2499,11 @@ let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
let Sigma (refl, sigma, q) = Sigma.fresh_global env sigma eqdata.refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
- let newenv = insert_before [heq,None,eq;id,body,t] lastlhyp env in
+ let newenv = insert_before [LocalAssum (heq,eq); decl] lastlhyp env in
let Sigma (x, sigma, r) = new_evar newenv sigma ~principal:true ~store ccl in
Sigma (mkNamedLetIn id c t (mkNamedLetIn heq refl eq x), sigma, p +> q +> r)
| None ->
- let newenv = insert_before [id,body,t] lastlhyp env in
+ let newenv = insert_before [decl] lastlhyp env in
let Sigma (x, sigma, p) = new_evar newenv sigma ~principal:true ~store ccl in
Sigma (mkNamedLetIn id c t x, sigma, p)
@@ -2557,12 +2585,17 @@ let generalized_name c t ids cl = function
but only those at [occs] in [T] *)
let generalize_goal_gen env sigma ids i ((occs,c,b),na) t cl =
+ let open Context.Rel.Declaration in
let decls,cl = decompose_prod_n_assum i cl in
let dummy_prod = it_mkProd_or_LetIn mkProp decls in
let newdecls,_ = decompose_prod_n_assum i (subst_term_gen eq_constr_nounivs c dummy_prod) in
let cl',sigma' = subst_closed_term_occ env sigma (AtOccs occs) c (it_mkProd_or_LetIn cl newdecls) in
let na = generalized_name c t ids cl' na in
- mkProd_or_LetIn (na,b,t) cl', sigma'
+ let decl = match b with
+ | None -> LocalAssum (na,t)
+ | Some b -> LocalDef (na,b,t)
+ in
+ mkProd_or_LetIn decl cl', sigma'
let generalize_goal gl i ((occs,c,b),na as o) (cl,sigma) =
let env = Tacmach.pf_env gl in
@@ -2571,18 +2604,19 @@ let generalize_goal gl i ((occs,c,b),na as o) (cl,sigma) =
generalize_goal_gen env sigma ids i o t cl
let generalize_dep ?(with_let=false) c gl =
+ let open Context.Named.Declaration in
let env = pf_env gl in
let sign = pf_hyps gl in
let init_ids = ids_of_named_context (Global.named_context()) in
- let seek d toquant =
- if List.exists (fun (id,_,_) -> occur_var_in_decl env id d) toquant
+ let seek (d:Context.Named.Declaration.t) (toquant:Context.Named.t) =
+ if List.exists (fun d' -> occur_var_in_decl env (get_id d') d) toquant
|| dependent_in_decl c d then
d::toquant
else
toquant in
let to_quantify = Context.Named.fold_outside seek sign ~init:[] in
let to_quantify_rev = List.rev to_quantify in
- let qhyps = List.map (fun (id,_,_) -> id) to_quantify_rev in
+ let qhyps = List.map get_id to_quantify_rev in
let tothin = List.filter (fun id -> not (Id.List.mem id init_ids)) qhyps in
let tothin' =
match kind_of_term c with
@@ -2594,7 +2628,7 @@ let generalize_dep ?(with_let=false) c gl =
let body =
if with_let then
match kind_of_term c with
- | Var id -> pi2 (Tacmach.pf_get_hyp gl id)
+ | Var id -> Tacmach.pf_get_hyp gl id |> get_value
| _ -> None
else None
in
@@ -2720,14 +2754,15 @@ let specialize (c,lbind) =
(* The two following functions should already exist, but found nowhere *)
(* Unfolds x by its definition everywhere *)
let unfold_body x gl =
+ let open Context.Named.Declaration in
let hyps = pf_hyps gl in
let xval =
match Context.Named.lookup x hyps with
- (_,Some xval,_) -> xval
+ | LocalDef (_,xval,_) -> xval
| _ -> errorlabstrm "unfold_body"
(pr_id x ++ str" is not a defined hypothesis.") in
let aft = afterHyp x gl in
- let hl = List.fold_right (fun (y,yval,_) cl -> (y,InHyp) :: cl) aft [] in
+ let hl = List.fold_right (fun decl cl -> (get_id decl, InHyp) :: cl) aft [] in
let xvar = mkVar x in
let rfun _ _ c = replace_term xvar xval c in
tclTHENLIST
@@ -3041,6 +3076,7 @@ exception Shunt of Id.t move_location
let cook_sign hyp0_opt inhyps indvars env =
(* First phase from L to R: get [toclear], [decldep] and [statuslist]
for the hypotheses before (= more ancient than) hyp0 (see above) *)
+ let open Context.Named.Declaration in
let toclear = ref [] in
let avoid = ref [] in
let decldeps = ref [] in
@@ -3049,7 +3085,8 @@ let cook_sign hyp0_opt inhyps indvars env =
let lstatus = ref [] in
let before = ref true in
let maindep = ref false in
- let seek_deps env (hyp,_,_ as decl) rhyp =
+ let seek_deps env decl rhyp =
+ let hyp = get_id decl in
if (match hyp0_opt with Some hyp0 -> Id.equal hyp hyp0 | _ -> false)
then begin
before:=false;
@@ -3068,7 +3105,7 @@ let cook_sign hyp0_opt inhyps indvars env =
in
let depother = List.is_empty inhyps &&
(List.exists (fun id -> occur_var_in_decl env id decl) indvars ||
- List.exists (fun (id,_,_) -> occur_var_in_decl env id decl) !decldeps)
+ List.exists (fun decl' -> occur_var_in_decl env (get_id decl') decl) !decldeps)
in
if not (List.is_empty inhyps) && Id.List.mem hyp inhyps
|| dephyp0 || depother
@@ -3090,7 +3127,8 @@ let cook_sign hyp0_opt inhyps indvars env =
in
let _ = fold_named_context seek_deps env ~init:MoveFirst in
(* 2nd phase from R to L: get left hyp of [hyp0] and [lhyps] *)
- let compute_lstatus lhyp (hyp,_,_) =
+ let compute_lstatus lhyp decl =
+ let hyp = get_id decl in
if (match hyp0_opt with Some hyp0 -> Id.equal hyp hyp0 | _ -> false) then
raise (Shunt lhyp);
if Id.List.mem hyp !ldeps then begin
@@ -3280,6 +3318,7 @@ let mk_term_eq env sigma ty t ty' t' =
mkHEq ty t ty' t', mkHRefl ty' t'
let make_abstract_generalize env id typ concl dep ctx body c eqs args refls =
+ let open Context.Rel.Declaration in
Proofview.Refine.refine { run = begin fun sigma ->
let eqslen = List.length eqs in
(* Abstract by the "generalized" hypothesis equality proof if necessary. *)
@@ -3291,9 +3330,13 @@ let make_abstract_generalize env id typ concl dep ctx body c eqs args refls =
in
(* Abstract by equalities *)
let eqs = lift_togethern 1 eqs in (* lift together and past genarg *)
- let abseqs = it_mkProd_or_LetIn (lift eqslen abshypeq) (List.map (fun x -> (Anonymous, None, x)) eqs) in
+ let abseqs = it_mkProd_or_LetIn (lift eqslen abshypeq) (List.map (fun x -> LocalAssum (Anonymous, x)) eqs) in
+ let decl = match body with
+ | None -> LocalAssum (Name id, c)
+ | Some body -> LocalDef (Name id, body, c)
+ in
(* Abstract by the "generalized" hypothesis. *)
- let genarg = mkProd_or_LetIn (Name id, body, c) abseqs in
+ let genarg = mkProd_or_LetIn decl abseqs in
(* Abstract by the extension of the context *)
let genctyp = it_mkProd_or_LetIn genarg ctx in
(* The goal will become this product. *)
@@ -3309,11 +3352,13 @@ let make_abstract_generalize env id typ concl dep ctx body c eqs args refls =
end }
let hyps_of_vars env sign nogen hyps =
+ let open Context.Named.Declaration in
if Id.Set.is_empty hyps then []
else
let (_,lh) =
Context.Named.fold_inside
- (fun (hs,hl) (x,_,_ as d) ->
+ (fun (hs,hl) d ->
+ let x = get_id d in
if Id.Set.mem x nogen then (hs,hl)
else if Id.Set.mem x hs then (hs,x::hl)
else
@@ -3342,11 +3387,12 @@ let linear vars args =
true
with Seen -> false
-let is_defined_variable env id = match lookup_named id env with
-| (_, None, _) -> false
-| (_, Some _, _) -> true
+let is_defined_variable env id =
+ let open Context.Named.Declaration in
+ lookup_named id env |> is_local_def
let abstract_args gl generalize_vars dep id defined f args =
+ let open Context.Rel.Declaration in
let sigma = ref (Tacmach.project gl) in
let env = Tacmach.pf_env gl in
let concl = Tacmach.pf_concl gl in
@@ -3363,9 +3409,10 @@ let abstract_args gl generalize_vars dep id defined f args =
eqs are not lifted w.r.t. each other yet. (* will be needed when going to dependent indexes *)
*)
let aux (prod, ctx, ctxenv, c, args, eqs, refls, nongenvars, vars, env) arg =
- let (name, _, ty), arity =
+ let name, ty, arity =
let rel, c = Reductionops.splay_prod_n env !sigma 1 prod in
- List.hd rel, c
+ let decl = List.hd rel in
+ get_name decl, get_type decl, c
in
let argty = Tacmach.pf_unsafe_type_of gl arg in
let sigma', ty = Evarsolve.refresh_universes (Some true) env !sigma ty in
@@ -3379,7 +3426,7 @@ let abstract_args gl generalize_vars dep id defined f args =
Id.Set.add id nongenvars, Id.Set.remove id vars, env)
| _ ->
let name = get_id name in
- let decl = (Name name, None, ty) in
+ let decl = LocalAssum (Name name, ty) in
let ctx = decl :: ctx in
let c' = mkApp (lift 1 c, [|mkRel 1|]) in
let args = arg :: args in
@@ -3430,15 +3477,15 @@ let abstract_args gl generalize_vars dep id defined f args =
else None
let abstract_generalize ?(generalize_vars=true) ?(force_dep=false) id =
+ let open Context.Named.Declaration in
Proofview.Goal.nf_enter { enter = begin fun gl ->
Coqlib.check_required_library Coqlib.jmeq_module_name;
let (f, args, def, id, oldid) =
let oldid = Tacmach.New.pf_get_new_id id gl in
- let (_, b, t) = Tacmach.New.pf_get_hyp id gl in
- match b with
- | None -> let f, args = decompose_app t in
+ match Tacmach.New.pf_get_hyp id gl with
+ | LocalAssum (_,t) -> let f, args = decompose_app t in
(f, args, false, id, oldid)
- | Some t ->
+ | LocalDef (_,t,_) ->
let f, args = decompose_app t in
(f, args, true, id, oldid)
in
@@ -3473,6 +3520,7 @@ let rec compare_upto_variables x y =
else compare_constr compare_upto_variables x y
let specialize_eqs id gl =
+ let open Context.Rel.Declaration in
let env = Tacmach.pf_env gl in
let ty = Tacmach.pf_get_hyp_typ gl id in
let evars = ref (project gl) in
@@ -3501,15 +3549,14 @@ let specialize_eqs id gl =
if in_eqs then acc, in_eqs, ctx, ty
else
let e = e_new_evar (push_rel_context ctx env) evars t in
- aux false ((na, Some e, t) :: ctx) (mkApp (lift 1 acc, [| mkRel 1 |])) b)
+ aux false (LocalDef (na,e,t) :: ctx) (mkApp (lift 1 acc, [| mkRel 1 |])) b)
| t -> acc, in_eqs, ctx, ty
in
let acc, worked, ctx, ty = aux false [] (mkVar id) ty in
let ctx' = nf_rel_context_evar !evars ctx in
- let ctx'' = List.map (fun (n,b,t as decl) ->
- match b with
- | Some k when isEvar k -> (n,None,t)
- | b -> decl) ctx'
+ let ctx'' = List.map (function
+ | LocalDef (n,k,t) when isEvar k -> LocalAssum (n,t)
+ | decl -> decl) ctx'
in
let ty' = it_mkProd_or_LetIn ty ctx'' in
let acc' = it_mkLambda_or_LetIn acc ctx'' in
@@ -3543,18 +3590,19 @@ let occur_rel n c =
We also return the conclusion.
*)
let decompose_paramspred_branch_args elimt =
- let rec cut_noccur elimt acc2 : Context.Rel.t * Context.Rel.t * types =
+ let open Context.Rel.Declaration in
+ let rec cut_noccur elimt acc2 =
match kind_of_term elimt with
| Prod(nme,tpe,elimt') ->
let hd_tpe,_ = decompose_app ((strip_prod_assum tpe)) in
if not (occur_rel 1 elimt') && isRel hd_tpe
- then cut_noccur elimt' ((nme,None,tpe)::acc2)
+ then cut_noccur elimt' (LocalAssum (nme,tpe)::acc2)
else let acc3,ccl = decompose_prod_assum elimt in acc2 , acc3 , ccl
| App(_, _) | Rel _ -> acc2 , [] , elimt
| _ -> error_ind_scheme "" in
- let rec cut_occur elimt acc1 : Context.Rel.t * Context.Rel.t * Context.Rel.t * types =
+ let rec cut_occur elimt acc1 =
match kind_of_term elimt with
- | Prod(nme,tpe,c) when occur_rel 1 c -> cut_occur c ((nme,None,tpe)::acc1)
+ | Prod(nme,tpe,c) when occur_rel 1 c -> cut_occur c (LocalAssum (nme,tpe)::acc1)
| Prod(nme,tpe,c) -> let acc2,acc3,ccl = cut_noccur elimt [] in acc1,acc2,acc3,ccl
| App(_, _) | Rel _ -> acc1,[],[],elimt
| _ -> error_ind_scheme "" in
@@ -3596,6 +3644,7 @@ let exchange_hd_app subst_hd t =
- finish to fill in the elim_scheme: indarg/farg/args and finally indref. *)
let compute_elim_sig ?elimc elimt =
+ let open Context.Rel.Declaration in
let params_preds,branches,args_indargs,conclusion =
decompose_paramspred_branch_args elimt in
@@ -3629,8 +3678,8 @@ let compute_elim_sig ?elimc elimt =
(* 3- Look at last arg: is it the indarg? *)
ignore (
match List.hd args_indargs with
- | hiname,Some _,hi -> error_ind_scheme ""
- | hiname,None,hi ->
+ | LocalDef (hiname,_,hi) -> error_ind_scheme ""
+ | LocalAssum (hiname,hi) ->
let hi_ind, hi_args = decompose_app hi in
let hi_is_ind = (* hi est d'un type globalisable *)
match kind_of_term hi_ind with
@@ -3654,24 +3703,25 @@ let compute_elim_sig ?elimc elimt =
with Exit -> (* Ending by computing indref: *)
match !res.indarg with
| None -> !res (* No indref *)
- | Some ( _,Some _,_) -> error_ind_scheme ""
- | Some ( _,None,ind) ->
+ | Some (LocalDef _) -> error_ind_scheme ""
+ | Some (LocalAssum (_,ind)) ->
let indhd,indargs = decompose_app ind in
try {!res with indref = Some (global_of_constr indhd) }
with e when Errors.noncritical e ->
error "Cannot find the inductive type of the inductive scheme."
let compute_scheme_signature scheme names_info ind_type_guess =
+ let open Context.Rel.Declaration in
let f,l = decompose_app scheme.concl in
(* Vérifier que les arguments de Qi sont bien les xi. *)
let cond, check_concl =
match scheme.indarg with
- | Some (_,Some _,_) ->
+ | Some (LocalDef _) ->
error "Strange letin, cannot recognize an induction scheme."
| None -> (* Non standard scheme *)
let cond hd = Term.eq_constr hd ind_type_guess && not scheme.farg_in_concl
in (cond, fun _ _ -> ())
- | Some ( _,None,ind) -> (* Standard scheme from an inductive type *)
+ | Some (LocalAssum (_,ind)) -> (* Standard scheme from an inductive type *)
let indhd,indargs = decompose_app ind in
let cond hd = Term.eq_constr hd indhd in
let check_concl is_pred p =
@@ -3703,7 +3753,7 @@ let compute_scheme_signature scheme names_info ind_type_guess =
in
let rec find_branches p lbrch =
match lbrch with
- | (_,None,t)::brs ->
+ | LocalAssum (_,t) :: brs ->
(try
let lchck_brch = check_branch p t in
let n = List.fold_left
@@ -3716,7 +3766,7 @@ let compute_scheme_signature scheme names_info ind_type_guess =
lchck_brch in
(avoid,namesign) :: find_branches (p+1) brs
with Exit-> error_ind_scheme "the branches of")
- | (_,Some _,_)::_ -> error_ind_scheme "the branches of"
+ | LocalDef _ :: _ -> error_ind_scheme "the branches of"
| [] -> check_concl is_pred p; []
in
Array.of_list (find_branches 0 (List.rev scheme.branches))
@@ -3797,13 +3847,15 @@ let is_functional_induction elimc gl =
(* Wait the last moment to guess the eliminator so as to know if we
need a dependent one or not *)
-let get_eliminator elim dep s gl = match elim with
+let get_eliminator elim dep s gl =
+ let open Context.Rel.Declaration in
+ match elim with
| ElimUsing (elim,indsign) ->
Tacmach.New.project gl, (* bugged, should be computed *) true, elim, indsign
| ElimOver (isrec,id) ->
let evd, (elimc,elimt),_ as elims = guess_elim isrec dep s id gl in
let _, (l, s) = compute_elim_signature elims id in
- let branchlengthes = List.map (fun (_,b,c) -> assert (b=None); pi1 (decompose_prod_letin c)) (List.rev s.branches) in
+ let branchlengthes = List.map (fun d -> assert (is_local_assum d); pi1 (decompose_prod_letin (get_type d))) (List.rev s.branches) in
evd, isrec, ({elimindex = None; elimbody = elimc; elimrename = Some (isrec,Array.of_list branchlengthes)}, elimt), l
(* Instantiate all meta variables of elimclause using lid, some elts
@@ -3864,6 +3916,7 @@ let induction_tac with_evars params indvars elim gl =
induction applies with the induction hypotheses *)
let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
+ let open Context.Named.Declaration in
Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let env = Proofview.Goal.env gl in
@@ -3876,7 +3929,7 @@ let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
let s = Retyping.get_sort_family_of env sigma tmpcl in
let deps_cstr =
List.fold_left
- (fun a (id,b,_) -> if Option.is_empty b then (mkVar id)::a else a) [] deps in
+ (fun a decl -> if is_local_assum decl then (mkVar (get_id decl))::a else a) [] deps in
let (sigma, isrec, elim, indsign) = get_eliminator elim dep s (Proofview.Goal.assume gl) in
let branchletsigns =
let f (_,is_not_let,_,_) = is_not_let in
@@ -3956,6 +4009,7 @@ let induction_without_atomization isrec with_evars elim names lid =
(* assume that no occurrences are selected *)
let clear_unselected_context id inhyps cls gl =
+ let open Context.Named.Declaration in
if occur_var (Tacmach.pf_env gl) id (Tacmach.pf_concl gl) &&
cls.concl_occs == NoOccurrences
then errorlabstrm ""
@@ -3963,7 +4017,8 @@ let clear_unselected_context id inhyps cls gl =
++ str ".");
match cls.onhyps with
| Some hyps ->
- let to_erase (id',_,_ as d) =
+ let to_erase d =
+ let id' = get_id d in
if Id.List.mem id' inhyps then (* if selected, do not erase *) None
else
(* erase if not selected and dependent on id or selected hyps *)
@@ -4536,39 +4591,45 @@ let intros_transitivity n = Tacticals.New.tclTHEN intros (transitivity_gen n)
is solved by tac *)
(** d1 is the section variable in the global context, d2 in the goal context *)
-let interpretable_as_section_decl evd d1 d2 = match d2,d1 with
- | (_,Some _,_), (_,None,_) -> false
- | (_,Some b1,t1), (_,Some b2,t2) ->
+let interpretable_as_section_decl evd d1 d2 =
+ let open Context.Named.Declaration in
+ match d2, d1 with
+ | LocalDef _, LocalAssum _ -> false
+ | LocalDef (_,b1,t1), LocalDef (_,b2,t2) ->
e_eq_constr_univs evd b1 b2 && e_eq_constr_univs evd t1 t2
- | (_,None,t1), (_,_,t2) -> e_eq_constr_univs evd t1 t2
+ | LocalAssum (_,t1), d2 -> e_eq_constr_univs evd t1 (get_type d2)
let rec decompose len c t accu =
+ let open Context.Rel.Declaration in
if len = 0 then (c, t, accu)
else match kind_of_term c, kind_of_term t with
| Lambda (na, u, c), Prod (_, _, t) ->
- decompose (pred len) c t ((na, None, u) :: accu)
+ decompose (pred len) c t (LocalAssum (na, u) :: accu)
| LetIn (na, b, u, c), LetIn (_, _, _, t) ->
- decompose (pred len) c t ((na, Some b, u) :: accu)
+ decompose (pred len) c t (LocalDef (na, b, u) :: accu)
| _ -> assert false
-let rec shrink ctx sign c t accu = match ctx, sign with
-| [], [] -> (c, t, accu)
-| p :: ctx, (id, _, _) :: sign ->
- if noccurn 1 c then
- let c = subst1 mkProp c in
- let t = subst1 mkProp t in
- shrink ctx sign c t accu
- else
- let c = mkLambda_or_LetIn p c in
- let t = mkProd_or_LetIn p t in
- let accu = match p with
- | (_, None, _) -> mkVar id :: accu
- | (_, Some _, _) -> accu
+let rec shrink ctx sign c t accu =
+ let open Context.Rel.Declaration in
+ match ctx, sign with
+ | [], [] -> (c, t, accu)
+ | p :: ctx, decl :: sign ->
+ if noccurn 1 c then
+ let c = subst1 mkProp c in
+ let t = subst1 mkProp t in
+ shrink ctx sign c t accu
+ else
+ let c = mkLambda_or_LetIn p c in
+ let t = mkProd_or_LetIn p t in
+ let accu = if is_local_assum p then let open Context.Named.Declaration in
+ mkVar (get_id decl) :: accu
+ else accu
in
shrink ctx sign c t accu
| _ -> assert false
let shrink_entry sign const =
+ let open Context.Named.Declaration in
let open Entries in
let typ = match const.const_entry_type with
| None -> assert false
@@ -4589,6 +4650,7 @@ let abstract_subproof id gk tac =
let open Tacticals.New in
let open Tacmach.New in
let open Proofview.Notations in
+ let open Context.Named.Declaration in
Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let current_sign = Global.named_context()
@@ -4597,7 +4659,8 @@ let abstract_subproof id gk tac =
let evdref = ref sigma in
let sign,secsign =
List.fold_right
- (fun (id,_,_ as d) (s1,s2) ->
+ (fun d (s1,s2) ->
+ let id = get_id d in
if mem_named_context id current_sign &&
interpretable_as_section_decl evdref (Context.Named.lookup id current_sign) d
then (s1,push_named_context_val d s2)
diff --git a/toplevel/assumptions.ml b/toplevel/assumptions.ml
index cddc55515f..b29ceb78bd 100644
--- a/toplevel/assumptions.ml
+++ b/toplevel/assumptions.ml
@@ -23,6 +23,7 @@ open Declarations
open Mod_subst
open Globnames
open Printer
+open Context.Named.Declaration
(** For a constant c in a module sealed by an interface (M:T and
not M<:T), [Global.lookup_constant] may return a [constant_body]
@@ -145,7 +146,7 @@ let push (r : Context.Rel.Declaration.t) (ctx : Context.Rel.t) = r :: ctx
let rec traverse current ctx accu t = match kind_of_term t with
| Var id ->
- let body () = match Global.lookup_named id with (_, body, _) -> body in
+ let body () = Global.lookup_named id |> get_value in
traverse_object accu body (VarRef id)
| Const (kn, _) ->
let body () = Global.body_of_constant_body (lookup_constant kn) in
@@ -208,8 +209,8 @@ let assumptions ?(add_opaque=false) ?(add_transparent=false) st gr t =
let (_, graph, ax2ty) = traverse (label_of gr) t in
let fold obj _ accu = match obj with
| VarRef id ->
- let (_, body, t) = Global.lookup_named id in
- if Option.is_empty body then ContextObjectMap.add (Variable id) t accu
+ let decl = Global.lookup_named id in
+ if is_local_assum decl then ContextObjectMap.add (Variable id) t accu
else accu
| ConstRef kn ->
let cb = lookup_constant kn in
diff --git a/toplevel/auto_ind_decl.ml b/toplevel/auto_ind_decl.ml
index f0c7a39613..0755f8bcfd 100644
--- a/toplevel/auto_ind_decl.ml
+++ b/toplevel/auto_ind_decl.ml
@@ -25,6 +25,7 @@ open Tactics
open Ind_tables
open Misctypes
open Proofview.Notations
+open Context.Rel.Declaration
let out_punivs = Univ.out_punivs
@@ -146,17 +147,17 @@ let build_beq_scheme mode kn =
) ext_rel_list in
let eq_input = List.fold_left2
- ( fun a b (n,_,_) -> (* mkLambda(n,b,a) ) *)
+ ( fun a b decl -> (* mkLambda(n,b,a) ) *)
(* here I leave the Naming thingy so that the type of
the function is more readable for the user *)
- mkNamedLambda (eqName n) b a )
+ mkNamedLambda (eqName (get_name decl)) b a )
c (List.rev eqs_typ) lnamesparrec
in
- List.fold_left (fun a (n,_,t) ->(* mkLambda(n,t,a)) eq_input rel_list *)
+ List.fold_left (fun a decl ->(* mkLambda(n,t,a)) eq_input rel_list *)
(* Same here , hoping the auto renaming will do something good ;) *)
mkNamedLambda
- (match n with Name s -> s | Anonymous -> Id.of_string "A")
- t a) eq_input lnamesparrec
+ (match get_name decl with Name s -> s | Anonymous -> Id.of_string "A")
+ (get_type decl) a) eq_input lnamesparrec
in
let make_one_eq cur =
let u = Univ.Instance.empty in
@@ -248,7 +249,7 @@ let build_beq_scheme mode kn =
| 0 -> Lazy.force tt
| _ -> let eqs = Array.make nb_cstr_args (Lazy.force tt) in
for ndx = 0 to nb_cstr_args-1 do
- let _,_,cc = List.nth constrsi.(i).cs_args ndx in
+ let cc = get_type (List.nth constrsi.(i).cs_args ndx) in
let eqA, eff' = compute_A_equality rel_list
nparrec
(nparrec+3+2*nb_cstr_args)
@@ -267,14 +268,14 @@ let build_beq_scheme mode kn =
(Array.sub eqs 1 (nb_cstr_args - 1))
)
in
- (List.fold_left (fun a (p,q,r) -> mkLambda (p,r,a)) cc
+ (List.fold_left (fun a decl -> mkLambda (get_name decl, get_type decl, a)) cc
(constrsj.(j).cs_args)
)
- else ar2.(j) <- (List.fold_left (fun a (p,q,r) ->
- mkLambda (p,r,a)) (Lazy.force ff) (constrsj.(j).cs_args) )
+ else ar2.(j) <- (List.fold_left (fun a decl ->
+ mkLambda (get_name decl, get_type decl, a)) (Lazy.force ff) (constrsj.(j).cs_args) )
done;
- ar.(i) <- (List.fold_left (fun a (p,q,r) -> mkLambda (p,r,a))
+ ar.(i) <- (List.fold_left (fun a decl -> mkLambda (get_name decl, get_type decl, a))
(mkCase (ci,do_predicate rel_list nb_cstr_args,
mkVar (Id.of_string "Y") ,ar2))
(constrsi.(i).cs_args))
@@ -487,8 +488,8 @@ let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
create, from a list of ids [i1,i2,...,in] the list
[(in,eq_in,in_bl,in_al),,...,(i1,eq_i1,i1_bl_i1_al )]
*)
-let list_id l = List.fold_left ( fun a (n,_,t) -> let s' =
- match n with
+let list_id l = List.fold_left ( fun a decl -> let s' =
+ match get_name decl with
Name s -> Id.to_string s
| Anonymous -> "A" in
(Id.of_string s',Id.of_string ("eq_"^s'),
@@ -535,9 +536,9 @@ let compute_bl_goal ind lnamesparrec nparrec =
let eq_input = List.fold_left2 ( fun a (s,seq,_,_) b ->
mkNamedProd seq b a
) bl_input (List.rev list_id) (List.rev eqs_typ) in
- List.fold_left (fun a (n,_,t) -> mkNamedProd
- (match n with Name s -> s | Anonymous -> Id.of_string "A")
- t a) eq_input lnamesparrec
+ List.fold_left (fun a decl -> mkNamedProd
+ (match get_name decl with Name s -> s | Anonymous -> Id.of_string "A")
+ (get_type decl) a) eq_input lnamesparrec
in
let n = Id.of_string "x" and
m = Id.of_string "y" in
@@ -678,9 +679,9 @@ let compute_lb_goal ind lnamesparrec nparrec =
let eq_input = List.fold_left2 ( fun a (s,seq,_,_) b ->
mkNamedProd seq b a
) lb_input (List.rev list_id) (List.rev eqs_typ) in
- List.fold_left (fun a (n,_,t) -> mkNamedProd
- (match n with Name s -> s | Anonymous -> Id.of_string "A")
- t a) eq_input lnamesparrec
+ List.fold_left (fun a decl -> mkNamedProd
+ (match (get_name decl) with Name s -> s | Anonymous -> Id.of_string "A")
+ (get_type decl) a) eq_input lnamesparrec
in
let n = Id.of_string "x" and
m = Id.of_string "y" in
@@ -819,9 +820,9 @@ let compute_dec_goal ind lnamesparrec nparrec =
let eq_input = List.fold_left2 ( fun a (s,seq,_,_) b ->
mkNamedProd seq b a
) bl_input (List.rev list_id) (List.rev eqs_typ) in
- List.fold_left (fun a (n,_,t) -> mkNamedProd
- (match n with Name s -> s | Anonymous -> Id.of_string "A")
- t a) eq_input lnamesparrec
+ List.fold_left (fun a decl -> mkNamedProd
+ (match get_name decl with Name s -> s | Anonymous -> Id.of_string "A")
+ (get_type decl) a) eq_input lnamesparrec
in
let n = Id.of_string "x" and
m = Id.of_string "y" in
diff --git a/toplevel/classes.ml b/toplevel/classes.ml
index 6bb047af0d..2089bc9443 100644
--- a/toplevel/classes.ml
+++ b/toplevel/classes.ml
@@ -21,6 +21,7 @@ open Globnames
open Constrintern
open Constrexpr
open Sigma.Notations
+open Context.Rel.Declaration
(*i*)
open Decl_kinds
@@ -75,14 +76,14 @@ let mismatched_props env n m = mismatched_ctx_inst env Properties n m
let type_ctx_instance evars env ctx inst subst =
let rec aux (subst, instctx) l = function
- (na, b, t) :: ctx ->
- let t' = substl subst t in
+ decl :: ctx ->
+ let t' = substl subst (get_type decl) in
let c', l =
- match b with
- | None -> interp_casted_constr_evars env evars (List.hd l) t', List.tl l
- | Some b -> substl subst b, l
+ match decl with
+ | LocalAssum _ -> interp_casted_constr_evars env evars (List.hd l) t', List.tl l
+ | LocalDef (_,b,_) -> substl subst b, l
in
- let d = na, Some c', t' in
+ let d = get_name decl, Some c', t' in
aux (c' :: subst, d :: instctx) l ctx
| [] -> subst
in aux (subst, []) inst (List.rev ctx)
@@ -131,7 +132,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
match bk with
| Implicit ->
Implicit_quantifiers.implicit_application Id.Set.empty ~allow_partial:false
- (fun avoid (clname, (id, _, t)) ->
+ (fun avoid (clname, _) ->
match clname with
| Some (cl, b) ->
let t = CHole (Loc.ghost, None, Misctypes.IntroAnonymous, None) in
@@ -154,10 +155,11 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
let k, args = Typeclasses.dest_class_app (push_rel_context ctx'' env) c in
let cl, u = Typeclasses.typeclass_univ_instance k in
let _, args =
- List.fold_right (fun (na, b, t) (args, args') ->
- match b with
- | None -> (List.tl args, List.hd args :: args')
- | Some b -> (args, substl args' b :: args'))
+ List.fold_right (fun decl (args, args') ->
+ let open Context.Rel.Declaration in
+ match decl with
+ | LocalAssum _ -> (List.tl args, List.hd args :: args')
+ | LocalDef (_,b,_) -> (args, substl args' b :: args'))
(snd cl.cl_context) (args, [])
in
cl, u, c', ctx', ctx, len, imps, args
@@ -180,7 +182,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
if abstract then
begin
let subst = List.fold_left2
- (fun subst' s (_, b, _) -> if Option.is_empty b then s :: subst' else subst')
+ (fun subst' s decl -> if is_local_assum decl then s :: subst' else subst')
[] subst (snd k.cl_context)
in
let (_, ty_constr) = instance_constructor (k,u) subst in
@@ -224,10 +226,10 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
in
let props, rest =
List.fold_left
- (fun (props, rest) (id,b,_) ->
- if Option.is_empty b then
+ (fun (props, rest) decl ->
+ if is_local_assum decl then
try
- let is_id (id', _) = match id, get_id id' with
+ let is_id (id', _) = match get_name decl, get_id id' with
| Name id, (_, id') -> Id.equal id id'
| Anonymous, _ -> false
in
@@ -261,7 +263,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
None, termtype
| Some (Inl subst) ->
let subst = List.fold_left2
- (fun subst' s (_, b, _) -> if Option.is_empty b then s :: subst' else subst')
+ (fun subst' s decl -> if is_local_assum decl then s :: subst' else subst')
[] subst (k.cl_props @ snd k.cl_context)
in
let (app, ty_constr) = instance_constructor (k,u) subst in
@@ -344,9 +346,11 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
let named_of_rel_context l =
let acc, ctx =
List.fold_right
- (fun (na, b, t) (subst, ctx) ->
- let id = match na with Anonymous -> invalid_arg "named_of_rel_context" | Name id -> id in
- let d = (id, Option.map (substl subst) b, substl subst t) in
+ (fun decl (subst, ctx) ->
+ let id = match get_name decl with Anonymous -> invalid_arg "named_of_rel_context" | Name id -> id in
+ let d = match decl with
+ | LocalAssum (_,t) -> id, None, substl subst t
+ | LocalDef (_,b,t) -> id, Some (substl subst b), substl subst t in
(mkVar id :: subst, d :: ctx))
l ([], [])
in ctx
@@ -358,7 +362,7 @@ let context poly l =
let subst = Evarutil.evd_comb0 Evarutil.nf_evars_and_universes evars in
let fullctx = Context.Rel.map subst fullctx in
let ce t = Evarutil.check_evars env Evd.empty !evars t in
- let () = List.iter (fun (n, b, t) -> Option.iter ce b; ce t) fullctx in
+ let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) fullctx in
let ctx =
try named_of_rel_context fullctx
with e when Errors.noncritical e ->
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 18b2b1444d..02f29b155f 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -36,6 +36,7 @@ open Evarconv
open Indschemes
open Misctypes
open Vernacexpr
+open Context.Rel.Declaration
let do_universe poly l = Declare.do_universe poly l
let do_constraint poly l = Declare.do_constraint poly l
@@ -44,9 +45,9 @@ let rec under_binders env sigma f n c =
if Int.equal n 0 then snd (f env sigma c) else
match kind_of_term c with
| Lambda (x,t,c) ->
- mkLambda (x,t,under_binders (push_rel (x,None,t) env) sigma f (n-1) c)
+ mkLambda (x,t,under_binders (push_rel (LocalAssum (x,t)) env) sigma f (n-1) c)
| LetIn (x,b,t,c) ->
- mkLetIn (x,b,t,under_binders (push_rel (x,Some b,t) env) sigma f (n-1) c)
+ mkLetIn (x,b,t,under_binders (push_rel (LocalDef (x,b,t)) env) sigma f (n-1) c)
| _ -> assert false
let rec complete_conclusion a cs = function
@@ -259,6 +260,7 @@ let declare_assumptions idl is_coe k (c,ctx) pl imps impl_is_on nl =
List.rev refs, status
let do_assumptions_unbound_univs (_, poly, _ as kind) nl l =
+ let open Context.Named.Declaration in
let env = Global.env () in
let evdref = ref (Evd.from_env env) in
let l =
@@ -273,7 +275,7 @@ let do_assumptions_unbound_univs (_, poly, _ as kind) nl l =
let _,l = List.fold_map (fun (env,ienv) (is_coe,(idl,c)) ->
let (t,ctx),imps = interp_assumption evdref env ienv [] c in
let env =
- push_named_context (List.map (fun (_,id) -> (id,None,t)) idl) env in
+ push_named_context (List.map (fun (_,id) -> LocalAssum (id,t)) idl) env in
let ienv = List.fold_right (fun (_,id) ienv ->
let impls = compute_internalization_data env Variable t imps in
Id.Map.add id impls ienv) idl ienv in
@@ -335,7 +337,7 @@ let do_assumptions kind nl l = match l with
(* 3b| Mutual inductive definitions *)
let push_types env idl tl =
- List.fold_left2 (fun env id t -> Environ.push_rel (Name id,None,t) env)
+ List.fold_left2 (fun env id t -> Environ.push_rel (LocalAssum (Name id,t)) env)
env idl tl
type structured_one_inductive_expr = {
@@ -378,8 +380,8 @@ let mk_mltype_data evdref env assums arity indname =
(is_ml_type,indname,assums)
let prepare_param = function
- | (na,None,t) -> out_name na, LocalAssum t
- | (na,Some b,_) -> out_name na, LocalDef b
+ | LocalAssum (na,t) -> out_name na, Entries.LocalAssum t
+ | LocalDef (na,b,_) -> out_name na, Entries.LocalDef b
(** Make the arity conclusion flexible to avoid generating an upper bound universe now,
only if the universe does not appear anywhere else.
@@ -433,12 +435,12 @@ let interp_cstrs evdref env impls mldata arity ind =
let sign_level env evd sign =
fst (List.fold_right
- (fun (_,b,t as d) (lev,env) ->
- match b with
- | Some _ -> (lev, push_rel d env)
- | None ->
+ (fun d (lev,env) ->
+ match d with
+ | LocalDef _ -> lev, push_rel d env
+ | LocalAssum _ ->
let s = destSort (Reduction.whd_betadeltaiota env
- (nf_evar evd (Retyping.get_type_of env evd t)))
+ (nf_evar evd (Retyping.get_type_of env evd (get_type d))))
in
let u = univ_of_sort s in
(Univ.sup u lev, push_rel d env))
@@ -449,7 +451,7 @@ let sup_list min = List.fold_left Univ.sup min
let extract_level env evd min tys =
let sorts = List.map (fun ty ->
let ctx, concl = Reduction.dest_prod_assum env ty in
- sign_level env evd ((Anonymous, None, concl) :: ctx)) tys
+ sign_level env evd (LocalAssum (Anonymous, concl) :: ctx)) tys
in sup_list min sorts
let is_flexible_sort evd u =
@@ -555,8 +557,8 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
let indnames = List.map (fun ind -> ind.ind_name) indl in
(* Names of parameters as arguments of the inductive type (defs removed) *)
- let assums = List.filter(fun (_,b,_) -> Option.is_empty b) ctx_params in
- let params = List.map (fun (na,_,_) -> out_name na) assums in
+ let assums = List.filter is_local_assum ctx_params in
+ let params = List.map (fun decl -> out_name (get_name decl)) assums in
(* Interpret the arities *)
let arities = List.map (interp_ind_arity env_params evdref) indl in
@@ -876,12 +878,13 @@ let lt_ref = make_qref "Init.Peano.lt"
let rec telescope = function
| [] -> assert false
- | [(n, None, t)] -> t, [n, Some (mkRel 1), t], mkRel 1
- | (n, None, t) :: tl ->
+ | [LocalAssum (n, t)] -> t, [LocalDef (n, mkRel 1, t)], mkRel 1
+ | LocalAssum (n, t) :: tl ->
let ty, tys, (k, constr) =
List.fold_left
- (fun (ty, tys, (k, constr)) (n, b, t) ->
- let pred = mkLambda (n, t, ty) in
+ (fun (ty, tys, (k, constr)) decl ->
+ let t = get_type decl in
+ let pred = mkLambda (get_name decl, t, ty) in
let ty = Universes.constr_of_global (Lazy.force sigT).typ in
let intro = Universes.constr_of_global (Lazy.force sigT).intro in
let sigty = mkApp (ty, [|t; pred|]) in
@@ -890,21 +893,21 @@ let rec telescope = function
(t, [], (2, mkRel 1)) tl
in
let (last, subst) = List.fold_right2
- (fun pred (n, b, t) (prev, subst) ->
+ (fun pred decl (prev, subst) ->
+ let t = get_type decl in
let p1 = Universes.constr_of_global (Lazy.force sigT).proj1 in
let p2 = Universes.constr_of_global (Lazy.force sigT).proj2 in
let proj1 = applistc p1 [t; pred; prev] in
let proj2 = applistc p2 [t; pred; prev] in
- (lift 1 proj2, (n, Some proj1, t) :: subst))
+ (lift 1 proj2, LocalDef (get_name decl, proj1, t) :: subst))
(List.rev tys) tl (mkRel 1, [])
- in ty, ((n, Some last, t) :: subst), constr
+ in ty, (LocalDef (n, last, t) :: subst), constr
- | (n, Some b, t) :: tl -> let ty, subst, term = telescope tl in
- ty, ((n, Some b, t) :: subst), lift 1 term
+ | LocalDef (n, b, t) :: tl -> let ty, subst, term = telescope tl in
+ ty, (LocalDef (n, b, t) :: subst), lift 1 term
let nf_evar_context sigma ctx =
- List.map (fun (n, b, t) ->
- (n, Option.map (Evarutil.nf_evar sigma) b, Evarutil.nf_evar sigma t)) ctx
+ List.map (map_constr (Evarutil.nf_evar sigma)) ctx
let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
Coqlib.check_required_library ["Coq";"Program";"Wf"];
@@ -918,7 +921,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
let full_arity = it_mkProd_or_LetIn top_arity binders_rel in
let argtyp, letbinders, make = telescope binders_rel in
let argname = Id.of_string "recarg" in
- let arg = (Name argname, None, argtyp) in
+ let arg = LocalAssum (Name argname, argtyp) in
let binders = letbinders @ [arg] in
let binders_env = push_rel_context binders_rel env in
let rel, _ = interp_constr_evars_impls env evdref r in
@@ -933,7 +936,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
try
let ctx, ar = Reductionops.splay_prod_n env !evdref 2 relty in
match ctx, kind_of_term ar with
- | [(_, None, t); (_, None, u)], Sort (Prop Null)
+ | [LocalAssum (_,t); LocalAssum (_,u)], Sort (Prop Null)
when Reductionops.is_conv env !evdref t u -> t
| _, _ -> error ()
with e when Errors.noncritical e -> error ()
@@ -953,9 +956,9 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
in
let wf_proof = mkApp (delayed_force well_founded, [| argtyp ; wf_rel |]) in
let argid' = Id.of_string (Id.to_string argname ^ "'") in
- let wfarg len = (Name argid', None,
- mkSubset (Name argid') argtyp
- (wf_rel_fun (mkRel 1) (mkRel (len + 1))))
+ let wfarg len = LocalAssum (Name argid',
+ mkSubset (Name argid') argtyp
+ (wf_rel_fun (mkRel 1) (mkRel (len + 1))))
in
let intern_bl = wfarg 1 :: [arg] in
let _intern_env = push_rel_context intern_bl env in
@@ -969,22 +972,22 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
(* substitute the projection of wfarg for something,
now intern_arity is in wfarg :: arg *)
let intern_fun_arity_prod = it_mkProd_or_LetIn intern_arity [wfarg 1] in
- let intern_fun_binder = (Name (add_suffix recname "'"), None, intern_fun_arity_prod) in
+ let intern_fun_binder = LocalAssum (Name (add_suffix recname "'"), intern_fun_arity_prod) in
let curry_fun =
let wfpred = mkLambda (Name argid', argtyp, wf_rel_fun (mkRel 1) (mkRel (2 * len + 4))) in
let intro = (*FIXME*)Universes.constr_of_global (delayed_force build_sigma).Coqlib.intro in
let arg = mkApp (intro, [| argtyp; wfpred; lift 1 make; mkRel 1 |]) in
let app = mkApp (mkRel (2 * len + 2 (* recproof + orig binders + current binders *)), [| arg |]) in
let rcurry = mkApp (rel, [| measure; lift len measure |]) in
- let lam = (Name (Id.of_string "recproof"), None, rcurry) in
+ let lam = LocalAssum (Name (Id.of_string "recproof"), rcurry) in
let body = it_mkLambda_or_LetIn app (lam :: binders_rel) in
let ty = it_mkProd_or_LetIn (lift 1 top_arity) (lam :: binders_rel) in
- (Name recname, Some body, ty)
+ LocalDef (Name recname, body, ty)
in
let fun_bl = intern_fun_binder :: [arg] in
let lift_lets = Termops.lift_rel_context 1 letbinders in
let intern_body =
- let ctx = (Name recname, None, pi3 curry_fun) :: binders_rel in
+ let ctx = LocalAssum (Name recname, get_type curry_fun) :: binders_rel in
let (r, l, impls, scopes) =
Constrintern.compute_internalization_data env
Constrintern.Recursive full_arity impls
@@ -1046,6 +1049,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
evars_typ ctx evars ~hook)
let interp_recursive isfix fixl notations =
+ let open Context.Named.Declaration in
let env = Global.env() in
let fixnames = List.map (fun fix -> fix.fix_name) fixl in
@@ -1081,8 +1085,8 @@ let interp_recursive isfix fixl notations =
Typing.solve_evars env evdref app
with e when Errors.noncritical e -> t
in
- (id,None,fixprot) :: env'
- else (id,None,t) :: env')
+ LocalAssum (id,fixprot) :: env'
+ else LocalAssum (id,t) :: env')
[] fixnames fixtypes
in
let env_rec = push_named_context rec_sign env in
@@ -1104,7 +1108,7 @@ let interp_recursive isfix fixl notations =
let evd, nf = nf_evars_and_universes evd in
let fixdefs = List.map (Option.map nf) fixdefs in
let fixtypes = List.map nf fixtypes in
- let fixctxnames = List.map (fun (_,ctx) -> List.map pi1 ctx) fixctxs in
+ let fixctxnames = List.map (fun (_,ctx) -> List.map get_name ctx) fixctxs in
(* Build the fix declaration block *)
(env,rec_sign,all_universes,evd), (fixnames,fixdefs,fixtypes), List.combine3 fixctxnames fiximps fixannots
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index 61a6e10948..5fa51e06e4 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -14,14 +14,16 @@ open Vars
open Entries
open Declarations
open Cooking
+open Context.Rel.Declaration
(********************************)
(* Discharging mutual inductive *)
-let detype_param = function
- | (Name id,None,p) -> id, LocalAssum p
- | (Name id,Some p,_) -> id, LocalDef p
- | (Anonymous,_,_) -> anomaly (Pp.str "Unnamed inductive local variable")
+let detype_param =
+ function
+ | LocalAssum (Name id, p) -> id, Entries.LocalAssum p
+ | LocalDef (Name id, p,_) -> id, Entries.LocalDef p
+ | _ -> anomaly (Pp.str "Unnamed inductive local variable")
(* Replace
@@ -52,7 +54,7 @@ let abstract_inductive hyps nparams inds =
(* To be sure to be the same as before, should probably be moved to process_inductive *)
let params' = let (_,arity,_,_,_) = List.hd inds' in
let (params,_) = decompose_prod_n_assum nparams' arity in
- List.map detype_param params
+ List.map detype_param params
in
let ind'' =
List.map
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index 4a5f14917f..4a145481f7 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -23,22 +23,26 @@ open Cases
open Logic
open Printer
open Evd
+open Context.Rel.Declaration
(* This simplifies the typing context of Cases clauses *)
(* hope it does not disturb other typing contexts *)
let contract env lc =
let l = ref [] in
- let contract_context (na,c,t) env =
- match c with
- | Some c' when isRel c' ->
+ let contract_context decl env =
+ match decl with
+ | LocalDef (_,c',_) when isRel c' ->
l := (Vars.substl !l c') :: !l;
env
| _ ->
- let t' = Vars.substl !l t in
- let c' = Option.map (Vars.substl !l) c in
- let na' = named_hd env t' na in
+ let t' = Vars.substl !l (get_type decl) in
+ let c' = Option.map (Vars.substl !l) (get_value decl) in
+ let na' = named_hd env t' (get_name decl) in
l := (mkRel 1) :: List.map (Vars.lift 1) !l;
- push_rel (na',c',t') env in
+ match c' with
+ | None -> push_rel (LocalAssum (na',t')) env
+ | Some c' -> push_rel (LocalDef (na',c',t')) env
+ in
let env = process_rel_context contract_context env in
(env, List.map (Vars.substl !l) lc)
@@ -136,9 +140,9 @@ let pr_explicit env sigma t1 t2 = pr_explicit_aux env sigma t1 t2 explicit_flags
let pr_db env i =
try
- match lookup_rel i env with
- Name id, _, _ -> pr_id id
- | Anonymous, _, _ -> str "<>"
+ match lookup_rel i env |> get_name with
+ | Name id -> pr_id id
+ | Anonymous -> str "<>"
with Not_found -> str "UNBOUND_REL_" ++ int i
let explain_unbound_rel env sigma n =
diff --git a/toplevel/indschemes.ml b/toplevel/indschemes.ml
index c4ac0e4112..251d14af79 100644
--- a/toplevel/indschemes.ml
+++ b/toplevel/indschemes.ml
@@ -38,6 +38,7 @@ open Ind_tables
open Auto_ind_decl
open Eqschemes
open Elimschemes
+open Context.Rel.Declaration
(* Flags governing automatic synthesis of schemes *)
@@ -463,7 +464,7 @@ let build_combined_scheme env schemes =
in
let ctx, _ =
list_split_rev_at prods
- (List.rev_map (fun (x, y) -> x, None, y) ctx) in
+ (List.rev_map (fun (x, y) -> LocalAssum (x, y)) ctx) in
let typ = it_mkProd_wo_LetIn concl_typ ctx in
let body = it_mkLambda_or_LetIn concl_bod ctx in
(body, typ)
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index 0ea9f959f6..0e8d224e42 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -54,7 +54,8 @@ type oblinfo =
(** Substitute evar references in t using De Bruijn indices,
where n binders were passed through. *)
-let subst_evar_constr evs n idf t =
+let subst_evar_constr evs n idf t =
+ let open Context.Named.Declaration in
let seen = ref Int.Set.empty in
let transparent = ref Id.Set.empty in
let evar_info id = List.assoc_f Evar.equal id evs in
@@ -78,9 +79,9 @@ let subst_evar_constr evs n idf t =
let args =
let rec aux hyps args acc =
match hyps, args with
- ((_, None, _) :: tlh), (c :: tla) ->
+ (LocalAssum _ :: tlh), (c :: tla) ->
aux tlh tla ((substrec (depth, fixrels) c) :: acc)
- | ((_, Some _, _) :: tlh), (_ :: tla) ->
+ | (LocalDef _ :: tlh), (_ :: tla) ->
aux tlh tla acc
| [], [] -> acc
| _, _ -> acc (*failwith "subst_evars: invalid argument"*)
@@ -116,22 +117,23 @@ let subst_vars acc n t =
Changes evars and hypothesis references to variable references.
*)
let etype_of_evar evs hyps concl =
+ let open Context.Named.Declaration in
let rec aux acc n = function
- (id, copt, t) :: tl ->
- let t', s, trans = subst_evar_constr evs n mkVar t in
+ decl :: tl ->
+ let t', s, trans = subst_evar_constr evs n mkVar (get_type decl) in
let t'' = subst_vars acc 0 t' in
- let rest, s', trans' = aux (id :: acc) (succ n) tl in
+ let rest, s', trans' = aux (get_id decl :: acc) (succ n) tl in
let s' = Int.Set.union s s' in
let trans' = Id.Set.union trans trans' in
- (match copt with
- Some c ->
+ (match decl with
+ | LocalDef (id,c,_) ->
let c', s'', trans'' = subst_evar_constr evs n mkVar c in
let c' = subst_vars acc 0 c' in
- mkNamedProd_or_LetIn (id, Some c', t'') rest,
+ mkNamedProd_or_LetIn (LocalDef (id, c', t'')) rest,
Int.Set.union s'' s',
Id.Set.union trans'' trans'
- | None ->
- mkNamedProd_or_LetIn (id, None, t'') rest, s', trans')
+ | LocalAssum (id,_) ->
+ mkNamedProd_or_LetIn (LocalAssum (id, t'')) rest, s', trans')
| [] ->
let t', s, trans = subst_evar_constr evs n mkVar concl in
subst_vars acc 0 t', s, trans
@@ -589,15 +591,16 @@ let declare_mutual_definition l =
Lemmas.call_hook fix_exn first.prg_hook local gr first.prg_ctx;
List.iter progmap_remove l; kn
-let shrink_body c =
+let shrink_body c =
+ let open Context.Rel.Declaration in
let ctx, b = decompose_lam_assum c in
let b', n, args =
- List.fold_left (fun (b, i, args) (n, u, t) ->
+ List.fold_left (fun (b, i, args) decl ->
if noccurn 1 b then
subst1 mkProp b, succ i, args
else
- let args = if Option.is_empty u then mkRel i :: args else args in
- mkLambda_or_LetIn (n, u, t) b, succ i, args)
+ let args = if is_local_assum decl then mkRel i :: args else args in
+ mkLambda_or_LetIn decl b, succ i, args)
(b, 1, []) ctx
in ctx, b', Array.of_list args
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 7ae2030343..facc8b75d5 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -24,6 +24,7 @@ open Type_errors
open Constrexpr
open Constrexpr_ops
open Goptions
+open Context.Rel.Declaration
(********** definition d'un record (structure) **************)
@@ -68,16 +69,19 @@ let interp_fields_evars env evars impls_env nots l =
| Anonymous -> impls
| Name id -> Id.Map.add id (compute_internalization_data env Constrintern.Method t' impl) impls
in
- let d = (i,b',t') in
+ let d = match b' with
+ | None -> LocalAssum (i,t')
+ | Some b' -> LocalDef (i,b',t')
+ in
List.iter (Metasyntax.set_notation_for_interpretation impls) no;
(push_rel d env, impl :: uimpls, d::params, impls))
(env, [], [], impls_env) nots l
let compute_constructor_level evars env l =
- List.fold_right (fun (n,b,t as d) (env, univ) ->
+ List.fold_right (fun d (env, univ) ->
let univ =
- if b = None then
- let s = Retyping.get_sort_of env evars t in
+ if is_local_assum d then
+ let s = Retyping.get_sort_of env evars (get_type d) in
Univ.sup (univ_of_sort s) univ
else univ
in (push_rel d env, univ))
@@ -122,7 +126,7 @@ let typecheck_params_and_fields def id pl t ps nots fs =
mkSort (Evarutil.evd_comb0 (Evd.new_sort_variable uvarkind) evars), false
in
let fullarity = it_mkProd_or_LetIn t' newps in
- let env_ar = push_rel_context newps (push_rel (Name id,None,fullarity) env0) in
+ let env_ar = push_rel_context newps (push_rel (LocalAssum (Name id,fullarity)) env0) in
let env2,impls,newfs,data =
interp_fields_evars env_ar evars impls_env nots (binders_of_decls fs)
in
@@ -150,17 +154,17 @@ let typecheck_params_and_fields def id pl t ps nots fs =
let newps = Context.Rel.map nf newps in
let newfs = Context.Rel.map nf newfs in
let ce t = Evarutil.check_evars env0 Evd.empty evars t in
- List.iter (fun (n, b, t) -> Option.iter ce b; ce t) (List.rev newps);
- List.iter (fun (n, b, t) -> Option.iter ce b; ce t) (List.rev newfs);
+ List.iter (iter_constr ce) (List.rev newps);
+ List.iter (iter_constr ce) (List.rev newfs);
Evd.universe_context ?names:pl evars, nf arity, template, imps, newps, impls, newfs
-let degenerate_decl (na,b,t) =
- let id = match na with
+let degenerate_decl decl =
+ let id = match get_name decl with
| Name id -> id
| Anonymous -> anomaly (Pp.str "Unnamed record variable") in
- match b with
- | None -> (id, LocalAssum t)
- | Some b -> (id, LocalDef b)
+ match decl with
+ | LocalAssum (_,t) -> (id, Entries.LocalAssum t)
+ | LocalDef (_,b,_) -> (id, Entries.LocalDef b)
type record_error =
| MissingProj of Id.t * Id.t list
@@ -264,23 +268,25 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
in
let (_,_,kinds,sp_projs,_) =
List.fold_left3
- (fun (nfi,i,kinds,sp_projs,subst) coe (fi,optci,ti) impls ->
+ (fun (nfi,i,kinds,sp_projs,subst) coe decl impls ->
+ let fi = get_name decl in
+ let ti = get_type decl in
let (sp_projs,i,subst) =
match fi with
| Anonymous ->
(None::sp_projs,i,NoProjection fi::subst)
| Name fid -> try
let kn, term =
- if optci = None && primitive then
+ if is_local_assum decl && primitive then
(** Already defined in the kernel silently *)
let kn = destConstRef (Nametab.locate (Libnames.qualid_of_ident fid)) in
Declare.definition_message fid;
kn, mkProj (Projection.make kn false,mkRel 1)
else
let ccl = subst_projection fid subst ti in
- let body = match optci with
- | Some ci -> subst_projection fid subst ci
- | None ->
+ let body = match decl with
+ | LocalDef (_,ci,_) -> subst_projection fid subst ci
+ | LocalAssum _ ->
(* [ccl] is defined in context [params;x:rp] *)
(* [ccl'] is defined in context [params;x:rp;x:rp] *)
let ccl' = liftn 1 2 ccl in
@@ -322,28 +328,28 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
let cl = Class.class_of_global (IndRef indsp) in
Class.try_add_new_coercion_with_source refi ~local:false poly ~source:cl
end;
- let i = if Option.is_empty optci then i+1 else i in
+ let i = if is_local_assum decl then i+1 else i in
(Some kn::sp_projs, i, Projection term::subst)
with NotDefinable why ->
warning_or_error coe indsp why;
(None::sp_projs,i,NoProjection fi::subst) in
- (nfi-1,i,(fi, Option.is_empty optci)::kinds,sp_projs,subst))
+ (nfi-1,i,(fi, is_local_assum decl)::kinds,sp_projs,subst))
(List.length fields,0,[],[],[]) coers (List.rev fields) (List.rev fieldimpls)
in (kinds,sp_projs)
let structure_signature ctx =
let rec deps_to_evar evm l =
match l with [] -> Evd.empty
- | [(_,_,typ)] ->
+ | [decl] ->
let env = Environ.empty_named_context_val in
- let (evm, _) = Evarutil.new_pure_evar env evm typ in
+ let (evm, _) = Evarutil.new_pure_evar env evm (get_type decl) in
evm
- | (_,_,typ)::tl ->
+ | decl::tl ->
let env = Environ.empty_named_context_val in
- let (evm, ev) = Evarutil.new_pure_evar env evm typ in
+ let (evm, ev) = Evarutil.new_pure_evar env evm (get_type decl) in
let new_tl = Util.List.map_i
- (fun pos (n,c,t) -> n,c,
- Termops.replace_term (mkRel pos) (mkEvar(ev,[||])) t) 1 tl in
+ (fun pos decl ->
+ map_type (fun t -> Termops.replace_term (mkRel pos) (mkEvar(ev,[||])) t) decl) 1 tl in
deps_to_evar evm new_tl in
deps_to_evar Evd.empty (List.rev ctx)
@@ -391,7 +397,7 @@ let implicits_of_context ctx =
| Name n -> Some n
| Anonymous -> None
in ExplByPos (i, explname), (true, true, true))
- 1 (List.rev (Anonymous :: (List.map pi1 ctx)))
+ 1 (List.rev (Anonymous :: (List.map get_name ctx)))
let declare_class finite def poly ctx id idbuild paramimpls params arity
template fieldimpls fields ?(kind=StructureComponent) is_coe coers priorities sign =
@@ -404,7 +410,7 @@ let declare_class finite def poly ctx id idbuild paramimpls params arity
let binder_name = Namegen.next_ident_away (snd id) (Termops.ids_of_context (Global.env())) in
let impl, projs =
match fields with
- | [(Name proj_name, _, field)] when def ->
+ | [LocalAssum (Name proj_name, field) | LocalDef (Name proj_name, _, field)] when def ->
let class_body = it_mkLambda_or_LetIn field params in
let _class_type = it_mkProd_or_LetIn arity params in
let class_entry =
@@ -445,13 +451,13 @@ let declare_class finite def poly ctx id idbuild paramimpls params arity
if b then Backward, pri else Forward, pri) coe)
coers priorities
in
- let l = List.map3 (fun (id, _, _) b y -> (id, b, y))
+ let l = List.map3 (fun decl b y -> get_name decl, b, y)
(List.rev fields) coers (Recordops.lookup_projections ind)
in IndRef ind, l
in
let ctx_context =
- List.map (fun (na, b, t) ->
- match Typeclasses.class_of_constr t with
+ List.map (fun decl ->
+ match Typeclasses.class_of_constr (get_type decl) with
| Some (_, ((cl,_), _)) -> Some (cl.cl_impl, true)
| None -> None)
params, params
@@ -473,7 +479,7 @@ let add_constant_class cst =
let tc =
{ cl_impl = ConstRef cst;
cl_context = (List.map (const None) ctx, ctx);
- cl_props = [(Anonymous, None, arity)];
+ cl_props = [LocalAssum (Anonymous, arity)];
cl_projs = [];
cl_strict = !typeclasses_strict;
cl_unique = !typeclasses_unique
@@ -487,8 +493,8 @@ let add_inductive_class ind =
let ctx = oneind.mind_arity_ctxt in
let inst = Univ.UContext.instance mind.mind_universes in
let map = function
- | (_, Some _, _) -> None
- | (_, None, t) -> Some (lazy t)
+ | LocalDef _ -> None
+ | LocalAssum (_, t) -> Some (lazy t)
in
let args = List.map_filter map ctx in
let ty = Inductive.type_of_inductive_knowing_parameters
@@ -498,7 +504,7 @@ let add_inductive_class ind =
in
{ cl_impl = IndRef ind;
cl_context = List.map (const None) ctx, ctx;
- cl_props = [Anonymous, None, ty];
+ cl_props = [LocalAssum (Anonymous, ty)];
cl_projs = [];
cl_strict = !typeclasses_strict;
cl_unique = !typeclasses_unique }
diff --git a/toplevel/search.ml b/toplevel/search.ml
index 89e0eb88ac..646e2e08ac 100644
--- a/toplevel/search.ml
+++ b/toplevel/search.ml
@@ -67,7 +67,9 @@ let iter_constructors indsp u fn env nconstr =
fn (ConstructRef (indsp, i)) env typ
done
-let iter_named_context_name_type f = List.iter (fun (nme,_,typ) -> f nme typ)
+let iter_named_context_name_type f =
+ let open Context.Named.Declaration in
+ List.iter (fun decl -> f (get_id decl) (get_type decl))
(* General search over hypothesis of a goal *)
let iter_hypothesis glnum (fn : global_reference -> env -> constr -> unit) =
@@ -79,12 +81,13 @@ let iter_hypothesis glnum (fn : global_reference -> env -> constr -> unit) =
(* General search over declarations *)
let iter_declarations (fn : global_reference -> env -> constr -> unit) =
+ let open Context.Named.Declaration in
let env = Global.env () in
let iter_obj (sp, kn) lobj = match object_tag lobj with
| "VARIABLE" ->
begin try
- let (id, _, typ) = Global.lookup_named (basename sp) in
- fn (VarRef id) env typ
+ let decl = Global.lookup_named (basename sp) in
+ fn (VarRef (get_id decl)) env (get_type decl)
with Not_found -> (* we are in a section *) () end
| "CONSTANT" ->
let cst = Global.constant_of_delta_kn kn in
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 0f81943e2c..8b3e118485 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -871,13 +871,14 @@ let vernac_set_end_tac tac =
(* TO DO verifier s'il faut pas mettre exist s | TacId s ici*)
let vernac_set_used_variables e =
+ let open Context.Named.Declaration in
let env = Global.env () in
let tys =
List.map snd (Proof.initial_goals (Proof_global.give_me_the_proof ())) in
let l = Proof_using.process_expr env e tys in
let vars = Environ.named_context env in
List.iter (fun id ->
- if not (List.exists (fun (id',_,_) -> Id.equal id id') vars) then
+ if not (List.exists (Id.equal id % get_id) vars) then
errorlabstrm "vernac_set_used_variables"
(str "Unknown variable: " ++ pr_id id))
l;
@@ -1568,6 +1569,7 @@ exception NoHyp
We only print the type and a small statement to this comes from the
goal. Precondition: there must be at least one current goal. *)
let print_about_hyp_globs ref_or_by_not glnumopt =
+ let open Context.Named.Declaration in
try
let gl,id =
match glnumopt,ref_or_by_not with
@@ -1580,11 +1582,11 @@ let print_about_hyp_globs ref_or_by_not glnumopt =
(str "No such goal: " ++ int n ++ str "."))
| _ , _ -> raise NoHyp in
let hyps = pf_hyps gl in
- let (id,bdyopt,typ) = Context.Named.lookup id hyps in
- let natureofid = match bdyopt with
- | None -> "Hypothesis"
- | Some bdy ->"Constant (let in)" in
- v 0 (pr_id id ++ str":" ++ pr_constr typ ++ fnl() ++ fnl()
+ let decl = Context.Named.lookup id hyps in
+ let natureofid = match decl with
+ | LocalAssum _ -> "Hypothesis"
+ | LocalDef (_,bdy,_) ->"Constant (let in)" in
+ v 0 (pr_id id ++ str":" ++ pr_constr (get_type decl) ++ fnl() ++ fnl()
++ str natureofid ++ str " of the goal context.")
with (* fallback to globals *)
| NoHyp | Not_found -> print_about ref_or_by_not
--
cgit v1.2.3
From 5dfb5d5e48c86dabd17ee2167c6fd5304c788474 Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Tue, 9 Feb 2016 18:07:53 +0100
Subject: REFORMATTING: kernel/context.ml{,i}
---
kernel/context.ml | 718 +++++++++++++++++++++++++++--------------------------
kernel/context.mli | 8 +-
2 files changed, 364 insertions(+), 362 deletions(-)
diff --git a/kernel/context.ml b/kernel/context.ml
index cc1e6f1762..4e53b73a28 100644
--- a/kernel/context.ml
+++ b/kernel/context.ml
@@ -32,380 +32,382 @@ open Names
(** Representation of contexts that can capture anonymous as well as non-anonymous variables.
Individual declarations are then designated by de Bruijn indexes. *)
module Rel =
+struct
+ (** Representation of {e local declarations}. *)
+ module Declaration =
struct
- (** Representation of {e local declarations}. *)
- module Declaration =
- struct
- (* local declaration *)
- type t = LocalAssum of Name.t * Constr.t (* local assumption *)
- | LocalDef of Name.t * Constr.t * Constr.t (* local definition *)
-
- (** Return the name bound by a given declaration. *)
- let get_name = function
- | LocalAssum (na,_)
- | LocalDef (na,_,_) -> na
-
- (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
- let get_value = function
- | LocalAssum _ -> None
- | LocalDef (_,v,_) -> Some v
-
- (** Return the type of the name bound by a given declaration. *)
- let get_type = function
- | LocalAssum (_,ty)
- | LocalDef (_,_,ty) -> ty
-
- (** Set the name that is bound by a given declaration. *)
- let set_name na = function
- | LocalAssum (_,ty) -> LocalAssum (na, ty)
- | LocalDef (_,v,ty) -> LocalDef (na, v, ty)
-
- (** Set the type of the bound variable in a given declaration. *)
- let set_type ty = function
- | LocalAssum (na,_) -> LocalAssum (na, ty)
- | LocalDef (na,v,_) -> LocalDef (na, v, ty)
-
- (** Return [true] iff a given declaration is a local assumption. *)
- let is_local_assum = function
- | LocalAssum _ -> true
- | LocalDef _ -> false
-
- (** Return [true] iff a given declaration is a local definition. *)
- let is_local_def = function
- | LocalAssum _ -> false
- | LocalDef _ -> true
-
- (** Check whether any term in a given declaration satisfies a given predicate. *)
- let exists f = function
- | LocalAssum (_, ty) -> f ty
- | LocalDef (_, v, ty) -> f v || f ty
-
- (** Check whether all terms in a given declaration satisfy a given predicate. *)
- let for_all f = function
- | LocalAssum (_, ty) -> f ty
- | LocalDef (_, v, ty) -> f v && f ty
-
- (** Check whether the two given declarations are equal. *)
- let equal decl1 decl2 =
- match decl1, decl2 with
- | LocalAssum (n1,ty1), LocalAssum (n2, ty2) ->
- Name.equal n1 n2 && Constr.equal ty1 ty2
- | LocalDef (n1,v1,ty1), LocalDef (n2,v2,ty2) ->
- Name.equal n1 n2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
- | _ ->
- false
-
- (** Map the name bound by a given declaration. *)
- let map_name f = function
- | LocalAssum (na, ty) as decl ->
- let na' = f na in
- if na == na' then decl else LocalAssum (na', ty)
- | LocalDef (na, v, ty) as decl ->
- let na' = f na in
- if na == na' then decl else LocalDef (na', v, ty)
-
- (** For local assumptions, this function returns the original local assumptions.
- For local definitions, this function maps the value in the local definition. *)
- let map_value f = function
- | LocalAssum _ as decl -> decl
- | LocalDef (na, v, t) as decl ->
- let v' = f v in
- if v == v' then decl else LocalDef (na, v', t)
-
- (** Map the type of the name bound by a given declaration. *)
- let map_type f = function
- | LocalAssum (na, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalAssum (na, ty')
- | LocalDef (na, v, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalDef (na, v, ty')
-
- (** Map all terms in a given declaration. *)
- let map_constr f = function
- | LocalAssum (na, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalAssum (na, ty')
- | LocalDef (na, v, ty) as decl ->
- let v' = f v in
- let ty' = f ty in
- if v == v' && ty == ty' then decl else LocalDef (na, v', ty')
-
- (** Perform a given action on all terms in a given declaration. *)
- let iter_constr f = function
- | LocalAssum (_,ty) -> f ty
- | LocalDef (_,v,ty) -> f v; f ty
-
- (** Reduce all terms in a given declaration to a single value. *)
- let fold f decl acc =
- match decl with
- | LocalAssum (n,ty) -> f ty acc
- | LocalDef (n,v,ty) -> f ty (f v acc)
-
- let to_tuple = function
- | LocalAssum (na, ty) -> na, None, ty
- | LocalDef (na, v, ty) -> na, Some v, ty
-
- let of_tuple = function
- | n, None, ty -> LocalAssum (n,ty)
- | n, Some v, ty -> LocalDef (n,v,ty)
- end
-
- (** Rel-context is represented as a list of declarations.
- Inner-most declarations are at the beginning of the list.
- Outer-most declarations are at the end of the list. *)
- type t = Declaration.t list
+ (* local declaration *)
+ type t =
+ | LocalAssum of Name.t * Constr.t (** name, type *)
+ | LocalDef of Name.t * Constr.t * Constr.t (** name, value, type *)
+
+ (** Return the name bound by a given declaration. *)
+ let get_name = function
+ | LocalAssum (na,_)
+ | LocalDef (na,_,_) -> na
+
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ let get_value = function
+ | LocalAssum _ -> None
+ | LocalDef (_,v,_) -> Some v
+
+ (** Return the type of the name bound by a given declaration. *)
+ let get_type = function
+ | LocalAssum (_,ty)
+ | LocalDef (_,_,ty) -> ty
+
+ (** Set the name that is bound by a given declaration. *)
+ let set_name na = function
+ | LocalAssum (_,ty) -> LocalAssum (na, ty)
+ | LocalDef (_,v,ty) -> LocalDef (na, v, ty)
+
+ (** Set the type of the bound variable in a given declaration. *)
+ let set_type ty = function
+ | LocalAssum (na,_) -> LocalAssum (na, ty)
+ | LocalDef (na,v,_) -> LocalDef (na, v, ty)
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ let is_local_assum = function
+ | LocalAssum _ -> true
+ | LocalDef _ -> false
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ let is_local_def = function
+ | LocalAssum _ -> false
+ | LocalDef _ -> true
+
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ let exists f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v || f ty
+
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ let for_all f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v && f ty
+
+ (** Check whether the two given declarations are equal. *)
+ let equal decl1 decl2 =
+ match decl1, decl2 with
+ | LocalAssum (n1,ty1), LocalAssum (n2, ty2) ->
+ Name.equal n1 n2 && Constr.equal ty1 ty2
+ | LocalDef (n1,v1,ty1), LocalDef (n2,v2,ty2) ->
+ Name.equal n1 n2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
+ | _ ->
+ false
+
+ (** Map the name bound by a given declaration. *)
+ let map_name f = function
+ | LocalAssum (na, ty) as decl ->
+ let na' = f na in
+ if na == na' then decl else LocalAssum (na', ty)
+ | LocalDef (na, v, ty) as decl ->
+ let na' = f na in
+ if na == na' then decl else LocalDef (na', v, ty)
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ let map_value f = function
+ | LocalAssum _ as decl -> decl
+ | LocalDef (na, v, t) as decl ->
+ let v' = f v in
+ if v == v' then decl else LocalDef (na, v', t)
+
+ (** Map the type of the name bound by a given declaration. *)
+ let map_type f = function
+ | LocalAssum (na, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (na, ty')
+ | LocalDef (na, v, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalDef (na, v, ty')
- (** empty rel-context *)
- let empty = []
-
- (** Return a new rel-context enriched by with a given inner-most declaration. *)
- let add d ctx = d :: ctx
-
- (** Return the number of {e local declarations} in a given context. *)
- let length = List.length
-
- (** [extended_rel_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
- with n = |Δ| and with the local definitions of [Γ] skipped in
- [args]. Example: for [x:T,y:=c,z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
- let nhyps =
- let open Declaration in
- let rec nhyps acc = function
- | [] -> acc
- | LocalAssum _ :: hyps -> nhyps (succ acc) hyps
- | LocalDef _ :: hyps -> nhyps acc hyps
- in
- nhyps 0
-
- (** Return a declaration designated by a given de Bruijn index.
- @raise Not_found if the designated de Bruijn index is not present in the designated rel-context. *)
- let rec lookup n ctx =
- match n, ctx with
- | 1, decl :: _ -> decl
- | n, _ :: sign -> lookup (n-1) sign
- | _, [] -> raise Not_found
-
- (** Check whether given two rel-contexts are equal. *)
- let equal = List.equal Declaration.equal
-
- (** Map all terms in a given rel-context. *)
- let map f = List.smartmap (Declaration.map_constr f)
-
- (** Perform a given action on every declaration in a given rel-context. *)
- let iter f = List.iter (Declaration.iter_constr f)
-
- (** Reduce all terms in a given rel-context to a single value.
- Innermost declarations are processed first. *)
- let fold_inside f ~init = List.fold_left f init
-
- (** Reduce all terms in a given rel-context to a single value.
- Outermost declarations are processed first. *)
- let fold_outside f l ~init = List.fold_right f l init
-
- (** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
- and each {e local definition} is mapped to [false]. *)
- let to_tags =
- let rec aux l = function
- | [] -> l
- | Declaration.LocalDef _ :: ctx -> aux (true::l) ctx
- | Declaration.LocalAssum _ :: ctx -> aux (false::l) ctx
- in aux []
-
- (** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
- with n = |Δ| and with the {e local definitions} of [Γ] skipped in
- [args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
- let to_extended_list n =
- let rec reln l p = function
- | Declaration.LocalAssum _ :: hyps -> reln (Constr.mkRel (n+p) :: l) (p+1) hyps
- | Declaration.LocalDef _ :: hyps -> reln l (p+1) hyps
- | [] -> l
- in
- reln [] 1
-
- (** [extended_vect n Γ] does the same, returning instead an array. *)
- let to_extended_vect n hyps = Array.of_list (to_extended_list n hyps)
+ (** Map all terms in a given declaration. *)
+ let map_constr f = function
+ | LocalAssum (na, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (na, ty')
+ | LocalDef (na, v, ty) as decl ->
+ let v' = f v in
+ let ty' = f ty in
+ if v == v' && ty == ty' then decl else LocalDef (na, v', ty')
+
+ (** Perform a given action on all terms in a given declaration. *)
+ let iter_constr f = function
+ | LocalAssum (_,ty) -> f ty
+ | LocalDef (_,v,ty) -> f v; f ty
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f decl acc =
+ match decl with
+ | LocalAssum (n,ty) -> f ty acc
+ | LocalDef (n,v,ty) -> f ty (f v acc)
+
+ let to_tuple = function
+ | LocalAssum (na, ty) -> na, None, ty
+ | LocalDef (na, v, ty) -> na, Some v, ty
+
+ let of_tuple = function
+ | n, None, ty -> LocalAssum (n,ty)
+ | n, Some v, ty -> LocalDef (n,v,ty)
end
+ (** Rel-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Declaration.t list
+
+ (** empty rel-context *)
+ let empty = []
+
+ (** Return a new rel-context enriched by with a given inner-most declaration. *)
+ let add d ctx = d :: ctx
+
+ (** Return the number of {e local declarations} in a given context. *)
+ let length = List.length
+
+ (** [extended_rel_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the local definitions of [Γ] skipped in
+ [args]. Example: for [x:T,y:=c,z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ let nhyps =
+ let open Declaration in
+ let rec nhyps acc = function
+ | [] -> acc
+ | LocalAssum _ :: hyps -> nhyps (succ acc) hyps
+ | LocalDef _ :: hyps -> nhyps acc hyps
+ in
+ nhyps 0
+
+ (** Return a declaration designated by a given de Bruijn index.
+ @raise Not_found if the designated de Bruijn index is not present in the designated rel-context. *)
+ let rec lookup n ctx =
+ match n, ctx with
+ | 1, decl :: _ -> decl
+ | n, _ :: sign -> lookup (n-1) sign
+ | _, [] -> raise Not_found
+
+ (** Check whether given two rel-contexts are equal. *)
+ let equal = List.equal Declaration.equal
+
+ (** Map all terms in a given rel-context. *)
+ let map f = List.smartmap (Declaration.map_constr f)
+
+ (** Perform a given action on every declaration in a given rel-context. *)
+ let iter f = List.iter (Declaration.iter_constr f)
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Innermost declarations are processed first. *)
+ let fold_inside f ~init = List.fold_left f init
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Outermost declarations are processed first. *)
+ let fold_outside f l ~init = List.fold_right f l init
+
+ (** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
+ and each {e local definition} is mapped to [false]. *)
+ let to_tags =
+ let rec aux l = function
+ | [] -> l
+ | Declaration.LocalDef _ :: ctx -> aux (true::l) ctx
+ | Declaration.LocalAssum _ :: ctx -> aux (false::l) ctx
+ in aux []
+
+ (** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the {e local definitions} of [Γ] skipped in
+ [args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ let to_extended_list n =
+ let rec reln l p = function
+ | Declaration.LocalAssum _ :: hyps -> reln (Constr.mkRel (n+p) :: l) (p+1) hyps
+ | Declaration.LocalDef _ :: hyps -> reln l (p+1) hyps
+ | [] -> l
+ in
+ reln [] 1
+
+ (** [extended_vect n Γ] does the same, returning instead an array. *)
+ let to_extended_vect n hyps = Array.of_list (to_extended_list n hyps)
+end
+
(** This module represents contexts that can capture non-anonymous variables.
Individual declarations are then designated by the identifiers they bind. *)
module Named =
+struct
+ (** Representation of {e local declarations}. *)
+ module Declaration =
struct
- (** Representation of {e local declarations}. *)
- module Declaration =
- struct
- (** local declaration *)
- type t = LocalAssum of Id.t * Constr.t
- | LocalDef of Id.t * Constr.t * Constr.t
-
- (** Return the identifier bound by a given declaration. *)
- let get_id = function
- | LocalAssum (id,_) -> id
- | LocalDef (id,_,_) -> id
-
- (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
- let get_value = function
- | LocalAssum _ -> None
- | LocalDef (_,v,_) -> Some v
-
- (** Return the type of the name bound by a given declaration. *)
- let get_type = function
- | LocalAssum (_,ty)
- | LocalDef (_,_,ty) -> ty
-
- (** Set the identifier that is bound by a given declaration. *)
- let set_id id = function
- | LocalAssum (_,ty) -> LocalAssum (id, ty)
- | LocalDef (_, v, ty) -> LocalDef (id, v, ty)
-
- (** Set the type of the bound variable in a given declaration. *)
- let set_type ty = function
- | LocalAssum (id,_) -> LocalAssum (id, ty)
- | LocalDef (id,v,_) -> LocalDef (id, v, ty)
-
- (** Return [true] iff a given declaration is a local assumption. *)
- let is_local_assum = function
- | LocalAssum _ -> true
- | LocalDef _ -> false
-
- (** Return [true] iff a given declaration is a local definition. *)
- let is_local_def = function
- | LocalDef _ -> true
- | LocalAssum _ -> false
-
- (** Check whether any term in a given declaration satisfies a given predicate. *)
- let exists f = function
- | LocalAssum (_, ty) -> f ty
- | LocalDef (_, v, ty) -> f v || f ty
-
- (** Check whether all terms in a given declaration satisfy a given predicate. *)
- let for_all f = function
- | LocalAssum (_, ty) -> f ty
- | LocalDef (_, v, ty) -> f v && f ty
-
- (** Check whether the two given declarations are equal. *)
- let equal decl1 decl2 =
- match decl1, decl2 with
- | LocalAssum (id1, ty1), LocalAssum (id2, ty2) ->
- Id.equal id1 id2 && Constr.equal ty1 ty2
- | LocalDef (id1, v1, ty1), LocalDef (id2, v2, ty2) ->
- Id.equal id1 id2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
- | _ ->
- false
-
- (** Map the identifier bound by a given declaration. *)
- let map_id f = function
- | LocalAssum (id, ty) as decl ->
- let id' = f id in
- if id == id' then decl else LocalAssum (id', ty)
- | LocalDef (id, v, ty) as decl ->
- let id' = f id in
- if id == id' then decl else LocalDef (id', v, ty)
-
- (** For local assumptions, this function returns the original local assumptions.
- For local definitions, this function maps the value in the local definition. *)
- let map_value f = function
- | LocalAssum _ as decl -> decl
- | LocalDef (na, v, t) as decl ->
- let v' = f v in
- if v == v' then decl else LocalDef (na, v', t)
-
- (** Map the type of the name bound by a given declaration. *)
- let map_type f = function
- | LocalAssum (id, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalAssum (id, ty')
- | LocalDef (id, v, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalDef (id, v, ty')
-
- (** Map all terms in a given declaration. *)
- let map_constr f = function
- | LocalAssum (id, ty) as decl ->
- let ty' = f ty in
- if ty == ty' then decl else LocalAssum (id, ty')
- | LocalDef (id, v, ty) as decl ->
- let v' = f v in
- let ty' = f ty in
- if v == v' && ty == ty' then decl else LocalDef (id, v', ty')
-
- (** Perform a given action on all terms in a given declaration. *)
- let iter_constr f = function
- | LocalAssum (_, ty) -> f ty
- | LocalDef (_, v, ty) -> f v; f ty
-
- (** Reduce all terms in a given declaration to a single value. *)
- let fold f decl a =
- match decl with
- | LocalAssum (_, ty) -> f ty a
- | LocalDef (_, v, ty) -> a |> f v |> f ty
-
- let to_tuple = function
- | LocalAssum (id, ty) -> id, None, ty
- | LocalDef (id, v, ty) -> id, Some v, ty
-
- let of_tuple = function
- | id, None, ty -> LocalAssum (id, ty)
- | id, Some v, ty -> LocalDef (id, v, ty)
- end
-
- (** Named-context is represented as a list of declarations.
- Inner-most declarations are at the beginning of the list.
- Outer-most declarations are at the end of the list. *)
- type t = Declaration.t list
-
- (** empty named-context *)
- let empty = []
-
- (** empty named-context *)
- let add d ctx = d :: ctx
-
- (** Return the number of {e local declarations} in a given named-context. *)
- let length = List.length
-
- (** Return a declaration designated by a given de Bruijn index.
- @raise Not_found if the designated identifier is not present in the designated named-context. *) let rec lookup id = function
- | decl :: _ when Id.equal id (Declaration.get_id decl) -> decl
- | _ :: sign -> lookup id sign
- | [] -> raise Not_found
-
- (** Check whether given two named-contexts are equal. *)
- let equal = List.equal Declaration.equal
-
- (** Map all terms in a given named-context. *)
- let map f = List.smartmap (Declaration.map_constr f)
-
- (** Perform a given action on every declaration in a given named-context. *)
- let iter f = List.iter (Declaration.iter_constr f)
-
- (** Reduce all terms in a given named-context to a single value.
- Innermost declarations are processed first. *)
- let fold_inside f ~init = List.fold_left f init
-
- (** Reduce all terms in a given named-context to a single value.
- Outermost declarations are processed first. *)
- let fold_outside f l ~init = List.fold_right f l init
+ (** local declaration *)
+ type t =
+ | LocalAssum of Id.t * Constr.t (** identifier, type *)
+ | LocalDef of Id.t * Constr.t * Constr.t (** identifier, value, type *)
+
+ (** Return the identifier bound by a given declaration. *)
+ let get_id = function
+ | LocalAssum (id,_) -> id
+ | LocalDef (id,_,_) -> id
+
+ (** Return [Some value] for local-declarations and [None] for local-assumptions. *)
+ let get_value = function
+ | LocalAssum _ -> None
+ | LocalDef (_,v,_) -> Some v
+
+ (** Return the type of the name bound by a given declaration. *)
+ let get_type = function
+ | LocalAssum (_,ty)
+ | LocalDef (_,_,ty) -> ty
+
+ (** Set the identifier that is bound by a given declaration. *)
+ let set_id id = function
+ | LocalAssum (_,ty) -> LocalAssum (id, ty)
+ | LocalDef (_, v, ty) -> LocalDef (id, v, ty)
+
+ (** Set the type of the bound variable in a given declaration. *)
+ let set_type ty = function
+ | LocalAssum (id,_) -> LocalAssum (id, ty)
+ | LocalDef (id,v,_) -> LocalDef (id, v, ty)
+
+ (** Return [true] iff a given declaration is a local assumption. *)
+ let is_local_assum = function
+ | LocalAssum _ -> true
+ | LocalDef _ -> false
+
+ (** Return [true] iff a given declaration is a local definition. *)
+ let is_local_def = function
+ | LocalDef _ -> true
+ | LocalAssum _ -> false
+
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ let exists f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v || f ty
+
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ let for_all f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v && f ty
+
+ (** Check whether the two given declarations are equal. *)
+ let equal decl1 decl2 =
+ match decl1, decl2 with
+ | LocalAssum (id1, ty1), LocalAssum (id2, ty2) ->
+ Id.equal id1 id2 && Constr.equal ty1 ty2
+ | LocalDef (id1, v1, ty1), LocalDef (id2, v2, ty2) ->
+ Id.equal id1 id2 && Constr.equal v1 v2 && Constr.equal ty1 ty2
+ | _ ->
+ false
+
+ (** Map the identifier bound by a given declaration. *)
+ let map_id f = function
+ | LocalAssum (id, ty) as decl ->
+ let id' = f id in
+ if id == id' then decl else LocalAssum (id', ty)
+ | LocalDef (id, v, ty) as decl ->
+ let id' = f id in
+ if id == id' then decl else LocalDef (id', v, ty)
+
+ (** For local assumptions, this function returns the original local assumptions.
+ For local definitions, this function maps the value in the local definition. *)
+ let map_value f = function
+ | LocalAssum _ as decl -> decl
+ | LocalDef (na, v, t) as decl ->
+ let v' = f v in
+ if v == v' then decl else LocalDef (na, v', t)
+
+ (** Map the type of the name bound by a given declaration. *)
+ let map_type f = function
+ | LocalAssum (id, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (id, ty')
+ | LocalDef (id, v, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalDef (id, v, ty')
- (** Return the set of all identifiers bound in a given named-context. *)
- let to_vars =
- List.fold_left (fun accu decl -> Id.Set.add (Declaration.get_id decl) accu) Id.Set.empty
+ (** Map all terms in a given declaration. *)
+ let map_constr f = function
+ | LocalAssum (id, ty) as decl ->
+ let ty' = f ty in
+ if ty == ty' then decl else LocalAssum (id, ty')
+ | LocalDef (id, v, ty) as decl ->
+ let v' = f v in
+ let ty' = f ty in
+ if v == v' && ty == ty' then decl else LocalDef (id, v', ty')
+
+ (** Perform a given action on all terms in a given declaration. *)
+ let iter_constr f = function
+ | LocalAssum (_, ty) -> f ty
+ | LocalDef (_, v, ty) -> f v; f ty
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f decl a =
+ match decl with
+ | LocalAssum (_, ty) -> f ty a
+ | LocalDef (_, v, ty) -> a |> f v |> f ty
+
+ let to_tuple = function
+ | LocalAssum (id, ty) -> id, None, ty
+ | LocalDef (id, v, ty) -> id, Some v, ty
+
+ let of_tuple = function
+ | id, None, ty -> LocalAssum (id, ty)
+ | id, Some v, ty -> LocalDef (id, v, ty)
+ end
- (** [instance_from_named_context Ω] builds an instance [args] such
- that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
- definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
- gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
- let to_instance =
- let filter = function
- | Declaration.LocalAssum (id, _) -> Some (Constr.mkVar id)
- | _ -> None
- in
- List.map_filter filter
+ (** Named-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Declaration.t list
+
+ (** empty named-context *)
+ let empty = []
+
+ (** empty named-context *)
+ let add d ctx = d :: ctx
+
+ (** Return the number of {e local declarations} in a given named-context. *)
+ let length = List.length
+
+(** Return a declaration designated by a given de Bruijn index.
+ @raise Not_found if the designated identifier is not present in the designated named-context. *) let rec lookup id = function
+ | decl :: _ when Id.equal id (Declaration.get_id decl) -> decl
+ | _ :: sign -> lookup id sign
+ | [] -> raise Not_found
+
+ (** Check whether given two named-contexts are equal. *)
+ let equal = List.equal Declaration.equal
+
+ (** Map all terms in a given named-context. *)
+ let map f = List.smartmap (Declaration.map_constr f)
+
+ (** Perform a given action on every declaration in a given named-context. *)
+ let iter f = List.iter (Declaration.iter_constr f)
+
+ (** Reduce all terms in a given named-context to a single value.
+ Innermost declarations are processed first. *)
+ let fold_inside f ~init = List.fold_left f init
+
+ (** Reduce all terms in a given named-context to a single value.
+ Outermost declarations are processed first. *)
+ let fold_outside f l ~init = List.fold_right f l init
+
+ (** Return the set of all identifiers bound in a given named-context. *)
+ let to_vars =
+ List.fold_left (fun accu decl -> Id.Set.add (Declaration.get_id decl) accu) Id.Set.empty
+
+ (** [instance_from_named_context Ω] builds an instance [args] such
+ that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
+ definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
+ gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
+ let to_instance =
+ let filter = function
+ | Declaration.LocalAssum (id, _) -> Some (Constr.mkVar id)
+ | _ -> None
+ in
+ List.map_filter filter
end
module NamedList =
struct
module Declaration =
struct
- type t = Id.t list * Constr.t option * Constr.t
+ type t = Id.t list * Constr.t option * Constr.t
let map_constr f (ids, copt, ty as decl) =
let copt' = Option.map f copt in
diff --git a/kernel/context.mli b/kernel/context.mli
index a69754cc29..b5f3904d22 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -29,8 +29,8 @@ sig
module Declaration :
sig
(* local declaration *)
- type t = LocalAssum of Name.t * Constr.t (* local assumption *)
- | LocalDef of Name.t * Constr.t * Constr.t (* local definition *)
+ type t = LocalAssum of Name.t * Constr.t (** name, type *)
+ | LocalDef of Name.t * Constr.t * Constr.t (** name, value, type *)
(** Return the name bound by a given declaration. *)
val get_name : t -> Name.t
@@ -143,8 +143,8 @@ sig
(** Representation of {e local declarations}. *)
module Declaration :
sig
- type t = LocalAssum of Id.t * Constr.t
- | LocalDef of Id.t * Constr.t * Constr.t
+ type t = LocalAssum of Id.t * Constr.t (** identifier, type *)
+ | LocalDef of Id.t * Constr.t * Constr.t (** identifier, value, type *)
(** Return the identifier bound by a given declaration. *)
val get_id : t -> Id.t
--
cgit v1.2.3
From 5f29a92c0648afd4d9e46de79ab00d0c4b901ff0 Mon Sep 17 00:00:00 2001
From: Emilio Jesus Gallego Arias
Date: Tue, 9 Feb 2016 16:36:05 +0100
Subject: Don't fail fatally if PATH is not set.
This fixes micromega in certain environments.
---
lib/system.ml | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/system.ml b/lib/system.ml
index 9bdcecef19..0ad43a7423 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -149,10 +149,12 @@ let is_in_path lpath filename =
with Not_found -> false
let is_in_system_path filename =
- let path = try Sys.getenv "PATH"
- with Not_found -> error "system variable PATH not found" in
- let lpath = CUnix.path_to_list path in
- is_in_path lpath filename
+ try
+ let lpath = CUnix.path_to_list (Sys.getenv "PATH") in
+ is_in_path lpath filename
+ with Not_found ->
+ msg_warning (str "system variable PATH not found");
+ false
let open_trapping_failure name =
try open_out_bin name
--
cgit v1.2.3
From 22ab7fff908c259d6e433da246bebac519009905 Mon Sep 17 00:00:00 2001
From: Enrico Tassi
Date: Wed, 10 Feb 2016 17:54:25 +0100
Subject: STM: not delegate proofs that contain Vernac(Module|Require|Import),
#4530
---
stm/stm.ml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/stm/stm.ml b/stm/stm.ml
index d8b2de4a2c..5ad1aead61 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -1686,6 +1686,13 @@ let collect_proof keep cur hd brkind id =
| _ -> false in
let may_pierce_opaque = function
| { expr = VernacPrint (PrintName _) } -> true
+ (* These do not exactly pierce opaque, but are anyway impossible to properly
+ * delegate *)
+ | { expr = (VernacDeclareModule _
+ | VernacDefineModule _
+ | VernacDeclareModuleType _
+ | VernacInclude _) } -> true
+ | { expr = (VernacRequire _ | VernacImport _) } -> true
| _ -> false in
let parent = function Some (p, _) -> p | None -> assert false in
let is_empty = function `Async(_,_,[],_,_) | `MaybeASync(_,_,[],_,_) -> true | _ -> false in
--
cgit v1.2.3
From df6bb883920e3a03044d09f10b57a44a2e7c5196 Mon Sep 17 00:00:00 2001
From: Enrico Tassi
Date: Wed, 10 Feb 2016 17:59:14 +0100
Subject: STM: always stock in vio files the first node (state) of a proof
It used not to be the case when the proof contains Sideff, since
the code was picking the last known state and not necessarily the
first one. Because of side effects the last known state could be
the one corresponding to the side effect (that was executed to, say,
change the parser). This is also related to bug #4530
---
stm/stm.ml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/stm/stm.ml b/stm/stm.ml
index 5ad1aead61..56dcda6a4a 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -513,7 +513,10 @@ end = struct (* {{{ *)
let rec fill id =
if (get_info id).state = None then fill (Vcs_aux.visit v id).next
else copy_info_w_state v id in
- fill stop
+ let v = fill stop in
+ (* We put in the new dag the first state (since Qed shall run on it,
+ * see check_task_aux) *)
+ copy_info_w_state v start
let nodes_in_slice ~start ~stop =
List.rev (List.map fst (nodes_in_slice ~start ~stop))
--
cgit v1.2.3
From f46a5686853353f8de733ae7fbd21a3a61977bc7 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 3 Feb 2016 15:32:58 +0100
Subject: Do not give a name to anonymous evars anymore. See bug #4547.
The current solution may not be totally ideal though. We generate names for
anonymous evars on the fly at printing time, based on the Evar_kind data they
are wearing. This means in particular that the printed name of an anonymous
evar may change in the future because some unrelate evar has been solved or
introduced.
---
interp/constrextern.ml | 5 +-
pretyping/detyping.ml | 5 +-
pretyping/evarutil.ml | 9 +---
pretyping/evd.ml | 103 +++++++++++++++++++++++--------------
pretyping/evd.mli | 4 +-
printing/printer.ml | 2 +-
proofs/goal.ml | 5 +-
proofs/proofview.ml | 5 +-
test-suite/bugs/closed/3068.v | 2 +-
test-suite/output/Existentials.out | 3 +-
test-suite/output/Notations.out | 14 ++---
test-suite/output/inference.out | 8 +--
test-suite/success/apply.v | 2 +-
test-suite/success/destruct.v | 8 +--
14 files changed, 102 insertions(+), 73 deletions(-)
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 9df8f9c233..cc5d189e04 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -988,7 +988,10 @@ let rec glob_of_pat env sigma = function
| PEvar (evk,l) ->
let test (id,_,_) = function PVar id' -> Id.equal id id' | _ -> false in
let l = Evd.evar_instance_array test (Evd.find sigma evk) l in
- let id = Evd.evar_ident evk sigma in
+ let id = match Evd.evar_ident evk sigma with
+ | None -> Id.of_string "__"
+ | Some id -> id
+ in
GEvar (loc,id,List.map (on_snd (glob_of_pat env sigma)) l)
| PRel n ->
let id = try match lookup_name_of_rel n env with
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index c3877c56e4..0c487ced81 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -518,7 +518,10 @@ let rec detype flags avoid env sigma t =
with Not_found -> isVarId id c in
let id,l =
try
- let id = Evd.evar_ident evk sigma in
+ let id = match Evd.evar_ident evk sigma with
+ | None -> Evd.pr_evar_suggested_name evk sigma
+ | Some id -> id
+ in
let l = Evd.evar_instance_array bound_to_itself_or_letin (Evd.find sigma evk) cl in
let fvs,rels = List.fold_left (fun (fvs,rels) (_,c) -> match kind_of_term c with Rel n -> (fvs,Int.Set.add n rels) | Var id -> (Id.Set.add id fvs,rels) | _ -> (fvs,rels)) (Id.Set.empty,Int.Set.empty) l in
let l = Evd.evar_instance_array (fun d c -> not !print_evar_arguments && (bound_to_itself_or_letin d c && not (isRel c && Int.Set.mem (destRel c) rels || isVar c && (Id.Set.mem (destVar c) fvs)))) (Evd.find sigma evk) cl in
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index e23e5a53a7..759e0e4d6d 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -365,14 +365,7 @@ let new_pure_evar_full evd evi =
(evd, evk)
let new_pure_evar sign evd ?(src=default_source) ?filter ?candidates ?store ?naming ?(principal=false) typ =
- let default_naming =
- if principal then
- (* waiting for a more principled approach
- (unnamed evars, private names?) *)
- Misctypes.IntroFresh (Names.Id.of_string "tmp_goal")
- else
- Misctypes.IntroAnonymous
- in
+ let default_naming = Misctypes.IntroAnonymous in
let naming = Option.default default_naming naming in
let newevk = new_untyped_evar() in
let evd = evar_declare sign newevk typ ~src ?filter ?candidates ?store ~naming evd in
diff --git a/pretyping/evd.ml b/pretyping/evd.ml
index 8be09a7821..0bc688aacf 100644
--- a/pretyping/evd.ml
+++ b/pretyping/evd.ml
@@ -208,15 +208,6 @@ let map_evar_info f evi =
evar_concl = f evi.evar_concl;
evar_candidates = Option.map (List.map f) evi.evar_candidates }
-let evar_ident_info evi =
- match evi.evar_source with
- | _,Evar_kinds.ImplicitArg (c,(n,Some id),b) -> id
- | _,Evar_kinds.VarInstance id -> id
- | _,Evar_kinds.GoalEvar -> Id.of_string "Goal"
- | _ ->
- let env = reset_with_named_context evi.evar_hyps (Global.env()) in
- Namegen.id_of_name_using_hdchar env evi.evar_concl Anonymous
-
(* This exception is raised by *.existential_value *)
exception NotInstantiatedEvar
@@ -588,7 +579,7 @@ val add_name_undefined : intro_pattern_naming_expr -> Evar.t -> evar_info -> t -
val remove_name_defined : Evar.t -> t -> t
val rename : Evar.t -> Id.t -> t -> t
val reassign_name_defined : Evar.t -> Evar.t -> t -> t
-val ident : Evar.t -> t -> Id.t
+val ident : Evar.t -> t -> Id.t option
val key : Id.t -> t -> Evar.t
end =
@@ -598,21 +589,21 @@ type t = Id.t EvMap.t * existential_key Idmap.t
let empty = (EvMap.empty, Idmap.empty)
-let add_name_newly_undefined naming evk evi (evtoid,idtoev) =
+let add_name_newly_undefined naming evk evi (evtoid, idtoev as names) =
let id = match naming with
- | Misctypes.IntroAnonymous ->
- let id = evar_ident_info evi in
- Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev)
+ | Misctypes.IntroAnonymous -> None
| Misctypes.IntroIdentifier id ->
- let id' =
- Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev) in
- if not (Names.Id.equal id id') then
- user_err_loc
- (Loc.ghost,"",str "Already an existential evar of name " ++ pr_id id);
- id'
+ if Idmap.mem id idtoev then
+ user_err_loc
+ (Loc.ghost,"",str "Already an existential evar of name " ++ pr_id id);
+ Some id
| Misctypes.IntroFresh id ->
- Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev) in
- (EvMap.add evk id evtoid, Idmap.add id evk idtoev)
+ let id = Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev) in
+ Some id
+ in
+ match id with
+ | None -> names
+ | Some id -> (EvMap.add evk id evtoid, Idmap.add id evk idtoev)
let add_name_undefined naming evk evi (evtoid,idtoev as evar_names) =
if EvMap.mem evk evtoid then
@@ -620,25 +611,30 @@ let add_name_undefined naming evk evi (evtoid,idtoev as evar_names) =
else
add_name_newly_undefined naming evk evi evar_names
-let remove_name_defined evk (evtoid,idtoev) =
- let id = EvMap.find evk evtoid in
- (EvMap.remove evk evtoid, Idmap.remove id idtoev)
+let remove_name_defined evk (evtoid, idtoev as names) =
+ let id = try Some (EvMap.find evk evtoid) with Not_found -> None in
+ match id with
+ | None -> names
+ | Some id -> (EvMap.remove evk evtoid, Idmap.remove id idtoev)
let rename evk id (evtoid, idtoev) =
- let id' = EvMap.find evk evtoid in
- if Idmap.mem id idtoev then anomaly (str "Evar name already in use");
- (EvMap.add evk id evtoid (* overwrite old name *), Idmap.add id evk (Idmap.remove id' idtoev))
-
-let reassign_name_defined evk evk' (evtoid,idtoev) =
- let id = EvMap.find evk evtoid in
- (EvMap.add evk' id (EvMap.remove evk evtoid),
- Idmap.add id evk' (Idmap.remove id idtoev))
+ let id' = try Some (EvMap.find evk evtoid) with Not_found -> None in
+ match id' with
+ | None -> (EvMap.add evk id evtoid, Idmap.add id evk idtoev)
+ | Some id' ->
+ if Idmap.mem id idtoev then anomaly (str "Evar name already in use");
+ (EvMap.update evk id evtoid (* overwrite old name *), Idmap.add id evk (Idmap.remove id' idtoev))
+
+let reassign_name_defined evk evk' (evtoid, idtoev as names) =
+ let id = try Some (EvMap.find evk evtoid) with Not_found -> None in
+ match id with
+ | None -> names (** evk' must not be defined *)
+ | Some id ->
+ (EvMap.add evk' id (EvMap.remove evk evtoid),
+ Idmap.add id evk' (Idmap.remove id idtoev))
let ident evk (evtoid, _) =
- try EvMap.find evk evtoid
- with Not_found ->
- (* Unnamed (non-dependent) evar *)
- add_suffix (Id.of_string "X") (string_of_int (Evar.repr evk))
+ try Some (EvMap.find evk evtoid) with Not_found -> None
let key id (_, idtoev) =
Idmap.find id idtoev
@@ -682,7 +678,7 @@ let add d e i = match i.evar_body with
let evar_names = EvNames.add_name_undefined Misctypes.IntroAnonymous e i d.evar_names in
{ d with undf_evars = EvMap.add e i d.undf_evars; evar_names }
| Evar_defined _ ->
- let evar_names = try EvNames.remove_name_defined e d.evar_names with Not_found -> d.evar_names in
+ let evar_names = EvNames.remove_name_defined e d.evar_names in
{ d with defn_evars = EvMap.add e i d.defn_evars; evar_names }
let remove d e =
@@ -1706,7 +1702,34 @@ type unsolvability_explanation = SeveralInstancesFound of int
(**********************************************************)
(* Pretty-printing *)
-let pr_existential_key sigma evk = str "?" ++ pr_id (evar_ident evk sigma)
+let pr_evar_suggested_name evk sigma =
+ let base_id evk' evi =
+ match evar_ident evk' sigma with
+ | Some id -> id
+ | None -> match evi.evar_source with
+ | _,Evar_kinds.ImplicitArg (c,(n,Some id),b) -> id
+ | _,Evar_kinds.VarInstance id -> id
+ | _,Evar_kinds.GoalEvar -> Id.of_string "Goal"
+ | _ ->
+ let env = reset_with_named_context evi.evar_hyps (Global.env()) in
+ Namegen.id_of_name_using_hdchar env evi.evar_concl Anonymous
+ in
+ let names = EvMap.mapi base_id sigma.undf_evars in
+ let id = EvMap.find evk names in
+ let fold evk' id' (seen, n) =
+ if seen then (seen, n)
+ else if Evar.equal evk evk' then (true, n)
+ else if Id.equal id id' then (seen, succ n)
+ else (seen, n)
+ in
+ let (_, n) = EvMap.fold fold names (false, 0) in
+ if n = 0 then id else Nameops.add_suffix id (string_of_int (pred n))
+
+let pr_existential_key sigma evk = match evar_ident evk sigma with
+| None ->
+ str "?" ++ pr_id (pr_evar_suggested_name evk sigma)
+| Some id ->
+ str "?" ++ pr_id id
let pr_instance_status (sc,typ) =
begin match sc with
@@ -1895,7 +1918,7 @@ let pr_evar_list sigma l =
h 0 (str (string_of_existential ev) ++
str "==" ++ pr_evar_info evi ++
(if evi.evar_body == Evar_empty
- then str " {" ++ pr_id (evar_ident ev sigma) ++ str "}"
+ then str " {" ++ pr_existential_key sigma ev ++ str "}"
else mt ()))
in
h 0 (prlist_with_sep fnl pr l)
diff --git a/pretyping/evd.mli b/pretyping/evd.mli
index 9cfca02ed8..d2479c1229 100644
--- a/pretyping/evd.mli
+++ b/pretyping/evd.mli
@@ -249,7 +249,7 @@ val evar_source : existential_key -> evar_map -> Evar_kinds.t located
(** Convenience function. Wrapper around {!find} to recover the source of an
evar in a given evar map. *)
-val evar_ident : existential_key -> evar_map -> Id.t
+val evar_ident : existential_key -> evar_map -> Id.t option
val rename : existential_key -> Id.t -> evar_map -> evar_map
@@ -603,6 +603,8 @@ type unsolvability_explanation = SeveralInstancesFound of int
val pr_existential_key : evar_map -> evar -> Pp.std_ppcmds
+val pr_evar_suggested_name : existential_key -> evar_map -> Id.t
+
(** {5 Debug pretty-printers} *)
val pr_evar_info : evar_info -> Pp.std_ppcmds
diff --git a/printing/printer.ml b/printing/printer.ml
index 5ad0e45319..63755d7ff7 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -400,7 +400,7 @@ let display_name = false
(* display a goal name *)
let pr_goal_name sigma g =
- if display_name then str " " ++ Pp.surround (pr_id (Evd.evar_ident g sigma))
+ if display_name then str " " ++ Pp.surround (pr_existential_key sigma g)
else mt ()
(* display the conclusion of a goal *)
diff --git a/proofs/goal.ml b/proofs/goal.ml
index 1dd5be0e71..43a3024e50 100644
--- a/proofs/goal.ml
+++ b/proofs/goal.ml
@@ -89,7 +89,10 @@ module V82 = struct
(* Instantiates a goal with an open term, using name of goal for evk' *)
let partial_solution_to sigma evk evk' c =
let id = Evd.evar_ident evk sigma in
- Evd.rename evk' id (partial_solution sigma evk c)
+ let sigma = partial_solution sigma evk c in
+ match id with
+ | None -> sigma
+ | Some id -> Evd.rename evk' id sigma
(* Parts of the progress tactical *)
let same_goal evars1 gl1 evars2 gl2 =
diff --git a/proofs/proofview.ml b/proofs/proofview.ml
index a6d9735f14..49228c93ac 100644
--- a/proofs/proofview.ml
+++ b/proofs/proofview.ml
@@ -1093,7 +1093,10 @@ struct
| None -> Evd.define gl.Goal.self c sigma
| Some evk ->
let id = Evd.evar_ident gl.Goal.self sigma in
- Evd.rename evk id (Evd.define gl.Goal.self c sigma)
+ let sigma = Evd.define gl.Goal.self c sigma in
+ match id with
+ | None -> sigma
+ | Some id -> Evd.rename evk id sigma
in
(** Restore the [future goals] state. *)
let sigma = Evd.restore_future_goals sigma prev_future_goals prev_principal_goal in
diff --git a/test-suite/bugs/closed/3068.v b/test-suite/bugs/closed/3068.v
index ced6d95949..79671ce930 100644
--- a/test-suite/bugs/closed/3068.v
+++ b/test-suite/bugs/closed/3068.v
@@ -56,7 +56,7 @@ Section Finite_nat_set.
subst fs1.
apply iff_refl.
intros H.
- eapply counted_list_equal_nth_char.
+ eapply (counted_list_equal_nth_char _ _ _ _ ?[def]).
intros i.
destruct (counted_def_nth fs1 i _ ) eqn:H0.
(* This was not part of the initial bug report; this is to check that
diff --git a/test-suite/output/Existentials.out b/test-suite/output/Existentials.out
index 52e1e0ed01..9680d2bbff 100644
--- a/test-suite/output/Existentials.out
+++ b/test-suite/output/Existentials.out
@@ -1,5 +1,4 @@
-Existential 1 =
-?Goal1 : [p : nat q := S p : nat n : nat m : nat |- ?y = m]
+Existential 1 = ?Goal : [p : nat q := S p : nat n : nat m : nat |- ?y = m]
Existential 2 =
?y : [p : nat q := S p : nat n : nat m : nat |- nat] (p, q cannot be used)
Existential 3 = ?Goal0 : [q : nat n : nat m : nat |- n = ?y]
diff --git a/test-suite/output/Notations.out b/test-suite/output/Notations.out
index b1558dab1c..26eaca8272 100644
--- a/test-suite/output/Notations.out
+++ b/test-suite/output/Notations.out
@@ -111,14 +111,14 @@ fun x : option Z => match x with
| NONE2 => 0
end
: option Z -> Z
-fun x : list ?T1 => match x with
- | NIL => NONE2
- | (_ :') t => SOME2 t
- end
- : list ?T1 -> option (list ?T1)
+fun x : list ?T => match x with
+ | NIL => NONE2
+ | (_ :') t => SOME2 t
+ end
+ : list ?T -> option (list ?T)
where
-?T1 : [x : list ?T1 x1 : list ?T1 x0 := x1 : list ?T1 |- Type] (x, x1,
- x0 cannot be used)
+?T : [x : list ?T x1 : list ?T x0 := x1 : list ?T |- Type] (x, x1,
+ x0 cannot be used)
s
: s
10
diff --git a/test-suite/output/inference.out b/test-suite/output/inference.out
index f2d1447785..4512e2c5ce 100644
--- a/test-suite/output/inference.out
+++ b/test-suite/output/inference.out
@@ -9,10 +9,10 @@ fun (m n p : nat) (H : S m <= S n + p) => le_S_n m (n + p) H
fun n : nat => let x := A n in ?y ?y0 : T n
: forall n : nat, T n
where
-?y : [n : nat x := A n : T n |- ?T0 -> T n]
-?y0 : [n : nat x := A n : T n |- ?T0]
+?y : [n : nat x := A n : T n |- ?T -> T n]
+?y0 : [n : nat x := A n : T n |- ?T]
fun n : nat => ?y ?y0 : T n
: forall n : nat, T n
where
-?y : [n : nat |- ?T0 -> T n]
-?y0 : [n : nat |- ?T0]
+?y : [n : nat |- ?T -> T n]
+?y0 : [n : nat |- ?T]
diff --git a/test-suite/success/apply.v b/test-suite/success/apply.v
index 55b666b723..02e043bc36 100644
--- a/test-suite/success/apply.v
+++ b/test-suite/success/apply.v
@@ -543,7 +543,7 @@ Qed.
Lemma bar (X: nat -> nat -> Prop) (foo:forall x, X x x) (a: unit) (H: tt = a):
exists x, exists y, X x y.
Proof.
-intros; eexists; eexists; case H.
+intros; eexists; eexists ?[y]; case H.
apply (foo ?y).
Grab Existential Variables.
exact 0.
diff --git a/test-suite/success/destruct.v b/test-suite/success/destruct.v
index 9f091e3996..90a60daa66 100644
--- a/test-suite/success/destruct.v
+++ b/test-suite/success/destruct.v
@@ -96,21 +96,21 @@ Abort.
(* Check that subterm selection does not solve existing evars *)
Goal exists x, S x = S 0.
-eexists.
+eexists ?[x].
Show x. (* Incidentally test Show on a named goal *)
destruct (S _). (* Incompatible occurrences but takes the first one since Oct 2014 *)
change (0 = S 0).
Abort.
Goal exists x, S 0 = S x.
-eexists.
+eexists ?[x].
destruct (S _). (* Incompatible occurrences but takes the first one since Oct 2014 *)
change (0 = S ?x).
[x]: exact 0. (* Incidentally test applying a tactic to a goal on the shelve *)
Abort.
Goal exists n p:nat, (S n,S n) = (S p,S p) /\ p = n.
-do 2 eexists.
+eexists ?[n]; eexists ?[p].
destruct (_, S _). (* Was unifying at some time in trunk, now takes the first occurrence *)
change ((n, n0) = (S ?p, S ?p) /\ ?p = ?n).
Abort.
@@ -426,7 +426,7 @@ destruct b eqn:H.
(* Check natural instantiation behavior when the goal has already an evar *)
Goal exists x, S x = x.
-eexists.
+eexists ?[x].
destruct (S _).
change (0 = ?x).
Abort.
--
cgit v1.2.3
From 968dfdb15cc11d48783017b2a91147b25c854ad6 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Tue, 1 Dec 2015 19:45:01 +0100
Subject: Monotonizing the Evarutil module.
Some functions were left in the old paradigm because they are only used by the
unification algorithms, so they are not worthwhile to change for now.
---
engine/sigma.ml | 12 +++++++++
engine/sigma.mli | 7 +++++
plugins/firstorder/instances.ml | 5 +++-
pretyping/cases.ml | 5 +++-
pretyping/evarconv.ml | 4 ++-
pretyping/evarsolve.ml | 13 ++++++---
pretyping/evarutil.ml | 60 +++++++++++++++++++++++++----------------
pretyping/evarutil.mli | 26 +++++++++---------
pretyping/pretyping.ml | 12 ++++++---
pretyping/tacred.ml | 5 +++-
proofs/goal.ml | 11 +++++---
tactics/rewrite.ml | 22 ++++++++++-----
tactics/tactics.ml | 9 +++----
toplevel/record.ml | 9 +++++--
14 files changed, 136 insertions(+), 64 deletions(-)
diff --git a/engine/sigma.ml b/engine/sigma.ml
index e886b0d1e7..c25aac0c14 100644
--- a/engine/sigma.ml
+++ b/engine/sigma.ml
@@ -36,6 +36,18 @@ let new_evar sigma ?naming info =
let define evk c sigma =
Sigma ((), Evd.define evk c sigma, ())
+let new_univ_level_variable ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_univ_level_variable ?name ?predicative rigid sigma in
+ Sigma (u, sigma, ())
+
+let new_univ_variable ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_univ_variable ?name ?predicative rigid sigma in
+ Sigma (u, sigma, ())
+
+let new_sort_variable ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_sort_variable ?name ?predicative rigid sigma in
+ Sigma (u, sigma, ())
+
let fresh_sort_in_family ?rigid env sigma s =
let (sigma, s) = Evd.fresh_sort_in_family ?rigid env sigma s in
Sigma (s, sigma, ())
diff --git a/engine/sigma.mli b/engine/sigma.mli
index cb948dba59..d7ae2e4ac9 100644
--- a/engine/sigma.mli
+++ b/engine/sigma.mli
@@ -66,6 +66,13 @@ val define : 'r evar -> Constr.t -> 'r t -> (unit, 'r) sigma
(** Polymorphic universes *)
+val new_univ_level_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
+ 'r t -> (Univ.universe_level, 'r) sigma
+val new_univ_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
+ 'r t -> (Univ.universe, 'r) sigma
+val new_sort_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
+ 'r t -> (Sorts.t, 'r) sigma
+
val fresh_sort_in_family : ?rigid:Evd.rigid -> Environ.env ->
'r t -> Term.sorts_family -> (Term.sorts, 'r) sigma
val fresh_constant_instance :
diff --git a/plugins/firstorder/instances.ml b/plugins/firstorder/instances.ml
index a717cc91ea..fcbad46d46 100644
--- a/plugins/firstorder/instances.ml
+++ b/plugins/firstorder/instances.ml
@@ -22,6 +22,7 @@ open Formula
open Sequent
open Names
open Misctypes
+open Sigma.Notations
let compare_instance inst1 inst2=
match inst1,inst2 with
@@ -116,7 +117,9 @@ let mk_open_instance id idc gl m t=
let rec aux n avoid env evmap decls =
if Int.equal n 0 then evmap, decls else
let nid=(fresh_id avoid var_id gl) in
- let evmap, (c, _) = Evarutil.new_type_evar env evmap Evd.univ_flexible in
+ let evmap = Sigma.Unsafe.of_evar_map evmap in
+ let Sigma ((c, _), evmap, _) = Evarutil.new_type_evar env evmap Evd.univ_flexible in
+ let evmap = Sigma.to_evar_map evmap in
let decl = (Name nid,None,c) in
aux (n-1) (nid::avoid) (Environ.push_rel decl env) evmap (decl::decls) in
let evmap, decls = aux m [] env evmap [] in
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 2cbf3a2650..91bf11eb52 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -28,6 +28,7 @@ open Evarutil
open Evarsolve
open Evarconv
open Evd
+open Sigma.Notations
(* Pattern-matching errors *)
@@ -1947,8 +1948,10 @@ let prepare_predicate loc typing_fun env sigma tomatchs arsign tycon pred =
let sigma,t = match tycon with
| Some t -> sigma,t
| None ->
- let sigma, (t, _) =
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma ((t, _), sigma, _) =
new_type_evar env sigma univ_flexible_alg ~src:(loc, Evar_kinds.CasesType false) in
+ let sigma = Sigma.to_evar_map sigma in
sigma, t
in
(* First strategy: we build an "inversion" predicate *)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 99e51330ef..f3ff26876c 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -1007,7 +1007,9 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
| None ->
let evty = set_holes evdref cty subst in
let instance = Filter.filter_list filter instance in
- let evd,ev = new_evar_instance sign !evdref evty ~filter instance in
+ let evd = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma (ev, evd, _) = new_evar_instance sign evd evty ~filter instance in
+ let evd = Sigma.to_evar_map evd in
evdref := evd;
evsref := (fst (destEvar ev),evty)::!evsref;
ev in
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 0dd0ad2e08..518f4df408 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -19,6 +19,7 @@ open Retyping
open Reductionops
open Evarutil
open Pretype_errors
+open Sigma.Notations
let normalize_evar evd ev =
match kind_of_term (whd_evar evd (mkEvar ev)) with
@@ -180,7 +181,9 @@ let restrict_evar_key evd evk filter candidates =
let candidates = match candidates with
| NoUpdate -> evi.evar_candidates
| UpdateWith c -> Some c in
- restrict_evar evd evk filter candidates
+ let sigma = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (evk, sigma, _) = restrict_evar sigma evk filter candidates in
+ (Sigma.to_evar_map sigma, evk)
end
(* Restrict an applied evar and returns its restriction in the same context *)
@@ -570,7 +573,9 @@ let make_projectable_subst aliases sigma evi args =
*)
let define_evar_from_virtual_equation define_fun env evd src t_in_env ty_t_in_sign sign filter inst_in_env =
- let evd,evar_in_env = new_evar_instance sign evd ty_t_in_sign ~filter ~src inst_in_env in
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (evar_in_env, evd, _) = new_evar_instance sign evd ty_t_in_sign ~filter ~src inst_in_env in
+ let evd = Sigma.to_evar_map evd in
let t_in_env = whd_evar evd t_in_env in
let evd = define_fun env evd None (destEvar evar_in_env) t_in_env in
let ctxt = named_context_of_val sign in
@@ -631,8 +636,10 @@ let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
~status:univ_flexible (Some false) env evd (mkSort s) in
define_evar_from_virtual_equation define_fun env evd src ty_in_env
ty_t_in_sign sign2 filter2 inst2_in_env in
- let evd,ev2_in_sign =
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (ev2_in_sign, evd, _) =
new_evar_instance sign2 evd ev2ty_in_sign ~filter:filter2 ~src inst2_in_sign in
+ let evd = Sigma.to_evar_map evd in
let ev2_in_env = (fst (destEvar ev2_in_sign), Array.of_list inst2_in_env) in
(evd, ev2_in_sign, ev2_in_env)
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index cd5188cd75..2ed557683e 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -19,6 +19,7 @@ open Environ
open Evd
open Reductionops
open Pretype_errors
+open Sigma.Notations
(** Combinators *)
@@ -41,7 +42,7 @@ let e_new_global evdref x =
evd_comb1 (Evd.fresh_global (Global.env())) evdref x
let new_global evd x =
- Evd.fresh_global (Global.env()) evd x
+ Sigma.fresh_global (Global.env()) evd x
(****************************************************)
(* Expanding/testing/exposing existential variables *)
@@ -342,15 +343,18 @@ let push_rel_context_to_named_context env typ =
let default_source = (Loc.ghost,Evar_kinds.InternalHole)
let restrict_evar evd evk filter candidates =
+ let evd = Sigma.to_evar_map evd in
let evd, evk' = Evd.restrict evk filter ?candidates evd in
- Evd.declare_future_goal evk' evd, evk'
+ Sigma.Unsafe.of_pair (evk', Evd.declare_future_goal evk' evd)
let new_pure_evar_full evd evi =
+ let evd = Sigma.to_evar_map evd in
let (evd, evk) = Evd.new_evar evd evi in
let evd = Evd.declare_future_goal evk evd in
- (evd, evk)
+ Sigma.Unsafe.of_pair (evk, evd)
let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) typ =
+ let evd = Sigma.to_evar_map evd in
let default_naming = Misctypes.IntroAnonymous in
let naming = Option.default default_naming naming in
let evi = {
@@ -367,17 +371,17 @@ let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?ca
if principal then Evd.declare_principal_goal newevk evd
else Evd.declare_future_goal newevk evd
in
- (evd,newevk)
+ Sigma.Unsafe.of_pair (newevk, evd)
let new_evar_instance sign evd typ ?src ?filter ?candidates ?store ?naming ?principal instance =
assert (not !Flags.debug ||
List.distinct (ids_of_named_context (named_context_of_val sign)));
- let evd,newevk = new_pure_evar sign evd ?src ?filter ?candidates ?store ?naming ?principal typ in
- (evd,mkEvar (newevk,Array.of_list instance))
+ let Sigma (newevk, evd, p) = new_pure_evar sign evd ?src ?filter ?candidates ?store ?naming ?principal typ in
+ Sigma (mkEvar (newevk,Array.of_list instance), evd, p)
(* [new_evar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
-let new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
+let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
let sign,typ',instance,subst,vsubst = push_rel_context_to_named_context env typ in
let candidates = Option.map (List.map (subst2 subst vsubst)) candidates in
let instance =
@@ -386,24 +390,26 @@ let new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal t
| Some filter -> Filter.filter_list filter instance in
new_evar_instance sign evd typ' ?src ?filter ?candidates ?store ?naming ?principal instance
-let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
- let evd = Sigma.to_evar_map evd in
- let (sigma, c) = new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ in
- Sigma.Unsafe.of_pair (c, sigma)
+let new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (evk, evd, _) = new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ in
+ (Sigma.to_evar_map evd, evk)
let new_type_evar env evd ?src ?filter ?naming ?principal rigid =
- let evd', s = new_sort_variable rigid evd in
- let evd', e = new_evar_unsafe env evd' ?src ?filter ?naming ?principal (mkSort s) in
- evd', (e, s)
+ let Sigma (s, evd', p) = Sigma.new_sort_variable rigid evd in
+ let Sigma (e, evd', q) = new_evar env evd' ?src ?filter ?naming ?principal (mkSort s) in
+ Sigma ((e, s), evd', p +> q)
let e_new_type_evar env evdref ?src ?filter ?naming ?principal rigid =
- let evd', c = new_type_evar env !evdref ?src ?filter ?naming ?principal rigid in
- evdref := evd';
+ let sigma = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma (c, sigma, _) = new_type_evar env sigma ?src ?filter ?naming ?principal rigid in
+ let sigma = Sigma.to_evar_map sigma in
+ evdref := sigma;
c
let new_Type ?(rigid=Evd.univ_flexible) env evd =
- let evd', s = new_sort_variable rigid evd in
- evd', mkSort s
+ let Sigma (s, sigma, p) = Sigma.new_sort_variable rigid evd in
+ Sigma (mkSort s, sigma, p)
let e_new_Type ?(rigid=Evd.univ_flexible) env evdref =
let evd', s = new_sort_variable rigid !evdref in
@@ -501,7 +507,9 @@ let rec check_and_clear_in_constr env evdref err ids c =
else
let origfilter = Evd.evar_filter evi in
let filter = Evd.Filter.apply_subfilter origfilter filter in
- let evd,_ = restrict_evar !evdref evk filter None in
+ let evd = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma (_, evd, _) = restrict_evar evd evk filter None in
+ let evd = Sigma.to_evar_map evd in
evdref := evd;
(* spiwack: hacking session to mark the old [evk] as having been "cleared" *)
let evi = Evd.find !evdref evk in
@@ -708,7 +716,10 @@ let define_pure_evar_as_product evd evk =
let concl = whd_betadeltaiota evenv evd evi.evar_concl in
let s = destSort concl in
let evd1,(dom,u1) =
- new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi) in
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (e, evd1, _) = new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi) in
+ (Sigma.to_evar_map evd1, e)
+ in
let evd2,rng =
let newenv = push_named (id, None, dom) evenv in
let src = evar_source evk evd1 in
@@ -719,7 +730,10 @@ let define_pure_evar_as_product evd evk =
else
let status = univ_flexible_alg in
let evd3, (rng, srng) =
- new_type_evar newenv evd1 status ~src ~filter in
+ let evd1 = Sigma.Unsafe.of_evar_map evd1 in
+ let Sigma (e, evd3, _) = new_type_evar newenv evd1 status ~src ~filter in
+ (Sigma.to_evar_map evd3, e)
+ in
let prods = Univ.sup (univ_of_sort u1) (univ_of_sort srng) in
let evd3 = Evd.set_leq_sort evenv evd3 (Type prods) s in
evd3, rng
@@ -798,8 +812,8 @@ let define_evar_as_sort env evd (ev,args) =
any type has type Type. May cause some trouble, but not so far... *)
let judge_of_new_Type evd =
- let evd', s = new_univ_variable univ_rigid evd in
- evd', { uj_val = mkSort (Type s); uj_type = mkSort (Type (Univ.super s)) }
+ let Sigma (s, evd', p) = Sigma.new_univ_variable univ_rigid evd in
+ Sigma ({ uj_val = mkSort (Type s); uj_type = mkSort (Type (Univ.super s)) }, evd', p)
(* Propagation of constraints through application and abstraction:
Given a type constraint on a functional term, returns the type
diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli
index d87c7ef8d1..bc4c37a918 100644
--- a/pretyping/evarutil.mli
+++ b/pretyping/evarutil.mli
@@ -27,12 +27,12 @@ val new_evar :
?principal:bool -> types -> (constr, 'r) Sigma.sigma
val new_pure_evar :
- named_context_val -> evar_map -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
+ named_context_val -> 'r Sigma.t -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * evar
+ ?principal:bool -> types -> (evar, 'r) Sigma.sigma
-val new_pure_evar_full : evar_map -> evar_info -> evar_map * evar
+val new_pure_evar_full : 'r Sigma.t -> evar_info -> (evar, 'r) Sigma.sigma
(** the same with side-effects *)
val e_new_evar :
@@ -44,23 +44,23 @@ val e_new_evar :
(** Create a new Type existential variable, as we keep track of
them during type-checking and unification. *)
val new_type_evar :
- env -> evar_map -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
+ env -> 'r Sigma.t -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid ->
- evar_map * (constr * sorts)
+ (constr * sorts, 'r) Sigma.sigma
val e_new_type_evar : env -> evar_map ref ->
?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid -> constr * sorts
-val new_Type : ?rigid:rigid -> env -> evar_map -> evar_map * constr
+val new_Type : ?rigid:rigid -> env -> 'r Sigma.t -> (constr, 'r) Sigma.sigma
val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
-val restrict_evar : evar_map -> existential_key -> Filter.t ->
- constr list option -> evar_map * existential_key
+val restrict_evar : 'r Sigma.t -> existential_key -> Filter.t ->
+ constr list option -> (existential_key, 'r) Sigma.sigma
(** Polymorphic constants *)
-val new_global : evar_map -> Globnames.global_reference -> evar_map * constr
+val new_global : 'r Sigma.t -> Globnames.global_reference -> (constr, 'r) Sigma.sigma
val e_new_global : evar_map ref -> Globnames.global_reference -> constr
(** Create a fresh evar in a context different from its definition context:
@@ -70,11 +70,11 @@ val e_new_global : evar_map ref -> Globnames.global_reference -> constr
of [inst] are typed in the occurrence context and their type (seen
as a telescope) is [sign] *)
val new_evar_instance :
- named_context_val -> evar_map -> types ->
- ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t -> ?candidates:constr list ->
+ named_context_val -> 'r Sigma.t -> types ->
+ ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t -> ?candidates:constr list ->
?store:Store.t -> ?naming:Misctypes.intro_pattern_naming_expr ->
?principal:bool ->
- constr list -> evar_map * constr
+ constr list -> (constr, 'r) Sigma.sigma
val make_pure_subst : evar_info -> constr array -> (Id.t * constr) list
@@ -138,7 +138,7 @@ val occur_evar_upto : evar_map -> Evar.t -> Constr.t -> bool
(** {6 Value/Type constraints} *)
-val judge_of_new_Type : evar_map -> evar_map * unsafe_judgment
+val judge_of_new_Type : 'r Sigma.t -> (unsafe_judgment, 'r) Sigma.sigma
type type_constraint = types option
type val_constraint = constr option
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 11fba7b941..835dc2f808 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -42,6 +42,7 @@ open Glob_ops
open Evarconv
open Pattern
open Misctypes
+open Sigma.Notations
type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = constr_under_binders Id.Map.t
@@ -444,10 +445,13 @@ let pretype_sort evdref = function
| GType s -> evd_comb1 judge_of_Type evdref s
let new_type_evar env evdref loc =
- let e, s =
- evd_comb0 (fun evd -> Evarutil.new_type_evar env evd
- univ_flexible_alg ~src:(loc,Evar_kinds.InternalHole)) evdref
- in e
+ let sigma = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma ((e, _), sigma, _) =
+ Evarutil.new_type_evar env sigma
+ univ_flexible_alg ~src:(loc,Evar_kinds.InternalHole)
+ in
+ evdref := Sigma.to_evar_map sigma;
+ e
let (f_genarg_interp, genarg_interp_hook) = Hook.make ()
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index bd46911c92..085aaf78a1 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -23,6 +23,7 @@ open Reductionops
open Cbv
open Patternops
open Locus
+open Sigma.Notations
(* Errors *)
@@ -385,7 +386,9 @@ let substl_with_function subst sigma constr =
if i <= k + Array.length v then
match v.(i-k-1) with
| (fx, Some (min, ref)) ->
- let (sigma, evk) = Evarutil.new_pure_evar venv !evd dummy in
+ let sigma = Sigma.Unsafe.of_evar_map !evd in
+ let Sigma (evk, sigma, _) = Evarutil.new_pure_evar venv sigma dummy in
+ let sigma = Sigma.to_evar_map sigma in
evd := sigma;
minargs := Evar.Map.add evk min !minargs;
lift k (mkEvar (evk, [|fx;ref|]))
diff --git a/proofs/goal.ml b/proofs/goal.ml
index 43a3024e50..1251dacd5d 100644
--- a/proofs/goal.ml
+++ b/proofs/goal.ml
@@ -9,6 +9,7 @@
open Util
open Pp
open Term
+open Sigma.Notations
(* This module implements the abstract interface to goals *)
(* A general invariant of the module, is that a goal whose associated
@@ -70,7 +71,9 @@ module V82 = struct
Evd.evar_extra = extra }
in
let evi = Typeclasses.mark_unresolvable evi in
- let (evars, evk) = Evarutil.new_pure_evar_full evars evi in
+ let evars = Sigma.Unsafe.of_evar_map evars in
+ let Sigma (evk, evars, _) = Evarutil.new_pure_evar_full evars evi in
+ let evars = Sigma.to_evar_map evars in
let evars = Evd.restore_future_goals evars prev_future_goals prev_principal_goal in
let ctxt = Environ.named_context_of_val hyps in
let inst = Array.map_of_list (fun (id, _, _) -> mkVar id) ctxt in
@@ -126,8 +129,10 @@ module V82 = struct
let new_evi =
{ evi with Evd.evar_hyps = new_hyps; Evd.evar_filter = new_filter } in
let new_evi = Typeclasses.mark_unresolvable new_evi in
- let (new_sigma, evk) = Evarutil.new_pure_evar_full Evd.empty new_evi in
- { Evd.it = evk ; sigma = new_sigma; }
+ let sigma = Sigma.Unsafe.of_evar_map Evd.empty in
+ let Sigma (evk, sigma, _) = Evarutil.new_pure_evar_full sigma new_evi in
+ let sigma = Sigma.to_evar_map sigma in
+ { Evd.it = evk ; sigma = sigma; }
(* Used by the compatibility layer and typeclasses *)
let nf_evar sigma gl =
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 29002af9e0..c50535a17a 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -64,8 +64,10 @@ type evars = evar_map * Evar.Set.t (* goal evars, constraint evars *)
let find_global dir s =
let gr = lazy (try_find_global_reference dir s) in
- fun (evd,cstrs) ->
- let evd, c = Evarutil.new_global evd (Lazy.force gr) in
+ fun (evd,cstrs) ->
+ let sigma = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (c, sigma, _) = Evarutil.new_global sigma (Lazy.force gr) in
+ let evd = Sigma.to_evar_map sigma in
(evd, cstrs), c
(** Utility for dealing with polymorphic applications *)
@@ -172,13 +174,17 @@ end) = struct
let proper_type =
let l = lazy (Lazy.force proper_class).cl_impl in
fun (evd,cstrs) ->
- let evd, c = Evarutil.new_global evd (Lazy.force l) in
+ let sigma = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (c, sigma, _) = Evarutil.new_global sigma (Lazy.force l) in
+ let evd = Sigma.to_evar_map sigma in
(evd, cstrs), c
let proper_proxy_type =
let l = lazy (Lazy.force proper_proxy_class).cl_impl in
fun (evd,cstrs) ->
- let evd, c = Evarutil.new_global evd (Lazy.force l) in
+ let sigma = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (c, sigma, _) = Evarutil.new_global sigma (Lazy.force l) in
+ let evd = Sigma.to_evar_map sigma in
(evd, cstrs), c
let proper_proof env evars carrier relation x =
@@ -347,7 +353,9 @@ end) = struct
(try
let params, args = Array.chop (Array.length args - 2) args in
let env' = Environ.push_rel_context rels env in
- let evars, (evar, _) = Evarutil.new_type_evar env' sigma Evd.univ_flexible in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma ((evar, _), evars, _) = Evarutil.new_type_evar env' sigma Evd.univ_flexible in
+ let evars = Sigma.to_evar_map sigma in
let evars, inst =
app_poly env (evars,Evar.Set.empty)
rewrite_relation_class [| evar; mkApp (c, params) |] in
@@ -407,7 +415,9 @@ module TypeGlobal = struct
let inverse env (evd,cstrs) car rel =
- let evd, sort = Evarutil.new_Type ~rigid:Evd.univ_flexible env evd in
+ let sigma = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (sort, sigma, _) = Evarutil.new_Type ~rigid:Evd.univ_flexible env sigma in
+ let evd = Sigma.to_evar_map sigma in
app_poly_check env (evd,cstrs) coq_inverse [| car ; car; sort; rel |]
end
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index aeb3726a0c..46e8798543 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -163,14 +163,13 @@ let _ =
does not check anything. *)
let unsafe_intro env store (id, c, t) b =
Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
- let sigma = Sigma.to_evar_map sigma in
let ctx = named_context_val env in
let nctx = push_named_context_val (id, c, t) ctx in
let inst = List.map (fun (id, _, _) -> mkVar id) (named_context env) in
let ninst = mkRel 1 :: inst in
let nb = subst1 (mkVar id) b in
- let sigma, ev = new_evar_instance nctx sigma nb ~principal:true ~store ninst in
- Sigma.Unsafe.of_pair (mkNamedLambda_or_LetIn (id, c, t) ev, sigma)
+ let Sigma (ev, sigma, p) = new_evar_instance nctx sigma nb ~principal:true ~store ninst in
+ Sigma (mkNamedLambda_or_LetIn (id, c, t) ev, sigma, p)
end }
let introduction ?(check=true) id =
@@ -344,9 +343,7 @@ let rename_hyp repl =
let nctx = Environ.val_of_named_context nhyps in
let instance = List.map (fun (id, _, _) -> mkVar id) hyps in
Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = Evarutil.new_evar_instance nctx sigma nconcl ~store instance in
- Sigma.Unsafe.of_pair (c, sigma)
+ Evarutil.new_evar_instance nctx sigma nconcl ~store instance
end }
end }
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 7ae2030343..480e97169c 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -24,6 +24,7 @@ open Type_errors
open Constrexpr
open Constrexpr_ops
open Goptions
+open Sigma.Notations
(********** definition d'un record (structure) **************)
@@ -336,11 +337,15 @@ let structure_signature ctx =
match l with [] -> Evd.empty
| [(_,_,typ)] ->
let env = Environ.empty_named_context_val in
- let (evm, _) = Evarutil.new_pure_evar env evm typ in
+ let evm = Sigma.Unsafe.of_evar_map evm in
+ let Sigma (_, evm, _) = Evarutil.new_pure_evar env evm typ in
+ let evm = Sigma.to_evar_map evm in
evm
| (_,_,typ)::tl ->
let env = Environ.empty_named_context_val in
- let (evm, ev) = Evarutil.new_pure_evar env evm typ in
+ let evm = Sigma.Unsafe.of_evar_map evm in
+ let Sigma (ev, evm, _) = Evarutil.new_pure_evar env evm typ in
+ let evm = Sigma.to_evar_map evm in
let new_tl = Util.List.map_i
(fun pos (n,c,t) -> n,c,
Termops.replace_term (mkRel pos) (mkEvar(ev,[||])) t) 1 tl in
--
cgit v1.2.3
From 1a8c37ca352c95b4cd530efbbf47f0e7671d1fb3 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 13:31:54 +0100
Subject: Renaming functions in Typing to stick to the standard e_* scheme.
---
plugins/cc/cctac.ml | 2 +-
plugins/decl_mode/decl_proof_instr.ml | 4 ++--
plugins/micromega/coq_micromega.ml | 2 +-
plugins/setoid_ring/newring.ml | 8 ++++----
pretyping/coercion.ml | 2 +-
pretyping/typing.ml | 8 ++++----
pretyping/typing.mli | 6 +++---
proofs/proofview.ml | 8 ++++----
tactics/evar_tactics.ml | 2 +-
tactics/rewrite.ml | 4 ++--
tactics/tacinterp.ml | 2 +-
tactics/tactics.ml | 6 +++---
toplevel/command.ml | 4 ++--
13 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index 09d9cf0195..bea449c31a 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -47,7 +47,7 @@ let whd_delta env=
(* decompose member of equality in an applicative format *)
(** FIXME: evar leak *)
-let sf_of env sigma c = sort_of env (ref sigma) c
+let sf_of env sigma c = e_sort_of env (ref sigma) c
let rec decompose_term env sigma t=
match kind_of_term (whd env t) with
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index f47b355417..47d8eeca28 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -404,7 +404,7 @@ let concl_refiner metas body gls =
let concl = pf_concl gls in
let evd = sig_sig gls in
let env = pf_env gls in
- let sort = family_of_sort (Typing.sort_of env (ref evd) concl) in
+ let sort = family_of_sort (Typing.e_sort_of env (ref evd) concl) in
let rec aux env avoid subst = function
[] -> anomaly ~label:"concl_refiner" (Pp.str "cannot happen")
| (n,typ)::rest ->
@@ -412,7 +412,7 @@ let concl_refiner metas body gls =
let x = id_of_name_using_hdchar env _A Anonymous in
let _x = fresh_id avoid x gls in
let nenv = Environ.push_named (_x,None,_A) env in
- let asort = family_of_sort (Typing.sort_of nenv (ref evd) _A) in
+ let asort = family_of_sort (Typing.e_sort_of nenv (ref evd) _A) in
let nsubst = (n,mkVar _x)::subst in
if List.is_empty rest then
asort,_A,mkNamedLambda _x _A (subst_meta nsubst body)
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 1dd53a3fd8..27daa7e3c6 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -1170,7 +1170,7 @@ struct
let is_prop term =
let ty = Typing.unsafe_type_of (Tacmach.pf_env gl) (Tacmach.project gl) term in
- let sort = Typing.sort_of (Tacmach.pf_env gl) (ref (Tacmach.project gl)) ty in
+ let sort = Typing.e_sort_of (Tacmach.pf_env gl) (ref (Tacmach.project gl)) ty in
Term.is_prop_sort sort in
let rec xparse_formula env tg term =
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index e203b9f651..ed6db90d63 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -527,8 +527,8 @@ let ring_equality env evd (r,add,mul,opp,req) =
match opp with
Some opp -> plapp evd coq_eq_morph [|r;add;mul;opp|]
| None -> plapp evd coq_eq_smorph [|r;add;mul|] in
- let setoid = Typing.solve_evars env evd setoid in
- let op_morph = Typing.solve_evars env evd op_morph in
+ let setoid = Typing.e_solve_evars env evd setoid in
+ let op_morph = Typing.e_solve_evars env evd op_morph in
(setoid,op_morph)
| _ ->
let setoid = setoid_of_relation (Global.env ()) evd r req in
@@ -627,7 +627,7 @@ let make_hyp_list env evd lH =
(fun c l -> plapp evd coq_cons [|carrier; (make_hyp env evd c); l|]) lH
(plapp evd coq_nil [|carrier|])
in
- let l' = Typing.solve_evars env evd l in
+ let l' = Typing.e_solve_evars env evd l in
Evarutil.nf_evars_universes !evd l'
let interp_power env evd pow =
@@ -753,7 +753,7 @@ let make_term_list env evd carrier rl =
let l = List.fold_right
(fun x l -> plapp evd coq_cons [|carrier;x;l|]) rl
(plapp evd coq_nil [|carrier|])
- in Typing.solve_evars env evd l
+ in Typing.e_solve_evars env evd l
let carg = Tacinterp.Value.of_constr
let tacarg expr =
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 489a311bc6..8dae311a9f 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -187,7 +187,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
(subst1 hdy restT') (succ i) (fun x -> eq_app (co x))
else Some (fun x ->
let term = co x in
- Typing.solve_evars env evdref term)
+ Typing.e_solve_evars env evdref term)
in
if isEvar c || isEvar c' then
(* Second-order unification needed. *)
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index fb0c49320f..022c85340a 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -267,7 +267,7 @@ and execute_recdef env evdref (names,lar,vdef) =
and execute_array env evdref = Array.map (execute env evdref)
-let check env evdref c t =
+let e_check env evdref c t =
let env = enrich_env env evdref in
let j = execute env evdref c in
if not (Evarconv.e_cumul env evdref j.uj_type t) then
@@ -283,7 +283,7 @@ let unsafe_type_of env evd c =
(* Sort of a type *)
-let sort_of env evdref c =
+let e_sort_of env evdref c =
let env = enrich_env env evdref in
let j = execute env evdref c in
let a = e_type_judgment env evdref j in
@@ -310,10 +310,10 @@ let e_type_of ?(refresh=false) env evdref c =
c
else j.uj_type
-let solve_evars env evdref c =
+let e_solve_evars env evdref c =
let env = enrich_env env evdref in
let c = (execute env evdref c).uj_val in
(* side-effect on evdref *)
nf_evar !evdref c
-let _ = Evarconv.set_solve_evars solve_evars
+let _ = Evarconv.set_solve_evars e_solve_evars
diff --git a/pretyping/typing.mli b/pretyping/typing.mli
index dafd75231a..e524edcca8 100644
--- a/pretyping/typing.mli
+++ b/pretyping/typing.mli
@@ -24,16 +24,16 @@ val type_of : ?refresh:bool -> env -> evar_map -> constr -> evar_map * types
val e_type_of : ?refresh:bool -> env -> evar_map ref -> constr -> types
(** Typecheck a type and return its sort *)
-val sort_of : env -> evar_map ref -> types -> sorts
+val e_sort_of : env -> evar_map ref -> types -> sorts
(** Typecheck a term has a given type (assuming the type is OK) *)
-val check : env -> evar_map ref -> constr -> types -> unit
+val e_check : env -> evar_map ref -> constr -> types -> unit
(** Returns the instantiated type of a metavariable *)
val meta_type : evar_map -> metavariable -> types
(** Solve existential variables using typing *)
-val solve_evars : env -> evar_map ref -> constr -> constr
+val e_solve_evars : env -> evar_map ref -> constr -> constr
(** Raise an error message if incorrect elimination for this inductive *)
(** (first constr is term to match, second is return predicate) *)
diff --git a/proofs/proofview.ml b/proofs/proofview.ml
index 8008b00253..38e9cafad1 100644
--- a/proofs/proofview.ml
+++ b/proofs/proofview.ml
@@ -1077,10 +1077,10 @@ struct
(** Typecheck the hypotheses. *)
let type_hyp (sigma, env) (na, body, t as decl) =
let evdref = ref sigma in
- let _ = Typing.sort_of env evdref t in
+ let _ = Typing.e_sort_of env evdref t in
let () = match body with
| None -> ()
- | Some body -> Typing.check env evdref body t
+ | Some body -> Typing.e_check env evdref body t
in
(!evdref, Environ.push_named decl env)
in
@@ -1089,12 +1089,12 @@ struct
let (sigma, env) = List.fold_left type_hyp (sigma, env) changed in
(** Typecheck the conclusion *)
let evdref = ref sigma in
- let _ = Typing.sort_of env evdref (Evd.evar_concl info) in
+ let _ = Typing.e_sort_of env evdref (Evd.evar_concl info) in
!evdref
let typecheck_proof c concl env sigma =
let evdref = ref sigma in
- let () = Typing.check env evdref c concl in
+ let () = Typing.e_check env evdref c concl in
!evdref
let (pr_constrv,pr_constr) =
diff --git a/tactics/evar_tactics.ml b/tactics/evar_tactics.ml
index 97b5ba0cc5..30e157ffd3 100644
--- a/tactics/evar_tactics.ml
+++ b/tactics/evar_tactics.ml
@@ -74,7 +74,7 @@ let let_evar name typ =
let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let sigma = ref sigma in
- let _ = Typing.sort_of env sigma typ in
+ let _ = Typing.e_sort_of env sigma typ in
let sigma = Sigma.Unsafe.of_evar_map !sigma in
let id = match name with
| Names.Anonymous ->
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index c50535a17a..d0a090e5c1 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -107,7 +107,7 @@ let extends_undefined evars evars' =
let app_poly_check env evars f args =
let (evars, cstrs), fc = f evars in
let evdref = ref evars in
- let t = Typing.solve_evars env evdref (mkApp (fc, args)) in
+ let t = Typing.e_solve_evars env evdref (mkApp (fc, args)) in
(!evdref, cstrs), t
let app_poly_nocheck env evars f args =
@@ -1452,7 +1452,7 @@ type result = (evar_map * constr option * types) option option
let cl_rewrite_clause_aux ?(abs=None) strat env avoid sigma concl is_hyp : result =
let evdref = ref sigma in
- let sort = Typing.sort_of env evdref concl in
+ let sort = Typing.e_sort_of env evdref concl in
let evars = (!evdref, Evar.Set.empty) in
let evars, cstr =
let prop, (evars, arrow) =
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 1112da4a0d..91711c2f74 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -812,7 +812,7 @@ let interp_may_eval f ist env sigma = function
let ctxt = coerce_to_constr_context (Id.Map.find s ist.lfun) in
let evdref = ref sigma in
let c = subst_meta [Constr_matching.special_meta,ic] ctxt in
- let c = Typing.solve_evars env evdref c in
+ let c = Typing.e_solve_evars env evdref c in
!evdref , c
with
| Not_found ->
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 46e8798543..f76f4f6e20 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -1814,7 +1814,7 @@ let check_is_type env ty msg =
Proofview.tclEVARMAP >>= fun sigma ->
let evdref = ref sigma in
try
- let _ = Typing.sort_of env evdref ty in
+ let _ = Typing.e_sort_of env evdref ty in
Proofview.Unsafe.tclEVARS !evdref
with e when Errors.noncritical e ->
msg e
@@ -1823,10 +1823,10 @@ let check_decl env (_, c, ty) msg =
Proofview.tclEVARMAP >>= fun sigma ->
let evdref = ref sigma in
try
- let _ = Typing.sort_of env evdref ty in
+ let _ = Typing.e_sort_of env evdref ty in
let _ = match c with
| None -> ()
- | Some c -> Typing.check env evdref c ty
+ | Some c -> Typing.e_check env evdref c ty
in
Proofview.Unsafe.tclEVARS !evdref
with e when Errors.noncritical e ->
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 18b2b1444d..b6313cdbab 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -1004,7 +1004,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
~src:(Loc.ghost, Evar_kinds.QuestionMark (Evar_kinds.Define false)) wf_proof;
prop |])
in
- let def = Typing.solve_evars env evdref def in
+ let def = Typing.e_solve_evars env evdref def in
let _ = evdref := Evarutil.nf_evar_map !evdref in
let def = mkApp (def, [|intern_body_lam|]) in
let binders_rel = nf_evar_context !evdref binders_rel in
@@ -1078,7 +1078,7 @@ let interp_recursive isfix fixl notations =
let fixprot =
try
let app = mkApp (delayed_force fix_proto, [|sort; t|]) in
- Typing.solve_evars env evdref app
+ Typing.e_solve_evars env evdref app
with e when Errors.noncritical e -> t
in
(id,None,fixprot) :: env'
--
cgit v1.2.3
From 15b28f0ae1e31506f3fb153fc6e50bc861717eb9 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 14:26:43 +0100
Subject: Moving conversion functions to the new tactic API.
---
plugins/btauto/refl_btauto.ml | 2 +-
plugins/firstorder/rules.ml | 4 +--
plugins/funind/functional_principles_proofs.ml | 4 +--
plugins/funind/invfun.ml | 10 +++---
plugins/funind/recdef.ml | 14 ++++----
plugins/omega/coq_omega.ml | 46 +++++++++++++-------------
plugins/romega/refl_omega.ml | 2 +-
plugins/setoid_ring/newring.ml | 4 +--
tactics/class_tactics.ml | 2 +-
tactics/eauto.ml4 | 2 +-
tactics/eqdecide.ml | 2 +-
tactics/equality.ml | 4 +--
tactics/rewrite.ml | 4 +--
tactics/tactics.ml | 21 +++++++-----
tactics/tactics.mli | 40 +++++++++++-----------
toplevel/auto_ind_decl.ml | 6 ++--
16 files changed, 85 insertions(+), 82 deletions(-)
diff --git a/plugins/btauto/refl_btauto.ml b/plugins/btauto/refl_btauto.ml
index 5a49fc8f45..57eb80f5fb 100644
--- a/plugins/btauto/refl_btauto.ml
+++ b/plugins/btauto/refl_btauto.ml
@@ -250,7 +250,7 @@ module Btauto = struct
Tacticals.New.tclTHENLIST [
Tactics.change_concl changed_gl;
Tactics.apply (Lazy.force soundness);
- Proofview.V82.tactic (Tactics.normalise_vm_in_concl);
+ Tactics.normalise_vm_in_concl;
try_unification env
]
| _ ->
diff --git a/plugins/firstorder/rules.ml b/plugins/firstorder/rules.ml
index e676a8a936..d539eda579 100644
--- a/plugins/firstorder/rules.ml
+++ b/plugins/firstorder/rules.ml
@@ -210,6 +210,6 @@ let defined_connectives=lazy
let normalize_evaluables=
onAllHypsAndConcl
(function
- None->unfold_in_concl (Lazy.force defined_connectives)
+ None-> Proofview.V82.of_tactic (unfold_in_concl (Lazy.force defined_connectives))
| Some id ->
- unfold_in_hyp (Lazy.force defined_connectives) (id,InHypTypeOnly))
+ Proofview.V82.of_tactic (unfold_in_hyp (Lazy.force defined_connectives) (id,InHypTypeOnly)))
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 4eab5f9126..aa89f89b74 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -1334,7 +1334,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
in
let fname = destConst (fst (decompose_app (List.hd (List.rev pte_args)))) in
tclTHENSEQ
- [unfold_in_concl [(Locus.AllOccurrences, Names.EvalConstRef (fst fname))];
+ [Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, Names.EvalConstRef (fst fname))]);
let do_prove =
build_proof
interactive_proof
@@ -1460,7 +1460,7 @@ let new_prove_with_tcc is_mes acc_inv hrec tcc_hyps eqs : tactic =
(fun g ->
if is_mes
then
- unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference (delayed_force ltof_ref))] g
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference (delayed_force ltof_ref))]) g
else tclIDTAC g
);
observe_tac "rew_and_finish"
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index 0c9d3bb819..ae2091a227 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -484,15 +484,15 @@ and intros_with_rewrite_aux : tactic =
tclTHENSEQ [ Proofview.V82.of_tactic (Simple.intro id); thin [id]; intros_with_rewrite ] g
else if isVar args.(1) && (Environ.evaluable_named (destVar args.(1)) (pf_env g))
then tclTHENSEQ[
- unfold_in_concl [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(1)))];
- tclMAP (fun id -> tclTRY(unfold_in_hyp [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(1)))] ((destVar args.(1)),Locus.InHyp) ))
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(1)))]);
+ tclMAP (fun id -> tclTRY(Proofview.V82.of_tactic (unfold_in_hyp [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(1)))] ((destVar args.(1)),Locus.InHyp) )))
(pf_ids_of_hyps g);
intros_with_rewrite
] g
else if isVar args.(2) && (Environ.evaluable_named (destVar args.(2)) (pf_env g))
then tclTHENSEQ[
- unfold_in_concl [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(2)))];
- tclMAP (fun id -> tclTRY(unfold_in_hyp [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(2)))] ((destVar args.(2)),Locus.InHyp) ))
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(2)))]);
+ tclMAP (fun id -> tclTRY(Proofview.V82.of_tactic (unfold_in_hyp [(Locus.AllOccurrences, Names.EvalVarRef (destVar args.(2)))] ((destVar args.(2)),Locus.InHyp) )))
(pf_ids_of_hyps g);
intros_with_rewrite
] g
@@ -703,7 +703,7 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
thin ids
]
else
- unfold_in_concl [(Locus.AllOccurrences, Names.EvalConstRef (fst (destConst f)))]
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, Names.EvalConstRef (fst (destConst f)))])
in
(* The proof of each branche itself *)
let ind_number = ref 0 in
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index b096783412..834d0aceac 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -276,8 +276,8 @@ let tclUSER tac is_mes l g =
if is_mes
then observe_tclTHENLIST (str "tclUSER2")
[
- unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference
- (delayed_force Indfun_common.ltof_ref))];
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference
+ (delayed_force Indfun_common.ltof_ref))]);
tac
]
else tac
@@ -564,8 +564,8 @@ let rec destruct_bounds_aux infos (bound,hyple,rechyps) lbounds g =
h_intros [k;h';def];
observe_tac (str "simple_iter") (simpl_iter Locusops.onConcl);
observe_tac (str "unfold functional")
- (unfold_in_concl[(Locus.OnlyOccurrences [1],
- evaluable_of_global_reference infos.func)]);
+ (Proofview.V82.of_tactic (unfold_in_concl[(Locus.OnlyOccurrences [1],
+ evaluable_of_global_reference infos.func)]));
(
observe_tclTHENLIST (str "test")[
list_rewrite true
@@ -904,8 +904,8 @@ let make_rewrite expr_info l hp max =
(observe_tclTHENLIST (str "make_rewrite")[
simpl_iter Locusops.onConcl;
observe_tac (str "unfold functional")
- (unfold_in_concl[(Locus.OnlyOccurrences [1],
- evaluable_of_global_reference expr_info.func)]);
+ (Proofview.V82.of_tactic (unfold_in_concl[(Locus.OnlyOccurrences [1],
+ evaluable_of_global_reference expr_info.func)]));
(list_rewrite true
(List.map (fun e -> mkVar e,true) expr_info.eqs));
@@ -1425,7 +1425,7 @@ let start_equation (f:global_reference) (term_f:global_reference)
let x = n_x_id ids nargs in
observe_tac (str "start_equation") (observe_tclTHENLIST (str "start_equation") [
h_intros x;
- unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference f)];
+ Proofview.V82.of_tactic (unfold_in_concl [(Locus.AllOccurrences, evaluable_of_global_reference f)]);
observe_tac (str "simplest_case")
(Proofview.V82.of_tactic (simplest_case (mkApp (terminate_constr,
Array.of_list (List.map mkVar x)))));
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 7e38109d67..ad63c90f27 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -927,15 +927,15 @@ let rec transform p t =
transform p
(mkApp (Lazy.force coq_Zplus,
[| t1; (mkApp (Lazy.force coq_Zopp, [| t2 |])) |])) in
- unfold sp_Zminus :: tac,t
+ Proofview.V82.of_tactic (unfold sp_Zminus) :: tac,t
| Kapp(Zsucc,[t1]) ->
let tac,t = transform p (mkApp (Lazy.force coq_Zplus,
[| t1; mk_integer one |])) in
- unfold sp_Zsucc :: tac,t
+ Proofview.V82.of_tactic (unfold sp_Zsucc) :: tac,t
| Kapp(Zpred,[t1]) ->
let tac,t = transform p (mkApp (Lazy.force coq_Zplus,
[| t1; mk_integer negone |])) in
- unfold sp_Zpred :: tac,t
+ Proofview.V82.of_tactic (unfold sp_Zpred) :: tac,t
| Kapp(Zmult,[t1;t2]) ->
let tac1,t1' = transform (P_APP 1 :: p) t1
and tac2,t2' = transform (P_APP 2 :: p) t2 in
@@ -1091,8 +1091,8 @@ let replay_history tactic_normalisation =
in
Tacticals.New.tclTHENS
(Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zle);
- Proofview.V82.tactic (simpl_in_concl);
+ unfold sp_Zle;
+ simpl_in_concl;
intro;
(absurd not_sup_sup) ])
[ assumption ; reflexivity ]
@@ -1135,10 +1135,10 @@ let replay_history tactic_normalisation =
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHENLIST [
- (Proofview.V82.tactic (unfold sp_Zgt));
- (Proofview.V82.tactic simpl_in_concl);
+ (unfold sp_Zgt);
+ simpl_in_concl;
reflexivity ] ];
- Tacticals.New.tclTHENLIST [ Proofview.V82.tactic (unfold sp_Zgt); Proofview.V82.tactic simpl_in_concl; reflexivity ]
+ Tacticals.New.tclTHENLIST [ unfold sp_Zgt; simpl_in_concl; reflexivity ]
];
Tacticals.New.tclTHEN (Proofview.V82.tactic (mk_then tac)) reflexivity ]
@@ -1160,18 +1160,18 @@ let replay_history tactic_normalisation =
[mkApp (Lazy.force coq_OMEGA4,
[| dd;kk;eq2;mkVar aux1; mkVar aux2 |])]);
Proofview.V82.tactic (clear [aux1;aux2]);
- Proofview.V82.tactic (unfold sp_not);
+ unfold sp_not;
(intros_using [aux]);
Proofview.V82.tactic (resolve_id aux);
Proofview.V82.tactic (mk_then tac);
assumption ] ;
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zgt);
- Proofview.V82.tactic simpl_in_concl;
+ unfold sp_Zgt;
+ simpl_in_concl;
reflexivity ] ];
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zgt);
- Proofview.V82.tactic simpl_in_concl;
+ unfold sp_Zgt;
+ simpl_in_concl;
reflexivity ] ]
| EXACT_DIVIDE (e1,k) :: l ->
let id = hyp_of_tag e1.id in
@@ -1208,8 +1208,8 @@ let replay_history tactic_normalisation =
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zgt);
- Proofview.V82.tactic simpl_in_concl;
+ unfold sp_Zgt;
+ simpl_in_concl;
reflexivity ] ];
Tacticals.New.tclTHEN (Proofview.V82.tactic (mk_then tac)) reflexivity ]
| (MERGE_EQ(e3,e1,e2)) :: l ->
@@ -1329,12 +1329,12 @@ let replay_history tactic_normalisation =
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zgt);
- Proofview.V82.tactic simpl_in_concl;
+ unfold sp_Zgt;
+ simpl_in_concl;
reflexivity ] ];
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (unfold sp_Zgt);
- Proofview.V82.tactic simpl_in_concl;
+ unfold sp_Zgt;
+ simpl_in_concl;
reflexivity ] ]
| CONSTANT_NOT_NUL(e,k) :: l ->
Tacticals.New.tclTHEN (Proofview.V82.tactic (generalize_tac [mkVar (hyp_of_tag e)])) Equality.discrConcl
@@ -1343,9 +1343,9 @@ let replay_history tactic_normalisation =
| CONSTANT_NEG(e,k) :: l ->
Tacticals.New.tclTHENLIST [
Proofview.V82.tactic (generalize_tac [mkVar (hyp_of_tag e)]);
- Proofview.V82.tactic (unfold sp_Zle);
- Proofview.V82.tactic simpl_in_concl;
- Proofview.V82.tactic (unfold sp_not);
+ unfold sp_Zle;
+ simpl_in_concl;
+ unfold sp_not;
(intros_using [aux]);
Proofview.V82.tactic (resolve_id aux);
reflexivity
@@ -1839,7 +1839,7 @@ let destructure_goal =
match destructurate_prop t with
| Kapp(Not,[t]) ->
(Tacticals.New.tclTHEN
- (Tacticals.New.tclTHEN (Proofview.V82.tactic (unfold sp_not)) intro)
+ (Tacticals.New.tclTHEN (unfold sp_not) intro)
destructure_hyps)
| Kimp(a,b) -> (Tacticals.New.tclTHEN intro (loop b))
| Kapp(False,[]) -> destructure_hyps
diff --git a/plugins/romega/refl_omega.ml b/plugins/romega/refl_omega.ml
index 560e6a899e..177c870b3c 100644
--- a/plugins/romega/refl_omega.ml
+++ b/plugins/romega/refl_omega.ml
@@ -1285,7 +1285,7 @@ let resolution env full_reified_goal systems_list =
Proofview.V82.of_tactic (Tactics.change_concl reified) >>
Proofview.V82.of_tactic (Tactics.apply (app coq_do_omega [|decompose_tactic; normalization_trace|])) >>
show_goal >>
- Tactics.normalise_vm_in_concl >>
+ Proofview.V82.of_tactic (Tactics.normalise_vm_in_concl) >>
(*i Alternatives to the previous line:
- Normalisation without VM:
Tactics.normalise_in_concl
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index ed6db90d63..a67cc7cb87 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -99,10 +99,10 @@ let protect_red map env sigma c =
(mk_clos_but (lookup_map map c) (Esubst.subs_id 0) c);;
let protect_tac map =
- Tactics.reduct_option (protect_red map,DEFAULTcast) None ;;
+ Proofview.V82.of_tactic (Tactics.reduct_option (protect_red map,DEFAULTcast) None);;
let protect_tac_in map id =
- Tactics.reduct_option (protect_red map,DEFAULTcast) (Some(id, Locus.InHyp));;
+ Proofview.V82.of_tactic (Tactics.reduct_option (protect_red map,DEFAULTcast) (Some(id, Locus.InHyp)));;
(****************************************************************************)
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index c9b2c7cfde..3ac3daef9a 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -245,7 +245,7 @@ and e_my_find_search db_list local_db hdc complete sigma concl =
Proofview.V82.tactic (tclTHEN
(Proofview.V82.of_tactic ((with_prods nprods poly (term,cl) (unify_e_resolve poly flags))))
(if complete then tclIDTAC else e_trivial_fail_db db_list local_db))
- | Unfold_nth c -> Proofview.V82.tactic (tclWEAK_PROGRESS (unfold_in_concl [AllOccurrences,c]))
+ | Unfold_nth c -> Proofview.V82.tactic (tclWEAK_PROGRESS (Proofview.V82.of_tactic (unfold_in_concl [AllOccurrences,c])))
| Extern tacast -> conclPattern concl p tacast
in
let tac = Proofview.V82.of_tactic (run_hint t tac) in
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4
index 6117c8b432..ae85f02d59 100644
--- a/tactics/eauto.ml4
+++ b/tactics/eauto.ml4
@@ -503,7 +503,7 @@ let autounfolds db occs cls gl =
let ids = Idset.filter (fun id -> List.mem id hyps) ids in
Cset.fold (fun cst -> cons (AllOccurrences, EvalConstRef cst)) csts
(Id.Set.fold (fun id -> cons (AllOccurrences, EvalVarRef id)) ids [])) db)
- in unfold_option unfolds cls gl
+ in Proofview.V82.of_tactic (unfold_option unfolds cls) gl
let autounfold db cls gl =
let cls = concrete_clause_of (fun () -> pf_ids_of_hyps gl) cls in
diff --git a/tactics/eqdecide.ml b/tactics/eqdecide.ml
index be4b135974..7c821ddcb5 100644
--- a/tactics/eqdecide.ml
+++ b/tactics/eqdecide.ml
@@ -123,7 +123,7 @@ let diseqCase hyps eqonleft =
(tclTHEN (intro_using diseq)
(tclTHEN (choose_noteq eqonleft)
(tclTHEN (rewrite_and_clear (List.rev hyps))
- (tclTHEN (Proofview.V82.tactic red_in_concl)
+ (tclTHEN (red_in_concl)
(tclTHEN (intro_using absurd)
(tclTHEN (Simple.apply (mkVar diseq))
(tclTHEN (Extratactics.injHyp absurd)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 1e814e861c..c9ecc55d18 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1622,8 +1622,8 @@ let unfold_body x =
let hl = List.fold_right (fun (y,yval,_) cl -> (y,InHyp) :: cl) aft [] in
let xvar = mkVar x in
let rfun _ _ c = replace_term xvar xval c in
- let reducth h = Proofview.V82.tactic (fun gl -> reduct_in_hyp rfun h gl) in
- let reductc = Proofview.V82.tactic (fun gl -> reduct_in_concl (rfun, DEFAULTcast) gl) in
+ let reducth h = reduct_in_hyp rfun h in
+ let reductc = reduct_in_concl (rfun, DEFAULTcast) in
tclTHENLIST [tclMAP reducth hl; reductc]
end
end }
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index d0a090e5c1..8b71affffa 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -1569,10 +1569,10 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
convert_concl_no_check newt DEFAULTcast
in
let beta_red _ sigma c = Reductionops.nf_betaiota sigma c in
- let beta = Proofview.V82.tactic (Tactics.reduct_in_concl (beta_red, DEFAULTcast)) in
+ let beta = Tactics.reduct_in_concl (beta_red, DEFAULTcast) in
let opt_beta = match clause with
| None -> Proofview.tclUNIT ()
- | Some id -> Proofview.V82.tactic (Tactics.reduct_in_hyp beta_red (id, InHyp))
+ | Some id -> Tactics.reduct_in_hyp beta_red (id, InHyp)
in
Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index f76f4f6e20..28d3ed18a1 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -470,7 +470,7 @@ let cofix ido gl = match ido with
type tactic_reduction = env -> evar_map -> constr -> constr
let pf_reduce_decl redfun where (id,c,ty) gl =
- let redfun' = Tacmach.pf_reduce redfun gl in
+ let redfun' = Tacmach.New.pf_apply redfun gl in
match c with
| None ->
if where == InHypValueOnly then
@@ -549,12 +549,15 @@ let bind_red_expr_occurrences occs nbcl redexp =
reduction function either to the conclusion or to a
certain hypothesis *)
-let reduct_in_concl (redfun,sty) gl =
- Proofview.V82.of_tactic (convert_concl_no_check (Tacmach.pf_reduce redfun gl (Tacmach.pf_concl gl)) sty) gl
+let reduct_in_concl (redfun,sty) =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ convert_concl_no_check (Tacmach.New.pf_apply redfun gl (Tacmach.New.pf_concl gl)) sty
+ end }
-let reduct_in_hyp ?(check=false) redfun (id,where) gl =
- Proofview.V82.of_tactic (convert_hyp ~check
- (pf_reduce_decl redfun where (Tacmach.pf_get_hyp gl id) gl)) gl
+let reduct_in_hyp ?(check=false) redfun (id,where) =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ convert_hyp ~check (pf_reduce_decl redfun where (Tacmach.New.pf_get_hyp id gl) gl)
+ end }
let revert_cast (redfun,kind as r) =
if kind == DEFAULTcast then (redfun,REVERTcast) else r
@@ -798,7 +801,7 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
else Proofview.tclUNIT ()
end <*>
Proofview.tclORELSE
- (Tacticals.New.tclTHEN (Proofview.V82.tactic hnf_in_concl)
+ (Tacticals.New.tclTHEN hnf_in_concl
(intro_then_gen name_flag move_flag false dep_flag tac))
begin function (e, info) -> match e with
| RefinerError IntroNeedsProduct ->
@@ -2728,8 +2731,8 @@ let unfold_body x gl =
let xvar = mkVar x in
let rfun _ _ c = replace_term xvar xval c in
tclTHENLIST
- [tclMAP (fun h -> reduct_in_hyp rfun h) hl;
- reduct_in_concl (rfun,DEFAULTcast)] gl
+ [tclMAP (fun h -> Proofview.V82.of_tactic (reduct_in_hyp rfun h)) hl;
+ Proofview.V82.of_tactic (reduct_in_concl (rfun,DEFAULTcast))] gl
(* Either unfold and clear if defined or simply clear if not a definition *)
let expand_hyp id = tclTHEN (tclTRY (unfold_body id)) (clear [id])
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 5564b61c37..657367e36c 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -128,38 +128,38 @@ type tactic_reduction = env -> evar_map -> constr -> constr
type change_arg = patvar_map -> constr Sigma.run
val make_change_arg : constr -> change_arg
-val reduct_in_hyp : ?check:bool -> tactic_reduction -> hyp_location -> tactic
-val reduct_option : ?check:bool -> tactic_reduction * cast_kind -> goal_location -> tactic
-val reduct_in_concl : tactic_reduction * cast_kind -> tactic
+val reduct_in_hyp : ?check:bool -> tactic_reduction -> hyp_location -> unit Proofview.tactic
+val reduct_option : ?check:bool -> tactic_reduction * cast_kind -> goal_location -> unit Proofview.tactic
+val reduct_in_concl : tactic_reduction * cast_kind -> unit Proofview.tactic
val change_in_concl : (occurrences * constr_pattern) option -> change_arg -> unit Proofview.tactic
val change_concl : constr -> unit Proofview.tactic
val change_in_hyp : (occurrences * constr_pattern) option -> change_arg ->
hyp_location -> unit Proofview.tactic
-val red_in_concl : tactic
-val red_in_hyp : hyp_location -> tactic
-val red_option : goal_location -> tactic
-val hnf_in_concl : tactic
-val hnf_in_hyp : hyp_location -> tactic
-val hnf_option : goal_location -> tactic
-val simpl_in_concl : tactic
-val simpl_in_hyp : hyp_location -> tactic
-val simpl_option : goal_location -> tactic
-val normalise_in_concl : tactic
-val normalise_in_hyp : hyp_location -> tactic
-val normalise_option : goal_location -> tactic
-val normalise_vm_in_concl : tactic
+val red_in_concl : unit Proofview.tactic
+val red_in_hyp : hyp_location -> unit Proofview.tactic
+val red_option : goal_location -> unit Proofview.tactic
+val hnf_in_concl : unit Proofview.tactic
+val hnf_in_hyp : hyp_location -> unit Proofview.tactic
+val hnf_option : goal_location -> unit Proofview.tactic
+val simpl_in_concl : unit Proofview.tactic
+val simpl_in_hyp : hyp_location -> unit Proofview.tactic
+val simpl_option : goal_location -> unit Proofview.tactic
+val normalise_in_concl : unit Proofview.tactic
+val normalise_in_hyp : hyp_location -> unit Proofview.tactic
+val normalise_option : goal_location -> unit Proofview.tactic
+val normalise_vm_in_concl : unit Proofview.tactic
val unfold_in_concl :
- (occurrences * evaluable_global_reference) list -> tactic
+ (occurrences * evaluable_global_reference) list -> unit Proofview.tactic
val unfold_in_hyp :
- (occurrences * evaluable_global_reference) list -> hyp_location -> tactic
+ (occurrences * evaluable_global_reference) list -> hyp_location -> unit Proofview.tactic
val unfold_option :
- (occurrences * evaluable_global_reference) list -> goal_location -> tactic
+ (occurrences * evaluable_global_reference) list -> goal_location -> unit Proofview.tactic
val change :
constr_pattern option -> change_arg -> clause -> tactic
val pattern_option :
(occurrences * constr) list -> goal_location -> tactic
val reduce : red_expr -> clause -> tactic
-val unfold_constr : global_reference -> tactic
+val unfold_constr : global_reference -> unit Proofview.tactic
(** {6 Modification of the local context. } *)
diff --git a/toplevel/auto_ind_decl.ml b/toplevel/auto_ind_decl.ml
index f0c7a39613..c143243b1d 100644
--- a/toplevel/auto_ind_decl.ml
+++ b/toplevel/auto_ind_decl.ml
@@ -580,7 +580,7 @@ let compute_bl_tact mode bl_scheme_key ind lnamesparrec nparrec =
Tacticals.New.tclTRY (
Tacticals.New.tclORELSE reflexivity (Equality.discr_tac false None)
);
- Proofview.V82.tactic (simpl_in_hyp (freshz,Locus.InHyp));
+ simpl_in_hyp (freshz,Locus.InHyp);
(*
repeat ( apply andb_prop in z;let z1:= fresh "Z" in destruct z as [z1 z]).
*)
@@ -724,7 +724,7 @@ let compute_lb_tact mode lb_scheme_key ind lnamesparrec nparrec =
Tacticals.New.tclORELSE reflexivity (Equality.discr_tac false None)
);
Equality.inj None false None (mkVar freshz,NoBindings);
- intros; (Proofview.V82.tactic simpl_in_concl);
+ intros; simpl_in_concl;
Auto.default_auto;
Tacticals.New.tclREPEAT (
Tacticals.New.tclTHENLIST [apply (andb_true_intro());
@@ -901,7 +901,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
let freshH3 = fresh_id (Id.of_string "H") gl in
Tacticals.New.tclTHENLIST [
simplest_right ;
- Proofview.V82.tactic (unfold_constr (Lazy.force Coqlib.coq_not_ref));
+ unfold_constr (Lazy.force Coqlib.coq_not_ref);
intro;
Equality.subst_all ();
assert_by (Name freshH3)
--
cgit v1.2.3
From 4ea9b3193eaced958bb277c0723fb54d661ff520 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 15:17:05 +0100
Subject: More conversion functions in the new tactic API.
---
plugins/funind/functional_principles_proofs.ml | 8 ++---
plugins/funind/indfun.ml | 2 +-
plugins/funind/invfun.ml | 16 +++++-----
plugins/funind/recdef.ml | 4 +--
tactics/auto.ml | 2 +-
tactics/eauto.ml4 | 2 +-
tactics/tacinterp.ml | 2 +-
tactics/tactics.ml | 42 ++++++++++++++------------
tactics/tactics.mli | 4 +--
9 files changed, 42 insertions(+), 40 deletions(-)
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index aa89f89b74..86302dc6ce 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -371,12 +371,12 @@ let isLetIn t =
| _ -> false
-let h_reduce_with_zeta =
- reduce
+let h_reduce_with_zeta cl =
+ Proofview.V82.of_tactic (reduce
(Genredexpr.Cbv
{Redops.all_flags
with Genredexpr.rDelta = false;
- })
+ }) cl)
@@ -707,7 +707,7 @@ let build_proof
[
generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps));
thin dyn_infos.rec_hyps;
- pattern_option [Locus.AllOccurrencesBut [1],t] None;
+ Proofview.V82.of_tactic (pattern_option [Locus.AllOccurrencesBut [1],t] None);
(fun g -> observe_tac "toto" (
tclTHENSEQ [Proofview.V82.of_tactic (Simple.case t);
(fun g' ->
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index d1e1098259..41fd0bd18e 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -113,7 +113,7 @@ let functional_induction with_clean c princl pat =
in
Tacticals.tclTHEN
(Tacticals.tclMAP (fun id -> Tacticals.tclTRY (Proofview.V82.of_tactic (Equality.subst_gen (do_rewrite_dependent ()) [id]))) idl )
- (Tactics.reduce flag Locusops.allHypsAndConcl)
+ (Proofview.V82.of_tactic (Tactics.reduce flag Locusops.allHypsAndConcl))
g
else Tacticals.tclIDTAC g
in
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index ae2091a227..2b45206bb4 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -363,14 +363,14 @@ let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes
(* unfolding of all the defined variables introduced by this branch *)
(* observe_tac "unfolding" pre_tac; *)
(* $zeta$ normalizing of the conclusion *)
- reduce
+ Proofview.V82.of_tactic (reduce
(Genredexpr.Cbv
{ Redops.all_flags with
Genredexpr.rDelta = false ;
Genredexpr.rConst = []
}
)
- Locusops.onConcl;
+ Locusops.onConcl);
observe_tac ("toto ") tclIDTAC;
(* introducing the the result of the graph and the equality hypothesis *)
@@ -532,12 +532,12 @@ and intros_with_rewrite_aux : tactic =
] g
| LetIn _ ->
tclTHENSEQ[
- reduce
+ Proofview.V82.of_tactic (reduce
(Genredexpr.Cbv
{Redops.all_flags
with Genredexpr.rDelta = false;
})
- Locusops.onConcl
+ Locusops.onConcl)
;
intros_with_rewrite
] g
@@ -547,12 +547,12 @@ and intros_with_rewrite_aux : tactic =
end
| LetIn _ ->
tclTHENSEQ[
- reduce
+ Proofview.V82.of_tactic (reduce
(Genredexpr.Cbv
{Redops.all_flags
with Genredexpr.rDelta = false;
})
- Locusops.onConcl
+ Locusops.onConcl)
;
intros_with_rewrite
] g
@@ -692,12 +692,12 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
Proofview.V82.of_tactic (Equality.rewriteLR (mkConst eq_lemma));
(* Don't forget to $\zeta$ normlize the term since the principles
have been $\zeta$-normalized *)
- reduce
+ Proofview.V82.of_tactic (reduce
(Genredexpr.Cbv
{Redops.all_flags
with Genredexpr.rDelta = false;
})
- Locusops.onConcl
+ Locusops.onConcl)
;
generalize (List.map mkVar ids);
thin ids
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 834d0aceac..6c6caa6284 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -562,7 +562,7 @@ let rec destruct_bounds_aux infos (bound,hyple,rechyps) lbounds g =
observe_tclTHENLIST (str "destruct_bounds_aux2")[
observe_tac (str "clearing k ") (clear [id]);
h_intros [k;h';def];
- observe_tac (str "simple_iter") (simpl_iter Locusops.onConcl);
+ observe_tac (str "simple_iter") (Proofview.V82.of_tactic (simpl_iter Locusops.onConcl));
observe_tac (str "unfold functional")
(Proofview.V82.of_tactic (unfold_in_concl[(Locus.OnlyOccurrences [1],
evaluable_of_global_reference infos.func)]));
@@ -902,7 +902,7 @@ let make_rewrite expr_info l hp max =
[observe_tac(str "make_rewrite finalize") (
(* tclORELSE( h_reflexivity) *)
(observe_tclTHENLIST (str "make_rewrite")[
- simpl_iter Locusops.onConcl;
+ Proofview.V82.of_tactic (simpl_iter Locusops.onConcl);
observe_tac (str "unfold functional")
(Proofview.V82.of_tactic (unfold_in_concl[(Locus.OnlyOccurrences [1],
evaluable_of_global_reference expr_info.func)]));
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 6caebf6c4f..1d6cd8e99b 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -390,7 +390,7 @@ and tac_of_hint dbg db_list local_db concl (flags, ({pat=p; code=t;poly=poly}))
| Unfold_nth c ->
Proofview.V82.tactic (fun gl ->
if exists_evaluable_reference (pf_env gl) c then
- tclPROGRESS (reduce (Unfold [AllOccurrences,c]) Locusops.onConcl) gl
+ tclPROGRESS (Proofview.V82.of_tactic (reduce (Unfold [AllOccurrences,c]) Locusops.onConcl)) gl
else tclFAIL 0 (str"Unbound reference") gl)
| Extern tacast ->
conclPattern concl p tacast
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4
index ae85f02d59..f2d26ec86b 100644
--- a/tactics/eauto.ml4
+++ b/tactics/eauto.ml4
@@ -198,7 +198,7 @@ and e_my_find_search db_list local_db hdc concl =
| Res_pf_THEN_trivial_fail (term,cl) ->
Tacticals.New.tclTHEN (unify_e_resolve poly st (term,cl))
(e_trivial_fail_db db_list local_db)
- | Unfold_nth c -> Proofview.V82.tactic (reduce (Unfold [AllOccurrences,c]) onConcl)
+ | Unfold_nth c -> reduce (Unfold [AllOccurrences,c]) onConcl
| Extern tacast -> conclPattern concl p tacast
in
let tac = run_hint t tac in
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 91711c2f74..73aa4c3373 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1967,7 +1967,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let (sigma,r_interp) = interp_red_expr ist (pf_env gl) (project gl) r in
tclTHEN
(tclEVARS sigma)
- (Tactics.reduce r_interp (interp_clause ist (pf_env gl) (project gl) cl))
+ (Proofview.V82.of_tactic (Tactics.reduce r_interp (interp_clause ist (pf_env gl) (project gl) cl)))
gl
end
end
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 28d3ed18a1..210888b67c 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -569,8 +569,8 @@ let reduct_option ?(check=false) redfun = function
(** Tactic reduction modulo evars (for universes essentially) *)
let pf_e_reduce_decl redfun where (id,c,ty) gl =
- let sigma = project gl in
- let redfun = redfun (pf_env gl) in
+ let sigma = Tacmach.New.project gl in
+ let redfun = redfun (Tacmach.New.pf_env gl) in
match c with
| None ->
if where == InHypValueOnly then
@@ -582,17 +582,17 @@ let pf_e_reduce_decl redfun where (id,c,ty) gl =
let sigma, ty' = if where != InHypValueOnly then redfun sigma ty else sigma, ty in
sigma, (id,Some b',ty')
-let e_reduct_in_concl (redfun,sty) gl =
- Proofview.V82.of_tactic
- (let sigma, c' = (Tacmach.pf_apply redfun gl (Tacmach.pf_concl gl)) in
- Proofview.Unsafe.tclEVARS sigma <*>
- convert_concl_no_check c' sty) gl
+let e_reduct_in_concl (redfun, sty) =
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma, c' = Tacmach.New.pf_apply redfun gl (Tacmach.New.pf_concl gl) in
+ Sigma.Unsafe.of_pair (convert_concl_no_check c' sty, sigma)
+ end }
-let e_reduct_in_hyp ?(check=false) redfun (id,where) gl =
- Proofview.V82.of_tactic
- (let sigma, decl' = pf_e_reduce_decl redfun where (Tacmach.pf_get_hyp gl id) gl in
- Proofview.Unsafe.tclEVARS sigma <*>
- convert_hyp ~check decl') gl
+let e_reduct_in_hyp ?(check=false) redfun (id, where) =
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma, decl' = pf_e_reduce_decl redfun where (Tacmach.New.pf_get_hyp id gl) gl in
+ Sigma.Unsafe.of_pair (convert_hyp ~check decl', sigma)
+ end }
let e_reduct_option ?(check=false) redfun = function
| Some id -> e_reduct_in_hyp ~check (fst redfun) id
@@ -739,14 +739,16 @@ let reduction_clause redexp cl =
| OnConcl occs ->
(None, bind_red_expr_occurrences occs nbcl redexp)) cl
-let reduce redexp cl goal =
- let cl = concrete_clause_of (fun () -> Tacmach.pf_ids_of_hyps goal) cl in
+let reduce redexp cl =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let cl = concrete_clause_of (fun () -> Tacmach.New.pf_ids_of_hyps gl) cl in
let redexps = reduction_clause redexp cl in
let check = match redexp with Fold _ | Pattern _ -> true | _ -> false in
- let tac = tclMAP (fun (where,redexp) ->
+ let tac = Tacticals.New.tclMAP (fun (where,redexp) ->
e_reduct_option ~check
- (Redexpr.reduction_of_red_expr (Tacmach.pf_env goal) redexp) where) redexps in
- if check then with_check tac goal else tac goal
+ (Redexpr.reduction_of_red_expr (Tacmach.New.pf_env gl) redexp) where) redexps in
+ if check then Proofview.V82.tactic (fun gl -> with_check (Proofview.V82.of_tactic tac) gl) else tac (** FIXME *)
+ end }
(* Unfolding occurrences of a constant *)
@@ -3943,7 +3945,7 @@ let induction_without_atomization isrec with_evars elim names lid =
if indvars = [] then [List.hd lid_params] else indvars in
let induct_tac elim = Proofview.V82.tactic (tclTHENLIST [
(* pattern to make the predicate appear. *)
- reduce (Pattern (List.map inj_with_occurrences lidcstr)) onConcl;
+ Proofview.V82.of_tactic (reduce (Pattern (List.map inj_with_occurrences lidcstr)) onConcl);
(* Induction by "refine (indscheme ?i ?j ?k...)" + resolution of all
possible holes using arguments given by the user (but the
functional one). *)
@@ -4717,9 +4719,9 @@ module New = struct
open Locus
let reduce_after_refine =
- Proofview.V82.tactic (reduce
+ reduce
(Lazy {rBeta=true;rIota=true;rZeta=false;rDelta=false;rConst=[]})
- {onhyps=None; concl_occs=AllOccurrences })
+ {onhyps=None; concl_occs=AllOccurrences }
let refine ?unsafe c =
Proofview.Refine.refine ?unsafe c <*>
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 657367e36c..367430d918 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -157,8 +157,8 @@ val unfold_option :
val change :
constr_pattern option -> change_arg -> clause -> tactic
val pattern_option :
- (occurrences * constr) list -> goal_location -> tactic
-val reduce : red_expr -> clause -> tactic
+ (occurrences * constr) list -> goal_location -> unit Proofview.tactic
+val reduce : red_expr -> clause -> unit Proofview.tactic
val unfold_constr : global_reference -> unit Proofview.tactic
(** {6 Modification of the local context. } *)
--
cgit v1.2.3
From 4689c62b791ae384f2f603c7f22d5088eafa1d3e Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 15:53:25 +0100
Subject: Code factorization of tactic "unfold_body".
---
tactics/equality.ml | 20 --------------------
tactics/tactics.ml | 31 ++++++++++++++++++-------------
tactics/tactics.mli | 2 +-
3 files changed, 19 insertions(+), 34 deletions(-)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index c9ecc55d18..b287eb8e57 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1608,26 +1608,6 @@ user = raise user error specific to rewrite
(**********************************************************************)
(* Substitutions tactics (JCF) *)
-let unfold_body x =
- Proofview.Goal.enter { enter = begin fun gl ->
- (** We normalize the given hypothesis immediately. *)
- let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let (_, xval, _) = Context.Named.lookup x hyps in
- let xval = match xval with
- | None -> errorlabstrm "unfold_body"
- (pr_id x ++ str" is not a defined hypothesis.")
- | Some xval -> pf_nf_evar gl xval
- in
- afterHyp x begin fun aft ->
- let hl = List.fold_right (fun (y,yval,_) cl -> (y,InHyp) :: cl) aft [] in
- let xvar = mkVar x in
- let rfun _ _ c = replace_term xvar xval c in
- let reducth h = reduct_in_hyp rfun h in
- let reductc = reduct_in_concl (rfun, DEFAULTcast) in
- tclTHENLIST [tclMAP reducth hl; reductc]
- end
- end }
-
let restrict_to_eq_and_identity eq = (* compatibility *)
if not (is_global glob_eq eq) &&
not (is_global glob_identity eq)
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 210888b67c..e363538471 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -2721,23 +2721,28 @@ let specialize (c,lbind) =
(* The two following functions should already exist, but found nowhere *)
(* Unfolds x by its definition everywhere *)
-let unfold_body x gl =
- let hyps = pf_hyps gl in
- let xval =
- match Context.Named.lookup x hyps with
- (_,Some xval,_) -> xval
- | _ -> errorlabstrm "unfold_body"
- (pr_id x ++ str" is not a defined hypothesis.") in
- let aft = afterHyp x gl in
+let unfold_body x =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ (** We normalize the given hypothesis immediately. *)
+ let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
+ let (_, xval, _) = Context.Named.lookup x hyps in
+ let xval = match xval with
+ | None -> errorlabstrm "unfold_body"
+ (pr_id x ++ str" is not a defined hypothesis.")
+ | Some xval -> pf_nf_evar gl xval
+ in
+ Tacticals.New.afterHyp x begin fun aft ->
let hl = List.fold_right (fun (y,yval,_) cl -> (y,InHyp) :: cl) aft [] in
let xvar = mkVar x in
let rfun _ _ c = replace_term xvar xval c in
- tclTHENLIST
- [tclMAP (fun h -> Proofview.V82.of_tactic (reduct_in_hyp rfun h)) hl;
- Proofview.V82.of_tactic (reduct_in_concl (rfun,DEFAULTcast))] gl
+ let reducth h = reduct_in_hyp rfun h in
+ let reductc = reduct_in_concl (rfun, DEFAULTcast) in
+ Tacticals.New.tclTHENLIST [Tacticals.New.tclMAP reducth hl; reductc]
+ end
+ end }
(* Either unfold and clear if defined or simply clear if not a definition *)
-let expand_hyp id = tclTHEN (tclTRY (unfold_body id)) (clear [id])
+let expand_hyp id = Tacticals.New.tclTHEN (Tacticals.New.tclTRY (unfold_body id)) (Proofview.V82.tactic (clear [id]))
(*****************************)
(* High-level induction *)
@@ -3891,7 +3896,7 @@ let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
if deps = [] then Proofview.tclUNIT () else apply_type tmpcl deps_cstr;
(* side-conditions in elim (resp case) schemes come last (resp first) *)
induct_tac elim;
- Proofview.V82.tactic (tclMAP expand_hyp toclear)
+ Tacticals.New.tclMAP expand_hyp toclear;
])
(Array.map2
(induct_discharge lhyp0 avoid (re_intro_dependent_hypotheses statuslists))
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 367430d918..26ea017696 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -165,7 +165,7 @@ val unfold_constr : global_reference -> unit Proofview.tactic
val clear : Id.t list -> tactic
val clear_body : Id.t list -> unit Proofview.tactic
-val unfold_body : Id.t -> tactic
+val unfold_body : Id.t -> unit Proofview.tactic
val keep : Id.t list -> unit Proofview.tactic
val apply_clear_request : clear_flag -> bool -> constr -> unit Proofview.tactic
--
cgit v1.2.3
From 4f041384cb27f0d24fa14b272884b4b7f69cacbe Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Mon, 15 Feb 2016 11:55:43 +0100
Subject: CLEANUP: Simplifying the changes done in "kernel/*" ...
...
...
...
...
...
...
...
...
...
...
...
...
...
---
kernel/closure.ml | 11 +++++++----
kernel/cooking.ml | 5 ++---
kernel/csymtable.ml | 8 ++++----
kernel/declareops.ml | 31 +++++--------------------------
kernel/environ.ml | 17 ++++++-----------
kernel/fast_typeops.ml | 3 +--
kernel/inductive.ml | 2 +-
kernel/nativecode.ml | 8 ++++----
8 files changed, 30 insertions(+), 55 deletions(-)
diff --git a/kernel/closure.ml b/kernel/closure.ml
index dc98cc65d0..4476fe5241 100644
--- a/kernel/closure.ml
+++ b/kernel/closure.ml
@@ -245,10 +245,12 @@ and 'a infos = {
let info_flags info = info.i_flags
let info_env info = info.i_cache.i_env
+open Context.Named.Declaration
+
let rec assoc_defined id = function
| [] -> raise Not_found
-| Context.Named.Declaration.LocalAssum _ :: ctxt -> assoc_defined id ctxt
-| Context.Named.Declaration.LocalDef (id', c, _) :: ctxt ->
+| LocalAssum _ :: ctxt -> assoc_defined id ctxt
+| LocalDef (id', c, _) :: ctxt ->
if Id.equal id id' then c else assoc_defined id ctxt
let ref_value_cache ({i_cache = cache} as infos) ref =
@@ -285,9 +287,10 @@ let defined_rels flags env =
let ctx = rel_context env in
let len = List.length ctx in
let ans = Array.make len None in
+ let open Context.Rel.Declaration in
let iter i = function
- | Context.Rel.Declaration.LocalAssum _ -> ()
- | Context.Rel.Declaration.LocalDef (_,b,_) -> Array.unsafe_set ans i (Some b)
+ | LocalAssum _ -> ()
+ | LocalDef (_,b,_) -> Array.unsafe_set ans i (Some b)
in
let () = List.iteri iter ctx in
ans
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index d2106f8609..86d786b09a 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -203,9 +203,8 @@ let cook_constant env { from = cb; info } =
let const_hyps =
Context.Named.fold_outside (fun decl hyps ->
let open Context.Named.Declaration in
- let h = get_id decl in
- List.filter (fun decl -> let id = get_id decl in
- not (Id.equal id h)) hyps)
+ List.filter (fun decl' -> not (Id.equal (get_id decl) (get_id decl')))
+ hyps)
hyps ~init:cb.const_hyps in
let typ = match cb.const_type with
| RegularArity t ->
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index cfbb89f06c..9d58f66154 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -190,8 +190,8 @@ and slot_for_fv env fv =
begin match force_lazy_val nv with
| None ->
let open Context.Named in
- let open Context.Named.Declaration in
- fill_fv_cache nv id val_of_named idfun (lookup id env.env_named_context |> get_value)
+ let open Declaration in
+ env.env_named_context |> lookup id |> get_value |> fill_fv_cache nv id val_of_named idfun
| Some (v, _) -> v
end
| FVrel i ->
@@ -199,8 +199,8 @@ and slot_for_fv env fv =
begin match force_lazy_val rv with
| None ->
let open Context.Rel in
- let open Context.Rel.Declaration in
- fill_fv_cache rv i val_of_rel env_of_rel (lookup i env.env_rel_context |> get_value)
+ let open Declaration in
+ env.env_rel_context |> lookup i |> get_value |> fill_fv_cache rv i val_of_rel env_of_rel
| Some (v, _) -> v
end
| FVuniv_var idu ->
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index cb67135ad4..a09a8b7862 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -9,6 +9,7 @@
open Declarations
open Mod_subst
open Util
+open Context.Rel.Declaration
(** Operations concernings types in [Declarations] :
[constant_body], [mutual_inductive_body], [module_body] ... *)
@@ -87,18 +88,8 @@ let is_opaque cb = match cb.const_body with
(** {7 Constant substitutions } *)
-let subst_rel_declaration sub x =
- let open Context.Rel.Declaration in
- match x with
- | LocalAssum (id,t) ->
- let t' = subst_mps sub t in
- if t == t' then x
- else LocalAssum (id,t')
- | LocalDef (id,v,t) ->
- let v' = subst_mps sub v in
- let t' = subst_mps sub t in
- if v == v' && t == t' then x
- else LocalDef (id,v',t')
+let subst_rel_declaration sub =
+ map_constr (subst_mps sub)
let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
@@ -148,20 +139,8 @@ let subst_const_body sub cb =
share internal fields (e.g. constr), and not the records
themselves. But would it really bring substantial gains ? *)
-let hcons_rel_decl d =
- let open Context.Rel.Declaration in
- match d with
- | LocalAssum (n,t) ->
- let n' = Names.Name.hcons n
- and t' = Term.hcons_types t in
- if n' == n && t' == t then d
- else LocalAssum (n',t')
- | LocalDef (n,v,t) ->
- let n' = Names.Name.hcons n
- and v' = Term.hcons_constr v
- and t' = Term.hcons_types t in
- if n' == n && v' == v && t' == t then d
- else LocalDef (n',v',t')
+let hcons_rel_decl =
+ map_type Term.hcons_types % map_value Term.hcons_constr % map_name Names.Name.hcons
let hcons_rel_context l = List.smartmap hcons_rel_decl l
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 1089dff92c..d8493d9baf 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -27,6 +27,7 @@ open Term
open Vars
open Declarations
open Pre_env
+open Context.Rel.Declaration
(* The type of environments. *)
@@ -72,8 +73,7 @@ let lookup_rel n env =
Context.Rel.lookup n env.env_rel_context
let evaluable_rel n env =
- let open Context.Rel.Declaration in
- lookup_rel n env |> is_local_def
+ is_local_def (lookup_rel n env)
let nb_rel env = env.env_nb_rel
@@ -82,7 +82,6 @@ let push_rel = push_rel
let push_rel_context ctxt x = Context.Rel.fold_outside push_rel ctxt ~init:x
let push_rec_types (lna,typarray,_) env =
- let open Context.Rel.Declaration in
let ctxt = Array.map2_i (fun i na t -> LocalAssum (na, lift i t)) lna typarray in
Array.fold_left (fun e assum -> push_rel assum e) env ctxt
@@ -128,11 +127,13 @@ let eq_named_context_val c1 c2 =
(* A local const is evaluable if it is defined *)
+open Context.Named.Declaration
+
let named_type id env =
- lookup_named id env |> Context.Named.Declaration.get_type
+ get_type (lookup_named id env)
let named_body id env =
- lookup_named id env |> Context.Named.Declaration.get_value
+ get_value (lookup_named id env)
let evaluable_named id env =
match named_body id env with
@@ -417,7 +418,6 @@ let global_vars_set env constr =
contained in the types of the needed variables. *)
let really_needed env needed =
- let open Context.Named.Declaration in
Context.Named.fold_inside
(fun need decl ->
if Id.Set.mem (get_id decl) need then
@@ -436,7 +436,6 @@ let keep_hyps env needed =
let really_needed = really_needed env needed in
Context.Named.fold_outside
(fun d nsign ->
- let open Context.Named.Declaration in
if Id.Set.mem (get_id d) really_needed then Context.Named.add d nsign
else nsign)
(named_context env)
@@ -487,7 +486,6 @@ let compile_constant_body = Cbytegen.compile_constant_body false
exception Hyp_not_found
let apply_to_hyp (ctxt,vals) id f =
- let open Context.Named.Declaration in
let rec aux rtail ctxt vals =
match ctxt, vals with
| d::ctxt, v::vals ->
@@ -501,7 +499,6 @@ let apply_to_hyp (ctxt,vals) id f =
in aux [] ctxt vals
let apply_to_hyp_and_dependent_on (ctxt,vals) id f g =
- let open Context.Named.Declaration in
let rec aux ctxt vals =
match ctxt,vals with
| d::ctxt, v::vals ->
@@ -516,7 +513,6 @@ let apply_to_hyp_and_dependent_on (ctxt,vals) id f g =
in aux ctxt vals
let insert_after_hyp (ctxt,vals) id d check =
- let open Context.Named.Declaration in
let rec aux ctxt vals =
match ctxt, vals with
| decl::ctxt', v::vals' ->
@@ -533,7 +529,6 @@ let insert_after_hyp (ctxt,vals) id d check =
(* To be used in Logic.clear_hyps *)
let remove_hyps ids check_context check_value (ctxt, vals) =
- let open Context.Named.Declaration in
let rec remove_hyps ctxt vals = match ctxt, vals with
| [], [] -> [], []
| d :: rctxt, (nid, v) :: rvals ->
diff --git a/kernel/fast_typeops.ml b/kernel/fast_typeops.ml
index df95c93dc5..7f4ba8ecbe 100644
--- a/kernel/fast_typeops.ml
+++ b/kernel/fast_typeops.ml
@@ -74,8 +74,7 @@ let judge_of_type u =
let judge_of_relative env n =
try
let open Context.Rel.Declaration in
- let typ = get_type (lookup_rel n env) in
- lift n typ
+ env |> lookup_rel n |> get_type |> lift n
with Not_found ->
error_unbound_rel env n
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index ca29d83f6a..229508ea34 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -319,7 +319,7 @@ let is_correct_arity env c pj ind specif params =
let () =
try conv env a1 a1'
with NotConvertible -> raise (LocalArity None) in
- srec (push_rel (LocalAssum (na1,a1)) env) t ar'
+ srec (push_rel (LocalAssum (na1,a1)) env) t ar'
(* The last Prod domain is the type of the scrutinee *)
| Prod (na1,a1,a2), [] -> (* whnf of t was not needed here! *)
let env' = push_rel (LocalAssum (na1,a1)) env in
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 47274a5cd5..dabe905dee 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -1832,10 +1832,10 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
auxdefs, MLlet(aux_name, ml, mkMLapp (MLlocal aux_name) (Array.of_list (fv_rel@fv_named)))
and compile_rel env sigma univ auxdefs n =
- let decl = Context.Rel.lookup n env.env_rel_context in
- let n = Context.Rel.length env.env_rel_context - n in
- let open Context.Rel.Declaration in
- match decl with
+ let open Context.Rel in
+ let n = length env.env_rel_context - n in
+ let open Declaration in
+ match lookup n env.env_rel_context with
| LocalDef (_,t,_) ->
let code = lambda_of_constr env sigma t in
let auxdefs,code = compile_with_fv env sigma univ auxdefs None code in
--
cgit v1.2.3
From 5180ab68819f10949cd41a2458bff877b3ec3204 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 16:45:18 +0100
Subject: Using monotonic types for conversion functions.
---
plugins/funind/recdef.ml | 5 ++--
pretyping/reductionops.ml | 2 +-
pretyping/reductionops.mli | 2 +-
pretyping/tacred.ml | 24 ++++++++++-----
pretyping/tacred.mli | 3 +-
proofs/redexpr.ml | 2 +-
proofs/tacmach.ml | 6 +++-
tactics/extratactics.ml4 | 5 ++--
tactics/rewrite.ml | 4 ++-
tactics/tacinterp.ml | 5 +++-
tactics/tactics.ml | 74 +++++++++++++++++++++++-----------------------
toplevel/command.ml | 13 +++++---
toplevel/vernacentries.ml | 8 ++++-
13 files changed, 90 insertions(+), 63 deletions(-)
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 6c6caa6284..555f08fa86 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -690,9 +690,8 @@ let mkDestructEq :
[generalize new_hyps;
(fun g2 ->
let changefun patvars = { run = fun sigma ->
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = pattern_occs [Locus.AllOccurrencesBut [1], expr] (pf_env g2) sigma (pf_concl g2) in
- Sigma.Unsafe.of_pair (c, sigma)
+ let redfun = pattern_occs [Locus.AllOccurrencesBut [1], expr] in
+ redfun.Reductionops.e_redfun (pf_env g2) sigma (pf_concl g2)
} in
Proofview.V82.of_tactic (change_in_concl None changefun) g2);
Proofview.V82.of_tactic (simplest_case expr)]), to_revert
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 5e21154a67..a677458dab 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -572,7 +572,7 @@ type state = constr * constr Stack.t
type contextual_reduction_function = env -> evar_map -> constr -> constr
type reduction_function = contextual_reduction_function
type local_reduction_function = evar_map -> constr -> constr
-type e_reduction_function = env -> evar_map -> constr -> evar_map * constr
+type e_reduction_function = { e_redfun : 'r. env -> 'r Sigma.t -> constr -> (constr, 'r) Sigma.sigma }
type contextual_stack_reduction_function =
env -> evar_map -> constr -> constr * constr list
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index e65ab83b29..b38252e971 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -108,7 +108,7 @@ type contextual_reduction_function = env -> evar_map -> constr -> constr
type reduction_function = contextual_reduction_function
type local_reduction_function = evar_map -> constr -> constr
-type e_reduction_function = env -> evar_map -> constr -> evar_map * constr
+type e_reduction_function = { e_redfun : 'r. env -> 'r Sigma.t -> constr -> (constr, 'r) Sigma.sigma }
type contextual_stack_reduction_function =
env -> evar_map -> constr -> constr * constr list
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 085aaf78a1..be95de873e 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -963,10 +963,12 @@ let change_map_constr_with_binders_left_to_right g f (env, l as acc) sigma c =
| _ -> mkApp (app', [| a' |]))
| _ -> map_constr_with_binders_left_to_right g f acc c
-let e_contextually byhead (occs,c) f env sigma t =
+let e_contextually byhead (occs,c) f = { e_redfun = begin fun env sigma t ->
let (nowhere_except_in,locs) = Locusops.convert_occs occs in
let maxocc = List.fold_right max locs 0 in
let pos = ref 1 in
+ let sigma = Sigma.to_evar_map sigma in
+ (** FIXME: we do suspicious things with this evarmap *)
let evd = ref sigma in
let rec traverse nested (env,c as envc) t =
if nowhere_except_in && (!pos > maxocc) then (* Shortcut *) t
@@ -985,8 +987,8 @@ let e_contextually byhead (occs,c) f env sigma t =
(* Skip inner occurrences for stable counting of occurrences *)
if locs != [] then
ignore (traverse_below (Some (!pos-1)) envc t);
- let evm, t = f subst env !evd t in
- (evd := evm; t)
+ let Sigma (t, evm, _) = (f subst).e_redfun env (Sigma.Unsafe.of_evar_map !evd) t in
+ (evd := Sigma.to_evar_map evm; t)
end
else
traverse_below nested envc t
@@ -1005,11 +1007,15 @@ let e_contextually byhead (occs,c) f env sigma t =
in
let t' = traverse None (env,c) t in
if List.exists (fun o -> o >= !pos) locs then error_invalid_occurrence locs;
- !evd, t'
+ Sigma.Unsafe.of_pair (t', !evd)
+ end }
let contextually byhead occs f env sigma t =
- let f' subst env sigma t = sigma, f subst env sigma t in
- snd (e_contextually byhead occs f' env sigma t)
+ let f' subst = { e_redfun = begin fun env sigma t ->
+ Sigma.here (f subst env (Sigma.to_evar_map sigma) t) sigma
+ end } in
+ let Sigma (c, _, _) = (e_contextually byhead occs f').e_redfun env (Sigma.Unsafe.of_evar_map sigma) t in
+ c
(* linear bindings (following pretty-printer) of the value of name in c.
* n is the number of the next occurrence of name.
@@ -1128,13 +1134,15 @@ let abstract_scheme env (locc,a) (c, sigma) =
let c', sigma' = subst_closed_term_occ env sigma (AtOccs locc) a c in
mkLambda (na,ta,c'), sigma'
-let pattern_occs loccs_trm env sigma c =
+let pattern_occs loccs_trm = { e_redfun = begin fun env sigma c ->
+ let sigma = Sigma.to_evar_map sigma in
let abstr_trm, sigma = List.fold_right (abstract_scheme env) loccs_trm (c,sigma) in
try
let _ = Typing.unsafe_type_of env sigma abstr_trm in
- sigma, applist(abstr_trm, List.map snd loccs_trm)
+ Sigma.Unsafe.of_pair (applist(abstr_trm, List.map snd loccs_trm), sigma)
with Type_errors.TypeError (env',t) ->
raise (ReductionTacticError (InvalidAbstraction (env,sigma,abstr_trm,(env',t))))
+ end }
(* Used in several tactics. *)
diff --git a/pretyping/tacred.mli b/pretyping/tacred.mli
index 6a7248e197..195b21bbf2 100644
--- a/pretyping/tacred.mli
+++ b/pretyping/tacred.mli
@@ -61,8 +61,7 @@ val unfoldn :
val fold_commands : constr list -> reduction_function
(** Pattern *)
-val pattern_occs : (occurrences * constr) list -> env -> evar_map -> constr ->
- evar_map * constr
+val pattern_occs : (occurrences * constr) list -> e_reduction_function
(** Rem: Lazy strategies are defined in Reduction *)
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index 818805a56c..2d886b8e1f 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -194,7 +194,7 @@ let out_arg = function
let out_with_occurrences (occs,c) =
(Locusops.occurrences_map (List.map out_arg) occs, c)
-let e_red f env evm c = evm, f env evm c
+let e_red f = { e_redfun = fun env evm c -> Sigma.here (f env (Sigma.to_evar_map evm) c) evm }
let head_style = false (* Turn to true to have a semantics where simpl
only reduce at the head when an evaluable reference is given, e.g.
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index a1ebacea84..a10d8fd2f7 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -18,6 +18,7 @@ open Tacred
open Proof_type
open Logic
open Refiner
+open Sigma.Notations
let re_sig it gc = { it = it; sigma = gc; }
@@ -70,7 +71,10 @@ let pf_get_new_ids ids gls =
let pf_global gls id = Constrintern.construct_reference (pf_hyps gls) id
let pf_reduction_of_red_expr gls re c =
- (fst (reduction_of_red_expr (pf_env gls) re)) (pf_env gls) (project gls) c
+ let (redfun, _) = reduction_of_red_expr (pf_env gls) re in
+ let sigma = Sigma.Unsafe.of_evar_map (project gls) in
+ let Sigma (c, sigma, _) = redfun.e_redfun (pf_env gls) sigma c in
+ (Sigma.to_evar_map sigma, c)
let pf_apply f gls = f (pf_env gls) (project gls)
let pf_eapply f gls x =
diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4
index 930cfebf4c..cdf29e4c62 100644
--- a/tactics/extratactics.ml4
+++ b/tactics/extratactics.ml4
@@ -724,8 +724,9 @@ let mkCaseEq a : unit Proofview.tactic =
Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
- change_concl
- (snd (Tacred.pattern_occs [Locus.OnlyOccurrences [1], a] env Evd.empty concl))
+ (** FIXME: this looks really wrong. Does anybody really use this tactic? *)
+ let Sigma (c, _, _) = (Tacred.pattern_occs [Locus.OnlyOccurrences [1], a]).Reductionops.e_redfun env (Sigma.Unsafe.of_evar_map Evd.empty) concl in
+ change_concl c
end };
simplest_case a]
end }
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 8b71affffa..4fa5ccf35a 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -1370,7 +1370,9 @@ module Strategies =
let reduce (r : Redexpr.red_expr) : 'a pure_strategy = { strategy =
fun { state = state ; env = env ; term1 = t ; ty1 = ty ; cstr = cstr ; evars = evars } ->
let rfn, ckind = Redexpr.reduction_of_red_expr env r in
- let evars', t' = rfn env (goalevars evars) t in
+ let sigma = Sigma.Unsafe.of_evar_map (goalevars evars) in
+ let Sigma (t', sigma, _) = rfn.Reductionops.e_redfun env sigma t in
+ let evars' = Sigma.to_evar_map sigma in
if eq_constr t' t then
state, Identity
else
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 73aa4c3373..edad75339e 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -805,7 +805,10 @@ let interp_may_eval f ist env sigma = function
| ConstrEval (r,c) ->
let (sigma,redexp) = interp_red_expr ist env sigma r in
let (sigma,c_interp) = f ist env sigma c in
- (fst (Redexpr.reduction_of_red_expr env redexp) env sigma c_interp)
+ let (redfun, _) = Redexpr.reduction_of_red_expr env redexp in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (c, sigma, _) = redfun.Reductionops.e_redfun env sigma c_interp in
+ (Sigma.to_evar_map sigma, c)
| ConstrContext ((loc,s),c) ->
(try
let (sigma,ic) = f ist env sigma c in
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index e363538471..6d589f46f7 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -569,29 +569,30 @@ let reduct_option ?(check=false) redfun = function
(** Tactic reduction modulo evars (for universes essentially) *)
let pf_e_reduce_decl redfun where (id,c,ty) gl =
- let sigma = Tacmach.New.project gl in
- let redfun = redfun (Tacmach.New.pf_env gl) in
+ let sigma = Proofview.Goal.sigma gl in
+ let redfun sigma c = redfun.e_redfun (Tacmach.New.pf_env gl) sigma c in
match c with
| None ->
if where == InHypValueOnly then
errorlabstrm "" (pr_id id ++ str " has no value.");
- let sigma, ty' = redfun sigma ty in
- sigma, (id,None,ty')
+ let Sigma (ty', sigma, p) = redfun sigma ty in
+ Sigma ((id, None, ty'), sigma, p)
| Some b ->
- let sigma, b' = if where != InHypTypeOnly then redfun sigma b else sigma, b in
- let sigma, ty' = if where != InHypValueOnly then redfun sigma ty else sigma, ty in
- sigma, (id,Some b',ty')
+ let Sigma (b', sigma, p) = if where != InHypTypeOnly then redfun sigma b else Sigma.here b sigma in
+ let Sigma (ty', sigma, q) = if where != InHypValueOnly then redfun sigma ty else Sigma.here ty sigma in
+ Sigma ((id, Some b', ty'), sigma, p +> q)
let e_reduct_in_concl (redfun, sty) =
Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
- let sigma, c' = Tacmach.New.pf_apply redfun gl (Tacmach.New.pf_concl gl) in
- Sigma.Unsafe.of_pair (convert_concl_no_check c' sty, sigma)
+ let sigma = Proofview.Goal.sigma gl in
+ let Sigma (c', sigma, p) = redfun.e_redfun (Tacmach.New.pf_env gl) sigma (Tacmach.New.pf_concl gl) in
+ Sigma (convert_concl_no_check c' sty, sigma, p)
end }
let e_reduct_in_hyp ?(check=false) redfun (id, where) =
Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
- let sigma, decl' = pf_e_reduce_decl redfun where (Tacmach.New.pf_get_hyp id gl) gl in
- Sigma.Unsafe.of_pair (convert_hyp ~check decl', sigma)
+ let Sigma (decl', sigma, p) = pf_e_reduce_decl redfun where (Tacmach.New.pf_get_hyp id gl) gl in
+ Sigma (convert_hyp ~check decl', sigma, p)
end }
let e_reduct_option ?(check=false) redfun = function
@@ -604,9 +605,8 @@ let e_reduct_option ?(check=false) redfun = function
let e_change_in_concl (redfun,sty) =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = redfun (Proofview.Goal.env gl) sigma (Proofview.Goal.raw_concl gl) in
- Sigma.Unsafe.of_pair (convert_concl_no_check c sty, sigma)
+ let Sigma (c, sigma, p) = redfun.e_redfun (Proofview.Goal.env gl) sigma (Proofview.Goal.raw_concl gl) in
+ Sigma (convert_concl_no_check c sty, sigma, p)
end }
let e_pf_change_decl (redfun : bool -> e_reduction_function) where (id,c,ty) env sigma =
@@ -614,24 +614,23 @@ let e_pf_change_decl (redfun : bool -> e_reduction_function) where (id,c,ty) env
| None ->
if where == InHypValueOnly then
errorlabstrm "" (pr_id id ++ str " has no value.");
- let sigma',ty' = redfun false env sigma ty in
- sigma', (id,None,ty')
+ let Sigma (ty', sigma, p) = (redfun false).e_redfun env sigma ty in
+ Sigma ((id, None, ty'), sigma, p)
| Some b ->
- let sigma',b' =
- if where != InHypTypeOnly then redfun true env sigma b else sigma, b
+ let Sigma (b', sigma, p) =
+ if where != InHypTypeOnly then (redfun true).e_redfun env sigma b else Sigma.here b sigma
in
- let sigma',ty' =
- if where != InHypValueOnly then redfun false env sigma' ty else sigma', ty
+ let Sigma (ty', sigma, q) =
+ if where != InHypValueOnly then (redfun false).e_redfun env sigma ty else Sigma.here ty sigma
in
- sigma', (id,Some b',ty')
+ Sigma ((id, Some b', ty'), sigma, p +> q)
let e_change_in_hyp redfun (id,where) =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
- let sigma = Sigma.to_evar_map sigma in
let hyp = Tacmach.New.pf_get_hyp id (Proofview.Goal.assume gl) in
- let sigma, c = e_pf_change_decl redfun where hyp (Proofview.Goal.env gl) sigma in
- Sigma.Unsafe.of_pair (convert_hyp c, sigma)
+ let Sigma (c, sigma, p) = e_pf_change_decl redfun where hyp (Proofview.Goal.env gl) sigma in
+ Sigma (convert_hyp c, sigma, p)
end }
type change_arg = Pattern.patvar_map -> constr Sigma.run
@@ -661,32 +660,33 @@ let check_types env sigma mayneedglobalcheck deep newc origc =
else sigma
(* Now we introduce different instances of the previous tacticals *)
-let change_and_check cv_pb mayneedglobalcheck deep t env sigma c =
- let sigma = Sigma.Unsafe.of_evar_map sigma in
+let change_and_check cv_pb mayneedglobalcheck deep t = { e_redfun = begin fun env sigma c ->
let Sigma (t', sigma, p) = t.run sigma in
let sigma = Sigma.to_evar_map sigma in
let sigma = check_types env sigma mayneedglobalcheck deep t' c in
let sigma, b = infer_conv ~pb:cv_pb env sigma t' c in
if not b then errorlabstrm "convert-check-hyp" (str "Not convertible.");
- sigma, t'
+ Sigma.Unsafe.of_pair (t', sigma)
+end }
(* Use cumulativity only if changing the conclusion not a subterm *)
-let change_on_subterm cv_pb deep t where env sigma c =
+let change_on_subterm cv_pb deep t where = { e_redfun = begin fun env sigma c ->
let mayneedglobalcheck = ref false in
- let sigma,c = match where with
- | None -> change_and_check cv_pb mayneedglobalcheck deep (t Id.Map.empty) env sigma c
+ let Sigma (c, sigma, p) = match where with
+ | None -> (change_and_check cv_pb mayneedglobalcheck deep (t Id.Map.empty)).e_redfun env sigma c
| Some occl ->
- e_contextually false occl
+ (e_contextually false occl
(fun subst ->
- change_and_check Reduction.CONV mayneedglobalcheck true (t subst))
+ change_and_check Reduction.CONV mayneedglobalcheck true (t subst))).e_redfun
env sigma c in
if !mayneedglobalcheck then
begin
- try ignore (Typing.unsafe_type_of env sigma c)
+ try ignore (Typing.unsafe_type_of env (Sigma.to_evar_map sigma) c)
with e when catchable_exception e ->
error "Replacement would lead to an ill-typed term."
end;
- sigma,c
+ Sigma (c, sigma, p)
+end }
let change_in_concl occl t =
e_change_in_concl ((change_on_subterm Reduction.CUMUL false t occl),DEFAULTcast)
@@ -924,9 +924,9 @@ let lookup_hypothesis_as_renamed_gen red h gl =
let rec aux ccl =
match lookup_hypothesis_as_renamed env ccl h with
| None when red ->
- aux
- (snd ((fst (Redexpr.reduction_of_red_expr env (Red true)))
- env (Sigma.to_evar_map (Proofview.Goal.sigma gl)) ccl))
+ let (redfun, _) = Redexpr.reduction_of_red_expr env (Red true) in
+ let Sigma (c, _, _) = redfun.e_redfun env (Proofview.Goal.sigma gl) ccl in
+ aux c
| x -> x
in
try aux (Proofview.Goal.concl gl)
diff --git a/toplevel/command.ml b/toplevel/command.ml
index b6313cdbab..aa5f7a6927 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -36,12 +36,13 @@ open Evarconv
open Indschemes
open Misctypes
open Vernacexpr
+open Sigma.Notations
let do_universe poly l = Declare.do_universe poly l
let do_constraint poly l = Declare.do_constraint poly l
let rec under_binders env sigma f n c =
- if Int.equal n 0 then snd (f env sigma c) else
+ if Int.equal n 0 then f env sigma c else
match kind_of_term c with
| Lambda (x,t,c) ->
mkLambda (x,t,under_binders (push_rel (x,None,t) env) sigma f (n-1) c)
@@ -71,10 +72,14 @@ let red_constant_entry n ce sigma = function
| Some red ->
let proof_out = ce.const_entry_body in
let env = Global.env () in
+ let (redfun, _) = reduction_of_red_expr env red in
+ let redfun env sigma c =
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (c, _, _) = redfun.e_redfun env sigma c in
+ c
+ in
{ ce with const_entry_body = Future.chain ~greedy:true ~pure:true proof_out
- (fun ((body,ctx),eff) ->
- (under_binders env sigma
- (fst (reduction_of_red_expr env red)) n body,ctx),eff) }
+ (fun ((body,ctx),eff) -> (under_binders env sigma redfun n body,ctx),eff) }
let interp_definition pl bl p red_option c ctypopt =
let env = Global.env() in
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 0f81943e2c..60aab09fdc 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -32,6 +32,7 @@ open Redexpr
open Lemmas
open Misctypes
open Locality
+open Sigma.Notations
let debug = false
let prerr_endline =
@@ -1537,7 +1538,12 @@ let vernac_check_may_eval redexp glopt rc =
| Some r ->
Tacintern.dump_glob_red_expr r;
let (sigma',r_interp) = interp_redexp env sigma' r in
- let redfun env evm c = snd (fst (reduction_of_red_expr env r_interp) env evm c) in
+ let redfun env evm c =
+ let (redfun, _) = reduction_of_red_expr env r_interp in
+ let evm = Sigma.Unsafe.of_evar_map evm in
+ let Sigma (c, _, _) = redfun.Reductionops.e_redfun env evm c in
+ c
+ in
msg_notice (print_eval redfun env sigma' rc j)
let vernac_declare_reduction locality s r =
--
cgit v1.2.3
From 13e847b7092d53ffec63e4cba54c67d39560e67a Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Mon, 15 Feb 2016 23:33:01 +0100
Subject: CLEANUP: Simplifying the changes done in "checker/*"
---
checker/declarations.ml | 10 ++--------
checker/indtypes.ml | 7 ++++---
checker/inductive.ml | 5 +++--
checker/term.ml | 26 +++++++++++++-------------
checker/term.mli | 1 +
5 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/checker/declarations.ml b/checker/declarations.ml
index 2f6eeba1d9..3ce3125337 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -517,14 +517,8 @@ let map_decl_arity f g = function
| RegularArity a -> RegularArity (f a)
| TemplateArity a -> TemplateArity (g a)
-let subst_rel_declaration sub = function
- | LocalAssum (id,t) as x ->
- let t' = subst_mps sub t in
- if t == t' then x else LocalAssum (id,t')
- | LocalDef (id,c,t) as x ->
- let c' = subst_mps sub c in
- let t' = subst_mps sub t in
- if c == c' && t == t' then x else LocalDef (id,c',t')
+let subst_rel_declaration sub =
+ Term.map_rel_decl (subst_mps sub)
let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index f11fa5a7ad..566df673c1 100644
--- a/checker/indtypes.ml
+++ b/checker/indtypes.ml
@@ -319,7 +319,7 @@ let check_correct_par (env,n,ntypes,_) hyps l largs =
let nhyps = List.length hyps in
let rec check k index = function
| [] -> ()
- | LocalDef (_,_,_) :: hyps -> check k (index+1) hyps
+ | LocalDef _ :: hyps -> check k (index+1) hyps
| _::hyps ->
match whd_betadeltaiota env lpar.(k) with
| Rel w when w = index -> check (k-1) (index+1) hyps
@@ -376,8 +376,9 @@ let ienv_push_inductive (env, n, ntypes, ra_env) ((mi,u),lpar) =
let auxntyp = 1 in
let specif = lookup_mind_specif env mi in
let env' =
- push_rel (LocalAssum (Anonymous,
- hnf_prod_applist env (type_of_inductive env (specif,u)) lpar)) env in
+ let decl = LocalAssum (Anonymous,
+ hnf_prod_applist env (type_of_inductive env (specif,u)) lpar) in
+ push_rel decl env in
let ra_env' =
(Imbr mi,(Rtree.mk_rec_calls 1).(0)) ::
List.map (fun (r,t) -> (r,Rtree.lift 1 t)) ra_env in
diff --git a/checker/inductive.ml b/checker/inductive.ml
index 9480124211..5e2e14f7fb 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -634,8 +634,9 @@ let ienv_push_inductive (env, ra_env) ((mind,u),lpar) =
let mib = Environ.lookup_mind mind env in
let ntypes = mib.mind_ntypes in
let push_ind specif env =
- push_rel (LocalAssum (Anonymous,
- hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar)) env
+ let decl = LocalAssum (Anonymous,
+ hnf_prod_applist env (type_of_inductive env ((mib,specif),u)) lpar) in
+ push_rel decl env
in
let env = Array.fold_right push_ind mib.mind_packets env in
let rc = Array.mapi (fun j t -> (Imbr (mind,j),t)) (Rtree.mk_rec_calls ntypes) in
diff --git a/checker/term.ml b/checker/term.ml
index 181d292ad4..56cc9cdc22 100644
--- a/checker/term.ml
+++ b/checker/term.ml
@@ -227,19 +227,19 @@ let rel_context_nhyps hyps =
nhyps 0 hyps
let fold_rel_context f l ~init = List.fold_right f l init
-let map_rel_context f l =
- let map_decl = function
- | LocalAssum (n, typ) as decl ->
- let typ' = f typ in
- if typ' == typ then decl else
- LocalAssum (n, typ')
- | LocalDef (n, body, typ) as decl ->
- let body' = f body in
- let typ' = f typ in
- if body' == body && typ' == typ then decl else
- LocalDef (n, body', typ')
- in
- List.smartmap map_decl l
+let map_rel_decl f = function
+ | LocalAssum (n, typ) as decl ->
+ let typ' = f typ in
+ if typ' == typ then decl else
+ LocalAssum (n, typ')
+ | LocalDef (n, body, typ) as decl ->
+ let body' = f body in
+ let typ' = f typ in
+ if body' == body && typ' == typ then decl else
+ LocalDef (n, body', typ')
+
+let map_rel_context f =
+ List.smartmap (map_rel_decl f)
let extended_rel_list n hyps =
let rec reln l p = function
diff --git a/checker/term.mli b/checker/term.mli
index d6455e23f4..0af83e05d7 100644
--- a/checker/term.mli
+++ b/checker/term.mli
@@ -35,6 +35,7 @@ val rel_context_length : rel_context -> int
val rel_context_nhyps : rel_context -> int
val fold_rel_context :
(rel_declaration -> 'a -> 'a) -> rel_context -> init:'a -> 'a
+val map_rel_decl : (constr -> constr) -> rel_declaration -> rel_declaration
val map_rel_context : (constr -> constr) -> rel_context -> rel_context
val extended_rel_list : int -> rel_context -> constr list
val compose_lam : (name * constr) list -> constr -> constr
--
cgit v1.2.3
From 1dddd062f35736285eb2940382df2b53224578a7 Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Tue, 16 Feb 2016 07:38:45 +0100
Subject: Renaming variants of Entries.local_entry
The original datatype:
Entries.local_entry = LocalDef of constr
| LocalAssum of constr
was changed to:
Entries.local_entry = LocalDefEntry of constr
| LocalAssumEntry of constr
There are two advantages:
1. the new names are consistent with other variant names in the same module
which also have this "*Entry" suffix
2. the new names do not collide with variants defined in the Context.{Rel,Named}.Declaration
modules so both, "Entries" as well as "Context.{Rel,Named}.Declaration" can be open at the same time.
The disadvantage is that those new variants are longer.
But since those variants are rarely used, it it is not a big deal.
---
kernel/entries.mli | 4 ++--
kernel/typeops.ml | 14 ++++++--------
toplevel/command.ml | 5 +++--
toplevel/discharge.ml | 5 +++--
toplevel/record.ml | 5 +++--
5 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/kernel/entries.mli b/kernel/entries.mli
index b2a77dd950..3ecfcca64c 100644
--- a/kernel/entries.mli
+++ b/kernel/entries.mli
@@ -18,8 +18,8 @@ open Term
(** {6 Local entries } *)
type local_entry =
- | LocalDef of constr
- | LocalAssum of constr
+ | LocalDefEntry of constr
+ | LocalAssumEntry of constr
(** {6 Declaration of inductive types. } *)
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index eeb12a2b49..0ea68e2bcc 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -18,6 +18,7 @@ open Entries
open Reduction
open Inductive
open Type_errors
+open Context.Rel.Declaration
let conv_leq l2r env x y = default_conv CUMUL ~l2r env x y
@@ -77,7 +78,6 @@ let judge_of_type u =
(*s Type of a de Bruijn index. *)
let judge_of_relative env n =
- let open Context.Rel.Declaration in
try
let typ = get_type (lookup_rel n env) in
{ uj_val = mkRel n;
@@ -99,9 +99,9 @@ let judge_of_variable env id =
variables of the current env.
Order does not have to be checked assuming that all names are distinct *)
let check_hyps_inclusion env c sign =
- let open Context.Named.Declaration in
Context.Named.fold_outside
(fun d1 () ->
+ let open Context.Named.Declaration in
let id = get_id d1 in
try
let d2 = lookup_named id env in
@@ -127,7 +127,6 @@ let extract_level env p =
match kind_of_term c with Sort (Type u) -> Univ.Universe.level u | _ -> None
let extract_context_levels env l =
- let open Context.Rel.Declaration in
let fold l = function
| LocalAssum (_,p) -> extract_level env p :: l
| LocalDef _ -> l
@@ -420,7 +419,6 @@ let type_fixpoint env lna lar vdefj =
Ind et Constructsi un jour cela devient des constructions
arbitraires et non plus des variables *)
let rec execute env cstr =
- let open Context.Rel.Declaration in
match kind_of_term cstr with
(* Atomic terms *)
| Sort (Prop c) ->
@@ -553,12 +551,12 @@ let infer_v env cv =
(* Typing of several terms. *)
let infer_local_decl env id = function
- | LocalDef c ->
+ | LocalDefEntry c ->
let j = infer env c in
- Context.Rel.Declaration.LocalDef (Name id, j.uj_val, j.uj_type)
- | LocalAssum c ->
+ LocalDef (Name id, j.uj_val, j.uj_type)
+ | LocalAssumEntry c ->
let j = infer env c in
- Context.Rel.Declaration.LocalAssum (Name id, assumption_of_judgment env j)
+ LocalAssum (Name id, assumption_of_judgment env j)
let infer_local_decls env decls =
let rec inferec env = function
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 166fe94ead..284bcd75ec 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -38,6 +38,7 @@ open Misctypes
open Vernacexpr
open Sigma.Notations
open Context.Rel.Declaration
+open Entries
let do_universe poly l = Declare.do_universe poly l
let do_constraint poly l = Declare.do_constraint poly l
@@ -385,8 +386,8 @@ let mk_mltype_data evdref env assums arity indname =
(is_ml_type,indname,assums)
let prepare_param = function
- | LocalAssum (na,t) -> out_name na, Entries.LocalAssum t
- | LocalDef (na,b,_) -> out_name na, Entries.LocalDef b
+ | LocalAssum (na,t) -> out_name na, LocalAssumEntry t
+ | LocalDef (na,b,_) -> out_name na, LocalDefEntry b
(** Make the arity conclusion flexible to avoid generating an upper bound universe now,
only if the universe does not appear anywhere else.
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index 5fa51e06e4..ffa11679c2 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -14,6 +14,7 @@ open Vars
open Entries
open Declarations
open Cooking
+open Entries
open Context.Rel.Declaration
(********************************)
@@ -21,8 +22,8 @@ open Context.Rel.Declaration
let detype_param =
function
- | LocalAssum (Name id, p) -> id, Entries.LocalAssum p
- | LocalDef (Name id, p,_) -> id, Entries.LocalDef p
+ | LocalAssum (Name id, p) -> id, LocalAssumEntry p
+ | LocalDef (Name id, p,_) -> id, LocalDefEntry p
| _ -> anomaly (Pp.str "Unnamed inductive local variable")
(* Replace
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 4cf81a250c..c0bb9eb86c 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -26,6 +26,7 @@ open Constrexpr_ops
open Goptions
open Sigma.Notations
open Context.Rel.Declaration
+open Entries
(********** definition d'un record (structure) **************)
@@ -164,8 +165,8 @@ let degenerate_decl decl =
| Name id -> id
| Anonymous -> anomaly (Pp.str "Unnamed record variable") in
match decl with
- | LocalAssum (_,t) -> (id, Entries.LocalAssum t)
- | LocalDef (_,b,_) -> (id, Entries.LocalDef b)
+ | LocalAssum (_,t) -> (id, LocalAssumEntry t)
+ | LocalDef (_,b,_) -> (id, LocalDefEntry b)
type record_error =
| MissingProj of Id.t * Id.t list
--
cgit v1.2.3
From 3960836e255e3738cabcd559cc1c133c5f30137a Mon Sep 17 00:00:00 2001
From: Pierre Letouzey
Date: Tue, 16 Feb 2016 11:46:37 +0100
Subject: Term: fix a comment (first de Bruijn index is 1)
---
kernel/term.mli | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/term.mli b/kernel/term.mli
index 7f79f64033..32267f6c4c 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -202,7 +202,7 @@ val destCoFix : constr -> cofixpoint
(** non-dependent product [t1 -> t2], an alias for
[forall (_:t1), t2]. Beware [t_2] is NOT lifted.
- Eg: in context [A:Prop], [A->A] is built by [(mkArrow (mkRel 0) (mkRel 1))]
+ Eg: in context [A:Prop], [A->A] is built by [(mkArrow (mkRel 1) (mkRel 2))]
*)
val mkArrow : types -> types -> constr
--
cgit v1.2.3
From 9a7afc12e0573c74d0bb0943372dddc3c61a03f1 Mon Sep 17 00:00:00 2001
From: Pierre Letouzey
Date: Tue, 16 Feb 2016 11:48:28 +0100
Subject: Tacticals: typo in a comment
---
tactics/tacticals.mli | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index ffcc71b458..0f926468b9 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -147,7 +147,7 @@ val case_on_ba : (branch_assumptions -> tactic) -> branch_args -> tactic
semantics as the similarly named tacticals in [Proofview]. The
tactical of [Proofview] are used in the definition of the
tacticals of [Tacticals.New], but they are more atomic. In
- particular [Tacticals.New.tclORELSE] sees like of progress as a
+ particular [Tacticals.New.tclORELSE] sees lack of progress as a
failure, whereas [Proofview.tclORELSE] doesn't. Additionally every
tactic which can catch failure ([tclOR], [tclORELSE], [tclTRY],
[tclREPEAt], etc…) are run into each goal independently (failures
--
cgit v1.2.3
From 06fa0334047a9400d0b5a144601fca35746a53b8 Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Wed, 17 Feb 2016 10:32:40 +0100
Subject: CLEANUP: Renaming "Util.compose" function to "%"
I propose to change the name of the "Util.compose" function to "%".
Reasons:
1. If one wants to express function composition,
then the new name enables us to achieve this goal easier.
2. In "Batteries Included" they had made the same choice.
---
lib/util.ml | 8 +++++++-
lib/util.mli | 10 +++++++++-
proofs/tacmach.ml | 2 +-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/lib/util.ml b/lib/util.ml
index b67539918d..0f79c10df1 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -87,7 +87,13 @@ let matrix_transpose mat =
let identity x = x
-let compose f g x = f (g x)
+(** Function composition: the mathematical [∘] operator.
+
+ So [g % f] is a synonym for [fun x -> g (f x)].
+
+ Also because [%] is right-associative, [h % g % f] means [fun x -> h (g (f x))].
+ *)
+let (%) f g x = f (g x)
let const x _ = x
diff --git a/lib/util.mli b/lib/util.mli
index 7923c65a3b..559874bb83 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -83,7 +83,15 @@ val matrix_transpose : 'a list list -> 'a list list
(** {6 Functions. } *)
val identity : 'a -> 'a
-val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
+
+(** Function composition: the mathematical [∘] operator.
+
+ So [g % f] is a synonym for [fun x -> g (f x)].
+
+ Also because [%] is right-associative, [h % g % f] means [fun x -> h (g (f x))].
+*)
+val (%) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
+
val const : 'a -> 'b -> 'a
val iterate : ('a -> 'a) -> int -> 'a -> 'a
val repeat : int -> ('a -> unit) -> 'a -> unit
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index a10d8fd2f7..1e59c182ce 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -99,7 +99,7 @@ let pf_const_value = pf_reduce (fun env _ -> constant_value_in env)
let pf_reduce_to_quantified_ind = pf_reduce reduce_to_quantified_ind
let pf_reduce_to_atomic_ind = pf_reduce reduce_to_atomic_ind
-let pf_hnf_type_of gls = compose (pf_whd_betadeltaiota gls) (pf_get_type_of gls)
+let pf_hnf_type_of gls = pf_whd_betadeltaiota gls % pf_get_type_of gls
let pf_is_matching = pf_apply Constr_matching.is_matching_conv
let pf_matches = pf_apply Constr_matching.matches_conv
--
cgit v1.2.3
From 65b901534649c5f29e245a4960fa66f6e9d9c257 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 17 Feb 2016 18:11:02 +0100
Subject: Fix bug #4574: Anomaly: Uncaught exception
Invalid_argument("splay_arity").
The setoid_rewrite tactic was not checking that the relation it was looking for
was indeed a relation, i.e. that its type was an arity.
---
tactics/rewrite.ml | 13 +++++++++----
test-suite/bugs/closed/4574.v | 8 ++++++++
2 files changed, 17 insertions(+), 4 deletions(-)
create mode 100644 test-suite/bugs/closed/4574.v
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 83742bfbdd..b04fb660d8 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -446,6 +446,8 @@ type hypinfo = {
let get_symmetric_proof b =
if b then PropGlobal.get_symmetric_proof else TypeGlobal.get_symmetric_proof
+let error_no_relation () = error "Cannot find a relation to rewrite."
+
let rec decompose_app_rel env evd t =
(** Head normalize for compatibility with the old meta mechanism *)
let t = Reductionops.whd_betaiota evd t in
@@ -461,8 +463,11 @@ let rec decompose_app_rel env evd t =
| App (f, args) ->
let len = Array.length args in
let fargs = Array.sub args 0 (Array.length args - 2) in
- mkApp (f, fargs), args.(len - 2), args.(len - 1)
- | _ -> error "Cannot find a relation to rewrite."
+ let rel = mkApp (f, fargs) in
+ let ty = Retyping.get_type_of env evd rel in
+ let () = if not (Reduction.is_arity env ty) then error_no_relation () in
+ rel, args.(len - 2), args.(len - 1)
+ | _ -> error_no_relation ()
let decompose_applied_relation env sigma (c,l) =
let ctype = Retyping.get_type_of env sigma c in
@@ -2048,8 +2053,8 @@ let setoid_proof ty fn fallback =
begin
try
let rel, _, _ = decompose_app_rel env sigma concl in
- let evm = sigma in
- let car = pi3 (List.hd (fst (Reduction.dest_prod env (Typing.unsafe_type_of env evm rel)))) in
+ let (sigma, t) = Typing.type_of env sigma rel in
+ let car = pi3 (List.hd (fst (Reduction.dest_prod env t))) in
(try init_setoid () with _ -> raise Not_found);
fn env sigma car rel
with e -> Proofview.tclZERO e
diff --git a/test-suite/bugs/closed/4574.v b/test-suite/bugs/closed/4574.v
new file mode 100644
index 0000000000..39ba190369
--- /dev/null
+++ b/test-suite/bugs/closed/4574.v
@@ -0,0 +1,8 @@
+Require Import Setoid.
+
+Definition block A (a : A) := a.
+
+Goal forall A (a : A), block Type nat.
+Proof.
+Fail reflexivity.
+
--
cgit v1.2.3
From 8a179389fe5199e79d05b2c72ff2aae2061820aa Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 17 Feb 2016 18:53:45 +0100
Subject: Fixing the Proofview.Goal.goal function.
The environment put in the goals was not the right one and could lead to
various leaks.
---
proofs/proofview.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/proofs/proofview.ml b/proofs/proofview.ml
index 49228c93ac..6d7dcb9257 100644
--- a/proofs/proofview.ml
+++ b/proofs/proofview.ml
@@ -1000,7 +1000,6 @@ module Goal = struct
end
let goals =
- Env.get >>= fun env ->
Pv.get >>= fun step ->
let sigma = step.solution in
let map goal =
@@ -1008,6 +1007,7 @@ module Goal = struct
| None -> None (** ppedrot: Is this check really necessary? *)
| Some goal ->
let gl =
+ Env.get >>= fun env ->
tclEVARMAP >>= fun sigma ->
tclUNIT (gmake env sigma goal)
in
--
cgit v1.2.3
From e4c9dfe7277ec2e2c4b1e40f60044ba4cade8e61 Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Thu, 18 Feb 2016 14:19:21 +0100
Subject: ADD: Names.Name.is_{anonymous,name}
Two new (trivial) functions were added:
Names.Name.is_anonymous : Names.Name.t -> bool
Names.Name.is_name : Names.Name.t -> bool
They enable us to write a more compact code.
(example: commit "99633f4" in "relation-extraction" module of "coq-contribs").
---
kernel/names.ml | 6 ++++++
kernel/names.mli | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/kernel/names.ml b/kernel/names.ml
index 02587bad9b..0aa26fb9cc 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -82,6 +82,12 @@ struct
type t = Anonymous (** anonymous identifier *)
| Name of Id.t (** non-anonymous identifier *)
+ let is_anonymous = function
+ | Anonymous -> true
+ | Name _ -> false
+
+ let is_name = not % is_anonymous
+
let compare n1 n2 = match n1, n2 with
| Anonymous, Anonymous -> 0
| Name id1, Name id2 -> Id.compare id1 id2
diff --git a/kernel/names.mli b/kernel/names.mli
index 40f96813fc..6380b17fbf 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -68,6 +68,12 @@ sig
type t = Anonymous (** anonymous identifier *)
| Name of Id.t (** non-anonymous identifier *)
+ val is_anonymous : t -> bool
+ (** Return [true] iff a given name is [Anonymous]. *)
+
+ val is_name : t -> bool
+ (** Return [true] iff a given name is [Name _]. *)
+
val compare : t -> t -> int
(** Comparison over names. *)
--
cgit v1.2.3
From 82e4e8f2afbff4f1dbecb8a37e3c1c18a41c754f Mon Sep 17 00:00:00 2001
From: Matej Kosik
Date: Thu, 18 Feb 2016 17:32:15 +0100
Subject: FIX: of my previous merging mistake
---
tactics/inv.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 9bfbbc41b7..6841ab0ecd 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -298,7 +298,7 @@ let get_names (allow_conj,issimple) (loc, pat as x) = match pat with
| IntroAction (IntroRewrite _) ->
error "Rewriting pattern not allowed for inversion equations."
| IntroAction (IntroOrAndPattern (IntroAndPattern [])) when allow_conj -> (None, [])
- | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l)))
+ | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l) | IntroOrPattern [(_,IntroNaming (IntroIdentifier id)) :: _ as l ]))
when allow_conj -> (Some id,l)
| IntroAction (IntroOrAndPattern (IntroAndPattern _)) ->
if issimple then
--
cgit v1.2.3
From 4f640bb24dfc45699670f41441355cdf71c83130 Mon Sep 17 00:00:00 2001
From: Enrico Tassi
Date: Mon, 15 Feb 2016 16:11:11 +0100
Subject: STM: classify some variants of Instance as regular `Fork nodes.
"Instance name : Type." is like "Lemma name : Type", i.e. it starts
a proof. Unfortunately sometimes it does not, so we say VtUnknown.
Still, if there is an open proof, we classify it as a regular Lemma,
i.e. the opacity depends only on the terminator.
This makes CoqIDE and PIDE based UI way more responsive when processing
files containing Instance that are proved by tactics, since they are now
correctly delegated to workers. Bug reported privately by Alec Faithfull.
---
stm/stm.ml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/stm/stm.ml b/stm/stm.ml
index 56dcda6a4a..f2855d5087 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -2254,7 +2254,11 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
Proof_global.there_are_pending_proofs ()
then begin
let bname = VCS.mk_branch_name x in
- VCS.commit id (Fork (x,bname,Doesn'tGuaranteeOpacity,[]));
+ let opacity_of_produced_term =
+ match x.expr with
+ | VernacInstance (false, _,_ , None, _) -> GuaranteesOpacity
+ | _ -> Doesn'tGuaranteeOpacity in
+ VCS.commit id (Fork (x,bname,opacity_of_produced_term,[]));
VCS.branch bname (`Proof ("Classic", VCS.proof_nesting () + 1));
Proof_global.activate_proof_mode "Classic";
end else begin
--
cgit v1.2.3
From 37479c1b59b7492abb5c89a42c5a76d4cd9d48cd Mon Sep 17 00:00:00 2001
From: Enrico Tassi
Date: Thu, 18 Feb 2016 19:13:40 +0100
Subject: CoqIDE: STOP button also stops workers (fix #4542)
---
ide/coq.ml | 15 +++++++++++----
ide/coq.mli | 4 ++--
ide/coqide.ml | 2 +-
ide/session.ml | 3 +++
ide/session.mli | 1 +
5 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/ide/coq.ml b/ide/coq.ml
index 98576a9811..7edae47ca1 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -465,10 +465,6 @@ let close_coqtop coqtop =
let reset_coqtop coqtop = respawn_coqtop ~why:Planned coqtop
-let break_coqtop coqtop =
- try !interrupter (CoqTop.unixpid coqtop.handle.proc)
- with _ -> Minilib.log "Error while sending Ctrl-C"
-
let get_arguments coqtop = coqtop.sup_args
let set_arguments coqtop args =
@@ -518,6 +514,17 @@ let search flags = eval_call (Xmlprotocol.search flags)
let init x = eval_call (Xmlprotocol.init x)
let stop_worker x = eval_call (Xmlprotocol.stop_worker x)
+let break_coqtop coqtop workers =
+ if coqtop.status = Busy then
+ try !interrupter (CoqTop.unixpid coqtop.handle.proc)
+ with _ -> Minilib.log "Error while sending Ctrl-C"
+ else
+ let rec aux = function
+ | [] -> Void
+ | w :: ws -> stop_worker w coqtop.handle (fun _ -> aux ws)
+ in
+ let Void = aux workers in ()
+
module PrintOpt =
struct
type t = string list
diff --git a/ide/coq.mli b/ide/coq.mli
index d9eda0f342..7cef6a4d0a 100644
--- a/ide/coq.mli
+++ b/ide/coq.mli
@@ -70,8 +70,8 @@ val init_coqtop : coqtop -> unit task -> unit
(** Finish initializing a freshly spawned coqtop, by running a first task on it.
The task should run its inner continuation at the end. *)
-val break_coqtop : coqtop -> unit
-(** Interrupt the current computation of coqtop. *)
+val break_coqtop : coqtop -> string list -> unit
+(** Interrupt the current computation of coqtop or the worker if coqtop it not running. *)
val close_coqtop : coqtop -> unit
(** Close coqtop. Subsequent requests will be discarded. Hook ignored. *)
diff --git a/ide/coqide.ml b/ide/coqide.ml
index 608cf82ff8..36aab30e60 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -574,7 +574,7 @@ module Nav = struct
let restart _ = on_current_term restart
let interrupt sn =
Minilib.log "User break received";
- Coq.break_coqtop sn.coqtop
+ Coq.break_coqtop sn.coqtop CString.(Set.elements (Map.domain sn.jobpage#data))
let interrupt = cb_on_current_term interrupt
let join_document _ = send_to_coq (fun sn -> sn.coqops#join_document)
end
diff --git a/ide/session.ml b/ide/session.ml
index 34c533b8e5..168ddd4df9 100644
--- a/ide/session.ml
+++ b/ide/session.ml
@@ -19,6 +19,7 @@ class type ['a] page =
method update : 'a -> unit
method on_update : callback:('a -> unit) -> unit
method refresh_color : unit -> unit
+ method data : 'a
end
class type control =
@@ -321,6 +322,7 @@ let create_errpage (script : Wg_ScriptView.script_view) : errpage =
end
method on_update ~callback:cb = callback := cb
method refresh_color () = refresh ()
+ method data = !last_update
end
let create_jobpage coqtop coqops : jobpage =
@@ -361,6 +363,7 @@ let create_jobpage coqtop coqops : jobpage =
end
method on_update ~callback:cb = callback := cb
method refresh_color () = refresh ()
+ method data = !last_update
end
let create_proof () =
diff --git a/ide/session.mli b/ide/session.mli
index 0881e40392..ef39ab2e0d 100644
--- a/ide/session.mli
+++ b/ide/session.mli
@@ -15,6 +15,7 @@ class type ['a] page =
method update : 'a -> unit
method on_update : callback:('a -> unit) -> unit
method refresh_color : unit -> unit
+ method data : 'a
end
class type control =
--
cgit v1.2.3
From 9aa2d99fb1ad6b348142fce244f277b9dd25017f Mon Sep 17 00:00:00 2001
From: Enrico Tassi
Date: Fri, 19 Feb 2016 11:51:04 +0100
Subject: STM: Print/Extraction have to be skipped if -quick
Print and Extraction commands may pierce opacity: if the
task producing the proof term is not finished, we wait for
its completion.
In -quick mode no worker is going to process a task, since tasks
are simply stored to disk (and resumed later in -vio2vo mode).
This commit avoids coqc waits forever for a task in order to
Print/Extract the corresponding term. Bug reported privately
by Alec Faithfull.
---
stm/stm.ml | 31 +++++++++++++++++++++++--------
test-suite/vio/print.v | 10 ++++++++++
2 files changed, 33 insertions(+), 8 deletions(-)
create mode 100644 test-suite/vio/print.v
diff --git a/stm/stm.ml b/stm/stm.ml
index f2855d5087..a6d119f0cd 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -83,6 +83,18 @@ let async_proofs_workers_extra_env = ref [||]
type ast = { verbose : bool; loc : Loc.t; mutable expr : vernac_expr }
let pr_ast { expr } = pr_vernac expr
+(* Commands piercing opaque *)
+let may_pierce_opaque = function
+ | { expr = VernacPrint (PrintName _) } -> true
+ | { expr = VernacExtend (("Extraction",_), _) } -> true
+ | { expr = VernacExtend (("SeparateExtraction",_), _) } -> true
+ | { expr = VernacExtend (("ExtractionLibrary",_), _) } -> true
+ | { expr = VernacExtend (("RecursiveExtractionLibrary",_), _) } -> true
+ | { expr = VernacExtend (("ExtractionConstant",_), _) } -> true
+ | { expr = VernacExtend (("ExtractionInlinedConstant",_), _) } -> true
+ | { expr = VernacExtend (("ExtractionInductive",_), _) } -> true
+ | _ -> false
+
(* Wrapper for Vernacentries.interp to set the feedback id *)
let vernac_interp ?proof id ?route { verbose; loc; expr } =
let rec internal_command = function
@@ -145,7 +157,7 @@ type cmd_t = {
ceff : bool; (* is a side-effecting command *)
cast : ast;
cids : Id.t list;
- cqueue : [ `MainQueue | `TacQueue of cancel_switch | `QueryQueue of cancel_switch ] }
+ cqueue : [ `MainQueue | `TacQueue of cancel_switch | `QueryQueue of cancel_switch | `SkipQueue ] }
type fork_t = ast * Vcs_.Branch.t * Vernacexpr.opacity_guarantee * Id.t list
type qed_t = {
qast : ast;
@@ -1665,7 +1677,7 @@ let delegate name =
let time = get_hint_bp_time name in
time >= 1.0 || !Flags.compilation_mode = Flags.BuildVio
|| !Flags.async_proofs_full
-
+
let collect_proof keep cur hd brkind id =
prerr_endline ("Collecting proof ending at "^Stateid.to_string id);
let no_name = "" in
@@ -1687,23 +1699,20 @@ let collect_proof keep cur hd brkind id =
let has_proof_no_using = function
| Some (_, { expr = VernacProof(_,None) }) -> true
| _ -> false in
- let may_pierce_opaque = function
- | { expr = VernacPrint (PrintName _) } -> true
- (* These do not exactly pierce opaque, but are anyway impossible to properly
- * delegate *)
+ let too_complex_to_delegate = function
| { expr = (VernacDeclareModule _
| VernacDefineModule _
| VernacDeclareModuleType _
| VernacInclude _) } -> true
| { expr = (VernacRequire _ | VernacImport _) } -> true
- | _ -> false in
+ | ast -> may_pierce_opaque ast in
let parent = function Some (p, _) -> p | None -> assert false in
let is_empty = function `Async(_,_,[],_,_) | `MaybeASync(_,_,[],_,_) -> true | _ -> false in
let rec collect last accn id =
let view = VCS.visit id in
match view.step with
| (`Sideff (`Ast(x,_)) | `Cmd { cast = x })
- when may_pierce_opaque x -> `Sync(no_name,None,`Print)
+ when too_complex_to_delegate x -> `Sync(no_name,None,`Print)
| `Cmd { cast = x } -> collect (Some (id,x)) (id::accn) view.next
| `Sideff (`Ast(x,_)) -> collect (Some (id,x)) (id::accn) view.next
(* An Alias could jump everywhere... we hope we can ignore it*)
@@ -1811,6 +1820,8 @@ let known_state ?(redefine_qed=false) ~cache id =
| `Alias (id,_) -> (fun () ->
reach view.next; reach id
), cache, true
+ | `Cmd { cast = x; cqueue = `SkipQueue } -> (fun () ->
+ reach view.next), cache, true
| `Cmd { cast = x; cqueue = `TacQueue cancel } -> (fun () ->
reach ~cache:`Shallow view.next;
Hooks.(call tactic_being_run true);
@@ -2176,6 +2187,10 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
let id = VCS.new_node ~id:newtip () in
let queue =
if !Flags.async_proofs_full then `QueryQueue (ref false)
+ else if Flags.(!compilation_mode = BuildVio) &&
+ VCS.((get_branch head).kind = `Master) &&
+ may_pierce_opaque x
+ then `SkipQueue
else `MainQueue in
VCS.commit id (Cmd {ctac=false;ceff=false;cast = x; cids = []; cqueue = queue });
Backtrack.record (); if w == VtNow then finish (); `Ok
diff --git a/test-suite/vio/print.v b/test-suite/vio/print.v
new file mode 100644
index 0000000000..9c36a463c9
--- /dev/null
+++ b/test-suite/vio/print.v
@@ -0,0 +1,10 @@
+Lemma a : True.
+Proof.
+idtac.
+exact I.
+Qed.
+
+Print a.
+
+Lemma b : False.
+Admitted.
--
cgit v1.2.3
From d3012c8ac308b18272ddaa90c4eae7e517b63c7c Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 19 Feb 2016 13:59:33 +0100
Subject: Fixing bug #4582: cannot override notation [ x ].
---
test-suite/bugs/closed/4582.v | 10 ++++++++++
theories/Lists/List.v | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
create mode 100644 test-suite/bugs/closed/4582.v
diff --git a/test-suite/bugs/closed/4582.v b/test-suite/bugs/closed/4582.v
new file mode 100644
index 0000000000..0842fb8fa7
--- /dev/null
+++ b/test-suite/bugs/closed/4582.v
@@ -0,0 +1,10 @@
+Require List.
+Import List.ListNotations.
+
+Variable Foo : nat -> nat.
+
+Delimit Scope Foo_scope with F.
+
+Notation " [ x ] " := (Foo x) : Foo_scope.
+
+Check ([1] : nat)%F.
diff --git a/theories/Lists/List.v b/theories/Lists/List.v
index cc7586fecb..957f1066d2 100644
--- a/theories/Lists/List.v
+++ b/theories/Lists/List.v
@@ -26,7 +26,7 @@ In a special module to avoid conflicts. *)
Module ListNotations.
Notation " [ ] " := nil (format "[ ]") : list_scope.
Notation " [ x ] " := (cons x nil) : list_scope.
-Notation " [ x ; .. ; y ] " := (cons x .. (cons y nil) ..) : list_scope.
+Notation " [ x ; y ; .. ; z ] " := (cons x (cons y .. (cons z nil) ..)) : list_scope.
End ListNotations.
Import ListNotations.
--
cgit v1.2.3
From 924d2833644735a9fa8289ffaa9bac9fbc43982c Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 19 Feb 2016 14:27:31 +0100
Subject: Fixing bug #4580: [Set Refine Instance Mode] also used for Program
Instance.
---
test-suite/bugs/closed/4580.v | 6 ++++++
toplevel/classes.ml | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
create mode 100644 test-suite/bugs/closed/4580.v
diff --git a/test-suite/bugs/closed/4580.v b/test-suite/bugs/closed/4580.v
new file mode 100644
index 0000000000..4ffd5f0f4b
--- /dev/null
+++ b/test-suite/bugs/closed/4580.v
@@ -0,0 +1,6 @@
+Require Import Program.
+
+Class Foo (A : Type) := foo : A.
+
+Unset Refine Instance Mode.
+Program Instance f1 : Foo nat := S _.
diff --git a/toplevel/classes.ml b/toplevel/classes.ml
index f73dd5a2e6..5f73b70a2e 100644
--- a/toplevel/classes.ml
+++ b/toplevel/classes.ml
@@ -290,7 +290,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
if not (Evd.has_undefined evm) && not (Option.is_empty term) then
declare_instance_constant k pri global imps ?hook id pl
poly evm (Option.get term) termtype
- else if !refine_instance || Option.is_empty term then begin
+ else if Flags.is_program_mode () || !refine_instance || Option.is_empty term then begin
let kind = Decl_kinds.Global, poly, Decl_kinds.DefinitionBody Decl_kinds.Instance in
if Flags.is_program_mode () then
let hook vis gr _ =
--
cgit v1.2.3
From 8d0ff142913fc6351ff7f0a6b8eacc6c21d36000 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 19 Feb 2016 15:12:53 +0100
Subject: Allowing to attach location to universes in UState.
---
engine/evd.ml | 42 +++++++++++++++++++++---------------------
engine/evd.mli | 20 ++++++++++----------
engine/sigma.ml | 32 ++++++++++++++++----------------
engine/sigma.mli | 24 ++++++++++++------------
engine/uState.ml | 49 +++++++++++++++++++++++++++++++++++++------------
engine/uState.mli | 4 ++--
6 files changed, 98 insertions(+), 73 deletions(-)
diff --git a/engine/evd.ml b/engine/evd.ml
index f751f4d922..b6849f7ffb 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -781,25 +781,25 @@ let restrict_universe_context evd vars =
let universe_subst evd =
UState.subst evd.universes
-let merge_context_set ?(sideff=false) rigid evd ctx' =
- {evd with universes = UState.merge sideff rigid evd.universes ctx'}
+let merge_context_set ?loc ?(sideff=false) rigid evd ctx' =
+ {evd with universes = UState.merge ?loc sideff rigid evd.universes ctx'}
let merge_universe_subst evd subst =
{evd with universes = UState.merge_subst evd.universes subst }
-let with_context_set rigid d (a, ctx) =
- (merge_context_set rigid d ctx, a)
+let with_context_set ?loc rigid d (a, ctx) =
+ (merge_context_set ?loc rigid d ctx, a)
-let new_univ_level_variable ?name ?(predicative=true) rigid evd =
- let uctx', u = UState.new_univ_variable rigid name evd.universes in
+let new_univ_level_variable ?loc ?name ?(predicative=true) rigid evd =
+ let uctx', u = UState.new_univ_variable ?loc rigid name evd.universes in
({evd with universes = uctx'}, u)
-let new_univ_variable ?name ?(predicative=true) rigid evd =
- let uctx', u = UState.new_univ_variable rigid name evd.universes in
+let new_univ_variable ?loc ?name ?(predicative=true) rigid evd =
+ let uctx', u = UState.new_univ_variable ?loc rigid name evd.universes in
({evd with universes = uctx'}, Univ.Universe.make u)
-let new_sort_variable ?name ?(predicative=true) rigid d =
- let (d', u) = new_univ_variable rigid ?name ~predicative d in
+let new_sort_variable ?loc ?name ?(predicative=true) rigid d =
+ let (d', u) = new_univ_variable ?loc rigid ?name ~predicative d in
(d', Type u)
let add_global_univ d u =
@@ -815,27 +815,27 @@ let make_evar_universe_context e l =
| Some us ->
List.fold_left
(fun uctx (loc,id) ->
- fst (UState.new_univ_variable univ_rigid (Some (Id.to_string id)) uctx))
+ fst (UState.new_univ_variable ~loc univ_rigid (Some (Id.to_string id)) uctx))
uctx us
(****************************************)
(* Operations on constants *)
(****************************************)
-let fresh_sort_in_family ?(rigid=univ_flexible) env evd s =
- with_context_set rigid evd (Universes.fresh_sort_in_family env s)
+let fresh_sort_in_family ?loc ?(rigid=univ_flexible) env evd s =
+ with_context_set ?loc rigid evd (Universes.fresh_sort_in_family env s)
-let fresh_constant_instance env evd c =
- with_context_set univ_flexible evd (Universes.fresh_constant_instance env c)
+let fresh_constant_instance ?loc env evd c =
+ with_context_set ?loc univ_flexible evd (Universes.fresh_constant_instance env c)
-let fresh_inductive_instance env evd i =
- with_context_set univ_flexible evd (Universes.fresh_inductive_instance env i)
+let fresh_inductive_instance ?loc env evd i =
+ with_context_set ?loc univ_flexible evd (Universes.fresh_inductive_instance env i)
-let fresh_constructor_instance env evd c =
- with_context_set univ_flexible evd (Universes.fresh_constructor_instance env c)
+let fresh_constructor_instance ?loc env evd c =
+ with_context_set ?loc univ_flexible evd (Universes.fresh_constructor_instance env c)
-let fresh_global ?(rigid=univ_flexible) ?names env evd gr =
- with_context_set rigid evd (Universes.fresh_global_instance ?names env gr)
+let fresh_global ?loc ?(rigid=univ_flexible) ?names env evd gr =
+ with_context_set ?loc rigid evd (Universes.fresh_global_instance ?names env gr)
let whd_sort_variable evd t = t
diff --git a/engine/evd.mli b/engine/evd.mli
index a9ca9a7408..3ae6e586c1 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -504,9 +504,9 @@ val normalize_evar_universe_context_variables : evar_universe_context ->
val normalize_evar_universe_context : evar_universe_context ->
evar_universe_context
-val new_univ_level_variable : ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * Univ.universe_level
-val new_univ_variable : ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * Univ.universe
-val new_sort_variable : ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * sorts
+val new_univ_level_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * Univ.universe_level
+val new_univ_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * Univ.universe
+val new_sort_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool -> rigid -> evar_map -> evar_map * sorts
val add_global_univ : evar_map -> Univ.Level.t -> evar_map
val make_flexible_variable : evar_map -> bool -> Univ.universe_level -> evar_map
@@ -541,10 +541,10 @@ val universes : evar_map -> UGraph.t
val merge_universe_context : evar_map -> evar_universe_context -> evar_map
val set_universe_context : evar_map -> evar_universe_context -> evar_map
-val merge_context_set : ?sideff:bool -> rigid -> evar_map -> Univ.universe_context_set -> evar_map
+val merge_context_set : ?loc:Loc.t -> ?sideff:bool -> rigid -> evar_map -> Univ.universe_context_set -> evar_map
val merge_universe_subst : evar_map -> Universes.universe_opt_subst -> evar_map
-val with_context_set : rigid -> evar_map -> 'a Univ.in_universe_context_set -> evar_map * 'a
+val with_context_set : ?loc:Loc.t -> rigid -> evar_map -> 'a Univ.in_universe_context_set -> evar_map * 'a
val nf_univ_variables : evar_map -> evar_map * Univ.universe_subst
val abstract_undefined_variables : evar_universe_context -> evar_universe_context
@@ -559,12 +559,12 @@ val update_sigma_env : evar_map -> env -> evar_map
(** Polymorphic universes *)
-val fresh_sort_in_family : ?rigid:rigid -> env -> evar_map -> sorts_family -> evar_map * sorts
-val fresh_constant_instance : env -> evar_map -> constant -> evar_map * pconstant
-val fresh_inductive_instance : env -> evar_map -> inductive -> evar_map * pinductive
-val fresh_constructor_instance : env -> evar_map -> constructor -> evar_map * pconstructor
+val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:rigid -> env -> evar_map -> sorts_family -> evar_map * sorts
+val fresh_constant_instance : ?loc:Loc.t -> env -> evar_map -> constant -> evar_map * pconstant
+val fresh_inductive_instance : ?loc:Loc.t -> env -> evar_map -> inductive -> evar_map * pinductive
+val fresh_constructor_instance : ?loc:Loc.t -> env -> evar_map -> constructor -> evar_map * pconstructor
-val fresh_global : ?rigid:rigid -> ?names:Univ.Instance.t -> env -> evar_map ->
+val fresh_global : ?loc:Loc.t -> ?rigid:rigid -> ?names:Univ.Instance.t -> env -> evar_map ->
Globnames.global_reference -> evar_map * constr
(********************************************************************
diff --git a/engine/sigma.ml b/engine/sigma.ml
index c25aac0c14..c7b0bb5a50 100644
--- a/engine/sigma.ml
+++ b/engine/sigma.ml
@@ -36,36 +36,36 @@ let new_evar sigma ?naming info =
let define evk c sigma =
Sigma ((), Evd.define evk c sigma, ())
-let new_univ_level_variable ?name ?predicative rigid sigma =
- let (sigma, u) = Evd.new_univ_level_variable ?name ?predicative rigid sigma in
+let new_univ_level_variable ?loc ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_univ_level_variable ?loc ?name ?predicative rigid sigma in
Sigma (u, sigma, ())
-let new_univ_variable ?name ?predicative rigid sigma =
- let (sigma, u) = Evd.new_univ_variable ?name ?predicative rigid sigma in
+let new_univ_variable ?loc ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_univ_variable ?loc ?name ?predicative rigid sigma in
Sigma (u, sigma, ())
-let new_sort_variable ?name ?predicative rigid sigma =
- let (sigma, u) = Evd.new_sort_variable ?name ?predicative rigid sigma in
+let new_sort_variable ?loc ?name ?predicative rigid sigma =
+ let (sigma, u) = Evd.new_sort_variable ?loc ?name ?predicative rigid sigma in
Sigma (u, sigma, ())
-let fresh_sort_in_family ?rigid env sigma s =
- let (sigma, s) = Evd.fresh_sort_in_family ?rigid env sigma s in
+let fresh_sort_in_family ?loc ?rigid env sigma s =
+ let (sigma, s) = Evd.fresh_sort_in_family ?loc ?rigid env sigma s in
Sigma (s, sigma, ())
-let fresh_constant_instance env sigma cst =
- let (sigma, cst) = Evd.fresh_constant_instance env sigma cst in
+let fresh_constant_instance ?loc env sigma cst =
+ let (sigma, cst) = Evd.fresh_constant_instance ?loc env sigma cst in
Sigma (cst, sigma, ())
-let fresh_inductive_instance env sigma ind =
- let (sigma, ind) = Evd.fresh_inductive_instance env sigma ind in
+let fresh_inductive_instance ?loc env sigma ind =
+ let (sigma, ind) = Evd.fresh_inductive_instance ?loc env sigma ind in
Sigma (ind, sigma, ())
-let fresh_constructor_instance env sigma pc =
- let (sigma, c) = Evd.fresh_constructor_instance env sigma pc in
+let fresh_constructor_instance ?loc env sigma pc =
+ let (sigma, c) = Evd.fresh_constructor_instance ?loc env sigma pc in
Sigma (c, sigma, ())
-let fresh_global ?rigid ?names env sigma r =
- let (sigma, c) = Evd.fresh_global ?rigid ?names env sigma r in
+let fresh_global ?loc ?rigid ?names env sigma r =
+ let (sigma, c) = Evd.fresh_global ?loc ?rigid ?names env sigma r in
Sigma (c, sigma, ())
(** Run *)
diff --git a/engine/sigma.mli b/engine/sigma.mli
index d7ae2e4ac9..643bea4036 100644
--- a/engine/sigma.mli
+++ b/engine/sigma.mli
@@ -66,23 +66,23 @@ val define : 'r evar -> Constr.t -> 'r t -> (unit, 'r) sigma
(** Polymorphic universes *)
-val new_univ_level_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
- 'r t -> (Univ.universe_level, 'r) sigma
-val new_univ_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
- 'r t -> (Univ.universe, 'r) sigma
-val new_sort_variable : ?name:string -> ?predicative:bool -> Evd.rigid ->
- 'r t -> (Sorts.t, 'r) sigma
-
-val fresh_sort_in_family : ?rigid:Evd.rigid -> Environ.env ->
+val new_univ_level_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool ->
+ Evd.rigid -> 'r t -> (Univ.universe_level, 'r) sigma
+val new_univ_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool ->
+ Evd.rigid -> 'r t -> (Univ.universe, 'r) sigma
+val new_sort_variable : ?loc:Loc.t -> ?name:string -> ?predicative:bool ->
+ Evd.rigid -> 'r t -> (Sorts.t, 'r) sigma
+
+val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:Evd.rigid -> Environ.env ->
'r t -> Term.sorts_family -> (Term.sorts, 'r) sigma
val fresh_constant_instance :
- Environ.env -> 'r t -> constant -> (pconstant, 'r) sigma
+ ?loc:Loc.t -> Environ.env -> 'r t -> constant -> (pconstant, 'r) sigma
val fresh_inductive_instance :
- Environ.env -> 'r t -> inductive -> (pinductive, 'r) sigma
-val fresh_constructor_instance : Environ.env -> 'r t -> constructor ->
+ ?loc:Loc.t -> Environ.env -> 'r t -> inductive -> (pinductive, 'r) sigma
+val fresh_constructor_instance : ?loc:Loc.t -> Environ.env -> 'r t -> constructor ->
(pconstructor, 'r) sigma
-val fresh_global : ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
+val fresh_global : ?loc:Loc.t -> ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
'r t -> Globnames.global_reference -> (constr, 'r) sigma
(** FILLME *)
diff --git a/engine/uState.ml b/engine/uState.ml
index 75c03bc89c..8aa9a61ab9 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -25,9 +25,14 @@ module UNameMap = struct
| _, _ -> r) s t
end
+type uinfo = {
+ uname : string option;
+ uloc : Loc.t option;
+}
+
(* 2nd part used to check consistency on the fly. *)
type t =
- { uctx_names : Univ.Level.t UNameMap.t * string Univ.LMap.t;
+ { uctx_names : Univ.Level.t UNameMap.t * uinfo Univ.LMap.t;
uctx_local : Univ.universe_context_set; (** The local context of variables *)
uctx_univ_variables : Universes.universe_opt_subst;
(** The local universes that are unification variables *)
@@ -104,8 +109,13 @@ let constrain_variables diff ctx =
with Not_found | Option.IsNone -> cstrs)
diff Univ.Constraint.empty
-let add_uctx_names s l (names, names_rev) =
- (UNameMap.add s l names, Univ.LMap.add l s names_rev)
+let add_uctx_names ?loc s l (names, names_rev) =
+ (UNameMap.add s l names, Univ.LMap.add l { uname = Some s; uloc = loc } names_rev)
+
+let add_uctx_loc l loc (names, names_rev) =
+ match loc with
+ | None -> (names, names_rev)
+ | Some _ -> (names, Univ.LMap.add l { uname = None; uloc = loc } names_rev)
let of_binders b =
let ctx = empty in
@@ -230,8 +240,8 @@ let add_universe_constraints ctx cstrs =
let pr_uctx_level uctx =
let map, map_rev = uctx.uctx_names in
fun l ->
- try str(Univ.LMap.find l map_rev)
- with Not_found ->
+ try str (Option.get (Univ.LMap.find l map_rev).uname)
+ with Not_found | Option.IsNone ->
Universes.pr_with_global_universes l
let universe_context ?names ctx =
@@ -252,10 +262,14 @@ let universe_context ?names ctx =
in
if not (Univ.LSet.is_empty left) then
let n = Univ.LSet.cardinal left in
- errorlabstrm "universe_context"
+ let loc =
+ let get_loc u = try (Univ.LMap.find u (snd ctx.uctx_names)).uloc with Not_found -> None in
+ try List.find_map get_loc (Univ.LSet.elements left) with Not_found -> Loc.ghost
+ in
+ user_err_loc (loc, "universe_context",
(str(CString.plural n "Universe") ++ spc () ++
Univ.LSet.pr (pr_uctx_level ctx) left ++
- spc () ++ str (CString.conjugate_verb_to_be n) ++ str" unbound.")
+ spc () ++ str (CString.conjugate_verb_to_be n) ++ str" unbound."))
else
let inst = Univ.Instance.of_array (Array.of_list newinst) in
let ctx = Univ.UContext.make (inst,
@@ -274,7 +288,7 @@ let univ_rigid = UnivRigid
let univ_flexible = UnivFlexible false
let univ_flexible_alg = UnivFlexible true
-let merge sideff rigid uctx ctx' =
+let merge ?loc sideff rigid uctx ctx' =
let open Univ in
let levels = ContextSet.levels ctx' in
let uctx = if sideff then uctx else
@@ -301,10 +315,21 @@ let merge sideff rigid uctx ctx' =
with UGraph.AlreadyDeclared when sideff -> g)
levels g
in
+ let uctx_names =
+ let fold u accu =
+ let modify _ info = match info.uloc with
+ | None -> { info with uloc = loc }
+ | Some _ -> info
+ in
+ try LMap.modify u modify accu
+ with Not_found -> LMap.add u { uname = None; uloc = loc } accu
+ in
+ (fst uctx.uctx_names, LSet.fold fold levels (snd uctx.uctx_names))
+ in
let initial = declare uctx.uctx_initial_universes in
let univs = declare uctx.uctx_universes in
let uctx_universes = UGraph.merge_constraints (ContextSet.constraints ctx') univs in
- { uctx with uctx_local; uctx_universes; uctx_initial_universes = initial }
+ { uctx with uctx_names; uctx_local; uctx_universes; uctx_initial_universes = initial }
let merge_subst uctx s =
{ uctx with uctx_univ_variables = Univ.LMap.subst_union uctx.uctx_univ_variables s }
@@ -313,7 +338,7 @@ let emit_side_effects eff u =
let uctxs = Safe_typing.universes_of_private eff in
List.fold_left (merge true univ_rigid) u uctxs
-let new_univ_variable rigid name
+let new_univ_variable ?loc rigid name
({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
let u = Universes.new_univ_level (Global.current_dirpath ()) in
let ctx' = Univ.ContextSet.add_universe u ctx in
@@ -328,8 +353,8 @@ let new_univ_variable rigid name
in
let names =
match name with
- | Some n -> add_uctx_names n u uctx.uctx_names
- | None -> uctx.uctx_names
+ | Some n -> add_uctx_names ?loc n u uctx.uctx_names
+ | None -> add_uctx_loc u loc uctx.uctx_names
in
let initial =
UGraph.add_universe u false uctx.uctx_initial_universes
diff --git a/engine/uState.mli b/engine/uState.mli
index 9dc96622ea..c5c454020c 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -84,11 +84,11 @@ val univ_rigid : rigid
val univ_flexible : rigid
val univ_flexible_alg : rigid
-val merge : bool -> rigid -> t -> Univ.universe_context_set -> t
+val merge : ?loc:Loc.t -> bool -> rigid -> t -> Univ.universe_context_set -> t
val merge_subst : t -> Universes.universe_opt_subst -> t
val emit_side_effects : Safe_typing.private_constants -> t -> t
-val new_univ_variable : rigid -> string option -> t -> t * Univ.Level.t
+val new_univ_variable : ?loc:Loc.t -> rigid -> string option -> t -> t * Univ.Level.t
val add_global_univ : t -> Univ.Level.t -> t
val make_flexible_variable : t -> bool -> Univ.Level.t -> t
--
cgit v1.2.3
From bd0dc480ec02352b83e335ed2209abcf3d0f89eb Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 19 Feb 2016 15:56:02 +0100
Subject: Adding location to universes generated by the pretyper.
---
pretyping/pretyping.ml | 32 ++++++++++++++++----------------
pretyping/pretyping.mli | 2 +-
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 5e8c5beb58..8329de2ee4 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -143,12 +143,12 @@ let interp_universe_level_name evd (loc,s) =
evd, Idmap.find id names
with Not_found ->
if not (is_strict_universe_declarations ()) then
- new_univ_level_variable ~name:s univ_rigid evd
+ new_univ_level_variable ~loc ~name:s univ_rigid evd
else user_err_loc (loc, "interp_universe_level_name",
Pp.(str "Undeclared universe: " ++ str s))
-let interp_universe evd = function
- | [] -> let evd, l = new_univ_level_variable univ_rigid evd in
+let interp_universe ?loc evd = function
+ | [] -> let evd, l = new_univ_level_variable ?loc univ_rigid evd in
evd, Univ.Universe.make l
| l ->
List.fold_left (fun (evd, u) l ->
@@ -156,15 +156,15 @@ let interp_universe evd = function
(evd', Univ.sup u (Univ.Universe.make l)))
(evd, Univ.Universe.type0m) l
-let interp_universe_level evd = function
- | None -> new_univ_level_variable univ_rigid evd
+let interp_universe_level loc evd = function
+ | None -> new_univ_level_variable ~loc univ_rigid evd
| Some (loc,s) -> interp_universe_level_name evd (loc,s)
-let interp_sort evd = function
+let interp_sort ?loc evd = function
| GProp -> evd, Prop Null
| GSet -> evd, Prop Pos
| GType n ->
- let evd, u = interp_universe evd n in
+ let evd, u = interp_universe ?loc evd n in
evd, Type u
let interp_elimination_sort = function
@@ -385,11 +385,11 @@ let evar_kind_of_term sigma c =
(*************************************************************************)
(* Main pretyping function *)
-let interp_universe_level_name evd l =
+let interp_universe_level_name loc evd l =
match l with
| GProp -> evd, Univ.Level.prop
| GSet -> evd, Univ.Level.set
- | GType s -> interp_universe_level evd s
+ | GType s -> interp_universe_level loc evd s
let pretype_global loc rigid env evd gr us =
let evd, instance =
@@ -404,7 +404,7 @@ let pretype_global loc rigid env evd gr us =
str "Universe instance should have length " ++ int len)
else
let evd, l' = List.fold_left (fun (evd, univs) l ->
- let evd, l = interp_universe_level_name evd l in
+ let evd, l = interp_universe_level_name loc evd l in
(evd, l :: univs)) (evd, []) l
in
if List.exists (fun l -> Univ.Level.is_prop l) l' then
@@ -413,7 +413,7 @@ let pretype_global loc rigid env evd gr us =
str " universe instances must be greater or equal to Set.");
evd, Some (Univ.Instance.of_array (Array.of_list (List.rev l')))
in
- Evd.fresh_global ~rigid ?names:instance env evd gr
+ Evd.fresh_global ~loc ~rigid ?names:instance env evd gr
let pretype_ref loc evdref env ref us =
match ref with
@@ -431,17 +431,17 @@ let pretype_ref loc evdref env ref us =
let ty = Typing.unsafe_type_of env evd c in
make_judge c ty
-let judge_of_Type evd s =
- let evd, s = interp_universe evd s in
+let judge_of_Type loc evd s =
+ let evd, s = interp_universe ~loc evd s in
let judge =
{ uj_val = mkSort (Type s); uj_type = mkSort (Type (Univ.super s)) }
in
evd, judge
-let pretype_sort evdref = function
+let pretype_sort loc evdref = function
| GProp -> judge_of_prop
| GSet -> judge_of_set
- | GType s -> evd_comb1 judge_of_Type evdref s
+ | GType s -> evd_comb1 (judge_of_Type loc) evdref s
let new_type_evar env evdref loc =
let sigma = Sigma.Unsafe.of_evar_map !evdref in
@@ -598,7 +598,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
inh_conv_coerce_to_tycon loc env evdref fixj tycon
| GSort (loc,s) ->
- let j = pretype_sort evdref s in
+ let j = pretype_sort loc evdref s in
inh_conv_coerce_to_tycon loc env evdref j tycon
| GApp (loc,f,args) ->
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index bfb4e7325e..40745ed097 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -148,7 +148,7 @@ val ise_pretype_gen :
(** To embed constr in glob_constr *)
-val interp_sort : evar_map -> glob_sort -> evar_map * sorts
+val interp_sort : ?loc:Loc.t -> evar_map -> glob_sort -> evar_map * sorts
val interp_elimination_sort : glob_sort -> sorts_family
val genarg_interp_hook :
--
cgit v1.2.3
From fd8038facfe10abb2c874ca4602b1d2ee0903056 Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Tue, 9 Feb 2016 17:46:37 +0100
Subject: Fix regression from 8.4 in reflexivity/...
reflexivity/symmetry/transitivity only need
RelationClasses to be loaded.
---
tactics/rewrite.ml | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index b04fb660d8..5ca74050a1 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -42,6 +42,10 @@ open Libnames
let classes_dirpath =
Names.DirPath.make (List.map Id.of_string ["Classes";"Coq"])
+let init_relation_classes () =
+ if is_dirpath_prefix_of classes_dirpath (Lib.cwd ()) then ()
+ else Coqlib.check_required_library ["Coq";"Classes";"RelationClasses"]
+
let init_setoid () =
if is_dirpath_prefix_of classes_dirpath (Lib.cwd ()) then ()
else Coqlib.check_required_library ["Coq";"Setoids";"Setoid"]
@@ -2041,8 +2045,9 @@ let _ = Hook.set Equality.general_setoid_rewrite_clause general_s_rewrite_clause
(** [setoid_]{reflexivity,symmetry,transitivity} tactics *)
let not_declared env ty rel =
- Tacticals.New.tclFAIL 0 (str" The relation " ++ Printer.pr_constr_env env Evd.empty rel ++ str" is not a declared " ++
- str ty ++ str" relation. Maybe you need to require the Setoid library")
+ Tacticals.New.tclFAIL 0
+ (str" The relation " ++ Printer.pr_constr_env env Evd.empty rel ++ str" is not a declared " ++
+ str ty ++ str" relation. Maybe you need to require the Coq.Classes.RelationClasses library")
let setoid_proof ty fn fallback =
Proofview.Goal.nf_enter begin fun gl ->
@@ -2055,7 +2060,7 @@ let setoid_proof ty fn fallback =
let rel, _, _ = decompose_app_rel env sigma concl in
let (sigma, t) = Typing.type_of env sigma rel in
let car = pi3 (List.hd (fst (Reduction.dest_prod env t))) in
- (try init_setoid () with _ -> raise Not_found);
+ (try init_relation_classes () with _ -> raise Not_found);
fn env sigma car rel
with e -> Proofview.tclZERO e
end
--
cgit v1.2.3
From e54d014ce10dea4a74b66e5091d25e4b26bd71fa Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 15 Feb 2016 20:17:24 +0100
Subject: Fixing bug #4540: CoqIDE bottom progress bar does not update.
---
ide/coqOps.ml | 67 +++++++++++++++++++++++++--------
ide/document.ml | 27 +++++++++-----
ide/document.mli | 4 +-
ide/wg_Segment.ml | 106 ++++++++++++++++++++---------------------------------
ide/wg_Segment.mli | 14 +++++--
5 files changed, 119 insertions(+), 99 deletions(-)
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index 89f4e513ed..58f5eda62e 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -169,6 +169,55 @@ let flags_to_color f =
module Doc = Document
+let segment_model (doc : sentence Doc.document) : Wg_Segment.model =
+object (self)
+
+ val mutable cbs = []
+
+ val mutable document_length = 0
+
+ method length = document_length
+
+ method changed ~callback = cbs <- callback :: cbs
+
+ method fold : 'a. ('a -> Wg_Segment.color -> 'a) -> 'a -> 'a = fun f accu ->
+ let fold accu _ _ s =
+ let flags = List.map mem_flag_of_flag s.flags in
+ f accu (flags_to_color flags)
+ in
+ Doc.fold_all doc accu fold
+
+ method private on_changed (i, f) =
+ let data = (i, flags_to_color f) in
+ List.iter (fun f -> f (`SET data)) cbs
+
+ method private on_push s ctx =
+ let after = match ctx with
+ | None -> []
+ | Some (l, _) -> l
+ in
+ List.iter (fun s -> set_index s (s.index + 1)) after;
+ set_index s (document_length - List.length after);
+ ignore ((SentenceId.connect s)#changed self#on_changed);
+ document_length <- document_length + 1;
+ List.iter (fun f -> f `INSERT) cbs
+
+ method private on_pop s ctx =
+ let () = match ctx with
+ | None -> ()
+ | Some (l, _) -> List.iter (fun s -> set_index s (s.index - 1)) l
+ in
+ set_index s (-1);
+ document_length <- document_length - 1;
+ List.iter (fun f -> f `REMOVE) cbs
+
+ initializer
+ let _ = (Doc.connect doc)#pushed self#on_push in
+ let _ = (Doc.connect doc)#popped self#on_pop in
+ ()
+
+end
+
class coqops
(_script:Wg_ScriptView.script_view)
(_pv:Wg_ProofView.proof_view)
@@ -201,20 +250,8 @@ object(self)
script#misc#set_has_tooltip true;
ignore(script#misc#connect#query_tooltip ~callback:self#tooltip_callback);
feedback_timer.Ideutils.run ~ms:300 ~callback:self#process_feedback;
- let on_changed (i, f) = segment#add i (flags_to_color f) in
- let on_push s =
- set_index s document_length;
- ignore ((SentenceId.connect s)#changed on_changed);
- document_length <- succ document_length;
- segment#set_length document_length;
- let flags = List.map mem_flag_of_flag s.flags in
- segment#add s.index (flags_to_color flags);
- in
- let on_pop s =
- set_index s (-1);
- document_length <- pred document_length;
- segment#set_length document_length;
- in
+ let md = segment_model document in
+ segment#set_model md;
let on_click id =
let find _ _ s = Int.equal s.index id in
let sentence = Doc.find document find in
@@ -230,8 +267,6 @@ object(self)
script#buffer#place_cursor iter;
ignore (script#scroll_to_iter ~use_align:true ~yalign:0. iter)
in
- let _ = (Doc.connect document)#pushed on_push in
- let _ = (Doc.connect document)#popped on_pop in
let _ = segment#connect#clicked on_click in
()
diff --git a/ide/document.ml b/ide/document.ml
index 9823e7576c..6566ee3f81 100644
--- a/ide/document.ml
+++ b/ide/document.ml
@@ -16,8 +16,8 @@ type id = Stateid.t
class type ['a] signals =
object
- method popped : callback:('a -> unit) -> unit
- method pushed : callback:('a -> unit) -> unit
+ method popped : callback:('a -> ('a list * 'a list) option -> unit) -> unit
+ method pushed : callback:('a -> ('a list * 'a list) option -> unit) -> unit
end
class ['a] signal () =
@@ -32,14 +32,14 @@ end
type 'a document = {
mutable stack : 'a sentence list;
mutable context : ('a sentence list * 'a sentence list) option;
- pushed_sig : 'a signal;
- popped_sig : 'a signal;
+ pushed_sig : ('a * ('a list * 'a list) option) signal;
+ popped_sig : ('a * ('a list * 'a list) option) signal;
}
-let connect d =
+let connect d : 'a signals =
object
- method pushed ~callback = d.pushed_sig#connect callback
- method popped ~callback = d.popped_sig#connect callback
+ method pushed ~callback = d.pushed_sig#connect (fun (x, ctx) -> callback x ctx)
+ method popped ~callback = d.popped_sig#connect (fun (x, ctx) -> callback x ctx)
end
let create () = {
@@ -49,6 +49,12 @@ let create () = {
popped_sig = new signal ();
}
+let repr_context s = match s.context with
+| None -> None
+| Some (cl, cr) ->
+ let map s = s.data in
+ Some (List.map map cl, List.map map cr)
+
(* Invariant, only the tip is a allowed to have state_id = None *)
let invariant l = l = [] || (List.hd l).state_id <> None
@@ -64,12 +70,13 @@ let tip_data = function
let push d x =
assert(invariant d.stack);
d.stack <- { data = x; state_id = None } :: d.stack;
- d.pushed_sig#call x
+ d.pushed_sig#call (x, repr_context d)
let pop = function
| { stack = [] } -> raise Empty
- | { stack = { data }::xs } as s -> s.stack <- xs; s.popped_sig#call data; data
-
+ | { stack = { data }::xs } as s ->
+ s.stack <- xs; s.popped_sig#call (data, repr_context s); data
+
let focus d ~cond_top:c_start ~cond_bot:c_stop =
assert(invariant d.stack);
if d.context <> None then invalid_arg "focus";
diff --git a/ide/document.mli b/ide/document.mli
index 0d803ff003..fb96cb6d76 100644
--- a/ide/document.mli
+++ b/ide/document.mli
@@ -108,8 +108,8 @@ val print :
class type ['a] signals =
object
- method popped : callback:('a -> unit) -> unit
- method pushed : callback:('a -> unit) -> unit
+ method popped : callback:('a -> ('a list * 'a list) option -> unit) -> unit
+ method pushed : callback:('a -> ('a list * 'a list) option -> unit) -> unit
end
val connect : 'a document -> 'a signals
diff --git a/ide/wg_Segment.ml b/ide/wg_Segment.ml
index b4b02a7fa2..47fdeb127b 100644
--- a/ide/wg_Segment.ml
+++ b/ide/wg_Segment.ml
@@ -10,53 +10,13 @@ open Util
type color = GDraw.color
-module Segment :
-sig
- type +'a t
- val length : 'a t -> int
- val resize : 'a t -> int -> 'a t
- val empty : 'a t
- val add : int -> 'a -> 'a t -> 'a t
- val remove : int -> 'a t -> 'a t
- val fold : ('a -> 'a -> bool) -> (int -> int -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
-end =
-struct
- type 'a t = {
- length : int;
- content : 'a Int.Map.t;
- }
-
- let empty = { length = 0; content = Int.Map.empty }
-
- let length s = s.length
-
- let resize s len =
- if s.length <= len then { s with length = len }
- else
- let filter i v = i < len in
- { length = len; content = Int.Map.filter filter s.content }
-
- let add i v s =
- if i < s.length then
- { s with content = Int.Map.add i v s.content }
- else s
-
- let remove i s = { s with content = Int.Map.remove i s.content }
-
- let fold eq f s accu =
- let make k v (cur, accu) = match cur with
- | None -> Some (k, k, v), accu
- | Some (i, j, w) ->
- if k = j + 1 && eq v w then Some (i, k, w), accu
- else Some (k, k, v), (i, j, w) :: accu
- in
- let p, segments = Int.Map.fold make s.content (None, []) in
- let segments = match p with
- | None -> segments
- | Some p -> p :: segments
- in
- List.fold_left (fun accu (i, j, v) -> f i j v accu) accu segments
+type model_event = [ `INSERT | `REMOVE | `SET of int * color ]
+class type model =
+object
+ method changed : callback:(model_event -> unit) -> unit
+ method length : int
+ method fold : 'a. ('a -> color -> 'a) -> 'a -> 'a
end
let i2f = float_of_int
@@ -95,7 +55,7 @@ object (self)
val mutable width = 1
val mutable height = 20
- val mutable data = Segment.empty
+ val mutable model : model option = None
val mutable default : color = `WHITE
val mutable pixmap : GDraw.pixmap = GDraw.pixmap ~width:1 ~height:1 ()
val clicked = new GUtil.signal ()
@@ -113,10 +73,12 @@ object (self)
end
in
let _ = box#misc#connect#size_allocate cb in
- let clicked_cb ev =
+ let clicked_cb ev = match model with
+ | None -> true
+ | Some md ->
let x = GdkEvent.Button.x ev in
let (width, _) = pixmap#size in
- let len = Segment.length data in
+ let len = md#length in
let idx = f2i ((x *. i2f len) /. i2f width) in
let () = clicked#call idx in
true
@@ -125,17 +87,23 @@ object (self)
(** Initial pixmap *)
draw#set_pixmap pixmap
- method length = Segment.length data
-
- method set_length len =
- data <- Segment.resize data len;
- if self#misc#visible then self#refresh ()
+ method set_model md =
+ model <- Some md;
+ let changed_cb = function
+ | `INSERT | `REMOVE ->
+ if self#misc#visible then self#refresh ()
+ | `SET (i, color) ->
+ if self#misc#visible then self#fill_range color i (i + 1)
+ in
+ md#changed changed_cb
- method private fill_range color i j =
+ method private fill_range color i j = match model with
+ | None -> ()
+ | Some md ->
let i = i2f i in
let j = i2f j in
let width = i2f width in
- let len = i2f (Segment.length data) in
+ let len = i2f md#length in
let x = f2i ((i *. width) /. len) in
let x' = f2i ((j *. width) /. len) in
let w = x' - x in
@@ -143,14 +111,6 @@ object (self)
pixmap#rectangle ~x ~y:0 ~width:w ~height ~filled:true ();
draw#set_mask None;
- method add i color =
- data <- Segment.add i color data;
- if self#misc#visible then self#fill_range color i (i + 1)
-
- method remove i =
- data <- Segment.remove i data;
- if self#misc#visible then self#fill_range default i (i + 1)
-
method set_default_color color = default <- color
method default_color = default
@@ -159,11 +119,23 @@ object (self)
draw#set_pixmap pixmap;
self#refresh ();
- method private refresh () =
+ method private refresh () = match model with
+ | None -> ()
+ | Some md ->
pixmap#set_foreground default;
pixmap#rectangle ~x:0 ~y:0 ~width ~height ~filled:true ();
- let fold i j v () = self#fill_range v i (j + 1) in
- Segment.fold color_eq fold data ();
+ let make (k, cur, accu) v = match cur with
+ | None -> pred k, Some (k, k, v), accu
+ | Some (i, j, w) ->
+ if k = j - 1 && color_eq v w then pred k, Some (k, i, w), accu
+ else pred k, Some (k, k, v), (i, j, w) :: accu
+ in
+ let _, p, segments = md#fold make (md#length - 1, None, []) in
+ let segments = match p with
+ | None -> segments
+ | Some p -> p :: segments
+ in
+ List.iter (fun (i, j, v) -> self#fill_range v i (j + 1)) segments;
draw#set_mask None;
method connect =
diff --git a/ide/wg_Segment.mli b/ide/wg_Segment.mli
index 0fc8ebd75e..29cbbedacf 100644
--- a/ide/wg_Segment.mli
+++ b/ide/wg_Segment.mli
@@ -8,6 +8,8 @@
type color = GDraw.color
+type model_event = [ `INSERT | `REMOVE | `SET of int * color ]
+
class type segment_signals =
object
inherit GObj.misc_signals
@@ -15,15 +17,19 @@ object
method clicked : callback:(int -> unit) -> GtkSignal.id
end
+class type model =
+object
+ method changed : callback:(model_event -> unit) -> unit
+ method length : int
+ method fold : 'a. ('a -> color -> 'a) -> 'a -> 'a
+end
+
class segment : unit ->
object
inherit GObj.widget
val obj : Gtk.widget Gtk.obj
+ method set_model : model -> unit
method connect : segment_signals
- method length : int
- method set_length : int -> unit
method default_color : color
method set_default_color : color -> unit
- method add : int -> color -> unit
- method remove : int -> unit
end
--
cgit v1.2.3
From f358d7b4c962f5288ad9ce2dc35802666c882422 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 22 Feb 2016 10:32:57 +0100
Subject: The tactic generic argument now returns a value rather than a
glob_expr.
The glob_expr was actually always embedded as a VFun, so this patch should
not change anything semantically. The only change occurs in the plugin API
where one should use the Tacinterp.tactic_of_value function instead of
Tacinterp.eval_tactic.
Moreover, this patch allows to use tactics returning arguments from the ML
side.
---
interp/constrarg.ml | 2 +-
interp/constrarg.mli | 2 +-
plugins/decl_mode/decl_expr.mli | 2 +-
plugins/decl_mode/decl_interp.ml | 2 +-
plugins/decl_mode/decl_proof_instr.ml | 4 ++--
plugins/firstorder/g_ground.ml4 | 8 ++++----
plugins/quote/g_quote.ml4 | 13 ++++++-------
plugins/setoid_ring/newring.ml | 13 +++++--------
plugins/setoid_ring/newring.mli | 4 ++--
printing/pptactic.ml | 10 ++++++----
printing/pptactic.mli | 2 +-
tactics/extraargs.mli | 2 +-
tactics/extratactics.ml4 | 16 ++++++++--------
tactics/g_class.ml4 | 2 +-
tactics/tacinterp.ml | 7 ++-----
tactics/tacinterp.mli | 2 ++
tactics/tauto.ml4 | 7 ++++---
17 files changed, 48 insertions(+), 50 deletions(-)
diff --git a/interp/constrarg.ml b/interp/constrarg.ml
index b093d92e73..a48d683754 100644
--- a/interp/constrarg.ml
+++ b/interp/constrarg.ml
@@ -25,7 +25,7 @@ let wit_int_or_var =
let wit_intro_pattern : (Constrexpr.constr_expr intro_pattern_expr located, glob_constr_and_expr intro_pattern_expr located, intro_pattern) genarg_type =
Genarg.make0 None "intropattern"
-let wit_tactic : (raw_tactic_expr, glob_tactic_expr, glob_tactic_expr) genarg_type =
+let wit_tactic : (raw_tactic_expr, glob_tactic_expr, Val.t) genarg_type =
Genarg.make0 None "tactic"
let wit_ident =
diff --git a/interp/constrarg.mli b/interp/constrarg.mli
index e1a5f4d7c9..5c26af3c2a 100644
--- a/interp/constrarg.mli
+++ b/interp/constrarg.mli
@@ -69,6 +69,6 @@ val wit_red_expr :
(glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) red_expr_gen,
(constr,evaluable_global_reference,constr_pattern) red_expr_gen) genarg_type
-val wit_tactic : (raw_tactic_expr, glob_tactic_expr, glob_tactic_expr) genarg_type
+val wit_tactic : (raw_tactic_expr, glob_tactic_expr, Val.t) genarg_type
val wit_clause_dft_concl : (Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Locus.clause_expr) genarg_type
diff --git a/plugins/decl_mode/decl_expr.mli b/plugins/decl_mode/decl_expr.mli
index 79ef3d186b..9d78a51ef6 100644
--- a/plugins/decl_mode/decl_expr.mli
+++ b/plugins/decl_mode/decl_expr.mli
@@ -99,4 +99,4 @@ type proof_instr =
(Term.constr statement,
Term.constr,
proof_pattern,
- Tacexpr.glob_tactic_expr) gen_proof_instr
+ Genarg.Val.t) gen_proof_instr
diff --git a/plugins/decl_mode/decl_interp.ml b/plugins/decl_mode/decl_interp.ml
index 7cfca53c50..4874552d6a 100644
--- a/plugins/decl_mode/decl_interp.ml
+++ b/plugins/decl_mode/decl_interp.ml
@@ -384,7 +384,7 @@ let interp_cases info env sigma params (pat:cases_pattern_expr) hyps =
let interp_cut interp_it env sigma cut=
let nenv,nstat = interp_it env sigma cut.cut_stat in
- {cut with
+ { cut_using=Option.map (Tacinterp.Value.of_closure (Tacinterp.default_ist ())) cut.cut_using;
cut_stat=nstat;
cut_by=interp_justification_items nenv sigma cut.cut_by}
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index adfcb3e60d..090b293f5c 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -496,7 +496,7 @@ let just_tac _then cut info gls0 =
None ->
Proofview.V82.of_tactic automation_tac gls
| Some tac ->
- Proofview.V82.of_tactic (Tacinterp.eval_tactic tac) gls in
+ Proofview.V82.of_tactic (Tacinterp.tactic_of_value (Tacinterp.default_ist ()) tac) gls in
justification (tclTHEN items_tac method_tac) gls0
let instr_cut mkstat _thus _then cut gls0 =
@@ -546,7 +546,7 @@ let instr_rew _thus rew_side cut gls0 =
None ->
Proofview.V82.of_tactic automation_tac gls
| Some tac ->
- Proofview.V82.of_tactic (Tacinterp.eval_tactic tac) gls in
+ Proofview.V82.of_tactic (Tacinterp.tactic_of_value (Tacinterp.default_ist ()) tac) gls in
let just_tac gls =
justification (tclTHEN items_tac method_tac) gls in
let (c_id,_) = match cut.cut_stat.st_label with
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index 25509b4b5f..3e8be36993 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -135,17 +135,17 @@ END
TACTIC EXTEND firstorder
[ "firstorder" tactic_opt(t) firstorder_using(l) ] ->
- [ Proofview.V82.tactic (gen_ground_tac true (Option.map eval_tactic t) l []) ]
+ [ Proofview.V82.tactic (gen_ground_tac true (Option.map (tactic_of_value ist) t) l []) ]
| [ "firstorder" tactic_opt(t) "with" ne_preident_list(l) ] ->
- [ Proofview.V82.tactic (gen_ground_tac true (Option.map eval_tactic t) [] l) ]
+ [ Proofview.V82.tactic (gen_ground_tac true (Option.map (tactic_of_value ist) t) [] l) ]
| [ "firstorder" tactic_opt(t) firstorder_using(l)
"with" ne_preident_list(l') ] ->
- [ Proofview.V82.tactic (gen_ground_tac true (Option.map eval_tactic t) l l') ]
+ [ Proofview.V82.tactic (gen_ground_tac true (Option.map (tactic_of_value ist) t) l l') ]
END
TACTIC EXTEND gintuition
[ "gintuition" tactic_opt(t) ] ->
- [ Proofview.V82.tactic (gen_ground_tac false (Option.map eval_tactic t) [] []) ]
+ [ Proofview.V82.tactic (gen_ground_tac false (Option.map (tactic_of_value ist) t) [] []) ]
END
open Proofview.Notations
diff --git a/plugins/quote/g_quote.ml4 b/plugins/quote/g_quote.ml4
index fdc5c2bbda..7a3d7936a6 100644
--- a/plugins/quote/g_quote.ml4
+++ b/plugins/quote/g_quote.ml4
@@ -17,15 +17,14 @@ open Quote
DECLARE PLUGIN "quote_plugin"
let loc = Loc.ghost
-let cont = (loc, Id.of_string "cont")
-let x = (loc, Id.of_string "x")
+let cont = Id.of_string "cont"
+let x = Id.of_string "x"
-let make_cont (k : glob_tactic_expr) (c : Constr.t) =
+let make_cont (k : Genarg.Val.t) (c : Constr.t) =
let c = Tacinterp.Value.of_constr c in
- let tac = TacCall (loc, ArgVar cont, [Reference (ArgVar x)]) in
- let tac = TacLetIn (false, [(cont, Tacexp k)], TacArg (loc, tac)) in
- let ist = { lfun = Id.Map.singleton (snd x) c; extra = TacStore.empty; } in
- Tacinterp.eval_tactic_ist ist tac
+ let tac = TacCall (loc, ArgVar (loc, cont), [Reference (ArgVar (loc, x))]) in
+ let ist = { lfun = Id.Map.add cont k (Id.Map.singleton x c); extra = TacStore.empty; } in
+ Tacinterp.eval_tactic_ist ist (TacArg (loc, tac))
TACTIC EXTEND quote
[ "quote" ident(f) ] -> [ quote f [] ]
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index a67cc7cb87..37a8959767 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -176,19 +176,16 @@ let ltac_call tac (args:glob_tactic_arg list) =
let ltac_lcall tac args =
TacArg(Loc.ghost,TacCall(Loc.ghost, ArgVar(Loc.ghost, Id.of_string tac),args))
-let ltac_letin (x, e1) e2 =
- TacLetIn(false,[(Loc.ghost,Id.of_string x),e1],e2)
-
-let ltac_apply (f:glob_tactic_expr) (args: Tacinterp.Value.t list) =
+let ltac_apply (f : Value.t) (args: Tacinterp.Value.t list) =
let fold arg (i, vars, lfun) =
let id = Id.of_string ("x" ^ string_of_int i) in
let x = Reference (ArgVar (Loc.ghost, id)) in
(succ i, x :: vars, Id.Map.add id arg lfun)
in
let (_, args, lfun) = List.fold_right fold args (0, [], Id.Map.empty) in
+ let lfun = Id.Map.add (Id.of_string "F") f lfun in
let ist = { (Tacinterp.default_ist ()) with Tacinterp.lfun = lfun; } in
- Tacinterp.eval_tactic_ist ist
- (ltac_letin ("F", Tacexp f) (ltac_lcall "F" args))
+ Tacinterp.eval_tactic_ist ist (ltac_lcall "F" args)
let ltac_record flds =
TacFun([Some(Id.of_string"proj")], ltac_lcall "proj" flds)
@@ -774,7 +771,7 @@ let ltac_ring_structure e =
[req;sth;ext;morph;th;cst_tac;pow_tac;
lemma1;lemma2;pretac;posttac]
-let ring_lookup (f:glob_tactic_expr) lH rl t =
+let ring_lookup (f : Value.t) lH rl t =
Proofview.Goal.enter { enter = begin fun gl ->
let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
@@ -1046,7 +1043,7 @@ let ltac_field_structure e =
[req;cst_tac;pow_tac;field_ok;field_simpl_ok;field_simpl_eq_ok;
field_simpl_eq_in_ok;cond_ok;pretac;posttac]
-let field_lookup (f:glob_tactic_expr) lH rl t =
+let field_lookup (f : Value.t) lH rl t =
Proofview.Goal.enter { enter = begin fun gl ->
let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
index 4bd3383d65..07a1ae833b 100644
--- a/plugins/setoid_ring/newring.mli
+++ b/plugins/setoid_ring/newring.mli
@@ -45,7 +45,7 @@ val ic : constr_expr -> Evd.evar_map * constr
val from_name : ring_info Spmap.t ref
val ring_lookup :
- glob_tactic_expr ->
+ Genarg.Val.t ->
constr list ->
constr list -> constr -> unit Proofview.tactic
@@ -73,6 +73,6 @@ val add_field_theory :
val field_from_name : field_info Spmap.t ref
val field_lookup :
- glob_tactic_expr ->
+ Genarg.Val.t ->
constr list ->
constr list -> constr -> unit Proofview.tactic
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index c00036bb3c..ed85b21478 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -61,7 +61,7 @@ type 'a glob_extra_genarg_printer =
type 'a extra_genarg_printer =
(Term.constr -> std_ppcmds) ->
(Term.constr -> std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
+ (tolerability -> Val.t -> std_ppcmds) ->
'a -> std_ppcmds
let genarg_pprule = ref String.Map.empty
@@ -106,6 +106,8 @@ module Make
let keyword x = tag_keyword (str x)
let primitive x = tag_primitive (str x)
+ let pr_value _ _ = str "(* FIXME *)"
+
let pr_with_occurrences pr (occs,c) =
match occs with
| AllOccurrences ->
@@ -1308,10 +1310,10 @@ module Make
pr_generic = Genprint.generic_top_print;
pr_extend = pr_extend_rec
(pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- (pr_glob_tactic_level env) pr_constr_pattern;
+ pr_value pr_constr_pattern;
pr_alias = pr_alias
(pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- (pr_glob_tactic_level env) pr_constr_pattern;
+ pr_value pr_constr_pattern;
}
in
make_pr_tac
@@ -1330,7 +1332,7 @@ module Make
let pr_top_generic env = pr_top_generic_rec
(pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- (pr_glob_tactic_level env) pr_constr_pattern
+ pr_value pr_constr_pattern
let pr_raw_extend env = pr_raw_extend_rec
pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr
diff --git a/printing/pptactic.mli b/printing/pptactic.mli
index 2bc64509f0..31a5a5d4a8 100644
--- a/printing/pptactic.mli
+++ b/printing/pptactic.mli
@@ -32,7 +32,7 @@ type 'a glob_extra_genarg_printer =
type 'a extra_genarg_printer =
(Term.constr -> std_ppcmds) ->
(Term.constr -> std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
+ (tolerability -> Val.t -> std_ppcmds) ->
'a -> std_ppcmds
val declare_extra_genarg_pprule :
diff --git a/tactics/extraargs.mli b/tactics/extraargs.mli
index 7c206d95cb..7df845e4bd 100644
--- a/tactics/extraargs.mli
+++ b/tactics/extraargs.mli
@@ -47,7 +47,7 @@ val by_arg_tac : Tacexpr.raw_tactic_expr option Pcoq.Gram.entry
val wit_by_arg_tac :
(raw_tactic_expr option,
glob_tactic_expr option,
- glob_tactic_expr option) Genarg.genarg_type
+ Genarg.Val.t option) Genarg.genarg_type
val pr_by_arg_tac :
(int * Ppextend.parenRelation -> raw_tactic_expr -> Pp.std_ppcmds) ->
diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4
index cdf29e4c62..151949c3c6 100644
--- a/tactics/extratactics.ml4
+++ b/tactics/extratactics.ml4
@@ -44,7 +44,7 @@ let with_delayed_uconstr ist c tac =
let replace_in_clause_maybe_by ist c1 c2 cl tac =
with_delayed_uconstr ist c1
- (fun c1 -> replace_in_clause_maybe_by c1 c2 cl (Option.map Tacinterp.eval_tactic tac))
+ (fun c1 -> replace_in_clause_maybe_by c1 c2 cl (Option.map (Tacinterp.tactic_of_value ist) tac))
let replace_term ist dir_opt c cl =
with_delayed_uconstr ist c (fun c -> replace_term dir_opt c cl)
@@ -237,7 +237,7 @@ TACTIC EXTEND autorewrite
[ auto_multi_rewrite l ( cl) ]
| [ "autorewrite" "with" ne_preident_list(l) clause(cl) "using" tactic(t) ] ->
[
- auto_multi_rewrite_with (Tacinterp.eval_tactic t) l cl
+ auto_multi_rewrite_with (Tacinterp.tactic_of_value ist t) l cl
]
END
@@ -245,14 +245,14 @@ TACTIC EXTEND autorewrite_star
| [ "autorewrite" "*" "with" ne_preident_list(l) clause(cl) ] ->
[ auto_multi_rewrite ~conds:AllMatches l cl ]
| [ "autorewrite" "*" "with" ne_preident_list(l) clause(cl) "using" tactic(t) ] ->
- [ auto_multi_rewrite_with ~conds:AllMatches (Tacinterp.eval_tactic t) l cl ]
+ [ auto_multi_rewrite_with ~conds:AllMatches (Tacinterp.tactic_of_value ist t) l cl ]
END
(**********************************************************************)
(* Rewrite star *)
-let rewrite_star ist clause orient occs c (tac : glob_tactic_expr option) =
- let tac' = Option.map (fun t -> Tacinterp.eval_tactic t, FirstSolved) tac in
+let rewrite_star ist clause orient occs c (tac : Val.t option) =
+ let tac' = Option.map (fun t -> Tacinterp.tactic_of_value ist t, FirstSolved) tac in
with_delayed_uconstr ist c
(fun c -> general_rewrite_ebindings_clause clause orient occs ?tac:tac' true true (c,NoBindings) true)
@@ -512,12 +512,12 @@ let add_transitivity_lemma left lem =
(* Vernacular syntax *)
TACTIC EXTEND stepl
-| ["stepl" constr(c) "by" tactic(tac) ] -> [ step true c (Tacinterp.eval_tactic tac) ]
+| ["stepl" constr(c) "by" tactic(tac) ] -> [ step true c (Tacinterp.tactic_of_value ist tac) ]
| ["stepl" constr(c) ] -> [ step true c (Proofview.tclUNIT ()) ]
END
TACTIC EXTEND stepr
-| ["stepr" constr(c) "by" tactic(tac) ] -> [ step false c (Tacinterp.eval_tactic tac) ]
+| ["stepr" constr(c) "by" tactic(tac) ] -> [ step false c (Tacinterp.tactic_of_value ist tac) ]
| ["stepr" constr(c) ] -> [ step false c (Proofview.tclUNIT ()) ]
END
@@ -883,7 +883,7 @@ END
TACTIC EXTEND unshelve
| [ "unshelve" tactic1(t) ] ->
[
- Proofview.with_shelf (Tacinterp.eval_tactic t) >>= fun (gls, ()) ->
+ Proofview.with_shelf (Tacinterp.tactic_of_value ist t) >>= fun (gls, ()) ->
Proofview.Unsafe.tclGETGOALS >>= fun ogls ->
Proofview.Unsafe.tclSETGOALS (gls @ ogls)
]
diff --git a/tactics/g_class.ml4 b/tactics/g_class.ml4
index e0c1f671fd..766593543c 100644
--- a/tactics/g_class.ml4
+++ b/tactics/g_class.ml4
@@ -14,7 +14,7 @@ open Class_tactics
DECLARE PLUGIN "g_class"
TACTIC EXTEND progress_evars
- [ "progress_evars" tactic(t) ] -> [ progress_evars (Tacinterp.eval_tactic t) ]
+ [ "progress_evars" tactic(t) ] -> [ progress_evars (Tacinterp.tactic_of_value ist t) ]
END
(** Options: depth, debug and transparency settings. *)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 2af21fac6e..cb4a9f320d 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1458,7 +1458,7 @@ and tactic_of_value ist vle =
| (VFun _|VRec _) -> Tacticals.New.tclZEROMSG (str "A fully applied tactic is expected.")
else if has_type vle (topwit wit_tactic) then
let tac = out_gen (topwit wit_tactic) vle in
- eval_tactic ist tac
+ tactic_of_value ist tac
else Tacticals.New.tclZEROMSG (str "Expression does not evaluate to a tactic.")
(* Interprets the clauses of a recursive LetIn *)
@@ -2232,10 +2232,7 @@ let () =
()
let () =
- let interp ist tac =
- let f = VFun (UnnamedAppl,extract_trace ist, ist.lfun, [], tac) in
- Ftactic.return (TacArg (dloc, TacGeneric (Genarg.in_gen (glbwit wit_tacvalue) f)))
- in
+ let interp ist tac = Ftactic.return (Value.of_closure ist tac) in
Geninterp.register_interp0 wit_tactic interp
let () =
diff --git a/tactics/tacinterp.mli b/tactics/tacinterp.mli
index 89d34231b8..c5da3494cb 100644
--- a/tactics/tacinterp.mli
+++ b/tactics/tacinterp.mli
@@ -88,6 +88,8 @@ val eval_tactic : glob_tactic_expr -> unit Proofview.tactic
val eval_tactic_ist : interp_sign -> glob_tactic_expr -> unit Proofview.tactic
(** Same as [eval_tactic], but with the provided [interp_sign]. *)
+val tactic_of_value : interp_sign -> Value.t -> unit Proofview.tactic
+
(** Globalization + interpretation *)
val interp_tac_gen : value Id.Map.t -> Id.t list ->
diff --git a/tactics/tauto.ml4 b/tactics/tauto.ml4
index 4dc5388eeb..5485f344b3 100644
--- a/tactics/tauto.ml4
+++ b/tactics/tauto.ml4
@@ -352,7 +352,6 @@ let t_reduction_not_iff = tacticIn reduction_not_iff "reduction_not_iff"
let intuition_gen ist flags tac =
Proofview.Goal.enter { enter = begin fun gl ->
- let tac = Value.of_closure ist tac in
let env = Proofview.Goal.env gl in
let vars, ist, intuition = tauto_intuit flags t_reduction_not_iff tac in
let glb_intuition = Tacintern.glob_tactic_env vars env intuition in
@@ -360,8 +359,9 @@ let intuition_gen ist flags tac =
end }
let tauto_intuitionistic flags =
+ let fail = Value.of_closure (default_ist ()) <:tactic> in
Proofview.tclORELSE
- (intuition_gen (default_ist ()) flags <:tactic>)
+ (intuition_gen (default_ist ()) flags fail)
begin function (e, info) -> match e with
| Refiner.FailError _ | UserError _ ->
Tacticals.New.tclZEROMSG (str "tauto failed.")
@@ -395,7 +395,8 @@ let tauto_gen flags =
let default_intuition_tac =
let tac _ _ = Auto.h_auto None [] None in
- register_tauto_tactic tac "auto_with"
+ let tac = register_tauto_tactic tac "auto_with" in
+ Value.of_closure (default_ist ()) tac
(* This is the uniform mode dealing with ->, not, iff and types isomorphic to
/\ and *, \/ and +, False and Empty_set, True and unit, _and_ eq-like types.
--
cgit v1.2.3
From 33fe6e61ff2f1f8184373ed8fccc403591c4605a Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 21 Feb 2016 17:13:26 +0100
Subject: Moving the Tauto tactic to proper Ltac.
This gets rid of brittle code written in ML files through Ltac quotations, and
reduces the dependance of Coq to such a feature. This also fixes the particular
instance of bug #2800, although the underlying issue is still there.
---
plugins/funind/invfun.ml | 11 +-
tactics/tauto.ml4 | 249 +++++++-----------------------------------
tactics/tauto.mli | 0
test-suite/bugs/closed/2800.v | 6 +
test-suite/bugs/opened/2800.v | 6 -
theories/Init/Notations.v | 1 -
theories/Init/Prelude.v | 1 +
theories/Init/Tauto.v | 101 +++++++++++++++++
theories/Init/vo.itarget | 3 +-
theories/Logic/Decidable.v | 2 +-
10 files changed, 161 insertions(+), 219 deletions(-)
create mode 100644 tactics/tauto.mli
create mode 100644 test-suite/bugs/closed/2800.v
delete mode 100644 test-suite/bugs/opened/2800.v
create mode 100644 theories/Init/Tauto.v
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index cdb9c5067f..6a5a5ad533 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -474,6 +474,15 @@ let generalize_dependent_of x hyp g =
(* [intros_with_rewrite] do the intros in each branch and treat each new hypothesis
(unfolding, substituting, destructing cases \ldots)
*)
+let tauto =
+ let dp = List.map Id.of_string ["Tauto" ; "Init"; "Coq"] in
+ let mp = ModPath.MPfile (DirPath.make dp) in
+ let kn = KerName.make2 mp (Label.make "tauto") in
+ Proofview.tclBIND (Proofview.tclUNIT ()) begin fun () ->
+ let body = Tacenv.interp_ltac kn in
+ Tacinterp.eval_tactic body
+ end
+
let rec intros_with_rewrite g =
observe_tac "intros_with_rewrite" intros_with_rewrite_aux g
and intros_with_rewrite_aux : tactic =
@@ -530,7 +539,7 @@ and intros_with_rewrite_aux : tactic =
] g
end
| Ind _ when eq_constr t (Coqlib.build_coq_False ()) ->
- Proofview.V82.of_tactic Tauto.tauto g
+ Proofview.V82.of_tactic tauto g
| Case(_,_,v,_) ->
tclTHENSEQ[
Proofview.V82.of_tactic (simplest_case v);
diff --git a/tactics/tauto.ml4 b/tactics/tauto.ml4
index 5485f344b3..e0427ae89a 100644
--- a/tactics/tauto.ml4
+++ b/tactics/tauto.ml4
@@ -14,6 +14,7 @@ open Names
open Pp
open Genarg
open Stdarg
+open Misctypes
open Tacexpr
open Tacinterp
open Tactics
@@ -90,6 +91,7 @@ let _ =
(** Base tactics *)
+let loc = Loc.ghost
let idtac = Proofview.tclUNIT ()
let fail = Proofview.tclINDEPENDENT (tclFAIL 0 (Pp.mt ()))
@@ -112,38 +114,9 @@ let split = Tactics.split_with_bindings false [Misctypes.NoBindings]
(** Test *)
-let make_lfun l =
- let fold accu (id, v) = Id.Map.add (Id.of_string id) v accu in
- List.fold_left fold Id.Map.empty l
-
-let register_tauto_tactic tac name =
- let name = { mltac_plugin = "tauto"; mltac_tactic = name; } in
- let entry = { mltac_name = name; mltac_index = 0 } in
- Tacenv.register_ml_tactic name [| tac |];
- TacML (Loc.ghost, entry, [])
-
-let tacticIn_ist tac name =
- let tac _ ist =
- let avoid = Option.default [] (TacStore.get ist.extra f_avoid_ids) in
- let debug = Option.default Tactic_debug.DebugOff (TacStore.get ist.extra f_debug) in
- let (tac, ist) = tac ist in
- interp_tac_gen ist.lfun avoid debug tac
- in
- register_tauto_tactic tac name
-
-let tacticIn tac name =
- tacticIn_ist (fun ist -> tac ist, ist) name
-
-let push_ist ist args =
- let fold accu (id, arg) = Id.Map.add (Id.of_string id) arg accu in
- let lfun = List.fold_left fold ist.lfun args in
- { ist with lfun = lfun }
-
let is_empty _ ist =
if is_empty_type (assoc_var "X1" ist) then idtac else fail
-let t_is_empty = register_tauto_tactic is_empty "is_empty"
-
(* Strictly speaking, this exceeds the propositional fragment as it
matches also equality types (and solves them if a reflexivity) *)
let is_unit_or_eq _ ist =
@@ -151,16 +124,6 @@ let is_unit_or_eq _ ist =
let test = if flags.strict_unit then is_unit_type else is_unit_or_eq_type in
if test (assoc_var "X1" ist) then idtac else fail
-let t_is_unit_or_eq = register_tauto_tactic is_unit_or_eq "is_unit_or_eq"
-
-let is_record t =
- let (hdapp,args) = decompose_app t in
- match (kind_of_term hdapp) with
- | Ind (ind,u) ->
- let (mib,mip) = Global.lookup_inductive ind in
- mib.Declarations.mind_record <> None
- | _ -> false
-
let bugged_is_binary t =
isApp t &&
let (hdapp,args) = decompose_app t in
@@ -182,8 +145,6 @@ let is_conj _ ist =
then idtac
else fail
-let t_is_conj = register_tauto_tactic is_conj "is_conj"
-
let flatten_contravariant_conj _ ist =
let flags = assoc_flags ist in
let typ = assoc_var "X1" ist in
@@ -200,18 +161,8 @@ let flatten_contravariant_conj _ ist =
tclTHENLIST [assert_ ~by newtyp; clear (destVar hyp)]
| _ -> fail
-let t_flatten_contravariant_conj =
- register_tauto_tactic flatten_contravariant_conj "flatten_contravariant_conj"
-
(** Dealing with disjunction *)
-let constructor i =
- let name = { Tacexpr.mltac_plugin = "coretactics"; mltac_tactic = "constructor" } in
- (** Take care of the index: this is the second entry in constructor. *)
- let name = { Tacexpr.mltac_name = name; mltac_index = 1 } in
- let i = in_gen (rawwit Constrarg.wit_int_or_var) (Misctypes.ArgArg i) in
- Tacexpr.TacML (Loc.ghost, name, [TacGeneric i])
-
let is_disj _ ist =
let flags = assoc_flags ist in
let t = assoc_var "X1" ist in
@@ -222,8 +173,6 @@ let is_disj _ ist =
then idtac
else fail
-let t_is_disj = register_tauto_tactic is_disj "is_disj"
-
let flatten_contravariant_disj _ ist =
let flags = assoc_flags ist in
let typ = assoc_var "X1" ist in
@@ -245,159 +194,30 @@ let flatten_contravariant_disj _ ist =
tclTHEN (tclTHENLIST tacs) tac0
| _ -> fail
-let t_flatten_contravariant_disj =
- register_tauto_tactic flatten_contravariant_disj "flatten_contravariant_disj"
-
-(** Main tactic *)
-
-let not_dep_intros ist =
- <:tactic<
- repeat match goal with
- | |- (forall (_: ?X1), ?X2) => intro
- | |- (Coq.Init.Logic.not _) => unfold Coq.Init.Logic.not at 1; intro
- end >>
-
-let t_not_dep_intros = tacticIn not_dep_intros "not_dep_intros"
-
-let axioms ist =
- let c1 = constructor 1 in
- <:tactic<
- match reverse goal with
- | |- ?X1 => $t_is_unit_or_eq; $c1
- | _:?X1 |- _ => $t_is_empty; elimtype X1; assumption
- | _:?X1 |- ?X1 => assumption
- end >>
-
-let t_axioms = tacticIn axioms "axioms"
-
-let simplif ist =
- let c1 = constructor 1 in
- <:tactic<
- $t_not_dep_intros;
- repeat
- (match reverse goal with
- | id: ?X1 |- _ => $t_is_conj; elim id; do 2 intro; clear id
- | id: (Coq.Init.Logic.iff _ _) |- _ => elim id; do 2 intro; clear id
- | id: (Coq.Init.Logic.not _) |- _ => red in id
- | id: ?X1 |- _ => $t_is_disj; elim id; intro; clear id
- | id0: (forall (_: ?X1), ?X2), id1: ?X1|- _ =>
- (* generalize (id0 id1); intro; clear id0 does not work
- (see Marco Maggiesi's bug PR#301)
- so we instead use Assert and exact. *)
- assert X2; [exact (id0 id1) | clear id0]
- | id: forall (_ : ?X1), ?X2|- _ =>
- $t_is_unit_or_eq; cut X2;
- [ intro; clear id
- | (* id : forall (_: ?X1), ?X2 |- ?X2 *)
- cut X1; [exact id| $c1; fail]
- ]
- | id: forall (_ : ?X1), ?X2|- _ =>
- $t_flatten_contravariant_conj
- (* moved from "id:(?A/\?B)->?X2|-" to "?A->?B->?X2|-" *)
- | id: forall (_: Coq.Init.Logic.iff ?X1 ?X2), ?X3|- _ =>
- assert (forall (_: forall _:X1, X2), forall (_: forall _: X2, X1), X3)
- by (do 2 intro; apply id; split; assumption);
- clear id
- | id: forall (_:?X1), ?X2|- _ =>
- $t_flatten_contravariant_disj
- (* moved from "id:(?A\/?B)->?X2|-" to "?A->?X2,?B->?X2|-" *)
- | |- ?X1 => $t_is_conj; split
- | |- (Coq.Init.Logic.iff _ _) => split
- | |- (Coq.Init.Logic.not _) => red
- end;
- $t_not_dep_intros) >>
-
-let t_simplif = tacticIn simplif "simplif"
-
-let tauto_intuit flags t_reduce solver =
- let flags = Genarg.Val.Dyn (Genarg.val_tag (topwit wit_tauto_flags), flags) in
- let lfun = make_lfun [("t_solver", solver); ("tauto_flags", flags)] in
- let ist = { default_ist () with lfun = lfun; } in
- let vars = [Id.of_string "t_solver"] in
- (vars, ist, <:tactic<
- let rec t_tauto_intuit :=
- ($t_simplif;$t_axioms
- || match reverse goal with
- | id:forall(_: forall (_: ?X1), ?X2), ?X3|- _ =>
- cut X3;
- [ intro; clear id; t_tauto_intuit
- | cut (forall (_: X1), X2);
- [ exact id
- | generalize (fun y:X2 => id (fun x:X1 => y)); intro; clear id;
- solve [ t_tauto_intuit ]]]
- | id:forall (_:not ?X1), ?X3|- _ =>
- cut X3;
- [ intro; clear id; t_tauto_intuit
- | cut (not X1); [ exact id | clear id; intro; solve [t_tauto_intuit ]]]
- | |- ?X1 =>
- $t_is_disj; solve [left;t_tauto_intuit | right;t_tauto_intuit]
- end
- ||
- (* NB: [|- _ -> _] matches any product *)
- match goal with | |- forall (_ : _), _ => intro; t_tauto_intuit
- | |- _ => $t_reduce;t_solver
- end
- ||
- t_solver
- ) in t_tauto_intuit >>)
-
-let reduction_not_iff _ist =
- match !negation_unfolding, unfold_iff () with
+let reduction_not_iff _ ist =
+ let avoid = Option.default [] (TacStore.get ist.extra f_avoid_ids) in
+ let debug = Option.default Tactic_debug.DebugOff (TacStore.get ist.extra f_debug) in
+ let tac = match !negation_unfolding, unfold_iff () with
| true, true -> <:tactic< unfold Coq.Init.Logic.not, Coq.Init.Logic.iff in * >>
| true, false -> <:tactic< unfold Coq.Init.Logic.not in * >>
| false, true -> <:tactic< unfold Coq.Init.Logic.iff in * >>
| false, false -> <:tactic< idtac >>
-
-let t_reduction_not_iff = tacticIn reduction_not_iff "reduction_not_iff"
-
-let intuition_gen ist flags tac =
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let vars, ist, intuition = tauto_intuit flags t_reduction_not_iff tac in
- let glb_intuition = Tacintern.glob_tactic_env vars env intuition in
- eval_tactic_ist ist glb_intuition
- end }
-
-let tauto_intuitionistic flags =
- let fail = Value.of_closure (default_ist ()) <:tactic> in
- Proofview.tclORELSE
- (intuition_gen (default_ist ()) flags fail)
- begin function (e, info) -> match e with
- | Refiner.FailError _ | UserError _ ->
- Tacticals.New.tclZEROMSG (str "tauto failed.")
- | e -> Proofview.tclZERO ~info e
- end
+ in
+ interp_tac_gen ist.lfun avoid debug tac
let coq_nnpp_path =
let dir = List.map Id.of_string ["Classical_Prop";"Logic";"Coq"] in
Libnames.make_path (DirPath.make dir) (Id.of_string "NNPP")
-let tauto_classical flags nnpp =
- Proofview.tclORELSE
- (Tacticals.New.tclTHEN (apply nnpp) (tauto_intuitionistic flags))
- begin function (e, info) -> match e with
- | UserError _ -> Tacticals.New.tclZEROMSG (str "Classical tauto failed.")
- | e -> Proofview.tclZERO ~info e
- end
-
-let tauto_gen flags =
- (* spiwack: I use [tclBIND (tclUNIT ())] as a way to delay the effect
- (in [constr_of_global]) to the application of the tactic. *)
+let apply_nnpp _ ist =
Proofview.tclBIND
(Proofview.tclUNIT ())
begin fun () -> try
let nnpp = Universes.constr_of_global (Nametab.global_of_path coq_nnpp_path) in
- (* try intuitionistic version first to avoid an axiom if possible *)
- Tacticals.New.tclORELSE (tauto_intuitionistic flags) (tauto_classical flags nnpp)
- with Not_found ->
- tauto_intuitionistic flags
+ apply nnpp
+ with Not_found -> tclFAIL 0 (Pp.mt ())
end
-let default_intuition_tac =
- let tac _ _ = Auto.h_auto None [] None in
- let tac = register_tauto_tactic tac "auto_with" in
- Value.of_closure (default_ist ()) tac
-
(* This is the uniform mode dealing with ->, not, iff and types isomorphic to
/\ and *, \/ and +, False and Empty_set, True and unit, _and_ eq-like types.
For the moment not and iff are still always unfolded. *)
@@ -427,23 +247,34 @@ let tauto_power_flags = {
strict_unit = false
}
-let tauto = tauto_gen tauto_uniform_unit_flags
-let dtauto = tauto_gen tauto_power_flags
-
-TACTIC EXTEND tauto
-| [ "tauto" ] -> [ tauto ]
-END
-
-TACTIC EXTEND dtauto
-| [ "dtauto" ] -> [ dtauto ]
+let with_flags flags ist tac =
+ let f = (loc, Id.of_string "f") in
+ let x = (loc, Id.of_string "x") in
+ let arg = Val.Dyn (val_tag (topwit wit_tauto_flags), flags) in
+ let ist = { ist with lfun = Id.Map.add (snd f) tac (Id.Map.add (snd x) arg ist.lfun) } in
+ eval_tactic_ist ist (TacArg (loc, TacCall (loc, ArgVar f, [Reference (ArgVar x)])))
+
+TACTIC EXTEND with_flags
+| [ "with_uniform_flags" tactic(tac) ] -> [ with_flags tauto_uniform_unit_flags ist tac ]
+| [ "with_legacy_flags" tactic(tac) ] -> [ with_flags tauto_legacy_flags ist tac ]
+| [ "with_power_flags" tactic(tac) ] -> [ with_flags tauto_power_flags ist tac ]
END
-TACTIC EXTEND intuition
-| [ "intuition" ] -> [ intuition_gen ist tauto_uniform_unit_flags default_intuition_tac ]
-| [ "intuition" tactic(t) ] -> [ intuition_gen ist tauto_uniform_unit_flags t ]
-END
-
-TACTIC EXTEND dintuition
-| [ "dintuition" ] -> [ intuition_gen ist tauto_power_flags default_intuition_tac ]
-| [ "dintuition" tactic(t) ] -> [ intuition_gen ist tauto_power_flags t ]
-END
+let register_tauto_tactic_ tac name0 args =
+ let ids = List.map (fun id -> Id.of_string id) args in
+ let ids = List.map (fun id -> Some id) ids in
+ let name = { mltac_plugin = "tauto"; mltac_tactic = name0 ^ "_"; } in
+ let entry = { mltac_name = name; mltac_index = 0 } in
+ let () = Tacenv.register_ml_tactic name [| tac |] in
+ let tac = TacFun (ids, TacML (loc, entry, [])) in
+ let obj () = Tacenv.register_ltac true true (Id.of_string name0) tac in
+ Mltop.declare_cache_obj obj "tauto"
+
+let () = register_tauto_tactic_ is_empty "is_empty" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic_ is_unit_or_eq "is_unit_or_eq" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic_ is_disj "is_disj" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic_ is_conj "is_conj" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic_ flatten_contravariant_disj "flatten_contravariant_disj" ["tauto_flags"; "X1"; "X2"; "id"]
+let () = register_tauto_tactic_ flatten_contravariant_conj "flatten_contravariant_conj" ["tauto_flags"; "X1"; "X2"; "id"]
+let () = register_tauto_tactic_ apply_nnpp "apply_nnpp" []
+let () = register_tauto_tactic_ reduction_not_iff "reduction_not_iff" []
diff --git a/tactics/tauto.mli b/tactics/tauto.mli
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test-suite/bugs/closed/2800.v b/test-suite/bugs/closed/2800.v
new file mode 100644
index 0000000000..2ee438934e
--- /dev/null
+++ b/test-suite/bugs/closed/2800.v
@@ -0,0 +1,6 @@
+Goal False.
+
+intuition
+ match goal with
+ | |- _ => idtac " foo"
+ end.
diff --git a/test-suite/bugs/opened/2800.v b/test-suite/bugs/opened/2800.v
deleted file mode 100644
index c559ab0c17..0000000000
--- a/test-suite/bugs/opened/2800.v
+++ /dev/null
@@ -1,6 +0,0 @@
-Goal False.
-
-Fail intuition
- match goal with
- | |- _ => idtac " foo"
- end.
diff --git a/theories/Init/Notations.v b/theories/Init/Notations.v
index e1ddaeaeff..55eb699be6 100644
--- a/theories/Init/Notations.v
+++ b/theories/Init/Notations.v
@@ -90,4 +90,3 @@ Declare ML Module "eauto".
Declare ML Module "g_class".
Declare ML Module "g_eqdecide".
Declare ML Module "g_rewrite".
-Declare ML Module "tauto".
diff --git a/theories/Init/Prelude.v b/theories/Init/Prelude.v
index 04a263ad94..03f2328dec 100644
--- a/theories/Init/Prelude.v
+++ b/theories/Init/Prelude.v
@@ -15,6 +15,7 @@ Require Coq.Init.Nat.
Require Export Peano.
Require Export Coq.Init.Wf.
Require Export Coq.Init.Tactics.
+Require Export Coq.Init.Tauto.
(* Initially available plugins
(+ nat_syntax_plugin loaded in Datatypes) *)
Declare ML Module "extraction_plugin".
diff --git a/theories/Init/Tauto.v b/theories/Init/Tauto.v
new file mode 100644
index 0000000000..e0949eb732
--- /dev/null
+++ b/theories/Init/Tauto.v
@@ -0,0 +1,101 @@
+Require Import Notations.
+Require Import Datatypes.
+Require Import Logic.
+
+Local Declare ML Module "tauto".
+
+Local Ltac not_dep_intros :=
+ repeat match goal with
+ | |- (forall (_: ?X1), ?X2) => intro
+ | |- (Coq.Init.Logic.not _) => unfold Coq.Init.Logic.not at 1; intro
+ end.
+
+Local Ltac axioms flags :=
+ match reverse goal with
+ | |- ?X1 => is_unit_or_eq flags X1; constructor 1
+ | _:?X1 |- _ => is_empty flags X1; elimtype X1; assumption
+ | _:?X1 |- ?X1 => assumption
+ end.
+
+Local Ltac simplif flags :=
+ not_dep_intros;
+ repeat
+ (match reverse goal with
+ | id: ?X1 |- _ => is_conj flags X1; elim id; do 2 intro; clear id
+ | id: (Coq.Init.Logic.iff _ _) |- _ => elim id; do 2 intro; clear id
+ | id: (Coq.Init.Logic.not _) |- _ => red in id
+ | id: ?X1 |- _ => is_disj flags X1; elim id; intro; clear id
+ | id0: (forall (_: ?X1), ?X2), id1: ?X1|- _ =>
+ (* generalize (id0 id1); intro; clear id0 does not work
+ (see Marco Maggiesi's bug PR#301)
+ so we instead use Assert and exact. *)
+ assert X2; [exact (id0 id1) | clear id0]
+ | id: forall (_ : ?X1), ?X2|- _ =>
+ is_unit_or_eq flags X1; cut X2;
+ [ intro; clear id
+ | (* id : forall (_: ?X1), ?X2 |- ?X2 *)
+ cut X1; [exact id| constructor 1; fail]
+ ]
+ | id: forall (_ : ?X1), ?X2|- _ =>
+ flatten_contravariant_conj flags X1 X2 id
+ (* moved from "id:(?A/\?B)->?X2|-" to "?A->?B->?X2|-" *)
+ | id: forall (_: Coq.Init.Logic.iff ?X1 ?X2), ?X3|- _ =>
+ assert (forall (_: forall _:X1, X2), forall (_: forall _: X2, X1), X3)
+ by (do 2 intro; apply id; split; assumption);
+ clear id
+ | id: forall (_:?X1), ?X2|- _ =>
+ flatten_contravariant_disj flags X1 X2 id
+ (* moved from "id:(?A\/?B)->?X2|-" to "?A->?X2,?B->?X2|-" *)
+ | |- ?X1 => is_conj flags X1; split
+ | |- (Coq.Init.Logic.iff _ _) => split
+ | |- (Coq.Init.Logic.not _) => red
+ end;
+ not_dep_intros).
+
+Local Ltac tauto_intuit flags t_reduce t_solver :=
+ let rec t_tauto_intuit :=
+ (simplif flags; axioms flags
+ || match reverse goal with
+ | id:forall(_: forall (_: ?X1), ?X2), ?X3|- _ =>
+ cut X3;
+ [ intro; clear id; t_tauto_intuit
+ | cut (forall (_: X1), X2);
+ [ exact id
+ | generalize (fun y:X2 => id (fun x:X1 => y)); intro; clear id;
+ solve [ t_tauto_intuit ]]]
+ | id:forall (_:not ?X1), ?X3|- _ =>
+ cut X3;
+ [ intro; clear id; t_tauto_intuit
+ | cut (not X1); [ exact id | clear id; intro; solve [t_tauto_intuit ]]]
+ | |- ?X1 =>
+ is_disj flags X1; solve [left;t_tauto_intuit | right;t_tauto_intuit]
+ end
+ ||
+ (* NB: [|- _ -> _] matches any product *)
+ match goal with | |- forall (_ : _), _ => intro; t_tauto_intuit
+ | |- _ => t_reduce;t_solver
+ end
+ ||
+ t_solver
+ ) in t_tauto_intuit.
+
+Local Ltac intuition_gen flags solver := tauto_intuit flags reduction_not_iff solver.
+Local Ltac tauto_intuitionistic flags := intuition_gen flags fail || fail "tauto failed".
+Local Ltac tauto_classical flags :=
+ (apply_nnpp || fail "tauto failed"); (tauto_intuitionistic flags || fail "Classical tauto failed").
+Local Ltac tauto_gen flags := tauto_intuitionistic flags || tauto_classical flags.
+
+Ltac tauto := with_uniform_flags (fun flags => tauto_gen flags).
+Ltac dtauto := with_power_flags (fun flags => tauto_gen flags).
+
+Ltac intuition := with_uniform_flags (fun flags => intuition_gen flags ltac:(auto with *)).
+Local Ltac intuition_then tac := with_uniform_flags (fun flags => intuition_gen flags tac).
+
+Ltac dintuition := with_power_flags (fun flags => intuition_gen flags ltac:(auto with *)).
+Local Ltac dintuition_then tac := with_power_flags (fun flags => intuition_gen flags tac).
+
+Tactic Notation "intuition" := intuition.
+Tactic Notation "intuition" tactic(t) := intuition_then t.
+
+Tactic Notation "dintuition" := dintuition.
+Tactic Notation "dintuition" tactic(t) := dintuition_then t.
diff --git a/theories/Init/vo.itarget b/theories/Init/vo.itarget
index cc62e66cce..99877065e8 100644
--- a/theories/Init/vo.itarget
+++ b/theories/Init/vo.itarget
@@ -7,4 +7,5 @@ Prelude.vo
Specif.vo
Tactics.vo
Wf.vo
-Nat.vo
\ No newline at end of file
+Nat.vo
+Tauto.vo
diff --git a/theories/Logic/Decidable.v b/theories/Logic/Decidable.v
index 2ba7253c44..8b6054f9d0 100644
--- a/theories/Logic/Decidable.v
+++ b/theories/Logic/Decidable.v
@@ -50,7 +50,7 @@ Qed.
Theorem dec_iff :
forall A B:Prop, decidable A -> decidable B -> decidable (A<->B).
Proof.
-unfold decidable; tauto.
+unfold decidable. tauto.
Qed.
Theorem not_not : forall P:Prop, decidable P -> ~ ~ P -> P.
--
cgit v1.2.3
From 55ce331822a673d710451c628ec5a731ab36da1f Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Tue, 2 Feb 2016 15:28:48 +0100
Subject: Fix bug #4544: Backtrack on using full betaiota reduction during
keyed unification.
---
tactics/equality.ml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index ef1ec13bae..80f6038cb7 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -228,8 +228,8 @@ let rewrite_keyed_core_unif_flags = {
(* This is set dynamically *)
restrict_conv_on_strict_subterms = false;
- modulo_betaiota = true;
- (* Different from conv_closed *)
+ modulo_betaiota = false;
+
modulo_eta = true;
}
--
cgit v1.2.3
From 5bca0e81c46c1cc6427f939263670996f570dbcf Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Tue, 2 Feb 2016 15:47:23 +0100
Subject: Fix part of bug #4533: respect declared global transparency of
projections in unification.ml
---
pretyping/unification.ml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 6cb1bc7028..55210d067e 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -481,7 +481,8 @@ let key_of env b flags f =
Id.Pred.mem id (fst flags.modulo_delta) ->
Some (IsKey (VarKey id))
| Proj (p, c) when Projection.unfolded p
- || Cpred.mem (Projection.constant p) (snd flags.modulo_delta) ->
+ || (is_transparent env (ConstKey (Projection.constant p)) &&
+ (Cpred.mem (Projection.constant p) (snd flags.modulo_delta))) ->
Some (IsProj (p, c))
| _ -> None
--
cgit v1.2.3
From e7b292de756b335069fce9d9a999904ea2af6630 Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Tue, 23 Feb 2016 18:21:02 +0100
Subject: Document differences of Hint Resolve and Hint Extern
---
test-suite/success/auto.v | 89 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/test-suite/success/auto.v b/test-suite/success/auto.v
index aaa7b3a514..5477c83316 100644
--- a/test-suite/success/auto.v
+++ b/test-suite/success/auto.v
@@ -45,3 +45,92 @@ Proof.
eexists. Fail progress debug eauto with test2.
progress eauto with test.
Qed.
+
+(** Patterns of Extern have a "matching" semantics.
+ It is not so for apply/exact hints *)
+
+Class B (A : Type).
+Class I.
+Instance i : I.
+
+Definition flip {A B C : Type} (f : A -> B -> C) := fun y x => f x y.
+Class D (f : nat -> nat -> nat).
+Definition ftest (x y : nat) := x + y.
+Definition flipD (f : nat -> nat -> nat) : D f -> D (flip f).
+ Admitted.
+Module Instnopat.
+ Local Instance: B nat.
+ (* pattern_of_constr -> B nat *)
+ (* exact hint *)
+ Check (_ : B nat).
+ (* map_eauto -> B_instance0 *)
+ (* NO Constr_matching.matches !!! *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ eauto with typeclass_instances.
+ Qed.
+
+ Local Instance: D ftest.
+ Local Hint Resolve flipD | 0 : typeclass_instances.
+ (* pattern: D (flip _) *)
+ Fail Timeout 1 Check (_ : D _). (* loops applying flipD *)
+
+End Instnopat.
+
+Module InstnopatApply.
+ Local Instance: I -> B nat.
+ (* pattern_of_constr -> B nat *)
+ (* apply hint *)
+ Check (_ : B nat).
+ (* map_eauto -> B_instance0 *)
+ (* NO Constr_matching.matches !!! *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ eauto with typeclass_instances.
+ Qed.
+End InstnopatApply.
+
+Module InstPat.
+ Hint Extern 3 (B nat) => split : typeclass_instances.
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> true *)
+ Check (_ : B nat).
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> false:
+ Because an inductive in the pattern does not match an evar in the goal *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ (* map_existential -> Extern hint *)
+ (* Constr_matching.matches -> false *)
+ Fail progress eauto with typeclass_instances.
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> false *)
+ Fail typeclasses eauto.
+ Abort.
+
+ Hint Extern 0 (D (flip _)) => apply flipD : typeclass_instances.
+ Module withftest.
+ Local Instance: D ftest.
+
+ Check (_ : D _).
+ (* D_instance_0 : D ftest *)
+ Check (_ : D (flip _)).
+ (* ... : D (flip ftest) *)
+ End withftest.
+ Module withoutftest.
+ Hint Extern 0 (D ftest) => split : typeclass_instances.
+ Check (_ : D _).
+ (* ? : D ?, _not_ looping *)
+ Check (_ : D (flip _)).
+ (* ? : D (flip ?), _not_ looping *)
+
+ Check (_ : D (flip ftest)).
+ (* flipD ftest {| |} : D (flip ftest) *)
+ End withoutftest.
+End InstPat.
--
cgit v1.2.3
From 7fb5a9c518f30298a7a9332f0280c2ca0e690f18 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Tue, 23 Feb 2016 10:28:00 +0100
Subject: Moving tauto.ml4 to a proper ML file.
---
tactics/tauto.ml | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++
tactics/tauto.ml4 | 280 -------------------------------------------------
theories/Init/Tauto.v | 12 +--
3 files changed, 290 insertions(+), 286 deletions(-)
create mode 100644 tactics/tauto.ml
delete mode 100644 tactics/tauto.ml4
diff --git a/tactics/tauto.ml b/tactics/tauto.ml
new file mode 100644
index 0000000000..67ef25d49f
--- /dev/null
+++ b/tactics/tauto.ml
@@ -0,0 +1,284 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* c
+ | None -> failwith "tauto: anomaly"
+
+(** Parametrization of tauto *)
+
+type tauto_flags = {
+
+(* Whether conjunction and disjunction are restricted to binary connectives *)
+ binary_mode : bool;
+
+(* Whether compatibility for buggy detection of binary connective is on *)
+ binary_mode_bugged_detection : bool;
+
+(* Whether conjunction and disjunction are restricted to the connectives *)
+(* having the structure of "and" and "or" (up to the choice of sorts) in *)
+(* contravariant position in an hypothesis *)
+ strict_in_contravariant_hyp : bool;
+
+(* Whether conjunction and disjunction are restricted to the connectives *)
+(* having the structure of "and" and "or" (up to the choice of sorts) in *)
+(* an hypothesis and in the conclusion *)
+ strict_in_hyp_and_ccl : bool;
+
+(* Whether unit type includes equality types *)
+ strict_unit : bool;
+}
+
+let wit_tauto_flags : tauto_flags uniform_genarg_type =
+ Genarg.create_arg None "tauto_flags"
+
+let assoc_flags ist =
+ let v = Id.Map.find (Names.Id.of_string "tauto_flags") ist.lfun in
+ try Value.cast (topwit wit_tauto_flags) v with _ -> assert false
+
+(* Whether inner not are unfolded *)
+let negation_unfolding = ref true
+
+(* Whether inner iff are unfolded *)
+let iff_unfolding = ref false
+
+let unfold_iff () = !iff_unfolding || Flags.version_less_or_equal Flags.V8_2
+
+open Goptions
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "unfolding of not in intuition";
+ optkey = ["Intuition";"Negation";"Unfolding"];
+ optread = (fun () -> !negation_unfolding);
+ optwrite = (:=) negation_unfolding }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "unfolding of iff in intuition";
+ optkey = ["Intuition";"Iff";"Unfolding"];
+ optread = (fun () -> !iff_unfolding);
+ optwrite = (:=) iff_unfolding }
+
+(** Base tactics *)
+
+let loc = Loc.ghost
+let idtac = Proofview.tclUNIT ()
+let fail = Proofview.tclINDEPENDENT (tclFAIL 0 (Pp.mt ()))
+
+let intro = Tactics.intro
+
+let assert_ ?by c =
+ let tac = match by with
+ | None -> None
+ | Some tac -> Some (tclCOMPLETE tac)
+ in
+ Proofview.tclINDEPENDENT (Tactics.forward true tac None c)
+
+let apply c = Tactics.apply c
+
+let clear id = Proofview.V82.tactic (fun gl -> Tactics.clear [id] gl)
+
+let assumption = Tactics.assumption
+
+let split = Tactics.split_with_bindings false [Misctypes.NoBindings]
+
+(** Test *)
+
+let is_empty _ ist =
+ if is_empty_type (assoc_var "X1" ist) then idtac else fail
+
+(* Strictly speaking, this exceeds the propositional fragment as it
+ matches also equality types (and solves them if a reflexivity) *)
+let is_unit_or_eq _ ist =
+ let flags = assoc_flags ist in
+ let test = if flags.strict_unit then is_unit_type else is_unit_or_eq_type in
+ if test (assoc_var "X1" ist) then idtac else fail
+
+let bugged_is_binary t =
+ isApp t &&
+ let (hdapp,args) = decompose_app t in
+ match (kind_of_term hdapp) with
+ | Ind (ind,u) ->
+ let (mib,mip) = Global.lookup_inductive ind in
+ Int.equal mib.Declarations.mind_nparams 2
+ | _ -> false
+
+(** Dealing with conjunction *)
+
+let is_conj _ ist =
+ let flags = assoc_flags ist in
+ let ind = assoc_var "X1" ist in
+ if (not flags.binary_mode_bugged_detection || bugged_is_binary ind) &&
+ is_conjunction
+ ~strict:flags.strict_in_hyp_and_ccl
+ ~onlybinary:flags.binary_mode ind
+ then idtac
+ else fail
+
+let flatten_contravariant_conj _ ist =
+ let flags = assoc_flags ist in
+ let typ = assoc_var "X1" ist in
+ let c = assoc_var "X2" ist in
+ let hyp = assoc_var "id" ist in
+ match match_with_conjunction
+ ~strict:flags.strict_in_contravariant_hyp
+ ~onlybinary:flags.binary_mode typ
+ with
+ | Some (_,args) ->
+ let newtyp = List.fold_right mkArrow args c in
+ let intros = tclMAP (fun _ -> intro) args in
+ let by = tclTHENLIST [intros; apply hyp; split; assumption] in
+ tclTHENLIST [assert_ ~by newtyp; clear (destVar hyp)]
+ | _ -> fail
+
+(** Dealing with disjunction *)
+
+let is_disj _ ist =
+ let flags = assoc_flags ist in
+ let t = assoc_var "X1" ist in
+ if (not flags.binary_mode_bugged_detection || bugged_is_binary t) &&
+ is_disjunction
+ ~strict:flags.strict_in_hyp_and_ccl
+ ~onlybinary:flags.binary_mode t
+ then idtac
+ else fail
+
+let flatten_contravariant_disj _ ist =
+ let flags = assoc_flags ist in
+ let typ = assoc_var "X1" ist in
+ let c = assoc_var "X2" ist in
+ let hyp = assoc_var "id" ist in
+ match match_with_disjunction
+ ~strict:flags.strict_in_contravariant_hyp
+ ~onlybinary:flags.binary_mode
+ typ with
+ | Some (_,args) ->
+ let map i arg =
+ let typ = mkArrow arg c in
+ let ci = Tactics.constructor_tac false None (succ i) Misctypes.NoBindings in
+ let by = tclTHENLIST [intro; apply hyp; ci; assumption] in
+ assert_ ~by typ
+ in
+ let tacs = List.mapi map args in
+ let tac0 = clear (destVar hyp) in
+ tclTHEN (tclTHENLIST tacs) tac0
+ | _ -> fail
+
+let make_unfold name =
+ let dir = DirPath.make (List.map Id.of_string ["Logic"; "Init"; "Coq"]) in
+ let const = Constant.make2 (MPfile dir) (Label.make name) in
+ (Locus.AllOccurrences, ArgArg (EvalConstRef const, None))
+
+let u_iff = make_unfold "iff"
+let u_not = make_unfold "not"
+
+let reduction_not_iff _ ist =
+ let make_reduce c = TacAtom (loc, TacReduce (Genredexpr.Unfold c, Locusops.allHypsAndConcl)) in
+ let tac = match !negation_unfolding, unfold_iff () with
+ | true, true -> make_reduce [u_not; u_iff]
+ | true, false -> make_reduce [u_not]
+ | false, true -> make_reduce [u_iff]
+ | false, false -> TacId []
+ in
+ eval_tactic_ist ist tac
+
+let coq_nnpp_path =
+ let dir = List.map Id.of_string ["Classical_Prop";"Logic";"Coq"] in
+ Libnames.make_path (DirPath.make dir) (Id.of_string "NNPP")
+
+let apply_nnpp _ ist =
+ Proofview.tclBIND
+ (Proofview.tclUNIT ())
+ begin fun () -> try
+ let nnpp = Universes.constr_of_global (Nametab.global_of_path coq_nnpp_path) in
+ apply nnpp
+ with Not_found -> tclFAIL 0 (Pp.mt ())
+ end
+
+(* This is the uniform mode dealing with ->, not, iff and types isomorphic to
+ /\ and *, \/ and +, False and Empty_set, True and unit, _and_ eq-like types.
+ For the moment not and iff are still always unfolded. *)
+let tauto_uniform_unit_flags = {
+ binary_mode = true;
+ binary_mode_bugged_detection = false;
+ strict_in_contravariant_hyp = true;
+ strict_in_hyp_and_ccl = true;
+ strict_unit = false
+}
+
+(* This is the compatibility mode (not used) *)
+let tauto_legacy_flags = {
+ binary_mode = true;
+ binary_mode_bugged_detection = true;
+ strict_in_contravariant_hyp = true;
+ strict_in_hyp_and_ccl = false;
+ strict_unit = false
+}
+
+(* This is the improved mode *)
+let tauto_power_flags = {
+ binary_mode = false; (* support n-ary connectives *)
+ binary_mode_bugged_detection = false;
+ strict_in_contravariant_hyp = false; (* supports non-regular connectives *)
+ strict_in_hyp_and_ccl = false;
+ strict_unit = false
+}
+
+let with_flags flags _ ist =
+ let f = (loc, Id.of_string "f") in
+ let x = (loc, Id.of_string "x") in
+ let arg = Val.Dyn (val_tag (topwit wit_tauto_flags), flags) in
+ let ist = { ist with lfun = Id.Map.add (snd x) arg ist.lfun } in
+ eval_tactic_ist ist (TacArg (loc, TacCall (loc, ArgVar f, [Reference (ArgVar x)])))
+
+let register_tauto_tactic tac name0 args =
+ let ids = List.map (fun id -> Id.of_string id) args in
+ let ids = List.map (fun id -> Some id) ids in
+ let name = { mltac_plugin = tauto_plugin; mltac_tactic = name0; } in
+ let entry = { mltac_name = name; mltac_index = 0 } in
+ let () = Tacenv.register_ml_tactic name [| tac |] in
+ let tac = TacFun (ids, TacML (loc, entry, [])) in
+ let obj () = Tacenv.register_ltac true true (Id.of_string name0) tac in
+ Mltop.declare_cache_obj obj tauto_plugin
+
+let () = register_tauto_tactic is_empty "is_empty" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic is_unit_or_eq "is_unit_or_eq" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic is_disj "is_disj" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic is_conj "is_conj" ["tauto_flags"; "X1"]
+let () = register_tauto_tactic flatten_contravariant_disj "flatten_contravariant_disj" ["tauto_flags"; "X1"; "X2"; "id"]
+let () = register_tauto_tactic flatten_contravariant_conj "flatten_contravariant_conj" ["tauto_flags"; "X1"; "X2"; "id"]
+let () = register_tauto_tactic apply_nnpp "apply_nnpp" []
+let () = register_tauto_tactic reduction_not_iff "reduction_not_iff" []
+let () = register_tauto_tactic (with_flags tauto_uniform_unit_flags) "with_uniform_flags" ["f"]
+let () = register_tauto_tactic (with_flags tauto_power_flags) "with_power_flags" ["f"]
diff --git a/tactics/tauto.ml4 b/tactics/tauto.ml4
deleted file mode 100644
index e0427ae89a..0000000000
--- a/tactics/tauto.ml4
+++ /dev/null
@@ -1,280 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* c
- | None -> failwith "tauto: anomaly"
-
-(** Parametrization of tauto *)
-
-type tauto_flags = {
-
-(* Whether conjunction and disjunction are restricted to binary connectives *)
- binary_mode : bool;
-
-(* Whether compatibility for buggy detection of binary connective is on *)
- binary_mode_bugged_detection : bool;
-
-(* Whether conjunction and disjunction are restricted to the connectives *)
-(* having the structure of "and" and "or" (up to the choice of sorts) in *)
-(* contravariant position in an hypothesis *)
- strict_in_contravariant_hyp : bool;
-
-(* Whether conjunction and disjunction are restricted to the connectives *)
-(* having the structure of "and" and "or" (up to the choice of sorts) in *)
-(* an hypothesis and in the conclusion *)
- strict_in_hyp_and_ccl : bool;
-
-(* Whether unit type includes equality types *)
- strict_unit : bool;
-}
-
-let wit_tauto_flags : tauto_flags uniform_genarg_type =
- Genarg.create_arg None "tauto_flags"
-
-let assoc_flags ist =
- let v = Id.Map.find (Names.Id.of_string "tauto_flags") ist.lfun in
- try Value.cast (topwit wit_tauto_flags) v with _ -> assert false
-
-(* Whether inner not are unfolded *)
-let negation_unfolding = ref true
-
-(* Whether inner iff are unfolded *)
-let iff_unfolding = ref false
-
-let unfold_iff () = !iff_unfolding || Flags.version_less_or_equal Flags.V8_2
-
-open Goptions
-let _ =
- declare_bool_option
- { optsync = true;
- optdepr = false;
- optname = "unfolding of not in intuition";
- optkey = ["Intuition";"Negation";"Unfolding"];
- optread = (fun () -> !negation_unfolding);
- optwrite = (:=) negation_unfolding }
-
-let _ =
- declare_bool_option
- { optsync = true;
- optdepr = false;
- optname = "unfolding of iff in intuition";
- optkey = ["Intuition";"Iff";"Unfolding"];
- optread = (fun () -> !iff_unfolding);
- optwrite = (:=) iff_unfolding }
-
-(** Base tactics *)
-
-let loc = Loc.ghost
-let idtac = Proofview.tclUNIT ()
-let fail = Proofview.tclINDEPENDENT (tclFAIL 0 (Pp.mt ()))
-
-let intro = Tactics.intro
-
-let assert_ ?by c =
- let tac = match by with
- | None -> None
- | Some tac -> Some (tclCOMPLETE tac)
- in
- Proofview.tclINDEPENDENT (Tactics.forward true tac None c)
-
-let apply c = Tactics.apply c
-
-let clear id = Proofview.V82.tactic (fun gl -> Tactics.clear [id] gl)
-
-let assumption = Tactics.assumption
-
-let split = Tactics.split_with_bindings false [Misctypes.NoBindings]
-
-(** Test *)
-
-let is_empty _ ist =
- if is_empty_type (assoc_var "X1" ist) then idtac else fail
-
-(* Strictly speaking, this exceeds the propositional fragment as it
- matches also equality types (and solves them if a reflexivity) *)
-let is_unit_or_eq _ ist =
- let flags = assoc_flags ist in
- let test = if flags.strict_unit then is_unit_type else is_unit_or_eq_type in
- if test (assoc_var "X1" ist) then idtac else fail
-
-let bugged_is_binary t =
- isApp t &&
- let (hdapp,args) = decompose_app t in
- match (kind_of_term hdapp) with
- | Ind (ind,u) ->
- let (mib,mip) = Global.lookup_inductive ind in
- Int.equal mib.Declarations.mind_nparams 2
- | _ -> false
-
-(** Dealing with conjunction *)
-
-let is_conj _ ist =
- let flags = assoc_flags ist in
- let ind = assoc_var "X1" ist in
- if (not flags.binary_mode_bugged_detection || bugged_is_binary ind) &&
- is_conjunction
- ~strict:flags.strict_in_hyp_and_ccl
- ~onlybinary:flags.binary_mode ind
- then idtac
- else fail
-
-let flatten_contravariant_conj _ ist =
- let flags = assoc_flags ist in
- let typ = assoc_var "X1" ist in
- let c = assoc_var "X2" ist in
- let hyp = assoc_var "id" ist in
- match match_with_conjunction
- ~strict:flags.strict_in_contravariant_hyp
- ~onlybinary:flags.binary_mode typ
- with
- | Some (_,args) ->
- let newtyp = List.fold_right mkArrow args c in
- let intros = tclMAP (fun _ -> intro) args in
- let by = tclTHENLIST [intros; apply hyp; split; assumption] in
- tclTHENLIST [assert_ ~by newtyp; clear (destVar hyp)]
- | _ -> fail
-
-(** Dealing with disjunction *)
-
-let is_disj _ ist =
- let flags = assoc_flags ist in
- let t = assoc_var "X1" ist in
- if (not flags.binary_mode_bugged_detection || bugged_is_binary t) &&
- is_disjunction
- ~strict:flags.strict_in_hyp_and_ccl
- ~onlybinary:flags.binary_mode t
- then idtac
- else fail
-
-let flatten_contravariant_disj _ ist =
- let flags = assoc_flags ist in
- let typ = assoc_var "X1" ist in
- let c = assoc_var "X2" ist in
- let hyp = assoc_var "id" ist in
- match match_with_disjunction
- ~strict:flags.strict_in_contravariant_hyp
- ~onlybinary:flags.binary_mode
- typ with
- | Some (_,args) ->
- let map i arg =
- let typ = mkArrow arg c in
- let ci = Tactics.constructor_tac false None (succ i) Misctypes.NoBindings in
- let by = tclTHENLIST [intro; apply hyp; ci; assumption] in
- assert_ ~by typ
- in
- let tacs = List.mapi map args in
- let tac0 = clear (destVar hyp) in
- tclTHEN (tclTHENLIST tacs) tac0
- | _ -> fail
-
-let reduction_not_iff _ ist =
- let avoid = Option.default [] (TacStore.get ist.extra f_avoid_ids) in
- let debug = Option.default Tactic_debug.DebugOff (TacStore.get ist.extra f_debug) in
- let tac = match !negation_unfolding, unfold_iff () with
- | true, true -> <:tactic< unfold Coq.Init.Logic.not, Coq.Init.Logic.iff in * >>
- | true, false -> <:tactic< unfold Coq.Init.Logic.not in * >>
- | false, true -> <:tactic< unfold Coq.Init.Logic.iff in * >>
- | false, false -> <:tactic< idtac >>
- in
- interp_tac_gen ist.lfun avoid debug tac
-
-let coq_nnpp_path =
- let dir = List.map Id.of_string ["Classical_Prop";"Logic";"Coq"] in
- Libnames.make_path (DirPath.make dir) (Id.of_string "NNPP")
-
-let apply_nnpp _ ist =
- Proofview.tclBIND
- (Proofview.tclUNIT ())
- begin fun () -> try
- let nnpp = Universes.constr_of_global (Nametab.global_of_path coq_nnpp_path) in
- apply nnpp
- with Not_found -> tclFAIL 0 (Pp.mt ())
- end
-
-(* This is the uniform mode dealing with ->, not, iff and types isomorphic to
- /\ and *, \/ and +, False and Empty_set, True and unit, _and_ eq-like types.
- For the moment not and iff are still always unfolded. *)
-let tauto_uniform_unit_flags = {
- binary_mode = true;
- binary_mode_bugged_detection = false;
- strict_in_contravariant_hyp = true;
- strict_in_hyp_and_ccl = true;
- strict_unit = false
-}
-
-(* This is the compatibility mode (not used) *)
-let tauto_legacy_flags = {
- binary_mode = true;
- binary_mode_bugged_detection = true;
- strict_in_contravariant_hyp = true;
- strict_in_hyp_and_ccl = false;
- strict_unit = false
-}
-
-(* This is the improved mode *)
-let tauto_power_flags = {
- binary_mode = false; (* support n-ary connectives *)
- binary_mode_bugged_detection = false;
- strict_in_contravariant_hyp = false; (* supports non-regular connectives *)
- strict_in_hyp_and_ccl = false;
- strict_unit = false
-}
-
-let with_flags flags ist tac =
- let f = (loc, Id.of_string "f") in
- let x = (loc, Id.of_string "x") in
- let arg = Val.Dyn (val_tag (topwit wit_tauto_flags), flags) in
- let ist = { ist with lfun = Id.Map.add (snd f) tac (Id.Map.add (snd x) arg ist.lfun) } in
- eval_tactic_ist ist (TacArg (loc, TacCall (loc, ArgVar f, [Reference (ArgVar x)])))
-
-TACTIC EXTEND with_flags
-| [ "with_uniform_flags" tactic(tac) ] -> [ with_flags tauto_uniform_unit_flags ist tac ]
-| [ "with_legacy_flags" tactic(tac) ] -> [ with_flags tauto_legacy_flags ist tac ]
-| [ "with_power_flags" tactic(tac) ] -> [ with_flags tauto_power_flags ist tac ]
-END
-
-let register_tauto_tactic_ tac name0 args =
- let ids = List.map (fun id -> Id.of_string id) args in
- let ids = List.map (fun id -> Some id) ids in
- let name = { mltac_plugin = "tauto"; mltac_tactic = name0 ^ "_"; } in
- let entry = { mltac_name = name; mltac_index = 0 } in
- let () = Tacenv.register_ml_tactic name [| tac |] in
- let tac = TacFun (ids, TacML (loc, entry, [])) in
- let obj () = Tacenv.register_ltac true true (Id.of_string name0) tac in
- Mltop.declare_cache_obj obj "tauto"
-
-let () = register_tauto_tactic_ is_empty "is_empty" ["tauto_flags"; "X1"]
-let () = register_tauto_tactic_ is_unit_or_eq "is_unit_or_eq" ["tauto_flags"; "X1"]
-let () = register_tauto_tactic_ is_disj "is_disj" ["tauto_flags"; "X1"]
-let () = register_tauto_tactic_ is_conj "is_conj" ["tauto_flags"; "X1"]
-let () = register_tauto_tactic_ flatten_contravariant_disj "flatten_contravariant_disj" ["tauto_flags"; "X1"; "X2"; "id"]
-let () = register_tauto_tactic_ flatten_contravariant_conj "flatten_contravariant_conj" ["tauto_flags"; "X1"; "X2"; "id"]
-let () = register_tauto_tactic_ apply_nnpp "apply_nnpp" []
-let () = register_tauto_tactic_ reduction_not_iff "reduction_not_iff" []
diff --git a/theories/Init/Tauto.v b/theories/Init/Tauto.v
index e0949eb732..1e409607ae 100644
--- a/theories/Init/Tauto.v
+++ b/theories/Init/Tauto.v
@@ -85,14 +85,14 @@ Local Ltac tauto_classical flags :=
(apply_nnpp || fail "tauto failed"); (tauto_intuitionistic flags || fail "Classical tauto failed").
Local Ltac tauto_gen flags := tauto_intuitionistic flags || tauto_classical flags.
-Ltac tauto := with_uniform_flags (fun flags => tauto_gen flags).
-Ltac dtauto := with_power_flags (fun flags => tauto_gen flags).
+Ltac tauto := with_uniform_flags ltac:(fun flags => tauto_gen flags).
+Ltac dtauto := with_power_flags ltac:(fun flags => tauto_gen flags).
-Ltac intuition := with_uniform_flags (fun flags => intuition_gen flags ltac:(auto with *)).
-Local Ltac intuition_then tac := with_uniform_flags (fun flags => intuition_gen flags tac).
+Ltac intuition := with_uniform_flags ltac:(fun flags => intuition_gen flags ltac:(auto with *)).
+Local Ltac intuition_then tac := with_uniform_flags ltac:(fun flags => intuition_gen flags tac).
-Ltac dintuition := with_power_flags (fun flags => intuition_gen flags ltac:(auto with *)).
-Local Ltac dintuition_then tac := with_power_flags (fun flags => intuition_gen flags tac).
+Ltac dintuition := with_power_flags ltac:(fun flags => intuition_gen flags ltac:(auto with *)).
+Local Ltac dintuition_then tac := with_power_flags ltac:(fun flags => intuition_gen flags tac).
Tactic Notation "intuition" := intuition.
Tactic Notation "intuition" tactic(t) := intuition_then t.
--
cgit v1.2.3
From 60f6d46c6e623a39fc66a21cbac5aaecdf4c67c6 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Tue, 23 Feb 2016 18:50:31 +0100
Subject: Getting rid of the "<:tactic< ... >>" quotations.
It used to allow to represent parts of tactic AST directly in ML code. Most of
the uses were trivial, only calling a constant, except for tauto that had an
important code base written in this style. Removing this reduces the dependency
to CAMLPX and the preeminence of Ltac in ML code.
---
plugins/omega/g_omega.ml4 | 15 +++++++++++----
plugins/romega/g_romega.ml4 | 15 +++++++++++----
tactics/extratactics.ml4 | 5 ++++-
3 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/plugins/omega/g_omega.ml4 b/plugins/omega/g_omega.ml4
index c96b4a4f4a..04c62eb487 100644
--- a/plugins/omega/g_omega.ml4
+++ b/plugins/omega/g_omega.ml4
@@ -17,15 +17,22 @@
DECLARE PLUGIN "omega_plugin"
+open Names
open Coq_omega
+let eval_tactic name =
+ let dp = DirPath.make (List.map Id.of_string ["PreOmega"; "omega"; "Coq"]) in
+ let kn = KerName.make2 (MPfile dp) (Label.make name) in
+ let tac = Tacenv.interp_ltac kn in
+ Tacinterp.eval_tactic tac
+
let omega_tactic l =
let tacs = List.map
(function
- | "nat" -> Tacinterp.interp <:tactic>
- | "positive" -> Tacinterp.interp <:tactic>
- | "N" -> Tacinterp.interp <:tactic>
- | "Z" -> Tacinterp.interp <:tactic>
+ | "nat" -> eval_tactic "zify_nat"
+ | "positive" -> eval_tactic "zify_positive"
+ | "N" -> eval_tactic "zify_N"
+ | "Z" -> eval_tactic "zify_op"
| s -> Errors.error ("No Omega knowledge base for type "^s))
(Util.List.sort_uniquize String.compare l)
in
diff --git a/plugins/romega/g_romega.ml4 b/plugins/romega/g_romega.ml4
index 0a99a26b36..6b2b2bbfaf 100644
--- a/plugins/romega/g_romega.ml4
+++ b/plugins/romega/g_romega.ml4
@@ -10,15 +10,22 @@
DECLARE PLUGIN "romega_plugin"
+open Names
open Refl_omega
+let eval_tactic name =
+ let dp = DirPath.make (List.map Id.of_string ["PreOmega"; "omega"; "Coq"]) in
+ let kn = KerName.make2 (MPfile dp) (Label.make name) in
+ let tac = Tacenv.interp_ltac kn in
+ Tacinterp.eval_tactic tac
+
let romega_tactic l =
let tacs = List.map
(function
- | "nat" -> Tacinterp.interp <:tactic>
- | "positive" -> Tacinterp.interp <:tactic>
- | "N" -> Tacinterp.interp <:tactic>
- | "Z" -> Tacinterp.interp <:tactic>
+ | "nat" -> eval_tactic "zify_nat"
+ | "positive" -> eval_tactic "zify_positive"
+ | "N" -> eval_tactic "zify_N"
+ | "Z" -> eval_tactic "zify_op"
| s -> Errors.error ("No ROmega knowledge base for type "^s))
(Util.List.sort_uniquize String.compare l)
in
diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4
index 151949c3c6..85b9d6a08f 100644
--- a/tactics/extratactics.ml4
+++ b/tactics/extratactics.ml4
@@ -752,11 +752,14 @@ let case_eq_intros_rewrite x =
end }
let rec find_a_destructable_match t =
+ let cl = induction_arg_of_quantified_hyp (NamedHyp (Id.of_string "x")) in
+ let cl = [cl, (None, None), None], None in
+ let dest = TacAtom (Loc.ghost, TacInductionDestruct(false, false, cl)) in
match kind_of_term t with
| Case (_,_,x,_) when closed0 x ->
if isVar x then
(* TODO check there is no rel n. *)
- raise (Found (Tacinterp.eval_tactic(<:tactic>)))
+ raise (Found (Tacinterp.eval_tactic dest))
else
(* let _ = Pp.msgnl (Printer.pr_lconstr x) in *)
raise (Found (case_eq_intros_rewrite x))
--
cgit v1.2.3
From 0a024252f6346287cf4886903c800590191ddec0 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Tue, 23 Feb 2016 19:27:07 +0100
Subject: Removing the Q_coqast module.
It implemented the quotation logic of terms and tactics, although it was
mostly obsolete. With quotations gone, it is now useless and thus removed.
I fundamentally doubt that anyone hardly depends on this out there.
---
grammar/grammar.mllib | 1 -
grammar/q_coqast.ml4 | 573 --------------------------------------------------
grammar/q_util.ml4 | 3 +
grammar/q_util.mli | 2 +
grammar/tacextend.ml4 | 10 +-
5 files changed, 14 insertions(+), 575 deletions(-)
delete mode 100644 grammar/q_coqast.ml4
diff --git a/grammar/grammar.mllib b/grammar/grammar.mllib
index 6098de8f03..4432f4306e 100644
--- a/grammar/grammar.mllib
+++ b/grammar/grammar.mllib
@@ -60,7 +60,6 @@ G_ltac
G_constr
Q_util
-Q_coqast
Egramml
Argextend
Tacextend
diff --git a/grammar/q_coqast.ml4 b/grammar/q_coqast.ml4
deleted file mode 100644
index f6abe12cf2..0000000000
--- a/grammar/q_coqast.ml4
+++ /dev/null
@@ -1,573 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* 0 && s.[0] == '$'
-
-let purge_str s =
- if String.length s == 0 || s.[0] <> '$' then s
- else String.sub s 1 (String.length s - 1)
-
-let anti loc x =
- expl_anti loc <:expr< $lid:purge_str x$ >>
-
-(* We don't give location for tactic quotation! *)
-let loc = CompatLoc.ghost
-
-let dloc = <:expr< Loc.ghost >>
-
-let mlexpr_of_ident id =
- <:expr< Names.Id.of_string $str:Names.Id.to_string id$ >>
-
-let mlexpr_of_name = function
- | Names.Anonymous -> <:expr< Names.Anonymous >>
- | Names.Name id ->
- <:expr< Names.Name (Names.Id.of_string $str:Names.Id.to_string id$) >>
-
-let mlexpr_of_dirpath dir =
- let l = Names.DirPath.repr dir in
- <:expr< Names.DirPath.make $mlexpr_of_list mlexpr_of_ident l$ >>
-
-let mlexpr_of_qualid qid =
- let (dir, id) = Libnames.repr_qualid qid in
- <:expr< Libnames.make_qualid $mlexpr_of_dirpath dir$ $mlexpr_of_ident id$ >>
-
-let mlexpr_of_reference = function
- | Libnames.Qualid (loc,qid) ->
- let loc = of_coqloc loc in <:expr< Libnames.Qualid $dloc$ $mlexpr_of_qualid qid$ >>
- | Libnames.Ident (loc,id) ->
- let loc = of_coqloc loc in <:expr< Libnames.Ident $dloc$ $mlexpr_of_ident id$ >>
-
-let mlexpr_of_union f g = function
- | Util.Inl a -> <:expr< Util.Inl $f a$ >>
- | Util.Inr b -> <:expr< Util.Inr $g b$ >>
-
-let mlexpr_of_located f (loc,x) =
- let loc = of_coqloc loc in
- <:expr< ($dloc$, $f x$) >>
-
-let mlexpr_of_loc loc = <:expr< $dloc$ >>
-
-let mlexpr_of_by_notation f = function
- | Misctypes.AN x -> <:expr< Misctypes.AN $f x$ >>
- | Misctypes.ByNotation (loc,s,sco) ->
- let loc = of_coqloc loc in
- <:expr< Misctypes.ByNotation $dloc$ $str:s$ $mlexpr_of_option mlexpr_of_string sco$ >>
-
-let mlexpr_of_global_flag = function
- | Tacexpr.TacGlobal -> <:expr>
- | Tacexpr.TacLocal -> <:expr>
-
-let mlexpr_of_intro_pattern_disjunctive = function
- _ -> failwith "mlexpr_of_intro_pattern_disjunctive: TODO"
-
-let mlexpr_of_intro_pattern_naming = function
- | Misctypes.IntroAnonymous -> <:expr< Misctypes.IntroAnonymous >>
- | Misctypes.IntroFresh id -> <:expr< Misctypes.IntroFresh (mlexpr_of_ident $dloc$ id) >>
- | Misctypes.IntroIdentifier id ->
- <:expr< Misctypes.IntroIdentifier (mlexpr_of_ident $dloc$ id) >>
-
-let mlexpr_of_intro_pattern = function
- | Misctypes.IntroForthcoming b -> <:expr< Misctypes.IntroForthcoming (mlexpr_of_bool $dloc$ b) >>
- | Misctypes.IntroNaming pat ->
- <:expr< Misctypes.IntroNaming $mlexpr_of_intro_pattern_naming pat$ >>
- | Misctypes.IntroAction _ ->
- failwith "mlexpr_of_intro_pattern: TODO"
-
-let mlexpr_of_ident_option = mlexpr_of_option (mlexpr_of_ident)
-
-let mlexpr_of_quantified_hypothesis = function
- | Misctypes.AnonHyp n -> <:expr< Glob_term.AnonHyp $mlexpr_of_int n$ >>
- | Misctypes.NamedHyp id -> <:expr< Glob_term.NamedHyp $mlexpr_of_ident id$ >>
-
-let mlexpr_of_or_var f = function
- | Misctypes.ArgArg x -> <:expr< Misctypes.ArgArg $f x$ >>
- | Misctypes.ArgVar id -> <:expr< Misctypes.ArgVar $mlexpr_of_located mlexpr_of_ident id$ >>
-
-let mlexpr_of_hyp = (mlexpr_of_located mlexpr_of_ident)
-
-let mlexpr_of_occs = function
- | Locus.AllOccurrences -> <:expr< Locus.AllOccurrences >>
- | Locus.AllOccurrencesBut l ->
- <:expr< Locus.AllOccurrencesBut
- $mlexpr_of_list (mlexpr_of_or_var mlexpr_of_int) l$ >>
- | Locus.NoOccurrences -> <:expr< Locus.NoOccurrences >>
- | Locus.OnlyOccurrences l ->
- <:expr< Locus.OnlyOccurrences
- $mlexpr_of_list (mlexpr_of_or_var mlexpr_of_int) l$ >>
-
-let mlexpr_of_occurrences f = mlexpr_of_pair mlexpr_of_occs f
-
-let mlexpr_of_hyp_location = function
- | occs, Locus.InHyp ->
- <:expr< ($mlexpr_of_occurrences mlexpr_of_hyp occs$, Locus.InHyp) >>
- | occs, Locus.InHypTypeOnly ->
- <:expr< ($mlexpr_of_occurrences mlexpr_of_hyp occs$, Locus.InHypTypeOnly) >>
- | occs, Locus.InHypValueOnly ->
- <:expr< ($mlexpr_of_occurrences mlexpr_of_hyp occs$, Locus.InHypValueOnly) >>
-
-let mlexpr_of_clause cl =
- <:expr< {Locus.onhyps=
- $mlexpr_of_option (mlexpr_of_list mlexpr_of_hyp_location)
- cl.Locus.onhyps$;
- Locus.concl_occs= $mlexpr_of_occs cl.Locus.concl_occs$} >>
-
-let mlexpr_of_red_flags {
- Genredexpr.rBeta = bb;
- Genredexpr.rIota = bi;
- Genredexpr.rZeta = bz;
- Genredexpr.rDelta = bd;
- Genredexpr.rConst = l
-} = <:expr< {
- Genredexpr.rBeta = $mlexpr_of_bool bb$;
- Genredexpr.rIota = $mlexpr_of_bool bi$;
- Genredexpr.rZeta = $mlexpr_of_bool bz$;
- Genredexpr.rDelta = $mlexpr_of_bool bd$;
- Genredexpr.rConst = $mlexpr_of_list (mlexpr_of_by_notation mlexpr_of_reference) l$
-} >>
-
-let mlexpr_of_instance c = <:expr< None >>
-
-let mlexpr_of_explicitation = function
- | Constrexpr.ExplByName id -> <:expr< Constrexpr.ExplByName $mlexpr_of_ident id$ >>
- | Constrexpr.ExplByPos (n,_id) -> <:expr< Constrexpr.ExplByPos $mlexpr_of_int n$ >>
-
-let mlexpr_of_binding_kind = function
- | Decl_kinds.Implicit -> <:expr< Decl_kinds.Implicit >>
- | Decl_kinds.Explicit -> <:expr< Decl_kinds.Explicit >>
-
-let mlexpr_of_binder_kind = function
- | Constrexpr.Default b -> <:expr< Constrexpr.Default $mlexpr_of_binding_kind b$ >>
- | Constrexpr.Generalized (b,b',b'') ->
- <:expr< Constrexpr.TypeClass $mlexpr_of_binding_kind b$
- $mlexpr_of_binding_kind b'$ $mlexpr_of_bool b''$ >>
-
-let rec mlexpr_of_constr = function
- | Constrexpr.CRef (Libnames.Ident (loc,id),_) when is_meta (Id.to_string id) ->
- let loc = of_coqloc loc in
- anti loc (Id.to_string id)
- | Constrexpr.CRef (r,n) -> <:expr< Constrexpr.CRef $mlexpr_of_reference r$ None >>
- | Constrexpr.CFix (loc,_,_) -> failwith "mlexpr_of_constr: TODO"
- | Constrexpr.CCoFix (loc,_,_) -> failwith "mlexpr_of_constr: TODO"
- | Constrexpr.CProdN (loc,l,a) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CProdN $dloc$ $mlexpr_of_list
- (mlexpr_of_triple (mlexpr_of_list (mlexpr_of_pair (fun _ -> dloc) mlexpr_of_name)) mlexpr_of_binder_kind mlexpr_of_constr) l$ $mlexpr_of_constr a$ >>
- | Constrexpr.CLambdaN (loc,l,a) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CLambdaN $dloc$ $mlexpr_of_list (mlexpr_of_triple (mlexpr_of_list (mlexpr_of_pair (fun _ -> dloc) mlexpr_of_name)) mlexpr_of_binder_kind mlexpr_of_constr) l$ $mlexpr_of_constr a$ >>
- | Constrexpr.CLetIn (loc,_,_,_) -> failwith "mlexpr_of_constr: TODO"
- | Constrexpr.CAppExpl (loc,(p,r,us),l) ->
- let loc = of_coqloc loc in
- let a = (p,r,us) in
- <:expr< Constrexpr.CAppExpl $dloc$ $mlexpr_of_triple (mlexpr_of_option mlexpr_of_int) mlexpr_of_reference mlexpr_of_instance a$ $mlexpr_of_list mlexpr_of_constr l$ >>
- | Constrexpr.CApp (loc,a,l) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CApp $dloc$ $mlexpr_of_pair (mlexpr_of_option mlexpr_of_int) mlexpr_of_constr a$ $mlexpr_of_list (mlexpr_of_pair mlexpr_of_constr (mlexpr_of_option (mlexpr_of_located mlexpr_of_explicitation))) l$ >>
- | Constrexpr.CCases (loc,_,_,_,_) -> failwith "mlexpr_of_constr: TODO"
- | Constrexpr.CHole (loc, None, ipat, None) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CHole $dloc$ None $mlexpr_of_intro_pattern_naming ipat$ None >>
- | Constrexpr.CHole (loc,_,_,_) -> failwith "mlexpr_of_constr: TODO CHole (Some _)"
- | Constrexpr.CNotation(_,ntn,(subst,substl,[])) ->
- <:expr< Constrexpr.CNotation $dloc$ $mlexpr_of_string ntn$
- ($mlexpr_of_list mlexpr_of_constr subst$,
- $mlexpr_of_list (mlexpr_of_list mlexpr_of_constr) substl$,[]) >>
- | Constrexpr.CPatVar (loc,n) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CPatVar $dloc$ $mlexpr_of_ident n$ >>
- | Constrexpr.CEvar (loc,n,[]) ->
- let loc = of_coqloc loc in
- <:expr< Constrexpr.CEvar $dloc$ $mlexpr_of_ident n$ [] >>
- | _ -> failwith "mlexpr_of_constr: TODO"
-
-let mlexpr_of_occ_constr =
- mlexpr_of_occurrences mlexpr_of_constr
-
-let mlexpr_of_occ_ref_or_constr =
- mlexpr_of_occurrences
- (mlexpr_of_union
- (mlexpr_of_by_notation mlexpr_of_reference) mlexpr_of_constr)
-
-let mlexpr_of_red_expr = function
- | Genredexpr.Red b -> <:expr< Genredexpr.Red $mlexpr_of_bool b$ >>
- | Genredexpr.Hnf -> <:expr< Genredexpr.Hnf >>
- | Genredexpr.Simpl (f,o) ->
- <:expr< Genredexpr.Simpl $mlexpr_of_red_flags f$ $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >>
- | Genredexpr.Cbv f ->
- <:expr< Genredexpr.Cbv $mlexpr_of_red_flags f$ >>
- | Genredexpr.Cbn f ->
- <:expr< Genredexpr.Cbn $mlexpr_of_red_flags f$ >>
- | Genredexpr.Lazy f ->
- <:expr< Genredexpr.Lazy $mlexpr_of_red_flags f$ >>
- | Genredexpr.Unfold l ->
- let f1 = mlexpr_of_by_notation mlexpr_of_reference in
- let f = mlexpr_of_list (mlexpr_of_occurrences f1) in
- <:expr< Genredexpr.Unfold $f l$ >>
- | Genredexpr.Fold l ->
- <:expr< Genredexpr.Fold $mlexpr_of_list mlexpr_of_constr l$ >>
- | Genredexpr.Pattern l ->
- let f = mlexpr_of_list mlexpr_of_occ_constr in
- <:expr< Genredexpr.Pattern $f l$ >>
- | Genredexpr.CbvVm o -> <:expr< Genredexpr.CbvVm $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >>
- | Genredexpr.CbvNative o -> <:expr< Genredexpr.CbvNative $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >>
- | Genredexpr.ExtraRedExpr s ->
- <:expr< Genredexpr.ExtraRedExpr $mlexpr_of_string s$ >>
-
-let rec mlexpr_of_argtype loc = function
- | Genarg.ListArgType t -> <:expr< Genarg.ListArgType $mlexpr_of_argtype loc t$ >>
- | Genarg.OptArgType t -> <:expr< Genarg.OptArgType $mlexpr_of_argtype loc t$ >>
- | Genarg.PairArgType (t1,t2) ->
- let t1 = mlexpr_of_argtype loc t1 in
- let t2 = mlexpr_of_argtype loc t2 in
- <:expr< Genarg.PairArgType $t1$ $t2$ >>
- | Genarg.ExtraArgType s -> <:expr< Genarg.ExtraArgType $str:s$ >>
-
-let mlexpr_of_may_eval f = function
- | Genredexpr.ConstrEval (r,c) ->
- <:expr< Genredexpr.ConstrEval $mlexpr_of_red_expr r$ $f c$ >>
- | Genredexpr.ConstrContext ((loc,id),c) ->
- let loc = of_coqloc loc in
- let id = mlexpr_of_ident id in
- <:expr< Genredexpr.ConstrContext (loc,$id$) $f c$ >>
- | Genredexpr.ConstrTypeOf c ->
- <:expr< Genredexpr.ConstrTypeOf $mlexpr_of_constr c$ >>
- | Genredexpr.ConstrTerm c ->
- <:expr< Genredexpr.ConstrTerm $mlexpr_of_constr c$ >>
-
-let mlexpr_of_binding_kind = function
- | Misctypes.ExplicitBindings l ->
- let l = mlexpr_of_list (mlexpr_of_triple mlexpr_of_loc mlexpr_of_quantified_hypothesis mlexpr_of_constr) l in
- <:expr< Misctypes.ExplicitBindings $l$ >>
- | Misctypes.ImplicitBindings l ->
- let l = mlexpr_of_list mlexpr_of_constr l in
- <:expr< Misctypes.ImplicitBindings $l$ >>
- | Misctypes.NoBindings ->
- <:expr< Misctypes.NoBindings >>
-
-let mlexpr_of_binding = mlexpr_of_pair mlexpr_of_binding_kind mlexpr_of_constr
-
-let mlexpr_of_constr_with_binding =
- mlexpr_of_pair mlexpr_of_constr mlexpr_of_binding_kind
-
-let mlexpr_of_constr_with_binding_arg =
- mlexpr_of_pair (mlexpr_of_option mlexpr_of_bool) mlexpr_of_constr_with_binding
-
-let mlexpr_of_move_location f = function
- | Misctypes.MoveAfter id -> <:expr< Misctypes.MoveAfter $f id$ >>
- | Misctypes.MoveBefore id -> <:expr< Misctypes.MoveBefore $f id$ >>
- | Misctypes.MoveFirst -> <:expr< Misctypes.MoveFirst >>
- | Misctypes.MoveLast -> <:expr< Misctypes.MoveLast >>
-
-let mlexpr_of_induction_arg = function
- | Tacexpr.ElimOnConstr c ->
- <:expr< Tacexpr.ElimOnConstr $mlexpr_of_constr_with_binding c$ >>
- | Tacexpr.ElimOnIdent (_,id) ->
- <:expr< Tacexpr.ElimOnIdent $dloc$ $mlexpr_of_ident id$ >>
- | Tacexpr.ElimOnAnonHyp n ->
- <:expr< Tacexpr.ElimOnAnonHyp $mlexpr_of_int n$ >>
-
-let mlexpr_of_clause_pattern _ = failwith "mlexpr_of_clause_pattern: TODO"
-
-let mlexpr_of_pattern_ast = mlexpr_of_constr
-
-let mlexpr_of_entry_type = function
- _ -> failwith "mlexpr_of_entry_type: TODO"
-
-let mlexpr_of_match_lazy_flag = function
- | Tacexpr.General -> <:expr>
- | Tacexpr.Select -> <:expr>
- | Tacexpr.Once -> <:expr>
-
-let mlexpr_of_match_pattern = function
- | Tacexpr.Term t -> <:expr< Tacexpr.Term $mlexpr_of_pattern_ast t$ >>
- | Tacexpr.Subterm (b,ido,t) ->
- <:expr< Tacexpr.Subterm $mlexpr_of_bool b$ $mlexpr_of_option mlexpr_of_ident ido$ $mlexpr_of_pattern_ast t$ >>
-
-let mlexpr_of_match_context_hyps = function
- | Tacexpr.Hyp (id,l) ->
- let f = mlexpr_of_located mlexpr_of_name in
- <:expr< Tacexpr.Hyp $f id$ $mlexpr_of_match_pattern l$ >>
- | Tacexpr.Def (id,v,l) ->
- let f = mlexpr_of_located mlexpr_of_name in
- <:expr< Tacexpr.Def $f id$ $mlexpr_of_match_pattern v$ $mlexpr_of_match_pattern l$ >>
-
-let mlexpr_of_match_rule f = function
- | Tacexpr.Pat (l,mp,t) -> <:expr< Tacexpr.Pat $mlexpr_of_list mlexpr_of_match_context_hyps l$ $mlexpr_of_match_pattern mp$ $f t$ >>
- | Tacexpr.All t -> <:expr< Tacexpr.All $f t$ >>
-
-let mlexpr_of_message_token = function
- | Tacexpr.MsgString s -> <:expr< Tacexpr.MsgString $str:s$ >>
- | Tacexpr.MsgInt n -> <:expr< Tacexpr.MsgInt $mlexpr_of_int n$ >>
- | Tacexpr.MsgIdent id -> <:expr< Tacexpr.MsgIdent $mlexpr_of_hyp id$ >>
-
-let mlexpr_of_debug = function
- | Tacexpr.Off -> <:expr< Tacexpr.Off >>
- | Tacexpr.Debug -> <:expr< Tacexpr.Debug >>
- | Tacexpr.Info -> <:expr< Tacexpr.Info >>
-
-let rec mlexpr_of_atomic_tactic = function
- (* Basic tactics *)
- | Tacexpr.TacIntroPattern pl ->
- let pl = mlexpr_of_list (mlexpr_of_located mlexpr_of_intro_pattern) pl in
- <:expr< Tacexpr.TacIntroPattern $pl$ >>
- | Tacexpr.TacIntroMove (idopt,idopt') ->
- let idopt = mlexpr_of_ident_option idopt in
- let idopt'= mlexpr_of_move_location mlexpr_of_hyp idopt' in
- <:expr< Tacexpr.TacIntroMove $idopt$ $idopt'$ >>
- | Tacexpr.TacExact c ->
- <:expr< Tacexpr.TacExact $mlexpr_of_constr c$ >>
- | Tacexpr.TacApply (b,false,cb,None) ->
- <:expr< Tacexpr.TacApply $mlexpr_of_bool b$ False $mlexpr_of_list mlexpr_of_constr_with_binding_arg cb$ None >>
- | Tacexpr.TacElim (false,cb,cbo) ->
- let cb = mlexpr_of_constr_with_binding_arg cb in
- let cbo = mlexpr_of_option mlexpr_of_constr_with_binding cbo in
- <:expr< Tacexpr.TacElim False $cb$ $cbo$ >>
- | Tacexpr.TacCase (false,cb) ->
- let cb = mlexpr_of_constr_with_binding_arg cb in
- <:expr< Tacexpr.TacCase False $cb$ >>
- | Tacexpr.TacFix (ido,n) ->
- let ido = mlexpr_of_ident_option ido in
- let n = mlexpr_of_int n in
- <:expr< Tacexpr.TacFix $ido$ $n$ >>
- | Tacexpr.TacMutualFix (id,n,l) ->
- let id = mlexpr_of_ident id in
- let n = mlexpr_of_int n in
- let f =mlexpr_of_triple mlexpr_of_ident mlexpr_of_int mlexpr_of_constr in
- let l = mlexpr_of_list f l in
- <:expr< Tacexpr.TacMutualFix $id$ $n$ $l$ >>
- | Tacexpr.TacCofix ido ->
- let ido = mlexpr_of_ident_option ido in
- <:expr< Tacexpr.TacCofix $ido$ >>
- | Tacexpr.TacMutualCofix (id,l) ->
- let id = mlexpr_of_ident id in
- let f = mlexpr_of_pair mlexpr_of_ident mlexpr_of_constr in
- let l = mlexpr_of_list f l in
- <:expr< Tacexpr.TacMutualCofix $id$ $l$ >>
-
- | Tacexpr.TacAssert (b,t,ipat,c) ->
- let ipat = mlexpr_of_option (mlexpr_of_located mlexpr_of_intro_pattern) ipat in
- <:expr< Tacexpr.TacAssert $mlexpr_of_bool b$
- $mlexpr_of_option mlexpr_of_tactic t$ $ipat$
- $mlexpr_of_constr c$ >>
- | Tacexpr.TacGeneralize cl ->
- <:expr< Tacexpr.TacGeneralize
- $mlexpr_of_list
- (mlexpr_of_pair mlexpr_of_occ_constr mlexpr_of_name) cl$ >>
- | Tacexpr.TacGeneralizeDep c ->
- <:expr< Tacexpr.TacGeneralizeDep $mlexpr_of_constr c$ >>
- | Tacexpr.TacLetTac (na,c,cl,b,e) ->
- let na = mlexpr_of_name na in
- let cl = mlexpr_of_clause_pattern cl in
- <:expr< Tacexpr.TacLetTac $na$ $mlexpr_of_constr c$ $cl$
- $mlexpr_of_bool b$
- (mlexpr_of_option (mlexpr_of_located mlexpr_of_intro_pattern) e)
- >>
-
- (* Derived basic tactics *)
- | Tacexpr.TacInductionDestruct (isrec,ev,l) ->
- <:expr< Tacexpr.TacInductionDestruct $mlexpr_of_bool isrec$ $mlexpr_of_bool ev$
- $mlexpr_of_pair
- (mlexpr_of_list
- (mlexpr_of_triple
- (mlexpr_of_pair
- (mlexpr_of_option mlexpr_of_bool)
- mlexpr_of_induction_arg)
- (mlexpr_of_pair
- (mlexpr_of_option (mlexpr_of_located mlexpr_of_intro_pattern_naming))
- (mlexpr_of_option (mlexpr_of_intro_pattern_disjunctive)))
- (mlexpr_of_option mlexpr_of_clause)))
- (mlexpr_of_option mlexpr_of_constr_with_binding)
- l$ >>
-
- (* Context management *)
- | Tacexpr.TacClear (b,l) ->
- let l = mlexpr_of_list (mlexpr_of_hyp) l in
- <:expr< Tacexpr.TacClear $mlexpr_of_bool b$ $l$ >>
- | Tacexpr.TacClearBody l ->
- let l = mlexpr_of_list (mlexpr_of_hyp) l in
- <:expr< Tacexpr.TacClearBody $l$ >>
- | Tacexpr.TacMove (id1,id2) ->
- <:expr< Tacexpr.TacMove
- $mlexpr_of_hyp id1$
- $mlexpr_of_move_location mlexpr_of_hyp id2$ >>
-
- (* Constructors *)
- | Tacexpr.TacSplit (ev,l) ->
- <:expr< Tacexpr.TacSplit
- ($mlexpr_of_bool ev$, $mlexpr_of_list mlexpr_of_binding_kind l$)>>
- (* Conversion *)
- | Tacexpr.TacReduce (r,cl) ->
- let l = mlexpr_of_clause cl in
- <:expr< Tacexpr.TacReduce $mlexpr_of_red_expr r$ $l$ >>
- | Tacexpr.TacChange (p,c,cl) ->
- let l = mlexpr_of_clause cl in
- let g = mlexpr_of_option mlexpr_of_constr in
- <:expr< Tacexpr.TacChange $g p$ $mlexpr_of_constr c$ $l$ >>
-
- (* Equivalence relations *)
- | Tacexpr.TacSymmetry ido -> <:expr< Tacexpr.TacSymmetry $mlexpr_of_clause ido$ >>
-
- | _ -> failwith "Quotation of atomic tactic expressions: TODO"
-
-and mlexpr_of_tactic : (Tacexpr.raw_tactic_expr -> MLast.expr) = function
- | Tacexpr.TacAtom (loc,t) ->
- let loc = of_coqloc loc in
- <:expr< Tacexpr.TacAtom $dloc$ $mlexpr_of_atomic_tactic t$ >>
- | Tacexpr.TacThen (t1,t2) ->
- <:expr< Tacexpr.TacThen $mlexpr_of_tactic t1$ $mlexpr_of_tactic t2$>>
- | Tacexpr.TacThens (t,tl) ->
- <:expr< Tacexpr.TacThens $mlexpr_of_tactic t$ $mlexpr_of_list mlexpr_of_tactic tl$>>
- | Tacexpr.TacFirst tl ->
- <:expr< Tacexpr.TacFirst $mlexpr_of_list mlexpr_of_tactic tl$ >>
- | Tacexpr.TacSolve tl ->
- <:expr< Tacexpr.TacSolve $mlexpr_of_list mlexpr_of_tactic tl$ >>
- | Tacexpr.TacTry t ->
- <:expr< Tacexpr.TacTry $mlexpr_of_tactic t$ >>
- | Tacexpr.TacOr (t1,t2) ->
- <:expr< Tacexpr.TacOr $mlexpr_of_tactic t1$ $mlexpr_of_tactic t2$ >>
- | Tacexpr.TacOrelse (t1,t2) ->
- <:expr< Tacexpr.TacOrelse $mlexpr_of_tactic t1$ $mlexpr_of_tactic t2$ >>
- | Tacexpr.TacDo (n,t) ->
- <:expr< Tacexpr.TacDo $mlexpr_of_or_var mlexpr_of_int n$ $mlexpr_of_tactic t$ >>
- | Tacexpr.TacTimeout (n,t) ->
- <:expr< Tacexpr.TacTimeout $mlexpr_of_or_var mlexpr_of_int n$ $mlexpr_of_tactic t$ >>
- | Tacexpr.TacRepeat t ->
- <:expr< Tacexpr.TacRepeat $mlexpr_of_tactic t$ >>
- | Tacexpr.TacProgress t ->
- <:expr< Tacexpr.TacProgress $mlexpr_of_tactic t$ >>
- | Tacexpr.TacShowHyps t ->
- <:expr< Tacexpr.TacShowHyps $mlexpr_of_tactic t$ >>
- | Tacexpr.TacId l ->
- <:expr< Tacexpr.TacId $mlexpr_of_list mlexpr_of_message_token l$ >>
- | Tacexpr.TacFail (g,n,l) ->
- <:expr< Tacexpr.TacFail $mlexpr_of_global_flag g$ $mlexpr_of_or_var mlexpr_of_int n$ $mlexpr_of_list mlexpr_of_message_token l$ >>
-(*
- | Tacexpr.TacInfo t -> TacInfo (loc,f t)
-
- | Tacexpr.TacRec (id,(idl,t)) -> TacRec (loc,(id,(idl,f t)))
- | Tacexpr.TacRecIn (l,t) -> TacRecIn(loc,List.map (fun (id,t) -> (id,f t)) l,f t)
-*)
- | Tacexpr.TacLetIn (isrec,l,t) ->
- let f =
- mlexpr_of_pair
- (mlexpr_of_pair (fun _ -> dloc) mlexpr_of_ident)
- mlexpr_of_tactic_arg in
- <:expr< Tacexpr.TacLetIn $mlexpr_of_bool isrec$ $mlexpr_of_list f l$ $mlexpr_of_tactic t$ >>
- | Tacexpr.TacMatch (lz,t,l) ->
- <:expr< Tacexpr.TacMatch
- $mlexpr_of_match_lazy_flag lz$
- $mlexpr_of_tactic t$
- $mlexpr_of_list (mlexpr_of_match_rule mlexpr_of_tactic) l$>>
- | Tacexpr.TacMatchGoal (lz,lr,l) ->
- <:expr< Tacexpr.TacMatchGoal
- $mlexpr_of_match_lazy_flag lz$
- $mlexpr_of_bool lr$
- $mlexpr_of_list (mlexpr_of_match_rule mlexpr_of_tactic) l$>>
-
- | Tacexpr.TacFun (idol,body) ->
- <:expr< Tacexpr.TacFun
- ($mlexpr_of_list mlexpr_of_ident_option idol$,
- $mlexpr_of_tactic body$) >>
- | Tacexpr.TacArg (_,Tacexpr.MetaIdArg (_,true,id)) -> anti loc id
- | Tacexpr.TacArg (_,t) ->
- <:expr< Tacexpr.TacArg $dloc$ $mlexpr_of_tactic_arg t$ >>
- | Tacexpr.TacComplete t ->
- <:expr< Tacexpr.TacComplete $mlexpr_of_tactic t$ >>
- | _ -> failwith "Quotation of tactic expressions: TODO"
-
-and mlexpr_of_tactic_arg = function
- | Tacexpr.MetaIdArg (loc,true,id) ->
- let loc = of_coqloc loc in
- anti loc id
- | Tacexpr.MetaIdArg (loc,false,id) ->
- let loc = of_coqloc loc in
- <:expr< Tacexpr.ConstrMayEval (Genredexpr.ConstrTerm $anti loc id$) >>
- | Tacexpr.TacCall (loc,t,tl) ->
- let loc = of_coqloc loc in
- <:expr< Tacexpr.TacCall $dloc$ $mlexpr_of_reference t$ $mlexpr_of_list mlexpr_of_tactic_arg tl$>>
- | Tacexpr.Tacexp t ->
- <:expr< Tacexpr.Tacexp $mlexpr_of_tactic t$ >>
- | Tacexpr.ConstrMayEval c ->
- <:expr< Tacexpr.ConstrMayEval $mlexpr_of_may_eval mlexpr_of_constr c$ >>
- | Tacexpr.Reference r ->
- <:expr< Tacexpr.Reference $mlexpr_of_reference r$ >>
- | _ -> failwith "mlexpr_of_tactic_arg: TODO"
-
-
-IFDEF CAMLP5 THEN
-
-let not_impl x =
- let desc =
- if Obj.is_block (Obj.repr x) then
- "tag = " ^ string_of_int (Obj.tag (Obj.repr x))
- else "int_val = " ^ string_of_int (Obj.magic x)
- in
- failwith (" PaAcc (loc, patt_of_expr e1, patt_of_expr e2)
- | ExApp (_, e1, e2) -> PaApp (loc, patt_of_expr e1, patt_of_expr e2)
- | ExLid (_, x) when x = vala "loc" -> PaAny loc
- | ExLid (_, s) -> PaLid (loc, s)
- | ExUid (_, s) -> PaUid (loc, s)
- | ExStr (_, s) -> PaStr (loc, s)
- | ExAnt (_, e) -> PaAnt (loc, patt_of_expr e)
- | _ -> not_impl e
-
-let fconstr e =
- let ee s =
- mlexpr_of_constr (Pcoq.Gram.entry_parse e
- (Pcoq.Gram.parsable (Stream.of_string s)))
- in
- let ep s = patt_of_expr (ee s) in
- Quotation.ExAst (ee, ep)
-
-let ftac e =
- let ee s =
- mlexpr_of_tactic (Pcoq.Gram.entry_parse e
- (Pcoq.Gram.parsable (Stream.of_string s)))
- in
- let ep s = patt_of_expr (ee s) in
- Quotation.ExAst (ee, ep)
-
-let _ =
- Quotation.add "constr" (fconstr Pcoq.Constr.constr_eoi);
- Quotation.add "tactic" (ftac Pcoq.Tactic.tactic_eoi);
- Quotation.default := "constr"
-
-ELSE
-
-open Pcaml
-
-let expand_constr_quot_expr loc _loc_name_opt contents =
- mlexpr_of_constr
- (Pcoq.Gram.parse_string Pcoq.Constr.constr_eoi loc contents)
-
-let expand_tactic_quot_expr loc _loc_name_opt contents =
- mlexpr_of_tactic
- (Pcoq.Gram.parse_string Pcoq.Tactic.tactic_eoi loc contents)
-
-let _ =
- (* FIXME: for the moment, we add quotations in expressions only, not pattern *)
- Quotation.add "constr" Quotation.DynAst.expr_tag expand_constr_quot_expr;
- Quotation.add "tactic" Quotation.DynAst.expr_tag expand_tactic_quot_expr;
- Quotation.default := "constr"
-
-END
diff --git a/grammar/q_util.ml4 b/grammar/q_util.ml4
index 4b0be1b1cb..d668e3d398 100644
--- a/grammar/q_util.ml4
+++ b/grammar/q_util.ml4
@@ -54,6 +54,9 @@ let mlexpr_of_option f = function
| None -> <:expr< None >>
| Some e -> <:expr< Some $f e$ >>
+let mlexpr_of_ident id =
+ <:expr< Names.Id.of_string $str:Names.Id.to_string id$ >>
+
let mlexpr_of_token = function
| Tok.KEYWORD s -> <:expr< Tok.KEYWORD $mlexpr_of_string s$ >>
| Tok.METAIDENT s -> <:expr< Tok.METAIDENT $mlexpr_of_string s$ >>
diff --git a/grammar/q_util.mli b/grammar/q_util.mli
index 50827ead25..d0e0dab22e 100644
--- a/grammar/q_util.mli
+++ b/grammar/q_util.mli
@@ -34,6 +34,8 @@ val mlexpr_of_string : string -> MLast.expr
val mlexpr_of_option : ('a -> MLast.expr) -> 'a option -> MLast.expr
+val mlexpr_of_ident : Names.Id.t -> MLast.expr
+
val mlexpr_of_prod_entry_key : Extend.user_symbol -> MLast.expr
val type_of_user_symbol : Extend.user_symbol -> Genarg.argument_type
diff --git a/grammar/tacextend.ml4 b/grammar/tacextend.ml4
index ef7cdbfa3a..10afcdd21a 100644
--- a/grammar/tacextend.ml4
+++ b/grammar/tacextend.ml4
@@ -15,7 +15,6 @@ open Pp
open Names
open Genarg
open Q_util
-open Q_coqast
open Argextend
open Pcoq
open Egramml
@@ -32,6 +31,15 @@ let rec make_patt = function
<:patt< [ $lid:p$ :: $make_patt l$ ] >>
| _::l -> make_patt l
+let rec mlexpr_of_argtype loc = function
+ | Genarg.ListArgType t -> <:expr< Genarg.ListArgType $mlexpr_of_argtype loc t$ >>
+ | Genarg.OptArgType t -> <:expr< Genarg.OptArgType $mlexpr_of_argtype loc t$ >>
+ | Genarg.PairArgType (t1,t2) ->
+ let t1 = mlexpr_of_argtype loc t1 in
+ let t2 = mlexpr_of_argtype loc t2 in
+ <:expr< Genarg.PairArgType $t1$ $t2$ >>
+ | Genarg.ExtraArgType s -> <:expr< Genarg.ExtraArgType $str:s$ >>
+
let rec make_when loc = function
| [] -> <:expr< True >>
| ExtNonTerminal (t, _, p) :: l ->
--
cgit v1.2.3
From ee162ba3b28fccca0a2b3ea4b1e0811006840570 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 24 Feb 2016 10:07:57 +0100
Subject: Removing the MetaIdArg entry of tactic expressions.
This was historically used together with the <:tactic< ... >> quotation to insert
foreign code as $foo, but it actually only survived in the implementation of Tauto.
With the removal of the quotation feature, this is now totally obsolete.
---
intf/tacexpr.mli | 1 -
parsing/g_ltac.ml4 | 4 +---
printing/pptactic.ml | 4 ----
tactics/tacintern.ml | 13 -------------
tactics/tacinterp.ml | 1 -
tactics/tacsubst.ml | 1 -
6 files changed, 1 insertion(+), 23 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 57c61874a5..502f2db4c1 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -206,7 +206,6 @@ constraint 'a = <
and 'a gen_tactic_arg =
| TacGeneric of 'lev generic_argument
- | MetaIdArg of Loc.t * bool * string
| ConstrMayEval of ('trm,'cst,'pat) may_eval
| UConstr of 'utrm
| Reference of 'ref
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 12d53030d7..0a11d3928a 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -146,7 +146,6 @@ GEXTEND Gram
| r = reference -> Reference r
| c = Constr.constr -> ConstrMayEval (ConstrTerm c)
(* Unambigous entries: tolerated w/o "ltac:" modifier *)
- | id = METAIDENT -> MetaIdArg (!@loc,true,id)
| "()" -> TacGeneric (genarg_of_unit ()) ] ]
;
(* Can be used as argument and at toplevel in tactic expressions. *)
@@ -179,8 +178,7 @@ GEXTEND Gram
| c = Constr.constr -> ConstrTerm c ] ]
;
tactic_atom:
- [ [ id = METAIDENT -> MetaIdArg (!@loc,true,id)
- | n = integer -> TacGeneric (genarg_of_int n)
+ [ [ n = integer -> TacGeneric (genarg_of_int n)
| r = reference -> TacCall (!@loc,r,[])
| "()" -> TacGeneric (genarg_of_unit ()) ] ]
;
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index ed85b21478..12667d0f24 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -1189,10 +1189,6 @@ module Make
else str"(" ++ strm ++ str")"
and pr_tacarg = function
- | MetaIdArg (loc,true,s) ->
- pr_with_comments loc (str "$" ++ str s)
- | MetaIdArg (loc,false,s) ->
- pr_with_comments loc (keyword "constr:" ++ str " $" ++ str s)
| Reference r ->
pr.pr_reference r
| ConstrMayEval c ->
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index 4ef1beb034..cbb9db65c1 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -35,11 +35,6 @@ let dloc = Loc.ghost
let error_global_not_found_loc (loc,qid) =
error_global_not_found_loc loc qid
-let error_syntactic_metavariables_not_allowed loc =
- user_err_loc
- (loc,"out_ident",
- str "Syntactic metavariables allowed only in quotations.")
-
let error_tactic_expected loc =
user_err_loc (loc,"",str "Tactic expected.")
@@ -672,7 +667,6 @@ and intern_tactic_as_arg loc onlytac ist a =
| Tacexp a -> a
| ConstrMayEval _ | UConstr _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
if onlytac then error_tactic_expected loc else TacArg (loc,a)
- | MetaIdArg _ -> assert false
and intern_tactic_or_tacarg ist = intern_tactic false ist
@@ -686,13 +680,6 @@ and intern_tacarg strict onlytac ist = function
| Reference r -> intern_non_tactic_reference strict ist r
| ConstrMayEval c -> ConstrMayEval (intern_constr_may_eval ist c)
| UConstr c -> UConstr (intern_constr ist c)
- | MetaIdArg (loc,istac,s) ->
- (* $id can occur in Grammar tactic... *)
- let id = Id.of_string s in
- if find_var id ist then
- if istac then Reference (ArgVar (adjust_loc loc,id))
- else ConstrMayEval (ConstrTerm (GVar (adjust_loc loc,id), None))
- else error_syntactic_metavariables_not_allowed loc
| TacCall (loc,f,[]) -> intern_isolated_tactic_reference strict ist f
| TacCall (loc,f,l) ->
TacCall (loc,
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index cb4a9f320d..43c9ee9be4 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1371,7 +1371,6 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
let env = Proofview.Goal.env gl in
Ftactic.return (Value.of_uconstr (interp_uconstr ist env c))
end }
- | MetaIdArg (loc,_,id) -> assert false
| TacCall (loc,r,[]) ->
interp_ltac_reference loc true ist r
| TacCall (loc,f,l) ->
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index dd851b5c0d..4a5fa9828e 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -260,7 +260,6 @@ and subst_tacarg subst = function
| Reference r -> Reference (subst_reference subst r)
| ConstrMayEval c -> ConstrMayEval (subst_raw_may_eval subst c)
| UConstr c -> UConstr (subst_glob_constr subst c)
- | MetaIdArg (_loc,_,_) -> assert false
| TacCall (_loc,f,l) ->
TacCall (_loc, subst_reference subst f, List.map (subst_tacarg subst) l)
| TacFreshId _ as x -> x
--
cgit v1.2.3
From d96bf1b1ec79fa93787d23e1c42f803d74b49321 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Wed, 24 Feb 2016 10:26:56 +0100
Subject: Removing the METAIDENT token, as it is not used anymore.
METAIDENT were idents of the form $foobar, only used in quotations.
Note that it removes two dollars in the Coq codebase! Guess I'm absolved
for the $(...) syntax.
---
grammar/q_util.ml4 | 1 -
parsing/compat.ml4 | 1 -
parsing/g_constr.ml4 | 5 +----
parsing/lexer.ml4 | 3 ---
parsing/tok.ml | 7 -------
parsing/tok.mli | 1 -
6 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/grammar/q_util.ml4 b/grammar/q_util.ml4
index d668e3d398..c6e2e99668 100644
--- a/grammar/q_util.ml4
+++ b/grammar/q_util.ml4
@@ -59,7 +59,6 @@ let mlexpr_of_ident id =
let mlexpr_of_token = function
| Tok.KEYWORD s -> <:expr< Tok.KEYWORD $mlexpr_of_string s$ >>
-| Tok.METAIDENT s -> <:expr< Tok.METAIDENT $mlexpr_of_string s$ >>
| Tok.PATTERNIDENT s -> <:expr< Tok.PATTERNIDENT $mlexpr_of_string s$ >>
| Tok.IDENT s -> <:expr< Tok.IDENT $mlexpr_of_string s$ >>
| Tok.FIELD s -> <:expr< Tok.FIELD $mlexpr_of_string s$ >>
diff --git a/parsing/compat.ml4 b/parsing/compat.ml4
index 3405d2429b..0e416fe32c 100644
--- a/parsing/compat.ml4
+++ b/parsing/compat.ml4
@@ -262,7 +262,6 @@ IFDEF CAMLP5 THEN
let pattern = match tok with
| Tok.KEYWORD s -> "", s
| Tok.IDENT s -> "IDENT", s
- | Tok.METAIDENT s -> "METAIDENT", s
| Tok.PATTERNIDENT s -> "PATTERNIDENT", s
| Tok.FIELD s -> "FIELD", s
| Tok.INT s -> "INT", s
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 1ac260ebeb..0fe0ac42b1 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -132,10 +132,7 @@ GEXTEND Gram
closed_binder open_binders binder binders binders_fixannot
record_declaration typeclass_constraint pattern appl_arg;
Constr.ident:
- [ [ id = Prim.ident -> id
-
- (* This is used in quotations and Syntax *)
- | id = METAIDENT -> Id.of_string id ] ]
+ [ [ id = Prim.ident -> id ] ]
;
Prim.name:
[ [ "_" -> (!@loc, Anonymous) ] ]
diff --git a/parsing/lexer.ml4 b/parsing/lexer.ml4
index 74e05ce84d..232e9aee3f 100644
--- a/parsing/lexer.ml4
+++ b/parsing/lexer.ml4
@@ -493,7 +493,6 @@ let process_chars bp c cs =
err (bp, ep') Undefined_token
let token_of_special c s = match c with
- | '$' -> METAIDENT s
| '.' -> FIELD s
| _ -> assert false
@@ -532,8 +531,6 @@ let blank_or_eof cs =
let rec next_token = parser bp
| [< '' ' | '\t' | '\n' |'\r' as c; s >] ->
comm_loc bp; push_char c; next_token s
- | [< ''$' as c; t = parse_after_special c bp >] ep ->
- comment_stop bp; (t, (ep, bp))
| [< ''.' as c; t = parse_after_special c bp; s >] ep ->
comment_stop bp;
(* We enforce that "." should either be part of a larger keyword,
diff --git a/parsing/tok.ml b/parsing/tok.ml
index 4f50c48d0d..6b90086155 100644
--- a/parsing/tok.ml
+++ b/parsing/tok.ml
@@ -10,7 +10,6 @@
type t =
| KEYWORD of string
- | METAIDENT of string
| PATTERNIDENT of string
| IDENT of string
| FIELD of string
@@ -24,7 +23,6 @@ type t =
let equal t1 t2 = match t1, t2 with
| IDENT s1, KEYWORD s2 -> CString.equal s1 s2
| KEYWORD s1, KEYWORD s2 -> CString.equal s1 s2
-| METAIDENT s1, METAIDENT s2 -> CString.equal s1 s2
| PATTERNIDENT s1, PATTERNIDENT s2 -> CString.equal s1 s2
| IDENT s1, IDENT s2 -> CString.equal s1 s2
| FIELD s1, FIELD s2 -> CString.equal s1 s2
@@ -40,7 +38,6 @@ let extract_string = function
| KEYWORD s -> s
| IDENT s -> s
| STRING s -> s
- | METAIDENT s -> s
| PATTERNIDENT s -> s
| FIELD s -> s
| INT s -> s
@@ -52,7 +49,6 @@ let extract_string = function
let to_string = function
| KEYWORD s -> Format.sprintf "%S" s
| IDENT s -> Format.sprintf "IDENT %S" s
- | METAIDENT s -> Format.sprintf "METAIDENT %S" s
| PATTERNIDENT s -> Format.sprintf "PATTERNIDENT %S" s
| FIELD s -> Format.sprintf "FIELD %S" s
| INT s -> Format.sprintf "INT %s" s
@@ -76,7 +72,6 @@ let print ppf tok = Format.pp_print_string ppf (to_string tok)
let of_pattern = function
| "", s -> KEYWORD s
| "IDENT", s -> IDENT s
- | "METAIDENT", s -> METAIDENT s
| "PATTERNIDENT", s -> PATTERNIDENT s
| "FIELD", s -> FIELD s
| "INT", s -> INT s
@@ -90,7 +85,6 @@ let of_pattern = function
let to_pattern = function
| KEYWORD s -> "", s
| IDENT s -> "IDENT", s
- | METAIDENT s -> "METAIDENT", s
| PATTERNIDENT s -> "PATTERNIDENT", s
| FIELD s -> "FIELD", s
| INT s -> "INT", s
@@ -105,7 +99,6 @@ let match_pattern =
function
| "", "" -> (function KEYWORD s -> s | _ -> err ())
| "IDENT", "" -> (function IDENT s -> s | _ -> err ())
- | "METAIDENT", "" -> (function METAIDENT s -> s | _ -> err ())
| "PATTERNIDENT", "" -> (function PATTERNIDENT s -> s | _ -> err ())
| "FIELD", "" -> (function FIELD s -> s | _ -> err ())
| "INT", "" -> (function INT s -> s | _ -> err ())
diff --git a/parsing/tok.mli b/parsing/tok.mli
index f37de05a44..416ce468e3 100644
--- a/parsing/tok.mli
+++ b/parsing/tok.mli
@@ -10,7 +10,6 @@
type t =
| KEYWORD of string
- | METAIDENT of string
| PATTERNIDENT of string
| IDENT of string
| FIELD of string
--
cgit v1.2.3
From 20fe4afb53e2b68ffb06a5504a444e536d4b813e Mon Sep 17 00:00:00 2001
From: Matthieu Sozeau
Date: Wed, 24 Feb 2016 16:06:40 +0100
Subject: Document Hint Mode, cleanup Hint doc.
---
doc/refman/RefMan-tac.tex | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex
index 9a365b8297..903e2e19af 100644
--- a/doc/refman/RefMan-tac.tex
+++ b/doc/refman/RefMan-tac.tex
@@ -3669,9 +3669,6 @@ The {\hintdef} is one of the following expressions:
the number of subgoals generated by {\tt simple apply {\term}}.
%{\tt auto} actually uses a slightly modified variant of {\tt simple apply} with use_metas_eagerly_in_conv_on_closed_terms set to false
- The cost of that hint is the number of subgoals generated by that
- tactic.
-
% Is it really needed?
%% In case the inferred type of \term\ does not start with a product
%% the tactic added in the hint list is {\tt exact {\term}}. In case
@@ -3869,7 +3866,25 @@ is to set the cut expression to $c | e$, the initial cut expression
being \texttt{emp}.
+\item \texttt{Mode} {\tt (+ | -)}$^*$ {\qualid}
+\label{HintMode}
+\comindex{Hint Mode}
+
+This sets an optional mode of use of the identifier {\qualid}. When
+proof-search faces a goal that ends in an application of {\qualid} to
+arguments {\tt \term$_1$ \mbox{\dots} \term$_n$}, the mode tells if the
+hints associated to qualid can be applied or not. A mode specification
+is a list of $n$ {\tt +} or {\tt -} items that specify if an argument is
+to be treated as an input {\tt +} or an output {\tt -} of the
+identifier. For a mode to match a list of arguments, input terms \emph{must
+not} contain existential variables, while outputs can be any term.
+Multiple modes can be declared for a single identifier, in that case
+only one mode needs to match the arguments for the hints to be applied.
+{\tt Hint Mode} is especially useful for typeclasses, when one does not
+want to support default instances and avoid ambiguity in
+general. Setting a parameter of a class as an input forces proof-search
+to be driven by that index of the class.
\end{itemize}
@@ -3877,25 +3892,6 @@ being \texttt{emp}.
pattern-matching on hypotheses using \texttt{match goal with} inside
the tactic.
-\begin{Variants}
-\item {\tt Hint \hintdef}
-
- No database name is given: the hint is registered in the {\tt core}
- database.
-
-\item {\tt Hint Local {\hintdef} : \ident$_1$ \mbox{\dots} \ident$_n$}
-
- This is used to declare hints that must not be exported to the other
- modules that require and import the current module. Inside a
- section, the option {\tt Local} is useless since hints do not
- survive anyway to the closure of sections.
-
-\item {\tt Hint Local \hintdef}
-
- Idem for the {\tt core} database.
-
-\end{Variants}
-
% There are shortcuts that allow to define several goal at once:
% \begin{itemize}
--
cgit v1.2.3
From ea05377f19404e0627a105b07c10ce72fb010af9 Mon Sep 17 00:00:00 2001
From: Pierre Letouzey
Date: Fri, 26 Feb 2016 16:12:33 +0100
Subject: Qcanon : implement some old suggestions by C. Auger
---
theories/Numbers/Rational/BigQ/QMake.v | 37 +++++-----
theories/QArith/Qcanon.v | 120 ++++++++++++++++++---------------
2 files changed, 83 insertions(+), 74 deletions(-)
diff --git a/theories/Numbers/Rational/BigQ/QMake.v b/theories/Numbers/Rational/BigQ/QMake.v
index 4ac36425b4..b9fed9d566 100644
--- a/theories/Numbers/Rational/BigQ/QMake.v
+++ b/theories/Numbers/Rational/BigQ/QMake.v
@@ -1050,13 +1050,13 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
Theorem spec_of_Qc: forall q, [[of_Qc q]] = q.
Proof.
intros; apply Qc_decomp; simpl; intros.
- rewrite strong_spec_of_Qc; auto.
+ rewrite strong_spec_of_Qc. apply canon.
Qed.
Theorem spec_oppc: forall q, [[opp q]] = -[[q]].
Proof.
intros q; unfold Qcopp, to_Qc, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
rewrite spec_opp, <- Qred_opp, Qred_correct.
apply Qeq_refl.
@@ -1085,10 +1085,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x] + [y])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_add; auto.
unfold Qcplus, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qplus_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1099,10 +1099,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x] + [y])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_add_norm; auto.
unfold Qcplus, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qplus_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1147,10 +1147,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x] * [y])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_mul; auto.
unfold Qcmult, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qmult_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1161,10 +1161,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x] * [y])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_mul_norm; auto.
unfold Qcmult, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qmult_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1185,10 +1185,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc (/[x])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_inv; auto.
unfold Qcinv, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qinv_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1199,10 +1199,10 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc (/[x])).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_inv_norm; auto.
unfold Qcinv, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qinv_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1247,13 +1247,13 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x]^2)).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_square; auto.
simpl Qcpower.
replace (Q2Qc [x] * 1) with (Q2Qc [x]); try ring.
simpl.
unfold Qcmult, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
apply Qmult_comp; apply Qeq_sym; apply Qred_correct.
Qed.
@@ -1264,14 +1264,14 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
unfold to_Qc.
transitivity (Q2Qc ([x]^Zpos p)).
unfold Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete; apply spec_power_pos; auto.
induction p using Pos.peano_ind.
simpl; ring.
rewrite Pos2Nat.inj_succ; simpl Qcpower.
rewrite <- IHp; clear IHp.
unfold Qcmult, Q2Qc.
- apply Qc_decomp; intros _ _; unfold this.
+ apply Qc_decomp; unfold this.
apply Qred_complete.
setoid_replace ([x] ^ ' Pos.succ p)%Q with ([x] * [x] ^ ' p)%Q.
apply Qmult_comp; apply Qeq_sym; apply Qred_correct.
@@ -1281,4 +1281,3 @@ Module Make (NN:NType)(ZZ:ZType)(Import NZ:NType_ZType NN ZZ) <: QType.
Qed.
End Make.
-
diff --git a/theories/QArith/Qcanon.v b/theories/QArith/Qcanon.v
index d966b050c3..86be28d7b8 100644
--- a/theories/QArith/Qcanon.v
+++ b/theories/QArith/Qcanon.v
@@ -21,37 +21,30 @@ Bind Scope Qc_scope with Qc.
Arguments Qcmake this%Q _.
Open Scope Qc_scope.
+(** An alternative statement of [Qred q = q] via [Z.gcd] *)
+
Lemma Qred_identity :
forall q:Q, Z.gcd (Qnum q) (QDen q) = 1%Z -> Qred q = q.
Proof.
- unfold Qred; intros (a,b); simpl.
- generalize (Z.ggcd_gcd a ('b)) (Z.ggcd_correct_divisors a ('b)).
- intros.
- rewrite H1 in H; clear H1.
- destruct (Z.ggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
- destruct H0.
- rewrite Z.mul_1_l in H, H0.
- subst; simpl; auto.
+ intros (a,b) H; simpl in *.
+ rewrite <- Z.ggcd_gcd in H.
+ generalize (Z.ggcd_correct_divisors a ('b)).
+ destruct Z.ggcd as (g,(aa,bb)); simpl in *; subst.
+ rewrite !Z.mul_1_l. now intros (<-,<-).
Qed.
Lemma Qred_identity2 :
forall q:Q, Qred q = q -> Z.gcd (Qnum q) (QDen q) = 1%Z.
Proof.
- unfold Qred; intros (a,b); simpl.
- generalize (Z.ggcd_gcd a ('b)) (Z.ggcd_correct_divisors a ('b)) (Z.gcd_nonneg a ('b)).
- intros.
- rewrite <- H; rewrite <- H in H1; clear H.
- destruct (Z.ggcd a ('b)) as (g,(aa,bb)); simpl in *; subst.
- injection H2; intros; clear H2.
- destruct H0.
- clear H0 H3.
- destruct g as [|g|g]; destruct bb as [|bb|bb]; simpl in *; try discriminate.
- f_equal.
- apply Pos.mul_reg_r with bb.
- injection H2; intros.
- rewrite <- H0.
- rewrite H; simpl; auto.
- elim H1; auto.
+ intros (a,b) H; simpl in *.
+ generalize (Z.gcd_nonneg a ('b)) (Z.ggcd_correct_divisors a ('b)).
+ rewrite <- Z.ggcd_gcd.
+ destruct Z.ggcd as (g,(aa,bb)); simpl in *.
+ injection H as <- <-. intros H (_,H').
+ destruct g as [|g|g]; [ discriminate | | now elim H ].
+ destruct bb as [|b|b]; simpl in *; try discriminate.
+ injection H' as H'. f_equal.
+ apply Pos.mul_reg_r with b. now rewrite Pos.mul_1_l.
Qed.
Lemma Qred_iff : forall q:Q, Qred q = q <-> Z.gcd (Qnum q) (QDen q) = 1%Z.
@@ -61,6 +54,23 @@ Proof.
apply Qred_identity; auto.
Qed.
+(** Coercion from [Qc] to [Q] and equality *)
+
+Lemma Qc_is_canon : forall q q' : Qc, q == q' -> q = q'.
+Proof.
+ intros (q,hq) (q',hq') H. simpl in *.
+ assert (H' := Qred_complete _ _ H).
+ rewrite hq, hq' in H'. subst q'. f_equal.
+ apply eq_proofs_unicity. intros. repeat decide equality.
+Qed.
+Hint Resolve Qc_is_canon.
+
+Theorem Qc_decomp: forall q q': Qc, (q:Q) = q' -> q = q'.
+Proof.
+ intros. apply Qc_is_canon. now rewrite H.
+Qed.
+
+(** [Q2Qc] : a conversion from [Q] to [Qc]. *)
Lemma Qred_involutive : forall q:Q, Qred (Qred q) = Qred q.
Proof.
@@ -71,20 +81,20 @@ Qed.
Definition Q2Qc (q:Q) : Qc := Qcmake (Qred q) (Qred_involutive q).
Arguments Q2Qc q%Q.
-Lemma Qc_is_canon : forall q q' : Qc, q == q' -> q = q'.
+Lemma Qred_eq_iff (q q' : Q) : Qred q = Qred q' <-> q == q'.
Proof.
- intros (q,proof_q) (q',proof_q').
- simpl.
- intros H.
- assert (H0:=Qred_complete _ _ H).
- assert (q = q') by congruence.
- subst q'.
- assert (proof_q = proof_q').
- apply eq_proofs_unicity; auto; intros.
- repeat decide equality.
- congruence.
+ split.
+ - intros E. rewrite <- (Qred_correct q), <- (Qred_correct q').
+ now rewrite E.
+ - apply Qred_complete.
+Qed.
+
+Lemma Q2Qc_eq_iff (q q' : Q) : Q2Qc q = Q2Qc q' <-> q == q'.
+Proof.
+ split; intro H.
+ - injection H. apply Qred_eq_iff.
+ - apply Qc_is_canon. simpl. now rewrite H.
Qed.
-Hint Resolve Qc_is_canon.
Notation " 0 " := (Q2Qc 0) : Qc_scope.
Notation " 1 " := (Q2Qc 1) : Qc_scope.
@@ -107,8 +117,7 @@ Lemma Qceq_alt : forall p q, (p = q) <-> (p ?= q) = Eq.
Proof.
unfold Qccompare.
intros; rewrite <- Qeq_alt.
- split; auto.
- intro H; rewrite H; auto with qarith.
+ split; auto. now intros <-.
Qed.
Lemma Qclt_alt : forall p q, (p (p?=q = Lt).
@@ -166,7 +175,7 @@ Qed.
Ltac qc := match goal with
| q:Qc |- _ => destruct q; qc
- | _ => apply Qc_is_canon; simpl; repeat rewrite Qred_correct
+ | _ => apply Qc_is_canon; simpl; rewrite !Qred_correct
end.
Opaque Qred.
@@ -216,6 +225,18 @@ Proof.
intros; qc; apply Qmult_assoc.
Qed.
+(** [0] is absorbing for multiplication: *)
+
+Lemma Qcmult_0_l : forall n, 0*n = 0.
+Proof.
+ intros; qc; split.
+Qed.
+
+Theorem Qcmult_0_r : forall n, n*0=0.
+Proof.
+ intros; qc; rewrite Qmult_comm; split.
+Qed.
+
(** [1] is a neutral element for multiplication: *)
Lemma Qcmult_1_l : forall n, 1*n = n.
@@ -303,7 +324,7 @@ Proof.
apply Qcmult_1_l.
Qed.
-(** Properties of order upon Q. *)
+(** Properties of order upon Qc. *)
Lemma Qcle_refl : forall x, x<=x.
Proof.
@@ -372,9 +393,11 @@ Proof.
unfold Qcle, Qclt; intros; apply Qle_not_lt; auto.
Qed.
-Lemma Qcle_lt_or_eq : forall x y, x<=y -> x xO -> 0^n = 0.
Proof.
destruct n; simpl.
@@ -525,16 +548,3 @@ intros.
field.
auto.
Qed.
-
-
-Theorem Qc_decomp: forall x y: Qc,
- (Qred x = x -> Qred y = y -> (x:Q) = y)-> x = y.
-Proof.
- intros (q, Hq) (q', Hq'); simpl; intros H.
- assert (H1 := H Hq Hq').
- subst q'.
- assert (Hq = Hq').
- apply Eqdep_dec.eq_proofs_unicity; auto; intros.
- repeat decide equality.
- congruence.
-Qed.
--
cgit v1.2.3
From 20adaabfa96744442f201287e2900b1575614577 Mon Sep 17 00:00:00 2001
From: Pierre Letouzey
Date: Fri, 26 Feb 2016 20:01:18 +0100
Subject: Qcanon : fix names of lemmas Qcle_alt & Qcge_alt (were Qle_alt &
Qge_alt)
---
theories/QArith/Qcanon.v | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/theories/QArith/Qcanon.v b/theories/QArith/Qcanon.v
index 86be28d7b8..078926e321 100644
--- a/theories/QArith/Qcanon.v
+++ b/theories/QArith/Qcanon.v
@@ -130,12 +130,12 @@ Proof.
intros; exact (Qgt_alt p q).
Qed.
-Lemma Qle_alt : forall p q, (p<=q) <-> (p?=q <> Gt).
+Lemma Qcle_alt : forall p q, (p<=q) <-> (p?=q <> Gt).
Proof.
intros; exact (Qle_alt p q).
Qed.
-Lemma Qge_alt : forall p q, (p>=q) <-> (p?=q <> Lt).
+Lemma Qcge_alt : forall p q, (p>=q) <-> (p?=q <> Lt).
Proof.
intros; exact (Qge_alt p q).
Qed.
--
cgit v1.2.3
From 3246b4fd3d03cba93c556986ed1a0f9629e4bb73 Mon Sep 17 00:00:00 2001
From: Pierre Letouzey
Date: Fri, 26 Feb 2016 20:16:00 +0100
Subject: Qcabs : absolute value on normalized rational numbers Qc
File contributed by Cédric Auger (a long time ago, sorry!)
Qarith and Qc would probably deserve many more results like this one,
and a more modern style (for instance qualified names), but this commit
is better than nothing...
---
theories/QArith/Qcabs.v | 129 +++++++++++++++++++++++++++++++++++++++++++
theories/QArith/Qcanon.v | 10 +---
theories/QArith/Qreduction.v | 22 +++++++-
theories/QArith/vo.itarget | 1 +
4 files changed, 150 insertions(+), 12 deletions(-)
create mode 100644 theories/QArith/Qcabs.v
diff --git a/theories/QArith/Qcabs.v b/theories/QArith/Qcabs.v
new file mode 100644
index 0000000000..c0ababfff5
--- /dev/null
+++ b/theories/QArith/Qcabs.v
@@ -0,0 +1,129 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* Qred (Qabs x) = Qabs x.
+Proof. intros H; now rewrite (Qred_abs x), H. Qed.
+
+Definition Qcabs (x:Qc) : Qc := {| canon := Qcabs_canon x (canon x) |}.
+Notation "[ q ]" := (Qcabs q) (q at next level, format "[ q ]") : Qc_scope.
+
+Ltac Qc_unfolds :=
+ unfold Qcabs, Qcminus, Qcopp, Qcplus, Qcmult, Qcle, Q2Qc, this.
+
+Lemma Qcabs_case (x:Qc) (P : Qc -> Type) :
+ (0 <= x -> P x) -> (x <= 0 -> P (- x)) -> P [x].
+Proof.
+ intros A B.
+ apply (Qabs_case x (fun x => forall Hx, P {|this:=x;canon:=Hx|})).
+ intros; case (Qc_decomp x {|canon:=Hx|}); auto.
+ intros; case (Qc_decomp (-x) {|canon:=Hx|}); auto.
+Qed.
+
+Lemma Qcabs_pos x : 0 <= x -> [x] = x.
+Proof.
+ intro Hx; apply Qc_decomp; Qc_unfolds; fold (this x).
+ set (K := canon [x]); simpl in K; case K; clear K.
+ set (a := x) at 1; case (canon x); subst a; apply Qred_complete.
+ now apply Qabs_pos.
+Qed.
+
+Lemma Qcabs_neg x : x <= 0 -> [x] = - x.
+Proof.
+ intro Hx; apply Qc_decomp; Qc_unfolds; fold (this x).
+ set (K := canon [x]); simpl in K; case K; clear K.
+ now apply Qred_complete; apply Qabs_neg.
+Qed.
+
+Lemma Qcabs_nonneg x : 0 <= [x].
+Proof. intros; apply Qabs_nonneg. Qed.
+
+Lemma Qcabs_opp x : [(-x)] = [x].
+Proof.
+ apply Qc_decomp; Qc_unfolds; fold (this x).
+ set (K := canon [x]); simpl in K; case K; clear K.
+ case Qred_abs; apply Qred_complete; apply Qabs_opp.
+Qed.
+
+Lemma Qcabs_triangle x y : [x+y] <= [x] + [y].
+Proof.
+ Qc_unfolds; case Qred_abs; rewrite !Qred_le; apply Qabs_triangle.
+Qed.
+
+Lemma Qcabs_Qcmult x y : [x*y] = [x]*[y].
+Proof.
+ apply Qc_decomp; Qc_unfolds; fold (this x) (this y); case Qred_abs.
+ apply Qred_complete; apply Qabs_Qmult.
+Qed.
+
+Lemma Qcabs_Qcminus x y: [x-y] = [y-x].
+Proof.
+ apply Qc_decomp; Qc_unfolds; fold (this x) (this y) (this (-x)) (this (-y)).
+ set (a := x) at 2; case (canon x); subst a.
+ set (a := y) at 1; case (canon y); subst a.
+ rewrite !Qred_opp; fold (Qred x - Qred y)%Q (Qred y - Qred x)%Q.
+ repeat case Qred_abs; f_equal; apply Qabs_Qminus.
+Qed.
+
+Lemma Qcle_Qcabs x : x <= [x].
+Proof. apply Qle_Qabs. Qed.
+
+Lemma Qcabs_triangle_reverse x y : [x] - [y] <= [x - y].
+Proof.
+ unfold Qcle, Qcabs, Qcminus, Qcplus, Qcopp, Q2Qc, this;
+ fold (this x) (this y) (this (-x)) (this (-y)).
+ case Qred_abs; rewrite !Qred_le, !Qred_opp, Qred_abs.
+ apply Qabs_triangle_reverse.
+Qed.
+
+Lemma Qcabs_Qcle_condition x y : [x] <= y <-> -y <= x <= y.
+Proof.
+ Qc_unfolds; fold (this x) (this y).
+ destruct (Qabs_Qle_condition x y) as [A B].
+ split; intros H.
+ + destruct (A H) as [X Y]; split; auto.
+ now case (canon x); apply Qred_le.
+ + destruct H as [X Y]; apply B; split; auto.
+ now case (canon y); case Qred_opp.
+Qed.
+
+Lemma Qcabs_diff_Qcle_condition x y r : [x-y] <= r <-> x - r <= y <= x + r.
+Proof.
+ Qc_unfolds; fold (this x) (this y) (this r).
+ case Qred_abs; repeat rewrite Qred_opp.
+ set (a := y) at 1; case (canon y); subst a.
+ set (a := r) at 2; case (canon r); subst a.
+ set (a := Qred r) at 2 3;
+ assert (K := canon (Q2Qc r)); simpl in K; case K; clear K; subst a.
+ set (a := Qred y) at 1;
+ assert (K := canon (Q2Qc y)); simpl in K; case K; clear K; subst a.
+ fold (x - Qred y)%Q (x - Qred r)%Q.
+ destruct (Qabs_diff_Qle_condition x (Qred y) (Qred r)) as [A B].
+ split.
+ + clear B; rewrite !Qred_le. auto.
+ + clear A; rewrite !Qred_le. auto.
+Qed.
+
+Lemma Qcabs_null x : [x] = 0 -> x = 0.
+Proof.
+ intros H.
+ destruct (proj1 (Qcabs_Qcle_condition x 0)) as [A B].
+ + rewrite H; apply Qcle_refl.
+ + apply Qcle_antisym; auto.
+Qed.
\ No newline at end of file
diff --git a/theories/QArith/Qcanon.v b/theories/QArith/Qcanon.v
index 078926e321..6bfa47bc55 100644
--- a/theories/QArith/Qcanon.v
+++ b/theories/QArith/Qcanon.v
@@ -81,14 +81,6 @@ Qed.
Definition Q2Qc (q:Q) : Qc := Qcmake (Qred q) (Qred_involutive q).
Arguments Q2Qc q%Q.
-Lemma Qred_eq_iff (q q' : Q) : Qred q = Qred q' <-> q == q'.
-Proof.
- split.
- - intros E. rewrite <- (Qred_correct q), <- (Qred_correct q').
- now rewrite E.
- - apply Qred_complete.
-Qed.
-
Lemma Q2Qc_eq_iff (q q' : Q) : Q2Qc q = Q2Qc q' <-> q == q'.
Proof.
split; intro H.
@@ -488,7 +480,7 @@ Proof.
destruct n; simpl.
destruct 1; auto.
intros.
- now apply Qc_is_canon.
+ now apply Qc_is_canon.
Qed.
Lemma Qcpower_pos : forall p n, 0 <= p -> 0 <= p^n.
diff --git a/theories/QArith/Qreduction.v b/theories/QArith/Qreduction.v
index c50c38b28f..131214f516 100644
--- a/theories/QArith/Qreduction.v
+++ b/theories/QArith/Qreduction.v
@@ -93,11 +93,17 @@ Proof.
Close Scope Z_scope.
Qed.
+Lemma Qred_eq_iff q q' : Qred q = Qred q' <-> q == q'.
+Proof.
+ split.
+ - intros E. rewrite <- (Qred_correct q), <- (Qred_correct q').
+ now rewrite E.
+ - apply Qred_complete.
+Qed.
+
Add Morphism Qred : Qred_comp.
Proof.
- intros q q' H.
- rewrite (Qred_correct q); auto.
- rewrite (Qred_correct q'); auto.
+ intros. now rewrite !Qred_correct.
Qed.
Definition Qplus' (p q : Q) := Qred (Qplus p q).
@@ -149,3 +155,13 @@ Theorem Qred_compare: forall x y,
Proof.
intros x y; apply Qcompare_comp; apply Qeq_sym; apply Qred_correct.
Qed.
+
+Lemma Qred_le q q' : Qred q <= Qred q' <-> q <= q'.
+Proof.
+ now rewrite !Qle_alt, <- Qred_compare.
+Qed.
+
+Lemma Qred_lt q q' : Qred q < Qred q' <-> q < q'.
+Proof.
+ now rewrite !Qlt_alt, <- Qred_compare.
+Qed.
diff --git a/theories/QArith/vo.itarget b/theories/QArith/vo.itarget
index b3faef8817..b550b47128 100644
--- a/theories/QArith/vo.itarget
+++ b/theories/QArith/vo.itarget
@@ -2,6 +2,7 @@ Qabs.vo
QArith_base.vo
QArith.vo
Qcanon.vo
+Qcabs.vo
Qfield.vo
Qpower.vo
Qreals.vo
--
cgit v1.2.3
From 8810dc5bfec0452bfa45f6594382d273c806cc82 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sat, 27 Feb 2016 15:05:39 +0100
Subject: Removing some compatibility layers in Tacinterp.
---
tactics/tacinterp.ml | 76 +++++++++++++++++++++-------------------------------
1 file changed, 30 insertions(+), 46 deletions(-)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 43c9ee9be4..9337e604ec 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -23,7 +23,7 @@ open Nametab
open Pfedit
open Proof_type
open Refiner
-open Tacmach
+open Tacmach.New
open Tactic_debug
open Constrexpr
open Term
@@ -718,8 +718,8 @@ let interp_open_constr_list =
interp_constr_in_compound_list (fun x -> x) (fun x -> x) interp_open_constr
(* Interprets a type expression *)
-let pf_interp_type ist gl =
- interp_type ist (pf_env gl) (project gl)
+let pf_interp_type ist env sigma =
+ interp_type ist env sigma
(* Fully evaluate an untyped constr *)
let type_uconstr ?(flags = constr_flags)
@@ -1240,7 +1240,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
end
| TacAbstract (tac,ido) ->
Proofview.Goal.nf_enter { enter = begin fun gl -> Tactics.tclABSTRACT
- (Option.map (Tacmach.New.of_old (pf_interp_ident ist) gl) ido) (interp_tactic ist tac)
+ (Option.map (pf_interp_ident ist gl) ido) (interp_tactic ist tac)
end }
| TacThen (t1,t) ->
Tacticals.New.tclTHEN (interp_tactic ist t1) (interp_tactic ist t)
@@ -1704,13 +1704,10 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacExact c ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
- Proofview.V82.tactic begin fun gl ->
- let (sigma,c_interp) = pf_interp_casted_constr ist gl c in
- tclTHEN
- (tclEVARS sigma)
- (Tactics.exact_no_check c_interp)
- gl
- end
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let (sigma, c_interp) = pf_interp_casted_constr ist gl c in
+ Sigma.Unsafe.of_pair (Proofview.V82.tactic (Tactics.exact_no_check c_interp), sigma)
+ end }
end
| TacApply (a,ev,cb,cl) ->
(* spiwack: until the tactic is in the monad *)
@@ -1765,19 +1762,17 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacMutualFix (id,n,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
- Proofview.V82.tactic begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let env = pf_env gl in
let f sigma (id,n,c) =
- let (sigma,c_interp) = pf_interp_type ist { gl with sigma=sigma } c in
+ let (sigma,c_interp) = pf_interp_type ist env sigma c in
sigma , (interp_ident ist env sigma id,n,c_interp) in
let (sigma,l_interp) =
Evd.MonadR.List.map_right (fun c sigma -> f sigma c) l (project gl)
in
- tclTHEN
- (tclEVARS sigma)
- (Tactics.mutual_fix (interp_ident ist env sigma id) n l_interp 0)
- gl
- end
+ let tac = Proofview.V82.tactic (Tactics.mutual_fix (interp_ident ist env sigma id) n l_interp 0) in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
end
| TacCofix idopt ->
Proofview.Goal.enter { enter = begin fun gl ->
@@ -1791,19 +1786,17 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacMutualCofix (id,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
- Proofview.V82.tactic begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let env = pf_env gl in
let f sigma (id,c) =
- let (sigma,c_interp) = pf_interp_type ist { gl with sigma=sigma } c in
+ let (sigma,c_interp) = pf_interp_type ist env sigma c in
sigma , (interp_ident ist env sigma id,c_interp) in
let (sigma,l_interp) =
Evd.MonadR.List.map_right (fun c sigma -> f sigma c) l (project gl)
in
- tclTHEN
- (tclEVARS sigma)
- (Tactics.mutual_cofix (interp_ident ist env sigma id) l_interp 0)
- gl
- end
+ let tac = Proofview.V82.tactic (Tactics.mutual_cofix (interp_ident ist env sigma id) l_interp 0) in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
end
| TacAssert (b,t,ipat,c) ->
Proofview.Goal.enter { enter = begin fun gl ->
@@ -1844,9 +1837,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let eqpat = interp_intro_pattern_naming_option ist env sigma eqpat in
if Locusops.is_nowhere clp then
(* We try to fully-typecheck the term *)
- let (sigma,c_interp) =
- Tacmach.New.of_old (fun gl -> pf_interp_constr ist gl c) gl
- in
+ let (sigma,c_interp) = pf_interp_constr ist gl c in
let let_tac b na c cl eqpat =
let id = Option.default (Loc.ghost,IntroAnonymous) eqpat in
let with_eq = if b then None else Some (true,id) in
@@ -1930,11 +1921,10 @@ and interp_atomic ist tac : unit Proofview.tactic =
(Tactics.clear_body l)
end }
| TacMove (id1,id2) ->
- Proofview.V82.tactic begin fun gl ->
- Tactics.move_hyp (interp_hyp ist (pf_env gl) (project gl) id1)
- (interp_move_location ist (pf_env gl) (project gl) id2)
- gl
- end
+ Proofview.Goal.enter { enter = begin fun gl ->
+ Proofview.V82.tactic (Tactics.move_hyp (interp_hyp ist (pf_env gl) (project gl) id1)
+ (interp_move_location ist (pf_env gl) (project gl) id2))
+ end }
| TacRename l ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Tacmach.New.pf_env gl in
@@ -1965,19 +1955,16 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacReduce (r,cl) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
- Proofview.V82.tactic begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let (sigma,r_interp) = interp_red_expr ist (pf_env gl) (project gl) r in
- tclTHEN
- (tclEVARS sigma)
- (Proofview.V82.of_tactic (Tactics.reduce r_interp (interp_clause ist (pf_env gl) (project gl) cl)))
- gl
- end
+ Sigma.Unsafe.of_pair (Tactics.reduce r_interp (interp_clause ist (pf_env gl) (project gl) cl), sigma)
+ end }
end
| TacChange (None,c,cl) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
Proofview.V82.nf_evar_goals <*>
- Proofview.V82.tactic begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let is_onhyps = match cl.onhyps with
| None | Some [] -> true
| _ -> false
@@ -2000,9 +1987,8 @@ and interp_atomic ist tac : unit Proofview.tactic =
in
Sigma.Unsafe.of_pair (c, sigma)
end } in
- (Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl))
- gl
- end
+ Proofview.V82.tactic (Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl))
+ end }
end
| TacChange (Some op,c,cl) ->
(* spiwack: until the tactic is in the monad *)
@@ -2072,9 +2058,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
match c with
| None -> sigma , None
| Some c ->
- let (sigma,c_interp) =
- Tacmach.New.of_old (fun gl -> pf_interp_constr ist gl c) gl
- in
+ let (sigma,c_interp) = pf_interp_constr ist gl c in
sigma , Some c_interp
in
let dqhyps = interp_declared_or_quantified_hypothesis ist env sigma hyp in
--
cgit v1.2.3
From 334302a25bd6c225a95fd82e03a6426497d5106b Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sat, 27 Feb 2016 15:40:30 +0100
Subject: Removing Tacmach.New qualification in Tacinterp.
---
tactics/tacinterp.ml | 73 ++++++++++++++++++++++++++--------------------------
1 file changed, 36 insertions(+), 37 deletions(-)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 9337e604ec..d5a1215b87 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -692,7 +692,7 @@ let pf_interp_constr ist gl =
let new_interp_constr ist c k =
let open Proofview in
Proofview.Goal.s_enter { s_enter = begin fun gl ->
- let (sigma, c) = interp_constr ist (Goal.env gl) (Tacmach.New.project gl) c in
+ let (sigma, c) = interp_constr ist (Goal.env gl) (project gl) c in
Sigma.Unsafe.of_pair (k c, sigma)
end }
@@ -860,17 +860,16 @@ let interp_constr_may_eval ist env sigma c =
(** TODO: should use dedicated printers *)
let rec message_of_value v =
let v = Value.normalize v in
- let open Tacmach.New in
let open Ftactic in
if has_type v (topwit wit_tacvalue) then
Ftactic.return (str "")
else if has_type v (topwit wit_constr) then
let v = out_gen (topwit wit_constr) v in
- Ftactic.nf_enter {enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Tacmach.New.project gl) v) end }
+ Ftactic.nf_enter {enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (project gl) v) end }
else if has_type v (topwit wit_constr_under_binders) then
let c = out_gen (topwit wit_constr_under_binders) v in
Ftactic.nf_enter { enter = begin fun gl ->
- Ftactic.return (pr_constr_under_binders_env (pf_env gl) (Tacmach.New.project gl) c)
+ Ftactic.return (pr_constr_under_binders_env (pf_env gl) (project gl) c)
end }
else if has_type v (topwit wit_unit) then
Ftactic.return (str "()")
@@ -880,16 +879,16 @@ let rec message_of_value v =
let p = out_gen (topwit wit_intro_pattern) v in
let print env sigma c = pr_constr_env env sigma (fst (Tactics.run_delayed env Evd.empty c)) in
Ftactic.nf_enter { enter = begin fun gl ->
- Ftactic.return (Miscprint.pr_intro_pattern (fun c -> print (pf_env gl) (Tacmach.New.project gl) c) p)
+ Ftactic.return (Miscprint.pr_intro_pattern (fun c -> print (pf_env gl) (project gl) c) p)
end }
else if has_type v (topwit wit_constr_context) then
let c = out_gen (topwit wit_constr_context) v in
- Ftactic.nf_enter { enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Tacmach.New.project gl) c) end }
+ Ftactic.nf_enter { enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (project gl) c) end }
else if has_type v (topwit wit_uconstr) then
let c = out_gen (topwit wit_uconstr) v in
Ftactic.nf_enter { enter = begin fun gl ->
Ftactic.return (pr_closed_glob_env (pf_env gl)
- (Tacmach.New.project gl) c)
+ (project gl) c)
end }
else match Value.to_list v with
| Some l ->
@@ -1361,7 +1360,7 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
| Reference r -> interp_ltac_reference dloc false ist r
| ConstrMayEval c ->
Ftactic.s_enter { s_enter = begin fun gl ->
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let env = Proofview.Goal.env gl in
let (sigma,c_interp) = interp_constr_may_eval ist env sigma c in
Sigma.Unsafe.of_pair (Ftactic.return (Value.of_constr c_interp), sigma)
@@ -1380,7 +1379,7 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
interp_app loc ist fv largs
| TacFreshId l ->
Ftactic.enter { enter = begin fun gl ->
- let id = interp_fresh_id ist (Tacmach.New.pf_env gl) (Tacmach.New.project gl) l in
+ let id = interp_fresh_id ist (pf_env gl) (project gl) l in
Ftactic.return (in_gen (topwit wit_intro_pattern) (dloc, IntroNaming (IntroIdentifier id)))
end }
| TacPretype c ->
@@ -1545,7 +1544,7 @@ and interp_match ist lz constr lmr =
end
end >>= fun constr ->
Ftactic.enter { enter = begin fun gl ->
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let env = Proofview.Goal.env gl in
let ilr = read_match_rule (extract_ltac_constr_values ist env) ist env sigma lmr in
interp_match_successes lz ist (Tactic_matching.match_term env sigma constr ilr)
@@ -1554,7 +1553,7 @@ and interp_match ist lz constr lmr =
(* Interprets the Match Context expressions *)
and interp_match_goal ist lz lr lmr =
Ftactic.nf_enter { enter = begin fun gl ->
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let env = Proofview.Goal.env gl in
let hyps = Proofview.Goal.hyps gl in
let hyps = if lr then List.rev hyps else hyps in
@@ -1644,7 +1643,7 @@ and interp_ltac_constr ist e : constr Ftactic.t =
end >>= fun result ->
Ftactic.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let result = Value.normalize result in
try
let cresult = coerce_to_closed_constr env result in
@@ -1682,7 +1681,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacIntroPattern l ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let sigma,l' = interp_intro_pattern_list_as_list ist env sigma l in
Tacticals.New.tclWITHHOLES false
(name_atomic ~env
@@ -1694,7 +1693,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacIntroMove (ido,hto) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let mloc = interp_move_location ist env sigma hto in
let ido = Option.map (interp_ident ist env sigma) ido in
name_atomic ~env
@@ -1714,7 +1713,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let l = List.map (fun (k,c) ->
let loc, f = interp_open_constr_with_bindings_loc ist c in
(k,(loc,f))) cb
@@ -1730,7 +1729,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacElim (ev,(keep,cb),cbo) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let sigma, cb = interp_constr_with_bindings ist env sigma cb in
let sigma, cbo = Option.fold_map (interp_constr_with_bindings ist env) sigma cbo in
let named_tac =
@@ -1741,7 +1740,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
end }
| TacCase (ev,(keep,cb)) ->
Proofview.Goal.enter { enter = begin fun gl ->
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let env = Proofview.Goal.env gl in
let sigma, cb = interp_constr_with_bindings ist env sigma cb in
let named_tac =
@@ -1753,7 +1752,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacFix (idopt,n) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let idopt = Option.map (interp_ident ist env sigma) idopt in
name_atomic ~env
(TacFix(idopt,n))
@@ -1777,7 +1776,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacCofix idopt ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let idopt = Option.map (interp_ident ist env sigma) idopt in
name_atomic ~env
(TacCofix (idopt))
@@ -1801,7 +1800,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacAssert (b,t,ipat,c) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let (sigma,c) =
(if Option.is_empty t then interp_constr else interp_type) ist env sigma c
in
@@ -1814,7 +1813,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
end }
| TacGeneralize cl ->
Proofview.Goal.enter { enter = begin fun gl ->
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let env = Proofview.Goal.env gl in
let sigma, cl = interp_constr_with_occurrences_and_name_as_list ist env sigma cl in
Tacticals.New.tclWITHHOLES false
@@ -1832,7 +1831,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
Proofview.V82.nf_evar_goals <*>
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let clp = interp_clause ist env sigma clp in
let eqpat = interp_intro_pattern_naming_option ist env sigma eqpat in
if Locusops.is_nowhere clp then
@@ -1870,7 +1869,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
Proofview.V82.nf_evar_goals <*>
Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let sigma,l =
List.fold_map begin fun sigma (c,(ipato,ipats),cls) ->
(* TODO: move sigma as a side-effect *)
@@ -1902,8 +1901,8 @@ and interp_atomic ist tac : unit Proofview.tactic =
(* Context management *)
| TacClear (b,l) ->
Proofview.Goal.enter { enter = begin fun gl ->
- let env = Tacmach.New.pf_env gl in
- let sigma = Tacmach.New.project gl in
+ let env = pf_env gl in
+ let sigma = project gl in
let l = interp_hyp_list ist env sigma l in
if b then name_atomic ~env (TacClear (b, l)) (Tactics.keep l)
else
@@ -1913,8 +1912,8 @@ and interp_atomic ist tac : unit Proofview.tactic =
end }
| TacClearBody l ->
Proofview.Goal.enter { enter = begin fun gl ->
- let env = Tacmach.New.pf_env gl in
- let sigma = Tacmach.New.project gl in
+ let env = pf_env gl in
+ let sigma = project gl in
let l = interp_hyp_list ist env sigma l in
name_atomic ~env
(TacClearBody l)
@@ -1927,8 +1926,8 @@ and interp_atomic ist tac : unit Proofview.tactic =
end }
| TacRename l ->
Proofview.Goal.enter { enter = begin fun gl ->
- let env = Tacmach.New.pf_env gl in
- let sigma = Tacmach.New.project gl in
+ let env = pf_env gl in
+ let sigma = project gl in
let l =
List.map (fun (id1,id2) ->
interp_hyp ist env sigma id1,
@@ -1943,7 +1942,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacSplit (ev,bll) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let sigma, bll = List.fold_map (interp_bindings ist env) sigma bll in
let named_tac =
let tac = Tactics.split_with_bindings ev bll in
@@ -1996,7 +1995,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
Proofview.V82.nf_evar_goals <*>
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
Proofview.V82.tactic begin fun gl ->
let op = interp_typed_pattern ist env sigma op in
let to_catch = function Not_found -> true | e -> Errors.is_anomaly e in
@@ -2023,7 +2022,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacSymmetry c ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let cl = interp_clause ist env sigma c in
name_atomic ~env
(TacSymmetry cl)
@@ -2041,7 +2040,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
} in
(b,m,keep,f)) l in
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let cl = interp_clause ist env sigma cl in
name_atomic ~env
(TacRewrite (ev,l,cl,by))
@@ -2053,7 +2052,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacInversion (DepInversion (k,c,ids),hyp) ->
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let (sigma,c_interp) =
match c with
| None -> sigma , None
@@ -2071,7 +2070,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacInversion (NonDepInversion (k,idl,ids),hyp) ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let hyps = interp_hyp_list ist env sigma idl in
let dqhyps = interp_declared_or_quantified_hypothesis ist env sigma hyp in
let sigma, ids_interp = interp_or_and_intro_pattern_option ist env sigma ids in
@@ -2083,7 +2082,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacInversion (InversionUsing (c,idl),hyp) ->
Proofview.Goal.s_enter { s_enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let (sigma,c_interp) = interp_constr ist env sigma c in
let dqhyps = interp_declared_or_quantified_hypothesis ist env sigma hyp in
let hyps = interp_hyp_list ist env sigma idl in
@@ -2263,7 +2262,7 @@ let dummy_id = Id.of_string "_"
let lift_constr_tac_to_ml_tac vars tac =
let tac _ ist = Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = project gl in
let map = function
| None -> None
| Some id ->
--
cgit v1.2.3
From db2c6f0054d3e05f82da7494ce790c04b1976401 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 28 Feb 2016 13:19:47 +0100
Subject: Fixing bug #4596: [rewrite] broke in the past few weeks.
Checking that a term was indeed a relation was made too early, as the
decomposition function recognized relations of the form "f (g .. (h x y))
with f, g unary and only h binary. We postpone this check to the very end.
---
tactics/rewrite.ml | 8 ++++++--
test-suite/bugs/closed/4596.v | 14 ++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
create mode 100644 test-suite/bugs/closed/4596.v
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 5ca74050a1..803e187ff5 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -468,11 +468,15 @@ let rec decompose_app_rel env evd t =
let len = Array.length args in
let fargs = Array.sub args 0 (Array.length args - 2) in
let rel = mkApp (f, fargs) in
- let ty = Retyping.get_type_of env evd rel in
- let () = if not (Reduction.is_arity env ty) then error_no_relation () in
rel, args.(len - 2), args.(len - 1)
| _ -> error_no_relation ()
+let decompose_app_rel env evd t =
+ let (rel, t1, t2) = decompose_app_rel env evd t in
+ let ty = Retyping.get_type_of env evd rel in
+ let () = if not (Reduction.is_arity env ty) then error_no_relation () in
+ (rel, t1, t2)
+
let decompose_applied_relation env sigma (c,l) =
let ctype = Retyping.get_type_of env sigma c in
let find_rel ty =
diff --git a/test-suite/bugs/closed/4596.v b/test-suite/bugs/closed/4596.v
new file mode 100644
index 0000000000..592fdb6580
--- /dev/null
+++ b/test-suite/bugs/closed/4596.v
@@ -0,0 +1,14 @@
+Require Import Coq.Setoids.Setoid Coq.Classes.Morphisms.
+
+Definition T (x : bool) := x = true.
+
+Goal forall (S : Type) (b b0 : S -> nat -> bool) (str : S) (p : nat)
+ (s : forall n : nat, bool)
+ (s0 s1 : nat -> S -> S),
+ (forall (str0 : S) (n m : nat),
+ (if s m then T (b0 (s1 n str0) 0) else T (b (s1 n str0) 0)) -> T (b (s0 n str0) m) ->
+ T (b str0 m)) ->
+ T (b str p).
+Proof.
+intros ???????? H0.
+rewrite H0.
--
cgit v1.2.3
From 4fcd7fd68986246adb666ed46d066fcf0355bf09 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Sat, 20 Feb 2016 14:32:40 +0100
Subject: Slightly contracting code of evarconv.ml.
---
pretyping/evarconv.ml | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 0a45ae9fd8..0ccc5b654b 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -322,25 +322,22 @@ let rec evar_conv_x ts env evd pbty term1 term2 =
Note: incomplete heuristic... *)
let ground_test =
if is_ground_term evd term1 && is_ground_term evd term2 then (
- let evd, e =
+ let e =
try
let evd, b = infer_conv ~catch_incon:false ~pb:pbty ~ts:(fst ts)
env evd term1 term2
in
- if b then evd, None
- else evd, Some (ConversionFailed (env,term1,term2))
- with Univ.UniverseInconsistency e -> evd, Some (UnifUnivInconsistency e)
+ if b then Success evd
+ else UnifFailure (evd, ConversionFailed (env,term1,term2))
+ with Univ.UniverseInconsistency e -> UnifFailure (evd, UnifUnivInconsistency e)
in
match e with
- | None -> Some (evd, e)
- | Some e ->
- if is_ground_env evd env then Some (evd, Some e)
- else None)
+ | UnifFailure (evd, e) when not (is_ground_env evd env) -> None
+ | _ -> Some e)
else None
in
match ground_test with
- | Some (evd, None) -> Success evd
- | Some (evd, Some e) -> UnifFailure (evd,e)
+ | Some result -> result
| None ->
(* Until pattern-unification is used consistently, use nohdbeta to not
destroy beta-redexes that can be used for 1st-order unification *)
--
cgit v1.2.3
From 4d25b224b91959b85fcd68c825a307ec684f0bac Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Sun, 28 Feb 2016 18:28:14 +0100
Subject: Printing notations: Cleaning in anticipation of fixing #4592.
- Making a clear distinction between expressions of the notation which
are associated to binding variables only (as in `Notation "'lam' x ,
P" := (fun x => P)" or `Notation "'exists2' x : t , p & q" := (ex2
(fun x:t => p) (fun x:t => q))') and those which are associated to
at list one subterm (e.g. `Notation "x .+1" := (S x)' but also
"Notation "{# x | P }" := (ex2 _ (fun y => x = F y) (fun x => P))'
as in #4592). The former have type NtnTypeOnlyBinder.
- Thus avoiding in particular encoding too early Anonymous as GHole
and "Name id" as "GVar id".
There is a non-trivial alpha-conversion work to do to get #4592
working. See comments in Notation_ops.add_env.
---
interp/constrintern.ml | 10 +--
interp/constrintern.mli | 2 +-
interp/notation.ml | 3 +-
interp/notation_ops.ml | 183 ++++++++++++++++++++++++++++++++----------------
intf/notation_term.mli | 2 +-
toplevel/metasyntax.ml | 20 ++++--
6 files changed, 146 insertions(+), 74 deletions(-)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 70802d5cba..36f88fc3cc 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -275,7 +275,8 @@ let error_expect_binder_notation_type loc id =
let set_var_scope loc id istermvar env ntnvars =
try
- let idscopes,typ = Id.Map.find id ntnvars in
+ let isonlybinding,idscopes,typ = Id.Map.find id ntnvars in
+ if istermvar then isonlybinding := false;
let () = if istermvar then
(* scopes have no effect on the interpretation of identifiers *)
begin match !idscopes with
@@ -629,7 +630,7 @@ let subst_aconstr_in_glob_constr loc intern (_,ntnvars as lvar) subst infos c =
let split_by_type ids =
List.fold_right (fun (x,(scl,typ)) (l1,l2,l3) ->
match typ with
- | NtnTypeConstr -> ((x,scl)::l1,l2,l3)
+ | NtnTypeConstr | NtnTypeOnlyBinder -> ((x,scl)::l1,l2,l3)
| NtnTypeConstrList -> (l1,(x,scl)::l2,l3)
| NtnTypeBinderList -> (l1,l2,(x,scl)::l3)) ids ([],[],[])
@@ -1845,7 +1846,7 @@ let intern_constr_pattern env ?(as_type=false) ?(ltacvars=empty_ltac_sign) c =
let interp_notation_constr ?(impls=empty_internalization_env) nenv a =
let env = Global.env () in
(* [vl] is intended to remember the scope of the free variables of [a] *)
- let vl = Id.Map.map (fun typ -> (ref None, typ)) nenv.ninterp_var_type in
+ let vl = Id.Map.map (fun typ -> (ref true, ref None, typ)) nenv.ninterp_var_type in
let c = internalize (Global.env()) {ids = extract_ids env; unb = false;
tmp_scope = None; scopes = []; impls = impls}
false (empty_ltac_sign, vl) a in
@@ -1854,7 +1855,8 @@ let interp_notation_constr ?(impls=empty_internalization_env) nenv a =
(* Splits variables into those that are binding, bound, or both *)
(* binding and bound *)
let out_scope = function None -> None,[] | Some (a,l) -> a,l in
- let vars = Id.Map.map (fun (sc, typ) -> (out_scope !sc, typ)) vl in
+ let vars = Id.Map.map (fun (isonlybinding, sc, typ) ->
+ (!isonlybinding, out_scope !sc, typ)) vl in
(* Returns [a] and the ordered list of variables with their scopes *)
vars, a
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index 73ecc437dd..eea76aa310 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -185,7 +185,7 @@ val global_reference_in_absolute_module : DirPath.t -> Id.t -> constr
guaranteed to have the same domain as the input one. *)
val interp_notation_constr : ?impls:internalization_env ->
notation_interp_env -> constr_expr ->
- (subscopes * notation_var_internalization_type) Id.Map.t *
+ (bool * subscopes * notation_var_internalization_type) Id.Map.t *
notation_constr
(** Globalization options *)
diff --git a/interp/notation.ml b/interp/notation.ml
index 5c10e0af71..04918bf7dd 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -529,9 +529,10 @@ let pair_eq f g (x1, y1) (x2, y2) = f x1 x2 && g y1 y2
let ntpe_eq t1 t2 = match t1, t2 with
| NtnTypeConstr, NtnTypeConstr -> true
+| NtnTypeOnlyBinder, NtnTypeOnlyBinder -> true
| NtnTypeConstrList, NtnTypeConstrList -> true
| NtnTypeBinderList, NtnTypeBinderList -> true
-| (NtnTypeConstr | NtnTypeConstrList | NtnTypeBinderList), _ -> false
+| (NtnTypeConstr | NtnTypeOnlyBinder | NtnTypeConstrList | NtnTypeBinderList), _ -> false
let vars_eq (id1, (sc1, tp1)) (id2, (sc2, tp2)) =
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 51dfadac02..6561000c47 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -567,6 +567,18 @@ let abstract_return_type_context_notation_constr =
abstract_return_type_context snd
(fun na c -> NLambda(na,NHole (Evar_kinds.InternalHole, Misctypes.IntroAnonymous, None),c))
+let is_term_meta id metas =
+ try match Id.List.assoc id metas with _,(NtnTypeConstr | NtnTypeConstrList) -> true | _ -> false
+ with Not_found -> false
+
+let is_onlybinding_meta id metas =
+ try match Id.List.assoc id metas with _,NtnTypeOnlyBinder -> true | _ -> false
+ with Not_found -> false
+
+let is_bindinglist_meta id metas =
+ try match Id.List.assoc id metas with _,NtnTypeBinderList -> true | _ -> false
+ with Not_found -> false
+
exception No_match
let rec alpha_var id1 id2 = function
@@ -575,26 +587,67 @@ let rec alpha_var id1 id2 = function
| _::idl -> alpha_var id1 id2 idl
| [] -> Id.equal id1 id2
-let add_env alp (sigma,sigmalist,sigmabinders) var v =
+let add_env (alp,alpmetas) (terms,onlybinders,termlists,binderlists) var v =
(* Check that no capture of binding variables occur *)
+ (* [alp] is used when matching a pattern "fun x => ... x ... ?var ... x ..."
+ with an actual term "fun z => ... z ..." when "x" is not bound in the
+ notation, as in "Notation "'twice_upto' y" := (fun x => x + x + y)". Then
+ we keep (z,x) in alp, and we have to check that what the [v] which is bound
+ to [var] does not contain z *)
if List.exists (fun (id,_) ->occur_glob_constr id v) alp then raise No_match;
+ (* [alpmetas] is used when matching a pattern "fun x => ... x ... ?var ... x ..."
+ with an actual term "fun z => ... z ..." when "x" is bound in the
+ notation and the name "x" cannot be changed to "z", e.g. because
+ used at another occurrence, as in "Notation "'lam' y , P & Q" :=
+ ((fun y => P),(fun y => Q))". Then, we keep (z,y) in alpmetas, and we
+ have to check that "fun z => ... z ..." denotes the same term as
+ "fun x => ... x ... ?var ... x" up to alpha-conversion when [var]
+ is instantiated by [v];
+ Currently, we fail, but, eventually, [x] in [v] could be replaced by [x],
+ and, in match_, when finding "x" in subterm, failing because of a capture,
+ and, in match_, when finding "z" in subterm, replacing it with "x",
+ and, in an even further step, being even more robust, independent of the order, so
+ that e.g. the notation for ex2 works on "x y |- ex2 (fun x => y=x) (fun y => x=y)"
+ by giving, say, "exists2 x0, y=x0 & x=x0", but this would typically require the
+ glob_constr_eq in bind_term_env to be postponed in match_notation_constr, and the
+ choice of exact variable be done there; but again, this would be a non-trivial
+ refinement *)
+ if alpmetas != [] then raise No_match;
+ (* TODO: handle the case of multiple occs in different scopes *)
+ ((var,v)::terms,onlybinders,termlists,binderlists)
+
+let add_binding_env alp (terms,onlybinders,termlists,binderlists) var v =
(* TODO: handle the case of multiple occs in different scopes *)
- ((var,v)::sigma,sigmalist,sigmabinders)
+ (terms,(var,v)::onlybinders,termlists,binderlists)
-let bind_env alp (sigma,sigmalist,sigmabinders as fullsigma) var v =
+let add_bindinglist_env (terms,onlybinders,termlists,binderlists) x bl =
+ (terms,onlybinders,termlists,(x,List.rev bl)::binderlists)
+
+let bind_term_env alp (terms,onlybinders,termlists,binderlists as sigma) var v =
try
- let v' = Id.List.assoc var sigma in
+ let v' = Id.List.assoc var terms in
match v, v' with
- | GHole _, _ -> fullsigma
+ | GHole _, _ -> sigma
| _, GHole _ ->
- add_env alp (Id.List.remove_assoc var sigma,sigmalist,sigmabinders) var v
+ let sigma = Id.List.remove_assoc var terms,onlybinders,termlists,binderlists in
+ add_env alp sigma var v
| _, _ ->
- if glob_constr_eq v v' then fullsigma
+ if glob_constr_eq v v' then sigma
else raise No_match
- with Not_found -> add_env alp fullsigma var v
+ with Not_found -> add_env alp sigma var v
-let bind_binder (sigma,sigmalist,sigmabinders) x bl =
- (sigma,sigmalist,(x,List.rev bl)::sigmabinders)
+let bind_binding_env alp (terms,onlybinders,termlists,binderlists as sigma) var v =
+ try
+ let v' = Id.List.assoc var onlybinders in
+ match v, v' with
+ | Anonymous, _ -> alp, sigma
+ | _, Anonymous ->
+ let sigma = (terms,Id.List.remove_assoc var onlybinders,termlists,binderlists) in
+ alp, add_binding_env alp sigma var v
+ | Name id1, Name id2 ->
+ if Id.equal id1 id2 then alp,sigma
+ else (fst alp,(id1,id2)::snd alp),sigma
+ with Not_found -> alp, add_binding_env alp sigma var v
let match_fix_kind fk1 fk2 =
match (fk1,fk2) with
@@ -615,12 +668,16 @@ let match_opt f sigma t1 t2 = match (t1,t2) with
| _ -> raise No_match
let match_names metas (alp,sigma) na1 na2 = match (na1,na2) with
- | (_,Name id2) when Id.List.mem id2 (fst metas) ->
- let rhs = match na1 with
- | Name id1 -> GVar (Loc.ghost,id1)
- | Anonymous -> GHole (Loc.ghost,Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None) in
- alp, bind_env alp sigma id2 rhs
- | (Name id1,Name id2) -> (id1,id2)::alp,sigma
+ | (na1,Name id2) when is_onlybinding_meta id2 metas ->
+ bind_binding_env alp sigma id2 na1
+ | (Name id1,Name id2) when is_term_meta id2 metas ->
+ (* We let the non-binding occurrence define the rhs and hence reason up to *)
+ (* alpha-conversion for the given occurrence of the name (see #)) *)
+ (fst alp,(id1,id2)::snd alp), sigma
+ | (Anonymous,Name id2) when is_term_meta id2 metas ->
+ (* We let the non-binding occurrence define the rhs *)
+ alp, sigma
+ | (Name id1,Name id2) -> ((id1,id2)::fst alp, snd alp),sigma
| (Anonymous,Anonymous) -> alp,sigma
| _ -> raise No_match
@@ -645,36 +702,38 @@ let rec match_iterated_binders islambda decls = function
((na,Explicit (*?*), Some c,GHole(loc,Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None))::decls) b
| b -> (decls,b)
-let remove_sigma x (sigmavar,sigmalist,sigmabinders) =
- (Id.List.remove_assoc x sigmavar,sigmalist,sigmabinders)
+let remove_sigma x (terms,onlybinders,termlists,binderlists) =
+ (Id.List.remove_assoc x terms,onlybinders,termlists,binderlists)
+
+let add_ldots_var metas = (ldots_var,((None,[]),NtnTypeConstr))::metas
let match_abinderlist_with_app match_fun metas sigma rest x iter termin =
let rec aux sigma acc rest =
try
- let sigma = match_fun (ldots_var::fst metas,snd metas) sigma rest iter in
- let rest = Id.List.assoc ldots_var (pi1 sigma) in
+ let (terms,_,_,binderlists as sigma) = match_fun (add_ldots_var metas) sigma rest iter in
+ let rest = Id.List.assoc ldots_var terms in
let b =
- match Id.List.assoc x (pi3 sigma) with [b] -> b | _ ->assert false
+ match Id.List.assoc x binderlists with [b] -> b | _ ->assert false
in
let sigma = remove_sigma x (remove_sigma ldots_var sigma) in
aux sigma (b::acc) rest
with No_match when not (List.is_empty acc) ->
acc, match_fun metas sigma rest termin in
let bl,sigma = aux sigma [] rest in
- bind_binder sigma x bl
+ add_bindinglist_env sigma x bl
let match_alist match_fun metas sigma rest x iter termin lassoc =
let rec aux sigma acc rest =
try
- let sigma = match_fun (ldots_var::fst metas,snd metas) sigma rest iter in
- let rest = Id.List.assoc ldots_var (pi1 sigma) in
- let t = Id.List.assoc x (pi1 sigma) in
+ let (terms,_,_,_ as sigma) = match_fun (add_ldots_var metas) sigma rest iter in
+ let rest = Id.List.assoc ldots_var terms in
+ let t = Id.List.assoc x terms in
let sigma = remove_sigma x (remove_sigma ldots_var sigma) in
aux sigma (t::acc) rest
with No_match when not (List.is_empty acc) ->
acc, match_fun metas sigma rest termin in
- let l,sigma = aux sigma [] rest in
- (pi1 sigma, (x,if lassoc then l else List.rev l)::pi2 sigma, pi3 sigma)
+ let l,(terms,onlybinders,termlists,binderlists as sigma) = aux sigma [] rest in
+ (terms,onlybinders,(x,if lassoc then l else List.rev l)::termlists, binderlists)
let does_not_come_from_already_eta_expanded_var =
(* This is hack to avoid looping on a rule with rhs of the form *)
@@ -688,11 +747,11 @@ let does_not_come_from_already_eta_expanded_var =
(* checked). *)
function GVar _ -> false | _ -> true
-let rec match_ inner u alp (tmetas,blmetas as metas) sigma a1 a2 =
+let rec match_ inner u alp metas sigma a1 a2 =
match (a1,a2) with
(* Matching notation variable *)
- | r1, NVar id2 when Id.List.mem id2 tmetas -> bind_env alp sigma id2 r1
+ | r1, NVar id2 when is_term_meta id2 metas -> bind_term_env alp sigma id2 r1
(* Matching recursive notations for terms *)
| r1, NList (x,_,iter,termin,lassoc) ->
@@ -702,25 +761,26 @@ let rec match_ inner u alp (tmetas,blmetas as metas) sigma a1 a2 =
| GLambda (_,na1,bk,t1,b1), NBinderList (x,_,NLambda (Name id2,_,b2),termin)->
let (decls,b) = match_iterated_binders true [(na1,bk,None,t1)] b1 in
(* TODO: address the possibility that termin is a Lambda itself *)
- match_in u alp metas (bind_binder sigma x decls) b termin
+ match_in u alp metas (add_bindinglist_env sigma x decls) b termin
| GProd (_,na1,bk,t1,b1), NBinderList (x,_,NProd (Name id2,_,b2),termin)
when na1 != Anonymous ->
let (decls,b) = match_iterated_binders false [(na1,bk,None,t1)] b1 in
(* TODO: address the possibility that termin is a Prod itself *)
- match_in u alp metas (bind_binder sigma x decls) b termin
+ match_in u alp metas (add_bindinglist_env sigma x decls) b termin
(* Matching recursive notations for binders: general case *)
| r, NBinderList (x,_,iter,termin) ->
match_abinderlist_with_app (match_hd u alp) metas sigma r x iter termin
(* Matching individual binders as part of a recursive pattern *)
- | GLambda (_,na,bk,t,b1), NLambda (Name id,_,b2) when Id.List.mem id blmetas ->
- match_in u alp metas (bind_binder sigma id [(na,bk,None,t)]) b1 b2
+ | GLambda (_,na,bk,t,b1), NLambda (Name id,_,b2)
+ when is_bindinglist_meta id metas ->
+ match_in u alp metas (add_bindinglist_env sigma id [(na,bk,None,t)]) b1 b2
| GProd (_,na,bk,t,b1), NProd (Name id,_,b2)
- when Id.List.mem id blmetas && na != Anonymous ->
- match_in u alp metas (bind_binder sigma id [(na,bk,None,t)]) b1 b2
+ when is_bindinglist_meta id metas && na != Anonymous ->
+ match_in u alp metas (add_bindinglist_env sigma id [(na,bk,None,t)]) b1 b2
(* Matching compositionally *)
- | GVar (_,id1), NVar id2 when alpha_var id1 id2 alp -> sigma
+ | GVar (_,id1), NVar id2 when alpha_var id1 id2 (fst alp) -> sigma
| GRef (_,r1,_), NRef r2 when (eq_gr r1 r2) -> sigma
| GPatVar (_,(_,n1)), NPatVar n2 when Id.equal n1 n2 -> sigma
| GApp (loc,f1,l1), NApp (f2,l2) ->
@@ -799,9 +859,9 @@ let rec match_ inner u alp (tmetas,blmetas as metas) sigma a1 a2 =
let t1 = GHole(Loc.ghost,Evar_kinds.BinderType (Name id'),Misctypes.IntroAnonymous,None) in
let sigma = match t2 with
| NHole _ -> sigma
- | NVar id2 -> bind_env alp sigma id2 t1
+ | NVar id2 -> bind_term_env alp sigma id2 t1
| _ -> assert false in
- match_in u alp metas (bind_binder sigma id [(Name id',Explicit,None,t1)])
+ match_in u alp metas (add_bindinglist_env sigma id [(Name id',Explicit,None,t1)])
(mkGApp Loc.ghost b1 (GVar (Loc.ghost,id'))) b2
| (GRec _ | GEvar _), _
@@ -823,14 +883,16 @@ and match_equations u alp metas sigma (_,_,patl1,rhs1) (patl2,rhs2) =
(alp,sigma) patl1 patl2 in
match_in u alp metas sigma rhs1 rhs2
+let term_of_binder = function
+ | Name id -> GVar (Loc.ghost,id)
+ | Anonymous -> GHole (Loc.ghost,Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None)
+
let match_notation_constr u c (metas,pat) =
- let test (_, (_, x)) = match x with NtnTypeBinderList -> false | _ -> true in
- let vars = List.partition test metas in
- let vars = (List.map fst (fst vars), List.map fst (snd vars)) in
- let terms,termlists,binders = match_ false u [] vars ([],[],[]) c pat in
+ let terms,binders,termlists,binderlists =
+ match_ false u ([],[]) metas ([],[],[],[]) c pat in
(* Reorder canonically the substitution *)
- let find x =
- try Id.List.assoc x terms
+ let find_binder x =
+ try term_of_binder (Id.List.assoc x binders)
with Not_found ->
(* Happens for binders bound to Anonymous *)
(* Find a better way to propagate Anonymous... *)
@@ -838,11 +900,13 @@ let match_notation_constr u c (metas,pat) =
List.fold_right (fun (x,(scl,typ)) (terms',termlists',binders') ->
match typ with
| NtnTypeConstr ->
- ((find x, scl)::terms',termlists',binders')
+ ((Id.List.assoc x terms, scl)::terms',termlists',binders')
+ | NtnTypeOnlyBinder ->
+ ((find_binder x, scl)::terms',termlists',binders')
| NtnTypeConstrList ->
(terms',(Id.List.assoc x termlists,scl)::termlists',binders')
| NtnTypeBinderList ->
- (terms',termlists',(Id.List.assoc x binders,scl)::binders'))
+ (terms',termlists',(Id.List.assoc x binderlists,scl)::binders'))
metas ([],[],[])
(* Matching cases pattern *)
@@ -851,17 +915,17 @@ let add_patterns_for_params ind l =
let nparams = mib.Declarations.mind_nparams in
Util.List.addn nparams (PatVar (Loc.ghost,Anonymous)) l
-let bind_env_cases_pattern (sigma,sigmalist,x as fullsigma) var v =
+let bind_env_cases_pattern (terms,x,termlists,y as sigma) var v =
try
- let vvar = Id.List.assoc var sigma in
- if cases_pattern_eq v vvar then fullsigma else raise No_match
+ let vvar = Id.List.assoc var terms in
+ if cases_pattern_eq v vvar then sigma else raise No_match
with Not_found ->
(* TODO: handle the case of multiple occs in different scopes *)
- (var,v)::sigma,sigmalist,x
+ (var,v)::terms,x,termlists,y
-let rec match_cases_pattern metas sigma a1 a2 =
+let rec match_cases_pattern metas (terms,x,termlists,y as sigma) a1 a2 =
match (a1,a2) with
- | r1, NVar id2 when Id.List.mem id2 metas -> (bind_env_cases_pattern sigma id2 r1),(0,[])
+ | r1, NVar id2 when Id.List.mem_assoc id2 metas -> (bind_env_cases_pattern sigma id2 r1),(0,[])
| PatVar (_,Anonymous), NHole _ -> sigma,(0,[])
| PatCstr (loc,(ind,_ as r1),largs,_), NRef (ConstructRef r2) when eq_constructor r1 r2 ->
sigma,(0,add_patterns_for_params (fst r1) largs)
@@ -876,14 +940,14 @@ let rec match_cases_pattern metas sigma a1 a2 =
let l1',more_args = Util.List.chop le2 l1 in
(List.fold_left2 (match_cases_pattern_no_more_args metas) sigma l1' l2),(le2,more_args)
| r1, NList (x,_,iter,termin,lassoc) ->
- (match_alist (fun (metas,_) -> match_cases_pattern_no_more_args metas)
- (metas,[]) (pi1 sigma,pi2 sigma,()) r1 x iter termin lassoc),(0,[])
+ (match_alist (match_cases_pattern_no_more_args)
+ metas (terms,(),termlists,()) r1 x iter termin lassoc),(0,[])
| _ -> raise No_match
and match_cases_pattern_no_more_args metas sigma a1 a2 =
match match_cases_pattern metas sigma a1 a2 with
- |out,(_,[]) -> out
- |_ -> raise No_match
+ | out,(_,[]) -> out
+ | _ -> raise No_match
let match_ind_pattern metas sigma ind pats a2 =
match a2 with
@@ -904,16 +968,15 @@ let reorder_canonically_substitution terms termlists metas =
List.fold_right (fun (x,(scl,typ)) (terms',termlists') ->
match typ with
| NtnTypeConstr -> ((Id.List.assoc x terms, scl)::terms',termlists')
+ | NtnTypeOnlyBinder -> assert false
| NtnTypeConstrList -> (terms',(Id.List.assoc x termlists,scl)::termlists')
| NtnTypeBinderList -> assert false)
metas ([],[])
let match_notation_constr_cases_pattern c (metas,pat) =
- let vars = List.map fst metas in
- let (terms,termlists,()),more_args = match_cases_pattern vars ([],[],()) c pat in
+ let (terms,(),termlists,()),more_args = match_cases_pattern metas ([],(),[],()) c pat in
reorder_canonically_substitution terms termlists metas, more_args
let match_notation_constr_ind_pattern ind args (metas,pat) =
- let vars = List.map fst metas in
- let (terms,termlists,()),more_args = match_ind_pattern vars ([],[],()) ind args pat in
+ let (terms,(),termlists,()),more_args = match_ind_pattern metas ([],(),[],()) ind args pat in
reorder_canonically_substitution terms termlists metas, more_args
diff --git a/intf/notation_term.mli b/intf/notation_term.mli
index 3a643b99b2..39a36310d1 100644
--- a/intf/notation_term.mli
+++ b/intf/notation_term.mli
@@ -61,7 +61,7 @@ type subscopes = tmp_scope_name option * scope_name list
(** Type of the meta-variables of an notation_constr: in a recursive pattern x..y,
x carries the sequence of objects bound to the list x..y *)
type notation_var_instance_type =
- | NtnTypeConstr | NtnTypeConstrList | NtnTypeBinderList
+ | NtnTypeConstr | NtnTypeOnlyBinder | NtnTypeConstrList | NtnTypeBinderList
(** Type of variables when interpreting a constr_expr as an notation_constr:
in a recursive pattern x..y, both x and y carry the individual type
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index 0d002aa8e9..98d1a23770 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -1017,9 +1017,10 @@ let make_internalization_vars recvars mainvars typs =
let extratyps = List.map (fun (x,y) -> (y,List.assoc x maintyps)) recvars in
maintyps @ extratyps
-let make_interpretation_type isrec = function
+let make_interpretation_type isrec isonlybinding = function
| NtnInternTypeConstr when isrec -> NtnTypeConstrList
- | NtnInternTypeConstr | NtnInternTypeIdent -> NtnTypeConstr
+ | NtnInternTypeConstr | NtnInternTypeIdent ->
+ if isonlybinding then NtnTypeOnlyBinder else NtnTypeConstr
| NtnInternTypeBinder when isrec -> NtnTypeBinderList
| NtnInternTypeBinder -> error "Type not allowed in recursive notation."
@@ -1029,16 +1030,16 @@ let make_interpretation_vars recvars allvars =
List.equal String.equal l1 l2
in
let check (x, y) =
- let (scope1, _) = Id.Map.find x allvars in
- let (scope2, _) = Id.Map.find y allvars in
+ let (_,scope1, _) = Id.Map.find x allvars in
+ let (_,scope2, _) = Id.Map.find y allvars in
if not (eq_subscope scope1 scope2) then error_not_same_scope x y
in
let () = List.iter check recvars in
let useless_recvars = List.map snd recvars in
let mainvars =
Id.Map.filter (fun x _ -> not (Id.List.mem x useless_recvars)) allvars in
- Id.Map.mapi (fun x (sc, typ) ->
- (sc, make_interpretation_type (Id.List.mem_assoc x recvars) typ)) mainvars
+ Id.Map.mapi (fun x (isonlybinding, sc, typ) ->
+ (sc, make_interpretation_type (Id.List.mem_assoc x recvars) isonlybinding typ)) mainvars
let check_rule_productivity l =
if List.for_all (function NonTerminal _ -> true | _ -> false) l then
@@ -1492,7 +1493,12 @@ let add_syntactic_definition ident (vars,c) local onlyparse =
} in
let nvars, pat = interp_notation_constr nenv c in
let () = nonprintable := nenv.ninterp_only_parse in
- let map id = let (sc, _) = Id.Map.find id nvars in (id, sc) in
+ let map id =
+ let (isonlybinding,sc, _) = Id.Map.find id nvars in
+ (* if a notation contains an ltac:, the body is not analyzed
+ and onlybinding detection fails *)
+ assert (!nonprintable || not isonlybinding);
+ (id, sc) in
List.map map vars, pat
in
let onlyparse = match onlyparse with
--
cgit v1.2.3
From 48327426b59144f1a7181092068077c5a6df7c60 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 10:45:31 +0100
Subject: Moving the "fix" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 2 --
printing/pptactic.ml | 1 -
tactics/coretactics.ml4 | 7 +++++++
tactics/tacintern.ml | 1 -
tactics/tacinterp.ml | 9 ---------
tactics/tacsubst.ml | 1 -
7 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 502f2db4c1..3993f1b371 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -145,7 +145,6 @@ type 'a gen_atomic_tactic_expr =
('nam * 'dtrm intro_pattern_expr located option) option
| TacElim of evars_flag * 'trm with_bindings_arg * 'trm with_bindings option
| TacCase of evars_flag * 'trm with_bindings_arg
- | TacFix of Id.t option * int
| TacMutualFix of Id.t * int * (Id.t * int * 'trm) list
| TacCofix of Id.t option
| TacMutualCofix of Id.t * (Id.t * 'trm) list
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 77b7b05a39..497819b327 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -555,8 +555,6 @@ GEXTEND Gram
TacAtom (!@loc, TacElim (true,cl,el))
| IDENT "case"; icl = induction_clause_list -> TacAtom (!@loc, mkTacCase false icl)
| IDENT "ecase"; icl = induction_clause_list -> TacAtom (!@loc, mkTacCase true icl)
- | "fix"; n = natural -> TacAtom (!@loc, TacFix (None,n))
- | "fix"; id = ident; n = natural -> TacAtom (!@loc, TacFix (Some id,n))
| "fix"; id = ident; n = natural; "with"; fd = LIST1 fixdecl ->
TacAtom (!@loc, TacMutualFix (id,n,List.map mk_fix_tac fd))
| "cofix" -> TacAtom (!@loc, TacCofix None)
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 12667d0f24..fe0be9b255 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -828,7 +828,6 @@ module Make
++ pr_opt pr_eliminator cbo)
| TacCase (ev,cb) ->
hov 1 (primitive (with_evars ev "case") ++ spc () ++ pr_with_bindings_arg cb)
- | TacFix (ido,n) -> hov 1 (primitive "fix" ++ pr_opt pr_id ido ++ pr_intarg n)
| TacMutualFix (id,n,l) ->
hov 1 (
primitive "fix" ++ spc () ++ pr_id id ++ pr_intarg n ++ spc()
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 63fb67e146..c6f59f79e3 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -192,6 +192,13 @@ TACTIC EXTEND admit
[ "admit" ] -> [ Proofview.give_up ]
END
+(* Fix *)
+
+TACTIC EXTEND fix
+ [ "fix" natural(n) ] -> [ Proofview.V82.tactic (Tactics.fix None n) ]
+| [ "fix" ident(id) natural(n) ] -> [ Proofview.V82.tactic (Tactics.fix (Some id) n) ]
+END
+
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
open Tacexpr
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index cbb9db65c1..b4a595b051 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -491,7 +491,6 @@ let rec intern_atomic lf ist x =
TacElim (ev,intern_constr_with_bindings_arg ist cb,
Option.map (intern_constr_with_bindings ist) cbo)
| TacCase (ev,cb) -> TacCase (ev,intern_constr_with_bindings_arg ist cb)
- | TacFix (idopt,n) -> TacFix (Option.map (intern_ident lf ist) idopt,n)
| TacMutualFix (id,n,l) ->
let f (id,n,c) = (intern_ident lf ist id,n,intern_type ist c) in
TacMutualFix (intern_ident lf ist id, n, List.map f l)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index d5a1215b87..f74ea4fc9b 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1749,15 +1749,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
in
Tacticals.New.tclWITHHOLES ev named_tac sigma
end }
- | TacFix (idopt,n) ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = project gl in
- let idopt = Option.map (interp_ident ist env sigma) idopt in
- name_atomic ~env
- (TacFix(idopt,n))
- (Proofview.V82.tactic (Tactics.fix idopt n))
- end }
| TacMutualFix (id,n,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 4a5fa9828e..f611f03684 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -146,7 +146,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
TacElim (ev,subst_glob_with_bindings_arg subst cb,
Option.map (subst_glob_with_bindings subst) cbo)
| TacCase (ev,cb) -> TacCase (ev,subst_glob_with_bindings_arg subst cb)
- | TacFix (idopt,n) as x -> x
| TacMutualFix (id,n,l) ->
TacMutualFix(id,n,List.map (fun (id,n,c) -> (id,n,subst_glob_constr subst c)) l)
| TacCofix idopt as x -> x
--
cgit v1.2.3
From bda8b2e8f90235ca875422f211cb781068b20b3c Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 10:54:08 +0100
Subject: Moving the "cofix" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 2 --
printing/pptactic.ml | 2 --
tactics/coretactics.ml4 | 8 +++++++-
tactics/tacintern.ml | 1 -
tactics/tacinterp.ml | 9 ---------
tactics/tacsubst.ml | 1 -
7 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 3993f1b371..33a96150c1 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -146,7 +146,6 @@ type 'a gen_atomic_tactic_expr =
| TacElim of evars_flag * 'trm with_bindings_arg * 'trm with_bindings option
| TacCase of evars_flag * 'trm with_bindings_arg
| TacMutualFix of Id.t * int * (Id.t * int * 'trm) list
- | TacCofix of Id.t option
| TacMutualCofix of Id.t * (Id.t * 'trm) list
| TacAssert of
bool * 'tacexpr option *
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 497819b327..6c3918be3a 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -557,8 +557,6 @@ GEXTEND Gram
| IDENT "ecase"; icl = induction_clause_list -> TacAtom (!@loc, mkTacCase true icl)
| "fix"; id = ident; n = natural; "with"; fd = LIST1 fixdecl ->
TacAtom (!@loc, TacMutualFix (id,n,List.map mk_fix_tac fd))
- | "cofix" -> TacAtom (!@loc, TacCofix None)
- | "cofix"; id = ident -> TacAtom (!@loc, TacCofix (Some id))
| "cofix"; id = ident; "with"; fd = LIST1 cofixdecl ->
TacAtom (!@loc, TacMutualCofix (id,List.map mk_cofix_tac fd))
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index fe0be9b255..05c3b3bf42 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -832,8 +832,6 @@ module Make
hov 1 (
primitive "fix" ++ spc () ++ pr_id id ++ pr_intarg n ++ spc()
++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_fix_tac l)
- | TacCofix ido ->
- hov 1 (primitive "cofix" ++ pr_opt pr_id ido)
| TacMutualCofix (id,l) ->
hov 1 (
primitive "cofix" ++ spc () ++ pr_id id ++ spc()
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index c6f59f79e3..27efc06cca 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -199,6 +199,13 @@ TACTIC EXTEND fix
| [ "fix" ident(id) natural(n) ] -> [ Proofview.V82.tactic (Tactics.fix (Some id) n) ]
END
+(* Cofix *)
+
+TACTIC EXTEND cofix
+ [ "cofix" ] -> [ Proofview.V82.tactic (Tactics.cofix None) ]
+| [ "cofix" ident(id) ] -> [ Proofview.V82.tactic (Tactics.cofix (Some id)) ]
+END
+
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
open Tacexpr
@@ -217,7 +224,6 @@ let initial_atomic () =
"compute", TacReduce(Cbv Redops.all_flags,nocl);
"intro", TacIntroMove(None,MoveLast);
"intros", TacIntroPattern [];
- "cofix", TacCofix None;
]
in
let iter (s, t) = Tacenv.register_ltac false false (Id.of_string s) t in
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index b4a595b051..e7545597cc 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -494,7 +494,6 @@ let rec intern_atomic lf ist x =
| TacMutualFix (id,n,l) ->
let f (id,n,c) = (intern_ident lf ist id,n,intern_type ist c) in
TacMutualFix (intern_ident lf ist id, n, List.map f l)
- | TacCofix idopt -> TacCofix (Option.map (intern_ident lf ist) idopt)
| TacMutualCofix (id,l) ->
let f (id,c) = (intern_ident lf ist id,intern_type ist c) in
TacMutualCofix (intern_ident lf ist id, List.map f l)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index f74ea4fc9b..2a741ee367 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1764,15 +1764,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
Sigma.Unsafe.of_pair (tac, sigma)
end }
end
- | TacCofix idopt ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = project gl in
- let idopt = Option.map (interp_ident ist env sigma) idopt in
- name_atomic ~env
- (TacCofix (idopt))
- (Proofview.V82.tactic (Tactics.cofix idopt))
- end }
| TacMutualCofix (id,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"") begin
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index f611f03684..faf068bfd5 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -148,7 +148,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacCase (ev,cb) -> TacCase (ev,subst_glob_with_bindings_arg subst cb)
| TacMutualFix (id,n,l) ->
TacMutualFix(id,n,List.map (fun (id,n,c) -> (id,n,subst_glob_constr subst c)) l)
- | TacCofix idopt as x -> x
| TacMutualCofix (id,l) ->
TacMutualCofix (id, List.map (fun (id,c) -> (id,subst_glob_constr subst c)) l)
| TacAssert (b,otac,na,c) ->
--
cgit v1.2.3
From d0bc16d1a0626f4137797bbf0c91e972a0ff43ac Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 11:05:26 +0100
Subject: Moving the "clear" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 4 ----
printing/pptactic.ml | 9 ---------
tactics/coretactics.ml4 | 10 ++++++++++
tactics/tacintern.ml | 1 -
tactics/tacinterp.ml | 11 -----------
tactics/tacsubst.ml | 1 -
test-suite/bugs/closed/3612.v | 3 +++
toplevel/vernacentries.ml | 9 +++++++--
9 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 33a96150c1..10c616627a 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -161,7 +161,6 @@ type 'a gen_atomic_tactic_expr =
| TacDoubleInduction of quantified_hypothesis * quantified_hypothesis
(* Context management *)
- | TacClear of bool * 'nam list
| TacClearBody of 'nam list
| TacMove of 'nam * 'nam move_location
| TacRename of ('nam *'nam) list
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 6c3918be3a..ad5f78b46d 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -618,10 +618,6 @@ GEXTEND Gram
TacAtom (!@loc, TacInductionDestruct(false,true,icl))
(* Context management *)
- | IDENT "clear"; "-"; l = LIST1 id_or_meta -> TacAtom (!@loc, TacClear (true, l))
- | IDENT "clear"; l = LIST0 id_or_meta ->
- let is_empty = match l with [] -> true | _ -> false in
- TacAtom (!@loc, TacClear (is_empty, l))
| IDENT "clearbody"; l = LIST1 id_or_meta -> TacAtom (!@loc, TacClearBody l)
| IDENT "move"; hfrom = id_or_meta; hto = move_location ->
TacAtom (!@loc, TacMove (hfrom,hto))
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 05c3b3bf42..c61b80c834 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -793,7 +793,6 @@ module Make
let rec pr_atom0 a = tag_atom a (match a with
| TacIntroPattern [] -> primitive "intros"
| TacIntroMove (None,MoveLast) -> primitive "intro"
- | TacClear (true,[]) -> primitive "clear"
| t -> str "(" ++ pr_atom1 t ++ str ")"
)
@@ -899,14 +898,6 @@ module Make
)
(* Context management *)
- | TacClear (true,[]) as t ->
- pr_atom0 t
- | TacClear (keep,l) ->
- hov 1 (
- primitive "clear" ++ spc ()
- ++ (if keep then str "- " else mt ())
- ++ prlist_with_sep spc pr.pr_name l
- )
| TacClearBody l ->
hov 1 (
primitive "clearbody" ++ spc ()
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 27efc06cca..ab97dad706 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -206,6 +206,16 @@ TACTIC EXTEND cofix
| [ "cofix" ident(id) ] -> [ Proofview.V82.tactic (Tactics.cofix (Some id)) ]
END
+(* Clear *)
+
+TACTIC EXTEND clear
+ [ "clear" hyp_list(ids) ] -> [
+ if List.is_empty ids then Tactics.keep []
+ else Proofview.V82.tactic (Tactics.clear ids)
+ ]
+| [ "clear" "-" ne_hyp_list(ids) ] -> [ Tactics.keep ids ]
+END
+
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
open Tacexpr
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index e7545597cc..bea8d3469b 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -525,7 +525,6 @@ let rec intern_atomic lf ist x =
let h2 = intern_quantified_hypothesis ist h2 in
TacDoubleInduction (h1,h2)
(* Context management *)
- | TacClear (b,l) -> TacClear (b,List.map (intern_hyp ist) l)
| TacClearBody l -> TacClearBody (List.map (intern_hyp ist) l)
| TacMove (id1,id2) ->
TacMove (intern_hyp ist id1,intern_move_location ist id2)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 2a741ee367..74121d3abe 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1881,17 +1881,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
(TacDoubleInduction (h1,h2))
(Elim.h_double_induction h1 h2)
(* Context management *)
- | TacClear (b,l) ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = pf_env gl in
- let sigma = project gl in
- let l = interp_hyp_list ist env sigma l in
- if b then name_atomic ~env (TacClear (b, l)) (Tactics.keep l)
- else
- (* spiwack: until the tactic is in the monad *)
- let tac = Proofview.V82.tactic (fun gl -> Tactics.clear l gl) in
- Proofview.Trace.name_tactic (fun () -> Pp.str"") tac
- end }
| TacClearBody l ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = pf_env gl in
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index faf068bfd5..0b8dbb6e3a 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -167,7 +167,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacDoubleInduction (h1,h2) as x -> x
(* Context management *)
- | TacClear _ as x -> x
| TacClearBody l as x -> x
| TacMove (id1,id2) as x -> x
| TacRename l as x -> x
diff --git a/test-suite/bugs/closed/3612.v b/test-suite/bugs/closed/3612.v
index 9125ab16dd..25060debe2 100644
--- a/test-suite/bugs/closed/3612.v
+++ b/test-suite/bugs/closed/3612.v
@@ -35,6 +35,9 @@ Axiom path_path_sigma : forall {A : Type} (P : A -> Type) (u v : sigT P)
(r : p..1 = q..1)
(s : transport (fun x => transport P x u.2 = v.2) r p..2 = q..2),
p = q.
+
+Declare ML Module "coretactics".
+
Goal forall (A : Type) (B : forall _ : A, Type) (x : @sigT A (fun x : A => B x))
(xx : @paths (@sigT A (fun x0 : A => B x0)) x x),
@paths (@paths (@sigT A (fun x0 : A => B x0)) x x) xx
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index a6a1546ae3..38832b422f 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -884,8 +884,13 @@ let vernac_set_used_variables e =
(str "Unknown variable: " ++ pr_id id))
l;
let _, to_clear = set_used_variables l in
- vernac_solve
- SelectAll None Tacexpr.(TacAtom (Loc.ghost,TacClear(false,to_clear))) false
+ (** FIXME: too fragile *)
+ let open Tacexpr in
+ let tac = { mltac_plugin = "coretactics"; mltac_tactic = "clear" } in
+ let tac = { mltac_name = tac; mltac_index = 0 } in
+ let arg = Genarg.in_gen (Genarg.rawwit (Genarg.wit_list Constrarg.wit_var)) to_clear in
+ let tac = if List.is_empty to_clear then TacId [] else TacML (Loc.ghost, tac, [TacGeneric arg]) in
+ vernac_solve SelectAll None tac false
(*****************************)
--
cgit v1.2.3
From 7dd8c2bf4747c94be6f18d7fdd0e3b593f560a2f Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 11:20:26 +0100
Subject: Moving the "clearbody" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 1 -
printing/pptactic.ml | 5 -----
tactics/coretactics.ml4 | 6 ++++++
tactics/tacintern.ml | 1 -
tactics/tacinterp.ml | 9 ---------
tactics/tacsubst.ml | 1 -
7 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 10c616627a..d936748f2d 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -161,7 +161,6 @@ type 'a gen_atomic_tactic_expr =
| TacDoubleInduction of quantified_hypothesis * quantified_hypothesis
(* Context management *)
- | TacClearBody of 'nam list
| TacMove of 'nam * 'nam move_location
| TacRename of ('nam *'nam) list
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index ad5f78b46d..04ee02f944 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -618,7 +618,6 @@ GEXTEND Gram
TacAtom (!@loc, TacInductionDestruct(false,true,icl))
(* Context management *)
- | IDENT "clearbody"; l = LIST1 id_or_meta -> TacAtom (!@loc, TacClearBody l)
| IDENT "move"; hfrom = id_or_meta; hto = move_location ->
TacAtom (!@loc, TacMove (hfrom,hto))
| IDENT "rename"; l = LIST1 rename SEP "," -> TacAtom (!@loc, TacRename l)
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index c61b80c834..b1d6fb0c0f 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -898,11 +898,6 @@ module Make
)
(* Context management *)
- | TacClearBody l ->
- hov 1 (
- primitive "clearbody" ++ spc ()
- ++ prlist_with_sep spc pr.pr_name l
- )
| TacMove (id1,id2) ->
hov 1 (
primitive "move"
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index ab97dad706..b68aab621e 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -216,6 +216,12 @@ TACTIC EXTEND clear
| [ "clear" "-" ne_hyp_list(ids) ] -> [ Tactics.keep ids ]
END
+(* Clearbody *)
+
+TACTIC EXTEND clearbody
+ [ "clearbody" ne_hyp_list(ids) ] -> [ Tactics.clear_body ids ]
+END
+
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
open Tacexpr
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index bea8d3469b..9775f103f8 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -525,7 +525,6 @@ let rec intern_atomic lf ist x =
let h2 = intern_quantified_hypothesis ist h2 in
TacDoubleInduction (h1,h2)
(* Context management *)
- | TacClearBody l -> TacClearBody (List.map (intern_hyp ist) l)
| TacMove (id1,id2) ->
TacMove (intern_hyp ist id1,intern_move_location ist id2)
| TacRename l ->
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 74121d3abe..b2f539fb97 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1881,15 +1881,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
(TacDoubleInduction (h1,h2))
(Elim.h_double_induction h1 h2)
(* Context management *)
- | TacClearBody l ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = pf_env gl in
- let sigma = project gl in
- let l = interp_hyp_list ist env sigma l in
- name_atomic ~env
- (TacClearBody l)
- (Tactics.clear_body l)
- end }
| TacMove (id1,id2) ->
Proofview.Goal.enter { enter = begin fun gl ->
Proofview.V82.tactic (Tactics.move_hyp (interp_hyp ist (pf_env gl) (project gl) id1)
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 0b8dbb6e3a..50730eaea1 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -167,7 +167,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacDoubleInduction (h1,h2) as x -> x
(* Context management *)
- | TacClearBody l as x -> x
| TacMove (id1,id2) as x -> x
| TacRename l as x -> x
--
cgit v1.2.3
From 6c4fcb156dea5a71fd227606b87333ae00aacb69 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 11:35:34 +0100
Subject: Moving the "generalize dependent" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 1 -
printing/pptactic.ml | 5 -----
tactics/coretactics.ml4 | 6 ++++++
tactics/tacintern.ml | 1 -
tactics/tacinterp.ml | 6 ------
tactics/tacsubst.ml | 1 -
7 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index d936748f2d..52c07e089a 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -151,7 +151,6 @@ type 'a gen_atomic_tactic_expr =
bool * 'tacexpr option *
'dtrm intro_pattern_expr located option * 'trm
| TacGeneralize of ('trm with_occurrences * Name.t) list
- | TacGeneralizeDep of 'trm
| TacLetTac of Name.t * 'trm * 'nam clause_expr * letin_flag *
intro_pattern_naming_expr located option
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 04ee02f944..238b9a60f7 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -603,7 +603,6 @@ GEXTEND Gram
na = as_name;
l = LIST0 [","; c = pattern_occ; na = as_name -> (c,na)] ->
TacAtom (!@loc, TacGeneralize (((nl,c),na)::l))
- | IDENT "generalize"; IDENT "dependent"; c = constr -> TacAtom (!@loc, TacGeneralizeDep c)
(* Derived basic tactics *)
| IDENT "induction"; ic = induction_clause_list ->
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index b1d6fb0c0f..f4007e25e1 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -854,11 +854,6 @@ module Make
pr_with_occurrences pr.pr_constr cl ++ pr_as_name na)
l
)
- | TacGeneralizeDep c ->
- hov 1 (
- primitive "generalize" ++ spc () ++ str "dependent"
- ++ pr_constrarg c
- )
| TacLetTac (na,c,cl,true,_) when Locusops.is_nowhere cl ->
hov 1 (primitive "pose" ++ pr_pose pr.pr_constr pr.pr_lconstr na c)
| TacLetTac (na,c,cl,b,e) ->
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index b68aab621e..5862e0f8a0 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -222,6 +222,12 @@ TACTIC EXTEND clearbody
[ "clearbody" ne_hyp_list(ids) ] -> [ Tactics.clear_body ids ]
END
+(* Generalize dependent *)
+
+TACTIC EXTEND generalize_dependent
+ [ "generalize" "dependent" constr(c) ] -> [ Proofview.V82.tactic (Tactics.generalize_dep c) ]
+END
+
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
open Tacexpr
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index 9775f103f8..d5f7c72ec1 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -505,7 +505,6 @@ let rec intern_atomic lf ist x =
TacGeneralize (List.map (fun (c,na) ->
intern_constr_with_occurrences ist c,
intern_name lf ist na) cl)
- | TacGeneralizeDep c -> TacGeneralizeDep (intern_constr ist c)
| TacLetTac (na,c,cls,b,eqpat) ->
let na = intern_name lf ist na in
TacLetTac (na,intern_constr ist c,
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index b2f539fb97..d1a47dce5a 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1803,12 +1803,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
(TacGeneralize cl)
(Proofview.V82.tactic (Tactics.generalize_gen cl))) sigma
end }
- | TacGeneralizeDep c ->
- (new_interp_constr ist c) (fun c ->
- name_atomic (* spiwack: probably needs a goal environment *)
- (TacGeneralizeDep c)
- (Proofview.V82.tactic (Tactics.generalize_dep c))
- )
| TacLetTac (na,c,clp,b,eqpat) ->
Proofview.V82.nf_evar_goals <*>
Proofview.Goal.nf_enter { enter = begin fun gl ->
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 50730eaea1..36e0b4278e 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -154,7 +154,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
TacAssert (b,Option.map (subst_tactic subst) otac,na,subst_glob_constr subst c)
| TacGeneralize cl ->
TacGeneralize (List.map (on_fst (subst_constr_with_occurrences subst))cl)
- | TacGeneralizeDep c -> TacGeneralizeDep (subst_glob_constr subst c)
| TacLetTac (id,c,clp,b,eqpat) ->
TacLetTac (id,subst_glob_constr subst c,clp,b,eqpat)
--
cgit v1.2.3
From ae3bbff3ca2564fe24bdf3dd517c82807eae9151 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 12:11:52 +0100
Subject: Moving the "symmetry" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 3 ---
parsing/g_tactic.ml4 | 2 --
printing/pptactic.ml | 4 ----
tactics/coretactics.ml4 | 1 +
tactics/tacintern.ml | 4 ----
tactics/tacinterp.ml | 10 ----------
tactics/tacsubst.ml | 3 ---
7 files changed, 1 insertion(+), 26 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 52c07e089a..3f1d0fd76c 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -170,9 +170,6 @@ type 'a gen_atomic_tactic_expr =
| TacReduce of ('trm,'cst,'pat) red_expr_gen * 'nam clause_expr
| TacChange of 'pat option * 'dtrm * 'nam clause_expr
- (* Equivalence relations *)
- | TacSymmetry of 'nam clause_expr
-
(* Equality and inversion *)
| TacRewrite of evars_flag *
(bool * multi * 'dtrm with_bindings_arg) list * 'nam clause_expr *
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 238b9a60f7..4587e321f0 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -625,8 +625,6 @@ GEXTEND Gram
| "exists"; bll = opt_bindings -> TacAtom (!@loc, TacSplit (false,bll))
| IDENT "eexists"; bll = opt_bindings ->
TacAtom (!@loc, TacSplit (true,bll))
- (* Equivalence relations *)
- | IDENT "symmetry"; "in"; cl = in_clause -> TacAtom (!@loc, TacSymmetry cl)
(* Equality and inversion *)
| IDENT "rewrite"; l = LIST1 oriented_rewriter SEP ",";
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index f4007e25e1..689ac6e4eb 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -935,10 +935,6 @@ module Make
) ++ pr.pr_dconstr c ++ pr_clauses (Some true) pr.pr_name h
)
- (* Equivalence relations *)
- | TacSymmetry cls ->
- primitive "symmetry" ++ pr_clauses (Some true) pr.pr_name cls
-
(* Equality and inversion *)
| TacRewrite (ev,l,cl,by) ->
hov 1 (
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 5862e0f8a0..55461ef7c5 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -140,6 +140,7 @@ END
TACTIC EXTEND symmetry
[ "symmetry" ] -> [ Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} ]
+| [ "symmetry" clause(cl) ] -> [ Tactics.intros_symmetry cl ]
END
(** Split *)
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index d5f7c72ec1..84df21eb81 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -555,10 +555,6 @@ let rec intern_atomic lf ist x =
TacChange (Some (intern_typed_pattern ist p),intern_constr ist c,
clause_app (intern_hyp_location ist) cl)
- (* Equivalence relations *)
- | TacSymmetry idopt ->
- TacSymmetry (clause_app (intern_hyp_location ist) idopt)
-
(* Equality and inversion *)
| TacRewrite (ev,l,cl,by) ->
TacRewrite
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index d1a47dce5a..81fbcc6db6 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1974,16 +1974,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
end }
end
- (* Equivalence relations *)
- | TacSymmetry c ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = project gl in
- let cl = interp_clause ist env sigma c in
- name_atomic ~env
- (TacSymmetry cl)
- (Tactics.intros_symmetry cl)
- end }
(* Equality and inversion *)
| TacRewrite (ev,l,cl,by) ->
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 36e0b4278e..142a964454 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -178,9 +178,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
TacChange (Option.map (subst_glob_constr_or_pattern subst) op,
subst_glob_constr subst c, cl)
- (* Equivalence relations *)
- | TacSymmetry _ as x -> x
-
(* Equality and inversion *)
| TacRewrite (ev,l,cl,by) ->
TacRewrite (ev,
--
cgit v1.2.3
From 293222e49ff81bc1299b3822d2a8c526ca803307 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 12:40:45 +0100
Subject: Moving the "exists" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 3 ---
parsing/g_tactic.ml4 | 5 -----
printing/pptactic.ml | 8 --------
tactics/coretactics.ml4 | 23 +++++++++++++++++++++++
tactics/tacintern.ml | 3 ---
tactics/tacinterp.ml | 12 ------------
tactics/tacsubst.ml | 3 ---
7 files changed, 23 insertions(+), 34 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 3f1d0fd76c..dae960e0e5 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -163,9 +163,6 @@ type 'a gen_atomic_tactic_expr =
| TacMove of 'nam * 'nam move_location
| TacRename of ('nam *'nam) list
- (* Trmuctors *)
- | TacSplit of evars_flag * 'trm bindings list
-
(* Conversion *)
| TacReduce of ('trm,'cst,'pat) red_expr_gen * 'nam clause_expr
| TacChange of 'pat option * 'dtrm * 'nam clause_expr
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 4587e321f0..e50eca25be 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -621,11 +621,6 @@ GEXTEND Gram
TacAtom (!@loc, TacMove (hfrom,hto))
| IDENT "rename"; l = LIST1 rename SEP "," -> TacAtom (!@loc, TacRename l)
- (* Constructors *)
- | "exists"; bll = opt_bindings -> TacAtom (!@loc, TacSplit (false,bll))
- | IDENT "eexists"; bll = opt_bindings ->
- TacAtom (!@loc, TacSplit (true,bll))
-
(* Equality and inversion *)
| IDENT "rewrite"; l = LIST1 oriented_rewriter SEP ",";
cl = clause_dft_concl; t=opt_by_tactic -> TacAtom (!@loc, TacRewrite (false,l,cl,t))
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 689ac6e4eb..2c57cb811e 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -725,7 +725,6 @@ module Make
(* some shortcuts *)
let _pr_bindings = pr_bindings pr.pr_constr pr.pr_lconstr in
- let pr_ex_bindings = pr_bindings_gen true pr.pr_constr pr.pr_lconstr in
let pr_with_bindings = pr_with_bindings pr.pr_constr pr.pr_lconstr in
let pr_with_bindings_arg_full = pr_with_bindings_arg in
let pr_with_bindings_arg = pr_with_bindings_arg pr.pr_constr pr.pr_lconstr in
@@ -909,13 +908,6 @@ module Make
l
)
- (* Constructors *)
- | TacSplit (ev,l) ->
- hov 1 (
- primitive (with_evars ev "exists")
- ++ prlist_with_sep (fun () -> str",") pr_ex_bindings l
- )
-
(* Conversion *)
| TacReduce (r,h) ->
hov 1 (
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 55461ef7c5..2d5ce53075 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -15,6 +15,7 @@ open Misctypes
open Genredexpr
open Proofview.Notations
+open Sigma.Notations
DECLARE PLUGIN "coretactics"
@@ -145,6 +146,14 @@ END
(** Split *)
+let rec delayed_list = function
+| [] -> { Tacexpr.delayed = fun _ sigma -> Sigma.here [] sigma }
+| x :: l ->
+ { Tacexpr.delayed = fun env sigma ->
+ let Sigma (x, sigma, p) = x.Tacexpr.delayed env sigma in
+ let Sigma (l, sigma, q) = (delayed_list l).Tacexpr.delayed env sigma in
+ Sigma (x :: l, sigma, p +> q) }
+
TACTIC EXTEND split
[ "split" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
END
@@ -165,6 +174,20 @@ TACTIC EXTEND esplit_with
]
END
+TACTIC EXTEND exists
+ [ "exists" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
+| [ "exists" ne_bindings_list_sep(bll, ",") ] -> [
+ Tacticals.New.tclDELAYEDWITHHOLES false (delayed_list bll) (fun bll -> Tactics.split_with_bindings false bll)
+ ]
+END
+
+TACTIC EXTEND eexists
+ [ "eexists" ] -> [ Tactics.split_with_bindings true [NoBindings] ]
+| [ "eexists" ne_bindings_list_sep(bll, ",") ] -> [
+ Tacticals.New.tclDELAYEDWITHHOLES true (delayed_list bll) (fun bll -> Tactics.split_with_bindings true bll)
+ ]
+END
+
(** Intro *)
TACTIC EXTEND intros_until
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index 84df21eb81..e69d3f61e0 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -531,9 +531,6 @@ let rec intern_atomic lf ist x =
intern_hyp ist id1,
intern_hyp ist id2) l)
- (* Constructors *)
- | TacSplit (ev,bll) -> TacSplit (ev,List.map (intern_bindings ist) bll)
-
(* Conversion *)
| TacReduce (r,cl) ->
dump_glob_red_expr r;
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 81fbcc6db6..65fdecc29b 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1894,18 +1894,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
(Tactics.rename_hyp l)
end }
- (* Constructors *)
- | TacSplit (ev,bll) ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = project gl in
- let sigma, bll = List.fold_map (interp_bindings ist env) sigma bll in
- let named_tac =
- let tac = Tactics.split_with_bindings ev bll in
- name_atomic ~env (TacSplit (ev, bll)) tac
- in
- Tacticals.New.tclWITHHOLES ev named_tac sigma
- end }
(* Conversion *)
| TacReduce (r,cl) ->
(* spiwack: until the tactic is in the monad *)
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 142a964454..ba9a74d05a 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -169,9 +169,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacMove (id1,id2) as x -> x
| TacRename l as x -> x
- (* Constructors *)
- | TacSplit (ev,bll) -> TacSplit (ev,List.map (subst_bindings subst) bll)
-
(* Conversion *)
| TacReduce (r,cl) -> TacReduce (subst_redexp subst r, cl)
| TacChange (op,c,cl) ->
--
cgit v1.2.3
From 1397f791b1699b0f04d971465270d5b2df9a6d7f Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Mon, 29 Feb 2016 13:32:39 +0100
Subject: Moving the "move" tactic to TACTIC EXTEND.
---
intf/tacexpr.mli | 1 -
parsing/g_tactic.ml4 | 2 --
printing/pptactic.ml | 6 ------
tactics/coretactics.ml4 | 9 +++++++++
tactics/tacintern.ml | 2 --
tactics/tacinterp.ml | 5 -----
tactics/tacsubst.ml | 1 -
7 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index dae960e0e5..7366bc03e6 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -160,7 +160,6 @@ type 'a gen_atomic_tactic_expr =
| TacDoubleInduction of quantified_hypothesis * quantified_hypothesis
(* Context management *)
- | TacMove of 'nam * 'nam move_location
| TacRename of ('nam *'nam) list
(* Conversion *)
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index e50eca25be..0c90a8bca4 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -617,8 +617,6 @@ GEXTEND Gram
TacAtom (!@loc, TacInductionDestruct(false,true,icl))
(* Context management *)
- | IDENT "move"; hfrom = id_or_meta; hto = move_location ->
- TacAtom (!@loc, TacMove (hfrom,hto))
| IDENT "rename"; l = LIST1 rename SEP "," -> TacAtom (!@loc, TacRename l)
(* Equality and inversion *)
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 2c57cb811e..36863906ea 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -892,12 +892,6 @@ module Make
)
(* Context management *)
- | TacMove (id1,id2) ->
- hov 1 (
- primitive "move"
- ++ brk (1,1) ++ pr.pr_name id1
- ++ Miscprint.pr_move_location pr.pr_name id2
- )
| TacRename l ->
hov 1 (
primitive "rename" ++ brk (1,1)
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 2d5ce53075..74d98176a4 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -194,6 +194,15 @@ TACTIC EXTEND intros_until
[ "intros" "until" quantified_hypothesis(h) ] -> [ Tactics.intros_until h ]
END
+(** Move *)
+
+TACTIC EXTEND move
+ [ "move" hyp(id) "at" "top" ] -> [ Proofview.V82.tactic (Tactics.move_hyp id MoveFirst) ]
+| [ "move" hyp(id) "at" "bottom" ] -> [ Proofview.V82.tactic (Tactics.move_hyp id MoveLast) ]
+| [ "move" hyp(id) "after" hyp(h) ] -> [ Proofview.V82.tactic (Tactics.move_hyp id (MoveAfter h)) ]
+| [ "move" hyp(id) "before" hyp(h) ] -> [ Proofview.V82.tactic (Tactics.move_hyp id (MoveBefore h)) ]
+END
+
(** Revert *)
TACTIC EXTEND revert
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index e69d3f61e0..a069fd7557 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -524,8 +524,6 @@ let rec intern_atomic lf ist x =
let h2 = intern_quantified_hypothesis ist h2 in
TacDoubleInduction (h1,h2)
(* Context management *)
- | TacMove (id1,id2) ->
- TacMove (intern_hyp ist id1,intern_move_location ist id2)
| TacRename l ->
TacRename (List.map (fun (id1,id2) ->
intern_hyp ist id1,
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 65fdecc29b..1a8a95158a 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1875,11 +1875,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
(TacDoubleInduction (h1,h2))
(Elim.h_double_induction h1 h2)
(* Context management *)
- | TacMove (id1,id2) ->
- Proofview.Goal.enter { enter = begin fun gl ->
- Proofview.V82.tactic (Tactics.move_hyp (interp_hyp ist (pf_env gl) (project gl) id1)
- (interp_move_location ist (pf_env gl) (project gl) id2))
- end }
| TacRename l ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = pf_env gl in
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index ba9a74d05a..3f103a290d 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -166,7 +166,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacDoubleInduction (h1,h2) as x -> x
(* Context management *)
- | TacMove (id1,id2) as x -> x
| TacRename l as x -> x
(* Conversion *)
--
cgit v1.2.3
From 508d5a99101097948b6de342295eec0d5c8cbe72 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Thu, 3 Mar 2016 18:59:51 +0100
Subject: Fixing bug #4105: poor escaping in the protocol between CoqIDE and
coqtop.
Printing invalid UTF-8 string startled GTK too much, leading to CoqIDE dying
improperly. We now check that all strings outputed by Coq are proper UTF-8.
This is not perfect, as CoqIDE will sometimes truncate strings which contains
the null character, but at least it should not crash.
---
interp/notation.ml | 6 ++++--
lib/unicode.ml | 7 +++++++
lib/unicode.mli | 3 +++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/interp/notation.ml b/interp/notation.ml
index 5c10e0af71..c4addbf10f 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -314,7 +314,9 @@ let declare_prim_token_interpreter sc interp (patl,uninterp,b) =
patl
let mkNumeral n = Numeral n
-let mkString s = String s
+let mkString = function
+| None -> None
+| Some s -> if Unicode.is_utf8 s then Some (String s) else None
let delay dir int loc x = (dir, (fun () -> int loc x))
@@ -326,7 +328,7 @@ let declare_numeral_interpreter sc dir interp (patl,uninterp,inpat) =
let declare_string_interpreter sc dir interp (patl,uninterp,inpat) =
declare_prim_token_interpreter sc
(fun cont loc -> function String s -> delay dir interp loc s | p -> cont loc p)
- (patl, (fun r -> Option.map mkString (uninterp r)), inpat)
+ (patl, (fun r -> mkString (uninterp r)), inpat)
let check_required_module loc sc (sp,d) =
try let _ = Nametab.global_of_path sp in ()
diff --git a/lib/unicode.ml b/lib/unicode.ml
index 1765e93dcd..cfaa73cc11 100644
--- a/lib/unicode.ml
+++ b/lib/unicode.ml
@@ -168,6 +168,13 @@ let next_utf8 s i =
(c land 0x3F) lsl 6 + (d land 0x3F)
else err ()
+let is_utf8 s =
+ let rec check i =
+ let (off, _) = next_utf8 s i in
+ check (i + off)
+ in
+ try check 0 with End_of_input -> true | Invalid_argument _ -> false
+
(* Check the well-formedness of an identifier *)
let initial_refutation j n s =
diff --git a/lib/unicode.mli b/lib/unicode.mli
index 520203d435..65e75a20d6 100644
--- a/lib/unicode.mli
+++ b/lib/unicode.mli
@@ -26,3 +26,6 @@ val lowercase_first_char : string -> string
(** For extraction, turn a unicode string into an ascii-only one *)
val is_basic_ascii : string -> bool
val ascii_of_ident : string -> string
+
+(** Validate an UTF-8 string *)
+val is_utf8 : string -> bool
--
cgit v1.2.3
From 7461aaedef508570fba6334e18fd10d5b32bda0e Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Thu, 3 Mar 2016 21:35:42 +0100
Subject: Adding a test for the behaviour of open_constr described in #3777.
---
test-suite/typeclasses/open_constr.v | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 test-suite/typeclasses/open_constr.v
diff --git a/test-suite/typeclasses/open_constr.v b/test-suite/typeclasses/open_constr.v
new file mode 100644
index 0000000000..5f1785c706
--- /dev/null
+++ b/test-suite/typeclasses/open_constr.v
@@ -0,0 +1,12 @@
+Tactic Notation "opose" open_constr(foo) := pose foo.
+Class Foo := Build_Foo : Set.
+Axiom f : forall `{Foo}, Set.
+Set Printing Implicit.
+Goal forall `{Foo}, True.
+Proof.
+ intro H.
+ pose f.
+ opose f.
+ Fail let x := (eval hnf in P) in has_evar x.
+ let x := (eval hnf in P0) in has_evar x.
+
--
cgit v1.2.3
From 78b5670a0a1cf7ba31acabe710b311bf13df8745 Mon Sep 17 00:00:00 2001
From: Jason Gross
Date: Thu, 3 Mar 2016 20:34:35 -0500
Subject: Fix a typo in dev/doc/changes.txt
CQQ -> COQ---
dev/doc/changes.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index 2f62be9aff..f7621a4076 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -1,5 +1,5 @@
=========================================
-= CHANGES BETWEEN COQ V8.4 AND CQQ V8.5 =
+= CHANGES BETWEEN COQ V8.4 AND COQ V8.5 =
=========================================
** Refactoring : more mli interfaces and simpler grammar.cma **
--
cgit v1.2.3
From 143bb68613bcb314e2feffd643f539fba9cd3912 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Thu, 3 Mar 2016 23:52:15 +0100
Subject: Uniformizing the parsing of argument scopes in Ltac.
---
parsing/g_constr.ml4 | 2 +-
parsing/g_ltac.ml4 | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 0fe0ac42b1..6eeae925a3 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -215,7 +215,7 @@ GEXTEND Gram
CGeneralization (!@loc, Implicit, None, c)
| "`("; c = operconstr LEVEL "200"; ")" ->
CGeneralization (!@loc, Explicit, None, c)
- | "ltac:"; "("; tac = Tactic.tactic_expr; ")" ->
+ | IDENT "ltac"; ":"; "("; tac = Tactic.tactic_expr; ")" ->
let arg = Genarg.in_gen (Genarg.rawwit Constrarg.wit_tactic) tac in
CHole (!@loc, None, IntroAnonymous, Some arg)
] ]
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 0a11d3928a..45d2a09e73 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -111,8 +111,6 @@ GEXTEND Gram
| g=failkw; n = [ n = int_or_var -> n | -> fail_default_value ];
l = LIST0 message_token -> TacFail (g,n,l)
| st = simple_tactic -> st
- | IDENT "constr"; ":"; c = Constr.constr ->
- TacArg(!@loc,ConstrMayEval(ConstrTerm c))
| a = tactic_top_or_arg -> TacArg(!@loc,a)
| r = reference; la = LIST0 tactic_arg ->
TacArg(!@loc,TacCall (!@loc,r,la)) ]
@@ -140,9 +138,7 @@ GEXTEND Gram
;
(* Tactic arguments *)
tactic_arg:
- [ [ "ltac:"; a = tactic_expr LEVEL "0" -> arg_of_expr a
- | "ltac:"; n = natural -> TacGeneric (genarg_of_int n)
- | a = tactic_top_or_arg -> a
+ [ [ a = tactic_top_or_arg -> a
| r = reference -> Reference r
| c = Constr.constr -> ConstrMayEval (ConstrTerm c)
(* Unambigous entries: tolerated w/o "ltac:" modifier *)
@@ -151,6 +147,9 @@ GEXTEND Gram
(* Can be used as argument and at toplevel in tactic expressions. *)
tactic_top_or_arg:
[ [ IDENT "uconstr"; ":" ; c = uconstr -> UConstr c
+ | IDENT "constr"; ":"; c = Constr.constr -> ConstrMayEval (ConstrTerm c)
+ | IDENT "ltac"; ":"; a = tactic_expr LEVEL "0" -> arg_of_expr a
+ | IDENT "ltac"; ":"; n = natural -> TacGeneric (genarg_of_int n)
| IDENT "ipattern"; ":"; ipat = simple_intropattern ->
TacGeneric (genarg_of_ipattern ipat)
| c = constr_eval -> ConstrMayEval c
--
cgit v1.2.3
From d5656a6c28f79d59590d4fde60c5158a649d1b65 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 11:16:03 +0100
Subject: Making parentheses mandatory in tactic scopes.
---
CHANGES | 2 +
parsing/g_ltac.ml4 | 10 ++--
plugins/micromega/Psatz.v | 2 +-
plugins/romega/ReflOmegaCore.v | 2 +-
plugins/setoid_ring/ArithRing.v | 4 +-
plugins/setoid_ring/InitialRing.v | 48 ++++++++--------
plugins/setoid_ring/NArithRing.v | 2 +-
plugins/setoid_ring/Ring.v | 6 +-
plugins/setoid_ring/ZArithRing.v | 8 +--
test-suite/bugs/closed/3699.v | 4 +-
test-suite/bugs/closed/3881.v | 2 +-
test-suite/complexity/ring2.v | 2 +-
test-suite/success/MatchFail.v | 8 +--
test-suite/success/ltac.v | 14 ++---
theories/Classes/CMorphisms.v | 2 +-
theories/Classes/Morphisms.v | 2 +-
theories/Classes/SetoidTactics.v | 16 +++---
theories/Numbers/Cyclic/Int31/Ring31.v | 20 +++----
theories/Numbers/Integer/BigZ/BigZ.v | 22 ++++----
theories/Numbers/Natural/BigN/BigN.v | 24 ++++----
theories/Numbers/Rational/BigQ/BigQ.v | 14 ++---
theories/Program/Equality.v | 4 +-
theories/Program/Tactics.v | 2 +-
theories/Reals/Ranalysis_reg.v | 100 ++++++++++++++++-----------------
theories/ZArith/Int.v | 14 ++---
theories/ZArith/Zsqrt_compat.v | 4 +-
26 files changed, 170 insertions(+), 168 deletions(-)
diff --git a/CHANGES b/CHANGES
index e80a3b4547..ae055cb2f8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,8 @@ Tactics
- In introduction patterns of the form (pat1,...,patn), n should match
the exact number of hypotheses introduced (except for local definitions
for which pattern can be omitted, as in regular pattern-matching).
+- Tactic scopes in Ltac like constr: and ltac: now require parentheses around
+ their argument.
Program
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 45d2a09e73..b76f5dda25 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -146,11 +146,11 @@ GEXTEND Gram
;
(* Can be used as argument and at toplevel in tactic expressions. *)
tactic_top_or_arg:
- [ [ IDENT "uconstr"; ":" ; c = uconstr -> UConstr c
- | IDENT "constr"; ":"; c = Constr.constr -> ConstrMayEval (ConstrTerm c)
- | IDENT "ltac"; ":"; a = tactic_expr LEVEL "0" -> arg_of_expr a
- | IDENT "ltac"; ":"; n = natural -> TacGeneric (genarg_of_int n)
- | IDENT "ipattern"; ":"; ipat = simple_intropattern ->
+ [ [ IDENT "uconstr"; ":"; "("; c = Constr.lconstr; ")" -> UConstr c
+ | IDENT "constr"; ":"; "("; c = Constr.lconstr; ")" -> ConstrMayEval (ConstrTerm c)
+ | IDENT "ltac"; ":"; "("; a = tactic_expr LEVEL "5"; ")" -> arg_of_expr a
+ | IDENT "ltac"; ":"; "("; n = natural; ")" -> TacGeneric (genarg_of_int n)
+ | IDENT "ipattern"; ":"; "("; ipat = simple_intropattern; ")" ->
TacGeneric (genarg_of_ipattern ipat)
| c = constr_eval -> ConstrMayEval c
| IDENT "fresh"; l = LIST0 fresh_id -> TacFreshId l
diff --git a/plugins/micromega/Psatz.v b/plugins/micromega/Psatz.v
index 50e0033e59..ba1f8956e3 100644
--- a/plugins/micromega/Psatz.v
+++ b/plugins/micromega/Psatz.v
@@ -69,7 +69,7 @@ Ltac xpsatz dom d :=
end in tac.
Tactic Notation "psatz" constr(dom) int_or_var(n) := xpsatz dom n.
-Tactic Notation "psatz" constr(dom) := xpsatz dom ltac:-1.
+Tactic Notation "psatz" constr(dom) := xpsatz dom ltac:(-1).
Ltac psatzl dom :=
let tac := lazymatch dom with
diff --git a/plugins/romega/ReflOmegaCore.v b/plugins/romega/ReflOmegaCore.v
index b84cf25405..36511386ac 100644
--- a/plugins/romega/ReflOmegaCore.v
+++ b/plugins/romega/ReflOmegaCore.v
@@ -1492,7 +1492,7 @@ with Simplify := match goal with
end.
Ltac prove_stable x th :=
- match constr:x with
+ match constr:(x) with
| ?X1 =>
unfold term_stable, X1; intros; Simplify; simpl;
apply th
diff --git a/plugins/setoid_ring/ArithRing.v b/plugins/setoid_ring/ArithRing.v
index 04decbce19..5f5b97925f 100644
--- a/plugins/setoid_ring/ArithRing.v
+++ b/plugins/setoid_ring/ArithRing.v
@@ -32,13 +32,13 @@ Qed.
Ltac natcst t :=
match isnatcst t with
true => constr:(N.of_nat t)
- | _ => constr:InitialRing.NotConstant
+ | _ => constr:(InitialRing.NotConstant)
end.
Ltac Ss_to_add f acc :=
match f with
| S ?f1 => Ss_to_add f1 (S acc)
- | _ => constr:(acc + f)%nat
+ | _ => constr:((acc + f)%nat)
end.
Ltac natprering :=
diff --git a/plugins/setoid_ring/InitialRing.v b/plugins/setoid_ring/InitialRing.v
index 8362c8c261..8fcc077164 100644
--- a/plugins/setoid_ring/InitialRing.v
+++ b/plugins/setoid_ring/InitialRing.v
@@ -612,32 +612,32 @@ End GEN_DIV.
Ltac inv_gen_phi_pos rI add mul t :=
let rec inv_cst t :=
match t with
- rI => constr:1%positive
- | (add rI rI) => constr:2%positive
- | (add rI (add rI rI)) => constr:3%positive
+ rI => constr:(1%positive)
+ | (add rI rI) => constr:(2%positive)
+ | (add rI (add rI rI)) => constr:(3%positive)
| (mul (add rI rI) ?p) => (* 2p *)
match inv_cst p with
- NotConstant => constr:NotConstant
- | 1%positive => constr:NotConstant (* 2*1 is not convertible to 2 *)
+ NotConstant => constr:(NotConstant)
+ | 1%positive => constr:(NotConstant) (* 2*1 is not convertible to 2 *)
| ?p => constr:(xO p)
end
| (add rI (mul (add rI rI) ?p)) => (* 1+2p *)
match inv_cst p with
- NotConstant => constr:NotConstant
- | 1%positive => constr:NotConstant
+ NotConstant => constr:(NotConstant)
+ | 1%positive => constr:(NotConstant)
| ?p => constr:(xI p)
end
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end in
inv_cst t.
(* The (partial) inverse of gen_phiNword *)
Ltac inv_gen_phiNword rO rI add mul opp t :=
match t with
- rO => constr:NwO
+ rO => constr:(NwO)
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Npos p::nil)
end
end.
@@ -646,10 +646,10 @@ End GEN_DIV.
(* The inverse of gen_phiN *)
Ltac inv_gen_phiN rO rI add mul t :=
match t with
- rO => constr:0%N
+ rO => constr:(0%N)
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Npos p)
end
end.
@@ -657,15 +657,15 @@ End GEN_DIV.
(* The inverse of gen_phiZ *)
Ltac inv_gen_phiZ rO rI add mul opp t :=
match t with
- rO => constr:0%Z
+ rO => constr:(0%Z)
| (opp ?p) =>
match inv_gen_phi_pos rI add mul p with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Zneg p)
end
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Zpos p)
end
end.
@@ -681,7 +681,7 @@ Ltac inv_gen_phi rO rI cO cI t :=
end.
(* A simple tactic recognizing no constant *)
- Ltac inv_morph_nothing t := constr:NotConstant.
+ Ltac inv_morph_nothing t := constr:(NotConstant).
Ltac coerce_to_almost_ring set ext rspec :=
match type of rspec with
@@ -825,31 +825,31 @@ Ltac ring_elements set ext rspec pspec sspec dspec rk :=
(* Tactic for constant *)
Ltac isnatcst t :=
match t with
- O => constr:true
+ O => constr:(true)
| S ?p => isnatcst p
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isPcst t :=
match t with
| xI ?p => isPcst p
| xO ?p => isPcst p
- | xH => constr:true
+ | xH => constr:(true)
(* nat -> positive *)
| Pos.of_succ_nat ?n => isnatcst n
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isNcst t :=
match t with
- N0 => constr:true
+ N0 => constr:(true)
| Npos ?p => isPcst p
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isZcst t :=
match t with
- Z0 => constr:true
+ Z0 => constr:(true)
| Zpos ?p => isPcst p
| Zneg ?p => isPcst p
(* injection nat -> Z *)
@@ -857,7 +857,7 @@ Ltac isZcst t :=
(* injection N -> Z *)
| Z.of_N ?n => isNcst n
(* *)
- | _ => constr:false
+ | _ => constr:(false)
end.
diff --git a/plugins/setoid_ring/NArithRing.v b/plugins/setoid_ring/NArithRing.v
index 6c1a79e4ed..54e2789ba4 100644
--- a/plugins/setoid_ring/NArithRing.v
+++ b/plugins/setoid_ring/NArithRing.v
@@ -15,7 +15,7 @@ Set Implicit Arguments.
Ltac Ncst t :=
match isNcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Add Ring Nr : Nth (decidable Neqb_ok, constants [Ncst]).
diff --git a/plugins/setoid_ring/Ring.v b/plugins/setoid_ring/Ring.v
index a0844100c2..77576cb933 100644
--- a/plugins/setoid_ring/Ring.v
+++ b/plugins/setoid_ring/Ring.v
@@ -36,9 +36,9 @@ Qed.
Ltac bool_cst t :=
let t := eval hnf in t in
match t with
- true => constr:true
- | false => constr:false
- | _ => constr:NotConstant
+ true => constr:(true)
+ | false => constr:(false)
+ | _ => constr:(NotConstant)
end.
Add Ring bool_ring : BoolTheory (decidable bool_eq_ok, constants [bool_cst]).
diff --git a/plugins/setoid_ring/ZArithRing.v b/plugins/setoid_ring/ZArithRing.v
index 9148437278..23784cf33f 100644
--- a/plugins/setoid_ring/ZArithRing.v
+++ b/plugins/setoid_ring/ZArithRing.v
@@ -17,14 +17,14 @@ Set Implicit Arguments.
Ltac Zcst t :=
match isZcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Ltac isZpow_coef t :=
match t with
| Zpos ?p => isPcst p
- | Z0 => constr:true
- | _ => constr:false
+ | Z0 => constr:(true)
+ | _ => constr:(false)
end.
Notation N_of_Z := Z.to_N (only parsing).
@@ -32,7 +32,7 @@ Notation N_of_Z := Z.to_N (only parsing).
Ltac Zpow_tac t :=
match isZpow_coef t with
| true => constr:(N_of_Z t)
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Ltac Zpower_neg :=
diff --git a/test-suite/bugs/closed/3699.v b/test-suite/bugs/closed/3699.v
index aad0bb44d5..8dadc2419c 100644
--- a/test-suite/bugs/closed/3699.v
+++ b/test-suite/bugs/closed/3699.v
@@ -65,7 +65,7 @@ Module NonPrim.
set (fibermap := fun a0p : hfiber f (f a)
=> let (a0, p) := a0p in transport P p (d a0)).
Set Printing Implicit.
- let G := match goal with |- ?G => constr:G end in
+ let G := match goal with |- ?G => constr:(G) end in
first [ match goal with
| [ |- (@isconnected_elim n (@hfiber A B f (f a))
(@isconnected_hfiber_conn_map n A B f H (f a))
@@ -142,7 +142,7 @@ Module Prim.
set (fibermap := fun a0p : hfiber f (f a)
=> let (a0, p) := a0p in transport P p (d a0)).
Set Printing Implicit.
- let G := match goal with |- ?G => constr:G end in
+ let G := match goal with |- ?G => constr:(G) end in
first [ match goal with
| [ |- (@isconnected_elim n (@hfiber A B f (f a))
(@isconnected_hfiber_conn_map n A B f H (f a))
diff --git a/test-suite/bugs/closed/3881.v b/test-suite/bugs/closed/3881.v
index 070d1e9c71..a327bbf2a9 100644
--- a/test-suite/bugs/closed/3881.v
+++ b/test-suite/bugs/closed/3881.v
@@ -23,7 +23,7 @@ Proof.
pose (fun H => @isequiv_homotopic _ _ ((g o f) o f^-1) _ H
(fun b => ap g (eisretr f b))) as k.
revert k.
- let x := match goal with |- let k := ?x in _ => constr:x end in
+ let x := match goal with |- let k := ?x in _ => constr:(x) end in
intro k; clear k;
pose (x _).
pose (@isequiv_homotopic _ _ ((g o f) o f^-1) g _
diff --git a/test-suite/complexity/ring2.v b/test-suite/complexity/ring2.v
index 52dae265bd..04fa59075b 100644
--- a/test-suite/complexity/ring2.v
+++ b/test-suite/complexity/ring2.v
@@ -39,7 +39,7 @@ Admitted.
Ltac Zcst t :=
match isZcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Add Ring Zr : Zth
diff --git a/test-suite/success/MatchFail.v b/test-suite/success/MatchFail.v
index 7069bba430..8462d36272 100644
--- a/test-suite/success/MatchFail.v
+++ b/test-suite/success/MatchFail.v
@@ -9,14 +9,14 @@ Require Export ZArithRing.
Ltac compute_POS :=
match goal with
| |- context [(Zpos (xI ?X1))] =>
- let v := constr:X1 in
- match constr:v with
+ let v := constr:(X1) in
+ match constr:(v) with
| 1%positive => fail 1
| _ => rewrite (BinInt.Pos2Z.inj_xI v)
end
| |- context [(Zpos (xO ?X1))] =>
- let v := constr:X1 in
- match constr:v with
+ let v := constr:(X1) in
+ match constr:(v) with
| 1%positive => fail 1
| _ => rewrite (BinInt.Pos2Z.inj_xO v)
end
diff --git a/test-suite/success/ltac.v b/test-suite/success/ltac.v
index 6c4d4ae98f..ce90990594 100644
--- a/test-suite/success/ltac.v
+++ b/test-suite/success/ltac.v
@@ -15,7 +15,7 @@ Ltac F x := idtac; G x
with G y := idtac; F y.
(* Check that Match Context keeps a closure *)
-Ltac U := let a := constr:I in
+Ltac U := let a := constr:(I) in
match goal with
| |- _ => apply a
end.
@@ -75,7 +75,7 @@ Qed.
(* Check context binding *)
Ltac sym t :=
- match constr:t with
+ match constr:(t) with
| context C[(?X1 = ?X2)] => context C [X1 = X2]
end.
@@ -143,7 +143,7 @@ Qed.
Ltac check_binding y := cut ((fun y => y) = S).
Goal True.
-check_binding ipattern:H.
+check_binding ipattern:(H).
Abort.
(* Check that variables explicitly parsed as ltac variables are not
@@ -151,7 +151,7 @@ Abort.
Ltac afi tac := intros; tac.
Goal 1 = 2.
-afi ltac:auto.
+afi ltac:(auto).
Abort.
(* Tactic Notation avec listes *)
@@ -174,7 +174,7 @@ Abort.
empty args *)
Goal True.
-match constr:@None with @None => exact I end.
+match constr:(@None) with @None => exact I end.
Abort.
(* Check second-order pattern unification *)
@@ -218,7 +218,7 @@ Ltac Z1 t := set (x:=t).
Ltac Z2 t := t.
Goal True -> True.
Z1 O.
-Z2 ltac:O.
+Z2 ltac:(O).
exact I.
Qed.
@@ -302,7 +302,7 @@ Abort.
(* Check instantiation of binders using ltac names *)
Goal True.
-let x := ipattern:y in assert (forall x y, x = y + 0).
+let x := ipattern:(y) in assert (forall x y, x = y + 0).
intro.
destruct y. (* Check that the name is y here *)
Abort.
diff --git a/theories/Classes/CMorphisms.v b/theories/Classes/CMorphisms.v
index c41eb2fa29..627a1a4957 100644
--- a/theories/Classes/CMorphisms.v
+++ b/theories/Classes/CMorphisms.v
@@ -452,7 +452,7 @@ Ltac partial_application_tactic :=
let rec do_partial_apps H m cont :=
match m with
| ?m' ?x => class_apply @Reflexive_partial_app_morphism ;
- [(do_partial_apps H m' ltac:idtac)|clear H]
+ [(do_partial_apps H m' ltac:(idtac))|clear H]
| _ => cont
end
in
diff --git a/theories/Classes/Morphisms.v b/theories/Classes/Morphisms.v
index 8d942d9087..81b31d783f 100644
--- a/theories/Classes/Morphisms.v
+++ b/theories/Classes/Morphisms.v
@@ -465,7 +465,7 @@ Ltac partial_application_tactic :=
let rec do_partial_apps H m cont :=
match m with
| ?m' ?x => class_apply @Reflexive_partial_app_morphism ;
- [(do_partial_apps H m' ltac:idtac)|clear H]
+ [(do_partial_apps H m' ltac:(idtac))|clear H]
| _ => cont
end
in
diff --git a/theories/Classes/SetoidTactics.v b/theories/Classes/SetoidTactics.v
index 145d451f0f..190397ae49 100644
--- a/theories/Classes/SetoidTactics.v
+++ b/theories/Classes/SetoidTactics.v
@@ -77,23 +77,23 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"by" tactic3(t) :=
- setoidreplace (default_relation x y) ltac:t.
+ setoidreplace (default_relation x y) ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceat (default_relation x y) ltac:t o.
+ setoidreplaceat (default_relation x y) ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"in" hyp(id)
"by" tactic3(t) :=
- setoidreplacein (default_relation x y) id ltac:t.
+ setoidreplacein (default_relation x y) id ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"in" hyp(id)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceinat (default_relation x y) id ltac:t o.
+ setoidreplaceinat (default_relation x y) id ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel) :=
@@ -107,13 +107,13 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"by" tactic3(t) :=
- setoidreplace (rel x y) ltac:t.
+ setoidreplace (rel x y) ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceat (rel x y) ltac:t o.
+ setoidreplaceat (rel x y) ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
@@ -130,14 +130,14 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"in" hyp(id)
"by" tactic3(t) :=
- setoidreplacein (rel x y) id ltac:t.
+ setoidreplacein (rel x y) id ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"in" hyp(id)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceinat (rel x y) id ltac:t o.
+ setoidreplaceinat (rel x y) id ltac:(t) o.
(** The [add_morphism_tactic] tactic is run at each [Add Morphism]
command before giving the hand back to the user to discharge the
diff --git a/theories/Numbers/Cyclic/Int31/Ring31.v b/theories/Numbers/Cyclic/Int31/Ring31.v
index 215b8bd581..d160f5f1de 100644
--- a/theories/Numbers/Cyclic/Int31/Ring31.v
+++ b/theories/Numbers/Cyclic/Int31/Ring31.v
@@ -19,13 +19,13 @@ Local Open Scope list_scope.
Ltac isInt31cst_lst l :=
match l with
- | nil => constr:true
+ | nil => constr:(true)
| ?t::?l => match t with
| D1 => isInt31cst_lst l
| D0 => isInt31cst_lst l
- | _ => constr:false
+ | _ => constr:(false)
end
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isInt31cst t :=
@@ -38,17 +38,17 @@ Ltac isInt31cst t :=
::i11::i12::i13::i14::i15::i16::i17::i18::i19::i20
::i21::i22::i23::i24::i25::i26::i27::i28::i29::i30::nil)
in isInt31cst_lst l
- | Int31.On => constr:true
- | Int31.In => constr:true
- | Int31.Tn => constr:true
- | Int31.Twon => constr:true
- | _ => constr:false
+ | Int31.On => constr:(true)
+ | Int31.In => constr:(true)
+ | Int31.Tn => constr:(true)
+ | Int31.Twon => constr:(true)
+ | _ => constr:(false)
end.
Ltac Int31cst t :=
match isInt31cst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
(** The generic ring structure inferred from the Cyclic structure *)
diff --git a/theories/Numbers/Integer/BigZ/BigZ.v b/theories/Numbers/Integer/BigZ/BigZ.v
index ec495d0947..56cb9bbc2c 100644
--- a/theories/Numbers/Integer/BigZ/BigZ.v
+++ b/theories/Numbers/Integer/BigZ/BigZ.v
@@ -148,26 +148,26 @@ Ltac isBigZcst t :=
match t with
| BigZ.Pos ?t => isBigNcst t
| BigZ.Neg ?t => isBigNcst t
- | BigZ.zero => constr:true
- | BigZ.one => constr:true
- | BigZ.two => constr:true
- | BigZ.minus_one => constr:true
- | _ => constr:false
+ | BigZ.zero => constr:(true)
+ | BigZ.one => constr:(true)
+ | BigZ.two => constr:(true)
+ | BigZ.minus_one => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigZcst t :=
match isBigZcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Ltac BigZ_to_N t :=
match t with
| BigZ.Pos ?t => BigN_to_N t
- | BigZ.zero => constr:0%N
- | BigZ.one => constr:1%N
- | BigZ.two => constr:2%N
- | _ => constr:NotConstant
+ | BigZ.zero => constr:(0%N)
+ | BigZ.one => constr:(1%N)
+ | BigZ.two => constr:(2%N)
+ | _ => constr:(NotConstant)
end.
(** Registration for the "ring" tactic *)
diff --git a/theories/Numbers/Natural/BigN/BigN.v b/theories/Numbers/Natural/BigN/BigN.v
index 29a1145e0c..ec1017f505 100644
--- a/theories/Numbers/Natural/BigN/BigN.v
+++ b/theories/Numbers/Natural/BigN/BigN.v
@@ -119,10 +119,10 @@ Qed.
Ltac isStaticWordCst t :=
match t with
- | W0 => constr:true
+ | W0 => constr:(true)
| WW ?t1 ?t2 =>
match isStaticWordCst t1 with
- | false => constr:false
+ | false => constr:(false)
| true => isStaticWordCst t2
end
| _ => isInt31cst t
@@ -139,30 +139,30 @@ Ltac isBigNcst t :=
| BigN.N6 ?t => isStaticWordCst t
| BigN.Nn ?n ?t => match isnatcst n with
| true => isStaticWordCst t
- | false => constr:false
+ | false => constr:(false)
end
- | BigN.zero => constr:true
- | BigN.one => constr:true
- | BigN.two => constr:true
- | _ => constr:false
+ | BigN.zero => constr:(true)
+ | BigN.one => constr:(true)
+ | BigN.two => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigNcst t :=
match isBigNcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Ltac BigN_to_N t :=
match isBigNcst t with
| true => eval vm_compute in (BigN.to_N t)
- | false => constr:NotConstant
+ | false => constr:(NotConstant)
end.
Ltac Ncst t :=
match isNcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
(** Registration for the "ring" tactic *)
diff --git a/theories/Numbers/Rational/BigQ/BigQ.v b/theories/Numbers/Rational/BigQ/BigQ.v
index fe38ea4f2d..850afe5345 100644
--- a/theories/Numbers/Rational/BigQ/BigQ.v
+++ b/theories/Numbers/Rational/BigQ/BigQ.v
@@ -104,18 +104,18 @@ Ltac isBigQcst t :=
| BigQ.Qz ?t => isBigZcst t
| BigQ.Qq ?n ?d => match isBigZcst n with
| true => isBigNcst d
- | false => constr:false
+ | false => constr:(false)
end
- | BigQ.zero => constr:true
- | BigQ.one => constr:true
- | BigQ.minus_one => constr:true
- | _ => constr:false
+ | BigQ.zero => constr:(true)
+ | BigQ.one => constr:(true)
+ | BigQ.minus_one => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigQcst t :=
match isBigQcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Add Field BigQfield : BigQfieldth
diff --git a/theories/Program/Equality.v b/theories/Program/Equality.v
index 27e1ca8444..17f05c5113 100644
--- a/theories/Program/Equality.v
+++ b/theories/Program/Equality.v
@@ -238,8 +238,8 @@ Ltac inject_left H :=
Ltac inject_right H :=
progress (inversion H ; subst_right_no_fail ; clear_dups) ; clear H.
-Ltac autoinjections_left := repeat autoinjection ltac:inject_left.
-Ltac autoinjections_right := repeat autoinjection ltac:inject_right.
+Ltac autoinjections_left := repeat autoinjection ltac:(inject_left).
+Ltac autoinjections_right := repeat autoinjection ltac:(inject_right).
Ltac simpl_depind := subst_no_fail ; autoinjections ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simplify_IH_hyps.
diff --git a/theories/Program/Tactics.v b/theories/Program/Tactics.v
index 66ca3e577d..7384790dae 100644
--- a/theories/Program/Tactics.v
+++ b/theories/Program/Tactics.v
@@ -252,7 +252,7 @@ Ltac autoinjection tac :=
Ltac inject H := progress (inversion H ; subst*; clear_dups) ; clear H.
-Ltac autoinjections := repeat (clear_dups ; autoinjection ltac:inject).
+Ltac autoinjections := repeat (clear_dups ; autoinjection ltac:(inject)).
(** Destruct an hypothesis by first copying it to avoid dependencies. *)
diff --git a/theories/Reals/Ranalysis_reg.v b/theories/Reals/Ranalysis_reg.v
index 2465f03992..e57af7311f 100644
--- a/theories/Reals/Ranalysis_reg.v
+++ b/theories/Reals/Ranalysis_reg.v
@@ -35,7 +35,7 @@ Qed.
(**********)
Ltac intro_hyp_glob trm :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
match goal with
| |- (derivable _) => intro_hyp_glob X1; intro_hyp_glob X2
@@ -55,7 +55,7 @@ Ltac intro_hyp_glob trm :=
| _ => idtac
end
| (?X1 / ?X2)%F =>
- let aux := constr:X2 in
+ let aux := constr:(X2) in
match goal with
| _:(forall x0:R, aux x0 <> 0) |- (derivable _) =>
intro_hyp_glob X1; intro_hyp_glob X2
@@ -82,7 +82,7 @@ Ltac intro_hyp_glob trm :=
| _ => idtac
end
| (/ ?X1)%F =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| _:(forall x0:R, aux x0 <> 0) |- (derivable _) =>
intro_hyp_glob X1
@@ -108,7 +108,7 @@ Ltac intro_hyp_glob trm :=
| (pow_fct _) => idtac
| Rabs => idtac
| ?X1 =>
- let p := constr:X1 in
+ let p := constr:(X1) in
match goal with
| _:(derivable p) |- _ => idtac
| |- (derivable p) => idtac
@@ -130,7 +130,7 @@ Ltac intro_hyp_glob trm :=
(**********)
Ltac intro_hyp_pt trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
match goal with
| |- (derivable_pt _ _) => intro_hyp_pt X1 pt; intro_hyp_pt X2 pt
@@ -156,7 +156,7 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| (?X1 / ?X2)%F =>
- let aux := constr:X2 in
+ let aux := constr:(X2) in
match goal with
| _:(aux pt <> 0) |- (derivable_pt _ _) =>
intro_hyp_pt X1 pt; intro_hyp_pt X2 pt
@@ -202,7 +202,7 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| (/ ?X1)%F =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| _:(aux pt <> 0) |- (derivable_pt _ _) =>
intro_hyp_pt X1 pt
@@ -249,7 +249,7 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| ?X1 =>
- let p := constr:X1 in
+ let p := constr:(X1) in
match goal with
| _:(derivable_pt p pt) |- _ => idtac
| |- (derivable_pt p pt) => idtac
@@ -578,89 +578,89 @@ Ltac is_cont_glob :=
(**********)
Ltac rew_term trm :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 + X4))
- | _ => constr:(p1 + p2)%F
+ | _ => constr:((p1 + p2)%F)
end
- | _ => constr:(p1 + p2)%F
+ | _ => constr:((p1 + p2)%F)
end
| (?X1 - ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 - X4))
- | _ => constr:(p1 - p2)%F
+ | _ => constr:((p1 - p2)%F)
end
- | _ => constr:(p1 - p2)%F
+ | _ => constr:((p1 - p2)%F)
end
| (?X1 / ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 / X4))
- | _ => constr:(p1 / p2)%F
+ | _ => constr:((p1 / p2)%F)
end
| _ =>
- match constr:p2 with
- | (fct_cte ?X4) => constr:(p1 * fct_cte (/ X4))%F
- | _ => constr:(p1 / p2)%F
+ match constr:(p2) with
+ | (fct_cte ?X4) => constr:((p1 * fct_cte (/ X4))%F)
+ | _ => constr:((p1 / p2)%F)
end
end
| (?X1 * / ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 / X4))
- | _ => constr:(p1 / p2)%F
+ | _ => constr:((p1 / p2)%F)
end
| _ =>
- match constr:p2 with
- | (fct_cte ?X4) => constr:(p1 * fct_cte (/ X4))%F
- | _ => constr:(p1 / p2)%F
+ match constr:(p2) with
+ | (fct_cte ?X4) => constr:((p1 * fct_cte (/ X4))%F)
+ | _ => constr:((p1 / p2)%F)
end
end
| (?X1 * ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 * X4))
- | _ => constr:(p1 * p2)%F
+ | _ => constr:((p1 * p2)%F)
end
- | _ => constr:(p1 * p2)%F
+ | _ => constr:((p1 * p2)%F)
end
| (- ?X1) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X2) => constr:(fct_cte (- X2))
- | _ => constr:(- p)%F
+ | _ => constr:((- p)%F)
end
| (/ ?X1) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X2) => constr:(fct_cte (/ X2))
- | _ => constr:(/ p)%F
+ | _ => constr:((/ p)%F)
end
- | (?X1 AppVar) => constr:X1
+ | (?X1 AppVar) => constr:(X1)
| (?X1 ?X2) =>
let p := rew_term X2 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X3) => constr:(fct_cte (X1 X3))
| _ => constr:(comp X1 p)
end
- | AppVar => constr:id
+ | AppVar => constr:(id)
| (AppVar ^ ?X1) => constr:(pow_fct X1)
| (?X1 ^ ?X2) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X3) => constr:(fct_cte (pow_fct X2 X3))
| _ => constr:(comp (pow_fct X2) p)
end
@@ -669,7 +669,7 @@ Ltac rew_term trm :=
(**********)
Ltac deriv_proof trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
let p1 := deriv_proof X1 pt with p2 := deriv_proof X2 pt in
constr:(derivable_pt_plus X1 X2 pt p1 p2)
@@ -684,14 +684,14 @@ Ltac deriv_proof trm pt :=
| id:(?X2 pt <> 0) |- _ =>
let p1 := deriv_proof X1 pt with p2 := deriv_proof X2 pt in
constr:(derivable_pt_div X1 X2 pt p1 p2 id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (/ ?X1)%F =>
match goal with
| id:(?X1 pt <> 0) |- _ =>
let p1 := deriv_proof X1 pt in
constr:(derivable_pt_inv X1 pt p1 id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (comp ?X1 ?X2) =>
let pt_f1 := eval cbv beta in (X2 pt) in
@@ -710,21 +710,21 @@ Ltac deriv_proof trm pt :=
| sqrt =>
match goal with
| id:(0 < pt) |- _ => constr:(derivable_pt_sqrt pt id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (fct_cte ?X1) => constr:(derivable_pt_const X1 pt)
| ?X1 =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
- | id:(derivable_pt aux pt) |- _ => constr:id
+ | id:(derivable_pt aux pt) |- _ => constr:(id)
| id:(derivable aux) |- _ => constr:(id pt)
- | _ => constr:False
+ | _ => constr:(False)
end
end.
(**********)
Ltac simplify_derive trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
try rewrite derive_pt_plus; simplify_derive X1 pt;
simplify_derive X2 pt
@@ -753,7 +753,7 @@ Ltac simplify_derive trm pt :=
| Rsqr => try rewrite derive_pt_Rsqr
| sqrt => try rewrite derive_pt_sqrt
| ?X1 =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| id:(derive_pt aux pt ?X2 = _),H:(derivable aux) |- _ =>
try replace (derive_pt aux pt (H pt)) with (derive_pt aux pt X2);
diff --git a/theories/ZArith/Int.v b/theories/ZArith/Int.v
index d210792f9a..32e13d3892 100644
--- a/theories/ZArith/Int.v
+++ b/theories/ZArith/Int.v
@@ -225,11 +225,11 @@ Module MoreInt (Import I:Int).
(** [int] to [ExprI] *)
Ltac i2ei trm :=
- match constr:trm with
- | 0 => constr:EI0
- | 1 => constr:EI1
- | 2 => constr:EI2
- | 3 => constr:EI3
+ match constr:(trm) with
+ | 0 => constr:(EI0)
+ | 1 => constr:(EI1)
+ | 2 => constr:(EI2)
+ | 3 => constr:(EI3)
| ?x + ?y => let ex := i2ei x with ey := i2ei y in constr:(EIadd ex ey)
| ?x - ?y => let ex := i2ei x with ey := i2ei y in constr:(EIsub ex ey)
| ?x * ?y => let ex := i2ei x with ey := i2ei y in constr:(EImul ex ey)
@@ -241,7 +241,7 @@ Module MoreInt (Import I:Int).
(** [Z] to [ExprZ] *)
with z2ez trm :=
- match constr:trm with
+ match constr:(trm) with
| (?x + ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZadd ex ey)
| (?x - ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZsub ex ey)
| (?x * ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZmul ex ey)
@@ -254,7 +254,7 @@ Module MoreInt (Import I:Int).
(** [Prop] to [ExprP] *)
Ltac p2ep trm :=
- match constr:trm with
+ match constr:(trm) with
| (?x <-> ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPequiv ex ey)
| (?x -> ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPimpl ex ey)
| (?x /\ ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPand ex ey)
diff --git a/theories/ZArith/Zsqrt_compat.v b/theories/ZArith/Zsqrt_compat.v
index b80eb4451e..f4baba1902 100644
--- a/theories/ZArith/Zsqrt_compat.v
+++ b/theories/ZArith/Zsqrt_compat.v
@@ -30,12 +30,12 @@ Local Open Scope Z_scope.
Ltac compute_POS :=
match goal with
| |- context [(Zpos (xI ?X1))] =>
- match constr:X1 with
+ match constr:(X1) with
| context [1%positive] => fail 1
| _ => rewrite (Pos2Z.inj_xI X1)
end
| |- context [(Zpos (xO ?X1))] =>
- match constr:X1 with
+ match constr:(X1) with
| context [1%positive] => fail 1
| _ => rewrite (Pos2Z.inj_xO X1)
end
--
cgit v1.2.3
From 098d283e58966124cfe0e97a3229a9e7e6284120 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 15:04:35 +0100
Subject: Removing the UConstr entry of the tactic_arg AST.
This was redundant with the wit_uconstr generic argument, so there was no real
point on keeping it there.
---
intf/tacexpr.mli | 11 -----------
parsing/g_ltac.ml4 | 3 ++-
printing/pptactic.ml | 7 -------
tactics/tacintern.ml | 3 +--
tactics/tacinterp.ml | 5 -----
tactics/tacsubst.ml | 1 -
6 files changed, 3 insertions(+), 27 deletions(-)
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 7366bc03e6..f2a567c00d 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -180,7 +180,6 @@ type 'a gen_atomic_tactic_expr =
constraint 'a = <
term:'trm;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'pat;
constant:'cst;
@@ -195,7 +194,6 @@ constraint 'a = <
and 'a gen_tactic_arg =
| TacGeneric of 'lev generic_argument
| ConstrMayEval of ('trm,'cst,'pat) may_eval
- | UConstr of 'utrm
| Reference of 'ref
| TacCall of Loc.t * 'ref *
'a gen_tactic_arg list
@@ -206,7 +204,6 @@ and 'a gen_tactic_arg =
constraint 'a = <
term:'trm;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'pat;
constant:'cst;
@@ -285,7 +282,6 @@ and 'a gen_tactic_expr =
constraint 'a = <
term:'t;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'p;
constant:'c;
@@ -300,7 +296,6 @@ and 'a gen_tactic_fun_ast =
constraint 'a = <
term:'t;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'p;
constant:'c;
@@ -313,7 +308,6 @@ constraint 'a = <
(** Globalized tactics *)
type g_trm = glob_constr_and_expr
-type g_utrm = g_trm
type g_pat = glob_constr_pattern_and_expr
type g_cst = evaluable_global_reference and_short_name or_var
type g_ref = ltac_constant located or_var
@@ -321,7 +315,6 @@ type g_nam = Id.t located
type g_dispatch = <
term:g_trm;
- utrm:g_utrm;
dterm:g_trm;
pattern:g_pat;
constant:g_cst;
@@ -343,7 +336,6 @@ type glob_tactic_arg =
(** Raw tactics *)
type r_trm = constr_expr
-type r_utrm = r_trm
type r_pat = constr_pattern_expr
type r_cst = reference or_by_notation
type r_ref = reference
@@ -352,7 +344,6 @@ type r_lev = rlevel
type r_dispatch = <
term:r_trm;
- utrm:r_utrm;
dterm:r_trm;
pattern:r_pat;
constant:r_cst;
@@ -374,7 +365,6 @@ type raw_tactic_arg =
(** Interpreted tactics *)
type t_trm = Term.constr
-type t_utrm = Glob_term.closed_glob_constr
type t_pat = constr_pattern
type t_cst = evaluable_global_reference
type t_ref = ltac_constant located
@@ -382,7 +372,6 @@ type t_nam = Id.t
type t_dispatch = <
term:t_trm;
- utrm:t_utrm;
dterm:g_trm;
pattern:t_pat;
constant:t_cst;
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index b76f5dda25..4da32c9b26 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -28,6 +28,7 @@ let arg_of_expr = function
let genarg_of_unit () = in_gen (rawwit Stdarg.wit_unit) ()
let genarg_of_int n = in_gen (rawwit Stdarg.wit_int) n
let genarg_of_ipattern pat = in_gen (rawwit Constrarg.wit_intro_pattern) pat
+let genarg_of_uconstr c = in_gen (rawwit Constrarg.wit_uconstr) c
let reference_to_id = function
| Libnames.Ident (loc, id) -> (loc, id)
@@ -146,7 +147,7 @@ GEXTEND Gram
;
(* Can be used as argument and at toplevel in tactic expressions. *)
tactic_top_or_arg:
- [ [ IDENT "uconstr"; ":"; "("; c = Constr.lconstr; ")" -> UConstr c
+ [ [ IDENT "uconstr"; ":"; "("; c = Constr.lconstr; ")" -> TacGeneric (genarg_of_uconstr c)
| IDENT "constr"; ":"; "("; c = Constr.lconstr; ")" -> ConstrMayEval (ConstrTerm c)
| IDENT "ltac"; ":"; "("; a = tactic_expr LEVEL "5"; ")" -> arg_of_expr a
| IDENT "ltac"; ":"; "("; n = natural; ")" -> TacGeneric (genarg_of_int n)
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 36863906ea..fdc1288aec 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -696,7 +696,6 @@ module Make
type 'a printer = {
pr_tactic : tolerability -> 'tacexpr -> std_ppcmds;
pr_constr : 'trm -> std_ppcmds;
- pr_uconstr : 'utrm -> std_ppcmds;
pr_lconstr : 'trm -> std_ppcmds;
pr_dconstr : 'dtrm -> std_ppcmds;
pr_pattern : 'pat -> std_ppcmds;
@@ -711,7 +710,6 @@ module Make
constraint 'a = <
term :'trm;
- utrm :'utrm;
dterm :'dtrm;
pattern :'pat;
constant :'cst;
@@ -1153,8 +1151,6 @@ module Make
pr.pr_reference r
| ConstrMayEval c ->
pr_may_eval pr.pr_constr pr.pr_lconstr pr.pr_constant pr.pr_pattern c
- | UConstr c ->
- keyword "uconstr:" ++ pr.pr_uconstr c
| TacFreshId l ->
keyword "fresh" ++ pr_fresh_ids l
| TacPretype c ->
@@ -1182,7 +1178,6 @@ module Make
let pr = {
pr_tactic = pr_raw_tactic_level;
pr_constr = pr_constr_expr;
- pr_uconstr = pr_constr_expr;
pr_dconstr = pr_constr_expr;
pr_lconstr = pr_lconstr_expr;
pr_pattern = pr_constr_pattern_expr;
@@ -1213,7 +1208,6 @@ module Make
let pr = {
pr_tactic = prtac;
pr_constr = pr_and_constr_expr (pr_glob_constr_env env);
- pr_uconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_dconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_lconstr = pr_and_constr_expr (pr_lglob_constr_env env);
pr_pattern = pr_pat_and_constr_expr (pr_glob_constr_env env);
@@ -1255,7 +1249,6 @@ module Make
let pr = {
pr_tactic = pr_glob_tactic_level env;
pr_constr = pr_constr_env env Evd.empty;
- pr_uconstr = pr_closed_glob_env env Evd.empty;
pr_dconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_lconstr = pr_lconstr_env env Evd.empty;
pr_pattern = pr_constr_pattern_env env Evd.empty;
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index a069fd7557..89dc843cb8 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -651,7 +651,7 @@ and intern_tactic_as_arg loc onlytac ist a =
| TacCall _ | Reference _
| TacGeneric _ as a -> TacArg (loc,a)
| Tacexp a -> a
- | ConstrMayEval _ | UConstr _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
+ | ConstrMayEval _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
if onlytac then error_tactic_expected loc else TacArg (loc,a)
and intern_tactic_or_tacarg ist = intern_tactic false ist
@@ -665,7 +665,6 @@ and intern_tactic_fun ist (var,body) =
and intern_tacarg strict onlytac ist = function
| Reference r -> intern_non_tactic_reference strict ist r
| ConstrMayEval c -> ConstrMayEval (intern_constr_may_eval ist c)
- | UConstr c -> UConstr (intern_constr ist c)
| TacCall (loc,f,[]) -> intern_isolated_tactic_reference strict ist f
| TacCall (loc,f,l) ->
TacCall (loc,
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 1a8a95158a..bf5f9ddc86 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -1365,11 +1365,6 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
let (sigma,c_interp) = interp_constr_may_eval ist env sigma c in
Sigma.Unsafe.of_pair (Ftactic.return (Value.of_constr c_interp), sigma)
end }
- | UConstr c ->
- Ftactic.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- Ftactic.return (Value.of_uconstr (interp_uconstr ist env c))
- end }
| TacCall (loc,r,[]) ->
interp_ltac_reference loc true ist r
| TacCall (loc,f,l) ->
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 3f103a290d..55941c1ca6 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -247,7 +247,6 @@ and subst_tactic_fun subst (var,body) = (var,subst_tactic subst body)
and subst_tacarg subst = function
| Reference r -> Reference (subst_reference subst r)
| ConstrMayEval c -> ConstrMayEval (subst_raw_may_eval subst c)
- | UConstr c -> UConstr (subst_glob_constr subst c)
| TacCall (_loc,f,l) ->
TacCall (_loc, subst_reference subst f, List.map (subst_tacarg subst) l)
| TacFreshId _ as x -> x
--
cgit v1.2.3
From 5b4fd2f5a3c6d031d551f9b5730fe30a69337c76 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 15:47:27 +0100
Subject: Exchanging roles of tactic_arg and tactic_top_or_arg entries.
The tactic_arg entry was essentially a hack to keep parsing constrs as tactic
arguments. We rather use tactic_top_or_arg as the true entry for tactic arguments
now.
---
parsing/g_ltac.ml4 | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 4da32c9b26..06675baa7d 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -112,8 +112,8 @@ GEXTEND Gram
| g=failkw; n = [ n = int_or_var -> n | -> fail_default_value ];
l = LIST0 message_token -> TacFail (g,n,l)
| st = simple_tactic -> st
- | a = tactic_top_or_arg -> TacArg(!@loc,a)
- | r = reference; la = LIST0 tactic_arg ->
+ | a = tactic_arg -> TacArg(!@loc,a)
+ | r = reference; la = LIST0 tactic_arg_compat ->
TacArg(!@loc,TacCall (!@loc,r,la)) ]
| "0"
[ "("; a = tactic_expr; ")" -> a
@@ -137,16 +137,16 @@ GEXTEND Gram
body = tactic_expr LEVEL "5" -> TacLetIn (isrec,llc,body)
| IDENT "info"; tc = tactic_expr LEVEL "5" -> TacInfo tc ] ]
;
- (* Tactic arguments *)
- tactic_arg:
- [ [ a = tactic_top_or_arg -> a
+ (* Tactic arguments to the right of an application *)
+ tactic_arg_compat:
+ [ [ a = tactic_arg -> a
| r = reference -> Reference r
| c = Constr.constr -> ConstrMayEval (ConstrTerm c)
(* Unambigous entries: tolerated w/o "ltac:" modifier *)
| "()" -> TacGeneric (genarg_of_unit ()) ] ]
;
(* Can be used as argument and at toplevel in tactic expressions. *)
- tactic_top_or_arg:
+ tactic_arg:
[ [ IDENT "uconstr"; ":"; "("; c = Constr.lconstr; ")" -> TacGeneric (genarg_of_uconstr c)
| IDENT "constr"; ":"; "("; c = Constr.lconstr; ")" -> ConstrMayEval (ConstrTerm c)
| IDENT "ltac"; ":"; "("; a = tactic_expr LEVEL "5"; ")" -> arg_of_expr a
--
cgit v1.2.3
From 8e77752080b6f0da3ce396e7537db9676e848a70 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 15:55:02 +0100
Subject: Replacing ad-hoc tactic scopes by generic ones using
[create_ltac_quotations].
---
parsing/egramcoq.ml | 21 ++++++++++++---------
parsing/egramcoq.mli | 10 +++++-----
parsing/g_ltac.ml4 | 8 +-------
tactics/coretactics.ml4 | 2 ++
tactics/extraargs.ml4 | 14 ++++++++++++++
5 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/parsing/egramcoq.ml b/parsing/egramcoq.ml
index 465073b7aa..2cf590b1d8 100644
--- a/parsing/egramcoq.ml
+++ b/parsing/egramcoq.ml
@@ -379,24 +379,27 @@ let with_grammar_rule_protection f x =
let ltac_quotations = ref String.Set.empty
-let create_ltac_quotation name cast wit e =
+let create_ltac_quotation name cast (e, l) =
let () =
if String.Set.mem name !ltac_quotations then
failwith ("Ltac quotation " ^ name ^ " already registered")
in
let () = ltac_quotations := String.Set.add name !ltac_quotations in
+ let entry = match l with
+ | None -> Aentry (name_of_entry e)
+ | Some l -> Aentryl (name_of_entry e, l)
+ in
(* let level = Some "1" in *)
let level = None in
- let assoc = Some Extend.RightA in
+ let assoc = None in
let rule =
- Next (Next (Next (Stop,
+ Next (Next (Next (Next (Next (Stop,
Atoken (Lexer.terminal name)),
Atoken (Lexer.terminal ":")),
- Aentry (name_of_entry e))
- in
- let action v _ _ loc =
- let arg = TacGeneric (Genarg.in_gen (Genarg.rawwit wit) (cast (loc, v))) in
- TacArg (loc, arg)
+ Atoken (Lexer.terminal "(")),
+ entry),
+ Atoken (Lexer.terminal ")"))
in
+ let action _ v _ _ _ loc = cast (loc, v) in
let gram = (level, assoc, [Rule (rule, action)]) in
- Pcoq.grammar_extend Tactic.tactic_expr None (None, [gram])
+ Pcoq.grammar_extend Tactic.tactic_arg None (None, [gram])
diff --git a/parsing/egramcoq.mli b/parsing/egramcoq.mli
index 17524971f2..23eaa64eec 100644
--- a/parsing/egramcoq.mli
+++ b/parsing/egramcoq.mli
@@ -62,8 +62,8 @@ val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
(** {5 Adding tactic quotations} *)
-val create_ltac_quotation : string -> ('grm Loc.located -> 'raw) ->
- ('raw, 'glb, 'top) genarg_type -> 'grm Gram.entry -> unit
-(** [create_ltac_quotation name f wit e] adds a quotation rule to Ltac, that is,
- Ltac grammar now accepts arguments of the form ["name" ":" ], and
- generates a generic argument using [f] on the entry parsed by [e]. *)
+val create_ltac_quotation : string ->
+ ('grm Loc.located -> Tacexpr.raw_tactic_arg) -> ('grm Gram.entry * int option) -> unit
+(** [create_ltac_quotation name f e] adds a quotation rule to Ltac, that is,
+ Ltac grammar now accepts arguments of the form ["name" ":" "(" ")"], and
+ generates an argument using [f] on the entry parsed by [e]. *)
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 06675baa7d..e4ca936a69 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -147,13 +147,7 @@ GEXTEND Gram
;
(* Can be used as argument and at toplevel in tactic expressions. *)
tactic_arg:
- [ [ IDENT "uconstr"; ":"; "("; c = Constr.lconstr; ")" -> TacGeneric (genarg_of_uconstr c)
- | IDENT "constr"; ":"; "("; c = Constr.lconstr; ")" -> ConstrMayEval (ConstrTerm c)
- | IDENT "ltac"; ":"; "("; a = tactic_expr LEVEL "5"; ")" -> arg_of_expr a
- | IDENT "ltac"; ":"; "("; n = natural; ")" -> TacGeneric (genarg_of_int n)
- | IDENT "ipattern"; ":"; "("; ipat = simple_intropattern; ")" ->
- TacGeneric (genarg_of_ipattern ipat)
- | c = constr_eval -> ConstrMayEval c
+ [ [ c = constr_eval -> ConstrMayEval c
| IDENT "fresh"; l = LIST0 fresh_id -> TacFreshId l
| IDENT "type_term"; c=uconstr -> TacPretype c
| IDENT "numgoals" -> TacNumgoals ] ]
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 74d98176a4..7da6df717e 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -19,6 +19,8 @@ open Sigma.Notations
DECLARE PLUGIN "coretactics"
+(** Basic tactics *)
+
TACTIC EXTEND reflexivity
[ "reflexivity" ] -> [ Tactics.intros_reflexivity ]
END
diff --git a/tactics/extraargs.ml4 b/tactics/extraargs.ml4
index 8f336cdb30..9946aea82a 100644
--- a/tactics/extraargs.ml4
+++ b/tactics/extraargs.ml4
@@ -17,6 +17,20 @@ open Tacinterp
open Misctypes
open Locus
+(** Adding scopes for generic arguments not defined through ARGUMENT EXTEND *)
+
+let create_generic_quotation name e wit =
+ let inject (loc, v) = Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit wit) v) in
+ Egramcoq.create_ltac_quotation name inject (e, None)
+
+let () = create_generic_quotation "uconstr" Pcoq.Constr.lconstr Constrarg.wit_uconstr
+let () = create_generic_quotation "constr" Pcoq.Constr.lconstr Constrarg.wit_constr
+let () = create_generic_quotation "ipattern" Pcoq.Tactic.simple_intropattern Constrarg.wit_intro_pattern
+let () = create_generic_quotation "int" Pcoq.Prim.integer Stdarg.wit_int
+let () =
+ let inject (loc, v) = Tacexpr.Tacexp v in
+ Egramcoq.create_ltac_quotation "ltac" inject (Pcoq.Tactic.tactic_expr, Some 5)
+
(* Rewriting orientation *)
let _ = Metasyntax.add_token_obj "<-"
--
cgit v1.2.3
From cbc3a5f16871adb399689f7673a2a29a82dbf0cb Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 16:30:40 +0100
Subject: All arguments defined through ARGUMENT EXTEND declare a tactic scope.
Amongs other things, it kind of fixes bug #4492, even though you cannot really
take advantage of the parsed data for now.
---
CHANGES | 3 +++
grammar/argextend.ml4 | 7 +++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/CHANGES b/CHANGES
index ae055cb2f8..7de1015275 100644
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,9 @@ Tactics
for which pattern can be omitted, as in regular pattern-matching).
- Tactic scopes in Ltac like constr: and ltac: now require parentheses around
their argument.
+- Every generic argument type declares a tactic scope of the form "name:(...)"
+ where name is the name of the argument. This generalizes the constr: and ltac:
+ instances.
Program
diff --git a/grammar/argextend.ml4 b/grammar/argextend.ml4
index 13f7611131..65dc237bb7 100644
--- a/grammar/argextend.ml4
+++ b/grammar/argextend.ml4
@@ -231,8 +231,11 @@ let declare_tactic_argument loc s (typ, pr, f, g, h) cl =
<:str_item< do {
Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]);
Pptactic.declare_extra_genarg_pprule
- $wit$ $lid:rawpr$ $lid:globpr$ $lid:pr$ }
- >> ]
+ $wit$ $lid:rawpr$ $lid:globpr$ $lid:pr$;
+ Egramcoq.create_ltac_quotation $se$
+ (fun (loc, v) -> Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit $wit$) v))
+ ($lid:s$, None)
+ } >> ]
let declare_vernac_argument loc s pr cl =
let se = mlexpr_of_string s in
--
cgit v1.2.3
From b98e4857a13a4014c65882af5321ebdb09f41890 Mon Sep 17 00:00:00 2001
From: Maxime Dénès
Date: Fri, 4 Mar 2016 17:40:10 +0100
Subject: Rename Ephemeron -> CEphemeron.
Fixes compilation of Coq with OCaml 4.03 beta 1.
---
checker/check.mllib | 2 +-
dev/printers.mllib | 2 +-
kernel/csymtable.ml | 6 +-
kernel/entries.mli | 2 +-
kernel/pre_env.ml | 8 +--
kernel/pre_env.mli | 2 +-
kernel/safe_typing.ml | 4 +-
kernel/term_typing.ml | 4 +-
lib/cEphemeron.ml | 89 +++++++++++++++++++++++++++
lib/cEphemeron.mli | 52 ++++++++++++++++
lib/ephemeron.ml | 89 ---------------------------
lib/ephemeron.mli | 52 ----------------
lib/future.ml | 8 +--
lib/lib.mllib | 2 +-
plugins/funind/functional_principles_types.ml | 2 +-
plugins/funind/indfun_common.ml | 2 +-
plugins/funind/indfun_common.mli | 2 +-
proofs/proof_global.ml | 28 ++++-----
stm/asyncTaskQueue.ml | 2 +-
toplevel/obligations.ml | 16 ++---
20 files changed, 187 insertions(+), 187 deletions(-)
create mode 100644 lib/cEphemeron.ml
create mode 100644 lib/cEphemeron.mli
delete mode 100644 lib/ephemeron.ml
delete mode 100644 lib/ephemeron.mli
diff --git a/checker/check.mllib b/checker/check.mllib
index 0d36e3a0f1..902ab9ddf6 100644
--- a/checker/check.mllib
+++ b/checker/check.mllib
@@ -32,7 +32,7 @@ CStack
Util
Ppstyle
Errors
-Ephemeron
+CEphemeron
Future
CUnix
System
diff --git a/dev/printers.mllib b/dev/printers.mllib
index ab7e9fc346..ad9a5d75e6 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -48,7 +48,7 @@ Rtree
Heap
Genarg
Stateid
-Ephemeron
+CEphemeron
Future
RemoteCounter
Monad
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index fc7e1b9374..7e1a5d5b7e 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -131,8 +131,8 @@ let key rk =
match !rk with
| None -> raise NotEvaluated
| Some k ->
- try Ephemeron.get k
- with Ephemeron.InvalidKey -> raise NotEvaluated
+ try CEphemeron.get k
+ with CEphemeron.InvalidKey -> raise NotEvaluated
(************************)
(* traduction des patch *)
@@ -171,7 +171,7 @@ let rec slot_for_getglobal env kn =
| BCconstant -> set_global (val_of_constant kn)
in
(*Pp.msgnl(str"value stored at: "++int pos);*)
- rk := Some (Ephemeron.create pos);
+ rk := Some (CEphemeron.create pos);
pos
and slot_for_fv env fv =
diff --git a/kernel/entries.mli b/kernel/entries.mli
index b2a77dd950..f94068f31e 100644
--- a/kernel/entries.mli
+++ b/kernel/entries.mli
@@ -104,7 +104,7 @@ type side_eff =
| SEscheme of (inductive * constant * Declarations.constant_body * seff_env) list * string
type side_effect = {
- from_env : Declarations.structure_body Ephemeron.key;
+ from_env : Declarations.structure_body CEphemeron.key;
eff : side_eff;
}
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index e1fe02595a..df3495569a 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -25,7 +25,7 @@ open Declarations
(* The key attached to each constant is used by the VM to retrieve previous *)
(* evaluations of the constant. It is essentially an index in the symbols table *)
(* used by the VM. *)
-type key = int Ephemeron.key option ref
+type key = int CEphemeron.key option ref
(** Linking information for the native compiler. *)
@@ -50,17 +50,17 @@ type stratification = {
}
type val_kind =
- | VKvalue of (values * Id.Set.t) Ephemeron.key
+ | VKvalue of (values * Id.Set.t) CEphemeron.key
| VKnone
type lazy_val = val_kind ref
let force_lazy_val vk = match !vk with
| VKnone -> None
-| VKvalue v -> try Some (Ephemeron.get v) with Ephemeron.InvalidKey -> None
+| VKvalue v -> try Some (CEphemeron.get v) with CEphemeron.InvalidKey -> None
let dummy_lazy_val () = ref VKnone
-let build_lazy_val vk key = vk := VKvalue (Ephemeron.create key)
+let build_lazy_val vk key = vk := VKvalue (CEphemeron.create key)
type named_vals = (Id.t * lazy_val) list
diff --git a/kernel/pre_env.mli b/kernel/pre_env.mli
index 23f9a3f419..99d3e2e252 100644
--- a/kernel/pre_env.mli
+++ b/kernel/pre_env.mli
@@ -19,7 +19,7 @@ type link_info =
| LinkedInteractive of string
| NotLinked
-type key = int Ephemeron.key option ref
+type key = int CEphemeron.key option ref
type constant_key = constant_body * (link_info ref * key)
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 4c3264861e..0926d35f6d 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -231,11 +231,11 @@ let constant_entry_of_private_constant = function
let private_con_of_con env c =
let cbo = Environ.lookup_constant c env.env in
- { Entries.from_env = Ephemeron.create env.revstruct;
+ { Entries.from_env = CEphemeron.create env.revstruct;
Entries.eff = Entries.SEsubproof (c,cbo,get_opaque_body env.env cbo) }
let private_con_of_scheme ~kind env cl =
- { Entries.from_env = Ephemeron.create env.revstruct;
+ { Entries.from_env = CEphemeron.create env.revstruct;
Entries.eff = Entries.SEscheme(
List.map (fun (i,c) ->
let cbo = Environ.lookup_constant c env.env in
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 510f43542f..fdbd1e3b19 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -126,14 +126,14 @@ let check_signatures curmb sl =
| None -> None, None
| Some curmb ->
try
- let mb = Ephemeron.get mb in
+ let mb = CEphemeron.get mb in
match sl with
| None -> sl, None
| Some n ->
if List.length mb >= how_many && CList.skipn how_many mb == curmb
then Some (n + how_many), Some mb
else None, None
- with Ephemeron.InvalidKey -> None, None in
+ with CEphemeron.InvalidKey -> None, None in
let sl, _ = List.fold_left is_direct_ancestor (Some 0,Some curmb) sl in
sl
diff --git a/lib/cEphemeron.ml b/lib/cEphemeron.ml
new file mode 100644
index 0000000000..a38ea11e10
--- /dev/null
+++ b/lib/cEphemeron.ml
@@ -0,0 +1,89 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* boxed_key =
+ (* TODO: take a random value here. Is there a random function in OCaml? *)
+ let bid = ref 0 in
+ (* According to OCaml Gc module documentation, Pervasives.ref is one of the
+ few ways of getting a boxed value the compiler will never alias. *)
+ fun () -> incr bid; Pervasives.ref (Pervasives.ref !bid)
+
+(* A phantom type to preserve type safety *)
+type 'a key = boxed_key
+
+(* Comparing keys with == grants that if a key is unmarshalled (in the same
+ process where it was created or in another one) it is not mistaken for
+ an already existing one (unmarshal has no right to alias). If the initial
+ value of bid is taken at random, then one also avoids potential collisions *)
+module HT = Hashtbl.Make(struct
+ type t = key_type ref
+ let equal k1 k2 = k1 == k2
+ let hash id = !id
+end)
+
+(* A key is the (unique) value inside a boxed key, hence it does not
+ keep its corresponding boxed key reachable (replacing key_type by boxed_key
+ would make the key always reachable) *)
+let values : Obj.t HT.t = HT.create 1001
+
+(* To avoid a race contidion between the finalization function and
+ get/create on the values hashtable, the finalization function just
+ enqueues in an imperative list the item to be collected. Being the list
+ imperative, even if the Gc enqueue an item while run_collection is operating,
+ the tail of the list is eventually set to Empty on completion.
+ Kudos to the authors of Why3 that came up with this solution for their
+ implementation of weak hash tables! *)
+type imperative_list = cell ref
+and cell = Empty | Item of key_type ref * imperative_list
+
+let collection_queue : imperative_list ref = ref (ref Empty)
+
+let enqueue x = collection_queue := ref (Item (!x, !collection_queue))
+
+let run_collection () =
+ let rec aux l = match !l with
+ | Empty -> ()
+ | Item (k, tl) -> HT.remove values k; aux tl in
+ let l = !collection_queue in
+ aux l;
+ l := Empty
+
+(* The only reference to the boxed key is the one returned, when the user drops
+ it the value eventually disappears from the values table above *)
+let create (v : 'a) : 'a key =
+ run_collection ();
+ let k = mk_key () in
+ HT.add values !k (Obj.repr v);
+ Gc.finalise enqueue k;
+ k
+
+(* Avoid raising Not_found *)
+exception InvalidKey
+let get (k : 'a key) : 'a =
+ run_collection ();
+ try Obj.obj (HT.find values !k)
+ with Not_found -> raise InvalidKey
+
+(* Simple utils *)
+let default k v =
+ try get k
+ with InvalidKey -> v
+
+let iter_opt k f =
+ match
+ try Some (get k)
+ with InvalidKey -> None
+ with
+ | None -> ()
+ | Some v -> f v
+
+let clear () = run_collection ()
diff --git a/lib/cEphemeron.mli b/lib/cEphemeron.mli
new file mode 100644
index 0000000000..1200e4e208
--- /dev/null
+++ b/lib/cEphemeron.mli
@@ -0,0 +1,52 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* 'a key
+
+(* May raise InvalidKey *)
+exception InvalidKey
+val get : 'a key -> 'a
+
+(* These never fail. *)
+val iter_opt : 'a key -> ('a -> unit) -> unit
+val default : 'a key -> 'a -> 'a
+
+val clear : unit -> unit
diff --git a/lib/ephemeron.ml b/lib/ephemeron.ml
deleted file mode 100644
index a38ea11e10..0000000000
--- a/lib/ephemeron.ml
+++ /dev/null
@@ -1,89 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* boxed_key =
- (* TODO: take a random value here. Is there a random function in OCaml? *)
- let bid = ref 0 in
- (* According to OCaml Gc module documentation, Pervasives.ref is one of the
- few ways of getting a boxed value the compiler will never alias. *)
- fun () -> incr bid; Pervasives.ref (Pervasives.ref !bid)
-
-(* A phantom type to preserve type safety *)
-type 'a key = boxed_key
-
-(* Comparing keys with == grants that if a key is unmarshalled (in the same
- process where it was created or in another one) it is not mistaken for
- an already existing one (unmarshal has no right to alias). If the initial
- value of bid is taken at random, then one also avoids potential collisions *)
-module HT = Hashtbl.Make(struct
- type t = key_type ref
- let equal k1 k2 = k1 == k2
- let hash id = !id
-end)
-
-(* A key is the (unique) value inside a boxed key, hence it does not
- keep its corresponding boxed key reachable (replacing key_type by boxed_key
- would make the key always reachable) *)
-let values : Obj.t HT.t = HT.create 1001
-
-(* To avoid a race contidion between the finalization function and
- get/create on the values hashtable, the finalization function just
- enqueues in an imperative list the item to be collected. Being the list
- imperative, even if the Gc enqueue an item while run_collection is operating,
- the tail of the list is eventually set to Empty on completion.
- Kudos to the authors of Why3 that came up with this solution for their
- implementation of weak hash tables! *)
-type imperative_list = cell ref
-and cell = Empty | Item of key_type ref * imperative_list
-
-let collection_queue : imperative_list ref = ref (ref Empty)
-
-let enqueue x = collection_queue := ref (Item (!x, !collection_queue))
-
-let run_collection () =
- let rec aux l = match !l with
- | Empty -> ()
- | Item (k, tl) -> HT.remove values k; aux tl in
- let l = !collection_queue in
- aux l;
- l := Empty
-
-(* The only reference to the boxed key is the one returned, when the user drops
- it the value eventually disappears from the values table above *)
-let create (v : 'a) : 'a key =
- run_collection ();
- let k = mk_key () in
- HT.add values !k (Obj.repr v);
- Gc.finalise enqueue k;
- k
-
-(* Avoid raising Not_found *)
-exception InvalidKey
-let get (k : 'a key) : 'a =
- run_collection ();
- try Obj.obj (HT.find values !k)
- with Not_found -> raise InvalidKey
-
-(* Simple utils *)
-let default k v =
- try get k
- with InvalidKey -> v
-
-let iter_opt k f =
- match
- try Some (get k)
- with InvalidKey -> None
- with
- | None -> ()
- | Some v -> f v
-
-let clear () = run_collection ()
diff --git a/lib/ephemeron.mli b/lib/ephemeron.mli
deleted file mode 100644
index 1200e4e208..0000000000
--- a/lib/ephemeron.mli
+++ /dev/null
@@ -1,52 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* 'a key
-
-(* May raise InvalidKey *)
-exception InvalidKey
-val get : 'a key -> 'a
-
-(* These never fail. *)
-val iter_opt : 'a key -> ('a -> unit) -> unit
-val default : 'a key -> 'a -> 'a
-
-val clear : unit -> unit
diff --git a/lib/future.ml b/lib/future.ml
index 5cd2beba91..e8f33db5e1 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -62,7 +62,7 @@ and 'a comp =
| Exn of Exninfo.iexn (* Invariant: this exception is always "fixed" as in fix_exn *)
and 'a comput =
- | Ongoing of string * (UUID.t * fix_exn * 'a comp ref) Ephemeron.key
+ | Ongoing of string * (UUID.t * fix_exn * 'a comp ref) CEphemeron.key
| Finished of 'a
and 'a computation = 'a comput ref
@@ -70,13 +70,13 @@ and 'a computation = 'a comput ref
let unnamed = "unnamed"
let create ?(name=unnamed) ?(uuid=UUID.fresh ()) f x =
- ref (Ongoing (name, Ephemeron.create (uuid, f, Pervasives.ref x)))
+ ref (Ongoing (name, CEphemeron.create (uuid, f, Pervasives.ref x)))
let get x =
match !x with
| Finished v -> unnamed, UUID.invalid, id, ref (Val (v,None))
| Ongoing (name, x) ->
- try let uuid, fix, c = Ephemeron.get x in name, uuid, fix, c
- with Ephemeron.InvalidKey ->
+ try let uuid, fix, c = CEphemeron.get x in name, uuid, fix, c
+ with CEphemeron.InvalidKey ->
name, UUID.invalid, id, ref (Exn (NotHere name, Exninfo.null))
type 'a value = [ `Val of 'a | `Exn of Exninfo.iexn ]
diff --git a/lib/lib.mllib b/lib/lib.mllib
index f3f6ad8fc7..6805ce4919 100644
--- a/lib/lib.mllib
+++ b/lib/lib.mllib
@@ -15,6 +15,6 @@ Rtree
Heap
Unionfind
Genarg
-Ephemeron
+CEphemeron
Future
RemoteCounter
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index c47602bda0..18200307a8 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -291,7 +291,7 @@ let build_functional_principle (evd:Evd.evar_map ref) interactive_proof old_prin
(* let dur1 = System.time_difference tim1 tim2 in *)
(* Pp.msgnl (str ("Time to compute proof: ") ++ str (string_of_float dur1)); *)
(* end; *)
- get_proof_clean true, Ephemeron.create hook
+ get_proof_clean true, CEphemeron.create hook
end
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index aa47e26192..2449678a13 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -163,7 +163,7 @@ let save with_clean id const (locality,_,kind) hook =
(locality, ConstRef kn)
in
if with_clean then Pfedit.delete_current_proof ();
- Ephemeron.iter_opt hook (fun f -> Lemmas.call_hook fix_exn f l r);
+ CEphemeron.iter_opt hook (fun f -> Lemmas.call_hook fix_exn f l r);
definition_message id
diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli
index 23f1da1ba7..e5c756f564 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -47,7 +47,7 @@ val jmeq : unit -> Term.constr
val jmeq_refl : unit -> Term.constr
val save : bool -> Id.t -> Safe_typing.private_constants Entries.definition_entry -> Decl_kinds.goal_kind ->
- unit Lemmas.declaration_hook Ephemeron.key -> unit
+ unit Lemmas.declaration_hook CEphemeron.key -> unit
(* [get_proof_clean do_reduce] : returns the proof name, definition, kind and hook and
abort the proof
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index f22cdbcc8e..541f299d4f 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -36,7 +36,7 @@ let find_proof_mode n =
Errors.error (Format.sprintf "No proof mode named \"%s\"." n)
let register_proof_mode ({name = n} as m) =
- Hashtbl.add proof_modes n (Ephemeron.create m)
+ Hashtbl.add proof_modes n (CEphemeron.create m)
(* initial mode: standard mode *)
let standard = { name = "No" ; set = (fun ()->()) ; reset = (fun () -> ()) }
@@ -52,7 +52,7 @@ let _ =
optname = "default proof mode" ;
optkey = ["Default";"Proof";"Mode"] ;
optread = begin fun () ->
- (Ephemeron.default !default_proof_mode standard).name
+ (CEphemeron.default !default_proof_mode standard).name
end;
optwrite = begin fun n ->
default_proof_mode := find_proof_mode n
@@ -83,12 +83,12 @@ type closed_proof = proof_object * proof_terminator
type pstate = {
pid : Id.t;
- terminator : proof_terminator Ephemeron.key;
+ terminator : proof_terminator CEphemeron.key;
endline_tactic : Tacexpr.raw_tactic_expr option;
section_vars : Context.section_context option;
proof : Proof.proof;
strength : Decl_kinds.goal_kind;
- mode : proof_mode Ephemeron.key;
+ mode : proof_mode CEphemeron.key;
universe_binders: universe_binders option;
}
@@ -103,11 +103,11 @@ let current_proof_mode = ref !default_proof_mode
let update_proof_mode () =
match !pstates with
| { mode = m } :: _ ->
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
current_proof_mode := m;
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.set ())
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.set ())
| _ ->
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
current_proof_mode := find_proof_mode "No"
(* combinators for the current_proof lists *)
@@ -215,9 +215,9 @@ let set_proof_mode mn =
set_proof_mode (find_proof_mode mn) (get_current_proof_name ())
let activate_proof_mode mode =
- Ephemeron.iter_opt (find_proof_mode mode) (fun x -> x.set ())
+ CEphemeron.iter_opt (find_proof_mode mode) (fun x -> x.set ())
let disactivate_proof_mode mode =
- Ephemeron.iter_opt (find_proof_mode mode) (fun x -> x.reset ())
+ CEphemeron.iter_opt (find_proof_mode mode) (fun x -> x.reset ())
(** [start_proof sigma id str goals terminator] starts a proof of name
[id] with goals [goals] (a list of pairs of environment and
@@ -230,7 +230,7 @@ let disactivate_proof_mode mode =
let start_proof sigma id ?pl str goals terminator =
let initial_state = {
pid = id;
- terminator = Ephemeron.create terminator;
+ terminator = CEphemeron.create terminator;
proof = Proof.start sigma goals;
endline_tactic = None;
section_vars = None;
@@ -242,7 +242,7 @@ let start_proof sigma id ?pl str goals terminator =
let start_dependent_proof id ?pl str goals terminator =
let initial_state = {
pid = id;
- terminator = Ephemeron.create terminator;
+ terminator = CEphemeron.create terminator;
proof = Proof.dependent_start goals;
endline_tactic = None;
section_vars = None;
@@ -375,7 +375,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
in
{ id = pid; entries = entries; persistence = strength;
universes = (universes, binders) },
- fun pr_ending -> Ephemeron.get terminator pr_ending
+ fun pr_ending -> CEphemeron.get terminator pr_ending
type closed_proof_output = (Term.constr * Safe_typing.private_constants) list * Evd.evar_universe_context
@@ -423,11 +423,11 @@ let close_proof ~keep_body_ucst_separate fix_exn =
(** Gets the current terminator without checking that the proof has
been completed. Useful for the likes of [Admitted]. *)
-let get_terminator () = Ephemeron.get ( cur_pstate() ).terminator
+let get_terminator () = CEphemeron.get ( cur_pstate() ).terminator
let set_terminator hook =
match !pstates with
| [] -> raise NoCurrentProof
- | p :: ps -> pstates := { p with terminator = Ephemeron.create hook } :: ps
+ | p :: ps -> pstates := { p with terminator = CEphemeron.create hook } :: ps
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index cc97326047..5f018ec39d 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -314,7 +314,7 @@ module Make(T : Task) = struct
let response = slave_respond request in
report_status "Idle";
marshal_response (Option.get !slave_oc) response;
- Ephemeron.clear ()
+ CEphemeron.clear ()
with
| MarshalError s ->
pr_err ("Fatal marshal error: " ^ s); flush_all (); exit 2
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index 7e0d30a63e..615257a1c8 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -324,11 +324,11 @@ type program_info_aux = {
prg_sign: named_context_val;
}
-type program_info = program_info_aux Ephemeron.key
+type program_info = program_info_aux CEphemeron.key
let get_info x =
- try Ephemeron.get x
- with Ephemeron.InvalidKey ->
+ try CEphemeron.get x
+ with CEphemeron.InvalidKey ->
Errors.anomaly Pp.(str "Program obligation can't be accessed by a worker")
let assumption_message = Declare.assumption_message
@@ -461,7 +461,7 @@ let subst_deps_obl obls obl =
module ProgMap = Map.Make(Id)
-let map_replace k v m = ProgMap.add k (Ephemeron.create v) (ProgMap.remove k m)
+let map_replace k v m = ProgMap.add k (CEphemeron.create v) (ProgMap.remove k m)
let map_keys m = ProgMap.fold (fun k _ l -> k :: l) m []
@@ -682,7 +682,7 @@ let init_prog_info ?(opaque = false) sign n pl b t ctx deps fixkind
let map_cardinal m =
let i = ref 0 in
ProgMap.iter (fun _ v ->
- if snd (Ephemeron.get v).prg_obligations > 0 then incr i) m;
+ if snd (CEphemeron.get v).prg_obligations > 0 then incr i) m;
!i
exception Found of program_info
@@ -690,7 +690,7 @@ exception Found of program_info
let map_first m =
try
ProgMap.iter (fun _ v ->
- if snd (Ephemeron.get v).prg_obligations > 0 then
+ if snd (CEphemeron.get v).prg_obligations > 0 then
raise (Found v)) m;
assert(false)
with Found x -> x
@@ -1016,7 +1016,7 @@ let add_definition n ?term t ctx ?pl ?(implicits=[]) ?(kind=Global,false,Definit
else (
let len = Array.length obls in
let _ = Flags.if_verbose msg_info (info ++ str ", generating " ++ int len ++ str " obligation(s)") in
- progmap_add n (Ephemeron.create prg);
+ progmap_add n (CEphemeron.create prg);
let res = auto_solve_obligations (Some n) tactic in
match res with
| Remain rem -> Flags.if_verbose (fun () -> show_obligations ~msg:false (Some n)) (); res
@@ -1030,7 +1030,7 @@ let add_mutual_definitions l ctx ?pl ?tactic ?(kind=Global,false,Definition) ?(r
(fun (n, b, t, imps, obls) ->
let prg = init_prog_info sign ~opaque n pl (Some b) t ctx deps (Some fixkind)
notations obls imps kind reduce hook
- in progmap_add n (Ephemeron.create prg)) l;
+ in progmap_add n (CEphemeron.create prg)) l;
let _defined =
List.fold_left (fun finished x ->
if finished then finished
--
cgit v1.2.3
From 18a5eb4ecfcb7c2fbb315719c09e3d5fc0a3574e Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Fri, 4 Mar 2016 16:56:08 +0100
Subject: Adding some standard arguments in tactic scopes.
This is not perfect and repeats what we do in Pcoq, but it is hard to factorize
because rules defined in Pcoq do not have the same precedence. For instance,
constr as a Tactic Notation argument is a Pcoq.Constr.constr while as a
quotation argument is a Pcoq.Constr.lconstr. We should think of a fix in the
long run, but for now it is reasonable to duplicate code.
---
tactics/extraargs.ml4 | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tactics/extraargs.ml4 b/tactics/extraargs.ml4
index 9946aea82a..98868e8f91 100644
--- a/tactics/extraargs.ml4
+++ b/tactics/extraargs.ml4
@@ -23,10 +23,15 @@ let create_generic_quotation name e wit =
let inject (loc, v) = Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit wit) v) in
Egramcoq.create_ltac_quotation name inject (e, None)
+let () = create_generic_quotation "integer" Pcoq.Prim.integer Stdarg.wit_int
+let () = create_generic_quotation "string" Pcoq.Prim.string Stdarg.wit_string
+
+let () = create_generic_quotation "ident" Pcoq.Prim.ident Constrarg.wit_ident
+let () = create_generic_quotation "reference" Pcoq.Prim.reference Constrarg.wit_ref
let () = create_generic_quotation "uconstr" Pcoq.Constr.lconstr Constrarg.wit_uconstr
let () = create_generic_quotation "constr" Pcoq.Constr.lconstr Constrarg.wit_constr
let () = create_generic_quotation "ipattern" Pcoq.Tactic.simple_intropattern Constrarg.wit_intro_pattern
-let () = create_generic_quotation "int" Pcoq.Prim.integer Stdarg.wit_int
+let () = create_generic_quotation "open_constr" Pcoq.Constr.lconstr Constrarg.wit_open_constr
let () =
let inject (loc, v) = Tacexpr.Tacexp v in
Egramcoq.create_ltac_quotation "ltac" inject (Pcoq.Tactic.tactic_expr, Some 5)
--
cgit v1.2.3
From 120053a50f87bd53398eedc887fa5e979f56f112 Mon Sep 17 00:00:00 2001
From: Maxime Dénès
Date: Fri, 4 Mar 2016 18:17:56 +0100
Subject: This fix is probably not enough to justify that there are no problems
with primitive projections and prop. ext. or univalence, but at least it
prevents known proofs of false (see discussion on #4588).
---
kernel/inductive.ml | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 80dc690422..fbe0920bcf 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -814,7 +814,15 @@ let rec subterm_specif renv stack t =
| Proj (p, c) ->
let subt = subterm_specif renv stack c in
(match subt with
- | Subterm (s, wf) -> Subterm (Strict, wf)
+ | Subterm (s, wf) ->
+ (* We take the subterm specs of the constructor of the record *)
+ let wf_args = (dest_subterms wf).(0) in
+ (* We extract the tree of the projected argument *)
+ let kn = Projection.constant p in
+ let cb = lookup_constant kn renv.env in
+ let pb = Option.get cb.const_proj in
+ let n = pb.proj_arg in
+ Subterm (Strict, List.nth wf_args n)
| Dead_code -> Dead_code
| Not_subterm -> Not_subterm)
--
cgit v1.2.3
From 35cc038e96395b0f4eaaeed3a5a48e6da2293f7e Mon Sep 17 00:00:00 2001
From: Maxime Dénès
Date: Fri, 4 Mar 2016 19:01:35 +0100
Subject: Fix #4607: do not read native code files if native compiler was
disabled.
---
library/library.ml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/library/library.ml b/library/library.ml
index 79e5792c02..ccda57c2c5 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -171,9 +171,8 @@ let register_loaded_library m =
let prefix = Nativecode.mod_uid_of_dirpath libname ^ "." in
let f = prefix ^ "cmo" in
let f = Dynlink.adapt_filename f in
- (* This will not produce errors or warnings if the native compiler was
- not enabled *)
- Nativelib.link_library ~prefix ~dirname ~basename:f
+ if not Coq_config.no_native_compiler then
+ Nativelib.link_library ~prefix ~dirname ~basename:f
in
let rec aux = function
| [] -> link m; [libname]
--
cgit v1.2.3
From 32baedf7a3aebb96f7dd2c7d90a1aef40ed93792 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sat, 5 Mar 2016 18:16:31 +0100
Subject: Fixing bug #4608: Anomaly "output_value: abstract value (outside
heap)".
The ARGUMENT EXTEND statement was wrongly using a CompatLoc instead of a Loc,
and this was not detected by typing "thanks" to the Gram.action magic. When
using CAMLP4, this was wreaking havoc at runtime, but not when using CAMLP5,
as the locations where sharing the same representation.
---
grammar/argextend.ml4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grammar/argextend.ml4 b/grammar/argextend.ml4
index 8def9537cb..cb0f7d2d31 100644
--- a/grammar/argextend.ml4
+++ b/grammar/argextend.ml4
@@ -120,7 +120,7 @@ let make_possibly_empty_subentries loc s cl =
let make_act loc act pil =
let rec make = function
- | [] -> <:expr< Pcoq.Gram.action (fun loc -> ($act$ : 'a)) >>
+ | [] -> <:expr< Pcoq.Gram.action (fun loc -> let loc = Compat.to_coqloc loc in ($act$ : 'a)) >>
| GramNonTerminal (_,t,_,Some p) :: tl ->
let p = Names.Id.to_string p in
<:expr<
--
cgit v1.2.3
From c6d6e27330f0a1c9e89b6b60953d4df757edfdb8 Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Sat, 5 Mar 2016 18:13:23 +0100
Subject: Exporting build_selector, a component of discriminate, for use in
congruence.
---
tactics/equality.ml | 37 +++++++++++++++++++------------------
tactics/equality.mli | 5 +++++
2 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 453f81af57..8eadd4aeec 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -861,13 +861,13 @@ let descend_then env sigma head dirn =
*)
-(* [construct_discriminator env dirn headval]
- constructs a case-split on [headval], with the [dirn]-th branch
- giving [True], and all the rest giving False. *)
+(* [construct_discriminator env sigma dirn c ind special default]]
+ constructs a case-split on [c] of type [ind], with the [dirn]-th
+ branch giving [special], and all the rest giving [default]. *)
-let construct_discriminator env sigma dirn c sort =
+let build_selector env sigma dirn c ind special default =
let IndType(indf,_) =
- try find_rectype env sigma (get_type_of env sigma c)
+ try find_rectype env sigma ind
with Not_found ->
(* one can find Rel(k) in case of dependent constructors
like T := c : (A:Set)A->T and a discrimination
@@ -879,25 +879,29 @@ let construct_discriminator env sigma dirn c sort =
dependent types.") in
let (indp,_) = dest_ind_family indf in
let ind, _ = check_privacy env indp in
+ let typ = Retyping.get_type_of env sigma default in
let (mib,mip) = lookup_mind_specif env ind in
- let (true_0,false_0,sort_0) = build_coq_True(),build_coq_False(),Prop Null in
let deparsign = make_arity_signature env true indf in
- let p = it_mkLambda_or_LetIn (mkSort sort_0) deparsign in
+ let p = it_mkLambda_or_LetIn typ deparsign in
let cstrs = get_constructors env indf in
let build_branch i =
- let endpt = if Int.equal i dirn then true_0 else false_0 in
+ let endpt = if Int.equal i dirn then special else default in
it_mkLambda_or_LetIn endpt cstrs.(i-1).cs_args in
let brl =
List.map build_branch(List.interval 1 (Array.length mip.mind_consnames)) in
let ci = make_case_info env ind RegularStyle in
mkCase (ci, p, c, Array.of_list brl)
-let rec build_discriminator env sigma dirn c sort = function
- | [] -> construct_discriminator env sigma dirn c sort
+let rec build_discriminator env sigma dirn c = function
+ | [] ->
+ let ind = get_type_of env sigma c in
+ let true_0,false_0 =
+ build_coq_True(),build_coq_False() in
+ build_selector env sigma dirn c ind true_0 false_0
| ((sp,cnum),argnum)::l ->
let (cnum_nlams,cnum_env,kont) = descend_then env sigma c cnum in
let newc = mkRel(cnum_nlams-argnum) in
- let subval = build_discriminator cnum_env sigma dirn newc sort l in
+ let subval = build_discriminator cnum_env sigma dirn newc l in
kont subval (build_coq_False (),mkSort (Prop Null))
(* Note: discrimination could be more clever: if some elimination is
@@ -959,11 +963,11 @@ let apply_on_clause (f,t) clause =
| _ -> errorlabstrm "" (str "Ill-formed clause applicator.")) in
clenv_fchain ~with_univs:false argmv f_clause clause
-let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
+let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn =
let e = next_ident_away eq_baseid (ids_of_context env) in
let e_env = push_named (Context.Named.Declaration.LocalAssum (e,t)) env in
let discriminator =
- build_discriminator e_env sigma dirn (mkVar e) sort cpath in
+ build_discriminator e_env sigma dirn (mkVar e) cpath in
let sigma,(pf, absurd_term), eff =
discrimination_pf env sigma e (t,t1,t2) discriminator lbeq in
let pf_ty = mkArrow eqn absurd_term in
@@ -978,13 +982,11 @@ let discrEq (lbeq,_,(t,t1,t2) as u) eq_clause =
let sigma = eq_clause.evd in
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let concl = Proofview.Goal.concl gl in
match find_positions env sigma t1 t2 with
| Inr _ ->
tclZEROMSG (str"Not a discriminable equality.")
| Inl (cpath, (_,dirn), _) ->
- let sort = pf_apply get_type_of gl concl in
- discr_positions env sigma u eq_clause cpath dirn sort
+ discr_positions env sigma u eq_clause cpath dirn
end }
let onEquality with_evars tac (c,lbindc) =
@@ -1414,12 +1416,11 @@ let injHyp clear_flag id = injClause None false (Some (clear_flag,ElimOnIdent (L
let decompEqThen ntac (lbeq,_,(t,t1,t2) as u) clause =
Proofview.Goal.nf_enter { enter = begin fun gl ->
- let sort = pf_apply get_type_of gl (Proofview.Goal.concl gl) in
let sigma = clause.evd in
let env = Proofview.Goal.env gl in
match find_positions env sigma t1 t2 with
| Inl (cpath, (_,dirn), _) ->
- discr_positions env sigma u clause cpath dirn sort
+ discr_positions env sigma u clause cpath dirn
| Inr [] -> (* Change: do not fail, simplify clear this trivial hyp *)
ntac (clenv_value clause) 0
| Inr posns ->
diff --git a/tactics/equality.mli b/tactics/equality.mli
index f84dafb31f..458d8f3722 100644
--- a/tactics/equality.mli
+++ b/tactics/equality.mli
@@ -117,3 +117,8 @@ val subst_all : ?flags:subst_tactic_flags -> unit -> unit Proofview.tactic
val replace_term : bool option -> constr -> clause -> unit Proofview.tactic
val set_eq_dec_scheme_kind : mutual scheme_kind -> unit
+
+(* [build_selector env sigma i c t u v] matches on [c] of
+ type [t] and returns [u] in branch [i] and [v] on other branches *)
+val build_selector : env -> evar_map -> int -> constr -> types ->
+ constr -> constr -> constr
--
cgit v1.2.3
From eb0feed6d22c11c44e7091c64ce5b1c9d5af987a Mon Sep 17 00:00:00 2001
From: Hugo Herbelin
Date: Sat, 5 Mar 2016 18:23:05 +0100
Subject: Using build_selector from Equality as a replacement of the selector
in cctac which does not support indices properly.
Incidentally, this should fix a failure in RelationAlgebra, where
making prod_applist more robust (e8c47b652) revealed the discriminate
bug in congruence.
---
plugins/cc/cctac.ml | 25 +++++--------------------
test-suite/success/cc.v | 7 ++++++-
2 files changed, 11 insertions(+), 21 deletions(-)
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index b52f156a1b..a1aff12d4f 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -223,24 +223,9 @@ let make_prb gls depth additionnal_terms =
(* indhyps builds the array of arrays of constructor hyps for (ind largs) *)
-let build_projection intype outtype (cstr:pconstructor) special default gls=
- let env=pf_env gls in
- let (h,argv) = try destApp intype with DestKO -> (intype,[||]) in
- let ind,u=destInd h in
- let types=Inductiveops.arities_of_constructors env (ind,u) in
- let lp=Array.length types in
- let ci=pred (snd(fst cstr)) in
- let branch i=
- let ti= prod_appvect types.(i) argv in
- let rc=fst (decompose_prod_assum ti) in
- let head=
- if Int.equal i ci then special else default in
- it_mkLambda_or_LetIn head rc in
- let branches=Array.init lp branch in
- let casee=mkRel 1 in
- let pred=mkLambda(Anonymous,intype,outtype) in
- let case_info=make_case_info (pf_env gls) ind RegularStyle in
- let body= mkCase(case_info, pred, casee, branches) in
+let build_projection intype (cstr:pconstructor) special default gls=
+ let ci= (snd(fst cstr)) in
+ let body=Equality.build_selector (pf_env gls) (project gls) ci (mkRel 1) intype special default in
let id=pf_get_new_id (Id.of_string "t") gls in
mkLambda(Name id,intype,body)
@@ -322,7 +307,7 @@ let rec proof_tac p : unit Proofview.tactic =
let outtype = (* Termops.refresh_universes *) (type_of default) in
let special=mkRel (1+nargs-argind) in
let proj =
- Tacmach.New.of_old (build_projection intype outtype cstr special default) gl
+ Tacmach.New.of_old (build_projection intype cstr special default) gl
in
let injt=
app_global _f_equal [|intype;outtype;proj;ti;tj;_M 1|] in
@@ -391,7 +376,7 @@ let discriminate_tac (cstr,u as cstru) p =
let outtype = mkSort outtype in
let pred=mkLambda(Name xid,outtype,mkRel 1) in
let hid = Tacmach.New.of_old (pf_get_new_id (Id.of_string "Heq")) gl in
- let proj = Tacmach.New.of_old (build_projection intype outtype cstru trivial concl) gl in
+ let proj = Tacmach.New.of_old (build_projection intype cstru trivial concl) gl in
let injt=app_global _f_equal
[|intype;outtype;proj;t1;t2;mkVar hid|] in
let endt k =
diff --git a/test-suite/success/cc.v b/test-suite/success/cc.v
index a70d919635..dc0527d826 100644
--- a/test-suite/success/cc.v
+++ b/test-suite/success/cc.v
@@ -129,5 +129,10 @@ Qed.
End bug_2447.
+(* congruence was supposed to do discriminate but it was bugged for
+ types with indices *)
-
+Inductive I : nat -> Type := C : I 0 | D : I 0.
+Goal ~C=D.
+congruence.
+Qed.
--
cgit v1.2.3
From 8d828a124d66a79b6e35c02097b05df252d1e1d4 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 03:02:01 +0100
Subject: Moving Eauto to a simple ML file.
---
plugins/funind/functional_principles_proofs.ml | 2 +-
tactics/eauto.ml | 528 +++++++++++++++++++
tactics/eauto.ml4 | 667 -------------------------
tactics/eauto.mli | 14 +-
tactics/g_auto.ml4 | 130 +++++
tactics/hightactics.mllib | 2 +-
theories/Init/Notations.v | 1 -
7 files changed, 668 insertions(+), 676 deletions(-)
create mode 100644 tactics/eauto.ml
delete mode 100644 tactics/eauto.ml4
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index c8f8a19e5b..02cd819f4a 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -1407,7 +1407,7 @@ let prove_with_tcc tcc_lemma_constr eqs : tactic =
(* let ids = List.filter (fun id -> not (List.mem id ids)) ids' in *)
(* rewrite *)
(* ) *)
- Eauto.gen_eauto (false,5) [] (Some [])
+ Proofview.V82.of_tactic (Eauto.gen_eauto (false,5) [] (Some []))
]
gls
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
new file mode 100644
index 0000000000..a118f2642f
--- /dev/null
+++ b/tactics/eauto.ml
@@ -0,0 +1,528 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(*
+ let t1 = Tacmach.New.pf_unsafe_type_of gl c in
+ let t2 = Tacmach.New.pf_concl gl in
+ if occur_existential t1 || occur_existential t2 then
+ Tacticals.New.tclTHEN (Clenvtac.unify ~flags t1) (Proofview.V82.tactic (exact_no_check c))
+ else exact_check c
+ end }
+
+let assumption id = e_give_exact (mkVar id)
+
+let e_assumption =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ Tacticals.New.tclFIRST (List.map assumption (Tacmach.New.pf_ids_of_hyps gl))
+ end }
+
+let registered_e_assumption =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ Tacticals.New.tclFIRST (List.map (fun id -> e_give_exact (mkVar id))
+ (Tacmach.New.pf_ids_of_hyps gl))
+ end }
+
+let eval_uconstrs ist cs =
+ let flags = {
+ Pretyping.use_typeclasses = false;
+ use_unif_heuristics = true;
+ use_hook = Some Pfedit.solve_by_implicit_tactic;
+ fail_evar = false;
+ expand_evars = true
+ } in
+ List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
+
+(************************************************************************)
+(* PROLOG tactic *)
+(************************************************************************)
+
+(*s Tactics handling a list of goals. *)
+
+(* first_goal : goal list sigma -> goal sigma *)
+
+let first_goal gls =
+ let gl = gls.Evd.it and sig_0 = gls.Evd.sigma in
+ if List.is_empty gl then error "first_goal";
+ { Evd.it = List.hd gl; Evd.sigma = sig_0; }
+
+(* tactic -> tactic_list : Apply a tactic to the first goal in the list *)
+
+let apply_tac_list tac glls =
+ let (sigr,lg) = unpackage glls in
+ match lg with
+ | (g1::rest) ->
+ let gl = apply_sig_tac sigr tac g1 in
+ repackage sigr (gl@rest)
+ | _ -> error "apply_tac_list"
+
+let one_step l gl =
+ [Proofview.V82.of_tactic Tactics.intro]
+ @ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) (List.map mkVar (pf_ids_of_hyps gl)))
+ @ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) l)
+ @ (List.map (fun c -> Proofview.V82.of_tactic (assumption c)) (pf_ids_of_hyps gl))
+
+let rec prolog l n gl =
+ if n <= 0 then error "prolog - failure";
+ let prol = (prolog l (n-1)) in
+ (tclFIRST (List.map (fun t -> (tclTHEN t prol)) (one_step l gl))) gl
+
+let out_term = function
+ | IsConstr (c, _) -> c
+ | IsGlobRef gr -> fst (Universes.fresh_global_instance (Global.env ()) gr)
+
+let prolog_tac l n =
+ Proofview.V82.tactic begin fun gl ->
+ let map c =
+ let (c, sigma) = Tactics.run_delayed (pf_env gl) (project gl) c in
+ let c = pf_apply (prepare_hint false (false,true)) gl (sigma, c) in
+ out_term c
+ in
+ let l = List.map map l in
+ try (prolog l n gl)
+ with UserError ("Refiner.tclFIRST",_) ->
+ errorlabstrm "Prolog.prolog" (str "Prolog failed.")
+ end
+
+open Auto
+open Unification
+
+(***************************************************************************)
+(* A tactic similar to Auto, but using EApply, Assumption and e_give_exact *)
+(***************************************************************************)
+
+let priority l = List.map snd (List.filter (fun (pr,_) -> Int.equal pr 0) l)
+
+let unify_e_resolve poly flags (c,clenv) =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let clenv', c = connect_hint_clenv poly c clenv gl in
+ Proofview.V82.tactic
+ (fun gls ->
+ let clenv' = clenv_unique_resolver ~flags clenv' gls in
+ tclTHEN (Refiner.tclEVARUNIVCONTEXT (Evd.evar_universe_context clenv'.evd))
+ (Proofview.V82.of_tactic (Tactics.Simple.eapply c)) gls)
+ end }
+
+let hintmap_of hdc concl =
+ match hdc with
+ | None -> fun db -> Hint_db.map_none db
+ | Some hdc ->
+ if occur_existential concl then (fun db -> Hint_db.map_existential hdc concl db)
+ else (fun db -> Hint_db.map_auto hdc concl db)
+ (* FIXME: should be (Hint_db.map_eauto hdc concl db) *)
+
+let e_exact poly flags (c,clenv) =
+ let (c, _, _) = c in
+ let clenv', subst =
+ if poly then Clenv.refresh_undefined_univs clenv
+ else clenv, Univ.empty_level_subst
+ in e_give_exact (* ~flags *) (Vars.subst_univs_level_constr subst c)
+
+let rec e_trivial_fail_db db_list local_db =
+ let next = Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let d = Tacmach.New.pf_last_hyp gl in
+ let hintl = make_resolve_hyp (Tacmach.New.pf_env gl) (Tacmach.New.project gl) d in
+ e_trivial_fail_db db_list (Hint_db.add_list (Tacmach.New.pf_env gl) (Tacmach.New.project gl) hintl local_db)
+ end } in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let tacl =
+ registered_e_assumption ::
+ (Tacticals.New.tclTHEN Tactics.intro next) ::
+ (List.map fst (e_trivial_resolve db_list local_db (Tacmach.New.pf_nf_concl gl)))
+ in
+ Tacticals.New.tclFIRST (List.map Tacticals.New.tclCOMPLETE tacl)
+ end }
+
+and e_my_find_search db_list local_db hdc concl =
+ let hint_of_db = hintmap_of hdc concl in
+ let hintl =
+ List.map_append (fun db ->
+ let flags = auto_flags_of_state (Hint_db.transparent_state db) in
+ List.map (fun x -> flags, x) (hint_of_db db)) (local_db::db_list)
+ in
+ let tac_of_hint =
+ fun (st, {pri = b; pat = p; code = t; poly = poly}) ->
+ let b = match Hints.repr_hint t with
+ | Unfold_nth _ -> 1
+ | _ -> b
+ in
+ (b,
+ let tac = function
+ | Res_pf (term,cl) -> unify_resolve poly st (term,cl)
+ | ERes_pf (term,cl) -> unify_e_resolve poly st (term,cl)
+ | Give_exact (c,cl) -> e_exact poly st (c,cl)
+ | Res_pf_THEN_trivial_fail (term,cl) ->
+ Tacticals.New.tclTHEN (unify_e_resolve poly st (term,cl))
+ (e_trivial_fail_db db_list local_db)
+ | Unfold_nth c -> reduce (Unfold [AllOccurrences,c]) onConcl
+ | Extern tacast -> conclPattern concl p tacast
+ in
+ let tac = run_hint t tac in
+ (tac, lazy (pr_hint t)))
+ in
+ List.map tac_of_hint hintl
+
+and e_trivial_resolve db_list local_db gl =
+ let hd = try Some (decompose_app_bound gl) with Bound -> None in
+ try priority (e_my_find_search db_list local_db hd gl)
+ with Not_found -> []
+
+let e_possible_resolve db_list local_db gl =
+ let hd = try Some (decompose_app_bound gl) with Bound -> None in
+ try List.map (fun (b, (tac, pp)) -> (tac, b, pp)) (e_my_find_search db_list local_db hd gl)
+ with Not_found -> []
+
+let find_first_goal gls =
+ try first_goal gls with UserError _ -> assert false
+
+(*s The following module [SearchProblem] is used to instantiate the generic
+ exploration functor [Explore.Make]. *)
+
+type search_state = {
+ priority : int;
+ depth : int; (*r depth of search before failing *)
+ tacres : goal list sigma;
+ last_tactic : std_ppcmds Lazy.t;
+ dblist : hint_db list;
+ localdb : hint_db list;
+ prev : prev_search_state;
+ local_lemmas : Tacexpr.delayed_open_constr list;
+}
+
+and prev_search_state = (* for info eauto *)
+ | Unknown
+ | Init
+ | State of search_state
+
+module SearchProblem = struct
+
+ type state = search_state
+
+ let success s = List.is_empty (sig_it s.tacres)
+
+(* let pr_ev evs ev = Printer.pr_constr_env (Evd.evar_env ev) (Evarutil.nf_evar evs ev.Evd.evar_concl) *)
+
+ let filter_tactics glls l =
+(* let _ = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
+(* let evars = Evarutil.nf_evars (Refiner.project glls) in *)
+(* msg (str"Goal:" ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n"); *)
+ let rec aux = function
+ | [] -> []
+ | (tac, cost, pptac) :: tacl ->
+ try
+ let lgls = apply_tac_list (Proofview.V82.of_tactic tac) glls in
+(* let gl = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
+(* msg (hov 1 (pptac ++ str" gives: \n" ++ pr_goals lgls ++ str"\n")); *)
+ (lgls, cost, pptac) :: aux tacl
+ with e when Errors.noncritical e ->
+ let e = Errors.push e in
+ Refiner.catch_failerror e; aux tacl
+ in aux l
+
+ (* Ordering of states is lexicographic on depth (greatest first) then
+ number of remaining goals. *)
+ let compare s s' =
+ let d = s'.depth - s.depth in
+ let d' = Int.compare s.priority s'.priority in
+ let nbgoals s = List.length (sig_it s.tacres) in
+ if not (Int.equal d 0) then d
+ else if not (Int.equal d' 0) then d'
+ else Int.compare (nbgoals s) (nbgoals s')
+
+ let branching s =
+ if Int.equal s.depth 0 then
+ []
+ else
+ let ps = if s.prev == Unknown then Unknown else State s in
+ let lg = s.tacres in
+ let nbgl = List.length (sig_it lg) in
+ assert (nbgl > 0);
+ let g = find_first_goal lg in
+ let map_assum id = (e_give_exact (mkVar id), (-1), lazy (str "exact" ++ spc () ++ pr_id id)) in
+ let assumption_tacs =
+ let tacs = List.map map_assum (pf_ids_of_hyps g) in
+ let l = filter_tactics s.tacres tacs in
+ List.map (fun (res, cost, pp) -> { depth = s.depth; priority = cost; tacres = res;
+ last_tactic = pp; dblist = s.dblist;
+ localdb = List.tl s.localdb;
+ prev = ps; local_lemmas = s.local_lemmas}) l
+ in
+ let intro_tac =
+ let l = filter_tactics s.tacres [Tactics.intro, (-1), lazy (str "intro")] in
+ List.map
+ (fun (lgls, cost, pp) ->
+ let g' = first_goal lgls in
+ let hintl =
+ make_resolve_hyp (pf_env g') (project g') (pf_last_hyp g')
+ in
+ let ldb = Hint_db.add_list (pf_env g') (project g')
+ hintl (List.hd s.localdb) in
+ { depth = s.depth; priority = cost; tacres = lgls;
+ last_tactic = pp; dblist = s.dblist;
+ localdb = ldb :: List.tl s.localdb; prev = ps;
+ local_lemmas = s.local_lemmas})
+ l
+ in
+ let rec_tacs =
+ let l =
+ filter_tactics s.tacres (e_possible_resolve s.dblist (List.hd s.localdb) (pf_concl g))
+ in
+ List.map
+ (fun (lgls, cost, pp) ->
+ let nbgl' = List.length (sig_it lgls) in
+ if nbgl' < nbgl then
+ { depth = s.depth; priority = cost; tacres = lgls; last_tactic = pp;
+ prev = ps; dblist = s.dblist; localdb = List.tl s.localdb;
+ local_lemmas = s.local_lemmas }
+ else
+ let newlocal =
+ let hyps = pf_hyps g in
+ List.map (fun gl ->
+ let gls = {Evd.it = gl; sigma = lgls.Evd.sigma } in
+ let hyps' = pf_hyps gls in
+ if hyps' == hyps then List.hd s.localdb
+ else make_local_hint_db (pf_env gls) (project gls) ~ts:full_transparent_state true s.local_lemmas)
+ (List.firstn ((nbgl'-nbgl) + 1) (sig_it lgls))
+ in
+ { depth = pred s.depth; priority = cost; tacres = lgls;
+ dblist = s.dblist; last_tactic = pp; prev = ps;
+ localdb = newlocal @ List.tl s.localdb;
+ local_lemmas = s.local_lemmas })
+ l
+ in
+ List.sort compare (assumption_tacs @ intro_tac @ rec_tacs)
+
+ let pp s = hov 0 (str " depth=" ++ int s.depth ++ spc () ++
+ (Lazy.force s.last_tactic))
+
+end
+
+module Search = Explore.Make(SearchProblem)
+
+(** Utilities for debug eauto / info eauto *)
+
+let global_debug_eauto = ref false
+let global_info_eauto = ref false
+
+let _ =
+ Goptions.declare_bool_option
+ { Goptions.optsync = true;
+ Goptions.optdepr = false;
+ Goptions.optname = "Debug Eauto";
+ Goptions.optkey = ["Debug";"Eauto"];
+ Goptions.optread = (fun () -> !global_debug_eauto);
+ Goptions.optwrite = (:=) global_debug_eauto }
+
+let _ =
+ Goptions.declare_bool_option
+ { Goptions.optsync = true;
+ Goptions.optdepr = false;
+ Goptions.optname = "Info Eauto";
+ Goptions.optkey = ["Info";"Eauto"];
+ Goptions.optread = (fun () -> !global_info_eauto);
+ Goptions.optwrite = (:=) global_info_eauto }
+
+let mk_eauto_dbg d =
+ if d == Debug || !global_debug_eauto then Debug
+ else if d == Info || !global_info_eauto then Info
+ else Off
+
+let pr_info_nop = function
+ | Info -> msg_debug (str "idtac.")
+ | _ -> ()
+
+let pr_dbg_header = function
+ | Off -> ()
+ | Debug -> msg_debug (str "(* debug eauto : *)")
+ | Info -> msg_debug (str "(* info eauto : *)")
+
+let pr_info dbg s =
+ if dbg != Info then ()
+ else
+ let rec loop s =
+ match s.prev with
+ | Unknown | Init -> s.depth
+ | State sp ->
+ let mindepth = loop sp in
+ let indent = String.make (mindepth - sp.depth) ' ' in
+ msg_debug (str indent ++ Lazy.force s.last_tactic ++ str ".");
+ mindepth
+ in
+ ignore (loop s)
+
+(** Eauto main code *)
+
+let make_initial_state dbg n gl dblist localdb lems =
+ { depth = n;
+ priority = 0;
+ tacres = tclIDTAC gl;
+ last_tactic = lazy (mt());
+ dblist = dblist;
+ localdb = [localdb];
+ prev = if dbg == Info then Init else Unknown;
+ local_lemmas = lems;
+ }
+
+let e_search_auto debug (in_depth,p) lems db_list gl =
+ let local_db = make_local_hint_db (pf_env gl) (project gl) ~ts:full_transparent_state true lems in
+ let d = mk_eauto_dbg debug in
+ let tac = match in_depth,d with
+ | (true,Debug) -> Search.debug_depth_first
+ | (true,_) -> Search.depth_first
+ | (false,Debug) -> Search.debug_breadth_first
+ | (false,_) -> Search.breadth_first
+ in
+ try
+ pr_dbg_header d;
+ let s = tac (make_initial_state d p gl db_list local_db lems) in
+ pr_info d s;
+ s.tacres
+ with Not_found ->
+ pr_info_nop d;
+ error "eauto: search failed"
+
+(* let e_search_auto_key = Profile.declare_profile "e_search_auto" *)
+(* let e_search_auto = Profile.profile5 e_search_auto_key e_search_auto *)
+
+let eauto_with_bases ?(debug=Off) np lems db_list =
+ tclTRY (e_search_auto debug np lems db_list)
+
+let eauto ?(debug=Off) np lems dbnames =
+ let db_list = make_db_list dbnames in
+ tclTRY (e_search_auto debug np lems db_list)
+
+let full_eauto ?(debug=Off) n lems gl =
+ let dbnames = current_db_names () in
+ let dbnames = String.Set.remove "v62" dbnames in
+ let db_list = List.map searchtable_map (String.Set.elements dbnames) in
+ tclTRY (e_search_auto debug n lems db_list) gl
+
+let gen_eauto ?(debug=Off) np lems = function
+ | None -> Proofview.V82.tactic (full_eauto ~debug np lems)
+ | Some l -> Proofview.V82.tactic (eauto ~debug np lems l)
+
+let make_depth = function
+ | None -> !default_search_depth
+ | Some d -> d
+
+let make_dimension n = function
+ | None -> (true,make_depth n)
+ | Some d -> (false,d)
+
+let cons a l = a :: l
+
+let autounfolds db occs cls gl =
+ let unfolds = List.concat (List.map (fun dbname ->
+ let db = try searchtable_map dbname
+ with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname)
+ in
+ let (ids, csts) = Hint_db.unfolds db in
+ let hyps = pf_ids_of_hyps gl in
+ let ids = Idset.filter (fun id -> List.mem id hyps) ids in
+ Cset.fold (fun cst -> cons (AllOccurrences, EvalConstRef cst)) csts
+ (Id.Set.fold (fun id -> cons (AllOccurrences, EvalVarRef id)) ids [])) db)
+ in Proofview.V82.of_tactic (unfold_option unfolds cls) gl
+
+let autounfold db cls =
+ Proofview.V82.tactic begin fun gl ->
+ let cls = concrete_clause_of (fun () -> pf_ids_of_hyps gl) cls in
+ let tac = autounfolds db in
+ tclMAP (function
+ | OnHyp (id,occs,where) -> tac occs (Some (id,where))
+ | OnConcl occs -> tac occs None)
+ cls gl
+ end
+
+let autounfold_tac db cls =
+ Proofview.tclUNIT () >>= fun () ->
+ let dbs = match db with
+ | None -> String.Set.elements (current_db_names ())
+ | Some [] -> ["core"]
+ | Some l -> l
+ in
+ autounfold dbs cls
+
+let unfold_head env (ids, csts) c =
+ let rec aux c =
+ match kind_of_term c with
+ | Var id when Id.Set.mem id ids ->
+ (match Environ.named_body id env with
+ | Some b -> true, b
+ | None -> false, c)
+ | Const (cst,u as c) when Cset.mem cst csts ->
+ true, Environ.constant_value_in env c
+ | App (f, args) ->
+ (match aux f with
+ | true, f' -> true, Reductionops.whd_betaiota Evd.empty (mkApp (f', args))
+ | false, _ ->
+ let done_, args' =
+ Array.fold_left_i (fun i (done_, acc) arg ->
+ if done_ then done_, arg :: acc
+ else match aux arg with
+ | true, arg' -> true, arg' :: acc
+ | false, arg' -> false, arg :: acc)
+ (false, []) args
+ in
+ if done_ then true, mkApp (f, Array.of_list (List.rev args'))
+ else false, c)
+ | _ ->
+ let done_ = ref false in
+ let c' = map_constr (fun c ->
+ if !done_ then c else
+ let x, c' = aux c in
+ done_ := x; c') c
+ in !done_, c'
+ in aux c
+
+let autounfold_one db cl =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let concl = Proofview.Goal.concl gl in
+ let st =
+ List.fold_left (fun (i,c) dbname ->
+ let db = try searchtable_map dbname
+ with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname)
+ in
+ let (ids, csts) = Hint_db.unfolds db in
+ (Id.Set.union ids i, Cset.union csts c)) (Id.Set.empty, Cset.empty) db
+ in
+ let did, c' = unfold_head env st
+ (match cl with Some (id, _) -> Tacmach.New.pf_get_hyp_typ id gl | None -> concl)
+ in
+ if did then
+ match cl with
+ | Some hyp -> change_in_hyp None (make_change_arg c') hyp
+ | None -> convert_concl_no_check c' DEFAULTcast
+ else Tacticals.New.tclFAIL 0 (str "Nothing to unfold")
+ end }
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4
deleted file mode 100644
index f2d26ec86b..0000000000
--- a/tactics/eauto.ml4
+++ /dev/null
@@ -1,667 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(*
- let t1 = Tacmach.New.pf_unsafe_type_of gl c in
- let t2 = Tacmach.New.pf_concl gl in
- if occur_existential t1 || occur_existential t2 then
- Tacticals.New.tclTHEN (Clenvtac.unify ~flags t1) (Proofview.V82.tactic (exact_no_check c))
- else exact_check c
- end }
-
-let assumption id = e_give_exact (mkVar id)
-
-let e_assumption =
- Proofview.Goal.enter { enter = begin fun gl ->
- Tacticals.New.tclFIRST (List.map assumption (Tacmach.New.pf_ids_of_hyps gl))
- end }
-
-TACTIC EXTEND eassumption
-| [ "eassumption" ] -> [ e_assumption ]
-END
-
-TACTIC EXTEND eexact
-| [ "eexact" constr(c) ] -> [ e_give_exact c ]
-END
-
-let registered_e_assumption =
- Proofview.Goal.enter { enter = begin fun gl ->
- Tacticals.New.tclFIRST (List.map (fun id -> e_give_exact (mkVar id))
- (Tacmach.New.pf_ids_of_hyps gl))
- end }
-
-let eval_uconstrs ist cs =
- let flags = {
- Pretyping.use_typeclasses = false;
- use_unif_heuristics = true;
- use_hook = Some Pfedit.solve_by_implicit_tactic;
- fail_evar = false;
- expand_evars = true
- } in
- List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
-
-(************************************************************************)
-(* PROLOG tactic *)
-(************************************************************************)
-
-(*s Tactics handling a list of goals. *)
-
-(* first_goal : goal list sigma -> goal sigma *)
-
-let first_goal gls =
- let gl = gls.Evd.it and sig_0 = gls.Evd.sigma in
- if List.is_empty gl then error "first_goal";
- { Evd.it = List.hd gl; Evd.sigma = sig_0; }
-
-(* tactic -> tactic_list : Apply a tactic to the first goal in the list *)
-
-let apply_tac_list tac glls =
- let (sigr,lg) = unpackage glls in
- match lg with
- | (g1::rest) ->
- let gl = apply_sig_tac sigr tac g1 in
- repackage sigr (gl@rest)
- | _ -> error "apply_tac_list"
-
-let one_step l gl =
- [Proofview.V82.of_tactic Tactics.intro]
- @ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) (List.map mkVar (pf_ids_of_hyps gl)))
- @ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) l)
- @ (List.map (fun c -> Proofview.V82.of_tactic (assumption c)) (pf_ids_of_hyps gl))
-
-let rec prolog l n gl =
- if n <= 0 then error "prolog - failure";
- let prol = (prolog l (n-1)) in
- (tclFIRST (List.map (fun t -> (tclTHEN t prol)) (one_step l gl))) gl
-
-let out_term = function
- | IsConstr (c, _) -> c
- | IsGlobRef gr -> fst (Universes.fresh_global_instance (Global.env ()) gr)
-
-let prolog_tac l n gl =
- let map c =
- let (c, sigma) = Tactics.run_delayed (pf_env gl) (project gl) c in
- let c = pf_apply (prepare_hint false (false,true)) gl (sigma, c) in
- out_term c
- in
- let l = List.map map l in
- try (prolog l n gl)
- with UserError ("Refiner.tclFIRST",_) ->
- errorlabstrm "Prolog.prolog" (str "Prolog failed.")
-
-TACTIC EXTEND prolog
-| [ "prolog" "[" uconstr_list(l) "]" int_or_var(n) ] ->
- [ Proofview.V82.tactic (prolog_tac (eval_uconstrs ist l) n) ]
-END
-
-open Auto
-open Unification
-
-(***************************************************************************)
-(* A tactic similar to Auto, but using EApply, Assumption and e_give_exact *)
-(***************************************************************************)
-
-let priority l = List.map snd (List.filter (fun (pr,_) -> Int.equal pr 0) l)
-
-let unify_e_resolve poly flags (c,clenv) =
- Proofview.Goal.nf_enter { enter = begin fun gl ->
- let clenv', c = connect_hint_clenv poly c clenv gl in
- Proofview.V82.tactic
- (fun gls ->
- let clenv' = clenv_unique_resolver ~flags clenv' gls in
- tclTHEN (Refiner.tclEVARUNIVCONTEXT (Evd.evar_universe_context clenv'.evd))
- (Proofview.V82.of_tactic (Tactics.Simple.eapply c)) gls)
- end }
-
-let hintmap_of hdc concl =
- match hdc with
- | None -> fun db -> Hint_db.map_none db
- | Some hdc ->
- if occur_existential concl then (fun db -> Hint_db.map_existential hdc concl db)
- else (fun db -> Hint_db.map_auto hdc concl db)
- (* FIXME: should be (Hint_db.map_eauto hdc concl db) *)
-
-let e_exact poly flags (c,clenv) =
- let (c, _, _) = c in
- let clenv', subst =
- if poly then Clenv.refresh_undefined_univs clenv
- else clenv, Univ.empty_level_subst
- in e_give_exact (* ~flags *) (Vars.subst_univs_level_constr subst c)
-
-let rec e_trivial_fail_db db_list local_db =
- let next = Proofview.Goal.nf_enter { enter = begin fun gl ->
- let d = Tacmach.New.pf_last_hyp gl in
- let hintl = make_resolve_hyp (Tacmach.New.pf_env gl) (Tacmach.New.project gl) d in
- e_trivial_fail_db db_list (Hint_db.add_list (Tacmach.New.pf_env gl) (Tacmach.New.project gl) hintl local_db)
- end } in
- Proofview.Goal.enter { enter = begin fun gl ->
- let tacl =
- registered_e_assumption ::
- (Tacticals.New.tclTHEN Tactics.intro next) ::
- (List.map fst (e_trivial_resolve db_list local_db (Tacmach.New.pf_nf_concl gl)))
- in
- Tacticals.New.tclFIRST (List.map Tacticals.New.tclCOMPLETE tacl)
- end }
-
-and e_my_find_search db_list local_db hdc concl =
- let hint_of_db = hintmap_of hdc concl in
- let hintl =
- List.map_append (fun db ->
- let flags = auto_flags_of_state (Hint_db.transparent_state db) in
- List.map (fun x -> flags, x) (hint_of_db db)) (local_db::db_list)
- in
- let tac_of_hint =
- fun (st, {pri = b; pat = p; code = t; poly = poly}) ->
- let b = match Hints.repr_hint t with
- | Unfold_nth _ -> 1
- | _ -> b
- in
- (b,
- let tac = function
- | Res_pf (term,cl) -> unify_resolve poly st (term,cl)
- | ERes_pf (term,cl) -> unify_e_resolve poly st (term,cl)
- | Give_exact (c,cl) -> e_exact poly st (c,cl)
- | Res_pf_THEN_trivial_fail (term,cl) ->
- Tacticals.New.tclTHEN (unify_e_resolve poly st (term,cl))
- (e_trivial_fail_db db_list local_db)
- | Unfold_nth c -> reduce (Unfold [AllOccurrences,c]) onConcl
- | Extern tacast -> conclPattern concl p tacast
- in
- let tac = run_hint t tac in
- (tac, lazy (pr_hint t)))
- in
- List.map tac_of_hint hintl
-
-and e_trivial_resolve db_list local_db gl =
- let hd = try Some (decompose_app_bound gl) with Bound -> None in
- try priority (e_my_find_search db_list local_db hd gl)
- with Not_found -> []
-
-let e_possible_resolve db_list local_db gl =
- let hd = try Some (decompose_app_bound gl) with Bound -> None in
- try List.map (fun (b, (tac, pp)) -> (tac, b, pp)) (e_my_find_search db_list local_db hd gl)
- with Not_found -> []
-
-let find_first_goal gls =
- try first_goal gls with UserError _ -> assert false
-
-(*s The following module [SearchProblem] is used to instantiate the generic
- exploration functor [Explore.Make]. *)
-
-type search_state = {
- priority : int;
- depth : int; (*r depth of search before failing *)
- tacres : goal list sigma;
- last_tactic : std_ppcmds Lazy.t;
- dblist : hint_db list;
- localdb : hint_db list;
- prev : prev_search_state;
- local_lemmas : Tacexpr.delayed_open_constr list;
-}
-
-and prev_search_state = (* for info eauto *)
- | Unknown
- | Init
- | State of search_state
-
-module SearchProblem = struct
-
- type state = search_state
-
- let success s = List.is_empty (sig_it s.tacres)
-
-(* let pr_ev evs ev = Printer.pr_constr_env (Evd.evar_env ev) (Evarutil.nf_evar evs ev.Evd.evar_concl) *)
-
- let filter_tactics glls l =
-(* let _ = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
-(* let evars = Evarutil.nf_evars (Refiner.project glls) in *)
-(* msg (str"Goal:" ++ pr_ev evars (List.hd (sig_it glls)) ++ str"\n"); *)
- let rec aux = function
- | [] -> []
- | (tac, cost, pptac) :: tacl ->
- try
- let lgls = apply_tac_list (Proofview.V82.of_tactic tac) glls in
-(* let gl = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
-(* msg (hov 1 (pptac ++ str" gives: \n" ++ pr_goals lgls ++ str"\n")); *)
- (lgls, cost, pptac) :: aux tacl
- with e when Errors.noncritical e ->
- let e = Errors.push e in
- Refiner.catch_failerror e; aux tacl
- in aux l
-
- (* Ordering of states is lexicographic on depth (greatest first) then
- number of remaining goals. *)
- let compare s s' =
- let d = s'.depth - s.depth in
- let d' = Int.compare s.priority s'.priority in
- let nbgoals s = List.length (sig_it s.tacres) in
- if not (Int.equal d 0) then d
- else if not (Int.equal d' 0) then d'
- else Int.compare (nbgoals s) (nbgoals s')
-
- let branching s =
- if Int.equal s.depth 0 then
- []
- else
- let ps = if s.prev == Unknown then Unknown else State s in
- let lg = s.tacres in
- let nbgl = List.length (sig_it lg) in
- assert (nbgl > 0);
- let g = find_first_goal lg in
- let map_assum id = (e_give_exact (mkVar id), (-1), lazy (str "exact" ++ spc () ++ pr_id id)) in
- let assumption_tacs =
- let tacs = List.map map_assum (pf_ids_of_hyps g) in
- let l = filter_tactics s.tacres tacs in
- List.map (fun (res, cost, pp) -> { depth = s.depth; priority = cost; tacres = res;
- last_tactic = pp; dblist = s.dblist;
- localdb = List.tl s.localdb;
- prev = ps; local_lemmas = s.local_lemmas}) l
- in
- let intro_tac =
- let l = filter_tactics s.tacres [Tactics.intro, (-1), lazy (str "intro")] in
- List.map
- (fun (lgls, cost, pp) ->
- let g' = first_goal lgls in
- let hintl =
- make_resolve_hyp (pf_env g') (project g') (pf_last_hyp g')
- in
- let ldb = Hint_db.add_list (pf_env g') (project g')
- hintl (List.hd s.localdb) in
- { depth = s.depth; priority = cost; tacres = lgls;
- last_tactic = pp; dblist = s.dblist;
- localdb = ldb :: List.tl s.localdb; prev = ps;
- local_lemmas = s.local_lemmas})
- l
- in
- let rec_tacs =
- let l =
- filter_tactics s.tacres (e_possible_resolve s.dblist (List.hd s.localdb) (pf_concl g))
- in
- List.map
- (fun (lgls, cost, pp) ->
- let nbgl' = List.length (sig_it lgls) in
- if nbgl' < nbgl then
- { depth = s.depth; priority = cost; tacres = lgls; last_tactic = pp;
- prev = ps; dblist = s.dblist; localdb = List.tl s.localdb;
- local_lemmas = s.local_lemmas }
- else
- let newlocal =
- let hyps = pf_hyps g in
- List.map (fun gl ->
- let gls = {Evd.it = gl; sigma = lgls.Evd.sigma } in
- let hyps' = pf_hyps gls in
- if hyps' == hyps then List.hd s.localdb
- else make_local_hint_db (pf_env gls) (project gls) ~ts:full_transparent_state true s.local_lemmas)
- (List.firstn ((nbgl'-nbgl) + 1) (sig_it lgls))
- in
- { depth = pred s.depth; priority = cost; tacres = lgls;
- dblist = s.dblist; last_tactic = pp; prev = ps;
- localdb = newlocal @ List.tl s.localdb;
- local_lemmas = s.local_lemmas })
- l
- in
- List.sort compare (assumption_tacs @ intro_tac @ rec_tacs)
-
- let pp s = hov 0 (str " depth=" ++ int s.depth ++ spc () ++
- (Lazy.force s.last_tactic))
-
-end
-
-module Search = Explore.Make(SearchProblem)
-
-(** Utilities for debug eauto / info eauto *)
-
-let global_debug_eauto = ref false
-let global_info_eauto = ref false
-
-let _ =
- Goptions.declare_bool_option
- { Goptions.optsync = true;
- Goptions.optdepr = false;
- Goptions.optname = "Debug Eauto";
- Goptions.optkey = ["Debug";"Eauto"];
- Goptions.optread = (fun () -> !global_debug_eauto);
- Goptions.optwrite = (:=) global_debug_eauto }
-
-let _ =
- Goptions.declare_bool_option
- { Goptions.optsync = true;
- Goptions.optdepr = false;
- Goptions.optname = "Info Eauto";
- Goptions.optkey = ["Info";"Eauto"];
- Goptions.optread = (fun () -> !global_info_eauto);
- Goptions.optwrite = (:=) global_info_eauto }
-
-let mk_eauto_dbg d =
- if d == Debug || !global_debug_eauto then Debug
- else if d == Info || !global_info_eauto then Info
- else Off
-
-let pr_info_nop = function
- | Info -> msg_debug (str "idtac.")
- | _ -> ()
-
-let pr_dbg_header = function
- | Off -> ()
- | Debug -> msg_debug (str "(* debug eauto : *)")
- | Info -> msg_debug (str "(* info eauto : *)")
-
-let pr_info dbg s =
- if dbg != Info then ()
- else
- let rec loop s =
- match s.prev with
- | Unknown | Init -> s.depth
- | State sp ->
- let mindepth = loop sp in
- let indent = String.make (mindepth - sp.depth) ' ' in
- msg_debug (str indent ++ Lazy.force s.last_tactic ++ str ".");
- mindepth
- in
- ignore (loop s)
-
-(** Eauto main code *)
-
-let make_initial_state dbg n gl dblist localdb lems =
- { depth = n;
- priority = 0;
- tacres = tclIDTAC gl;
- last_tactic = lazy (mt());
- dblist = dblist;
- localdb = [localdb];
- prev = if dbg == Info then Init else Unknown;
- local_lemmas = lems;
- }
-
-let e_search_auto debug (in_depth,p) lems db_list gl =
- let local_db = make_local_hint_db (pf_env gl) (project gl) ~ts:full_transparent_state true lems in
- let d = mk_eauto_dbg debug in
- let tac = match in_depth,d with
- | (true,Debug) -> Search.debug_depth_first
- | (true,_) -> Search.depth_first
- | (false,Debug) -> Search.debug_breadth_first
- | (false,_) -> Search.breadth_first
- in
- try
- pr_dbg_header d;
- let s = tac (make_initial_state d p gl db_list local_db lems) in
- pr_info d s;
- s.tacres
- with Not_found ->
- pr_info_nop d;
- error "eauto: search failed"
-
-(* let e_search_auto_key = Profile.declare_profile "e_search_auto" *)
-(* let e_search_auto = Profile.profile5 e_search_auto_key e_search_auto *)
-
-let eauto_with_bases ?(debug=Off) np lems db_list =
- tclTRY (e_search_auto debug np lems db_list)
-
-let eauto ?(debug=Off) np lems dbnames =
- let db_list = make_db_list dbnames in
- tclTRY (e_search_auto debug np lems db_list)
-
-let full_eauto ?(debug=Off) n lems gl =
- let dbnames = current_db_names () in
- let dbnames = String.Set.remove "v62" dbnames in
- let db_list = List.map searchtable_map (String.Set.elements dbnames) in
- tclTRY (e_search_auto debug n lems db_list) gl
-
-let gen_eauto ?(debug=Off) np lems = function
- | None -> full_eauto ~debug np lems
- | Some l -> eauto ~debug np lems l
-
-let make_depth = function
- | None -> !default_search_depth
- | Some d -> d
-
-let make_dimension n = function
- | None -> (true,make_depth n)
- | Some d -> (false,d)
-
-open Genarg
-open G_auto
-
-let hintbases = G_auto.hintbases
-let wit_hintbases = G_auto.wit_hintbases
-
-TACTIC EXTEND eauto
-| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND new_eauto
-| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
- hintbases(db) ] ->
- [ match db with
- | None -> new_full_auto (make_depth n) (eval_uconstrs ist lems)
- | Some l -> new_auto (make_depth n) (eval_uconstrs ist lems) l ]
-END
-
-TACTIC EXTEND debug_eauto
-| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Debug (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND info_eauto
-| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Info (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND dfs_eauto
-| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (true, make_depth p) (eval_uconstrs ist lems) db) ]
-END
-
-let cons a l = a :: l
-
-let autounfolds db occs cls gl =
- let unfolds = List.concat (List.map (fun dbname ->
- let db = try searchtable_map dbname
- with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname)
- in
- let (ids, csts) = Hint_db.unfolds db in
- let hyps = pf_ids_of_hyps gl in
- let ids = Idset.filter (fun id -> List.mem id hyps) ids in
- Cset.fold (fun cst -> cons (AllOccurrences, EvalConstRef cst)) csts
- (Id.Set.fold (fun id -> cons (AllOccurrences, EvalVarRef id)) ids [])) db)
- in Proofview.V82.of_tactic (unfold_option unfolds cls) gl
-
-let autounfold db cls gl =
- let cls = concrete_clause_of (fun () -> pf_ids_of_hyps gl) cls in
- let tac = autounfolds db in
- tclMAP (function
- | OnHyp (id,occs,where) -> tac occs (Some (id,where))
- | OnConcl occs -> tac occs None)
- cls gl
-
-let autounfold_tac db cls gl =
- let dbs = match db with
- | None -> String.Set.elements (current_db_names ())
- | Some [] -> ["core"]
- | Some l -> l
- in
- autounfold dbs cls gl
-
-TACTIC EXTEND autounfold
-| [ "autounfold" hintbases(db) clause(cl) ] -> [ Proofview.V82.tactic (autounfold_tac db cl) ]
-END
-
-let unfold_head env (ids, csts) c =
- let rec aux c =
- match kind_of_term c with
- | Var id when Id.Set.mem id ids ->
- (match Environ.named_body id env with
- | Some b -> true, b
- | None -> false, c)
- | Const (cst,u as c) when Cset.mem cst csts ->
- true, Environ.constant_value_in env c
- | App (f, args) ->
- (match aux f with
- | true, f' -> true, Reductionops.whd_betaiota Evd.empty (mkApp (f', args))
- | false, _ ->
- let done_, args' =
- Array.fold_left_i (fun i (done_, acc) arg ->
- if done_ then done_, arg :: acc
- else match aux arg with
- | true, arg' -> true, arg' :: acc
- | false, arg' -> false, arg :: acc)
- (false, []) args
- in
- if done_ then true, mkApp (f, Array.of_list (List.rev args'))
- else false, c)
- | _ ->
- let done_ = ref false in
- let c' = map_constr (fun c ->
- if !done_ then c else
- let x, c' = aux c in
- done_ := x; c') c
- in !done_, c'
- in aux c
-
-let autounfold_one db cl =
- Proofview.Goal.nf_enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let concl = Proofview.Goal.concl gl in
- let st =
- List.fold_left (fun (i,c) dbname ->
- let db = try searchtable_map dbname
- with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname)
- in
- let (ids, csts) = Hint_db.unfolds db in
- (Id.Set.union ids i, Cset.union csts c)) (Id.Set.empty, Cset.empty) db
- in
- let did, c' = unfold_head env st
- (match cl with Some (id, _) -> Tacmach.New.pf_get_hyp_typ id gl | None -> concl)
- in
- if did then
- match cl with
- | Some hyp -> change_in_hyp None (make_change_arg c') hyp
- | None -> convert_concl_no_check c' DEFAULTcast
- else Tacticals.New.tclFAIL 0 (str "Nothing to unfold")
- end }
-
-(* Cset.fold (fun cst -> cons (all_occurrences, EvalConstRef cst)) csts *)
-(* (Id.Set.fold (fun id -> cons (all_occurrences, EvalVarRef id)) ids [])) db) *)
-(* in unfold_option unfolds cl *)
-
-(* let db = try searchtable_map dbname *)
-(* with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname) *)
-(* in *)
-(* let (ids, csts) = Hint_db.unfolds db in *)
-(* Cset.fold (fun cst -> tclORELSE (unfold_option [(occ, EvalVarRef id)] cst)) csts *)
-(* (Id.Set.fold (fun id -> tclORELSE (unfold_option [(occ, EvalVarRef id)] cl) ids acc))) *)
-(* (tclFAIL 0 (mt())) db *)
-
-TACTIC EXTEND autounfold_one
-| [ "autounfold_one" hintbases(db) "in" hyp(id) ] ->
- [ autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) (Some (id, InHyp)) ]
-| [ "autounfold_one" hintbases(db) ] ->
- [ autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) None ]
- END
-
-TACTIC EXTEND autounfoldify
-| [ "autounfoldify" constr(x) ] -> [
- Proofview.V82.tactic (
- let db = match kind_of_term x with
- | Const (c,_) -> Label.to_string (con_label c)
- | _ -> assert false
- in autounfold ["core";db] onConcl
- )]
-END
-
-TACTIC EXTEND unify
-| ["unify" constr(x) constr(y) ] -> [ unify x y ]
-| ["unify" constr(x) constr(y) "with" preident(base) ] -> [
- let table = try Some (searchtable_map base) with Not_found -> None in
- match table with
- | None ->
- let msg = str "Hint table " ++ str base ++ str " not found" in
- Tacticals.New.tclZEROMSG msg
- | Some t ->
- let state = Hint_db.transparent_state t in
- unify ~state x y
- ]
-END
-
-
-TACTIC EXTEND convert_concl_no_check
-| ["convert_concl_no_check" constr(x) ] -> [ convert_concl_no_check x DEFAULTcast ]
-END
-
-let pr_hints_path_atom _ _ _ = Hints.pp_hints_path_atom
-
-ARGUMENT EXTEND hints_path_atom
- TYPED AS hints_path_atom
- PRINTED BY pr_hints_path_atom
-| [ global_list(g) ] -> [ PathHints (List.map Nametab.global g) ]
-| [ "*" ] -> [ PathAny ]
-END
-
-let pr_hints_path prc prx pry c = Hints.pp_hints_path c
-
-ARGUMENT EXTEND hints_path
- TYPED AS hints_path
- PRINTED BY pr_hints_path
-| [ "(" hints_path(p) ")" ] -> [ p ]
-| [ "!" hints_path(p) ] -> [ PathStar p ]
-| [ "emp" ] -> [ PathEmpty ]
-| [ "eps" ] -> [ PathEpsilon ]
-| [ hints_path_atom(a) ] -> [ PathAtom a ]
-| [ hints_path(p) "|" hints_path(q) ] -> [ PathOr (p, q) ]
-| [ hints_path(p) ";" hints_path(q) ] -> [ PathSeq (p, q) ]
-END
-
-let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
-
-ARGUMENT EXTEND opthints
- TYPED AS preident_list_opt
- PRINTED BY pr_hintbases
-| [ ":" ne_preident_list(l) ] -> [ Some l ]
-| [ ] -> [ None ]
-END
-
-VERNAC COMMAND EXTEND HintCut CLASSIFIED AS SIDEFF
-| [ "Hint" "Cut" "[" hints_path(p) "]" opthints(dbnames) ] -> [
- let entry = HintsCutEntry p in
- Hints.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ()))
- (match dbnames with None -> ["core"] | Some l -> l) entry ]
-END
diff --git a/tactics/eauto.mli b/tactics/eauto.mli
index 0a490c65d8..8812093d5f 100644
--- a/tactics/eauto.mli
+++ b/tactics/eauto.mli
@@ -10,22 +10,24 @@ open Term
open Proof_type
open Hints
-val hintbases : hint_db_name list option Pcoq.Gram.entry
-
-val wit_hintbases : hint_db_name list option Genarg.uniform_genarg_type
-
val e_assumption : unit Proofview.tactic
val registered_e_assumption : unit Proofview.tactic
val e_give_exact : ?flags:Unification.unify_flags -> constr -> unit Proofview.tactic
+val prolog_tac : Tacexpr.delayed_open_constr list -> int -> unit Proofview.tactic
+
val gen_eauto : ?debug:Tacexpr.debug -> bool * int -> Tacexpr.delayed_open_constr list ->
- hint_db_name list option -> tactic
+ hint_db_name list option -> unit Proofview.tactic
val eauto_with_bases :
?debug:Tacexpr.debug ->
bool * int ->
Tacexpr.delayed_open_constr list -> hint_db list -> Proof_type.tactic
-val autounfold : hint_db_name list -> Locus.clause -> tactic
+val autounfold : hint_db_name list -> Locus.clause -> unit Proofview.tactic
+val autounfold_tac : hint_db_name list option -> Locus.clause -> unit Proofview.tactic
+val autounfold_one : hint_db_name list -> Locus.hyp_location option -> unit Proofview.tactic
+
+val make_dimension : int option -> int option -> bool * int
diff --git a/tactics/g_auto.ml4 b/tactics/g_auto.ml4
index 3a2cee9f72..f4fae763fd 100644
--- a/tactics/g_auto.ml4
+++ b/tactics/g_auto.ml4
@@ -16,6 +16,15 @@ DECLARE PLUGIN "g_auto"
(* Hint bases *)
+
+TACTIC EXTEND eassumption
+| [ "eassumption" ] -> [ Eauto.e_assumption ]
+END
+
+TACTIC EXTEND eexact
+| [ "eexact" constr(c) ] -> [ Eauto.e_give_exact c ]
+END
+
let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
ARGUMENT EXTEND hintbases
@@ -45,6 +54,8 @@ ARGUMENT EXTEND auto_using
| [ ] -> [ [] ]
END
+(** Auto *)
+
TACTIC EXTEND trivial
| [ "trivial" auto_using(lems) hintbases(db) ] ->
[ Auto.h_trivial (eval_uconstrs ist lems) db ]
@@ -74,3 +85,122 @@ TACTIC EXTEND debug_auto
| [ "debug" "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
[ Auto.h_auto ~debug:Debug n (eval_uconstrs ist lems) db ]
END
+
+(** Eauto *)
+
+TACTIC EXTEND prolog
+| [ "prolog" "[" uconstr_list(l) "]" int_or_var(n) ] ->
+ [ Eauto.prolog_tac (eval_uconstrs ist l) n ]
+END
+
+let make_depth n = snd (Eauto.make_dimension n None)
+
+TACTIC EXTEND eauto
+| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND new_eauto
+| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
+ hintbases(db) ] ->
+ [ match db with
+ | None -> Auto.new_full_auto (make_depth n) (eval_uconstrs ist lems)
+ | Some l -> Auto.new_auto (make_depth n) (eval_uconstrs ist lems) l ]
+END
+
+TACTIC EXTEND debug_eauto
+| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto ~debug:Debug (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_eauto
+| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto ~debug:Info (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND dfs_eauto
+| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto (Eauto.make_dimension p None) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND autounfold
+| [ "autounfold" hintbases(db) clause(cl) ] -> [ Eauto.autounfold_tac db cl ]
+END
+
+TACTIC EXTEND autounfold_one
+| [ "autounfold_one" hintbases(db) "in" hyp(id) ] ->
+ [ Eauto.autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) (Some (id, Locus.InHyp)) ]
+| [ "autounfold_one" hintbases(db) ] ->
+ [ Eauto.autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) None ]
+ END
+
+TACTIC EXTEND autounfoldify
+| [ "autounfoldify" constr(x) ] -> [
+ let db = match Term.kind_of_term x with
+ | Term.Const (c,_) -> Names.Label.to_string (Names.con_label c)
+ | _ -> assert false
+ in Eauto.autounfold ["core";db] Locusops.onConcl
+ ]
+END
+
+TACTIC EXTEND unify
+| ["unify" constr(x) constr(y) ] -> [ Tactics.unify x y ]
+| ["unify" constr(x) constr(y) "with" preident(base) ] -> [
+ let table = try Some (Hints.searchtable_map base) with Not_found -> None in
+ match table with
+ | None ->
+ let msg = str "Hint table " ++ str base ++ str " not found" in
+ Tacticals.New.tclZEROMSG msg
+ | Some t ->
+ let state = Hints.Hint_db.transparent_state t in
+ Tactics.unify ~state x y
+ ]
+END
+
+
+TACTIC EXTEND convert_concl_no_check
+| ["convert_concl_no_check" constr(x) ] -> [ Tactics.convert_concl_no_check x Term.DEFAULTcast ]
+END
+
+let pr_hints_path_atom _ _ _ = Hints.pp_hints_path_atom
+
+ARGUMENT EXTEND hints_path_atom
+ TYPED AS hints_path_atom
+ PRINTED BY pr_hints_path_atom
+| [ global_list(g) ] -> [ Hints.PathHints (List.map Nametab.global g) ]
+| [ "*" ] -> [ Hints.PathAny ]
+END
+
+let pr_hints_path prc prx pry c = Hints.pp_hints_path c
+
+ARGUMENT EXTEND hints_path
+ TYPED AS hints_path
+ PRINTED BY pr_hints_path
+| [ "(" hints_path(p) ")" ] -> [ p ]
+| [ "!" hints_path(p) ] -> [ Hints.PathStar p ]
+| [ "emp" ] -> [ Hints.PathEmpty ]
+| [ "eps" ] -> [ Hints.PathEpsilon ]
+| [ hints_path_atom(a) ] -> [ Hints.PathAtom a ]
+| [ hints_path(p) "|" hints_path(q) ] -> [ Hints.PathOr (p, q) ]
+| [ hints_path(p) ";" hints_path(q) ] -> [ Hints.PathSeq (p, q) ]
+END
+
+let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
+
+ARGUMENT EXTEND opthints
+ TYPED AS preident_list_opt
+ PRINTED BY pr_hintbases
+| [ ":" ne_preident_list(l) ] -> [ Some l ]
+| [ ] -> [ None ]
+END
+
+VERNAC COMMAND EXTEND HintCut CLASSIFIED AS SIDEFF
+| [ "Hint" "Cut" "[" hints_path(p) "]" opthints(dbnames) ] -> [
+ let entry = Hints.HintsCutEntry p in
+ Hints.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ()))
+ (match dbnames with None -> ["core"] | Some l -> l) entry ]
+END
diff --git a/tactics/hightactics.mllib b/tactics/hightactics.mllib
index 30e97f62d5..0d73cc27aa 100644
--- a/tactics/hightactics.mllib
+++ b/tactics/hightactics.mllib
@@ -1,8 +1,8 @@
Extraargs
Coretactics
Extratactics
-G_auto
Eauto
+G_auto
Class_tactics
G_class
Rewrite
diff --git a/theories/Init/Notations.v b/theories/Init/Notations.v
index 55eb699be6..65ea8028d1 100644
--- a/theories/Init/Notations.v
+++ b/theories/Init/Notations.v
@@ -86,7 +86,6 @@ Open Scope type_scope.
Declare ML Module "coretactics".
Declare ML Module "extratactics".
Declare ML Module "g_auto".
-Declare ML Module "eauto".
Declare ML Module "g_class".
Declare ML Module "g_eqdecide".
Declare ML Module "g_rewrite".
--
cgit v1.2.3
From 8f6d74c1e771966e3dd44704805a1e848af4802a Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 03:42:51 +0100
Subject: Splitting the nsatz ML module into an implementation and a grammar
files.
---
plugins/nsatz/g_nsatz.ml4 | 17 ++
plugins/nsatz/nsatz.ml | 590 ++++++++++++++++++++++++++++++++++++++
plugins/nsatz/nsatz.ml4 | 598 ---------------------------------------
plugins/nsatz/nsatz_plugin.mllib | 1 +
4 files changed, 608 insertions(+), 598 deletions(-)
create mode 100644 plugins/nsatz/g_nsatz.ml4
create mode 100644 plugins/nsatz/nsatz.ml
delete mode 100644 plugins/nsatz/nsatz.ml4
diff --git a/plugins/nsatz/g_nsatz.ml4 b/plugins/nsatz/g_nsatz.ml4
new file mode 100644
index 0000000000..0da6305304
--- /dev/null
+++ b/plugins/nsatz/g_nsatz.ml4
@@ -0,0 +1,17 @@
+DECLARE PLUGIN "nsatz_plugin"
+
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* [ Proofview.V82.tactic (Nsatz.nsatz_compute lt) ]
+END
diff --git a/plugins/nsatz/nsatz.ml b/plugins/nsatz/nsatz.ml
new file mode 100644
index 0000000000..ee1904a660
--- /dev/null
+++ b/plugins/nsatz/nsatz.ml
@@ -0,0 +1,590 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* 1
+ let puis = power_big_int_positive_int
+
+ (* a et b positifs, résultat positif *)
+ let rec pgcd a b =
+ if equal b coef0
+ then a
+ else if lt a b then pgcd b a else pgcd b (modulo a b)
+
+
+ (* signe du pgcd = signe(a)*signe(b) si non nuls. *)
+ let pgcd2 a b =
+ if equal a coef0 then b
+ else if equal b coef0 then a
+ else let c = pgcd (abs a) (abs b) in
+ if ((lt coef0 a)&&(lt b coef0))
+ ||((lt coef0 b)&&(lt a coef0))
+ then opp c else c
+end
+
+(*
+module Ent = struct
+ type t = Entiers.entiers
+ let of_int = Entiers.ent_of_int
+ let of_num x = Entiers.ent_of_string(Num.string_of_num x)
+ let to_num x = Num.num_of_string (Entiers.string_of_ent x)
+ let equal = Entiers.eq_ent
+ let lt = Entiers.lt_ent
+ let le = Entiers.le_ent
+ let abs = Entiers.abs_ent
+ let plus =Entiers.add_ent
+ let mult = Entiers.mult_ent
+ let sub = Entiers.moins_ent
+ let opp = Entiers.opp_ent
+ let div = Entiers.div_ent
+ let modulo = Entiers.mod_ent
+ let coef0 = Entiers.ent0
+ let coef1 = Entiers.ent1
+ let to_string = Entiers.string_of_ent
+ let to_int x = Entiers.int_of_ent x
+ let hash x =Entiers.hash_ent x
+ let signe = Entiers.signe_ent
+
+ let rec puis p n = match n with
+ 0 -> coef1
+ |_ -> (mult p (puis p (n-1)))
+
+ (* a et b positifs, résultat positif *)
+ let rec pgcd a b =
+ if equal b coef0
+ then a
+ else if lt a b then pgcd b a else pgcd b (modulo a b)
+
+
+ (* signe du pgcd = signe(a)*signe(b) si non nuls. *)
+ let pgcd2 a b =
+ if equal a coef0 then b
+ else if equal b coef0 then a
+ else let c = pgcd (abs a) (abs b) in
+ if ((lt coef0 a)&&(lt b coef0))
+ ||((lt coef0 b)&&(lt a coef0))
+ then opp c else c
+end
+*)
+
+(* ------------------------------------------------------------------------- *)
+(* ------------------------------------------------------------------------- *)
+
+type vname = string
+
+type term =
+ | Zero
+ | Const of Num.num
+ | Var of vname
+ | Opp of term
+ | Add of term * term
+ | Sub of term * term
+ | Mul of term * term
+ | Pow of term * int
+
+let const n =
+ if eq_num n num_0 then Zero else Const n
+let pow(p,i) = if Int.equal i 1 then p else Pow(p,i)
+let add = function
+ (Zero,q) -> q
+ | (p,Zero) -> p
+ | (p,q) -> Add(p,q)
+let mul = function
+ (Zero,_) -> Zero
+ | (_,Zero) -> Zero
+ | (p,Const n) when eq_num n num_1 -> p
+ | (Const n,q) when eq_num n num_1 -> q
+ | (p,q) -> Mul(p,q)
+
+let unconstr = mkRel 1
+
+let tpexpr =
+ lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PExpr")
+let ttconst = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEc")
+let ttvar = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEX")
+let ttadd = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEadd")
+let ttsub = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEsub")
+let ttmul = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEmul")
+let ttopp = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEopp")
+let ttpow = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEpow")
+
+let datatypes = ["Init";"Datatypes"]
+let binnums = ["Numbers";"BinNums"]
+
+let tlist = lazy (gen_constant "CC" datatypes "list")
+let lnil = lazy (gen_constant "CC" datatypes "nil")
+let lcons = lazy (gen_constant "CC" datatypes "cons")
+
+let tz = lazy (gen_constant "CC" binnums "Z")
+let z0 = lazy (gen_constant "CC" binnums "Z0")
+let zpos = lazy (gen_constant "CC" binnums "Zpos")
+let zneg = lazy(gen_constant "CC" binnums "Zneg")
+
+let pxI = lazy(gen_constant "CC" binnums "xI")
+let pxO = lazy(gen_constant "CC" binnums "xO")
+let pxH = lazy(gen_constant "CC" binnums "xH")
+
+let nN0 = lazy (gen_constant "CC" binnums "N0")
+let nNpos = lazy(gen_constant "CC" binnums "Npos")
+
+let mkt_app name l = mkApp (Lazy.force name, Array.of_list l)
+
+let tlp () = mkt_app tlist [mkt_app tpexpr [Lazy.force tz]]
+let tllp () = mkt_app tlist [tlp()]
+
+let rec mkt_pos n =
+ if n =/ num_1 then Lazy.force pxH
+ else if mod_num n num_2 =/ num_0 then
+ mkt_app pxO [mkt_pos (quo_num n num_2)]
+ else
+ mkt_app pxI [mkt_pos (quo_num n num_2)]
+
+let mkt_n n =
+ if Num.eq_num n num_0
+ then Lazy.force nN0
+ else mkt_app nNpos [mkt_pos n]
+
+let mkt_z z =
+ if z =/ num_0 then Lazy.force z0
+ else if z >/ num_0 then
+ mkt_app zpos [mkt_pos z]
+ else
+ mkt_app zneg [mkt_pos ((Int 0) -/ z)]
+
+let rec mkt_term t = match t with
+| Zero -> mkt_term (Const num_0)
+| Const r -> let (n,d) = numdom r in
+ mkt_app ttconst [Lazy.force tz; mkt_z n]
+| Var v -> mkt_app ttvar [Lazy.force tz; mkt_pos (num_of_string v)]
+| Opp t1 -> mkt_app ttopp [Lazy.force tz; mkt_term t1]
+| Add (t1,t2) -> mkt_app ttadd [Lazy.force tz; mkt_term t1; mkt_term t2]
+| Sub (t1,t2) -> mkt_app ttsub [Lazy.force tz; mkt_term t1; mkt_term t2]
+| Mul (t1,t2) -> mkt_app ttmul [Lazy.force tz; mkt_term t1; mkt_term t2]
+| Pow (t1,n) -> if Int.equal n 0 then
+ mkt_app ttconst [Lazy.force tz; mkt_z num_1]
+else
+ mkt_app ttpow [Lazy.force tz; mkt_term t1; mkt_n (num_of_int n)]
+
+let rec parse_pos p =
+ match kind_of_term p with
+| App (a,[|p2|]) ->
+ if eq_constr a (Lazy.force pxO) then num_2 */ (parse_pos p2)
+ else num_1 +/ (num_2 */ (parse_pos p2))
+| _ -> num_1
+
+let parse_z z =
+ match kind_of_term z with
+| App (a,[|p2|]) ->
+ if eq_constr a (Lazy.force zpos) then parse_pos p2 else (num_0 -/ (parse_pos p2))
+| _ -> num_0
+
+let parse_n z =
+ match kind_of_term z with
+| App (a,[|p2|]) ->
+ parse_pos p2
+| _ -> num_0
+
+let rec parse_term p =
+ match kind_of_term p with
+| App (a,[|_;p2|]) ->
+ if eq_constr a (Lazy.force ttvar) then Var (string_of_num (parse_pos p2))
+ else if eq_constr a (Lazy.force ttconst) then Const (parse_z p2)
+ else if eq_constr a (Lazy.force ttopp) then Opp (parse_term p2)
+ else Zero
+| App (a,[|_;p2;p3|]) ->
+ if eq_constr a (Lazy.force ttadd) then Add (parse_term p2, parse_term p3)
+ else if eq_constr a (Lazy.force ttsub) then Sub (parse_term p2, parse_term p3)
+ else if eq_constr a (Lazy.force ttmul) then Mul (parse_term p2, parse_term p3)
+ else if eq_constr a (Lazy.force ttpow) then
+ Pow (parse_term p2, int_of_num (parse_n p3))
+ else Zero
+| _ -> Zero
+
+let rec parse_request lp =
+ match kind_of_term lp with
+ | App (_,[|_|]) -> []
+ | App (_,[|_;p;lp1|]) ->
+ (parse_term p)::(parse_request lp1)
+ |_-> assert false
+
+let nvars = ref 0
+
+let set_nvars_term t =
+ let rec aux t =
+ match t with
+ | Zero -> ()
+ | Const r -> ()
+ | Var v -> let n = int_of_string v in
+ nvars:= max (!nvars) n
+ | Opp t1 -> aux t1
+ | Add (t1,t2) -> aux t1; aux t2
+ | Sub (t1,t2) -> aux t1; aux t2
+ | Mul (t1,t2) -> aux t1; aux t2
+ | Pow (t1,n) -> aux t1
+ in aux t
+
+let string_of_term p =
+ let rec aux p =
+ match p with
+ | Zero -> "0"
+ | Const r -> string_of_num r
+ | Var v -> "x"^v
+ | Opp t1 -> "(-"^(aux t1)^")"
+ | Add (t1,t2) -> "("^(aux t1)^"+"^(aux t2)^")"
+ | Sub (t1,t2) -> "("^(aux t1)^"-"^(aux t2)^")"
+ | Mul (t1,t2) -> "("^(aux t1)^"*"^(aux t2)^")"
+ | Pow (t1,n) -> (aux t1)^"^"^(string_of_int n)
+ in aux p
+
+
+(***********************************************************************
+ Coefficients: recursive polynomials
+ *)
+
+module Coef = BigInt
+(*module Coef = Ent*)
+module Poly = Polynom.Make(Coef)
+module PIdeal = Ideal.Make(Poly)
+open PIdeal
+
+(* term to sparse polynomial
+ varaibles <=np are in the coefficients
+*)
+
+let term_pol_sparse np t=
+ let d = !nvars in
+ let rec aux t =
+(* info ("conversion de: "^(string_of_term t)^"\n");*)
+ let res =
+ match t with
+ | Zero -> zeroP
+ | Const r ->
+ if Num.eq_num r num_0
+ then zeroP
+ else polconst d (Poly.Pint (Coef.of_num r))
+ | Var v ->
+ let v = int_of_string v in
+ if v <= np
+ then polconst d (Poly.x v)
+ else gen d v
+ | Opp t1 -> oppP (aux t1)
+ | Add (t1,t2) -> plusP (aux t1) (aux t2)
+ | Sub (t1,t2) -> plusP (aux t1) (oppP (aux t2))
+ | Mul (t1,t2) -> multP (aux t1) (aux t2)
+ | Pow (t1,n) -> puisP (aux t1) n
+ in
+(* info ("donne: "^(stringP res)^"\n");*)
+ res
+ in
+ let res= aux t in
+ res
+
+(* sparse polynomial to term *)
+
+let polrec_to_term p =
+ let rec aux p =
+ match p with
+ |Poly.Pint n -> const (Coef.to_num n)
+ |Poly.Prec (v,coefs) ->
+ let res = ref Zero in
+ Array.iteri
+ (fun i c ->
+ res:=add(!res, mul(aux c,
+ pow (Var (string_of_int v),
+ i))))
+ coefs;
+ !res
+ in aux p
+
+(* approximation of the Horner form used in the tactic ring *)
+
+let pol_sparse_to_term n2 p =
+ (* info "pol_sparse_to_term ->\n";*)
+ let p = PIdeal.repr p in
+ let rec aux p =
+ match p with
+ [] -> const (num_of_string "0")
+ | (a,m)::p1 ->
+ let n = (Array.length m)-1 in
+ let (i0,e0) =
+ List.fold_left (fun (r,d) (a,m) ->
+ let i0= ref 0 in
+ for k=1 to n do
+ if m.(k)>0
+ then i0:=k
+ done;
+ if Int.equal !i0 0
+ then (r,d)
+ else if !i0 > r
+ then (!i0, m.(!i0))
+ else if Int.equal !i0 r && m.(!i0)
+ if m.(i0)>=e0
+ then (m.(i0)<-m.(i0)-e0;
+ p1:=(a,m)::(!p1))
+ else p2:=(a,m)::(!p2))
+ p;
+ let vm =
+ if Int.equal e0 1
+ then Var (string_of_int (i0))
+ else pow (Var (string_of_int (i0)),e0) in
+ add(mul(vm, aux (List.rev (!p1))), aux (List.rev (!p2))))
+ in (*info "-> pol_sparse_to_term\n";*)
+ aux p
+
+
+let remove_list_tail l i =
+ let rec aux l i =
+ if List.is_empty l
+ then []
+ else if i<0
+ then l
+ else if Int.equal i 0
+ then List.tl l
+ else
+ match l with
+ |(a::l1) ->
+ a::(aux l1 (i-1))
+ |_ -> assert false
+ in
+ List.rev (aux (List.rev l) i)
+
+(*
+ lq = [cn+m+1 n+m ...cn+m+1 1]
+ lci=[[cn+1 n,...,cn1 1]
+ ...
+ [cn+m n+m-1,...,cn+m 1]]
+
+ removes intermediate polynomials not useful to compute the last one.
+ *)
+
+let remove_zeros zero lci =
+ let n = List.length (List.hd lci) in
+ let m=List.length lci in
+ let u = Array.make m false in
+ let rec utiles k =
+ if k>=m
+ then ()
+ else (
+ u.(k)<-true;
+ let lc = List.nth lci k in
+ for i=0 to List.length lc - 1 do
+ if not (zero (List.nth lc i))
+ then utiles (i+k+1);
+ done)
+ in utiles 0;
+ let lr = ref [] in
+ for i=0 to m-1 do
+ if u.(i)
+ then lr:=(List.nth lci i)::(!lr)
+ done;
+ let lr=List.rev !lr in
+ let lr = List.map
+ (fun lc ->
+ let lcr=ref lc in
+ for i=0 to m-1 do
+ if not u.(i)
+ then lcr:=remove_list_tail !lcr (m-i+(n-m))
+ done;
+ !lcr)
+ lr in
+ info ("useless spolynomials: "
+ ^string_of_int (m-List.length lr)^"\n");
+ info ("useful spolynomials: "
+ ^string_of_int (List.length lr)^"\n");
+ lr
+
+let theoremedeszeros lpol p =
+ let t1 = Unix.gettimeofday() in
+ let m = !nvars in
+ let (lp0,p,cert) = in_ideal m lpol p in
+ let lpc = List.rev !poldepcontent in
+ info ("time: "^Format.sprintf "@[%10.3f@]s\n" (Unix.gettimeofday ()-.t1));
+ (cert,lp0,p,lpc)
+
+open Ideal
+
+let theoremedeszeros_termes lp =
+ nvars:=0;(* mise a jour par term_pol_sparse *)
+ List.iter set_nvars_term lp;
+ match lp with
+ | Const (Int sugarparam)::Const (Int nparam)::lp ->
+ ((match sugarparam with
+ |0 -> info "computation without sugar\n";
+ lexico:=false;
+ sugar_flag := false;
+ divide_rem_with_critical_pair := false
+ |1 -> info "computation with sugar\n";
+ lexico:=false;
+ sugar_flag := true;
+ divide_rem_with_critical_pair := false
+ |2 -> info "ordre lexico computation without sugar\n";
+ lexico:=true;
+ sugar_flag := false;
+ divide_rem_with_critical_pair := false
+ |3 -> info "ordre lexico computation with sugar\n";
+ lexico:=true;
+ sugar_flag := true;
+ divide_rem_with_critical_pair := false
+ |4 -> info "computation without sugar, division by pairs\n";
+ lexico:=false;
+ sugar_flag := false;
+ divide_rem_with_critical_pair := true
+ |5 -> info "computation with sugar, division by pairs\n";
+ lexico:=false;
+ sugar_flag := true;
+ divide_rem_with_critical_pair := true
+ |6 -> info "ordre lexico computation without sugar, division by pairs\n";
+ lexico:=true;
+ sugar_flag := false;
+ divide_rem_with_critical_pair := true
+ |7 -> info "ordre lexico computation with sugar, division by pairs\n";
+ lexico:=true;
+ sugar_flag := true;
+ divide_rem_with_critical_pair := true
+ | _ -> error "nsatz: bad parameter"
+ );
+ let m= !nvars in
+ let lvar=ref [] in
+ for i=m downto 1 do lvar:=["x"^(string_of_int i)^""]@(!lvar); done;
+ lvar:=["a";"b";"c";"d";"e";"f";"g";"h";"i";"j";"k";"l";"m";"n";"o";"p";"q";"r";"s";"t";"u";"v";"w";"x";"y";"z"] @ (!lvar); (* pour macaulay *)
+ name_var:=!lvar;
+ let lp = List.map (term_pol_sparse nparam) lp in
+ match lp with
+ | [] -> assert false
+ | p::lp1 ->
+ let lpol = List.rev lp1 in
+ let (cert,lp0,p,_lct) = theoremedeszeros lpol p in
+ info "cert ok\n";
+ let lc = cert.last_comb::List.rev cert.gb_comb in
+ match remove_zeros (fun x -> equal x zeroP) lc with
+ | [] -> assert false
+ | (lq::lci) ->
+ (* lci commence par les nouveaux polynomes *)
+ let m= !nvars in
+ let c = pol_sparse_to_term m (polconst m cert.coef) in
+ let r = Pow(Zero,cert.power) in
+ let lci = List.rev lci in
+ let lci = List.map (List.map (pol_sparse_to_term m)) lci in
+ let lq = List.map (pol_sparse_to_term m) lq in
+ info ("number of parametres: "^string_of_int nparam^"\n");
+ info "term computed\n";
+ (c,r,lci,lq)
+ )
+ |_ -> assert false
+
+
+(* version avec hash-consing du certificat:
+let nsatz lpol =
+ Hashtbl.clear Dansideal.hmon;
+ Hashtbl.clear Dansideal.coefpoldep;
+ Hashtbl.clear Dansideal.sugartbl;
+ Hashtbl.clear Polynomesrec.hcontentP;
+ init_constants ();
+ let lp= parse_request lpol in
+ let (_lp0,_p,c,r,_lci,_lq as rthz) = theoremedeszeros_termes lp in
+ let certif = certificat_vers_polynome_creux rthz in
+ let certif = hash_certif certif in
+ let certif = certif_term certif in
+ let c = mkt_term c in
+ info "constr computed\n";
+ (c, certif)
+*)
+
+let nsatz lpol =
+ let lp= parse_request lpol in
+ let (c,r,lci,lq) = theoremedeszeros_termes lp in
+ let res = [c::r::lq]@lci in
+ let res = List.map (fun lx -> List.map mkt_term lx) res in
+ let res =
+ List.fold_right
+ (fun lt r ->
+ let ltterm =
+ List.fold_right
+ (fun t r ->
+ mkt_app lcons [mkt_app tpexpr [Lazy.force tz];t;r])
+ lt
+ (mkt_app lnil [mkt_app tpexpr [Lazy.force tz]]) in
+ mkt_app lcons [tlp ();ltterm;r])
+ res
+ (mkt_app lnil [tlp ()]) in
+ info "term computed\n";
+ res
+
+let return_term t =
+ let a =
+ mkApp(gen_constant "CC" ["Init";"Logic"] "refl_equal",[|tllp ();t|]) in
+ generalize [a]
+
+let nsatz_compute t =
+ let lpol =
+ try nsatz t
+ with Ideal.NotInIdeal ->
+ error "nsatz cannot solve this problem" in
+ return_term lpol
+
+
diff --git a/plugins/nsatz/nsatz.ml4 b/plugins/nsatz/nsatz.ml4
deleted file mode 100644
index ced53d82f4..0000000000
--- a/plugins/nsatz/nsatz.ml4
+++ /dev/null
@@ -1,598 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* 1
- let puis = power_big_int_positive_int
-
- (* a et b positifs, résultat positif *)
- let rec pgcd a b =
- if equal b coef0
- then a
- else if lt a b then pgcd b a else pgcd b (modulo a b)
-
-
- (* signe du pgcd = signe(a)*signe(b) si non nuls. *)
- let pgcd2 a b =
- if equal a coef0 then b
- else if equal b coef0 then a
- else let c = pgcd (abs a) (abs b) in
- if ((lt coef0 a)&&(lt b coef0))
- ||((lt coef0 b)&&(lt a coef0))
- then opp c else c
-end
-
-(*
-module Ent = struct
- type t = Entiers.entiers
- let of_int = Entiers.ent_of_int
- let of_num x = Entiers.ent_of_string(Num.string_of_num x)
- let to_num x = Num.num_of_string (Entiers.string_of_ent x)
- let equal = Entiers.eq_ent
- let lt = Entiers.lt_ent
- let le = Entiers.le_ent
- let abs = Entiers.abs_ent
- let plus =Entiers.add_ent
- let mult = Entiers.mult_ent
- let sub = Entiers.moins_ent
- let opp = Entiers.opp_ent
- let div = Entiers.div_ent
- let modulo = Entiers.mod_ent
- let coef0 = Entiers.ent0
- let coef1 = Entiers.ent1
- let to_string = Entiers.string_of_ent
- let to_int x = Entiers.int_of_ent x
- let hash x =Entiers.hash_ent x
- let signe = Entiers.signe_ent
-
- let rec puis p n = match n with
- 0 -> coef1
- |_ -> (mult p (puis p (n-1)))
-
- (* a et b positifs, résultat positif *)
- let rec pgcd a b =
- if equal b coef0
- then a
- else if lt a b then pgcd b a else pgcd b (modulo a b)
-
-
- (* signe du pgcd = signe(a)*signe(b) si non nuls. *)
- let pgcd2 a b =
- if equal a coef0 then b
- else if equal b coef0 then a
- else let c = pgcd (abs a) (abs b) in
- if ((lt coef0 a)&&(lt b coef0))
- ||((lt coef0 b)&&(lt a coef0))
- then opp c else c
-end
-*)
-
-(* ------------------------------------------------------------------------- *)
-(* ------------------------------------------------------------------------- *)
-
-type vname = string
-
-type term =
- | Zero
- | Const of Num.num
- | Var of vname
- | Opp of term
- | Add of term * term
- | Sub of term * term
- | Mul of term * term
- | Pow of term * int
-
-let const n =
- if eq_num n num_0 then Zero else Const n
-let pow(p,i) = if Int.equal i 1 then p else Pow(p,i)
-let add = function
- (Zero,q) -> q
- | (p,Zero) -> p
- | (p,q) -> Add(p,q)
-let mul = function
- (Zero,_) -> Zero
- | (_,Zero) -> Zero
- | (p,Const n) when eq_num n num_1 -> p
- | (Const n,q) when eq_num n num_1 -> q
- | (p,q) -> Mul(p,q)
-
-let unconstr = mkRel 1
-
-let tpexpr =
- lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PExpr")
-let ttconst = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEc")
-let ttvar = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEX")
-let ttadd = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEadd")
-let ttsub = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEsub")
-let ttmul = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEmul")
-let ttopp = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEopp")
-let ttpow = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PEpow")
-
-let datatypes = ["Init";"Datatypes"]
-let binnums = ["Numbers";"BinNums"]
-
-let tlist = lazy (gen_constant "CC" datatypes "list")
-let lnil = lazy (gen_constant "CC" datatypes "nil")
-let lcons = lazy (gen_constant "CC" datatypes "cons")
-
-let tz = lazy (gen_constant "CC" binnums "Z")
-let z0 = lazy (gen_constant "CC" binnums "Z0")
-let zpos = lazy (gen_constant "CC" binnums "Zpos")
-let zneg = lazy(gen_constant "CC" binnums "Zneg")
-
-let pxI = lazy(gen_constant "CC" binnums "xI")
-let pxO = lazy(gen_constant "CC" binnums "xO")
-let pxH = lazy(gen_constant "CC" binnums "xH")
-
-let nN0 = lazy (gen_constant "CC" binnums "N0")
-let nNpos = lazy(gen_constant "CC" binnums "Npos")
-
-let mkt_app name l = mkApp (Lazy.force name, Array.of_list l)
-
-let tlp () = mkt_app tlist [mkt_app tpexpr [Lazy.force tz]]
-let tllp () = mkt_app tlist [tlp()]
-
-let rec mkt_pos n =
- if n =/ num_1 then Lazy.force pxH
- else if mod_num n num_2 =/ num_0 then
- mkt_app pxO [mkt_pos (quo_num n num_2)]
- else
- mkt_app pxI [mkt_pos (quo_num n num_2)]
-
-let mkt_n n =
- if Num.eq_num n num_0
- then Lazy.force nN0
- else mkt_app nNpos [mkt_pos n]
-
-let mkt_z z =
- if z =/ num_0 then Lazy.force z0
- else if z >/ num_0 then
- mkt_app zpos [mkt_pos z]
- else
- mkt_app zneg [mkt_pos ((Int 0) -/ z)]
-
-let rec mkt_term t = match t with
-| Zero -> mkt_term (Const num_0)
-| Const r -> let (n,d) = numdom r in
- mkt_app ttconst [Lazy.force tz; mkt_z n]
-| Var v -> mkt_app ttvar [Lazy.force tz; mkt_pos (num_of_string v)]
-| Opp t1 -> mkt_app ttopp [Lazy.force tz; mkt_term t1]
-| Add (t1,t2) -> mkt_app ttadd [Lazy.force tz; mkt_term t1; mkt_term t2]
-| Sub (t1,t2) -> mkt_app ttsub [Lazy.force tz; mkt_term t1; mkt_term t2]
-| Mul (t1,t2) -> mkt_app ttmul [Lazy.force tz; mkt_term t1; mkt_term t2]
-| Pow (t1,n) -> if Int.equal n 0 then
- mkt_app ttconst [Lazy.force tz; mkt_z num_1]
-else
- mkt_app ttpow [Lazy.force tz; mkt_term t1; mkt_n (num_of_int n)]
-
-let rec parse_pos p =
- match kind_of_term p with
-| App (a,[|p2|]) ->
- if eq_constr a (Lazy.force pxO) then num_2 */ (parse_pos p2)
- else num_1 +/ (num_2 */ (parse_pos p2))
-| _ -> num_1
-
-let parse_z z =
- match kind_of_term z with
-| App (a,[|p2|]) ->
- if eq_constr a (Lazy.force zpos) then parse_pos p2 else (num_0 -/ (parse_pos p2))
-| _ -> num_0
-
-let parse_n z =
- match kind_of_term z with
-| App (a,[|p2|]) ->
- parse_pos p2
-| _ -> num_0
-
-let rec parse_term p =
- match kind_of_term p with
-| App (a,[|_;p2|]) ->
- if eq_constr a (Lazy.force ttvar) then Var (string_of_num (parse_pos p2))
- else if eq_constr a (Lazy.force ttconst) then Const (parse_z p2)
- else if eq_constr a (Lazy.force ttopp) then Opp (parse_term p2)
- else Zero
-| App (a,[|_;p2;p3|]) ->
- if eq_constr a (Lazy.force ttadd) then Add (parse_term p2, parse_term p3)
- else if eq_constr a (Lazy.force ttsub) then Sub (parse_term p2, parse_term p3)
- else if eq_constr a (Lazy.force ttmul) then Mul (parse_term p2, parse_term p3)
- else if eq_constr a (Lazy.force ttpow) then
- Pow (parse_term p2, int_of_num (parse_n p3))
- else Zero
-| _ -> Zero
-
-let rec parse_request lp =
- match kind_of_term lp with
- | App (_,[|_|]) -> []
- | App (_,[|_;p;lp1|]) ->
- (parse_term p)::(parse_request lp1)
- |_-> assert false
-
-let nvars = ref 0
-
-let set_nvars_term t =
- let rec aux t =
- match t with
- | Zero -> ()
- | Const r -> ()
- | Var v -> let n = int_of_string v in
- nvars:= max (!nvars) n
- | Opp t1 -> aux t1
- | Add (t1,t2) -> aux t1; aux t2
- | Sub (t1,t2) -> aux t1; aux t2
- | Mul (t1,t2) -> aux t1; aux t2
- | Pow (t1,n) -> aux t1
- in aux t
-
-let string_of_term p =
- let rec aux p =
- match p with
- | Zero -> "0"
- | Const r -> string_of_num r
- | Var v -> "x"^v
- | Opp t1 -> "(-"^(aux t1)^")"
- | Add (t1,t2) -> "("^(aux t1)^"+"^(aux t2)^")"
- | Sub (t1,t2) -> "("^(aux t1)^"-"^(aux t2)^")"
- | Mul (t1,t2) -> "("^(aux t1)^"*"^(aux t2)^")"
- | Pow (t1,n) -> (aux t1)^"^"^(string_of_int n)
- in aux p
-
-
-(***********************************************************************
- Coefficients: recursive polynomials
- *)
-
-module Coef = BigInt
-(*module Coef = Ent*)
-module Poly = Polynom.Make(Coef)
-module PIdeal = Ideal.Make(Poly)
-open PIdeal
-
-(* term to sparse polynomial
- varaibles <=np are in the coefficients
-*)
-
-let term_pol_sparse np t=
- let d = !nvars in
- let rec aux t =
-(* info ("conversion de: "^(string_of_term t)^"\n");*)
- let res =
- match t with
- | Zero -> zeroP
- | Const r ->
- if Num.eq_num r num_0
- then zeroP
- else polconst d (Poly.Pint (Coef.of_num r))
- | Var v ->
- let v = int_of_string v in
- if v <= np
- then polconst d (Poly.x v)
- else gen d v
- | Opp t1 -> oppP (aux t1)
- | Add (t1,t2) -> plusP (aux t1) (aux t2)
- | Sub (t1,t2) -> plusP (aux t1) (oppP (aux t2))
- | Mul (t1,t2) -> multP (aux t1) (aux t2)
- | Pow (t1,n) -> puisP (aux t1) n
- in
-(* info ("donne: "^(stringP res)^"\n");*)
- res
- in
- let res= aux t in
- res
-
-(* sparse polynomial to term *)
-
-let polrec_to_term p =
- let rec aux p =
- match p with
- |Poly.Pint n -> const (Coef.to_num n)
- |Poly.Prec (v,coefs) ->
- let res = ref Zero in
- Array.iteri
- (fun i c ->
- res:=add(!res, mul(aux c,
- pow (Var (string_of_int v),
- i))))
- coefs;
- !res
- in aux p
-
-(* approximation of the Horner form used in the tactic ring *)
-
-let pol_sparse_to_term n2 p =
- (* info "pol_sparse_to_term ->\n";*)
- let p = PIdeal.repr p in
- let rec aux p =
- match p with
- [] -> const (num_of_string "0")
- | (a,m)::p1 ->
- let n = (Array.length m)-1 in
- let (i0,e0) =
- List.fold_left (fun (r,d) (a,m) ->
- let i0= ref 0 in
- for k=1 to n do
- if m.(k)>0
- then i0:=k
- done;
- if Int.equal !i0 0
- then (r,d)
- else if !i0 > r
- then (!i0, m.(!i0))
- else if Int.equal !i0 r && m.(!i0)
- if m.(i0)>=e0
- then (m.(i0)<-m.(i0)-e0;
- p1:=(a,m)::(!p1))
- else p2:=(a,m)::(!p2))
- p;
- let vm =
- if Int.equal e0 1
- then Var (string_of_int (i0))
- else pow (Var (string_of_int (i0)),e0) in
- add(mul(vm, aux (List.rev (!p1))), aux (List.rev (!p2))))
- in (*info "-> pol_sparse_to_term\n";*)
- aux p
-
-
-let remove_list_tail l i =
- let rec aux l i =
- if List.is_empty l
- then []
- else if i<0
- then l
- else if Int.equal i 0
- then List.tl l
- else
- match l with
- |(a::l1) ->
- a::(aux l1 (i-1))
- |_ -> assert false
- in
- List.rev (aux (List.rev l) i)
-
-(*
- lq = [cn+m+1 n+m ...cn+m+1 1]
- lci=[[cn+1 n,...,cn1 1]
- ...
- [cn+m n+m-1,...,cn+m 1]]
-
- removes intermediate polynomials not useful to compute the last one.
- *)
-
-let remove_zeros zero lci =
- let n = List.length (List.hd lci) in
- let m=List.length lci in
- let u = Array.make m false in
- let rec utiles k =
- if k>=m
- then ()
- else (
- u.(k)<-true;
- let lc = List.nth lci k in
- for i=0 to List.length lc - 1 do
- if not (zero (List.nth lc i))
- then utiles (i+k+1);
- done)
- in utiles 0;
- let lr = ref [] in
- for i=0 to m-1 do
- if u.(i)
- then lr:=(List.nth lci i)::(!lr)
- done;
- let lr=List.rev !lr in
- let lr = List.map
- (fun lc ->
- let lcr=ref lc in
- for i=0 to m-1 do
- if not u.(i)
- then lcr:=remove_list_tail !lcr (m-i+(n-m))
- done;
- !lcr)
- lr in
- info ("useless spolynomials: "
- ^string_of_int (m-List.length lr)^"\n");
- info ("useful spolynomials: "
- ^string_of_int (List.length lr)^"\n");
- lr
-
-let theoremedeszeros lpol p =
- let t1 = Unix.gettimeofday() in
- let m = !nvars in
- let (lp0,p,cert) = in_ideal m lpol p in
- let lpc = List.rev !poldepcontent in
- info ("time: "^Format.sprintf "@[%10.3f@]s\n" (Unix.gettimeofday ()-.t1));
- (cert,lp0,p,lpc)
-
-open Ideal
-
-let theoremedeszeros_termes lp =
- nvars:=0;(* mise a jour par term_pol_sparse *)
- List.iter set_nvars_term lp;
- match lp with
- | Const (Int sugarparam)::Const (Int nparam)::lp ->
- ((match sugarparam with
- |0 -> info "computation without sugar\n";
- lexico:=false;
- sugar_flag := false;
- divide_rem_with_critical_pair := false
- |1 -> info "computation with sugar\n";
- lexico:=false;
- sugar_flag := true;
- divide_rem_with_critical_pair := false
- |2 -> info "ordre lexico computation without sugar\n";
- lexico:=true;
- sugar_flag := false;
- divide_rem_with_critical_pair := false
- |3 -> info "ordre lexico computation with sugar\n";
- lexico:=true;
- sugar_flag := true;
- divide_rem_with_critical_pair := false
- |4 -> info "computation without sugar, division by pairs\n";
- lexico:=false;
- sugar_flag := false;
- divide_rem_with_critical_pair := true
- |5 -> info "computation with sugar, division by pairs\n";
- lexico:=false;
- sugar_flag := true;
- divide_rem_with_critical_pair := true
- |6 -> info "ordre lexico computation without sugar, division by pairs\n";
- lexico:=true;
- sugar_flag := false;
- divide_rem_with_critical_pair := true
- |7 -> info "ordre lexico computation with sugar, division by pairs\n";
- lexico:=true;
- sugar_flag := true;
- divide_rem_with_critical_pair := true
- | _ -> error "nsatz: bad parameter"
- );
- let m= !nvars in
- let lvar=ref [] in
- for i=m downto 1 do lvar:=["x"^(string_of_int i)^""]@(!lvar); done;
- lvar:=["a";"b";"c";"d";"e";"f";"g";"h";"i";"j";"k";"l";"m";"n";"o";"p";"q";"r";"s";"t";"u";"v";"w";"x";"y";"z"] @ (!lvar); (* pour macaulay *)
- name_var:=!lvar;
- let lp = List.map (term_pol_sparse nparam) lp in
- match lp with
- | [] -> assert false
- | p::lp1 ->
- let lpol = List.rev lp1 in
- let (cert,lp0,p,_lct) = theoremedeszeros lpol p in
- info "cert ok\n";
- let lc = cert.last_comb::List.rev cert.gb_comb in
- match remove_zeros (fun x -> equal x zeroP) lc with
- | [] -> assert false
- | (lq::lci) ->
- (* lci commence par les nouveaux polynomes *)
- let m= !nvars in
- let c = pol_sparse_to_term m (polconst m cert.coef) in
- let r = Pow(Zero,cert.power) in
- let lci = List.rev lci in
- let lci = List.map (List.map (pol_sparse_to_term m)) lci in
- let lq = List.map (pol_sparse_to_term m) lq in
- info ("number of parametres: "^string_of_int nparam^"\n");
- info "term computed\n";
- (c,r,lci,lq)
- )
- |_ -> assert false
-
-
-(* version avec hash-consing du certificat:
-let nsatz lpol =
- Hashtbl.clear Dansideal.hmon;
- Hashtbl.clear Dansideal.coefpoldep;
- Hashtbl.clear Dansideal.sugartbl;
- Hashtbl.clear Polynomesrec.hcontentP;
- init_constants ();
- let lp= parse_request lpol in
- let (_lp0,_p,c,r,_lci,_lq as rthz) = theoremedeszeros_termes lp in
- let certif = certificat_vers_polynome_creux rthz in
- let certif = hash_certif certif in
- let certif = certif_term certif in
- let c = mkt_term c in
- info "constr computed\n";
- (c, certif)
-*)
-
-let nsatz lpol =
- let lp= parse_request lpol in
- let (c,r,lci,lq) = theoremedeszeros_termes lp in
- let res = [c::r::lq]@lci in
- let res = List.map (fun lx -> List.map mkt_term lx) res in
- let res =
- List.fold_right
- (fun lt r ->
- let ltterm =
- List.fold_right
- (fun t r ->
- mkt_app lcons [mkt_app tpexpr [Lazy.force tz];t;r])
- lt
- (mkt_app lnil [mkt_app tpexpr [Lazy.force tz]]) in
- mkt_app lcons [tlp ();ltterm;r])
- res
- (mkt_app lnil [tlp ()]) in
- info "term computed\n";
- res
-
-let return_term t =
- let a =
- mkApp(gen_constant "CC" ["Init";"Logic"] "refl_equal",[|tllp ();t|]) in
- generalize [a]
-
-let nsatz_compute t =
- let lpol =
- try nsatz t
- with Ideal.NotInIdeal ->
- error "nsatz cannot solve this problem" in
- return_term lpol
-
-TACTIC EXTEND nsatz_compute
-| [ "nsatz_compute" constr(lt) ] -> [ Proofview.V82.tactic (nsatz_compute lt) ]
-END
-
-
diff --git a/plugins/nsatz/nsatz_plugin.mllib b/plugins/nsatz/nsatz_plugin.mllib
index a25e649d0f..e991fb76f7 100644
--- a/plugins/nsatz/nsatz_plugin.mllib
+++ b/plugins/nsatz/nsatz_plugin.mllib
@@ -2,4 +2,5 @@ Utile
Polynom
Ideal
Nsatz
+G_nsatz
Nsatz_plugin_mod
--
cgit v1.2.3
From b18bc8d5fe64d395197b172b5574f03d50d8157d Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 03:56:11 +0100
Subject: Removing useless grammar.cma dependencies.
---
plugins/setoid_ring/newring.ml | 2 --
tactics/eauto.ml | 2 --
tactics/eqdecide.ml | 2 --
tactics/rewrite.ml | 2 --
tactics/tauto.ml | 2 --
5 files changed, 10 deletions(-)
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 37a8959767..7ef89b7a0e 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Pp
open Errors
open Util
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
index a118f2642f..0449467598 100644
--- a/tactics/eauto.ml
+++ b/tactics/eauto.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Pp
open Errors
open Util
diff --git a/tactics/eqdecide.ml b/tactics/eqdecide.ml
index 7c821ddcb5..7d0df2f522 100644
--- a/tactics/eqdecide.ml
+++ b/tactics/eqdecide.ml
@@ -12,8 +12,6 @@
(* by Eduardo Gimenez *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Errors
open Util
open Names
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 9532354632..1be78c2add 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Names
open Pp
open Errors
diff --git a/tactics/tauto.ml b/tactics/tauto.ml
index 67ef25d49f..d3e0b1f449 100644
--- a/tactics/tauto.ml
+++ b/tactics/tauto.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Term
open Hipattern
open Names
--
cgit v1.2.3
From d3653c6da5770dfc4d439639b49193e30172763a Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 15:10:27 +0100
Subject: Fixing bug #4610: Fails to build with camlp4 since the TACTIC EXTEND
move.
We just reuse the same one weird old trick in CAMLP4 to compare keywords and
identifiers as tokens. Note though that the commit 982460743 does not fix the
keyword vs. identifier issue in CAMLP4, so that the corresponding test fails.
This means that since that commit, some code compiling with CAMLP5 does not
when using CAMLP4, making it a second-class citizen.
---
dev/printers.mllib | 2 +-
grammar/grammar.mllib | 2 +-
parsing/compat.ml4 | 2 +-
parsing/tok.mli | 1 +
4 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/dev/printers.mllib b/dev/printers.mllib
index 21868203f8..39e4b1cdb1 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -19,6 +19,7 @@ Pp_control
Loc
CList
CString
+Tok
Compat
Flags
Control
@@ -153,7 +154,6 @@ Library
States
Genprint
-Tok
Lexer
Ppextend
Pputils
diff --git a/grammar/grammar.mllib b/grammar/grammar.mllib
index 4432f4306e..fc7cb392bf 100644
--- a/grammar/grammar.mllib
+++ b/grammar/grammar.mllib
@@ -49,8 +49,8 @@ Stdarg
Constrarg
Constrexpr_ops
-Compat
Tok
+Compat
Lexer
Entry
Pcoq
diff --git a/parsing/compat.ml4 b/parsing/compat.ml4
index 0e416fe32c..c482c694e1 100644
--- a/parsing/compat.ml4
+++ b/parsing/compat.ml4
@@ -276,7 +276,7 @@ ELSE
module Gramext = G
let stoken tok = match tok with
| Tok.KEYWORD s -> Gramext.Skeyword s
- | tok -> Gramext.Stoken ((=) tok, G.Token.to_string tok)
+ | tok -> Gramext.Stoken (Tok.equal tok, G.Token.to_string tok)
END
IFDEF CAMLP5_6_00 THEN
diff --git a/parsing/tok.mli b/parsing/tok.mli
index 416ce468e3..54b747952a 100644
--- a/parsing/tok.mli
+++ b/parsing/tok.mli
@@ -20,6 +20,7 @@ type t =
| BULLET of string
| EOI
+val equal : t -> t -> bool
val extract_string : t -> string
val to_string : t -> string
(* Needed to fit Camlp4 signature *)
--
cgit v1.2.3
From 6ecbc9990a49a0dd51970c7fc8b13f39f02be773 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 18:34:39 +0100
Subject: Moving Ltac traces to Tacexpr and Tacinterp.
---
dev/printers.mllib | 1 -
intf/tacexpr.mli | 12 ++++++++++++
proofs/proof_type.ml | 52 ---------------------------------------------------
proofs/proof_type.mli | 16 ----------------
proofs/proofs.mllib | 1 -
tactics/tacinterp.ml | 2 ++
tactics/tacinterp.mli | 2 ++
tactics/tacsubst.ml | 2 ++
tactics/tacsubst.mli | 4 ++++
toplevel/cerrors.ml | 2 +-
toplevel/himsg.ml | 22 +++++++++++-----------
toplevel/himsg.mli | 2 +-
12 files changed, 35 insertions(+), 83 deletions(-)
delete mode 100644 proofs/proof_type.ml
diff --git a/dev/printers.mllib b/dev/printers.mllib
index 39e4b1cdb1..34bde1ac27 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -174,7 +174,6 @@ Implicit_quantifiers
Constrintern
Modintern
Constrextern
-Proof_type
Goal
Miscprint
Logic
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index f2a567c00d..b1dc174d4b 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -394,3 +394,15 @@ type tactic_arg =
type raw_red_expr = (r_trm, r_cst, r_pat) red_expr_gen
type glob_red_expr = (g_trm, g_cst, g_pat) red_expr_gen
+
+(** Traces *)
+
+type ltac_call_kind =
+ | LtacMLCall of glob_tactic_expr
+ | LtacNotationCall of KerName.t
+ | LtacNameCall of ltac_constant
+ | LtacAtomCall of glob_atomic_tactic_expr
+ | LtacVarCall of Id.t * glob_tactic_expr
+ | LtacConstrInterp of Glob_term.glob_constr * Pretyping.ltac_var_map
+
+type ltac_trace = (Loc.t * ltac_call_kind) list
diff --git a/proofs/proof_type.ml b/proofs/proof_type.ml
deleted file mode 100644
index dd2c7b253d..0000000000
--- a/proofs/proof_type.ml
+++ /dev/null
@@ -1,52 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* goal list sigma
-
-type prim_rule =
- | Cut of bool * bool * Id.t * types
- | FixRule of Id.t * int * (Id.t * int * constr) list * int
- | Cofix of Id.t * (Id.t * constr) list * int
- | Refine of constr
- | Thin of Id.t list
- | Move of Id.t * Id.t move_location
-
-(** Nowadays, the only rules we'll consider are the primitive rules *)
-
-type rule = prim_rule
-
-(** Ltac traces *)
-
-type ltac_call_kind =
- | LtacMLCall of glob_tactic_expr
- | LtacNotationCall of KerName.t
- | LtacNameCall of ltac_constant
- | LtacAtomCall of glob_atomic_tactic_expr
- | LtacVarCall of Id.t * glob_tactic_expr
- | LtacConstrInterp of glob_constr * Pretyping.ltac_var_map
-
-type ltac_trace = (Loc.t * ltac_call_kind) list
-
-let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
diff --git a/proofs/proof_type.mli b/proofs/proof_type.mli
index aa05f58ab6..b4c9dae2a3 100644
--- a/proofs/proof_type.mli
+++ b/proofs/proof_type.mli
@@ -57,19 +57,3 @@ type rule = prim_rule
type goal = Goal.goal
type tactic = goal sigma -> goal list sigma
-
-(** Ltac traces *)
-
-(** TODO: Move those definitions somewhere sensible *)
-
-type ltac_call_kind =
- | LtacMLCall of glob_tactic_expr
- | LtacNotationCall of KerName.t
- | LtacNameCall of ltac_constant
- | LtacAtomCall of glob_atomic_tactic_expr
- | LtacVarCall of Id.t * glob_tactic_expr
- | LtacConstrInterp of glob_constr * Pretyping.ltac_var_map
-
-type ltac_trace = (Loc.t * ltac_call_kind) list
-
-val ltac_trace_info : ltac_trace Exninfo.t
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 1bd701cb9b..47a637575f 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -2,7 +2,6 @@ Miscprint
Goal
Evar_refiner
Proof_using
-Proof_type
Proof_errors
Logic
Proofview
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index bf5f9ddc86..82252610a8 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -44,6 +44,8 @@ open Sigma.Notations
open Proofview.Notations
open Context.Named.Declaration
+let ltac_trace_info = Tacsubst.ltac_trace_info
+
let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
let Val.Dyn (t, _) = v in
match Val.eq t (val_tag wit) with
diff --git a/tactics/tacinterp.mli b/tactics/tacinterp.mli
index c5da3494cb..31327873e9 100644
--- a/tactics/tacinterp.mli
+++ b/tactics/tacinterp.mli
@@ -14,6 +14,8 @@ open Genarg
open Redexpr
open Misctypes
+val ltac_trace_info : ltac_trace Exninfo.t
+
module Value :
sig
type t = Val.t
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 55941c1ca6..17cb8ad19b 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -18,6 +18,8 @@ open Genredexpr
open Patternops
open Pretyping
+let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
+
(** Substitution of tactics at module closing time *)
(** For generic arguments, we declare and store substitutions
diff --git a/tactics/tacsubst.mli b/tactics/tacsubst.mli
index c1bf272579..8b686c5cec 100644
--- a/tactics/tacsubst.mli
+++ b/tactics/tacsubst.mli
@@ -11,6 +11,10 @@ open Mod_subst
open Genarg
open Misctypes
+(** TODO: Move those definitions somewhere sensible *)
+
+val ltac_trace_info : ltac_trace Exninfo.t
+
(** Substitution of tactics at module closing time *)
val subst_tactic : substitution -> glob_tactic_expr -> glob_tactic_expr
diff --git a/toplevel/cerrors.ml b/toplevel/cerrors.ml
index 600683d359..91ef45393c 100644
--- a/toplevel/cerrors.ml
+++ b/toplevel/cerrors.ml
@@ -120,7 +120,7 @@ let process_vernac_interp_error ?(allow_uncaught=true) ?(with_header=true) (exc,
let err = Errors.make_anomaly msg in
Util.iraise (err, info)
in
- let ltac_trace = Exninfo.get info Proof_type.ltac_trace_info in
+ let ltac_trace = Exninfo.get info Tacsubst.ltac_trace_info in
let loc = Option.default Loc.ghost (Loc.get_loc info) in
match ltac_trace with
| None -> e
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index de7ec61c81..1af09dd845 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -1247,9 +1247,9 @@ let explain_reduction_tactic_error = function
let is_defined_ltac trace =
let rec aux = function
- | (_, Proof_type.LtacNameCall f) :: tail ->
+ | (_, Tacexpr.LtacNameCall f) :: tail ->
not (Tacenv.is_ltac_for_ml_tactic f)
- | (_, Proof_type.LtacAtomCall _) :: tail ->
+ | (_, Tacexpr.LtacAtomCall _) :: tail ->
false
| _ :: tail -> aux tail
| [] -> false in
@@ -1258,17 +1258,17 @@ let is_defined_ltac trace =
let explain_ltac_call_trace last trace loc =
let calls = last :: List.rev_map snd trace in
let pr_call ck = match ck with
- | Proof_type.LtacNotationCall kn -> quote (KerName.print kn)
- | Proof_type.LtacNameCall cst -> quote (Pptactic.pr_ltac_constant cst)
- | Proof_type.LtacMLCall t ->
+ | Tacexpr.LtacNotationCall kn -> quote (KerName.print kn)
+ | Tacexpr.LtacNameCall cst -> quote (Pptactic.pr_ltac_constant cst)
+ | Tacexpr.LtacMLCall t ->
quote (Pptactic.pr_glob_tactic (Global.env()) t)
- | Proof_type.LtacVarCall (id,t) ->
+ | Tacexpr.LtacVarCall (id,t) ->
quote (Nameops.pr_id id) ++ strbrk " (bound to " ++
Pptactic.pr_glob_tactic (Global.env()) t ++ str ")"
- | Proof_type.LtacAtomCall te ->
+ | Tacexpr.LtacAtomCall te ->
quote (Pptactic.pr_glob_tactic (Global.env())
(Tacexpr.TacAtom (Loc.ghost,te)))
- | Proof_type.LtacConstrInterp (c, { Pretyping.ltac_constrs = vars }) ->
+ | Tacexpr.LtacConstrInterp (c, { Pretyping.ltac_constrs = vars }) ->
quote (pr_glob_constr_env (Global.env()) c) ++
(if not (Id.Map.is_empty vars) then
strbrk " (with " ++
@@ -1282,7 +1282,7 @@ let explain_ltac_call_trace last trace loc =
| [] -> mt ()
| _ ->
let kind_of_last_call = match List.last calls with
- | Proof_type.LtacConstrInterp _ -> ", last term evaluation failed."
+ | Tacexpr.LtacConstrInterp _ -> ", last term evaluation failed."
| _ -> ", last call failed."
in
hov 0 (str "In nested Ltac calls to " ++
@@ -1290,9 +1290,9 @@ let explain_ltac_call_trace last trace loc =
let skip_extensions trace =
let rec aux = function
- | (_,Proof_type.LtacNameCall f as tac) :: _
+ | (_,Tacexpr.LtacNameCall f as tac) :: _
when Tacenv.is_ltac_for_ml_tactic f -> [tac]
- | (_,(Proof_type.LtacNotationCall _ | Proof_type.LtacMLCall _) as tac)
+ | (_,(Tacexpr.LtacNotationCall _ | Tacexpr.LtacMLCall _) as tac)
:: _ -> [tac]
| t :: tail -> t :: aux tail
| [] -> [] in
diff --git a/toplevel/himsg.mli b/toplevel/himsg.mli
index 3ef98380b5..50bbd15c6d 100644
--- a/toplevel/himsg.mli
+++ b/toplevel/himsg.mli
@@ -37,7 +37,7 @@ val explain_reduction_tactic_error :
Tacred.reduction_tactic_error -> std_ppcmds
val extract_ltac_trace :
- Proof_type.ltac_trace -> Loc.t -> std_ppcmds option * Loc.t
+ Tacexpr.ltac_trace -> Loc.t -> std_ppcmds option * Loc.t
val explain_module_error : Modops.module_typing_error -> std_ppcmds
--
cgit v1.2.3
From 9e96794d6a4327761ce1ff992351199919431be1 Mon Sep 17 00:00:00 2001
From: Pierre-Marie Pédrot
Date: Sun, 6 Mar 2016 19:01:38 +0100
Subject: Moving Tactic_debug to tactics/ folder.
---
dev/printers.mllib | 2 +-
printing/pptactic.ml | 11 --
printing/pptacticsig.mli | 5 +
proofs/proofs.mllib | 1 -
proofs/tactic_debug.ml | 319 ---------------------------------------------
proofs/tactic_debug.mli | 79 -----------
tactics/tacinterp.ml | 15 ++-
tactics/tacsubst.ml | 2 -
tactics/tacsubst.mli | 4 -
tactics/tactic_debug.ml | 324 ++++++++++++++++++++++++++++++++++++++++++++++
tactics/tactic_debug.mli | 77 +++++++++++
tactics/tactics.mllib | 1 +
toplevel/cerrors.ml | 2 +-
toplevel/vernacentries.ml | 12 --
14 files changed, 423 insertions(+), 431 deletions(-)
delete mode 100644 proofs/tactic_debug.ml
delete mode 100644 proofs/tactic_debug.mli
create mode 100644 tactics/tactic_debug.ml
create mode 100644 tactics/tactic_debug.mli
diff --git a/dev/printers.mllib b/dev/printers.mllib
index 34bde1ac27..d8fb2b906c 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -187,13 +187,13 @@ Proofview
Proof
Proof_global
Pfedit
-Tactic_debug
Decl_mode
Ppconstr
Entry
Pcoq
Printer
Pptactic
+Tactic_debug
Ppdecl_proof
Egramml
Egramcoq
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index fdc1288aec..7d5e7772c3 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -1415,17 +1415,6 @@ let () =
let printer _ _ prtac = prtac (0, E) in
declare_extra_genarg_pprule wit_tactic printer printer printer
-let _ = Hook.set Tactic_debug.tactic_printer
- (fun x -> pr_glob_tactic (Global.env()) x)
-
-let _ = Hook.set Tactic_debug.match_pattern_printer
- (fun env sigma hyp -> pr_match_pattern (pr_constr_pattern_env env sigma) hyp)
-
-let _ = Hook.set Tactic_debug.match_rule_printer
- (fun rl ->
- pr_match_rule false (pr_glob_tactic (Global.env()))
- (fun (_,p) -> pr_constr_pattern p) rl)
-
module Richpp = struct
include Make (Ppconstr.Richpp) (struct
diff --git a/printing/pptacticsig.mli b/printing/pptacticsig.mli
index c5ec6bb092..b98b6c67e7 100644
--- a/printing/pptacticsig.mli
+++ b/printing/pptacticsig.mli
@@ -67,4 +67,9 @@ module type Pp = sig
('constr -> std_ppcmds) ->
('constr -> std_ppcmds) -> 'constr bindings -> std_ppcmds
+ val pr_match_pattern : ('a -> std_ppcmds) -> 'a match_pattern -> std_ppcmds
+
+ val pr_match_rule : bool -> ('a -> std_ppcmds) -> ('b -> std_ppcmds) ->
+ ('b, 'a) match_rule -> std_ppcmds
+
end
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 47a637575f..08556d62ec 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -11,6 +11,5 @@ Redexpr
Refiner
Tacmach
Pfedit
-Tactic_debug
Clenv
Clenvtac
diff --git a/proofs/tactic_debug.ml b/proofs/tactic_debug.ml
deleted file mode 100644
index d33278ff8d..0000000000
--- a/proofs/tactic_debug.ml
+++ /dev/null
@@ -1,319 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* mt())
-
-let explain_logic_error_no_anomaly = ref (fun e -> mt())
-
-let msg_tac_debug s = Proofview.NonLogical.print_debug (s++fnl())
-let msg_tac_notice s = Proofview.NonLogical.print_notice (s++fnl())
-
-(* Prints the goal *)
-
-let db_pr_goal gl =
- let env = Proofview.Goal.env gl in
- let concl = Proofview.Goal.concl gl in
- let penv = print_named_context env in
- let pc = print_constr_env env concl in
- str" " ++ hv 0 (penv ++ fnl () ++
- str "============================" ++ fnl () ++
- str" " ++ pc) ++ fnl ()
-
-let db_pr_goal =
- Proofview.Goal.nf_enter { enter = begin fun gl ->
- let pg = db_pr_goal gl in
- Proofview.tclLIFT (msg_tac_notice (str "Goal:" ++ fnl () ++ pg))
- end }
-
-
-(* Prints the commands *)
-let help () =
- msg_tac_debug (str "Commands: = Continue" ++ fnl() ++
- str " h/? = Help" ++ fnl() ++
- str " r = Run times" ++ fnl() ++
- str " r = Run up to next idtac " ++ fnl() ++
- str " s = Skip" ++ fnl() ++
- str " x = Exit")
-
-(* Prints the goal and the command to be executed *)
-let goal_com tac =
- Proofview.tclTHEN
- db_pr_goal
- (Proofview.tclLIFT (msg_tac_debug (str "Going to execute:" ++ fnl () ++ Hook.get prtac tac)))
-
-(* [run (new_ref _)] gives us a ref shared among [NonLogical.t]
- expressions. It avoids parametrizing everything over a
- reference. *)
-let skipped = Proofview.NonLogical.run (Proofview.NonLogical.ref 0)
-let skip = Proofview.NonLogical.run (Proofview.NonLogical.ref 0)
-let breakpoint = Proofview.NonLogical.run (Proofview.NonLogical.ref None)
-
-let rec drop_spaces inst i =
- if String.length inst > i && inst.[i] == ' ' then drop_spaces inst (i+1)
- else i
-
-let possibly_unquote s =
- if String.length s >= 2 && s.[0] == '"' && s.[String.length s - 1] == '"' then
- String.sub s 1 (String.length s - 2)
- else
- s
-
-(* (Re-)initialize debugger *)
-let db_initialize =
- let open Proofview.NonLogical in
- (skip:=0) >> (skipped:=0) >> (breakpoint:=None)
-
-let int_of_string s =
- try Proofview.NonLogical.return (int_of_string s)
- with e -> Proofview.NonLogical.raise e
-
-let string_get s i =
- try Proofview.NonLogical.return (String.get s i)
- with e -> Proofview.NonLogical.raise e
-
-(* Gives the number of steps or next breakpoint of a run command *)
-let run_com inst =
- let open Proofview.NonLogical in
- string_get inst 0 >>= fun first_char ->
- if first_char ='r' then
- let i = drop_spaces inst 1 in
- if String.length inst > i then
- let s = String.sub inst i (String.length inst - i) in
- if inst.[0] >= '0' && inst.[0] <= '9' then
- int_of_string s >>= fun num ->
- (if num<0 then invalid_arg "run_com" else return ()) >>
- (skip:=num) >> (skipped:=0)
- else
- breakpoint:=Some (possibly_unquote s)
- else
- invalid_arg "run_com"
- else
- invalid_arg "run_com"
-
-(* Prints the run counter *)
-let run ini =
- let open Proofview.NonLogical in
- if not ini then
- begin
- Proofview.NonLogical.print_notice (str"\b\r\b\r") >>
- !skipped >>= fun skipped ->
- msg_tac_debug (str "Executed expressions: " ++ int skipped ++ fnl())
- end >>
- !skipped >>= fun x ->
- skipped := x+1
- else
- return ()
-
-(* Prints the prompt *)
-let rec prompt level =
- (* spiwack: avoid overriding by the open below *)
- let runtrue = run true in
- begin
- let open Proofview.NonLogical in
- Proofview.NonLogical.print_notice (fnl () ++ str "TcDebug (" ++ int level ++ str ") > ") >>
- let exit = (skip:=0) >> (skipped:=0) >> raise Sys.Break in
- Proofview.NonLogical.catch Proofview.NonLogical.read_line
- begin function (e, info) -> match e with
- | End_of_file -> exit
- | e -> raise ~info e
- end
- >>= fun inst ->
- match inst with
- | "" -> return (DebugOn (level+1))
- | "s" -> return (DebugOff)
- | "x" -> Proofview.NonLogical.print_char '\b' >> exit
- | "h"| "?" ->
- begin
- help () >>
- prompt level
- end
- | _ ->
- Proofview.NonLogical.catch (run_com inst >> runtrue >> return (DebugOn (level+1)))
- begin function (e, info) -> match e with
- | Failure _ | Invalid_argument _ -> prompt level
- | e -> raise ~info e
- end
- end
-
-(* Prints the state and waits for an instruction *)
-(* spiwack: the only reason why we need to take the continuation [f]
- as an argument rather than returning the new level directly seems to
- be that [f] is wrapped in with "explain_logic_error". I don't think
- it serves any purpose in the current design, so we could just drop
- that. *)
-let debug_prompt lev tac f =
- (* spiwack: avoid overriding by the open below *)
- let runfalse = run false in
- let open Proofview.NonLogical in
- let (>=) = Proofview.tclBIND in
- (* What to print and to do next *)
- let newlevel =
- Proofview.tclLIFT !skip >= fun initial_skip ->
- if Int.equal initial_skip 0 then
- Proofview.tclLIFT !breakpoint >= fun breakpoint ->
- if Option.is_empty breakpoint then Proofview.tclTHEN (goal_com tac) (Proofview.tclLIFT (prompt lev))
- else Proofview.tclLIFT(runfalse >> return (DebugOn (lev+1)))
- else Proofview.tclLIFT begin
- (!skip >>= fun s -> skip:=s-1) >>
- runfalse >>
- !skip >>= fun new_skip ->
- (if Int.equal new_skip 0 then skipped:=0 else return ()) >>
- return (DebugOn (lev+1))
- end in
- newlevel >= fun newlevel ->
- (* What to execute *)
- Proofview.tclOR
- (f newlevel)
- begin fun (reraise, info) ->
- Proofview.tclTHEN
- (Proofview.tclLIFT begin
- (skip:=0) >> (skipped:=0) >>
- if Logic.catchable_exception reraise then
- msg_tac_debug (str "Level " ++ int lev ++ str ": " ++ Pervasives.(!) explain_logic_error reraise)
- else return ()
- end)
- (Proofview.tclZERO ~info reraise)
- end
-
-let is_debug db =
- let open Proofview.NonLogical in
- !breakpoint >>= fun breakpoint ->
- match db, breakpoint with
- | DebugOff, _ -> return false
- | _, Some _ -> return false
- | _ ->
- !skip >>= fun skip ->
- return (Int.equal skip 0)
-
-(* Prints a constr *)
-let db_constr debug env c =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "Evaluated term: " ++ print_constr_env env c)
- else return ()
-
-(* Prints the pattern rule *)
-let db_pattern_rule debug num r =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- begin
- msg_tac_debug (str "Pattern rule " ++ int num ++ str ":" ++ fnl () ++
- str "|" ++ spc () ++ Hook.get prmatchrl r)
- end
- else return ()
-
-(* Prints the hypothesis pattern identifier if it exists *)
-let hyp_bound = function
- | Anonymous -> str " (unbound)"
- | Name id -> str " (bound to " ++ pr_id id ++ str ")"
-
-(* Prints a matched hypothesis *)
-let db_matched_hyp debug env (id,_,c) ido =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "Hypothesis " ++ pr_id id ++ hyp_bound ido ++
- str " has been matched: " ++ print_constr_env env c)
- else return ()
-
-(* Prints the matched conclusion *)
-let db_matched_concl debug env c =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "Conclusion has been matched: " ++ print_constr_env env c)
- else return ()
-
-(* Prints a success message when the goal has been matched *)
-let db_mc_pattern_success debug =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "The goal has been successfully matched!" ++ fnl() ++
- str "Let us execute the right-hand side part..." ++ fnl())
- else return ()
-
-(* Prints a failure message for an hypothesis pattern *)
-let db_hyp_pattern_failure debug env sigma (na,hyp) =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "The pattern hypothesis" ++ hyp_bound na ++
- str " cannot match: " ++
- Hook.get prmatchpatt env sigma hyp)
- else return ()
-
-(* Prints a matching failure message for a rule *)
-let db_matching_failure debug =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- msg_tac_debug (str "This rule has failed due to matching errors!" ++ fnl() ++
- str "Let us try the next one...")
- else return ()
-
-(* Prints an evaluation failure message for a rule *)
-let db_eval_failure debug s =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- let s = str "message \"" ++ s ++ str "\"" in
- msg_tac_debug
- (str "This rule has failed due to \"Fail\" tactic (" ++
- s ++ str ", level 0)!" ++ fnl() ++ str "Let us try the next one...")
- else return ()
-
-(* Prints a logic failure message for a rule *)
-let db_logic_failure debug err =
- let open Proofview.NonLogical in
- is_debug debug >>= fun db ->
- if db then
- begin
- msg_tac_debug (Pervasives.(!) explain_logic_error err) >>
- msg_tac_debug (str "This rule has failed due to a logic error!" ++ fnl() ++
- str "Let us try the next one...")
- end
- else return ()
-
-let is_breakpoint brkname s = match brkname, s with
- | Some s, MsgString s'::_ -> String.equal s s'
- | _ -> false
-
-let db_breakpoint debug s =
- let open Proofview.NonLogical in
- !breakpoint >>= fun opt_breakpoint ->
- match debug with
- | DebugOn lev when not (CList.is_empty s) && is_breakpoint opt_breakpoint s ->
- breakpoint:=None
- | _ ->
- return ()
diff --git a/proofs/tactic_debug.mli b/proofs/tactic_debug.mli
deleted file mode 100644
index 215c5b29b5..0000000000
--- a/proofs/tactic_debug.mli
+++ /dev/null
@@ -1,79 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* Pp.std_ppcmds) Hook.t
-val match_pattern_printer :
- (env -> evar_map -> constr_pattern match_pattern -> Pp.std_ppcmds) Hook.t
-val match_rule_printer :
- ((Tacexpr.glob_constr_and_expr * constr_pattern,glob_tactic_expr) match_rule -> Pp.std_ppcmds) Hook.t
-
-(** Debug information *)
-type debug_info =
- | DebugOn of int
- | DebugOff
-
-(** Prints the state and waits *)
-val debug_prompt :
- int -> glob_tactic_expr -> (debug_info -> 'a Proofview.tactic) -> 'a Proofview.tactic
-
-(** Initializes debugger *)
-val db_initialize : unit Proofview.NonLogical.t
-
-(** Prints a constr *)
-val db_constr : debug_info -> env -> constr -> unit Proofview.NonLogical.t
-
-(** Prints the pattern rule *)
-val db_pattern_rule :
- debug_info -> int -> (Tacexpr.glob_constr_and_expr * constr_pattern,glob_tactic_expr) match_rule -> unit Proofview.NonLogical.t
-
-(** Prints a matched hypothesis *)
-val db_matched_hyp :
- debug_info -> env -> Id.t * constr option * constr -> Name.t -> unit Proofview.NonLogical.t
-
-(** Prints the matched conclusion *)
-val db_matched_concl : debug_info -> env -> constr -> unit Proofview.NonLogical.t
-
-(** Prints a success message when the goal has been matched *)
-val db_mc_pattern_success : debug_info -> unit Proofview.NonLogical.t
-
-(** Prints a failure message for an hypothesis pattern *)
-val db_hyp_pattern_failure :
- debug_info -> env -> evar_map -> Name.t * constr_pattern match_pattern -> unit Proofview.NonLogical.t
-
-(** Prints a matching failure message for a rule *)
-val db_matching_failure : debug_info -> unit Proofview.NonLogical.t
-
-(** Prints an evaluation failure message for a rule *)
-val db_eval_failure : debug_info -> Pp.std_ppcmds -> unit Proofview.NonLogical.t
-
-(** An exception handler *)
-val explain_logic_error: (exn -> Pp.std_ppcmds) ref
-
-(** For use in the Ltac debugger: some exception that are usually
- consider anomalies are acceptable because they are caught later in
- the process that is being debugged. One should not require
- from users that they report these anomalies. *)
-val explain_logic_error_no_anomaly : (exn -> Pp.std_ppcmds) ref
-
-(** Prints a logic failure message for a rule *)
-val db_logic_failure : debug_info -> exn -> unit Proofview.NonLogical.t
-
-(** Prints a logic failure message for a rule *)
-val db_breakpoint : debug_info ->
- Id.t Loc.located message_token list -> unit Proofview.NonLogical.t
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 82252610a8..36a23d5809 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -44,7 +44,7 @@ open Sigma.Notations
open Proofview.Notations
open Context.Named.Declaration
-let ltac_trace_info = Tacsubst.ltac_trace_info
+let ltac_trace_info = Tactic_debug.ltac_trace_info
let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
let Val.Dyn (t, _) = v in
@@ -2201,3 +2201,16 @@ let lift_constr_tac_to_ml_tac vars tac =
tac args ist
end } in
tac
+
+let vernac_debug b =
+ set_debug (if b then Tactic_debug.DebugOn 0 else Tactic_debug.DebugOff)
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optsync = false;
+ optdepr = false;
+ optname = "Ltac debug";
+ optkey = ["Ltac";"Debug"];
+ optread = (fun () -> get_debug () != Tactic_debug.DebugOff);
+ optwrite = vernac_debug }
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index 17cb8ad19b..55941c1ca6 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -18,8 +18,6 @@ open Genredexpr
open Patternops
open Pretyping
-let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
-
(** Substitution of tactics at module closing time *)
(** For generic arguments, we declare and store substitutions
diff --git a/tactics/tacsubst.mli b/tactics/tacsubst.mli
index 8b686c5cec..c1bf272579 100644
--- a/tactics/tacsubst.mli
+++ b/tactics/tacsubst.mli
@@ -11,10 +11,6 @@ open Mod_subst
open Genarg
open Misctypes
-(** TODO: Move those definitions somewhere sensible *)
-
-val ltac_trace_info : ltac_trace Exninfo.t
-
(** Substitution of tactics at module closing time *)
val subst_tactic : substitution -> glob_tactic_expr -> glob_tactic_expr
diff --git a/tactics/tactic_debug.ml b/tactics/tactic_debug.ml
new file mode 100644
index 0000000000..b278c371b3
--- /dev/null
+++ b/tactics/tactic_debug.ml
@@ -0,0 +1,324 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(*