aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml1
-rw-r--r--API/API.ml4
-rw-r--r--API/API.mli86
-rw-r--r--CHANGES18
-rw-r--r--META.coq2
-rw-r--r--Makefile4
-rw-r--r--Makefile.build124
-rw-r--r--Makefile.checker26
-rw-r--r--Makefile.common2
-rw-r--r--Makefile.install3
-rw-r--r--checker/inductive.ml4
-rw-r--r--config/coq_config.mli7
-rw-r--r--configure.ml48
-rw-r--r--dev/base_include2
-rw-r--r--dev/build/windows/ReadMe.txt2
-rwxr-xr-xdev/ci/ci-compcert.sh3
-rw-r--r--dev/ci/user-overlays/06169-Zimmi48-clean-up-deprecated-options.sh4
-rw-r--r--dev/ci/user-overlays/06217-coqdep-at-once.sh3
-rw-r--r--dev/ci/user-overlays/06392-ejgallego-econstr+fix_class.sh4
-rw-r--r--dev/ci/user-overlays/06413-ejgallego-interp+less_impstyle_p2.sh4
-rw-r--r--dev/doc/changes.md5
-rw-r--r--dev/doc/debugging.md4
-rw-r--r--dev/doc/setup.txt2
-rw-r--r--doc/refman/Cases.tex12
-rw-r--r--doc/refman/Classes.tex4
-rw-r--r--doc/refman/Omega.tex26
-rw-r--r--doc/refman/RefMan-ext.tex54
-rw-r--r--doc/refman/RefMan-ltac.tex17
-rw-r--r--doc/refman/RefMan-mod.tex6
-rw-r--r--doc/refman/RefMan-pro.tex2
-rw-r--r--doc/refman/RefMan-sch.tex6
-rw-r--r--doc/refman/RefMan-ssr.tex8
-rw-r--r--doc/refman/RefMan-tac.tex48
-rw-r--r--doc/refman/RefMan-uti.tex55
-rw-r--r--engine/eConstr.ml25
-rw-r--r--engine/eConstr.mli9
-rw-r--r--engine/evarutil.ml7
-rw-r--r--engine/evarutil.mli2
-rw-r--r--engine/evd.ml5
-rw-r--r--engine/evd.mli2
-rw-r--r--engine/uState.ml4
-rw-r--r--engine/universes.ml4
-rw-r--r--ide/ide_slave.ml3
-rw-r--r--interp/constrexpr_ops.ml8
-rw-r--r--interp/constrextern.ml8
-rw-r--r--interp/constrintern.ml63
-rw-r--r--interp/constrintern.mli28
-rw-r--r--intf/constrexpr.ml2
-rw-r--r--intf/glob_term.ml8
-rw-r--r--kernel/cooking.ml4
-rw-r--r--kernel/inductive.ml4
-rw-r--r--kernel/nativeconv.ml2
-rw-r--r--kernel/reduction.ml16
-rw-r--r--kernel/safe_typing.ml2
-rw-r--r--kernel/typeops.ml4
-rw-r--r--kernel/uGraph.ml16
-rw-r--r--kernel/vars.ml12
-rw-r--r--kernel/vconv.ml2
-rw-r--r--lib/cList.ml35
-rw-r--r--lib/cList.mli7
-rw-r--r--lib/cProfile.ml (renamed from lib/profile.ml)0
-rw-r--r--lib/cProfile.mli (renamed from lib/profile.mli)0
-rw-r--r--lib/control.ml7
-rw-r--r--lib/control.mli3
-rw-r--r--lib/dyn.ml10
-rw-r--r--lib/dyn.mli1
-rw-r--r--lib/envars.ml12
-rw-r--r--lib/flags.ml39
-rw-r--r--lib/flags.mli39
-rw-r--r--lib/lib.mllib2
-rw-r--r--lib/pp.ml1
-rw-r--r--lib/pp.mli3
-rw-r--r--lib/system.ml6
-rw-r--r--lib/system.mli3
-rw-r--r--library/global.ml9
-rw-r--r--library/global.mli2
-rw-r--r--library/library.ml4
-rw-r--r--library/summary.ml203
-rw-r--r--library/summary.mli41
-rw-r--r--man/coqmktop.171
-rw-r--r--parsing/g_constr.ml48
-rw-r--r--parsing/pcoq.ml4
-rw-r--r--parsing/pcoq.mli3
-rw-r--r--plugins/derive/derive.ml5
-rw-r--r--plugins/firstorder/g_ground.ml46
-rw-r--r--plugins/funind/glob_term_to_relation.ml2
-rw-r--r--plugins/funind/indfun.ml13
-rw-r--r--plugins/funind/indfun_common.ml4
-rw-r--r--plugins/funind/merge.ml6
-rw-r--r--plugins/funind/recdef.ml28
-rw-r--r--plugins/ltac/g_ltac.ml412
-rw-r--r--plugins/ltac/pptactic.ml6
-rw-r--r--plugins/ltac/profile_ltac.ml10
-rw-r--r--plugins/ltac/profile_ltac.mli33
-rw-r--r--plugins/ltac/profile_ltac_tactics.ml44
-rw-r--r--plugins/ltac/rewrite.ml31
-rw-r--r--plugins/ltac/tacexpr.mli2
-rw-r--r--plugins/ltac/tacintern.ml4
-rw-r--r--plugins/ltac/tacinterp.ml12
-rw-r--r--plugins/ltac/tacsubst.ml2
-rw-r--r--plugins/ltac/tactic_matching.ml4
-rw-r--r--plugins/ssr/ssrcommon.ml1
-rw-r--r--plugins/ssr/ssrequality.ml6
-rw-r--r--plugins/ssr/ssrvernac.ml46
-rw-r--r--plugins/ssrmatching/ssrmatching.ml433
-rw-r--r--pretyping/cases.ml6
-rw-r--r--pretyping/classops.ml34
-rw-r--r--pretyping/classops.mli2
-rw-r--r--pretyping/constr_matching.ml77
-rw-r--r--pretyping/constr_matching.mli12
-rw-r--r--pretyping/detyping.ml107
-rw-r--r--pretyping/detyping.mli10
-rw-r--r--pretyping/evarconv.ml4
-rw-r--r--pretyping/nativenorm.ml4
-rw-r--r--pretyping/reductionops.ml115
-rw-r--r--pretyping/reductionops.mli2
-rw-r--r--pretyping/retyping.ml4
-rw-r--r--pretyping/tacred.ml4
-rw-r--r--pretyping/typeclasses.ml11
-rw-r--r--pretyping/typeclasses.mli4
-rw-r--r--pretyping/unification.ml10
-rw-r--r--pretyping/vnorm.ml2
-rw-r--r--printing/ppconstr.ml11
-rw-r--r--printing/prettyp.ml12
-rw-r--r--printing/prettyp.mli5
-rw-r--r--printing/printer.ml3
-rw-r--r--printing/printer.mli3
-rw-r--r--proofs/clenvtac.ml3
-rw-r--r--proofs/logic.ml41
-rw-r--r--proofs/logic.mli6
-rw-r--r--proofs/redexpr.ml15
-rw-r--r--proofs/refiner.ml4
-rw-r--r--proofs/tacmach.ml6
-rw-r--r--stm/asyncTaskQueue.ml12
-rw-r--r--stm/asyncTaskQueue.mli3
-rw-r--r--stm/coqworkmgrApi.ml25
-rw-r--r--stm/coqworkmgrApi.mli8
-rw-r--r--stm/spawned.ml6
-rw-r--r--stm/spawned.mli2
-rw-r--r--stm/stm.ml152
-rw-r--r--stm/stm.mli27
-rw-r--r--stm/workerLoop.ml6
-rw-r--r--stm/workerLoop.mli3
-rw-r--r--tactics/auto.ml4
-rw-r--r--tactics/class_tactics.ml17
-rw-r--r--tactics/eauto.ml19
-rw-r--r--tactics/equality.ml3
-rw-r--r--tactics/hints.ml12
-rw-r--r--tactics/leminv.ml8
-rw-r--r--tactics/tactics.ml95
-rw-r--r--test-suite/bugs/closed/6378.v4
-rw-r--r--test-suite/bugs/closed/gh6384.v5
-rw-r--r--test-suite/bugs/closed/gh6385.v5
-rw-r--r--test-suite/coq-makefile/timing/after/time-of-build-after.log.desired3
-rw-r--r--test-suite/coq-makefile/timing/after/time-of-build-before.log.desired3
-rw-r--r--test-suite/output-modulo-time/ltacprof.out13
-rw-r--r--test-suite/output-modulo-time/ltacprof_cutoff.out40
-rw-r--r--test-suite/output-modulo-time/ltacprof_cutoff.v34
-rw-r--r--test-suite/output/Cases.out51
-rw-r--r--test-suite/output/Cases.v32
-rw-r--r--test-suite/output/InvalidDisjunctiveIntro.out16
-rw-r--r--test-suite/output/InvalidDisjunctiveIntro.v18
-rw-r--r--test-suite/output/Notations2.out11
-rw-r--r--test-suite/output/Notations2.v7
-rw-r--r--test-suite/success/Check.v2
-rw-r--r--theories/Logic/FunctionalExtensionality.v3
-rw-r--r--theories/Program/Combinators.v12
-rw-r--r--theories/Sets/Powerset_facts.v91
-rw-r--r--tools/CoqMakefile.in26
-rw-r--r--tools/coqmktop.ml314
-rw-r--r--tools/coqworkmgr.ml8
-rw-r--r--toplevel/coqtop.ml48
-rw-r--r--toplevel/coqtop_bin.ml2
-rw-r--r--toplevel/coqtop_byte_bin.ml21
-rw-r--r--toplevel/coqtop_opt_bin.ml3
-rw-r--r--vernac/classes.ml172
-rw-r--r--vernac/classes.mli1
-rw-r--r--vernac/comAssumption.ml182
-rw-r--r--vernac/comAssumption.mli34
-rw-r--r--vernac/comDefinition.ml131
-rw-r--r--vernac/comDefinition.mli30
-rw-r--r--vernac/comFixpoint.ml356
-rw-r--r--vernac/comFixpoint.mli93
-rw-r--r--vernac/comInductive.ml456
-rw-r--r--vernac/comInductive.mli65
-rw-r--r--vernac/comProgramFixpoint.ml342
-rw-r--r--vernac/comProgramFixpoint.mli12
-rw-r--r--vernac/command.ml1364
-rw-r--r--vernac/command.mli163
-rw-r--r--vernac/explainErr.ml3
-rw-r--r--vernac/lemmas.ml66
-rw-r--r--vernac/lemmas.mli5
-rw-r--r--vernac/mltop.ml2
-rw-r--r--vernac/obligations.ml5
-rw-r--r--vernac/obligations.mli3
-rw-r--r--vernac/record.ml93
-rw-r--r--vernac/vernac.mllib6
-rw-r--r--vernac/vernacentries.ml41
199 files changed, 3664 insertions, 3236 deletions
diff --git a/.gitignore b/.gitignore
index 36536ec96..cec51986d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -157,7 +157,6 @@ plugins/ssr/ssrvernac.ml
kernel/byterun/coq_jumptbl.h
kernel/copcodes.ml
-tools/tolink.ml
ide/index_urls.txt
.lia.cache
checker/names.ml
diff --git a/.travis.yml b/.travis.yml
index 83a4e7fdd..54e7754f2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -183,6 +183,7 @@ matrix:
- if: NOT (type = pull_request)
os: osx
+ osx_image: xcode7.3
env:
- TEST_TARGET=""
- COMPILER="4.02.3"
diff --git a/API/API.ml b/API/API.ml
index 378c03ee4..081ac2bb2 100644
--- a/API/API.ml
+++ b/API/API.ml
@@ -267,7 +267,9 @@ module Metasyntax = Metasyntax
module Search = Search
(* module Indschemes *)
module Obligations = Obligations
-module Command = Command
+module ComDefinition = ComDefinition
+module ComInductive = ComInductive
+module ComFixpoint = ComFixpoint
module Classes = Classes
(* module Record *)
(* module Assumptions *)
diff --git a/API/API.mli b/API/API.mli
index 3ed008ff5..a69766901 100644
--- a/API/API.mli
+++ b/API/API.mli
@@ -2394,7 +2394,7 @@ sig
and case_expr = constr_expr * Names.Name.t Loc.located option * cases_pattern_expr option
and branch_expr =
- (cases_pattern_expr list Loc.located list * constr_expr) Loc.located
+ (cases_pattern_expr list list * constr_expr) Loc.located
and binder_expr =
Names.Name.t Loc.located list * binder_kind * constr_expr
@@ -3853,10 +3853,9 @@ sig
type matching_result =
{ m_sub : bound_ident_map * Ltac_pretype.patvar_map;
m_ctx : EConstr.constr }
- val match_subterm_gen : Environ.env -> Evd.evar_map ->
- bool ->
- binding_bound_vars * Pattern.constr_pattern -> EConstr.constr ->
- matching_result IStream.t
+ val match_subterm : Environ.env -> Evd.evar_map ->
+ binding_bound_vars * Pattern.constr_pattern -> EConstr.constr ->
+ matching_result IStream.t
val matches : Environ.env -> Evd.evar_map -> Pattern.constr_pattern -> EConstr.constr -> Ltac_pretype.patvar_map
end
@@ -4347,6 +4346,7 @@ sig
| Later : [ `thunk ] delay
val print_universes : bool ref
val print_evar_arguments : bool ref
+ val print_allow_match_default_clause : bool ref
val detype : 'a delay -> ?lax:bool -> bool -> Names.Id.Set.t -> Environ.env -> Evd.evar_map -> EConstr.constr -> 'a Glob_term.glob_constr_g
val subst_glob_constr : Mod_subst.substitution -> Glob_term.glob_constr -> Glob_term.glob_constr
val set_detype_anonymous : (?loc:Loc.t -> int -> Names.Id.t) -> unit
@@ -4620,6 +4620,9 @@ end
module Constrintern :
sig
+
+ open Evd
+
type ltac_sign = {
ltac_vars : Names.Id.Set.t;
ltac_bound : Names.Id.Set.t;
@@ -4635,11 +4638,11 @@ sig
| Variable
type internalization_env = var_internalization_data Names.Id.Map.t
- val interp_constr_evars : Environ.env -> Evd.evar_map ref ->
- ?impls:internalization_env -> Constrexpr.constr_expr -> EConstr.constr
+ val interp_constr_evars : Environ.env -> evar_map ->
+ ?impls:internalization_env -> Constrexpr.constr_expr -> evar_map * EConstr.constr
- val interp_type_evars : Environ.env -> Evd.evar_map ref ->
- ?impls:internalization_env -> Constrexpr.constr_expr -> EConstr.types
+ val interp_type_evars : Environ.env -> Evd.evar_map ->
+ ?impls:internalization_env -> Constrexpr.constr_expr -> evar_map * EConstr.types
val empty_ltac_sign : ltac_sign
val intern_gen : Pretyping.typing_constraint -> Environ.env ->
@@ -4657,10 +4660,12 @@ sig
val locate_reference : Libnames.qualid -> Globnames.global_reference
val interp_type : Environ.env -> Evd.evar_map -> ?impls:internalization_env ->
Constrexpr.constr_expr -> Constr.types Evd.in_evar_universe_context
+
val interp_context_evars :
?global_level:bool -> ?impl_env:internalization_env -> ?shift:int ->
- Environ.env -> Evd.evar_map ref -> Constrexpr.local_binder_expr list ->
- internalization_env * ((Environ.env * EConstr.rel_context) * Impargs.manual_implicits)
+ Environ.env -> Evd.evar_map -> Constrexpr.local_binder_expr list ->
+ evar_map * (internalization_env * ((Environ.env * EConstr.rel_context) * Impargs.manual_implicits))
+
val compute_internalization_data : Environ.env -> var_internalization_type ->
Constr.types -> Impargs.manual_explicitation list -> var_internalization_data
val empty_internalization_env : internalization_env
@@ -4801,7 +4806,7 @@ sig
| IntroNeedsProduct
| DoesNotOccurIn of Constr.t * Names.Id.t
| NoSuchHyp of Names.Id.t
- exception RefinerError of refiner_error
+ exception RefinerError of Environ.env * Evd.evar_map * refiner_error
val catchable_exception : exn -> bool
end
@@ -6045,21 +6050,53 @@ sig
val show_term : Names.Id.t option -> Pp.t
end
-module Command :
+module ComDefinition :
+sig
+ val do_definition :
+ program_mode:bool ->
+ Names.Id.t -> Decl_kinds.definition_kind -> Vernacexpr.universe_decl_expr option ->
+ Constrexpr.local_binder_expr list -> Redexpr.red_expr option -> Constrexpr.constr_expr ->
+ Constrexpr.constr_expr option -> unit Lemmas.declaration_hook -> unit
+end
+
+module ComFixpoint :
sig
+
open Names
open Constrexpr
- open Vernacexpr
type structured_fixpoint_expr = {
fix_name : Id.t;
- fix_univs : universe_decl_expr option;
+ fix_univs : Vernacexpr.universe_decl_expr option;
fix_annot : Id.t Loc.located option;
fix_binders : local_binder_expr list;
fix_body : constr_expr option;
fix_type : constr_expr
}
+ type recursive_preentry = Names.Id.t list * Constr.t option list * Constr.types list
+
+ val interp_fixpoint :
+ cofix:bool ->
+ structured_fixpoint_expr list -> Vernacexpr.decl_notation list ->
+ recursive_preentry * Univdecls.universe_decl * UState.t *
+ (EConstr.rel_context * Impargs.manual_implicits * int option) list
+
+ val extract_fixpoint_components : bool ->
+ (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list ->
+ structured_fixpoint_expr list * Vernacexpr.decl_notation list
+
+ val do_fixpoint :
+ Decl_kinds.locality -> Decl_kinds.polymorphic -> (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list -> unit
+
+end
+
+module ComInductive :
+sig
+ open Names
+ open Constrexpr
+ open Vernacexpr
+
type structured_one_inductive_expr = {
ind_name : Id.t;
ind_univs : universe_decl_expr option;
@@ -6070,30 +6107,12 @@ sig
type structured_inductive_expr =
local_binder_expr list * structured_one_inductive_expr list
- type recursive_preentry = Names.Id.t list * Constr.t option list * Constr.types list
-
type one_inductive_impls
val do_mutual_inductive :
(Vernacexpr.one_inductive_expr * Vernacexpr.decl_notation list) list -> Decl_kinds.cumulative_inductive_flag -> Decl_kinds.polymorphic ->
Decl_kinds.private_flag -> Declarations.recursivity_kind -> unit
- val do_definition : Names.Id.t -> Decl_kinds.definition_kind -> Vernacexpr.universe_decl_expr option ->
- Constrexpr.local_binder_expr list -> Redexpr.red_expr option -> Constrexpr.constr_expr ->
- Constrexpr.constr_expr option -> unit Lemmas.declaration_hook -> unit
-
- val do_fixpoint :
- Decl_kinds.locality -> Decl_kinds.polymorphic -> (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list -> unit
-
- val extract_fixpoint_components : bool ->
- (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list ->
- structured_fixpoint_expr list * Vernacexpr.decl_notation list
-
- val interp_fixpoint :
- structured_fixpoint_expr list -> Vernacexpr.decl_notation list ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (EConstr.rel_context * Impargs.manual_implicits * int option) list
-
val extract_mutual_inductive_declaration_components :
(Vernacexpr.one_inductive_expr * Vernacexpr.decl_notation list) list ->
structured_inductive_expr * Libnames.qualid list * Vernacexpr.decl_notation list
@@ -6117,6 +6136,7 @@ sig
?abstract:bool ->
?global:bool ->
?refine:bool ->
+ program_mode:bool ->
Decl_kinds.polymorphic ->
Constrexpr.local_binder_expr list ->
Vernacexpr.typeclass_constraint ->
diff --git a/CHANGES b/CHANGES
index b2b9da8ce..d6e92a9bf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,16 @@ Notations
opened rather than to the latest notations defined independently of
whether they are in an opened scope or not.
+Specification language
+
+- When printing clauses of a "match", clauses with same right-hand
+ side are factorized and the last most factorized clause with no
+ variables, if it exists, is turned into a default clause.
+ Use "Unset Printing Allow Default Clause" do deactivate printing
+ of a default clause.
+ Use "Unset Printing Factorizable Match Patterns" to deactivate
+ factorization of clauses with same right-hand side.
+
Tactics
- On Linux, "native_compute" calls can be profiled using the "perf"
@@ -42,6 +52,14 @@ Checker
- The checker now accepts filenames in addition to logical paths.
+Changes from 8.7.0 to 8.7.1
+===========================
+
+Compatibility with OCaml 4.06.0.
+
+Many bug fixes, documentation improvements, and user message improvements (for
+details see the 8.7.1 milestone at https://github.com/coq/coq/milestone/10?closed=1).
+
Changes from 8.7+beta2 to 8.7.0
===============================
diff --git a/META.coq b/META.coq
index 29bb13ea5..504a85ba6 100644
--- a/META.coq
+++ b/META.coq
@@ -233,7 +233,7 @@ package "API" (
description = "Coq API"
version = "8.7"
- requires = "coq.stm"
+ requires = "coq.intf, coq.stm"
directory = "API"
archive(byte) = "API.cma"
diff --git a/Makefile b/Makefile
index 620fec546..2637996ed 100644
--- a/Makefile
+++ b/Makefile
@@ -87,7 +87,7 @@ EXISTINGMLI := $(call find, '*.mli')
## Files that will be generated
GENML4FILES:= $(ML4FILES:.ml4=.ml)
-export GENMLFILES:=$(LEXFILES:.mll=.ml) tools/tolink.ml kernel/copcodes.ml
+export GENMLFILES:=$(LEXFILES:.mll=.ml) kernel/copcodes.ml
export GENHFILES:=kernel/byterun/coq_jumptbl.h
export GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES)
@@ -246,7 +246,7 @@ archclean: clean-ide optclean voclean
rm -f $(ALLSTDLIB).*
optclean:
- rm -f $(COQTOPEXE) $(COQMKTOP) $(CHICKEN)
+ rm -f $(COQTOPEXE) $(CHICKEN)
rm -f $(TOOLS) $(PRIVATEBINARIES) $(CSDPCERT)
find . -name '*.cmx' -o -name '*.cmx[as]' -o -name '*.[soa]' -o -name '*.so' | xargs rm -f
diff --git a/Makefile.build b/Makefile.build
index 867c494a1..cbc1cbaab 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -147,8 +147,14 @@ endif
# For creating the missing .d, make will recursively build things like
# coqdep_boot (for the .v.d files) or grammar.cma (for .ml4 -> .ml -> .ml.d).
+VDFILE := .vfiles
+MLDFILE := .mlfiles
+PLUGMLDFILE := plugins/.mlfiles
+MLLIBDFILE := .mllibfiles
+PLUGMLLIBDFILE := plugins/.mllibfiles
+
DEPENDENCIES := \
- $(addsuffix .d, $(MLFILES) $(MLIFILES) $(MLLIBFILES) $(MLPACKFILES) $(CFILES) $(VFILES))
+ $(addsuffix .d, $(MLDFILE) $(MLLIBDFILE) $(PLUGMLDFILE) $(PLUGMLLIBDFILE) $(CFILES) $(VDFILE))
-include $(DEPENDENCIES)
@@ -189,7 +195,7 @@ TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
COQOPTS=$(NATIVECOMPUTE)
BOOTCOQC=$(TIMER) $(COQTOPBEST) -boot $(COQOPTS) -compile
-LOCALINCLUDES=$(if $(filter plugins/%,$<),-I lib -I API -open API $(addprefix -I plugins/,$(PLUGINDIRS)),$(addprefix -I ,$(SRCDIRS)))
+LOCALINCLUDES=$(if $(filter plugins/%,$@),-I lib -I API -open API $(addprefix -I plugins/,$(PLUGINDIRS)),$(addprefix -I ,$(SRCDIRS)))
MLINCLUDES=$(LOCALINCLUDES) -I $(MYCAMLP4LIB)
OCAMLC := $(OCAMLFIND) ocamlc $(CAMLFLAGS)
@@ -197,7 +203,7 @@ OCAMLOPT := $(OCAMLFIND) opt $(CAMLFLAGS)
BYTEFLAGS=$(CAMLDEBUG) $(USERFLAGS)
OPTFLAGS=$(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS) $(FLAMBDA_FLAGS)
-DEPFLAGS=$(LOCALINCLUDES)$(if $(filter plugins/%,$<),, -I ide -I ide/utils)
+DEPFLAGS=$(LOCALINCLUDES)$(if $(filter plugins/%,$@),, -I ide -I ide/utils)
# On MacOS, the binaries are signed, except our private ones
ifeq ($(shell which codesign > /dev/null 2>&1 && echo $(ARCH)),Darwin)
@@ -228,8 +234,8 @@ endef
define bestocaml
$(if $(OPT),\
-$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ $(1) $(addsuffix .cmxa,$(2)) $^ && $(STRIP) $@ && $(CODESIGN) $@,\
-$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ $(1) $(addsuffix .cma,$(2)) $^)
+$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ -linkpkg $(1) $^ && $(STRIP) $@ && $(CODESIGN) $@,\
+$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^)
endef
# Camlp5 settings
@@ -239,9 +245,8 @@ CAMLP4USE=pa_extend.cmo q_MLast.cmo pa_macro.cmo -D$(CAMLVERSION)
PR_O := $(if $(READABLE_ML4),pr_o.cmo,pr_dump.cmo)
-SYSMOD:=str unix dynlink threads
-SYSCMA:=$(addsuffix .cma,$(SYSMOD))
-SYSCMXA:=$(addsuffix .cmxa,$(SYSMOD))
+# Main packages linked by Coq.
+SYSMOD:=-package num,str,unix,dynlink,threads
# We do not repeat the dependencies already in SYSMOD here
P4CMA:=gramlib.cma
@@ -370,19 +375,30 @@ grammar/%.cmi: grammar/%.mli
###########################################################################
-# Main targets (coqmktop, coqtop.opt, coqtop.byte)
+# Main targets (coqtop.opt, coqtop.byte)
###########################################################################
.PHONY: coqbinaries coqbyte
-coqbinaries: $(COQMKTOP) $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbinaries: $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
coqbyte: $(COQTOPBYTE) $(CHICKENBYTE)
+COQTOP_OPT_MLTOP=toplevel/coqtop_opt_bin.cmx
+COQTOP_BYTE_MLTOP=toplevel/coqtop_byte_bin.cmo
+
+$(COQTOP_BYTE_MLTOP): toplevel/coqtop_byte_bin.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -package compiler-libs.toplevel -c $<
+
ifeq ($(BEST),opt)
-$(COQTOPEXE): $(COQMKTOP) $(LINKCMX) $(LIBCOQRUN) $(TOPLOOPCMA:.cma=.cmxs)
+$(COQTOPEXE): $(LINKCMX) $(LIBCOQRUN) $(TOPLOOPCMA:.cma=.cmxs) $(COQTOP_OPT_MLTOP)
$(SHOW)'COQMKTOP -o $@'
- $(HIDE)$(COQMKTOP) -boot -opt $(OPTFLAGS) $(LINKMETADATA) -o $@
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg -I toplevel \
+ -I kernel/byterun/ -cclib -lcoqrun \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) \
+ $(COQTOP_OPT_MLTOP) toplevel/coqtop_bin.ml -o $@
$(STRIP) $@
$(CODESIGN) $@
else
@@ -390,23 +406,14 @@ $(COQTOPEXE): $(COQTOPBYTE)
cp $< $@
endif
-$(COQTOPBYTE): $(COQMKTOP) $(LINKCMO) $(LIBCOQRUN) $(TOPLOOPCMA)
+# Are "-cclib lcoqrun -dllib -lcoqrun" necessary?
+$(COQTOPBYTE): $(LINKCMO) $(LIBCOQRUN) $(TOPLOOPCMA) $(COQTOP_BYTE_MLTOP)
$(SHOW)'COQMKTOP -o $@'
- $(HIDE)$(COQMKTOP) -boot -top $(BYTEFLAGS) -o $@
-
-# coqmktop
-
-COQMKTOPCMO:=lib/clib.cma lib/cErrors.cmo tools/tolink.cmo tools/coqmktop.cmo
-
-$(COQMKTOP): $(call bestobj, $(COQMKTOPCMO))
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
-
-tools/tolink.ml: Makefile.build Makefile.common
- $(SHOW)"ECHO... >" $@
- $(HIDE)echo "let copts = \"-cclib -lcoqrun\"" > $@
- $(HIDE)echo "let core_libs = \""$(LINKCMO)"\"" >> $@
- $(HIDE)echo "let core_objs = \""$(OBJSMOD)"\"" >> $@
+ $(HIDE)$(OCAMLC) -linkall -linkpkg -I toplevel \
+ -I kernel/byterun -dllpath $(abspath kernel/byterun) -cclib -lcoqrun -dllib -lcoqrun \
+ $(SYSMOD) -package camlp5.gramlib,compiler-libs.toplevel \
+ $(LINKCMO) $(BYTEFLAGS) \
+ $(COQTOP_BYTE_MLTOP) toplevel/coqtop_bin.ml -o $@
# coqc
@@ -414,7 +421,7 @@ COQCCMO:=lib/clib.cma lib/cErrors.cmo toplevel/usage.cmo tools/coqc.cmo
$(COQC): $(call bestobj, $(COQCCMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
+ $(HIDE)$(call bestocaml, $(SYSMOD))
###########################################################################
# other tools
@@ -451,11 +458,11 @@ tools/coqdep_boot.cmx : tools/coqdep_common.cmx
$(COQDEPBOOT): $(call bestobj, $(COQDEPBOOTSRC))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I tools, unix)
+ $(HIDE)$(call bestocaml, -I tools -package unix)
$(OCAMLLIBDEP): $(call bestobj, tools/ocamllibdep.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I tools, unix)
+ $(HIDE)$(call bestocaml, -I tools -package unix)
# The full coqdep (unused by this build, but distributed by make install)
@@ -466,36 +473,36 @@ COQDEPCMO:=lib/clib.cma lib/cErrors.cmo lib/cWarnings.cmo \
$(COQDEP): $(call bestobj, $(COQDEPCMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
+ $(HIDE)$(call bestocaml, $(SYSMOD))
$(GALLINA): $(call bestobj, tools/gallina_lexer.cmo tools/gallina.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,)
+ $(HIDE)$(call bestocaml,)
COQMAKEFILECMO:=lib/clib.cma tools/coq_makefile.cmo
$(COQMAKEFILE): $(call bestobj,$(COQMAKEFILECMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str unix threads)
+ $(HIDE)$(call bestocaml, -package str,unix,threads)
$(COQTEX): $(call bestobj, tools/coq_tex.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str)
+ $(HIDE)$(call bestocaml, -package str)
$(COQWC): $(call bestobj, tools/coqwc.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,)
+ $(HIDE)$(call bestocaml, -package str)
COQDOCCMO:=lib/clib.cma $(addprefix tools/coqdoc/, \
cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
$(COQDOC): $(call bestobj, $(COQDOCCMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str unix)
+ $(HIDE)$(call bestocaml, -package str,unix)
-$(COQWORKMGR): $(call bestobj, lib/clib.cma stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo)
+$(COQWORKMGR): $(call bestobj, lib/clib.cma lib/lib.cma stm/spawned.cmo stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,, $(SYSMOD))
+ $(HIDE)$(call bestocaml, $(SYSMOD))
# fake_ide : for debugging or test-suite purpose, a fake ide simulating
# a connection to coqtop -ideslave
@@ -506,13 +513,13 @@ FAKEIDECMO:= lib/clib.cma lib/cErrors.cmo lib/spawn.cmo ide/document.cmo \
$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOPLOOPCMA:.cma=$(BESTDYN))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,-I ide,str unix threads)
+ $(HIDE)$(call bestocaml, -I ide -package str,unix,threads)
# votour: a small vo explorer (based on the checker)
bin/votour: $(call bestobj, lib/cObj.cmo checker/analyze.cmo checker/values.cmo checker/votour.cmo)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I checker,)
+ $(HIDE)$(call bestocaml, -I checker)
###########################################################################
# Csdp to micromega special targets
@@ -524,7 +531,7 @@ CSDPCERTCMO:=lib/clib.cma $(addprefix plugins/micromega/, \
$(CSDPCERT): $(call bestobj, $(CSDPCERTCMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,nums unix)
+ $(HIDE)$(call bestocaml, -package num,unix)
###########################################################################
# tests
@@ -670,21 +677,24 @@ plugins/%.cmx: plugins/%.ml
# Ocamldep is now used directly again (thanks to -ml-synonym in OCaml >= 3.12)
OCAMLDEP = $(OCAMLFIND) ocamldep -slash -ml-synonym .ml4 -ml-synonym .mlpack
-%.ml.d: $(D_DEPEND_BEFORE_SRC) %.ml $(D_DEPEND_AFTER_SRC) $(GENFILES)
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP) $(DEPFLAGS) "$<" $(TOTARGET)
+MAINMLFILES := $(filter-out checker/% plugins/%, $(MLFILES) $(MLIFILES))
+MAINMLLIBFILES := $(filter-out checker/% plugins/%, $(MLLIBFILES) $(MLPACKFILES))
+
+$(MLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLFILES) $(D_DEPEND_AFTER_SRC) $(GENFILES)
+ $(SHOW)'OCAMLDEP MLFILES MLIFILES'
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) $(MAINMLFILES) $(TOTARGET)
-%.mli.d: $(D_DEPEND_BEFORE_SRC) %.mli $(D_DEPEND_AFTER_SRC) $(GENFILES)
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP) $(DEPFLAGS) "$<" $(TOTARGET)
+$(MLLIBDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLLIBFILES) $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP MLLIBFILES MLPACKFILES'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) $(MAINMLLIBFILES) $(TOTARGET)
-%.mllib.d: $(D_DEPEND_BEFORE_SRC) %.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
- $(SHOW)'OCAMLLIBDEP $<'
- $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) "$<" $(TOTARGET)
+$(PLUGMLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(filter plugins/%, $(MLFILES) $(MLIFILES)) $(D_DEPEND_AFTER_SRC) $(GENFILES)
+ $(SHOW)'OCAMLDEP plugins/MLFILES plugins/MLIFILES'
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) $(filter plugins/%, $(MLFILES) $(MLIFILES)) $(TOTARGET)
-%.mlpack.d: $(D_DEPEND_BEFORE_SRC) %.mlpack $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
- $(SHOW)'OCAMLLIBDEP $<'
- $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) "$<" $(TOTARGET)
+$(PLUGMLLIBDFILE).d: $(D_DEPEND_BEFORE_SRC) $(filter plugins/%, $(MLLIBFILES) $(MLPACKFILES)) $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP plugins/MLLIBFILES plugins/MLPACKFILES'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) $(filter plugins/%, $(MLLIBFILES) $(MLPACKFILES)) $(TOTARGET)
###########################################################################
# Compilation of .v files
@@ -756,9 +766,9 @@ endif
# Dependencies of .v files
-%.v.d: $(D_DEPEND_BEFORE_SRC) %.v $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT)
- $(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEPBOOT) -boot $(DYNDEP) "$<" $(TOTARGET)
+$(VDFILE).d: $(D_DEPEND_BEFORE_SRC) $(VFILES) $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT)
+ $(SHOW)'COQDEP VFILES'
+ $(HIDE)$(COQDEPBOOT) -boot $(DYNDEP) $(VFILES) $(TOTARGET)
###########################################################################
diff --git a/Makefile.checker b/Makefile.checker
index f9ed2d957..7e0f58875 100644
--- a/Makefile.checker
+++ b/Makefile.checker
@@ -26,10 +26,16 @@ CHKLIBS:= -I config -I lib -I checker
# The rules
+CHECKMLDFILE := checker/.mlfiles
+CHECKMLLIBFILE := checker/.mllibfiles
+
+CHECKERDEPS := $(addsuffix .d, $(CHECKMLDFILE) $(CHECKMLLIBFILE))
+-include $(CHECKERDEPS)
+
ifeq ($(BEST),opt)
$(CHICKEN): checker/check.cmxa checker/main.ml
$(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(SYSCMXA) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -o $@ $^
+ $(HIDE)$(OCAMLOPT) -linkpkg $(SYSMOD) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -o $@ $^
$(STRIP) $@
$(CODESIGN) $@
else
@@ -39,7 +45,7 @@ endif
$(CHICKENBYTE): checker/check.cma checker/main.ml
$(SHOW)'OCAMLC -o $@'
- $(HIDE)$(OCAMLC) $(SYSCMA) $(CHKLIBS) $(BYTEFLAGS) $(CUSTOM) -o $@ $^
+ $(HIDE)$(OCAMLC) -linkpkg $(SYSMOD) $(CHKLIBS) $(BYTEFLAGS) $(CUSTOM) -o $@ $^
checker/check.cma: checker/check.mllib | md5chk
$(SHOW)'OCAMLC -a -o $@'
@@ -49,17 +55,13 @@ checker/check.cmxa: checker/check.mllib | md5chk
$(SHOW)'OCAMLOPT -a -o $@'
$(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) -a -o $@ $(filter-out %.mllib, $^)
-checker/%.ml.d: checker/%.ml
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) "$<" $(TOTARGET)
-
-checker/%.mli.d: checker/%.mli
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) "$<" $(TOTARGET)
+$(CHECKMLDFILE).d: $(filter checker/%, $(MLFILES) $(MLIFILES))
+ $(SHOW)'OCAMLDEP checker/MLFILES checker/MLIFILES'
+ $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) $(filter checker/%, $(MLFILES) $(MLIFILES)) $(TOTARGET)
-checker/%.mllib.d: checker/%.mllib | $(OCAMLLIBDEP)
- $(SHOW)'OCAMLLIBDEP $<'
- $(HIDE)$(OCAMLLIBDEP) $(CHKLIBS) "$<" $(TOTARGET)
+$(CHECKMLLIBFILE).d: $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES)) | $(OCAMLLIBDEP)
+ $(SHOW)'OCAMLLIBDEP checker/MLLIBFILES checker/MLPACKFILES'
+ $(HIDE)$(OCAMLLIBDEP) $(CHKLIBS) $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES)) $(TOTARGET)
checker/%.cmi: checker/%.mli
$(SHOW)'OCAMLC $<'
diff --git a/Makefile.common b/Makefile.common
index 4d63b08e2..f436d3e8f 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -12,8 +12,6 @@
# Executables
###########################################################################
-COQMKTOP:=bin/coqmktop$(EXE)
-
COQTOPBYTE:=bin/coqtop.byte$(EXE)
COQTOPEXE:=bin/coqtop$(EXE)
diff --git a/Makefile.install b/Makefile.install
index 27694106f..84aa11a5e 100644
--- a/Makefile.install
+++ b/Makefile.install
@@ -105,7 +105,6 @@ INSTALLCMX = $(sort $(filter-out checker/% ide/% tools/% dev/% configure.cmx, $(
install-devfiles:
$(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQMKTOP) $(FULLBINDIR)
$(MKDIR) $(FULLCOQLIB)
$(INSTALLSH) $(FULLCOQLIB) $(GRAMMARCMA)
$(INSTALLSH) $(FULLCOQLIB) $(INSTALLCMI)
@@ -140,7 +139,7 @@ install-coq-info: install-coq-manpages install-emacs install-latex
MANPAGES:=man/coq-tex.1 man/coqdep.1 man/gallina.1 \
man/coqc.1 man/coqtop.1 man/coqtop.byte.1 man/coqtop.opt.1 \
man/coqwc.1 man/coqdoc.1 man/coqide.1 \
- man/coq_makefile.1 man/coqmktop.1 man/coqchk.1
+ man/coq_makefile.1 man/coqchk.1
install-coq-manpages:
$(MKDIR) $(FULLMANDIR)/man1
diff --git a/checker/inductive.ml b/checker/inductive.ml
index 1271a02b0..22353ec16 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -1070,8 +1070,8 @@ let check_fix env ((nvect,_),(names,_,bodies as _recdef) as fix) =
done
(*
-let cfkey = Profile.declare_profile "check_fix";;
-let check_fix env fix = Profile.profile3 cfkey check_fix env fix;;
+let cfkey = CProfile.declare_profile "check_fix";;
+let check_fix env fix = CProfile.profile3 cfkey check_fix env fix;;
*)
(************************************************************************)
diff --git a/config/coq_config.mli b/config/coq_config.mli
index 6a834a304..1666df0bd 100644
--- a/config/coq_config.mli
+++ b/config/coq_config.mli
@@ -41,12 +41,8 @@ val caml_flags : string (* arguments passed to ocamlc (ie. CAMLFLAGS) *)
val best : string (* byte/opt *)
val arch : string (* architecture *)
val arch_is_win32 : bool
-val osdeplibs : string (* OS dependent link options for ocamlc *)
val vmbyteflags : string list (* -custom/-dllib -lcoqrun *)
-
-(* val defined : string list (* options for lib/ocamlpp *) *)
-
val version : string (* version number of Coq *)
val caml_version : string (* OCaml version used to compile Coq *)
val caml_version_nums : int list (* OCaml version used to compile Coq by components *)
@@ -80,4 +76,5 @@ val wwwbugtracker : string
val wwwstdlib : string
val localwwwrefman : string
-val no_native_compiler : bool
+val bytecode_compiler : bool
+val native_compiler : bool
diff --git a/configure.ml b/configure.ml
index c7d25bfc8..06aa5e766 100644
--- a/configure.ml
+++ b/configure.ml
@@ -16,7 +16,7 @@ let coq_macos_version = "8.7.90" (** "[...] should be a string comprised of
three non-negative, period-separated integers [...]" *)
let vo_magic = 8791
let state_magic = 58791
-let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqmktop";"coqworkmgr";
+let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqworkmgr";
"coqdoc";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
let verbose = ref false (* for debugging this script *)
@@ -178,6 +178,20 @@ let which prog =
let program_in_path prog =
try let _ = which prog in true with Not_found -> false
+(** Choose a command among a list of candidates
+ (command name, mandatory arguments, arguments for this test).
+ Chooses the first one whose execution outputs a non-empty (first) line.
+ Dies with message [msg] if none is found. *)
+
+let select_command msg candidates =
+ let rec search = function
+ | [] -> die msg
+ | (p, x, y) :: tl ->
+ if fst (tryrun p (x @ y)) <> ""
+ then List.fold_left (Printf.sprintf "%s %s") p x
+ else search tl
+ in search candidates
+
(** As per bug #4828, ocamlfind on Windows/Cygwin barfs if you pass it
a quoted path to camlpXo via -pp. So we only quote camlpXo on not
Windows, and warn on Windows if the path contains spaces *)
@@ -263,6 +277,7 @@ module Prefs = struct
let debug = ref true
let profile = ref false
let annotate = ref false
+ let bytecodecompiler = ref true
let nativecompiler = ref (not (os_type_win32 || os_type_cygwin))
let coqwebsite = ref "http://coq.inria.fr/"
let force_caml_version = ref false
@@ -329,6 +344,8 @@ let args_options = Arg.align [
" Add profiling information in the Coq executables";
"-annotate", Arg.Set Prefs.annotate,
" Dumps ml annotation files while compiling Coq";
+ "-bytecode-compiler", arg_bool Prefs.bytecodecompiler,
+ "(yes|no) Enable Coq's bytecode reduction machine (VM)";
"-native-compiler", arg_bool Prefs.nativecompiler,
"(yes|no) Compilation to native code for conversion and normalization";
"-coqwebsite", Arg.Set_string Prefs.coqwebsite,
@@ -666,17 +683,15 @@ let natdynlinkflag =
(** * OS dependent libraries *)
-let osdeplibs = "-cclib -lunix"
-
-let operating_system, osdeplibs =
+let operating_system =
if starts_with arch "sun4" then
let os, _ = run "uname" ["-r"] in
if starts_with os "5" then
- "Sun Solaris "^os, osdeplibs^" -cclib -lnsl -cclib -lsocket"
+ "Sun Solaris "^os
else
- "Sun OS "^os, osdeplibs
+ "Sun OS "^os
else
- (try Sys.getenv "OS" with Not_found -> ""), osdeplibs
+ (try Sys.getenv "OS" with Not_found -> "")
(** Num library *)
@@ -853,9 +868,10 @@ let strip =
(** * md5sum command *)
let md5sum =
- if List.mem arch ["Darwin"; "FreeBSD"; "OpenBSD"]
- then "md5 -q" else "md5sum"
-
+ select_command "Don’t know how to compute MD5 checksums…" [
+ "md5sum", [], [ "--version" ];
+ "md5", ["-q"], [ "-s" ; "''" ];
+ ]
(** * Documentation : do we have latex, hevea, ... *)
@@ -1001,7 +1017,6 @@ let print_summary () =
pr " Operating system : %s\n" operating_system;
pr " Coq VM bytecode link flags : %s\n" (String.concat " " vmbyteflags);
pr " Other bytecode link flags : %s\n" custom_flag;
- pr " OS dependent libraries : %s\n" osdeplibs;
pr " OCaml version : %s\n" caml_version;
pr " OCaml binaries in : %s\n" (esc camlbin);
pr " OCaml library in : %s\n" (esc camllib);
@@ -1019,9 +1034,9 @@ let print_summary () =
pr " Documentation : %s\n"
(if withdoc then "All" else "None");
pr " Web browser : %s\n" browser;
- pr " Coq web site : %s\n\n" !Prefs.coqwebsite;
- if not !Prefs.nativecompiler then
- pr " Native compiler for conversion and normalization disabled\n\n";
+ pr " Coq web site : %s\n" !Prefs.coqwebsite;
+ pr " Bytecode VM enabled : %B\n" !Prefs.bytecodecompiler;
+ pr " Native Compiler enabled : %B\n\n" !Prefs.nativecompiler;
if !Prefs.local then
pr " Local build, no installation...\n"
else
@@ -1094,7 +1109,6 @@ let write_configml f =
pr_s "cflags" cflags;
pr_s "caml_flags" caml_flags;
pr_s "best" best_compiler;
- pr_s "osdeplibs" osdeplibs;
pr_s "version" coq_version;
pr_s "caml_version" caml_version;
pr_li "caml_version_nums" caml_version_nums;
@@ -1117,7 +1131,8 @@ let write_configml f =
pr_s "wwwrefman" (!Prefs.coqwebsite ^ "distrib/" ^ coq_version ^ "/refman/");
pr_s "wwwstdlib" (!Prefs.coqwebsite ^ "distrib/" ^ coq_version ^ "/stdlib/");
pr_s "localwwwrefman" ("file:/" ^ docdir ^ "/html/refman");
- pr_b "no_native_compiler" (not !Prefs.nativecompiler);
+ pr_b "bytecode_compiler" !Prefs.bytecodecompiler;
+ pr_b "native_compiler" !Prefs.nativecompiler;
let core_src_dirs = [ "config"; "dev"; "kernel"; "library";
"engine"; "pretyping"; "interp"; "parsing"; "proofs";
@@ -1225,7 +1240,6 @@ let write_makefile f =
pr "# Supplementary libs for some systems, currently:\n";
pr "# . Sun Solaris: -cclib -lunix -cclib -lnsl -cclib -lsocket\n";
pr "# . others : -cclib -lunix\n";
- pr "OSDEPLIBS=%s\n\n" osdeplibs;
pr "# executable files extension, currently:\n";
pr "# Unix systems:\n";
pr "# Win32 systems : .exe\n";
diff --git a/dev/base_include b/dev/base_include
index 1da5e3ed1..d7059fe74 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -170,7 +170,7 @@ open Eqschemes
open ExplainErr
open Class
-open Command
+open ComDefinition
open Indschemes
open Ind_tables
open Auto_ind_decl
diff --git a/dev/build/windows/ReadMe.txt b/dev/build/windows/ReadMe.txt
index a6d8e4462..7e80e33c6 100644
--- a/dev/build/windows/ReadMe.txt
+++ b/dev/build/windows/ReadMe.txt
@@ -418,7 +418,6 @@ Binary file ./bin/coqchk.exe matches
Binary file ./bin/coqdep.exe matches
Binary file ./bin/coqdoc.exe matches
Binary file ./bin/coqide.exe matches
-Binary file ./bin/coqmktop.exe matches
Binary file ./bin/coqtop.byte.exe matches
Binary file ./bin/coqtop.exe matches
Binary file ./bin/coqworkmgr.exe matches
@@ -438,7 +437,6 @@ Binary file ./bin/ocamldoc.exe matches
Binary file ./bin/ocamldoc.opt.exe matches
Binary file ./bin/ocamlfind.exe matches
Binary file ./bin/ocamlmklib.exe matches
-Binary file ./bin/ocamlmktop.exe matches
Binary file ./bin/ocamlobjinfo.exe matches
Binary file ./bin/ocamlopt.exe matches
Binary file ./bin/ocamlopt.opt.exe matches
diff --git a/dev/ci/ci-compcert.sh b/dev/ci/ci-compcert.sh
index 7bf2c7427..fc3cef342 100755
--- a/dev/ci/ci-compcert.sh
+++ b/dev/ci/ci-compcert.sh
@@ -8,5 +8,4 @@ CompCert_CI_DIR=${CI_BUILD_DIR}/CompCert
opam install -j ${NJOBS} -y menhir
git_checkout ${CompCert_CI_BRANCH} ${CompCert_CI_GITURL} ${CompCert_CI_DIR}
-#( cd ${CompCert_CI_DIR} && ./configure -ignore-coq-version x86_32-linux && make && make check-proof )
-( cd ${CompCert_CI_DIR} && ./configure -ignore-coq-version x86_32-linux && make )
+( cd ${CompCert_CI_DIR} && ./configure -ignore-coq-version x86_32-linux && make && make check-proof )
diff --git a/dev/ci/user-overlays/06169-Zimmi48-clean-up-deprecated-options.sh b/dev/ci/user-overlays/06169-Zimmi48-clean-up-deprecated-options.sh
new file mode 100644
index 000000000..6741cf26f
--- /dev/null
+++ b/dev/ci/user-overlays/06169-Zimmi48-clean-up-deprecated-options.sh
@@ -0,0 +1,4 @@
+if [ "$TRAVIS_PULL_REQUEST" = "6169" ] || [ "$TRAVIS_BRANCH" = "clean-up/deprecated-options" ]; then
+ ltac2_CI_BRANCH=master
+ ltac2_CI_GITURL=https://github.com/Zimmi48/ltac2
+fi
diff --git a/dev/ci/user-overlays/06217-coqdep-at-once.sh b/dev/ci/user-overlays/06217-coqdep-at-once.sh
new file mode 100644
index 000000000..68e1901f7
--- /dev/null
+++ b/dev/ci/user-overlays/06217-coqdep-at-once.sh
@@ -0,0 +1,3 @@
+if [ "$TRAVIS_PULL_REQUEST" = "6217" ] || [ "$TRAVIS_BRANCH" = "coqdep-at-once" ]; then
+ UniMath_CI_GITURL=https://github.com/SkySkimmer/UniMath.git
+fi
diff --git a/dev/ci/user-overlays/06392-ejgallego-econstr+fix_class.sh b/dev/ci/user-overlays/06392-ejgallego-econstr+fix_class.sh
new file mode 100644
index 000000000..c0dcf79e1
--- /dev/null
+++ b/dev/ci/user-overlays/06392-ejgallego-econstr+fix_class.sh
@@ -0,0 +1,4 @@
+if [ "$TRAVIS_PULL_REQUEST" = "6392" ] || [ "$TRAVIS_BRANCH" = "econstr+fix_class" ]; then
+ Equations_CI_BRANCH=econstr+fix_class
+ Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations.git
+fi
diff --git a/dev/ci/user-overlays/06413-ejgallego-interp+less_impstyle_p2.sh b/dev/ci/user-overlays/06413-ejgallego-interp+less_impstyle_p2.sh
new file mode 100644
index 000000000..8aea7dee3
--- /dev/null
+++ b/dev/ci/user-overlays/06413-ejgallego-interp+less_impstyle_p2.sh
@@ -0,0 +1,4 @@
+if [ "$TRAVIS_PULL_REQUEST" = "6413" ] || [ "$TRAVIS_BRANCH" = "interp+less_impstyle_p2" ]; then
+ Equations_CI_BRANCH=interp+less_impstyle_p2
+ Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations.git
+fi
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index c69be4f4d..01aa6b599 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -46,6 +46,11 @@ We changed the type of the following functions:
- `Global.body_of_constant`: same as above.
+- `Constrinterp.*` generally, many functions that used to take an
+ `evar_map ref` have been now switched to functions that will work in
+ a functional way. The old style of passing `evar_map`s as references
+ is not supported anymore.
+
We have changed the representation of the following types:
- `Lib.object_prefix` is now a record instead of a nested tuple.
diff --git a/dev/doc/debugging.md b/dev/doc/debugging.md
index 7d3d811cc..fa145d498 100644
--- a/dev/doc/debugging.md
+++ b/dev/doc/debugging.md
@@ -73,8 +73,8 @@ Per function profiling
To profile function foo in file bar.ml, add the following lines, just
after the definition of the function:
- let fookey = Profile.declare_profile "foo";;
- let foo a b c = Profile.profile3 fookey foo a b c;;
+ let fookey = CProfile.declare_profile "foo";;
+ let foo a b c = CProfile.profile3 fookey foo a b c;;
where foo is assumed to have three arguments (adapt using
Profile.profile1, Profile. profile2, etc).
diff --git a/dev/doc/setup.txt b/dev/doc/setup.txt
index 0c6d3ee80..26f3d0ddc 100644
--- a/dev/doc/setup.txt
+++ b/dev/doc/setup.txt
@@ -279,7 +279,7 @@ You can load them by switching to the window holding the "ocamldebug" shell and
Some of the functions were you might want to set a breakpoint and see what happens next
---------------------------------------------------------------------------------------
-- Coqtop.start : This function is called by the code produced by "coqmktop".
+- Coqtop.start : This function is the main entry point of coqtop.
- Coqtop.parse_args : This function is responsible for parsing command-line arguments.
- Coqloop.loop : This function implements the read-eval-print loop.
- Vernacentries.interp : This function is called to execute the Vernacular command user have typed.\
diff --git a/doc/refman/Cases.tex b/doc/refman/Cases.tex
index 7ad895f9d..376ef031d 100644
--- a/doc/refman/Cases.tex
+++ b/doc/refman/Cases.tex
@@ -280,6 +280,18 @@ Fail Check
end).
\end{coq_example}
+The option {\tt Set Asymmetric Patterns} \optindex{Asymmetric Patterns}
+(off by default) removes parameters from constructors in patterns:
+\begin{coq_example}
+ Set Asymmetric Patterns.
+ Check (fun l:List nat =>
+ match l with
+ | nil => nil
+ | cons _ l' => l'
+ end)
+ Unset Asymmetric Patterns.
+\end{coq_example}
+
\paragraph{Implicit arguments in patterns}
By default, implicit arguments are omitted in patterns. So we write:
diff --git a/doc/refman/Classes.tex b/doc/refman/Classes.tex
index cab673999..6e76d04e7 100644
--- a/doc/refman/Classes.tex
+++ b/doc/refman/Classes.tex
@@ -526,14 +526,14 @@ potentially more expensive proof-search (i.e. more useless
backtracking).
\subsection{\tt Set Typeclass Resolution After Apply}
-\optindex{Typeclasses Resolution After Apply}
+\optindex{Typeclass Resolution After Apply}
\emph{Deprecated since 8.6}
This option (off by default in Coq 8.6 and 8.5) controls the resolution
of typeclass subgoals generated by the {\tt apply} tactic.
\subsection{\tt Set Typeclass Resolution For Conversion}
-\optindex{Typeclasses Resolution For Conversion}
+\optindex{Typeclass Resolution For Conversion}
This option (on by default) controls the use of typeclass resolution
when a unification problem cannot be solved during
diff --git a/doc/refman/Omega.tex b/doc/refman/Omega.tex
index 8025fbe29..82765da6e 100644
--- a/doc/refman/Omega.tex
+++ b/doc/refman/Omega.tex
@@ -149,6 +149,32 @@ intro; omega.
% Other examples can be found in \verb+$COQLIB/theories/DEMOS/OMEGA+.
+\section{Options}
+
+\begin{quote}
+ \optindex{Stable Omega}
+ {\tt Unset Stable Omega}
+\end{quote}
+This deprecated option (on by default) is for compatibility with Coq
+pre 8.5. It resets internal name counters to make executions of
+{\tt omega} independent.
+
+\begin{quote}
+ \optindex{Omega UseLocalDefs}
+ {\tt Unset Omega UseLocalDefs}
+\end{quote}
+This option (on by default) allows {\tt omega} to use the bodies of
+local variables.
+
+\begin{quote}
+ \optindex{Omega System}
+ {\tt Set Omega System}
+ \optindex{Omega Action}
+ {\tt Set Omega Action}
+\end{quote}
+These two options (off by default) activate the printing of debug
+information.
+
\asection{Technical data}
\label{technical}
diff --git a/doc/refman/RefMan-ext.tex b/doc/refman/RefMan-ext.tex
index 5c519e46e..a1950d136 100644
--- a/doc/refman/RefMan-ext.tex
+++ b/doc/refman/RefMan-ext.tex
@@ -550,6 +550,60 @@ the same way as the {\Coq} kernel handles them.
This tells if the printing matching mode is on or off. The default is
on.
+\subsubsection{Factorization of clauses with same right-hand side}
+\label{SetPrintingFactorizableMatchPatterns}
+\optindex{Printing Factorizable Match Patterns}
+
+When several patterns share the same right-hand side, it is
+additionally possible to share the clauses using disjunctive patterns.
+Assuming that the printing matching mode is on, whether {\Coq}'s
+printer shall try to do this kind of factorization is governed by the
+following commands:
+
+\begin{quote}
+{\tt Set Printing Factorizable Match Patterns.}
+\end{quote}
+This tells {\Coq}'s printer to try to use disjunctive patterns. This is the default
+behavior.
+
+\begin{quote}
+{\tt Unset Printing Factorizable Match Patterns.}
+\end{quote}
+This tells {\Coq}'s printer not to try to use disjunctive patterns.
+
+\begin{quote}
+{\tt Test Printing Factorizable Match Patterns.}
+\end{quote}
+This tells if the factorization of clauses with same right-hand side is
+on or off.
+
+\subsubsection{Use of a default clause}
+\label{SetPrintingAllowDefaultClause}
+\optindex{Printing Allow Default Clause}
+
+When several patterns share the same right-hand side which do not
+depend on the arguments of the patterns, yet an extra factorization is
+possible: the disjunction of patterns can be replaced with a ``{\tt
+ \_}'' default clause. Assuming that the printing matching mode and
+the factorization mode are on, whether {\Coq}'s printer shall try to
+use a default clause is governed by the following commands:
+
+\begin{quote}
+{\tt Set Printing Allow Default Clause.}
+\end{quote}
+This tells {\Coq}'s printer to use a default clause when relevant. This is the default
+behavior.
+
+\begin{quote}
+{\tt Unset Printing Allow Default Clause.}
+\end{quote}
+This tells {\Coq}'s printer not to use a default clause.
+
+\begin{quote}
+{\tt Test Printing Allow Default Clause.}
+\end{quote}
+This tells if the use of a default clause is allowed.
+
\subsubsection{Printing of wildcard pattern
\optindex{Printing Wildcard}}
diff --git a/doc/refman/RefMan-ltac.tex b/doc/refman/RefMan-ltac.tex
index 7034c5608..8d82460a7 100644
--- a/doc/refman/RefMan-ltac.tex
+++ b/doc/refman/RefMan-ltac.tex
@@ -198,8 +198,6 @@ is understood as
{\cpattern} {\tt =>} {\tacexpr}\\
& $|$ & {\tt context} {\zeroone{\ident}} {\tt [} {\cpattern} {\tt ]}
{\tt =>} {\tacexpr}\\
-& $|$ & {\tt appcontext} {\zeroone{\ident}} {\tt [} {\cpattern} {\tt ]}
- {\tt =>} {\tacexpr}\\
& $|$ & {\tt \_ =>} {\tacexpr}\\
\\
{\it test} & ::= &
@@ -876,21 +874,6 @@ Goal True.
f (3+4).
\end{coq_example}
-\item \index{appcontext@\texttt{appcontext}!in pattern}
- \optindex{Tactic Compat Context}
-For historical reasons, {\tt context} used to consider $n$-ary applications
-such as {\tt (f 1 2)} as a whole, and not as a sequence of unary
-applications {\tt ((f 1) 2)}. Hence {\tt context [f ?x]} would fail
-to find a matching subterm in {\tt (f 1 2)}: if the pattern was a partial
-application, the matched subterms would have necessarily been
-applications with exactly the same number of arguments.
-As a workaround, one could use the following variant of {\tt context}:
-\begin{quote}
-{\tt appcontext} {\ident} {\tt [} {\cpattern} {\tt ]}
-\end{quote}
-This syntax is now deprecated, as {\tt context} behaves as intended. The former
-behavior can be retrieved with the {\tt Tactic Compat Context} flag.
-
\end{Variants}
\subsubsection[Pattern matching on goals]{Pattern matching on goals\index{Ltac!match goal@\texttt{match goal}}\label{ltac-match-goal}
diff --git a/doc/refman/RefMan-mod.tex b/doc/refman/RefMan-mod.tex
index e56c8fa7f..b4e270e6c 100644
--- a/doc/refman/RefMan-mod.tex
+++ b/doc/refman/RefMan-mod.tex
@@ -403,10 +403,14 @@ Fail Check B.T.
\end{Warnings}
\subsection{\tt Print Module {\ident}
-\comindex{Print Module}}
+\comindex{Print Module} \optindex{Short Module Printing}}
Prints the module type and (optionally) the body of the module {\ident}.
+For this command and {\tt Print Module Type}, the option {\tt Short
+ Module Printing} (off by default) disables the printing of the types of fields,
+leaving only their names.
+
\subsection{\tt Print Module Type {\ident}
\comindex{Print Module Type}}
diff --git a/doc/refman/RefMan-pro.tex b/doc/refman/RefMan-pro.tex
index 8f659ded3..1d3311edc 100644
--- a/doc/refman/RefMan-pro.tex
+++ b/doc/refman/RefMan-pro.tex
@@ -395,6 +395,8 @@ Proof.
\end{ErrMsgs}
+\subsection[\tt Set Bullet Behavior.]{\tt Set Bullet Behavior.\optindex{Bullet Behavior}}
+
The bullet behavior can be controlled by the following commands.
\begin{quote}
diff --git a/doc/refman/RefMan-sch.tex b/doc/refman/RefMan-sch.tex
index 956f30851..30724759d 100644
--- a/doc/refman/RefMan-sch.tex
+++ b/doc/refman/RefMan-sch.tex
@@ -127,8 +127,10 @@ conclusion is {\tt (n:nat)(even n)->(Q n)}.
\optindex{Boolean Equality Schemes}
\optindex{Elimination Schemes}
\optindex{Nonrecursive Elimination Schemes}
+\optindex{Record Elimination Schemes}
\optindex{Case Analysis Schemes}
\optindex{Decidable Equality Schemes}
+\optindex{Rewriting Schemes}
\label{set-nonrecursive-elimination-schemes}
}
@@ -142,6 +144,7 @@ and {\tt Record} (see~\ref{Record}) do not have an automatic
declaration of the induction principles. It can be activated with the
command {\tt Set Nonrecursive Elimination Schemes}. It can be
deactivated again with {\tt Unset Nonrecursive Elimination Schemes}.
+{\tt Record Elimination Schemes} is a deprecated alias of {\tt Nonrecursive Elimination Schemes}.
In addition, the {\tt Case Analysis Schemes} flag governs the generation of
case analysis lemmas for inductive types, i.e. corresponding to the
@@ -156,6 +159,9 @@ However you have to be careful with this option since
\Coq~ may now reject well-defined inductive types because it cannot compute
a Boolean equality for them.
+The {\tt Rewriting Schemes} flag governs generation of equality
+related schemes such as congruence.
+
\subsection{\tt Combined Scheme}
\label{CombinedScheme}
\comindex{Combined Scheme}
diff --git a/doc/refman/RefMan-ssr.tex b/doc/refman/RefMan-ssr.tex
index be199e0b2..31dabcdd4 100644
--- a/doc/refman/RefMan-ssr.tex
+++ b/doc/refman/RefMan-ssr.tex
@@ -3096,10 +3096,10 @@ the tactic \ssrC{rewrite (=~ multi1)} is equivalent to
\end{lstlisting}
except that the constants \ssrC{eqba, eqab, mult1_rev} have not been created.
-Rewriting with multirules
-is useful to implement simplification or transformation
-procedures, to be applied on terms of small to medium size. For
-instance the library \ssrL{ssrnat} provides two implementations for
+Rewriting with multirules is useful to implement simplification or
+transformation procedures, to be applied on terms of small to medium
+size. For instance, the library \ssrL{ssrnat} --- available in the
+external math-comp library --- provides two implementations for
arithmetic operations on natural numbers: an elementary one and a tail
recursive version, less inefficient but also less convenient for
reasoning purposes. The library also provides one lemma per such
diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex
index 675c2bf17..66a5f107a 100644
--- a/doc/refman/RefMan-tac.tex
+++ b/doc/refman/RefMan-tac.tex
@@ -3334,6 +3334,14 @@ evaluating purely computational expressions (i.e. with little dead code).
\end{Variants}
+\Rem The following option makes {\tt cbv} (and its derivative {\tt
+ compute}) print information about the constants it encounters and
+the unfolding decisions it makes.
+\begin{quote}
+ \optindex{Debug Cbv}
+ {\tt Set Debug Cbv}
+\end{quote}
+
% Obsolete? Anyway not very important message
%\begin{ErrMsgs}
%\item \errindex{Delta must be specified before}
@@ -3507,6 +3515,13 @@ of {\tt cbn} while doing reductions in unification, type inference and
tactic applications. It can result in expensive unifications, as
refolding currently uses a potentially exponential heuristic.
+\begin{quote}
+ \optindex{Debug RAKAM}
+ {\tt Set Debug RAKAM}
+\end{quote}
+This option makes {\tt cbn} print various debugging information.
+{\tt RAKAM} is the Refolding Algebraic Krivine Abstract Machine.
+
\subsection{\tt unfold \qualid}
\tacindex{unfold}
\label{unfold}
@@ -3703,6 +3718,9 @@ hints of the database named {\tt core}.
This variant is very useful for getting a better understanding of automation,
or to know what lemmas/assumptions were used.
+\item {\tt debug auto} Behaves like {\tt auto} but shows the tactics
+ it tries to solve the goal, including failing paths.
+
\item {\tt \zeroone{info\_}auto \zeroone{\num}} \zeroone{{\tt using} \nterm{lemma}$_1$
{\tt ,} {\ldots} {\tt ,} \nterm{lemma}$_n$} \zeroone{{\tt with}
\ident$_1$ {\ldots} \ident$_n$}
@@ -3723,6 +3741,8 @@ hints of the database named {\tt core}.
\item {\tt info\_trivial}
+\item {\tt debug trivial}
+
\item {\tt \zeroone{info\_}trivial} \zeroone{{\tt using} \nterm{lemma}$_1$
{\tt ,} {\ldots} {\tt ,} \nterm{lemma}$_n$} \zeroone{{\tt with}
\ident$_1$ {\ldots} \ident$_n$}
@@ -3732,6 +3752,19 @@ hints of the database named {\tt core}.
\Rem {\tt auto} either solves completely the goal or else leaves it
intact. \texttt{auto} and \texttt{trivial} never fail.
+\Rem The following options enable printing of informative or debug
+information for the {\tt auto} and {\tt trivial} tactics:
+\begin{quote}
+ \optindex{Info Auto}
+ {\tt Set Info Auto}
+ \optindex{Debug Auto}
+ {\tt Set Debug Auto}
+ \optindex{Info Trivial}
+ {\tt Set Info Trivial}
+ \optindex{Debug Trivial}
+ {\tt Set Debug Trivial}
+\end{quote}
+
\SeeAlso Section~\ref{Hints-databases}
\subsection{\tt eauto}
@@ -3768,6 +3801,14 @@ Note that {\tt ex\_intro} should be declared as a hint.
\end{Variants}
+\Rem {\tt eauto} obeys the following options:
+\begin{quote}
+ \optindex{Info Eauto}
+ {\tt Set Info Eauto}
+ \optindex{Debug Eauto}
+ {\tt Set Debug Eauto}
+\end{quote}
+
\SeeAlso Section~\ref{Hints-databases}
\subsection{\tt autounfold with \ident$_1$ \mbox{\dots} \ident$_n$}
@@ -4710,6 +4751,13 @@ congruence.
described above.
\end{ErrMsgs}
+\noindent {\bf Remark: } {\tt congruence} can be made to print debug
+information by setting the following option:
+
+\begin{quote}
+\optindex{Congruence Verbose}
+{\tt Set Congruence Verbose}
+\end{quote}
\section{Checking properties of terms}
diff --git a/doc/refman/RefMan-uti.tex b/doc/refman/RefMan-uti.tex
index c411db100..962aa98b6 100644
--- a/doc/refman/RefMan-uti.tex
+++ b/doc/refman/RefMan-uti.tex
@@ -4,53 +4,24 @@
The distribution provides utilities to simplify some tedious works
beside proof development, tactics writing or documentation.
-\section[Building a toplevel extended with user tactics]{Building a toplevel extended with user tactics\label{Coqmktop}\ttindex{coqmktop}}
+\section[Using Coq as a library]{Using Coq as a library}
-The native-code version of \Coq\ cannot dynamically load user tactics
-using {\ocaml} code. It is possible to build a toplevel of \Coq,
-with {\ocaml} code statically linked, with the tool {\tt
- coqmktop}.
-
-For example, one can build a native-code \Coq\ toplevel extended with a tactic
-which source is in {\tt tactic.ml} with the command
-\begin{verbatim}
- % coqmktop -opt -o mytop.out tactic.cmx
-\end{verbatim}
-where {\tt tactic.ml} has been compiled with the native-code
-compiler {\tt ocamlopt}. This command generates an executable
-called {\tt mytop.out}. To use this executable to compile your \Coq\
-files, use {\tt coqc -image mytop.out}.
-
-A basic example is the native-code version of \Coq\ ({\tt coqtop.opt}),
-which can be generated by {\tt coqmktop -opt -o coqopt.opt}.
-
-
-\paragraph[Application: how to use the {\ocaml} debugger with Coq.]{Application: how to use the {\ocaml} debugger with Coq.\index{Debugger}}
-
-One useful application of \texttt{coqmktop} is to build a \Coq\ toplevel in
-order to debug your tactics with the {\ocaml} debugger.
-You need to have configured and compiled \Coq\ for debugging
-(see the file \texttt{INSTALL} included in the distribution).
-Then, you must compile the Caml modules of your tactic with the
-option \texttt{-g} (with the bytecode compiler) and build a stand-alone
-bytecode toplevel with the following command:
+In previous versions, \texttt{coqmktop} was used to build custom
+toplevels --- for example for better debugging or custom static
+linking. Nowadays, the preferred method is to use \texttt{ocamlfind}.
+The most basic custom toplevel is built using:
\begin{quotation}
-\texttt{\% coqmktop -g -o coq-debug}~\emph{<your \texttt{.cmo} files>}
+\texttt{\% ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg
+ -package coq.toplevel toplevel/coqtop\_bin.ml -o my\_toplevel.native}
\end{quotation}
-
-To launch the \ocaml\ debugger with the image you need to execute it in
-an environment which correctly sets the \texttt{COQLIB} variable.
-Moreover, you have to indicate the directories in which
-\texttt{ocamldebug} should search for Caml modules.
-
-A possible solution is to use a wrapper around \texttt{ocamldebug}
-which detects the executables containing the word \texttt{coq}. In
-this case, the debugger is called with the required additional
-arguments. In other cases, the debugger is simply called without additional
-arguments. Such a wrapper can be found in the \texttt{dev/}
-subdirectory of the sources.
+For example, to statically link LTAC, you can just do:
+\begin{quotation}
+\texttt{\% ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg
+ -package coq.toplevel -package coq.ltac toplevel/coqtop\_bin.ml -o my\_toplevel.native}
+\end{quotation}
+and similarly for other plugins.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index d303038c5..a65b3941e 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -150,6 +150,8 @@ type rel_declaration = (constr, types) Context.Rel.Declaration.pt
type named_context = (constr, types) Context.Named.pt
type rel_context = (constr, types) Context.Rel.pt
+type 'a puniverses = 'a * EInstance.t
+
let in_punivs a = (a, EInstance.empty)
let mkProp = of_kind (Sort (ESorts.make Sorts.prop))
@@ -768,6 +770,20 @@ let rec isArity sigma c =
| Sort _ -> true
| _ -> false
+type arity = rel_context * ESorts.t
+
+let destArity sigma =
+ let open Context.Rel.Declaration in
+ let rec prodec_rec l c =
+ match kind sigma c with
+ | 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.")
+ in
+ prodec_rec []
+
let mkProd_or_LetIn decl c =
let open Context.Rel.Declaration in
match decl with
@@ -815,6 +831,15 @@ let lookup_rel i e = cast_rel_decl (sym unsafe_eq) (lookup_rel i e)
let lookup_named n e = cast_named_decl (sym unsafe_eq) (lookup_named n e)
let lookup_named_val n e = cast_named_decl (sym unsafe_eq) (lookup_named_val n e)
+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_constr (f env) d :: acc) sign
+ | [] ->
+ acc
+ in
+ aux env [] (List.rev sign)
+
let fresh_global ?loc ?rigid ?names env sigma reference =
let (evd,t) = Evd.fresh_global ?loc ?rigid ?names env sigma reference in
evd, of_constr t
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index f54c422ad..30de748a1 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -56,6 +56,8 @@ sig
val is_empty : t -> bool
end
+type 'a puniverses = 'a * EInstance.t
+
(** {5 Destructors} *)
val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
@@ -144,7 +146,11 @@ val isFix : Evd.evar_map -> t -> bool
val isCoFix : Evd.evar_map -> t -> bool
val isCase : Evd.evar_map -> t -> bool
val isProj : Evd.evar_map -> t -> bool
+
+type arity = rel_context * ESorts.t
+val destArity : Evd.evar_map -> types -> arity
val isArity : Evd.evar_map -> t -> bool
+
val isVarId : Evd.evar_map -> Id.t -> t -> bool
val isRelN : Evd.evar_map -> int -> t -> bool
@@ -260,6 +266,9 @@ val lookup_rel : int -> env -> rel_declaration
val lookup_named : variable -> env -> named_declaration
val lookup_named_val : variable -> named_context_val -> named_declaration
+val map_rel_context_in_env :
+ (env -> constr -> constr) -> env -> rel_context -> rel_context
+
(* XXX Missing Sigma proxy *)
val fresh_global :
?loc:Loc.t -> ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 907f1b1ac..3445b744a 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -199,9 +199,10 @@ let whd_head_evar sigma c =
let meta_counter_summary_name = "meta counter"
(* Generator of metavariables *)
-let new_meta =
- let meta_ctr = Summary.ref 0 ~name:meta_counter_summary_name in
- fun () -> incr meta_ctr; !meta_ctr
+let meta_ctr, meta_counter_summary_tag =
+ Summary.ref_tag 0 ~name:meta_counter_summary_name
+
+let new_meta () = incr meta_ctr; !meta_ctr
let mk_new_meta () = EConstr.mkMeta(new_meta())
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index 5fd4634d6..9d0b973a7 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -236,7 +236,7 @@ val evd_comb2 : (evar_map -> 'b -> 'c -> evar_map * 'a) -> evar_map ref -> 'b ->
val subterm_source : Evar.t -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
-val meta_counter_summary_name : string
+val meta_counter_summary_tag : int Summary.Dyn.tag
(** Deprecated *)
type type_constraint = types option
diff --git a/engine/evd.ml b/engine/evd.ml
index 45d2a8b08..e33c851f6 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -466,9 +466,8 @@ let add d e i = add_with_name d e i
let evar_counter_summary_name = "evar counter"
(* Generator of existential names *)
-let new_untyped_evar =
- let evar_ctr = Summary.ref 0 ~name:evar_counter_summary_name in
- fun () -> incr evar_ctr; Evar.unsafe_of_int !evar_ctr
+let evar_ctr, evar_counter_summary_tag = Summary.ref_tag 0 ~name:evar_counter_summary_name
+let new_untyped_evar () = incr evar_ctr; Evar.unsafe_of_int !evar_ctr
let new_evar evd ?name evi =
let evk = new_untyped_evar () in
diff --git a/engine/evd.mli b/engine/evd.mli
index 636bd1be1..b28ce2a62 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -613,7 +613,7 @@ type unsolvability_explanation = SeveralInstancesFound of int
(* This stuff is internal and should not be used. Currently a hack in
the STM relies on it. *)
-val evar_counter_summary_name : string
+val evar_counter_summary_tag : int Summary.Dyn.tag
(** {5 Deprecated functions} *)
val create_evar_defs : evar_map -> evar_map
diff --git a/engine/uState.ml b/engine/uState.ml
index 6566ad989..6131f4c03 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -240,8 +240,8 @@ let add_constraints ctx cstrs =
uctx_univ_variables = vars;
uctx_universes = UGraph.merge_constraints local' ctx.uctx_universes }
-(* let addconstrkey = Profile.declare_profile "add_constraints_context";; *)
-(* let add_constraints_context = Profile.profile2 addconstrkey add_constraints_context;; *)
+(* let addconstrkey = CProfile.declare_profile "add_constraints_context";; *)
+(* let add_constraints_context = CProfile.profile2 addconstrkey add_constraints_context;; *)
let add_universe_constraints ctx cstrs =
let univs, local = ctx.uctx_local in
diff --git a/engine/universes.ml b/engine/universes.ml
index 0250295fd..30490ec56 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -946,8 +946,8 @@ let normalize_context_set ctx us algs =
let us = normalize_opt_subst us in
(us, algs), (ctx', Constraint.union noneqs eqs)
-(* let normalize_conkey = Profile.declare_profile "normalize_context_set" *)
-(* let normalize_context_set a b c = Profile.profile3 normalize_conkey normalize_context_set a b c *)
+(* let normalize_conkey = CProfile.declare_profile "normalize_context_set" *)
+(* let normalize_context_set a b c = CProfile.profile3 normalize_conkey normalize_context_set a b c *)
let is_trivial_leq (l,d,r) =
Univ.Level.is_prop l && (d == Univ.Le || (d == Univ.Lt && Univ.Level.is_set r))
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index 43d7aa363..58599a14d 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -13,7 +13,6 @@ open Util
open Pp
open Printer
-module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
module CompactedDecl = Context.Compacted.Declaration
@@ -510,7 +509,7 @@ let rec parse = function
let () = Coqtop.toploop_init := (fun args ->
let args = parse args in
Flags.quiet := true;
- CoqworkmgrApi.(init Flags.High);
+ CoqworkmgrApi.(init High);
args)
let () = Coqtop.toploop_run := loop
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 8b78a91b5..7cc8de85d 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -188,7 +188,7 @@ and case_expr_eq (e1, n1, p1) (e2, n2, p2) =
Option.equal cases_pattern_expr_eq p1 p2
and branch_expr_eq (_, (p1, e1)) (_, (p2, e2)) =
- List.equal (eq_located (List.equal cases_pattern_expr_eq)) p1 p2 &&
+ List.equal (List.equal cases_pattern_expr_eq) p1 p2 &&
constr_expr_eq e1 e2
and binder_expr_eq ((n1, _, e1) : binder_expr) (n2, _, e2) =
@@ -260,7 +260,6 @@ let local_binders_loc bll = match bll with
(* Legacy functions *)
let down_located f (_l, x) = f x
-let located_fold_left f x (_l, y) = f x y
let is_constructor id =
try Globnames.isConstructRef
@@ -292,8 +291,7 @@ let ids_of_pattern =
let ids_of_pattern_list =
List.fold_left
- (located_fold_left
- (List.fold_left (cases_pattern_fold_names Id.Set.add)))
+ (List.fold_left (cases_pattern_fold_names Id.Set.add))
Id.Set.empty
let ids_of_cases_indtype p =
@@ -571,7 +569,7 @@ let expand_binders ?loc mkC bl c =
let c = CAst.make ?loc @@
CCases
(LetPatternStyle, None, [(e,None,None)],
- [(Loc.tag ?loc:loc1 ([(loc1,[p])], c))])
+ [(Loc.tag ?loc:loc1 ([[p]], c))])
in
(ni :: env, mkC ?loc ([id],Default Explicit,ty) c)
in
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index bc8debd02..1330b3741 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -852,7 +852,7 @@ let rec extern inctx scopes vars r =
) x))
tml
in
- let eqns = List.map (extern_eqn inctx scopes vars) eqns in
+ let eqns = List.map (extern_eqn inctx scopes vars) (factorize_eqns eqns) in
CCases (sty,rtntypopt',tml,eqns)
| GLetTuple (nal,(na,typopt),tm,b) ->
@@ -966,9 +966,9 @@ and extern_local_binder scopes vars = function
let (assums,ids,l) = extern_local_binder scopes vars l in
(assums,ids, CLocalPattern(Loc.tag @@ (p,ty)) :: l)
-and extern_eqn inctx scopes vars (loc,(ids,pl,c)) =
- Loc.tag ?loc ([loc,List.map (extern_cases_pattern_in_scope scopes vars) pl],
- extern inctx scopes vars c)
+and extern_eqn inctx scopes vars (loc,(ids,pll,c)) =
+ let pll = List.map (List.map (extern_cases_pattern_in_scope scopes vars)) pll in
+ Loc.tag ?loc (pll,extern inctx scopes vars c)
and extern_notation (tmp_scope,scopes as allscopes) vars t = function
| [] -> raise No_match
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 977146b2f..61b33aa41 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -958,8 +958,11 @@ let rec has_duplicate = function
| [] -> None
| x::l -> if Id.List.mem x l then (Some x) else has_duplicate l
+let loc_of_multiple_pattern pl =
+ Loc.merge_opt (cases_pattern_expr_loc (List.hd pl)) (cases_pattern_expr_loc (List.last pl))
+
let loc_of_lhs lhs =
- Loc.merge_opt (fst (List.hd lhs)) (fst (List.last lhs))
+ Loc.merge_opt (loc_of_multiple_pattern (List.hd lhs)) (loc_of_multiple_pattern (List.last lhs))
let check_linearity lhs ids =
match has_duplicate ids with
@@ -1873,8 +1876,9 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
intern_local_binder_aux intern ntnvars env bind
(* Expands a multiple pattern into a disjunction of multiple patterns *)
- and intern_multiple_pattern env n (loc,pl) =
+ and intern_multiple_pattern env n pl =
let idsl_pll = List.map (intern_cases_pattern globalenv (None,env.scopes) empty_alias) pl in
+ let loc = loc_of_multiple_pattern pl in
check_number_of_pattern loc n pl;
product_of_cases_patterns empty_alias idsl_pll
@@ -2094,39 +2098,36 @@ let interp_open_constr env sigma c =
(* Not all evars expected to be resolved and computation of implicit args *)
-let interp_constr_evars_gen_impls env evdref
+let interp_constr_evars_gen_impls env sigma
?(impls=empty_internalization_env) expected_type c =
let c = intern_gen expected_type ~impls env c in
let imps = Implicit_quantifiers.implicits_of_glob_constr ~with_products:(expected_type == IsType) c in
- let evd, c = understand_tcc env !evdref ~expected_type c in
- evdref := evd;
- c, imps
+ let sigma, c = understand_tcc env sigma ~expected_type c in
+ sigma, (c, imps)
-let interp_constr_evars_impls env evdref ?(impls=empty_internalization_env) c =
- interp_constr_evars_gen_impls env evdref ~impls WithoutTypeConstraint c
+let interp_constr_evars_impls env sigma ?(impls=empty_internalization_env) c =
+ interp_constr_evars_gen_impls env sigma ~impls WithoutTypeConstraint c
let interp_casted_constr_evars_impls env evdref ?(impls=empty_internalization_env) c typ =
interp_constr_evars_gen_impls env evdref ~impls (OfType typ) c
-let interp_type_evars_impls env evdref ?(impls=empty_internalization_env) c =
- interp_constr_evars_gen_impls env evdref ~impls IsType c
+let interp_type_evars_impls env sigma ?(impls=empty_internalization_env) c =
+ interp_constr_evars_gen_impls env sigma ~impls IsType c
(* Not all evars expected to be resolved, with side-effect on evars *)
-let interp_constr_evars_gen env evdref ?(impls=empty_internalization_env) expected_type c =
+let interp_constr_evars_gen env sigma ?(impls=empty_internalization_env) expected_type c =
let c = intern_gen expected_type ~impls env c in
- let evd, c = understand_tcc env !evdref ~expected_type c in
- evdref := evd;
- c
+ understand_tcc env sigma ~expected_type c
let interp_constr_evars env evdref ?(impls=empty_internalization_env) c =
interp_constr_evars_gen env evdref WithoutTypeConstraint ~impls c
-let interp_casted_constr_evars env evdref ?(impls=empty_internalization_env) c typ =
- interp_constr_evars_gen env evdref ~impls (OfType (EConstr.of_constr typ)) c
+let interp_casted_constr_evars env sigma ?(impls=empty_internalization_env) c typ =
+ interp_constr_evars_gen env sigma ~impls (OfType typ) c
-let interp_type_evars env evdref ?(impls=empty_internalization_env) c =
- interp_constr_evars_gen env evdref IsType ~impls c
+let interp_type_evars env sigma ?(impls=empty_internalization_env) c =
+ interp_constr_evars_gen env sigma IsType ~impls c
(* Miscellaneous *)
@@ -2181,17 +2182,16 @@ let intern_context global_level env impl_env binders =
with InternalizationError (loc,e) ->
user_err ?loc ~hdr:"internalize" (explain_internalization_error e)
-let interp_glob_context_evars env evdref k bl =
+let interp_glob_context_evars env sigma k bl =
let open EConstr in
- let (env, par, _, impls) =
+ let env, sigma, par, _, impls =
List.fold_left
- (fun (env,params,n,impls) (na, k, b, t) ->
+ (fun (env,sigma,params,n,impls) (na, k, b, t) ->
let t' =
if Option.is_empty b then locate_if_hole ?loc:(loc_of_glob_constr t) na t
else t
in
- let (evd,t) = understand_tcc env !evdref ~expected_type:IsType t' in
- evdref := evd;
+ let sigma, t = understand_tcc env sigma ~expected_type:IsType t' in
match b with
None ->
let d = LocalAssum (na,t) in
@@ -2201,16 +2201,15 @@ let interp_glob_context_evars env evdref k bl =
(ExplByPos (n, na), (true, true, true)) :: impls
else impls
in
- (push_rel d env, d::params, succ n, impls)
+ (push_rel d env, sigma, d::params, succ n, impls)
| Some b ->
- let (evd,c) = understand_tcc env !evdref ~expected_type:(OfType t) b in
- evdref := evd;
+ let sigma, c = understand_tcc env sigma ~expected_type:(OfType t) b in
let d = LocalDef (na, c, t) in
- (push_rel d env, d::params, n, impls))
- (env,[],k+1,[]) (List.rev bl)
- in (env, par), impls
+ (push_rel d env, sigma, d::params, n, impls))
+ (env,sigma,[],k+1,[]) (List.rev bl)
+ in sigma, ((env, par), impls)
-let interp_context_evars ?(global_level=false) ?(impl_env=empty_internalization_env) ?(shift=0) env evdref params =
+let interp_context_evars ?(global_level=false) ?(impl_env=empty_internalization_env) ?(shift=0) env sigma params =
let int_env,bl = intern_context global_level env impl_env params in
- let x = interp_glob_context_evars env evdref shift bl in
- int_env, x
+ let sigma, x = interp_glob_context_evars env sigma shift bl in
+ sigma, (int_env, x)
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index 46f96d20b..632b423b0 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -112,28 +112,28 @@ val interp_open_constr : env -> evar_map -> constr_expr -> evar_map * EConstr.co
(** Accepting unresolved evars *)
-val interp_constr_evars : env -> evar_map ref ->
- ?impls:internalization_env -> constr_expr -> EConstr.constr
+val interp_constr_evars : env -> evar_map ->
+ ?impls:internalization_env -> constr_expr -> evar_map * EConstr.constr
-val interp_casted_constr_evars : env -> evar_map ref ->
- ?impls:internalization_env -> constr_expr -> types -> EConstr.constr
+val interp_casted_constr_evars : env -> evar_map ->
+ ?impls:internalization_env -> constr_expr -> EConstr.types -> evar_map * EConstr.constr
-val interp_type_evars : env -> evar_map ref ->
- ?impls:internalization_env -> constr_expr -> EConstr.types
+val interp_type_evars : env -> evar_map ->
+ ?impls:internalization_env -> constr_expr -> evar_map * EConstr.types
(** Accepting unresolved evars and giving back the manual implicit arguments *)
-val interp_constr_evars_impls : env -> evar_map ref ->
+val interp_constr_evars_impls : env -> evar_map ->
?impls:internalization_env -> constr_expr ->
- EConstr.constr * Impargs.manual_implicits
+ evar_map * (EConstr.constr * Impargs.manual_implicits)
-val interp_casted_constr_evars_impls : env -> evar_map ref ->
+val interp_casted_constr_evars_impls : env -> evar_map ->
?impls:internalization_env -> constr_expr -> EConstr.types ->
- EConstr.constr * Impargs.manual_implicits
+ evar_map * (EConstr.constr * Impargs.manual_implicits)
-val interp_type_evars_impls : env -> evar_map ref ->
+val interp_type_evars_impls : env -> evar_map ->
?impls:internalization_env -> constr_expr ->
- EConstr.types * Impargs.manual_implicits
+ evar_map * (EConstr.types * Impargs.manual_implicits)
(** Interprets constr patterns *)
@@ -158,8 +158,8 @@ val interp_binder_evars : env -> evar_map ref -> Name.t -> constr_expr -> EConst
val interp_context_evars :
?global_level:bool -> ?impl_env:internalization_env -> ?shift:int ->
- env -> evar_map ref -> local_binder_expr list ->
- internalization_env * ((env * EConstr.rel_context) * Impargs.manual_implicits)
+ env -> evar_map -> local_binder_expr list ->
+ evar_map * (internalization_env * ((env * EConstr.rel_context) * Impargs.manual_implicits))
(* val interp_context_gen : (env -> glob_constr -> unsafe_type_judgment Evd.in_evar_universe_context) -> *)
(* (env -> Evarutil.type_constraint -> glob_constr -> unsafe_judgment Evd.in_evar_universe_context) -> *)
diff --git a/intf/constrexpr.ml b/intf/constrexpr.ml
index e0d2d7bf4..8bcdbcc0e 100644
--- a/intf/constrexpr.ml
+++ b/intf/constrexpr.ml
@@ -104,7 +104,7 @@ and case_expr = constr_expr (* expression that is being matched
* cases_pattern_expr option (* in-clause *)
and branch_expr =
- (cases_pattern_expr list Loc.located list * constr_expr) Loc.located
+ (cases_pattern_expr list list * constr_expr) Loc.located
and binder_expr =
Name.t Loc.located list * binder_kind * constr_expr
diff --git a/intf/glob_term.ml b/intf/glob_term.ml
index 72c91db6a..f311d33b8 100644
--- a/intf/glob_term.ml
+++ b/intf/glob_term.ml
@@ -93,6 +93,14 @@ type fix_recursion_order = [ `any ] fix_recursion_order_g
type any_glob_constr = AnyGlobConstr : 'r glob_constr_g -> any_glob_constr
+type 'a disjunctive_cases_clause_g = (Id.t list * 'a cases_pattern_g list list * 'a glob_constr_g) Loc.located
+type 'a disjunctive_cases_clauses_g = 'a disjunctive_cases_clause_g list
+type 'a cases_pattern_disjunction_g = 'a cases_pattern_g list
+
+type disjunctive_cases_clause = [ `any ] disjunctive_cases_clause_g
+type disjunctive_cases_clauses = [ `any ] disjunctive_cases_clauses_g
+type cases_pattern_disjunction = [ `any ] cases_pattern_disjunction_g
+
type 'a extended_glob_local_binder_r =
| GLocalAssum of Name.t * binding_kind * 'a glob_constr_g
| GLocalDef of Name.t * binding_kind * 'a glob_constr_g * 'a glob_constr_g option
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 2579ac045..7b921d35b 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -250,7 +250,7 @@ let cook_constant ~hcons env { from = cb; info } =
cook_context = Some const_hyps;
}
-(* let cook_constant_key = Profile.declare_profile "cook_constant" *)
-(* let cook_constant = Profile.profile2 cook_constant_key cook_constant *)
+(* let cook_constant_key = CProfile.declare_profile "cook_constant" *)
+(* let cook_constant = CProfile.profile2 cook_constant_key cook_constant *)
let expmod_constr modlist c = expmod_constr (RefTable.create 13) modlist c
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 62aa9a2d7..2a629f00a 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -1098,8 +1098,8 @@ let check_fix env ((nvect,_),(names,_,bodies as recdef) as fix) =
()
(*
-let cfkey = Profile.declare_profile "check_fix";;
-let check_fix env fix = Profile.profile3 cfkey check_fix env fix;;
+let cfkey = CProfile.declare_profile "check_fix";;
+let check_fix env fix = CProfile.profile3 cfkey check_fix env fix;;
*)
(************************************************************************)
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index a62a079da..9f9102f7d 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -154,7 +154,7 @@ let warn_no_native_compiler =
(* Wrapper for [native_conv] above *)
let native_conv cv_pb sigma env t1 t2 =
- if Coq_config.no_native_compiler then begin
+ if not Coq_config.native_compiler then begin
warn_no_native_compiler ();
vm_conv cv_pb env t1 t2
end
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index b0f4a1e5f..c07ac973b 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -833,8 +833,8 @@ let gen_conv cv_pb l2r reds env evars univs t1 t2 =
let gen_conv cv_pb ?(l2r=false) ?(reds=full_transparent_state) env ?(evars=(fun _->None), universes env) =
let evars, univs = evars in
if Flags.profile then
- let fconv_universes_key = Profile.declare_profile "trans_fconv_universes" in
- Profile.profile8 fconv_universes_key gen_conv cv_pb l2r reds env evars univs
+ let fconv_universes_key = CProfile.declare_profile "trans_fconv_universes" in
+ CProfile.profile8 fconv_universes_key gen_conv cv_pb l2r reds env evars univs
else gen_conv cv_pb l2r reds env evars univs
let conv = gen_conv CONV
@@ -860,8 +860,8 @@ let infer_conv_universes cv_pb l2r evars reds env univs t1 t2 =
(* Profiling *)
let infer_conv_universes =
if Flags.profile then
- let infer_conv_universes_key = Profile.declare_profile "infer_conv_universes" in
- Profile.profile8 infer_conv_universes_key infer_conv_universes
+ let infer_conv_universes_key = CProfile.declare_profile "infer_conv_universes" in
+ CProfile.profile8 infer_conv_universes_key infer_conv_universes
else infer_conv_universes
let infer_conv ?(l2r=false) ?(evars=fun _ -> None) ?(ts=full_transparent_state)
@@ -895,13 +895,13 @@ let default_conv cv_pb ?(l2r=false) env t1 t2 =
let default_conv_leq = default_conv CUMUL
(*
-let convleqkey = Profile.declare_profile "Kernel_reduction.conv_leq";;
+let convleqkey = CProfile.declare_profile "Kernel_reduction.conv_leq";;
let conv_leq env t1 t2 =
- Profile.profile4 convleqkey conv_leq env t1 t2;;
+ CProfile.profile4 convleqkey conv_leq env t1 t2;;
-let convkey = Profile.declare_profile "Kernel_reduction.conv";;
+let convkey = CProfile.declare_profile "Kernel_reduction.conv";;
let conv env t1 t2 =
- Profile.profile4 convleqkey conv env t1 t2;;
+ CProfile.profile4 convleqkey conv env t1 t2;;
*)
(* Application with on-the-fly reduction *)
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 0e41bfc3c..5150ad411 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -858,7 +858,7 @@ let export ?except senv dir =
}
in
let ast, symbols =
- if !Flags.native_compiler then
+ if !Flags.output_native_objects then
Nativelibrary.dump_library mp dir senv.env str
else [], Nativecode.empty_symbols
in
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index 4ccef5c38..4a935f581 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -435,8 +435,8 @@ let infer env constr =
let infer =
if Flags.profile then
- let infer_key = Profile.declare_profile "Fast_infer" in
- Profile.profile2 infer_key (fun b c -> infer b c)
+ let infer_key = CProfile.declare_profile "Fast_infer" in
+ CProfile.profile2 infer_key (fun b c -> infer b c)
else (fun b c -> infer b c)
let assumption_of_judgment env {uj_val=c; uj_type=t} =
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index 00c0ea70d..f1e8d1031 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -890,24 +890,24 @@ let dump_universes output g =
let merge_constraints =
if Flags.profile then
- let key = Profile.declare_profile "merge_constraints" in
- Profile.profile2 key merge_constraints
+ let key = CProfile.declare_profile "merge_constraints" in
+ CProfile.profile2 key merge_constraints
else merge_constraints
let check_constraints =
if Flags.profile then
- let key = Profile.declare_profile "check_constraints" in
- Profile.profile2 key check_constraints
+ let key = CProfile.declare_profile "check_constraints" in
+ CProfile.profile2 key check_constraints
else check_constraints
let check_eq =
if Flags.profile then
- let check_eq_key = Profile.declare_profile "check_eq" in
- Profile.profile3 check_eq_key check_eq
+ let check_eq_key = CProfile.declare_profile "check_eq" in
+ CProfile.profile3 check_eq_key check_eq
else check_eq
let check_leq =
if Flags.profile then
- let check_leq_key = Profile.declare_profile "check_leq" in
- Profile.profile3 check_leq_key check_leq
+ let check_leq_key = CProfile.declare_profile "check_leq" in
+ CProfile.profile3 check_leq_key check_leq
else check_leq
diff --git a/kernel/vars.ml b/kernel/vars.ml
index f52d734ef..eae917b5a 100644
--- a/kernel/vars.ml
+++ b/kernel/vars.ml
@@ -133,8 +133,8 @@ let substn_many lamv n c =
substrec n c
(*
-let substkey = Profile.declare_profile "substn_many";;
-let substn_many lamv n c = Profile.profile3 substkey substn_many lamv n c;;
+let substkey = CProfile.declare_profile "substn_many";;
+let substn_many lamv n c = CProfile.profile3 substkey substn_many lamv n c;;
*)
let make_subst = function
@@ -274,8 +274,8 @@ let subst_univs_constr subst c =
let subst_univs_constr =
if Flags.profile then
- let subst_univs_constr_key = Profile.declare_profile "subst_univs_constr" in
- Profile.profile2 subst_univs_constr_key subst_univs_constr
+ let subst_univs_constr_key = CProfile.declare_profile "subst_univs_constr" in
+ CProfile.profile2 subst_univs_constr_key subst_univs_constr
else subst_univs_constr
let subst_univs_level_constr subst c =
@@ -347,8 +347,8 @@ let subst_instance_constr subst c =
in
aux c
-(* let substkey = Profile.declare_profile "subst_instance_constr";; *)
-(* let subst_instance_constr inst c = Profile.profile2 substkey subst_instance_constr inst c;; *)
+(* let substkey = CProfile.declare_profile "subst_instance_constr";; *)
+(* let subst_instance_constr inst c = CProfile.profile2 substkey subst_instance_constr inst c;; *)
let subst_instance_context s ctx =
if Univ.Instance.is_empty s then ctx
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 578a89371..3ef297b1f 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -204,4 +204,4 @@ let vm_conv cv_pb env t1 t2 =
let univs = (univs, checked_universes) in
let _ = vm_conv_gen cv_pb env univs t1 t2 in ()
-let _ = Reduction.set_vm_conv vm_conv
+let _ = if Coq_config.bytecode_compiler then Reduction.set_vm_conv vm_conv
diff --git a/lib/cList.ml b/lib/cList.ml
index ca69628af..0ef7c3d8b 100644
--- a/lib/cList.ml
+++ b/lib/cList.ml
@@ -96,6 +96,8 @@ sig
val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
@@ -446,6 +448,12 @@ let rec fold_left3 f accu l1 l2 l3 =
| (a1::l1, a2::l2, a3::l3) -> fold_left3 f (f accu a1 a2 a3) l1 l2 l3
| (_, _, _) -> invalid_arg "List.fold_left3"
+let rec fold_left4 f accu l1 l2 l3 l4 =
+ match (l1, l2, l3, l4) with
+ ([], [], [], []) -> accu
+ | (a1::l1, a2::l2, a3::l3, a4::l4) -> fold_left4 f (f accu a1 a2 a3 a4) l1 l2 l3 l4
+ | (_,_, _, _) -> invalid_arg "List.fold_left4"
+
(* [fold_right_and_left f [a1;...;an] hd =
f (f (... (f (f hd
an
@@ -765,12 +773,13 @@ let share_tails l1 l2 =
in
shr_rev [] (List.rev l1, List.rev l2)
+(* Poor man's monadic map *)
let rec fold_left_map f e = function
- | [] -> (e,[])
- | h::t ->
- let e',h' = f e h in
- let e'',t' = fold_left_map f e' t in
- e'',h'::t'
+ | [] -> (e,[])
+ | h::t ->
+ let e',h' = f e h in
+ let e'',t' = fold_left_map f e' t in
+ e'',h'::t'
let fold_map = fold_left_map
@@ -790,12 +799,26 @@ let fold_right_map f l e =
let fold_map' = fold_right_map
+let on_snd f (x,y) = (x,f y)
+
let fold_left2_map f e l l' =
- List.fold_left2 (fun (e,l) x x' -> let (e,y) = f e x x' in (e,y::l)) (e,[]) l l'
+ on_snd List.rev @@
+ List.fold_left2 (fun (e,l) x x' ->
+ let (e,y) = f e x x' in
+ (e, y::l)
+ ) (e, []) l l'
let fold_right2_map f l l' e =
List.fold_right2 (fun x x' (l,e) -> let (y,e) = f x x' e in (y::l,e)) l l' ([],e)
+let fold_left3_map f e l l' l'' =
+ on_snd List.rev @@
+ fold_left3 (fun (e,l) x x' x'' -> let (e,y) = f e x x' x'' in (e,y::l)) (e,[]) l l' l''
+
+let fold_left4_map f e l1 l2 l3 l4 =
+ on_snd List.rev @@
+ fold_left4 (fun (e,l) x1 x2 x3 x4 -> let (e,y) = f e x1 x2 x3 x4 in (e,y::l)) (e,[]) l1 l2 l3 l4
+
let map_assoc f = List.map (fun (x,a) -> (x,f a))
let rec assoc_f f a = function
diff --git a/lib/cList.mli b/lib/cList.mli
index 8cb07da79..f87db04cf 100644
--- a/lib/cList.mli
+++ b/lib/cList.mli
@@ -211,7 +211,14 @@ sig
val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
(** Same with two lists, folding on the right *)
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ (** Same with three lists, folding on the left *)
+
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
+ (** Same with four lists, folding on the left *)
+
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ (* [@@ocaml.deprecated "Same as [fold_left_map]"] *)
(** @deprecated Same as [fold_left_map] *)
val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
diff --git a/lib/profile.ml b/lib/cProfile.ml
index 0bc226a45..0bc226a45 100644
--- a/lib/profile.ml
+++ b/lib/cProfile.ml
diff --git a/lib/profile.mli b/lib/cProfile.mli
index cae4397a1..cae4397a1 100644
--- a/lib/profile.mli
+++ b/lib/cProfile.mli
diff --git a/lib/control.ml b/lib/control.ml
index d936d7557..c6489938e 100644
--- a/lib/control.ml
+++ b/lib/control.ml
@@ -12,15 +12,12 @@ let interrupt = ref false
let steps = ref 0
-let are_we_threading = lazy (
- match !Flags.async_proofs_mode with
- | Flags.APon -> true
- | _ -> false)
+let enable_thread_delay = ref false
let check_for_interrupt () =
if !interrupt then begin interrupt := false; raise Sys.Break end;
incr steps;
- if !steps = 1000 && Lazy.force are_we_threading then begin
+ if !enable_thread_delay && !steps = 1000 then begin
Thread.delay 0.001;
steps := 0;
end
diff --git a/lib/control.mli b/lib/control.mli
index f6c63ffb3..261b07693 100644
--- a/lib/control.mli
+++ b/lib/control.mli
@@ -8,6 +8,9 @@
(** Global control of Coq. *)
+(** Will periodically call [Thread.delay] if set to true *)
+val enable_thread_delay : bool ref
+
val interrupt : bool ref
(** Coq interruption: set the following boolean reference to interrupt Coq
(it eventually raises [Break], simulating a Ctrl-C) *)
diff --git a/lib/dyn.ml b/lib/dyn.ml
index 83e673d2c..64535d35f 100644
--- a/lib/dyn.ml
+++ b/lib/dyn.ml
@@ -55,6 +55,8 @@ sig
include PreS
module Easy : sig
+
+ val make_dyn_tag : string -> ('a -> t) * (t -> 'a) * 'a tag
val make_dyn : string -> ('a -> t) * (t -> 'a)
val inj : 'a -> 'a tag -> t
val prj : t -> 'a tag -> 'a option
@@ -129,8 +131,9 @@ end
include Self
module Easy = struct
+
(* now tags are opaque, we can do the trick *)
-let make_dyn (s : string) =
+let make_dyn_tag (s : string) =
(fun (type a) (tag : a tag) ->
let infun : (a -> t) = fun x -> Dyn (tag, x) in
let outfun : (t -> a) = fun (Dyn (t, x)) ->
@@ -138,9 +141,12 @@ let make_dyn (s : string) =
| None -> assert false
| Some CSig.Refl -> x
in
- (infun, outfun))
+ infun, outfun, tag)
(create s)
+let make_dyn (s : string) =
+ let inf, outf, _ = make_dyn_tag s in inf, outf
+
let inj x tag = Dyn(tag,x)
let prj : type a. t -> a tag -> a option =
fun (Dyn(tag',x)) tag ->
diff --git a/lib/dyn.mli b/lib/dyn.mli
index e0e1a9d14..2206394e2 100644
--- a/lib/dyn.mli
+++ b/lib/dyn.mli
@@ -53,6 +53,7 @@ val dump : unit -> (int * string) list
module Easy : sig
(* To create a dynamic type on the fly *)
+ val make_dyn_tag : string -> ('a -> t) * (t -> 'a) * 'a tag
val make_dyn : string -> ('a -> t) * (t -> 'a)
(* For types declared with the [create] function above *)
diff --git a/lib/envars.ml b/lib/envars.ml
index 206d75033..8ebf84057 100644
--- a/lib/envars.ml
+++ b/lib/envars.ml
@@ -153,19 +153,17 @@ let coqpath =
let exe s = s ^ Coq_config.exec_extension
-let ocamlfind () =
- if !Flags.ocamlfind_spec then !Flags.ocamlfind else Coq_config.ocamlfind
+let ocamlfind () = Coq_config.ocamlfind
(** {2 Camlp4 paths} *)
let guess_camlp4bin () = which (user_path ()) (exe Coq_config.camlp4)
let camlp4bin () =
- if !Flags.camlp4bin_spec then !Flags.camlp4bin else
- if !Flags.boot then Coq_config.camlp4bin else
- try guess_camlp4bin ()
- with Not_found ->
- Coq_config.camlp4bin
+ if !Flags.boot then Coq_config.camlp4bin else
+ try guess_camlp4bin ()
+ with Not_found ->
+ Coq_config.camlp4bin
let camlp4 () = camlp4bin () / exe Coq_config.camlp4
diff --git a/lib/flags.ml b/lib/flags.ml
index ddc8f8482..644f66d02 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -35,36 +35,10 @@ let record_aux_file = ref false
let test_mode = ref false
-type async_proofs = APoff | APonLazy | APon
-let async_proofs_mode = ref APoff
-type cache = Force
-let async_proofs_cache = ref None
-let async_proofs_n_workers = ref 1
-let async_proofs_n_tacworkers = ref 2
-let async_proofs_private_flags = ref None
-let async_proofs_full = ref false
-let async_proofs_never_reopen_branch = ref false
-let async_proofs_flags_for_workers = ref []
let async_proofs_worker_id = ref "master"
-type priority = Low | High
-let async_proofs_worker_priority = ref Low
-let string_of_priority = function Low -> "low" | High -> "high"
-let priority_of_string = function
- | "low" -> Low
- | "high" -> High
- | _ -> raise (Invalid_argument "priority_of_string")
-type tac_error_filter = [ `None | `Only of string list | `All ]
-let async_proofs_tac_error_resilience = ref (`Only [ "curly" ])
-let async_proofs_cmd_error_resilience = ref true
-
-let async_proofs_is_worker () =
- !async_proofs_worker_id <> "master"
-let async_proofs_is_master () =
- !async_proofs_mode = APon && !async_proofs_worker_id = "master"
-let async_proofs_delegation_threshold = ref 0.03
+let async_proofs_is_worker () = !async_proofs_worker_id <> "master"
let debug = ref false
-let stm_debug = ref false
let in_debugger = ref false
let in_toplevel = ref false
@@ -179,14 +153,6 @@ let is_standard_doc_url url =
let coqlib_spec = ref false
let coqlib = ref "(not initialized yet)"
-(* Options for changing ocamlfind (used by coqmktop) *)
-let ocamlfind_spec = ref false
-let ocamlfind = ref Coq_config.camlbin
-
-(* Options for changing camlp4bin (used by coqmktop) *)
-let camlp4bin_spec = ref false
-let camlp4bin = ref Coq_config.camlp4bin
-
(* Level of inlining during a functor application *)
let default_inline_level = 100
@@ -195,12 +161,11 @@ let set_inline_level = (:=) inline_level
let get_inline_level () = !inline_level
(* Native code compilation for conversion and normalization *)
-let native_compiler = ref false
+let output_native_objects = ref false
(* Print the mod uid associated to a vo file by the native compiler *)
let print_mod_uid = ref false
-let tactic_context_compat = ref false
let profile_ltac = ref false
let profile_ltac_cutoff = ref 2.0
diff --git a/lib/flags.mli b/lib/flags.mli
index c4afb8318..000862b2c 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -21,35 +21,14 @@ val record_aux_file : bool ref
val test_mode : bool ref
(** Async-related flags *)
-type async_proofs = APoff | APonLazy | APon
-val async_proofs_mode : async_proofs ref
-type cache = Force
-val async_proofs_cache : cache option ref
-val async_proofs_n_workers : int ref
-val async_proofs_n_tacworkers : int ref
-val async_proofs_private_flags : string option ref
-val async_proofs_is_worker : unit -> bool
-val async_proofs_is_master : unit -> bool
-val async_proofs_full : bool ref
-val async_proofs_never_reopen_branch : bool ref
-val async_proofs_flags_for_workers : string list ref
val async_proofs_worker_id : string ref
-type priority = Low | High
-val async_proofs_worker_priority : priority ref
-val string_of_priority : priority -> string
-val priority_of_string : string -> priority
-type tac_error_filter = [ `None | `Only of string list | `All ]
-val async_proofs_tac_error_resilience : tac_error_filter ref
-val async_proofs_cmd_error_resilience : bool ref
-val async_proofs_delegation_threshold : float ref
+val async_proofs_is_worker : unit -> bool
+(** Debug flags *)
val debug : bool ref
val in_debugger : bool ref
val in_toplevel : bool ref
-(** Enable STM debugging *)
-val stm_debug : bool ref
-
val profile : bool
(* -ide_slave: printing will be more verbose, will affect stm caching *)
@@ -143,27 +122,17 @@ val is_standard_doc_url : string -> bool
val coqlib_spec : bool ref
val coqlib : string ref
-(** Options for specifying where OCaml binaries reside *)
-val ocamlfind_spec : bool ref
-val ocamlfind : string ref
-val camlp4bin_spec : bool ref
-val camlp4bin : string ref
-
(** Level of inlining during a functor application *)
val set_inline_level : int -> unit
val get_inline_level : unit -> int
val default_inline_level : int
-(** Native code compilation for conversion and normalization *)
-val native_compiler : bool ref
+(** When producing vo objects, also compile the native-code version *)
+val output_native_objects : bool ref
(** Print the mod uid associated to a vo file by the native compiler *)
val print_mod_uid : bool ref
-val tactic_context_compat : bool ref
-(** Set to [true] to trigger the compatibility bugged context matching (old
- context vs. appcontext) is set. *)
-
val profile_ltac : bool ref
val profile_ltac_cutoff : float ref
diff --git a/lib/lib.mllib b/lib/lib.mllib
index 8791f0741..66f939a91 100644
--- a/lib/lib.mllib
+++ b/lib/lib.mllib
@@ -9,7 +9,7 @@ System
CThread
Spawn
Trie
-Profile
+CProfile
Explore
Predicate
Rtree
diff --git a/lib/pp.ml b/lib/pp.ml
index c3338688d..770e650cb 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -208,6 +208,7 @@ let string_of_ppcmds c =
let pr_comma () = str "," ++ spc ()
let pr_semicolon () = str ";" ++ spc ()
let pr_bar () = str "|" ++ spc ()
+let pr_spcbar () = str " |" ++ spc ()
let pr_arg pr x = spc () ++ pr x
let pr_non_empty_arg pr x = let pp = pr x in if ismt pp then mt () else spc () ++ pr x
let pr_opt pr = function None -> mt () | Some x -> pr_arg pr x
diff --git a/lib/pp.mli b/lib/pp.mli
index 2d11cad86..d9be1c5ce 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -120,6 +120,9 @@ val pr_semicolon : unit -> t
val pr_bar : unit -> t
(** Well-spaced pipe bar. *)
+val pr_spcbar : unit -> t
+(** Pipe bar with space before and after. *)
+
val pr_arg : ('a -> t) -> 'a -> t
(** Adds a space in front of its argument. *)
diff --git a/lib/system.ml b/lib/system.ml
index 4b5066ef4..2c8dbac7c 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -309,9 +309,3 @@ let with_time time f x =
let msg2 = if time then "" else " (failure)" in
Feedback.msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
raise e
-
-let process_id () =
- Printf.sprintf "%d:%s:%d" (Unix.getpid ())
- (if Flags.async_proofs_is_worker () then !Flags.async_proofs_worker_id
- else "master")
- (Thread.id (Thread.self ()))
diff --git a/lib/system.mli b/lib/system.mli
index aa964abeb..c02bc9c8a 100644
--- a/lib/system.mli
+++ b/lib/system.mli
@@ -105,6 +105,3 @@ val time_difference : time -> time -> float (** in seconds *)
val fmt_time_difference : time -> time -> Pp.t
val with_time : bool -> ('a -> 'b) -> 'a -> 'b
-
-(** {6 Name of current process.} *)
-val process_id : unit -> string
diff --git a/library/global.ml b/library/global.ml
index 03d7612a4..ce37dfecf 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -20,6 +20,7 @@ module GlobalSafeEnv : sig
val set_safe_env : Safe_typing.safe_environment -> unit
val join_safe_environment : ?except:Future.UUIDSet.t -> unit -> unit
val is_joined_environment : unit -> bool
+ val global_env_summary_tag : Safe_typing.safe_environment Summary.Dyn.tag
end = struct
@@ -30,9 +31,9 @@ let join_safe_environment ?except () =
let is_joined_environment () =
Safe_typing.is_joined_environment !global_env
-
-let () =
- Summary.declare_summary global_env_summary_name
+
+let global_env_summary_tag =
+ Summary.declare_summary_tag global_env_summary_name
{ Summary.freeze_function = (function
| `Yes -> join_safe_environment (); !global_env
| `No -> !global_env
@@ -51,6 +52,8 @@ let set_safe_env e = global_env := e
end
+let global_env_summary_tag = GlobalSafeEnv.global_env_summary_tag
+
let safe_env = GlobalSafeEnv.safe_env
let join_safe_environment ?except () =
GlobalSafeEnv.join_safe_environment ?except ()
diff --git a/library/global.mli b/library/global.mli
index c62462f9f..324181e79 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -159,4 +159,4 @@ val current_dirpath : unit -> DirPath.t
val with_global : (Environ.env -> DirPath.t -> 'a Univ.in_universe_context_set) -> 'a
-val global_env_summary_name : string
+val global_env_summary_tag : Safe_typing.safe_environment Summary.Dyn.tag
diff --git a/library/library.ml b/library/library.ml
index 88470d121..868e26684 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -170,7 +170,7 @@ 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
- if not Coq_config.no_native_compiler then
+ if Coq_config.native_compiler then
Nativelib.link_library ~prefix ~dirname ~basename:f
in
let rec aux = function
@@ -738,7 +738,7 @@ let save_library_to ?todo dir f otab =
System.marshal_out_segment f' ch (opaque_table : seg_proofs);
close_out ch;
(* Writing native code files *)
- if !Flags.native_compiler then
+ if !Flags.output_native_objects then
let fn = Filename.dirname f'^"/"^Nativecode.mod_uid_of_dirpath dir in
if not (Nativelib.compile_library dir ast fn) then
user_err Pp.(str "Could not compile the library to native code.")
diff --git a/library/summary.ml b/library/summary.ml
index 9f49d1f83..6df17476b 100644
--- a/library/summary.ml
+++ b/library/summary.ml
@@ -13,17 +13,22 @@ open Util
module Dyn = Dyn.Make ()
type marshallable = [ `Yes | `No | `Shallow ]
+
type 'a summary_declaration = {
freeze_function : marshallable -> 'a;
unfreeze_function : 'a -> unit;
init_function : unit -> unit }
-let summaries = ref Int.Map.empty
+let sum_mod = ref None
+let sum_map = ref String.Map.empty
let mangle id = id ^ "-SUMMARY"
+let unmangle id = String.(sub id 0 (length id - 8))
+
+let ml_modules = "ML-MODULES"
-let internal_declare_summary hash sumname sdecl =
- let (infun, outfun) = Dyn.Easy.make_dyn (mangle sumname) in
+let internal_declare_summary fadd sumname sdecl =
+ let infun, outfun, tag = Dyn.Easy.make_dyn_tag (mangle sumname) in
let dyn_freeze b = infun (sdecl.freeze_function b)
and dyn_unfreeze sum = sdecl.unfreeze_function (outfun sum)
and dyn_init = sdecl.init_function in
@@ -32,140 +37,116 @@ let internal_declare_summary hash sumname sdecl =
unfreeze_function = dyn_unfreeze;
init_function = dyn_init }
in
- summaries := Int.Map.add hash (sumname, ddecl) !summaries
+ fadd sumname ddecl;
+ tag
-let all_declared_summaries = ref Int.Set.empty
+let declare_ml_modules_summary decl =
+ let ml_add _ ddecl = sum_mod := Some ddecl in
+ internal_declare_summary ml_add ml_modules decl
-let summary_names = ref []
-let name_of_summary name =
- try List.assoc name !summary_names
- with Not_found -> "summary name not found"
+let declare_ml_modules_summary decl =
+ ignore(declare_ml_modules_summary decl)
-let declare_summary sumname decl =
- let hash = String.hash sumname in
- let () = if Int.Map.mem hash !summaries then
- let (name, _) = Int.Map.find hash !summaries in
- anomaly ~label:"Summary.declare_summary"
- (str "Colliding summary names: " ++ str sumname ++ str " vs. " ++ str name ++ str ".")
+let declare_summary_tag sumname decl =
+ let fadd name ddecl = sum_map := String.Map.add name ddecl !sum_map in
+ let () = if String.Map.mem sumname !sum_map then
+ anomaly ~label:"Summary.declare_summary"
+ (str "Colliding summary names: " ++ str sumname ++ str " vs. " ++ str sumname ++ str ".")
in
- all_declared_summaries := Int.Set.add hash !all_declared_summaries;
- summary_names := (hash, sumname) :: !summary_names;
- internal_declare_summary hash sumname decl
+ internal_declare_summary fadd sumname decl
+
+let declare_summary sumname decl =
+ ignore(declare_summary_tag sumname decl)
type frozen = {
- summaries : (int * Dyn.t) list;
+ summaries : Dyn.t String.Map.t;
(** Ordered list w.r.t. the first component. *)
ml_module : Dyn.t option;
(** Special handling of the ml_module summary. *)
}
-let empty_frozen = { summaries = []; ml_module = None; }
-
-let ml_modules = "ML-MODULES"
-let ml_modules_summary = String.hash ml_modules
+let empty_frozen = { summaries = String.Map.empty; ml_module = None }
let freeze_summaries ~marshallable : frozen =
- let fold id (_, decl) accu =
- (* to debug missing Lazy.force
- if marshallable <> `No then begin
- let id, _ = Int.Map.find id !summaries in
- prerr_endline ("begin marshalling " ^ id);
- ignore(Marshal.to_string (decl.freeze_function marshallable) []);
- prerr_endline ("end marshalling " ^ id);
- end;
- /debug *)
- let state = decl.freeze_function marshallable in
- if Int.equal id ml_modules_summary then { accu with ml_module = Some state }
- else { accu with summaries = (id, state) :: accu.summaries }
+ let smap decl = decl.freeze_function marshallable in
+ { summaries = String.Map.map smap !sum_map;
+ ml_module = Option.map (fun decl -> decl.freeze_function marshallable) !sum_mod;
+ }
+
+let unfreeze_single name state =
+ let decl =
+ try String.Map.find name !sum_map
+ with
+ | Not_found ->
+ CErrors.anomaly Pp.(str "trying to unfreeze unregistered summary " ++ str name)
in
- Int.Map.fold_right fold !summaries empty_frozen
-
-let unfreeze_summaries fs =
+ try decl.unfreeze_function state
+ with e when CErrors.noncritical e ->
+ let e = CErrors.push e in
+ Feedback.msg_warning
+ Pp.(seq [str "Error unfreezing summary "; str name; fnl (); CErrors.iprint e]);
+ iraise e
+
+let unfreeze_summaries ?(partial=false) { summaries; ml_module } =
(* The unfreezing of [ml_modules_summary] has to be anticipated since it
- * may modify the content of [summaries] ny loading new ML modules *)
- let (_, decl) =
- try Int.Map.find ml_modules_summary !summaries
- with Not_found -> anomaly (str "Undeclared summary " ++ str ml_modules ++ str ".")
- in
- let () = match fs.ml_module with
+ * may modify the content of [summaries] by loading new ML modules *)
+ begin match !sum_mod with
| None -> anomaly (str "Undeclared summary " ++ str ml_modules ++ str ".")
- | Some state -> decl.unfreeze_function state
- in
- let fold id (_, decl) states =
- if Int.equal id ml_modules_summary then states
- else match states with
- | [] ->
- let () = decl.init_function () in
- []
- | (nid, state) :: rstates ->
- if Int.equal id nid then
- let () = decl.unfreeze_function state in rstates
- else
- let () = decl.init_function () in states
+ | Some decl -> Option.iter (fun state -> decl.unfreeze_function state) ml_module
+ end;
+ (** We must be independent on the order of the map! *)
+ let ufz name decl =
+ try decl.unfreeze_function String.Map.(find name summaries)
+ with Not_found ->
+ if not partial then begin
+ Feedback.msg_warning Pp.(str "Summary was captured out of module scope for entry " ++ str name);
+ decl.init_function ()
+ end;
in
- let fold id decl state =
- try fold id decl state
- with e when CErrors.noncritical e ->
- let e = CErrors.push e in
- Feedback.msg_error
- Pp.(seq [str "Error unfreezing summary %s\n%s\n%!";
- str (name_of_summary id);
- CErrors.iprint e]);
- iraise e
- in
- (** We rely on the order of the frozen list, and the order of folding *)
- ignore (Int.Map.fold_left fold !summaries fs.summaries)
+ (* String.Map.iter unfreeze_single !sum_map *)
+ String.Map.iter ufz !sum_map
let init_summaries () =
- Int.Map.iter (fun _ (_, decl) -> decl.init_function ()) !summaries
+ String.Map.iter (fun _ decl -> decl.init_function ()) !sum_map
(** For global tables registered statically before the end of coqtop
launch, the following empty [init_function] could be used. *)
let nop () = ()
-(** Selective freeze *)
+(** Summary projection *)
+let project_from_summary { summaries } tag =
+ let id = unmangle (Dyn.repr tag) in
+ let state = String.Map.find id summaries in
+ Option.get (Dyn.Easy.prj state tag)
+
+let modify_summary st tag v =
+ let id = unmangle (Dyn.repr tag) in
+ let summaries = String.Map.set id (Dyn.Easy.inj v tag) st.summaries in
+ {st with summaries}
-type frozen_bits = (int * Dyn.t) list
+let remove_from_summary st tag =
+ let id = unmangle (Dyn.repr tag) in
+ let summaries = String.Map.remove id st.summaries in
+ {st with summaries}
+
+(** Selective freeze *)
-let ids_of_string_list complement ids =
- if not complement then List.map String.hash ids
- else
- let fold accu id =
- let id = String.hash id in
- Int.Set.remove id accu
- in
- let ids = List.fold_left fold !all_declared_summaries ids in
- Int.Set.elements ids
+type frozen_bits = Dyn.t String.Map.t
let freeze_summary ~marshallable ?(complement=false) ids =
- let ids = ids_of_string_list complement ids in
- List.map (fun id ->
- let (_, summary) = Int.Map.find id !summaries in
- id, summary.freeze_function marshallable)
- ids
-
-let unfreeze_summary datas =
- List.iter
- (fun (id, data) ->
- let (name, summary) = Int.Map.find id !summaries in
- try summary.unfreeze_function data
- with e ->
- let e = CErrors.push e in
- prerr_endline ("Exception unfreezing " ^ name);
- iraise e)
- datas
+ let sub_map = String.Map.filter (fun id _ -> complement <> List.(mem id ids)) !sum_map in
+ String.Map.map (fun decl -> decl.freeze_function marshallable) sub_map
+
+let unfreeze_summary = String.Map.iter unfreeze_single
let surgery_summary { summaries; ml_module } bits =
- let summaries = List.map (fun (id, _ as orig) ->
- try id, List.assoc id bits
- with Not_found -> orig)
- summaries in
+ let summaries =
+ String.Map.fold (fun hash state sum -> String.Map.set hash state sum ) summaries bits in
{ summaries; ml_module }
let project_summary { summaries; ml_module } ?(complement=false) ids =
- let ids = ids_of_string_list complement ids in
- List.filter (fun (id, _) -> List.mem id ids) summaries
+ String.Map.filter (fun name _ -> complement <> List.(mem name ids)) summaries
let pointer_equal l1 l2 =
let ptr_equal d1 d2 =
@@ -174,19 +155,22 @@ let pointer_equal l1 l2 =
match Dyn.eq t1 t2 with
| None -> false
| Some Refl -> x1 == x2
- in
+ in
+ let l1, l2 = String.Map.bindings l1, String.Map.bindings l2 in
CList.for_all2eq
(fun (id1,v1) (id2,v2) -> id1 = id2 && ptr_equal v1 v2) l1 l2
(** All-in-one reference declaration + registration *)
-let ref ?(freeze=fun _ r -> r) ~name x =
+let ref_tag ?(freeze=fun _ r -> r) ~name x =
let r = ref x in
- declare_summary name
+ let tag = declare_summary_tag name
{ freeze_function = (fun b -> freeze b !r);
unfreeze_function = ((:=) r);
- init_function = (fun () -> r := x) };
- r
+ init_function = (fun () -> r := x) } in
+ r, tag
+
+let ref ?freeze ~name x = fst @@ ref_tag ?freeze ~name x
module Local = struct
@@ -198,8 +182,7 @@ let (!) r =
let key, name = !r in
try CEphemeron.get key
with CEphemeron.InvalidKey ->
- let _, { init_function } =
- Int.Map.find (String.hash (mangle name)) !summaries in
+ let { init_function } = String.Map.find name !sum_map in
init_function ();
CEphemeron.get (fst !r)
diff --git a/library/summary.mli b/library/summary.mli
index d093d95f2..09447199e 100644
--- a/library/summary.mli
+++ b/library/summary.mli
@@ -36,6 +36,12 @@ type 'a summary_declaration = {
val declare_summary : string -> 'a summary_declaration -> unit
+(** We provide safe projection from the summary to the types stored in
+ it.*)
+module Dyn : Dyn.S
+
+val declare_summary_tag : string -> 'a summary_declaration -> 'a Dyn.tag
+
(** All-in-one reference declaration + summary registration.
It behaves just as OCaml's standard [ref] function, except
that a [declare_summary] is done, with [name] as string.
@@ -43,6 +49,7 @@ val declare_summary : string -> 'a summary_declaration -> unit
The [freeze_function] can be overridden *)
val ref : ?freeze:(marshallable -> 'a -> 'a) -> name:string -> 'a -> 'a ref
+val ref_tag : ?freeze:(marshallable -> 'a -> 'a) -> name:string -> 'a -> 'a ref * 'a Dyn.tag
(* As [ref] but the value is local to a process, i.e. not sent to, say, proof
* workers. It is useful to implement a local cache for example. *)
@@ -55,10 +62,11 @@ module Local : sig
end
-(** Special name for the summary of ML modules. This summary entry is
- special because its unfreeze may load ML code and hence add summary
- entries. Thus is has to be recognizable, and handled appropriately *)
-val ml_modules : string
+(** Special summary for ML modules. This summary entry is special
+ because its unfreeze may load ML code and hence add summary
+ entries. Thus is has to be recognizable, and handled properly.
+ *)
+val declare_ml_modules_summary : 'a summary_declaration -> unit
(** For global tables registered statically before the end of coqtop
launch, the following empty [init_function] could be used. *)
@@ -72,19 +80,34 @@ type frozen
val empty_frozen : frozen
val freeze_summaries : marshallable:marshallable -> frozen
-val unfreeze_summaries : frozen -> unit
+val unfreeze_summaries : ?partial:bool -> frozen -> unit
val init_summaries : unit -> unit
-(** The type [frozen_bits] is a snapshot of some of the registered tables *)
+(** Typed projection of the summary. Experimental API, use with CARE *)
+
+val modify_summary : frozen -> 'a Dyn.tag -> 'a -> frozen
+val project_from_summary : frozen -> 'a Dyn.tag -> 'a
+val remove_from_summary : frozen -> 'a Dyn.tag -> frozen
+
+(** The type [frozen_bits] is a snapshot of some of the registered
+ tables. It is DEPRECATED in favor of the typed projection
+ version. *)
+
type frozen_bits
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
-val freeze_summary :
- marshallable:marshallable -> ?complement:bool -> string list -> frozen_bits
+[@@@ocaml.warning "-3"]
+val freeze_summary : marshallable:marshallable -> ?complement:bool -> string list -> frozen_bits
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
val unfreeze_summary : frozen_bits -> unit
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
val surgery_summary : frozen -> frozen_bits -> frozen
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
val project_summary : frozen -> ?complement:bool -> string list -> frozen_bits
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
val pointer_equal : frozen_bits -> frozen_bits -> bool
+[@@ocaml.deprecated "Please use the typed version of summary projection"]
+[@@@ocaml.warning "+3"]
(** {6 Debug} *)
-
val dump : unit -> (int * string) list
diff --git a/man/coqmktop.1 b/man/coqmktop.1
deleted file mode 100644
index 810df782c..000000000
--- a/man/coqmktop.1
+++ /dev/null
@@ -1,71 +0,0 @@
-.TH COQ 1 "April 25, 2001"
-
-.SH NAME
-coqmktop \- The Coq Proof Assistant user-tactics linker
-
-
-.SH SYNOPSIS
-.B coqmktop
-[
-.I options
-]
-.I files
-
-
-.SH DESCRIPTION
-
-.B coqmktop
-builds a new Coq toplevel extended with user-tactics.
-.IR files \&
-are the Objective Caml object or library files
-(i.e. with suffix .cmo, .cmx, .cma or .cmxa) to link with the Coq system.
-The linker produces an executable Coq toplevel which can be called
-directly or through coqc(1), using the \-image option.
-
-.SH OPTIONS
-
-.TP
-.BI \-h
-Help. List the available options.
-
-.TP
-.BI \-srcdir \ dir
-Specify where the Coq source files are
-
-.TP
-.BI \-o \ exec\-file
-Specify the name of the resulting toplevel
-
-.TP
-.B \-opt
-Compile in native code
-
-.TP
-.B \-full
-Link high level tactics
-
-.TP
-.B \-top
-Build Coq on a ocaml toplevel (incompatible with
-.BR \-opt )
-
-.TP
-.BI \-R \ dir
-Specify recursively directories for Ocaml
-
-.TP
-.B \-v8
-Link with V8 grammar
-
-
-.SH SEE ALSO
-
-.BR coqtop (1),
-.BR ocamlmktop (1).
-.BR ocamlc (1).
-.BR ocamlopt (1).
-.br
-.I
-The Coq Reference Manual.
-.I
-The Coq web site: http://coq.inria.fr
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 0cf96d487..db68a75e0 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -267,17 +267,17 @@ GEXTEND Gram
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
"in"; c2 = operconstr LEVEL "200" ->
CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, None, [c1, None, None], [Loc.tag ~loc:!@loc ([(Loc.tag ~loc:!@loc [p])], c2)])
+ CCases (LetPatternStyle, None, [c1, None, None], [Loc.tag ~loc:!@loc ([[p]], c2)])
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
rt = case_type; "in"; c2 = operconstr LEVEL "200" ->
CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, Some rt, [c1, aliasvar p, None], [Loc.tag ~loc:!@loc ([(Loc.tag ~loc:!@loc [p])], c2)])
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, None], [Loc.tag ~loc:!@loc ([[p]], c2)])
| "let"; "'"; p=pattern; "in"; t = pattern LEVEL "200";
":="; c1 = operconstr LEVEL "200"; rt = case_type;
"in"; c2 = operconstr LEVEL "200" ->
CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [Loc.tag ~loc:!@loc ([(Loc.tag ~loc:!@loc [p])], c2)])
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [Loc.tag ~loc:!@loc ([[p]], c2)])
| "if"; c=operconstr LEVEL "200"; po = return_type;
"then"; b1=operconstr LEVEL "200";
"else"; b2=operconstr LEVEL "200" ->
@@ -362,7 +362,7 @@ GEXTEND Gram
[ [ OPT"|"; br=LIST0 eqn SEP "|" -> br ] ]
;
mult_pattern:
- [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> (Loc.tag ~loc:!@loc pl) ] ]
+ [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> pl ] ]
;
eqn:
[ [ pll = LIST1 mult_pattern SEP "|";
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 8e6a01aa3..b766f0c6b 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -611,8 +611,8 @@ let unfreeze (grams, lex) =
the lexer state should not be resetted, since it contains
keywords declared in g_*.ml4 *)
-let _ =
- Summary.declare_summary "GRAMMAR_LEXER"
+let parser_summary_tag =
+ Summary.declare_summary_tag "GRAMMAR_LEXER"
{ Summary.freeze_function = freeze;
Summary.unfreeze_function = unfreeze;
Summary.init_function = Summary.nop }
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index d17ccb0b4..3ca013a96 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -313,3 +313,6 @@ val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
(** Location Utils *)
val to_coqloc : Ploc.t -> Loc.t
val (!@) : Ploc.t -> Loc.t
+
+type frozen_t
+val parser_summary_tag : frozen_t Summary.Dyn.tag
diff --git a/plugins/derive/derive.ml b/plugins/derive/derive.ml
index fb65a8639..c8c4c2dad 100644
--- a/plugins/derive/derive.ml
+++ b/plugins/derive/derive.ml
@@ -38,9 +38,8 @@ let start_deriving f suchthat lemma =
let f_type = EConstr.Unsafe.to_constr f_type in
let ef = EConstr.Unsafe.to_constr ef 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 _ ->
+ let sigma, suchthat = Constrintern.interp_type_evars env' sigma suchthat in
+ TCons ( env' , sigma , suchthat , (fun sigma _ ->
TNil sigma))))))
in
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index 938bec25b..b81010c7b 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -40,17 +40,17 @@ let _=
in
declare_int_option gdopt
-let congruence_depth=ref 100
let _=
+ let congruence_depth=ref 100 in
let gdopt=
- { optdepr=false;
+ { optdepr=true; (* noop *)
optname="Congruence Depth";
optkey=["Congruence";"Depth"];
optread=(fun ()->Some !congruence_depth);
optwrite=
(function
- None->congruence_depth:=0
+ None->congruence_depth:=0
| Some i->congruence_depth:=(max i 0))}
in
declare_int_option gdopt
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index fa4353630..889c064b2 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -1497,7 +1497,7 @@ let do_build_inductive
let _time2 = System.get_time () in
try
with_full_print
- (Flags.silently (Command.do_mutual_inductive rel_inds (Flags.is_universe_polymorphism ()) false false))
+ (Flags.silently (ComInductive.do_mutual_inductive rel_inds (Flags.is_universe_polymorphism ()) false false))
Decl_kinds.Finite
with
| UserError(s,msg) as e ->
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 9e22ad306..071599d9c 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -158,8 +158,8 @@ let build_newrecursive
(fun (env,impls) (((_,recname),_),bl,arityc,_) ->
let arityc = Constrexpr_ops.mkCProdN bl arityc in
let arity,ctx = Constrintern.interp_type env0 sigma arityc in
- let evdref = ref (Evd.from_env env0) in
- let _, (_, impls') = Constrintern.interp_context_evars env evdref bl in
+ let evd = Evd.from_env env0 in
+ let evd, (_, (_, impls')) = Constrintern.interp_context_evars env evd bl in
let impl = Constrintern.compute_internalization_data env0 Constrintern.Recursive arity impls' in
let open Context.Named.Declaration in
(Environ.push_named (LocalAssum (recname,arity)) env, Id.Map.add recname impl impls))
@@ -406,7 +406,8 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
match fixpoint_exprl with
| [(((_,fname),pl),_,bl,ret_type,body),_] when not is_rec ->
let body = match body with | Some body -> body | None -> user_err ~hdr:"Function" (str "Body of Function must be given") in
- Command.do_definition
+ ComDefinition.do_definition
+ ~program_mode:false
fname
(Decl_kinds.Global,(Flags.is_universe_polymorphism ()),Decl_kinds.Definition) pl
bl None body (Some ret_type) (Lemmas.mk_hook (fun _ _ -> ()));
@@ -426,7 +427,7 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
in
evd,List.rev rev_pconstants
| _ ->
- Command.do_fixpoint Global (Flags.is_universe_polymorphism ()) fixpoint_exprl;
+ ComFixpoint.do_fixpoint Global (Flags.is_universe_polymorphism ()) fixpoint_exprl;
let evd,rev_pconstants =
List.fold_left
(fun (evd,l) ((((_,fname),_),_,_,_,_),_) ->
@@ -616,8 +617,8 @@ and rebuild_nal aux bk bl' nal typ =
let rebuild_bl aux bl typ = rebuild_bl aux bl typ
let recompute_binder_list (fixpoint_exprl : (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) list) =
- let fixl,ntns = Command.extract_fixpoint_components false fixpoint_exprl in
- let ((_,_,typel),_,ctx,_) = Command.interp_fixpoint fixl ntns in
+ let fixl,ntns = ComFixpoint.extract_fixpoint_components false fixpoint_exprl in
+ let ((_,_,typel),_,ctx,_) = ComFixpoint.interp_fixpoint ~cofix:false fixl ntns in
let constr_expr_typel =
with_full_print (List.map (fun c -> Constrextern.extern_constr false (Global.env ()) (Evd.from_ctx ctx) (EConstr.of_constr c))) typel in
let fixpoint_exprl_with_new_bl =
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index 8bf6e48fd..5a9248d47 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -183,7 +183,9 @@ let with_full_print f a =
and old_contextual_implicit_args = Impargs.is_contextual_implicit_args () in
let old_rawprint = !Flags.raw_print in
let old_printuniverses = !Constrextern.print_universes in
+ let old_printallowmatchdefaultclause = !Detyping.print_allow_match_default_clause in
Constrextern.print_universes := true;
+ Detyping.print_allow_match_default_clause := false;
Flags.raw_print := true;
Impargs.make_implicit_args false;
Impargs.make_strict_implicit_args false;
@@ -197,6 +199,7 @@ let with_full_print f a =
Impargs.make_contextual_implicit_args old_contextual_implicit_args;
Flags.raw_print := old_rawprint;
Constrextern.print_universes := old_printuniverses;
+ Detyping.print_allow_match_default_clause := old_printallowmatchdefaultclause;
Dumpglob.continue ();
res
with
@@ -206,6 +209,7 @@ let with_full_print f a =
Impargs.make_contextual_implicit_args old_contextual_implicit_args;
Flags.raw_print := old_rawprint;
Constrextern.print_universes := old_printuniverses;
+ Detyping.print_allow_match_default_clause := old_printallowmatchdefaultclause;
Dumpglob.continue ();
raise reraise
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
index 9e2774ff3..9fcb35f89 100644
--- a/plugins/funind/merge.ml
+++ b/plugins/funind/merge.ml
@@ -889,11 +889,11 @@ let merge_inductive (ind1: inductive) (ind2: inductive)
} in *)
let indexpr = glob_constr_list_to_inductive_expr prms1 prms2 mib1 mib2 shift_prm rawlist in
(* Declare inductive *)
- let indl,_,_ = Command.extract_mutual_inductive_declaration_components [(indexpr,[])] in
- let mie,pl,impls = Command.interp_mutual_inductive indl []
+ let indl,_,_ = ComInductive.extract_mutual_inductive_declaration_components [(indexpr,[])] in
+ let mie,pl,impls = ComInductive.interp_mutual_inductive indl []
false (* non-cumulative *) false (*FIXMEnon-poly *) false (* means not private *) Decl_kinds.Finite (* means: not coinductive *) in
(* Declare the mutual inductive block with its associated schemes *)
- ignore (Command.declare_mutual_inductive_with_eliminations mie pl impls)
+ ignore (ComInductive.declare_mutual_inductive_with_eliminations mie pl impls)
(* Find infos on identifier id. *)
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 766adfc63..363ad5dfc 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -1427,7 +1427,7 @@ let com_terminate
nb_args ctx
hook =
let start_proof ctx (tac_start:tactic) (tac_end:tactic) =
- let evmap, env = Pfedit.get_current_context () in
+ let evd, env = Pfedit.get_current_context () in
Lemmas.start_proof thm_name
(Global, false (* FIXME *), Proof Lemma) ~sign:(Environ.named_context_val env)
ctx (EConstr.of_constr (compute_terminate_type nb_args fonctional_ref)) hook;
@@ -1479,13 +1479,13 @@ let (com_eqn : int -> Id.t ->
| ConstRef c -> is_opaque_constant c
| _ -> anomaly ~label:"terminate_lemma" (Pp.str "not a constant.")
in
- let evmap, env = Pfedit.get_current_context () in
- let evmap = Evd.from_ctx (Evd.evar_universe_context evmap) in
+ let evd, env = Pfedit.get_current_context () in
+ let evd = Evd.from_ctx (Evd.evar_universe_context evd) in
let f_constr = constr_of_global f_ref in
let equation_lemma_type = subst1 f_constr equation_lemma_type in
(Lemmas.start_proof eq_name (Global, false, Proof Lemma)
~sign:(Environ.named_context_val env)
- evmap
+ evd
(EConstr.of_constr equation_lemma_type)
(Lemmas.mk_hook (fun _ _ -> ()));
ignore (by
@@ -1528,14 +1528,14 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let open Constr in
let open CVars in
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 evd = Evd.from_env env in
+ let evd, function_type = interp_type_evars env evd type_of_f in
let function_type = EConstr.Unsafe.to_constr function_type 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 evd, ty = interp_type_evars env evd ~impls:rec_impls eq in
let ty = EConstr.Unsafe.to_constr ty in
- let evm, nf = Evarutil.nf_evars_and_universes !evd in
+ let evd, nf = Evarutil.nf_evars_and_universes evd in
let equation_lemma_type = nf_betaiotazeta (EConstr.of_constr (nf ty)) in
let function_type = nf function_type in
let equation_lemma_type = EConstr.Unsafe.to_constr equation_lemma_type in
@@ -1560,16 +1560,16 @@ 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 =
- let univs = Entries.Monomorphic_const_entry (Evd.universe_context_set evm) in
+ let univs = Entries.Monomorphic_const_entry (Evd.universe_context_set evd) in
declare_fun functional_id (IsDefinition Decl_kinds.Definition) ~univs res
in
(* Refresh the global universes, now including those of _F *)
- let evm = Evd.from_env (Global.env ()) in
+ let evd = Evd.from_env (Global.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, evuctx =
- interp_constr env_with_pre_rec_args evm r
+ interp_constr env_with_pre_rec_args evd r
in
- let evm = Evd.from_ctx evuctx in
+ let evd = Evd.from_ctx evuctx in
let tcc_lemma_name = add_suffix function_name "_tcc" in
let tcc_lemma_constr = ref Undefined in
(* let _ = Pp.msgnl (str "relation := " ++ Printer.pr_lconstr_env env_with_pre_rec_args relation) in *)
@@ -1599,7 +1599,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
and functional_ref = destConst (constr_of_global functional_ref)
and eq_ref = destConst (constr_of_global eq_ref) in
generate_induction_principle f_ref tcc_lemma_constr
- functional_ref eq_ref rec_arg_num (EConstr.of_constr rec_arg_type) (nb_prod evm (EConstr.of_constr res)) (EConstr.of_constr relation);
+ functional_ref eq_ref rec_arg_num (EConstr.of_constr rec_arg_type) (nb_prod evd (EConstr.of_constr res)) (EConstr.of_constr relation);
Flags.if_verbose
msgnl (h 1 (Ppconstr.pr_id function_name ++
spc () ++ str"is defined" )++ fnl () ++
@@ -1618,5 +1618,5 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
term_id
using_lemmas
(List.length res_vars)
- evm (Lemmas.mk_hook hook))
+ evd (Lemmas.mk_hook hook))
()
diff --git a/plugins/ltac/g_ltac.ml4 b/plugins/ltac/g_ltac.ml4
index 8b9eb3983..ebf6e450b 100644
--- a/plugins/ltac/g_ltac.ml4
+++ b/plugins/ltac/g_ltac.ml4
@@ -78,11 +78,6 @@ let test_bracket_ident =
let hint = G_proofs.hint
-let warn_deprecated_appcontext =
- CWarnings.create ~name:"deprecated-appcontext" ~category:"deprecated"
- (fun () -> strbrk "appcontext is deprecated and will be removed " ++
- strbrk "in a future version")
-
GEXTEND Gram
GLOBAL: tactic tacdef_body tactic_expr binder_tactic tactic_arg command hint
tactic_mode constr_may_eval constr_eval toplevel_selector
@@ -242,12 +237,7 @@ GEXTEND Gram
match_pattern:
[ [ IDENT "context"; oid = OPT Constr.ident;
"["; pc = Constr.lconstr_pattern; "]" ->
- let mode = not (!Flags.tactic_context_compat) in
- Subterm (mode, oid, pc)
- | IDENT "appcontext"; oid = OPT Constr.ident;
- "["; pc = Constr.lconstr_pattern; "]" ->
- warn_deprecated_appcontext ~loc:!@loc ();
- Subterm (true,oid, pc)
+ Subterm (oid, pc)
| pc = Constr.lconstr_pattern -> Term pc ] ]
;
match_hyps:
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 6aa2f6f89..e5ff47356 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -526,11 +526,9 @@ let pr_goal_selector ~toplevel s =
let pr_match_pattern pr_pat = function
| Term a -> pr_pat a
- | Subterm (b,None,a) ->
- (** ppedrot: we don't make difference between [appcontext] and [context]
- anymore, and the interpretation is governed by a flag instead. *)
+ | Subterm (None,a) ->
keyword "context" ++ str" [ " ++ pr_pat a ++ str " ]"
- | Subterm (b,Some id,a) ->
+ | Subterm (Some id,a) ->
keyword "context" ++ spc () ++ pr_id id ++ str "[ " ++ pr_pat a ++ str " ]"
let pr_match_hyps pr_pat = function
diff --git a/plugins/ltac/profile_ltac.ml b/plugins/ltac/profile_ltac.ml
index 9ae8bfe65..5e3b7cf77 100644
--- a/plugins/ltac/profile_ltac.ml
+++ b/plugins/ltac/profile_ltac.ml
@@ -289,7 +289,7 @@ let rec find_in_stack what acc = function
| { name } as x :: rest when String.equal name what -> Some(acc, x, rest)
| { name } as x :: rest -> find_in_stack what (x :: acc) rest
-let exit_tactic start_time c =
+let exit_tactic ~count_call start_time c =
let diff = time () -. start_time in
match Local.(!stack) with
| [] | [_] ->
@@ -304,7 +304,7 @@ let exit_tactic start_time c =
let node = { node with
total = node.total +. diff;
local = node.local +. diff;
- ncalls = node.ncalls + 1;
+ ncalls = node.ncalls + (if count_call then 1 else 0);
max_total = max node.max_total diff;
} in
(* updating the stack *)
@@ -341,7 +341,7 @@ let tclFINALLY tac (finally : unit Proofview.tactic) =
(fun v -> finally <*> Proofview.tclUNIT v)
(fun (exn, info) -> finally <*> Proofview.tclZERO ~info exn)
-let do_profile s call_trace tac =
+let do_profile s call_trace ?(count_call=true) tac =
let open Proofview.Notations in
Proofview.tclLIFT (Proofview.NonLogical.make (fun () ->
if !is_profiling then
@@ -359,7 +359,7 @@ let do_profile s call_trace tac =
tac
(Proofview.tclLIFT (Proofview.NonLogical.make (fun () ->
(match call_trace with
- | (_, c) :: _ -> exit_tactic start_time c
+ | (_, c) :: _ -> exit_tactic ~count_call start_time c
| [] -> ()))))
| None -> tac
@@ -408,7 +408,7 @@ let print_results_filter ~cutoff ~filter =
let results =
SM.fold (fun _ -> merge_roots ~disjoint:true) !data (empty_treenode root) in
let results = merge_roots results Local.(CList.last !stack) in
- Feedback.msg_notice (to_string ~cutoff ~filter results)
+ Feedback.msg_info (to_string ~cutoff ~filter results)
;;
let print_results ~cutoff =
diff --git a/plugins/ltac/profile_ltac.mli b/plugins/ltac/profile_ltac.mli
index 52827cb36..feb777352 100644
--- a/plugins/ltac/profile_ltac.mli
+++ b/plugins/ltac/profile_ltac.mli
@@ -9,9 +9,39 @@
(** Ltac profiling primitives *)
+(* Note(JasonGross): Ltac semantics are a bit insane. There isn't
+ really a good notion of how many times a tactic has been "called",
+ because tactics can be partially evaluated, and it's unclear
+ whether the number of "calls" should be the number of times the
+ body is fetched and unfolded, or the number of times the code is
+ executed to a value, etc. The logic in [Tacinterp.eval_tactic]
+ gives a decent approximation, which I believe roughly corresponds
+ to the number of times that the engine runs the tactic value which
+ results from evaluating the tactic expression bound to the name
+ we're considering. However, this is a poor approximation of the
+ time spent in the tactic; we want to consider time spent evaluating
+ a tactic expression to a tactic value to be time spent in the
+ expression, not just time spent in the caller of the expression.
+ So we need to wrap some nodes in additional profiling calls which
+ don't count towards to total call count. Whether or not a call
+ "counts" is indicated by the [count_call] boolean argument.
+
+ Unfortunately, at present, we can get very strange call graphs when
+ a named tactic expression never runs as a tactic value: if we have
+ [Ltac t0 := t.] and [Ltac t1 := t0.], then [t1] is considered to
+ run 0(!) times. It evaluates to [t] during tactic expression
+ evaluation, and although the call trace records the fact that it
+ was called by [t0] which was called by [t1], the tactic running
+ phase never sees this. Thus we get one call tree (from expression
+ evaluation) that has [t1] calls [t0] calls [t], and another call
+ tree which says that the caller of [t1] calls [t] directly; the
+ expression evaluation time goes in the first tree, and the call
+ count and tactic running time goes in the second tree. Alas, I
+ suspect that fixing this requires a redesign of how the profiler
+ hooks into the tactic engine. *)
val do_profile :
string -> ('a * Tacexpr.ltac_call_kind) list ->
- 'b Proofview.tactic -> 'b Proofview.tactic
+ ?count_call:bool -> 'b Proofview.tactic -> 'b Proofview.tactic
val set_profiling : bool -> unit
@@ -46,4 +76,3 @@ type treenode = {
(* Returns the profiling results known by the current process *)
val get_local_profiling_results : unit -> treenode
val feedback_results : treenode -> unit
-
diff --git a/plugins/ltac/profile_ltac_tactics.ml4 b/plugins/ltac/profile_ltac_tactics.ml4
index 2b1106ee2..f09566063 100644
--- a/plugins/ltac/profile_ltac_tactics.ml4
+++ b/plugins/ltac/profile_ltac_tactics.ml4
@@ -13,7 +13,7 @@
open Profile_ltac
open Stdarg
-DECLARE PLUGIN "profile_ltac_plugin"
+DECLARE PLUGIN "ltac_plugin"
let tclSET_PROFILING b =
Proofview.tclLIFT (Proofview.NonLogical.make (fun () -> set_profiling b))
@@ -22,7 +22,7 @@ TACTIC EXTEND start_ltac_profiling
| [ "start" "ltac" "profiling" ] -> [ tclSET_PROFILING true ]
END
-TACTIC EXTEND stop_profiling
+TACTIC EXTEND stop_ltac_profiling
| [ "stop" "ltac" "profiling" ] -> [ tclSET_PROFILING false ]
END
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index c0060c5a7..a698b05dd 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -361,8 +361,8 @@ end) = struct
end
(* let my_type_of env evars c = Typing.e_type_of env evars c *)
-(* let mytypeofkey = Profile.declare_profile "my_type_of";; *)
-(* let my_type_of = Profile.profile3 mytypeofkey my_type_of *)
+(* let mytypeofkey = CProfile.declare_profile "my_type_of";; *)
+(* let my_type_of = CProfile.profile3 mytypeofkey my_type_of *)
let type_app_poly env env evd f args =
@@ -1781,7 +1781,9 @@ let declare_an_instance n s args =
let declare_instance a aeq n s = declare_an_instance n s [a;aeq]
let anew_instance global binders instance fields =
- new_instance (Flags.is_universe_polymorphism ())
+ let program_mode = Flags.is_program_mode () in
+ let poly = Flags.is_universe_polymorphism () in
+ new_instance ~program_mode poly
binders instance (Some (true, CAst.make @@ CRecord (fields)))
~global ~generalize:false ~refine:false Hints.empty_hint_info
@@ -2012,23 +2014,26 @@ let add_morphism glob binders m s n =
[cHole; s; m]))
in
let tac = Tacinterp.interp (make_tactic "add_morphism_tactic") in
- ignore(new_instance ~global:glob poly binders instance
- (Some (true, CAst.make @@ CRecord []))
- ~generalize:false ~tac ~hook:(declare_projection n instance_id) Hints.empty_hint_info)
+ let program_mode = Flags.is_program_mode () in
+ ignore(new_instance ~program_mode ~global:glob poly binders instance
+ (Some (true, CAst.make @@ CRecord []))
+ ~generalize:false ~tac ~hook:(declare_projection n instance_id) Hints.empty_hint_info)
(** Bind to "rewrite" too *)
(** Taken from original setoid_replace, to emulate the old rewrite semantics where
lemmas are first instantiated and then rewrite proceeds. *)
-let check_evar_map_of_evars_defs evd =
+let check_evar_map_of_evars_defs env evd =
let metas = Evd.meta_list evd in
let check_freemetas_is_empty rebus =
Evd.Metaset.iter
(fun m ->
- if Evd.meta_defined evd m then () else
- raise
- (Logic.RefinerError (Logic.UnresolvedBindings [Evd.meta_name evd m])))
+ if Evd.meta_defined evd m then ()
+ else begin
+ raise
+ (Logic.RefinerError (env, evd, Logic.UnresolvedBindings [Evd.meta_name evd m]))
+ end)
in
List.iter
(fun (_,binding) ->
@@ -2063,7 +2068,7 @@ let unification_rewrite l2r c1 c2 sigma prf car rel but env =
let c1 = if l2r then nf c' else nf c1
and c2 = if l2r then nf c2 else nf c'
and car = nf car and rel = nf rel in
- check_evar_map_of_evars_defs sigma;
+ check_evar_map_of_evars_defs env sigma;
let prf = nf prf in
let prfty = nf (Retyping.get_type_of env sigma prf) in
let sort = sort_of_rel env sigma but in
@@ -2084,8 +2089,8 @@ let get_hyp gl (c,l) clause l2r =
let general_rewrite_flags = { under_lambdas = false; on_morphisms = true }
-(* let rewriteclaustac_key = Profile.declare_profile "cl_rewrite_clause_tac";; *)
-(* let cl_rewrite_clause_tac = Profile.profile5 rewriteclaustac_key cl_rewrite_clause_tac *)
+(* let rewriteclaustac_key = CProfile.declare_profile "cl_rewrite_clause_tac";; *)
+(* let cl_rewrite_clause_tac = CProfile.profile5 rewriteclaustac_key cl_rewrite_clause_tac *)
(** Setoid rewriting when called with "rewrite" *)
let general_s_rewrite cl l2r occs (c,l) ~new_goals =
diff --git a/plugins/ltac/tacexpr.mli b/plugins/ltac/tacexpr.mli
index 9bd3efc6b..ccd555b61 100644
--- a/plugins/ltac/tacexpr.mli
+++ b/plugins/ltac/tacexpr.mli
@@ -81,7 +81,7 @@ type 'a with_bindings_arg = clear_flag * 'a with_bindings
(* Type of patterns *)
type 'a match_pattern =
| Term of 'a
- | Subterm of bool * Id.t option * 'a
+ | Subterm of Id.t option * 'a
(* Type of hypotheses for a Match Context rule *)
type 'a match_context_hyps =
diff --git a/plugins/ltac/tacintern.ml b/plugins/ltac/tacintern.ml
index b16b0a7ba..ebffde441 100644
--- a/plugins/ltac/tacintern.ml
+++ b/plugins/ltac/tacintern.ml
@@ -428,9 +428,9 @@ let intern_hyp_location ist ((occs,id),hl) =
(* Reads a pattern *)
let intern_pattern ist ?(as_type=false) ltacvars = function
- | Subterm (b,ido,pc) ->
+ | Subterm (ido,pc) ->
let (metas,pc) = intern_constr_pattern ist ~as_type:false ~ltacvars pc in
- ido, metas, Subterm (b,ido,pc)
+ ido, metas, Subterm (ido,pc)
| Term pc ->
let (metas,pc) = intern_constr_pattern ist ~as_type ~ltacvars pc in
None, metas, Term pc
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index e0d7eca5f..179952f28 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -420,7 +420,7 @@ let interp_hyp ist env sigma (loc,id as locid) =
with Not_found ->
(* Then look if bound in the proof context at calling time *)
if is_variable env id then id
- else Loc.raise ?loc (Logic.RefinerError (Logic.NoSuchHyp id))
+ else Loc.raise ?loc (Logic.RefinerError (env, sigma, Logic.NoSuchHyp id))
let interp_hyp_list_as_list ist env sigma (loc,id as x) =
try coerce_to_hyp_list env sigma (Id.Map.find id ist.lfun)
@@ -890,7 +890,7 @@ let interp_intro_pattern_naming_option ist env sigma = function
let interp_or_and_intro_pattern_option ist env sigma = function
| None -> sigma, None
| Some (ArgVar (loc,id)) ->
- (match coerce_to_intro_pattern env sigma (Id.Map.find id ist.lfun) with
+ (match interp_intro_pattern_var loc ist env sigma id with
| IntroAction (IntroOrAndPattern l) -> sigma, Some (loc,l)
| _ ->
user_err ?loc (str "Cannot coerce to a disjunctive/conjunctive pattern."))
@@ -1040,7 +1040,7 @@ let eval_pattern lfun ist env sigma (bvars,(glob,_),pat as c) =
(bvars,instantiate_pattern env sigma lfun pat)
let read_pattern lfun ist env sigma = function
- | Subterm (b,ido,c) -> Subterm (b,ido,eval_pattern lfun ist env sigma c)
+ | Subterm (ido,c) -> Subterm (ido,eval_pattern lfun ist env sigma c)
| Term c -> Term (eval_pattern lfun ist env sigma c)
(* Reads the hypotheses of a Match Context rule *)
@@ -1272,7 +1272,8 @@ and interp_ltac_reference ?loc' mustbetac ist r : Val.t Ftactic.t =
let extra = TacStore.set extra f_trace trace in
let ist = { lfun = Id.Map.empty; extra = extra; } in
let appl = GlbAppl[r,[]] in
- val_interp ~appl ist (Tacenv.interp_ltac r)
+ Profile_ltac.do_profile "interp_ltac_reference" trace ~count_call:false
+ (val_interp ~appl ist (Tacenv.interp_ltac r))
and interp_tacarg ist arg : Val.t Ftactic.t =
match arg with
@@ -1338,7 +1339,8 @@ and interp_app loc ist fv largs : Val.t Ftactic.t =
let ist = {
lfun = newlfun;
extra = TacStore.set ist.extra f_trace []; } in
- catch_error_tac trace (val_interp ist body) >>= fun v ->
+ Profile_ltac.do_profile "interp_app" trace ~count_call:false
+ (catch_error_tac trace (val_interp ist body)) >>= fun v ->
Ftactic.return (name_vfun (push_appl appl largs) v)
end
begin fun (e, info) ->
diff --git a/plugins/ltac/tacsubst.ml b/plugins/ltac/tacsubst.ml
index 918d1faeb..79bf3685e 100644
--- a/plugins/ltac/tacsubst.ml
+++ b/plugins/ltac/tacsubst.ml
@@ -121,7 +121,7 @@ let subst_raw_may_eval subst = function
| ConstrTerm c -> ConstrTerm (subst_glob_constr subst c)
let subst_match_pattern subst = function
- | Subterm (b,ido,pc) -> Subterm (b,ido,(subst_glob_constr_or_pattern subst pc))
+ | Subterm (ido,pc) -> Subterm (ido,(subst_glob_constr_or_pattern subst pc))
| Term pc -> Term (subst_glob_constr_or_pattern subst pc)
let rec subst_match_goal_hyps subst = function
diff --git a/plugins/ltac/tactic_matching.ml b/plugins/ltac/tactic_matching.ml
index 89b78e590..e87951dd7 100644
--- a/plugins/ltac/tactic_matching.ml
+++ b/plugins/ltac/tactic_matching.ml
@@ -237,7 +237,7 @@ module PatternMatching (E:StaticEnvironment) = struct
return lhs
with Constr_matching.PatternMatchingFailure -> fail
end
- | Subterm (with_app_context,id_ctxt,p) ->
+ | Subterm (id_ctxt,p) ->
let rec map s (e, info) =
{ stream = fun k ctx -> match IStream.peek s with
@@ -252,7 +252,7 @@ module PatternMatching (E:StaticEnvironment) = struct
| Some nctx -> Proofview.tclOR (k lhs nctx) (fun e -> (map s e).stream k ctx)
}
in
- map (Constr_matching.match_subterm_gen E.env E.sigma with_app_context p term) imatching_error
+ map (Constr_matching.match_subterm E.env E.sigma p term) imatching_error
(** [rule_match_term term rule] matches the term [term] with the
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index 047ca509b..8493dbdbb 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -1159,6 +1159,7 @@ let pf_interp_gen_aux ist gl to_ind ((oclr, occ), t) =
let (c, ucst), cl =
try fill_occ_pattern ~raise_NoMatch:true env sigma (EConstr.Unsafe.to_constr cl) pat occ 1
with NoMatch -> redex_of_pattern env pat, (EConstr.Unsafe.to_constr cl) in
+ let gl = pf_merge_uc ucst gl in
let c = EConstr.of_constr c in
let cl = EConstr.of_constr cl in
let clr = interp_clr sigma (oclr, (tag_of_cpattern t, c)) in
diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml
index bd9633afb..6032ed2af 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -143,14 +143,14 @@ let newssrcongrtac arg ist gl =
(** Coq rewrite compatibility flag *)
-let ssr_strict_match = ref false
let _ =
- Goptions.declare_bool_option
+ let ssr_strict_match = ref false in
+ Goptions.declare_bool_option
{ Goptions.optname = "strict redex matching";
Goptions.optkey = ["Match"; "Strict"];
Goptions.optread = (fun () -> !ssr_strict_match);
- Goptions.optdepr = false;
+ Goptions.optdepr = true; (* noop *)
Goptions.optwrite = (fun b -> ssr_strict_match := b) }
(** Rewrite rules *)
diff --git a/plugins/ssr/ssrvernac.ml4 b/plugins/ssr/ssrvernac.ml4
index 3efb7b914..4f530a0ae 100644
--- a/plugins/ssr/ssrvernac.ml4
+++ b/plugins/ssr/ssrvernac.ml4
@@ -74,7 +74,7 @@ let frozen_lexer = CLexer.get_keyword_state () ;;
let no_ct = None, None and no_rt = None in
let aliasvar = function
- | [_, [{ CAst.v = CPatAlias (_, id); loc }]] -> Some (loc,Name id)
+ | [[{ CAst.v = CPatAlias (_, id); loc }]] -> Some (loc,Name id)
| _ -> None in
let mk_cnotype mp = aliasvar mp, None in
let mk_ctype mp t = aliasvar mp, Some t in
@@ -86,14 +86,14 @@ let mk_pat c (na, t) = (c, na, t) in
GEXTEND Gram
GLOBAL: binder_constr;
ssr_rtype: [[ "return"; t = operconstr LEVEL "100" -> mk_rtype t ]];
- ssr_mpat: [[ p = pattern -> [Loc.tag ~loc:!@loc [p]] ]];
+ ssr_mpat: [[ p = pattern -> [[p]] ]];
ssr_dpat: [
[ mp = ssr_mpat; "in"; t = pattern; rt = ssr_rtype -> mp, mk_ctype mp t, rt
| mp = ssr_mpat; rt = ssr_rtype -> mp, mk_cnotype mp, rt
| mp = ssr_mpat -> mp, no_ct, no_rt
] ];
ssr_dthen: [[ dp = ssr_dpat; "then"; c = lconstr -> mk_dthen ~loc:!@loc dp c ]];
- ssr_elsepat: [[ "else" -> [Loc.tag ~loc:!@loc [CAst.make ~loc:!@loc @@ CPatAtom None]] ]];
+ ssr_elsepat: [[ "else" -> [[CAst.make ~loc:!@loc @@ CPatAtom None]] ]];
ssr_else: [[ mp = ssr_elsepat; c = lconstr -> Loc.tag ~loc:!@loc (mp, c) ]];
binder_constr: [
[ "if"; c = operconstr LEVEL "200"; "is"; db1 = ssr_dthen; b2 = ssr_else ->
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml4
index e63a05b78..d6dbad7a9 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml4
@@ -1228,7 +1228,7 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let sigma,pat= mk_tpattern ?hack env sigma0 (sigma,p) ok L2R (fs sigma t) in
sigma, [pat] in
match pattern with
- | None -> do_subst env0 concl0 concl0 1
+ | None -> do_subst env0 concl0 concl0 1, Evd.empty_evar_universe_context
| Some (sigma, (T rp | In_T rp)) ->
let rp = fs sigma rp in
let ise = create_evar_defs sigma in
@@ -1236,8 +1236,8 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let rp = mk_upat_for env0 sigma0 (ise, rp) all_ok in
let find_T, end_T = mk_tpattern_matcher ?raise_NoMatch sigma0 occ rp in
let concl = find_T env0 concl0 1 ~k:do_subst in
- let _ = end_T () in
- concl
+ let _, _, (_, us, _) = end_T () in
+ concl, us
| Some (sigma, (X_In_T (hole, p) | In_X_In_T (hole, p))) ->
let p = fs sigma p in
let occ = match pattern with Some (_, X_In_T _) -> occ | _ -> noindex in
@@ -1252,8 +1252,8 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let sigma, e_body = pop_evar p_sigma ex p in
fs p_sigma (find_X env (fs sigma p) h
~k:(fun env _ -> do_subst env e_body))) in
- let _ = end_X () in let _ = end_T () in
- concl
+ let _ = end_X () in let _, _, (_, us, _) = end_T () in
+ concl, us
| Some (sigma, E_In_X_In_T (e, hole, p)) ->
let p, e = fs sigma p, fs sigma e in
let ex = ex_value hole in
@@ -1268,8 +1268,9 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let sigma, e_body = pop_evar p_sigma ex p in
fs p_sigma (find_X env (fs sigma p) h ~k:(fun env c _ h ->
find_E env e_body h ~k:do_subst))) in
- let _ = end_E () in let _ = end_X () in let _ = end_T () in
- concl
+ let _,_,(_,us,_) = end_E () in
+ let _ = end_X () in let _ = end_T () in
+ concl, us
| Some (sigma, E_As_X_In_T (e, hole, p)) ->
let p, e = fs sigma p, fs sigma e in
let ex = ex_value hole in
@@ -1287,8 +1288,8 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let e_sigma = unify_HO env sigma (EConstr.of_constr e_body) (EConstr.of_constr e) in
let e_body = fs e_sigma e in
do_subst env e_body e_body h))) in
- let _ = end_X () in let _ = end_TE () in
- concl
+ let _ = end_X () in let _,_,(_,us,_) = end_TE () in
+ concl, us
;;
let redex_of_pattern ?(resolve_typeclasses=false) env (sigma, p) =
@@ -1306,12 +1307,14 @@ let fill_occ_pattern ?raise_NoMatch env sigma cl pat occ h =
let find_R, conclude =
let r = ref None in
(fun env c _ h' ->
- do_once r (fun () -> c, Evd.empty_evar_universe_context);
+ do_once r (fun () -> c);
if do_make_rel then mkRel (h'+h-1) else c),
- (fun _ -> if !r = None then redex_of_pattern env pat else assert_done r) in
- let cl = eval_pattern ?raise_NoMatch env sigma cl (Some pat) occ find_R in
+ (fun _ -> if !r = None then fst(redex_of_pattern env pat)
+ else assert_done r) in
+ let cl, us =
+ eval_pattern ?raise_NoMatch env sigma cl (Some pat) occ find_R in
let e = conclude cl in
- e, cl
+ (e, us), cl
;;
(* clenup interface for external use *)
@@ -1319,6 +1322,10 @@ let mk_tpattern ?p_origin env sigma0 sigma_t f dir c =
mk_tpattern ?p_origin env sigma0 sigma_t f dir c
;;
+let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
+ fst (eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst)
+;;
+
let pf_fill_occ env concl occ sigma0 p (sigma, t) ok h =
let p = EConstr.Unsafe.to_constr p in
let concl = EConstr.Unsafe.to_constr concl in
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 4f3669a2b..1207c967b 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -1566,11 +1566,9 @@ substituer après par les initiaux *)
(* builds the matrix of equations testing that each eqn has n patterns
* and linearizing the _ patterns.
- * Syntactic correctness has already been done in astterm *)
+ * Syntactic correctness has already been done in constrintern *)
let matx_of_eqns env eqns =
- let build_eqn (loc,(ids,lpat,rhs)) =
- let initial_lpat,initial_rhs = lpat,rhs in
- let initial_rhs = rhs in
+ let build_eqn (loc,(ids,initial_lpat,initial_rhs)) =
let avoid = ids_of_named_context_val (named_context_val env) in
let avoid = List.fold_left (fun accu id -> Id.Set.add id accu) avoid ids in
let rhs =
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index c36630f5d..6d5ee504e 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -322,16 +322,16 @@ let coercion_value { coe_value = c; coe_type = t; coe_context = ctx;
(* pretty-print functions are now in Pretty *)
(* rajouter une coercion dans le graphe *)
-let path_printer = ref (fun _ -> str "<a class path>"
- : (Bijint.Index.t * Bijint.Index.t) * inheritance_path -> Pp.t)
+let path_printer : (env -> Evd.evar_map -> (Bijint.Index.t * Bijint.Index.t) * inheritance_path -> Pp.t) ref =
+ ref (fun _ _ _ -> str "<a class path>")
let install_path_printer f = path_printer := f
-let print_path x = !path_printer x
+let print_path env sigma x = !path_printer env sigma x
-let message_ambig l =
- (str"Ambiguous paths:" ++ spc () ++
- prlist_with_sep fnl (fun ijp -> print_path ijp) l)
+let message_ambig env sigma l =
+ str"Ambiguous paths:" ++ spc () ++
+ prlist_with_sep fnl (fun ijp -> print_path env sigma ijp) l
(* add_coercion_in_graph : coe_index * cl_index * cl_index -> unit
coercion,source,target *)
@@ -344,8 +344,8 @@ let different_class_params i =
| CL_IND i -> Global.is_polymorphic (IndRef i)
| CL_CONST c -> Global.is_polymorphic (ConstRef c)
| _ -> false
-
-let add_coercion_in_graph (ic,source,target) =
+
+let add_coercion_in_graph env sigma (ic,source,target) =
let old_inheritance_graph = !inheritance_graph in
let ambig_paths =
(ref [] : ((cl_index * cl_index) * inheritance_path) list ref) in
@@ -387,7 +387,7 @@ let add_coercion_in_graph (ic,source,target) =
end;
let is_ambig = match !ambig_paths with [] -> false | _ -> true in
if is_ambig && not !Flags.quiet then
- Feedback.msg_info (message_ambig !ambig_paths)
+ Feedback.msg_info (message_ambig env sigma !ambig_paths)
type coercion = {
coercion_type : coe_typ;
@@ -433,13 +433,13 @@ let _ =
optread = (fun () -> !automatically_import_coercions);
optwrite = (:=) automatically_import_coercions }
-let cache_coercion (_, c) =
+let cache_coercion env sigma (_, c) =
let () = add_class c.coercion_source in
let () = add_class c.coercion_target in
let is, _ = class_info c.coercion_source in
let it, _ = class_info c.coercion_target in
- let value, ctx = Universes.fresh_global_instance (Global.env()) c.coercion_type in
- let typ = Retyping.get_type_of (Global.env ()) Evd.empty (EConstr.of_constr value) in
+ let value, ctx = Universes.fresh_global_instance env c.coercion_type in
+ let typ = Retyping.get_type_of env sigma (EConstr.of_constr value) in
let typ = EConstr.Unsafe.to_constr typ in
let xf =
{ coe_value = value;
@@ -450,15 +450,15 @@ let cache_coercion (_, c) =
coe_is_projection = c.coercion_is_proj;
coe_param = c.coercion_params } in
let () = add_new_coercion c.coercion_type xf in
- add_coercion_in_graph (xf,is,it)
+ add_coercion_in_graph env sigma (xf,is,it)
let load_coercion _ o =
if !automatically_import_coercions then
- cache_coercion o
+ cache_coercion (Global.env ()) Evd.empty o
let open_coercion i o =
if Int.equal i 1 && not !automatically_import_coercions then
- cache_coercion o
+ cache_coercion (Global.env ()) Evd.empty o
let subst_coercion (subst, c) =
let coe = subst_coe_typ subst c.coercion_type in
@@ -497,7 +497,9 @@ let inCoercion : coercion -> obj =
declare_object {(default_object "COERCION") with
open_function = open_coercion;
load_function = load_coercion;
- cache_function = cache_coercion;
+ cache_function = (fun objn ->
+ let env = Global.env () in cache_coercion env Evd.empty objn
+ );
subst_function = subst_coercion;
classify_function = classify_coercion;
discharge_function = discharge_coercion }
diff --git a/pretyping/classops.mli b/pretyping/classops.mli
index b41d0efac..47b41f17b 100644
--- a/pretyping/classops.mli
+++ b/pretyping/classops.mli
@@ -96,7 +96,7 @@ val lookup_pattern_path_between :
(**/**)
(* Crade *)
val install_path_printer :
- ((cl_index * cl_index) * inheritance_path -> Pp.t) -> unit
+ (env -> evar_map -> (cl_index * cl_index) * inheritance_path -> Pp.t) -> unit
(**/**)
(** {6 This is for printing purpose } *)
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 478ba73fd..ec7c3077f 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -206,7 +206,7 @@ let merge_binding sigma allow_bound_rels ctx n cT subst =
in
constrain sigma n c subst
-let matches_core env sigma allow_partial_app allow_bound_rels
+let matches_core env sigma allow_bound_rels
(binding_vars,pat) c =
let open EConstr in
let convref ref c =
@@ -260,7 +260,7 @@ let matches_core env sigma allow_partial_app allow_bound_rels
| PApp (PApp (h, a1), a2), _ ->
sorec ctx env subst (PApp(h,Array.append a1 a2)) t
- | PApp (PMeta meta,args1), App (c2,args2) when allow_partial_app ->
+ | PApp (PMeta meta,args1), App (c2,args2) ->
(let diff = Array.length args2 - Array.length args1 in
if diff >= 0 then
let args21, args22 = Array.chop diff args2 in
@@ -373,14 +373,14 @@ let matches_core env sigma allow_partial_app allow_bound_rels
in
sorec [] env (Id.Map.empty, Id.Map.empty) pat c
-let matches_core_closed env sigma allow_partial_app pat c =
- let names, subst = matches_core env sigma allow_partial_app false pat c in
+let matches_core_closed env sigma pat c =
+ let names, subst = matches_core env sigma false pat c in
(names, Id.Map.map snd subst)
-let extended_matches env sigma = matches_core env sigma true true
+let extended_matches env sigma = matches_core env sigma true
let matches env sigma pat c =
- snd (matches_core_closed env sigma true (Id.Set.empty,pat) c)
+ snd (matches_core_closed env sigma (Id.Set.empty,pat) c)
let special_meta = (-1)
@@ -405,9 +405,9 @@ let matches_head env sigma pat c =
matches env sigma pat head
(* Tells if it is an authorized occurrence and if the instance is closed *)
-let authorized_occ env sigma partial_app closed pat c mk_ctx =
+let authorized_occ env sigma closed pat c mk_ctx =
try
- let subst = matches_core_closed env sigma partial_app pat c in
+ let subst = matches_core_closed env sigma pat c in
if closed && Id.Map.exists (fun _ c -> not (closed0 sigma c)) (snd subst)
then (fun next -> next ())
else (fun next -> mkresult subst (mk_ctx (mkMeta special_meta)) next)
@@ -416,10 +416,10 @@ let authorized_occ env sigma partial_app closed pat c mk_ctx =
let subargs env v = Array.map_to_list (fun c -> (env, c)) v
(* Tries to match a subterm of [c] with [pat] *)
-let sub_match ?(partial_app=false) ?(closed=true) env sigma pat c =
+let sub_match ?(closed=true) env sigma pat c =
let open EConstr in
let rec aux env c mk_ctx next =
- let here = authorized_occ env sigma partial_app closed pat c mk_ctx in
+ let here = authorized_occ env sigma closed pat c mk_ctx in
let next () = match EConstr.kind sigma c with
| Cast (c1,k,c2) ->
let next_mk_ctx = function
@@ -449,34 +449,12 @@ let sub_match ?(partial_app=false) ?(closed=true) env sigma pat c =
let env' = EConstr.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
- if partial_app then
- if topdown then
- let lc1 = Array.sub lc 0 (Array.length lc - 1) in
- let app = mkApp (c1,lc1) in
- let mk_ctx = function
- | [app';c] -> mk_ctx (mkApp (app',[|c|]))
- | _ -> assert false in
- try_aux [(env, app); (env, Array.last lc)] mk_ctx next
- else
- let rec aux2 app args next =
- match args with
- | [] ->
- let mk_ctx le =
- mk_ctx (mkApp (List.hd le, Array.of_list (List.tl le))) in
- let sub = (env, c1) :: subargs env lc in
- try_aux sub mk_ctx next
- | arg :: args ->
- let app = mkApp (app,[|arg|]) in
- let next () = aux2 app args next in
- let mk_ctx ce = mk_ctx (mkApp (ce, Array.of_list args)) in
- aux env app mk_ctx next in
- aux2 c1 (Array.to_list lc) next
- else
- let mk_ctx le =
- mk_ctx (mkApp (List.hd le, Array.of_list (List.tl le))) in
- let sub = (env, c1) :: subargs env lc in
- try_aux sub mk_ctx next
+ let lc1 = Array.sub lc 0 (Array.length lc - 1) in
+ let app = mkApp (c1,lc1) in
+ let mk_ctx = function
+ | [app';c] -> mk_ctx (mkApp (app',[|c|]))
+ | _ -> assert false in
+ try_aux [(env, app); (env, Array.last lc)] mk_ctx next
| Case (ci,hd,c1,lc) ->
let next_mk_ctx = function
| c1 :: hd :: lc -> mk_ctx (mkCase (ci,hd,c1,Array.of_list lc))
@@ -499,14 +477,11 @@ let sub_match ?(partial_app=false) ?(closed=true) env sigma pat c =
let sub = subargs env types @ subargs env bodies in
try_aux sub next_mk_ctx next
| Proj (p,c') ->
- let next_mk_ctx le = mk_ctx (mkProj (p,List.hd le)) in
- if partial_app then
- try
- let term = Retyping.expand_projection env sigma p c' [] in
- aux env term mk_ctx next
- with Retyping.RetypeError _ -> next ()
- else
- try_aux [env, c'] next_mk_ctx next
+ begin try
+ let term = Retyping.expand_projection env sigma p c' [] in
+ aux env term mk_ctx next
+ with Retyping.RetypeError _ -> next ()
+ end
| Construct _| Ind _|Evar _|Const _ | Rel _|Meta _|Var _|Sort _ ->
next ()
in
@@ -527,13 +502,7 @@ let sub_match ?(partial_app=false) ?(closed=true) env sigma pat c =
let result () = aux env c (fun x -> x) lempty in
IStream.thunk result
-let match_subterm env sigma pat c = sub_match env sigma (Id.Set.empty,pat) c
-
-let match_appsubterm env sigma pat c =
- sub_match ~partial_app:true env sigma (Id.Set.empty,pat) c
-
-let match_subterm_gen env sigma app pat c =
- sub_match ~partial_app:app env sigma pat c
+let match_subterm env sigma pat c = sub_match env sigma pat c
let is_matching env sigma pat c =
try let _ = matches env sigma pat c in true
@@ -545,5 +514,5 @@ let is_matching_head env sigma pat c =
let is_matching_appsubterm ?(closed=true) env sigma pat c =
let pat = (Id.Set.empty,pat) in
- let results = sub_match ~partial_app:true ~closed env sigma pat c in
+ let results = sub_match ~closed env sigma pat c in
not (IStream.is_empty results)
diff --git a/pretyping/constr_matching.mli b/pretyping/constr_matching.mli
index 60e1c34a1..e4d9ff9e1 100644
--- a/pretyping/constr_matching.mli
+++ b/pretyping/constr_matching.mli
@@ -61,18 +61,10 @@ type matching_result =
{ m_sub : bound_ident_map * patvar_map;
m_ctx : EConstr.t }
-(** [match_subterm n pat c] returns the substitution and the context
- corresponding to each **closed** subterm of [c] matching [pat]. *)
-val match_subterm : env -> Evd.evar_map -> constr_pattern -> constr -> matching_result IStream.t
-
-(** [match_appsubterm pat c] returns the substitution and the context
+(** [match_subterm pat c] returns the substitution and the context
corresponding to each **closed** subterm of [c] matching [pat],
considering application contexts as well. *)
-val match_appsubterm : env -> Evd.evar_map -> constr_pattern -> constr -> matching_result IStream.t
-
-(** [match_subterm_gen] calls either [match_subterm] or [match_appsubterm] *)
-val match_subterm_gen : env -> Evd.evar_map ->
- bool (** true = with app context *) ->
+val match_subterm : env -> Evd.evar_map ->
binding_bound_vars * constr_pattern -> constr ->
matching_result IStream.t
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 6527ba935..23993243f 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -252,6 +252,89 @@ let lookup_index_as_renamed env sigma t n =
in lookup n 1 t
(**********************************************************************)
+(* Factorization of match patterns *)
+
+let print_factorize_match_patterns = ref true
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optdepr = false;
+ optname = "factorization of \"match\" patterns in printing";
+ optkey = ["Printing";"Factorizable";"Match";"Patterns"];
+ optread = (fun () -> !print_factorize_match_patterns);
+ optwrite = (fun b -> print_factorize_match_patterns := b) }
+
+let print_allow_match_default_clause = ref true
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optdepr = false;
+ optname = "possible use of \"match\" default pattern in printing";
+ optkey = ["Printing";"Allow";"Match";"Default";"Clause"];
+ optread = (fun () -> !print_allow_match_default_clause);
+ optwrite = (fun b -> print_allow_match_default_clause := b) }
+
+let rec join_eqns (ids,rhs as x) patll = function
+ | (loc,(ids',patl',rhs') as eqn')::rest ->
+ if not !Flags.raw_print && !print_factorize_match_patterns &&
+ List.eq_set Id.equal ids ids' && glob_constr_eq rhs rhs'
+ then
+ join_eqns x (patl'::patll) rest
+ else
+ let eqn,rest = join_eqns x patll rest in
+ eqn, eqn'::rest
+ | [] ->
+ patll, []
+
+let number_of_patterns (_gloc,(_ids,patll,_rhs)) = List.length patll
+
+let is_default_candidate (_gloc,(ids,_patll,_rhs) ) = ids = []
+
+let rec move_more_factorized_default_candidate_to_end eqn n = function
+ | eqn' :: eqns ->
+ let set,get = set_temporary_memory () in
+ if is_default_candidate eqn' && set (number_of_patterns eqn') >= n then
+ let isbest, dft, eqns = move_more_factorized_default_candidate_to_end eqn' (get ()) eqns in
+ if isbest then false, dft, eqns else false, dft, eqn' :: eqns
+ else
+ let isbest, dft, eqns = move_more_factorized_default_candidate_to_end eqn n eqns in
+ isbest, dft, eqn' :: eqns
+ | [] -> true, Some eqn, []
+
+let rec select_default_clause = function
+ | eqn :: eqns ->
+ let set,get = set_temporary_memory () in
+ if is_default_candidate eqn && set (number_of_patterns eqn) > 1 then
+ let isbest, dft, eqns = move_more_factorized_default_candidate_to_end eqn (get ()) eqns in
+ if isbest then dft, eqns else dft, eqn :: eqns
+ else
+ let dft, eqns = select_default_clause eqns in dft, eqn :: eqns
+ | [] -> None, []
+
+let factorize_eqns eqns =
+ let rec aux found = function
+ | (loc,(ids,patl,rhs))::rest ->
+ let patll,rest = join_eqns (ids,rhs) [patl] rest in
+ aux ((loc,(ids,patll,rhs))::found) rest
+ | [] ->
+ found in
+ let eqns = aux [] (List.rev eqns) in
+ let mk_anon patl = List.map (fun _ -> DAst.make @@ PatVar Anonymous) patl in
+ if not !Flags.raw_print && !print_allow_match_default_clause && eqns <> [] then
+ match select_default_clause eqns with
+ (* At least two clauses and the last one is disjunctive with no variables *)
+ | Some (gloc,([],patl::_::_,rhs)), (_::_ as eqns) -> eqns@[gloc,([],[mk_anon patl],rhs)]
+ (* Only one clause which is disjunctive with no variables: we keep at least one constructor *)
+ (* so that it is not interpreted as a dummy "match" *)
+ | Some (gloc,([],patl::patl'::_,rhs)), [] -> [gloc,([],[patl;mk_anon patl'],rhs)]
+ | Some (_,((_::_,_,_ | _,([]|[_]),_))), _ -> assert false
+ | None, eqns -> eqns
+ else
+ eqns
+
+(**********************************************************************)
(* Fragile algorithm to reverse pattern-matching compilation *)
let update_name sigma na ((_,(e,_)),c) =
@@ -284,13 +367,12 @@ let rec decomp_branch tags nal b (avoid,env as e) sigma c =
let rec build_tree na isgoal e sigma ci cl =
let mkpat n rhs pl = DAst.make @@ PatCstr((ci.ci_ind,n+1),pl,update_name sigma na rhs) in
let cnl = ci.ci_pp_info.cstr_tags in
- let cna = ci.ci_cstr_nargs in
List.flatten
(List.init (Array.length cl)
- (fun i -> contract_branch isgoal e sigma (cnl.(i),cna.(i),mkpat i,cl.(i))))
+ (fun i -> contract_branch isgoal e sigma (cnl.(i),mkpat i,cl.(i))))
and align_tree nal isgoal (e,c as rhs) sigma = match nal with
- | [] -> [[],rhs]
+ | [] -> [Id.Set.empty,[],rhs]
| na::nal ->
match EConstr.kind sigma c with
| Case (ci,p,c,cl) when
@@ -300,19 +382,20 @@ and align_tree nal isgoal (e,c as rhs) sigma = match nal with
computable sigma p (List.length ci.ci_pp_info.ind_tags) (* FIXME: can do better *) ->
let clauses = build_tree na isgoal e sigma ci cl in
List.flatten
- (List.map (fun (pat,rhs) ->
+ (List.map (fun (ids,pat,rhs) ->
let lines = align_tree nal isgoal rhs sigma in
- List.map (fun (hd,rest) -> pat::hd,rest) lines)
+ List.map (fun (ids',hd,rest) -> Id.Set.fold Id.Set.add ids ids',pat::hd,rest) lines)
clauses)
| _ ->
- let pat = DAst.make @@ PatVar(update_name sigma na rhs) in
- let mat = align_tree nal isgoal rhs sigma in
- List.map (fun (hd,rest) -> pat::hd,rest) mat
+ let na = update_name sigma na rhs in
+ let pat = DAst.make @@ PatVar na in
+ let mat = align_tree nal isgoal rhs sigma in
+ List.map (fun (ids,hd,rest) -> Nameops.Name.fold_right Id.Set.add na ids,pat::hd,rest) mat
-and contract_branch isgoal e sigma (cdn,can,mkpat,b) =
- let nal,rhs = decomp_branch cdn [] isgoal e sigma b in
+and contract_branch isgoal e sigma (cdn,mkpat,rhs) =
+ let nal,rhs = decomp_branch cdn [] isgoal e sigma rhs in
let mat = align_tree nal isgoal rhs sigma in
- List.map (fun (hd,rhs) -> (mkpat rhs hd,rhs)) mat
+ List.map (fun (ids,hd,rhs) -> ids,mkpat rhs hd,rhs) mat
(**********************************************************************)
(* Transform internal representation of pattern-matching into list of *)
@@ -648,7 +731,7 @@ and detype_eqns d flags avoid env sigma ci computable constructs consnargsl bl =
try
if !Flags.raw_print || not (reverse_matching ()) then raise Exit;
let mat = build_tree Anonymous (snd flags) (avoid,env) sigma ci bl in
- List.map (fun (pat,((avoid,env),c)) -> Loc.tag ([],[pat],detype d flags avoid env sigma c))
+ List.map (fun (ids,pat,((avoid,env),c)) -> Loc.tag (Id.Set.elements ids,[pat],detype d flags avoid env sigma c))
mat
with e when CErrors.noncritical e ->
Array.to_list
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index cb1c0d8d4..f150cb195 100644
--- a/pretyping/detyping.mli
+++ b/pretyping/detyping.mli
@@ -26,10 +26,20 @@ val print_universes : bool ref
(** If true, prints full local context of evars *)
val print_evar_arguments : bool ref
+(** If true, contract branches with same r.h.s. and same matching
+ variables in a disjunctive pattern *)
+val print_factorize_match_patterns : bool ref
+
+(** If true and the last non unique clause of a "match" is a
+ variable-free disjunctive pattern, turn it into a catch-call case *)
+val print_allow_match_default_clause : bool ref
+
val subst_cases_pattern : substitution -> cases_pattern -> cases_pattern
val subst_glob_constr : substitution -> glob_constr -> glob_constr
+val factorize_eqns : 'a cases_clauses_g -> 'a disjunctive_cases_clauses_g
+
(** [detype isgoal avoid ctx c] turns a closed [c], into a glob_constr
de Bruijn indexes are turned to bound names, avoiding names in [avoid]
[isgoal] tells if naming must avoid global-level synonyms as intro does
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index e5776d2ec..cb8844623 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -1063,8 +1063,8 @@ let evar_conv_x ts = evar_conv_x (ts, true)
(* Profiling *)
let evar_conv_x =
if Flags.profile then
- let evar_conv_xkey = Profile.declare_profile "evar_conv_x" in
- Profile.profile6 evar_conv_xkey evar_conv_x
+ let evar_conv_xkey = CProfile.declare_profile "evar_conv_x" in
+ CProfile.profile6 evar_conv_xkey evar_conv_x
else evar_conv_x
let evar_conv_hook_get, evar_conv_hook_set = Hook.make ~default:evar_conv_x ()
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index dafe8cb26..79e0afa72 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -436,11 +436,11 @@ let stop_profiler m_pid =
match profiler_platform() with
"Unix (Linux)" -> stop_profiler_linux m_pid
| _ -> ()
-
+
let native_norm env sigma c ty =
let c = EConstr.Unsafe.to_constr c in
let ty = EConstr.Unsafe.to_constr ty in
- if Coq_config.no_native_compiler then
+ if not Coq_config.native_compiler then
user_err Pp.(str "Native_compute reduction has been disabled at configure time.")
else
let penv = Environ.pre_env env in
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 318176611..ac8846854 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -294,12 +294,12 @@ sig
val append_app : 'a array -> 'a t -> 'a t
val decomp : 'a t -> ('a * 'a t) option
val decomp_node_last : 'a app_node -> 'a t -> ('a * 'a t)
- val equal : ('a * int -> 'a * int -> bool) -> (('a, 'a) pfixpoint * int -> ('a, 'a) pfixpoint * int -> bool)
- -> 'a t -> 'a t -> (int * int) option
+ val equal : ('a -> 'a -> bool) -> (('a, 'a) pfixpoint -> ('a, 'a) pfixpoint -> bool)
+ -> 'a t -> 'a t -> bool
val compare_shape : 'a t -> 'a t -> bool
val map : ('a -> 'a) -> 'a t -> 'a t
val fold2 : ('a -> constr -> constr -> 'a) -> 'a ->
- constr t -> constr t -> 'a * int * int
+ constr t -> constr t -> 'a
val append_app_list : 'a list -> 'a t -> 'a t
val strip_app : 'a t -> 'a t * 'a t
val strip_n_app : int -> 'a t -> ('a t * 'a * 'a t) option
@@ -397,44 +397,37 @@ struct
else (l.(j), sk)
let equal f f_fix sk1 sk2 =
- let equal_cst_member x lft1 y lft2 =
+ let equal_cst_member x y =
match x, y with
| Cst_const (c1,u1), Cst_const (c2, u2) ->
- Constant.equal c1 c2 && Univ.Instance.equal u1 u2
+ Constant.equal c1 c2 && Univ.Instance.equal u1 u2
| Cst_proj p1, Cst_proj p2 ->
- Constant.equal (Projection.constant p1) (Projection.constant p2)
+ Constant.equal (Projection.constant p1) (Projection.constant p2)
| _, _ -> false
in
- let rec equal_rec sk1 lft1 sk2 lft2 =
+ let rec equal_rec sk1 sk2 =
match sk1,sk2 with
- | [],[] -> Some (lft1,lft2)
+ | [],[] -> true
| App a1 :: s1, App a2 :: s2 ->
- let t1,s1' = decomp_node_last a1 s1 in
- let t2,s2' = decomp_node_last a2 s2 in
- if f (t1,lft1) (t2,lft2) then equal_rec s1' lft1 s2' lft2 else None
+ let t1,s1' = decomp_node_last a1 s1 in
+ let t2,s2' = decomp_node_last a2 s2 in
+ (f t1 t2) && (equal_rec s1' s2')
| Case (_,t1,a1,_) :: s1, Case (_,t2,a2,_) :: s2 ->
- if f (t1,lft1) (t2,lft2) && CArray.equal (fun x y -> f (x,lft1) (y,lft2)) a1 a2
- then equal_rec s1 lft1 s2 lft2
- else None
+ f t1 t2 && CArray.equal (fun x y -> f x y) a1 a2 && equal_rec s1 s2
| (Proj (n1,m1,p,_)::s1, Proj(n2,m2,p2,_)::s2) ->
- if Int.equal n1 n2 && Int.equal m1 m2
- && Constant.equal (Projection.constant p) (Projection.constant p2)
- then equal_rec s1 lft1 s2 lft2
- else None
+ Int.equal n1 n2 && Int.equal m1 m2
+ && Constant.equal (Projection.constant p) (Projection.constant p2)
+ && equal_rec s1 s2
| Fix (f1,s1,_) :: s1', Fix (f2,s2,_) :: s2' ->
- if f_fix (f1,lft1) (f2,lft2) then
- match equal_rec (List.rev s1) lft1 (List.rev s2) lft2 with
- | None -> None
- | Some (lft1',lft2') -> equal_rec s1' lft1' s2' lft2'
- else None
+ f_fix f1 f2
+ && equal_rec (List.rev s1) (List.rev s2)
+ && equal_rec s1' s2'
| Cst (c1,curr1,remains1,params1,_)::s1', Cst (c2,curr2,remains2,params2,_)::s2' ->
- if equal_cst_member c1 lft1 c2 lft2 then
- match equal_rec (List.rev params1) lft1 (List.rev params2) lft2 with
- | Some (lft1',lft2') -> equal_rec s1' lft1' s2' lft2'
- | None -> None
- else None
- | ((App _|Case _|Proj _|Fix _|Cst _)::_|[]), _ -> None
- in equal_rec (List.rev sk1) 0 (List.rev sk2) 0
+ equal_cst_member c1 c2
+ && equal_rec (List.rev params1) (List.rev params2)
+ && equal_rec s1' s2'
+ | ((App _|Case _|Proj _|Fix _|Cst _)::_|[]), _ -> false
+ in equal_rec (List.rev sk1) (List.rev sk2)
let compare_shape stk1 stk2 =
let rec compare_rec bal stk1 stk2 =
@@ -455,34 +448,26 @@ struct
exception IncompatibleFold2
let fold2 f o sk1 sk2 =
- let rec aux o lft1 sk1 lft2 sk2 =
- let fold_array =
- Array.fold_left2 (fun a x y -> f a (Vars.lift lft1 x) (Vars.lift lft2 y))
- in
+ let rec aux o sk1 sk2 =
match sk1,sk2 with
- | [], [] -> o,lft1,lft2
+ | [], [] -> o
| App n1 :: q1, App n2 :: q2 ->
- let t1,l1 = decomp_node_last n1 q1 in
- let t2,l2 = decomp_node_last n2 q2 in
- aux (f o (Vars.lift lft1 t1) (Vars.lift lft2 t2))
- lft1 l1 lft2 l2
+ let t1,l1 = decomp_node_last n1 q1 in
+ let t2,l2 = decomp_node_last n2 q2 in
+ aux (f o t1 t2) l1 l2
| Case (_,t1,a1,_) :: q1, Case (_,t2,a2,_) :: q2 ->
- aux (fold_array
- (f o (Vars.lift lft1 t1) (Vars.lift lft2 t2))
- a1 a2) lft1 q1 lft2 q2
+ aux (Array.fold_left2 f (f o t1 t2) a1 a2) q1 q2
| Proj (n1,m1,p1,_) :: q1, Proj (n2,m2,p2,_) :: q2 ->
- aux o lft1 q1 lft2 q2
+ aux o q1 q2
| Fix ((_,(_,a1,b1)),s1,_) :: q1, Fix ((_,(_,a2,b2)),s2,_) :: q2 ->
- let (o',lft1',lft2') = aux (fold_array (fold_array o b1 b2) a1 a2)
- lft1 (List.rev s1) lft2 (List.rev s2) in
- aux o' lft1' q1 lft2' q2
+ let o' = aux (Array.fold_left2 f (Array.fold_left2 f o b1 b2) a1 a2) (List.rev s1) (List.rev s2) in
+ aux o' q1 q2
| Cst (cst1,_,_,params1,_) :: q1, Cst (cst2,_,_,params2,_) :: q2 ->
- let (o',lft1',lft2') =
- aux o lft1 (List.rev params1) lft2 (List.rev params2)
- in aux o' lft1' q1 lft2' q2
+ let o' = aux o (List.rev params1) (List.rev params2) in
+ aux o' q1 q2
| (((App _|Case _|Proj _|Fix _| Cst _) :: _|[]), _) ->
- raise IncompatibleFold2
- in aux o 0 (List.rev sk1) 0 (List.rev sk2)
+ raise IncompatibleFold2
+ in aux o (List.rev sk1) (List.rev sk2)
let rec map f x = List.map (function
| (Proj (_,_,_,_)) as e -> e
@@ -535,12 +520,12 @@ struct
let list_of_app_stack s =
let rec aux = function
| App (i,a,j) :: s ->
- let (k,(args',s')) = aux s in
- let a' = Array.map (Vars.lift k) (Array.sub a i (j - i + 1)) in
- k,(Array.fold_right (fun x y -> x::y) a' args', s')
- | s -> (0,([],s)) in
- let (lft,(out,s')) = aux s in
- let init = match s' with [] when Int.equal lft 0 -> true | _ -> false in
+ let (args',s') = aux s in
+ let a' = Array.sub a i (j - i + 1) in
+ (Array.fold_right (fun x y -> x::y) a' args', s')
+ | s -> ([],s) in
+ let (out,s') = aux s in
+ let init = match s' with [] -> true | _ -> false in
Option.init init out
let assign s p c =
@@ -845,11 +830,9 @@ let _ = Goptions.declare_bool_option {
}
let equal_stacks sigma (x, l) (y, l') =
- let f_equal (x,lft1) (y,lft2) = eq_constr sigma (Vars.lift lft1 x) (Vars.lift lft2 y) in
- let eq_fix (a,b) (c,d) = f_equal (mkFix a, b) (mkFix c, d) in
- match Stack.equal f_equal eq_fix l l' with
- | None -> false
- | Some (lft1,lft2) -> f_equal (x, lft1) (y, lft2)
+ let f_equal x y = eq_constr sigma x y in
+ let eq_fix a b = f_equal (mkFix a) (mkFix b) in
+ Stack.equal f_equal eq_fix l l' && f_equal x y
let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
let open Context.Named.Declaration in
@@ -1269,11 +1252,11 @@ let nf_all env sigma =
(* Conversion *)
(********************************************************************)
(*
-let fkey = Profile.declare_profile "fhnf";;
-let fhnf info v = Profile.profile2 fkey fhnf info v;;
+let fkey = CProfile.declare_profile "fhnf";;
+let fhnf info v = CProfile.profile2 fkey fhnf info v;;
-let fakey = Profile.declare_profile "fhnf_apply";;
-let fhnf_apply info k h a = Profile.profile4 fakey fhnf_apply info k h a;;
+let fakey = CProfile.declare_profile "fhnf_apply";;
+let fhnf_apply info k h a = CProfile.profile4 fakey fhnf_apply info k h a;;
*)
let is_transparent e k =
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index 7e12d263a..a277864c9 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -100,7 +100,7 @@ module Stack : sig
@return the result and the lifts to apply on the terms
@raise IncompatibleFold2 when [sk1] and [sk2] have incompatible shapes *)
val fold2 : ('a -> constr -> constr -> 'a) -> 'a ->
- constr t -> constr t -> 'a * int * int
+ constr t -> constr t -> 'a
val map : ('a -> 'a) -> 'a t -> 'a t
val append_app_list : 'a list -> 'a t -> 'a t
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index f8f086fad..00b175c48 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -227,8 +227,8 @@ let type_of_global_reference_knowing_conclusion env sigma c conclty =
(* let f,_,_,_ = retype ~polyprop sigma in *)
(* if lax then f env c else anomaly_on_error (f env) c *)
-(* let get_type_of_key = Profile.declare_profile "get_type_of" *)
-(* let get_type_of = Profile.profile5 get_type_of_key get_type_of *)
+(* let get_type_of_key = CProfile.declare_profile "get_type_of" *)
+(* let get_type_of = CProfile.profile5 get_type_of_key get_type_of *)
(* let get_type_of ?(polyprop=true) ?(lax=false) env sigma c = *)
(* get_type_of polyprop lax env sigma c *)
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 85383ba39..5a522e06a 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -927,8 +927,8 @@ let whd_simpl_orelse_delta_but_fix_old env sigma c =
let whd_simpl_stack =
if Flags.profile then
- let key = Profile.declare_profile "whd_simpl_stack" in
- Profile.profile3 key whd_simpl_stack
+ let key = CProfile.declare_profile "whd_simpl_stack" in
+ CProfile.profile3 key whd_simpl_stack
else whd_simpl_stack
(* Same as [whd_simpl] but also reduces constants that do not hide a
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 2e213a51d..bbb3a1bb2 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -442,19 +442,20 @@ let add_class cl =
let instance_constructor (cl,u) args =
let lenpars = List.count is_local_assum (snd cl.cl_context) in
+ let open EConstr in
let pars = fst (List.chop lenpars args) in
match cl.cl_impl with
| IndRef ind ->
let ind = ind, u in
- (Some (applistc (mkConstructUi (ind, 1)) args),
- applistc (mkIndU ind) pars)
+ (Some (applist (mkConstructUi (ind, 1), args)),
+ applist (mkIndU ind, pars))
| ConstRef cst ->
let cst = cst, u in
let term = match args with
| [] -> None
| _ -> Some (List.last args)
in
- (term, applistc (mkConstU cst) pars)
+ (term, applist (mkConstU cst, pars))
| _ -> assert false
let typeclasses () = Refmap.fold (fun _ l c -> l :: c) !classes []
@@ -552,8 +553,8 @@ let solve_all_instances env evd filter unique split fail =
Hook.get get_solve_all_instances env evd filter unique split fail
(** Profiling resolution of typeclasses *)
-(* let solve_classeskey = Profile.declare_profile "solve_typeclasses" *)
-(* let solve_problem = Profile.profile5 solve_classeskey solve_problem *)
+(* let solve_classeskey = CProfile.declare_profile "solve_typeclasses" *)
+(* let solve_problem = CProfile.profile5 solve_classeskey solve_problem *)
let resolve_typeclasses ?(fast_path = true) ?(filter=no_goals) ?(unique=get_typeclasses_unique_solutions ())
?(split=true) ?(fail=true) env evd =
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index 618826f3d..8ee061330 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -83,8 +83,8 @@ val is_instance : global_reference -> bool
(** Returns the term and type for the given instance of the parameters and fields
of the type class. *)
-val instance_constructor : typeclass Univ.puniverses -> constr list ->
- constr option * types
+val instance_constructor : typeclass EConstr.puniverses -> EConstr.t list ->
+ EConstr.t option * EConstr.t
(** Filter which evars to consider for resolution. *)
type evar_filter = Evar.t -> Evar_kinds.t -> bool
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 84ffab426..30674fee2 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -1077,13 +1077,13 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
in
try
let opt' = {opt with with_types = false} in
- let (substn,_,_) = Reductionops.Stack.fold2
+ let substn = Reductionops.Stack.fold2
(fun s u1 u -> unirec_rec curenvnb pb opt' s u1 (substl ks u))
(evd,ms,es) us2 us in
- let (substn,_,_) = Reductionops.Stack.fold2
+ let substn = Reductionops.Stack.fold2
(fun s u1 u -> unirec_rec curenvnb pb opt' s u1 (substl ks u))
substn params1 params in
- let (substn,_,_) = Reductionops.Stack.fold2 (fun s u1 u2 -> unirec_rec curenvnb pb opt' s u1 u2) substn ts ts1 in
+ let substn = Reductionops.Stack.fold2 (fun s u1 u2 -> unirec_rec curenvnb pb opt' s u1 u2) substn ts ts1 in
let app = mkApp (c, Array.rev_of_list ks) in
(* let substn = unirec_rec curenvnb pb b false substn t cN in *)
unirec_rec curenvnb pb opt' substn c1 app
@@ -2015,8 +2015,8 @@ let w_unify env evd cv_pb flags ty1 ty2 =
let w_unify =
if Flags.profile then
- let wunifkey = Profile.declare_profile "w_unify" in
- Profile.profile6 wunifkey w_unify
+ let wunifkey = CProfile.declare_profile "w_unify" in
+ CProfile.profile6 wunifkey w_unify
else w_unify
let w_unify env evd cv_pb ?(flags=default_unify_flags ()) ty1 ty2 =
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index b5b8987e3..e395bdbc6 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -365,4 +365,4 @@ let vm_infer_conv ?(pb=Reduction.CUMUL) env sigma t1 t2 =
Reductionops.infer_conv_gen (fun pb ~l2r sigma ts -> Vconv.vm_conv_gen pb)
~catch_incon:true ~pb env sigma t1 t2
-let _ = Reductionops.set_vm_infer_conv vm_infer_conv
+let _ = if Coq_config.bytecode_compiler then Reductionops.set_vm_infer_conv vm_infer_conv
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 2abbc389f..51735bc9e 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -286,7 +286,7 @@ let tag_var = tag Tag.variable
pr_reference r, latom
| CPatOr pl ->
- hov 0 (prlist_with_sep pr_bar (pr_patt spc (lpator,L)) pl), lpator
+ hov 0 (prlist_with_sep pr_spcbar (pr_patt mt (lpator,L)) pl), lpator
| CPatNotation ("( _ )",([p],[]),[]) ->
pr_patt (fun()->str"(") (max_int,E) p ++ str")", latom
@@ -311,11 +311,10 @@ let tag_var = tag Tag.variable
let pr_patt = pr_patt mt
let pr_eqn pr (loc,(pl,rhs)) =
- let pl = List.map snd pl in
spc() ++ hov 4
(pr_with_comments ?loc
(str "| " ++
- hov 0 (prlist_with_sep pr_bar (prlist_with_sep sep_v (pr_patt ltop)) pl
+ hov 0 (prlist_with_sep pr_spcbar (prlist_with_sep sep_v (pr_patt ltop)) pl
++ str " =>") ++
pr_sep_com spc (pr ltop) rhs))
@@ -402,7 +401,7 @@ let tag_var = tag Tag.variable
| { v = CProdN ([],c) } ->
extract_prod_binders c
| { loc; v = CProdN ([[_,Name id],bk,t],
- { v = CCases (LetPatternStyle,None, [{ v = CRef (Ident (_,id'),None)},None,None],[(_,([_,[p]],b))])} ) }
+ { v = CCases (LetPatternStyle,None, [{ v = CRef (Ident (_,id'),None)},None,None],[(_,([[p]],b))])} ) }
when Id.equal id id' && not (Id.Set.mem id (free_vars_of_constr_expr b)) ->
let bl,c = extract_prod_binders b in
CLocalPattern (loc, (p,None)) :: bl, c
@@ -418,7 +417,7 @@ let tag_var = tag Tag.variable
| CLambdaN ([],c) ->
extract_lam_binders c
| CLambdaN ([[_,Name id],bk,t],
- { v = CCases (LetPatternStyle,None, [{ v = CRef (Ident (_,id'),None)},None,None],[(_,([_,[p]],b))])} )
+ { v = CCases (LetPatternStyle,None, [{ v = CRef (Ident (_,id'),None)},None,None],[(_,([[p]],b))])} )
when Id.equal id id' && not (Id.Set.mem id (free_vars_of_constr_expr b)) ->
let bl,c = extract_lam_binders b in
CLocalPattern (ce.loc,(p,None)) :: bl, c
@@ -650,7 +649,7 @@ let tag_var = tag Tag.variable
hv 0 (str"{|" ++ pr_record_body_gen (pr spc) l ++ str" |}"),
latom
)
- | CCases (LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[(_,([(loc,[p])],b))]) ->
+ | CCases (LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[(_,([[p]],b))]) ->
return (
hv 0 (
keyword "let" ++ spc () ++ str"'" ++
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 1eb2c31c8..647111bbe 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -903,18 +903,16 @@ let print_class i =
let cl,_ = class_info_from_index i in
pr_class cl
-let print_path ((i,j),p) =
- let sigma, env = Pfedit.get_current_context () in
+let print_path env sigma ((i,j),p) =
hov 2 (
str"[" ++ hov 0 (prlist_with_sep pr_semicolon (print_coercion_value env sigma) p) ++
str"] : ") ++
print_class i ++ str" >-> " ++ print_class j
-(* XXX: This is suspicious!!! *)
let _ = Classops.install_path_printer print_path
-let print_graph () =
- prlist_with_sep fnl print_path (inheritance_graph())
+let print_graph env sigma =
+ prlist_with_sep fnl (print_path env sigma) (inheritance_graph())
let print_classes () =
pr_sequence pr_class (classes())
@@ -929,7 +927,7 @@ let index_of_class cl =
user_err ~hdr:"index_of_class"
(pr_class cl ++ spc() ++ str "not a defined class.")
-let print_path_between cls clt =
+let print_path_between env sigma cls clt =
let i = index_of_class cls in
let j = index_of_class clt in
let p =
@@ -940,7 +938,7 @@ let print_path_between cls clt =
(str"No path between " ++ pr_class cls ++ str" and " ++ pr_class clt
++ str ".")
in
- print_path ((i,j),p)
+ print_path env sigma ((i,j),p)
let print_canonical_projections env sigma =
prlist_with_sep fnl
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 8f3a6ddc4..fd7f1f92b 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -12,6 +12,7 @@ open Reductionops
open Libnames
open Globnames
open Misctypes
+open Evd
(** A Pretty-Printer for the Calculus of Inductive Constructions. *)
@@ -39,10 +40,10 @@ val print_about : env -> Evd.evar_map -> reference or_by_notation ->
val print_impargs : reference or_by_notation -> Pp.t
(** Pretty-printing functions for classes and coercions *)
-val print_graph : unit -> Pp.t
+val print_graph : env -> evar_map -> Pp.t
val print_classes : unit -> Pp.t
val print_coercions : env -> Evd.evar_map -> Pp.t
-val print_path_between : Classops.cl_typ -> Classops.cl_typ -> Pp.t
+val print_path_between : env -> evar_map -> Classops.cl_typ -> Classops.cl_typ -> Pp.t
val print_canonical_projections : env -> Evd.evar_map -> Pp.t
(** Pretty-printing functions for type classes and instances *)
diff --git a/printing/printer.ml b/printing/printer.ml
index 6a0597860..a63004ceb 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -905,7 +905,7 @@ end
module ContextObjectSet = Set.Make (OrderedContextObject)
module ContextObjectMap = Map.Make (OrderedContextObject)
-let pr_assumptionset env s =
+let pr_assumptionset env sigma s =
if ContextObjectMap.is_empty s &&
engagement env = PredicativeSet then
str "Closed under the global context"
@@ -921,7 +921,6 @@ let pr_assumptionset env s =
with e when CErrors.noncritical e -> mt ()
in
let safe_pr_ltype_relctx (rctx, typ) =
- let sigma, env = Pfedit.get_current_context () in
let env = Environ.push_rel_context rctx env in
try str " " ++ pr_ltype_env env sigma typ
with e when CErrors.noncritical e -> mt ()
diff --git a/printing/printer.mli b/printing/printer.mli
index 36ca1bdcc..804014745 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -217,8 +217,7 @@ module ContextObjectSet : Set.S with type elt = context_object
module ContextObjectMap : CMap.ExtS
with type key = context_object and module Set := ContextObjectSet
-val pr_assumptionset :
- env -> types ContextObjectMap.t -> Pp.t
+val pr_assumptionset : env -> evar_map -> types ContextObjectMap.t -> Pp.t
val pr_goal_by_id : proof:Proof.t -> Id.t -> Pp.t
diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml
index 4a92c3856..8bd5d98cb 100644
--- a/proofs/clenvtac.ml
+++ b/proofs/clenvtac.ml
@@ -54,9 +54,10 @@ let clenv_value_cast_meta clenv =
let clenv_pose_dependent_evars with_evars clenv =
let dep_mvs = clenv_dependent clenv in
+ let env, sigma = clenv.env, clenv.evd in
if not (List.is_empty dep_mvs) && not with_evars then
raise
- (RefinerError (UnresolvedBindings (List.map (meta_name clenv.evd) dep_mvs)));
+ (RefinerError (env, sigma, UnresolvedBindings (List.map (meta_name clenv.evd) dep_mvs)));
clenv_pose_metas_as_evars clenv dep_mvs
(** Use our own fast path, more informative than from Typeclasses *)
diff --git a/proofs/logic.ml b/proofs/logic.ml
index a9ad606a0..1d86a0909 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -40,7 +40,7 @@ type refiner_error =
| DoesNotOccurIn of constr * Id.t
| NoSuchHyp of Id.t
-exception RefinerError of refiner_error
+exception RefinerError of Environ.env * Evd.evar_map * refiner_error
open Pretype_errors
@@ -69,7 +69,7 @@ let catchable_exception = function
| PretypeError(_,_, e) -> is_unification_error e || is_typing_error e
| _ -> false
-let error_no_such_hypothesis id = raise (RefinerError (NoSuchHyp id))
+let error_no_such_hypothesis env sigma id = raise (RefinerError (env, sigma, NoSuchHyp id))
(* Tells if the refiner should check that the submitted rules do not
produce invalid subgoals *)
@@ -78,10 +78,10 @@ let with_check = Flags.with_option check
(* [apply_to_hyp sign id f] splits [sign] into [tail::[id,_,_]::head] and
returns [tail::(f head (id,_,_) (rev tail))] *)
-let apply_to_hyp check sign id f =
+let apply_to_hyp env sigma check sign id f =
try apply_to_hyp sign id f
with Hyp_not_found ->
- if check then error_no_such_hypothesis id
+ if check then error_no_such_hypothesis env sigma id
else sign
let check_typability env sigma c =
@@ -147,7 +147,7 @@ let reorder_context env sigma sign ord =
step ord' expected ctxt_head mh (d::ctxt_tail)
| _ ->
(match ctxt_head with
- | [] -> error_no_such_hypothesis (List.hd ord)
+ | [] -> error_no_such_hypothesis env sigma (List.hd ord)
| d :: ctxt ->
let x = NamedDecl.get_id d in
if Id.Set.mem x expected then
@@ -190,9 +190,9 @@ let move_location_eq m1 m2 = match m1, m2 with
| MoveFirst, MoveFirst -> true
| _ -> false
-let split_sign hfrom hto l =
+let split_sign env sigma hfrom hto l =
let rec splitrec left toleft = function
- | [] -> error_no_such_hypothesis hfrom
+ | [] -> error_no_such_hypothesis env sigma hfrom
| d :: right ->
let hyp = NamedDecl.get_id d in
if Id.equal hyp hfrom then
@@ -222,7 +222,7 @@ let move_hyp sigma toleft (left,declfrom,right) hto =
let rec moverec first middle = function
| [] ->
if match hto with MoveFirst | MoveLast -> false | _ -> true then
- error_no_such_hypothesis (hyp_of_move_location hto);
+ error_no_such_hypothesis env sigma (hyp_of_move_location hto);
List.rev first @ List.rev middle
| d :: _ as right when move_location_eq hto (MoveBefore (NamedDecl.get_id d)) ->
List.rev first @ List.rev middle @ right
@@ -258,10 +258,10 @@ let move_hyp sigma toleft (left,declfrom,right) hto =
List.fold_left (fun sign d -> push_named_context_val d sign)
right left
-let move_hyp_in_named_context sigma hfrom hto sign =
+let move_hyp_in_named_context env sigma hfrom hto sign =
let open EConstr in
let (left,right,declfrom,toleft) =
- split_sign hfrom hto (named_context_of_val sign) in
+ split_sign env sigma hfrom hto (named_context_of_val sign) in
move_hyp sigma toleft (left,declfrom,right) hto
let insert_decl_in_named_context sigma decl hto sign =
@@ -293,15 +293,15 @@ let collect_meta_variables c =
in
List.rev (collrec false [] c)
-let check_meta_variables c =
+let check_meta_variables env sigma c =
if not (List.distinct_f Int.compare (collect_meta_variables c)) then
- raise (RefinerError (NonLinearProof c))
+ raise (RefinerError (env, sigma, NonLinearProof c))
let check_conv_leq_goal env sigma arg ty conclty =
if !check then
let evm, b = Reductionops.infer_conv env sigma (EConstr.of_constr ty) (EConstr.of_constr conclty) in
if b then evm
- else raise (RefinerError (BadType (arg,ty,conclty)))
+ else raise (RefinerError (env, sigma, BadType (arg,ty,conclty)))
else sigma
exception Stop of EConstr.t list
@@ -336,7 +336,7 @@ let rec mk_refgoals sigma goal goalacc conclty trm =
| Meta _ ->
let conclty = nf_betaiota sigma (EConstr.of_constr conclty) in
if !check && occur_meta sigma conclty then
- raise (RefinerError (MetaInType conclty));
+ raise (RefinerError (env, sigma, MetaInType conclty));
let (gl,ev,sigma) = mk_goal hyps conclty in
let ev = EConstr.Unsafe.to_constr ev in
let conclty = EConstr.Unsafe.to_constr conclty in
@@ -477,7 +477,9 @@ and mk_arggoals sigma goal goalacc funty allargs =
| Prod (_, c1, b) ->
let (acc, hargty, sigma, arg) = mk_refgoals sigma goal goalacc c1 harg in
(acc, subst1 harg b, sigma), arg
- | _ -> raise (RefinerError (CannotApply (t, harg)))
+ | _ ->
+ let env = Goal.V82.env sigma goal in
+ raise (RefinerError (env,sigma,CannotApply (t, harg)))
in
Array.smartfoldmap foldmap (goalacc, funty, sigma) allargs
@@ -497,10 +499,10 @@ and mk_casegoals sigma goal goalacc p c =
let convert_hyp check sign sigma d =
let id = NamedDecl.get_id d in
let b = NamedDecl.get_value d in
- let env = Global.env() in
+ let env = Global.env () in
let reorder = ref [] in
let sign' =
- apply_to_hyp check sign id
+ apply_to_hyp env sigma check sign id
(fun _ d' _ ->
let c = Option.map EConstr.of_constr (NamedDecl.get_value d') in
let env = Global.env_of_context sign in
@@ -514,19 +516,18 @@ let convert_hyp check sign sigma d =
map_named_decl EConstr.Unsafe.to_constr d) in
reorder_val_context env sigma sign' !reorder
-
-
(************************************************************************)
(************************************************************************)
(* Primitive tactics are handled here *)
let prim_refiner r sigma goal =
+ let env = Goal.V82.env sigma goal in
let cl = Goal.V82.concl sigma goal in
match r with
(* Logical rules *)
| Refine c ->
let cl = EConstr.Unsafe.to_constr cl in
- check_meta_variables c;
+ check_meta_variables env sigma c;
let (sgl,cl',sigma,oterm) = mk_refgoals sigma goal [] cl c in
let sgl = List.rev sgl in
let sigma = Goal.V82.partial_solution sigma goal (EConstr.of_constr oterm) in
diff --git a/proofs/logic.mli b/proofs/logic.mli
index 7df7fd66b..afd1ecf70 100644
--- a/proofs/logic.mli
+++ b/proofs/logic.mli
@@ -50,16 +50,16 @@ type refiner_error =
| DoesNotOccurIn of constr * Id.t
| NoSuchHyp of Id.t
-exception RefinerError of refiner_error
+exception RefinerError of Environ.env * evar_map * refiner_error
-val error_no_such_hypothesis : Id.t -> 'a
+val error_no_such_hypothesis : Environ.env -> evar_map -> Id.t -> 'a
val catchable_exception : exn -> bool
val convert_hyp : bool -> Environ.named_context_val -> evar_map ->
EConstr.named_declaration -> Environ.named_context_val
-val move_hyp_in_named_context : Evd.evar_map -> Id.t -> Id.t Misctypes.move_location ->
+val move_hyp_in_named_context : Environ.env -> Evd.evar_map -> Id.t -> Id.t Misctypes.move_location ->
Environ.named_context_val -> Environ.named_context_val
val insert_decl_in_named_context : Evd.evar_map ->
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index 6052ba367..9a5d4e154 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -25,8 +25,11 @@ open Misctypes
(* call by value normalisation function using the virtual machine *)
let cbv_vm env sigma c =
- let ctyp = Retyping.get_type_of env sigma c in
- Vnorm.cbv_vm env sigma c ctyp
+ if Coq_config.bytecode_compiler then
+ let ctyp = Retyping.get_type_of env sigma c in
+ Vnorm.cbv_vm env sigma c ctyp
+ else
+ compute env sigma c
let warn_native_compute_disabled =
CWarnings.create ~name:"native-compute-disabled" ~category:"native-compiler"
@@ -34,12 +37,12 @@ let warn_native_compute_disabled =
strbrk "native_compute disabled at configure time; falling back to vm_compute.")
let cbv_native env sigma c =
- if Coq_config.no_native_compiler then
- (warn_native_compute_disabled ();
- cbv_vm env sigma c)
- else
+ if Coq_config.native_compiler then
let ctyp = Retyping.get_type_of env sigma c in
Nativenorm.native_norm env sigma c ctyp
+ else
+ (warn_native_compute_disabled ();
+ cbv_vm env sigma c)
let whd_cbn flags env sigma t =
let (state,_) =
diff --git a/proofs/refiner.ml b/proofs/refiner.ml
index 3e3313eb5..cd2b10906 100644
--- a/proofs/refiner.ml
+++ b/proofs/refiner.ml
@@ -30,8 +30,8 @@ let refiner pr goal_sigma =
(* Profiling refiner *)
let refiner =
if Flags.profile then
- let refiner_key = Profile.declare_profile "refiner" in
- Profile.profile2 refiner_key refiner
+ let refiner_key = CProfile.declare_profile "refiner" in
+ CProfile.profile2 refiner_key refiner
else refiner
(*********************)
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index cab8d7b52..d41541251 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -55,10 +55,11 @@ let pf_nth_hyp_id gls n = List.nth (pf_hyps gls) (n-1) |> NamedDecl.get_id
let pf_last_hyp gl = List.hd (pf_hyps gl)
let pf_get_hyp gls id =
+ let env, sigma = pf_env gls, project gls in
try
Context.Named.lookup id (pf_hyps gls)
with Not_found ->
- raise (RefinerError (NoSuchHyp id))
+ raise (RefinerError (env, sigma, NoSuchHyp id))
let pf_get_hyp_typ gls id =
id |> pf_get_hyp gls |> NamedDecl.get_type
@@ -182,9 +183,10 @@ module New = struct
let pf_get_hyp id gl =
let hyps = Proofview.Goal.env gl in
+ let sigma = project gl in
let sign =
try EConstr.lookup_named id hyps
- with Not_found -> raise (RefinerError (NoSuchHyp id))
+ with Not_found -> raise (RefinerError (hyps, sigma, NoSuchHyp id))
in
sign
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index cd22a7183..26aef5355 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -10,11 +10,11 @@ open CErrors
open Pp
open Util
-let stm_pr_err pp = Format.eprintf "%s] @[%a@]\n%!" (System.process_id ()) Pp.pp_with pp
-
+let stm_pr_err pp = Format.eprintf "%s] @[%a@]\n%!" (Spawned.process_id ()) Pp.pp_with pp
let stm_prerr_endline s = if !Flags.debug then begin stm_pr_err (str s) end else ()
type cancel_switch = bool ref
+let async_proofs_flags_for_workers = ref []
module type Task = sig
@@ -117,12 +117,12 @@ module Make(T : Task) () = struct
let name = Printf.sprintf "%s:%d" !T.name id in
let proc, ic, oc =
let rec set_slave_opt = function
- | [] -> !Flags.async_proofs_flags_for_workers @
+ | [] -> !async_proofs_flags_for_workers @
["-toploop"; !T.name^"top";
"-worker-id"; name;
"-async-proofs-worker-priority";
- Flags.string_of_priority !Flags.async_proofs_worker_priority]
- | ("-ideslave"|"-emacs"|"-batch")::tl -> set_slave_opt tl
+ CoqworkmgrApi.(string_of_priority !WorkerLoop.async_proofs_worker_priority)]
+ | ("-ideslave"|"-emacs"|"-emacs-U"|"-batch")::tl -> set_slave_opt tl
| ("-async-proofs" |"-toploop" |"-vio2vo"
|"-load-vernac-source" |"-l" |"-load-vernac-source-verbose" |"-lv"
|"-compile" |"-compile-verbose"
@@ -295,7 +295,7 @@ module Make(T : Task) () = struct
let slave_handshake () =
Pool.worker_handshake (Option.get !slave_ic) (Option.get !slave_oc)
- let pp_pid pp = Pp.(str (System.process_id () ^ " ") ++ pp)
+ let pp_pid pp = Pp.(str (Spawned.process_id () ^ " ") ++ pp)
let debug_with_pid = Feedback.(function
| { contents = Message(Debug, loc, pp) } as fb ->
diff --git a/stm/asyncTaskQueue.mli b/stm/asyncTaskQueue.mli
index ccd643deb..07689389f 100644
--- a/stm/asyncTaskQueue.mli
+++ b/stm/asyncTaskQueue.mli
@@ -6,6 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* Default flags for workers *)
+val async_proofs_flags_for_workers : string list ref
+
(** This file provides an API for defining and managing a queue of
tasks to be done by external workers.
diff --git a/stm/coqworkmgrApi.ml b/stm/coqworkmgrApi.ml
index 6d6a198c5..14fd97a6d 100644
--- a/stm/coqworkmgrApi.ml
+++ b/stm/coqworkmgrApi.ml
@@ -8,8 +8,15 @@
let debug = false
+type priority = Low | High
+let string_of_priority = function Low -> "low" | High -> "high"
+let priority_of_string = function
+ | "low" -> Low
+ | "high" -> High
+ | _ -> raise (Invalid_argument "priority_of_string")
+
type request =
- | Hello of Flags.priority
+ | Hello of priority
| Get of int
| TryGet of int
| GiveBack of int
@@ -36,8 +43,8 @@ let positive_int_of_string n =
let parse_request s =
if debug then Printf.eprintf "parsing '%s'\n" s;
match Str.split (Str.regexp " ") (strip_r s) with
- | [ "HELLO"; "LOW" ] -> Hello Flags.Low
- | [ "HELLO"; "HIGH" ] -> Hello Flags.High
+ | [ "HELLO"; "LOW" ] -> Hello Low
+ | [ "HELLO"; "HIGH" ] -> Hello High
| [ "GET"; n ] -> Get (positive_int_of_string n)
| [ "TRYGET"; n ] -> TryGet (positive_int_of_string n)
| [ "GIVEBACK"; n ] -> GiveBack (positive_int_of_string n)
@@ -57,8 +64,8 @@ let parse_response s =
| _ -> raise ParseError
let print_request = function
- | Hello Flags.Low -> "HELLO LOW\n"
- | Hello Flags.High -> "HELLO HIGH\n"
+ | Hello Low -> "HELLO LOW\n"
+ | Hello High -> "HELLO HIGH\n"
| Get n -> Printf.sprintf "GET %d\n" n
| TryGet n -> Printf.sprintf "TRYGET %d\n" n
| GiveBack n -> Printf.sprintf "GIVEBACK %d\n" n
@@ -106,8 +113,7 @@ let with_manager f g =
let get n =
with_manager
- (fun () ->
- min n (min !Flags.async_proofs_n_workers !Flags.async_proofs_n_tacworkers))
+ (fun () -> n)
(fun cin cout ->
output_string cout (print_request (Get n));
flush cout;
@@ -118,10 +124,7 @@ let get n =
let tryget n =
with_manager
- (fun () ->
- Some
- (min n
- (min !Flags.async_proofs_n_workers !Flags.async_proofs_n_tacworkers)))
+ (fun () -> Some n)
(fun cin cout ->
output_string cout (print_request (TryGet n));
flush cout;
diff --git a/stm/coqworkmgrApi.mli b/stm/coqworkmgrApi.mli
index 70d4173ae..953903810 100644
--- a/stm/coqworkmgrApi.mli
+++ b/stm/coqworkmgrApi.mli
@@ -8,9 +8,13 @@
(* High level api for clients of the service (like coqtop) *)
+type priority = Low | High
+val string_of_priority : priority -> string
+val priority_of_string : string -> priority
+
(* Connects to a work manager if any. If no worker manager, then
-async-proofs-j and -async-proofs-tac-j are used *)
-val init : Flags.priority -> unit
+val init : priority -> unit
(* blocking *)
val get : int -> int
@@ -21,7 +25,7 @@ val giveback : int -> unit
(* Low level *)
type request =
- | Hello of Flags.priority
+ | Hello of priority
| Get of int
| TryGet of int
| GiveBack of int
diff --git a/stm/spawned.ml b/stm/spawned.ml
index 6ab096abf..fb5708f3a 100644
--- a/stm/spawned.ml
+++ b/stm/spawned.ml
@@ -73,3 +73,9 @@ let get_channels () =
Printf.eprintf "Fatal error: ideslave communication channels not set.\n";
exit 1
| Some(ic, oc) -> ic, oc
+
+let process_id () =
+ Printf.sprintf "%d:%s:%d" (Unix.getpid ())
+ (if Flags.async_proofs_is_worker () then !Flags.async_proofs_worker_id
+ else "master")
+ (Thread.id (Thread.self ()))
diff --git a/stm/spawned.mli b/stm/spawned.mli
index c3cf4d67b..7f463c6a6 100644
--- a/stm/spawned.mli
+++ b/stm/spawned.mli
@@ -20,3 +20,5 @@ val init_channels : unit -> unit
(* Once initialized, these are the channels to talk with our master *)
val get_channels : unit -> CThread.thread_ic * out_channel
+(** {6 Name of current process.} *)
+val process_id : unit -> string
diff --git a/stm/stm.ml b/stm/stm.ml
index 8aa832da8..1d46e0833 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -8,13 +8,13 @@
(* enable in case of stm problems *)
(* let stm_debug () = !Flags.debug *)
-let stm_debug () = !Flags.stm_debug
+let stm_debug = ref false
-let stm_pr_err s = Format.eprintf "%s] %s\n%!" (System.process_id ()) s
-let stm_pp_err pp = Format.eprintf "%s] @[%a@]\n%!" (System.process_id ()) Pp.pp_with pp
+let stm_pr_err s = Format.eprintf "%s] %s\n%!" (Spawned.process_id ()) s
+let stm_pp_err pp = Format.eprintf "%s] @[%a@]\n%!" (Spawned.process_id ()) Pp.pp_with pp
-let stm_prerr_endline s = if stm_debug () then begin stm_pr_err (s ()) end else ()
-let stm_pperr_endline s = if stm_debug () then begin stm_pp_err (s ()) end else ()
+let stm_prerr_endline s = if !stm_debug then begin stm_pr_err (s ()) end else ()
+let stm_pperr_endline s = if !stm_debug then begin stm_pp_err (s ()) end else ()
let stm_prerr_debug s = if !Flags.debug then begin stm_pr_err (s ()) end else ()
@@ -23,6 +23,35 @@ open CErrors
open Feedback
open Vernacexpr
+module AsyncOpts = struct
+
+ let async_proofs_n_workers = ref 1
+ let async_proofs_n_tacworkers = ref 2
+
+ type cache = Force
+ let async_proofs_cache : cache option ref = ref None
+
+ type async_proofs = APoff | APonLazy | APon
+ let async_proofs_mode = ref APoff
+
+ let async_proofs_private_flags = ref None
+ let async_proofs_full = ref false
+ let async_proofs_never_reopen_branch = ref false
+
+ type tac_error_filter = [ `None | `Only of string list | `All ]
+ let async_proofs_tac_error_resilience = ref (`Only [ "curly" ])
+ let async_proofs_cmd_error_resilience = ref true
+
+ let async_proofs_delegation_threshold = ref 0.03
+
+end
+
+open AsyncOpts
+
+let async_proofs_is_master () =
+ !async_proofs_mode = APon &&
+ !Flags.async_proofs_worker_id = "master"
+
(* Protect against state changes *)
let stm_purify f x =
let st = Vernacstate.freeze_interp_state `No in
@@ -158,9 +187,10 @@ let mkTransCmd cast cids ceff cqueue =
Cmd { ctac = false; cast; cblock = None; cqueue; cids; ceff }
(* Parts of the system state that are morally part of the proof state *)
-let summary_pstate = [ Evarutil.meta_counter_summary_name;
- Evd.evar_counter_summary_name;
- "program-tcc-table" ]
+let summary_pstate = Evarutil.meta_counter_summary_tag,
+ Evd.evar_counter_summary_tag,
+ Obligations.program_tcc_summary_tag
+
type cached_state =
| Empty
| Error of Exninfo.iexn
@@ -352,10 +382,10 @@ end = struct (* {{{ *)
In case you are hitting the race enable stm_debug.
*)
- if stm_debug () then Flags.we_are_parsing := false;
+ if !stm_debug then Flags.we_are_parsing := false;
let fname =
- "stm_" ^ Str.global_replace (Str.regexp " ") "_" (System.process_id ()) in
+ "stm_" ^ Str.global_replace (Str.regexp " ") "_" (Spawned.process_id ()) in
let string_of_transaction = function
| Cmd { cast = t } | Fork (t, _,_,_) ->
(try Pp.string_of_ppcmds (pr_ast t) with _ -> "ERR")
@@ -529,7 +559,7 @@ end = struct (* {{{ *)
| None -> raise Vcs_aux.Expired
let set_state id s =
(get_info id).state <- s;
- if Flags.async_proofs_is_master () then Hooks.(call state_ready id)
+ if async_proofs_is_master () then Hooks.(call state_ready id)
let get_state id = (get_info id).state
let reached id =
let info = get_info id in
@@ -762,15 +792,21 @@ end = struct (* {{{ *)
let fix_exn_ref = ref (fun x -> x)
type proof_part =
- Proof_global.t * Summary.frozen_bits (* only meta counters *)
+ Proof_global.t *
+ int * (* Evarutil.meta_counter_summary_tag *)
+ int * (* Evd.evar_counter_summary_tag *)
+ Obligations.program_info Names.Id.Map.t (* Obligations.program_tcc_summary_tag *)
type partial_state =
[ `Full of Vernacstate.t
| `ProofOnly of Stateid.t * proof_part ]
let proof_part_of_frozen { Vernacstate.proof; system } =
+ let st = States.summary_of_state system in
proof,
- Summary.project_summary (States.summary_of_state system) summary_pstate
+ Summary.project_from_summary st Util.(pi1 summary_pstate),
+ Summary.project_from_summary st Util.(pi2 summary_pstate),
+ Summary.project_from_summary st Util.(pi3 summary_pstate)
let freeze marshallable id =
VCS.set_state id (Valid (Vernacstate.freeze_interp_state marshallable))
@@ -830,16 +866,21 @@ end = struct (* {{{ *)
else s
with VCS.Expired -> s in
VCS.set_state id (Valid s)
- | `ProofOnly(ontop,(pstate,counters)) ->
+ | `ProofOnly(ontop,(pstate,c1,c2,c3)) ->
if is_cached_and_valid ontop then
let s = get_cached ontop in
let s = { s with proof =
Proof_global.copy_terminators ~src:s.proof ~tgt:pstate } in
let s = { s with system =
States.replace_summary s.system
- (Summary.surgery_summary
- (States.summary_of_state s.system)
- counters) } in
+ begin
+ let st = States.summary_of_state s.system in
+ let st = Summary.modify_summary st Util.(pi1 summary_pstate) c1 in
+ let st = Summary.modify_summary st Util.(pi2 summary_pstate) c2 in
+ let st = Summary.modify_summary st Util.(pi3 summary_pstate) c3 in
+ st
+ end
+ } in
VCS.set_state id (Valid s)
with VCS.Expired -> ()
@@ -854,10 +895,10 @@ end = struct (* {{{ *)
let same_env { Vernacstate.system = s1 } { Vernacstate.system = s2 } =
let s1 = States.summary_of_state s1 in
- let e1 = Summary.project_summary s1 [Global.global_env_summary_name] in
+ let e1 = Summary.project_from_summary s1 Global.global_env_summary_tag in
let s2 = States.summary_of_state s2 in
- let e2 = Summary.project_summary s2 [Global.global_env_summary_name] in
- Summary.pointer_equal e1 e2
+ let e2 = Summary.project_from_summary s2 Global.global_env_summary_tag in
+ e1 == e2
let define ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
f id
@@ -1105,7 +1146,7 @@ end = struct (* {{{ *)
" the \"-async-proofs-cache force\" option to Coq."))
let undo_vernac_classifier v =
- if VCS.is_interactive () = `No && !Flags.async_proofs_cache <> Some Flags.Force
+ if VCS.is_interactive () = `No && !async_proofs_cache <> Some Force
then undo_costly_in_batch_mode v;
try
match v with
@@ -1241,7 +1282,7 @@ let prev_node { id } =
let cur_node id = mk_doc_node id (VCS.visit id)
let is_block_name_enabled name =
- match !Flags.async_proofs_tac_error_resilience with
+ match !async_proofs_tac_error_resilience with
| `None -> false
| `All -> true
| `Only l -> List.mem name l
@@ -1249,7 +1290,7 @@ let is_block_name_enabled name =
let detect_proof_block id name =
let name = match name with None -> "indent" | Some x -> x in
if is_block_name_enabled name &&
- (Flags.async_proofs_is_master () || Flags.async_proofs_is_worker ())
+ (async_proofs_is_master () || Flags.async_proofs_is_worker ())
then (
match cur_node id with
| None -> ()
@@ -1351,7 +1392,7 @@ end = struct (* {{{ *)
let task_match age t =
match age, t with
| Fresh, BuildProof { t_states } ->
- not !Flags.async_proofs_full ||
+ not !async_proofs_full ||
List.exists (fun x -> CList.mem_f Stateid.equal x !perspective) t_states
| Old my_states, States l ->
List.for_all (fun x -> CList.mem_f Stateid.equal x my_states) l
@@ -1388,7 +1429,7 @@ end = struct (* {{{ *)
feedback (InProgress ~-1);
t_assign (`Val pl);
record_pb_time ?loc:t_loc t_name time;
- if !Flags.async_proofs_full || t_drop
+ if !async_proofs_full || t_drop
then `Stay(t_states,[States t_states])
else `End
| Fresh, BuildProof { t_assign; t_loc; t_name; t_states },
@@ -1562,8 +1603,8 @@ end = struct (* {{{ *)
let queue = ref None
let init () =
- if Flags.async_proofs_is_master () then
- queue := Some (TaskQueue.create !Flags.async_proofs_n_workers)
+ if async_proofs_is_master () then
+ queue := Some (TaskQueue.create !async_proofs_n_workers)
else
queue := Some (TaskQueue.create 0)
@@ -2028,7 +2069,7 @@ end = struct (* {{{ *)
QueryTask.({ t_where = prev; t_for = id; t_what = q }) ~cancel_switch
let init () = queue := Some (TaskQueue.create
- (if !Flags.async_proofs_full then 1 else 0))
+ (if !async_proofs_full then 1 else 0))
end (* }}} *)
@@ -2040,8 +2081,6 @@ and Reach : sig
end = struct (* {{{ *)
-let pstate = summary_pstate
-
let async_policy () =
let open Flags in
if is_universe_polymorphism () then false
@@ -2051,9 +2090,9 @@ let async_policy () =
(VCS.is_vio_doc () || !async_proofs_mode <> APoff)
let delegate name =
- get_hint_bp_time name >= !Flags.async_proofs_delegation_threshold
+ get_hint_bp_time name >= !async_proofs_delegation_threshold
|| VCS.is_vio_doc ()
- || !Flags.async_proofs_full
+ || !async_proofs_full
let warn_deprecated_nested_proofs =
CWarnings.create ~name:"deprecated-nested-proofs" ~category:"deprecated"
@@ -2150,7 +2189,7 @@ let collect_proof keep cur hd brkind id =
let rc = collect (Some cur) [] id in
if is_empty rc then make_sync `AlreadyEvaluated rc
else if (keep == VtKeep || keep == VtKeepAsAxiom) &&
- (not(State.is_cached_and_valid id) || !Flags.async_proofs_full)
+ (not(State.is_cached_and_valid id) || !async_proofs_full)
then check_policy rc
else make_sync `AlreadyEvaluated rc
@@ -2232,9 +2271,9 @@ let known_state ?(redefine_qed=false) ~cache id =
(* Absorb tactic errors from f () *)
let resilient_tactic id blockname f =
- if !Flags.async_proofs_tac_error_resilience = `None ||
- (Flags.async_proofs_is_master () &&
- !Flags.async_proofs_mode = Flags.APoff)
+ if !async_proofs_tac_error_resilience = `None ||
+ (async_proofs_is_master () &&
+ !async_proofs_mode = APoff)
then f ()
else
try f ()
@@ -2243,9 +2282,9 @@ let known_state ?(redefine_qed=false) ~cache id =
error_absorbing_tactic id blockname ie in
(* Absorb errors from f x *)
let resilient_command f x =
- if not !Flags.async_proofs_cmd_error_resilience ||
- (Flags.async_proofs_is_master () &&
- !Flags.async_proofs_mode = Flags.APoff)
+ if not !async_proofs_cmd_error_resilience ||
+ (async_proofs_is_master () &&
+ !async_proofs_mode = APoff)
then f x
else
try f x
@@ -2254,10 +2293,14 @@ let known_state ?(redefine_qed=false) ~cache id =
(* ugly functions to process nested lemmas, i.e. hard to reproduce
* side effects *)
let cherry_pick_non_pstate () =
- Summary.freeze_summary ~marshallable:`No ~complement:true pstate,
- Lib.freeze ~marshallable:`No in
+ let st = Summary.freeze_summaries ~marshallable:`No in
+ let st = Summary.remove_from_summary st Util.(pi1 summary_pstate) in
+ let st = Summary.remove_from_summary st Util.(pi2 summary_pstate) in
+ let st = Summary.remove_from_summary st Util.(pi3 summary_pstate) in
+ st, Lib.freeze ~marshallable:`No in
+
let inject_non_pstate (s,l) =
- Summary.unfreeze_summary s; Lib.unfreeze l; update_global_env ()
+ Summary.unfreeze_summaries ~partial:true s; Lib.unfreeze l; update_global_env ()
in
let rec pure_cherry_pick_non_pstate safe_id id =
stm_purify (fun id ->
@@ -2287,10 +2330,10 @@ let known_state ?(redefine_qed=false) ~cache id =
resilient_tactic id cblock (fun () ->
reach ~cache:`Shallow view.next;
Partac.vernac_interp ~solve ~abstract ~cancel_switch
- !Flags.async_proofs_n_tacworkers view.next id x)
+ !async_proofs_n_tacworkers view.next id x)
), cache, true
| `Cmd { cast = x; cqueue = `QueryQueue cancel_switch }
- when Flags.async_proofs_is_master () -> (fun () ->
+ when async_proofs_is_master () -> (fun () ->
reach view.next;
Query.vernac_interp ~cancel_switch view.next id x
), cache, false
@@ -2304,10 +2347,10 @@ let known_state ?(redefine_qed=false) ~cache id =
if eff then update_global_env ()
), (if eff then `Yes else cache), true
| `Cmd { cast = x; ceff = eff } -> (fun () ->
- (match !Flags.async_proofs_mode with
- | Flags.APon | Flags.APonLazy ->
+ (match !async_proofs_mode with
+ | APon | APonLazy ->
resilient_command reach view.next
- | Flags.APoff -> reach view.next);
+ | APoff -> reach view.next);
let st = Vernacstate.freeze_interp_state `No in
ignore(stm_vernac_interp id st x);
if eff then update_global_env ()
@@ -2434,7 +2477,7 @@ let known_state ?(redefine_qed=false) ~cache id =
), cache, true
in
let cache_step =
- if !Flags.async_proofs_cache = Some Flags.Force then `Yes
+ if !async_proofs_cache = Some Force then `Yes
else cache_step in
State.define ?safe_id
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
@@ -2465,6 +2508,7 @@ let doc_type_module_name (std : stm_doc_type) =
*)
let init_core () =
+ if !async_proofs_mode = APon then Control.enable_thread_delay := true;
State.register_root_state ()
let new_doc { doc_type ; require_libs } =
@@ -2503,10 +2547,10 @@ let new_doc { doc_type ; require_libs } =
State.define ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
Backtrack.record ();
Slaves.init ();
- if Flags.async_proofs_is_master () then begin
+ if async_proofs_is_master () then begin
stm_prerr_endline (fun () -> "Initializing workers");
Query.init ();
- let opts = match !Flags.async_proofs_private_flags with
+ let opts = match !async_proofs_private_flags with
| None -> []
| Some s -> Str.split_delim (Str.regexp ",") s in
begin try
@@ -2705,7 +2749,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
| VtQuery (true, route), w ->
let id = VCS.new_node ~id:newtip () in
let queue =
- if !Flags.async_proofs_full then `QueryQueue (ref false)
+ if !async_proofs_full then `QueryQueue (ref false)
else if VCS.is_vio_doc () &&
VCS.((get_branch head).kind = `Master) &&
may_pierce_opaque x
@@ -2870,7 +2914,7 @@ let parse_sentence ~doc sid pa =
(str "Currently, the parsing api only supports parsing at the tip of the document." ++ fnl () ++
str "You wanted to parse at: " ++ str (Stateid.to_string sid) ++
str " but the current tip is: " ++ str (Stateid.to_string cur_tip)) ;
- if not (Stateid.equal sid real_tip) && !Flags.debug && stm_debug () then
+ if not (Stateid.equal sid real_tip) && !Flags.debug && !stm_debug then
Feedback.msg_debug
(str "Warning, the real tip doesn't match the current tip." ++
str "You wanted to parse at: " ++ str (Stateid.to_string sid) ++
@@ -3029,7 +3073,7 @@ let edit_at ~doc id =
VCS.delete_boxes_of id;
VCS.gc ();
VCS.print ();
- if not !Flags.async_proofs_full then
+ if not !async_proofs_full then
Reach.known_state ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip in
@@ -3045,7 +3089,7 @@ let edit_at ~doc id =
| _, Some _, None -> assert false
| false, Some { qed = qed_id ; lemma = start }, Some(mode,bn) ->
let tip = VCS.cur_tip () in
- if has_failed qed_id && is_pure qed_id && not !Flags.async_proofs_never_reopen_branch
+ if has_failed qed_id && is_pure qed_id && not !async_proofs_never_reopen_branch
then reopen_branch start id mode qed_id tip bn
else backto id (Some bn)
| true, Some { qed = qed_id }, Some(mode,bn) ->
diff --git a/stm/stm.mli b/stm/stm.mli
index 9fd35a0d3..ef95be0e4 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -225,3 +225,30 @@ val state_of_id : doc:doc ->
(* Queries for backward compatibility *)
val current_proof_depth : doc:doc -> int
val get_all_proof_names : doc:doc -> Id.t list
+
+(** Enable STM debugging *)
+val stm_debug : bool ref
+
+(* Flags *)
+module AsyncOpts : sig
+
+ (* Defaults for worker creation *)
+ val async_proofs_n_workers : int ref
+ val async_proofs_n_tacworkers : int ref
+
+ type async_proofs = APoff | APonLazy | APon
+ val async_proofs_mode : async_proofs ref
+
+ type cache = Force
+ val async_proofs_cache : cache option ref
+
+ val async_proofs_private_flags : string option ref
+ val async_proofs_full : bool ref
+ val async_proofs_never_reopen_branch : bool ref
+
+ type tac_error_filter = [ `None | `Only of string list | `All ]
+ val async_proofs_tac_error_resilience : tac_error_filter ref
+ val async_proofs_cmd_error_resilience : bool ref
+ val async_proofs_delegation_threshold : float ref
+
+end
diff --git a/stm/workerLoop.ml b/stm/workerLoop.ml
index 64121eb3d..704119186 100644
--- a/stm/workerLoop.ml
+++ b/stm/workerLoop.ml
@@ -6,6 +6,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* Default priority *)
+open CoqworkmgrApi
+let async_proofs_worker_priority = ref Low
+
let rec parse = function
| "--xml_format=Ppcmds" :: rest -> parse rest
| x :: rest -> x :: parse rest
@@ -15,5 +19,5 @@ let loop init args =
let args = parse args in
Flags.quiet := true;
init ();
- CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
+ CoqworkmgrApi.init !async_proofs_worker_priority;
args
diff --git a/stm/workerLoop.mli b/stm/workerLoop.mli
index 53f745935..da2e6fe0c 100644
--- a/stm/workerLoop.mli
+++ b/stm/workerLoop.mli
@@ -6,4 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* Default priority *)
+val async_proofs_worker_priority : CoqworkmgrApi.priority ref
+
val loop : (unit -> unit) -> string list -> string list
diff --git a/tactics/auto.ml b/tactics/auto.ml
index fa8435d1f..e7e21b5f4 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -514,8 +514,8 @@ let delta_auto debug mod_delta n lems dbnames =
let delta_auto =
if Flags.profile then
- let key = Profile.declare_profile "delta_auto" in
- Profile.profile5 key delta_auto
+ let key = CProfile.declare_profile "delta_auto" in
+ CProfile.profile5 key delta_auto
else delta_auto
let auto ?(debug=Off) n = delta_auto debug false n
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index cee6d4bea..9e4d132d4 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -376,7 +376,7 @@ let rec e_trivial_fail_db only_classes db_list local_db secvars =
Proofview.Goal.enter
begin fun gl ->
let tacs = e_trivial_resolve db_list local_db secvars only_classes
- (project gl) (pf_concl gl) in
+ (pf_env gl) (project gl) (pf_concl gl) in
tclFIRST (List.map (fun (x,_,_,_,_) -> x) tacs)
end
in
@@ -386,7 +386,7 @@ let rec e_trivial_fail_db only_classes db_list local_db secvars =
in
tclFIRST (List.map tclCOMPLETE tacl)
-and e_my_find_search db_list local_db secvars hdc complete only_classes sigma concl =
+and e_my_find_search db_list local_db secvars hdc complete only_classes env sigma concl =
let open Proofview.Notations in
let prods, concl = EConstr.decompose_prod_assum sigma concl in
let nprods = List.length prods in
@@ -464,7 +464,6 @@ and e_my_find_search db_list local_db secvars hdc complete only_classes sigma co
in
let tac = run_hint t tac in
let tac = if complete then Tacticals.New.tclCOMPLETE tac else tac in
- let _, env = Pfedit.get_current_context () in
let pp =
match p with
| Some pat when get_typeclasses_filtered_unification () ->
@@ -476,16 +475,16 @@ and e_my_find_search db_list local_db secvars hdc complete only_classes sigma co
| _ -> (tac, b, false, name, lazy (pr_hint env sigma t ++ pp))
in List.map tac_of_hint hintl
-and e_trivial_resolve db_list local_db secvars only_classes sigma concl =
+and e_trivial_resolve db_list local_db secvars only_classes env sigma concl =
let hd = try Some (decompose_app_bound sigma concl) with Bound -> None in
try
- e_my_find_search db_list local_db secvars hd true only_classes sigma concl
+ e_my_find_search db_list local_db secvars hd true only_classes env sigma concl
with Not_found -> []
-let e_possible_resolve db_list local_db secvars only_classes sigma concl =
+let e_possible_resolve db_list local_db secvars only_classes env sigma concl =
let hd = try Some (decompose_app_bound sigma concl) with Bound -> None in
try
- e_my_find_search db_list local_db secvars hd false only_classes sigma concl
+ e_my_find_search db_list local_db secvars hd false only_classes env sigma concl
with Not_found -> []
let cut_of_hints h =
@@ -719,7 +718,7 @@ module V85 = struct
let concl = Goal.V82.concl s gl in
let tacgl = {it = gl; sigma = s;} in
let secvars = secvars_of_hyps (Environ.named_context_of_val (Goal.V82.hyps s gl)) in
- let poss = e_possible_resolve hints info.hints secvars info.only_classes s concl in
+ let poss = e_possible_resolve hints info.hints secvars info.only_classes env s concl in
let unique = is_unique env s concl in
let rec aux i foundone = function
| (tac, _, extern, name, pp) :: tl ->
@@ -1072,7 +1071,7 @@ module Search = struct
else str" without backtracking"));
let secvars = compute_secvars gl in
let poss =
- e_possible_resolve hints info.search_hints secvars info.search_only_classes sigma concl in
+ e_possible_resolve hints info.search_hints secvars info.search_only_classes env sigma concl in
(* If no goal depends on the solution of this one or the
instances are irrelevant/assumed to be unique, then
we don't need to backtrack, as long as no evar appears in the goal
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
index f5c6ab879..6ea6155e0 100644
--- a/tactics/eauto.ml
+++ b/tactics/eauto.ml
@@ -148,12 +148,12 @@ let rec e_trivial_fail_db db_list local_db =
let tacl =
registered_e_assumption ::
(Tacticals.New.tclTHEN Tactics.intro next) ::
- (List.map fst (e_trivial_resolve (Tacmach.New.project gl) db_list local_db secvars (Tacmach.New.pf_concl gl)))
+ (List.map fst (e_trivial_resolve (Tacmach.New.pf_env gl) (Tacmach.New.project gl) db_list local_db secvars (Tacmach.New.pf_concl gl)))
in
Tacticals.New.tclFIRST (List.map Tacticals.New.tclCOMPLETE tacl)
end
-and e_my_find_search sigma db_list local_db secvars hdc concl =
+and e_my_find_search env sigma db_list local_db secvars hdc concl =
let hint_of_db = hintmap_of sigma secvars hdc concl in
let hintl =
List.map_append (fun db ->
@@ -178,20 +178,19 @@ and e_my_find_search sigma db_list local_db secvars hdc concl =
| Extern tacast -> conclPattern concl p tacast
in
let tac = run_hint t tac in
- let sigma, env = Pfedit.get_current_context () in
(tac, lazy (pr_hint env sigma t)))
in
List.map tac_of_hint hintl
-and e_trivial_resolve sigma db_list local_db secvars gl =
+and e_trivial_resolve env sigma db_list local_db secvars gl =
let hd = try Some (decompose_app_bound sigma gl) with Bound -> None in
- try priority (e_my_find_search sigma db_list local_db secvars hd gl)
+ try priority (e_my_find_search env sigma db_list local_db secvars hd gl)
with Not_found -> []
-let e_possible_resolve sigma db_list local_db secvars gl =
+let e_possible_resolve env sigma db_list local_db secvars gl =
let hd = try Some (decompose_app_bound sigma gl) with Bound -> None in
try List.map (fun (b, (tac, pp)) -> (tac, b, pp))
- (e_my_find_search sigma db_list local_db secvars hd gl)
+ (e_my_find_search env sigma db_list local_db secvars hd gl)
with Not_found -> []
let find_first_goal gls =
@@ -291,7 +290,7 @@ module SearchProblem = struct
let l =
let concl = Reductionops.nf_evar (project g) (pf_concl g) in
filter_tactics s.tacres
- (e_possible_resolve (project g) s.dblist (List.hd s.localdb) secvars concl)
+ (e_possible_resolve (pf_env g) (project g) s.dblist (List.hd s.localdb) secvars concl)
in
List.map
(fun (lgls, cost, pp) ->
@@ -405,8 +404,8 @@ let e_search_auto debug (in_depth,p) lems db_list gl =
pr_info_nop d;
user_err Pp.(str "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 e_search_auto_key = CProfile.declare_profile "e_search_auto" *)
+(* let e_search_auto = CProfile.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)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 0d6263246..22073d39b 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1436,8 +1436,9 @@ let injEqThen keep_proofs tac l2r (eq,_,(t,t1,t2) as u) eq_clause =
(tac (clenv_value eq_clause))
let get_previous_hyp_position id gl =
+ let env, sigma = Proofview.Goal.(env gl, sigma gl) in
let rec aux dest = function
- | [] -> raise (RefinerError (NoSuchHyp id))
+ | [] -> raise (RefinerError (env, sigma, NoSuchHyp id))
| d :: right ->
let hyp = Context.Named.Declaration.get_id d in
if Id.equal hyp id then dest else aux (MoveAfter hyp) right
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 70e84013b..7f9b5ef34 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -1400,15 +1400,10 @@ let pr_hint env sigma h = match h.obj with
| Give_exact (c, _) -> (str"exact " ++ pr_hint_elt env sigma c)
| Res_pf_THEN_trivial_fail (c, _) ->
(str"simple apply " ++ pr_hint_elt env sigma c ++ str" ; trivial")
- | Unfold_nth c -> (str"unfold " ++ pr_evaluable_reference c)
+ | Unfold_nth c ->
+ str"unfold " ++ pr_evaluable_reference c
| Extern tac ->
- let env =
- try
- let (_, env) = Pfedit.get_current_goal_context () in
- env
- with e when CErrors.noncritical e -> Global.env ()
- in
- (str "(*external*) " ++ Pputils.pr_glb_generic env tac)
+ str "(*external*) " ++ Pputils.pr_glb_generic env tac
let pr_id_hint env sigma (id, v) =
let pr_pat p = str", pattern " ++ pr_lconstr_pattern_env env sigma p in
@@ -1507,6 +1502,7 @@ let pr_hint_db_env env sigma db =
hov 2 (str"Cut: " ++ pp_hints_path (Hint_db.cut db)) ++ fnl () ++
content
+(* Deprecated in the mli *)
let pr_hint_db db =
let sigma, env = Pfedit.get_current_context () in
pr_hint_db_env env sigma db
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index 1ae3577ed..01065868d 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -249,11 +249,11 @@ let add_inversion_lemma name env sigma t sort dep inv_op =
let add_inversion_lemma_exn na com comsort bool tac =
let env = Global.env () in
- let evd = ref (Evd.from_env env) in
- let c = Constrintern.interp_type_evars env evd com in
- let evd, sort = Evd.fresh_sort_in_family ~rigid:univ_rigid env !evd comsort in
+ let sigma = Evd.from_env env in
+ let sigma, c = Constrintern.interp_type_evars env sigma com in
+ let sigma, sort = Evd.fresh_sort_in_family ~rigid:univ_rigid env sigma comsort in
try
- add_inversion_lemma na env evd c sort bool tac
+ add_inversion_lemma na env sigma c sort bool tac
with
| UserError (Some "Case analysis",s) -> (* Reference to Indrec *)
user_err ~hdr:"Inv needs Nodep Prop Set" s
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index e072bd95f..508040ec1 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -59,28 +59,6 @@ let typ_of env sigma c =
open Goptions
-(* Option for 8.2 compatibility *)
-let dependent_propositions_elimination = ref true
-
-let use_dependent_propositions_elimination () =
- !dependent_propositions_elimination
-
-let _ =
- declare_bool_option
- { optdepr = true; (* remove in 8.8 *)
- optname = "dependent-propositions-elimination tactic";
- optkey = ["Dependent";"Propositions";"Elimination"];
- optread = (fun () -> !dependent_propositions_elimination) ;
- optwrite = (fun b -> dependent_propositions_elimination := b) }
-
-let _ =
- declare_bool_option
- { optdepr = true; (* remove in 8.8 *)
- optname = "trigger bugged context matching compatibility";
- optkey = ["Tactic";"Compat";"Context"];
- optread = (fun () -> !Flags.tactic_context_compat) ;
- optwrite = (fun b -> Flags.tactic_context_compat := b) }
-
let apply_solve_class_goals = ref false
let _ =
@@ -187,7 +165,7 @@ let introduction ?(check=true) id =
match EConstr.kind sigma concl with
| 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)
+ | _ -> raise (RefinerError (env, sigma, IntroNeedsProduct))
end
let refine = Tacmach.refine
@@ -319,7 +297,7 @@ let move_hyp id dest =
let ty = Proofview.Goal.concl gl in
let store = Proofview.Goal.extra gl in
let sign = named_context_val env in
- let sign' = move_hyp_in_named_context sigma id dest sign in
+ let sign' = move_hyp_in_named_context env sigma id dest sign in
let env = reset_with_named_context sign' env in
Refine.refine ~typecheck:false begin fun sigma ->
Evarutil.new_evar env sigma ~principal:true ~store ty
@@ -348,13 +326,15 @@ let rename_hyp repl =
let hyps = Proofview.Goal.hyps gl in
let concl = Proofview.Goal.concl gl in
let store = Proofview.Goal.extra gl in
+ let env = Proofview.Goal.env gl in
+ let sigma = Proofview.Goal.sigma gl in
(** Check that we do not mess variables *)
let fold accu decl = Id.Set.add (NamedDecl.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
let hyp = Id.Set.choose (Id.Set.diff src vars) in
- raise (RefinerError (NoSuchHyp hyp))
+ raise (RefinerError (env, sigma, NoSuchHyp hyp))
in
let mods = Id.Set.diff vars src in
let () =
@@ -442,9 +422,9 @@ let find_name mayrepl decl naming gl = match naming with
(* Computing position of hypotheses for replacing *)
(**************************************************************)
-let get_next_hyp_position id =
+let get_next_hyp_position env sigma id =
let rec aux = function
- | [] -> error_no_such_hypothesis id
+ | [] -> error_no_such_hypothesis env sigma id
| decl :: right ->
if Id.equal (NamedDecl.get_id decl) id then
match right with decl::_ -> MoveBefore (NamedDecl.get_id decl) | [] -> MoveFirst
@@ -453,9 +433,9 @@ let get_next_hyp_position id =
in
aux
-let get_previous_hyp_position id =
+let get_previous_hyp_position env sigma id =
let rec aux dest = function
- | [] -> error_no_such_hypothesis id
+ | [] -> error_no_such_hypothesis env sigma id
| decl :: right ->
let hyp = NamedDecl.get_id decl in
if Id.equal hyp id then dest else aux (MoveAfter hyp) right
@@ -483,7 +463,7 @@ let internal_cut_gen ?(check=true) dir replace id t =
let sign = named_context_val env in
let sign',t,concl,sigma =
if replace then
- let nexthyp = get_next_hyp_position id (named_context_of_val sign) in
+ let nexthyp = get_next_hyp_position env sigma id (named_context_of_val sign) in
let sign',t,concl,sigma = clear_hyps2 env sigma (Id.Set.singleton id) sign t concl in
let sign' = insert_decl_in_named_context sigma (LocalAssum (id,t)) nexthyp sign' in
sign',t,concl,sigma
@@ -1000,6 +980,7 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
let open Context.Rel.Declaration in
Proofview.Goal.enter begin fun gl ->
let sigma = Tacmach.New.project gl in
+ let env = Tacmach.New.pf_env gl in
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
match EConstr.kind sigma concl with
| Prod (name,t,u) when not dep_flag || not (noccurn sigma 1 u) ->
@@ -1009,7 +990,7 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
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)
+ begin if not force_flag then Proofview.tclZERO (RefinerError (env, sigma, IntroNeedsProduct))
(* Note: red_in_concl includes betaiotazeta and this was like *)
(* this since at least V6.3 (a pity *)
(* that intro do betaiotazeta only when reduction is needed; and *)
@@ -1020,7 +1001,7 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
(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 ->
+ | RefinerError (env, sigma, IntroNeedsProduct) ->
Tacticals.New.tclZEROMSG (str "No product even after head-reduction.")
| e -> Proofview.tclZERO ~info e
end
@@ -1059,7 +1040,7 @@ let intro_forthcoming_then_gen name_flag move_flag dep_flag n bound tac =
(fun id -> aux (n+1) (id::ids))
end
begin function (e, info) -> match e with
- | RefinerError IntroNeedsProduct ->
+ | RefinerError (env, sigma, IntroNeedsProduct) ->
tac ids
| e -> Proofview.tclZERO ~info e
end
@@ -1070,8 +1051,9 @@ let intro_forthcoming_then_gen name_flag move_flag dep_flag n bound tac =
let intro_replacing id =
Proofview.Goal.enter begin fun gl ->
+ let env, sigma = Proofview.Goal.(env gl, sigma gl) in
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let next_hyp = get_next_hyp_position id hyps in
+ let next_hyp = get_next_hyp_position env sigma id hyps in
Tacticals.New.tclTHENLIST [
clear_for_replacing [id];
introduction id;
@@ -1090,8 +1072,9 @@ let intro_replacing id =
let intros_possibly_replacing ids =
let suboptimal = true in
Proofview.Goal.enter begin fun gl ->
+ let env, sigma = Proofview.Goal.(env gl, sigma gl) in
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let posl = List.map (fun id -> (id, get_next_hyp_position id hyps)) ids in
+ let posl = List.map (fun id -> (id, get_next_hyp_position env sigma id hyps)) ids in
Tacticals.New.tclTHEN
(Tacticals.New.tclMAP (fun id ->
Tacticals.New.tclTRY (clear_for_replacing [id]))
@@ -1105,7 +1088,8 @@ let intros_possibly_replacing ids =
let intros_replacing ids =
Proofview.Goal.enter begin fun gl ->
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let posl = List.map (fun id -> (id, get_next_hyp_position id hyps)) ids in
+ let env, sigma = Proofview.Goal.(env gl, sigma gl) in
+ let posl = List.map (fun id -> (id, get_next_hyp_position env sigma id hyps)) ids in
Tacticals.New.tclTHEN
(clear_for_replacing ids)
(Tacticals.New.tclMAP (fun (id,pos) -> intro_move (Some id) pos) posl)
@@ -1976,11 +1960,11 @@ let cut_and_apply c =
(* Exact tactics *)
(********************************************************************)
-(* let convert_leqkey = Profile.declare_profile "convert_leq";; *)
-(* let convert_leq = Profile.profile3 convert_leqkey convert_leq *)
+(* let convert_leqkey = CProfile.declare_profile "convert_leq";; *)
+(* let convert_leq = CProfile.profile3 convert_leqkey convert_leq *)
-(* let refine_no_checkkey = Profile.declare_profile "refine_no_check";; *)
-(* let refine_no_check = Profile.profile2 refine_no_checkkey refine_no_check *)
+(* let refine_no_checkkey = CProfile.declare_profile "refine_no_check";; *)
+(* let refine_no_check = CProfile.profile2 refine_no_checkkey refine_no_check *)
let exact_no_check c =
Refine.refine ~typecheck:false (fun h -> (h,c))
@@ -2633,8 +2617,10 @@ let general_apply_in sidecond_first with_delta with_destruct with_evars
Proofview.Goal.enter begin fun gl ->
let destopt =
if with_evars then MoveLast (* evars would depend on the whole context *)
- else
- get_previous_hyp_position id (Proofview.Goal.hyps (Proofview.Goal.assume gl)) in
+ else (
+ let env, sigma = Proofview.Goal.(env gl, sigma gl) in
+ get_previous_hyp_position env sigma id (Proofview.Goal.hyps (Proofview.Goal.assume gl))
+ ) in
let naming,ipat_tac =
prepare_intros_opt with_evars (IntroIdentifier id) destopt ipat in
let lemmas_target, last_lemma_target =
@@ -4141,8 +4127,7 @@ let guess_elim isrec dep s hyp0 gl =
let env = Tacmach.New.pf_env gl in
let sigma = Tacmach.New.project gl in
let u = EInstance.kind (Tacmach.New.project gl) u in
- if use_dependent_propositions_elimination () && dep = Some true
- then
+ if dep then
let (sigma, ind) = build_case_analysis_scheme env sigma (mind, u) true s in
let ind = EConstr.of_constr ind in
(sigma, ind)
@@ -4174,11 +4159,10 @@ let find_induction_type isrec elim hyp0 gl =
match elim with
| None ->
let sort = Tacticals.New.elimination_sort_of_goal gl in
- let _, (elimc,elimt),_ =
- guess_elim isrec None sort hyp0 gl in
- let scheme = compute_elim_sig sigma ~elimc elimt in
- (* We drop the scheme waiting to know if it is dependent *)
- scheme, ElimOver (isrec,hyp0)
+ let _, (elimc,elimt),_ = guess_elim isrec false sort hyp0 gl in
+ let scheme = compute_elim_sig sigma ~elimc elimt in
+ (* We drop the scheme waiting to know if it is dependent *)
+ scheme, ElimOver (isrec,hyp0)
| Some e ->
let evd, (elimc,elimt),ind_guess = given_elim hyp0 e gl in
let scheme = compute_elim_sig sigma ~elimc elimt in
@@ -4209,7 +4193,7 @@ let get_eliminator elim dep s gl =
| 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 (Some dep) s id gl in
+ 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 d -> assert (RelDecl.is_local_assum d); pi1 (decompose_prod_letin (Tacmach.New.project gl) (RelDecl.get_type d)))
(List.rev s.branches)
@@ -4448,8 +4432,11 @@ let check_enough_applied env sigma elim =
check_expected_type env sigma elimc elimt
let guard_no_unifiable = Proofview.guard_no_unifiable >>= function
-| None -> Proofview.tclUNIT ()
-| Some l -> Proofview.tclZERO (RefinerError (UnresolvedBindings l))
+ | None -> Proofview.tclUNIT ()
+ | Some l ->
+ Proofview.tclENV >>= function env ->
+ Proofview.tclEVARMAP >>= function sigma ->
+ Proofview.tclZERO (RefinerError (env, sigma, UnresolvedBindings l))
let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
id ((pending,(c0,lbind)),(eqname,names)) t0 inhyps cls tac =
@@ -4648,7 +4635,7 @@ let induction_destruct isrec with_evars (lc,elim) =
(Tacticals.New.tclMAP (fun (a,b,cl) ->
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
+ let sigma = Tacmach.New.project gl in
onOpenInductionArg env sigma (fun clear_flag a ->
induction_gen clear_flag false with_evars None (a,b) cl) a
end) l)
@@ -4673,7 +4660,7 @@ let induction_destruct isrec with_evars (lc,elim) =
end
let induction ev clr c l e =
- induction_gen clr true ev e
+ induction_gen clr true ev e
((Evd.empty,(c,NoBindings)),(None,l)) None
let destruct ev clr c l e =
diff --git a/test-suite/bugs/closed/6378.v b/test-suite/bugs/closed/6378.v
new file mode 100644
index 000000000..d0ef090d0
--- /dev/null
+++ b/test-suite/bugs/closed/6378.v
@@ -0,0 +1,4 @@
+Goal True.
+ start ltac profiling.
+ stop ltac profiling.
+Abort.
diff --git a/test-suite/bugs/closed/gh6384.v b/test-suite/bugs/closed/gh6384.v
new file mode 100644
index 000000000..cec84642f
--- /dev/null
+++ b/test-suite/bugs/closed/gh6384.v
@@ -0,0 +1,5 @@
+Theorem test (A:Prop) : A \/ A -> A.
+ Fail intro H; destruct H as H.
+ (* Error: Disjunctive/conjunctive introduction pattern expected. *)
+ Fail intros H; destruct H as H.
+Abort.
diff --git a/test-suite/bugs/closed/gh6385.v b/test-suite/bugs/closed/gh6385.v
new file mode 100644
index 000000000..3bbb664f4
--- /dev/null
+++ b/test-suite/bugs/closed/gh6385.v
@@ -0,0 +1,5 @@
+Theorem test (A:Prop) : A \/ A -> A.
+ Fail let H := idtac in intros H; destruct H as H'.
+ (* Disjunctive/conjunctive introduction pattern expected. *)
+ Fail let H' := idtac in intros H; destruct H as H'.
+Abort.
diff --git a/test-suite/coq-makefile/timing/after/time-of-build-after.log.desired b/test-suite/coq-makefile/timing/after/time-of-build-after.log.desired
index 729de2f36..7900c034d 100644
--- a/test-suite/coq-makefile/timing/after/time-of-build-after.log.desired
+++ b/test-suite/coq-makefile/timing/after/time-of-build-after.log.desired
@@ -1,7 +1,6 @@
Makefile:69: warning: undefined variable '*'
Makefile:204: warning: undefined variable 'DSTROOT'
-COQDEP Fast.v
-COQDEP Slow.v
+COQDEP VFILES
Makefile:69: warning: undefined variable '*'
Makefile:204: warning: undefined variable 'DSTROOT'
Makefile:69: warning: undefined variable '*'
diff --git a/test-suite/coq-makefile/timing/after/time-of-build-before.log.desired b/test-suite/coq-makefile/timing/after/time-of-build-before.log.desired
index b25bc3683..7ab0bc75d 100644
--- a/test-suite/coq-makefile/timing/after/time-of-build-before.log.desired
+++ b/test-suite/coq-makefile/timing/after/time-of-build-before.log.desired
@@ -1,7 +1,6 @@
Makefile:69: warning: undefined variable '*'
Makefile:204: warning: undefined variable 'DSTROOT'
-COQDEP Fast.v
-COQDEP Slow.v
+COQDEP VFILES
Makefile:69: warning: undefined variable '*'
Makefile:204: warning: undefined variable 'DSTROOT'
Makefile:69: warning: undefined variable '*'
diff --git a/test-suite/output-modulo-time/ltacprof.out b/test-suite/output-modulo-time/ltacprof.out
index cc04c2c9b..5553e1b38 100644
--- a/test-suite/output-modulo-time/ltacprof.out
+++ b/test-suite/output-modulo-time/ltacprof.out
@@ -1,12 +1,15 @@
-total time: 1.528s
+total time: 1.032s
- tactic local total calls max
+ tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─sleep' -------------------------------- 100.0% 100.0% 1 1.528s
+─sleep' -------------------------------- 100.0% 100.0% 1 1.032s
+─sleep --------------------------------- 0.0% 0.0% 0 0.000s
─constructor --------------------------- 0.0% 0.0% 1 0.000s
- tactic local total calls max
+ tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─sleep' -------------------------------- 100.0% 100.0% 1 1.528s
+─sleep' -------------------------------- 100.0% 100.0% 1 1.032s
+─sleep --------------------------------- 0.0% 0.0% 0 0.000s
+â””sleep' -------------------------------- 0.0% 0.0% 0 0.000s
─constructor --------------------------- 0.0% 0.0% 1 0.000s
diff --git a/test-suite/output-modulo-time/ltacprof_cutoff.out b/test-suite/output-modulo-time/ltacprof_cutoff.out
index 0cd5777cc..d91a38bb5 100644
--- a/test-suite/output-modulo-time/ltacprof_cutoff.out
+++ b/test-suite/output-modulo-time/ltacprof_cutoff.out
@@ -1,31 +1,37 @@
-total time: 1.584s
+total time: 1.632s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─foo2 ---------------------------------- 0.0% 100.0% 1 1.584s
-─sleep --------------------------------- 100.0% 100.0% 3 0.572s
-─foo1 ---------------------------------- 0.0% 63.9% 1 1.012s
+─sleep --------------------------------- 100.0% 100.0% 3 0.584s
+─foo2 ---------------------------------- 0.0% 100.0% 1 1.632s
+─foo1 ---------------------------------- 0.0% 64.2% 1 1.048s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─foo2 ---------------------------------- 0.0% 100.0% 1 1.584s
-â””foo1 ---------------------------------- 0.0% 63.9% 1 1.012s
+─foo2 ---------------------------------- 0.0% 100.0% 1 1.632s
+â””foo1 ---------------------------------- 0.0% 64.2% 1 1.048s
-total time: 1.584s
+total time: 0.520s
+
+ tactic local total calls max
+────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
+─foo2 ---------------------------------- 0.0% 100.0% 1 0.520s
+─sleep --------------------------------- 99.2% 99.2% 52 0.016s
+─foo1 ---------------------------------- 0.0% 97.7% 1 0.508s
+─foo0 ---------------------------------- 0.8% 96.2% 1 0.500s
+
+ tactic local total calls max
+────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
+─foo2 ---------------------------------- 0.0% 100.0% 1 0.520s
+â””foo1 ---------------------------------- 0.0% 97.7% 1 0.508s
+â””foo0 ---------------------------------- 0.8% 96.2% 1 0.500s
+â””sleep --------------------------------- 95.4% 95.4% 50 0.016s
+
+total time: 0.000s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─sleep --------------------------------- 100.0% 100.0% 3 0.572s
-─foo2 ---------------------------------- 0.0% 100.0% 1 1.584s
-─foo1 ---------------------------------- 0.0% 63.9% 1 1.012s
-─foo0 ---------------------------------- 0.0% 31.3% 1 0.496s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
-─foo2 ---------------------------------- 0.0% 100.0% 1 1.584s
- ├─foo1 -------------------------------- 0.0% 63.9% 1 1.012s
- │ ├─sleep ----------------------------- 32.6% 32.6% 1 0.516s
- │ └─foo0 ------------------------------ 0.0% 31.3% 1 0.496s
- │ └sleep ----------------------------- 31.3% 31.3% 1 0.496s
- └─sleep ------------------------------- 36.1% 36.1% 1 0.572s
diff --git a/test-suite/output-modulo-time/ltacprof_cutoff.v b/test-suite/output-modulo-time/ltacprof_cutoff.v
index 3dad6271a..ae5d51bae 100644
--- a/test-suite/output-modulo-time/ltacprof_cutoff.v
+++ b/test-suite/output-modulo-time/ltacprof_cutoff.v
@@ -1,12 +1,28 @@
(* -*- coq-prog-args: ("-profile-ltac") -*- *)
Require Coq.ZArith.BinInt.
-Ltac sleep := do 50 (idtac; let sleep := (eval vm_compute in Coq.ZArith.BinInt.Z.div_eucl) in idtac).
+Module WithIdTac.
+ Ltac sleep := do 50 (idtac; let sleep := (eval vm_compute in Coq.ZArith.BinInt.Z.div_eucl) in idtac).
-Ltac foo0 := idtac; sleep.
-Ltac foo1 := sleep; foo0.
-Ltac foo2 := sleep; foo1.
-Goal True.
- foo2.
- Show Ltac Profile CutOff 47.
- constructor.
-Qed.
+ Ltac foo0 := idtac; sleep.
+ Ltac foo1 := sleep; foo0.
+ Ltac foo2 := sleep; foo1.
+ Goal True.
+ foo2.
+ Show Ltac Profile CutOff 47.
+ constructor.
+ Qed.
+End WithIdTac.
+
+Module TestEval.
+ Ltac sleep := let sleep := (eval vm_compute in Coq.ZArith.BinInt.Z.div_eucl) in idtac.
+
+ Ltac foo0 := idtac; do 50 (idtac; sleep).
+ Ltac foo1 := sleep; foo0.
+ Ltac foo2 := sleep; foo1.
+ Goal True.
+ Reset Ltac Profile.
+ foo2.
+ Show Ltac Profile CutOff 47.
+ constructor.
+ Qed.
+End TestEval.
diff --git a/test-suite/output/Cases.out b/test-suite/output/Cases.out
index 97fa8e254..419dcadb4 100644
--- a/test-suite/output/Cases.out
+++ b/test-suite/output/Cases.out
@@ -95,8 +95,7 @@ fun dd : nat * nat => let (bb, cc) as aa return (aa = aa) := dd in eq_refl
x : nat
n, n0 := match x + 0 with
- | 0 => 0
- | S _ => 0
+ | 0 | S _ => 0
end : nat
e,
e0 := match x + 0 as y return (y = y) with
@@ -104,8 +103,7 @@ fun dd : nat * nat => let (bb, cc) as aa return (aa = aa) := dd in eq_refl
| S n => eq_refl
end : x + 0 = x + 0
n1, n2 := match x with
- | 0 => 0
- | S _ => 0
+ | 0 | S _ => 0
end : nat
e1, e2 := match x return (x = x) with
| 0 => eq_refl
@@ -126,3 +124,48 @@ fun dd : nat * nat => let (bb, cc) as aa return (aa = aa) := dd in eq_refl
end : p = p /\ p = p
============================
eq_refl = eq_refl
+fun x : comparison => match x with
+ | Eq => 1
+ | _ => 0
+ end
+ : comparison -> nat
+fun x : comparison => match x with
+ | Eq => 1
+ | Lt => 0
+ | Gt => 0
+ end
+ : comparison -> nat
+fun x : comparison => match x with
+ | Eq => 1
+ | Lt | Gt => 0
+ end
+ : comparison -> nat
+fun x : comparison =>
+match x return nat with
+| Eq => S O
+| Lt => O
+| Gt => O
+end
+ : forall _ : comparison, nat
+fun x : K => match x with
+ | a3 | a4 => 3
+ | _ => 2
+ end
+ : K -> nat
+fun x : K => match x with
+ | a1 | a2 => 4
+ | a3 => 3
+ | _ => 2
+ end
+ : K -> nat
+fun x : K => match x with
+ | a1 | a2 => 4
+ | a4 => 3
+ | _ => 2
+ end
+ : K -> nat
+fun x : K => match x with
+ | a1 | a3 | a4 => 3
+ | _ => 2
+ end
+ : K -> nat
diff --git a/test-suite/output/Cases.v b/test-suite/output/Cases.v
index 17fee3303..caf3b2870 100644
--- a/test-suite/output/Cases.v
+++ b/test-suite/output/Cases.v
@@ -1,5 +1,7 @@
(* Cases with let-in in constructors types *)
+Unset Printing Allow Match Default Clause.
+
Inductive t : Set :=
k : let x := t in x -> x.
@@ -184,3 +186,33 @@ let p := fresh "p" in
|- eq_refl ?p = _ => pose (match eq_refl p in _ = z return p=p /\ z=z with eq_refl => conj eq_refl eq_refl end)
end.
Show.
+
+Set Printing Allow Match Default Clause.
+
+(***************************************************)
+(* Testing strategy for factorizing cases branches *)
+
+(* Factorization + default clause *)
+Check fun x => match x with Eq => 1 | _ => 0 end.
+
+(* No factorization *)
+Unset Printing Factorizable Match Patterns.
+Check fun x => match x with Eq => 1 | _ => 0 end.
+Set Printing Factorizable Match Patterns.
+
+(* Factorization but no default clause *)
+Unset Printing Allow Match Default Clause.
+Check fun x => match x with Eq => 1 | _ => 0 end.
+Set Printing Allow Match Default Clause.
+
+(* No factorization in printing all mode *)
+Set Printing All.
+Check fun x => match x with Eq => 1 | _ => 0 end.
+Unset Printing All.
+
+(* Several clauses *)
+Inductive K := a1|a2|a3|a4|a5|a6.
+Check fun x => match x with a3 | a4 => 3 | _ => 2 end.
+Check fun x => match x with a3 => 3 | a2 | a1 => 4 | _ => 2 end.
+Check fun x => match x with a4 => 3 | a2 | a1 => 4 | _ => 2 end.
+Check fun x => match x with a3 | a4 | a1 => 3 | _ => 2 end.
diff --git a/test-suite/output/InvalidDisjunctiveIntro.out b/test-suite/output/InvalidDisjunctiveIntro.out
new file mode 100644
index 000000000..25a306b45
--- /dev/null
+++ b/test-suite/output/InvalidDisjunctiveIntro.out
@@ -0,0 +1,16 @@
+The command has indeed failed with message:
+Cannot coerce to a disjunctive/conjunctive pattern.
+The command has indeed failed with message:
+Disjunctive/conjunctive introduction pattern expected.
+The command has indeed failed with message:
+Cannot coerce to a disjunctive/conjunctive pattern.
+The command has indeed failed with message:
+Cannot coerce to a disjunctive/conjunctive pattern.
+The command has indeed failed with message:
+Ltac variable H is bound to <tactic closure> which cannot be coerced to
+an introduction pattern.
+The command has indeed failed with message:
+Disjunctive/conjunctive introduction pattern expected.
+The command has indeed failed with message:
+Ltac variable H' is bound to <tactic closure> which cannot be coerced to
+an introduction pattern.
diff --git a/test-suite/output/InvalidDisjunctiveIntro.v b/test-suite/output/InvalidDisjunctiveIntro.v
new file mode 100644
index 000000000..4febdf034
--- /dev/null
+++ b/test-suite/output/InvalidDisjunctiveIntro.v
@@ -0,0 +1,18 @@
+Theorem test (A:Prop) : A \/ A -> A.
+ Fail intros H; destruct H as H.
+ (* Cannot coerce to a disjunctive/conjunctive pattern. *)
+ Fail intro H; destruct H as H.
+ (* Disjunctive/conjunctive introduction pattern expected. *)
+ Fail let H := fresh in intro H; destruct H as H.
+ (* Cannot coerce to a disjunctive/conjunctive pattern. *)
+ Fail let H := fresh in intros H; destruct H as H.
+ (* Cannot coerce to a disjunctive/conjunctive pattern. *)
+ Fail let H := idtac in intros H; destruct H as H.
+ (* Ltac variable H is bound to <tactic closure> which cannot be
+coerced to an introduction pattern. *)
+ Fail let H := idtac in intros H; destruct H as H'.
+ (* Disjunctive/conjunctive introduction pattern expected. *)
+ Fail let H' := idtac in intros H; destruct H as H'.
+(* Ltac variable H' is bound to <tactic closure> which cannot
+be coerced to an introduction pattern. *)
+Abort.
diff --git a/test-suite/output/Notations2.out b/test-suite/output/Notations2.out
index a1028bda0..121a369a9 100644
--- a/test-suite/output/Notations2.out
+++ b/test-suite/output/Notations2.out
@@ -37,6 +37,17 @@ let' f (x y : nat) (a := 0) (z : nat) (_ : bool) := x + y + z + 1 in f 0 1 2
λ (f : nat -> nat) (x : nat), f(x) + S(x)
: (nat -> nat) -> nat -> nat
Notation plus2 n := (S(S(n)))
+λ n : list(nat), match n with
+ | 1 :: nil => 0
+ | _ => 2
+ end
+ : list(nat) -> nat
+λ n : list(nat),
+match n with
+| 1 :: nil => 0
+| nil | 0 :: _ | 1 :: _ :: _ | plus2 _ :: _ => 2
+end
+ : list(nat) -> nat
λ n : list(nat),
match n with
| nil => 2
diff --git a/test-suite/output/Notations2.v b/test-suite/output/Notations2.v
index 4c3eaa0c7..531398bb0 100644
--- a/test-suite/output/Notations2.v
+++ b/test-suite/output/Notations2.v
@@ -79,6 +79,13 @@ Notation plus2 n := (S (S n)).
(* plus2 was not correctly printed in the two following tests in 8.3pl1 *)
Print plus2.
Check fun n => match n with list1 => 0 | _ => 2 end.
+Unset Printing Allow Match Default Clause.
+Check fun n => match n with list1 => 0 | _ => 2 end.
+Unset Printing Factorizable Match Patterns.
+Check fun n => match n with list1 => 0 | _ => 2 end.
+Set Printing Allow Match Default Clause.
+Set Printing Factorizable Match Patterns.
+
End A.
(* This one is not fully satisfactory because binders in the same type
diff --git a/test-suite/success/Check.v b/test-suite/success/Check.v
index 0f677a849..82b51b1ff 100644
--- a/test-suite/success/Check.v
+++ b/test-suite/success/Check.v
@@ -12,3 +12,5 @@
Check 0.
Check S.
Check nat.
+
+Type Type : Type.
diff --git a/theories/Logic/FunctionalExtensionality.v b/theories/Logic/FunctionalExtensionality.v
index ac95ddd0c..82b04d132 100644
--- a/theories/Logic/FunctionalExtensionality.v
+++ b/theories/Logic/FunctionalExtensionality.v
@@ -221,13 +221,12 @@ Tactic Notation "extensionality" "in" hyp(H) :=
(* If we [subst H], things break if we already have another equation of the form [_ = H] *)
destruct Heq; rename H_out into H.
-(** Eta expansion follows from extensionality. *)
+(** Eta expansion is built into Coq. *)
Lemma eta_expansion_dep {A} {B : A -> Type} (f : forall x : A, B x) :
f = fun x => f x.
Proof.
intros.
- extensionality x.
reflexivity.
Qed.
diff --git a/theories/Program/Combinators.v b/theories/Program/Combinators.v
index 90db10ef1..237d878bf 100644
--- a/theories/Program/Combinators.v
+++ b/theories/Program/Combinators.v
@@ -22,15 +22,13 @@ Open Scope program_scope.
Lemma compose_id_left : forall A B (f : A -> B), id ∘ f = f.
Proof.
intros.
- unfold id, compose.
- symmetry. apply eta_expansion.
+ reflexivity.
Qed.
Lemma compose_id_right : forall A B (f : A -> B), f ∘ id = f.
Proof.
intros.
- unfold id, compose.
- symmetry ; apply eta_expansion.
+ reflexivity.
Qed.
Lemma compose_assoc : forall A B C D (f : A -> B) (g : B -> C) (h : C -> D),
@@ -47,9 +45,7 @@ Hint Rewrite <- @compose_assoc : core.
Lemma flip_flip : forall A B C, @flip A B C ∘ flip = id.
Proof.
- unfold flip, compose.
intros.
- extensionality x ; extensionality y ; extensionality z.
reflexivity.
Qed.
@@ -57,9 +53,7 @@ Qed.
Lemma prod_uncurry_curry : forall A B C, @prod_uncurry A B C ∘ prod_curry = id.
Proof.
- simpl ; intros.
- unfold prod_uncurry, prod_curry, compose.
- extensionality x ; extensionality y ; extensionality z.
+ intros.
reflexivity.
Qed.
diff --git a/theories/Sets/Powerset_facts.v b/theories/Sets/Powerset_facts.v
index 2dd559a95..209c22f71 100644
--- a/theories/Sets/Powerset_facts.v
+++ b/theories/Sets/Powerset_facts.v
@@ -40,6 +40,11 @@ Section Sets_as_an_algebra.
auto 6 with sets.
Qed.
+ Theorem Empty_set_zero_right : forall X:Ensemble U, Union U X (Empty_set U) = X.
+ Proof.
+ auto 6 with sets.
+ Qed.
+
Theorem Empty_set_zero' : forall x:U, Add U (Empty_set U) x = Singleton U x.
Proof.
unfold Add at 1; auto using Empty_set_zero with sets.
@@ -131,6 +136,17 @@ Section Sets_as_an_algebra.
elim H'; intros x0 H'0; elim H'0; auto with sets.
Qed.
+ Lemma Distributivity_l
+ : forall (A B C : Ensemble U),
+ Intersection U (Union U A B) C =
+ Union U (Intersection U A C) (Intersection U B C).
+ Proof.
+ intros A B C.
+ rewrite Intersection_commutative.
+ rewrite Distributivity.
+ f_equal; apply Intersection_commutative.
+ Qed.
+
Theorem Distributivity' :
forall A B C:Ensemble U,
Union U A (Intersection U B C) =
@@ -251,6 +267,81 @@ Section Sets_as_an_algebra.
intros; apply Definition_of_covers; auto with sets.
Qed.
+ Lemma Disjoint_Intersection:
+ forall A s1 s2, Disjoint A s1 s2 -> Intersection A s1 s2 = Empty_set A.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * destruct H.
+ intros x H1. unfold In in *. exfalso. intuition. apply (H _ H1).
+ * intuition.
+ Qed.
+
+ Lemma Intersection_Empty_set_l:
+ forall A s, Intersection A (Empty_set A) s = Empty_set A.
+ Proof.
+ intros. auto with sets.
+ Qed.
+
+ Lemma Intersection_Empty_set_r:
+ forall A s, Intersection A s (Empty_set A) = Empty_set A.
+ Proof.
+ intros. auto with sets.
+ Qed.
+
+ Lemma Seminus_Empty_set_l:
+ forall A s, Setminus A (Empty_set A) s = Empty_set A.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H1. destruct H1. unfold In in *. assumption.
+ * intuition.
+ Qed.
+
+ Lemma Seminus_Empty_set_r:
+ forall A s, Setminus A s (Empty_set A) = s.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H1. destruct H1. unfold In in *. assumption.
+ * intuition.
+ Qed.
+
+ Lemma Setminus_Union_l:
+ forall A s1 s2 s3,
+ Setminus A (Union A s1 s2) s3 = Union A (Setminus A s1 s3) (Setminus A s2 s3).
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H. inversion H. inversion H0; intuition.
+ * intros x H. constructor; inversion H; inversion H0; intuition.
+ Qed.
+
+ Lemma Setminus_Union_r:
+ forall A s1 s2 s3,
+ Setminus A s1 (Union A s2 s3) = Setminus A (Setminus A s1 s2) s3.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H. inversion H. constructor. intuition. contradict H1. intuition.
+ * intros x H. inversion H. inversion H0. constructor; intuition. inversion H4; intuition.
+ Qed.
+
+ Lemma Setminus_Disjoint_noop:
+ forall A s1 s2,
+ Intersection A s1 s2 = Empty_set A -> Setminus A s1 s2 = s1.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H1. inversion_clear H1. intuition.
+ * intros x H1. constructor; intuition. contradict H.
+ apply Inhabited_not_empty.
+ exists x. intuition.
+ Qed.
+
+ Lemma Setminus_Included_empty:
+ forall A s1 s2,
+ Included A s1 s2 -> Setminus A s1 s2 = Empty_set A.
+ Proof.
+ intros. apply Extensionality_Ensembles. split.
+ * intros x H1. inversion_clear H1. contradiction H2. intuition.
+ * intuition.
+ Qed.
+
End Sets_as_an_algebra.
Hint Resolve Empty_set_zero Empty_set_zero' Union_associative Union_add
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index 7fd942908..33a2f8593 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -87,7 +87,6 @@ COQCHK ?= "$(COQBIN)coqchk"
COQDEP ?= "$(COQBIN)coqdep"
GALLINA ?= "$(COQBIN)gallina"
COQDOC ?= "$(COQBIN)coqdoc"
-COQMKTOP ?= "$(COQBIN)coqmktop"
COQMKFILE ?= "$(COQBIN)coq_makefile"
# Timing scripts
@@ -228,8 +227,9 @@ COQTOPINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)toploop)
# We here define a bunch of variables about the files being part of the
# Coq project in order to ease the writing of build target and build rules
+VDFILE := .coqdeps
+
ALLSRCFILES := \
- $(VFILES) \
$(ML4FILES) \
$(MLFILES) \
$(MLPACKFILES) \
@@ -289,13 +289,15 @@ ALLNATIVEFILES = \
$(OBJFILES:.o=.cmi) \
$(OBJFILES:.o=.cmx) \
$(OBJFILES:.o=.cmxs)
-# trick: wildcard filters out non-existing files
-NATIVEFILESTOINSTALL = $(foreach f, $(ALLNATIVEFILES), $(wildcard $f))
+# trick: wildcard filters out non-existing files, so that `install` doesn't show
+# warnings and `clean` doesn't pass to rm a list of files that is too long for
+# the shell.
+NATIVEFILES = $(wildcard $(ALLNATIVEFILES))
FILESTOINSTALL = \
$(VOFILES) \
$(VFILES) \
$(GLOBFILES) \
- $(NATIVEFILESTOINSTALL) \
+ $(NATIVEFILES) \
$(CMIFILESTOINSTALL)
BYTEFILESTOINSTALL = \
$(CMOFILESTOINSTALL) \
@@ -307,7 +309,7 @@ else
DO_NATDYNLINK =
endif
-ALLDFILES = $(addsuffix .d,$(ALLSRCFILES))
+ALLDFILES = $(addsuffix .d,$(ALLSRCFILES) $(VDFILE))
# Compilation targets #########################################################
@@ -432,7 +434,7 @@ all.pdf: $(VFILES)
-o $@ `$(COQDEP) -sort -suffix .v $(VFILES)`
# FIXME: not quite right, since the output name is different
-gallinahtml: GAL=g
+gallinahtml: GAL=-g
gallinahtml: html
all-gal.ps: GAL=-g
@@ -535,7 +537,7 @@ clean::
$(HIDE)rm -f $(CMOFILES:.cmo=.o)
$(HIDE)rm -f $(CMXAFILES:.cmxa=.a)
$(HIDE)rm -f $(ALLDFILES)
- $(HIDE)rm -f $(ALLNATIVEFILES)
+ $(HIDE)rm -f $(NATIVEFILES)
$(HIDE)find . -name .coq-native -type d -empty -delete
$(HIDE)rm -f $(VOFILES)
$(HIDE)rm -f $(VOFILES:.vo=.vio)
@@ -563,7 +565,7 @@ cleanall:: clean
archclean::
@# Extension point
$(SHOW)'CLEAN *.cmx *.o'
- $(HIDE)rm -f $(ALLNATIVEFILES)
+ $(HIDE)rm -f $(NATIVEFILES)
$(HIDE)rm -f $(CMOFILES:%.cmo=%.cmx)
.PHONY: archclean
@@ -712,9 +714,9 @@ $(addsuffix .d,$(MLPACKFILES)): %.mlpack.d: %.mlpack
$(SHOW)'COQDEP $<'
$(HIDE)$(COQDEP) $(OCAMLLIBS) -c "$<" $(redir_if_ok)
-$(addsuffix .d,$(VFILES)): %.v.d: %.v
- $(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEP) $(COQLIBS) -dyndep var -c "$<" $(redir_if_ok)
+$(VDFILE).d: $(VFILES)
+ $(SHOW)'COQDEP VFILES'
+ $(HIDE)$(COQDEP) $(COQLIBS) -dyndep var -c $(VFILES) $(redir_if_ok)
# Misc ########################################################################
diff --git a/tools/coqmktop.ml b/tools/coqmktop.ml
deleted file mode 100644
index 950ed53cc..000000000
--- a/tools/coqmktop.ml
+++ /dev/null
@@ -1,314 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** {1 Coqmktop} *)
-
-(** coqmktop is a script to link Coq, analogous to ocamlmktop.
- The command line contains options specific to coqmktop, options for the
- Ocaml linker and files to link (in addition to the default Coq files). *)
-
-(** {6 Utilities} *)
-
-(** Split a string at each blank
-*)
-let split_list =
- let spaces = Str.regexp "[ \t\n]+" in
- fun str -> Str.split spaces str
-
-[@@@ocaml.warning "-3"] (* String.uncapitalize_ascii since 4.03.0 GPR#124 *)
-let capitalize = String.capitalize
-[@@@ocaml.warning "+3"]
-
-let (/) = Filename.concat
-
-(** Which user files do we support (and propagate to ocamlopt) ?
-*)
-let supported_suffix f = match CUnix.get_extension f with
- | ".ml" | ".cmx" | ".cmo" | ".cmxa" | ".cma" | ".c" -> true
- | _ -> false
-
-let supported_flambda_option f = List.mem f Coq_config.flambda_flags
-
-(** From bytecode extension to native
-*)
-let native_suffix f = match CUnix.get_extension f with
- | ".cmo" -> (Filename.chop_suffix f ".cmo") ^ ".cmx"
- | ".cma" -> (Filename.chop_suffix f ".cma") ^ ".cmxa"
- | ".a" -> f
- | _ -> failwith ("File "^f^" has not extension .cmo, .cma or .a")
-
-(** Transforms a file name in the corresponding Caml module name.
-*)
-let module_of_file name =
- capitalize (try Filename.chop_extension name with Invalid_argument _ -> name)
-
-(** Run a command [prog] with arguments [args].
- We do not use [Sys.command] anymore, see comment in [CUnix.sys_command].
-*)
-let run_command prog args =
- match CUnix.sys_command prog args with
- | Unix.WEXITED 127 -> failwith ("no such command "^prog)
- | Unix.WEXITED n -> n
- | Unix.WSIGNALED n -> failwith (prog^" killed by signal "^string_of_int n)
- | Unix.WSTOPPED n -> failwith (prog^" stopped by signal "^string_of_int n)
-
-
-
-(** {6 Coqmktop options} *)
-
-let opt = ref false
-let top = ref false
-let echo = ref false
-let no_start = ref false
-
-let is_ocaml4 = Coq_config.caml_version.[0] <> '3'
-
-(** {6 Includes options} *)
-
-(** Since the Coq core .cma are given with their relative paths
- (e.g. "lib/clib.cma"), we only need to include directories mentionned in
- the temp main ml file below (for accessing the corresponding .cmi). *)
-
-let std_includes basedir =
- let rebase d = match basedir with None -> d | Some base -> base / d in
- ["-I"; rebase ".";
- "-I"; rebase "lib";
- "-I"; rebase "vernac"; (* For Mltop *)
- "-I"; rebase "toplevel";
- "-I"; rebase "kernel/byterun";
- "-I"; Envars.camlp4lib () ] @
- (if is_ocaml4 then ["-I"; "+compiler-libs"] else [])
-
-(** For the -R option, visit all directories under [dir] and add
- corresponding -I to the [opts] option list (in reversed order) *)
-let incl_all_subdirs dir opts =
- let l = ref opts in
- let add f = l := f :: "-I" :: !l in
- let rec traverse dir =
- if Sys.file_exists dir && Sys.is_directory dir then
- let () = add dir in
- let subdirs = try Sys.readdir dir with any -> [||] in
- Array.iter (fun f -> traverse (dir/f)) subdirs
- in
- traverse dir; !l
-
-
-(** {6 Objects to link} *)
-
-(** NB: dynlink is now always linked, it is used for loading plugins
- and compiled vm code (see native-compiler). We now reject platforms
- with ocamlopt but no dynlink.cmxa during ./configure, and give
- instructions there about how to build a dummy dynlink.cmxa,
- cf. dev/dynlink.ml. *)
-
-(** OCaml + CamlpX libraries *)
-
-let ocaml_libs = ["str.cma";"unix.cma";"nums.cma";"dynlink.cma";"threads.cma"]
-let camlp4_libs = ["gramlib.cma"]
-let libobjs = ocaml_libs @ camlp4_libs
-
-(** Toplevel objects *)
-
-let ocaml_topobjs =
- if is_ocaml4 then
- ["ocamlcommon.cma";"ocamlbytecomp.cma";"ocamltoplevel.cma"]
- else
- ["toplevellib.cma"]
-
-let camlp4_topobjs = ["camlp5_top.cma"; "pa_o.cmo"; "pa_extend.cmo"]
-
-let topobjs = ocaml_topobjs @ camlp4_topobjs
-
-(** Coq Core objects *)
-
-let copts = (split_list Coq_config.osdeplibs) @ (split_list Tolink.copts)
-let core_objs = split_list Tolink.core_objs
-let core_libs = split_list Tolink.core_libs
-
-(** Build the list of files to link and the list of modules names
-*)
-let files_to_link userfiles =
- let top = if !top then topobjs else [] in
- let modules = List.map module_of_file (top @ core_objs @ userfiles) in
- let objs = libobjs @ top @ core_libs in
- let objs' = (if !opt then List.map native_suffix objs else objs) @ userfiles
- in (modules, objs')
-
-
-(** {6 Parsing of the command-line} *)
-
-let usage () =
- prerr_endline "Usage: coqmktop <options> <ocaml options> files\
-\nFlags are:\
-\n -coqlib dir Specify where the Coq object files are\
-\n -ocamlfind dir Specify where the ocamlfind binary is\
-\n -camlp4bin dir Specify where the Camlp4/5 binaries are\
-\n -o exec-file Specify the name of the resulting toplevel\
-\n -boot Run in boot mode\
-\n -echo Print calls to external commands\
-\n -opt Compile in native code\
-\n -top Build Coq on a OCaml toplevel (incompatible with -opt)\
-\n -R dir Add recursively dir to OCaml search path\
-\n";
- exit 1
-
-let parse_args () =
- let rec parse (op,fl) = function
- | [] -> List.rev op, List.rev fl
-
- (* Directories *)
- | "-coqlib" :: d :: rem ->
- Flags.coqlib_spec := true; Flags.coqlib := d ; parse (op,fl) rem
- | "-ocamlfind" :: d :: rem ->
- Flags.ocamlfind_spec := true; Flags.ocamlfind := d ; parse (op,fl) rem
- | "-camlp4bin" :: d :: rem ->
- Flags.camlp4bin_spec := true; Flags.camlp4bin := d ; parse (op,fl) rem
- | "-R" :: d :: rem -> parse (incl_all_subdirs d op,fl) rem
- | ("-coqlib"|"-camlbin"|"-camlp4bin"|"-R") :: [] -> usage ()
-
- (* Boolean options of coqmktop *)
- | "-boot" :: rem -> Flags.boot := true; parse (op,fl) rem
- | "-opt" :: rem -> opt := true ; parse (op,fl) rem
- | "-top" :: rem -> top := true ; parse (op,fl) rem
- | "-no-start" :: rem -> no_start:=true; parse (op, fl) rem
- | "-echo" :: rem -> echo := true ; parse (op,fl) rem
-
- (* Extra options with arity 0 or 1, directly passed to ocamlc/ocamlopt *)
- | ("-noassert"|"-compact"|"-g"|"-p"|"-thread"|"-dtypes" as o) :: rem ->
- parse (o::op,fl) rem
- | ("-cclib"|"-ccopt"|"-I"|"-o"|"-w" as o) :: rem' ->
- begin
- match rem' with
- | a :: rem -> parse (a::o::op,fl) rem
- | [] -> usage ()
- end
-
- | ("-h"|"-help"|"--help") :: _ -> usage ()
- | f :: rem when supported_flambda_option f -> parse (op,fl) rem
- | f :: rem when supported_suffix f -> parse (op,f::fl) rem
- | f :: _ -> prerr_endline ("Don't know what to do with " ^ f); exit 1
- in
- parse ([],[]) (List.tl (Array.to_list Sys.argv))
-
-
-(** {6 Temporary main file} *)
-
-(** remove the temporary main file
-*)
-let clean file =
- let rm f = if Sys.file_exists f then Sys.remove f in
- let basename = Filename.chop_suffix file ".ml" in
- if not !echo then begin
- rm file;
- rm (basename ^ ".o");
- rm (basename ^ ".cmi");
- rm (basename ^ ".cmo");
- rm (basename ^ ".cmx")
- end
-
-(** Initializes the kind of loading in the main program
-*)
-let declare_loading_string () =
- if not !top then
- "Mltop.remove ();;"
- else
- "begin try\
-\n (* Enable rectypes in the toplevel if it has the directive #rectypes *)\
-\n begin match Hashtbl.find Toploop.directive_table \"rectypes\" with\
-\n | Toploop.Directive_none f -> f ()\
-\n | _ -> ()\
-\n end\
-\n with\
-\n | Not_found -> ()\
-\n end;;\
-\n\
-\n let ppf = Format.std_formatter;;\
-\n Mltop.set_top\
-\n {Mltop.load_obj=\
-\n (fun f -> if not (Topdirs.load_file ppf f)\
-\n then CErrors.user_err Pp.(str (\"Could not load plugin \"^f)));\
-\n Mltop.use_file=Topdirs.dir_use ppf;\
-\n Mltop.add_dir=Topdirs.dir_directory;\
-\n Mltop.ml_loop=(fun () -> Toploop.loop ppf) };;\
-\n"
-
-(** create a temporary main file to link
-*)
-let create_tmp_main_file modules =
- let main_name,oc = Filename.open_temp_file "coqmain" ".ml" in
- try
- (* Add the pre-linked modules *)
- output_string oc "List.iter Mltop.add_known_module [\"";
- output_string oc (String.concat "\";\"" modules);
- output_string oc "\"];;\n";
- (* Initializes the kind of loading *)
- output_string oc (declare_loading_string());
- (* Start the toplevel loop *)
- if not !no_start then output_string oc "Coqtop.start();;\n";
- close_out oc;
- main_name
- with reraise ->
- clean main_name; raise reraise
-
-(* TODO: remove once OCaml 4.04 is adopted *)
-let split_on_char sep s =
- let r = ref [] in
- let j = ref (String.length s) in
- for i = String.length s - 1 downto 0 do
- if s.[i] = sep then begin
- r := String.sub s (i + 1) (!j - i - 1) :: !r;
- j := i
- end
- done;
- String.sub s 0 !j :: !r
-
-(** {6 Main } *)
-
-let main () =
- let (options, userfiles) = parse_args () in
- (* Directories: *)
- let () = Envars.set_coqlib ~fail:(fun x -> CErrors.user_err Pp.(str x)) in
- let basedir = if !Flags.boot then None else Some (Envars.coqlib ()) in
- (* Which ocaml compiler to invoke *)
- let prog = if !opt then "opt" else "ocamlc" in
- (* Which arguments ? *)
- if !opt && !top then failwith "no custom toplevel in native code!";
- let flags = if !opt then Coq_config.flambda_flags else Coq_config.vmbyteflags in
- let topstart = if !top then [ "topstart.cmo" ] else [] in
- let (modules, tolink) = files_to_link userfiles in
- let main_file = create_tmp_main_file modules in
- try
- (* - We add topstart.cmo explicitly because we shunted ocamlmktop wrapper.
- - With the coq .cma, we MUST use the -linkall option. *)
- let coq_camlflags =
- List.filter ((<>) "") (split_on_char ' ' Coq_config.caml_flags) in
- let args =
- coq_camlflags @ "-linkall" :: "-w" :: "-31" :: flags @ copts @ options @
- (std_includes basedir) @ tolink @ [ main_file ] @ topstart
- in
- if !echo then begin
- let command = String.concat " " (Envars.ocamlfind ()::prog::args) in
- print_endline command;
- print_endline
- ("(command length is " ^
- (string_of_int (String.length command)) ^ " characters)");
- flush Pervasives.stdout
- end;
- let exitcode = run_command (Envars.ocamlfind ()) (prog::args) in
- clean main_file;
- exitcode
- with reraise -> clean main_file; raise reraise
-
-let pr_exn = function
- | Failure msg -> msg
- | Unix.Unix_error (err,fn,arg) -> fn^" "^arg^" : "^Unix.error_message err
- | any -> Printexc.to_string any
-
-let _ =
- try exit (main ())
- with any -> Printf.eprintf "Error: %s\n" (pr_exn any); exit 1
diff --git a/tools/coqworkmgr.ml b/tools/coqworkmgr.ml
index e1d1c60d7..f4777c4fb 100644
--- a/tools/coqworkmgr.ml
+++ b/tools/coqworkmgr.ml
@@ -14,7 +14,7 @@ type party = {
sock : Unix.file_descr;
cout : out_channel;
mutable tokens : int;
- priority : Flags.priority;
+ priority : priority;
}
let answer party msg =
@@ -42,10 +42,10 @@ end = struct
let is_empty q = !q = []
let rec split acc = function
| [] -> List.rev acc, []
- | (_, { priority = Flags.Low }) :: _ as l -> List.rev acc, l
+ | (_, { priority = Low }) :: _ as l -> List.rev acc, l
| x :: xs -> split (x :: acc) xs
let push (_,{ priority } as item) q =
- if priority = Flags.Low then q := !q @ [item]
+ if priority = Low then q := !q @ [item]
else
let high, low = split [] !q in
q := high @ (item :: low)
@@ -148,7 +148,7 @@ let check_alive s =
| Some s ->
let cout = Unix.out_channel_of_descr s in
set_binary_mode_out cout true;
- output_string cout (print_request (Hello Flags.Low)); flush cout;
+ output_string cout (print_request (Hello Low)); flush cout;
output_string cout (print_request Ping); flush cout;
begin match Unix.select [s] [] [] 1.0 with
| [s],_,_ ->
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index 553da2dc0..437b7b0ac 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -71,7 +71,7 @@ let init_color () =
let toploop_init = ref begin fun x ->
let () = init_color () in
- let () = CoqworkmgrApi.(init !Flags.async_proofs_worker_priority) in
+ let () = CoqworkmgrApi.init !WorkerLoop.async_proofs_worker_priority in
x
end
@@ -529,18 +529,18 @@ let print_config = ref false
let print_tags = ref false
let get_priority opt s =
- try Flags.priority_of_string s
+ try CoqworkmgrApi.priority_of_string s
with Invalid_argument _ ->
prerr_endline ("Error: low/high expected after "^opt); exit 1
-let get_async_proofs_mode opt = function
- | "no" | "off" -> Flags.APoff
- | "yes" | "on" -> Flags.APon
- | "lazy" -> Flags.APonLazy
+let get_async_proofs_mode opt = let open Stm.AsyncOpts in function
+ | "no" | "off" -> APoff
+ | "yes" | "on" -> APon
+ | "lazy" -> APonLazy
| _ -> prerr_endline ("Error: on/off/lazy expected after "^opt); exit 1
let get_cache opt = function
- | "force" -> Some Flags.Force
+ | "force" -> Some Stm.AsyncOpts.Force
| _ -> prerr_endline ("Error: force expected after "^opt); exit 1
@@ -649,23 +649,23 @@ let parse_args arglist =
(* Options with one arg *)
|"-coqlib" -> Flags.coqlib_spec:=true; Flags.coqlib:=(next ())
|"-async-proofs" ->
- Flags.async_proofs_mode := get_async_proofs_mode opt (next())
+ Stm.AsyncOpts.async_proofs_mode := get_async_proofs_mode opt (next())
|"-async-proofs-j" ->
- Flags.async_proofs_n_workers := (get_int opt (next ()))
+ Stm.AsyncOpts.async_proofs_n_workers := (get_int opt (next ()))
|"-async-proofs-cache" ->
- Flags.async_proofs_cache := get_cache opt (next ())
+ Stm.AsyncOpts.async_proofs_cache := get_cache opt (next ())
|"-async-proofs-tac-j" ->
- Flags.async_proofs_n_tacworkers := (get_int opt (next ()))
+ Stm.AsyncOpts.async_proofs_n_tacworkers := (get_int opt (next ()))
|"-async-proofs-worker-priority" ->
- Flags.async_proofs_worker_priority := get_priority opt (next ())
+ WorkerLoop.async_proofs_worker_priority := get_priority opt (next ())
|"-async-proofs-private-flags" ->
- Flags.async_proofs_private_flags := Some (next ());
+ Stm.AsyncOpts.async_proofs_private_flags := Some (next ());
|"-async-proofs-tactic-error-resilience" ->
- Flags.async_proofs_tac_error_resilience := get_error_resilience opt (next ())
+ Stm.AsyncOpts.async_proofs_tac_error_resilience := get_error_resilience opt (next ())
|"-async-proofs-command-error-resilience" ->
- Flags.async_proofs_cmd_error_resilience := get_bool opt (next ())
+ Stm.AsyncOpts.async_proofs_cmd_error_resilience := get_bool opt (next ())
|"-async-proofs-delegation-threshold" ->
- Flags.async_proofs_delegation_threshold:= get_float opt (next ())
+ Stm.AsyncOpts.async_proofs_delegation_threshold:= get_float opt (next ())
|"-worker-id" -> set_worker_id opt (next ())
|"-compat" ->
let v = G_vernac.parse_compat_version ~allow_old:false (next ()) in
@@ -705,9 +705,9 @@ let parse_args arglist =
|"-async-queries-always-delegate"
|"-async-proofs-always-delegate"
|"-async-proofs-full" ->
- Flags.async_proofs_full := true;
+ Stm.AsyncOpts.async_proofs_full := true;
|"-async-proofs-never-reopen-branch" ->
- Flags.async_proofs_never_reopen_branch := true;
+ Stm.AsyncOpts.async_proofs_never_reopen_branch := true;
|"-batch" -> set_batch_mode ()
|"-test-mode" -> Flags.test_mode := true
|"-beautify" -> Flags.beautify := true
@@ -716,7 +716,7 @@ let parse_args arglist =
|"-color" -> set_color (next ())
|"-config"|"--config" -> print_config := true
|"-debug" -> Coqinit.set_debug ()
- |"-stm-debug" -> Flags.stm_debug := true
+ |"-stm-debug" -> Stm.stm_debug := true
|"-emacs" -> set_emacs ()
|"-filteropts" -> filter_opts := true
|"-h"|"-H"|"-?"|"-help"|"--help" -> usage !batch_mode
@@ -727,9 +727,9 @@ let parse_args arglist =
|"-noinit"|"-nois" -> load_init := false
|"-no-glob"|"-noglob" -> Dumpglob.noglob (); glob_opt := true
|"-native-compiler" ->
- if Coq_config.no_native_compiler then
+ if not Coq_config.native_compiler then
warning "Native compilation was disabled at configure time."
- else Flags.native_compiler := true
+ else Flags.output_native_objects := true
|"-output-context" -> output_context := true
|"-profile-ltac" -> Flags.profile_ltac := true
|"-q" -> Coqinit.no_load_rc ()
@@ -756,7 +756,7 @@ let init_toplevel arglist =
(* Coq's init process, phase 1:
- OCaml parameters, and basic structures and IO
*)
- Profile.init_profile ();
+ CProfile.init_profile ();
init_gc ();
Sys.catch_break false; (* Ctrl-C is fatal during the initialisation *)
let init_feeder = Feedback.add_feeder coqtop_init_feed in
@@ -846,7 +846,5 @@ let start () =
let sigma, env = Pfedit.get_current_context () in
Feedback.msg_notice (Flags.(with_option raw_print (Prettyp.print_full_pure_context env) sigma) ++ fnl ())
end;
- Profile.print_profile ();
+ CProfile.print_profile ();
exit 0
-
-(* [Coqtop.start] will be called by the code produced by coqmktop *)
diff --git a/toplevel/coqtop_bin.ml b/toplevel/coqtop_bin.ml
new file mode 100644
index 000000000..56aced92a
--- /dev/null
+++ b/toplevel/coqtop_bin.ml
@@ -0,0 +1,2 @@
+(* Main coqtop initialization *)
+let () = Coqtop.start()
diff --git a/toplevel/coqtop_byte_bin.ml b/toplevel/coqtop_byte_bin.ml
new file mode 100644
index 000000000..7d8354ec3
--- /dev/null
+++ b/toplevel/coqtop_byte_bin.ml
@@ -0,0 +1,21 @@
+let drop_setup () =
+ begin try
+ (* Enable rectypes in the toplevel if it has the directive #rectypes *)
+ begin match Hashtbl.find Toploop.directive_table "rectypes" with
+ | Toploop.Directive_none f -> f ()
+ | _ -> ()
+ end
+ with
+ | Not_found -> ()
+ end;
+ let ppf = Format.std_formatter in
+ Mltop.(set_top
+ { load_obj = (fun f -> if not (Topdirs.load_file ppf f)
+ then CErrors.user_err Pp.(str ("Could not load plugin "^f))
+ );
+ use_file = Topdirs.dir_use ppf;
+ add_dir = Topdirs.dir_directory;
+ ml_loop = (fun () -> Toploop.loop ppf);
+ })
+
+let _ = drop_setup ()
diff --git a/toplevel/coqtop_opt_bin.ml b/toplevel/coqtop_opt_bin.ml
new file mode 100644
index 000000000..410b4679a
--- /dev/null
+++ b/toplevel/coqtop_opt_bin.ml
@@ -0,0 +1,3 @@
+let drop_setup () = Mltop.remove ()
+
+let _ = drop_setup ()
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 3e47f881c..c2e9a5ab4 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -8,10 +8,7 @@
(*i*)
open Names
-open Term
-open Constr
-open Vars
-open Environ
+open EConstr
open Nametab
open CErrors
open Util
@@ -70,7 +67,7 @@ let existing_instance glob g info =
let c = global g in
let info = Option.default Hints.empty_hint_info info in
let instance, _ = Global.type_of_global_in_context (Global.env ()) c in
- let _, r = decompose_prod_assum instance in
+ let _, r = Term.decompose_prod_assum instance in
match class_of_constr Evd.empty (EConstr.of_constr r) with
| Some (_, ((tc,u), _)) -> add_instance (new_instance tc info glob
(*FIXME*) (Flags.use_polymorphic_flag ()) c)
@@ -83,19 +80,20 @@ let mismatched_props env n m = mismatched_ctx_inst env Properties n m
(* Declare everything in the parameters as implicit, and the class instance as well *)
-let type_ctx_instance evars env ctx inst subst =
- let rec aux (subst, instctx) l = function
+let type_ctx_instance env sigma ctx inst subst =
+ let open Vars in
+ let rec aux (sigma, subst, instctx) l = function
decl :: ctx ->
let t' = substl subst (RelDecl.get_type decl) in
- let c', l =
+ let (sigma, c'), l =
match decl with
- | LocalAssum _ -> EConstr.Unsafe.to_constr (interp_casted_constr_evars env evars (List.hd l) t'), List.tl l
- | LocalDef (_,b,_) -> substl subst b, l
+ | LocalAssum _ -> interp_casted_constr_evars env sigma (List.hd l) t', List.tl l
+ | LocalDef (_,b,_) -> (sigma, substl subst b), l
in
let d = RelDecl.get_name decl, Some c', t' in
- aux (c' :: subst, d :: instctx) l ctx
- | [] -> subst
- in aux (subst, []) inst (List.rev ctx)
+ aux (sigma, c' :: subst, d :: instctx) l ctx
+ | [] -> sigma, subst
+ in aux (sigma, subst, []) inst (List.rev ctx)
let id_of_class cl =
match cl.cl_impl with
@@ -112,32 +110,31 @@ let instance_hook k info global imps ?hook cst =
Typeclasses.declare_instance (Some info) (not global) cst;
(match hook with Some h -> h cst | None -> ())
-let declare_instance_constant k info global imps ?hook id decl poly evm term termtype =
+let declare_instance_constant k info global imps ?hook id decl poly sigma term termtype =
let kind = IsDefinition Instance in
- let evm =
+ let sigma =
let env = Global.env () in
let levels = Univ.LSet.union (Univops.universes_of_constr env termtype)
(Univops.universes_of_constr env term) in
- Evd.restrict_universe_context evm levels
+ Evd.restrict_universe_context sigma levels
in
- let uctx = Evd.check_univ_decl ~poly evm decl in
+ let uctx = Evd.check_univ_decl ~poly sigma decl in
let entry =
Declare.definition_entry ~types:termtype ~univs:uctx term
in
let cdecl = (DefinitionEntry entry, kind) in
let kn = Declare.declare_constant id cdecl in
Declare.definition_message id;
- Declare.declare_univ_binders (ConstRef kn) (Evd.universe_binders evm);
+ Declare.declare_univ_binders (ConstRef kn) (Evd.universe_binders sigma);
instance_hook k info global imps ?hook (ConstRef kn);
id
let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
- poly ctx (instid, bk, cl) props ?(generalize=true)
+ ~program_mode poly ctx (instid, bk, cl) props ?(generalize=true)
?(tac:unit Proofview.tactic option) ?hook pri =
let env = Global.env() in
let ((loc, instid), pl) = instid in
- let evd, decl = Univdecls.interp_univ_decl_opt env pl in
- let evars = ref evd in
+ let sigma, decl = Univdecls.interp_univ_decl_opt env pl in
let tclass, ids =
match bk with
| Decl_kinds.Implicit ->
@@ -155,26 +152,26 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
if generalize then CAst.make @@ CGeneralization (Implicit, Some AbsPi, tclass)
else tclass
in
- let k, u, cty, ctx', ctx, len, imps, subst =
- let impls, ((env', ctx), imps) = interp_context_evars env evars ctx in
- let ctx = List.map (fun d -> Termops.map_rel_decl EConstr.Unsafe.to_constr d) ctx in
- let c', imps' = interp_type_evars_impls ~impls env' evars tclass in
- let c' = EConstr.Unsafe.to_constr c' in
+ let sigma, k, u, cty, ctx', ctx, len, imps, subst =
+ let sigma, (impls, ((env', ctx), imps)) = interp_context_evars env sigma ctx in
+ let sigma, (c', imps') = interp_type_evars_impls ~impls env' sigma tclass in
let len = List.length ctx in
let imps = imps @ Impargs.lift_implicits len imps' in
- let ctx', c = decompose_prod_assum c' in
+ let ctx', c = decompose_prod_assum sigma c' in
let ctx'' = ctx' @ ctx in
- let (k, u), args = Typeclasses.dest_class_app (push_rel_context ctx'' env) !evars (EConstr.of_constr c) in
- let u = EConstr.EInstance.kind !evars u in
- let cl = Typeclasses.typeclass_univ_instance (k, u) in
- let _, args =
+ let (k, u), args = Typeclasses.dest_class_app (push_rel_context ctx'' env) sigma c in
+ let u_s = EInstance.kind sigma u in
+ let cl = Typeclasses.typeclass_univ_instance (k, u_s) in
+ let args = List.map of_constr args in
+ let cl_context = List.map (Termops.map_rel_decl of_constr) (snd cl.cl_context) in
+ let _, args =
List.fold_right (fun decl (args, args') ->
match decl with
| LocalAssum _ -> (List.tl args, List.hd args :: args')
- | LocalDef (_,b,_) -> (args, substl args' b :: args'))
- (snd cl.cl_context) (args, [])
+ | LocalDef (_,b,_) -> (args, Vars.substl args' b :: args'))
+ cl_context (args, [])
in
- cl, u, c', ctx', ctx, len, imps, args
+ sigma, cl, u, c', ctx', ctx, len, imps, args
in
let id =
match instid with
@@ -188,9 +185,8 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
Namegen.next_global_ident_away i (Termops.vars_of_env env)
in
let env' = push_rel_context ctx env in
- evars := Evarutil.nf_evar_map !evars;
- evars := resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:true env !evars;
- let subst = List.map (fun c -> EConstr.Unsafe.to_constr (Evarutil.nf_evar !evars (EConstr.of_constr c))) subst in
+ let sigma = Evarutil.nf_evar_map sigma in
+ let sigma = resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:true env sigma in
if abstract then
begin
let subst = List.fold_left2
@@ -198,18 +194,16 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
[] subst (snd k.cl_context)
in
let (_, ty_constr) = instance_constructor (k,u) subst in
- let nf, subst = Evarutil.e_nf_evars_and_universes evars in
- let termtype =
- let t = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- nf t
- in
- Pretyping.check_evars env Evd.empty !evars (EConstr.of_constr termtype);
- let univs = Evd.check_univ_decl ~poly !evars decl in
+ let termtype = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
+ let sigma,_ = Evarutil.nf_evars_and_universes sigma in
+ Pretyping.check_evars env Evd.empty sigma termtype;
+ let univs = Evd.check_univ_decl ~poly sigma decl in
+ let termtype = to_constr sigma termtype in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
(ParameterEntry
(None,(termtype,univs),None), Decl_kinds.IsAssumption Decl_kinds.Logical)
in
- Declare.declare_univ_binders (ConstRef cst) (Evd.universe_binders !evars);
+ Declare.declare_univ_binders (ConstRef cst) (Evd.universe_binders sigma);
instance_hook k pri global imps ?hook (ConstRef cst); id
end
else (
@@ -221,16 +215,16 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
Some (Inl fs)
| Some (_, t) -> Some (Inr t)
| None ->
- if Flags.is_program_mode () then Some (Inl [])
+ if program_mode then Some (Inl [])
else None
in
- let subst =
+ let subst, sigma =
match props with
- | None -> if List.is_empty k.cl_props then Some (Inl subst) else None
+ | None ->
+ (if List.is_empty k.cl_props then Some (Inl subst) else None), sigma
| Some (Inr term) ->
- let c = interp_casted_constr_evars env' evars term cty in
- let c = EConstr.Unsafe.to_constr c in
- Some (Inr (c, subst))
+ let sigma, c = interp_casted_constr_evars env' sigma term cty in
+ Some (Inr (c, subst)), sigma
| Some (Inl props) ->
let get_id =
function
@@ -267,9 +261,10 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
| (n, _) :: _ ->
unbound_method env' k.cl_impl (get_id n)
| _ ->
- Some (Inl (type_ctx_instance evars (push_rel_context ctx' env')
- k.cl_props props subst))
- in
+ let kcl_props = List.map (Termops.map_rel_decl of_constr) k.cl_props in
+ let sigma, res = type_ctx_instance (push_rel_context ctx' env') sigma kcl_props props subst in
+ Some (Inl res), sigma
+ in
let term, termtype =
match subst with
| None -> let termtype = it_mkProd_or_LetIn cty ctx in
@@ -281,34 +276,30 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
in
let (app, ty_constr) = instance_constructor (k,u) subst in
let termtype = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- let term = Termops.it_mkLambda_or_LetIn (Option.get app) (ctx' @ ctx) in
+ let term = it_mkLambda_or_LetIn (Option.get app) (ctx' @ ctx) in
Some term, termtype
| Some (Inr (def, subst)) ->
let termtype = it_mkProd_or_LetIn cty ctx in
- let term = Termops.it_mkLambda_or_LetIn def ctx in
+ let term = it_mkLambda_or_LetIn def ctx in
Some term, termtype
in
- let _ =
- evars := Evarutil.nf_evar_map !evars;
- evars := Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals_or_obligations ~fail:true
- env !evars;
- (* Try resolving fields that are typeclasses automatically. *)
- evars := Typeclasses.resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:false
- env !evars
- in
- let _ = evars := Evarutil.nf_evar_map_undefined !evars in
- let evm, nf = Evarutil.nf_evar_map_universes !evars in
- let termtype = nf termtype in
- let _ = (* Check that the type is free of evars now. *)
- Pretyping.check_evars env Evd.empty evm (EConstr.of_constr termtype)
- in
- let term = Option.map nf term in
- if not (Evd.has_undefined evm) && not (Option.is_empty term) then
+ let sigma = Evarutil.nf_evar_map sigma in
+ let sigma = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals_or_obligations ~fail:true env sigma in
+ (* Try resolving fields that are typeclasses automatically. *)
+ let sigma = Typeclasses.resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:false env sigma in
+ let sigma = Evarutil.nf_evar_map_undefined sigma in
+ (* Beware of this step, it is required as to minimize universes. *)
+ let sigma, _nf = Evarutil.nf_evar_map_universes sigma in
+ (* Check that the type is free of evars now. *)
+ Pretyping.check_evars env Evd.empty sigma termtype;
+ let termtype = to_constr sigma termtype in
+ let term = Option.map (to_constr sigma) term in
+ if not (Evd.has_undefined sigma) && not (Option.is_empty term) then
declare_instance_constant k pri global imps ?hook id decl
- poly evm (Option.get term) termtype
- else if Flags.is_program_mode () || refine || Option.is_empty term then begin
+ poly sigma (Option.get term) termtype
+ else if program_mode || refine || 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
+ if program_mode then
let hook vis gr _ =
let cst = match gr with ConstRef kn -> kn | _ -> assert false in
Impargs.declare_manual_implicits false gr ~enriching:false [imps];
@@ -318,12 +309,12 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
match term with
| Some t ->
let obls, _, constr, typ =
- Obligations.eterm_obligations env id evm 0 t termtype
+ Obligations.eterm_obligations env id sigma 0 t termtype
in obls, Some constr, typ
| None -> [||], None, termtype
in
let hook = Lemmas.mk_hook hook in
- let ctx = Evd.evar_universe_context evm in
+ let ctx = Evd.evar_universe_context sigma in
ignore (Obligations.add_definition id ?term:constr
~univdecl:decl typ ctx ~kind:(Global,poly,Instance) ~hook obls);
id
@@ -334,16 +325,16 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
the pretyping after the proof has opened. As a
consequence, we use the low-level primitives to code
the refinement manually.*)
- let gls = List.rev (Evd.future_goals evm) in
- let evm = Evd.reset_future_goals evm in
- Lemmas.start_proof id ~pl:decl kind evm (EConstr.of_constr termtype)
+ let gls = List.rev (Evd.future_goals sigma) in
+ let sigma = Evd.reset_future_goals sigma in
+ Lemmas.start_proof id ~pl:decl kind sigma (EConstr.of_constr termtype)
(Lemmas.mk_hook
(fun _ -> instance_hook k pri global imps ?hook));
(* spiwack: I don't know what to do with the status here. *)
if not (Option.is_empty term) then
let init_refine =
Tacticals.New.tclTHENLIST [
- Refine.refine ~typecheck:false (fun evm -> (evm,EConstr.of_constr (Option.get term)));
+ Refine.refine ~typecheck:false (fun sigma -> (sigma,EConstr.of_constr (Option.get term)));
Proofview.Unsafe.tclNEWGOALS gls;
Tactics.New.reduce_after_refine;
]
@@ -357,6 +348,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
else CErrors.user_err Pp.(str "Unsolved obligations remaining."))
let named_of_rel_context l =
+ let open Vars in
let acc, ctx =
List.fold_right
(fun decl (subst, ctx) ->
@@ -370,20 +362,20 @@ let named_of_rel_context l =
let context poly l =
let env = Global.env() in
- let evars = ref (Evd.from_env env) in
- let _, ((env', fullctx), impls) = interp_context_evars env evars l in
- let fullctx = List.map (fun d -> Termops.map_rel_decl EConstr.Unsafe.to_constr d) fullctx in
- let subst = Evarutil.evd_comb0 Evarutil.nf_evars_and_universes evars in
- let fullctx = Context.Rel.map subst fullctx in
- let ce t = Pretyping.check_evars env Evd.empty !evars (EConstr.of_constr t) in
+ let sigma = Evd.from_env env in
+ let sigma, (_, ((env', fullctx), impls)) = interp_context_evars env sigma l in
+ (* Note, we must use the normalized evar from now on! *)
+ let sigma,_ = Evarutil.nf_evars_and_universes sigma in
+ let ce t = Pretyping.check_evars env Evd.empty sigma t 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 CErrors.noncritical e ->
user_err Pp.(str "Anonymous variables not allowed in contexts.")
in
- let uctx = ref (Evd.universe_context_set !evars) in
+ let uctx = ref (Evd.universe_context_set sigma) in
let fn status (id, b, t) =
+ let b, t = Option.map (to_constr sigma) b, to_constr sigma t in
if Lib.is_modtype () && not (Lib.sections_are_opened ()) then
(* Declare the universe context once *)
let univs = if poly
@@ -399,7 +391,7 @@ let context poly l =
(DefinitionEntry entry, IsAssumption Logical)
in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id decl in
- match class_of_constr !evars (EConstr.of_constr t) with
+ match class_of_constr sigma (of_constr t) with
| Some (rels, ((tc,_), args) as _cl) ->
add_instance (Typeclasses.new_instance tc Hints.empty_hint_info false (*FIXME*)
poly (ConstRef cst));
@@ -419,7 +411,7 @@ let context poly l =
in
let nstatus = match b with
| None ->
- pi3 (Command.declare_assumption false decl (t, univs) Universes.empty_binders [] impl
+ pi3 (ComAssumption.declare_assumption false decl (t, univs) Universes.empty_binders [] impl
Vernacexpr.NoInline (Loc.tag id))
| Some b ->
let decl = (Discharge, poly, Definition) in
diff --git a/vernac/classes.mli b/vernac/classes.mli
index c0f03227c..d47c6a6f8 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -41,6 +41,7 @@ val new_instance :
?abstract:bool -> (** Not abstract by default. *)
?global:bool -> (** Not global by default. *)
?refine:bool -> (** Allow refinement *)
+ program_mode:bool ->
Decl_kinds.polymorphic ->
local_binder_expr list ->
Vernacexpr.typeclass_constraint ->
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
new file mode 100644
index 000000000..5d7adb24a
--- /dev/null
+++ b/vernac/comAssumption.ml
@@ -0,0 +1,182 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open CErrors
+open Util
+open Vars
+open Environ
+open Declare
+open Names
+open Globnames
+open Constrexpr_ops
+open Constrintern
+open Impargs
+open Decl_kinds
+open Pretyping
+open Vernacexpr
+open Entries
+
+(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)
+
+let axiom_into_instance = ref false
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optdepr = false;
+ optname = "automatically declare axioms whose type is a typeclass as instances";
+ optkey = ["Typeclasses";"Axioms";"Are";"Instances"];
+ optread = (fun _ -> !axiom_into_instance);
+ optwrite = (:=) axiom_into_instance; }
+
+let should_axiom_into_instance = function
+ | Discharge ->
+ (* The typeclass behaviour of Variable and Context doesn't depend
+ on section status *)
+ true
+ | Global | Local -> !axiom_into_instance
+
+let declare_assumption is_coe (local,p,kind) (c,ctx) pl imps impl nl (_,ident) =
+match local with
+| Discharge when Lib.sections_are_opened () ->
+ let ctx = match ctx with
+ | Monomorphic_const_entry ctx -> ctx
+ | Polymorphic_const_entry ctx -> Univ.ContextSet.of_context ctx
+ in
+ let decl = (Lib.cwd(), SectionLocalAssum ((c,ctx),p,impl), IsAssumption kind) in
+ let _ = declare_variable ident decl in
+ let () = assumption_message ident in
+ let () =
+ if not !Flags.quiet && Proof_global.there_are_pending_proofs () then
+ Feedback.msg_info (str"Variable" ++ spc () ++ Id.print ident ++
+ strbrk " is not visible from current goals")
+ in
+ let r = VarRef ident in
+ let () = Typeclasses.declare_instance None true r in
+ let () = if is_coe then Class.try_add_new_coercion r ~local:true false in
+ (r,Univ.Instance.empty,true)
+
+| Global | Local | Discharge ->
+ let do_instance = should_axiom_into_instance local in
+ let local = DeclareDef.get_locality ident ~kind:"axiom" local in
+ let inl = match nl with
+ | NoInline -> None
+ | DefaultInline -> Some (Flags.get_inline_level())
+ | InlineAt i -> Some i
+ in
+ let decl = (ParameterEntry (None,(c,ctx),inl), IsAssumption kind) in
+ let kn = declare_constant ident ~local decl in
+ let gr = ConstRef kn in
+ let () = maybe_declare_manual_implicits false gr imps in
+ let () = Declare.declare_univ_binders gr pl in
+ let () = assumption_message ident in
+ let () = if do_instance then Typeclasses.declare_instance None false gr in
+ let () = if is_coe then Class.try_add_new_coercion gr ~local p in
+ let inst = match ctx with
+ | Polymorphic_const_entry ctx -> Univ.UContext.instance ctx
+ | Monomorphic_const_entry _ -> Univ.Instance.empty
+ in
+ (gr,inst,Lib.is_modtype_strict ())
+
+let interp_assumption sigma env impls bl c =
+ let c = mkCProdN ?loc:(local_binders_loc bl) bl c in
+ let sigma, (ty, impls) = interp_type_evars_impls env sigma ~impls c in
+ let ty = EConstr.Unsafe.to_constr ty in
+ sigma, (ty, impls)
+
+(* When monomorphic the universe constraints are declared with the first declaration only. *)
+let next_uctx =
+ let empty_uctx = Monomorphic_const_entry Univ.ContextSet.empty in
+ function
+ | Polymorphic_const_entry _ as uctx -> uctx
+ | Monomorphic_const_entry _ -> empty_uctx
+
+let declare_assumptions idl is_coe k (c,uctx) pl imps nl =
+ let refs, status, _ =
+ List.fold_left (fun (refs,status,uctx) id ->
+ let ref',u',status' =
+ declare_assumption is_coe k (c,uctx) pl imps false nl id in
+ (ref',u')::refs, status' && status, next_uctx uctx)
+ ([],true,uctx) idl
+ in
+ List.rev refs, status
+
+
+let maybe_error_many_udecls = function
+ | ((loc,id), Some _) ->
+ user_err ?loc ~hdr:"many_universe_declarations"
+ Pp.(str "When declaring multiple axioms in one command, " ++
+ str "only the first is allowed a universe binder " ++
+ str "(which will be shared by the whole block).")
+ | (_, None) -> ()
+
+let process_assumptions_udecls kind l =
+ let udecl, first_id = match l with
+ | (coe, ((id, udecl)::rest, c))::rest' ->
+ List.iter maybe_error_many_udecls rest;
+ List.iter (fun (coe, (idl, c)) -> List.iter maybe_error_many_udecls idl) rest';
+ udecl, id
+ | (_, ([], _))::_ | [] -> assert false
+ in
+ let () = match kind, udecl with
+ | (Discharge, _, _), Some _ when Lib.sections_are_opened () ->
+ let loc = fst first_id in
+ let msg = Pp.str "Section variables cannot be polymorphic." in
+ user_err ?loc msg
+ | _ -> ()
+ in
+ udecl, List.map (fun (coe, (idl, c)) -> coe, (List.map fst idl, c)) l
+
+let do_assumptions kind nl l =
+ let open Context.Named.Declaration in
+ let env = Global.env () in
+ let udecl, l = process_assumptions_udecls kind l in
+ let sigma, udecl = Univdecls.interp_univ_decl_opt env udecl in
+ let l =
+ if pi2 kind (* poly *) then
+ (* Separate declarations so that A B : Type puts A and B in different levels. *)
+ List.fold_right (fun (is_coe,(idl,c)) acc ->
+ List.fold_right (fun id acc ->
+ (is_coe, ([id], c)) :: acc) idl acc)
+ l []
+ else l
+ in
+ (* We intepret all declarations in the same evar_map, i.e. as a telescope. *)
+ let (sigma,_,_),l = List.fold_left_map (fun (sigma,env,ienv) (is_coe,(idl,c)) ->
+ let sigma,(t,imps) = interp_assumption sigma env ienv [] c in
+ let env =
+ 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
+ ((sigma,env,ienv),((is_coe,idl),t,imps)))
+ (sigma,env,empty_internalization_env) l
+ in
+ let sigma = solve_remaining_evars all_and_fail_flags env sigma Evd.empty in
+ (* The universe constraints come from the whole telescope. *)
+ let sigma = Evd.nf_constraints sigma in
+ let nf_evar c = EConstr.to_constr sigma (EConstr.of_constr c) in
+ let uvars, l = List.fold_left_map (fun uvars (coe,t,imps) ->
+ let t = nf_evar t in
+ let uvars = Univ.LSet.union uvars (Univops.universes_of_constr env t) in
+ uvars, (coe,t,imps))
+ Univ.LSet.empty l
+ in
+ let sigma = Evd.restrict_universe_context sigma uvars in
+ let uctx = Evd.check_univ_decl ~poly:(pi2 kind) sigma udecl in
+ let ubinders = Evd.universe_binders sigma in
+ pi2 (List.fold_left (fun (subst,status,uctx) ((is_coe,idl),t,imps) ->
+ let t = replace_vars subst t in
+ let refs, status' = declare_assumptions idl is_coe kind (t,uctx) ubinders imps nl in
+ let subst' = List.map2
+ (fun (_,id) (c,u) -> (id, Universes.constr_of_global_univ (c,u)))
+ idl refs
+ in
+ subst'@subst, status' && status, next_uctx uctx)
+ ([], true, uctx) l)
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
new file mode 100644
index 000000000..2fa156abd
--- /dev/null
+++ b/vernac/comAssumption.mli
@@ -0,0 +1,34 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Constr
+open Entries
+open Globnames
+open Vernacexpr
+open Constrexpr
+open Decl_kinds
+
+(** {6 Parameters/Assumptions} *)
+
+val do_assumptions : locality * polymorphic * assumption_object_kind ->
+ Vernacexpr.inline -> (Vernacexpr.ident_decl list * constr_expr) with_coercion list -> bool
+
+(************************************************************************)
+(** Internal API *)
+(************************************************************************)
+
+(** Exported for Classes *)
+
+(** returns [false] if the assumption is neither local to a section,
+ nor in a module type and meant to be instantiated. *)
+val declare_assumption : coercion_flag -> assumption_kind ->
+ types in_constant_universes_entry ->
+ Universes.universe_binders -> Impargs.manual_implicits ->
+ bool (** implicit *) -> Vernacexpr.inline -> variable Loc.located ->
+ global_reference * Univ.Instance.t * bool
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
new file mode 100644
index 000000000..883121479
--- /dev/null
+++ b/vernac/comDefinition.ml
@@ -0,0 +1,131 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2018 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open Util
+open Constr
+open Environ
+open Entries
+open Termops
+open Redexpr
+open Declare
+open Constrintern
+open Pretyping
+
+open Context.Rel.Declaration
+
+(* Commands of the interface: Constant definitions *)
+
+let rec under_binders env sigma f n c =
+ if Int.equal n 0 then f env sigma (EConstr.of_constr c) else
+ match Constr.kind c with
+ | Lambda (x,t,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 (LocalDef (x,b,t)) env) sigma f (n-1) c)
+ | _ -> assert false
+
+let red_constant_entry n ce sigma = function
+ | None -> ce
+ | 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 (_, c) = redfun env sigma c in
+ EConstr.Unsafe.to_constr c
+ in
+ { ce with const_entry_body = Future.chain proof_out
+ (fun ((body,ctx),eff) -> (under_binders env sigma redfun n body,ctx),eff) }
+
+let warn_implicits_in_term =
+ CWarnings.create ~name:"implicits-in-term" ~category:"implicits"
+ (fun () ->
+ strbrk "Implicit arguments declaration relies on type." ++ spc () ++
+ strbrk "The term declares more implicits than the type here.")
+
+let interp_definition pl bl poly red_option c ctypopt =
+ let env = Global.env() in
+ let evd, decl = Univdecls.interp_univ_decl_opt env pl in
+ let evd, (impls, ((env_bl, ctx), imps1)) = interp_context_evars env evd bl in
+ let ctx = List.map (fun d -> map_rel_decl EConstr.Unsafe.to_constr d) ctx in
+ let nb_args = Context.Rel.nhyps ctx in
+ let evd,imps,ce =
+ match ctypopt with
+ None ->
+ let evd, subst = Evd.nf_univ_variables evd in
+ let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
+ let env_bl = push_rel_context ctx env in
+ let evd, (c, imps2) = interp_constr_evars_impls ~impls env_bl evd c in
+ let c = EConstr.Unsafe.to_constr c in
+ let evd,nf = Evarutil.nf_evars_and_universes evd in
+ let body = nf (it_mkLambda_or_LetIn c ctx) in
+ let vars = EConstr.universes_of_constr env evd (EConstr.of_constr body) in
+ let evd = Evd.restrict_universe_context evd vars in
+ let uctx = Evd.check_univ_decl ~poly evd decl in
+ evd, imps1@(Impargs.lift_implicits nb_args imps2),
+ definition_entry ~univs:uctx body
+ | Some ctyp ->
+ let evd, (ty, impsty) = interp_type_evars_impls ~impls env_bl evd ctyp in
+ let evd, subst = Evd.nf_univ_variables evd in
+ let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
+ let env_bl = push_rel_context ctx env in
+ let evd, (c, imps2) = interp_casted_constr_evars_impls ~impls env_bl evd c ty in
+ let c = EConstr.Unsafe.to_constr c in
+ let evd, nf = Evarutil.nf_evars_and_universes evd in
+ let body = nf (it_mkLambda_or_LetIn c ctx) in
+ let ty = EConstr.Unsafe.to_constr ty in
+ let typ = nf (Term.it_mkProd_or_LetIn ty ctx) in
+ let beq b1 b2 = if b1 then b2 else not b2 in
+ let impl_eq (x,y,z) (x',y',z') = beq x x' && beq y y' && beq z z' in
+ (* Check that all implicit arguments inferable from the term
+ are inferable from the type *)
+ let chk (key,va) =
+ impl_eq (List.assoc_f Pervasives.(=) key impsty) va (* FIXME *)
+ in
+ if not (try List.for_all chk imps2 with Not_found -> false)
+ then warn_implicits_in_term ();
+ let bodyvars = EConstr.universes_of_constr env evd (EConstr.of_constr body) in
+ let tyvars = EConstr.universes_of_constr env evd (EConstr.of_constr ty) in
+ let vars = Univ.LSet.union bodyvars tyvars in
+ let evd = Evd.restrict_universe_context evd vars in
+ let uctx = Evd.check_univ_decl ~poly evd decl in
+ evd, imps1@(Impargs.lift_implicits nb_args impsty),
+ definition_entry ~types:typ ~univs:uctx body
+ in
+ (red_constant_entry (Context.Rel.length ctx) ce evd red_option, evd, decl, imps)
+
+let check_definition (ce, evd, _, imps) =
+ check_evars_are_solved (Global.env ()) evd Evd.empty;
+ ce
+
+let do_definition ~program_mode ident k univdecl bl red_option c ctypopt hook =
+ let (ce, evd, univdecl, imps as def) =
+ interp_definition univdecl bl (pi2 k) red_option c ctypopt
+ in
+ if program_mode then
+ let env = Global.env () in
+ let (c,ctx), sideff = Future.force ce.const_entry_body in
+ assert(Safe_typing.empty_private_constants = sideff);
+ assert(Univ.ContextSet.is_empty ctx);
+ let typ = match ce.const_entry_type with
+ | Some t -> t
+ | None -> EConstr.to_constr evd (Retyping.get_type_of env evd (EConstr.of_constr c))
+ in
+ Obligations.check_evars env evd;
+ let obls, _, c, cty =
+ Obligations.eterm_obligations env ident evd 0 c typ
+ in
+ 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 ~univdecl ~implicits:imps ~kind:k ~hook obls)
+ else let ce = check_definition def in
+ ignore(DeclareDef.declare_definition ident k ce (Evd.universe_binders evd) imps
+ (Lemmas.mk_hook
+ (fun l r -> Lemmas.call_hook (fun exn -> exn) hook l r;r)))
diff --git a/vernac/comDefinition.mli b/vernac/comDefinition.mli
new file mode 100644
index 000000000..4a65c1e91
--- /dev/null
+++ b/vernac/comDefinition.mli
@@ -0,0 +1,30 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2018 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Entries
+open Decl_kinds
+open Redexpr
+open Constrexpr
+
+(** {6 Definitions/Let} *)
+
+val do_definition : program_mode:bool ->
+ Id.t -> definition_kind -> Vernacexpr.universe_decl_expr option ->
+ local_binder_expr list -> red_expr option -> constr_expr ->
+ constr_expr option -> unit Lemmas.declaration_hook -> unit
+
+(************************************************************************)
+(** Internal API *)
+(************************************************************************)
+
+(** Not used anywhere. *)
+val interp_definition :
+ Vernacexpr.universe_decl_expr option -> local_binder_expr list -> polymorphic -> red_expr option -> constr_expr ->
+ constr_expr option -> Safe_typing.private_constants definition_entry * Evd.evar_map *
+ Univdecls.universe_decl * Impargs.manual_implicits
diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml
new file mode 100644
index 000000000..d648e293a
--- /dev/null
+++ b/vernac/comFixpoint.ml
@@ -0,0 +1,356 @@
+open Pp
+open CErrors
+open Util
+open Constr
+open Vars
+open Termops
+open Declare
+open Names
+open Constrexpr
+open Constrexpr_ops
+open Constrintern
+open Decl_kinds
+open Pretyping
+open Evarutil
+open Evarconv
+open Misctypes
+open Vernacexpr
+
+module RelDecl = Context.Rel.Declaration
+
+(* 3c| Fixpoints and co-fixpoints *)
+
+(* An (unoptimized) function that maps preorders to partial orders...
+
+ Input: a list of associations (x,[y1;...;yn]), all yi distincts
+ and different of x, meaning x<=y1, ..., x<=yn
+
+ Output: a list of associations (x,Inr [y1;...;yn]), collecting all
+ distincts yi greater than x, _or_, (x, Inl y) meaning that
+ x is in the same class as y (in which case, x occurs
+ nowhere else in the association map)
+
+ partial_order : ('a * 'a list) list -> ('a * ('a,'a list) union) list
+*)
+
+let rec partial_order cmp = function
+ | [] -> []
+ | (x,xge)::rest ->
+ let rec browse res xge' = function
+ | [] ->
+ let res = List.map (function
+ | (z, Inr zge) when List.mem_f cmp x zge ->
+ (z, Inr (List.union cmp zge xge'))
+ | r -> r) res in
+ (x,Inr xge')::res
+ | y::xge ->
+ let rec link y =
+ try match List.assoc_f cmp y res with
+ | Inl z -> link z
+ | Inr yge ->
+ if List.mem_f cmp x yge then
+ let res = List.remove_assoc_f cmp y res in
+ let res = List.map (function
+ | (z, Inl t) ->
+ if cmp t y then (z, Inl x) else (z, Inl t)
+ | (z, Inr zge) ->
+ if List.mem_f cmp y zge then
+ (z, Inr (List.add_set cmp x (List.remove cmp y zge)))
+ else
+ (z, Inr zge)) res in
+ browse ((y,Inl x)::res) xge' (List.union cmp xge (List.remove cmp x yge))
+ else
+ browse res (List.add_set cmp y (List.union cmp xge' yge)) xge
+ with Not_found -> browse res (List.add_set cmp y xge') xge
+ in link y
+ in browse (partial_order cmp rest) [] xge
+
+let non_full_mutual_message x xge y yge isfix rest =
+ let reason =
+ if Id.List.mem x yge then
+ Id.print y ++ str " depends on " ++ Id.print x ++ strbrk " but not conversely"
+ else if Id.List.mem y xge then
+ Id.print x ++ str " depends on " ++ Id.print y ++ strbrk " but not conversely"
+ else
+ Id.print y ++ str " and " ++ Id.print x ++ strbrk " are not mutually dependent" in
+ let e = if List.is_empty rest then reason else strbrk "e.g., " ++ reason in
+ let k = if isfix then "fixpoint" else "cofixpoint" in
+ let w =
+ if isfix
+ then strbrk "Well-foundedness check may fail unexpectedly." ++ fnl()
+ else mt () in
+ strbrk "Not a fully mutually defined " ++ str k ++ fnl () ++
+ str "(" ++ e ++ str ")." ++ fnl () ++ w
+
+let warn_non_full_mutual =
+ CWarnings.create ~name:"non-full-mutual" ~category:"fixpoints"
+ (fun (x,xge,y,yge,isfix,rest) ->
+ non_full_mutual_message x xge y yge isfix rest)
+
+let check_mutuality env evd isfix fixl =
+ let names = List.map fst fixl in
+ let preorder =
+ List.map (fun (id,def) ->
+ (id, List.filter (fun id' -> not (Id.equal id id') && occur_var env evd id' (EConstr.of_constr def)) names))
+ fixl in
+ let po = partial_order Id.equal preorder in
+ match List.filter (function (_,Inr _) -> true | _ -> false) po with
+ | (x,Inr xge)::(y,Inr yge)::rest ->
+ warn_non_full_mutual (x,xge,y,yge,isfix,rest)
+ | _ -> ()
+
+type structured_fixpoint_expr = {
+ fix_name : Id.t;
+ fix_univs : universe_decl_expr option;
+ fix_annot : Id.t Loc.located option;
+ fix_binders : local_binder_expr list;
+ fix_body : constr_expr option;
+ fix_type : constr_expr
+}
+
+let interp_fix_context ~cofix env sigma fix =
+ let before, after = if not cofix then split_at_annot fix.fix_binders fix.fix_annot else [], fix.fix_binders in
+ let sigma, (impl_env, ((env', ctx), imps)) = interp_context_evars env sigma before in
+ let sigma, (impl_env', ((env'', ctx'), imps')) = interp_context_evars ~impl_env ~shift:(Context.Rel.nhyps ctx) env' sigma after in
+ let annot = Option.map (fun _ -> List.length (assums_of_rel_context ctx)) fix.fix_annot in
+ sigma, ((env'', ctx' @ ctx), (impl_env',imps @ imps'), annot)
+
+let interp_fix_ccl sigma impls (env,_) fix =
+ interp_type_evars_impls ~impls env sigma fix.fix_type
+
+let interp_fix_body env_rec sigma impls (_,ctx) fix ccl =
+ let open EConstr in
+ Option.cata (fun body ->
+ let env = push_rel_context ctx env_rec in
+ let sigma, body = interp_casted_constr_evars env sigma ~impls body ccl in
+ sigma, Some (it_mkLambda_or_LetIn body ctx)) (sigma, None) fix.fix_body
+
+let build_fix_type (_,ctx) ccl = EConstr.it_mkProd_or_LetIn ccl ctx
+
+let prepare_recursive_declaration fixnames fixtypes fixdefs =
+ let defs = List.map (subst_vars (List.rev fixnames)) fixdefs in
+ let names = List.map (fun id -> Name id) fixnames in
+ (Array.of_list names, Array.of_list fixtypes, Array.of_list defs)
+
+(* Jump over let-bindings. *)
+
+let compute_possible_guardness_evidences (ctx,_,recindex) =
+ (* A recursive index is characterized by the number of lambdas to
+ skip before finding the relevant inductive argument *)
+ match recindex with
+ | Some i -> [i]
+ | None ->
+ (* If recursive argument was not given by user, we try all args.
+ An earlier approach was to look only for inductive arguments,
+ but doing it properly involves delta-reduction, and it finally
+ doesn't seem to worth the effort (except for huge mutual
+ fixpoints ?) *)
+ List.interval 0 (Context.Rel.nhyps ctx - 1)
+
+type recursive_preentry =
+ Id.t list * constr option list * types list
+
+(* Wellfounded definition *)
+
+let contrib_name = "Program"
+let subtac_dir = [contrib_name]
+let tactics_module = subtac_dir @ ["Tactics"]
+
+let init_constant dir s sigma =
+ Evarutil.new_global sigma (Coqlib.coq_reference "Command" dir s)
+
+let fix_proto = init_constant tactics_module "fix_proto"
+
+let interp_recursive ~program_mode ~cofix fixl notations =
+ let open Context.Named.Declaration in
+ let open EConstr in
+ let env = Global.env() in
+ let fixnames = List.map (fun fix -> fix.fix_name) fixl in
+
+ (* Interp arities allowing for unresolved types *)
+ let all_universes =
+ List.fold_right (fun sfe acc ->
+ match sfe.fix_univs , acc with
+ | None , acc -> acc
+ | x , None -> x
+ | Some ls , Some us ->
+ let lsu = ls.univdecl_instance and usu = us.univdecl_instance in
+ if not (CList.for_all2eq (fun x y -> Id.equal (snd x) (snd y)) lsu usu) then
+ user_err Pp.(str "(co)-recursive definitions should all have the same universe binders");
+ Some us) fixl None in
+ let sigma, decl = Univdecls.interp_univ_decl_opt env all_universes in
+ let sigma, (fixctxs, fiximppairs, fixannots) =
+ on_snd List.split3 @@
+ List.fold_left_map (fun sigma -> interp_fix_context env sigma ~cofix) sigma fixl in
+ let fixctximpenvs, fixctximps = List.split fiximppairs in
+ let sigma, (fixccls,fixcclimps) =
+ on_snd List.split @@
+ List.fold_left3_map interp_fix_ccl sigma fixctximpenvs fixctxs fixl in
+ let fixtypes = List.map2 build_fix_type fixctxs fixccls in
+ let fixtypes = List.map (fun c -> nf_evar sigma c) fixtypes in
+ let fiximps = List.map3
+ (fun ctximps cclimps (_,ctx) -> ctximps@(Impargs.lift_implicits (Context.Rel.nhyps ctx) cclimps))
+ fixctximps fixcclimps fixctxs in
+ let sigma, rec_sign =
+ List.fold_left2
+ (fun (sigma, env') id t ->
+ if program_mode then
+ let sigma, sort = Typing.type_of ~refresh:true env sigma t in
+ let sigma, fixprot =
+ try
+ let sigma, h_term = fix_proto sigma in
+ let app = mkApp (h_term, [|sort; t|]) in
+ let _evd = ref sigma in
+ let res = Typing.e_solve_evars env _evd app in
+ !_evd, res
+ with e when CErrors.noncritical e -> sigma, t
+ in
+ sigma, LocalAssum (id,fixprot) :: env'
+ else sigma, LocalAssum (id,t) :: env')
+ (sigma,[]) fixnames fixtypes
+ in
+ let env_rec = push_named_context rec_sign env in
+
+ (* Get interpretation metadatas *)
+ let fixtypes = List.map EConstr.Unsafe.to_constr fixtypes in
+ let impls = compute_internalization_env env Recursive fixnames fixtypes fiximps in
+
+ (* Interp bodies with rollback because temp use of notations/implicit *)
+ let sigma, fixdefs =
+ Metasyntax.with_syntax_protection (fun () ->
+ List.iter (Metasyntax.set_notation_for_interpretation env_rec impls) notations;
+ List.fold_left4_map
+ (fun sigma fixctximpenv -> interp_fix_body env_rec sigma (Id.Map.fold Id.Map.add fixctximpenv impls))
+ sigma fixctximpenvs fixctxs fixl fixccls)
+ () in
+
+ (* Instantiate evars and check all are resolved *)
+ let sigma = solve_unif_constraints_with_heuristics env_rec sigma in
+ let sigma, nf = nf_evars_and_universes sigma in
+ let fixdefs = List.map (fun c -> Option.map EConstr.Unsafe.to_constr c) fixdefs in
+ let fixdefs = List.map (Option.map nf) fixdefs in
+ let fixtypes = List.map nf fixtypes in
+ let fixctxs = List.map (fun (_,ctx) -> ctx) fixctxs in
+
+ (* Build the fix declaration block *)
+ (env,rec_sign,decl,sigma), (fixnames,fixdefs,fixtypes), List.combine3 fixctxs fiximps fixannots
+
+let check_recursive isfix env evd (fixnames,fixdefs,_) =
+ check_evars_are_solved env evd Evd.empty;
+ if List.for_all Option.has_some fixdefs then begin
+ let fixdefs = List.map Option.get fixdefs in
+ check_mutuality env evd isfix (List.combine fixnames fixdefs)
+ end
+
+let interp_fixpoint ~cofix l ntns =
+ let (env,_,pl,evd),fix,info = interp_recursive ~program_mode:false ~cofix l ntns in
+ check_recursive true env evd fix;
+ (fix,pl,Evd.evar_universe_context evd,info)
+
+let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) indexes ntns =
+ if List.exists Option.is_empty fixdefs then
+ (* Some bodies to define by proof *)
+ let thms =
+ List.map3 (fun id t (ctx,imps,_) -> (id,(EConstr.of_constr t,(List.map RelDecl.get_name ctx,imps))))
+ fixnames fixtypes fiximps in
+ let init_tac =
+ Some (List.map (Option.cata (EConstr.of_constr %> Tactics.exact_no_check) Tacticals.New.tclIDTAC)
+ fixdefs) in
+ let evd = Evd.from_ctx ctx in
+ Lemmas.start_proof_with_initialization (Global,poly,DefinitionBody Fixpoint)
+ evd pl (Some(false,indexes,init_tac)) thms None (Lemmas.mk_hook (fun _ _ -> ()))
+ else begin
+ (* We shortcut the proof process *)
+ let fixdefs = List.map Option.get fixdefs in
+ let fixdecls = prepare_recursive_declaration fixnames fixtypes fixdefs in
+ let env = Global.env() in
+ let indexes = search_guard env indexes fixdecls in
+ let fiximps = List.map (fun (n,r,p) -> r) fiximps in
+ let vars = Univops.universes_of_constr env (mkFix ((indexes,0),fixdecls)) in
+ let fixdecls =
+ List.map_i (fun i _ -> mkFix ((indexes,i),fixdecls)) 0 fixnames in
+ let evd = Evd.from_ctx ctx in
+ let evd = Evd.restrict_universe_context evd vars in
+ let ctx = Evd.check_univ_decl ~poly evd pl in
+ let pl = Evd.universe_binders evd in
+ let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
+ ignore (List.map4 (DeclareDef.declare_fix (local, poly, Fixpoint) pl ctx)
+ fixnames fixdecls fixtypes fiximps);
+ (* Declare the recursive definitions *)
+ fixpoint_message (Some indexes) fixnames;
+ end;
+ (* Declare notations *)
+ List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns
+
+let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) ntns =
+ if List.exists Option.is_empty fixdefs then
+ (* Some bodies to define by proof *)
+ let thms =
+ List.map3 (fun id t (ctx,imps,_) -> (id,(EConstr.of_constr t,(List.map RelDecl.get_name ctx,imps))))
+ fixnames fixtypes fiximps in
+ let init_tac =
+ Some (List.map (Option.cata (EConstr.of_constr %> Tactics.exact_no_check) Tacticals.New.tclIDTAC)
+ fixdefs) in
+ let evd = Evd.from_ctx ctx in
+ Lemmas.start_proof_with_initialization (Global,poly, DefinitionBody CoFixpoint)
+ evd pl (Some(true,[],init_tac)) thms None (Lemmas.mk_hook (fun _ _ -> ()))
+ else begin
+ (* We shortcut the proof process *)
+ let fixdefs = List.map Option.get fixdefs in
+ let fixdecls = prepare_recursive_declaration fixnames fixtypes fixdefs in
+ let fixdecls = List.map_i (fun i _ -> mkCoFix (i,fixdecls)) 0 fixnames in
+ let env = Global.env () in
+ let vars = Univops.universes_of_constr env (List.hd fixdecls) in
+ let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
+ let fiximps = List.map (fun (len,imps,idx) -> imps) fiximps in
+ let evd = Evd.from_ctx ctx in
+ let evd = Evd.restrict_universe_context evd vars in
+ let ctx = Evd.check_univ_decl ~poly evd pl in
+ let pl = Evd.universe_binders evd in
+ ignore (List.map4 (DeclareDef.declare_fix (local, poly, CoFixpoint) pl ctx)
+ fixnames fixdecls fixtypes fiximps);
+ (* Declare the recursive definitions *)
+ cofixpoint_message fixnames
+ end;
+ (* Declare notations *)
+ List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns
+
+let extract_decreasing_argument limit = function
+ | (na,CStructRec) -> na
+ | (na,_) when not limit -> na
+ | _ -> user_err Pp.(str
+ "Only structural decreasing is supported for a non-Program Fixpoint")
+
+let extract_fixpoint_components limit l =
+ let fixl, ntnl = List.split l in
+ let fixl = List.map (fun (((_,id),pl),ann,bl,typ,def) ->
+ let ann = extract_decreasing_argument limit ann in
+ {fix_name = id; fix_annot = ann; fix_univs = pl;
+ fix_binders = bl; fix_body = def; fix_type = typ}) fixl in
+ fixl, List.flatten ntnl
+
+let extract_cofixpoint_components l =
+ let fixl, ntnl = List.split l in
+ List.map (fun (((_,id),pl),bl,typ,def) ->
+ {fix_name = id; fix_annot = None; fix_univs = pl;
+ fix_binders = bl; fix_body = def; fix_type = typ}) fixl,
+ List.flatten ntnl
+
+let check_safe () =
+ let open Declarations in
+ let flags = Environ.typing_flags (Global.env ()) in
+ flags.check_universes && flags.check_guarded
+
+let do_fixpoint local poly l =
+ let fixl, ntns = extract_fixpoint_components true l in
+ let (_, _, _, info as fix) = interp_fixpoint ~cofix:false fixl ntns in
+ let possible_indexes =
+ List.map compute_possible_guardness_evidences info in
+ declare_fixpoint local poly fix possible_indexes ntns;
+ if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
+
+let do_cofixpoint local poly l =
+ let fixl,ntns = extract_cofixpoint_components l in
+ let cofix = interp_fixpoint ~cofix:true fixl ntns in
+ declare_cofixpoint local poly cofix ntns;
+ if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
diff --git a/vernac/comFixpoint.mli b/vernac/comFixpoint.mli
new file mode 100644
index 000000000..2c84bd84d
--- /dev/null
+++ b/vernac/comFixpoint.mli
@@ -0,0 +1,93 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2018 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Constr
+open Decl_kinds
+open Constrexpr
+open Vernacexpr
+
+(** {6 Fixpoints and cofixpoints} *)
+
+(** Entry points for the vernacular commands Fixpoint and CoFixpoint *)
+
+val do_fixpoint :
+ (* When [false], assume guarded. *)
+ locality -> polymorphic -> (fixpoint_expr * decl_notation list) list -> unit
+
+val do_cofixpoint :
+ (* When [false], assume guarded. *)
+ locality -> polymorphic -> (cofixpoint_expr * decl_notation list) list -> unit
+
+(************************************************************************)
+(** Internal API *)
+(************************************************************************)
+
+type structured_fixpoint_expr = {
+ fix_name : Id.t;
+ fix_univs : Vernacexpr.universe_decl_expr option;
+ fix_annot : Id.t Loc.located option;
+ fix_binders : local_binder_expr list;
+ fix_body : constr_expr option;
+ fix_type : constr_expr
+}
+
+(** Typing global fixpoints and cofixpoint_expr *)
+
+(** Exported for Program *)
+val interp_recursive :
+ (* Misc arguments *)
+ program_mode:bool -> cofix:bool ->
+ (* Notations of the fixpoint / should that be folded in the previous argument? *)
+ structured_fixpoint_expr list -> decl_notation list ->
+
+ (* env / signature / univs / evar_map *)
+ (Environ.env * EConstr.named_context * Univdecls.universe_decl * Evd.evar_map) *
+ (* names / defs / types *)
+ (Id.t list * Constr.constr option list * Constr.types list) *
+ (* ctx per mutual def / implicits / struct annotations *)
+ (EConstr.rel_context * Impargs.manual_explicitation list * int option) list
+
+(** Exported for Funind *)
+
+(** Extracting the semantical components out of the raw syntax of
+ (co)fixpoints declarations *)
+
+val extract_fixpoint_components : bool ->
+ (fixpoint_expr * decl_notation list) list ->
+ structured_fixpoint_expr list * decl_notation list
+
+val extract_cofixpoint_components :
+ (cofixpoint_expr * decl_notation list) list ->
+ structured_fixpoint_expr list * decl_notation list
+
+type recursive_preentry =
+ Id.t list * constr option list * types list
+
+val interp_fixpoint :
+ cofix:bool ->
+ structured_fixpoint_expr list -> decl_notation list ->
+ recursive_preentry * Univdecls.universe_decl * UState.t *
+ (EConstr.rel_context * Impargs.manual_implicits * int option) list
+
+(** Registering fixpoints and cofixpoints in the environment *)
+(** [Not used so far] *)
+val declare_fixpoint :
+ locality -> polymorphic ->
+ recursive_preentry * Univdecls.universe_decl * UState.t *
+ (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ Proof_global.lemma_possible_guards -> decl_notation list -> unit
+
+val declare_cofixpoint : locality -> polymorphic ->
+ recursive_preentry * Univdecls.universe_decl * UState.t *
+ (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ decl_notation list -> unit
+
+(** Very private function, do not use *)
+val compute_possible_guardness_evidences :
+ ('a, 'b) Context.Rel.pt * 'c * int option -> int list
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
new file mode 100644
index 000000000..f3f50f41d
--- /dev/null
+++ b/vernac/comInductive.ml
@@ -0,0 +1,456 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open CErrors
+open Sorts
+open Util
+open Constr
+open Termops
+open Environ
+open Declare
+open Names
+open Libnames
+open Globnames
+open Nameops
+open Constrexpr
+open Constrexpr_ops
+open Constrintern
+open Nametab
+open Impargs
+open Reductionops
+open Indtypes
+open Decl_kinds
+open Pretyping
+open Evarutil
+open Indschemes
+open Misctypes
+open Context.Rel.Declaration
+open Entries
+
+module RelDecl = Context.Rel.Declaration
+
+(* 3b| Mutual inductive definitions *)
+
+let rec complete_conclusion a cs = CAst.map_with_loc (fun ?loc -> function
+ | CProdN (bl,c) -> CProdN (bl,complete_conclusion a cs c)
+ | CLetIn (na,b,t,c) -> CLetIn (na,b,t,complete_conclusion a cs c)
+ | CHole (k, _, _) ->
+ let (has_no_args,name,params) = a in
+ if not has_no_args then
+ user_err ?loc
+ (strbrk"Cannot infer the non constant arguments of the conclusion of "
+ ++ Id.print cs ++ str ".");
+ let args = List.map (fun id -> CAst.make ?loc @@ CRef(Ident(loc,id),None)) params in
+ CAppExpl ((None,Ident(loc,name),None),List.rev args)
+ | c -> c
+ )
+
+let push_types env idl tl =
+ List.fold_left2 (fun env id t -> Environ.push_rel (LocalAssum (Name id,t)) env)
+ env idl tl
+
+type structured_one_inductive_expr = {
+ ind_name : Id.t;
+ ind_univs : Vernacexpr.universe_decl_expr option;
+ ind_arity : constr_expr;
+ ind_lc : (Id.t * constr_expr) list
+}
+
+type structured_inductive_expr =
+ local_binder_expr list * structured_one_inductive_expr list
+
+let minductive_message warn = function
+ | [] -> user_err Pp.(str "No inductive definition.")
+ | [x] -> (Id.print x ++ str " is defined" ++
+ if warn then str " as a non-primitive record" else mt())
+ | l -> hov 0 (prlist_with_sep pr_comma Id.print l ++
+ spc () ++ str "are defined")
+
+let check_all_names_different indl =
+ let ind_names = List.map (fun ind -> ind.ind_name) indl in
+ let cstr_names = List.map_append (fun ind -> List.map fst ind.ind_lc) indl in
+ let l = List.duplicates Id.equal ind_names in
+ let () = match l with
+ | [] -> ()
+ | t :: _ -> raise (InductiveError (SameNamesTypes t))
+ in
+ let l = List.duplicates Id.equal cstr_names in
+ let () = match l with
+ | [] -> ()
+ | c :: _ -> raise (InductiveError (SameNamesConstructors (List.hd l)))
+ in
+ let l = List.intersect Id.equal ind_names cstr_names in
+ match l with
+ | [] -> ()
+ | _ -> raise (InductiveError (SameNamesOverlap l))
+
+let mk_mltype_data sigma env assums arity indname =
+ let is_ml_type = is_sort env sigma (EConstr.of_constr arity) in
+ (is_ml_type,indname,assums)
+
+let prepare_param = function
+ | LocalAssum (na,t) -> Name.get_id na, LocalAssumEntry t
+ | LocalDef (na,b,_) -> Name.get_id 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.
+ This is really a hack to stay compatible with the semantics of template polymorphic
+ inductives which are recognized when a "Type" appears at the end of the conlusion in
+ the source syntax. *)
+
+let rec check_anonymous_type ind =
+ let open Glob_term in
+ match DAst.get ind with
+ | GSort (GType []) -> true
+ | GProd ( _, _, _, e)
+ | GLetIn (_, _, _, e)
+ | GLambda (_, _, _, e)
+ | GApp (e, _)
+ | GCast (e, _) -> check_anonymous_type e
+ | _ -> false
+
+let make_conclusion_flexible sigma ty poly =
+ if poly && Term.isArity ty then
+ let _, concl = Term.destArity ty in
+ match concl with
+ | Type u ->
+ (match Univ.universe_level u with
+ | Some u ->
+ Evd.make_flexible_variable sigma ~algebraic:true u
+ | None -> sigma)
+ | _ -> sigma
+ else sigma
+
+let is_impredicative env u =
+ u = Prop Null || (is_impredicative_set env && u = Prop Pos)
+
+let interp_ind_arity env sigma ind =
+ let c = intern_gen IsType env ind.ind_arity in
+ let impls = Implicit_quantifiers.implicits_of_glob_constr ~with_products:true c in
+ let sigma,t = understand_tcc env sigma ~expected_type:IsType c in
+ let pseudo_poly = check_anonymous_type c in
+ let () = if not (Reductionops.is_arity env sigma t) then
+ user_err ?loc:(constr_loc ind.ind_arity) (str "Not an arity")
+ in
+ let t = EConstr.Unsafe.to_constr t in
+ sigma, (t, pseudo_poly, impls)
+
+let interp_cstrs env sigma impls mldata arity ind =
+ let cnames,ctyps = List.split ind.ind_lc in
+ (* Complete conclusions of constructor types if given in ML-style syntax *)
+ let ctyps' = List.map2 (complete_conclusion mldata) cnames ctyps in
+ (* Interpret the constructor types *)
+ let sigma, (ctyps'', cimpls) =
+ on_snd List.split @@
+ List.fold_left_map (fun sigma l ->
+ on_snd (on_fst EConstr.Unsafe.to_constr) @@
+ interp_type_evars_impls env sigma ~impls l) sigma ctyps' in
+ sigma, (cnames, ctyps'', cimpls)
+
+let sign_level env evd sign =
+ fst (List.fold_right
+ (fun d (lev,env) ->
+ match d with
+ | LocalDef _ -> lev, push_rel d env
+ | LocalAssum _ ->
+ let s = destSort (Reduction.whd_all env
+ (EConstr.Unsafe.to_constr (nf_evar evd (Retyping.get_type_of env evd (EConstr.of_constr (RelDecl.get_type d))))))
+ in
+ let u = univ_of_sort s in
+ (Univ.sup u lev, push_rel d env))
+ sign (Univ.type0m_univ,env))
+
+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 (LocalAssum (Anonymous, concl) :: ctx)) tys
+ in sup_list min sorts
+
+let is_flexible_sort evd u =
+ match Univ.Universe.level u with
+ | Some l -> Evd.is_flexible_level evd l
+ | None -> false
+
+let inductive_levels env evd poly arities inds =
+ let destarities = List.map (fun x -> x, Reduction.dest_arity env x) arities in
+ let levels = List.map (fun (x,(ctx,a)) ->
+ if a = Prop Null then None
+ else Some (univ_of_sort a)) destarities
+ in
+ let cstrs_levels, min_levels, sizes =
+ CList.split3
+ (List.map2 (fun (_,tys,_) (arity,(ctx,du)) ->
+ let len = List.length tys in
+ let minlev = Sorts.univ_of_sort du in
+ let minlev =
+ if len > 1 && not (is_impredicative env du) then
+ Univ.sup minlev Univ.type0_univ
+ else minlev
+ in
+ let minlev =
+ (** Indices contribute. *)
+ if Indtypes.is_indices_matter () && List.length ctx > 0 then (
+ let ilev = sign_level env evd ctx in
+ Univ.sup ilev minlev)
+ else minlev
+ in
+ let clev = extract_level env evd minlev tys in
+ (clev, minlev, len)) inds destarities)
+ in
+ (* Take the transitive closure of the system of constructors *)
+ (* level constraints and remove the recursive dependencies *)
+ let levels' = Universes.solve_constraints_system (Array.of_list levels)
+ (Array.of_list cstrs_levels) (Array.of_list min_levels)
+ in
+ let evd, arities =
+ CList.fold_left3 (fun (evd, arities) cu (arity,(ctx,du)) len ->
+ if is_impredicative env du then
+ (** Any product is allowed here. *)
+ evd, arity :: arities
+ else (** If in a predicative sort, or asked to infer the type,
+ we take the max of:
+ - indices (if in indices-matter mode)
+ - constructors
+ - Type(1) if there is more than 1 constructor
+ *)
+ (** Constructors contribute. *)
+ let evd =
+ if Sorts.is_set du then
+ if not (Evd.check_leq evd cu Univ.type0_univ) then
+ raise (Indtypes.InductiveError Indtypes.LargeNonPropInductiveNotInType)
+ else evd
+ else evd
+ (* Evd.set_leq_sort env evd (Type cu) du *)
+ in
+ let evd =
+ if len >= 2 && Univ.is_type0m_univ cu then
+ (** "Polymorphic" type constraint and more than one constructor,
+ should not land in Prop. Add constraint only if it would
+ land in Prop directly (no informative arguments as well). *)
+ Evd.set_leq_sort env evd (Prop Pos) du
+ else evd
+ in
+ let duu = Sorts.univ_of_sort du in
+ let evd =
+ if not (Univ.is_small_univ duu) && Univ.Universe.equal cu duu then
+ if is_flexible_sort evd duu && not (Evd.check_leq evd Univ.type0_univ duu) then
+ Evd.set_eq_sort env evd (Prop Null) du
+ else evd
+ else Evd.set_eq_sort env evd (Type cu) du
+ in
+ (evd, arity :: arities))
+ (evd,[]) (Array.to_list levels') destarities sizes
+ in evd, List.rev arities
+
+let check_named (loc, na) = match na with
+| Name _ -> ()
+| Anonymous ->
+ let msg = str "Parameters must be named." in
+ user_err ?loc msg
+
+
+let check_param = function
+| CLocalDef (na, _, _) -> check_named na
+| CLocalAssum (nas, Default _, _) -> List.iter check_named nas
+| CLocalAssum (nas, Generalized _, _) -> ()
+| CLocalPattern (loc,_) ->
+ Loc.raise ?loc (Stream.Error "pattern with quote not allowed here.")
+
+let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
+ check_all_names_different indl;
+ List.iter check_param paramsl;
+ let env0 = Global.env() in
+ let pl = (List.hd indl).ind_univs in
+ let sigma, decl = Univdecls.interp_univ_decl_opt env0 pl in
+ let sigma, (impls, ((env_params, ctx_params), userimpls)) =
+ interp_context_evars env0 sigma paramsl
+ in
+ let ctx_params = List.map (fun d -> map_rel_decl EConstr.Unsafe.to_constr d) ctx_params in
+ 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 is_local_assum ctx_params in
+ let params = List.map (RelDecl.get_name %> Name.get_id) assums in
+
+ (* Interpret the arities *)
+ let sigma, arities = List.fold_left_map (fun sigma -> interp_ind_arity env_params sigma) sigma indl in
+
+ let fullarities = List.map (fun (c, _, _) -> Term.it_mkProd_or_LetIn c ctx_params) arities in
+ let env_ar = push_types env0 indnames fullarities in
+ let env_ar_params = push_rel_context ctx_params env_ar in
+
+ (* Compute interpretation metadatas *)
+ let indimpls = List.map (fun (_, _, impls) -> userimpls @
+ lift_implicits (Context.Rel.nhyps ctx_params) impls) arities in
+ let arities = List.map pi1 arities and aritypoly = List.map pi2 arities in
+ let impls = compute_internalization_env env0 ~impls (Inductive (params,true)) indnames fullarities indimpls in
+ let ntn_impls = compute_internalization_env env0 (Inductive (params,true)) indnames fullarities indimpls in
+ let mldatas = List.map2 (mk_mltype_data sigma env_params params) arities indnames in
+
+ let sigma, constructors =
+ Metasyntax.with_syntax_protection (fun () ->
+ (* Temporary declaration of notations and scopes *)
+ List.iter (Metasyntax.set_notation_for_interpretation env_params ntn_impls) notations;
+ (* Interpret the constructor types *)
+ List.fold_left3_map (fun sigma -> interp_cstrs env_ar_params sigma impls) sigma mldatas arities indl)
+ () in
+
+ (* Try further to solve evars, and instantiate them *)
+ let sigma = solve_remaining_evars all_and_fail_flags env_params sigma Evd.empty in
+ (* Compute renewed arities *)
+ let sigma, nf = nf_evars_and_universes sigma in
+ let arities = List.map nf arities in
+ let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
+ let sigma = List.fold_left2 (fun sigma ty poly -> make_conclusion_flexible sigma ty poly) sigma arities aritypoly in
+ let sigma, arities = inductive_levels env_ar_params sigma poly arities constructors in
+ let sigma, nf' = nf_evars_and_universes sigma in
+ let nf x = nf' (nf x) in
+ let arities = List.map nf' arities in
+ let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
+ let ctx_params = Context.Rel.map nf ctx_params in
+ let uctx = Evd.check_univ_decl ~poly sigma decl in
+ List.iter (fun c -> check_evars env_params Evd.empty sigma (EConstr.of_constr c)) arities;
+ Context.Rel.iter (fun c -> check_evars env0 Evd.empty sigma (EConstr.of_constr c)) ctx_params;
+ List.iter (fun (_,ctyps,_) ->
+ List.iter (fun c -> check_evars env_ar_params Evd.empty sigma (EConstr.of_constr c)) ctyps)
+ constructors;
+
+ (* Build the inductive entries *)
+ let entries = List.map4 (fun ind arity template (cnames,ctypes,cimpls) -> {
+ mind_entry_typename = ind.ind_name;
+ mind_entry_arity = arity;
+ mind_entry_template = template;
+ mind_entry_consnames = cnames;
+ mind_entry_lc = ctypes
+ }) indl arities aritypoly constructors in
+ let impls =
+ let len = Context.Rel.nhyps ctx_params in
+ List.map2 (fun indimpls (_,_,cimpls) ->
+ indimpls, List.map (fun impls ->
+ userimpls @ (lift_implicits len impls)) cimpls) indimpls constructors
+ in
+ let univs =
+ match uctx with
+ | Polymorphic_const_entry uctx ->
+ if cum then
+ Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context uctx)
+ else Polymorphic_ind_entry uctx
+ | Monomorphic_const_entry uctx ->
+ Monomorphic_ind_entry uctx
+ in
+ (* Build the mutual inductive entry *)
+ let mind_ent =
+ { mind_entry_params = List.map prepare_param ctx_params;
+ mind_entry_record = None;
+ mind_entry_finite = finite;
+ mind_entry_inds = entries;
+ mind_entry_private = if prv then Some false else None;
+ mind_entry_universes = univs;
+ }
+ in
+ (if poly && cum then
+ Inductiveops.infer_inductive_subtyping env_ar sigma mind_ent
+ else mind_ent), Evd.universe_binders sigma, impls
+
+(* Very syntactical equality *)
+let eq_local_binders bl1 bl2 =
+ List.equal local_binder_eq bl1 bl2
+
+let extract_coercions indl =
+ let mkqid (_,((_,id),_)) = qualid_of_ident id in
+ let extract lc = List.filter (fun (iscoe,_) -> iscoe) lc in
+ List.map mkqid (List.flatten(List.map (fun (_,_,_,lc) -> extract lc) indl))
+
+let extract_params indl =
+ let paramsl = List.map (fun (_,params,_,_) -> params) indl in
+ match paramsl with
+ | [] -> anomaly (Pp.str "empty list of inductive types.")
+ | params::paramsl ->
+ if not (List.for_all (eq_local_binders params) paramsl) then user_err Pp.(str
+ "Parameters should be syntactically the same for each inductive type.");
+ params
+
+let extract_inductive indl =
+ List.map (fun (((_,indname),pl),_,ar,lc) -> {
+ ind_name = indname; ind_univs = pl;
+ ind_arity = Option.cata (fun x -> x) (CAst.make @@ CSort (GType [])) ar;
+ ind_lc = List.map (fun (_,((_,id),t)) -> (id,t)) lc
+ }) indl
+
+let extract_mutual_inductive_declaration_components indl =
+ let indl,ntnl = List.split indl in
+ let params = extract_params indl in
+ let coes = extract_coercions indl in
+ let indl = extract_inductive indl in
+ (params,indl), coes, List.flatten ntnl
+
+let is_recursive mie =
+ let rec is_recursive_constructor lift typ =
+ match Constr.kind typ with
+ | Prod (_,arg,rest) ->
+ not (EConstr.Vars.noccurn Evd.empty (** FIXME *) lift (EConstr.of_constr arg)) ||
+ is_recursive_constructor (lift+1) rest
+ | LetIn (na,b,t,rest) -> is_recursive_constructor (lift+1) rest
+ | _ -> false
+ in
+ match mie.mind_entry_inds with
+ | [ind] ->
+ let nparams = List.length mie.mind_entry_params in
+ List.exists (fun t -> is_recursive_constructor (nparams+1) t) ind.mind_entry_lc
+ | _ -> false
+
+let declare_mutual_inductive_with_eliminations mie pl impls =
+ (* spiwack: raises an error if the structure is supposed to be non-recursive,
+ but isn't *)
+ begin match mie.mind_entry_finite with
+ | BiFinite when is_recursive mie ->
+ if Option.has_some mie.mind_entry_record then
+ user_err Pp.(str "Records declared with the keywords Record or Structure cannot be recursive. You can, however, define recursive records using the Inductive or CoInductive command.")
+ else
+ user_err Pp.(str ("Types declared with the keyword Variant cannot be recursive. Recursive types are defined with the Inductive and CoInductive command."))
+ | _ -> ()
+ end;
+ let names = List.map (fun e -> e.mind_entry_typename) mie.mind_entry_inds in
+ let (_, kn), prim = declare_mind mie in
+ let mind = Global.mind_of_delta_kn kn in
+ List.iteri (fun i (indimpls, constrimpls) ->
+ let ind = (mind,i) in
+ let gr = IndRef ind in
+ maybe_declare_manual_implicits false gr indimpls;
+ Declare.declare_univ_binders gr pl;
+ List.iteri
+ (fun j impls ->
+ maybe_declare_manual_implicits false
+ (ConstructRef (ind, succ j)) impls)
+ constrimpls)
+ impls;
+ let warn_prim = match mie.mind_entry_record with Some (Some _) -> not prim | _ -> false in
+ Flags.if_verbose Feedback.msg_info (minductive_message warn_prim names);
+ if mie.mind_entry_private == None
+ then declare_default_schemes mind;
+ mind
+
+type one_inductive_impls =
+ Impargs.manual_explicitation list (* for inds *)*
+ Impargs.manual_explicitation list list (* for constrs *)
+
+let do_mutual_inductive indl cum poly prv finite =
+ let indl,coes,ntns = extract_mutual_inductive_declaration_components indl in
+ (* Interpret the types *)
+ let mie,pl,impls = interp_mutual_inductive indl ntns cum poly prv finite in
+ (* Declare the mutual inductive block with its associated schemes *)
+ ignore (declare_mutual_inductive_with_eliminations mie pl impls);
+ (* Declare the possible notations of inductive types *)
+ List.iter (Metasyntax.add_notation_interpretation (Global.env ())) ntns;
+ (* Declare the coercions *)
+ List.iter (fun qid -> Class.try_add_new_coercion (locate qid) ~local:false poly) coes;
+ (* If positivity is assumed declares itself as unsafe. *)
+ if Environ.deactivated_guard (Global.env ()) then Feedback.feedback Feedback.AddedAxiom else ()
diff --git a/vernac/comInductive.mli b/vernac/comInductive.mli
new file mode 100644
index 000000000..82ea131e1
--- /dev/null
+++ b/vernac/comInductive.mli
@@ -0,0 +1,65 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Entries
+open Libnames
+open Vernacexpr
+open Constrexpr
+open Decl_kinds
+
+(** {6 Inductive and coinductive types} *)
+
+(** Entry points for the vernacular commands Inductive and CoInductive *)
+
+val do_mutual_inductive :
+ (one_inductive_expr * decl_notation list) list -> cumulative_inductive_flag ->
+ polymorphic -> private_flag -> Declarations.recursivity_kind -> unit
+
+(************************************************************************)
+(** Internal API *)
+(************************************************************************)
+
+(** Exported for Record and Funind *)
+
+(** Registering a mutual inductive definition together with its
+ associated schemes *)
+
+type one_inductive_impls =
+ Impargs.manual_implicits (** for inds *)*
+ Impargs.manual_implicits list (** for constrs *)
+
+val declare_mutual_inductive_with_eliminations :
+ mutual_inductive_entry -> Universes.universe_binders -> one_inductive_impls list ->
+ MutInd.t
+
+(** Exported for Funind *)
+
+(** Extracting the semantical components out of the raw syntax of mutual
+ inductive declarations *)
+
+type structured_one_inductive_expr = {
+ ind_name : Id.t;
+ ind_univs : Vernacexpr.universe_decl_expr option;
+ ind_arity : constr_expr;
+ ind_lc : (Id.t * constr_expr) list
+}
+
+type structured_inductive_expr =
+ local_binder_expr list * structured_one_inductive_expr list
+
+val extract_mutual_inductive_declaration_components :
+ (one_inductive_expr * decl_notation list) list ->
+ structured_inductive_expr * (*coercions:*) qualid list * decl_notation list
+
+(** Typing mutual inductive definitions *)
+
+val interp_mutual_inductive :
+ structured_inductive_expr -> decl_notation list -> cumulative_inductive_flag ->
+ polymorphic -> private_flag -> Declarations.recursivity_kind ->
+ mutual_inductive_entry * Universes.universe_binders * one_inductive_impls list
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
new file mode 100644
index 000000000..a9a91e304
--- /dev/null
+++ b/vernac/comProgramFixpoint.ml
@@ -0,0 +1,342 @@
+open Pp
+open CErrors
+open Util
+open Constr
+open Entries
+open Vars
+open Declare
+open Names
+open Libnames
+open Globnames
+open Nameops
+open Constrexpr
+open Constrexpr_ops
+open Constrintern
+open Decl_kinds
+open Evarutil
+open Context.Rel.Declaration
+open ComFixpoint
+
+module RelDecl = Context.Rel.Declaration
+
+(* Wellfounded definition *)
+
+open Coqlib
+
+let contrib_name = "Program"
+let subtac_dir = [contrib_name]
+let fixsub_module = subtac_dir @ ["Wf"]
+(* let tactics_module = subtac_dir @ ["Tactics"] *)
+
+let init_reference dir s () = Coqlib.coq_reference "Command" dir s
+let init_constant dir s sigma =
+ Evarutil.new_global sigma (Coqlib.coq_reference "Command" dir s)
+
+let make_ref l s = init_reference l s
+(* let fix_proto = init_constant tactics_module "fix_proto" *)
+let fix_sub_ref = make_ref fixsub_module "Fix_sub"
+let measure_on_R_ref = make_ref fixsub_module "MR"
+let well_founded = init_constant ["Init"; "Wf"] "well_founded"
+let mkSubset sigma name typ prop =
+ let open EConstr in
+ let sigma, app_h = Evarutil.new_global sigma (delayed_force build_sigma).typ in
+ sigma, mkApp (app_h, [| typ; mkLambda (name, typ, prop) |])
+
+let sigT = Lazy.from_fun build_sigma_type
+
+let make_qref s = Qualid (Loc.tag @@ qualid_of_string s)
+let lt_ref = make_qref "Init.Peano.lt"
+
+let rec telescope sigma l =
+ let open EConstr in
+ let open Vars in
+ match l with
+ | [] -> assert false
+ | [LocalAssum (n, t)] ->
+ sigma, t, [LocalDef (n, mkRel 1, t)], mkRel 1
+ | LocalAssum (n, t) :: tl ->
+ let sigma, ty, tys, (k, constr) =
+ List.fold_left
+ (fun (sigma, ty, tys, (k, constr)) decl ->
+ let t = RelDecl.get_type decl in
+ let pred = mkLambda (RelDecl.get_name decl, t, ty) in
+ let sigma, ty = Evarutil.new_global sigma (Lazy.force sigT).typ in
+ let sigma, intro = Evarutil.new_global sigma (Lazy.force sigT).intro in
+ let sigty = mkApp (ty, [|t; pred|]) in
+ let intro = mkApp (intro, [|lift k t; lift k pred; mkRel k; constr|]) in
+ (sigma, sigty, pred :: tys, (succ k, intro)))
+ (sigma, t, [], (2, mkRel 1)) tl
+ in
+ let sigma, last, subst = List.fold_right2
+ (fun pred decl (sigma, prev, subst) ->
+ let t = RelDecl.get_type decl in
+ let sigma, p1 = Evarutil.new_global sigma (Lazy.force sigT).proj1 in
+ let sigma, p2 = Evarutil.new_global sigma (Lazy.force sigT).proj2 in
+ let proj1 = applist (p1, [t; pred; prev]) in
+ let proj2 = applist (p2, [t; pred; prev]) in
+ (sigma, lift 1 proj2, LocalDef (get_name decl, proj1, t) :: subst))
+ (List.rev tys) tl (sigma, mkRel 1, [])
+ in sigma, ty, (LocalDef (n, last, t) :: subst), constr
+
+ | LocalDef (n, b, t) :: tl ->
+ let sigma, ty, subst, term = telescope sigma tl in
+ sigma, ty, (LocalDef (n, b, t) :: subst), lift 1 term
+
+let nf_evar_context sigma ctx =
+ List.map (map_constr (fun c -> Evarutil.nf_evar sigma c)) ctx
+
+let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
+ let open EConstr in
+ let open Vars in
+ let lift_rel_context n l = Termops.map_rel_context_with_binders (liftn n) l in
+ Coqlib.check_required_library ["Coq";"Program";"Wf"];
+ let env = Global.env() in
+ let sigma, decl = Univdecls.interp_univ_decl_opt env pl in
+ let sigma, (_, ((env', binders_rel), impls)) = interp_context_evars env sigma bl in
+ let len = List.length binders_rel in
+ let top_env = push_rel_context binders_rel env in
+ let sigma, top_arity = interp_type_evars top_env sigma arityc in
+ let full_arity = it_mkProd_or_LetIn top_arity binders_rel in
+ let sigma, argtyp, letbinders, make = telescope sigma binders_rel in
+ let argname = Id.of_string "recarg" in
+ let arg = LocalAssum (Name argname, argtyp) in
+ let binders = letbinders @ [arg] in
+ let binders_env = push_rel_context binders_rel env in
+ let sigma, (rel, _) = interp_constr_evars_impls env sigma r in
+ let relty = Typing.unsafe_type_of env sigma rel in
+ let relargty =
+ let error () =
+ user_err ?loc:(constr_loc r)
+ ~hdr:"Command.build_wellfounded"
+ (Printer.pr_econstr_env env sigma rel ++ str " is not an homogeneous binary relation.")
+ in
+ try
+ let ctx, ar = Reductionops.splay_prod_n env sigma 2 relty in
+ match ctx, EConstr.kind sigma ar with
+ | [LocalAssum (_,t); LocalAssum (_,u)], Sort s
+ when Sorts.is_prop (ESorts.kind sigma s) && Reductionops.is_conv env sigma t u -> t
+ | _, _ -> error ()
+ with e when CErrors.noncritical e -> error ()
+ in
+ let sigma, measure = interp_casted_constr_evars binders_env sigma measure relargty in
+ let sigma, wf_rel, wf_rel_fun, measure_fn =
+ let measure_body, measure =
+ it_mkLambda_or_LetIn measure letbinders,
+ it_mkLambda_or_LetIn measure binders
+ in
+ let sigma, comb = Evarutil.new_global sigma (delayed_force measure_on_R_ref) in
+ let wf_rel = mkApp (comb, [| argtyp; relargty; rel; measure |]) in
+ let wf_rel_fun x y =
+ mkApp (rel, [| subst1 x measure_body;
+ subst1 y measure_body |])
+ in sigma, wf_rel, wf_rel_fun, measure
+ in
+ let sigma, wf_term = well_founded sigma in
+ let wf_proof = mkApp (wf_term, [| argtyp ; wf_rel |]) in
+ let argid' = Id.of_string (Id.to_string argname ^ "'") in
+ let wfarg sigma len =
+ let sigma, ss_term = mkSubset sigma (Name argid') argtyp (wf_rel_fun (mkRel 1) (mkRel (len + 1))) in
+ sigma, LocalAssum (Name argid', ss_term)
+ in
+ let sigma, intern_bl =
+ let sigma, wfa = wfarg sigma 1 in
+ sigma, wfa :: [arg]
+ in
+ let _intern_env = push_rel_context intern_bl env in
+ let sigma, proj = Evarutil.new_global sigma (delayed_force build_sigma).Coqlib.proj1 in
+ let wfargpred = mkLambda (Name argid', argtyp, wf_rel_fun (mkRel 1) (mkRel 3)) in
+ let projection = (* in wfarg :: arg :: before *)
+ mkApp (proj, [| argtyp ; wfargpred ; mkRel 1 |])
+ in
+ let top_arity_let = it_mkLambda_or_LetIn top_arity letbinders in
+ let intern_arity = substl [projection] top_arity_let in
+ (* substitute the projection of wfarg for something,
+ now intern_arity is in wfarg :: arg *)
+ let sigma, wfa = wfarg sigma 1 in
+ let intern_fun_arity_prod = it_mkProd_or_LetIn intern_arity [wfa] in
+ let intern_fun_binder = LocalAssum (Name (add_suffix recname "'"), intern_fun_arity_prod) in
+ let sigma, curry_fun =
+ let wfpred = mkLambda (Name argid', argtyp, wf_rel_fun (mkRel 1) (mkRel (2 * len + 4))) in
+ let sigma, intro = Evarutil.new_global sigma (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 = 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
+ sigma, LocalDef (Name recname, body, ty)
+ in
+ let fun_bl = intern_fun_binder :: [arg] in
+ let lift_lets = lift_rel_context 1 letbinders in
+ let sigma, intern_body =
+ let ctx = LocalAssum (Name recname, get_type curry_fun) :: binders_rel in
+ let (r, l, impls, scopes) =
+ Constrintern.compute_internalization_data env
+ Constrintern.Recursive (EConstr.Unsafe.to_constr full_arity) impls
+ in
+ let newimpls = Id.Map.singleton recname
+ (r, l, impls @ [(Some (Id.of_string "recproof", Impargs.Manual, (true, false)))],
+ scopes @ [None]) in
+ interp_casted_constr_evars (push_rel_context ctx env) sigma
+ ~impls:newimpls body (lift 1 top_arity)
+ in
+ let intern_body_lam = it_mkLambda_or_LetIn intern_body (curry_fun :: lift_lets @ fun_bl) in
+ let prop = mkLambda (Name argname, argtyp, top_arity_let) in
+ (* XXX: Previous code did parallel evdref update, so possible old
+ weak ordering semantics may bite here. *)
+ let sigma, def =
+ let sigma, h_a_term = Evarutil.new_global sigma (delayed_force fix_sub_ref) in
+ let sigma, h_e_term = Evarutil.new_evar env sigma
+ ~src:(Loc.tag @@ Evar_kinds.QuestionMark (Evar_kinds.Define false,Anonymous)) wf_proof in
+ sigma, mkApp (h_a_term, [| argtyp ; wf_rel ; h_e_term; prop |])
+ in
+ let _evd = ref sigma in
+ let def = Typing.e_solve_evars env _evd def in
+ let sigma = !_evd in
+ let sigma = Evarutil.nf_evar_map sigma in
+ let def = mkApp (def, [|intern_body_lam|]) in
+ let binders_rel = nf_evar_context sigma binders_rel in
+ let binders = nf_evar_context sigma binders in
+ let top_arity = Evarutil.nf_evar sigma top_arity in
+ let hook, recname, typ =
+ if List.length binders_rel > 1 then
+ let name = add_suffix recname "_func" in
+ (* XXX: Mutating the evar_map in the hook! *)
+ (* XXX: Likely the sigma is out of date when the hook is called .... *)
+ let hook sigma l gr _ =
+ let sigma, h_body = Evarutil.new_global sigma gr in
+ let body = it_mkLambda_or_LetIn (mkApp (h_body, [|make|])) binders_rel in
+ let ty = it_mkProd_or_LetIn top_arity binders_rel in
+ let ty = EConstr.Unsafe.to_constr ty in
+ let univs = Evd.check_univ_decl ~poly sigma decl in
+ (*FIXME poly? *)
+ let ce = definition_entry ~types:ty ~univs (EConstr.to_constr sigma body) in
+ (** FIXME: include locality *)
+ let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
+ let gr = ConstRef c in
+ let () = Universes.register_universe_binders gr (Evd.universe_binders sigma) in
+ if Impargs.is_implicit_args () || not (List.is_empty impls) then
+ Impargs.declare_manual_implicits false gr [impls]
+ in
+ let typ = it_mkProd_or_LetIn top_arity binders in
+ hook, name, typ
+ else
+ let typ = it_mkProd_or_LetIn top_arity binders_rel in
+ let hook sigma l gr _ =
+ if Impargs.is_implicit_args () || not (List.is_empty impls) then
+ Impargs.declare_manual_implicits false gr [impls]
+ in hook, recname, typ
+ in
+ (* XXX: Capturing sigma here... bad bad *)
+ let hook = Lemmas.mk_hook (hook sigma) in
+ let fullcoqc = EConstr.to_constr sigma def in
+ let fullctyp = EConstr.to_constr sigma typ in
+ Obligations.check_evars env sigma;
+ let evars, _, evars_def, evars_typ =
+ Obligations.eterm_obligations env recname sigma 0 fullcoqc fullctyp
+ in
+ let ctx = Evd.evar_universe_context sigma in
+ ignore(Obligations.add_definition recname ~term:evars_def ~univdecl:decl
+ evars_typ ctx evars ~hook)
+
+let out_def = function
+ | Some def -> def
+ | None -> user_err Pp.(str "Program Fixpoint needs defined bodies.")
+
+let collect_evars_of_term evd c ty =
+ let evars = Evar.Set.union (Evd.evars_of_term c) (Evd.evars_of_term ty) in
+ Evar.Set.fold (fun ev acc -> Evd.add acc ev (Evd.find_undefined evd ev))
+ evars (Evd.from_ctx (Evd.evar_universe_context evd))
+
+let do_program_recursive local poly fixkind fixl ntns =
+ let cofix = fixkind = Obligations.IsCoFixpoint in
+ let (env, rec_sign, pl, evd), fix, info =
+ interp_recursive ~cofix ~program_mode:true fixl ntns
+ in
+ (* Program-specific code *)
+ (* Get the interesting evars, those that were not instanciated *)
+ let evd = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals ~fail:true env evd in
+ (* Solve remaining evars *)
+ let evd = nf_evar_map_undefined evd in
+ let collect_evars id def typ imps =
+ (* Generalize by the recursive prototypes *)
+ let def =
+ EConstr.to_constr evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
+ and typ =
+ EConstr.to_constr evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
+ in
+ let evm = collect_evars_of_term evd def typ in
+ let evars, _, def, typ =
+ Obligations.eterm_obligations env id evm
+ (List.length rec_sign) def typ
+ in (id, def, typ, imps, evars)
+ in
+ let (fixnames,fixdefs,fixtypes) = fix in
+ let fiximps = List.map pi2 info in
+ let fixdefs = List.map out_def fixdefs in
+ let defs = List.map4 collect_evars fixnames fixdefs fixtypes fiximps in
+ let () = if not cofix then begin
+ let possible_indexes = List.map ComFixpoint.compute_possible_guardness_evidences info in
+ let fixdecls = Array.of_list (List.map (fun x -> Name x) fixnames),
+ Array.of_list fixtypes,
+ Array.of_list (List.map (subst_vars (List.rev fixnames)) fixdefs)
+ in
+ let indexes =
+ Pretyping.search_guard (Global.env ()) possible_indexes fixdecls in
+ List.iteri (fun i _ ->
+ Inductive.check_fix env
+ ((indexes,i),fixdecls))
+ fixl
+ end in
+ let ctx = Evd.evar_universe_context evd in
+ let kind = match fixkind with
+ | Obligations.IsFixpoint _ -> (local, poly, Fixpoint)
+ | Obligations.IsCoFixpoint -> (local, poly, CoFixpoint)
+ in
+ Obligations.add_mutual_definitions defs ~kind ~univdecl: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),pl),_,bl,typ,def),ntn)] ->
+ let recarg =
+ match n with
+ | Some n -> mkIdentC (snd n)
+ | None ->
+ user_err ~hdr:"do_program_fixpoint"
+ (str "Recursive argument required for well-founded fixpoints")
+ in build_wellfounded (id, pl, n, bl, typ, out_def def) poly r recarg ntn
+
+ | [(n, CMeasureRec (m, r))], [((((_,id),pl),_,bl,typ,def),ntn)] ->
+ build_wellfounded (id, pl, n, bl, typ, out_def def) poly
+ (Option.default (CAst.make @@ CRef (lt_ref,None)) r) m ntn
+
+ | _, _ when List.for_all (fun (n, ro) -> ro == CStructRec) g ->
+ let fixl,ntns = extract_fixpoint_components true l in
+ let fixkind = Obligations.IsFixpoint g in
+ do_program_recursive local poly fixkind fixl ntns
+
+ | _, _ ->
+ user_err ~hdr:"do_program_fixpoint"
+ (str "Well-founded fixpoints not allowed in mutually recursive blocks")
+
+let extract_cofixpoint_components l =
+ let fixl, ntnl = List.split l in
+ List.map (fun (((_,id),pl),bl,typ,def) ->
+ {fix_name = id; fix_annot = None; fix_univs = pl;
+ fix_binders = bl; fix_body = def; fix_type = typ}) fixl,
+ List.flatten ntnl
+
+let check_safe () =
+ let open Declarations in
+ let flags = Environ.typing_flags (Global.env ()) in
+ flags.check_universes && flags.check_guarded
+
+let do_fixpoint local poly l =
+ do_program_fixpoint local poly l;
+ if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
+
+let do_cofixpoint local poly l =
+ let fixl,ntns = extract_cofixpoint_components l in
+ do_program_recursive local poly Obligations.IsCoFixpoint fixl ntns;
+ if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
diff --git a/vernac/comProgramFixpoint.mli b/vernac/comProgramFixpoint.mli
new file mode 100644
index 000000000..943cb8efe
--- /dev/null
+++ b/vernac/comProgramFixpoint.mli
@@ -0,0 +1,12 @@
+open Decl_kinds
+open Vernacexpr
+
+(** Special Fixpoint handling when command is activated. *)
+
+val do_fixpoint :
+ (* When [false], assume guarded. *)
+ locality -> polymorphic -> (fixpoint_expr * decl_notation list) list -> unit
+
+val do_cofixpoint :
+ (* When [false], assume guarded. *)
+ locality -> polymorphic -> (cofixpoint_expr * decl_notation list) list -> unit
diff --git a/vernac/command.ml b/vernac/command.ml
deleted file mode 100644
index 23be2c308..000000000
--- a/vernac/command.ml
+++ /dev/null
@@ -1,1364 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Pp
-open CErrors
-open Sorts
-open Util
-open Constr
-open Vars
-open Termops
-open Environ
-open Redexpr
-open Declare
-open Names
-open Libnames
-open Globnames
-open Nameops
-open Constrexpr
-open Constrexpr_ops
-open Constrintern
-open Nametab
-open Impargs
-open Reductionops
-open Indtypes
-open Decl_kinds
-open Pretyping
-open Evarutil
-open Evarconv
-open Indschemes
-open Misctypes
-open Vernacexpr
-open Context.Rel.Declaration
-open Entries
-
-module RelDecl = Context.Rel.Declaration
-
-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 f env sigma (EConstr.of_constr c) else
- match Constr.kind c with
- | Lambda (x,t,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 (LocalDef (x,b,t)) env) sigma f (n-1) c)
- | _ -> assert false
-
-let rec complete_conclusion a cs = CAst.map_with_loc (fun ?loc -> function
- | CProdN (bl,c) -> CProdN (bl,complete_conclusion a cs c)
- | CLetIn (na,b,t,c) -> CLetIn (na,b,t,complete_conclusion a cs c)
- | CHole (k, _, _) ->
- let (has_no_args,name,params) = a in
- if not has_no_args then
- user_err ?loc
- (strbrk"Cannot infer the non constant arguments of the conclusion of "
- ++ Id.print cs ++ str ".");
- let args = List.map (fun id -> CAst.make ?loc @@ CRef(Ident(loc,id),None)) params in
- CAppExpl ((None,Ident(loc,name),None),List.rev args)
- | c -> c
- )
-
-(* Commands of the interface *)
-
-(* 1| Constant definitions *)
-
-let red_constant_entry n ce sigma = function
- | None -> ce
- | 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 (_, c) = redfun env sigma c in
- EConstr.Unsafe.to_constr c
- in
- { ce with const_entry_body = Future.chain proof_out
- (fun ((body,ctx),eff) -> (under_binders env sigma redfun n body,ctx),eff) }
-
-let warn_implicits_in_term =
- CWarnings.create ~name:"implicits-in-term" ~category:"implicits"
- (fun () ->
- strbrk "Implicit arguments declaration relies on type." ++ spc () ++
- strbrk "The term declares more implicits than the type here.")
-
-let interp_definition pl bl poly red_option c ctypopt =
- let env = Global.env() in
- let evd, decl = Univdecls.interp_univ_decl_opt env pl in
- let evdref = ref evd in
- let impls, ((env_bl, ctx), imps1) = interp_context_evars env evdref bl in
- let ctx = List.map (fun d -> map_rel_decl EConstr.Unsafe.to_constr d) ctx in
- let nb_args = Context.Rel.nhyps ctx in
- let imps,ce =
- match ctypopt with
- None ->
- let subst = evd_comb0 Evd.nf_univ_variables evdref in
- let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
- let env_bl = push_rel_context ctx env in
- let c, imps2 = interp_constr_evars_impls ~impls env_bl evdref c in
- let c = EConstr.Unsafe.to_constr c in
- let nf,subst = Evarutil.e_nf_evars_and_universes evdref in
- let body = nf (it_mkLambda_or_LetIn c ctx) in
- let vars = EConstr.universes_of_constr env !evdref (EConstr.of_constr body) in
- let () = evdref := Evd.restrict_universe_context !evdref vars in
- let uctx = Evd.check_univ_decl ~poly !evdref decl in
- imps1@(Impargs.lift_implicits nb_args imps2),
- definition_entry ~univs:uctx body
- | Some ctyp ->
- let ty, impsty = interp_type_evars_impls ~impls env_bl evdref ctyp in
- let subst = evd_comb0 Evd.nf_univ_variables evdref in
- let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
- let env_bl = push_rel_context ctx env in
- let c, imps2 = interp_casted_constr_evars_impls ~impls env_bl evdref c ty in
- let c = EConstr.Unsafe.to_constr c in
- let nf, subst = Evarutil.e_nf_evars_and_universes evdref in
- let body = nf (it_mkLambda_or_LetIn c ctx) in
- let ty = EConstr.Unsafe.to_constr ty in
- let typ = nf (Term.it_mkProd_or_LetIn ty ctx) in
- let beq b1 b2 = if b1 then b2 else not b2 in
- let impl_eq (x,y,z) (x',y',z') = beq x x' && beq y y' && beq z z' in
- (* Check that all implicit arguments inferable from the term
- are inferable from the type *)
- let chk (key,va) =
- impl_eq (List.assoc_f Pervasives.(=) key impsty) va (* FIXME *)
- in
- if not (try List.for_all chk imps2 with Not_found -> false)
- then warn_implicits_in_term ();
- let bodyvars = EConstr.universes_of_constr env !evdref (EConstr.of_constr body) in
- let tyvars = EConstr.universes_of_constr env !evdref (EConstr.of_constr ty) in
- let vars = Univ.LSet.union bodyvars tyvars in
- let () = evdref := Evd.restrict_universe_context !evdref vars in
- let uctx = Evd.check_univ_decl ~poly !evdref decl in
- imps1@(Impargs.lift_implicits nb_args impsty),
- definition_entry ~types:typ ~univs:uctx body
- in
- (red_constant_entry (Context.Rel.length ctx) ce !evdref red_option, !evdref, decl, imps)
-
-let check_definition (ce, evd, _, imps) =
- check_evars_are_solved (Global.env ()) evd Evd.empty;
- ce
-
-let do_definition ident k univdecl bl red_option c ctypopt hook =
- let (ce, evd, univdecl, imps as def) =
- interp_definition univdecl 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
- assert(Safe_typing.empty_private_constants = sideff);
- assert(Univ.ContextSet.is_empty ctx);
- let typ = match ce.const_entry_type with
- | Some t -> t
- | None -> EConstr.to_constr evd (Retyping.get_type_of env evd (EConstr.of_constr c))
- in
- Obligations.check_evars env evd;
- let obls, _, c, cty =
- Obligations.eterm_obligations env ident evd 0 c typ
- in
- 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 ~univdecl ~implicits:imps ~kind:k ~hook obls)
- else let ce = check_definition def in
- ignore(DeclareDef.declare_definition ident k ce (Evd.universe_binders evd) imps
- (Lemmas.mk_hook
- (fun l r -> Lemmas.call_hook (fun exn -> exn) hook l r;r)))
-
-(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)
-
-let axiom_into_instance = ref false
-
-let _ =
- let open Goptions in
- declare_bool_option
- { optdepr = false;
- optname = "automatically declare axioms whose type is a typeclass as instances";
- optkey = ["Typeclasses";"Axioms";"Are";"Instances"];
- optread = (fun _ -> !axiom_into_instance);
- optwrite = (:=) axiom_into_instance; }
-
-let should_axiom_into_instance = function
- | Discharge ->
- (* The typeclass behaviour of Variable and Context doesn't depend
- on section status *)
- true
- | Global | Local -> !axiom_into_instance
-
-let declare_assumption is_coe (local,p,kind) (c,ctx) pl imps impl nl (_,ident) =
-match local with
-| Discharge when Lib.sections_are_opened () ->
- let ctx = match ctx with
- | Monomorphic_const_entry ctx -> ctx
- | Polymorphic_const_entry ctx -> Univ.ContextSet.of_context ctx
- in
- let decl = (Lib.cwd(), SectionLocalAssum ((c,ctx),p,impl), IsAssumption kind) in
- let _ = declare_variable ident decl in
- let () = assumption_message ident in
- let () =
- if not !Flags.quiet && Proof_global.there_are_pending_proofs () then
- Feedback.msg_info (str"Variable" ++ spc () ++ Id.print ident ++
- strbrk " is not visible from current goals")
- in
- let r = VarRef ident in
- let () = Typeclasses.declare_instance None true r in
- let () = if is_coe then Class.try_add_new_coercion r ~local:true false in
- (r,Univ.Instance.empty,true)
-
-| Global | Local | Discharge ->
- let do_instance = should_axiom_into_instance local in
- let local = DeclareDef.get_locality ident ~kind:"axiom" local in
- let inl = match nl with
- | NoInline -> None
- | DefaultInline -> Some (Flags.get_inline_level())
- | InlineAt i -> Some i
- in
- let decl = (ParameterEntry (None,(c,ctx),inl), IsAssumption kind) in
- let kn = declare_constant ident ~local decl in
- let gr = ConstRef kn in
- let () = maybe_declare_manual_implicits false gr imps in
- let () = Declare.declare_univ_binders gr pl in
- let () = assumption_message ident in
- let () = if do_instance then Typeclasses.declare_instance None false gr in
- let () = if is_coe then Class.try_add_new_coercion gr ~local p in
- let inst = match ctx with
- | Polymorphic_const_entry ctx -> Univ.UContext.instance ctx
- | Monomorphic_const_entry _ -> Univ.Instance.empty
- in
- (gr,inst,Lib.is_modtype_strict ())
-
-let interp_assumption evdref env impls bl c =
- let c = mkCProdN ?loc:(local_binders_loc bl) bl c in
- let ty, impls = interp_type_evars_impls env evdref ~impls c in
- let ty = EConstr.Unsafe.to_constr ty in
- (ty, impls)
-
-(* When monomorphic the universe constraints are declared with the first declaration only. *)
-let next_uctx =
- let empty_uctx = Monomorphic_const_entry Univ.ContextSet.empty in
- function
- | Polymorphic_const_entry _ as uctx -> uctx
- | Monomorphic_const_entry _ -> empty_uctx
-
-let declare_assumptions idl is_coe k (c,uctx) pl imps nl =
- let refs, status, _ =
- List.fold_left (fun (refs,status,uctx) id ->
- let ref',u',status' =
- declare_assumption is_coe k (c,uctx) pl imps false nl id in
- (ref',u')::refs, status' && status, next_uctx uctx)
- ([],true,uctx) idl
- in
- List.rev refs, status
-
-
-let maybe_error_many_udecls = function
- | ((loc,id), Some _) ->
- user_err ?loc ~hdr:"many_universe_declarations"
- Pp.(str "When declaring multiple axioms in one command, " ++
- str "only the first is allowed a universe binder " ++
- str "(which will be shared by the whole block).")
- | (_, None) -> ()
-
-let process_assumptions_udecls kind l =
- let udecl, first_id = match l with
- | (coe, ((id, udecl)::rest, c))::rest' ->
- List.iter maybe_error_many_udecls rest;
- List.iter (fun (coe, (idl, c)) -> List.iter maybe_error_many_udecls idl) rest';
- udecl, id
- | (_, ([], _))::_ | [] -> assert false
- in
- let () = match kind, udecl with
- | (Discharge, _, _), Some _ when Lib.sections_are_opened () ->
- let loc = fst first_id in
- let msg = Pp.str "Section variables cannot be polymorphic." in
- user_err ?loc msg
- | _ -> ()
- in
- udecl, List.map (fun (coe, (idl, c)) -> coe, (List.map fst idl, c)) l
-
-let do_assumptions kind nl l =
- let open Context.Named.Declaration in
- let env = Global.env () in
- let udecl, l = process_assumptions_udecls kind l in
- let evdref, udecl =
- let evd, udecl = Univdecls.interp_univ_decl_opt env udecl in
- ref evd, udecl
- in
- let l =
- if pi2 kind (* poly *) then
- (* Separate declarations so that A B : Type puts A and B in different levels. *)
- List.fold_right (fun (is_coe,(idl,c)) acc ->
- List.fold_right (fun id acc ->
- (is_coe, ([id], c)) :: acc) idl acc)
- l []
- else l
- in
- (* We intepret all declarations in the same evar_map, i.e. as a telescope. *)
- let _,l = List.fold_left_map (fun (env,ienv) (is_coe,(idl,c)) ->
- let t,imps = interp_assumption evdref env ienv [] c in
- let env =
- 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
- ((env,ienv),((is_coe,idl),t,imps)))
- (env,empty_internalization_env) l
- in
- let evd = solve_remaining_evars all_and_fail_flags env !evdref Evd.empty in
- (* The universe constraints come from the whole telescope. *)
- let evd = Evd.nf_constraints evd in
- let nf_evar c = EConstr.to_constr evd (EConstr.of_constr c) in
- let uvars, l = List.fold_left_map (fun uvars (coe,t,imps) ->
- let t = nf_evar t in
- let uvars = Univ.LSet.union uvars (Univops.universes_of_constr env t) in
- uvars, (coe,t,imps))
- Univ.LSet.empty l
- in
- let evd = Evd.restrict_universe_context evd uvars in
- let uctx = Evd.check_univ_decl ~poly:(pi2 kind) evd udecl in
- let ubinders = Evd.universe_binders evd in
- pi2 (List.fold_left (fun (subst,status,uctx) ((is_coe,idl),t,imps) ->
- let t = replace_vars subst t in
- let refs, status' = declare_assumptions idl is_coe kind (t,uctx) ubinders imps nl in
- let subst' = List.map2
- (fun (_,id) (c,u) -> (id, Universes.constr_of_global_univ (c,u)))
- idl refs
- in
- subst'@subst, status' && status, next_uctx uctx)
- ([], true, uctx) l)
-
-(* 3a| Elimination schemes for mutual inductive definitions *)
-
-(* 3b| Mutual inductive definitions *)
-
-let push_types env idl tl =
- List.fold_left2 (fun env id t -> Environ.push_rel (LocalAssum (Name id,t)) env)
- env idl tl
-
-type structured_one_inductive_expr = {
- ind_name : Id.t;
- ind_univs : Vernacexpr.universe_decl_expr option;
- ind_arity : constr_expr;
- ind_lc : (Id.t * constr_expr) list
-}
-
-type structured_inductive_expr =
- local_binder_expr list * structured_one_inductive_expr list
-
-let minductive_message warn = function
- | [] -> user_err Pp.(str "No inductive definition.")
- | [x] -> (Id.print x ++ str " is defined" ++
- if warn then str " as a non-primitive record" else mt())
- | l -> hov 0 (prlist_with_sep pr_comma Id.print l ++
- spc () ++ str "are defined")
-
-let check_all_names_different indl =
- let ind_names = List.map (fun ind -> ind.ind_name) indl in
- let cstr_names = List.map_append (fun ind -> List.map fst ind.ind_lc) indl in
- let l = List.duplicates Id.equal ind_names in
- let () = match l with
- | [] -> ()
- | t :: _ -> raise (InductiveError (SameNamesTypes t))
- in
- let l = List.duplicates Id.equal cstr_names in
- let () = match l with
- | [] -> ()
- | c :: _ -> raise (InductiveError (SameNamesConstructors (List.hd l)))
- in
- let l = List.intersect Id.equal ind_names cstr_names in
- match l with
- | [] -> ()
- | _ -> raise (InductiveError (SameNamesOverlap l))
-
-let mk_mltype_data evdref env assums arity indname =
- let is_ml_type = is_sort env !evdref (EConstr.of_constr arity) in
- (is_ml_type,indname,assums)
-
-let prepare_param = function
- | LocalAssum (na,t) -> Name.get_id na, LocalAssumEntry t
- | LocalDef (na,b,_) -> Name.get_id 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.
- This is really a hack to stay compatible with the semantics of template polymorphic
- inductives which are recognized when a "Type" appears at the end of the conlusion in
- the source syntax. *)
-
-let rec check_anonymous_type ind =
- let open Glob_term in
- match DAst.get ind with
- | GSort (GType []) -> true
- | GProd ( _, _, _, e)
- | GLetIn (_, _, _, e)
- | GLambda (_, _, _, e)
- | GApp (e, _)
- | GCast (e, _) -> check_anonymous_type e
- | _ -> false
-
-let make_conclusion_flexible evdref ty poly =
- if poly && Term.isArity ty then
- let _, concl = Term.destArity ty in
- match concl with
- | Type u ->
- (match Univ.universe_level u with
- | Some u ->
- evdref := Evd.make_flexible_variable !evdref ~algebraic:true u
- | None -> ())
- | _ -> ()
- else ()
-
-let is_impredicative env u =
- u = Prop Null || (is_impredicative_set env && u = Prop Pos)
-
-let interp_ind_arity env evdref ind =
- let c = intern_gen IsType env ind.ind_arity in
- let impls = Implicit_quantifiers.implicits_of_glob_constr ~with_products:true c in
- let (evd,t) = understand_tcc env !evdref ~expected_type:IsType c in
- evdref := evd;
- let pseudo_poly = check_anonymous_type c in
- let () = if not (Reductionops.is_arity env !evdref t) then
- user_err ?loc:(constr_loc ind.ind_arity) (str "Not an arity")
- in
- let t = EConstr.Unsafe.to_constr t in
- t, pseudo_poly, impls
-
-let interp_cstrs evdref env impls mldata arity ind =
- let cnames,ctyps = List.split ind.ind_lc in
- (* Complete conclusions of constructor types if given in ML-style syntax *)
- let ctyps' = List.map2 (complete_conclusion mldata) cnames ctyps in
- (* Interpret the constructor types *)
- let ctyps'', cimpls = List.split (List.map (interp_type_evars_impls evdref env ~impls %> on_fst EConstr.Unsafe.to_constr) ctyps') in
- (cnames, ctyps'', cimpls)
-
-let sign_level env evd sign =
- fst (List.fold_right
- (fun d (lev,env) ->
- match d with
- | LocalDef _ -> lev, push_rel d env
- | LocalAssum _ ->
- let s = destSort (Reduction.whd_all env
- (EConstr.Unsafe.to_constr (nf_evar evd (Retyping.get_type_of env evd (EConstr.of_constr (RelDecl.get_type d))))))
- in
- let u = univ_of_sort s in
- (Univ.sup u lev, push_rel d env))
- sign (Univ.type0m_univ,env))
-
-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 (LocalAssum (Anonymous, concl) :: ctx)) tys
- in sup_list min sorts
-
-let is_flexible_sort evd u =
- match Univ.Universe.level u with
- | Some l -> Evd.is_flexible_level evd l
- | None -> false
-
-let inductive_levels env evdref poly arities inds =
- let destarities = List.map (fun x -> x, Reduction.dest_arity env x) arities in
- let levels = List.map (fun (x,(ctx,a)) ->
- if a = Prop Null then None
- else Some (univ_of_sort a)) destarities
- in
- let cstrs_levels, min_levels, sizes =
- CList.split3
- (List.map2 (fun (_,tys,_) (arity,(ctx,du)) ->
- let len = List.length tys in
- let minlev = Sorts.univ_of_sort du in
- let minlev =
- if len > 1 && not (is_impredicative env du) then
- Univ.sup minlev Univ.type0_univ
- else minlev
- in
- let minlev =
- (** Indices contribute. *)
- if Indtypes.is_indices_matter () && List.length ctx > 0 then (
- let ilev = sign_level env !evdref ctx in
- Univ.sup ilev minlev)
- else minlev
- in
- let clev = extract_level env !evdref minlev tys in
- (clev, minlev, len)) inds destarities)
- in
- (* Take the transitive closure of the system of constructors *)
- (* level constraints and remove the recursive dependencies *)
- let levels' = Universes.solve_constraints_system (Array.of_list levels)
- (Array.of_list cstrs_levels) (Array.of_list min_levels)
- in
- let evd, arities =
- CList.fold_left3 (fun (evd, arities) cu (arity,(ctx,du)) len ->
- if is_impredicative env du then
- (** Any product is allowed here. *)
- evd, arity :: arities
- else (** If in a predicative sort, or asked to infer the type,
- we take the max of:
- - indices (if in indices-matter mode)
- - constructors
- - Type(1) if there is more than 1 constructor
- *)
- (** Constructors contribute. *)
- let evd =
- if Sorts.is_set du then
- if not (Evd.check_leq evd cu Univ.type0_univ) then
- raise (Indtypes.InductiveError Indtypes.LargeNonPropInductiveNotInType)
- else evd
- else evd
- (* Evd.set_leq_sort env evd (Type cu) du *)
- in
- let evd =
- if len >= 2 && Univ.is_type0m_univ cu then
- (** "Polymorphic" type constraint and more than one constructor,
- should not land in Prop. Add constraint only if it would
- land in Prop directly (no informative arguments as well). *)
- Evd.set_leq_sort env evd (Prop Pos) du
- else evd
- in
- let duu = Sorts.univ_of_sort du in
- let evd =
- if not (Univ.is_small_univ duu) && Univ.Universe.equal cu duu then
- if is_flexible_sort evd duu && not (Evd.check_leq evd Univ.type0_univ duu) then
- Evd.set_eq_sort env evd (Prop Null) du
- else evd
- else Evd.set_eq_sort env evd (Type cu) du
- in
- (evd, arity :: arities))
- (!evdref,[]) (Array.to_list levels') destarities sizes
- in evdref := evd; List.rev arities
-
-let check_named (loc, na) = match na with
-| Name _ -> ()
-| Anonymous ->
- let msg = str "Parameters must be named." in
- user_err ?loc msg
-
-
-let check_param = function
-| CLocalDef (na, _, _) -> check_named na
-| CLocalAssum (nas, Default _, _) -> List.iter check_named nas
-| CLocalAssum (nas, Generalized _, _) -> ()
-| CLocalPattern (loc,_) ->
- Loc.raise ?loc (Stream.Error "pattern with quote not allowed here.")
-
-let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
- check_all_names_different indl;
- List.iter check_param paramsl;
- let env0 = Global.env() in
- let pl = (List.hd indl).ind_univs in
- let evd, decl = Univdecls.interp_univ_decl_opt env0 pl in
- let evdref = ref evd in
- let impls, ((env_params, ctx_params), userimpls) =
- interp_context_evars env0 evdref paramsl
- in
- let ctx_params = List.map (fun d -> map_rel_decl EConstr.Unsafe.to_constr d) ctx_params in
- 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 is_local_assum ctx_params in
- let params = List.map (RelDecl.get_name %> Name.get_id) assums in
-
- (* Interpret the arities *)
- let arities = List.map (interp_ind_arity env_params evdref) indl in
-
- let fullarities = List.map (fun (c, _, _) -> Term.it_mkProd_or_LetIn c ctx_params) arities in
- let env_ar = push_types env0 indnames fullarities in
- let env_ar_params = push_rel_context ctx_params env_ar in
-
- (* Compute interpretation metadatas *)
- let indimpls = List.map (fun (_, _, impls) -> userimpls @
- lift_implicits (Context.Rel.nhyps ctx_params) impls) arities in
- let arities = List.map pi1 arities and aritypoly = List.map pi2 arities in
- let impls = compute_internalization_env env0 ~impls (Inductive (params,true)) indnames fullarities indimpls in
- let ntn_impls = compute_internalization_env env0 (Inductive (params,true)) indnames fullarities indimpls in
- let mldatas = List.map2 (mk_mltype_data evdref env_params params) arities indnames in
-
- let constructors =
- Metasyntax.with_syntax_protection (fun () ->
- (* Temporary declaration of notations and scopes *)
- List.iter (Metasyntax.set_notation_for_interpretation env_params ntn_impls) notations;
- (* Interpret the constructor types *)
- List.map3 (interp_cstrs env_ar_params evdref impls) mldatas arities indl)
- () in
-
- (* Try further to solve evars, and instantiate them *)
- let sigma = solve_remaining_evars all_and_fail_flags env_params !evdref Evd.empty in
- evdref := sigma;
- (* Compute renewed arities *)
- let nf,_ = e_nf_evars_and_universes evdref in
- let arities = List.map nf arities in
- let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
- let _ = List.iter2 (fun ty poly -> make_conclusion_flexible evdref ty poly) arities aritypoly in
- let arities = inductive_levels env_ar_params evdref poly arities constructors in
- let nf',_ = e_nf_evars_and_universes evdref in
- let nf x = nf' (nf x) in
- let arities = List.map nf' arities in
- let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
- let ctx_params = Context.Rel.map nf ctx_params in
- let evd = !evdref in
- let uctx = Evd.check_univ_decl ~poly evd decl in
- List.iter (fun c -> check_evars env_params Evd.empty evd (EConstr.of_constr c)) arities;
- Context.Rel.iter (fun c -> check_evars env0 Evd.empty evd (EConstr.of_constr c)) ctx_params;
- List.iter (fun (_,ctyps,_) ->
- List.iter (fun c -> check_evars env_ar_params Evd.empty evd (EConstr.of_constr c)) ctyps)
- constructors;
-
- (* Build the inductive entries *)
- let entries = List.map4 (fun ind arity template (cnames,ctypes,cimpls) -> {
- mind_entry_typename = ind.ind_name;
- mind_entry_arity = arity;
- mind_entry_template = template;
- mind_entry_consnames = cnames;
- mind_entry_lc = ctypes
- }) indl arities aritypoly constructors in
- let impls =
- let len = Context.Rel.nhyps ctx_params in
- List.map2 (fun indimpls (_,_,cimpls) ->
- indimpls, List.map (fun impls ->
- userimpls @ (lift_implicits len impls)) cimpls) indimpls constructors
- in
- let univs =
- match uctx with
- | Polymorphic_const_entry uctx ->
- if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context uctx)
- else Polymorphic_ind_entry uctx
- | Monomorphic_const_entry uctx ->
- Monomorphic_ind_entry uctx
- in
- (* Build the mutual inductive entry *)
- let mind_ent =
- { mind_entry_params = List.map prepare_param ctx_params;
- mind_entry_record = None;
- mind_entry_finite = finite;
- mind_entry_inds = entries;
- mind_entry_private = if prv then Some false else None;
- mind_entry_universes = univs;
- }
- in
- (if poly && cum then
- Inductiveops.infer_inductive_subtyping env_ar evd mind_ent
- else mind_ent), Evd.universe_binders evd, impls
-
-(* Very syntactical equality *)
-let eq_local_binders bl1 bl2 =
- List.equal local_binder_eq bl1 bl2
-
-let extract_coercions indl =
- let mkqid (_,((_,id),_)) = qualid_of_ident id in
- let extract lc = List.filter (fun (iscoe,_) -> iscoe) lc in
- List.map mkqid (List.flatten(List.map (fun (_,_,_,lc) -> extract lc) indl))
-
-let extract_params indl =
- let paramsl = List.map (fun (_,params,_,_) -> params) indl in
- match paramsl with
- | [] -> anomaly (Pp.str "empty list of inductive types.")
- | params::paramsl ->
- if not (List.for_all (eq_local_binders params) paramsl) then user_err Pp.(str
- "Parameters should be syntactically the same for each inductive type.");
- params
-
-let extract_inductive indl =
- List.map (fun (((_,indname),pl),_,ar,lc) -> {
- ind_name = indname; ind_univs = pl;
- ind_arity = Option.cata (fun x -> x) (CAst.make @@ CSort (GType [])) ar;
- ind_lc = List.map (fun (_,((_,id),t)) -> (id,t)) lc
- }) indl
-
-let extract_mutual_inductive_declaration_components indl =
- let indl,ntnl = List.split indl in
- let params = extract_params indl in
- let coes = extract_coercions indl in
- let indl = extract_inductive indl in
- (params,indl), coes, List.flatten ntnl
-
-let is_recursive mie =
- let rec is_recursive_constructor lift typ =
- match Constr.kind typ with
- | Prod (_,arg,rest) ->
- not (EConstr.Vars.noccurn Evd.empty (** FIXME *) lift (EConstr.of_constr arg)) ||
- is_recursive_constructor (lift+1) rest
- | LetIn (na,b,t,rest) -> is_recursive_constructor (lift+1) rest
- | _ -> false
- in
- match mie.mind_entry_inds with
- | [ind] ->
- let nparams = List.length mie.mind_entry_params in
- List.exists (fun t -> is_recursive_constructor (nparams+1) t) ind.mind_entry_lc
- | _ -> false
-
-let declare_mutual_inductive_with_eliminations mie pl impls =
- (* spiwack: raises an error if the structure is supposed to be non-recursive,
- but isn't *)
- begin match mie.mind_entry_finite with
- | BiFinite when is_recursive mie ->
- if Option.has_some mie.mind_entry_record then
- user_err Pp.(str "Records declared with the keywords Record or Structure cannot be recursive. You can, however, define recursive records using the Inductive or CoInductive command.")
- else
- user_err Pp.(str ("Types declared with the keyword Variant cannot be recursive. Recursive types are defined with the Inductive and CoInductive command."))
- | _ -> ()
- end;
- let names = List.map (fun e -> e.mind_entry_typename) mie.mind_entry_inds in
- let (_, kn), prim = declare_mind mie in
- let mind = Global.mind_of_delta_kn kn in
- List.iteri (fun i (indimpls, constrimpls) ->
- let ind = (mind,i) in
- let gr = IndRef ind in
- maybe_declare_manual_implicits false gr indimpls;
- Declare.declare_univ_binders gr pl;
- List.iteri
- (fun j impls ->
- maybe_declare_manual_implicits false
- (ConstructRef (ind, succ j)) impls)
- constrimpls)
- impls;
- let warn_prim = match mie.mind_entry_record with Some (Some _) -> not prim | _ -> false in
- Flags.if_verbose Feedback.msg_info (minductive_message warn_prim names);
- if mie.mind_entry_private == None
- then declare_default_schemes mind;
- mind
-
-type one_inductive_impls =
- Impargs.manual_explicitation list (* for inds *)*
- Impargs.manual_explicitation list list (* for constrs *)
-
-let do_mutual_inductive indl cum poly prv finite =
- let indl,coes,ntns = extract_mutual_inductive_declaration_components indl in
- (* Interpret the types *)
- let mie,pl,impls = interp_mutual_inductive indl ntns cum poly prv finite in
- (* Declare the mutual inductive block with its associated schemes *)
- ignore (declare_mutual_inductive_with_eliminations mie pl impls);
- (* Declare the possible notations of inductive types *)
- List.iter (Metasyntax.add_notation_interpretation (Global.env ())) ntns;
- (* Declare the coercions *)
- List.iter (fun qid -> Class.try_add_new_coercion (locate qid) ~local:false poly) coes;
- (* If positivity is assumed declares itself as unsafe. *)
- if Environ.deactivated_guard (Global.env ()) then Feedback.feedback Feedback.AddedAxiom else ()
-
-(* 3c| Fixpoints and co-fixpoints *)
-
-(* An (unoptimized) function that maps preorders to partial orders...
-
- Input: a list of associations (x,[y1;...;yn]), all yi distincts
- and different of x, meaning x<=y1, ..., x<=yn
-
- Output: a list of associations (x,Inr [y1;...;yn]), collecting all
- distincts yi greater than x, _or_, (x, Inl y) meaning that
- x is in the same class as y (in which case, x occurs
- nowhere else in the association map)
-
- partial_order : ('a * 'a list) list -> ('a * ('a,'a list) union) list
-*)
-
-let rec partial_order cmp = function
- | [] -> []
- | (x,xge)::rest ->
- let rec browse res xge' = function
- | [] ->
- let res = List.map (function
- | (z, Inr zge) when List.mem_f cmp x zge ->
- (z, Inr (List.union cmp zge xge'))
- | r -> r) res in
- (x,Inr xge')::res
- | y::xge ->
- let rec link y =
- try match List.assoc_f cmp y res with
- | Inl z -> link z
- | Inr yge ->
- if List.mem_f cmp x yge then
- let res = List.remove_assoc_f cmp y res in
- let res = List.map (function
- | (z, Inl t) ->
- if cmp t y then (z, Inl x) else (z, Inl t)
- | (z, Inr zge) ->
- if List.mem_f cmp y zge then
- (z, Inr (List.add_set cmp x (List.remove cmp y zge)))
- else
- (z, Inr zge)) res in
- browse ((y,Inl x)::res) xge' (List.union cmp xge (List.remove cmp x yge))
- else
- browse res (List.add_set cmp y (List.union cmp xge' yge)) xge
- with Not_found -> browse res (List.add_set cmp y xge') xge
- in link y
- in browse (partial_order cmp rest) [] xge
-
-let non_full_mutual_message x xge y yge isfix rest =
- let reason =
- if Id.List.mem x yge then
- Id.print y ++ str " depends on " ++ Id.print x ++ strbrk " but not conversely"
- else if Id.List.mem y xge then
- Id.print x ++ str " depends on " ++ Id.print y ++ strbrk " but not conversely"
- else
- Id.print y ++ str " and " ++ Id.print x ++ strbrk " are not mutually dependent" in
- let e = if List.is_empty rest then reason else strbrk "e.g., " ++ reason in
- let k = if isfix then "fixpoint" else "cofixpoint" in
- let w =
- if isfix
- then strbrk "Well-foundedness check may fail unexpectedly." ++ fnl()
- else mt () in
- strbrk "Not a fully mutually defined " ++ str k ++ fnl () ++
- str "(" ++ e ++ str ")." ++ fnl () ++ w
-
-let warn_non_full_mutual =
- CWarnings.create ~name:"non-full-mutual" ~category:"fixpoints"
- (fun (x,xge,y,yge,isfix,rest) ->
- non_full_mutual_message x xge y yge isfix rest)
-
-let check_mutuality env evd isfix fixl =
- let names = List.map fst fixl in
- let preorder =
- List.map (fun (id,def) ->
- (id, List.filter (fun id' -> not (Id.equal id id') && occur_var env evd id' (EConstr.of_constr def)) names))
- fixl in
- let po = partial_order Id.equal preorder in
- match List.filter (function (_,Inr _) -> true | _ -> false) po with
- | (x,Inr xge)::(y,Inr yge)::rest ->
- warn_non_full_mutual (x,xge,y,yge,isfix,rest)
- | _ -> ()
-
-type structured_fixpoint_expr = {
- fix_name : Id.t;
- fix_univs : universe_decl_expr option;
- fix_annot : Id.t Loc.located option;
- fix_binders : local_binder_expr list;
- fix_body : constr_expr option;
- fix_type : constr_expr
-}
-
-let interp_fix_context env evdref isfix fix =
- let before, after = if isfix then split_at_annot fix.fix_binders fix.fix_annot else [], fix.fix_binders in
- let impl_env, ((env', ctx), imps) = interp_context_evars env evdref before in
- let impl_env', ((env'', ctx'), imps') = interp_context_evars ~impl_env ~shift:(Context.Rel.nhyps ctx) env' evdref after in
- let annot = Option.map (fun _ -> List.length (assums_of_rel_context ctx)) fix.fix_annot in
- ((env'', ctx' @ ctx), (impl_env',imps @ imps'), annot)
-
-let interp_fix_ccl evdref impls (env,_) fix =
- let (c, impl) = interp_type_evars_impls ~impls env evdref fix.fix_type in
- (c, impl)
-
-let interp_fix_body env_rec evdref impls (_,ctx) fix ccl =
- let open EConstr in
- Option.map (fun body ->
- let env = push_rel_context ctx env_rec in
- let body = interp_casted_constr_evars env evdref ~impls body ccl in
- it_mkLambda_or_LetIn body ctx) fix.fix_body
-
-let build_fix_type (_,ctx) ccl = EConstr.it_mkProd_or_LetIn ccl ctx
-
-let prepare_recursive_declaration fixnames fixtypes fixdefs =
- let defs = List.map (subst_vars (List.rev fixnames)) fixdefs in
- let names = List.map (fun id -> Name id) fixnames in
- (Array.of_list names, Array.of_list fixtypes, Array.of_list defs)
-
-(* Jump over let-bindings. *)
-
-let compute_possible_guardness_evidences (ctx,_,recindex) =
- (* A recursive index is characterized by the number of lambdas to
- skip before finding the relevant inductive argument *)
- match recindex with
- | Some i -> [i]
- | None ->
- (* If recursive argument was not given by user, we try all args.
- An earlier approach was to look only for inductive arguments,
- but doing it properly involves delta-reduction, and it finally
- doesn't seem to worth the effort (except for huge mutual
- fixpoints ?) *)
- List.interval 0 (Context.Rel.nhyps ctx - 1)
-
-type recursive_preentry =
- Id.t list * constr option list * types list
-
-(* Wellfounded definition *)
-
-open Coqlib
-
-let contrib_name = "Program"
-let subtac_dir = [contrib_name]
-let fixsub_module = subtac_dir @ ["Wf"]
-let tactics_module = subtac_dir @ ["Tactics"]
-
-let init_reference dir s () = Coqlib.coq_reference "Command" dir s
-let init_constant dir s evdref =
- let (sigma, c) = Evarutil.new_global !evdref (Coqlib.coq_reference "Command" dir s)
- in evdref := sigma; c
-
-let make_ref l s = init_reference l s
-let fix_proto = init_constant tactics_module "fix_proto"
-let fix_sub_ref = make_ref fixsub_module "Fix_sub"
-let measure_on_R_ref = make_ref fixsub_module "MR"
-let well_founded = init_constant ["Init"; "Wf"] "well_founded"
-let mkSubset evdref name typ prop =
- let open EConstr in
- mkApp (Evarutil.e_new_global evdref (delayed_force build_sigma).typ,
- [| typ; mkLambda (name, typ, prop) |])
-let sigT = Lazy.from_fun build_sigma_type
-
-let make_qref s = Qualid (Loc.tag @@ qualid_of_string s)
-let lt_ref = make_qref "Init.Peano.lt"
-
-let rec telescope evdref l =
- let open EConstr in
- let open Vars in
- match l with
- | [] -> assert false
- | [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)) decl ->
- let t = RelDecl.get_type decl in
- let pred = mkLambda (RelDecl.get_name decl, t, ty) in
- let ty = Evarutil.e_new_global evdref (Lazy.force sigT).typ in
- let intro = Evarutil.e_new_global evdref (Lazy.force sigT).intro in
- let sigty = mkApp (ty, [|t; pred|]) in
- let intro = mkApp (intro, [|lift k t; lift k pred; mkRel k; constr|]) in
- (sigty, pred :: tys, (succ k, intro)))
- (t, [], (2, mkRel 1)) tl
- in
- let (last, subst) = List.fold_right2
- (fun pred decl (prev, subst) ->
- let t = RelDecl.get_type decl in
- let p1 = Evarutil.e_new_global evdref (Lazy.force sigT).proj1 in
- let p2 = Evarutil.e_new_global evdref (Lazy.force sigT).proj2 in
- let proj1 = applist (p1, [t; pred; prev]) in
- let proj2 = applist (p2, [t; pred; prev]) in
- (lift 1 proj2, LocalDef (get_name decl, proj1, t) :: subst))
- (List.rev tys) tl (mkRel 1, [])
- in ty, (LocalDef (n, last, t) :: subst), constr
-
- | LocalDef (n, b, t) :: tl -> let ty, subst, term = telescope evdref tl in
- ty, (LocalDef (n, b, t) :: subst), lift 1 term
-
-let nf_evar_context sigma ctx =
- List.map (map_constr (fun c -> Evarutil.nf_evar sigma c)) ctx
-
-let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
- let open EConstr in
- let open Vars in
- let lift_rel_context n l = Termops.map_rel_context_with_binders (liftn n) l in
- Coqlib.check_required_library ["Coq";"Program";"Wf"];
- let env = Global.env() in
- let evd, decl = Univdecls.interp_univ_decl_opt env pl in
- let evdref = ref evd 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
- let top_arity = interp_type_evars top_env evdref arityc in
- let full_arity = it_mkProd_or_LetIn top_arity binders_rel in
- let argtyp, letbinders, make = telescope evdref binders_rel in
- let argname = Id.of_string "recarg" 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
- let relty = Typing.unsafe_type_of env !evdref rel in
- let relargty =
- let error () =
- user_err ?loc:(constr_loc r)
- ~hdr:"Command.build_wellfounded"
- (Printer.pr_econstr_env env !evdref rel ++ str " is not an homogeneous binary relation.")
- in
- try
- let ctx, ar = Reductionops.splay_prod_n env !evdref 2 relty in
- match ctx, EConstr.kind !evdref ar with
- | [LocalAssum (_,t); LocalAssum (_,u)], Sort s
- when Sorts.is_prop (ESorts.kind !evdref s) && Reductionops.is_conv env !evdref t u -> t
- | _, _ -> error ()
- with e when CErrors.noncritical e -> error ()
- in
- let relargty = EConstr.Unsafe.to_constr relargty in
- let measure = interp_casted_constr_evars binders_env evdref measure relargty in
- let wf_rel, wf_rel_fun, measure_fn =
- let measure_body, measure =
- it_mkLambda_or_LetIn measure letbinders,
- it_mkLambda_or_LetIn measure binders
- in
- let comb = Evarutil.e_new_global evdref (delayed_force measure_on_R_ref) in
- let relargty = EConstr.of_constr relargty in
- let wf_rel = mkApp (comb, [| argtyp; relargty; rel; measure |]) in
- let wf_rel_fun x y =
- mkApp (rel, [| subst1 x measure_body;
- subst1 y measure_body |])
- in wf_rel, wf_rel_fun, measure
- in
- let wf_proof = mkApp (well_founded evdref, [| argtyp ; wf_rel |]) in
- let argid' = Id.of_string (Id.to_string argname ^ "'") in
- let wfarg len = LocalAssum (Name argid',
- mkSubset evdref (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
- let proj = Evarutil.e_new_global evdref (delayed_force build_sigma).Coqlib.proj1 in
- let wfargpred = mkLambda (Name argid', argtyp, wf_rel_fun (mkRel 1) (mkRel 3)) in
- let projection = (* in wfarg :: arg :: before *)
- mkApp (proj, [| argtyp ; wfargpred ; mkRel 1 |])
- in
- let top_arity_let = it_mkLambda_or_LetIn top_arity letbinders in
- let intern_arity = substl [projection] top_arity_let in
- (* 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 = 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 = Evarutil.e_new_global evdref (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 = 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
- LocalDef (Name recname, body, ty)
- in
- let fun_bl = intern_fun_binder :: [arg] in
- let lift_lets = lift_rel_context 1 letbinders in
- let intern_body =
- let ctx = LocalAssum (Name recname, get_type curry_fun) :: binders_rel in
- let (r, l, impls, scopes) =
- Constrintern.compute_internalization_data env
- Constrintern.Recursive (EConstr.Unsafe.to_constr full_arity) impls
- in
- let newimpls = Id.Map.singleton recname
- (r, l, impls @ [(Some (Id.of_string "recproof", Impargs.Manual, (true, false)))],
- scopes @ [None]) in
- interp_casted_constr_evars (push_rel_context ctx env) evdref
- ~impls:newimpls body (EConstr.Unsafe.to_constr (lift 1 top_arity))
- in
- let intern_body_lam = it_mkLambda_or_LetIn intern_body (curry_fun :: lift_lets @ fun_bl) in
- let prop = mkLambda (Name argname, argtyp, top_arity_let) in
- let def =
- mkApp (Evarutil.e_new_global evdref (delayed_force fix_sub_ref),
- [| argtyp ; wf_rel ;
- Evarutil.e_new_evar env evdref
- ~src:(Loc.tag @@ Evar_kinds.QuestionMark (Evar_kinds.Define false,Anonymous)) wf_proof;
- prop |])
- 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
- let binders = nf_evar_context !evdref binders in
- let top_arity = Evarutil.nf_evar !evdref top_arity in
- let hook, recname, typ =
- if List.length binders_rel > 1 then
- let name = add_suffix recname "_func" in
- let hook l gr _ =
- let body = it_mkLambda_or_LetIn (mkApp (Evarutil.e_new_global evdref gr, [|make|])) binders_rel in
- let ty = it_mkProd_or_LetIn top_arity binders_rel in
- let ty = EConstr.Unsafe.to_constr ty in
- let univs = Evd.check_univ_decl ~poly !evdref decl in
- (*FIXME poly? *)
- let ce = definition_entry ~types:ty ~univs (EConstr.to_constr !evdref body) in
- (** FIXME: include locality *)
- let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
- let gr = ConstRef c in
- let () = Universes.register_universe_binders gr (Evd.universe_binders !evdref) in
- if Impargs.is_implicit_args () || not (List.is_empty impls) then
- Impargs.declare_manual_implicits false gr [impls]
- in
- let typ = it_mkProd_or_LetIn top_arity binders in
- hook, name, typ
- else
- let typ = it_mkProd_or_LetIn top_arity binders_rel in
- let hook l gr _ =
- if Impargs.is_implicit_args () || not (List.is_empty impls) then
- Impargs.declare_manual_implicits false gr [impls]
- in hook, recname, typ
- in
- let hook = Lemmas.mk_hook hook in
- let fullcoqc = EConstr.to_constr !evdref def in
- let fullctyp = EConstr.to_constr !evdref typ in
- Obligations.check_evars env !evdref;
- let evars, _, evars_def, evars_typ =
- 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 ~univdecl:decl
- evars_typ ctx evars ~hook)
-
-let interp_recursive isfix fixl notations =
- let open Context.Named.Declaration in
- let open EConstr in
- let env = Global.env() in
- let fixnames = List.map (fun fix -> fix.fix_name) fixl in
-
- (* Interp arities allowing for unresolved types *)
- let all_universes =
- List.fold_right (fun sfe acc ->
- match sfe.fix_univs , acc with
- | None , acc -> acc
- | x , None -> x
- | Some ls , Some us ->
- let lsu = ls.univdecl_instance and usu = us.univdecl_instance in
- if not (CList.for_all2eq (fun x y -> Id.equal (snd x) (snd y)) lsu usu) then
- user_err Pp.(str "(co)-recursive definitions should all have the same universe binders");
- Some us) fixl None in
- let evd, decl = Univdecls.interp_univ_decl_opt env all_universes in
- let evdref = ref evd in
- let fixctxs, fiximppairs, fixannots =
- List.split3 (List.map (interp_fix_context env evdref isfix) fixl) in
- let fixctximpenvs, fixctximps = List.split fiximppairs in
- let fixccls,fixcclimps = List.split (List.map3 (interp_fix_ccl evdref) fixctximpenvs fixctxs fixl) in
- let fixtypes = List.map2 build_fix_type fixctxs fixccls in
- let fixtypes = List.map (fun c -> nf_evar !evdref c) fixtypes in
- let fiximps = List.map3
- (fun ctximps cclimps (_,ctx) -> ctximps@(Impargs.lift_implicits (Context.Rel.nhyps ctx) cclimps))
- fixctximps fixcclimps fixctxs in
- let rec_sign =
- List.fold_left2
- (fun env' id t ->
- if Flags.is_program_mode () then
- let sort = Evarutil.evd_comb1 (Typing.type_of ~refresh:true env) evdref t in
- let fixprot =
- try
- let app = mkApp (fix_proto evdref, [|sort; t|]) in
- Typing.e_solve_evars env evdref app
- with e when CErrors.noncritical e -> t
- in
- LocalAssum (id,fixprot) :: env'
- else LocalAssum (id,t) :: env')
- [] fixnames fixtypes
- in
- let env_rec = push_named_context rec_sign env in
-
- (* Get interpretation metadatas *)
- let fixtypes = List.map EConstr.Unsafe.to_constr fixtypes in
- let fixccls = List.map EConstr.Unsafe.to_constr fixccls in
- let impls = compute_internalization_env env Recursive fixnames fixtypes fiximps in
-
- (* Interp bodies with rollback because temp use of notations/implicit *)
- let fixdefs =
- Metasyntax.with_syntax_protection (fun () ->
- List.iter (Metasyntax.set_notation_for_interpretation env_rec impls) notations;
- List.map4
- (fun fixctximpenv -> interp_fix_body env_rec evdref (Id.Map.fold Id.Map.add fixctximpenv impls))
- fixctximpenvs fixctxs fixl fixccls)
- () in
-
- (* Instantiate evars and check all are resolved *)
- let evd = solve_unif_constraints_with_heuristics env_rec !evdref in
- let evd, nf = nf_evars_and_universes evd in
- let fixdefs = List.map (fun c -> Option.map EConstr.Unsafe.to_constr c) fixdefs in
- let fixdefs = List.map (Option.map nf) fixdefs in
- let fixtypes = List.map nf fixtypes in
- let fixctxs = List.map (fun (_,ctx) -> ctx) fixctxs in
-
- (* Build the fix declaration block *)
- (env,rec_sign,decl,evd), (fixnames,fixdefs,fixtypes), List.combine3 fixctxs fiximps fixannots
-
-let check_recursive isfix env evd (fixnames,fixdefs,_) =
- check_evars_are_solved env evd Evd.empty;
- if List.for_all Option.has_some fixdefs then begin
- let fixdefs = List.map Option.get fixdefs in
- check_mutuality env evd isfix (List.combine fixnames fixdefs)
- end
-
-let interp_fixpoint l ntns =
- let (env,_,pl,evd),fix,info = interp_recursive true l ntns in
- check_recursive true env evd fix;
- (fix,pl,Evd.evar_universe_context evd,info)
-
-let interp_cofixpoint l ntns =
- let (env,_,pl,evd),fix,info = interp_recursive false l ntns in
- check_recursive false env evd fix;
- (fix,pl,Evd.evar_universe_context evd,info)
-
-let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) indexes ntns =
- if List.exists Option.is_empty fixdefs then
- (* Some bodies to define by proof *)
- let thms =
- List.map3 (fun id t (ctx,imps,_) -> (id,(t,(List.map RelDecl.get_name ctx,imps))))
- fixnames fixtypes fiximps in
- let init_tac =
- Some (List.map (Option.cata (EConstr.of_constr %> Tactics.exact_no_check) Tacticals.New.tclIDTAC)
- fixdefs) in
- let evd = Evd.from_ctx ctx in
- Lemmas.start_proof_with_initialization (Global,poly,DefinitionBody Fixpoint)
- evd pl (Some(false,indexes,init_tac)) thms None (Lemmas.mk_hook (fun _ _ -> ()))
- else begin
- (* We shortcut the proof process *)
- let fixdefs = List.map Option.get fixdefs in
- let fixdecls = prepare_recursive_declaration fixnames fixtypes fixdefs in
- let env = Global.env() in
- let indexes = search_guard env indexes fixdecls in
- let fiximps = List.map (fun (n,r,p) -> r) fiximps in
- let vars = Univops.universes_of_constr env (mkFix ((indexes,0),fixdecls)) in
- let fixdecls =
- List.map_i (fun i _ -> mkFix ((indexes,i),fixdecls)) 0 fixnames in
- let evd = Evd.from_ctx ctx in
- let evd = Evd.restrict_universe_context evd vars in
- let ctx = Evd.check_univ_decl ~poly evd pl in
- let pl = Evd.universe_binders evd in
- let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
- ignore (List.map4 (DeclareDef.declare_fix (local, poly, Fixpoint) pl ctx)
- fixnames fixdecls fixtypes fiximps);
- (* Declare the recursive definitions *)
- fixpoint_message (Some indexes) fixnames;
- end;
- (* Declare notations *)
- List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns
-
-let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) ntns =
- if List.exists Option.is_empty fixdefs then
- (* Some bodies to define by proof *)
- let thms =
- List.map3 (fun id t (ctx,imps,_) -> (id,(t,(List.map RelDecl.get_name ctx,imps))))
- fixnames fixtypes fiximps in
- let init_tac =
- Some (List.map (Option.cata (EConstr.of_constr %> Tactics.exact_no_check) Tacticals.New.tclIDTAC)
- fixdefs) in
- let evd = Evd.from_ctx ctx in
- Lemmas.start_proof_with_initialization (Global,poly, DefinitionBody CoFixpoint)
- evd pl (Some(true,[],init_tac)) thms None (Lemmas.mk_hook (fun _ _ -> ()))
- else begin
- (* We shortcut the proof process *)
- let fixdefs = List.map Option.get fixdefs in
- let fixdecls = prepare_recursive_declaration fixnames fixtypes fixdefs in
- let fixdecls = List.map_i (fun i _ -> mkCoFix (i,fixdecls)) 0 fixnames in
- let env = Global.env () in
- let vars = Univops.universes_of_constr env (List.hd fixdecls) in
- let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
- let fiximps = List.map (fun (len,imps,idx) -> imps) fiximps in
- let evd = Evd.from_ctx ctx in
- let evd = Evd.restrict_universe_context evd vars in
- let ctx = Evd.check_univ_decl ~poly evd pl in
- let pl = Evd.universe_binders evd in
- ignore (List.map4 (DeclareDef.declare_fix (local, poly, CoFixpoint) pl ctx)
- fixnames fixdecls fixtypes fiximps);
- (* Declare the recursive definitions *)
- cofixpoint_message fixnames
- end;
- (* Declare notations *)
- List.iter (Metasyntax.add_notation_interpretation (Global.env())) ntns
-
-let extract_decreasing_argument limit = function
- | (na,CStructRec) -> na
- | (na,_) when not limit -> na
- | _ -> user_err Pp.(str
- "Only structural decreasing is supported for a non-Program Fixpoint")
-
-let extract_fixpoint_components limit l =
- let fixl, ntnl = List.split l in
- let fixl = List.map (fun (((_,id),pl),ann,bl,typ,def) ->
- let ann = extract_decreasing_argument limit ann in
- {fix_name = id; fix_annot = ann; fix_univs = pl;
- fix_binders = bl; fix_body = def; fix_type = typ}) fixl in
- fixl, List.flatten ntnl
-
-let extract_cofixpoint_components l =
- let fixl, ntnl = List.split l in
- List.map (fun (((_,id),pl),bl,typ,def) ->
- {fix_name = id; fix_annot = None; fix_univs = pl;
- fix_binders = bl; fix_body = def; fix_type = typ}) fixl,
- List.flatten ntnl
-
-let out_def = function
- | Some def -> def
- | None -> user_err Pp.(str "Program Fixpoint needs defined bodies.")
-
-let collect_evars_of_term evd c ty =
- let evars = Evar.Set.union (Evd.evars_of_term c) (Evd.evars_of_term ty) in
- Evar.Set.fold (fun ev acc -> Evd.add acc ev (Evd.find_undefined evd ev))
- evars (Evd.from_ctx (Evd.evar_universe_context evd))
-
-let do_program_recursive local poly fixkind fixl ntns =
- let isfix = fixkind != Obligations.IsCoFixpoint in
- let (env, rec_sign, pl, evd), fix, info =
- interp_recursive isfix fixl ntns
- in
- (* Program-specific code *)
- (* Get the interesting evars, those that were not instanciated *)
- let evd = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals ~fail:true env evd in
- (* Solve remaining evars *)
- let evd = nf_evar_map_undefined evd in
- let collect_evars id def typ imps =
- (* Generalize by the recursive prototypes *)
- let def =
- EConstr.to_constr evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
- and typ =
- EConstr.to_constr evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
- in
- let evm = collect_evars_of_term evd def typ in
- let evars, _, def, typ =
- Obligations.eterm_obligations env id evm
- (List.length rec_sign) def typ
- in (id, def, typ, imps, evars)
- in
- let (fixnames,fixdefs,fixtypes) = fix in
- let fiximps = List.map pi2 info in
- let fixdefs = List.map out_def fixdefs in
- let defs = List.map4 collect_evars fixnames fixdefs fixtypes fiximps in
- let () = if isfix then begin
- let possible_indexes = List.map compute_possible_guardness_evidences info in
- let fixdecls = Array.of_list (List.map (fun x -> Name x) fixnames),
- Array.of_list fixtypes,
- Array.of_list (List.map (subst_vars (List.rev fixnames)) fixdefs)
- in
- let indexes =
- Pretyping.search_guard (Global.env ()) possible_indexes fixdecls in
- List.iteri (fun i _ ->
- Inductive.check_fix env
- ((indexes,i),fixdecls))
- fixl
- end in
- let ctx = Evd.evar_universe_context evd in
- let kind = match fixkind with
- | Obligations.IsFixpoint _ -> (local, poly, Fixpoint)
- | Obligations.IsCoFixpoint -> (local, poly, CoFixpoint)
- in
- Obligations.add_mutual_definitions defs ~kind ~univdecl: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),pl),_,bl,typ,def),ntn)] ->
- let recarg =
- match n with
- | Some n -> mkIdentC (snd n)
- | None ->
- user_err ~hdr:"do_program_fixpoint"
- (str "Recursive argument required for well-founded fixpoints")
- in build_wellfounded (id, pl, n, bl, typ, out_def def) poly r recarg ntn
-
- | [(n, CMeasureRec (m, r))], [((((_,id),pl),_,bl,typ,def),ntn)] ->
- build_wellfounded (id, pl, n, bl, typ, out_def def) poly
- (Option.default (CAst.make @@ CRef (lt_ref,None)) r) m ntn
-
- | _, _ when List.for_all (fun (n, ro) -> ro == CStructRec) g ->
- let fixl,ntns = extract_fixpoint_components true l in
- let fixkind = Obligations.IsFixpoint g in
- do_program_recursive local poly fixkind fixl ntns
-
- | _, _ ->
- user_err ~hdr:"do_program_fixpoint"
- (str "Well-founded fixpoints not allowed in mutually recursive blocks")
-
-let check_safe () =
- let open Declarations in
- let flags = Environ.typing_flags (Global.env ()) in
- flags.check_universes && flags.check_guarded
-
-let do_fixpoint local poly l =
- if Flags.is_program_mode () then do_program_fixpoint local poly l
- else
- let fixl, ntns = extract_fixpoint_components true l in
- let (_, _, _, info as fix) = interp_fixpoint fixl ntns in
- let possible_indexes =
- List.map compute_possible_guardness_evidences info in
- declare_fixpoint local poly fix possible_indexes ntns;
- if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
-
-let do_cofixpoint local poly l =
- let fixl,ntns = extract_cofixpoint_components l in
- if Flags.is_program_mode () then
- do_program_recursive local poly Obligations.IsCoFixpoint fixl ntns
- else
- let cofix = interp_cofixpoint fixl ntns in
- declare_cofixpoint local poly cofix ntns;
- if not (check_safe ()) then Feedback.feedback Feedback.AddedAxiom else ()
diff --git a/vernac/command.mli b/vernac/command.mli
deleted file mode 100644
index c7342e6da..000000000
--- a/vernac/command.mli
+++ /dev/null
@@ -1,163 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Names
-open Constr
-open Entries
-open Libnames
-open Globnames
-open Vernacexpr
-open Constrexpr
-open Decl_kinds
-open Redexpr
-
-(** This file is about the interpretation of raw commands into typed
- ones and top-level declaration of the main Gallina objects *)
-
-val do_universe : polymorphic -> Id.t Loc.located list -> unit
-val do_constraint : polymorphic ->
- (Misctypes.glob_level * Univ.constraint_type * Misctypes.glob_level) list -> unit
-
-(** {6 Definitions/Let} *)
-
-val interp_definition :
- Vernacexpr.universe_decl_expr option -> local_binder_expr list -> polymorphic -> red_expr option -> constr_expr ->
- constr_expr option -> Safe_typing.private_constants definition_entry * Evd.evar_map *
- Univdecls.universe_decl * Impargs.manual_implicits
-
-val do_definition : Id.t -> definition_kind -> Vernacexpr.universe_decl_expr option ->
- local_binder_expr list -> red_expr option -> constr_expr ->
- constr_expr option -> unit Lemmas.declaration_hook -> unit
-
-(** {6 Parameters/Assumptions} *)
-
-(* val interp_assumption : env -> evar_map ref -> *)
-(* local_binder_expr list -> constr_expr -> *)
-(* types Univ.in_universe_context_set * Impargs.manual_implicits *)
-
-(** returns [false] if the assumption is neither local to a section,
- nor in a module type and meant to be instantiated. *)
-val declare_assumption : coercion_flag -> assumption_kind ->
- types in_constant_universes_entry ->
- Universes.universe_binders -> Impargs.manual_implicits ->
- bool (** implicit *) -> Vernacexpr.inline -> variable Loc.located ->
- global_reference * Univ.Instance.t * bool
-
-val do_assumptions : locality * polymorphic * assumption_object_kind ->
- Vernacexpr.inline -> (Vernacexpr.ident_decl list * constr_expr) with_coercion list -> bool
-
-(* val declare_assumptions : variable Loc.located list -> *)
-(* coercion_flag -> assumption_kind -> types Univ.in_universe_context_set -> *)
-(* Impargs.manual_implicits -> bool -> Vernacexpr.inline -> bool *)
-
-(** {6 Inductive and coinductive types} *)
-
-(** Extracting the semantical components out of the raw syntax of mutual
- inductive declarations *)
-
-type structured_one_inductive_expr = {
- ind_name : Id.t;
- ind_univs : Vernacexpr.universe_decl_expr option;
- ind_arity : constr_expr;
- ind_lc : (Id.t * constr_expr) list
-}
-
-type structured_inductive_expr =
- local_binder_expr list * structured_one_inductive_expr list
-
-val extract_mutual_inductive_declaration_components :
- (one_inductive_expr * decl_notation list) list ->
- structured_inductive_expr * (*coercions:*) qualid list * decl_notation list
-
-(** Typing mutual inductive definitions *)
-
-type one_inductive_impls =
- Impargs.manual_implicits (** for inds *)*
- Impargs.manual_implicits list (** for constrs *)
-
-val interp_mutual_inductive :
- structured_inductive_expr -> decl_notation list -> cumulative_inductive_flag ->
- polymorphic -> private_flag -> Declarations.recursivity_kind ->
- mutual_inductive_entry * Universes.universe_binders * one_inductive_impls list
-
-(** Registering a mutual inductive definition together with its
- associated schemes *)
-
-val declare_mutual_inductive_with_eliminations :
- mutual_inductive_entry -> Universes.universe_binders -> one_inductive_impls list ->
- MutInd.t
-
-(** Entry points for the vernacular commands Inductive and CoInductive *)
-
-val do_mutual_inductive :
- (one_inductive_expr * decl_notation list) list -> cumulative_inductive_flag ->
- polymorphic -> private_flag -> Declarations.recursivity_kind -> unit
-
-(** {6 Fixpoints and cofixpoints} *)
-
-type structured_fixpoint_expr = {
- fix_name : Id.t;
- fix_univs : Vernacexpr.universe_decl_expr option;
- fix_annot : Id.t Loc.located option;
- fix_binders : local_binder_expr list;
- fix_body : constr_expr option;
- fix_type : constr_expr
-}
-
-(** Extracting the semantical components out of the raw syntax of
- (co)fixpoints declarations *)
-
-val extract_fixpoint_components : bool ->
- (fixpoint_expr * decl_notation list) list ->
- structured_fixpoint_expr list * decl_notation list
-
-val extract_cofixpoint_components :
- (cofixpoint_expr * decl_notation list) list ->
- structured_fixpoint_expr list * decl_notation list
-
-(** Typing global fixpoints and cofixpoint_expr *)
-
-type recursive_preentry =
- Id.t list * constr option list * types list
-
-val interp_fixpoint :
- structured_fixpoint_expr list -> decl_notation list ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (EConstr.rel_context * Impargs.manual_implicits * int option) list
-
-val interp_cofixpoint :
- structured_fixpoint_expr list -> decl_notation list ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (EConstr.rel_context * Impargs.manual_implicits * int option) list
-
-(** Registering fixpoints and cofixpoints in the environment *)
-
-val declare_fixpoint :
- locality -> polymorphic ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
- Proof_global.lemma_possible_guards -> decl_notation list -> unit
-
-val declare_cofixpoint : locality -> polymorphic ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
- decl_notation list -> unit
-
-(** Entry points for the vernacular commands Fixpoint and CoFixpoint *)
-
-val do_fixpoint :
- (* When [false], assume guarded. *)
- locality -> polymorphic -> (fixpoint_expr * decl_notation list) list -> unit
-
-val do_cofixpoint :
- (* When [false], assume guarded. *)
- locality -> polymorphic -> (cofixpoint_expr * decl_notation list) list -> unit
-
-(** Utils *)
-
-val check_mutuality : Environ.env -> Evd.evar_map -> bool -> (Id.t * types) list -> unit
diff --git a/vernac/explainErr.ml b/vernac/explainErr.ml
index 3a8e8fb43..d328ad0cf 100644
--- a/vernac/explainErr.ml
+++ b/vernac/explainErr.ml
@@ -75,8 +75,7 @@ let process_vernac_interp_error exn = match fst exn with
wrap_vernac_error exn (Himsg.explain_pattern_matching_error env sigma e)
| Tacred.ReductionTacticError e ->
wrap_vernac_error exn (Himsg.explain_reduction_tactic_error e)
- | Logic.RefinerError e ->
- let sigma, env = Pfedit.get_current_context () in
+ | Logic.RefinerError (env, sigma, e) ->
wrap_vernac_error exn (Himsg.explain_refiner_error env sigma e)
| Nametab.GlobalizationError q ->
wrap_vernac_error exn
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 200c2260e..27a680b9b 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -13,12 +13,10 @@ open CErrors
open Util
open Pp
open Names
-open Term
open Constr
open Declarations
open Declareops
open Entries
-open Environ
open Nameops
open Globnames
open Decls
@@ -88,28 +86,28 @@ let adjust_guardness_conditions const = function
(mkFix ((indexes,0),fixdecls), ctx), eff
| _ -> (body, ctx), eff) }
-let find_mutually_recursive_statements thms =
+let find_mutually_recursive_statements sigma thms =
let n = List.length thms in
let inds = List.map (fun (id,(t,impls)) ->
- let (hyps,ccl) = decompose_prod_assum t in
+ let (hyps,ccl) = EConstr.decompose_prod_assum sigma t in
let x = (id,(t,impls)) in
- let whnf_hyp_hds = map_rel_context_in_env
- (fun env c -> EConstr.Unsafe.to_constr (fst (whd_all_stack env Evd.empty (EConstr.of_constr c))))
+ let whnf_hyp_hds = EConstr.map_rel_context_in_env
+ (fun env c -> fst (Reductionops.whd_all_stack env sigma c))
(Global.env()) hyps in
let ind_hyps =
List.flatten (List.map_i (fun i decl ->
let t = RelDecl.get_type decl in
- match Constr.kind t with
+ match EConstr.kind sigma t with
| Ind ((kn,_ as ind),u) when
let mind = Global.lookup_mind kn in
mind.mind_finite <> Decl_kinds.CoFinite ->
[ind,x,i]
| _ ->
- []) 0 (List.rev (List.filter RelDecl.is_local_assum whnf_hyp_hds))) in
+ []) 0 (List.rev (List.filter Context.Rel.Declaration.is_local_assum whnf_hyp_hds))) in
let ind_ccl =
- let cclenv = push_rel_context hyps (Global.env()) in
- let whnf_ccl,_ = whd_all_stack cclenv Evd.empty (EConstr.of_constr ccl) in
- match Constr.kind (EConstr.Unsafe.to_constr whnf_ccl) with
+ let cclenv = EConstr.push_rel_context hyps (Global.env()) in
+ let whnf_ccl,_ = whd_all_stack cclenv Evd.empty ccl in
+ match EConstr.kind sigma whnf_ccl with
| Ind ((kn,_ as ind),u) when
let mind = Global.lookup_mind kn in
Int.equal mind.mind_ntypes n && mind.mind_finite == Decl_kinds.CoFinite ->
@@ -163,14 +161,14 @@ let find_mutually_recursive_statements thms =
in
(finite,guard,None), ordered_inds
-let look_for_possibly_mutual_statements = function
+let look_for_possibly_mutual_statements sigma = function
| [id,(t,impls)] ->
(* One non recursively proved theorem *)
None,[id,(t,impls)],None
| _::_ as thms ->
(* More than one statement and/or an explicit decreasing mark: *)
(* we look for a common inductive hyp or a common coinductive conclusion *)
- let recguard,ordered_inds = find_mutually_recursive_statements thms in
+ let recguard,ordered_inds = find_mutually_recursive_statements sigma thms in
let thms = List.map pi2 ordered_inds in
Some recguard,thms, Some (List.map (fun (_,_,i) -> succ i) ordered_inds)
| [] -> anomaly (Pp.str "Empty list of theorems.")
@@ -377,7 +375,7 @@ let start_proof_univs id ?pl kind sigma ?terminator ?sign c ?init_tac ?(compute_
let rec_tac_initializer finite guard thms snl =
if finite then
- match List.map (fun (id,(t,_)) -> (id,EConstr.of_constr t)) thms with
+ match List.map (fun (id,(t,_)) -> (id,t)) thms with
| (id,_)::l -> Tactics.mutual_cofix id l 0
| _ -> assert false
else
@@ -385,11 +383,11 @@ let rec_tac_initializer finite guard thms snl =
let nl = match snl with
| None -> List.map succ (List.map List.last guard)
| Some nl -> nl
- in match List.map2 (fun (id,(t,_)) n -> (id,n, EConstr.of_constr t)) thms nl with
+ in match List.map2 (fun (id,(t,_)) n -> (id,n, t)) thms nl with
| (id,n,_)::l -> Tactics.mutual_fix id n l 0
| _ -> assert false
-let start_proof_with_initialization kind ctx decl recguard thms snl hook =
+let start_proof_with_initialization kind sigma decl recguard thms snl hook =
let intro_tac (_, (_, (ids, _))) =
Tacticals.New.tclMAP (function
| Name id -> Tactics.intro_mustbe_force id
@@ -424,16 +422,15 @@ let start_proof_with_initialization kind ctx decl recguard thms snl hook =
if List.is_empty other_thms then [] else
(* there are several theorems defined mutually *)
let body,opaq = retrieve_first_recthm ctx ref in
- let subst = Evd.evar_universe_context_subst ctx in
- let norm c = Universes.subst_opt_univs_constr subst c in
- let body = Option.map norm body in
+ let norm c = EConstr.to_constr (Evd.from_ctx ctx) c in
+ let body = Option.map EConstr.of_constr body in
let uctx = UState.check_univ_decl ~poly:(pi2 kind) ctx decl in
List.map_i (save_remaining_recthms kind norm uctx body opaq) 1 other_thms in
let thms_data = (strength,ref,imps)::other_thms_data in
List.iter (fun (strength,ref,imps) ->
maybe_declare_manual_implicits false ref imps;
call_hook (fun exn -> exn) hook strength ref) thms_data in
- start_proof_univs id ~pl:decl kind ctx (EConstr.of_constr t) ?init_tac (fun ctx -> mk_hook (hook ctx)) ~compute_guard:guard
+ start_proof_univs id ~pl:decl kind sigma t ?init_tac (fun ctx -> mk_hook (hook ctx)) ~compute_guard:guard
let start_proof_com ?inference_hook kind thms hook =
let env0 = Global.env () in
@@ -442,22 +439,24 @@ let start_proof_com ?inference_hook kind thms hook =
match decl with
| None -> Evd.from_env env0, Univdecls.default_univ_decl
| Some decl ->
- Univdecls.interp_univ_decl_opt env0 (snd decl) in
- let evdref = ref evd in
- let thms = List.map (fun (sopt,(bl,t)) ->
- let impls, ((env, ctx), imps) = interp_context_evars env0 evdref bl in
- let t', imps' = interp_type_evars_impls ~impls env evdref t in
+ Univdecls.interp_univ_decl_opt env0 (snd decl) in
+ let evd, thms = List.fold_left_map (fun evd (sopt,(bl,t)) ->
+ let evd, (impls, ((env, ctx), imps)) = interp_context_evars env0 evd bl in
+ let evd, (t', imps') = interp_type_evars_impls ~impls env evd t in
let flags = all_and_fail_flags in
let flags = { flags with use_hook = inference_hook } in
- evdref := solve_remaining_evars flags env !evdref Evd.empty;
+ let evd = solve_remaining_evars flags env evd Evd.empty in
let ids = List.map RelDecl.get_name ctx in
- (compute_proof_name (pi1 kind) sopt,
- (EConstr.Unsafe.to_constr (nf_evar !evdref (EConstr.it_mkProd_or_LetIn t' ctx)),
- (ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
- thms in
- let recguard,thms,snl = look_for_possibly_mutual_statements thms in
- let evd, nf = Evarutil.nf_evars_and_universes !evdref in
- let thms = List.map (fun (n, (t, info)) -> (n, (nf t, info))) thms in
+ (* XXX: The nf_evar is critical !! *)
+ evd, (compute_proof_name (pi1 kind) sopt,
+ (Evarutil.nf_evar evd (EConstr.it_mkProd_or_LetIn t' ctx),
+ (ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
+ evd thms in
+ let recguard,thms,snl = look_for_possibly_mutual_statements evd thms in
+ let evd, _nf = Evarutil.nf_evars_and_universes evd in
+ (* XXX: This nf_evar is critical too!! We are normalizing twice if
+ you look at the previous lines... *)
+ let thms = List.map (fun (n, (t, info)) -> (n, (nf_evar evd t, info))) thms in
let () =
let open Misctypes in
if not (decl.univdecl_extensible_instance && decl.univdecl_extensible_constraints) then
@@ -470,7 +469,6 @@ let start_proof_com ?inference_hook kind thms hook =
in
start_proof_with_initialization kind evd decl recguard thms snl hook
-
(* Saving a proof *)
let keep_admitted_vars = ref true
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index a4854b4a6..ca92e856b 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Names
-open Constr
open Decl_kinds
type 'a declaration_hook
@@ -37,11 +36,11 @@ val start_proof_com :
goal_kind -> Vernacexpr.proof_expr list ->
unit declaration_hook -> unit
-val start_proof_with_initialization :
+val start_proof_with_initialization :
goal_kind -> Evd.evar_map -> Univdecls.universe_decl ->
(bool * Proof_global.lemma_possible_guards * unit Proofview.tactic list option) option ->
(Id.t (* name of thm *) *
- (types (* type of thm *) * (Name.t list (* names to pre-introduce *) * Impargs.manual_explicitation list))) list
+ (EConstr.types (* type of thm *) * (Name.t list (* names to pre-introduce *) * Impargs.manual_explicitation list))) list
-> int list option -> unit declaration_hook -> unit
val universe_proof_terminator :
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index d3de10235..00554e3ba 100644
--- a/vernac/mltop.ml
+++ b/vernac/mltop.ml
@@ -378,7 +378,7 @@ let unfreeze_ml_modules x =
(fun (name,path) -> trigger_ml_object false false false ?path name) x
let _ =
- Summary.declare_summary Summary.ml_modules
+ Summary.declare_ml_modules_summary
{ Summary.freeze_function = (fun _ -> get_loaded_modules ());
Summary.unfreeze_function = unfreeze_ml_modules;
Summary.init_function = reset_loaded_modules }
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index 4f011e6ad..58e4b00fc 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -429,8 +429,8 @@ 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 []
-let from_prg : program_info ProgMap.t ref =
- Summary.ref ProgMap.empty ~name:"program-tcc-table"
+let from_prg, program_tcc_summary_tag =
+ Summary.ref_tag ProgMap.empty ~name:"program-tcc-table"
let close sec =
if not (ProgMap.is_empty !from_prg) then
@@ -1185,7 +1185,6 @@ let init_program () =
Coqlib.check_required_library ["Coq";"Init";"Specif"];
Coqlib.check_required_library ["Coq";"Program";"Tactics"]
-
let set_program_mode c =
if c then
if !Flags.program_mode then ()
diff --git a/vernac/obligations.mli b/vernac/obligations.mli
index 0602e52e9..bdc97d48c 100644
--- a/vernac/obligations.mli
+++ b/vernac/obligations.mli
@@ -104,3 +104,6 @@ exception NoObligations of Names.Id.t option
val explain_no_obligations : Names.Id.t option -> Pp.t
val set_program_mode : bool -> unit
+
+type program_info
+val program_tcc_summary_tag : program_info Id.Map.t Summary.Dyn.tag
diff --git a/vernac/record.ml b/vernac/record.ml
index 1cdc538b5..114b55cb4 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -60,23 +60,25 @@ let _ =
optread = (fun () -> !typeclasses_unique);
optwrite = (fun b -> typeclasses_unique := b); }
-let interp_fields_evars env evars impls_env nots l =
+let interp_fields_evars env sigma impls_env nots l =
List.fold_left2
- (fun (env, uimpls, params, impls) no ((loc, i), b, t) ->
- let t', impl = interp_type_evars_impls env evars ~impls t in
- let b' = Option.map (fun x -> fst (interp_casted_constr_evars_impls env evars ~impls x t')) b in
+ (fun (env, sigma, uimpls, params, impls) no ((loc, i), b, t) ->
+ let sigma, (t', impl) = interp_type_evars_impls env sigma ~impls t in
+ let sigma, b' =
+ Option.cata (fun x -> on_snd (fun x -> Some (fst x)) @@
+ interp_casted_constr_evars_impls env sigma ~impls x t') (sigma,None) b in
let impls =
match i with
| Anonymous -> impls
- | Name id -> Id.Map.add id (compute_internalization_data env Constrintern.Method (EConstr.to_constr !evars t') impl) impls
+ | Name id -> Id.Map.add id (compute_internalization_data env Constrintern.Method (EConstr.to_constr sigma t') impl) impls
in
let d = match b' with
| None -> LocalAssum (i,t')
| Some b' -> LocalDef (i,b',t')
in
List.iter (Metasyntax.set_notation_for_interpretation env impls) no;
- (EConstr.push_rel d env, impl :: uimpls, d::params, impls))
- (env, [], [], impls_env) nots l
+ (EConstr.push_rel d env, sigma, impl :: uimpls, d::params, impls))
+ (env, sigma, [], [], impls_env) nots l
let compute_constructor_level evars env l =
List.fold_right (fun d (env, univ) ->
@@ -97,10 +99,9 @@ let binders_of_decls = List.map binder_of_decl
let typecheck_params_and_fields finite def id poly pl t ps nots fs =
let env0 = Global.env () in
- let evd, decl = Univdecls.interp_univ_decl_opt env0 pl in
- let evars = ref evd in
- let _ =
- let error bk (loc, name) =
+ let sigma, decl = Univdecls.interp_univ_decl_opt env0 pl in
+ let _ =
+ let error bk (loc, name) =
match bk, name with
| Default _, Anonymous ->
user_err ?loc ~hdr:"record" (str "Record parameters must be named")
@@ -112,63 +113,65 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
| CLocalPattern (loc,(_,_)) ->
Loc.raise ?loc (Stream.Error "pattern with quote not allowed in record parameters.")) ps
in
- let impls_env, ((env1,newps), imps) = interp_context_evars env0 evars ps in
- let typ, sort, template = match t with
+ let sigma, (impls_env, ((env1,newps), imps)) = interp_context_evars env0 sigma ps in
+ let sigma, typ, sort, template = match t with
| Some t ->
let env = EConstr.push_rel_context newps env0 in
let poly =
match t with
| { CAst.v = CSort (Misctypes.GType []) } -> true | _ -> false in
- let s = interp_type_evars env evars ~impls:empty_internalization_env t in
- let sred = Reductionops.whd_all env !evars s in
- (match EConstr.kind !evars sred with
+ let sigma, s = interp_type_evars env sigma ~impls:empty_internalization_env t in
+ let sred = Reductionops.whd_all env sigma s in
+ (match EConstr.kind sigma sred with
| Sort s' ->
- let s' = EConstr.ESorts.kind !evars s' in
+ let s' = EConstr.ESorts.kind sigma s' in
(if poly then
- match Evd.is_sort_variable !evars s' with
- | Some l -> evars := Evd.make_flexible_variable !evars ~algebraic:true l;
- s, s', true
- | None -> s, s', false
- else s, s', false)
+ match Evd.is_sort_variable sigma s' with
+ | Some l ->
+ let sigma = Evd.make_flexible_variable sigma ~algebraic:true l in
+ sigma, s, s', true
+ | None ->
+ sigma, s, s', false
+ else sigma, s, s', false)
| _ -> user_err ?loc:(constr_loc t) (str"Sort expected."))
| None ->
let uvarkind = Evd.univ_flexible_alg in
- let s = Evarutil.evd_comb0 (Evd.new_sort_variable uvarkind) evars in
- EConstr.mkSort s, s, true
+ let sigma, s = Evd.new_sort_variable uvarkind sigma in
+ sigma, EConstr.mkSort s, s, true
in
let arity = EConstr.it_mkProd_or_LetIn typ newps in
let env_ar = EConstr.push_rel_context newps (EConstr.push_rel (LocalAssum (Name id,arity)) env0) in
let assums = List.filter is_local_assum newps in
let params = List.map (RelDecl.get_name %> Name.get_id) assums in
let ty = Inductive (params,(finite != BiFinite)) in
- let impls_env = compute_internalization_env env0 ~impls:impls_env ty [id] [EConstr.to_constr !evars arity] [imps] in
- let env2,impls,newfs,data =
- interp_fields_evars env_ar evars impls_env nots (binders_of_decls fs)
+ let impls_env = compute_internalization_env env0 ~impls:impls_env ty [id] [EConstr.to_constr sigma arity] [imps] in
+ let env2,sigma,impls,newfs,data =
+ interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs)
in
- let evars =
- Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar !evars Evd.empty in
- let typ, evars =
- let _, univ = compute_constructor_level evars env_ar newfs in
+ let sigma =
+ Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar sigma Evd.empty in
+ let sigma, typ =
+ let _, univ = compute_constructor_level sigma env_ar newfs in
if not def && (Sorts.is_prop sort ||
(Sorts.is_set sort && is_impredicative_set env0)) then
- typ, evars
+ sigma, typ
else
- let evars = Evd.set_leq_sort env_ar evars (Type univ) sort in
+ let sigma = Evd.set_leq_sort env_ar sigma (Type univ) sort in
if Univ.is_small_univ univ &&
- Option.cata (Evd.is_flexible_level evars) false (Evd.is_sort_variable evars sort) then
+ Option.cata (Evd.is_flexible_level sigma) false (Evd.is_sort_variable sigma sort) then
(* We can assume that the level in aritysort is not constrained
and clear it, if it is flexible *)
- EConstr.mkSort (Sorts.sort_of_univ univ),
- Evd.set_eq_sort env_ar evars (Prop Pos) sort
- else typ, evars
+ Evd.set_eq_sort env_ar sigma (Prop Pos) sort,
+ EConstr.mkSort (Sorts.sort_of_univ univ)
+ else sigma, typ
in
- let evars, nf = Evarutil.nf_evars_and_universes evars in
- let newfs = List.map (EConstr.to_rel_decl evars) newfs in
- let newps = List.map (EConstr.to_rel_decl evars) newps in
- let typ = EConstr.to_constr evars typ in
- let ce t = Pretyping.check_evars env0 Evd.empty evars (EConstr.of_constr t) in
- let univs = Evd.check_univ_decl ~poly evars decl in
- let ubinders = Evd.universe_binders evars in
+ let sigma, _ = Evarutil.nf_evars_and_universes sigma in
+ let newfs = List.map (EConstr.to_rel_decl sigma) newfs in
+ let newps = List.map (EConstr.to_rel_decl sigma) newps in
+ let typ = EConstr.to_constr sigma typ in
+ let ce t = Pretyping.check_evars env0 Evd.empty sigma (EConstr.of_constr t) in
+ let univs = Evd.check_univ_decl ~poly sigma decl in
+ let ubinders = Evd.universe_binders sigma in
List.iter (iter_constr ce) (List.rev newps);
List.iter (iter_constr ce) (List.rev newfs);
ubinders, univs, typ, template, imps, newps, impls, newfs
@@ -430,7 +433,7 @@ let declare_structure finite ubinders univs id idbuild paramimpls params arity t
| Monomorphic_const_entry _ ->
mie
in
- let kn = Command.declare_mutual_inductive_with_eliminations mie ubinders [(paramimpls,[])] in
+ let kn = ComInductive.declare_mutual_inductive_with_eliminations mie ubinders [(paramimpls,[])] in
let rsp = (kn,0) in (* This is ind path of idstruc *)
let cstr = (rsp,1) in
let kinds,sp_projs = declare_projections rsp ctx ~kind binder_name coers ubinders fieldimpls fields in
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index 8673155e2..f001b572a 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -11,7 +11,11 @@ Search
Indschemes
DeclareDef
Obligations
-Command
+ComDefinition
+ComAssumption
+ComInductive
+ComFixpoint
+ComProgramFixpoint
Classes
Record
Assumptions
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 63768d9b8..a581043ac 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -18,7 +18,6 @@ open Tacmach
open Constrintern
open Prettyp
open Printer
-open Command
open Goptions
open Libnames
open Globnames
@@ -479,6 +478,7 @@ let vernac_definition ~atts discharge kind ((loc,id as lid),pl) def =
| Discharge -> Dumpglob.dump_definition lid true "var"
| Local | Global -> Dumpglob.dump_definition lid false "def"
in
+ let program_mode = Flags.is_program_mode () in
(match def with
| ProveBody (bl,t) -> (* local binders, typ *)
start_proof_and_print (local, atts.polymorphic, DefinitionBody kind)
@@ -489,7 +489,7 @@ let vernac_definition ~atts discharge kind ((loc,id as lid),pl) def =
| Some r ->
let sigma, env = Pfedit.get_current_context () in
Some (snd (Hook.get f_interp_redexp env sigma r)) in
- do_definition id (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
+ ComDefinition.do_definition ~program_mode id (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
let vernac_start_proof ~atts kind l =
let local = enforce_locality_exp atts.locality NoDischarge in
@@ -520,7 +520,7 @@ let vernac_assumption ~atts discharge kind l nl =
List.iter (fun (lid, _) ->
if global then Dumpglob.dump_definition lid false "ax"
else Dumpglob.dump_definition lid true "var") idl) l;
- let status = do_assumptions kind nl l in
+ let status = ComAssumption.do_assumptions kind nl l in
if not status then Feedback.feedback Feedback.AddedAxiom
let should_treat_as_cumulative cum poly =
@@ -592,18 +592,29 @@ let vernac_inductive ~atts cum lo finite indl =
| _ -> user_err Pp.(str "Cannot handle mutually (co)inductive records.")
in
let indl = List.map unpack indl in
- do_mutual_inductive indl is_cumulative atts.polymorphic lo finite
+ ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo finite
let vernac_fixpoint ~atts discharge l =
let local = enforce_locality_exp atts.locality discharge in
if Dumpglob.dump () then
List.iter (fun (((lid,_), _, _, _, _), _) -> Dumpglob.dump_definition lid false "def") l;
+ (* XXX: Switch to the attribute system and match on ~atts *)
+ let do_fixpoint = if Flags.is_program_mode () then
+ ComProgramFixpoint.do_fixpoint
+ else
+ ComFixpoint.do_fixpoint
+ in
do_fixpoint local atts.polymorphic l
let vernac_cofixpoint ~atts discharge l =
let local = enforce_locality_exp atts.locality discharge in
if Dumpglob.dump () then
List.iter (fun (((lid,_), _, _, _), _) -> Dumpglob.dump_definition lid false "def") l;
+ let do_cofixpoint = if Flags.is_program_mode () then
+ ComProgramFixpoint.do_cofixpoint
+ else
+ ComFixpoint.do_cofixpoint
+ in
do_cofixpoint local atts.polymorphic l
let vernac_scheme l =
@@ -627,14 +638,14 @@ let vernac_universe ~atts l =
user_err ?loc:atts.loc ~hdr:"vernac_universe"
(str"Polymorphic universes can only be declared inside sections, " ++
str "use Monomorphic Universe instead");
- do_universe atts.polymorphic l
+ Declare.do_universe atts.polymorphic l
let vernac_constraint ~atts l =
if atts.polymorphic && not (Lib.sections_are_opened ()) then
user_err ?loc:atts.loc ~hdr:"vernac_constraint"
(str"Polymorphic universe constraints can only be declared"
++ str " inside sections, use Monomorphic Constraint instead");
- do_constraint atts.polymorphic l
+ Declare.do_constraint atts.polymorphic l
(**********************)
(* Modules *)
@@ -831,7 +842,8 @@ let vernac_identity_coercion ~atts id qids qidt =
let vernac_instance ~atts abst sup inst props pri =
let global = not (make_section_locality atts.locality) in
Dumpglob.dump_constraint inst false "inst";
- ignore(Classes.new_instance ~abstract:abst ~global atts.polymorphic sup inst props pri)
+ let program_mode = Flags.is_program_mode () in
+ ignore(Classes.new_instance ~program_mode ~abstract:abst ~global atts.polymorphic sup inst props pri)
let vernac_context ~atts l =
if not (Classes.context atts.polymorphic l) then Feedback.feedback Feedback.AddedAxiom
@@ -1591,13 +1603,14 @@ let vernac_declare_reduction ~atts s r =
let vernac_global_check c =
let env = Global.env() in
let sigma = Evd.from_env env in
- let c,ctx = interp_constr env sigma c in
+ let c,uctx = interp_constr env sigma c in
let senv = Global.safe_env() in
- let cstrs = snd (UState.context_set ctx) in
- let senv = Safe_typing.add_constraints cstrs senv in
+ let uctx = UState.context_set uctx in
+ let senv = Safe_typing.push_context_set false uctx senv in
let j = Safe_typing.typing senv c in
let env = Safe_typing.env_of_safe_env senv in
- Feedback.msg_notice (print_safe_judgment env sigma j)
+ Feedback.msg_notice (print_safe_judgment env sigma j ++
+ pr_universe_ctx_set sigma uctx)
let get_nth_goal n =
@@ -1656,13 +1669,13 @@ let vernac_print ~atts env sigma =
| PrintMLModules -> msg_notice (Mltop.print_ml_modules ())
| PrintDebugGC -> msg_notice (Mltop.print_gc ())
| PrintName (qid,udecl) -> dump_global qid; msg_notice (print_name env sigma qid udecl)
- | PrintGraph -> msg_notice (Prettyp.print_graph())
+ | PrintGraph -> msg_notice (Prettyp.print_graph env sigma)
| PrintClasses -> msg_notice (Prettyp.print_classes())
| PrintTypeClasses -> msg_notice (Prettyp.print_typeclasses())
| PrintInstances c -> msg_notice (Prettyp.print_instances (smart_global c))
| PrintCoercions -> msg_notice (Prettyp.print_coercions env sigma)
| PrintCoercionPaths (cls,clt) ->
- msg_notice (Prettyp.print_path_between (cl_of_qualid cls) (cl_of_qualid clt))
+ msg_notice (Prettyp.print_path_between env sigma (cl_of_qualid cls) (cl_of_qualid clt))
| PrintCanonicalConversions -> msg_notice (Prettyp.print_canonical_projections env sigma)
| PrintUniverses (b, dst) ->
let univ = Global.universes () in
@@ -1696,7 +1709,7 @@ let vernac_print ~atts env sigma =
let st = Conv_oracle.get_transp_state (Environ.oracle (Global.env())) in
let nassums =
Assumptions.assumptions st ~add_opaque:o ~add_transparent:t gr cstr in
- msg_notice (Printer.pr_assumptionset (Global.env ()) nassums)
+ msg_notice (Printer.pr_assumptionset env sigma nassums)
| PrintStrategy r -> print_strategy r
let global_module r =