aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml2
-rw-r--r--.github/CODEOWNERS72
-rw-r--r--.gitignore7
-rw-r--r--.gitlab-ci.yml37
-rw-r--r--.travis.yml9
-rw-r--r--CHANGES53
-rw-r--r--CONTRIBUTING.md3
-rw-r--r--INSTALL32
-rw-r--r--INSTALL.doc91
-rw-r--r--INSTALL.ide123
-rw-r--r--Makefile16
-rw-r--r--Makefile.build53
-rw-r--r--Makefile.checker4
-rw-r--r--Makefile.ci3
-rw-r--r--Makefile.common12
-rw-r--r--Makefile.ide10
-rw-r--r--Makefile.install14
-rw-r--r--README.md12
-rw-r--r--checker/cic.mli18
-rw-r--r--checker/closure.ml3
-rw-r--r--checker/environ.ml11
-rw-r--r--checker/indtypes.ml22
-rw-r--r--checker/inductive.ml24
-rw-r--r--checker/mod_checking.ml27
-rw-r--r--checker/modops.ml22
-rw-r--r--checker/print.ml4
-rw-r--r--checker/reduction.ml41
-rw-r--r--checker/subtyping.ml106
-rw-r--r--checker/term.ml20
-rw-r--r--checker/typeops.ml16
-rw-r--r--checker/univ.ml42
-rw-r--r--checker/univ.mli2
-rw-r--r--checker/values.ml14
-rw-r--r--clib/cList.ml10
-rw-r--r--clib/cList.mli5
-rw-r--r--clib/dyn.ml194
-rw-r--r--clib/dyn.mli63
-rw-r--r--configure.ml31
-rw-r--r--default.nix98
-rw-r--r--dev/README50
-rw-r--r--dev/README.md46
-rwxr-xr-x[-rw-r--r--]dev/build/windows/MakeCoq_MinGW.bat8
-rw-r--r--dev/build/windows/makecoq_mingw.sh78
-rw-r--r--dev/ci/README.md5
-rwxr-xr-xdev/ci/ci-basic-overlay.sh70
-rwxr-xr-xdev/ci/ci-bedrock2.sh11
-rw-r--r--dev/ci/ci-common.sh2
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile10
-rw-r--r--dev/ci/gitlab.bat2
-rw-r--r--dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh4
-rw-r--r--dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh2
-rw-r--r--dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh8
-rw-r--r--dev/ci/user-overlays/06859-ejgallego-stm+top.sh9
-rw-r--r--dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh12
-rw-r--r--dev/ci/user-overlays/07099-ppedrot-unification-returns-option.sh4
-rw-r--r--dev/ci/user-overlays/07136-evar-map-econstr.sh7
-rw-r--r--dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh12
-rw-r--r--dev/ci/user-overlays/07196-ejgallego-tactics+push_fix_naming_out.sh21
-rw-r--r--dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh6
-rw-r--r--dev/ci/user-overlays/07495-gares-elpi-test-bug.sh8
-rw-r--r--dev/ci/user-overlays/07558-ejgallego-vernac+move_parser.sh14
-rw-r--r--dev/ci/user-overlays/07677-ejgallego-misctypes+bye2.sh8
-rw-r--r--dev/ci/user-overlays/07746-cleanup-unused-various.sh6
-rw-r--r--dev/ci/user-overlays/07797-rm-reference.sh20
-rw-r--r--dev/ci/user-overlays/07820-mattam82-hints-constants.sh6
-rw-r--r--dev/ci/user-overlays/07902-ppedrot-camlp5-parser.sh8
-rw-r--r--dev/ci/user-overlays/README.md4
-rw-r--r--dev/doc/README.md77
-rw-r--r--dev/doc/changes.md113
-rw-r--r--dev/doc/critical-bugs252
-rw-r--r--dev/doc/profiling.txt2
-rw-r--r--dev/doc/setup.txt269
-rw-r--r--dev/doc/translate.txt495
-rw-r--r--dev/doc/versions-history.tex12
-rw-r--r--dev/doc/xml-protocol.md4
-rw-r--r--dev/top_printers.ml10
-rw-r--r--dev/vm_printers.ml4
-rw-r--r--doc/LICENSE23
-rw-r--r--doc/README.md102
-rw-r--r--doc/sphinx/README.rst15
-rw-r--r--doc/sphinx/addendum/ring.rst23
-rw-r--r--doc/sphinx/addendum/type-classes.rst4
-rw-r--r--doc/sphinx/biblio.bib32
-rwxr-xr-xdoc/sphinx/conf.py1
-rw-r--r--doc/sphinx/credits.rst7
-rw-r--r--doc/sphinx/index.rst38
-rw-r--r--doc/sphinx/introduction.rst61
-rw-r--r--doc/sphinx/language/cic.rst231
-rw-r--r--doc/sphinx/language/gallina-extensions.rst24
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst27
-rw-r--r--doc/sphinx/practical-tools/utilities.rst63
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst39
-rw-r--r--doc/sphinx/proof-engine/tactics.rst18
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst206
-rw-r--r--doc/tools/coqrst/coqdoc/main.py4
-rw-r--r--doc/tools/coqrst/coqdomain.py136
-rw-r--r--engine/eConstr.ml13
-rw-r--r--engine/eConstr.mli4
-rw-r--r--engine/evarutil.ml49
-rw-r--r--engine/evarutil.mli28
-rw-r--r--engine/evd.ml14
-rw-r--r--engine/evd.mli14
-rw-r--r--engine/namegen.ml5
-rw-r--r--engine/termops.ml15
-rw-r--r--engine/termops.mli24
-rw-r--r--engine/uState.ml2
-rw-r--r--engine/univGen.ml4
-rw-r--r--engine/univGen.mli2
-rw-r--r--engine/univSubst.ml12
-rw-r--r--engine/univSubst.mli2
-rw-r--r--engine/universes.mli4
-rw-r--r--engine/univops.ml15
-rw-r--r--engine/univops.mli4
-rw-r--r--grammar/coqpp_ast.mli95
-rw-r--r--grammar/coqpp_lex.mll167
-rw-r--r--grammar/coqpp_main.ml349
-rw-r--r--grammar/coqpp_parse.mly256
-rw-r--r--grammar/q_util.mlp2
-rw-r--r--grammar/tacextend.mlp9
-rw-r--r--ide/idetop.ml5
-rw-r--r--ide/wg_ProofView.ml4
-rw-r--r--interp/constrintern.ml10
-rw-r--r--interp/declare.ml20
-rw-r--r--interp/discharge.ml7
-rw-r--r--interp/dumpglob.ml2
-rw-r--r--interp/implicit_quantifiers.ml2
-rw-r--r--interp/implicit_quantifiers.mli8
-rw-r--r--kernel/cClosure.ml119
-rw-r--r--kernel/cClosure.mli2
-rw-r--r--kernel/cbytecodes.ml5
-rw-r--r--kernel/cbytecodes.mli1
-rw-r--r--kernel/cbytegen.ml33
-rw-r--r--kernel/clambda.ml2
-rw-r--r--kernel/constr.ml23
-rw-r--r--kernel/constr.mli9
-rw-r--r--kernel/context.ml9
-rw-r--r--kernel/context.mli9
-rw-r--r--kernel/cooking.ml23
-rw-r--r--kernel/cooking.mli5
-rw-r--r--kernel/declarations.ml29
-rw-r--r--kernel/declareops.ml19
-rw-r--r--kernel/entries.ml12
-rw-r--r--kernel/environ.ml27
-rw-r--r--kernel/environ.mli59
-rw-r--r--kernel/esubst.ml23
-rw-r--r--kernel/esubst.mli7
-rw-r--r--kernel/indtypes.ml84
-rw-r--r--kernel/indtypes.mli6
-rw-r--r--kernel/inductive.ml25
-rw-r--r--kernel/inductive.mli8
-rw-r--r--kernel/kernel.mllib2
-rw-r--r--kernel/modops.ml5
-rw-r--r--kernel/modops.mli1
-rw-r--r--kernel/nativecode.ml35
-rw-r--r--kernel/nativecode.mli2
-rw-r--r--kernel/nativelambda.ml8
-rw-r--r--kernel/nativelibrary.ml2
-rw-r--r--kernel/nativevalues.ml2
-rw-r--r--kernel/opaqueproof.ml2
-rw-r--r--kernel/opaqueproof.mli2
-rw-r--r--kernel/reduction.ml65
-rw-r--r--kernel/reduction.mli8
-rw-r--r--kernel/safe_typing.ml4
-rw-r--r--kernel/safe_typing.mli1
-rw-r--r--kernel/sorts.ml57
-rw-r--r--kernel/sorts.mli7
-rw-r--r--kernel/subtyping.ml90
-rw-r--r--kernel/term.ml7
-rw-r--r--kernel/term.mli41
-rw-r--r--kernel/term_typing.ml59
-rw-r--r--kernel/typeops.ml18
-rw-r--r--kernel/typeops.mli5
-rw-r--r--kernel/uGraph.ml39
-rw-r--r--kernel/uGraph.mli3
-rw-r--r--kernel/univ.ml9
-rw-r--r--kernel/vars.mli14
-rw-r--r--lib/cWarnings.ml6
-rw-r--r--lib/coqProject_file.ml (renamed from lib/coqProject_file.ml4)64
-rw-r--r--lib/envars.ml2
-rw-r--r--lib/system.ml2
-rw-r--r--lib/util.ml4
-rw-r--r--library/global.mli4
-rw-r--r--library/lib.ml2
-rw-r--r--library/lib.mli9
-rw-r--r--library/libobject.ml16
-rw-r--r--library/library.ml36
-rw-r--r--man/gallina.174
-rw-r--r--parsing/extend.ml2
-rw-r--r--parsing/g_constr.mlg (renamed from parsing/g_constr.ml4)351
-rw-r--r--parsing/g_prim.mlg (renamed from parsing/g_prim.ml4)69
-rw-r--r--parsing/pcoq.ml11
-rw-r--r--parsing/pcoq.mli3
-rw-r--r--plugins/btauto/g_btauto.mlg (renamed from plugins/btauto/g_btauto.ml4)6
-rw-r--r--plugins/cc/ccalgo.ml4
-rw-r--r--plugins/cc/g_congruence.mlg (renamed from plugins/cc/g_congruence.ml4)14
-rw-r--r--plugins/extraction/extraction.ml8
-rw-r--r--plugins/fourier/g_fourier.mlg (renamed from plugins/fourier/g_fourier.ml4)6
-rw-r--r--plugins/funind/functional_principles_types.ml11
-rw-r--r--plugins/funind/glob_term_to_relation.ml2
-rw-r--r--plugins/ltac/coretactics.mlg (renamed from plugins/ltac/coretactics.ml4)184
-rw-r--r--plugins/ltac/extratactics.ml42
-rw-r--r--plugins/ltac/g_eqdecide.mlg (renamed from plugins/ltac/g_eqdecide.ml4)8
-rw-r--r--plugins/ltac/g_tactic.mlg (renamed from plugins/ltac/g_tactic.ml4)452
-rw-r--r--plugins/ltac/pptactic.ml51
-rw-r--r--plugins/ltac/rewrite.ml2
-rw-r--r--plugins/ltac/taccoerce.ml32
-rw-r--r--plugins/ltac/taccoerce.mli14
-rw-r--r--plugins/ltac/tacentries.ml34
-rw-r--r--plugins/ltac/tacentries.mli4
-rw-r--r--plugins/ltac/tacinterp.ml14
-rw-r--r--plugins/micromega/g_micromega.mlg (renamed from plugins/micromega/g_micromega.ml4)38
-rw-r--r--plugins/nsatz/g_nsatz.mlg (renamed from plugins/nsatz/g_nsatz.ml4)6
-rw-r--r--plugins/omega/coq_omega.ml10
-rw-r--r--plugins/omega/g_omega.mlg (renamed from plugins/omega/g_omega.ml4)9
-rw-r--r--plugins/quote/g_quote.mlg (renamed from plugins/quote/g_quote.ml4)16
-rw-r--r--plugins/romega/g_romega.mlg (renamed from plugins/romega/g_romega.ml4)12
-rw-r--r--plugins/rtauto/g_rtauto.mlg (renamed from plugins/rtauto/g_rtauto.ml4)5
-rw-r--r--plugins/setoid_ring/g_newring.ml45
-rw-r--r--plugins/setoid_ring/newring.ml41
-rw-r--r--plugins/setoid_ring/newring.mli2
-rw-r--r--plugins/ssr/ssrast.mli2
-rw-r--r--plugins/ssr/ssrequality.ml2
-rw-r--r--plugins/ssr/ssrfwd.ml2
-rw-r--r--plugins/ssr/ssripats.ml50
-rw-r--r--plugins/ssr/ssrparser.ml420
-rw-r--r--plugins/ssr/ssrprinters.ml3
-rw-r--r--plugins/ssr/ssrview.ml91
-rw-r--r--plugins/ssr/ssrview.mli6
-rw-r--r--plugins/ssrmatching/g_ssrmatching.ml4101
-rw-r--r--plugins/ssrmatching/g_ssrmatching.mli17
-rw-r--r--plugins/ssrmatching/ssrmatching.ml (renamed from plugins/ssrmatching/ssrmatching.ml4)117
-rw-r--r--plugins/ssrmatching/ssrmatching.mli34
-rw-r--r--plugins/ssrmatching/ssrmatching_plugin.mlpack1
-rw-r--r--plugins/syntax/n_syntax.ml81
-rw-r--r--plugins/syntax/n_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/positive_syntax.ml101
-rw-r--r--plugins/syntax/positive_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/z_syntax.ml128
-rw-r--r--pretyping/coercion.ml4
-rw-r--r--pretyping/constr_matching.ml4
-rw-r--r--pretyping/detyping.ml7
-rw-r--r--pretyping/evarconv.ml8
-rw-r--r--pretyping/evarsolve.ml2
-rw-r--r--pretyping/geninterp.mli4
-rw-r--r--pretyping/glob_ops.ml4
-rw-r--r--pretyping/indrec.ml9
-rw-r--r--pretyping/inductiveops.ml40
-rw-r--r--pretyping/inductiveops.mli12
-rw-r--r--pretyping/nativenorm.ml48
-rw-r--r--pretyping/patternops.ml4
-rw-r--r--pretyping/retyping.ml13
-rw-r--r--pretyping/typeclasses.ml4
-rw-r--r--pretyping/typeclasses.mli4
-rw-r--r--pretyping/typing.ml13
-rw-r--r--pretyping/unification.ml10
-rw-r--r--pretyping/vnorm.ml39
-rw-r--r--printing/pputils.ml2
-rw-r--r--printing/prettyp.ml6
-rw-r--r--printing/prettyp.mli2
-rw-r--r--printing/printer.ml2
-rw-r--r--printing/printer.mli12
-rw-r--r--printing/printmod.ml2
-rw-r--r--proofs/pfedit.mli3
-rw-r--r--proofs/proof_global.ml7
-rw-r--r--proofs/proof_global.mli4
-rw-r--r--shell.nix4
-rw-r--r--tactics/class_tactics.ml2
-rw-r--r--tactics/elimschemes.ml2
-rw-r--r--tactics/eqschemes.ml6
-rw-r--r--tactics/equality.ml2
-rw-r--r--tactics/hints.ml128
-rw-r--r--tactics/hints.mli9
-rw-r--r--tactics/inv.ml4
-rw-r--r--tactics/leminv.ml2
-rw-r--r--tactics/tacticals.ml4
-rw-r--r--tactics/tactics.ml6
-rw-r--r--test-suite/Makefile1
-rw-r--r--test-suite/bugs/closed/5012.v17
-rw-r--r--test-suite/bugs/closed/5696.v5
-rw-r--r--test-suite/bugs/closed/7695.v20
-rw-r--r--test-suite/bugs/closed/7712.v4
-rw-r--r--test-suite/bugs/closed/7723.v58
-rw-r--r--test-suite/bugs/closed/7903.v4
-rw-r--r--test-suite/bugs/closed/8004.v47
-rw-r--r--test-suite/coq-makefile/timing/precomputed-time-tests/001-correct-diff-sorting-order/time-of-build-both.log.expected2
-rw-r--r--test-suite/coq-makefile/timing/precomputed-time-tests/002-single-file-sorting/time-of-build-pretty.log.expected2
-rwxr-xr-xtest-suite/misc/7704.sh7
-rw-r--r--test-suite/misc/aux7704.v6
-rw-r--r--test-suite/output/Notations3.out5
-rw-r--r--test-suite/output/Notations3.v14
-rw-r--r--test-suite/ssr/ipat_clear_if_id.v23
-rw-r--r--test-suite/ssr/rew_polyuniv.v90
-rw-r--r--test-suite/ssr/set_polyuniv.v11
-rw-r--r--test-suite/ssr/ssr_rew_illtyped.v9
-rw-r--r--test-suite/success/Hints.v30
-rw-r--r--test-suite/success/mutual_record.v57
-rw-r--r--test-suite/success/uniform_inductive_parameters.v13
-rw-r--r--test-suite/success/vm_records.v40
-rw-r--r--theories/Init/Logic.v7
-rw-r--r--theories/Numbers/BinNums.v2
-rw-r--r--tools/CoqMakefile.in19
-rw-r--r--tools/TimeFileMaker.py30
-rw-r--r--tools/coq-font-lock.el137
-rw-r--r--tools/coq_makefile.ml4
-rw-r--r--tools/coqdoc/index.ml2
-rw-r--r--tools/coqdoc/index.mli2
-rw-r--r--tools/coqdoc/output.ml4
-rw-r--r--tools/gallina-db.el240
-rw-r--r--tools/gallina-syntax.el979
-rw-r--r--tools/gallina.el142
-rw-r--r--tools/gallina.ml63
-rw-r--r--tools/gallina_lexer.mll126
-rw-r--r--tools/inferior-coq.el324
-rwxr-xr-xtools/make-both-single-timing-files.py2
-rwxr-xr-xtools/make-both-time-files.py2
-rwxr-xr-xtools/make-one-time-file.py2
-rw-r--r--toplevel/g_toplevel.mlg (renamed from toplevel/g_toplevel.ml4)19
-rw-r--r--vernac/assumptions.mli2
-rw-r--r--vernac/classes.ml7
-rw-r--r--vernac/classes.mli4
-rw-r--r--vernac/comAssumption.ml2
-rw-r--r--vernac/comDefinition.ml2
-rw-r--r--vernac/comFixpoint.ml5
-rw-r--r--vernac/comFixpoint.mli4
-rw-r--r--vernac/comInductive.ml57
-rw-r--r--vernac/comInductive.mli7
-rw-r--r--vernac/egramcoq.ml7
-rw-r--r--vernac/g_proofs.ml4131
-rw-r--r--vernac/g_proofs.mlg139
-rw-r--r--vernac/g_vernac.ml41156
-rw-r--r--vernac/g_vernac.mlg1173
-rw-r--r--vernac/himsg.ml3
-rw-r--r--vernac/himsg.mli2
-rw-r--r--vernac/metasyntax.ml30
-rw-r--r--vernac/misctypes.ml8
-rw-r--r--vernac/obligations.ml15
-rw-r--r--vernac/ppvernac.ml5
-rw-r--r--vernac/record.ml270
-rw-r--r--vernac/record.mli13
-rw-r--r--vernac/vernacentries.ml163
-rw-r--r--vernac/vernacexpr.ml7
341 files changed, 7129 insertions, 7730 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 03aeed2eb..950674b34 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,7 +11,7 @@ defaults:
- image: $CI_REGISTRY_IMAGE:$CACHEKEY
environment: &envvars
- CACHEKEY: "bionic_coq-V2018-06-13-V1"
+ CACHEKEY: "bionic_coq-V2018-07-02-V4"
CI_REGISTRY_IMAGE: registry.gitlab.com/coq/coq
version: 2
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9e87d2ca7..192a2b181 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -53,6 +53,9 @@
/doc/ @maximedenes
# Secondary maintainer @silene @Zimmi48
+/doc/tools/coqrst/ @maximedenes
+# Secondary maintainer @cpitclaudel
+
/man/ @silene
# Secondary maintainer @maximedenes
@@ -134,8 +137,7 @@
/plugins/derive/ @aspiwack
# Secondary maintainer @ppedrot
-/plugins/extraction/ @letouzey
-# Secondary maintainer @maximedenes
+/plugins/extraction/ @maximedenes
/plugins/firstorder/ @PierreCorbineau
# Secondary maintainer @herbelin
@@ -156,10 +158,6 @@
/plugins/nsatz/ @thery
# Secondary maintainer @ppedrot
-/plugins/omega/ @letouzey
-
-/plugins/romega/ @letouzey
-
/plugins/setoid_ring/ @amahboubi
# Secondary maintainer @bgregoir
@@ -183,6 +181,10 @@
/pretyping/ @mattam82
# Secondary maintainer @gares
+/pretyping/vnorm.* @maximedenes
+/pretyping/nativenorm.* @maximedenes
+# Secondary maintainer @ppedrot
+
########## Pretty printer ##########
/printing/ @herbelin
@@ -212,44 +214,34 @@
########## Standard library ##########
-/theories/Arith/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Arith/ @herbelin
-/theories/Bool/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Bool/ @herbelin
/theories/Classes/ @mattam82
# Secondary maintainer @herbelin
-/theories/FSets/ @letouzey
-# Secondary maintainer @herbelin
+/theories/FSets/ @herbelin
-/theories/Init/ @letouzey
-# Secondary maintainer @ppedrot
+/theories/Init/ @ppedrot
-/theories/Lists/ @letouzey
-# Secondary maintainer @ppedrot
+/theories/Lists/ @ppedrot
/theories/Logic/ @herbelin
# Secondary maintainer @ppedrot
-/theories/MSets/ @letouzey
-# Secondary maintainer @herbelin
+/theories/MSets/ @herbelin
-/theories/NArith/ @letouzey
-# Secondary maintainer @herbelin
+/theories/NArith/ @herbelin
-/theories/Numbers/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Numbers/ @herbelin
-/theories/PArith/ @letouzey
-# Secondary maintainer @herbelin
+/theories/PArith/ @herbelin
/theories/Program/ @mattam82
# Secondary maintainer @herbelin
-/theories/QArith/ @letouzey
-# Secondary maintainer @herbelin
+/theories/QArith/ @herbelin
/theories/Reals/ @silene
# Secondary maintainer @ppedrot
@@ -260,26 +252,19 @@
/theories/Setoids/ @mattam82
# Secondary maintainer @ppedrot
-/theories/Sets/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Sets/ @herbelin
-/theories/Sorting/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Sorting/ @herbelin
-/theories/Strings/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Strings/ @herbelin
-/theories/Structures/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Structures/ @herbelin
-/theories/Unicode/ @letouzey
-# Secondary maintainer @herbelin
+/theories/Unicode/ @herbelin
-/theories/Wellfounded/ @letouzey
-# Secondary maintainer @mattam82
+/theories/Wellfounded/ @mattam82
-/theories/ZArith/ @letouzey
-# Secondary maintainer @herbelin
+/theories/ZArith/ @herbelin
/theories/Compat/ @JasonGross
# Secondary maintainer @Zimmi48
@@ -324,14 +309,11 @@
########## Build system ##########
-/Makefile* @letouzey
-# Secondary maintainer @gares
+/Makefile* @gares
-/configure* @letouzey
-# Secondary maintainer @ejgallego
+/configure* @ejgallego
/META.coq @ejgallego
-# Secondary maintainer @letouzey
/dev/build/windows @MSoegtropIMC
# Secondary maintainer @maximedenes
diff --git a/.gitignore b/.gitignore
index 6adbc9fb2..466f4c1a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -115,17 +115,22 @@ dev/ocamldoc/*.css
# .mll files
+grammar/coqpp_lex.ml
dev/ocamlweb-doc/lex.ml
ide/coq_lex.ml
ide/config_lexer.ml
ide/utf8_convert.ml
-tools/gallina_lexer.ml
tools/coqwc.ml
tools/coqdep_lexer.ml
tools/ocamllibdep.ml
tools/coqdoc/cpretty.ml
ide/protocol/xml_lexer.ml
+# .mly files
+
+grammar/coqpp_parse.ml
+grammar/coqpp_parse.mli
+
# .ml4 / .mlp files
g_*.ml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 971a281ea..11614bc38 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,7 +9,7 @@ stages:
variables:
# Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
# for reference]
- CACHEKEY: "bionic_coq-V2018-06-13-V1"
+ CACHEKEY: "bionic_coq-V2018-07-02-V4"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
@@ -45,6 +45,9 @@ before_script:
- opam list
- opam config list
+after_script:
+ - echo "The build completed normally (not a runner failure)."
+
################ GITLAB CACHING ######################
# - use artifacts between jobs #
######################################################
@@ -233,6 +236,35 @@ windows32:
variables:
ARCH: "32"
+pkg:nix:
+ image: nixorg/nix:latest # Minimal NixOS image which doesn't even contain git
+ stage: test
+ variables:
+ # By default we use coq.cachix.org as an extra substituter but this can be overridden
+ EXTRA_SUBSTITUTERS: https://coq.cachix.org
+ EXTRA_PUBLIC_KEYS: coq.cachix.org-1:Jgt0DwGAUo+wpxCM52k2V+E0hLoOzFPzvg94F65agtI=
+ # The following variables should not be overridden
+ GIT_STRATEGY: none
+ CACHIX_PUBLIC_KEY: cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM=
+ NIXOS_PUBLIC_KEY: cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
+
+ dependencies: [] # We don't need to download build artifacts
+ before_script: [] # We don't want to use the shared 'before_script'
+ script:
+ # Use current worktree as tmpdir to allow exporting artifacts in case of failure
+ - export TMPDIR=$PWD
+ # Install Cachix as documented at https://github.com/cachix/cachix
+ - nix-env -if https://github.com/cachix/cachix/tarball/master --substituters https://cachix.cachix.org --trusted-public-keys "$CACHIX_PUBLIC_KEY"
+ # We build an expression rather than a direct URL to not be dependent on
+ # the URL location; we are forced to put the public key of cache.nixos.org
+ # because there is no --extra-trusted-public-key option.
+ - nix-build -E "import (fetchTarball $CI_PROJECT_URL/-/archive/$CI_COMMIT_SHA.tar.gz) {}" -K --extra-substituters "$EXTRA_SUBSTITUTERS" --trusted-public-keys "$NIXOS_PUBLIC_KEY $EXTRA_PUBLIC_KEYS" | if [ ! -z "$CACHIX_SIGNING_KEY" ]; then cachix push coq; fi
+ artifacts:
+ name: "$CI_JOB_NAME.logs"
+ when: on_failure
+ paths:
+ - nix-build-coq.drv-0/*/test-suite/logs
+
warnings:base:
<<: *warnings-template
@@ -306,6 +338,9 @@ validate:edge+flambda:
OPAM_SWITCH: edge
OPAM_VARIANT: "+flambda"
+ci-bedrock2:
+ <<: *ci-template
+
ci-bignums:
<<: *ci-template
diff --git a/.travis.yml b/.travis.yml
index 627334690..42c41249d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -67,9 +67,6 @@ matrix:
- TEST_TARGET="validate" COMPILER="${COMPILER_BE}+flambda" CAMLP5_VER="${CAMLP5_VER_BE}" NATIVE_COMP="no" EXTRA_CONF="-flambda-opts -O3" FINDLIB_VER="${FINDLIB_VER_BE}"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-bignums"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-color"
- if: NOT (type = pull_request)
env:
@@ -85,9 +82,6 @@ matrix:
- TEST_TARGET="ci-equations"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-fcsl-pcm"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-fiat-parsers"
- if: NOT (type = pull_request)
env:
@@ -100,9 +94,6 @@ matrix:
- TEST_TARGET="ci-ltac2"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-math-classes"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-mtac2"
- if: NOT (type = pull_request)
env:
diff --git a/CHANGES b/CHANGES
index c36f59726..689c1eff6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
Changes from 8.8.2 to 8.9+beta1
===============================
+Kernel
+
+- Mutually defined records are now supported.
+
Tactics
- Added toplevel goal selector ! which expects a single focused goal.
@@ -41,6 +45,16 @@ Tools
COQFLAGS is now entirely separate from COQLIBS, so in custom Makefiles
$(COQFLAGS) should be replaced by $(COQFLAGS) $(COQLIBS).
+- Removed the gallina utility (extracts specification from Coq vernacular files).
+ If you would like to maintain this tool externally, please contact us.
+
+- Removed the Emacs modes distributed with Coq. You are advised to
+ use Proof-General <https://proofgeneral.github.io/> (and optionally
+ Company-Coq <https://github.com/cpitclaudel/company-coq>) instead.
+ If your use case is not covered by these alternative Emacs modes,
+ please open an issue. We can help set up external maintenance as part
+ of Proof-General, or independently as part of coq-community.
+
Vernacular Commands
- Removed deprecated commands Arguments Scope and Implicit Arguments
@@ -48,6 +62,12 @@ Vernacular Commands
- Nested proofs may be enabled through the option `Nested Proofs Allowed`.
By default, they are disabled and produce an error. The deprecation
warning which used to occur when using nested proofs has been removed.
+- Added option Uniform Inductive Parameters which abstracts over parameters
+ before typechecking constructors, allowing to write for example
+ `Inductive list (A : Type) := nil : list | cons : A -> list -> list.`
+- New Set Hint Variables/Constants Opaque/Transparent commands for setting
+ globally the opacity flag of variables and constants in hint databases,
+ overwritting the opacity set of the hint database.
Coq binaries and process model
@@ -61,19 +81,52 @@ Coq binaries and process model
`coq{proof,tactic,query}worker` are in charge of task-specific and
parallel proof checking.
+SSReflect
+
+- The implementation of delayed clear switches in intro patterns
+ is now simpler to explain:
+ 1. The immediate effect of a clear switch like {x} is to rename the
+ variable x to _x_ (i.e. a reserved identifier that cannot be mentioned
+ explicitly)
+ 2. The delayed effect of {x} is that _x_ is cleared at the end of the intro
+ pattern
+ 3. A clear switch immediately before a view application like {x}/v is
+ translated to /v{x}.
+ In particular rule 3 lets one write {x}/v even if v uses the variable x:
+ indeed the view is executed before the renaming.
+
+- An empty clear switch is now accepted in intro patterns before a
+ view application whenever the view is a variable.
+ One can now write {}/v to mean {v}/v. Remark that {}/x is very similar
+ to the idiom {}e for the rewrite tactic (the equation e is used for
+ rewriting and then discarded).
+
Changes from 8.8.0 to 8.8.1
===========================
Kernel
- Fix a critical bug with cofixpoints and vm_compute/native_compute (#7333).
+- Fix a critical bug with modules and algebraic universes (#7695)
- Fix a critical bug with inlining of polymorphic constants (#7615).
+- Fix a critical bug with universe polymorphism and vm_compute (#7723). Was
+ present since 8.5.
Notations
- Fixed unexpected collision between only-parsing and only-printing
notations (issue #7462).
+Windows installer
+
+- The Windows installer now includes external packages Ltac2 and Equations
+ (it included the Bignums package since 8.8+beta1).
+
+Many other bug fixes, documentation improvements (including fixes of
+regressions due to the Sphinx migration), and user message improvements
+(for details, see the 8.8.1 milestone at
+https://github.com/coq/coq/milestone/13?closed=1).
+
Changes from 8.8+beta1 to 8.8.0
===============================
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2dffd2019..9bd3d0b7c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,6 +20,9 @@ If you want to minimize your bug (or help minimize someone else's) for more extr
## Pull requests
+**Beginner's guide to hacking Coq: [`dev/doc/README.md`](dev/doc/README.md)** \
+**Development information and tools: [`dev/README.md`](dev/README.md)**
+
If you want to contribute a bug fix or feature yourself, pull requests on the [GitHub repository](https://github.com/coq/coq) are the way to contribute directly to the Coq implementation. We recommend you create a fork of the repository on GitHub and push your changes to a new "topic branch" in that fork. From there you can follow the [GitHub pull request documentation](https://help.github.com/articles/about-pull-requests/) to get your changes reviewed and pulled into the Coq source repository.
Documentation for getting started with the Coq sources is located in various
diff --git a/INSTALL b/INSTALL
index 984b8e290..eabc729f7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
- INSTALLATION PROCEDURES FOR THE COQ V8.8 SYSTEM
- -----------------------------------------------
+ INSTALLATION PROCEDURE
+ ----------------------
WHAT DO YOU NEED ?
@@ -27,11 +27,14 @@ WHAT DO YOU NEED ?
port install coq
- To compile Coq V8.8 yourself, you need:
+ To compile Coq yourself, you need:
- OCaml version 4.02.3 or later
(available at https://ocaml.org/)
+ - The Num package, which used to be part of the OCaml standard library,
+ if you are using an OCaml version >= 4.06.0
+
- Findlib (version >= 1.4.1)
(available at http://projects.camlcity.org/projects/findlib.html)
@@ -42,20 +45,24 @@ WHAT DO YOU NEED ?
- a C compiler
- - for Coqide, the Lablgtk development files, and the GTK libraries
- including gtksourceview, see INSTALL.ide for more details
+ - for CoqIDE, the lablgtk development files (version >= 2.18.3),
+ and the GTK 2.x libraries including gtksourceview2.
- Note that camlp5 and lablgtk should be properly registered with
+ Note that num, camlp5 and lablgtk should be properly registered with
findlib/ocamlfind as Coq's makefile will use it to locate the
libraries during the build.
- Opam (https://opam.ocaml.org/) is recommended to install ocaml and
+ Opam (https://opam.ocaml.org/) is recommended to install OCaml and
the corresponding packages.
- $ opam install ocamlfind camlp5 lablgtk-extras
+ $ opam install num ocamlfind camlp5 lablgtk conf-gtksourceview
should get you a reasonable OCaml environment to compile Coq.
+ Nix users can also get all the required dependencies by running:
+
+ $ nix-shell
+
Advanced users may want to experiment with the OCaml Flambda
compiler as way to improve the performance of Coq. In order to
profit from Flambda, a special build of the OCaml compiler that has
@@ -76,7 +83,7 @@ QUICK INSTALLATION PROCEDURE.
INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
=================================================
-1- Check that you have the Objective Caml compiler installed on your
+1- Check that you have the OCaml compiler installed on your
computer and that "ocamlc" (or, better, its native code version
"ocamlc.opt") lies in a directory which is present in your $PATH
environment variable. At the time of writing this sentence, all
@@ -183,11 +190,6 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
make install
Of course, you may need superuser rights to do that.
- To use the Coq emacs mode you also need to put the following lines
- in you .emacs file:
-
- (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
- (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
7- Optionally, you could build the bytecode version of Coq via:
@@ -258,8 +260,6 @@ THE AVAILABLE COMMANDS.
directory, or read online on http://coq.inria.fr/doc/)
and in the corresponding manual pages.
- There is also a tutorial and a FAQ; see http://coq.inria.fr/getting-started
-
COMPILING FOR DIFFERENT ARCHITECTURES.
======================================
diff --git a/INSTALL.doc b/INSTALL.doc
deleted file mode 100644
index 13e6440d0..000000000
--- a/INSTALL.doc
+++ /dev/null
@@ -1,91 +0,0 @@
- The Coq documentation
- =====================
-
-The Coq documentation includes
-
-- A Reference Manual
-- A document presenting the Coq standard library
-
-The reference manual is written is reStructuredText and compiled
-using Sphinx (see `doc/sphinx/README.rst`) to learn more.
-
-The documentation for the standard library is generated from
-the `.v` source files using coqdoc.
-
-Prerequisite
-------------
-
-To produce all the documents, the following tools are needed:
-
- - latex (latex2e)
- - pdflatex
- - dvips
- - makeindex
- - Python 3
- - Sphinx 1.6.5 (http://www.sphinx-doc.org/en/stable/)
- - sphinx_rtd_theme
- - pexpect
- - beautifulsoup4
- - Antlr4 runtime for Python 3
-
-
-Under recent Debian based operating systems (Debian 10 "Buster",
-Ubuntu 18.04, ...) a working set of packages for compiling the
-documentation for Coq is:
-
- texlive-latex-extra texlive-fonts-recommended python3-sphinx
- python3-pexpect python3-sphinx-rtd-theme python3-bs4
- python3-sphinxcontrib.bibtex python3-pip
-
-Then, install the Python3 Antlr4 package:
-
- pip3 install antlr4-python3-runtime
-
-Nix users should get the correct development environment to build the
-HTML documentation from Coq's `default.nix`. [Note Nix setup doesn't
-include the LaTeX packages needed to build the full documentation.]
-
-If you are in an older/different distribution you can install the
-Python packages required to build the user manual using python3-pip:
-
- pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect sphinxcontrib-bibtex
-
-Compilation
------------
-
-To produce all documentation about Coq, just run:
-
- ./configure (if you hadn't already)
- make doc
-
-
-Alternatively, you can use some specific targets:
-
- make doc-ps
- to produce all PostScript documents
-
- make doc-pdf
- to produce all PDF documents
-
- make doc-html
- to produce all html documents
-
- make sphinx
- to produce the HTML version of the reference manual
-
- make stdlib
- to produce all formats of the Coq standard library
-
-
-Also note the "-with-doc yes" option of ./configure to enable the
-build of the documentation as part of the default make target.
-
-
-Installation
-------------
-
-To install all produced documents, do:
-
- make DOCDIR=/some/directory/for/documentation install-doc
-
-DOCDIR defaults to /usr/share/doc/coq
diff --git a/INSTALL.ide b/INSTALL.ide
deleted file mode 100644
index 26c192baa..000000000
--- a/INSTALL.ide
+++ /dev/null
@@ -1,123 +0,0 @@
- CoqIde Installation procedure
-
-CoqIde is a graphical interface to perform interactive proofs.
-You should be able to do everything you do in coqtop inside CoqIde
-excepted dropping to the ML toplevel.
-
-
-DISTRIBUTION PACKAGES
-
-Your POSIX operating system may already contain precompiled packages
-for Coq, including CoqIde, or a ready-to-compile... If the version
-provided there suits you, follow the usual procedure for your
-operating system.
-
-E.g., on Debian GNU/Linux (or Debian GNU/k*BSD or ...), do:
- aptitude install coqide
-On Gentoo GNU/Linux, do:
- USE=ide emerge sci-mathematics/coq
-
-Else, read the rest of this document to compile your own CoqIde.
-
-
-COMPILATION REQUIREMENTS
-
-- OCaml >= 4.02.1 with native threads support.
-- make world must succeed.
-- The graphical toolkit GTK+ 2.x. See http://www.gtk.org.
- The official supported version is at least 2.24.x.
- You may still compile CoqIde with older versions and use all features.
- Run
-
- pkg-config --modversion gtk+-2.0
-
- to check your version.
- Do not forget to install the development headers packages.
-
- On Debian, installing lablgtk2 (see below) will automatically
- install GTK+. (But "aptitude install libgtk2.0-dev" will
- install GTK+ 2.x, should you need to force it for one reason
- or another.)
-- The OCaml bindings for GTK+ 2.x, lablgtk2 with support for gtksourceview2.
- You need at least version 2.18.3.
-
- Your distribution may contain precompiled packages. For example, for
- Debian, run
-
- aptitude install liblablgtksourceview2-ocaml-dev
-
- for Mandriva, run
-
- urpmi ocaml-lablgtk-devel
-
- If it does not, see http://lablgtk.forge.ocamlcore.org/
-
- The basic command installing lablgtk2 from the source package is:
-
- ./configure && make world && make install
-
- You must have write access to the OCaml standard library path.
- If this fails, read the README.
-
-
-INSTALLATION
-
-0) For optimal performance, OCaml must support native threads (aka pthreads).
- If this not the case, this means that Coq computations will be slow and
- "make ide" will fail. Use "make bin/coqide.byte" instead. To fix this
- problem, just recompile OCaml from source and configure OCaml with:
-
- "./configure --with-pthreads".
-
- In case you install over an existing copy of OCaml, you should better
- empty the OCaml installation directory.
-
-1) Go into your Coq source directory and, as usual, configure with:
-
- ./configure
-
- This should detect the ability of making CoqIde; check in the
- report printed by configure that ability to build CoqIde is detected.
-
- Then compile with
-
- make world
-
- and install with
-
- make install
-
- In case you are upgrading from an old version you may need to run
-
- make clean-ide
-
-2) You may now run bin/coqide
-
-
-NOTES
-
-There are three configuration files located in your $(XDG_CONFIG_HOME)/coq
-dir (defaulting to $HOME/.config/coq).
-
-- coqiderc is generated by coqide itself. It may be edited by hand or
- by using the Preference menu from coqide. It will be generated the first time
- you save your the preferences in Coqide.
-
-- coqide.keys is a standard Gtk2 accelerator dump. You may edit this file
- to change the default shortcuts for the menus.
-
-Read ide/FAQ for more informations.
-
-
-TROUBLESHOOTING
-
-- Problem with automatic templates
-
- Some users may experiment problems with unwanted automatic
- templates while using Coqide. This is due to a change in the
- modifiers keys available through GTK. The straightest way to get
- rid of the problem is to edit by hand your coqiderc (either
- /home/<user>/.config/coq/coqiderc under Linux, or
- C:\Documents and Settings\<user>\.config\coq\coqiderc under Windows)
- and replace any occurrence of MOD4 by MOD1.
-
diff --git a/Makefile b/Makefile
index 4787377ea..df5caf0b7 100644
--- a/Makefile
+++ b/Makefile
@@ -74,9 +74,11 @@ endef
## Files in the source tree
LEXFILES := $(call find, '*.mll')
+YACCFILES := $(call find, '*.mly')
export MLLIBFILES := $(call find, '*.mllib')
export MLPACKFILES := $(call find, '*.mlpack')
export ML4FILES := $(call find, '*.ml4')
+export MLGFILES := $(call find, '*.mlg')
export CFILES := $(call findindir, 'kernel/byterun', '*.c')
export MERLINFILES := $(call find, '.merlin')
@@ -90,7 +92,8 @@ EXISTINGMLI := $(call find, '*.mli')
## Files that will be generated
GENML4FILES:= $(ML4FILES:.ml4=.ml)
-export GENMLFILES:=$(LEXFILES:.mll=.ml) kernel/copcodes.ml
+GENMLGFILES:= $(MLGFILES:.mlg=.ml)
+export GENMLFILES:=$(LEXFILES:.mll=.ml) $(YACCFILES:.mly=.ml) $(GENMLGFILES) kernel/copcodes.ml
export GENHFILES:=kernel/byterun/coq_jumptbl.h
export GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES)
@@ -100,7 +103,7 @@ export GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES)
## More complex file lists
-export MLSTATICFILES := $(filter-out $(GENMLFILES) $(GENML4FILES), $(EXISTINGML))
+export MLSTATICFILES := $(filter-out $(GENMLFILES) $(GENML4FILES) $(GENMLGFILES), $(EXISTINGML))
export MLIFILES := $(sort $(GENMLIFILES) $(EXISTINGMLI))
include Makefile.common
@@ -153,7 +156,10 @@ endif
MAKE_OPTS := --warn-undefined-variable --no-builtin-rules
-submake: alienclean
+bin:
+ mkdir bin
+
+submake: alienclean | bin
$(MAKE) $(MAKE_OPTS) -f Makefile.build $(MAKECMDGOALS)
noconfig:
@@ -211,7 +217,7 @@ archclean: clean-ide optclean voclean
rm -f $(ALLSTDLIB).*
optclean:
- rm -f $(COQTOPEXE) $(CHICKEN) $(TOPBIN)
+ rm -f $(COQTOPEXE) $(CHICKEN) $(TOPBINOPT)
rm -f $(TOOLS) $(PRIVATEBINARIES) $(CSDPCERT)
find . -name '*.cmx' -o -name '*.cmx[as]' -o -name '*.[soa]' -o -name '*.so' | xargs rm -f
@@ -223,7 +229,7 @@ clean-ide:
rm -rf $(COQIDEAPP)
ml4clean:
- rm -f $(GENML4FILES)
+ rm -f $(GENML4FILES) $(GENMLGFILES)
depclean:
find . $(FIND_SKIP_DIRS) '(' -name '*.d' ')' -print | xargs rm -f
diff --git a/Makefile.build b/Makefile.build
index b85418243..cd145ae64 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -212,9 +212,17 @@ DEPFLAGS=$(LOCALINCLUDES)$(if $(filter plugins/%,$@),, -I ide -I ide/protocol)
ifeq ($(shell which codesign > /dev/null 2>&1 && echo $(ARCH)),Darwin)
LINKMETADATA=$(if $(filter $(PRIVATEBINARIES),$@),,-ccopt "-sectcreate __TEXT __info_plist config/Info-$(notdir $@).plist")
CODESIGN=$(if $(filter $(PRIVATEBINARIES),$@),true,codesign -s -)
+CODESIGN_HIDE=$(CODESIGN)
else
LINKMETADATA=
CODESIGN=true
+CODESIGN_HIDE=$(HIDE)true
+endif
+
+ifeq ($(STRIP),true)
+STRIP_HIDE=$(HIDE)true
+else
+STRIP_HIDE=$(STRIP)
endif
# Best OCaml compiler, used in a generic way
@@ -342,6 +350,7 @@ kernel/copcodes.ml: kernel/byterun/coq_instruct.h
GRAMBASEDEPS := grammar/q_util.cmi
GRAMCMO := grammar/q_util.cmo \
grammar/argextend.cmo grammar/tacextend.cmo grammar/vernacextend.cmo
+COQPPCMO := grammar/coqpp_parse.cmo grammar/coqpp_lex.cmo
grammar/argextend.cmo : $(GRAMBASEDEPS)
grammar/q_util.cmo : $(GRAMBASEDEPS)
@@ -349,6 +358,10 @@ grammar/tacextend.cmo : $(GRAMBASEDEPS) grammar/argextend.cmo
grammar/vernacextend.cmo : $(GRAMBASEDEPS) grammar/tacextend.cmo \
grammar/argextend.cmo
+grammar/coqpp_parse.cmi: grammar/coqpp_ast.cmi
+grammar/coqpp_parse.cmo: grammar/coqpp_ast.cmi grammar/coqpp_parse.cmi
+grammar/coqpp_lex.cmo: grammar/coqpp_ast.cmi grammar/coqpp_parse.cmo
+
## Ocaml compiler with the right options and -I for grammar
GRAMC := $(OCAMLFIND) ocamlc $(CAMLFLAGS) $(CAMLDEBUG) $(USERFLAGS) \
@@ -359,11 +372,15 @@ GRAMC := $(OCAMLFIND) ocamlc $(CAMLFLAGS) $(CAMLDEBUG) $(USERFLAGS) \
grammar/grammar.cma : $(GRAMCMO)
$(SHOW)'Testing $@'
@touch grammar/test.mlp
- $(HIDE)$(GRAMC) -pp '$(CAMLP5O) -I $(MYCAMLP5LIB) $^ -impl' -impl grammar/test.mlp -o grammar/test
+ $(HIDE)$(GRAMC) -pp '$(CAMLP5O) $^ -impl' -impl grammar/test.mlp -o grammar/test
@rm -f grammar/test.* grammar/test
$(SHOW)'OCAMLC -a $@'
$(HIDE)$(GRAMC) $^ -linkall -a -o $@
+grammar/coqpp: $(COQPPCMO) grammar/coqpp_main.ml
+ $(SHOW)'OCAMLC -a $@'
+ $(HIDE)$(GRAMC) $^ -linkall -o $@
+
## Support of Camlp5 and Camlp5
COMPATCMO:=
@@ -376,6 +393,10 @@ grammar/%.cmo: grammar/%.mlp | $(COMPATCMO)
$(SHOW)'OCAMLC -c -pp $<'
$(HIDE)$(GRAMC) -c -pp '$(GRAMPP)' -impl $<
+grammar/%.cmo: grammar/%.ml | $(COMPATCMO)
+ $(SHOW)'OCAMLC -c -pp $<'
+ $(HIDE)$(GRAMC) -c $<
+
grammar/%.cmi: grammar/%.mli
$(SHOW)'OCAMLC -c $<'
$(HIDE)$(GRAMC) -c $<
@@ -387,20 +408,21 @@ grammar/%.cmi: grammar/%.mli
.PHONY: coqbinaries coqbyte
-coqbinaries: $(TOPBIN) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbinaries: $(TOPBINOPT) $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
coqbyte: $(TOPBYTE) $(CHICKENBYTE)
-# Special rule for coqtop
-$(COQTOPEXE): $(TOPBIN:.opt=.$(BEST))
- cp $< $@
+# Special rule for coqtop, we imitate `ocamlopt` can delete the target
+# to avoid #7666
+$(COQTOPEXE): $(TOPBINOPT:.opt=.$(BEST))
+ rm -f $@ && cp $< $@
bin/%.opt$(EXE): topbin/%_bin.ml $(LINKCMX) $(LIBCOQRUN)
$(SHOW)'COQMKTOP -o $@'
$(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) \
$(SYSMOD) -package camlp5.gramlib \
$(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
- $(STRIP) $@
- $(CODESIGN) $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
bin/%.byte$(EXE): topbin/%_bin.ml $(LINKCMO) $(LIBCOQRUN)
$(SHOW)'COQMKTOP -o $@'
@@ -493,14 +515,6 @@ $(COQDEPBYTE): $(COQDEPCMO)
$(SHOW)'OCAMLC -o $@'
$(HIDE)$(call ocamlbyte, $(SYSMOD))
-$(GALLINA): $(call bestobj, tools/gallina_lexer.cmo tools/gallina.cmo)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,)
-
-$(GALLINABYTE): tools/gallina_lexer.cmo tools/gallina.cmo
- $(SHOW)'OCAMLC -o $@'
- $(HIDE)$(call ocamlbyte,)
-
COQMAKEFILECMO:=clib/clib.cma lib/lib.cma tools/coq_makefile.cmo
$(COQMAKEFILE): $(call bestobj,$(COQMAKEFILECMO))
@@ -746,11 +760,18 @@ plugins/%.cmx: plugins/%.ml
$(SHOW)'OCAMLLEX $<'
$(HIDE)$(OCAMLLEX) -o $@ "$*.mll"
-%.ml: %.ml4 $(CAMLP5DEPS)
+%.ml %.mli: %.mly
+ $(SHOW)'OCAMLYACC $<'
+ $(HIDE)$(OCAMLYACC) --strict "$*.mly"
+
+%.ml: %.ml4 $(CAMLP5DEPS) grammar/coqpp
$(SHOW)'CAMLP5O $<'
$(HIDE)$(CAMLP5O) -I $(MYCAMLP5LIB) $(PR_O) \
$(CAMLP5DEPS) $(CAMLP5USE) $(CAMLP5COMPAT) -impl $< -o $@
+%.ml: %.mlg grammar/coqpp
+ $(SHOW)'COQPP $<'
+ $(HIDE)grammar/coqpp $<
###########################################################################
# Dependencies of ML code
diff --git a/Makefile.checker b/Makefile.checker
index 0ec565d61..6c19a1a42 100644
--- a/Makefile.checker
+++ b/Makefile.checker
@@ -52,8 +52,8 @@ ifeq ($(BEST),opt)
$(CHICKEN): checker/check.cmxa checker/main.mli checker/main.ml
$(SHOW)'OCAMLOPT -o $@'
$(HIDE)$(OCAMLOPT) -linkpkg $(SYSMOD) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -o $@ $^
- $(STRIP) $@
- $(CODESIGN) $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
else
$(CHICKEN): $(CHICKENBYTE)
cp $< $@
diff --git a/Makefile.ci b/Makefile.ci
index 7f63157fa..fce16906c 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -8,7 +8,8 @@
## # (see LICENSE file for the text of the license) ##
##########################################################################
-CI_TARGETS=ci-bignums \
+CI_TARGETS=ci-bedrock2 \
+ ci-bignums \
ci-color \
ci-compcert \
ci-coq-dpdgraph \
diff --git a/Makefile.common b/Makefile.common
index 5b1def40a..96d0d2ed8 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -14,8 +14,8 @@
# Executables
###########################################################################
-TOPBIN:=$(addsuffix .opt$(EXE), $(addprefix bin/, coqtop coqproofworker coqtacticworker coqqueryworker))
-TOPBYTE:=$(TOPBIN:.opt$(EXE)=.byte$(EXE))
+TOPBINOPT:=$(addsuffix .opt$(EXE), $(addprefix bin/, coqtop coqproofworker coqtacticworker coqqueryworker))
+TOPBYTE:=$(TOPBINOPT:.opt$(EXE)=.byte$(EXE))
COQTOPEXE:=bin/coqtop$(EXE)
COQTOPBYTE:=bin/coqtop.byte$(EXE)
@@ -24,8 +24,6 @@ COQDEP:=bin/coqdep$(EXE)
COQDEPBYTE:=bin/coqdep.byte$(EXE)
COQMAKEFILE:=bin/coq_makefile$(EXE)
COQMAKEFILEBYTE:=bin/coq_makefile.byte$(EXE)
-GALLINA:=bin/gallina$(EXE)
-GALLINABYTE:=bin/gallina.byte$(EXE)
COQTEX:=bin/coq-tex$(EXE)
COQTEXBYTE:=bin/coq-tex.byte$(EXE)
COQWC:=bin/coqwc$(EXE)
@@ -41,7 +39,7 @@ COQTIME_FILE_MAKER:=tools/TimeFileMaker.py
COQMAKE_BOTH_TIME_FILES:=tools/make-both-time-files.py
COQMAKE_BOTH_SINGLE_TIMING_FILES:=tools/make-both-single-timing-files.py
-TOOLS:=$(COQDEP) $(COQMAKEFILE) $(GALLINA) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
+TOOLS:=$(COQDEP) $(COQMAKEFILE) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
$(COQWORKMGR)
TOOLS_HELPERS:=tools/CoqMakefile.in $(COQMAKE_ONE_TIME_FILE) $(COQTIME_FILE_MAKER)\
$(COQMAKE_BOTH_TIME_FILES) $(COQMAKE_BOTH_SINGLE_TIMING_FILES)
@@ -143,8 +141,8 @@ BTAUTOCMO:=plugins/btauto/btauto_plugin.cmo
RTAUTOCMO:=plugins/rtauto/rtauto_plugin.cmo
NATSYNTAXCMO:=plugins/syntax/nat_syntax_plugin.cmo
OTHERSYNTAXCMO:=$(addprefix plugins/syntax/, \
- z_syntax_plugin.cmo \
- r_syntax_plugin.cmo \
+ positive_syntax_plugin.cmo n_syntax_plugin.cmo \
+ z_syntax_plugin.cmo r_syntax_plugin.cmo \
int31_syntax_plugin.cmo \
ascii_syntax_plugin.cmo \
string_syntax_plugin.cmo )
diff --git a/Makefile.ide b/Makefile.ide
index 6bb0f62f3..cb5596020 100644
--- a/Makefile.ide
+++ b/Makefile.ide
@@ -99,7 +99,7 @@ $(COQIDE): $(LINKIDEOPT)
$(SHOW)'OCAMLOPT -o $@'
$(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
-linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
+ $(STRIP_HIDE) $@
else
$(COQIDE): $(COQIDEBYTE)
cp $< $@
@@ -149,8 +149,8 @@ $(IDETOP): ide/idetop.ml $(LINKCMX) $(LIBCOQRUN) $(IDETOPCMX)
$(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) -I ide -I ide/protocol/ \
$(SYSMOD) -package camlp5.gramlib \
$(LINKCMX) $(IDETOPCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
- $(STRIP) $@
- $(CODESIGN) $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
$(IDETOPBYTE): ide/idetop.ml $(LINKCMO) $(LIBCOQRUN) $(IDETOPCMA)
$(SHOW)'COQMKTOP -o $@'
@@ -229,7 +229,7 @@ $(COQIDEINAPP): ide/macos_prehook.cmx $(LINKIDEOPT) | $(COQIDEAPP)/Contents
$(SHOW)'OCAMLOPT -o $@'
$(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
-linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
+ $(STRIP_HIDE) $@
$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
$(MKDIR) $@/coq/
@@ -275,7 +275,7 @@ $(COQIDEAPP)/Contents/Resources:$(COQIDEAPP)/Contents/Resources/etc $(COQIDEAPP)
$(INSTALLLIB) ide/MacOS/*.icns $@
$(COQIDEAPP):$(COQIDEAPP)/Contents/Resources
- $(CODESIGN) $@
+ $(CODESIGN_HIDE) $@
###########################################################################
# CoqIde for Windows special targets
diff --git a/Makefile.install b/Makefile.install
index 010e35d42..be6fe5493 100644
--- a/Makefile.install
+++ b/Makefile.install
@@ -43,7 +43,6 @@ FULLCOQLIB=$(COQLIBINSTALL:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
FULLCONFIGDIR=$(CONFIGDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
FULLDATADIR=$(DATADIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
FULLMANDIR=$(MANDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLEMACSLIB=$(EMACSLIB:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
FULLCOQDOCDIR=$(COQDOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
FULLDOCDIR=$(DOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
else
@@ -52,14 +51,13 @@ FULLCOQLIB=$(COQLIBINSTALL)
FULLCONFIGDIR=$(CONFIGDIR)
FULLDATADIR=$(DATADIR)
FULLMANDIR=$(MANDIR)
-FULLEMACSLIB=$(EMACSLIB)
FULLCOQDOCDIR=$(COQDOCDIR)
FULLDOCDIR=$(DOCDIR)
endif
.PHONY: install-coq install-binaries install-byte install-opt
.PHONY: install-tools install-library install-devfiles install-merlin
-.PHONY: install-coq-info install-coq-manpages install-emacs install-latex
+.PHONY: install-coq-info install-coq-manpages install-latex
.PHONY: install-meta
install-coq: install-binaries install-library install-coq-info install-devfiles
@@ -70,7 +68,7 @@ endif
install-binaries: install-tools
$(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQC) $(CHICKEN) $(COQTOPEXE) $(TOPBIN) $(FULLBINDIR)
+ $(INSTALLBIN) $(COQC) $(CHICKEN) $(COQTOPEXE) $(TOPBINOPT) $(FULLBINDIR)
install-byte: install-coqide-byte
$(MKDIR) $(FULLBINDIR)
@@ -136,9 +134,9 @@ endif
rm -f $(FULLCOQLIB)/revision
-$(INSTALLLIB) revision $(FULLCOQLIB)
-install-coq-info: install-coq-manpages install-emacs install-latex
+install-coq-info: install-coq-manpages install-latex
-MANPAGES:=man/coq-tex.1 man/coqdep.1 man/gallina.1 \
+MANPAGES:=man/coq-tex.1 man/coqdep.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/coqchk.1
@@ -147,10 +145,6 @@ install-coq-manpages:
$(MKDIR) $(FULLMANDIR)/man1
$(INSTALLLIB) $(MANPAGES) $(FULLMANDIR)/man1
-install-emacs:
- $(MKDIR) $(FULLEMACSLIB)
- $(INSTALLLIB) tools/gallina-db.el tools/coq-font-lock.el tools/gallina-syntax.el tools/gallina.el tools/inferior-coq.el $(FULLEMACSLIB)
-
# command to update TeX' kpathsea database
#UPDATETEX = $(MKTEXLSR) /usr/share/texmf /var/spool/texmf $(BASETEXDIR) > /dev/null
diff --git a/README.md b/README.md
index 0903abdd4..67f4f6fea 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,9 @@ or refer to the [`INSTALL` file](INSTALL) for the procedure to install from sour
## Documentation
-The sources of the documentation can be found in directory [`doc`](doc). The
+The sources of the documentation can be found in directory [`doc`](doc).
+See [`doc/README.md`](/doc/README.md) to learn more about the documentation,
+in particular how to build it. The
documentation of the last released version is available on the Coq
web site at [coq.inria.fr/documentation](http://coq.inria.fr/documentation).
See also [Cocorico](https://github.com/coq/coq/wiki) (the Coq wiki),
@@ -54,3 +56,11 @@ used, and include a complete source example leading to the bug.
## Contributing
Guidelines for contributing to Coq in various ways are listed in the [contributor's guide](CONTRIBUTING.md).
+
+## Supporting Coq
+
+Help the Coq community grow and prosper by becoming a sponsor! The [Coq
+Consortium](https://coq.inria.fr/consortium) can establish sponsorship contracts
+or receive donations. If you want to take an active role in shaping Coq's
+future, you can also become a Consortium member. If you are interested, please
+get in touch!
diff --git a/checker/cic.mli b/checker/cic.mli
index 3304b032e..4846a9af8 100644
--- a/checker/cic.mli
+++ b/checker/cic.mli
@@ -33,11 +33,10 @@ open Names
(** {6 The sorts of CCI. } *)
-type contents = Pos | Null
-
type sorts =
- | Prop of contents (** Prop and Set *)
- | Type of Univ.universe (** Type *)
+ | Prop
+ | Set
+ | Type of Univ.universe
(** {6 The sorts family of CCI. } *)
@@ -207,7 +206,7 @@ type inline = int option
always transparent. *)
type projection_body = {
- proj_ind : MutInd.t;
+ proj_ind : inductive;
proj_npars : int;
proj_arg : int;
proj_type : constr; (* Type under params *)
@@ -252,9 +251,10 @@ type recarg =
type wf_paths = recarg Rtree.t
-type record_body = (Id.t * Constant.t array * projection_body array) option
- (* The body is empty for non-primitive records, otherwise we get its
- binder name in projections and list of projections if it is primitive. *)
+type record_info =
+| NotRecord
+| FakeRecord
+| PrimRecord of (Id.t * Constant.t array * projection_body array) array
type regular_inductive_arity = {
mind_user_arity : constr;
@@ -322,7 +322,7 @@ type mutual_inductive_body = {
mind_packets : one_inductive_body array; (** The component of the mutual inductive block *)
- mind_record : record_body option; (** Whether the inductive type has been declared as a record. *)
+ mind_record : record_info; (** Whether the inductive type has been declared as a record. *)
mind_finite : recursivity_kind; (** Whether the type is inductive or coinductive *)
diff --git a/checker/closure.ml b/checker/closure.ml
index b9ae4daa8..2dcc1a984 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -619,7 +619,8 @@ let drop_parameters depth n argstk =
let eta_expand_ind_stack env ind m s (f, s') =
let mib = lookup_mind (fst ind) env in
match mib.mind_record with
- | Some (Some (_,projs,pbs)) when mib.mind_finite <> CoFinite ->
+ | PrimRecord info when mib.mind_finite <> CoFinite ->
+ let (_, projs, pbs) = info.(snd ind) in
(* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
arg1..argn ~= (proj1 t...projn t) where t = zip (f,s') *)
let pars = mib.mind_nparams in
diff --git a/checker/environ.ml b/checker/environ.ml
index 3d5fac806..ba1eb0ddb 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -192,11 +192,12 @@ let add_mind kn mib env =
(MutInd.to_string kn);
let new_inds = Mindmap_env.add kn mib env.env_globals.env_inductives in
let new_projections = match mib.mind_record with
- | None | Some None -> env.env_globals.env_projections
- | Some (Some (id, kns, pbs)) ->
- Array.fold_left2 (fun projs kn pb ->
- Cmap_env.add kn pb projs)
- env.env_globals.env_projections kns pbs
+ | NotRecord | FakeRecord -> env.env_globals.env_projections
+ | PrimRecord projs ->
+ Array.fold_left (fun accu (id, kns, pbs) ->
+ Array.fold_left2 (fun accu kn pb ->
+ Cmap_env.add kn pb accu) accu kns pbs)
+ env.env_globals.env_projections projs
in
let kn1,kn2 = MutInd.user kn, MutInd.canonical kn in
let new_inds_eq = if KerName.equal kn1 kn2 then
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index 916934a81..8f11e01c3 100644
--- a/checker/indtypes.ml
+++ b/checker/indtypes.ml
@@ -107,11 +107,11 @@ let rec sorts_of_constr_args env t =
(* Prop and Set are small *)
let is_small_sort = function
- | Prop _ -> true
+ | Prop | Set -> true
| _ -> false
let is_logic_sort = function
-| Prop Null -> true
+| Prop -> true
| _ -> false
(* [infos] is a sequence of pair [islogic,issmall] for each type in
@@ -186,10 +186,10 @@ let check_predicativity env s small level =
(* (universes env) in *)
if not (Univ.check_leq (universes env) level u) then
failwith "impredicative Type inductive type"
- | Prop Pos, ImpredicativeSet -> ()
- | Prop Pos, _ ->
+ | Set, ImpredicativeSet -> ()
+ | Set, _ ->
if not small then failwith "impredicative Set inductive type"
- | Prop Null,_ -> ()
+ | Prop,_ -> ()
let sort_of_ind = function
@@ -221,7 +221,7 @@ let allowed_sorts issmall isunit s =
-let compute_elim_sorts env_ar params mib arity lc =
+let compute_elim_sorts env_ar params arity lc =
let inst = extended_rel_list 0 params in
let env_params = push_rel_context params env_ar in
let lc = Array.map
@@ -239,7 +239,7 @@ let compute_elim_sorts env_ar params mib arity lc =
allowed_sorts small unit s
-let typecheck_one_inductive env params mib mip =
+let typecheck_one_inductive env params mip =
(* mind_typename and mind_consnames not checked *)
(* mind_reloc_tbl, mind_nb_constant, mind_nb_args not checked (VM) *)
(* mind_arity_ctxt, mind_arity, mind_nrealargs DONE (typecheck_arity) *)
@@ -256,7 +256,7 @@ let typecheck_one_inductive env params mib mip =
Array.iter2 check_cons_args mip.mind_nf_lc mip.mind_consnrealdecls;
(* mind_kelim: checked by positivity criterion ? *)
let sorts =
- compute_elim_sorts env params mib mip.mind_arity mip.mind_nf_lc in
+ compute_elim_sorts env params mip.mind_arity mip.mind_nf_lc in
let reject_sort s = not (List.mem_f family_equal s sorts) in
if List.exists reject_sort mip.mind_kelim then
failwith "elimination not allowed";
@@ -355,7 +355,7 @@ let lambda_implicit_lift n a =
(* This removes global parameters of the inductive types in lc (for
nested inductive types only ) *)
-let abstract_mind_lc env ntyps npars lc =
+let abstract_mind_lc ntyps npars lc =
if npars = 0 then
lc
else
@@ -448,7 +448,7 @@ let check_positivity_one (env, _,ntypes,_ as ienv) hyps nrecp (_,i as ind) indlc
let auxntyp = mib.mind_ntypes in
if auxntyp <> 1 then raise (IllFormedInd (LocalNonPos n));
(* The nested inductive type with parameters removed *)
- let auxlcvect = abstract_mind_lc env auxntyp auxnpar mip.mind_nf_lc in
+ let auxlcvect = abstract_mind_lc auxntyp auxnpar mip.mind_nf_lc in
(* Extends the environment with a variable corresponding to
the inductive def *)
let (env',_,_,_ as ienv') = ienv_push_inductive ienv ((mi,u),lpar) in
@@ -625,7 +625,7 @@ let check_inductive env kn mib =
(* - check arities *)
let env_ar = typecheck_arity env0 params mib.mind_packets in
(* - check constructor types *)
- Array.iter (typecheck_one_inductive env_ar params mib) mib.mind_packets;
+ Array.iter (typecheck_one_inductive env_ar params) mib.mind_packets;
(* check the inferred subtyping relation *)
let () =
match mib.mind_universes with
diff --git a/checker/inductive.ml b/checker/inductive.ml
index e1c6b135d..d15380643 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -101,7 +101,7 @@ let instantiate_params full t u args sign =
substl subs ty
let full_inductive_instantiate mib u params sign =
- let dummy = Prop Null in
+ let dummy = Prop in
let t = mkArity (Term.subst_instance_context u sign,dummy) in
fst (destArity (instantiate_params true t u params mib.mind_params_ctxt))
@@ -137,8 +137,8 @@ Remark: Set (predicative) is encoded as Type(0)
let sort_as_univ = function
| Type u -> u
-| Prop Null -> Univ.type0m_univ
-| Prop Pos -> Univ.type0_univ
+| Prop -> Univ.type0m_univ
+| Set -> Univ.type0_univ
(* cons_subst add the mapping [u |-> su] in subst if [u] is not *)
(* in the domain or add [u |-> sup x su] if [u] is already mapped *)
@@ -195,9 +195,9 @@ let instantiate_universes env ctx ar argsorts =
let level = Univ.subst_univs_universe (Univ.make_subst subst) ar.template_level in
let ty =
(* Singleton type not containing types are interpretable in Prop *)
- if Univ.is_type0m_univ level then Prop Null
+ if Univ.is_type0m_univ level then Prop
(* Non singleton type not containing types are interpretable in Set *)
- else if Univ.is_type0_univ level then Prop Pos
+ else if Univ.is_type0_univ level then Set
(* This is a Type with constraints *)
else Type level
in
@@ -226,8 +226,8 @@ let type_of_inductive env mip =
(* The max of an array of universes *)
let cumulate_constructor_univ u = function
- | Prop Null -> u
- | Prop Pos -> Univ.sup Univ.type0_univ u
+ | Prop -> u
+ | Set -> Univ.sup Univ.type0_univ u
| Type u' -> Univ.sup u u'
let max_inductive_sort =
@@ -797,7 +797,7 @@ let rec subterm_specif renv stack t =
| Lambda (x,a,b) ->
assert (l=[]);
- let spec,stack' = extract_stack renv a stack in
+ let spec,stack' = extract_stack stack in
subterm_specif (push_var renv (x,a,spec)) stack' b
(* Metas and evars are considered OK *)
@@ -813,7 +813,7 @@ and stack_element_specif = function
|SClosure (h_renv,h) -> lazy_subterm_specif h_renv [] h
|SArg x -> x
-and extract_stack renv a = function
+and extract_stack = function
| [] -> Lazy.from_val Not_subterm , []
| h::t -> stack_element_specif h, t
@@ -845,7 +845,7 @@ let error_illegal_rec_call renv fx (arg_renv,arg) =
let error_partial_apply renv fx =
raise (FixGuardError (renv.env,NotEnoughArgumentsForFixCall fx))
-let filter_stack_domain env ci p stack =
+let filter_stack_domain env p stack =
let absctx, ar = dest_lam_assum env p in
(* Optimization: if the predicate is not dependent, no restriction is needed
and we avoid building the recargs tree. *)
@@ -925,7 +925,7 @@ let check_one_fix renv recpos trees def =
let case_spec = branches_specif renv
(lazy_subterm_specif renv [] c_0) ci in
let stack' = push_stack_closures renv l stack in
- let stack' = filter_stack_domain renv.env ci p stack' in
+ let stack' = filter_stack_domain renv.env p stack' in
Array.iteri (fun k br' ->
let stack_br = push_stack_args case_spec.(k) stack' in
check_rec_call renv stack_br br') lrest
@@ -968,7 +968,7 @@ let check_one_fix renv recpos trees def =
| Lambda (x,a,b) ->
assert (l = []);
check_rec_call renv [] a ;
- let spec, stack' = extract_stack renv a stack in
+ let spec, stack' = extract_stack stack in
check_rec_call (push_var renv (x,a,spec)) stack' b
| Prod (x,a,b) ->
diff --git a/checker/mod_checking.ml b/checker/mod_checking.ml
index ca9581167..6b2af71f3 100644
--- a/checker/mod_checking.ml
+++ b/checker/mod_checking.ml
@@ -2,7 +2,6 @@ open Pp
open Util
open Names
open Cic
-open Term
open Reduction
open Typeops
open Indtypes
@@ -13,17 +12,6 @@ open Environ
(** {6 Checking constants } *)
-let refresh_arity ar =
- let ctxt, hd = decompose_prod_assum ar in
- match hd with
- Sort (Type u) when not (Univ.is_univ_variable u) ->
- let ul = Univ.Level.make DirPath.empty 1 in
- let u' = Univ.Universe.make ul in
- let cst = Univ.enforce_leq u u' Univ.empty_constraint in
- let ctx = Univ.ContextSet.make (Univ.LSet.singleton ul) cst in
- mkArity (ctxt,Prop Null), ctx
- | _ -> ar, Univ.ContextSet.empty
-
let check_constant_declaration env kn cb =
Flags.if_verbose Feedback.msg_notice (str " checking cst:" ++ prcon kn);
(** Locally set the oracle for further typechecking *)
@@ -37,18 +25,13 @@ let check_constant_declaration env kn cb =
let ctx = Univ.AUContext.repr auctx in
push_context ~strict:false ctx env
in
- let envty, ty =
- let ty = cb.const_type in
- let ty', cu = refresh_arity ty in
- let envty = push_context_set cu env' in
- let _ = infer_type envty ty' in
- envty, ty
- in
- let () =
+ let ty = cb.const_type in
+ let _ = infer_type env' ty in
+ let () =
match body_of_constant cb with
| Some bd ->
- let j = infer envty bd in
- conv_leq envty j ty
+ let j = infer env' bd in
+ conv_leq env' j ty
| None -> ()
in
let env =
diff --git a/checker/modops.ml b/checker/modops.ml
index c7ad0977a..b92d7bbf1 100644
--- a/checker/modops.ml
+++ b/checker/modops.ml
@@ -80,7 +80,7 @@ and add_module mb env =
let add_module_type mp mtb env = add_module (module_body_of_type mp mtb) env
-let strengthen_const mp_from l cb resolver =
+let strengthen_const mp_from l cb =
match cb.const_body with
| Def _ -> cb
| _ ->
@@ -104,34 +104,34 @@ and strengthen_body : 'a. (_ -> 'a) -> _ -> _ -> 'a generic_module_body -> 'a ge
match mb.mod_type with
| MoreFunctor _ -> mb
| NoFunctor sign ->
- let resolve_out,sign_out = strengthen_sig mp_from sign mp_to mb.mod_delta
+ let resolve_out,sign_out = strengthen_sig mp_from sign mp_to
in
{ mb with
mod_expr = mk_expr mp_to;
mod_type = NoFunctor sign_out;
mod_delta = resolve_out }
-and strengthen_sig mp_from sign mp_to resolver =
+and strengthen_sig mp_from sign mp_to =
match sign with
| [] -> empty_delta_resolver,[]
| (l,SFBconst cb) :: rest ->
- let item' = l,SFBconst (strengthen_const mp_from l cb resolver) in
- let resolve_out,rest' = strengthen_sig mp_from rest mp_to resolver in
+ let item' = l,SFBconst (strengthen_const mp_from l cb) in
+ let resolve_out,rest' = strengthen_sig mp_from rest mp_to in
resolve_out,item'::rest'
| (_,SFBmind _ as item):: rest ->
- let resolve_out,rest' = strengthen_sig mp_from rest mp_to resolver in
+ let resolve_out,rest' = strengthen_sig mp_from rest mp_to in
resolve_out,item::rest'
| (l,SFBmodule mb) :: rest ->
let mp_from' = MPdot (mp_from,l) in
let mp_to' = MPdot(mp_to,l) in
let mb_out = strengthen_mod mp_from' mp_to' mb in
let item' = l,SFBmodule (mb_out) in
- let resolve_out,rest' = strengthen_sig mp_from rest mp_to resolver in
+ let resolve_out,rest' = strengthen_sig mp_from rest mp_to in
resolve_out (*add_delta_resolver resolve_out mb.mod_delta*),
- item':: rest'
- | (l,SFBmodtype mty as item) :: rest ->
- let resolve_out,rest' = strengthen_sig mp_from rest mp_to resolver in
- resolve_out,item::rest'
+ item':: rest'
+ | (_,SFBmodtype _ as item) :: rest ->
+ let resolve_out,rest' = strengthen_sig mp_from rest mp_to in
+ resolve_out,item::rest'
let strengthen mtb mp =
strengthen_body ignore mtb.mod_mp mp mtb
diff --git a/checker/print.ml b/checker/print.ml
index fc9cd687e..247c811f8 100644
--- a/checker/print.ml
+++ b/checker/print.ml
@@ -57,8 +57,8 @@ let print_pure_constr fmt csr =
fprintf fmt "Proj(%a,@,@[%a@])" sp_con_display (Projection.constant p) pp_term c
and pp_sort fmt = function
- | Prop(Pos) -> pp_print_string fmt "Set"
- | Prop(Null) -> pp_print_string fmt "Prop"
+ | Set -> pp_print_string fmt "Set"
+ | Prop -> pp_print_string fmt "Prop"
| Type u -> fprintf fmt "Type(%a)" chk_pp (Univ.pr_uni u)
and pp_name fmt = function
diff --git a/checker/reduction.ml b/checker/reduction.ml
index 4e508dc77..16c701213 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -210,29 +210,26 @@ let convert_constructors
let sort_cmp env univ pb s0 s1 =
match (s0,s1) with
- | (Prop c1, Prop c2) when pb = CUMUL -> if c1 = Pos && c2 = Null then raise NotConvertible
- | (Prop c1, Prop c2) -> if c1 <> c2 then raise NotConvertible
- | (Prop c1, Type u) ->
+ | Prop, Prop | Set, Set -> ()
+ | Prop, (Set | Type _) | Set, Type _ ->
+ if not (pb = CUMUL) then raise NotConvertible
+ | Type u1, Type u2 ->
+ (** FIXME: handle type-in-type option here *)
+ if (* snd (engagement env) == StratifiedType && *)
+ not
(match pb with
- CUMUL -> ()
- | _ -> raise NotConvertible)
- | (Type u1, Type u2) ->
- (** FIXME: handle type-in-type option here *)
- if (* snd (engagement env) == StratifiedType && *)
- not
- (match pb with
- | CONV -> Univ.check_eq univ u1 u2
- | CUMUL -> Univ.check_leq univ u1 u2)
- then begin
- if !Flags.debug then begin
- let op = match pb with CONV -> "=" | CUMUL -> "<=" in
- Format.eprintf "sort_cmp: @[%a@]\n%!" Pp.pp_with Pp.(
- str"Error: " ++ Univ.pr_uni u1 ++ str op ++ Univ.pr_uni u2 ++ str ":" ++ cut()
- ++ Univ.pr_universes univ)
- end;
- raise NotConvertible
- end
- | (_, _) -> raise NotConvertible
+ | CONV -> Univ.check_eq univ u1 u2
+ | CUMUL -> Univ.check_leq univ u1 u2)
+ then begin
+ if !Flags.debug then begin
+ let op = match pb with CONV -> "=" | CUMUL -> "<=" in
+ Format.eprintf "sort_cmp: @[%a@]\n%!" Pp.pp_with Pp.(
+ str"Error: " ++ Univ.pr_uni u1 ++ str op ++ Univ.pr_uni u2 ++ str ":" ++ cut()
+ ++ Univ.pr_universes univ)
+ end;
+ raise NotConvertible
+ end
+ | Set, Prop | Type _, (Prop | Set) -> raise NotConvertible
let rec no_arg_available = function
| [] -> true
diff --git a/checker/subtyping.ml b/checker/subtyping.ml
index f4ae02084..3f7f84470 100644
--- a/checker/subtyping.ml
+++ b/checker/subtyping.ml
@@ -9,7 +9,6 @@
(************************************************************************)
(*i*)
-open CErrors
open Util
open Names
open Cic
@@ -126,46 +125,13 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
in
let eq_projection_body p1 p2 =
let check eq f = if not (eq (f p1) (f p2)) then error () in
- check MutInd.equal (fun x -> x.proj_ind);
+ check eq_ind (fun x -> x.proj_ind);
check (==) (fun x -> x.proj_npars);
check (==) (fun x -> x.proj_arg);
check (eq_constr) (fun x -> x.proj_type);
true
in
- let check_inductive_type t1 t2 =
-
- (* Due to template polymorphism, the conclusions of
- t1 and t2, if in Type, are generated as the least upper bounds
- of the types of the constructors.
-
- By monotonicity of the infered l.u.b. wrt subtyping (i.e. if X:U
- |- T(X):s and |- M:U' and U'<=U then infer_type(T(M))<=s), each
- universe in the conclusion of t1 has an bounding universe in
- the conclusion of t2, so that we don't need to check the
- subtyping of the conclusions of t1 and t2.
-
- Even if we'd like to recheck it, the inference of constraints
- is not designed to deal with algebraic constraints of the form
- max-univ(u1..un) <= max-univ(u'1..u'n), so that it is not easy
- to recheck it (in short, we would need the actual graph of
- constraints as input while type checking is currently designed
- to output a set of constraints instead) *)
-
- (* So we cheat and replace the subtyping problem on algebraic
- constraints of the form max-univ(u1..un) <= max-univ(u'1..u'n)
- (that we know are necessary true) by trivial constraints that
- the constraint generator knows how to deal with *)
-
- let (ctx1,s1) = dest_arity env t1 in
- let (ctx2,s2) = dest_arity env t2 in
- let s1,s2 =
- match s1, s2 with
- | Type _, Type _ -> (* shortcut here *) Prop Null, Prop Null
- | (Prop _, Type _) | (Type _,Prop _) -> error ()
- | _ -> (s1, s2) in
- check_conv conv_leq env
- (mkArity (ctx1,s1)) (mkArity (ctx2,s2))
- in
+ let check_inductive_type t1 t2 = check_conv conv_leq env t1 t2 in
let check_packet p1 p2 =
let check eq f = if not (eq (f p1) (f p2)) then error () in
@@ -218,16 +184,19 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
(* we check that records and their field names are preserved. *)
let record_equal x y =
match x, y with
- | None, None -> true
- | Some None, Some None -> true
- | Some (Some (id1,p1,pb1)), Some (Some (id2,p2,pb2)) ->
- Id.equal id1 id2 &&
- Array.for_all2 Constant.UserOrd.equal p1 p2 &&
- Array.for_all2 eq_projection_body pb1 pb2
+ | NotRecord, NotRecord -> true
+ | FakeRecord, FakeRecord -> true
+ | PrimRecord info1, PrimRecord info2 ->
+ let check (id1, p1, pb1) (id2, p2, pb2) =
+ Id.equal id1 id2 &&
+ Array.for_all2 Constant.UserOrd.equal p1 p2 &&
+ Array.for_all2 eq_projection_body pb1 pb2
+ in
+ Array.equal check info1 info2
| _, _ -> false
in
check record_equal (fun mib -> mib.mind_record);
- if mib1.mind_record != None then begin
+ if mib1.mind_record != NotRecord then begin
let rec names_prod_letin t = match t with
| Prod(n,_,t) -> n::(names_prod_letin t)
| LetIn(n,_,_,t) -> n::(names_prod_letin t)
@@ -248,55 +217,10 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
let _ = Array.map2_i check_cons_types mib1.mind_packets mib2.mind_packets
in ()
-let check_constant env mp1 l info1 cb2 spec2 subst1 subst2 =
+let check_constant env l info1 cb2 spec2 subst1 subst2 =
let error () = error_not_match l spec2 in
let check_conv f = check_conv_error error f in
- let check_type env t1 t2 =
-
- (* If the type of a constant is generated, it may mention
- non-variable algebraic universes that the general conversion
- algorithm is not ready to handle. Anyway, generated types of
- constants are functions of the body of the constant. If the
- bodies are the same in environments that are subtypes one of
- the other, the types are subtypes too (i.e. if Gamma <= Gamma',
- Gamma |- A |> T, Gamma |- A' |> T' and Gamma |- A=A' then T <= T').
- Hence they don't have to be checked again *)
-
- let t1,t2 =
- if isArity t2 then
- let (ctx2,s2) = destArity t2 in
- match s2 with
- | Type v when not (Univ.is_univ_variable v) ->
- (* The type in the interface is inferred and is made of algebraic
- universes *)
- begin try
- let (ctx1,s1) = dest_arity env t1 in
- match s1 with
- | Type u when not (Univ.is_univ_variable u) ->
- (* Both types are inferred, no need to recheck them. We
- cheat and collapse the types to Prop *)
- mkArity (ctx1,Prop Null), mkArity (ctx2,Prop Null)
- | Prop _ ->
- (* The type in the interface is inferred, it may be the case
- that the type in the implementation is smaller because
- the body is more reduced. We safely collapse the upper
- type to Prop *)
- mkArity (ctx1,Prop Null), mkArity (ctx2,Prop Null)
- | Type _ ->
- (* The type in the interface is inferred and the type in the
- implementation is not inferred or is inferred but from a
- more reduced body so that it is just a variable. Since
- constraints of the form "univ <= max(...)" are not
- expressible in the system of algebraic universes: we fail
- (the user has to use an explicit type in the interface *)
- error ()
- with UserError _ (* "not an arity" *) ->
- error () end
- | _ -> t1,t2
- else
- (t1,t2) in
- check_conv conv_leq env t1 t2
- in
+ let check_type env t1 t2 = check_conv conv_leq env t1 t2 in
match info1 with
| Constant cb1 ->
let cb1 = subst_const_body subst1 cb1 in
@@ -357,7 +281,7 @@ and check_signatures env mp1 sig1 sig2 subst1 subst2 =
let check_one_body (l,spec2) =
match spec2 with
| SFBconst cb2 ->
- check_constant env mp1 l (get_obj mp1 map1 l)
+ check_constant env l (get_obj mp1 map1 l)
cb2 spec2 subst1 subst2
| SFBmind mib2 ->
check_inductive env mp1 l (get_obj mp1 map1 l)
diff --git a/checker/term.ml b/checker/term.ml
index 509634bdb..d84491b38 100644
--- a/checker/term.ml
+++ b/checker/term.ml
@@ -20,15 +20,15 @@ open Cic
(* Sorts. *)
let family_of_sort = function
- | Prop Null -> InProp
- | Prop Pos -> InSet
+ | Prop -> InProp
+ | Set -> InSet
| Type _ -> InType
let family_equal = (==)
let sort_of_univ u =
- if Univ.is_type0m_univ u then Prop Null
- else if Univ.is_type0_univ u then Prop Pos
+ if Univ.is_type0m_univ u then Prop
+ else if Univ.is_type0_univ u then Set
else Type u
(********************************************************************)
@@ -356,15 +356,11 @@ let rec isArity c =
(* alpha conversion : ignore print names and casts *)
let compare_sorts s1 s2 = match s1, s2 with
-| Prop c1, Prop c2 ->
- begin match c1, c2 with
- | Pos, Pos | Null, Null -> true
- | Pos, Null -> false
- | Null, Pos -> false
- end
+| Prop, Prop | Set, Set -> true
| Type u1, Type u2 -> Univ.Universe.equal u1 u2
-| Prop _, Type _ -> false
-| Type _, Prop _ -> false
+| Prop, Set | Set, Prop -> false
+| (Prop | Set), Type _ -> false
+| Type _, (Prop | Set) -> false
let eq_puniverses f (c1,u1) (c2,u2) =
Univ.Instance.equal u1 u2 && f c1 c2
diff --git a/checker/typeops.ml b/checker/typeops.ml
index 18f07dc0b..19ede4b9a 100644
--- a/checker/typeops.ml
+++ b/checker/typeops.ml
@@ -103,11 +103,11 @@ let judge_of_apply env (f,funj) argjv =
let sort_of_product env domsort rangsort =
match (domsort, rangsort) with
(* Product rule (s,Prop,Prop) *)
- | (_, Prop Null) -> rangsort
+ | _, Prop -> rangsort
(* Product rule (Prop/Set,Set,Set) *)
- | (Prop _, Prop Pos) -> rangsort
+ | (Prop | Set), Set -> rangsort
(* Product rule (Type,Set,?) *)
- | (Type u1, Prop Pos) ->
+ | Type u1, Set ->
if engagement env = ImpredicativeSet then
(* Rule is (Type,Set,Set) in the Set-impredicative calculus *)
rangsort
@@ -115,11 +115,11 @@ let sort_of_product env domsort rangsort =
(* Rule is (Type_i,Set,Type_i) in the Set-predicative calculus *)
Type (Univ.sup u1 Univ.type0_univ)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Pos, Type u2) -> Type (Univ.sup Univ.type0_univ u2)
+ | Set, Type u2 -> Type (Univ.sup Univ.type0_univ u2)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Null, Type _) -> rangsort
+ | Prop, Type _ -> rangsort
(* Product rule (Type_i,Type_i,Type_i) *)
- | (Type u1, Type u2) -> Type (Univ.sup u1 u2)
+ | Type u1, Type u2 -> Type (Univ.sup u1 u2)
(* Type of a type cast *)
@@ -203,7 +203,7 @@ let judge_of_projection env p c ct =
try find_rectype env ct
with Not_found -> error_case_not_inductive env (c, ct)
in
- assert(MutInd.equal pb.proj_ind (fst ind));
+ assert(eq_ind pb.proj_ind ind);
let ty = subst_instance_constr u pb.proj_type in
substl (c :: List.rev args) ty
@@ -239,7 +239,7 @@ let type_fixpoint env lna lar lbody vdefj =
let rec execute env cstr =
match cstr with
(* Atomic terms *)
- | Sort (Prop _) -> judge_of_prop
+ | Sort (Prop | Set) -> judge_of_prop
| Sort (Type u) -> judge_of_type u
diff --git a/checker/univ.ml b/checker/univ.ml
index 15673736f..e50e883ad 100644
--- a/checker/univ.ml
+++ b/checker/univ.ml
@@ -190,13 +190,6 @@ struct
(let (u,n) = x and (v,n') = y in
Int.equal n n' && Level.equal u v)
- let leq (u,n) (v,n') =
- let cmp = Level.compare u v in
- if Int.equal cmp 0 then n <= n'
- else if n <= n' then
- (Level.is_prop u && Level.is_small v)
- else false
-
let successor (u,n) =
if Level.is_prop u then type1
else (u, n + 1)
@@ -833,41 +826,6 @@ type 'a constrained = 'a * constraints
type 'a constraint_function = 'a -> 'a -> constraints -> constraints
-let constraint_add_leq v u c =
- (* We just discard trivial constraints like u<=u *)
- if Expr.equal v u then c
- else
- match v, u with
- | (x,n), (y,m) ->
- let j = m - n in
- if j = -1 (* n = m+1, v+1 <= u <-> v < u *) then
- Constraint.add (x,Lt,y) c
- else if j <= -1 (* n = m+k, v+k <= u <-> v+(k-1) < u *) then
- if Level.equal x y then (* u+(k+1) <= u *)
- raise (UniverseInconsistency (Le, Universe.tip v, Universe.tip u))
- else anomaly (Pp.str"Unable to handle arbitrary u+k <= v constraints.")
- else if j = 0 then
- Constraint.add (x,Le,y) c
- else (* j >= 1 *) (* m = n + k, u <= v+k *)
- if Level.equal x y then c (* u <= u+k, trivial *)
- else if Level.is_small x then c (* Prop,Set <= u+S k, trivial *)
- else anomaly (Pp.str"Unable to handle arbitrary u <= v+k constraints.")
-
-let check_univ_leq_one u v = Universe.exists (Expr.leq u) v
-
-let check_univ_leq u v =
- Universe.for_all (fun u -> check_univ_leq_one u v) u
-
-let enforce_leq u v c =
- match v with
- | [v] ->
- List.fold_right (fun u -> constraint_add_leq u v) u c
- | _ -> anomaly (Pp.str"A universe bound can only be a variable.")
-
-let enforce_leq u v c =
- if check_univ_leq u v then c
- else enforce_leq u v c
-
let check_constraint g (l,d,r) =
match d with
| Eq -> check_equal g l r
diff --git a/checker/univ.mli b/checker/univ.mli
index 6cd3b3638..3b29b158f 100644
--- a/checker/univ.mli
+++ b/checker/univ.mli
@@ -109,8 +109,6 @@ type 'a constrained = 'a * constraints
type 'a constraint_function = 'a -> 'a -> constraints -> constraints
-val enforce_leq : universe constraint_function
-
(** {6 ... } *)
(** Merge of constraints in a universes graph.
The function [merge_constraints] merges a set of constraints in a given
diff --git a/checker/values.ml b/checker/values.ml
index 31e65729b..88cdb644d 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -15,7 +15,7 @@
To ensure this file is up-to-date, 'make' now compares the md5 of cic.mli
with a copy we maintain here:
-MD5 07651f61f86d91b22ff7056c6a8d86bc checker/cic.mli
+MD5 c395aa2dbfc18794b3b7192f3dc5b2e5 checker/cic.mli
*)
@@ -122,7 +122,7 @@ let v_context_set = v_tuple "universe_context_set" [|v_hset v_level;v_cstrs|]
(** kernel/term *)
-let v_sort = v_sum "sort" 0 [|[|v_enum "cnt" 2|];[|v_univ|]|]
+let v_sort = v_sum "sort" 2 (*Prop, Set*) [|[|v_univ(*Type*)|]|]
let v_sortfam = v_enum "sorts_family" 3
let v_puniverses v = v_tuple "punivs" [|v;v_instance|]
@@ -225,7 +225,7 @@ let v_cst_def =
let v_projbody =
v_tuple "projection_body"
- [|v_cst;Int;Int;v_constr|]
+ [|v_ind;Int;Int;v_constr|]
let v_typing_flags =
v_tuple "typing_flags" [|v_bool; v_bool; v_oracle|]
@@ -274,8 +274,10 @@ let v_one_ind = v_tuple "one_inductive_body"
Any|]
let v_finite = v_enum "recursivity_kind" 3
-let v_mind_record = Annot ("mind_record",
- Opt (Opt (v_tuple "record" [| v_id; Array v_cst; Array v_projbody |])))
+
+let v_record_info =
+ v_sum "record_info" 2
+ [| [| Array (v_tuple "record" [| v_id; Array v_cst; Array v_projbody |]) |] |]
let v_ind_pack_univs =
v_sum "abstract_inductive_universes" 0
@@ -283,7 +285,7 @@ let v_ind_pack_univs =
let v_ind_pack = v_tuple "mutual_inductive_body"
[|Array v_one_ind;
- v_mind_record;
+ v_record_info;
v_finite;
Int;
v_section_ctxt;
diff --git a/clib/cList.ml b/clib/cList.ml
index 2b627f745..de42886dc 100644
--- a/clib/cList.ml
+++ b/clib/cList.ml
@@ -122,6 +122,7 @@ sig
val duplicates : 'a eq -> 'a list -> 'a list
val uniquize : 'a list -> 'a list
val sort_uniquize : 'a cmp -> 'a list -> 'a list
+ val min : 'a cmp -> 'a list -> 'a
val cartesian : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val cartesians : ('a -> 'b -> 'b) -> 'b -> 'a list list -> 'b list
val combinations : 'a list list -> 'a list list
@@ -971,6 +972,15 @@ let rec uniquize_sorted cmp = function
let sort_uniquize cmp l =
uniquize_sorted cmp (List.sort cmp l)
+let min cmp l =
+ let rec aux cur = function
+ | [] -> cur
+ | x :: l -> if cmp x cur < 0 then aux x l else aux cur l
+ in
+ match l with
+ | x :: l -> aux x l
+ | [] -> raise Not_found
+
let rec duplicates cmp = function
| [] -> []
| x :: l ->
diff --git a/clib/cList.mli b/clib/cList.mli
index 13e069e94..42fae5ed3 100644
--- a/clib/cList.mli
+++ b/clib/cList.mli
@@ -376,6 +376,11 @@ sig
(** Return a sorted version of a list without duplicates
according to some comparison function. *)
+ val min : 'a cmp -> 'a list -> 'a
+ (** Return minimum element according to some comparison function.
+
+ @raise Not_found on an empty list. *)
+
(** {6 Cartesian product} *)
val cartesian : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
diff --git a/clib/dyn.ml b/clib/dyn.ml
index e9b041988..6c4576724 100644
--- a/clib/dyn.ml
+++ b/clib/dyn.ml
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-module type TParam =
+module type ValueS =
sig
type 'a t
end
@@ -16,40 +16,38 @@ end
module type MapS =
sig
type t
- type 'a obj
type 'a key
+ type 'a value
val empty : t
- val add : 'a key -> 'a obj -> t -> t
+ val add : 'a key -> 'a value -> t -> t
val remove : 'a key -> t -> t
- val find : 'a key -> t -> 'a obj
+ val find : 'a key -> t -> 'a value
val mem : 'a key -> t -> bool
- type any = Any : 'a key * 'a obj -> any
-
- type map = { map : 'a. 'a key -> 'a obj -> 'a obj }
+ type map = { map : 'a. 'a key -> 'a value -> 'a value }
val map : map -> t -> t
+ type any = Any : 'a key * 'a value -> any
val iter : (any -> unit) -> t -> unit
val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
end
module type PreS =
sig
-type 'a tag
-type t = Dyn : 'a tag * 'a -> t
-
-val create : string -> 'a tag
-val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
-val repr : 'a tag -> string
+ type 'a tag
+ type t = Dyn : 'a tag * 'a -> t
-type any = Any : 'a tag -> any
+ val create : string -> 'a tag
+ val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+ val repr : 'a tag -> string
-val name : string -> any option
+ val dump : unit -> (int * string) list
-module Map(M : TParam) : MapS with type 'a obj = 'a M.t with type 'a key = 'a tag
-
-val dump : unit -> (int * string) list
+ type any = Any : 'a tag -> any
+ val name : string -> any option
+ module Map(Value : ValueS) :
+ MapS with type 'a key = 'a tag and type 'a value = 'a Value.t
end
module type S =
@@ -57,104 +55,100 @@ 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
end
-
end
module Make () = struct
-module Self : PreS = struct
-(* Dynamics, programmed with DANGER !!! *)
-
-type 'a tag = int
-type t = Dyn : 'a tag * 'a -> t
-
-type any = Any : 'a tag -> any
-
-let dyntab = ref (Int.Map.empty : string Int.Map.t)
-(** Instead of working with tags as strings, which are costly, we use their
- hash. We ensure unicity of the hash in the [create] function. If ever a
- collision occurs, which is unlikely, it is sufficient to tweak the offending
- dynamic tag. *)
-
-let create (s : string) =
- let hash = Hashtbl.hash s in
- let () =
- if Int.Map.mem hash !dyntab then
- let old = Int.Map.find hash !dyntab in
- let () = Printf.eprintf "Dynamic tag collision: %s vs. %s\n%!" s old in
+module Self : PreS = struct
+ (* Dynamics, programmed with DANGER !!! *)
+
+ type 'a tag = int
+
+ type t = Dyn : 'a tag * 'a -> t
+
+ type any = Any : 'a tag -> any
+
+ let dyntab = ref (Int.Map.empty : string Int.Map.t)
+ (** Instead of working with tags as strings, which are costly, we use their
+ hash. We ensure unicity of the hash in the [create] function. If ever a
+ collision occurs, which is unlikely, it is sufficient to tweak the offending
+ dynamic tag. *)
+
+ let create (s : string) =
+ let hash = Hashtbl.hash s in
+ let () =
+ if Int.Map.mem hash !dyntab then
+ let old = Int.Map.find hash !dyntab in
+ let () = Printf.eprintf "Dynamic tag collision: %s vs. %s\n%!" s old in
+ assert false
+ in
+ let () = dyntab := Int.Map.add hash s !dyntab in
+ hash
+
+ let eq : 'a 'b. 'a tag -> 'b tag -> ('a, 'b) CSig.eq option =
+ fun h1 h2 -> if Int.equal h1 h2 then Some (Obj.magic CSig.Refl) else None
+
+ let repr s =
+ try Int.Map.find s !dyntab
+ with Not_found ->
+ let () = Printf.eprintf "Unknown dynamic tag %i\n%!" s in
assert false
- in
- let () = dyntab := Int.Map.add hash s !dyntab in
- hash
-
-let eq : 'a 'b. 'a tag -> 'b tag -> ('a, 'b) CSig.eq option =
- fun h1 h2 -> if Int.equal h1 h2 then Some (Obj.magic CSig.Refl) else None
-
-let repr s =
- try Int.Map.find s !dyntab
- with Not_found ->
- let () = Printf.eprintf "Unknown dynamic tag %i\n%!" s in
- assert false
-
-let name s =
- let hash = Hashtbl.hash s in
- if Int.Map.mem hash !dyntab then Some (Any hash) else None
-
-let dump () = Int.Map.bindings !dyntab
-
-module Map(M : TParam) =
-struct
-type t = Obj.t M.t Int.Map.t
-type 'a obj = 'a M.t
-type 'a key = 'a tag
-let cast : 'a M.t -> 'b M.t = Obj.magic
-let empty = Int.Map.empty
-let add tag v m = Int.Map.add tag (cast v) m
-let remove tag m = Int.Map.remove tag m
-let find tag m = cast (Int.Map.find tag m)
-let mem = Int.Map.mem
-
-type any = Any : 'a tag * 'a M.t -> any
-
-type map = { map : 'a. 'a tag -> 'a M.t -> 'a M.t }
-let map f m = Int.Map.mapi f.map m
-
-let iter f m = Int.Map.iter (fun k v -> f (Any (k, v))) m
-let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
-end
+ let name s =
+ let hash = Hashtbl.hash s in
+ if Int.Map.mem hash !dyntab then Some (Any hash) else None
+
+ let dump () = Int.Map.bindings !dyntab
+
+ module Map(Value: ValueS) =
+ struct
+ type t = Obj.t Value.t Int.Map.t
+ type 'a key = 'a tag
+ type 'a value = 'a Value.t
+ let cast : 'a value -> 'b value = Obj.magic
+ let empty = Int.Map.empty
+ let add tag v m = Int.Map.add tag (cast v) m
+ let remove tag m = Int.Map.remove tag m
+ let find tag m = cast (Int.Map.find tag m)
+ let mem = Int.Map.mem
+
+ type map = { map : 'a. 'a tag -> 'a value -> 'a value }
+ let map f m = Int.Map.mapi f.map m
+
+ type any = Any : 'a tag * 'a value -> any
+ let iter f m = Int.Map.iter (fun k v -> f (Any (k, v))) m
+ let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
+ end
end
include Self
module Easy = struct
-
-(* now tags are opaque, we can do the trick *)
-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)) ->
- match eq tag t with
- | None -> assert false
- | Some CSig.Refl -> x
- in
- 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 =
+ (* now tags are opaque, we can do the trick *)
+ 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)) ->
+ match eq tag t with
+ | None -> assert false
+ | Some CSig.Refl -> x
+ in
+ 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 ->
- match eq tag tag' with
- | None -> None
- | Some CSig.Refl -> Some x
+ match eq tag tag' with
+ | None -> None
+ | Some CSig.Refl -> Some x
end
end
diff --git a/clib/dyn.mli b/clib/dyn.mli
index 51d309142..ff9762bd6 100644
--- a/clib/dyn.mli
+++ b/clib/dyn.mli
@@ -10,7 +10,7 @@
(** Dynamically typed values *)
-module type TParam =
+module type ValueS =
sig
type 'a t
end
@@ -18,51 +18,66 @@ end
module type MapS =
sig
type t
- type 'a obj
type 'a key
+ type 'a value
val empty : t
- val add : 'a key -> 'a obj -> t -> t
+ val add : 'a key -> 'a value -> t -> t
val remove : 'a key -> t -> t
- val find : 'a key -> t -> 'a obj
+ val find : 'a key -> t -> 'a value
val mem : 'a key -> t -> bool
- type any = Any : 'a key * 'a obj -> any
-
- type map = { map : 'a. 'a key -> 'a obj -> 'a obj }
+ type map = { map : 'a. 'a key -> 'a value -> 'a value }
val map : map -> t -> t
+ type any = Any : 'a key * 'a value -> any
val iter : (any -> unit) -> t -> unit
val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
end
module type S =
sig
-type 'a tag
-type t = Dyn : 'a tag * 'a -> t
+ type 'a tag
+ (** Type of dynamic tags *)
-val create : string -> 'a tag
-val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
-val repr : 'a tag -> string
+ type t = Dyn : 'a tag * 'a -> t
+ (** Type of dynamic values *)
-type any = Any : 'a tag -> any
+ val create : string -> 'a tag
+ (** [create n] returns a tag describing a type called [n].
+ [create] raises an exception if [n] is already registered.
+ Type names are hashed, so [create] may raise even if no type with
+ the exact same name was registered due to a collision. *)
-val name : string -> any option
+ val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+ (** [eq t1 t2] returns [Some witness] if [t1] is the same as [t2], [None] otherwise. *)
-module Map(M : TParam) : MapS with type 'a obj = 'a M.t with type 'a key = 'a tag
+ val repr : 'a tag -> string
+ (** [repr tag] returns the name of the type represented by [tag]. *)
-val dump : unit -> (int * string) list
+ val dump : unit -> (int * string) list
+ (** [dump ()] returns a list of (tag, name) pairs for every type tag registered
+ in this [Dyn.Make] instance. *)
-module Easy : sig
+ type any = Any : 'a tag -> any
+ (** Type of boxed dynamic tags *)
- (* 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)
+ val name : string -> any option
+ (** [name n] returns [Some t] where t is a boxed tag previously registered
+ with [create n], or [None] if there is no such tag. *)
- (* For types declared with the [create] function above *)
- val inj : 'a -> 'a tag -> t
- val prj : t -> 'a tag -> 'a option
-end
+ module Map(Value : ValueS) :
+ MapS with type 'a key = 'a tag and type 'a value = 'a Value.t
+ (** Map from type tags to values parameterized by the tag type *)
+
+ 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 *)
+ val inj : 'a -> 'a tag -> t
+ val prj : t -> 'a tag -> 'a option
+ end
end
module Make () : S
diff --git a/configure.ml b/configure.ml
index 9d959b9af..194f47c49 100644
--- a/configure.ml
+++ b/configure.ml
@@ -18,7 +18,7 @@ let vo_magic = 8891
let state_magic = 58891
let distributed_exec =
["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
- "coqc";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
+ "coqc";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"coqwc";"csdpcert";"coqdep"]
let verbose = ref false (* for debugging this script *)
@@ -235,12 +235,6 @@ let get_date () =
let short_date, full_date = get_date ()
-
-(** Create the bin/ directory if non-existent *)
-
-let _ = if not (dir_exists "bin") then Unix.mkdir "bin" 0o755
-
-
(** * Command-line parsing *)
type ide = Opt | Byte | No
@@ -256,7 +250,6 @@ type preferences = {
datadir : string option;
mandir : string option;
docdir : string option;
- emacslib : string option;
coqdocdir : string option;
ocamlfindcmd : string option;
lablgtkdir : string option;
@@ -294,7 +287,6 @@ let default = {
datadir = None;
mandir = None;
docdir = None;
- emacslib = None;
coqdocdir = None;
ocamlfindcmd = None;
lablgtkdir = None;
@@ -392,8 +384,6 @@ let args_options = Arg.align [
"<dir> Where to install man files";
"-docdir", arg_string_option (fun p docdir -> { p with docdir }),
"<dir> Where to install doc files";
- "-emacslib", arg_string_option (fun p emacslib -> { p with emacslib }),
- "<dir> Where to install emacs files";
"-coqdocdir", arg_string_option (fun p coqdocdir -> { p with coqdocdir }),
"<dir> Where to install Coqdoc style files";
"-ocamlfind", arg_string_option (fun p ocamlfindcmd -> { p with ocamlfindcmd }),
@@ -461,14 +451,19 @@ let _ = parse_args ()
type camlexec =
{ mutable find : string;
mutable top : string;
- mutable lex : string; }
+ mutable lex : string;
+ mutable yacc : string;
+ }
let camlexec =
{ find = "ocamlfind";
top = "ocaml";
- lex = "ocamllex"; }
+ lex = "ocamllex";
+ yacc = "ocamlyacc";
+ }
let reset_caml_lex c o = c.lex <- o
+let reset_caml_yacc c o = c.yacc <- o
let reset_caml_top c o = c.top <- o
let reset_caml_find c o = c.find <- o
@@ -580,6 +575,9 @@ let camlbin, caml_version, camllib, findlib_version =
if is_executable (camlbin / "ocamllex")
then reset_caml_lex camlexec (camlbin / "ocamllex") in
let () =
+ if is_executable (camlbin / "ocamlyacc")
+ then reset_caml_yacc camlexec (camlbin / "ocamlyacc") in
+ let () =
if is_executable (camlbin / "ocaml")
then reset_caml_top camlexec (camlbin / "ocaml") in
camlbin, caml_version, camllib, findlib_version
@@ -601,14 +599,14 @@ let caml_version_nums =
"Is it installed properly?")
let check_caml_version () =
- if caml_version_nums >= [4;2;1] then
+ if caml_version_nums >= [4;2;3] then
cprintf "You have OCaml %s. Good!" caml_version
else
let () = cprintf "Your version of OCaml is %s." caml_version in
if !prefs.force_caml_version then
warn "Your version of OCaml is outdated."
else
- die "You need OCaml 4.02.1 or later."
+ die "You need OCaml 4.02.3 or later."
let _ = check_caml_version ()
@@ -1006,8 +1004,6 @@ let install = [
Relative "man", Relative "share/man", Relative "man";
"DOCDIR", "the Coq documentation", !prefs.docdir,
Relative "doc", Relative "share/doc/coq", Relative "doc";
- "EMACSLIB", "the Coq Emacs mode", !prefs.emacslib,
- Relative "emacs", Relative "share/emacs/site-lisp", Relative "tools";
"COQDOCDIR", "the Coqdoc LaTeX files", !prefs.coqdocdir,
Relative "latex", Relative "share/texmf/tex/latex/misc", Relative "tools/coqdoc";
]
@@ -1280,6 +1276,7 @@ let write_makefile f =
pr "OCAML=%S\n" camlexec.top;
pr "OCAMLFIND=%S\n" camlexec.find;
pr "OCAMLLEX=%S\n" camlexec.lex;
+ pr "OCAMLYACC=%S\n" camlexec.yacc;
pr "# The best compiler: native (=opt) or bytecode (=byte)\n";
pr "BEST=%s\n\n" best_compiler;
pr "# Ocaml version number\n";
diff --git a/default.nix b/default.nix
index 91d963604..d9317bcca 100644
--- a/default.nix
+++ b/default.nix
@@ -9,23 +9,30 @@
# nix-shell supports the --arg option (see Nix doc) that allows you for
# instance to do this:
-# $ nix-shell --arg ocamlPackages "(import <nixpkgs> {}).ocamlPackages_latest" --arg buildIde false
+# $ nix-shell --arg ocamlPackages "(import <nixpkgs> {}).ocaml-ng.ocamlPackages_4_05" --arg buildIde false
# You can also compile Coq and "install" it by running:
# $ make clean # (only needed if you have left-over compilation files)
# $ nix-build
# at the root of the Coq repository.
# nix-build also supports the --arg option, so you will be able to do:
-# $ nix-build --arg doCheck false
+# $ nix-build --arg doInstallCheck false
# if you want to speed up things by not running the test-suite.
# Once the build is finished, you will find, in the current directory,
# a symlink to where Coq was installed.
-{ pkgs ? (import <nixpkgs> {})
+{ pkgs ?
+ (import (fetchTarball {
+ url = "https://github.com/NixOS/nixpkgs/archive/060a98e9f4ad879492e48d63e887b0b6db26299e.tar.gz";
+ sha256 = "1lzvp3md0hf6kp2bvc6dbzh40navlyd51qlns9wbkz6lqk3lgf6j";
+ }) {})
, ocamlPackages ? pkgs.ocaml-ng.ocamlPackages_4_06
, buildIde ? true
, buildDoc ? true
-, doCheck ? true
+, doInstallCheck ? true
+, shell ? false
+ # We don't use lib.inNixShell because that would also apply
+ # when in a nix-shell of some package depending on this one.
}:
with pkgs;
@@ -36,63 +43,64 @@ stdenv.mkDerivation rec {
name = "coq";
buildInputs = [
-
- # Coq dependencies
hostname
- ] ++ (with ocamlPackages; [
- ocaml
- findlib
- camlp5_strict
- num
-
- ]) ++ (if buildIde then [
-
- # CoqIDE dependencies
- ocamlPackages.lablgtk
-
- ] else []) ++ (if buildDoc then [
-
+ python2 time # coq-makefile timing tools
+ ]
+ ++ (with ocamlPackages; [ ocaml findlib camlp5_strict num ])
+ ++ optional buildIde ocamlPackages.lablgtk
+ ++ optionals buildDoc [
# Sphinx doc dependencies
pkgconfig (python3.withPackages
(ps: [ ps.sphinx ps.sphinx_rtd_theme ps.pexpect ps.beautifulsoup4
ps.antlr4-python3-runtime ps.sphinxcontrib-bibtex ]))
- antlr4
-
- ] else []) ++ (if doCheck then
-
+ antlr4
+ ]
+ ++ optionals doInstallCheck (
# Test-suite dependencies
# ncurses is required to build an OCaml REPL
optional (!versionAtLeast ocaml.version "4.07") ncurses
- ++ [
- python
- rsync
- which
- ocamlPackages.ounit
-
- ] else []) ++ (if lib.inNixShell then [
- ocamlPackages.merlin
- ocamlPackages.ocpIndent
-
- # Dependencies of the merging script
- jq
- curl
- git
- gnupg
-
- ] else []);
+ ++ [ ocamlPackages.ounit rsync which ]
+ )
+ ++ optionals shell (
+ [ jq curl git gnupg ] # Dependencies of the merging script
+ ++ (with ocamlPackages; [ merlin ocp-indent ocp-index ]) # Dev tools
+ );
src =
- if lib.inNixShell then null
+ if shell then null
else
with builtins; filterSource
- (path: _: !elem (baseNameOf path) [".git" "result" "bin"]) ./.;
+ (path: _:
+ !elem (baseNameOf path) [".git" "result" "bin" "_build_ci"]) ./.;
prefixKey = "-prefix ";
- buildFlags = [ "world" ] ++ optional buildDoc "doc-html";
+ buildFlags = [ "world" "byte" ] ++ optional buildDoc "doc-html";
+
+ installTargets =
+ [ "install" "install-byte" ] ++ optional buildDoc "install-doc-html";
+
+ inherit doInstallCheck;
+
+ preInstallCheck = ''
+ patchShebangs tools/
+ patchShebangs test-suite/
+ '';
+
+ installCheckTarget = [ "check" ];
- installTargets = [ "install" ] ++ optional buildDoc "install-doc-html";
+ passthru = { inherit ocamlPackages; };
- inherit doCheck;
+ meta = {
+ description = "Coq proof assistant";
+ longDescription = ''
+ Coq is a formal proof management system. It provides a formal language
+ to write mathematical definitions, executable algorithms and theorems
+ together with an environment for semi-interactive development of
+ machine-checked proofs.
+ '';
+ homepage = http://coq.inria.fr;
+ license = licenses.lgpl21;
+ };
}
diff --git a/dev/README b/dev/README
deleted file mode 100644
index 453f85f0d..000000000
--- a/dev/README
+++ /dev/null
@@ -1,50 +0,0 @@
-This directory contains information and tools to help develop the
- Coq system
- ======================
-
-
-Debugging and profiling (in current directory - see doc/debugging.txt)
------------------------
-
-ocamldebug-coq: to launch ocaml debugger (generated by the configure script)
-
-db: to install pretty-printers from ocaml debugger
-base_db: to install raw pretty-printers from ocaml debugger
-
-include: to install pretty-printers from ocaml toplevel (use with the coq Drop command)
-base_include: to install raw pretty-printers from ocaml toplevel
-
-vm_printers.ml, top_printers.ml: ML pretty-printers for debugging
-
-
-Miscellaneous information about the code (directory doc)
------------------------------------------
-
-changes.md: (partial) per-version summary of the evolution of Coq ML source
-style.txt: a few style recommendations for writing Coq ML files
-debugging.md: help for debugging or profiling
-universes.txt: help for debugging universes
-translate.txt: help for using coq translator
-extensions.txt: some help about TACTIC EXTEND
-
-header: standard header for Coq ML files
-perf-analysis: analysis of perfs measured on the compilation of user contribs
-cic.dtd: official dtd of the calc. of ind. constr. for im/ex-portation
-
-
-Documentation of ML interfaces using ocamldoc (directory ocamldoc/html)
-----------------------------------------
-"make mli-doc" in coq root directory.
-
-
-Other development tools (directory tools)
------------------------
-
-coqdev.el: helper customizations for everyday Coq development, eg
- making `compile' work in subdirectories
-
-objects.el: various development utilities at emacs level
-
-anomaly-traces-parser.el: a .emacs-ready elisp snippet to parse
- location of Anomaly backtraces and jump to them conveniently from
- the Emacs *compilation* output.
diff --git a/dev/README.md b/dev/README.md
new file mode 100644
index 000000000..4642aaf06
--- /dev/null
+++ b/dev/README.md
@@ -0,0 +1,46 @@
+# This directory contains information and tools to help develop the Coq system
+
+
+## Debugging and profiling (`dev/`)
+**More info on debugging: [`doc/debugging.md`](doc/debugging.md)**
+
+| File | Description |
+| ---- | ----------- |
+| dev/ocamldebug-coq | To launch ocaml debugger (generated by the configure script) |
+| dev/db | To install pretty-printers from ocaml debugger |
+| dev/base_db | To install raw pretty-printers from ocaml debugger |
+| dev/include | To install pretty-printers from ocaml toplevel (use with the coq Drop command) |
+| dev/base_include | To install raw pretty-printers from ocaml toplevel |
+| dev/vm_printers.ml, top_printers.ml | ML pretty-printers for debugging |
+
+
+## Miscellaneous information about the code (`dev/doc`)
+**Beginner's guide to hacking Coq: [`dev/doc/README.md`](doc/README.md)**
+
+| File | Description |
+| ---- | ----------- |
+| [`dev/doc/changes.md`](doc/changes.md) | (partial) Per-version summary of the evolution of Coq ML source |
+| [`dev/doc/style.txt`](doc/style.txt) | A few style recommendations for writing Coq ML files |
+| [`dev/doc/debugging.md`](doc/debugging.md) | Help for debugging or profiling |
+| [`dev/doc/universes.txt`](doc/universes.txt) | Help for debugging universes |
+| [`dev/doc/extensions.txt`](doc/extensions.txt) | Some help about TACTIC EXTEND |
+| [`dev/doc/perf-analysis`](doc/perf-analysis)| Analysis of perfs measured on the compilation of user contribs |
+| [`dev/doc/cic.dtd`](doc/cic.dtd) | Official dtd of the calc. of ind. constr. for im/ex-portation |
+| [`dev/doc/econstr.md`](doc/econstr.md) | Describes `Econstr`, implementation of treatment of `evar` in the engine |
+| [`dev/doc/primproj.md`](doc/primproj.md) | Describes primitive projections |
+| [`dev/doc/proof-engine.md`](doc/proof-engine.md) | Tutorial on new proof engine |
+| [`dev/doc/xml-protocol.md`](doc/proof-engine.md) | XML protocol that coqtop and IDEs use to communicate |
+| [`dev/doc/MERGING.md`](doc/MERGING.md) | How pull requests should be merged into `master` |
+| [`dev/doc/release-process.md`](doc/release-process.md) | Process of creating a new Coq release |
+
+
+## Documentation of ML interfaces using ocamldoc ( `dev/ocamldoc/html`)
+`make mli-doc` in coq root directory.
+
+
+## Other development tools (`dev/tools`)
+
+| File | Description |
+| ---- | ----------- |
+| [`dev/tools/coqdev.el`](tools/coqdev.el) | Helper customizations for everyday Coq development, eg making `compile` work in subdirectories
+| [`dev/tools/objects.el`](tools/objects.el) | Various development utilities at emacs level |
diff --git a/dev/build/windows/MakeCoq_MinGW.bat b/dev/build/windows/MakeCoq_MinGW.bat
index f960ff008..5af0fcff3 100644..100755
--- a/dev/build/windows/MakeCoq_MinGW.bat
+++ b/dev/build/windows/MakeCoq_MinGW.bat
@@ -255,6 +255,7 @@ IF NOT "%~0" == "" (
IF NOT EXIST %SETUP% (
ECHO The cygwin setup program %SETUP% doesn't exist. You must download it from https://cygwin.com/install.html.
+ ECHO If the setup is in a different folder, set the full path to %SETUP% using the -setup option.
GOTO :EOF
)
@@ -385,7 +386,6 @@ IF "%RUNSETUP%"=="Y" (
MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build\buildlogs"
)
-
IF NOT "%CYGWIN_QUIET%" == "Y" (
REM Like most setup programs, cygwin setup starts the real setup as a separate process, so wait for it.
REM This is not required with the -cygquiet=Y and the resulting --no-admin option.
@@ -396,6 +396,12 @@ IF NOT "%CYGWIN_QUIET%" == "Y" (
ECHO ========== CONFIGURE CYGWIN USER ACCOUNT ==========
+REM In case this batch file is called from a cygwin bash (e.g. a git repo) we need to clear
+REM HOME (otherwise we get to the home directory of the other installation)
+REM PROFILEREAD (this is set to true if the /etc/profile has been read, which creates user)
+SET "HOME="
+SET "PROFILEREAD="
+
copy "%BATCHDIR%\configure_profile.sh" "%CYGWIN_INSTALLDIR_WFMT%\var\tmp" || GOTO ErrorExit
%BASH% --login "%CYGWIN_INSTALLDIR_CFMT%\var\tmp\configure_profile.sh" "%PROXY%" || GOTO ErrorExit
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 508dcf5fb..94e90bf4f 100644
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -118,6 +118,9 @@ mkdir -p "$PREFIX/bin"
mkdir -p "$PREFIXCOQ/bin"
mkdir -p "$PREFIXOCAML/bin"
+# This is required for building addons and plugins
+export COQBIN=$RESULT_INSTALLDIR_CFMT/bin/
+
###################### Copy Cygwin Setup Info #####################
# Copy Cygwin repo ini file and installed files db to tarballs folder.
@@ -1128,14 +1131,12 @@ function copy_coq_license {
install -D doc/LICENSE "$PREFIXCOQ/license_readme/coq/LicenseDoc.txt"
install -D LICENSE "$PREFIXCOQ/license_readme/coq/License.txt"
install -D plugins/micromega/LICENSE.sos "$PREFIXCOQ/license_readme/coq/LicenseMicromega.txt"
- install -D README "$PREFIXCOQ/license_readme/coq/ReadMe.txt" || true
- install -D README.md "$PREFIXCOQ/license_readme/coq/ReadMe.md" || true
- install -D README.win "$PREFIXCOQ/license_readme/coq/ReadMeWindows.txt" || true
- install -D README.doc "$PREFIXCOQ/license_readme/coq/ReadMeDoc.txt" || true
+ # FIXME: this is not the micromega license
+ # It only applies to code that was copied into one single file!
+ install -D README.md "$PREFIXCOQ/license_readme/coq/ReadMe.md"
install -D CHANGES "$PREFIXCOQ/license_readme/coq/Changes.txt"
install -D INSTALL "$PREFIXCOQ/license_readme/coq/Install.txt"
- install -D INSTALL.doc "$PREFIXCOQ/license_readme/coq/InstallDoc.txt"
- install -D INSTALL.ide "$PREFIXCOQ/license_readme/coq/InstallIde.txt"
+ install -D doc/README.md "$PREFIXCOQ/license_readme/coq/ReadMeDoc.md"
fi
}
@@ -1211,6 +1212,10 @@ function make_coq {
# 2.) clean of test suites fails with "cannot run complexity tests (no bogomips found)"
# make clean
+ # Copy these files somewhere the plugin builds can find them
+ cp dev/ci/ci-basic-overlay.sh /build/
+ cp -r dev/ci/user-overlays /build/
+
build_post
fi
}
@@ -1378,8 +1383,16 @@ function make_coq_installer {
###################### ADDONS #####################
+# The bignums library
+# Provides BigN, BigZ, BigQ that used to be part of Coq standard library
+
function make_addon_bignums {
- if build_prep https://github.com/coq/bignums/archive/ V8.8+beta1 zip 1 bignums-8.8+beta1; then
+ bignums_SHA=$(git ls-remote "$bignums_CI_GITURL" "refs/heads/$bignums_CI_BRANCH" | cut -f 1)
+ if [[ "$bignums_SHA" == "" ]]; then
+ # $bignums_CI_BRANCH must have been a tag and not a branch
+ bignums_SHA="$bignums_CI_BRANCH"
+ fi
+ if build_prep "${bignums_CI_GITURL}/archive" "$bignums_SHA" zip 1 "bignums-$bignums_SHA"; then
# To make command lines shorter :-(
echo 'COQ_SRC_SUBDIRS:=$(filter-out plugins/%,$(COQ_SRC_SUBDIRS)) plugins/syntax' >> Makefile.coq.local
log1 make all
@@ -1388,7 +1401,58 @@ function make_addon_bignums {
fi
}
+# Ltac-2 plugin
+# A new (experimental) tactic language
+
+function make_addon_ltac2 {
+ ltac2_SHA=$(git ls-remote "$ltac2_CI_GITURL" "refs/heads/$ltac2_CI_BRANCH" | cut -f 1)
+ if [[ "$ltac2_SHA" == "" ]]; then
+ # $ltac2_CI_BRANCH must have been a tag and not a branch
+ ltac2_SHA="$ltac2_CI_BRANCH"
+ fi
+ if build_prep "${ltac2_CI_GITURL}/archive" "$ltac2_SHA" zip 1 "ltac2-$ltac2_SHA"; then
+ log1 make all
+ log2 make install
+ build_post
+ fi
+}
+
+# Equations plugin
+# A function definition plugin
+
+function make_addon_equations {
+ Equations_SHA=$(git ls-remote "$Equations_CI_GITURL" "refs/heads/$Equations_CI_BRANCH" | cut -f 1)
+ if [[ "$Equations_SHA" == "" ]]; then
+ # $Equations_CI_BRANCH must have been a tag and not a branch
+ Equations_SHA="$Equations_CI_BRANCH"
+ fi
+ if build_prep "${Equations_CI_GITURL}/archive" "$Equations_SHA" zip 1 "Equations-$Equations_SHA"; then
+ # Note: PATH is autmatically saved/restored by build_prep / build_post
+ PATH=$COQBIN:$PATH
+ logn coq_makefile ${COQBIN}coq_makefile -f _CoqProject -o Makefile
+ log1 make
+ log2 make install
+ build_post
+ fi
+}
+
function make_addons {
+ if [ -n "$GITLAB_CI" ]; then
+ export CI_BRANCH="$CI_COMMIT_REF_NAME"
+ if [[ ${CI_BRANCH#pr-} =~ ^[0-9]*$ ]]; then
+ export CI_PULL_REQUEST="${CI_BRANCH#pr-}"
+ else
+ export CI_PULL_REQUEST=""
+ fi
+ else
+ export CI_BRANCH=""
+ export CI_PULL_REQUEST=""
+ fi
+ . /build/ci-basic-overlay.sh
+ for overlay in /build/user-overlays/*.sh; do
+ . "$overlay"
+ done
+
for addon in $COQ_ADDONS; do
"make_addon_$addon"
done
diff --git a/dev/ci/README.md b/dev/ci/README.md
index 08364c897..45176581c 100644
--- a/dev/ci/README.md
+++ b/dev/ci/README.md
@@ -86,11 +86,6 @@ We are currently running tests on the following platforms:
- AppVeyor is used to test the compilation of Coq and run the test-suite on
Windows.
-GitLab CI and Travis CI and AppVeyor support putting `[ci skip]` in a commit
-message to bypass CI. Do not use this unless your commit only changes files
-that are not compiled (e.g. Markdown files like this one, or files under
-[`.github/`](../../.github/)).
-
You can anticipate the results of most of these tests prior to submitting your
PR by running GitLab CI on your private branches. To do so follow these steps:
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 87d837b38..28321d13e 100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -10,123 +10,123 @@
# MathComp
########################################################################
: "${mathcomp_CI_BRANCH:=master}"
-: "${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp.git}"
+: "${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp}"
: "${oddorder_CI_BRANCH:=master}"
-: "${oddorder_CI_GITURL:=https://github.com/math-comp/odd-order.git}"
+: "${oddorder_CI_GITURL:=https://github.com/math-comp/odd-order}"
########################################################################
# UniMath
########################################################################
: "${UniMath_CI_BRANCH:=master}"
-: "${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath.git}"
+: "${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath}"
########################################################################
# Unicoq + Mtac2
########################################################################
: "${unicoq_CI_BRANCH:=master}"
-: "${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq.git}"
+: "${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq}"
: "${mtac2_CI_BRANCH:=master-sync}"
-: "${mtac2_CI_GITURL:=https://github.com/Mtac2/Mtac2.git}"
+: "${mtac2_CI_GITURL:=https://github.com/Mtac2/Mtac2}"
########################################################################
# Mathclasses + Corn
########################################################################
: "${math_classes_CI_BRANCH:=master}"
-: "${math_classes_CI_GITURL:=https://github.com/math-classes/math-classes.git}"
+: "${math_classes_CI_GITURL:=https://github.com/math-classes/math-classes}"
: "${Corn_CI_BRANCH:=master}"
-: "${Corn_CI_GITURL:=https://github.com/c-corn/corn.git}"
+: "${Corn_CI_GITURL:=https://github.com/c-corn/corn}"
########################################################################
# Iris
########################################################################
: "${stdpp_CI_BRANCH:=master}"
-: "${stdpp_CI_GITURL:=https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp.git}"
+: "${stdpp_CI_GITURL:=https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp}"
: "${Iris_CI_BRANCH:=master}"
-: "${Iris_CI_GITURL:=https://gitlab.mpi-sws.org/FP/iris-coq.git}"
+: "${Iris_CI_GITURL:=https://gitlab.mpi-sws.org/FP/iris-coq}"
: "${lambdaRust_CI_BRANCH:=master}"
-: "${lambdaRust_CI_GITURL:=https://gitlab.mpi-sws.org/FP/LambdaRust-coq.git}"
+: "${lambdaRust_CI_GITURL:=https://gitlab.mpi-sws.org/FP/LambdaRust-coq}"
########################################################################
# HoTT
########################################################################
: "${HoTT_CI_BRANCH:=master}"
-: "${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT.git}"
+: "${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT}"
########################################################################
# Ltac2
########################################################################
: "${ltac2_CI_BRANCH:=master}"
-: "${ltac2_CI_GITURL:=https://github.com/ppedrot/ltac2.git}"
+: "${ltac2_CI_GITURL:=https://github.com/ppedrot/ltac2}"
########################################################################
# GeoCoq
########################################################################
: "${GeoCoq_CI_BRANCH:=master}"
-: "${GeoCoq_CI_GITURL:=https://github.com/GeoCoq/GeoCoq.git}"
+: "${GeoCoq_CI_GITURL:=https://github.com/GeoCoq/GeoCoq}"
########################################################################
# Flocq
########################################################################
: "${Flocq_CI_BRANCH:=master}"
-: "${Flocq_CI_GITURL:=https://gitlab.inria.fr/flocq/flocq.git}"
+: "${Flocq_CI_GITURL:=https://gitlab.inria.fr/flocq/flocq}"
########################################################################
# Coquelicot
########################################################################
: "${Coquelicot_CI_BRANCH:=master}"
-: "${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot.git}"
+: "${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot}"
########################################################################
# CompCert
########################################################################
: "${CompCert_CI_BRANCH:=master}"
-: "${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert.git}"
+: "${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert}"
########################################################################
# VST
########################################################################
: "${VST_CI_BRANCH:=master}"
-: "${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST.git}"
+: "${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST}"
########################################################################
# cross-crypto
########################################################################
: "${cross_crypto_CI_BRANCH:=master}"
-: "${cross_crypto_CI_GITURL:=https://github.com/mit-plv/cross-crypto.git}"
+: "${cross_crypto_CI_GITURL:=https://github.com/mit-plv/cross-crypto}"
########################################################################
# fiat_parsers
########################################################################
: "${fiat_parsers_CI_BRANCH:=master}"
-: "${fiat_parsers_CI_GITURL:=https://github.com/mit-plv/fiat.git}"
+: "${fiat_parsers_CI_GITURL:=https://github.com/mit-plv/fiat}"
########################################################################
# fiat_crypto
########################################################################
: "${fiat_crypto_CI_BRANCH:=master}"
-: "${fiat_crypto_CI_GITURL:=https://github.com/mit-plv/fiat-crypto.git}"
+: "${fiat_crypto_CI_GITURL:=https://github.com/mit-plv/fiat-crypto}"
########################################################################
# formal-topology
########################################################################
: "${formal_topology_CI_BRANCH:=ci}"
-: "${formal_topology_CI_GITURL:=https://github.com/bmsherman/topology.git}"
+: "${formal_topology_CI_GITURL:=https://github.com/bmsherman/topology}"
########################################################################
# coq-dpdgraph
########################################################################
-: "${coq_dpdgraph_CI_BRANCH:=coq-trunk}"
-: "${coq_dpdgraph_CI_GITURL:=https://github.com/Karmaki/coq-dpdgraph.git}"
+: "${coq_dpdgraph_CI_BRANCH:=coq-master}"
+: "${coq_dpdgraph_CI_GITURL:=https://github.com/Karmaki/coq-dpdgraph}"
########################################################################
# CoLoR
########################################################################
: "${CoLoR_CI_BRANCH:=master}"
-: "${CoLoR_CI_GITURL:=https://github.com/fblanqui/color.git}"
+: "${CoLoR_CI_GITURL:=https://github.com/fblanqui/color}"
########################################################################
# SF
@@ -139,46 +139,52 @@
# TLC
########################################################################
: "${tlc_CI_BRANCH:=master}"
-: "${tlc_CI_GITURL:=https://gforge.inria.fr/git/tlc/tlc.git}"
+: "${tlc_CI_GITURL:=https://gforge.inria.fr/git/tlc/tlc}"
########################################################################
# Bignums
########################################################################
: "${bignums_CI_BRANCH:=master}"
-: "${bignums_CI_GITURL:=https://github.com/coq/bignums.git}"
+: "${bignums_CI_GITURL:=https://github.com/coq/bignums}"
+
+########################################################################
+# bedrock2
+########################################################################
+: "${bedrock2_CI_BRANCH:=master}"
+: "${bedrock2_CI_GITURL:=https://github.com/mit-plv/bedrock2}"
########################################################################
# Equations
########################################################################
: "${Equations_CI_BRANCH:=master}"
-: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations.git}"
+: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations}"
########################################################################
# Elpi
########################################################################
: "${Elpi_CI_BRANCH:=coq-master}"
-: "${Elpi_CI_GITURL:=https://github.com/LPCIC/coq-elpi.git}"
+: "${Elpi_CI_GITURL:=https://github.com/LPCIC/coq-elpi}"
########################################################################
# fcsl-pcm
########################################################################
: "${fcsl_pcm_CI_BRANCH:=master}"
-: "${fcsl_pcm_CI_GITURL:=https://github.com/imdea-software/fcsl-pcm.git}"
+: "${fcsl_pcm_CI_GITURL:=https://github.com/imdea-software/fcsl-pcm}"
########################################################################
# pidetop
########################################################################
: "${pidetop_CI_BRANCH:=v8.9}"
-: "${pidetop_CI_GITURL:=https://bitbucket.org/coqpide/pidetop.git}"
+: "${pidetop_CI_GITURL:=https://bitbucket.org/coqpide/pidetop}"
########################################################################
# ext-lib
########################################################################
: "${ext_lib_CI_BRANCH:=master}"
-: "${ext_lib_CI_GITURL:=https://github.com/coq-ext-lib/coq-ext-lib.git}"
+: "${ext_lib_CI_GITURL:=https://github.com/coq-ext-lib/coq-ext-lib}"
########################################################################
# quickchick
########################################################################
: "${quickchick_CI_BRANCH:=master}"
-: "${quickchick_CI_GITURL:=https://github.com/QuickChick/QuickChick.git}"
+: "${quickchick_CI_GITURL:=https://github.com/QuickChick/QuickChick}"
diff --git a/dev/ci/ci-bedrock2.sh b/dev/ci/ci-bedrock2.sh
new file mode 100755
index 000000000..447076e09
--- /dev/null
+++ b/dev/ci/ci-bedrock2.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+bedrock2_CI_DIR="${CI_BUILD_DIR}/bedrock2"
+
+git_checkout "${bedrock2_CI_BRANCH}" "${bedrock2_CI_GITURL}" "${bedrock2_CI_DIR}"
+( cd "${bedrock2_CI_DIR}" && git submodule update --init --recursive )
+
+( cd "${bedrock2_CI_DIR}" && make )
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index 85df249d3..a68cd0933 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -69,7 +69,7 @@ git_checkout()
if [ ! -d .git ] ; then git clone "${_DEPTH[@]}" "${_URL}" . ; fi && \
echo "Checking out ${_DEST}" && \
git fetch "${_URL}" "${_BRANCH}" && \
- git checkout "${_COMMIT}" && \
+ git -c advice.detachedHead=false checkout "${_COMMIT}" && \
echo "${_DEST}: $(git log -1 --format='%s | %H | %cd | %aN')" )
}
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index 52f851917..a4ee6a379 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -1,4 +1,4 @@
-# CACHEKEY: "bionic_coq-V2018-06-13-V1"
+# CACHEKEY: "bionic_coq-V2018-07-02-V4"
# ^^ Update when modifying this file.
FROM ubuntu:bionic
@@ -6,10 +6,12 @@ LABEL maintainer="e@x80.org"
ENV DEBIAN_FRONTEND="noninteractive"
-RUN apt-get update -qq && apt-get install -y -qq m4 wget time gcc-multilib opam \
+RUN apt-get update -qq && apt-get install --no-install-recommends -y -qq \
+ m4 automake autoconf time wget rsync git gcc-multilib opam \
libgtk2.0-dev libgtksourceview2.0-dev \
- texlive-latex-extra texlive-fonts-recommended texlive-science \
- python3-sphinx python3-pexpect python3-sphinx-rtd-theme python3-bs4 python3-sphinxcontrib.bibtex python3-pip
+ texlive-latex-extra texlive-fonts-recommended texlive-science tipa \
+ python3-sphinx python3-pexpect python3-sphinx-rtd-theme python3-bs4 python3-sphinxcontrib.bibtex \
+ python3-setuptools python3-wheel python3-pip
RUN pip3 install antlr4-python3-runtime
diff --git a/dev/ci/gitlab.bat b/dev/ci/gitlab.bat
index 70278e6d0..973319de6 100644
--- a/dev/ci/gitlab.bat
+++ b/dev/ci/gitlab.bat
@@ -28,7 +28,7 @@ if exist %DESTCOQ%\ rd /s /q %DESTCOQ%
call %CI_PROJECT_DIR%\dev\build\windows\MakeCoq_MinGW.bat -threads=1 ^
-arch=%ARCH% -installer=Y -coqver=%CI_PROJECT_DIR_CFMT% ^
-destcyg=%CYGROOT% -destcoq=%DESTCOQ% -cygcache=%CYGCACHE% ^
- -addon=bignums -make=N ^
+ -addon="bignums ltac2 equations" -make=N ^
-setup %CI_PROJECT_DIR%\%SETUP% || GOTO ErrorExit
copy "%CYGROOT%\build\coq-local\dev\nsis\*.exe" dev\nsis || GOTO ErrorExit
diff --git a/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh b/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh
deleted file mode 100644
index 9d96b6d4c..000000000
--- a/dev/ci/user-overlays/00664-herbelin-master+change-for-coq-pr664-compatibility.sh
+++ /dev/null
@@ -1,4 +0,0 @@
- if [ "$CI_PULL_REQUEST" = "664" ] || [ "$CI_BRANCH" = "trunk+fix-5500-too-weak-test-return-clause" ]; then
- fiat_parsers_CI_BRANCH=master+change-for-coq-pr664-compatibility
- fiat_parsers_CI_GITURL=https://github.com/herbelin/fiat
-fi
diff --git a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
index e9ba11414..e6a2c4460 100644
--- a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
+++ b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
@@ -2,5 +2,5 @@
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_BRANCH=ssr-merge
- mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp.git
+ mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp
fi
diff --git a/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh b/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh
deleted file mode 100644
index f4cb71cf1..000000000
--- a/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6454" ] || [ "$CI_BRANCH" = "evar+strict_to_constr" ]; then
-
- # ltac2_CI_BRANCH=econstr+more_fix
- # ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=evar+strict_to_constr
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06859-ejgallego-stm+top.sh b/dev/ci/user-overlays/06859-ejgallego-stm+top.sh
deleted file mode 100644
index b22ab3630..000000000
--- a/dev/ci/user-overlays/06859-ejgallego-stm+top.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-if [ "$CI_PULL_REQUEST" = "6859" ] || [ "$CI_BRANCH" = "stm+top" ] || \
- [ "$CI_PULL_REQUEST" = "7543" ] || [ "$CI_BRANCH" = "ide+split" ] ; then
-
- pidetop_CI_BRANCH=stm+top
- pidetop_CI_GITURL=https://bitbucket.org/ejgallego/pidetop.git
-
-fi
diff --git a/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh b/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh
deleted file mode 100644
index cf2af9ae9..000000000
--- a/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6960" ] || [ "$CI_BRANCH" = "ltac+tacdepr" ]; then
-
- # Equations_CI_BRANCH=ssr+correct_packing
- # Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- ltac2_CI_BRANCH=ltac+tacdepr
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- # Elpi_CI_BRANCH=ssr+correct_packing
- # Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-
-fi
diff --git a/dev/ci/user-overlays/07099-ppedrot-unification-returns-option.sh b/dev/ci/user-overlays/07099-ppedrot-unification-returns-option.sh
deleted file mode 100644
index e6c48d10a..000000000
--- a/dev/ci/user-overlays/07099-ppedrot-unification-returns-option.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7099" ] || [ "$CI_BRANCH" = "unification-returns-option" ]; then
- Equations_CI_BRANCH=unification-returns-option
- Equations_CI_GITURL=https://github.com/ppedrot/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/07136-evar-map-econstr.sh b/dev/ci/user-overlays/07136-evar-map-econstr.sh
deleted file mode 100644
index 06aa62726..000000000
--- a/dev/ci/user-overlays/07136-evar-map-econstr.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7136" ] || [ "$CI_BRANCH" = "evar-map-econstr" ]; then
- Equations_CI_BRANCH=8.9+alpha
- Equations_CI_GITURL=https://github.com/SkySkimmer/Coq-Equations.git
-
- Elpi_CI_BRANCH=coq-7136
- Elpi_CI_GITURL=https://github.com/SkySkimmer/coq-elpi.git
-fi
diff --git a/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh b/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh
deleted file mode 100644
index 7e554684e..000000000
--- a/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7152" ] || [ "$CI_BRANCH" = "api+vernac_expr_iso" ]; then
-
- # Equations_CI_BRANCH=ssr+correct_packing
- # Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- # ltac2_CI_BRANCH=ssr+correct_packing
- # ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Elpi_CI_BRANCH=api+vernac_expr_iso
- Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-
-fi
diff --git a/dev/ci/user-overlays/07196-ejgallego-tactics+push_fix_naming_out.sh b/dev/ci/user-overlays/07196-ejgallego-tactics+push_fix_naming_out.sh
deleted file mode 100644
index ea9cd8ee0..000000000
--- a/dev/ci/user-overlays/07196-ejgallego-tactics+push_fix_naming_out.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7196" ] || [ "$CI_BRANCH" = "tactics+push_fix_naming_out" ] || [ "$CI_BRANCH" = "pr-7196" ]; then
-
- # Needed overlays: https://gitlab.com/coq/coq/pipelines/21244550
- #
- # equations
- # ltac2
-
- # The below developments should instead use a backwards compatible fix.
- #
- # color
- # iris-lambda-rust
- # math-classes
- # formal-topology
-
- ltac2_CI_BRANCH=tactics+push_fix_naming_out
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=tactics+push_fix_naming_out
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
-fi
diff --git a/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh b/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh
deleted file mode 100644
index 517088a24..000000000
--- a/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7213" ] || [ "$CI_BRANCH" = "fast-constr-match-no-context" ]; then
-
- ltac2_CI_BRANCH=fast-constr-match-no-context
- ltac2_CI_GITURL=https://github.com/ppedrot/ltac2
-
-fi
diff --git a/dev/ci/user-overlays/07495-gares-elpi-test-bug.sh b/dev/ci/user-overlays/07495-gares-elpi-test-bug.sh
deleted file mode 100644
index 6939ead2b..000000000
--- a/dev/ci/user-overlays/07495-gares-elpi-test-bug.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7495" ] || [ "$CI_BRANCH" = "fix-restrict" ]; then
-
- # this branch contains a commit not present on coq-master that triggers
- # the universe restriction bug #7472
- Elpi_CI_BRANCH=overlay-7495
- Elpi_CI_GITURL=https://github.com/LPCIC/coq-elpi.git
-
-fi
diff --git a/dev/ci/user-overlays/07558-ejgallego-vernac+move_parser.sh b/dev/ci/user-overlays/07558-ejgallego-vernac+move_parser.sh
deleted file mode 100644
index 115f29f1e..000000000
--- a/dev/ci/user-overlays/07558-ejgallego-vernac+move_parser.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "7558" ] || [ "$CI_BRANCH" = "vernac+move_parser" ]; then
-
- _OVERLAY_BRANCH=vernac+move_parser
-
- Equations_CI_BRANCH="$_OVERLAY_BRANCH"
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- ltac2_CI_BRANCH="$_OVERLAY_BRANCH"
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- mtac2_CI_BRANCH="$_OVERLAY_BRANCH"
- mtac2_CI_GITURL=https://github.com/ejgallego/Mtac2
-
-fi
diff --git a/dev/ci/user-overlays/07677-ejgallego-misctypes+bye2.sh b/dev/ci/user-overlays/07677-ejgallego-misctypes+bye2.sh
deleted file mode 100644
index b4f716139..000000000
--- a/dev/ci/user-overlays/07677-ejgallego-misctypes+bye2.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-_OVERLAY_BRANCH=misctypes+bye2
-
-if [ "$CI_PULL_REQUEST" = "7677" ] || [ "$CI_BRANCH" = "_OVERLAY_BRANCH" ]; then
-
- Equations_CI_BRANCH="$_OVERLAY_BRANCH"
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
-fi
diff --git a/dev/ci/user-overlays/07746-cleanup-unused-various.sh b/dev/ci/user-overlays/07746-cleanup-unused-various.sh
new file mode 100644
index 000000000..8688b0d53
--- /dev/null
+++ b/dev/ci/user-overlays/07746-cleanup-unused-various.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if [ "$CI_PULL_REQUEST" = "7746" ] || [ "$CI_BRANCH" = "cleanup-unused-various" ]; then
+ Equations_CI_BRANCH="adapt-unused"
+ Equations_CI_GITURL="https://github.com/SkySkimmer/Coq-Equations.git"
+fi
diff --git a/dev/ci/user-overlays/07797-rm-reference.sh b/dev/ci/user-overlays/07797-rm-reference.sh
deleted file mode 100644
index f7811cd6f..000000000
--- a/dev/ci/user-overlays/07797-rm-reference.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-_OVERLAY_BRANCH=rm-reference
-
-if [ "$CI_PULL_REQUEST" = "7797" ] || [ "$CI_BRANCH" = "_OVERLAY_BRANCH" ]; then
-
- Equations_CI_BRANCH="$_OVERLAY_BRANCH"
- Equations_CI_GITURL=https://github.com/maximedenes/Coq-Equations.git
-
- ltac2_CI_BRANCH="fix-7797"
- ltac2_CI_GITURL=https://github.com/ppedrot/Ltac2.git
-
- quickchick_CI_BRANCH="$_OVERLAY_BRANCH"
- quickchick_CI_GITURL=https://github.com/maximedenes/QuickChick.git
-
- coq_dpdgraph_CI_BRANCH="$_OVERLAY_BRANCH"
- coq_dpdgraph_CI_GITURL=https://github.com/maximedenes/coq-dpdgraph.git
-
- Elpi_CI_BRANCH="$_OVERLAY_BRANCH"
- Elpi_CI_GITURL=https://github.com/maximedenes/coq-elpi.git
-
-fi
diff --git a/dev/ci/user-overlays/07820-mattam82-hints-constants.sh b/dev/ci/user-overlays/07820-mattam82-hints-constants.sh
new file mode 100644
index 000000000..2ae86ae22
--- /dev/null
+++ b/dev/ci/user-overlays/07820-mattam82-hints-constants.sh
@@ -0,0 +1,6 @@
+_OVERLAY_BRANCH=hints-variables-overlay
+
+if [ "$CI_PULL_REQUEST" = "7820" ] || [ "$CI_BRANCH" = "_OVERLAY_BRANCH" ]; then
+
+ Equations_CI_BRANCH="$_OVERLAY_BRANCH"
+fi
diff --git a/dev/ci/user-overlays/07902-ppedrot-camlp5-parser.sh b/dev/ci/user-overlays/07902-ppedrot-camlp5-parser.sh
new file mode 100644
index 000000000..735153ebd
--- /dev/null
+++ b/dev/ci/user-overlays/07902-ppedrot-camlp5-parser.sh
@@ -0,0 +1,8 @@
+_OVERLAY_BRANCH=camlp5-parser
+
+if [ "$CI_PULL_REQUEST" = "7902" ] || [ "$CI_BRANCH" = "$_OVERLAY_BRANCH" ]; then
+
+ ltac2_CI_BRANCH="$_OVERLAY_BRANCH"
+ ltac2_CI_GITURL=https://github.com/ppedrot/ltac2
+
+fi
diff --git a/dev/ci/user-overlays/README.md b/dev/ci/user-overlays/README.md
index 41212568d..d38d1b06d 100644
--- a/dev/ci/user-overlays/README.md
+++ b/dev/ci/user-overlays/README.md
@@ -9,6 +9,8 @@ testing is possible. It redefines some variables from
[`ci-basic-overlay.sh`](../ci-basic-overlay.sh):
give the name of your branch using a `_CI_BRANCH` variable and the location of
your fork using a `_CI_GITURL` variable.
+The `_CI_GITURL` variable should be the URL of the repository without a
+trailing `.git`.
Moreover, the file contains very simple logic to test the pull request number
or branch name and apply it only in this case.
@@ -24,7 +26,7 @@ Example: `00669-maximedenes-ssr-merge.sh` containing
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_BRANCH=ssr-merge
- mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp.git
+ mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp
fi
```
diff --git a/dev/doc/README.md b/dev/doc/README.md
new file mode 100644
index 000000000..1a4e40f68
--- /dev/null
+++ b/dev/doc/README.md
@@ -0,0 +1,77 @@
+# Beginner's guide to hacking Coq
+
+## Getting dependencies
+
+Assuming one is running Ubuntu (if not, replace `apt` with the package manager of choice)
+
+```
+$ sudo apt-get install make opam git
+
+# At the time of writing, <latest-ocaml-version> is 4.06.1.
+# The latest version number is available at: https://ocaml.org/releases/
+
+$ opam init --comp <latest-ocaml-version>
+
+# Then follow the advice displayed at the end as how to update your
+ ~/.bashrc and ~/.ocamlinit files.
+
+$ source ~/.bashrc
+$ opam install camlp5
+
+# needed if you want to build "coqide" target
+
+$ sudo apt-get install liblablgtksourceview2-ocaml-dev \
+ libgtk2.0-dev libgtksourceview2.0-dev
+$ opam install lablgtk
+```
+
+## Building `coqtop`
+The general workflow is to first setup a development environment with
+the correct `configure` settings, then hacking on Coq, make-ing, and testing.
+
+
+This document will use `$JOBS` to refer to the number of parallel jobs one
+is willing to have with `make`.
+
+
+```
+$ git clone git clone https://github.com/coq/coq.git
+$ cd coq
+$ ./configure -profile devel
+$ make -j $JOBS # Make once for `merlin`(autocompletion tool)
+
+<hack>
+
+$ make -j $JOBS states # builds just enough to run coqtop
+$ bin/coqtop -compile <test_file_name.v>
+<goto hack until stuff works>
+
+<run test-suite>
+```
+
+To learn how to run the test suite, you can read
+[`test-suite/README.md`](../../test-suite/README.md).
+
+## Coq functions of interest
+- `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.
+ It dispatches the control to specific functions handling different Vernacular command.
+- `Vernacentries.vernac_check_may_eval`: This function handles the `Check ...` command.
+
+
+## Development environment + tooling
+- [`Merlin`](https://github.com/ocaml/merlin) for autocomplete.
+- [Wiki pages on tooling containing `emacs`, `vim`, and `git` information](https://github.com/coq/coq/wiki/DevelSetup)
+
+## A note about rlwrap
+
+When using `rlwrap coqtop` make sure the version of `rlwrap` is at least
+`0.42`, otherwise you will get
+
+```
+rlwrap: error: Couldn't read completions from /usr/share/rlwrap/completions/coqtop: No such file or directory
+```
+
+If this happens either update or use an alternate readline wrapper like `ledit`.
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index f3fc126f9..6d5023405 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -53,6 +53,16 @@ Printer.ml API
pr_subgoal and pr_goal was removed to simplify the code. It was
earlierly used by PCoq.
+Kernel
+
+ The following renamings happened:
+ - `Context.Rel.t` into `Constr.rel_context`
+ - `Context.Named.t` into `Constr.named_context`
+ - `Context.Compacted.t` into `Constr.compacted_context`
+ - `Context.Rel.Declaration.t` into `Constr.rel_declaration`
+ - `Context.Named.Declaration.t` into `Constr.named_declaration`
+ - `Context.Compacted.Declaration.t` into `Constr.compacted_declaration`
+
Source code organization
- We have eliminated / fused some redundant modules and relocated a
@@ -72,11 +82,114 @@ Vernacular commands
`tactics/`. In all cases adapting is a matter of changing the module
name.
+Primitive number parsers
+
+- For better modularity, the primitive parsers for positive, N and Z
+ have been split over three files (plugins/syntax/positive_syntax.ml,
+ plugins/syntax/n_syntax.ml, plugins/syntax/z_syntax.ml).
+
### Unit testing
The test suite now allows writing unit tests against OCaml code in the Coq
code base. Those unit tests create a dependency on the OUnit test framework.
+### Transitioning away from Camlp5
+
+In an effort to reduce dependency on camlp5, the use of several grammar macros
+is discouraged. Coq is now shipped with its own preprocessor, called coqpp,
+which serves the same purpose as camlp5.
+
+To perform the transition to coqpp macros, one first needs to change the
+extension of a macro file from `.ml4` to `.mlg`. Not all camlp5 macros are
+handled yet.
+
+Due to parsing constraints, the syntax of the macros is slightly different, but
+updating the source code is mostly a matter of straightforward
+search-and-replace. The main differences are summarized below.
+
+#### OCaml code
+
+Every piece of toplevel OCaml code needs to be wrapped into braces.
+
+For instance, code of the form
+```
+let myval = 0
+```
+should be turned into
+```
+{
+let myval = 0
+}
+```
+
+#### TACTIC EXTEND
+
+Steps to perform:
+- replace the brackets enclosing OCaml code in actions with braces
+- if not there yet, add a leading `|̀ to the first rule
+
+For instance, code of the form:
+```
+TACTIC EXTEND my_tac
+ [ "tac1" int_or_var(i) tactic(t) ] -> [ mytac1 ist i t ]
+| [ "tac2" tactic(t) ] -> [ mytac2 t ]
+END
+```
+should be turned into
+```
+TACTIC EXTEND my_tac
+| [ "tac1" int_or_var(i) tactic(t) ] -> { mytac1 ist i t }
+| [ "tac2" tactic(t) ] -> { mytac2 t }
+END
+```
+
+#### VERNAC EXTEND
+
+Not handled yet.
+
+#### ARGUMENT EXTEND
+
+Not handled yet.
+
+#### GEXTEND
+
+Most plugin writers do not need this low-level interface, but for the sake of
+completeness we document it.
+
+Steps to perform are:
+- replace GEXTEND with GRAMMAR EXTEND
+- wrap every occurrence of OCaml code in actions into braces { }
+
+For instance, code of the form
+```
+GEXTEND Gram
+ GLOBAL: my_entry;
+
+my_entry:
+[ [ x = bar; y = qux -> do_something x y
+ | "("; z = LIST0 my_entry; ")" -> do_other_thing z
+] ];
+END
+```
+should be turned into
+```
+GRAMMAR EXTEND Gram
+ GLOBAL: my_entry;
+
+my_entry:
+[ [ x = bar; y = qux -> { do_something x y }
+ | "("; z = LIST0 my_entry; ")" -> { do_other_thing z }
+] ];
+END
+```
+
+Caveats:
+- No `GLOBAL` entries mean that they are all local, while camlp5 special-cases
+ this as a shorthand for all global entries. Solution: always define a `GLOBAL`
+ section.
+- No complex patterns allowed in token naming. Solution: match on it inside the
+ OCaml quotation.
+
## Changes between Coq 8.7 and Coq 8.8
### Bug tracker
diff --git a/dev/doc/critical-bugs b/dev/doc/critical-bugs
new file mode 100644
index 000000000..6166d24b7
--- /dev/null
+++ b/dev/doc/critical-bugs
@@ -0,0 +1,252 @@
+Preliminary compilation of critical bugs in stable releases of Coq
+==================================================================
+ WORK IN PROGRESS WITH SEVERAL OPEN QUESTIONS
+
+
+To add: #7723 (vm_compute universe polymorphism), #7695 (modules and algebraic universes), #7615 (lost functor substitutions)
+
+Typing constructions
+
+ component: "match"
+ summary: substitution missing in the body of a let
+ introduced: ?
+ impacted released versions: V8.3-V8.3pl2, V8.4-V8.4pl4
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: master/trunk/v8.5 (e583a79b5, 22 Nov 2015, Herbelin), v8.4 (525056f1, 22 Nov 2015, Herbelin), v8.3 (4bed0289, 22 Nov 2015, Herbelin)
+ found by: Herbelin
+ exploit: test-suite/success/Case22.v
+ GH issue number: ?
+ risk: ?
+
+ component: fixpoint, guard
+ summary: missing lift in checking guard
+ introduced: probably from V5.10
+ impacted released versions: probably V5-V7, V8.0-V8.0pl4, V8.1-V8.1pl4
+ impacted development branches: v8.0 ?
+ impacted coqchk versions: ?
+ fixed in: master/trunk/v8.2 (ff45afa8, r11646, 2 Dec 2008, Barras), v8.1 (f8e7f273, r11648, 2 Dec 2008, Barras)
+ found by: Barras
+ exploit: test-suite/failure/guard.v
+ GH issue number: none
+ risk: unprobable by chance
+
+ component: cofixpoint, guard
+ summary: de Bruijn indice bug in checking guard of nested cofixpoints
+ introduced: after V6.3.1, before V7.0
+ impacted released versions: V8.0-V8.0pl4, V8.1-V8.1pl4, V8.2-V8.2pl2, V8.3-V8.3pl2, V8.4-V8.4pl4
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: master (9f81e2c36, 10 Apr 2014, Dénès), v8.4 (f50ec9e7d, 11 Apr 2014, Dénès), v8.3 (40c0fe7f4, 11 Apr 2014, Dénès), v8.2 (06d66df8c, 11 Apr 2014, Dénès), v8.1 (977afae90, 11 Apr 2014, Dénès), v8.0 (f1d632992, 29 Nov 2015, Herbelin, backport)
+ found by: Dénès
+ exploit: ?
+ GH issue number: none ?
+ risk: ?
+
+ component: inductive types, elimination principle
+ summary: de Bruijn indice bug in computing allowed elimination principle
+ introduced: 23 May 2006, 9c2d70b, r8845, Herbelin (part of universe polymorphism)
+ impacted released versions: V8.1-V8.1pl4, V8.2-V8.2pl2, V8.3-V8.3pl2, V8.4-V8.4pl4
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: master (8a01c3685, 24 Jan 2014, Dénès), v8.4 (8a01c3685, 25 Feb 2014, Dénès), v8.3 (2b3cc4f85, 25 Feb 2014, Dénès), v8.2 (459888488, 25 Feb 2014, Dénès), v8.1 (79aa20872, 25 Feb 2014, Dénès)
+ found by: Dénès
+ exploit: see GH#3211
+ GH issue number: #3211
+ risk: ?
+
+ component: universe subtyping
+ summary: bug in Prop<=Set conversion which made Set identifiable with Prop, preventing a proof-irrelevant interpretation of Prop
+ introduced: V8.2 (bba897d5f, 12 May 2008, Herbelin)
+ impacted released versions: V8.2-V8.2pl2
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: master/trunk (679801, r13450, 23 Sep 2010, Glondu), v8.3 (309a53f2, r13449, 22 Sep 2010, Glondu), v8.2 (41ea5f08, r14263, 6 Jul 2011, Herbelin, backport)
+ found by: Georgi Guninski
+ exploit: test-suite/bugs/closed/4294.v
+ GH issue number: #4294
+ risk: ?
+
+Module system
+
+ component: modules, universes
+ summary: missing universe constraints in typing "with" clause of a module type
+ introduced: ?
+ impacted released versions: V8.3-V8.3pl2, V8.4-V8.4pl6; unclear for V8.2 and previous versions
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: master/trunk (d4869e059, 2 Oct 2015, Sozeau), v8.4 (40350ef3b, 9 Sep 2015, Sozeau)
+ found by: Dénès
+ exploit: test-suite/bugs/closed/4294.v
+ GH issue number: #4294
+ risk: ?
+
+Module system
+
+ component: modules, universes
+ summary: universe constraints for module subtyping not stored in vo files
+ introduced: presumably 8.2 (b3d3b56)
+ impacted released versions: 8.2, 8.3, 8.4
+ impacted development branches: v8.5
+ impacted coqchk versions: none
+ fixed in: v8.2 (c1d9889), v8.3 (8056d02), v8.4 (a07deb4), trunk (0cd0a3e) Mar 5, 2014, Tassi
+ found by: Tassi by running coqchk on the mathematical components library
+ exploit: requires multiple files, no test provided
+ GH issue number: #3243
+ risk: could be exploited by mistake
+
+Universes
+
+ component: template polymorphism
+ summary: issue with two parameters in the same universe level
+ introduced: 23 May 2006, 9c2d70b, r8845, Herbelin
+ impacted released versions: V8.1-V8.1pl4, V8.2-V8.2pl2, V8.3-V8.3pl2
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: trunk/master/v8.4 (8082d1faf, 5 Oct 2011, Herbelin), V8.3pl3 (bb582bca2, 5 Oct 2011, Herbelin), v8.2 branch (3333e8d3, 5 Oct 2011, Herbelin), v8.1 branch (a8fc2027, 5 Oct 2011, Herbelin),
+ found by: Barras
+ exploit: test-suite/failure/inductive4.v
+ GH issue number: none
+ risk: unlikely to be activated by chance
+
+Primitive projections
+
+ component: primitive projections, guard condition
+ summary: check of guardedness of extra arguments of primitive projections missing
+ introduced: 6 May 2014, a4043608f, Sozeau
+ impacted released versions: V8.5-V8.5pl2,
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: trunk/master/v8.5 (ba00867d5, 25 Jul 2016, Sozeau)
+ found by: Sozeau, by analyzing bug report #4876
+ exploit: to be done (?)
+ GH issue number: #4876
+ risk: consequence of bug found by chance, unlikely to be exploited by chance (MS?)
+
+ component: primitive projections, guard condition
+ summary: records based on primitive projections became possibly recursive without the guard condition being updated
+ introduced: 10 Sep 2014, 6624459e4, Sozeau (?)
+ impacted released versions: V8.5
+ impacted development branches: none
+ impacted coqchk versions: ?
+ fixed in: trunk/master/v8.5 (120053a50, 4 Mar 2016, Dénès)
+ found by: Dénès exploiting bug #4588
+ exploit: test-suite/bugs/closed/4588.v
+ GH issue number: #4588
+ risk: ?
+
+Conversion machines
+
+ component: "lazy machine" (lazy krivine abstract machine)
+ summary: the invariant justifying some optimization was wrong for some combination of sharing side effects
+ introduced: prior to V7.0
+ impacted released versions: V8.0-V8.0pl4, V8.1-V8.1pl3
+ impacted development branches: none
+ impacted coqchk versions: (eefe63d52, Barras, 20 May 2008), was in beta-development for 8.2 at this time
+ fixed in: master/trunk/8.2 (f13aaec57/a8b034513, 15 May 2008, Barras), v8.1 (e7611477a, 15 May 2008, Barras), v8.0 (6ed40a8bc, 29 Nov 2016, Herbelin, backport)
+ found by: Gonthier
+ exploit: by Gonthier
+ GH issue number: none
+ risk: unrealistic to be exploited by chance
+
+ component: "virtual machine" (compilation to bytecode ran by a C-interpreter)
+ summary: collision between constructors when more than 256 constructors in a type
+ introduced: V8.1
+ impacted released versions: V8.1-V8.5pl3, V8.2-V8.2pl2, V8.3-V8.3pl3, V8.4-V8.4pl5
+ impacted development branches: none
+ impacted coqchk versions: none (no virtual machine in coqchk)
+ fixed in: master/trunk/v8.5 (00894adf6/596a4a525, 26-39 Mar 2015, Grégoire), v8.4 (cd2101a39, 1 Apr 2015, Grégoire), v8.3 (a0c7fc05b, 1 Apr 2015, Grégoire), v8.2 (2c6189f61, 1 Apr 2015, Grégoire), v8.1 (bb877e5b5, 29 Nov 2015, Herbelin, backport)
+ found by: Dénès, Pédrot
+ exploit: test-suite/failure/vm-bug4157.v
+ GH issue number: #4157
+ risk:
+
+ component: "virtual machine" (compilation to bytecode ran by a C-interpreter)
+ summary: wrong universe constraints
+ introduced: possibly exploitable from V8.1; exploitable at least from V8.5
+ impacted released versions: V8.1-V8.4pl5 unknown, V8.5-V8.5pl3, V8.6-V8.6.1, V8.7.0-V8.7.1
+ impacted development branches: unknown for v8.1-v8.4, none from v8.5
+ impacted coqchk versions: none (no virtual machine in coqchk)
+ fixed in: master (c9f3a6cbe, 12 Feb 2018, PR#6713, Dénès), v8.7 (c058a4182, 15 Feb 2018, Zimmermann, backport), v8.6 (a2cc54c64, 21 Feb 2018, Herbelin, backport), v8.5 (d4d550d0f, 21 Feb 2018, Herbelin, backport)
+ found by: Dénès
+ exploit: test-suite/bugs/closed/6677.v
+ GH issue number: #6677
+ risk:
+
+ component: "virtual machine" (compilation to bytecode ran by a C-interpreter)
+ summary: missing pops in executing 31bit arithmetic
+ introduced: V8.5
+ impacted released versions: V8.1-V8.4pl5
+ impacted development branches: v8.1 (probably)
+ impacted coqchk versions: none (no virtual machine in coqchk)
+ fixed in: master/trunk/v8.5 (a5e04d9dd, 6 Sep 2015, Dénès), v8.4 (d5aa3bf6, 9 Sep 2015, Dénès), v8.3 (5da5d751, 9 Sep 2015, Dénès), v8.2 (369e82d2, 9 Sep 2015, Dénès),
+ found by: Catalin Hritcu
+ exploit: lost?
+ GH issue number: ?
+ risk:
+
+ component: "native" conversion machine (translation to OCaml which compiles to native code)
+ summary: translation of identifier from Coq to OCaml was not bijective, leading to identify True and False
+ introduced: V8.5
+ impacted released versions: V8.5-V8.5pl1
+ impacted development branches: none
+ impacted coqchk versions: none (no native computation in coqchk)
+ fixed in: master/trunk/v8.6 (244d7a9aa, 19 May 2016, letouzey), v8.5 (088b3161c, 19 May 2016, letouzey),
+ found by: Letouzey, Dénès
+ exploit: lost?
+ GH issue number: ?
+ risk:
+
+Conflicts with axioms in library
+
+ component: library of real numbers
+ summary: axiom of description and decidability of equality on real numbers in library Reals was inconsistent with impredicative Set
+ introduced: 67c75fa01, 20 Jun 2002
+ impacted released versions: 7.3.1, 7.4
+ impacted coqchk versions:
+ fixed by deciding to drop impredicativity of Set: bac707973, 28 Oct 2004
+ found by: Herbelin & Werner
+ exploit: need to find the example again
+ GH issue number: no
+ risk: unlikely to be exploited by chance
+
+ component: library of extensional sets, guard condition
+ summary: guard condition was unknown to be inconsistent with propositional extensionality in library Sets
+ introduced: not a bug per se but an incompatibility discovered late
+ impacted released versions: technically speaking from V6.1 with the introduction of the Sets library which was then inconsistent from the very beginning without we knew it
+ impacted coqchk versions: ?
+ fixed by constraining the guard condition: (9b272a8, ccd7546c 28 Oct 2014, Barras, Dénès)
+ found by: Schepler, Dénès, Azevedo de Amorim
+ exploit: ?
+ GH issue number: none
+ risk: unlikely to be exploited by chance (?)
+
+ component: library for axiom of choice and excluded-middle
+ summary: incompatibility axiom of choice and excluded-middle with elimination of large singletons to Set
+ introduced: not a bug but a change of intended "model"
+ impacted released versions: strictly before 8.1
+ impacted coqchk versions: ?
+ fixed by constraining singleton elimination: b19397ed8, r9633, 9 Feb 2007, Herbelin
+ found by: Benjamin Werner
+ exploit:
+ GH issue number: none
+ risk:
+
+There were otherwise several bugs in beta-releases, from memory, bugs with beta versions of primitive projections or template polymorphism or native compilation or guard (e7fc96366, 2a4d714a1).
+
+There were otherwise maybe unexploitable kernel bugs, e.g. 2df88d83 (Require overloading), 0adf0838 ("Univs: uncovered bug in strengthening of opaque polymorphic definitions."), 5122a398 (#3746 about functors), #4346 (casts in VM), a14bef4 (guard condition in 8.1), 6ed40a8 ("Georges' bug" with ill-typed lazy machine), and various other bugs in 8.0 or 8.1 w/o knowing if they are critical.
+
+Another non exploitable bug?
+
+ component: "virtual machine" (compilation to bytecode ran by a C-interpreter)
+ summary: bug in 31bit arithmetic
+ introduced: V8.1
+ impacted released versions: none
+ impacted development branches:
+ impacted coqchk versions: none (no virtual machine in coqchk)
+ fixed in: master/trunk/v8.5 (0f8d1b92c, 6 Sep 2015, Dénès)
+ found by: Dénès, from a bug report by Tahina Ramananandro
+ exploit: ?
+ GH issue number: ?
+ risk:
+
diff --git a/dev/doc/profiling.txt b/dev/doc/profiling.txt
index 9d2ebf0d4..b5dd8445d 100644
--- a/dev/doc/profiling.txt
+++ b/dev/doc/profiling.txt
@@ -7,7 +7,7 @@ want to profile time or memory consumption. AFAIK, this only works for Linux.
In Coq source folder:
-opam switch 4.02.1+fp
+opam switch 4.02.3+fp
./configure -local -debug
make
perf record -g bin/coqtop -compile file.v
diff --git a/dev/doc/setup.txt b/dev/doc/setup.txt
deleted file mode 100644
index c48c2d5d1..000000000
--- a/dev/doc/setup.txt
+++ /dev/null
@@ -1,269 +0,0 @@
-This document provides detailed guidance on how to:
-- compile Coq
-- take advantage of Merlin in Emacs
-- enable auto-completion for Ocaml source-code
-- use ocamldebug in Emacs for debugging coqtop
-The instructions were tested with Debian 8.3 (Jessie).
-
-The procedure is somewhat tedious, but the final results are (still) worth the effort.
-
-How to compile Coq
-------------------
-
-Getting build dependencies:
-
- sudo apt-get install make opam git
- opam init --comp 4.02.3
- # Then follow the advice displayed at the end as how to update your ~/.bashrc and ~/.ocamlinit files.
-
- source ~/.bashrc
-
- # needed if you want to build "coqtop" target
- opam install camlp5
-
- # needed if you want to build "coqide" target
- sudo apt-get install liblablgtksourceview2-ocaml-dev libgtk2.0-dev libgtksourceview2.0-dev
- opam install lablgtk
-
- # needed if you want to build "doc" target
- sudo apt-get install texlive-latex-recommended texlive-fonts-extra texlive-math-extra \
- hevea texlive-latex-extra latex-xcolor
-
-Cloning Coq:
-
- # Go to the directory where you want to clone Coq's source-code. E.g.:
- cd ~/git
-
- git clone https://github.com/coq/coq.git
-
-Building coqtop:
-
- cd ~/git/coq
- git checkout trunk
- make distclean
- ./configure -profile devel
- make clean
- make -j4 coqide printers
-
-The "-profile devel" enables all options recommended for developers (like
-warnings, support for Merlin, etc). Moreover Coq is configured so that
-it can be run without installing it (i.e. from the current directory).
-
-Once the compilation is over check if
-- bin/coqtop
-- bin/coqide
-behave as expected.
-
-
-A note about rlwrap
--------------------
-
-When using "rlwrap coqtop" make sure the version of rlwrap is at least
-0.42, otherwise you will get
-
- rlwrap: error: Couldn't read completions from /usr/share/rlwrap/completions/coqtop: No such file or directory
-
-If this happens either update or use an alternate readline wrapper like "ledit".
-
-
-How to install and configure Merlin (for Emacs)
------------------------------------------------
-
- sudo apt-get install emacs
-
- opam install tuareg
- # Follow the advice displayed at the end as how to update your ~/.emacs file.
-
- opam install merlin
- # Follow the advice displayed at the end as how to update your ~/.emacs file.
-
-Then add this:
-
- (push "~/.opam/4.02.3/share/emacs/site-lisp" load-path) ; directory containing merlin.el
- (setq merlin-command "~/.opam/4.02.3/bin/ocamlmerlin") ; needed only if ocamlmerlin not already in your PATH
- (autoload 'merlin-mode "merlin" "Merlin mode" t)
- (add-hook 'tuareg-mode-hook 'merlin-mode)
- (add-hook 'caml-mode-hook 'merlin-mode)
- (load "~/.opam/4.02.3/share/emacs/site-lisp/tuareg-site-file")
-
- ;; Do not use TABs. These confuse Merlin.
- (setq-default indent-tabs-mode nil)
-
-to your ~/.emacs file.
-
-Further Emacs configuration when we start it for the first time.
-
-Try to open some *.ml file in Emacs, e.g.:
-
- cd ~/git/coq
- emacs toplevel/coqtop.ml &
-
-Emacs display the following strange message:
-
- The local variables list in ~/git/coq
- contains values that may be safe (*).
-
- Do you want to apply it?
-
-Just press "!", i.e. "apply the local variable list, and permanently mark these values (\*) as safe."
-
-Emacs then shows two windows:
-- one window that shows the contents of the "toplevel/coqtop.ml" file
-- and the other window that shows greetings for new Emacs users.
-
-If you do not want to see the second window next time you start Emacs, just check "Never show it again" and click on "Dismiss this startup screen."
-
-The default key-bindings are described here:
-
- https://github.com/the-lambda-church/merlin/wiki/emacs-from-scratch
-
-If you want, you can customize them by replacing the following lines:
-
- (define-key merlin-map (kbd "C-c C-x") 'merlin-error-next)
- (define-key merlin-map (kbd "C-c C-l") 'merlin-locate)
- (define-key merlin-map (kbd "C-c &") 'merlin-pop-stack)
- (define-key merlin-map (kbd "C-c C-t") 'merlin-type-enclosing)
-
-in the file "~/.opam/4.02.3/share/emacs/site-lisp/merlin.el" with what you want.
-In the text below we assume that you changed the origin key-bindings in the following way:
-
- (define-key merlin-map (kbd "C-n") 'merlin-error-next)
- (define-key merlin-map (kbd "C-l") 'merlin-locate)
- (define-key merlin-map (kbd "C-b") 'merlin-pop-stack)
- (define-key merlin-map (kbd "C-t") 'merlin-type-enclosing)
-
-Now, when you press <Ctrl+L>, Merlin will show the definition of the symbol in a separate window.
-If you prefer to jump to the definition within the same window, do this:
-
- <Alt+X> customize-group <ENTER> merlin <ENTER>
-
- Merlin Locate In New Window
-
- Value Menu
-
- Never Open In New Window
-
- State
-
- Set For Future Sessions
-
-Testing (Merlin):
-
- cd ~/git/coq
- emacs toplevel/coqtop.ml &
-
-Go to the end of the file where you will see the "start" function.
-
-Go to a line where "init_toplevel" function is called.
-
-If you want to jump to the position where that function or datatype under the cursor is defined, press <Ctrl+L>.
-
-If you want to jump back, type: <Ctrl+B>
-
-If you want to learn the type of the value at current cursor's position, type: <Ctrl+T>
-
-
-Enabling auto-completion in emacs
----------------------------------
-
-In Emacs, type: <Alt+M> list-packages <ENTER>
-
-In the list that is displayed, click on "company".
-
-A new window appears where just click on "Install" and then answer "Yes".
-
-These lines:
-
- (package-initialize)
- (require 'company)
- ; Make company aware of merlin
- (add-to-list 'company-backends 'merlin-company-backend)
- ; Enable company on merlin managed buffers
- (add-hook 'merlin-mode-hook 'company-mode)
- (global-set-key [C-tab] 'company-complete)
-
-then need to be added to your "~/.emacs" file.
-
-Next time when you start emacs and partially type some identifier,
-emacs will offer the corresponding completions.
-Auto-completion can also be manually invoked by typing <Ctrl+TAB>.
-Description of various other shortcuts is here.
-
- http://company-mode.github.io/
-
-
-Getting along with ocamldebug
------------------------------
-
-The default ocamldebug key-bindings are described here.
-
- http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec369
-
-If you want, you can customize them by putting the following commands:
-
- (global-set-key (kbd "<f5>") 'ocamldebug-break)
- (global-set-key (kbd "<f6>") 'ocamldebug-run)
- (global-set-key (kbd "<f7>") 'ocamldebug-next)
- (global-set-key (kbd "<f8>") 'ocamldebug-step)
- (global-set-key (kbd "<f9>") 'ocamldebug-finish)
- (global-set-key (kbd "<f10>") 'ocamldebug-print)
- (global-set-key (kbd "<f12>") 'camldebug)
-
-to your "~/.emacs" file.
-
-Let us try whether ocamldebug in Emacs works for us.
-(If necessary, re-)compile coqtop:
-
- cd ~/git/coq
- make -j4 coqide printers
-
-open Emacs:
-
- emacs toplevel/coqtop.ml &
-
-and type:
-
- <F12> ../bin/coqtop.byte <ENTER> ../dev/ocamldebug-coq <ENTER>
-
-As a result, a new window is open at the bottom where you should see:
-
- (ocd)
-
-i.e. an ocamldebug shell.
-
- 1. Switch to the window that contains the "coqtop.ml" file.
- 2. Go to the end of the file.
- 3. Find the definition of the "start" function.
- 4. Go to the "let" keyword that is at the beginning of the first line.
- 5. By pressing <F5> you set a breakpoint to the cursor's position.
- 6. By pressing <F6> you start the bin/coqtop process.
- 7. Then you can:
- - step over function calls: <F7>
- - step into function calls: <F8>
- - or finish execution of the current function until it returns: <F9>.
-
-Other ocamldebug commands, can be typed to the window that holds the ocamldebug shell.
-
-The points at which the execution of Ocaml program can stop are defined here:
-
- http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec350
-
-
-Installing printers to ocamldebug
----------------------------------
-
-There is a pretty comprehensive set of printers defined for many common data types.
-You can load them by switching to the window holding the "ocamldebug" shell and typing:
-
- (ocd) source "../dev/db"
-
-
-Some of the functions were you might want to set a breakpoint and see what happens next
----------------------------------------------------------------------------------------
-
-- 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.\
- It dispatches the control to specific functions handling different Vernacular command.
-- Vernacentries.vernac_check_may_eval : This function handles the "Check ..." command.
diff --git a/dev/doc/translate.txt b/dev/doc/translate.txt
deleted file mode 100644
index 5b372c96c..000000000
--- a/dev/doc/translate.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-
- How to use the translator
- =========================
-
- (temporary version to be included in the official
- TeX document describing the translator)
-
-The translator is a smart, robust and powerful tool to improve the
-readibility of your script. The current document describes the
-possibilities of the translator.
-
-In case of problem recompiling the translated files, don't waste time
-to modify the translated file by hand, read first the following
-document telling on how to modify the original files to get a smooth
-uniform safe translation. All 60000 lines of Coq lines on our
-user-contributions server have been translated without any change
-afterwards, and 0,5 % of the lines of the original files (mainly
-notations) had to be modified beforehand to get this result.
-
-Table of contents
------------------
-
-I) Implicit Arguments
- 1) Strict Implicit Arguments
- 2) Implicit Arguments in standard library
-
-II) Notations
- 1) Translating a V7 notation as it was
- 2) Translating a V7 notation which conflicts with the new syntax
- a) Associativity conflicts
- b) Conflicts with other notations
- b1) A notation hides another notation
- b2) A notation conflicts with the V8 grammar
- b3) My notation is already defined at another level
- c) How to use V8only with Distfix ?
- d) Can I overload a notation in V8, e.g. use "*" and "+" ?
- 3) Using the translator to have simplest notations
- 4) Setting the translator to automatically use new notations that
- wasn't used in old syntax
- 5) Defining a construction and its notation simultaneously
-
-III) Various pitfalls
- 1) New keywords
- 2) Old "Case" and "Match"
- 3) Change of definition or theorem names
- 4) Change of tactic names
-
----------------------------------------------------------------------
-
-I) Implicit Arguments
- ------------------
-
-1) Strict Implicit Arguments
-
- "Set Implicit Arguments" changes its meaning in V8: the default is
-to turn implicit only the arguments that are _strictly_ implicit (or
-rigid), i.e. that remains inferable whatever the other arguments
-are. E.g "x" inferable from "P x" is not strictly inferable since it
-can disappears if "P" is instanciated by a term which erase "x".
-
- To respect the old semantics, the default behaviour of the
-translator is to replace each occurrence "Set Implicit Arguments" by
-
- Set Implicit Arguments.
- Unset Strict Implicits.
-
- However, you may wish to adopt the new semantics of "Set Implicit
-Arguments" (for instance because you think that the choice of
-arguments it setsimplicit is more "natural" for you). In this case,
-add the option -strict-implicit to the translator.
-
- Warning: Changing the number of implicit arguments can break the
-notations. Then use the V8only modifier of Notations.
-
-2) Implicit Arguments in standard library
-
- Main definitions of standard library have now implicit
-arguments. These arguments are dropped in the translated files. This
-can exceptionally be a source of incompatibilities which has to be
-solved by hand (it typically happens for polymorphic functions applied
-to "nil" or "None").
-
-II) Notations
- ---------
-
- Grammar (on constr) and Syntax are no longer supported. Replace them by
-Notation before translation.
-
- Precedence levels are now from 0 to 200. In V8, the precedence and
-associativity of an operator cannot be redefined. Typical level are
-(refer to the chapter on notations in the Reference Manual for the
-full list):
-
- <-> : 95 (no associativity)
- -> : 90 (right associativity)
- \/ : 85 (right associativity)
- /\ : 80 (right associativity)
- ~ : 75 (right associativity)
- =, <, >, <=, >=, <> : 70 (no associativity)
- +, - : 50 (left associativity)
- *, / : 40 (left associativity)
- ^ : 30 (right associativity)
-
-1) Translating a V7 notation as it was
-
- By default, the translator keeps the associativity given in V7 while
-the levels are mapped according to the following table:
-
- the V7 levels [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
- are resp. mapped in V8 to [ 0; 20; 30; 40; 50; 70; 80; 85; 90; 95; 100]
- with predefined assoc [ No; L; R; L; L; No; R; R; R; No; L]
-
- If this is OK for you, just simply apply the translator.
-
-2) Translating a V7 notation which conflicts with the new syntax
-
-a) Associativity conflict
-
- Since the associativity of the levels obtained by translating a V7
-level (as shown on table above) cannot be changed, you have to choose
-another level with a compatible associativity.
-
- You can choose any level between 0 and 200, knowing that the
-standard operators are already set at the levels shown on the list
-above.
-
-Example 1: Assume you have a notation
-
-Infix NONA 2 "=_S" my_setoid_eq.
-
-By default, the translator moves it to level 30 which is right
-associative, hence a conflict with the expected no associativity.
-
-To solve the problem, just add the "V8only" modifier to reset the
-level and enforce the associativity as follows:
-
-Infix NONA 2 "=_S" my_setoid_eq V8only (at level 70, no associativity).
-
-The translator now knows that it has to translate "=_S" at level 70
-with no associativity.
-
-Rem: 70 is the "natural" level for relations, hence the choice of 70
-here, but any other level accepting a no-associativity would have been
-OK.
-
-Example 2: Assume you have a notation
-
-Infix RIGHTA 1 "o" my_comp.
-
-By default, the translator moves it to level 20 which is left
-associative, hence a conflict with the expected right associativity.
-
-To solve the problem, just add the "V8only" modifier to reset the
-level and enforce the associativity as follows:
-
-Infix RIGHTA 1 "o" my_comp V8only (at level 20, right associativity).
-
-The translator now knows that it has to translate "o" at level 20
-which has the correct "right associativity".
-
-Rem: We assumed here that the user wants a strong precedence for
-composition, in such a way, say, that "f o g + h" is parsed as
-"(f o g) + h". To get "o" binding less than the arithmetical operators,
-an appropriated level would have been close of 70, and below, e.g. 65.
-
-b) Conflicts with other notations
-
-Since the new syntax comes with new keywords and new predefined
-symbols, new conflicts can occur. Again, you can use the option V8only
-to inform the translator of the new syntax to use.
-
-b1) A notation hides another notation
-
-Rem: use Print Grammar constr in V8 to diagnose the overlap and see the
-section on factorization in the chapter on notations of the Reference
-Manual for hints on how to factorize.
-
-Example:
-
-Notation "{ x }" := (my_embedding x) (at level 1).
-
-overlaps in V8 with notation "{ x : A & P }" at level 0 and with x at
-level 99. The conflicts can be solved by left-factorizing the notation
-as follows:
-
-Notation "{ x }" := (my_embedding x) (at level 1)
- V8only (at level 0, x at level 99).
-
-b2) A notation conflicts with the V8 grammar.
-
-Again, use the V8only modifier to tell the translator to automatically
-take in charge the new syntax.
-
-Example:
-
-Infix 3 "@" app.
-
-Since "@" is used in the new syntax for deactivating the implicit
-arguments, another symbol has to be used, e.g. "@@". This is done via
-the V8only option as follows:
-
-Infix 3 "@" app V8only "@@" (at level 40, left associativity).
-
-or, alternatively by
-
-Notation "x @ y" := (app x y) (at level 3, left associativity)
- V8only "x @@ y" (at level 40, left associativity).
-
-b3) My notation is already defined at another level (or with another
-associativity)
-
-In V8, the level and associativity of a given notation can no longer
-be changed. Then, either you adopt the standard reserved levels and
-associativity for this notation (as given on the list above) or you
-change your notation.
-
-- To change the notation, follow the directions in section b2.
-
-- To adopt the standard level, just use V8only without any argument.
-
-Example.
-
-Infix 6 "*" my_mult.
-
-is not accepted as such in V8. Write
-
-Infix 6 "*" my_mult V8only.
-
-to tell the translator to use "*" at the reserved level (i.e. 40 with
-left associativity). Even better, use interpretation scopes (look at
-the Reference Manual).
-
-c) How to use V8only with Distfix ?
-
-You can't, use Notation instead of Distfix.
-
-d) Can I overload a notation in V8, e.g. use "*" and "+" for my own
-algebraic operations ?
-
-Yes, using interpretation scopes (see the corresponding chapter in the
-Reference Manual).
-
-3) Using the translator to have simplest notations
-
-Thanks to the new syntax, * has now the expected left associativity,
-and the symbols <, >, <= and >= are now available.
-
-Thanks to the interpretation scopes, you can overload the
-interpretation of these operators with the default interpretation
-provided in Coq.
-
-This may be a motivation to use the translator to automatically change
-the notations while switching to the new syntax.
-
-See sections b) and d) above for examples.
-
-4) Setting the translator to automatically use new notations that
-wasn't used in old syntax
-
-Thanks to the "Notation" mechanism, defining symbolic notations is
-simpler than in the previous versions of Coq.
-
-Thanks to the new syntax and interpretation scopes, new symbols and
-overloading is available.
-
-This may be a motivation for using the translator to automatically change
-the notations while switching to the new syntax.
-
-Use for that the commands V8Notation and V8Infix.
-
-Examples:
-
-V8Infix "==>" my_relation (at level 65, right associativity).
-
-tells the translator to write an infix "==>" instead of my_relation in
-the translated files.
-
-V8Infix ">=" my_ge.
-
-tells the translator to write an infix ">=" instead of my_ge in the
-translated files and that the level and associativity are the standard
-one (as defined in the chart above).
-
-V8Infix ">=" my_ge : my_scope.
-
-tells the translator to write an infix ">=" instead of my_ge in the
-translated files, that the level and associativity are the standard
-one (as defined in the chart above), but only if scope my_scope is
-open or if a delimiting key is available for "my_scope" (see the
-Reference Manual).
-
-5) Defining a construction and its notation simultaneously
-
-This is permitted by the new syntax. Look at the Reference Manual for
-explanation. The translator is not fully able to take this in charge...
-
-III) Various pitfalls
- ----------------
-
-1) New keywords
-
- The following identifiers are new keywords
-
- "forall"; "fun"; "match"; "fix"; "cofix"; "for"; "if"; "then";
- "else"; "return"; "mod"; "at"; "let"; "_"; ".("
-
- The translator automatically add a "_" to names clashing with a
-keyword, except for files. Hence users may need to rename the files
-whose name clashes with a keyword.
-
- Remark: "in"; "with"; "end"; "as"; "Prop"; "Set"; "Type"
- were already keywords
-
-2) Old "Case" and "Match"
-
- "Case" and "Match" are normally automatically translated into
- "match" or "match" and "fix", but sometimes it fails to do so. It
- typically fails when the Case or Match is argument of a tactic whose
- typing context is unknown because of a preceding Intro/Intros, as e.g. in
-
- Intros; Exists [m:nat](<quasiterm>Case m of t [p:nat](f m) end)
-
- The solution is then to replace the invocation of the sequence of
- tactics into several invocation of the elementary tactics as follows
-
- Intros. Exists [m:nat](<quasiterm>Case m of t [p:nat](f m) end)
- ^^^
-
-3) Change of definition or theorem names
-
- Type "entier" from fast_integer.v is renamed into "N" by the
-translator. As a consequence, user-defined objects of same name "N"
-are systematically qualified even tough it may not be necessary. The
-same apply for names "GREATER", "EQUAL", "LESS", etc... [COMPLETE LIST
-TO GIVE].
-
-4) Change of tactics names
-
- Since tactics names are now lowercase, this can clash with
-user-defined tactic definitions. To pally this, clashing names are
-renamed by adding an extra "_" to their name.
-
-======================================================================
-Main examples for new syntax
-----------------------------
-
-1) Constructions
-
- Applicative terms don't any longer require to be surrounded by parentheses as
-e.g in
-
- "x = f y -> S x = S (f y)"
-
-
- Product is written
-
- "forall x y : T, U"
- "forall x y, U"
- "forall (x y : T) z (v w : V), U"
- etc.
-
- Abstraction is written
-
- "fun x y : T, U"
- "fun x y, U"
- "fun (x y : T) z (v w : V), U"
- etc.
-
- Pattern-matching is written
-
- "match x with c1 x1 x2 => t | c2 y as z => u end"
- "match v1, v2 with c1 x1 x2, _ => t | c2 y, d z => u end"
- "match v1 as y in le _ n, v2 as z in I p q return P n y p q z with
- c1 x1 x2, _ => t | c2 y, d z => u end"
-
- The last example is the new form of what was written
-
- "<[n;y:(le ? n);p;q;z:(I p q)](P n y p q z)>Cases v1 v2 of
- (c1 x1 x2) _ => t | (c2 y) (d z) => u end"
-
- Pattern-matching of type with one constructors and no dependencies
-of the arguments in the resulting type can be written
-
- "let (x,y,z) as u return P u := t in v"
-
- Local fixpoints are written
-
- "fix f (n m:nat) z (x : X) {struct m} : nat := ...
- with ..."
-
- and "struct" tells which argument is structurally decreasing.
-
- Explicitation of implicit arguments is written
-
- "f @1:=u v @3:=w t"
- "@f u v w t"
-
-2) Tactics
-
- The main change is that tactics names are now lowercase. Besides
-this, the following renaming are applied:
-
- "NewDestruct" -> "destruct"
- "NewInduction" -> "induction"
- "Induction" -> "simple induction"
- "Destruct" -> "simple destruct"
-
- For tactics with occurrences, the occurrences now comes after and
- repeated use is separated by comma as in
-
- "Pattern 1 3 c d 4 e" -> "pattern c at 3 1, d, e at 4"
- "Unfold 1 3 f 4 g" -> "unfold f at 1 3, g at 4"
- "Simpl 1 3 e" -> "simpl e at 1 3"
-
-3) Tactic language
-
- Definitions are now introduced with keyword "Ltac" (instead of
-"Tactic"/"Meta" "Definition") and are implicitly recursive
-("Recursive" is no longer used).
-
- The new rule for distinguishing terms from ltac expressions is:
-
- Write "ltac:" in front of any tactic in argument position and
- "constr:" in front of any construction in head position
-
-4) Vernacular language
-
-a) Assumptions
-
- The syntax for commands is mainly unchanged. Declaration of
-assumptions is now done as follows
-
- Variable m : t.
- Variables m n p : t.
- Variables (m n : t) (u v : s) (w : r).
-
-b) Definitions
-
- Definitions are done as follows
-
- Definition f m n : t := ... .
- Definition f m n := ... .
- Definition f m n := ... : t.
- Definition f (m n : u) : t := ... .
- Definition f (m n : u) := ... : t.
- Definition f (m n : u) := ... .
- Definition f a b (p q : v) r s (m n : t) : t := ... .
- Definition f a b (p q : v) r s (m n : t) := ... .
- Definition f a b (p q : v) r s (m n : t) := ... : t.
-
-c) Fixpoints
-
- Fixpoints are done this way
-
- Fixpoint f x (y : t) z a (b c : u) {struct z} : v := ... with ... .
- Fixpoint f x : v := ... .
- Fixpoint f (x : t) : v := ... .
-
- It is possible to give a concrete notation to a fixpoint as follows
-
- Fixpoint plus (n m:nat) {struct n} : nat as "n + m" :=
- match n with
- | O => m
- | S p => S (p + m)
- end.
-
-d) Inductive types
-
- The syntax for inductive types is as follows
-
- Inductive t (a b : u) (d : e) : v :=
- c1 : w1 | c2 : w2 | ... .
-
- Inductive t (a b : u) (d : e) : v :=
- c1 : w1 | c2 : w2 | ... .
-
- Inductive t (a b : u) (d : e) : v :=
- c1 (x y : t) : w1 | c2 (z : r) : w2 | ... .
-
- As seen in the last example, arguments of the constructors can be
-given before the colon. If the type itself is omitted (allowed only in
-case the inductive type has no real arguments), this yields an
-ML-style notation as follows
-
- Inductive nat : Set := O | S (n:nat).
- Inductive bool : Set := true | false.
-
- It is even possible to define a syntax at the same time, as follows:
-
- Inductive or (A B:Prop) : Prop as "A \/ B":=
- | or_introl (a:A) : A \/ B
- | or_intror (b:B) : A \/ B.
-
- Inductive and (A B:Prop) : Prop as "A /\ B" := conj (a:A) (b:B).
-
diff --git a/dev/doc/versions-history.tex b/dev/doc/versions-history.tex
index 3867d4af9..8f9c3171d 100644
--- a/dev/doc/versions-history.tex
+++ b/dev/doc/versions-history.tex
@@ -395,7 +395,17 @@ Coq V8.7 beta 1 & released 6 September 2017 & \feature{bundled with Ssreflect pl
Coq V8.7 beta 2 & released 6 October 2017 & \\
-Coq V8.7 & released 18 October 2016 & \\
+Coq V8.7.0 & released 18 October 2017 & \\
+
+Coq V8.7.1 & released 15 December 2017 & \\
+
+Coq V8.7.2 & released 17 February 2018 & \\
+
+Coq V8.8 beta1 & released 19 March 2018 & \\
+
+Coq V8.8.0 & released 17 April 2018 & \feature{reference manual moved to Sphinx} \\
+&& \feature{effort towards better documented, better structured ML API}\\
+&& \feature{miscellaneous changes/improvements of existing features}\\
\end{tabular}
diff --git a/dev/doc/xml-protocol.md b/dev/doc/xml-protocol.md
index b35571e9c..48671c03b 100644
--- a/dev/doc/xml-protocol.md
+++ b/dev/doc/xml-protocol.md
@@ -10,9 +10,9 @@ versions of Proof General.
A somewhat out-of-date description of the async state machine is
[documented here](https://github.com/ejgallego/jscoq/blob/master/etc/notes/coq-notes.md).
-OCaml types for the protocol can be found in the [`ide/interface.mli` file](/ide/interface.mli).
+OCaml types for the protocol can be found in the [`ide/protocol/interface.ml` file](/ide/protocol/interface.ml).
-Changes to the XML protocol are documented as part of [`dev/doc/changes.txt`](/dev/doc/changes.txt).
+Changes to the XML protocol are documented as part of [`dev/doc/changes.md`](/dev/doc/changes.md).
* [Commands](#commands)
- [About](#command-about)
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index 844ad9188..ab679a71c 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -232,7 +232,7 @@ let ppenv e = pp
let ppenvwithcst e = pp
(str "[" ++ pr_named_context_of e Evd.empty ++ str "]" ++ spc() ++
str "[" ++ pr_rel_context e Evd.empty (rel_context e) ++ str "]" ++ spc() ++
- str "{" ++ Cmap_env.fold (fun a _ s -> Constant.print a ++ spc () ++ s) (Obj.magic e).env_globals.env_constants (mt ()) ++ str "}")
+ str "{" ++ Environ.fold_constants (fun a _ s -> Constant.print a ++ spc () ++ s) e (mt ()) ++ str "}")
let pptac = (fun x -> pp(Ltac_plugin.Pptactic.pr_glob_tactic (Global.env()) x))
@@ -301,8 +301,8 @@ let constr_display csr =
incr cnt; pp (str "with " ++ int !cnt ++ str" " ++ Level.pr u ++ fnl ())
and sort_display = function
- | Prop(Pos) -> "Prop(Pos)"
- | Prop(Null) -> "Prop(Null)"
+ | Set -> "Set"
+ | Prop -> "Prop"
| Type u -> univ_display u;
"Type("^(string_of_int !cnt)^")"
@@ -423,8 +423,8 @@ let print_pure_constr csr =
Array.iter (fun u -> print_space (); pp (Level.pr u)) (Instance.to_array u)
and sort_display = function
- | Prop(Pos) -> print_string "Set"
- | Prop(Null) -> print_string "Prop"
+ | Set -> print_string "Set"
+ | Prop -> print_string "Prop"
| Type u -> open_hbox();
print_string "Type("; pp (pr_uni u); print_string ")"; close_box()
diff --git a/dev/vm_printers.ml b/dev/vm_printers.ml
index 7589e5348..c8385da61 100644
--- a/dev/vm_printers.ml
+++ b/dev/vm_printers.ml
@@ -26,8 +26,8 @@ let print_vfix_app () = print_string "vfix_app"
let print_vswith () = print_string "switch"
let ppsort = function
- | Prop(Pos) -> print_string "Set"
- | Prop(Null) -> print_string "Prop"
+ | Set -> print_string "Set"
+ | Prop -> print_string "Prop"
| Type u -> print_string "Type"
diff --git a/doc/LICENSE b/doc/LICENSE
index c223a4e16..3789d9104 100644
--- a/doc/LICENSE
+++ b/doc/LICENSE
@@ -2,7 +2,7 @@ The Coq Reference Manual is a collective work from the Coq Development
Team whose members are listed in the file CREDITS of the Coq source
package. All related documents (the LaTeX and BibTeX sources, the
embedded png files, and the PostScript, PDF and html outputs) are
-copyright (c) INRIA 1999-2006, with the exception of the Ubuntu font
+copyright (c) INRIA 1999-2018, with the exception of the Ubuntu font
file UbuntuMono-B.ttf, which is
Copyright 2010,2011 Canonical Ltd and licensed under the Ubuntu font
license, version 1.0
@@ -14,33 +14,14 @@ License, v1.0 or later (the latest version is presently available at
http://www.opencontent.org/openpub/). Options A and B are *not*
elected.
-The Coq Tutorial is a work by Gérard Huet, Gilles Kahn and Christine
-Paulin-Mohring. All documents (the LaTeX source and the PostScript,
-PDF and html outputs) are copyright (c) INRIA 1999-2006. The material
-connected to the Coq Tutorial may be distributed only subject to the
-terms and conditions set forth in the Open Publication License, v1.0
-or later (the latest version is presently available at
-http://www.opencontent.org/openpub/). Options A and B are *not*
-elected.
-
The Coq Standard Library is a collective work from the Coq Development
Team whose members are listed in the file CREDITS of the Coq source
package. All related documents (the Coq vernacular source files and
the PostScript, PDF and html outputs) are copyright (c) INRIA
-1999-2006. The material connected to the Standard Library is
+1999-2018. The material connected to the Standard Library is
distributed under the terms of the Lesser General Public License
version 2.1 or later.
-The Tutorial on [Co-]Inductive Types in Coq is a work by Pierre
-Castéran and Eduardo Gimenez. All related documents (the LaTeX and
-BibTeX sources and the PostScript, PDF and html outputs) are copyright
-(c) INRIA 1997-2006. The material connected to the Tutorial on
-[Co-]Inductive Types in Coq may be distributed only subject to the
-terms and conditions set forth in the Open Publication License, v1.0
-or later (the latest version is presently available at
-http://www.opencontent.org/openpub/). Options A and B are
-*not* elected.
-
----------------------------------------------------------------------
*Open Publication License*
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 000000000..6c6e1f01f
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,102 @@
+The Coq documentation
+=====================
+
+The Coq documentation includes
+
+- A Reference Manual
+- A document presenting the Coq standard library
+
+The documentation of the latest released version is available on the Coq
+web site at [coq.inria.fr/documentation](http://coq.inria.fr/documentation).
+
+Additionnally, you can view the documentation for the current master version at
+<https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/_install_ci/share/doc/coq/sphinx/html/index.html?job=documentation>.
+
+The reference manual is written is reStructuredText and compiled
+using Sphinx. See [`sphinx/README.rst`](sphinx/README.rst)
+to learn more about the format that is used.
+
+The documentation for the standard library is generated from
+the `.v` source files using coqdoc.
+
+Dependencies
+------------
+
+### HTML documentation
+
+To produce the complete documentation in HTML, you will need Coq dependencies
+listed in [`INSTALL`](../INSTALL). Additionally, the Sphinx-based
+reference manual requires Python 3, and the following Python packages:
+
+ sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect sphinxcontrib-bibtex
+
+You can install them using `pip3 install` or using your distribution's package
+manager. E.g. under recent Debian-based operating systems (Debian 10 "Buster",
+Ubuntu 18.04, ...) you can use:
+
+ apt install python3-sphinx python3-pexpect python3-sphinx-rtd-theme \
+ python3-bs4 python3-sphinxcontrib.bibtex python3-pip
+
+Then, install the missing Python3 Antlr4 package:
+
+ pip3 install antlr4-python3-runtime
+
+Nix users should get the correct development environment to build the
+HTML documentation from Coq's [`default.nix`](../default.nix) (note this
+doesn't include the LaTeX packages needed to build the full documentation).
+
+### Other formats
+
+To produce the documentation in PDF and PostScript formats, the following
+additional tools are required:
+
+ - latex (latex2e)
+ - pdflatex
+ - dvips
+ - makeindex
+
+Install them using your package manager. E.g. on Debian / Ubuntu:
+
+ apt install texlive-latex-extra texlive-fonts-recommended
+
+Compilation
+-----------
+
+To produce all documentation about Coq in all formats, just run:
+
+ ./configure # (if you hadn't already)
+ make doc
+
+
+Alternatively, you can use some specific targets:
+
+- `make doc-ps`
+ to produce all PostScript documents
+
+- `make doc-pdf`
+ to produce all PDF documents
+
+- `make doc-html`
+ to produce all HTML documents
+
+- `make sphinx`
+ to produce the HTML version of the reference manual
+
+- `make stdlib`
+ to produce all formats of the Coq standard library
+
+
+Also note the `-with-doc yes` option of `./configure` to enable the
+build of the documentation as part of the default make target.
+
+
+Installation
+------------
+
+To install all produced documents, do:
+
+ make install-doc
+
+This will install the documentation in `/usr/share/doc/coq` unless you
+specify another value through the `-docdir` option of `./configure` or the
+`DOCDIR` environment variable.
diff --git a/doc/sphinx/README.rst b/doc/sphinx/README.rst
index 35a605ddd..32de15ee3 100644
--- a/doc/sphinx/README.rst
+++ b/doc/sphinx/README.rst
@@ -123,11 +123,24 @@ Here is the list of all objects of the Coq domain (The symbol :black_nib: indica
:cmd:`Variant` and :cmd:`Record` get an automatic declaration of the
induction principles.
-``.. prodn::`` :black_nib: Grammar productions.
+``.. prodn::`` A grammar production.
This is useful if you intend to document individual grammar productions.
Otherwise, use Sphinx's `production lists
<http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_.
+ Unlike ``.. productionlist``\ s, this directive accepts notation syntax.
+
+
+ Usage::
+
+ .. prodn:: token += production
+ .. prodn:: token ::= production
+
+ Example::
+
+ .. prodn:: term += let: @pattern := @term in @term
+ .. prodn:: occ_switch ::= { {? + %| - } {* @num } }
+
``.. tacn::`` :black_nib: A tactic, or a tactic notation.
Example::
diff --git a/doc/sphinx/addendum/ring.rst b/doc/sphinx/addendum/ring.rst
index 47d3a7d7c..6a9b343ba 100644
--- a/doc/sphinx/addendum/ring.rst
+++ b/doc/sphinx/addendum/ring.rst
@@ -310,16 +310,15 @@ The :n:`@ident` is not relevant. It is just used for error messages. The
axioms. The optional list of modifiers is used to tailor the behavior
of the tactic. The following list describes their syntax and effects:
-.. prodn::
- ring_mod ::= abstract %| decidable @term %| morphism @term
- %| setoid @term @term
- %| constants [@ltac]
- %| preprocess [@ltac]
- %| postprocess [@ltac]
- %| power_tac @term [@ltac]
- %| sign @term
- %| div @term
-
+.. productionlist:: coq
+ ring_mod : abstract | decidable `term` | morphism `term`
+ : | setoid `term` `term`
+ : | constants [`ltac`]
+ : | preprocess [`ltac`]
+ : | postprocess [`ltac`]
+ : | power_tac `term` [`ltac`]
+ : | sign `term`
+ : | div `term`
abstract
declares the ring as abstract. This is the default.
@@ -663,8 +662,8 @@ messages. :n:`@term` is a proof that the field signature satisfies the
(semi-)field axioms. The optional list of modifiers is used to tailor
the behavior of the tactic.
-.. prodn::
- field_mod := @ring_mod %| completeness @term
+.. productionlist:: coq
+ field_mod : `ring_mod` | completeness `term`
Since field tactics are built upon ``ring``
tactics, all modifiers of the ``Add Ring`` apply. There is only one
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index 6c7258f9c..68b5b9d6f 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -296,6 +296,10 @@ Variants:
This variant declares a class a posteriori from a constant or
inductive definition. No methods or instances are defined.
+ .. warn:: @ident is already declared as a typeclass
+
+ This command has no effect when used on a typeclass.
+
.. cmd:: Instance @ident {? @binders} : Class t1 … tn [| priority] := { field1 := b1 ; …; fieldi := bi }
The :cmd:`Instance` command is used to declare a type class instance named
diff --git a/doc/sphinx/biblio.bib b/doc/sphinx/biblio.bib
index 3e988709c..3574bf675 100644
--- a/doc/sphinx/biblio.bib
+++ b/doc/sphinx/biblio.bib
@@ -3,6 +3,21 @@
@String{lnai = "Lecture Notes in Artificial Intelligence"}
@String{SV = "{Sprin-ger-Verlag}"}
+@InCollection{Asp00,
+ Title = {Proof General: A Generic Tool for Proof Development},
+ Author = {Aspinall, David},
+ Booktitle = {Tools and Algorithms for the Construction and
+ Analysis of Systems, {TACAS} 2000},
+ Publisher = {Springer Berlin Heidelberg},
+ Year = {2000},
+ Editor = {Graf, Susanne and Schwartzbach, Michael},
+ Pages = {38--43},
+ Series = {Lecture Notes in Computer Science},
+ Volume = {1785},
+ Doi = {10.1007/3-540-46419-0_3},
+ ISBN = {978-3-540-67282-1},
+}
+
@Book{Bar81,
author = {H.P. Barendregt},
publisher = {North-Holland},
@@ -290,16 +305,13 @@ the Calculus of Inductive Constructions}},
year = {1995}
}
-@Misc{Pcoq,
- author = {Lemme Team},
- title = {Pcoq a graphical user-interface for {Coq}},
- note = {\url{http://www-sop.inria.fr/lemme/pcoq/}}
-}
-
-@Misc{ProofGeneral,
- author = {David Aspinall},
- title = {Proof General},
- note = {\url{https://proofgeneral.github.io/}}
+@InProceedings{Pit16,
+ Title = {Company-Coq: Taking Proof General one step closer to a real IDE},
+ Author = {Pit-Claudel, Clément and Courtieu, Pierre},
+ Booktitle = {CoqPL'16: The Second International Workshop on Coq for PL},
+ Year = {2016},
+ Month = jan,
+ Doi = {10.5281/zenodo.44331},
}
@Book{RC95,
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index 135c24aed..8127d3df3 100755
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -104,7 +104,6 @@ exclude_patterns = [
'Thumbs.db',
'.DS_Store',
'introduction.rst',
- 'credits.rst',
'README.rst',
'README.template.rst'
]
diff --git a/doc/sphinx/credits.rst b/doc/sphinx/credits.rst
index a75659798..5d9324a65 100644
--- a/doc/sphinx/credits.rst
+++ b/doc/sphinx/credits.rst
@@ -1,3 +1,8 @@
+.. include:: preamble.rst
+.. include:: replaces.rst
+
+.. _credits:
+
-------------------------------------------
Credits
-------------------------------------------
@@ -1388,7 +1393,7 @@ Version 8.8 is the third release of |Coq| developed on a time-based
development cycle. Its development spanned 6 months from the release of
|Coq| 8.7 and was based on a public roadmap. The development process
was coordinated by Matthieu Sozeau. Maxime Dénès was in charge of the
-release process.
+release process. Théo Zimmermann is the maintainer of this release.
Many power users helped to improve the design of the new features via
the bug tracker, the pull request system, the |Coq| development mailing
diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst
index 136f9088b..baf2e0d98 100644
--- a/doc/sphinx/index.rst
+++ b/doc/sphinx/index.rst
@@ -1,16 +1,31 @@
-.. _introduction:
-
.. include:: preamble.rst
.. include:: replaces.rst
.. include:: introduction.rst
-.. include:: credits.rst
------------------
Table of contents
------------------
.. toctree::
+ :caption: Indexes
+
+ genindex
+ coq-cmdindex
+ coq-tacindex
+ coq-optindex
+ coq-exnindex
+
+.. No entries yet
+ * :index:`thmindex`
+
+.. toctree::
+ :caption: Preamble
+
+ self
+ credits
+
+.. toctree::
:caption: The language
language/gallina-specification-language
@@ -65,19 +80,12 @@ Table of contents
zebibliography
-.. toctree::
- :caption: Indexes
-
- genindex
- coq-cmdindex
- coq-tacindex
- coq-optindex
- coq-exnindex
-
-.. No entries yet
- * :index:`thmindex`
-
This material (the Coq Reference Manual) may be distributed only subject to the
terms and conditions set forth in the Open Publication License, v1.0 or later
(the latest version is presently available at
http://www.opencontent.org/openpub). Options A and B are not elected.
+
+.. [#PG] Proof-General is available at https://proofgeneral.github.io/.
+ Optionally, you can enhance it with the minor mode
+ Company-Coq :cite:`Pit16`
+ (see https://github.com/cpitclaudel/company-coq).
diff --git a/doc/sphinx/introduction.rst b/doc/sphinx/introduction.rst
index 75ff72c4d..c7bc69db4 100644
--- a/doc/sphinx/introduction.rst
+++ b/doc/sphinx/introduction.rst
@@ -1,3 +1,5 @@
+.. _introduction:
+
------------------------
Introduction
------------------------
@@ -26,37 +28,35 @@ programs called *tactics*.
All services of the |Coq| proof assistant are accessible by interpretation
of a command language called *the vernacular*.
-Coq has an interactive mode in which commands are interpreted as the
+Coq has an interactive mode in which commands are interpreted as the
user types them in from the keyboard and a compiled mode where commands
are processed from a file.
-- The interactive mode may be used as a debugging mode in which the
- user can develop his theories and proofs step by step, backtracking
- if needed and so on. The interactive mode is run with the `coqtop`
- command from the operating system (which we shall assume to be some
- variety of UNIX in the rest of this document).
+- In interactive mode, users can develop their theories and proofs step by
+ step, and query the system for available theorems and definitions. The
+ interactive mode is generally run with the help of an IDE, such
+ as CoqIDE, documented in :ref:`coqintegrateddevelopmentenvironment`,
+ Emacs with Proof-General :cite:`Asp00` [#PG]_,
+ or jsCoq to run Coq in your browser (see https://github.com/ejgallego/jscoq).
+ The `coqtop` read-eval-print-loop can also be used directly, for debugging
+ purposes.
- The compiled mode acts as a proof checker taking a file containing a
whole development in order to ensure its correctness. Moreover,
|Coq|’s compiler provides an output file containing a compact
representation of its input. The compiled mode is run with the `coqc`
- command from the operating system.
-
-These two modes are documented in Chapter :ref:`thecoqcommands`.
+ command.
-Other modes of interaction with |Coq| are possible: through an emacs shell
-window, an emacs generic user-interface for proof assistant (Proof
-General :cite:`ProofGeneral`) or through a customized
-interface (PCoq :cite:`Pcoq`). These facilities are not
-documented here. There is also a |Coq| Integrated Development Environment
-described in :ref:`coqintegrateddevelopmentenvironment`.
+.. seealso:: :ref:`thecoqcommands`.
How to read this book
=====================
-This is a Reference Manual, not a User Manual, so it is not made for a
-continuous reading. However, it has some structure that is explained
-below.
+This is a Reference Manual, so it is not made for a continuous reading.
+We recommend using the various indexes to quickly locate the documentation
+you are looking for. There is a global index, and a number of specific indexes
+for tactics, vernacular commands, and error messages and warnings.
+Nonetheless, the manual has some structure that is explained below.
- The first part describes the specification language, |Gallina|.
Chapters :ref:`gallinaspecificationlanguage` and :ref:`extensionsofgallina` describe the concrete
@@ -66,7 +66,7 @@ below.
of the formalism. Chapter :ref:`themodulesystem` describes the module
system.
-- The second part describes the proof engine. It is divided in five
+- The second part describes the proof engine. It is divided in six
chapters. Chapter :ref:`vernacularcommands` presents all commands (we
call them *vernacular commands*) that are not directly related to
interactive proving: requests to the environment, complete or partial
@@ -77,42 +77,35 @@ below.
*tactics*. The language to combine these tactics into complex proof
strategies is given in Chapter :ref:`ltac`. Examples of tactics
are described in Chapter :ref:`detailedexamplesoftactics`.
+ Finally, the |SSR| proof language is presented in
+ Chapter :ref:`thessreflectprooflanguage`.
-- The third part describes how to extend the syntax of |Coq|. It
- corresponds to the Chapter :ref:`syntaxextensionsandinterpretationscopes`.
+- The third part describes how to extend the syntax of |Coq| in
+ Chapter :ref:`syntaxextensionsandinterpretationscopes` and how to define
+ new induction principles in Chapter :ref:`proofschemes`.
- In the fourth part more practical tools are documented. First in
Chapter :ref:`thecoqcommands`, the usage of `coqc` (batch mode) and
`coqtop` (interactive mode) with their options is described. Then,
in Chapter :ref:`utilities`, various utilities that come with the
|Coq| distribution are presented. Finally, Chapter :ref:`coqintegrateddevelopmentenvironment`
- describes the |Coq| integrated development environment.
+ describes CoqIDE.
- The fifth part documents a number of advanced features, including coercions,
canonical structures, typeclasses, program extraction, and specialized
solvers and tactics. See the table of contents for a complete list.
-At the end of the document, after the global index, the user can find
-specific indexes for tactics, vernacular commands, and error messages.
-
List of additional documentation
================================
This manual does not contain all the documentation the user may need
about |Coq|. Various informations can be found in the following documents:
-Tutorial
- A companion volume to this reference manual, the |Coq| Tutorial, is
- aimed at gently introducing new users to developing proofs in |Coq|
- without assuming prior knowledge of type theory. In a second step,
- the user can read also the tutorial on recursive types (document
- `RecTutorial.ps`).
-
Installation
A text file `INSTALL` that comes with the sources explains how to
install |Coq|.
The |Coq| standard library
A commented version of sources of the |Coq| standard library
- (including only the specifications, the proofs are removed) is given
- in the additional document `Library.ps`.
+ (including only the specifications, the proofs are removed) is
+ available at https://coq.inria.fr/stdlib/.
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index f6bab0267..b01a4ef0f 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -721,67 +721,68 @@ called the *context of parameters*. Furthermore, we must have that
each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where
:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type t and :math:`S` is called
the sort of the inductive type t (not to be confused with :math:`\Sort` which is the set of sorts).
-** Examples** The declaration for parameterized lists is:
-
-.. math::
- \ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
- \Nil & : & \forall A:\Set,\List~A \\
- \cons & : & \forall A:\Set, A→ \List~A→ \List~A
- \end{array}
- \right]}
-
-which corresponds to the result of the |Coq| declaration:
.. example::
- .. coqtop:: in
-
- Inductive list (A:Set) : Set :=
- | nil : list A
- | cons : A -> list A -> list A.
+ The declaration for parameterized lists is:
-The declaration for a mutual inductive definition of tree and forest
-is:
+ .. math::
+ \ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
+ \Nil & : & \forall A:\Set,\List~A \\
+ \cons & : & \forall A:\Set, A→ \List~A→ \List~A
+ \end{array}
+ \right]}
-.. math::
- \ind{~}{\left[\begin{array}{rcl}\tree&:&\Set\\\forest&:&\Set\end{array}\right]}
- {\left[\begin{array}{rcl}
- \node &:& \forest → \tree\\
- \emptyf &:& \forest\\
- \consf &:& \tree → \forest → \forest\\
- \end{array}\right]}
+ which corresponds to the result of the |Coq| declaration:
-which corresponds to the result of the |Coq| declaration:
+ .. coqtop:: in
+
+ Inductive list (A:Set) : Set :=
+ | nil : list A
+ | cons : A -> list A -> list A.
.. example::
- .. coqtop:: in
+ The declaration for a mutual inductive definition of tree and forest
+ is:
- Inductive tree : Set :=
- | node : forest -> tree
- with forest : Set :=
- | emptyf : forest
- | consf : tree -> forest -> forest.
+ .. math::
+ \ind{~}{\left[\begin{array}{rcl}\tree&:&\Set\\\forest&:&\Set\end{array}\right]}
+ {\left[\begin{array}{rcl}
+ \node &:& \forest → \tree\\
+ \emptyf &:& \forest\\
+ \consf &:& \tree → \forest → \forest\\
+ \end{array}\right]}
-The declaration for a mutual inductive definition of even and odd is:
+ which corresponds to the result of the |Coq| declaration:
-.. math::
- \ind{1}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\
- \odd&:&\nat → \Prop \end{array}\right]}
- {\left[\begin{array}{rcl}
- \evenO &:& \even~0\\
- \evenS &:& \forall n, \odd~n -> \even~(\kw{S}~n)\\
- \oddS &:& \forall n, \even~n -> \odd~(\kw{S}~n)
- \end{array}\right]}
+ .. coqtop:: in
-which corresponds to the result of the |Coq| declaration:
+ Inductive tree : Set :=
+ | node : forest -> tree
+ with forest : Set :=
+ | emptyf : forest
+ | consf : tree -> forest -> forest.
.. example::
- .. coqtop:: in
+ The declaration for a mutual inductive definition of even and odd is:
+
+ .. math::
+ \ind{1}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\
+ \odd&:&\nat → \Prop \end{array}\right]}
+ {\left[\begin{array}{rcl}
+ \evenO &:& \even~0\\
+ \evenS &:& \forall n, \odd~n -> \even~(\kw{S}~n)\\
+ \oddS &:& \forall n, \even~n -> \odd~(\kw{S}~n)
+ \end{array}\right]}
+
+ which corresponds to the result of the |Coq| declaration:
- Inductive even : nat -> prop :=
- | even_O : even 0
- | even_S : forall n, odd n -> even (S n)
- with odd : nat -> prop :=
- | odd_S : forall n, even n -> odd (S n).
+ .. coqtop:: in
+
+ Inductive even : nat -> prop :=
+ | even_O : even 0
+ | even_S : forall n, odd n -> even (S n)
+ with odd : nat -> prop :=
+ | odd_S : forall n, even n -> odd (S n).
@@ -838,8 +839,8 @@ rules, we need a few definitions:
Arity of a given sort
+++++++++++++++++++++
-A type :math:`T` is an *arity of sort s* if it converts to the sort s or to a
-product :math:`∀ x:T,U` with :math:`U` an arity of sort s.
+A type :math:`T` is an *arity of sort* :math:`s` if it converts to the sort :math:`s` or to a
+product :math:`∀ x:T,U` with :math:`U` an arity of sort :math:`s`.
.. example::
@@ -850,7 +851,7 @@ product :math:`∀ x:T,U` with :math:`U` an arity of sort s.
Arity
+++++
A type :math:`T` is an *arity* if there is a :math:`s∈ \Sort` such that :math:`T` is an arity of
-sort s.
+sort :math:`s`.
.. example::
@@ -921,29 +922,29 @@ condition* for a constant :math:`X` in the following cases:
For instance, if one considers the following variant of a tree type
branching over the natural numbers:
- .. coqtop:: in
+ .. coqtop:: in
- Inductive nattree (A:Type) : Type :=
- | leaf : nattree A
- | node : A -> (nat -> nattree A) -> nattree A.
- End TreeExample.
-
- Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
- condition for ``nattree``:
+ Inductive nattree (A:Type) : Type :=
+ | leaf : nattree A
+ | node : A -> (nat -> nattree A) -> nattree A.
+ End TreeExample.
+
+ Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
+ condition for ``nattree``:
- + Type ``nattree A`` of constructor ``leaf`` satisfies the positivity condition for
- ``nattree`` because ``nattree`` does not appear in any (real) arguments of the
- type of that constructor (primarily because ``nattree`` does not have any (real)
- arguments) ... (bullet 1)
+ + Type ``nattree A`` of constructor ``leaf`` satisfies the positivity condition for
+ ``nattree`` because ``nattree`` does not appear in any (real) arguments of the
+ type of that constructor (primarily because ``nattree`` does not have any (real)
+ arguments) ... (bullet 1)
- + Type ``A → (nat → nattree A) → nattree A`` of constructor ``node`` satisfies the
- positivity condition for ``nattree`` because:
+ + Type ``A → (nat → nattree A) → nattree A`` of constructor ``node`` satisfies the
+ positivity condition for ``nattree`` because:
- - ``nattree`` occurs only strictly positively in ``A`` ... (bullet 3)
+ - ``nattree`` occurs only strictly positively in ``A`` ... (bullet 3)
- - ``nattree`` occurs only strictly positively in ``nat → nattree A`` ... (bullet 3 + 2)
+ - ``nattree`` occurs only strictly positively in ``nat → nattree A`` ... (bullet 3 + 2)
- - ``nattree`` satisfies the positivity condition for ``nattree A`` ... (bullet 1)
+ - ``nattree`` satisfies the positivity condition for ``nattree A`` ... (bullet 1)
.. _Correctness-rules:
@@ -978,35 +979,33 @@ provided that the following side conditions hold:
One can remark that there is a constraint between the sort of the
arity of the inductive type and the sort of the type of its
constructors which will always be satisfied for the impredicative
-sortProp but may fail to define inductive definition on sort Set and
+sort :math:`\Prop` but may fail to define inductive definition on sort :math:`\Set` and
generate constraints between universes for inductive definitions in
the Type hierarchy.
-**Examples**. It is well known that the existential quantifier can be encoded as an
-inductive definition. The following declaration introduces the second-
-order existential quantifier :math:`∃ X.P(X)`.
-
.. example::
+ It is well known that the existential quantifier can be encoded as an
+ inductive definition. The following declaration introduces the second-
+ order existential quantifier :math:`∃ X.P(X)`.
+
.. coqtop:: in
-
+
Inductive exProp (P:Prop->Prop) : Prop :=
| exP_intro : forall X:Prop, P X -> exProp P.
-The same definition on Set is not allowed and fails:
+ The same definition on :math:`\Set` is not allowed and fails:
-.. example::
.. coqtop:: all
Fail Inductive exSet (P:Set->Prop) : Set :=
exS_intro : forall X:Set, P X -> exSet P.
-It is possible to declare the same inductive definition in the
-universe Type. The exType inductive definition has type
-:math:`(\Type(i)→\Prop)→\Type(j)` with the constraint that the parameter :math:`X` of :math:`\kw{exT_intro}`
-has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
+ It is possible to declare the same inductive definition in the
+ universe :math:`\Type`. The :g:`exType` inductive definition has type
+ :math:`(\Type(i)→\Prop)→\Type(j)` with the constraint that the parameter :math:`X` of :math:`\kw{exT_intro}`
+ has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
-.. example::
.. coqtop:: all
Inductive exType (P:Type->Prop) : Type :=
@@ -1019,9 +1018,9 @@ has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
Template polymorphism
+++++++++++++++++++++
-Inductive types declared in Type are polymorphic over their arguments
-in Type. If :math:`A` is an arity of some sort and s is a sort, we write :math:`A_{/s}`
-for the arity obtained from :math:`A` by replacing its sort with s.
+Inductive types declared in :math:`\Type` are polymorphic over their arguments
+in :math:`\Type`. If :math:`A` is an arity of some sort and math:`s` is a sort, we write :math:`A_{/s}`
+for the arity obtained from :math:`A` by replacing its sort with :math:`s`.
Especially, if :math:`A` is well-typed in some global environment and local
context, then :math:`A_{/s}` is typable by typability of all products in the
Calculus of Inductive Constructions. The following typing rule is
@@ -1382,7 +1381,7 @@ this type.
[I:Prop|I→ s]
A *singleton definition* has only one constructor and all the
-arguments of this constructor have type Prop. In that case, there is a
+arguments of this constructor have type :math:`\Prop`. In that case, there is a
canonical way to interpret the informative extraction on an object in
that type, such that the elimination on any sort :math:`s` is legal. Typical
examples are the conjunction of non-informative propositions and the
@@ -1421,45 +1420,45 @@ corresponding to the :math:`c:C` constructor.
We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:`c`.
-**Example.**
-The following term in concrete syntax::
+.. example::
+ The following term in concrete syntax::
- match t as l return P' with
- | nil _ => t1
- | cons _ hd tl => t2
- end
+ match t as l return P' with
+ | nil _ => t1
+ | cons _ hd tl => t2
+ end
-can be represented in abstract syntax as
+ can be represented in abstract syntax as
-.. math::
- \case(t,P,f 1 | f 2 )
+ .. math::
+ \case(t,P,f 1 | f 2 )
-where
+ where
-.. math::
- \begin{eqnarray*}
- P & = & \lambda~l~.~P^\prime\\
- f_1 & = & t_1\\
- f_2 & = & \lambda~(hd:\nat)~.~\lambda~(tl:\List~\nat)~.~t_2
- \end{eqnarray*}
+ .. math::
+ \begin{eqnarray*}
+ P & = & \lambda~l~.~P^\prime\\
+ f_1 & = & t_1\\
+ f_2 & = & \lambda~(hd:\nat)~.~\lambda~(tl:\List~\nat)~.~t_2
+ \end{eqnarray*}
-According to the definition:
+ According to the definition:
-.. math::
- \{(\kw{nil}~\nat)\}^P ≡ \{(\kw{nil}~\nat) : (\List~\nat)\}^P ≡ (P~(\kw{nil}~\nat))
+ .. math::
+ \{(\kw{nil}~\nat)\}^P ≡ \{(\kw{nil}~\nat) : (\List~\nat)\}^P ≡ (P~(\kw{nil}~\nat))
-.. math::
-
- \begin{array}{rl}
- \{(\kw{cons}~\nat)\}^P & ≡\{(\kw{cons}~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat, \{(\kw{cons}~\nat~n) : \List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat, ∀ l:\List~\nat, \{(\kw{cons}~\nat~n~l) : \List~\nat)\}^P \\
- & ≡∀ n:\nat, ∀ l:\List~\nat,(P~(\kw{cons}~\nat~n~l)).
- \end{array}
+ .. math::
+
+ \begin{array}{rl}
+ \{(\kw{cons}~\nat)\}^P & ≡\{(\kw{cons}~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
+ & ≡∀ n:\nat, \{(\kw{cons}~\nat~n) : \List~\nat→\List~\nat)\}^P \\
+ & ≡∀ n:\nat, ∀ l:\List~\nat, \{(\kw{cons}~\nat~n~l) : \List~\nat)\}^P \\
+ & ≡∀ n:\nat, ∀ l:\List~\nat,(P~(\kw{cons}~\nat~n~l)).
+ \end{array}
-Given some :math:`P` then :math:`\{(\kw{nil}~\nat)\}^P` represents the expected type of :math:`f_1` ,
-and :math:`\{(\kw{cons}~\nat)\}^P` represents the expected type of :math:`f_2`.
+ Given some :math:`P` then :math:`\{(\kw{nil}~\nat)\}^P` represents the expected type of :math:`f_1` ,
+ and :math:`\{(\kw{cons}~\nat)\}^P` represents the expected type of :math:`f_2`.
.. _Typing-rule:
@@ -1819,7 +1818,7 @@ while it will type-check, if one uses instead the `coqtop`
``-impredicative-set`` option..
The major change in the theory concerns the rule for product formation
-in the sort Set, which is extended to a domain in any sort:
+in the sort :math:`\Set`, which is extended to a domain in any sort:
.. inference:: ProdImp
@@ -1832,11 +1831,11 @@ in the sort Set, which is extended to a domain in any sort:
This extension has consequences on the inductive definitions which are
allowed. In the impredicative system, one can build so-called *large
inductive definitions* like the example of second-order existential
-quantifier (exSet).
+quantifier (:g:`exSet`).
There should be restrictions on the eliminations which can be
performed on such definitions. The eliminations rules in the
-impredicative system for sort Set become:
+impredicative system for sort :math:`\Set` become:
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index c21d8d4ec..509ac92f8 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -23,8 +23,9 @@ expressions. In this sense, the :cmd:`Record` construction allows defining
.. _record_grammar:
.. productionlist:: `sentence`
- record : `record_keyword` `ident` [ `binders` ] [: `sort` ] := [ `ident` ] { [ `field` ; … ; `field` ] }.
+ record : `record_keyword` `record_body` with … with `record_body`
record_keyword : Record | Inductive | CoInductive
+ record_body : `ident` [ `binders` ] [: `sort` ] := [ `ident` ] { [ `field` ; … ; `field` ] }.
field : `ident` [ `binders` ] : `type` [ where `notation` ]
: | `ident` [ `binders` ] [: `type` ] := `term`
@@ -167,12 +168,13 @@ and the syntax `term.(@qualid` |term_1| |term_n| `)` to `@qualid` |term_1| `…`
In each case, `term` is the object projected and the
other arguments are the parameters of the inductive type.
+
.. note:: Records defined with the ``Record`` keyword are not allowed to be
recursive (references to the record's name in the type of its field
raises an error). To define recursive records, one can use the ``Inductive``
and ``CoInductive`` keywords, resulting in an inductive or co-inductive record.
- A *caveat*, however, is that records cannot appear in mutually inductive
- (or co-inductive) definitions.
+ Definition of mutal inductive or co-inductive records are also allowed, as long
+ as all of the types in the block are records.
.. note:: Induction schemes are automatically generated for inductive records.
Automatic generation of induction schemes for non-recursive records
@@ -1347,7 +1349,7 @@ folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding
to invalid |Coq| identifiers are skipped, and, by convention,
subdirectories named ``CVS`` or ``_darcs`` are skipped too.
-Thanks to this mechanism, .vo files are made available through the
+Thanks to this mechanism, ``.vo`` files are made available through the
logical name of the folder they are in, extended with their own
basename. For example, the name associated to the file
``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for
@@ -1358,17 +1360,17 @@ wrong loadpath afterwards.
Some folders have a special status and are automatically put in the
path. |Coq| commands associate automatically a logical path to files in
the repository trees rooted at the directory from where the command is
-launched, coqlib/user-contrib/, the directories listed in the
-`$COQPATH`, `${XDG_DATA_HOME}/coq/` and `${XDG_DATA_DIRS}/coq/`
-environment variables (see`http://standards.freedesktop.org/basedir-
-spec/basedir-spec-latest.html`_) with the same physical-to-logical
-translation and with an empty logical prefix.
+launched, ``coqlib/user-contrib/``, the directories listed in the
+``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/``
+environment variables (see `XDG base directory specification
+<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_)
+with the same physical-to-logical translation and with an empty logical prefix.
The command line option ``-R`` is a variant of ``-Q`` which has the strictly
same behavior regarding loadpaths, but which also makes the
corresponding ``.vo`` files available through their short names in a way
not unlike the ``Import`` command (see :ref:`here <import_qualid>`). For instance, ``-R`` `path` ``Lib``
-associates to the ``filepath/fOO/Bar/File.vo`` the logical name
+associates to the file path `path`\ ``/path/fOO/Bar/File.vo`` the logical name
``Lib.fOO.Bar.File``, but allows this file to be accessed through the
short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with
identical base name are present in different subdirectories of a
@@ -2226,7 +2228,7 @@ existential variable used in the same context as its context of definition is wr
Check (fun x y => _) 0 1.
Existential variables can be named by the user upon creation using
-the syntax ``?``\ `ident`. This is useful when the existential
+the syntax :n:`?[@ident]`. This is useful when the existential
variable needs to be explicitly handled later in the script (e.g.
with a named-goal selector, see :ref:`goal-selectors`).
diff --git a/doc/sphinx/language/gallina-specification-language.rst b/doc/sphinx/language/gallina-specification-language.rst
index c26ae2a93..e13625286 100644
--- a/doc/sphinx/language/gallina-specification-language.rst
+++ b/doc/sphinx/language/gallina-specification-language.rst
@@ -38,6 +38,7 @@ At the end, the notation “``[entry sep … sep entry]``” stands for a
possibly empty sequence of expressions parsed by the “``entry``” entry,
separated by the literal “``sep``”.
+.. _lexical-conventions:
Lexical conventions
===================
@@ -905,6 +906,32 @@ Parametrized inductive types
sort for the inductive definition and will produce a less convenient
rule for case elimination.
+.. opt:: Uniform Inductive Parameters
+
+ When this option is set (it is off by default),
+ inductive definitions are abstracted over their parameters
+ before typechecking constructors, allowing to write:
+
+ .. coqtop:: all undo
+
+ Set Uniform Inductive Parameters.
+ Inductive list3 (A:Set) : Set :=
+ | nil3 : list3
+ | cons3 : A -> list3 -> list3.
+
+ This behavior is essentially equivalent to starting a new section
+ and using :cmd:`Context` to give the uniform parameters, like so
+ (cf. :ref:`section-mechanism`):
+
+ .. coqtop:: all undo
+
+ Section list3.
+ Context (A:Set).
+ Inductive list3 : Set :=
+ | nil3 : list3
+ | cons3 : A -> list3 -> list3.
+ End list3.
+
.. seealso::
Section :ref:`inductive-definitions` and the :tacn:`induction` tactic.
diff --git a/doc/sphinx/practical-tools/utilities.rst b/doc/sphinx/practical-tools/utilities.rst
index 5dba92429..bdaa2aa1a 100644
--- a/doc/sphinx/practical-tools/utilities.rst
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -950,71 +950,10 @@ There are options to produce the |Coq| parts in smaller font, italic,
between horizontal rules, etc. See the man page of ``coq-tex`` for more
details.
-|Coq| and GNU Emacs
------------------------
-
-
-The |Coq| Emacs mode
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-|Coq| comes with a Major mode for GNU Emacs, ``gallina.el``. This mode
-provides syntax highlighting and also a rudimentary indentation
-facility in the style of the ``Caml`` GNU Emacs mode.
-
-Add the following lines to your ``.emacs`` file:
-
-::
-
- (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
- (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
-
-
-The |Coq| major mode is triggered by visiting a file with extension ``.v``,
-or manually with the command ``M-x coq-mode``. It gives you the correct
-syntax table for the |Coq| language, and also a rudimentary indentation
-facility:
-
-
-+ pressing ``Tab`` at the beginning of a line indents the line like the
- line above;
-+ extra tabulations increase the indentation level (by 2 spaces by default);
-+ ``M-Tab`` decreases the indentation level.
-
-
-An inferior mode to run |Coq| under Emacs, by Marco Maggesi, is also
-included in the distribution, in file ``inferior-coq.el``. Instructions to
-use it are contained in this file.
-
-
-Proof-General
-~~~~~~~~~~~~~
-
-Proof-General is a generic interface for proof assistants based on
-Emacs. The main idea is that the |Coq| commands you are editing are sent
-to a |Coq| toplevel running behind Emacs and the answers of the system
-automatically inserted into other Emacs buffers. Thus you don’t need
-to copy-paste the |Coq| material from your files to the |Coq| toplevel or
-conversely from the |Coq| toplevel to some files.
-
-Proof-General is developed and distributed independently of the system
-|Coq|. It is freely available at `<https://proofgeneral.github.io/>`_.
-
-
-Module specification
---------------------
-
-Given a |Coq| vernacular file, the gallina filter extracts its
-specification (inductive types declarations, definitions, type of
-lemmas and theorems), removing the proofs parts of the file. The |Coq|
-file ``file.v`` gives birth to the specification file ``file.g`` (where
-the suffix ``.g`` stands for |Gallina|).
-
-See the man page of ``gallina`` for more details and options.
-
Man pages
---------
-There are man pages for the commands ``coqdep``, ``gallina`` and ``coq-tex``. Man
+There are man pages for the commands ``coqdep`` and ``coq-tex``. Man
pages are installed at installation time (see installation
instructions in file ``INSTALL``, step 6).
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 1c554acdb..6fb73a030 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -623,7 +623,9 @@ where:
+ In the occurrence switch :token:`occ_switch`, if the first element of the
list is a natural, this element should be a number, and not an Ltac
variable. The empty list ``{}`` is not interpreted as a valid occurrence
- switch.
+ switch, it is rather used as a flag to signal the intent of the user to
+ clear the name following it (see :ref:`ssr_rewrite_occ_switch` and
+ :ref:`introduction_ssr`)
The tactic:
@@ -1484,7 +1486,7 @@ The abstract tactic
```````````````````
.. tacn:: abstract: {+ d_item}
- :name abstract (ssreflect)
+ :name: abstract (ssreflect)
This tactic assigns an abstract constant previously introduced with the ``[:
name ]`` intro pattern (see section :ref:`introduction_ssr`).
@@ -1539,7 +1541,7 @@ whose general syntax is
:name: =>
.. prodn::
- i_item ::= @i_pattern %| @s_item %| @clear_switch %| /@term
+ i_item ::= @i_pattern %| @s_item %| @clear_switch %| {? %{%} } /@term
.. prodn::
s_item ::= /= %| // %| //=
@@ -1641,6 +1643,11 @@ The view is applied to the top assumption.
While it is good style to use the :token:`i_item` i * to pop the variables
and assumptions corresponding to each constructor, this is not enforced by
|SSR|.
+``/`` :token:`term`
+ Interprets the top of the stack with the view :token:`term`.
+ It is equivalent to ``move/term``. The optional flag ``{}`` can
+ be used to signal that the :token:`term`, when it is a context entry,
+ has to be cleared.
``-``
does nothing, but counts as an intro pattern. It can also be used to
force the interpretation of ``[`` :token:`i_item` * ``| … |``
@@ -2402,7 +2409,7 @@ tactic:
The behavior of the defective have tactic makes it possible to
generalize it in the following general construction:
-.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item | {+ @binder } } {? : @term } {? := @term | by @tactic }
+.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item | {+ @ssr_binder } } {? : @term } {? := @term | by @tactic }
Open syntax is supported for both :token:`term`. For the description
of :token:`i_item` and :token:`s_item` see section
@@ -3236,6 +3243,7 @@ the equality.
Indeed the left hand side of ``H`` does not match
the redex identified by the pattern ``x + y * 4``.
+.. _ssr_rewrite_occ_switch:
Occurrence switches and redex switches
``````````````````````````````````````
@@ -3260,6 +3268,9 @@ the rewrite tactic. The effect of the tactic on the initial goal is to
rewrite this lemma at the second occurrence of the first matching
``x + y + 0`` of the explicit rewrite redex ``_ + y + 0``.
+An empty occurrence switch ``{}`` is not interpreted as a valid occurrence
+switch. It has the effect of clearing the :token:`r_item` (when it is the name
+of a context entry).
Occurrence selection and repetition
```````````````````````````````````
@@ -5242,7 +5253,7 @@ Notation scope
Module name
-.. prodn:: name ::= @qualid
+.. prodn:: modname ::= @qualid
Natural number
@@ -5252,14 +5263,10 @@ where :token:`ident` is an Ltac variable denoting a standard |Coq| numeral
(should not be the name of a tactic which can be followed by a
bracket ``[``, like ``do``, ``have``,…)
-Pattern
-
-.. prodn:: pattern ::= @term
-
Items and switches
~~~~~~~~~~~~~~~~~~
-.. prodn:: binder ::= @ident %| ( @ident {? : @term } )
+.. prodn:: ssr_binder ::= @ident %| ( @ident {? : @term } )
binder see :ref:`abbreviations_ssr`.
@@ -5283,7 +5290,7 @@ generalization item see :ref:`structure_ssr`
intro pattern :ref:`introduction_ssr`
-.. prodn:: i_item ::= @clear_switch %| @s_item %| @i_pattern %| / @term
+.. prodn:: i_item ::= @clear_switch %| @s_item %| @i_pattern %| {? %{%} } / @term
intro item see :ref:`introduction_ssr`
@@ -5354,8 +5361,8 @@ case analysis see :ref:`the_defective_tactics_ssr`
rewrite see :ref:`rewriting_ssr`
-.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item %| {+ @binder } } {? : @term } := @term
-.. tacv:: have {* @i_item } {? @i_pattern } {? @s_item %| {+ @binder } } : @term {? by @tactic }
+.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item %| {+ @ssr_binder } } {? : @term } := @term
+.. tacv:: have {* @i_item } {? @i_pattern } {? @s_item %| {+ @ssr_binder } } : @term {? by @tactic }
.. tacn:: have suff {? @clear_switch } {? @i_pattern } {? : @term } := @term
.. tacv:: have suff {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
.. tacv:: gen have {? @ident , } {? @i_pattern } : {+ @gen_item } / @term {? by @tactic }
@@ -5369,9 +5376,9 @@ forward chaining see :ref:`structure_ssr`
specializing see :ref:`structure_ssr`
-.. tacn:: suff {* @i_item } {? @i_pattern } {+ @binder } : @term {? by @tactic }
+.. tacn:: suff {* @i_item } {? @i_pattern } {+ @ssr_binder } : @term {? by @tactic }
:name: suff
-.. tacv:: suffices {* @i_item } {? @i_pattern } {+ @binder } : @term {? by @tactic }
+.. tacv:: suffices {* @i_item } {? @i_pattern } {+ @ssr_binder } : @term {? by @tactic }
:name: suffices
.. tacv:: suff {? have } {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
.. tacv:: suffices {? have } {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
@@ -5382,7 +5389,7 @@ backchaining see :ref:`structure_ssr`
local definition :ref:`definitions_ssr`
-.. tacv:: pose @ident {+ @binder } := @term
+.. tacv:: pose @ident {+ @ssr_binder } := @term
local function definition
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index d0a0d568e..45667b099 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -3422,18 +3422,24 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
Adds each :n:`Hint Unfold @ident`.
- .. cmdv:: Hint %( Transparent %| Opaque %) @qualid
- :name: Hint ( Transparent | Opaque )
+ .. cmdv:: Hint Transparent {+ @qualid}
+ Hint Opaque {+ @qualid}
+ :name: Hint Transparent; Hint Opaque
- This adds a transparency hint to the database, making :n:`@qualid` a
- transparent or opaque constant during resolution. This information is used
+ This adds transparency hints to the database, making :n:`@qualid`
+ transparent or opaque constants during resolution. This information is used
during unification of the goal with any lemma in the database and inside the
discrimination network to relax or constrain it in the case of discriminated
databases.
- .. cmdv:: Hint %( Transparent %| Opaque %) {+ @ident}
+ .. cmdv:: Hint Variables %( Transparent %| Opaque %)
+ Hint Constants %( Transparent %| Opaque %)
+ :name: Hint Variables; Hint Constants
- Declares each :n:`@ident` as a transparent or opaque constant.
+ This sets the transparency flag used during unification of
+ hints in the database for all constants or all variables,
+ overwritting the existing settings of opacity. It is advised
+ to use this just after a :cmd:`Create HintDb` command.
.. cmdv:: Hint Extern @num {? @pattern} => @tactic
:name: Hint Extern
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index 3b95a37ed..dcefa293b 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -10,15 +10,14 @@ parses and prints objects, i.e. the translations between the concrete
and internal representations of terms and commands.
The main commands to provide custom symbolic notations for terms are
-``Notation`` and ``Infix``. They are described in section :ref:`Notations`. There is also a
-variant of ``Notation`` which does not modify the parser. This provides with a
-form of abbreviation and it is described in Section :ref:`Abbreviations`. It is
+:cmd:`Notation` and :cmd:`Infix`; they will be described in the
+:ref:`next section <Notations>`. There is also a
+variant of :cmd:`Notation` which does not modify the parser; this provides a
+form of :ref:`abbreviation <Abbreviations>`. It is
sometimes expected that the same symbolic notation has different meanings in
-different contexts. To achieve this form of overloading, |Coq| offers a notion
-of interpretation scope. This is described in Section :ref:`Scopes`.
-
-The main command to provide custom notations for tactics is ``Tactic Notation``.
-It is described in Section :ref:`TacticNotation`.
+different contexts; to achieve this form of overloading, |Coq| offers a notion
+of :ref:`interpretation scopes <Scopes>`.
+The main command to provide custom notations for tactics is :cmd:`Tactic Notation`.
.. coqtop:: none
@@ -44,7 +43,7 @@ logical conjunction (and). Such a notation is declared by
Notation "A /\ B" := (and A B).
-The expression :g:`(and A B)` is the abbreviated term and the string ``"A /\ B"``
+The expression :g:`(and A B)` is the abbreviated term and the string :g:`"A /\ B"`
(called a *notation*) tells how it is symbolically written.
A notation is always surrounded by double quotes (except when the
@@ -66,15 +65,15 @@ example.
A notation binds a syntactic expression to a term. Unless the parser
and pretty-printer of Coq already know how to deal with the syntactic
-expression (see 12.1.7), explicit precedences and associativity rules
-have to be given.
+expression (see :ref:`ReservingNotations`), explicit precedences and
+associativity rules have to be given.
.. note::
The right-hand side of a notation is interpreted at the time the notation is
- given. In particular, disambiguation of constants, implicit arguments (see
- Section :ref:`ImplicitArguments`), coercions (see Section :ref:`Coercions`),
- etc. are resolved at the time of the declaration of the notation.
+ given. In particular, disambiguation of constants, :ref:`implicit arguments
+ <ImplicitArguments>`, :ref:`coercions <Coercions>`, etc. are resolved at the
+ time of the declaration of the notation.
Precedences and associativity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -106,13 +105,13 @@ is 100, for example 85 for disjunction and 80 for conjunction [#and_or_levels]_.
Similarly, an associativity is needed to decide whether :g:`True /\ False /\ False`
defaults to :g:`True /\ (False /\ False)` (right associativity) or to
:g:`(True /\ False) /\ False` (left associativity). We may even consider that the
-expression is not well- formed and that parentheses are mandatory (this is a “no
+expression is not well-formed and that parentheses are mandatory (this is a “no
associativity”) [#no_associativity]_. We do not know of a special convention of
the associativity of disjunction and conjunction, so let us apply for instance a
right associativity (which is the choice of Coq).
Precedence levels and associativity rules of notations have to be
-given between parentheses in a list of modifiers that the ``Notation``
+given between parentheses in a list of modifiers that the :cmd:`Notation`
command understands. Here is how the previous examples refine.
.. coqtop:: in
@@ -122,9 +121,10 @@ command understands. Here is how the previous examples refine.
By default, a notation is considered non associative, but the
precedence level is mandatory (except for special cases whose level is
-canonical). The level is either a number or the phrase `next level`
-whose meaning is obvious. The list of levels already assigned is on
-Figure 3.1.
+canonical). The level is either a number or the phrase ``next level``
+whose meaning is obvious.
+Some :ref:`associativities are predefined <init-notations>` in the
+``Notations`` module.
.. TODO I don't find it obvious -- CPC
@@ -162,7 +162,7 @@ One can also define notations for binders.
In the last case though, there is a conflict with the notation for
type casts. The notation for types casts, as shown by the command :cmd:`Print
Grammar constr` is at level 100. To avoid ``x : A`` being parsed as a type cast,
-it is necessary to put x at a level below 100, typically 99. Hence, a correct
+it is necessary to put ``x`` at a level below 100, typically 99. Hence, a correct
definition is the following:
.. coqtop:: all
@@ -176,7 +176,7 @@ Simple factorization rules
~~~~~~~~~~~~~~~~~~~~~~~~~~
Coq extensible parsing is performed by *Camlp5* which is essentially a LL1
-parser: it decides which notation to parse by looking tokens from left to right.
+parser: it decides which notation to parse by looking at tokens from left to right.
Hence, some care has to be taken not to hide already existing rules by new
rules. Some simple left factorization work has to be done. Here is an example.
@@ -186,11 +186,11 @@ rules. Some simple left factorization work has to be done. Here is an example.
Notation "x < y < z" := (x < y /\ y < z) (at level 70).
In order to factorize the left part of the rules, the subexpression
-referred by y has to be at the same level in both rules. However the
-default behavior puts y at the next level below 70 in the first rule
-(no associativity is the default), and at the level 200 in the second
-rule (level 200 is the default for inner expressions). To fix this, we
-need to force the parsing level of y, as follows.
+referred by ``y`` has to be at the same level in both rules. However the
+default behavior puts ``y`` at the next level below 70 in the first rule
+(``no associativity`` is the default), and at the level 200 in the second
+rule (``level 200`` is the default for inner expressions). To fix this, we
+need to force the parsing level of ``y``, as follows.
.. coqtop:: all
@@ -198,9 +198,9 @@ need to force the parsing level of y, as follows.
Notation "x < y < z" := (x < y /\ y < z) (at level 70, y at next level).
For the sake of factorization with Coq predefined rules, simple rules
-have to be observed for notations starting with a symbol: e.g. rules
-starting with “{” or “(” should be put at level 0. The list of Coq
-predefined notations can be found in Chapter :ref:`thecoqlibrary`.
+have to be observed for notations starting with a symbol, e.g., rules
+starting with “\ ``{``\ ” or “\ ``(``\ ” should be put at level 0. The list
+of Coq predefined notations can be found in the chapter on :ref:`thecoqlibrary`.
.. cmd:: Print Grammar constr.
@@ -215,7 +215,7 @@ predefined notations can be found in Chapter :ref:`thecoqlibrary`.
Displaying symbolic notations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The command ``Notation`` has an effect both on the Coq parser and on the
+The command :cmd:`Notation` has an effect both on the Coq parser and on the
Coq printer. For example:
.. coqtop:: all
@@ -301,7 +301,7 @@ at the time of use of the notation.
.. note:: Sometimes, a notation is expected only for the parser. To do
so, the option ``only parsing`` is allowed in the list of modifiers
- of ``Notation``. Conversely, the ``only printing`` modifier can be
+ of :cmd:`Notation`. Conversely, the ``only printing`` modifier can be
used to declare that a notation should only be used for printing and
should not declare a parsing rule. In particular, such notations do
not modify the parser.
@@ -309,7 +309,7 @@ at the time of use of the notation.
The Infix command
~~~~~~~~~~~~~~~~~~
-The ``Infix`` command is a shortening for declaring notations of infix
+The :cmd:`Infix` command is a shortening for declaring notations of infix
symbols.
.. cmd:: Infix "@symbol" := @term ({+, @modifier}).
@@ -324,6 +324,8 @@ symbols.
Infix "/\" := and (at level 80, right associativity).
+.. _ReservingNotations:
+
Reserving notations
~~~~~~~~~~~~~~~~~~~
@@ -341,7 +343,7 @@ state of Coq.
Reserving a notation is also useful for simultaneously defining an
inductive type or a recursive constant and a notation for it.
-.. note:: The notations mentioned on Figure 3.1 are reserved. Hence
+.. note:: The notations mentioned in the module :ref:`init-notations` are reserved. Hence
their precedence and associativity cannot be changed.
Simultaneous definition of terms and notations
@@ -391,7 +393,7 @@ Locating notations
To know to which notations a given symbol belongs to, use the :cmd:`Locate`
command. You can call it on any (composite) symbol surrounded by double quotes.
To locate a particular notation, use a string where the variables of the
-notation are replaced by “_” and where possible single quotes inserted around
+notation are replaced by “``_``” and where possible single quotes inserted around
identifiers or tokens starting with a single quote are dropped.
.. coqtop:: all
@@ -404,7 +406,7 @@ Notations and binders
Notations can include binders. This section lists
different ways to deal with binders. For further examples, see also
-Section :ref:`RecursiveNotationsWithBinders`.
+:ref:`RecursiveNotationsWithBinders`.
Binders bound in the notation and parsed as identifiers
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -490,7 +492,7 @@ the following:
This is so because the grammar also contains rules starting with :g:`{}` and
followed by a term, such as the rule for the notation :g:`{ A } + { B }` for the
-constant :g:`sumbool` (see Section :ref:`specification`).
+constant :g:`sumbool` (see :ref:`specification`).
Then, in the rule, ``x ident`` is replaced by ``x at level 99 as ident`` meaning
that ``x`` is parsed as a term at level 99 (as done in the notation for
@@ -545,7 +547,7 @@ the next command fails because p does not bind in the instance of n.
Notation "[> a , .. , b <]" :=
(cons a .. (cons b nil) .., cons b .. (cons a nil) ..).
-.. _RecursiveNotationsWithBinders:
+.. _RecursiveNotations:
Notations with recursive patterns
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -563,7 +565,7 @@ confused with the three-dots notation “``…``” used in this manual to denot
a sequence of arbitrary size.
On the left-hand side, the part “``x s .. s y``” of the notation parses
-any number of time (but at least one time) a sequence of expressions
+any number of times (but at least one time) a sequence of expressions
separated by the sequence of tokens ``s`` (in the example, ``s`` is just “``;``”).
The right-hand side must contain a subterm of the form either
@@ -572,7 +574,7 @@ called the *iterator* of the recursive notation is an arbitrary expression with
distinguished placeholders and where :math:`t` is called the *terminating
expression* of the recursive notation. In the example, we choose the names
:math:`x` and :math:`y` but in practice they can of course be chosen
-arbitrarily. Not atht the placeholder :math:`[~]_I` has to occur only once but
+arbitrarily. Note that the placeholder :math:`[~]_I` has to occur only once but
:math:`[~]_E` can occur several times.
Parsing the notation produces a list of expressions which are used to
@@ -595,9 +597,10 @@ and the terminating expression is ``nil``. Here are other examples:
(t at level 39).
Notations with recursive patterns can be reserved like standard
-notations, they can also be declared within interpretation scopes (see
-section 12.2).
+notations, they can also be declared within
+:ref:`interpretation scopes <Scopes>`.
+.. _RecursiveNotationsWithBinders:
Notations with recursive patterns involving binders
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -611,7 +614,8 @@ is:
(ex (fun x => .. (ex (fun y => p)) ..))
(at level 200, x binder, y binder, right associativity).
-The principle is the same as in Section 12.1.12 except that in the iterator
+The principle is the same as in :ref:`RecursiveNotations`
+except that in the iterator
:math:`φ([~]_E , [~]_I)`, the placeholder :math:`[~]_E` can also occur in
position of the binding variable of a ``fun`` or a ``forall``.
@@ -620,8 +624,8 @@ binders, ``x`` and ``y`` must be marked as ``binder`` in the list of modifiers
of the notation. The binders of the parsed sequence are used to fill the
occurrences of the first placeholder of the iterating pattern which is
repeatedly nested as many times as the number of binders generated. If ever the
-generalization operator ``'`` (see Section 2.7.19) is used in the binding list,
-the added binders are taken into account too.
+generalization operator ``'`` (see :ref:`implicit-generalization`) is
+used in the binding list, the added binders are taken into account too.
Binders parsing exist in two flavors. If ``x`` and ``y`` are marked as binder,
then a sequence such as :g:`a b c : T` will be accepted and interpreted as
@@ -678,7 +682,7 @@ position of :g:`x`:
In addition to ``global``, one can restrict the syntax of a
sub-expression by using the entry names ``ident`` or ``pattern``
-already seen in Section :ref:`NotationsWithBinders`, even when the
+already seen in :ref:`NotationsWithBinders`, even when the
corresponding expression is not used as a binder in the right-hand
side. E.g.:
@@ -690,10 +694,14 @@ side. E.g.:
Summary
~~~~~~~
-**Syntax of notations**
+.. _NotationSyntax:
+
+Syntax of notations
++++++++++++++++++++
The different syntactic variants of the command Notation are given on the
-following figure. The optional :token:`scope` is described in the Section 12.2.
+following figure. The optional :production:`scope` is described in
+:ref:`Scopes`.
.. productionlist:: coq
notation : [Local] Notation `string` := `term` [`modifiers`] [: `scope`].
@@ -743,14 +751,15 @@ following figure. The optional :token:`scope` is described in the Section 12.2.
given to some notation, say ``"{ y } & { z }"`` in fact applies to the
underlying ``"{ x }"``\-free rule which is ``"y & z"``).
-**Persistence of notations**
+Persistence of notations
+++++++++++++++++++++++++
Notations do not survive the end of sections.
.. cmd:: Local Notation @notation
Notations survive modules unless the command ``Local Notation`` is used instead
- of ``Notation``.
+ of :cmd:`Notation`.
.. _Scopes:
@@ -762,13 +771,13 @@ interpretation. Interpretation scopes provide a weak, purely
syntactical form of notations overloading: the same notation, for
instance the infix symbol ``+`` can be used to denote distinct
definitions of the additive operator. Depending on which interpretation
-scopes is currently open, the interpretation is different.
+scopes are currently open, the interpretation is different.
Interpretation scopes can include an interpretation for numerals and
strings. However, this is only made possible at the Objective Caml
level.
-See Figure 12.1 for the syntax of notations including the possibility
-to declare them in a given scope. Here is a typical example which
+See :ref:`above <NotationSyntax>` for the syntax of notations including the
+possibility to declare them in a given scope. Here is a typical example which
declares the notation for conjunction in the scope ``type_scope``.
.. coqdoc::
@@ -892,27 +901,27 @@ Binding arguments of a constant to an interpretation scope
turn to be themselves arguments of a reference are interpreted
accordingly to the arguments scopes bound to this reference.
-.. cmdv:: Arguments @qualid : clear scopes
+ .. cmdv:: Arguments @qualid : clear scopes
- Arguments scopes can be cleared with :n:`Arguments @qualid : clear scopes`.
+ Arguments scopes can be cleared with :n:`Arguments @qualid : clear scopes`.
-.. cmdv:: Arguments @qualid {+ @name%scope} : extra scopes
+ .. cmdv:: Arguments @qualid {+ @name%scope} : extra scopes
- Defines extra argument scopes, to be used in case of coercion to Funclass
- (see Chapter :ref:`implicitcoercions`) or with a computed type.
+ Defines extra argument scopes, to be used in case of coercion to ``Funclass``
+ (see the :ref:`implicitcoercions` chapter) or with a computed type.
-.. cmdv:: Global Arguments @qualid {+ @name%@scope}
+ .. cmdv:: Global Arguments @qualid {+ @name%@scope}
- This behaves like :n:`Arguments qualid {+ @name%@scope}` but survives when a
- section is closed instead of stopping working at section closing. Without the
- ``Global`` modifier, the effect of the command stops when the section it belongs
- to ends.
+ This behaves like :n:`Arguments qualid {+ @name%@scope}` but survives when a
+ section is closed instead of stopping working at section closing. Without the
+ ``Global`` modifier, the effect of the command stops when the section it belongs
+ to ends.
-.. cmdv:: Local Arguments @qualid {+ @name%@scope}
+ .. cmdv:: Local Arguments @qualid {+ @name%@scope}
- This behaves like :n:`Arguments @qualid {+ @name%@scope}` but does not
- survive modules and files. Without the ``Local`` modifier, the effect of the
- command is visible from within other modules or files.
+ This behaves like :n:`Arguments @qualid {+ @name%@scope}` but does not
+ survive modules and files. Without the ``Local`` modifier, the effect of the
+ command is visible from within other modules or files.
.. seealso::
@@ -947,18 +956,18 @@ Binding types of arguments to an interpretation scope
When an interpretation scope is naturally associated to a type (e.g. the
scope of operations on the natural numbers), it may be convenient to bind it
- to this type. When a scope ``scope`` is bound to a type type, any new function
- defined later on gets its arguments of type type interpreted by default in
+ to this type. When a scope ``scope`` is bound to a type ``type``, any new function
+ defined later on gets its arguments of type ``type`` interpreted by default in
scope scope (this default behavior can however be overwritten by explicitly
- using the command ``Arguments``).
+ using the command :cmd:`Arguments`).
Whether the argument of a function has some type ``type`` is determined
- statically. For instance, if f is a polymorphic function of type :g:`forall
- X:Type, X -> X` and type :g:`t` is bound to a scope ``scope``, then :g:`a` of
- type :g:`t` in :g:`f t a` is not recognized as an argument to be interpreted
- in scope ``scope``.
+ statically. For instance, if ``f`` is a polymorphic function of type
+ :g:`forall X:Type, X -> X` and type :g:`t` is bound to a scope ``scope``,
+ then :g:`a` of type :g:`t` in :g:`f t a` is not recognized as an argument to
+ be interpreted in scope ``scope``.
- More generally, any coercion :n:`@class` (see Chapter :ref:`implicitcoercions`)
+ More generally, any coercion :n:`@class` (see the :ref:`implicitcoercions` chapter)
can be bound to an interpretation scope. The command to do it is
:n:`Bind Scope @scope with @class`
@@ -980,12 +989,6 @@ Binding types of arguments to an interpretation scope
.. note:: The scopes ``type_scope`` and ``function_scope`` also have a local
effect on interpretation. See the next section.
-.. seealso::
-
- :cmd:`About`
- The command to show the scopes bound to the arguments of a
- function is described in Section 2.
-
The ``type_scope`` interpretation scope
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -996,7 +999,7 @@ scope which is temporarily activated each time a subterm of an expression is
expected to be a type. It is delimited by the key ``type``, and bound to the
coercion class ``Sortclass``. It is also used in certain situations where an
expression is statically known to be a type, including the conclusion and the
-type of hypotheses within an Ltac goal match (see Section
+type of hypotheses within an Ltac goal match (see
:ref:`ltac-match-goal`), the statement of a theorem, the type of a definition,
the type of a binder, the domain and codomain of implication, the codomain of
products, and more generally any type argument of a declared or defined
@@ -1017,8 +1020,8 @@ Interpretation scopes used in the standard library of Coq
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We give an overview of the scopes used in the standard library of Coq.
-For a complete list of notations in each scope, use the commands Print
-Scopes or Print Scope scope.
+For a complete list of notations in each scope, use the commands :cmd:`Print
+Scopes` or :cmd:`Print Scope`.
``type_scope``
This scope includes infix * for product types and infix + for sum types. It
@@ -1084,7 +1087,7 @@ Scopes or Print Scope scope.
``string_scope``
This scope includes notation for strings as elements of the type string.
Special characters and escaping follow Coq conventions on strings (see
- Section 1.1). Especially, there is no convention to visualize non
+ :ref:`lexical-conventions`). Especially, there is no convention to visualize non
printable characters of a string. The file :file:`String.v` shows an example
that contains quotes, a newline and a beep (i.e. the ASCII character
of code 7).
@@ -1093,8 +1096,8 @@ Scopes or Print Scope scope.
This scope includes interpretation for all strings of the form ``"c"``
where :g:`c` is an ASCII character, or of the form ``"nnn"`` where nnn is
a three-digits number (possibly with leading 0's), or of the form
- ``""""``. Their respective denotations are the ASCII code of c, the
- decimal ASCII code nnn, or the ascii code of the character ``"`` (i.e.
+ ``""""``. Their respective denotations are the ASCII code of :g:`c`, the
+ decimal ASCII code ``nnn``, or the ascii code of the character ``"`` (i.e.
the ASCII code 34), all of them being represented in the type :g:`ascii`.
@@ -1109,25 +1112,26 @@ Displaying informations about scopes
by the same notation in a more recently open scope are not displayed.
Hence each notation is displayed only once.
-.. cmdv:: Print Visibility scope
-
- This displays the current stack of notations in scopes and lonely
- notations assuming that scope is pushed on top of the stack. This is
- useful to know how a subterm locally occurring in the scope ofscope is
- interpreted.
-
-.. cmdv:: Print Scope scope
+ .. cmdv:: Print Visibility @scope
- This displays all the notations defined in interpretation scopescope.
- It also displays the delimiting key if any and the class to which the
- scope is bound, if any.
+ This displays the current stack of notations in scopes and lonely
+ notations assuming that :token:`scope` is pushed on top of the stack. This is
+ useful to know how a subterm locally occurring in the scope :token:`scope` is
+ interpreted.
-.. cmdv:: Print Scopes
+.. cmd:: Print Scopes
This displays all the notations, delimiting keys and corresponding
class of all the existing interpretation scopes. It also displays the
lonely notations.
+ .. cmdv:: Print Scope @scope
+ :name: Print Scope
+
+ This displays all the notations defined in interpretation scope :token:`scope`.
+ It also displays the delimiting key if any and the class to which the
+ scope is bound, if any.
+
.. _Abbreviations:
Abbreviations
@@ -1324,7 +1328,7 @@ tactic language. Tactic notations obey the following syntax:
.. [#and_or_levels] which are the levels effectively chosen in the current
implementation of Coq
-.. [#no_associativity] Coq accepts notations declared as no associative but the parser on
+.. [#no_associativity] Coq accepts notations declared as ``no associative`` but the parser on
which Coq is built, namely Camlp4, currently does not implement the
- no-associativity and replaces it by a left associativity; hence it is
- the same for Coq: no-associativity is in fact left associativity
+ ``no associativity`` and replaces it by a ``left associativity``; hence it is
+ the same for Coq: ``no associativity`` is in fact ``left associativity``.
diff --git a/doc/tools/coqrst/coqdoc/main.py b/doc/tools/coqrst/coqdoc/main.py
index cedd60d3b..57adcb287 100644
--- a/doc/tools/coqrst/coqdoc/main.py
+++ b/doc/tools/coqrst/coqdoc/main.py
@@ -20,6 +20,7 @@ lexer.
"""
import os
+import platform
from tempfile import mkstemp
from subprocess import check_output
@@ -36,6 +37,9 @@ def coqdoc(coq_code, coqdoc_bin=None):
"""Get the output of coqdoc on coq_code."""
coqdoc_bin = coqdoc_bin or os.path.join(os.getenv("COQBIN"), "coqdoc")
fd, filename = mkstemp(prefix="coqdoc-", suffix=".v")
+ if platform.system().startswith("CYGWIN"):
+ # coqdoc currently doesn't accept cygwin style paths in the form "/cygdrive/c/..."
+ filename = check_output(["cygpath", "-w", filename]).decode("utf-8").strip()
try:
os.write(fd, COQDOC_HEADER.encode("utf-8"))
os.write(fd, coq_code.encode("utf-8"))
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index ab3a485b2..c9487abf0 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -28,6 +28,7 @@ from docutils.parsers.rst.directives.admonitions import BaseAdmonition
from sphinx import addnodes
from sphinx.roles import XRefRole
+from sphinx.errors import ExtensionError
from sphinx.util.nodes import set_source_info, set_role_source_info, make_refnode
from sphinx.util.logging import getLogger
from sphinx.directives import ObjectDescription
@@ -103,10 +104,16 @@ class CoqObject(ObjectDescription):
'undocumented': directives.flag
}
- def _subdomain(self):
+ def subdomain_data(self):
if self.subdomain is None:
raise ValueError()
- return self.subdomain
+ return self.env.domaindata['coq']['objects'][self.subdomain]
+
+ def _render_annotation(self, signode):
+ if self.annotation:
+ annot_node = nodes.inline(self.annotation, self.annotation, classes=['sigannot'])
+ signode += addnodes.desc_annotation(self.annotation, '', annot_node)
+ signode += nodes.Text(' ')
def handle_signature(self, signature, signode):
"""Prefix signature with the proper annotation, then render it using
@@ -114,29 +121,32 @@ class CoqObject(ObjectDescription):
:returns: the name given to the resulting node, if any
"""
- if self.annotation:
- annotation = self.annotation + ' '
- signode += addnodes.desc_annotation(annotation, annotation)
+ self._render_annotation(signode)
self._render_signature(signature, signode)
return self._names.get(signature) or self._name_from_signature(signature)
+ def _warn_if_duplicate_name(self, objects, name):
+ """Check that two objects in the same domain don't have the same name."""
+ if name in objects:
+ MSG = 'Duplicate object: {}; other is at {}'
+ msg = MSG.format(name, self.env.doc2path(objects[name][0]))
+ self.state_machine.reporter.warning(msg, line=self.lineno)
+
def _record_name(self, name, target_id):
"""Record a name, mapping it to target_id
Warns if another object of the same name already exists.
"""
- names_in_subdomain = self.env.domaindata['coq']['objects'][self._subdomain()]
- # Check that two objects in the same domain don't have the same name
- if name in names_in_subdomain:
- self.state_machine.reporter.warning(
- 'Duplicate Coq object: {}; other is at {}'.format(
- name, self.env.doc2path(names_in_subdomain[name][0])),
- line=self.lineno)
+ names_in_subdomain = self.subdomain_data()
+ self._warn_if_duplicate_name(names_in_subdomain, name)
names_in_subdomain[name] = (self.env.docname, self.objtype, target_id)
+ def _target_id(self, name):
+ return make_target(self.objtype, nodes.make_id(name))
+
def _add_target(self, signode, name):
"""Register a link target ‘name’, pointing to signode."""
- targetid = make_target(self.objtype, nodes.make_id(name))
+ targetid = self._target_id(name)
if targetid not in self.state.document.ids:
signode['ids'].append(targetid)
signode['names'].append(name)
@@ -314,50 +324,71 @@ class OptionObject(NotationObject):
def _name_from_signature(self, signature):
return stringify_with_ellipses(signature)
-class ProductionObject(NotationObject):
- """Grammar productions.
+class ProductionObject(CoqObject):
+ r"""A grammar production.
This is useful if you intend to document individual grammar productions.
Otherwise, use Sphinx's `production lists
<http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_.
+
+ Unlike ``.. productionlist``\ s, this directive accepts notation syntax.
+
+
+ Usage::
+
+ .. prodn:: token += production
+ .. prodn:: token ::= production
+
+ Example::
+
+ .. prodn:: term += let: @pattern := @term in @term
+ .. prodn:: occ_switch ::= { {? + %| - } {* @num } }
+
"""
- # FIXME (CPC): I have no idea what this does :/ Someone should add an example.
subdomain = "prodn"
- index_suffix = None
- annotation = None
+ #annotation = "Grammar production"
- # override to create link targets for production left-hand sides
- def run(self):
+ def _render_signature(self, signature, signode):
+ raise NotImplementedError(self)
+
+ SIG_ERROR = ("Invalid syntax in ``.. prodn::`` directive"
+ + "\nExpected ``name ::= ...`` or ``name += ...``"
+ + " (e.g. ``pattern += constr:(@ident)``)")
+
+ def handle_signature(self, signature, signode):
+ nsplits = 2
+ parts = signature.split(maxsplit=nsplits)
+ if len(parts) != 3:
+ raise ExtensionError(ProductionObject.SIG_ERROR)
+
+ lhs, op, rhs = (part.strip() for part in parts)
+ if op not in ["::=", "+="]:
+ raise ExtensionError(ProductionObject.SIG_ERROR)
+
+ self._render_annotation(signode)
+
+ lhs_op = '{} {} '.format(lhs, op)
+ lhs_node = nodes.literal(lhs_op, lhs_op)
+
+ position = self.state_machine.get_source_and_line(self.lineno)
+ rhs_node = parse_notation(rhs, *position)
+ signode += addnodes.desc_name(signature, '', lhs_node, rhs_node)
+
+ return ('token', lhs) if op == '::=' else None
+
+ def _add_index_entry(self, name, target):
+ pass
+
+ def _target_id(self, name):
+ # Use `name[1]` instead of ``nodes.make_id(name[1])`` to work around
+ # https://github.com/sphinx-doc/sphinx/issues/4983
+ return 'grammar-token-{}'.format(name[1])
+
+ def _record_name(self, name, targetid):
env = self.state.document.settings.env
objects = env.domaindata['std']['objects']
-
- class ProdnError(Exception):
- """Exception for ill-formed prodn"""
- pass
-
- [idx, node] = super().run()
- try:
- # find LHS of production
- inline_lhs = node[0][0][0][0] # may be fragile !!!
- lhs_str = str(inline_lhs)
- if lhs_str[0:7] != "<inline":
- raise ProdnError("Expected atom on LHS")
- lhs = inline_lhs[0]
- # register link target
- subnode = addnodes.production()
- subnode['tokenname'] = lhs
- idname = 'grammar-token-%s' % subnode['tokenname']
- if idname not in self.state.document.ids:
- subnode['ids'].append(idname)
- self.state.document.note_implicit_target(subnode, subnode)
- objects['token', subnode['tokenname']] = env.docname, idname
- subnode.extend(token_xrefs(lhs))
- # patch in link target
- inline_lhs['ids'].append(idname)
- except ProdnError as err:
- getLogger(__name__).warning("Could not create link target for prodn: " + str(err) +
- "\nSphinx represents the prodn as: " + str(node) + "\n")
- return [idx, node]
+ self._warn_if_duplicate_name(objects, name)
+ objects[name] = env.docname, targetid
class ExceptionObject(NotationObject):
"""An error raised by a Coq command or tactic.
@@ -841,11 +872,6 @@ class CoqOptionIndex(CoqSubdomainsIndex):
class CoqGallinaIndex(CoqSubdomainsIndex):
name, localname, shortname, subdomains = "thmindex", "Gallina Index", "theorems", ["thm"]
-# we specify an index to make productions fit into the framework of notations
-# but not likely to include a link to this index
-class CoqProductionIndex(CoqSubdomainsIndex):
- name, localname, shortname, subdomains = "prodnindex", "Production Index", "productions", ["prodn"]
-
class CoqExceptionIndex(CoqSubdomainsIndex):
name, localname, shortname, subdomains = "exnindex", "Errors and Warnings Index", "errors", ["exn", "warn"]
@@ -952,7 +978,7 @@ class CoqDomain(Domain):
'g': CoqCodeRole
}
- indices = [CoqVernacIndex, CoqTacticIndex, CoqOptionIndex, CoqGallinaIndex, CoqProductionIndex, CoqExceptionIndex]
+ indices = [CoqVernacIndex, CoqTacticIndex, CoqOptionIndex, CoqGallinaIndex, CoqExceptionIndex]
data_version = 1
initial_data = {
@@ -1047,7 +1073,7 @@ def setup(app):
# A few sanity checks:
subdomains = set(obj.subdomain for obj in CoqDomain.directives.values())
- assert subdomains == set(chain(*(idx.subdomains for idx in CoqDomain.indices)))
+ assert subdomains.issuperset(chain(*(idx.subdomains for idx in CoqDomain.indices)))
assert subdomains.issubset(CoqDomain.roles.keys())
# Add domain, directives, and roles
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index 6810626ad..005ef1635 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -592,25 +592,14 @@ let eq_constr_universes_proj env sigma m n =
let res = eq_constr' 0 (unsafe_to_constr m) (unsafe_to_constr n) in
if res then Some !cstrs else None
-let universes_of_constr env sigma c =
+let universes_of_constr sigma c =
let open Univ in
- let open Declarations in
let rec aux s c =
match kind sigma c with
| Const (c, u) ->
- begin match (Environ.lookup_constant c env).const_universes with
- | Polymorphic_const _ ->
LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s
- | Monomorphic_const (univs, _) ->
- LSet.union s univs
- end
| Ind ((mind,_), u) | Construct (((mind,_),_), u) ->
- begin match (Environ.lookup_mind mind env).mind_universes with
- | Cumulative_ind _ | Polymorphic_ind _ ->
LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s
- | Monomorphic_ind (univs,_) ->
- LSet.union s univs
- end
| Sort u ->
let sort = ESorts.kind sigma u in
if Sorts.is_small sort then s
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index e9d3e782b..ecb36615f 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -232,7 +232,7 @@ val fold : Evd.evar_map -> ('a -> t -> 'a) -> 'a -> t -> 'a
(** Gather the universes transitively used in the term, including in the
type of evars appearing in it. *)
-val universes_of_constr : Environ.env -> Evd.evar_map -> t -> Univ.LSet.t
+val universes_of_constr : Evd.evar_map -> t -> Univ.LSet.t
(** {6 Substitutions} *)
@@ -321,7 +321,7 @@ sig
val to_named_decl : (t, types) Context.Named.Declaration.pt -> (Constr.t, Constr.types) Context.Named.Declaration.pt
(** Physical identity. Does not care for defined evars. *)
- val to_named_context : (t, types) Context.Named.pt -> Context.Named.t
+ val to_named_context : (t, types) Context.Named.pt -> Constr.named_context
val to_sorts : ESorts.t -> Sorts.t
(** Physical identity. Does not care for normalization. *)
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 82be4791f..b77bf55d8 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -426,10 +426,6 @@ let push_rel_context_to_named_context ?hypnaming env sigma typ =
let default_source = Loc.tag @@ Evar_kinds.InternalHole
-let restrict_evar evd evk filter ?src candidates =
- let evd, evk' = Evd.restrict evk filter ?candidates ?src evd in
- Evd.declare_future_goal evk' evd, evk'
-
let new_pure_evar_full evd evi =
let (evd, evk) = Evd.new_evar evd evi in
let evd = Evd.declare_future_goal evk evd in
@@ -499,12 +495,12 @@ let e_new_type_evar env evdref ?src ?filter ?naming ?principal ?hypnaming rigid
evdref := evd;
c
-let new_Type ?(rigid=Evd.univ_flexible) env evd =
+let new_Type ?(rigid=Evd.univ_flexible) evd =
let open EConstr in
let (evd, s) = new_sort_variable rigid evd in
(evd, mkSort s)
-let e_new_Type ?(rigid=Evd.univ_flexible) env evdref =
+let e_new_Type ?(rigid=Evd.univ_flexible) evdref =
let evd', s = new_sort_variable rigid !evdref in
evdref := evd'; EConstr.mkSort s
@@ -514,6 +510,21 @@ let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?nami
evdref := evd';
ev
+(* Safe interface to unification problems *)
+type unification_pb = conv_pb * env * EConstr.constr * EConstr.constr
+
+let eq_unification_pb evd (pbty,env,t1,t2) (pbty',env',t1',t2') =
+ pbty == pbty' && env == env' &&
+ EConstr.eq_constr evd t1 t1' &&
+ EConstr.eq_constr evd t2 t2'
+
+let add_unification_pb ?(tail=false) pb evd =
+ let conv_pbs = Evd.conv_pbs evd in
+ if not (List.exists (eq_unification_pb evd pb) conv_pbs) then
+ let (pbty,env,t1,t2) = pb in
+ Evd.add_conv_pb ~tail (pbty,env,t1,t2) evd
+ else evd
+
(* This assumes an evar with identity instance and generalizes it over only
the de Bruijn part of the context *)
let generalize_evar_over_rels sigma (ev,args) =
@@ -532,11 +543,33 @@ let generalize_evar_over_rels sigma (ev,args) =
type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of existential
+| NoCandidatesLeft of Evar.t
exception ClearDependencyError of Id.t * clear_dependency_error * GlobRef.t option
exception Depends of Id.t
+let set_of_evctx l =
+ List.fold_left (fun s decl -> Id.Set.add (NamedDecl.get_id decl) s) Id.Set.empty l
+
+let filter_effective_candidates evd evi filter candidates =
+ let ids = set_of_evctx (Filter.filter_list filter (evar_context evi)) in
+ List.filter (fun a -> Id.Set.subset (collect_vars evd a) ids) candidates
+
+let restrict_evar evd evk filter ?src candidates =
+ let evar_info = Evd.find_undefined evd evk in
+ let candidates = Option.map (filter_effective_candidates evd evar_info filter) candidates in
+ match candidates with
+ | Some [] -> raise (ClearDependencyError (*FIXME*)(Id.of_string "blah", (NoCandidatesLeft evk), None))
+ | _ ->
+ let evd, evk' = Evd.restrict evk filter ?candidates ?src evd in
+ (** Mark new evar as future goal, removing previous one,
+ circumventing Proofview.advance but making Proof.run_tactic catch these. *)
+ let future_goals = Evd.save_future_goals evd in
+ let future_goals = Evd.filter_future_goals (fun evk' -> not (Evar.equal evk evk')) future_goals in
+ let evd = Evd.restore_future_goals evd future_goals in
+ (Evd.declare_future_goal evk' evd, evk')
+
let rec check_and_clear_in_constr env evdref err ids global c =
(* returns a new constr where all the evars have been 'cleaned'
(ie the hypotheses ids have been removed from the contexts of
@@ -606,7 +639,9 @@ let rec check_and_clear_in_constr env evdref err ids global c =
let origfilter = Evd.evar_filter evi in
let filter = Evd.Filter.apply_subfilter origfilter filter in
let evd = !evdref in
- let (evd,_) = restrict_evar evd evk filter None in
+ let candidates = Evd.evar_candidates evi in
+ let candidates = Option.map (List.map EConstr.of_constr) candidates in
+ let (evd,_) = restrict_evar evd evk filter candidates in
evdref := evd;
Evd.existential_value0 !evdref ev
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index c17f3d168..0ad323ac4 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -63,10 +63,7 @@ val new_type_evar :
env -> evar_map -> rigid ->
evar_map * (constr * Sorts.t)
-val new_Type : ?rigid:rigid -> env -> evar_map -> evar_map * constr
-
-val restrict_evar : evar_map -> Evar.t -> Filter.t ->
- ?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * Evar.t
+val new_Type : ?rigid:rigid -> evar_map -> evar_map * constr
(** Polymorphic constants *)
@@ -131,7 +128,7 @@ val advance : evar_map -> Evar.t -> Evar.t option
[nf_evar]. *)
val undefined_evars_of_term : evar_map -> constr -> Evar.Set.t
-val undefined_evars_of_named_context : evar_map -> Context.Named.t -> Evar.Set.t
+val undefined_evars_of_named_context : evar_map -> Constr.named_context -> Evar.Set.t
val undefined_evars_of_evar_info : evar_map -> evar_info -> Evar.Set.t
type undefined_evars_cache
@@ -164,7 +161,7 @@ val jv_nf_evar :
val tj_nf_evar :
evar_map -> unsafe_type_judgment -> unsafe_type_judgment
-val nf_named_context_evar : evar_map -> Context.Named.t -> Context.Named.t
+val nf_named_context_evar : evar_map -> Constr.named_context -> Constr.named_context
val nf_rel_context_evar : evar_map -> rel_context -> rel_context
val nf_env_evar : evar_map -> env -> env
@@ -217,15 +214,32 @@ val compare_cumulative_instances : Reduction.conv_pb -> Univ.Variance.t array ->
val compare_constructor_instances : evar_map ->
Univ.Instance.t -> Univ.Instance.t -> evar_map
+(** {6 Unification problems} *)
+type unification_pb = conv_pb * env * constr * constr
+
+(** [add_unification_pb ?tail pb sigma]
+ Add a unification problem [pb] to [sigma], if not already present.
+ Put it at the end of the list if [tail] is true, by default it is false. *)
+val add_unification_pb : ?tail:bool -> unification_pb -> evar_map -> evar_map
+
(** {6 Removing hyps in evars'context}
raise OccurHypInSimpleClause if the removal breaks dependencies *)
type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of Constr.existential
+| NoCandidatesLeft of Evar.t
exception ClearDependencyError of Id.t * clear_dependency_error * GlobRef.t option
+(** Restrict an undefined evar according to a (sub)filter and candidates.
+ The evar will be defined if there is only one candidate left,
+@raise ClearDependencyError NoCandidatesLeft if the filter turns the candidates
+ into an empty list. *)
+
+val restrict_evar : evar_map -> Evar.t -> Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * Evar.t
+
val clear_hyps_in_evi : env -> evar_map -> named_context_val -> types ->
Id.Set.t -> evar_map * named_context_val * types
@@ -273,7 +287,7 @@ val e_new_type_evar : env -> evar_map ref ->
?principal:bool -> ?hypnaming:naming_mode -> rigid -> constr * Sorts.t
[@@ocaml.deprecated "Use [Evarutil.new_type_evar]"]
-val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
+val e_new_Type : ?rigid:rigid -> evar_map ref -> constr
[@@ocaml.deprecated "Use [Evarutil.new_Type]"]
val e_new_global : evar_map ref -> GlobRef.t -> constr
diff --git a/engine/evd.ml b/engine/evd.ml
index f56f9662d..d1c7fef73 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -171,6 +171,8 @@ let evar_context evi = named_context_of_val evi.evar_hyps
let evar_filtered_context evi =
Filter.filter_list (evar_filter evi) (evar_context evi)
+let evar_candidates evi = evi.evar_candidates
+
let evar_hyps evi = evi.evar_hyps
let evar_filtered_hyps evi = match Filter.repr (evar_filter evi) with
@@ -620,11 +622,13 @@ let merge_universe_context evd uctx' =
let set_universe_context evd uctx' =
{ evd with universes = uctx' }
+(* TODO: make unique *)
let add_conv_pb ?(tail=false) pb d =
- (** MS: we have duplicates here, why? *)
if tail then {d with conv_pbs = d.conv_pbs @ [pb]}
else {d with conv_pbs = pb::d.conv_pbs}
+let conv_pbs d = d.conv_pbs
+
let evar_source evk d = (find d evk).evar_source
let evar_ident evk evd = EvNames.ident evk evd.evar_names
@@ -801,8 +805,8 @@ let make_flexible_variable evd ~algebraic u =
(* Operations on constants *)
(****************************************)
-let fresh_sort_in_family ?loc ?(rigid=univ_flexible) env evd s =
- with_context_set ?loc rigid evd (UnivGen.fresh_sort_in_family env s)
+let fresh_sort_in_family ?loc ?(rigid=univ_flexible) evd s =
+ with_context_set ?loc rigid evd (UnivGen.fresh_sort_in_family s)
let fresh_constant_instance ?loc env evd c =
with_context_set ?loc univ_flexible evd (UnivGen.fresh_constant_instance env c)
@@ -816,8 +820,6 @@ let fresh_constructor_instance ?loc env evd c =
let fresh_global ?loc ?(rigid=univ_flexible) ?names env evd gr =
with_context_set ?loc rigid evd (UnivGen.fresh_global_instance ?names env gr)
-let whd_sort_variable evd t = t
-
let is_sort_variable evd s = UState.is_sort_variable evd.universes s
let is_flexible_level evd l =
@@ -851,7 +853,7 @@ let normalize_universe_instance evd l =
let normalize_sort evars s =
match s with
- | Prop _ -> s
+ | Prop | Set -> s
| Type u ->
let u' = normalize_universe evars u in
if u' == u then s else Type u'
diff --git a/engine/evd.mli b/engine/evd.mli
index 405fcc403..db2bd4eed 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -113,6 +113,7 @@ val evar_filtered_context : evar_info -> (econstr, etypes) Context.Named.pt
val evar_hyps : evar_info -> named_context_val
val evar_filtered_hyps : evar_info -> named_context_val
val evar_body : evar_info -> evar_body
+val evar_candidates : evar_info -> constr list option
val evar_filter : evar_info -> Filter.t
val evar_env : evar_info -> env
val evar_filtered_env : evar_info -> env
@@ -229,7 +230,7 @@ val existential_opt_value : evar_map -> econstr pexistential -> econstr option
val existential_opt_value0 : evar_map -> existential -> constr option
-val evar_instance_array : (Context.Named.Declaration.t -> 'a -> bool) -> evar_info ->
+val evar_instance_array : (Constr.named_declaration -> 'a -> bool) -> evar_info ->
'a array -> (Id.t * 'a) list
val instantiate_evar_array : evar_info -> econstr -> econstr array -> econstr
@@ -243,7 +244,8 @@ val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
val restrict : Evar.t-> Filter.t -> ?candidates:econstr list ->
?src:Evar_kinds.t located -> evar_map -> evar_map * Evar.t
(** Restrict an undefined evar into a new evar by filtering context and
- possibly limiting the instances to a set of candidates *)
+ possibly limiting the instances to a set of candidates (candidates
+ are filtered according to the filter) *)
val is_restricted_evar : evar_info -> Evar.t option
(** Tell if an evar comes from restriction of another evar, and if yes, which *)
@@ -338,8 +340,6 @@ val shelve_on_future_goals : Evar.t list -> future_goals -> future_goals
Evar maps also keep track of the universe constraints defined at a given
point. This section defines the relevant manipulation functions. *)
-val whd_sort_variable : evar_map -> econstr -> econstr
-
exception UniversesDiffer
val add_universe_constraints : evar_map -> UnivProblem.Set.t -> evar_map
@@ -439,7 +439,11 @@ type clbinding =
(** Unification constraints *)
type conv_pb = Reduction.conv_pb
type evar_constraint = conv_pb * env * econstr * econstr
+
+(** The following two functions are for internal use only,
+ see [Evarutil.add_unification_pb] for a safe interface. *)
val add_conv_pb : ?tail:bool -> evar_constraint -> evar_map -> evar_map
+val conv_pbs : evar_map -> evar_constraint list
val extract_changed_conv_pbs : evar_map ->
(Evar.Set.t -> evar_constraint -> bool) ->
@@ -592,7 +596,7 @@ val update_sigma_env : evar_map -> env -> evar_map
(** Polymorphic universes *)
-val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:rigid -> env -> evar_map -> Sorts.family -> evar_map * Sorts.t
+val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:rigid -> evar_map -> Sorts.family -> evar_map * Sorts.t
val fresh_constant_instance : ?loc:Loc.t -> env -> evar_map -> Constant.t -> evar_map * pconstant
val fresh_inductive_instance : ?loc:Loc.t -> env -> evar_map -> inductive -> evar_map * pinductive
val fresh_constructor_instance : ?loc:Loc.t -> env -> evar_map -> constructor -> evar_map * pconstructor
diff --git a/engine/namegen.ml b/engine/namegen.ml
index 23c691139..978f33b68 100644
--- a/engine/namegen.ml
+++ b/engine/namegen.ml
@@ -137,8 +137,9 @@ let lowercase_first_char id = (* First character of a constr *)
s ^ Unicode.lowercase_first_char s'
let sort_hdchar = function
- | Prop(_) -> "P"
- | Type(_) -> "T"
+ | Prop -> "P"
+ | Set -> "S"
+ | Type _ -> "T"
let hdchar env sigma c =
let rec hdrec k c =
diff --git a/engine/termops.ml b/engine/termops.ml
index 2db2e07bf..2b179c43b 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -25,8 +25,8 @@ module CompactedDecl = Context.Compacted.Declaration
(* Sorts and sort family *)
let print_sort = function
- | Prop Pos -> (str "Set")
- | Prop Null -> (str "Prop")
+ | Set -> (str "Set")
+ | Prop -> (str "Prop")
| Type u -> (str "Type(" ++ Univ.Universe.pr u ++ str ")")
let pr_sort_family = function
@@ -1162,15 +1162,14 @@ let is_template_polymorphic env sigma f =
let base_sort_cmp pb s0 s1 =
match (s0,s1) with
- | (Prop c1, Prop c2) -> c1 == Null || c2 == Pos (* Prop <= Set *)
- | (Prop c1, Type u) -> pb == Reduction.CUMUL
- | (Type u1, Type u2) -> true
- | _ -> false
+ | Prop, Prop | Set, Set | Type _, Type _ -> true
+ | Prop, Set | Prop, Type _ | Set, Type _ -> pb == Reduction.CUMUL
+ | Set, Prop | Type _, Prop | Type _, Set -> false
let rec is_Prop sigma c = match EConstr.kind sigma c with
| Sort u ->
begin match EConstr.ESorts.kind sigma u with
- | Prop Null -> true
+ | Prop -> true
| _ -> false
end
| Cast (c,_,_) -> is_Prop sigma c
@@ -1179,7 +1178,7 @@ let rec is_Prop sigma c = match EConstr.kind sigma c with
let rec is_Set sigma c = match EConstr.kind sigma c with
| Sort u ->
begin match EConstr.ESorts.kind sigma u with
- | Prop Pos -> true
+ | Set -> true
| _ -> false
end
| Cast (c,_,_) -> is_Set sigma c
diff --git a/engine/termops.mli b/engine/termops.mli
index f9aa6ba63..80988989f 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -43,14 +43,14 @@ val it_mkProd : types -> (Name.t * types) list -> types
val it_mkLambda : constr -> (Name.t * types) list -> constr
val it_mkProd_or_LetIn : types -> rel_context -> types
val it_mkProd_wo_LetIn : types -> rel_context -> types
-val it_mkLambda_or_LetIn : Constr.constr -> Context.Rel.t -> Constr.constr
+val it_mkLambda_or_LetIn : Constr.constr -> Constr.rel_context -> Constr.constr
val it_mkNamedProd_or_LetIn : types -> named_context -> types
-val it_mkNamedProd_wo_LetIn : Constr.types -> Context.Named.t -> Constr.types
+val it_mkNamedProd_wo_LetIn : Constr.types -> Constr.named_context -> Constr.types
val it_mkNamedLambda_or_LetIn : constr -> named_context -> constr
(* Ad hoc version reinserting letin, assuming the body is defined in
the context where the letins are expanded *)
-val it_mkLambda_or_LetIn_from_no_LetIn : Constr.constr -> Context.Rel.t -> Constr.constr
+val it_mkLambda_or_LetIn_from_no_LetIn : Constr.constr -> Constr.rel_context -> Constr.constr
(** {6 Generic iterators on constr} *)
@@ -225,7 +225,7 @@ val names_of_rel_context : env -> names_context
(* [context_chop n Γ] returns (Γ₁,Γ₂) such that [Γ]=[Γ₂Γ₁], [Γ₁] has
[n] hypotheses, excluding local definitions, and [Γ₁], if not empty,
starts with an hypothesis (i.e. [Γ₁] has the form empty or [x:A;Γ₁'] *)
-val context_chop : int -> Context.Rel.t -> Context.Rel.t * Context.Rel.t
+val context_chop : int -> Constr.rel_context -> Constr.rel_context * Constr.rel_context
(* [env_rel_context_chop n env] extracts out the [n] top declarations
of the rel_context part of [env], counting both local definitions and
@@ -239,19 +239,19 @@ val add_vname : Id.Set.t -> Name.t -> Id.Set.t
(** other signature iterators *)
val process_rel_context : (rel_declaration -> env -> env) -> env -> env
val assums_of_rel_context : ('c, 't) Context.Rel.pt -> (Name.t * 't) list
-val lift_rel_context : int -> Context.Rel.t -> Context.Rel.t
-val substl_rel_context : Constr.constr list -> Context.Rel.t -> Context.Rel.t
-val smash_rel_context : Context.Rel.t -> Context.Rel.t (** expand lets in context *)
+val lift_rel_context : int -> Constr.rel_context -> Constr.rel_context
+val substl_rel_context : Constr.constr list -> Constr.rel_context -> Constr.rel_context
+val smash_rel_context : Constr.rel_context -> Constr.rel_context (** expand lets in context *)
val map_rel_context_in_env :
- (env -> Constr.constr -> Constr.constr) -> env -> Context.Rel.t -> Context.Rel.t
+ (env -> Constr.constr -> Constr.constr) -> env -> Constr.rel_context -> Constr.rel_context
val map_rel_context_with_binders :
(int -> 'c -> 'c) -> ('c, 'c) Context.Rel.pt -> ('c, 'c) Context.Rel.pt
val fold_named_context_both_sides :
- ('a -> Context.Named.Declaration.t -> Context.Named.Declaration.t list -> 'a) ->
- Context.Named.t -> init:'a -> 'a
+ ('a -> Constr.named_declaration -> Constr.named_declaration list -> 'a) ->
+ Constr.named_context -> init:'a -> 'a
val mem_named_context_val : Id.t -> named_context_val -> bool
-val compact_named_context : Context.Named.t -> Context.Compacted.t
+val compact_named_context : Constr.named_context -> Constr.compacted_context
val map_rel_decl : ('a -> 'b) -> ('a, 'a) Context.Rel.Declaration.pt -> ('b, 'b) Context.Rel.Declaration.pt
val map_named_decl : ('a -> 'b) -> ('a, 'a) Context.Named.Declaration.pt -> ('b, 'b) Context.Named.Declaration.pt
@@ -313,6 +313,6 @@ val set_print_constr : (env -> Evd.evar_map -> constr -> Pp.t) -> unit
val print_constr : constr -> Pp.t
val print_constr_env : env -> Evd.evar_map -> constr -> Pp.t
val print_named_context : env -> Pp.t
-val pr_rel_decl : env -> Context.Rel.Declaration.t -> Pp.t
+val pr_rel_decl : env -> Constr.rel_declaration -> Pp.t
val print_rel_context : env -> Pp.t
val print_env : env -> Pp.t
diff --git a/engine/uState.ml b/engine/uState.ml
index 81ab3dd66..0791e4c27 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -583,7 +583,7 @@ let refresh_constraints univs (ctx, cstrs) =
in ((ctx, cstrs'), univs')
let normalize_variables uctx =
- let normalized_variables, undef, def, subst =
+ let normalized_variables, def, subst =
UnivSubst.normalize_univ_variables uctx.uctx_univ_variables
in
let ctx_local = subst_univs_context_with_def def (Univ.make_subst subst) uctx.uctx_local in
diff --git a/engine/univGen.ml b/engine/univGen.ml
index 796a1bcc1..b07d4848f 100644
--- a/engine/univGen.ml
+++ b/engine/univGen.ml
@@ -215,7 +215,7 @@ let type_of_reference env r =
let type_of_global t = type_of_reference (Global.env ()) t
-let fresh_sort_in_family env = function
+let fresh_sort_in_family = function
| InProp -> Sorts.prop, ContextSet.empty
| InSet -> Sorts.set, ContextSet.empty
| InType ->
@@ -223,7 +223,7 @@ let fresh_sort_in_family env = function
Type (Univ.Universe.make u), ContextSet.singleton u
let new_sort_in_family sf =
- fst (fresh_sort_in_family (Global.env ()) sf)
+ fst (fresh_sort_in_family sf)
let extend_context (a, ctx) (ctx') =
(a, ContextSet.union ctx ctx')
diff --git a/engine/univGen.mli b/engine/univGen.mli
index 8169dbda4..439424934 100644
--- a/engine/univGen.mli
+++ b/engine/univGen.mli
@@ -39,7 +39,7 @@ val fresh_instance_from_context : AUContext.t ->
val fresh_instance_from : AUContext.t -> Instance.t option ->
Instance.t in_universe_context_set
-val fresh_sort_in_family : env -> Sorts.family ->
+val fresh_sort_in_family : Sorts.family ->
Sorts.t in_universe_context_set
val fresh_constant_instance : env -> Constant.t ->
pconstant in_universe_context_set
diff --git a/engine/univSubst.ml b/engine/univSubst.ml
index 6a433d9fb..2f59a3fa8 100644
--- a/engine/univSubst.ml
+++ b/engine/univSubst.ml
@@ -162,13 +162,13 @@ let subst_opt_univs_constr s =
let normalize_univ_variables ctx =
let ctx = normalize_opt_subst ctx in
- let undef, def, subst =
- Univ.LMap.fold (fun u v (undef, def, subst) ->
+ let def, subst =
+ Univ.LMap.fold (fun u v (def, subst) ->
match v with
- | None -> (Univ.LSet.add u undef, def, subst)
- | Some b -> (undef, Univ.LSet.add u def, Univ.LMap.add u b subst))
- ctx (Univ.LSet.empty, Univ.LSet.empty, Univ.LMap.empty)
- in ctx, undef, def, subst
+ | None -> (def, subst)
+ | Some b -> (Univ.LSet.add u def, Univ.LMap.add u b subst))
+ ctx (Univ.LSet.empty, Univ.LMap.empty)
+ in ctx, def, subst
let pr_universe_body = function
| None -> mt ()
diff --git a/engine/univSubst.mli b/engine/univSubst.mli
index 26e8d1db9..e76d25333 100644
--- a/engine/univSubst.mli
+++ b/engine/univSubst.mli
@@ -23,7 +23,7 @@ val make_opt_subst : universe_opt_subst -> universe_subst_fn
val subst_opt_univs_constr : universe_opt_subst -> constr -> constr
val normalize_univ_variables : universe_opt_subst ->
- universe_opt_subst * LSet.t * LSet.t * universe_subst
+ universe_opt_subst * LSet.t * universe_subst
val normalize_univ_variable :
find:(Level.t -> Universe.t) ->
diff --git a/engine/universes.mli b/engine/universes.mli
index 29673de1e..ad937471e 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -86,7 +86,7 @@ val fresh_instance_from : AUContext.t -> Instance.t option ->
Instance.t in_universe_context_set
[@@ocaml.deprecated "Use [UnivGen.fresh_instance_from]"]
-val fresh_sort_in_family : env -> Sorts.family ->
+val fresh_sort_in_family : Sorts.family ->
Sorts.t in_universe_context_set
[@@ocaml.deprecated "Use [UnivGen.fresh_sort_in_family]"]
@@ -154,7 +154,7 @@ val subst_opt_univs_constr : universe_opt_subst -> constr -> constr
[@@ocaml.deprecated "Use [UnivSubst.subst_opt_univs_constr]"]
val normalize_univ_variables : universe_opt_subst ->
- universe_opt_subst * LSet.t * LSet.t * universe_subst
+ universe_opt_subst * LSet.t * universe_subst
[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variables]"]
val normalize_univ_variable :
diff --git a/engine/univops.ml b/engine/univops.ml
index 3fd518490..7f9672f82 100644
--- a/engine/univops.ml
+++ b/engine/univops.ml
@@ -11,24 +11,13 @@
open Univ
open Constr
-let universes_of_constr env c =
- let open Declarations in
- let rec aux s c =
+let universes_of_constr c =
+ let rec aux s c =
match kind c with
| Const (c, u) ->
- begin match (Environ.lookup_constant c env).const_universes with
- | Polymorphic_const _ ->
LSet.fold LSet.add (Instance.levels u) s
- | Monomorphic_const (univs, _) ->
- LSet.union s univs
- end
| Ind ((mind,_), u) | Construct (((mind,_),_), u) ->
- begin match (Environ.lookup_mind mind env).mind_universes with
- | Cumulative_ind _ | Polymorphic_ind _ ->
LSet.fold LSet.add (Instance.levels u) s
- | Monomorphic_ind (univs,_) ->
- LSet.union s univs
- end
| Sort u when not (Sorts.is_small u) ->
let u = Sorts.univ_of_sort u in
LSet.fold LSet.add (Universe.levels u) s
diff --git a/engine/univops.mli b/engine/univops.mli
index 0b37ab975..57a53597b 100644
--- a/engine/univops.mli
+++ b/engine/univops.mli
@@ -11,8 +11,8 @@
open Constr
open Univ
-(** The universes of monomorphic constants appear. *)
-val universes_of_constr : Environ.env -> constr -> LSet.t
+(** Return the set of all universes appearing in [constr]. *)
+val universes_of_constr : constr -> LSet.t
(** [restrict_universe_context (univs,csts) keep] restricts [univs] to
the universes in [keep]. The constraints [csts] are adjusted so
diff --git a/grammar/coqpp_ast.mli b/grammar/coqpp_ast.mli
new file mode 100644
index 000000000..39b4d2ab3
--- /dev/null
+++ b/grammar/coqpp_ast.mli
@@ -0,0 +1,95 @@
+(************************************************************************)
+(* 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 *)
+(************************************************************************)
+
+type loc = {
+ loc_start : Lexing.position;
+ loc_end : Lexing.position;
+}
+
+type code = { code : string }
+
+type user_symbol =
+| Ulist1 of user_symbol
+| Ulist1sep of user_symbol * string
+| Ulist0 of user_symbol
+| Ulist0sep of user_symbol * string
+| Uopt of user_symbol
+| Uentry of string
+| Uentryl of string * int
+
+type token_data =
+| TokNone
+| TokName of string
+
+type ext_token =
+| ExtTerminal of string
+| ExtNonTerminal of user_symbol * token_data
+
+type tactic_rule = {
+ tac_toks : ext_token list;
+ tac_body : code;
+}
+
+type level = string
+
+type position =
+| First
+| Last
+| Before of level
+| After of level
+| Level of level
+
+type assoc =
+| LeftA
+| RightA
+| NonA
+
+type gram_symbol =
+| GSymbString of string
+| GSymbQualid of string * level option
+| GSymbParen of gram_symbol list
+| GSymbProd of gram_prod list
+
+and gram_prod = {
+ gprod_symbs : (string option * gram_symbol list) list;
+ gprod_body : code;
+}
+
+type gram_rule = {
+ grule_label : string option;
+ grule_assoc : assoc option;
+ grule_prods : gram_prod list;
+}
+
+type grammar_entry = {
+ gentry_name : string;
+ gentry_pos : position option;
+ gentry_rules : gram_rule list;
+}
+
+type grammar_ext = {
+ gramext_name : string;
+ gramext_globals : string list;
+ gramext_entries : grammar_entry list;
+}
+
+type tactic_ext = {
+ tacext_name : string;
+ tacext_level : int option;
+ tacext_rules : tactic_rule list;
+}
+
+type node =
+| Code of code
+| Comment of string
+| DeclarePlugin of string
+| GramExt of grammar_ext
+| VernacExt
+| TacticExt of tactic_ext
+
+type t = node list
diff --git a/grammar/coqpp_lex.mll b/grammar/coqpp_lex.mll
new file mode 100644
index 000000000..6c6562c20
--- /dev/null
+++ b/grammar/coqpp_lex.mll
@@ -0,0 +1,167 @@
+(************************************************************************)
+(* 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 Lexing
+open Coqpp_parse
+
+type mode =
+| OCaml
+| Extend
+
+exception Lex_error of Coqpp_ast.loc * string
+
+let loc lexbuf = {
+ Coqpp_ast.loc_start = lexeme_start_p lexbuf;
+ Coqpp_ast.loc_end = lexeme_end_p lexbuf;
+}
+
+let newline lexbuf =
+ let pos = lexbuf.lex_curr_p in
+ let pos = { pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum } in
+ lexbuf.lex_curr_p <- pos
+
+let num_comments = ref 0
+let num_braces = ref 0
+
+let mode () = if !num_braces = 0 then Extend else OCaml
+
+let comment_buf = Buffer.create 512
+let ocaml_buf = Buffer.create 512
+let string_buf = Buffer.create 512
+
+let lex_error lexbuf msg =
+ raise (Lex_error (loc lexbuf, msg))
+
+let lex_unexpected_eof lexbuf where =
+ lex_error lexbuf (Printf.sprintf "Unexpected end of file in %s" where)
+
+let start_comment _ =
+ let () = incr num_comments in
+ Buffer.add_string comment_buf "(*"
+
+let end_comment lexbuf =
+ let () = decr num_comments in
+ let () = Buffer.add_string comment_buf "*)" in
+ if !num_comments < 0 then lex_error lexbuf "Unexpected end of comment"
+ else if !num_comments = 0 then
+ let s = Buffer.contents comment_buf in
+ let () = Buffer.reset comment_buf in
+ Some (COMMENT s)
+ else
+ None
+
+let start_ocaml _ =
+ let () = match mode () with
+ | OCaml -> Buffer.add_string ocaml_buf "{"
+ | Extend -> ()
+ in
+ incr num_braces
+
+let end_ocaml lexbuf =
+ let () = decr num_braces in
+ if !num_braces < 0 then lex_error lexbuf "Unexpected end of OCaml code"
+ else if !num_braces = 0 then
+ let s = Buffer.contents ocaml_buf in
+ let () = Buffer.reset ocaml_buf in
+ Some (CODE { Coqpp_ast.code = s })
+ else
+ let () = Buffer.add_string ocaml_buf "}" in
+ None
+
+}
+
+let letter = ['a'-'z' 'A'-'Z']
+let letterlike = ['_' 'a'-'z' 'A'-'Z']
+let alphanum = ['_' 'a'-'z' 'A'-'Z' '0'-'9' '\'']
+let ident = letterlike alphanum*
+let qualid = ident ('.' ident)*
+let space = [' ' '\t' '\r']
+let number = [ '0'-'9' ]
+
+rule extend = parse
+| "(*" { start_comment (); comment lexbuf }
+| "{" { start_ocaml (); ocaml lexbuf }
+| "GRAMMAR" { GRAMMAR }
+| "VERNAC" { VERNAC }
+| "TACTIC" { TACTIC }
+| "EXTEND" { EXTEND }
+| "END" { END }
+| "DECLARE" { DECLARE }
+| "PLUGIN" { PLUGIN }
+(** Camlp5 specific keywords *)
+| "GLOBAL" { GLOBAL }
+| "FIRST" { FIRST }
+| "LAST" { LAST }
+| "BEFORE" { BEFORE }
+| "AFTER" { AFTER }
+| "LEVEL" { LEVEL }
+| "LEFTA" { LEFTA }
+| "RIGHTA" { RIGHTA }
+| "NONA" { NONA }
+(** Standard *)
+| ident { IDENT (Lexing.lexeme lexbuf) }
+| qualid { QUALID (Lexing.lexeme lexbuf) }
+| number { INT (int_of_string (Lexing.lexeme lexbuf)) }
+| space { extend lexbuf }
+| '\"' { string lexbuf }
+| '\n' { newline lexbuf; extend lexbuf }
+| '[' { LBRACKET }
+| ']' { RBRACKET }
+| '|' { PIPE }
+| "->" { ARROW }
+| ',' { COMMA }
+| ':' { COLON }
+| ';' { SEMICOLON }
+| '(' { LPAREN }
+| ')' { RPAREN }
+| '=' { EQUAL }
+| _ { lex_error lexbuf "syntax error" }
+| eof { EOF }
+
+and ocaml = parse
+| "{" { start_ocaml (); ocaml lexbuf }
+| "}" { match end_ocaml lexbuf with Some tk -> tk | None -> ocaml lexbuf }
+| '\n' { newline lexbuf; Buffer.add_char ocaml_buf '\n'; ocaml lexbuf }
+| '\"' { Buffer.add_char ocaml_buf '\"'; ocaml_string lexbuf }
+| (_ as c) { Buffer.add_char ocaml_buf c; ocaml lexbuf }
+| eof { lex_unexpected_eof lexbuf "OCaml code" }
+
+and comment = parse
+| "*)" { match end_comment lexbuf with Some _ -> extend lexbuf | None -> comment lexbuf }
+| "(*" { start_comment lexbuf; comment lexbuf }
+| '\n' { newline lexbuf; Buffer.add_char comment_buf '\n'; comment lexbuf }
+| (_ as c) { Buffer.add_char comment_buf c; comment lexbuf }
+| eof { lex_unexpected_eof lexbuf "comment" }
+
+and string = parse
+| '\"'
+ {
+ let s = Buffer.contents string_buf in
+ let () = Buffer.reset string_buf in
+ STRING s
+ }
+| "\\\"" { Buffer.add_char string_buf '\"'; string lexbuf }
+| '\n' { newline lexbuf; Buffer.add_char string_buf '\n'; string lexbuf }
+| (_ as c) { Buffer.add_char string_buf c; string lexbuf }
+| eof { lex_unexpected_eof lexbuf "string" }
+
+and ocaml_string = parse
+| "\\\"" { Buffer.add_string ocaml_buf "\\\""; ocaml_string lexbuf }
+| '\"' { Buffer.add_char ocaml_buf '\"'; ocaml lexbuf }
+| (_ as c) { Buffer.add_char ocaml_buf c; ocaml_string lexbuf }
+| eof { lex_unexpected_eof lexbuf "OCaml string" }
+
+{
+
+let token lexbuf = match mode () with
+| OCaml -> ocaml lexbuf
+| Extend -> extend lexbuf
+
+}
diff --git a/grammar/coqpp_main.ml b/grammar/coqpp_main.ml
new file mode 100644
index 000000000..e76a1e9ed
--- /dev/null
+++ b/grammar/coqpp_main.ml
@@ -0,0 +1,349 @@
+(************************************************************************)
+(* 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 Lexing
+open Coqpp_ast
+open Format
+
+let fatal msg =
+ let () = Format.eprintf "Error: %s@\n%!" msg in
+ exit 1
+
+let pr_loc loc =
+ let file = loc.loc_start.pos_fname in
+ let line = loc.loc_start.pos_lnum in
+ let bpos = loc.loc_start.pos_cnum - loc.loc_start.pos_bol in
+ let epos = loc.loc_end.pos_cnum - loc.loc_start.pos_bol in
+ Printf.sprintf "File \"%s\", line %d, characters %d-%d:" file line bpos epos
+
+let parse_file f =
+ let chan = open_in f in
+ let lexbuf = Lexing.from_channel chan in
+ let () = lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = f } in
+ let ans =
+ try Coqpp_parse.file Coqpp_lex.token lexbuf
+ with
+ | Coqpp_lex.Lex_error (loc, msg) ->
+ let () = close_in chan in
+ let () = Printf.eprintf "%s\n%!" (pr_loc loc) in
+ fatal msg
+ | Parsing.Parse_error ->
+ let () = close_in chan in
+ let loc = Coqpp_lex.loc lexbuf in
+ let () = Printf.eprintf "%s\n%!" (pr_loc loc) in
+ fatal "syntax error"
+ in
+ let () = close_in chan in
+ ans
+
+module StringSet = Set.Make(String)
+
+let string_split s =
+ let len = String.length s in
+ let rec split n =
+ try
+ let pos = String.index_from s n '.' in
+ let dir = String.sub s n (pos-n) in
+ dir :: split (succ pos)
+ with
+ | Not_found -> [String.sub s n (len-n)]
+ in
+ if len == 0 then [] else split 0
+
+let plugin_name = "__coq_plugin_name"
+
+module GramExt :
+sig
+
+val print_ast : Format.formatter -> grammar_ext -> unit
+
+end =
+struct
+
+let is_uident s = match s.[0] with
+| 'A'..'Z' -> true
+| _ -> false
+
+let is_qualified = is_uident
+
+let get_local_entries ext =
+ let global = StringSet.of_list ext.gramext_globals in
+ let map e = e.gentry_name in
+ let entries = List.map map ext.gramext_entries in
+ let local = List.filter (fun e -> not (is_qualified e || StringSet.mem e global)) entries in
+ let rec uniquize seen = function
+ | [] -> []
+ | id :: rem ->
+ let rem = uniquize (StringSet.add id seen) rem in
+ if StringSet.mem id seen then rem else id :: rem
+ in
+ uniquize StringSet.empty local
+
+let print_local fmt ext =
+ let locals = get_local_entries ext in
+ match locals with
+ | [] -> ()
+ | e :: locals ->
+ let mk_e fmt e = fprintf fmt "%s.Entry.create \"%s\"" ext.gramext_name e in
+ let () = fprintf fmt "@[<hv 2>let %s =@ @[%a@]@]@ " e mk_e e in
+ let iter e = fprintf fmt "@[<hv 2>and %s =@ @[%a@]@]@ " e mk_e e in
+ let () = List.iter iter locals in
+ fprintf fmt "in@ "
+
+let print_string fmt s = fprintf fmt "\"%s\"" s
+
+let print_list fmt pr l =
+ let rec prl fmt = function
+ | [] -> ()
+ | [x] -> fprintf fmt "%a" pr x
+ | x :: l -> fprintf fmt "%a;@ %a" pr x prl l
+ in
+ fprintf fmt "@[<hv>[%a]@]" prl l
+
+let print_opt fmt pr = function
+| None -> fprintf fmt "None"
+| Some x -> fprintf fmt "Some@ (%a)" pr x
+
+let print_position fmt pos = match pos with
+| First -> fprintf fmt "Extend.First"
+| Last -> fprintf fmt "Extend.Last"
+| Before s -> fprintf fmt "Extend.Before@ \"%s\"" s
+| After s -> fprintf fmt "Extend.After@ \"%s\"" s
+| Level s -> fprintf fmt "Extend.Level@ \"%s\"" s
+
+let print_assoc fmt = function
+| LeftA -> fprintf fmt "Extend.LeftA"
+| RightA -> fprintf fmt "Extend.RightA"
+| NonA -> fprintf fmt "Extend.NonA"
+
+type symb =
+| SymbToken of string * string option
+| SymbEntry of string * string option
+| SymbSelf
+| SymbNext
+| SymbList0 of symb * symb option
+| SymbList1 of symb * symb option
+| SymbOpt of symb
+| SymbRules of ((string option * symb) list * code) list
+
+let is_token s = match string_split s with
+| [s] -> is_uident s
+| _ -> false
+
+let rec parse_tokens = function
+| [GSymbString s] -> SymbToken ("", Some s)
+| [GSymbQualid ("SELF", None)] -> SymbSelf
+| [GSymbQualid ("NEXT", None)] -> SymbNext
+| [GSymbQualid ("LIST0", None); tkn] ->
+ SymbList0 (parse_token tkn, None)
+| [GSymbQualid ("LIST1", None); tkn] ->
+ SymbList1 (parse_token tkn, None)
+| [GSymbQualid ("LIST0", None); tkn; GSymbQualid ("SEP", None); tkn'] ->
+ SymbList0 (parse_token tkn, Some (parse_token tkn'))
+| [GSymbQualid ("LIST1", None); tkn; GSymbQualid ("SEP", None); tkn'] ->
+ SymbList1 (parse_token tkn, Some (parse_token tkn'))
+| [GSymbQualid ("OPT", None); tkn] ->
+ SymbOpt (parse_token tkn)
+| [GSymbQualid (e, None)] when is_token e -> SymbToken (e, None)
+| [GSymbQualid (e, None); GSymbString s] when is_token e -> SymbToken (e, Some s)
+| [GSymbQualid (e, lvl)] when not (is_token e) -> SymbEntry (e, lvl)
+| [GSymbParen tkns] -> parse_tokens tkns
+| [GSymbProd prds] ->
+ let map p =
+ let map (pat, tkns) = (pat, parse_tokens tkns) in
+ (List.map map p.gprod_symbs, p.gprod_body)
+ in
+ SymbRules (List.map map prds)
+| t ->
+ let rec db_token = function
+ | GSymbString s -> Printf.sprintf "\"%s\"" s
+ | GSymbQualid (s, _) -> Printf.sprintf "%s" s
+ | GSymbParen s -> Printf.sprintf "(%s)" (db_tokens s)
+ | GSymbProd _ -> Printf.sprintf "[...]"
+ and db_tokens tkns =
+ let s = List.map db_token tkns in
+ String.concat " " s
+ in
+ fatal (Printf.sprintf "Invalid token: %s" (db_tokens t))
+
+and parse_token tkn = parse_tokens [tkn]
+
+let print_fun fmt (vars, body) =
+ let vars = List.rev vars in
+ let iter = function
+ | None -> fprintf fmt "_@ "
+ | Some id -> fprintf fmt "%s@ " id
+ in
+ let () = fprintf fmt "fun@ " in
+ let () = List.iter iter vars in
+ (** FIXME: use Coq locations in the macros *)
+ let () = fprintf fmt "loc ->@ @[%s@]" body.code in
+ ()
+
+(** Meta-program instead of calling Tok.of_pattern here because otherwise
+ violates value restriction *)
+let print_tok fmt = function
+| "", s -> fprintf fmt "Tok.KEYWORD %a" print_string s
+| "IDENT", s -> fprintf fmt "Tok.IDENT %a" print_string s
+| "PATTERNIDENT", s -> fprintf fmt "Tok.PATTERNIDENT %a" print_string s
+| "FIELD", s -> fprintf fmt "Tok.FIELD %a" print_string s
+| "INT", s -> fprintf fmt "Tok.INT %a" print_string s
+| "STRING", s -> fprintf fmt "Tok.STRING %a" print_string s
+| "LEFTQMARK", _ -> fprintf fmt "Tok.LEFTQMARK"
+| "BULLET", s -> fprintf fmt "Tok.BULLET %a" print_string s
+| "EOI", _ -> fprintf fmt "Tok.EOI"
+| _ -> failwith "Tok.of_pattern: not a constructor"
+
+let rec print_prod fmt p =
+ let (vars, tkns) = List.split p.gprod_symbs in
+ let f = (vars, p.gprod_body) in
+ let tkn = List.rev_map parse_tokens tkns in
+ fprintf fmt "@[Extend.Rule@ (@[%a@],@ @[(%a)@])@]" print_symbols tkn print_fun f
+
+and print_symbols fmt = function
+| [] -> fprintf fmt "Extend.Stop"
+| tkn :: tkns ->
+ fprintf fmt "Extend.Next @[(%a,@ %a)@]" print_symbols tkns print_symbol tkn
+
+and print_symbol fmt tkn = match tkn with
+| SymbToken (t, s) ->
+ let s = match s with None -> "" | Some s -> s in
+ fprintf fmt "(Extend.Atoken (%a))" print_tok (t, s)
+| SymbEntry (e, None) ->
+ fprintf fmt "(Extend.Aentry %s)" e
+| SymbEntry (e, Some l) ->
+ fprintf fmt "(Extend.Aentryl (%s, %a))" e print_string l
+| SymbSelf ->
+ fprintf fmt "Extend.Aself"
+| SymbNext ->
+ fprintf fmt "Extend.Anext"
+| SymbList0 (s, None) ->
+ fprintf fmt "(Extend.Alist0 %a)" print_symbol s
+| SymbList0 (s, Some sep) ->
+ fprintf fmt "(Extend.Alist0sep (%a, %a))" print_symbol s print_symbol sep
+| SymbList1 (s, None) ->
+ fprintf fmt "(Extend.Alist1 %a)" print_symbol s
+| SymbList1 (s, Some sep) ->
+ fprintf fmt "(Extend.Alist1sep (%a, %a))" print_symbol s print_symbol sep
+| SymbOpt s ->
+ fprintf fmt "(Extend.Aopt %a)" print_symbol s
+| SymbRules rules ->
+ let pr fmt (r, body) =
+ let (vars, tkn) = List.split r in
+ let tkn = List.rev tkn in
+ fprintf fmt "Extend.Rules @[({ Extend.norec_rule = %a },@ (%a))@]" print_symbols tkn print_fun (vars, body)
+ in
+ let pr fmt rules = print_list fmt pr rules in
+ fprintf fmt "(Extend.Arules %a)" pr (List.rev rules)
+
+let print_rule fmt r =
+ let pr_lvl fmt lvl = print_opt fmt print_string lvl in
+ let pr_asc fmt asc = print_opt fmt print_assoc asc in
+ let pr_prd fmt prd = print_list fmt print_prod prd in
+ fprintf fmt "@[(%a,@ %a,@ %a)@]" pr_lvl r.grule_label pr_asc r.grule_assoc pr_prd (List.rev r.grule_prods)
+
+let print_entry fmt gram e =
+ let print_position_opt fmt pos = print_opt fmt print_position pos in
+ let print_rules fmt rules = print_list fmt print_rule rules in
+ fprintf fmt "let () =@ @[%s.gram_extend@ %s@ @[(%a, %a)@]@]@ in@ "
+ gram e.gentry_name print_position_opt e.gentry_pos print_rules e.gentry_rules
+
+let print_ast fmt ext =
+ let () = fprintf fmt "let _ = @[" in
+ let () = fprintf fmt "@[<v>%a@]" print_local ext in
+ let () = List.iter (fun e -> print_entry fmt ext.gramext_name e) ext.gramext_entries in
+ let () = fprintf fmt "()@]@\n" in
+ ()
+
+end
+
+module TacticExt :
+sig
+
+val print_ast : Format.formatter -> tactic_ext -> unit
+
+end =
+struct
+
+let rec print_symbol fmt = function
+| Ulist1 s ->
+ fprintf fmt "@[Extend.TUlist1 (%a)@]" print_symbol s
+| Ulist1sep (s, sep) ->
+ fprintf fmt "@[Extend.TUlist1sep (%a, \"%s\")@]" print_symbol s sep
+| Ulist0 s ->
+ fprintf fmt "@[Extend.TUlist0 (%a)@]" print_symbol s
+| Ulist0sep (s, sep) ->
+ fprintf fmt "@[Extend.TUlist0sep (%a, \"%s\")@]" print_symbol s sep
+| Uopt s ->
+ fprintf fmt "@[Extend.TUopt (%a)@]" print_symbol s
+| Uentry e ->
+ fprintf fmt "@[Extend.TUentry (Genarg.get_arg_tag wit_%s)@]" e
+| Uentryl (e, l) ->
+ assert (e = "tactic");
+ fprintf fmt "@[Extend.TUentryl (Genarg.get_arg_tag wit_%s, %i)@]" e l
+
+let rec print_clause fmt = function
+| [] -> fprintf fmt "@[TyNil@]"
+| ExtTerminal s :: cl -> fprintf fmt "@[TyIdent (\"%s\", %a)@]" s print_clause cl
+| ExtNonTerminal (g, TokNone) :: cl ->
+ fprintf fmt "@[TyAnonArg (%a, %a)@]"
+ print_symbol g print_clause cl
+| ExtNonTerminal (g, TokName id) :: cl ->
+ fprintf fmt "@[TyArg (%a, \"%s\", %a)@]"
+ print_symbol g id print_clause cl
+
+let rec print_binders fmt = function
+| [] -> fprintf fmt "ist@ "
+| (ExtTerminal _ | ExtNonTerminal (_, TokNone)) :: rem -> print_binders fmt rem
+| (ExtNonTerminal (_, TokName id)) :: rem ->
+ fprintf fmt "%s@ %a" id print_binders rem
+
+let print_rule fmt r =
+ fprintf fmt "@[TyML (%a, @[fun %a -> %s@])@]"
+ print_clause r.tac_toks print_binders r.tac_toks r.tac_body.code
+
+let rec print_rules fmt = function
+| [] -> ()
+| [r] -> fprintf fmt "(%a)@\n" print_rule r
+| r :: rem -> fprintf fmt "(%a);@\n%a" print_rule r print_rules rem
+
+let print_rules fmt rules =
+ fprintf fmt "Tacentries.([@[<v>%a@]])" print_rules rules
+
+let print_ast fmt ext =
+ let pr fmt () =
+ let level = match ext.tacext_level with None -> 0 | Some i -> i in
+ fprintf fmt "Tacentries.tactic_extend %s \"%s\" ~level:%i %a"
+ plugin_name ext.tacext_name level print_rules ext.tacext_rules
+ in
+ let () = fprintf fmt "let () = @[%a@]\n" pr () in
+ ()
+
+end
+
+let pr_ast fmt = function
+| Code s -> fprintf fmt "%s@\n" s.code
+| Comment s -> fprintf fmt "%s@\n" s
+| DeclarePlugin name -> fprintf fmt "let %s = \"%s\"@\n" plugin_name name
+| GramExt gram -> fprintf fmt "%a@\n" GramExt.print_ast gram
+| VernacExt -> fprintf fmt "VERNACEXT@\n"
+| TacticExt tac -> fprintf fmt "%a@\n" TacticExt.print_ast tac
+
+let () =
+ let () =
+ if Array.length Sys.argv <> 2 then fatal "Expected exactly one command line argument"
+ in
+ let file = Sys.argv.(1) in
+ let output = Filename.chop_extension file ^ ".ml" in
+ let ast = parse_file file in
+ let chan = open_out output in
+ let fmt = formatter_of_out_channel chan in
+ let iter ast = Format.fprintf fmt "@[%a@]%!"pr_ast ast in
+ let () = List.iter iter ast in
+ let () = close_out chan in
+ exit 0
diff --git a/grammar/coqpp_parse.mly b/grammar/coqpp_parse.mly
new file mode 100644
index 000000000..baafd633c
--- /dev/null
+++ b/grammar/coqpp_parse.mly
@@ -0,0 +1,256 @@
+/************************************************************************/
+/* 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 Coqpp_ast
+
+let starts s pat =
+ let len = String.length s in
+ let patlen = String.length pat in
+ if patlen <= len && String.sub s 0 patlen = pat then
+ Some (String.sub s patlen (len - patlen))
+ else None
+
+let ends s pat =
+ let len = String.length s in
+ let patlen = String.length pat in
+ if patlen <= len && String.sub s (len - patlen) patlen = pat then
+ Some (String.sub s 0 (len - patlen))
+ else None
+
+let between s pat1 pat2 = match starts s pat1 with
+| None -> None
+| Some s -> ends s pat2
+
+let without_sep k sep r =
+ if sep <> "" then raise Parsing.Parse_error else k r
+
+let parse_user_entry s sep =
+ let table = [
+ "ne_", "_list", without_sep (fun r -> Ulist1 r);
+ "ne_", "_list_sep", (fun sep r -> Ulist1sep (r, sep));
+ "", "_list", without_sep (fun r -> Ulist0 r);
+ "", "_list_sep", (fun sep r -> Ulist0sep (r, sep));
+ "", "_opt", without_sep (fun r -> Uopt r);
+ ] in
+ let rec parse s sep = function
+ | [] ->
+ let () = without_sep ignore sep () in
+ begin match starts s "tactic" with
+ | Some ("0"|"1"|"2"|"3"|"4"|"5") -> Uentryl ("tactic", int_of_string s)
+ | Some _ | None -> Uentry s
+ end
+ | (pat1, pat2, k) :: rem ->
+ match between s pat1 pat2 with
+ | None -> parse s sep rem
+ | Some s ->
+ let r = parse s "" table in
+ k sep r
+ in
+ parse s sep table
+
+%}
+
+%token <Coqpp_ast.code> CODE
+%token <string> COMMENT
+%token <string> IDENT QUALID
+%token <string> STRING
+%token <int> INT
+%token VERNAC TACTIC GRAMMAR EXTEND END DECLARE PLUGIN
+%token LBRACKET RBRACKET PIPE ARROW COMMA EQUAL
+%token LPAREN RPAREN COLON SEMICOLON
+%token GLOBAL FIRST LAST BEFORE AFTER LEVEL LEFTA RIGHTA NONA
+%token EOF
+
+%type <Coqpp_ast.t> file
+%start file
+
+%%
+
+file:
+| nodes EOF
+ { $1 }
+;
+
+nodes:
+|
+ { [] }
+| node nodes
+ { $1 :: $2 }
+;
+
+node:
+| CODE { Code $1 }
+| COMMENT { Comment $1 }
+| declare_plugin { $1 }
+| grammar_extend { $1 }
+| vernac_extend { $1 }
+| tactic_extend { $1 }
+;
+
+declare_plugin:
+| DECLARE PLUGIN STRING { DeclarePlugin $3 }
+;
+
+grammar_extend:
+| GRAMMAR EXTEND qualid_or_ident globals gram_entries END
+ { GramExt { gramext_name = $3; gramext_globals = $4; gramext_entries = $5 } }
+;
+
+vernac_extend:
+| VERNAC EXTEND IDENT END { VernacExt }
+;
+
+tactic_extend:
+| TACTIC EXTEND IDENT tactic_level tactic_rules END
+ { TacticExt { tacext_name = $3; tacext_level = $4; tacext_rules = $5 } }
+;
+
+tactic_level:
+| { None }
+| LEVEL INT { Some $2 }
+;
+
+tactic_rules:
+| tactic_rule { [$1] }
+| tactic_rule tactic_rules { $1 :: $2 }
+;
+
+tactic_rule:
+| PIPE LBRACKET ext_tokens RBRACKET ARROW CODE
+ { { tac_toks = $3; tac_body = $6 } }
+;
+
+ext_tokens:
+| { [] }
+| ext_token ext_tokens { $1 :: $2 }
+;
+
+ext_token:
+| STRING { ExtTerminal $1 }
+| IDENT {
+ let e = parse_user_entry $1 "" in
+ ExtNonTerminal (e, TokNone)
+ }
+| IDENT LPAREN IDENT RPAREN {
+ let e = parse_user_entry $1 "" in
+ ExtNonTerminal (e, TokName $3)
+ }
+| IDENT LPAREN IDENT COMMA STRING RPAREN {
+ let e = parse_user_entry $1 $5 in
+ ExtNonTerminal (e, TokName $3)
+}
+;
+
+qualid_or_ident:
+| QUALID { $1 }
+| IDENT { $1 }
+;
+
+globals:
+| { [] }
+| GLOBAL COLON idents SEMICOLON { $3 }
+;
+
+idents:
+| { [] }
+| qualid_or_ident idents { $1 :: $2 }
+;
+
+gram_entries:
+| { [] }
+| gram_entry gram_entries { $1 :: $2 }
+;
+
+gram_entry:
+| qualid_or_ident COLON position_opt LBRACKET levels RBRACKET SEMICOLON
+ { { gentry_name = $1; gentry_pos = $3; gentry_rules = $5; } }
+;
+
+position_opt:
+| { None }
+| position { Some $1 }
+;
+
+position:
+| FIRST { First }
+| LAST { Last }
+| BEFORE STRING { Before $2 }
+| AFTER STRING { After $2 }
+| LEVEL STRING { Level $2 }
+;
+
+string_opt:
+| { None }
+| STRING { Some $1 }
+;
+
+assoc_opt:
+| { None }
+| assoc { Some $1 }
+;
+
+assoc:
+| LEFTA { LeftA }
+| RIGHTA { RightA }
+| NONA { NonA }
+;
+
+levels:
+| level { [$1] }
+| level PIPE levels { $1 :: $3 }
+;
+
+level:
+| string_opt assoc_opt LBRACKET rules_opt RBRACKET
+ { { grule_label = $1; grule_assoc = $2; grule_prods = $4; } }
+;
+
+rules_opt:
+| { [] }
+| rules { $1 }
+;
+
+rules:
+| rule { [$1] }
+| rule PIPE rules { $1 :: $3 }
+;
+
+rule:
+| symbols_opt ARROW CODE
+ { { gprod_symbs = $1; gprod_body = $3; } }
+;
+
+symbols_opt:
+| { [] }
+| symbols { $1 }
+;
+
+symbols:
+| symbol { [$1] }
+| symbol SEMICOLON symbols { $1 :: $3 }
+;
+
+symbol:
+| IDENT EQUAL gram_tokens { (Some $1, $3) }
+| gram_tokens { (None, $1) }
+;
+
+gram_token:
+| qualid_or_ident { GSymbQualid ($1, None) }
+| qualid_or_ident LEVEL STRING { GSymbQualid ($1, Some $3) }
+| LPAREN gram_tokens RPAREN { GSymbParen $2 }
+| LBRACKET rules RBRACKET { GSymbProd $2 }
+| STRING { GSymbString $1 }
+;
+
+gram_tokens:
+| gram_token { [$1] }
+| gram_token gram_tokens { $1 :: $2 }
+;
diff --git a/grammar/q_util.mlp b/grammar/q_util.mlp
index 6cdd2ec19..0b8d7fda7 100644
--- a/grammar/q_util.mlp
+++ b/grammar/q_util.mlp
@@ -75,7 +75,7 @@ let rec mlexpr_of_prod_entry_key f = function
(** Keep in sync with Pcoq! *)
assert (e = "tactic");
if l = 5 then <:expr< Extend.Aentry Pltac.binder_tactic >>
- else <:expr< Extend.Aentryl (Pltac.tactic_expr) $mlexpr_of_int l$ >>
+ else <:expr< Extend.Aentryl (Pltac.tactic_expr) $mlexpr_of_string (string_of_int l)$ >>
let rec type_of_user_symbol = function
| Ulist1 s | Ulist1sep (s, _) | Ulist0 s | Ulist0sep (s, _) ->
diff --git a/grammar/tacextend.mlp b/grammar/tacextend.mlp
index 525be6432..cea0bed59 100644
--- a/grammar/tacextend.mlp
+++ b/grammar/tacextend.mlp
@@ -15,11 +15,6 @@ open Argextend
let plugin_name = <:expr< __coq_plugin_name >>
-let mlexpr_of_ident id =
- (** Workaround for badly-designed generic arguments lacking a closure *)
- let id = "$" ^ id in
- <:expr< Names.Id.of_string_soft $str:id$ >>
-
let rec mlexpr_of_symbol = function
| Ulist1 s -> <:expr< Extend.TUlist1 $mlexpr_of_symbol s$ >>
| Ulist1sep (s,sep) -> <:expr< Extend.TUlist1sep $mlexpr_of_symbol s$ $str:sep$ >>
@@ -38,9 +33,9 @@ let rec mlexpr_of_clause = function
| [] -> <:expr< TyNil >>
| ExtTerminal s :: cl -> <:expr< TyIdent($str:s$, $mlexpr_of_clause cl$) >>
| ExtNonTerminal(g,None) :: cl ->
- <:expr< TyAnonArg(Loc.tag($mlexpr_of_symbol g$), $mlexpr_of_clause cl$) >>
+ <:expr< TyAnonArg($mlexpr_of_symbol g$, $mlexpr_of_clause cl$) >>
| ExtNonTerminal(g,Some id) :: cl ->
- <:expr< TyArg(Loc.tag($mlexpr_of_symbol g$, $mlexpr_of_ident id$), $mlexpr_of_clause cl$) >>
+ <:expr< TyArg($mlexpr_of_symbol g$, $mlexpr_of_string id$, $mlexpr_of_clause cl$) >>
let rec binders_of_clause e = function
| [] -> <:expr< fun ist -> $e$ >>
diff --git a/ide/idetop.ml b/ide/idetop.ml
index 7abbf239b..6fb004061 100644
--- a/ide/idetop.ml
+++ b/ide/idetop.ml
@@ -151,7 +151,7 @@ let hyp_next_tac sigma env decl =
("inversion clear "^id_s), ("inversion_clear "^id_s^".")
]
-let concl_next_tac sigma concl =
+let concl_next_tac =
let expand s = (s,s^".") in
List.map expand ([
"intro";
@@ -230,10 +230,9 @@ let hints () =
| [] -> None
| g :: _ ->
let env = Goal.V82.env sigma g in
- let hint_goal = concl_next_tac sigma g in
let get_hint_hyp env d accu = hyp_next_tac sigma env d :: accu in
let hint_hyps = List.rev (Environ.fold_named_context get_hint_hyp env ~init: []) in
- Some (hint_hyps, hint_goal)
+ Some (hint_hyps, concl_next_tac)
with Proof_global.NoCurrentProof -> None
diff --git a/ide/wg_ProofView.ml b/ide/wg_ProofView.ml
index b3088ee28..9be562d3e 100644
--- a/ide/wg_ProofView.ml
+++ b/ide/wg_ProofView.ml
@@ -103,7 +103,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals ~unfoc_goals hints = mat
else []
in
proof#buffer#insert (goal_str ~shownum:true 1 goals_cnt);
- insert_xml proof#buffer (Richpp.richpp_of_pp width cur_goal);
+ insert_xml ~tags:[Tags.Proof.goal] proof#buffer (Richpp.richpp_of_pp width cur_goal);
proof#buffer#insert "\n"
in
(* Insert remaining goals (no hypotheses) *)
@@ -128,7 +128,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals ~unfoc_goals hints = mat
ignore(proof#buffer#place_cursor
~where:(proof#buffer#end_iter#backward_to_tag_toggle
(Some Tags.Proof.goal)));
- ignore(proof#scroll_to_mark ~use_align:true ~yalign:0.95 `INSERT)
+ ignore(proof#scroll_to_mark `INSERT)
let rec flatten = function
| [] -> []
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 4e217b2cd..18d6c1a5b 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -710,10 +710,12 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
let arg = match arg with
| None -> None
| Some arg ->
- let mk_env (c, (tmp_scope, subscopes)) =
+ let mk_env id (c, (tmp_scope, subscopes)) map =
let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in
- let gc = intern nenv c in
- (gc, Some c)
+ try
+ let gc = intern nenv c in
+ Id.Map.add id (gc, Some c) map
+ with GlobalizationError _ -> map
in
let mk_env' (c, (onlyident,(tmp_scope,subscopes))) =
let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in
@@ -725,7 +727,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
| [pat] -> (glob_constr_of_cases_pattern pat, None)
| _ -> error_cannot_coerce_disjunctive_pattern_term ?loc:c.loc ()
in
- let terms = Id.Map.map mk_env terms in
+ let terms = Id.Map.fold mk_env terms Id.Map.empty in
let binders = Id.Map.map mk_env' binders in
let bindings = Id.Map.fold Id.Map.add terms binders in
Some (Genintern.generic_substitute_notation bindings arg)
diff --git a/interp/declare.ml b/interp/declare.ml
index aa737239b..fcb62ac8c 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -384,10 +384,12 @@ let inInductive : inductive_obj -> obj =
let declare_projections univs mind =
let env = Global.env () in
- let spec,_ = Inductive.lookup_mind_specif env (mind,0) in
- match spec.mind_record with
- | Some (Some (_, kns, _)) ->
- let projs = Inductiveops.compute_projections env (mind, 0) in
+ let mib = Environ.lookup_mind mind env in
+ match mib.mind_record with
+ | PrimRecord info ->
+ let iter i (_, kns, _) =
+ let mind = (mind, i) in
+ let projs = Inductiveops.compute_projections env mind in
Array.iter2 (fun kn (term, types) ->
let id = Label.to_id (Constant.label kn) in
let univs = match univs with
@@ -408,10 +410,12 @@ let declare_projections univs mind =
let entry = definition_entry ~types ~univs term in
let kn' = declare_constant id (DefinitionEntry entry, IsDefinition StructureComponent) in
assert (Constant.equal kn kn')
- ) kns projs;
- true, true
- | Some None -> true,false
- | None -> false,false
+ ) kns projs
+ in
+ let () = Array.iteri iter info in
+ true, true
+ | FakeRecord -> true, false
+ | NotRecord -> false, false
(* for initial declaration *)
let declare_mind mie =
diff --git a/interp/discharge.ml b/interp/discharge.ml
index e16a955d9..0e44a8b46 100644
--- a/interp/discharge.ml
+++ b/interp/discharge.ml
@@ -111,9 +111,10 @@ let process_inductive info modlist mib =
let section_decls' = Context.Named.map discharge section_decls in
let (params',inds') = abstract_inductive section_decls' nparamdecls inds in
let record = match mib.mind_record with
- | Some (Some (id, _, _)) -> Some (Some id)
- | Some None -> Some None
- | None -> None
+ | PrimRecord info ->
+ Some (Some (Array.map pi1 info))
+ | FakeRecord -> Some None
+ | NotRecord -> None
in
{ mind_entry_record = record;
mind_entry_finite = mib.mind_finite;
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index 74618a290..5bf46282f 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -113,7 +113,7 @@ let type_of_global_ref gr =
"var" ^ type_of_logical_kind (Decls.variable_kind v)
| Globnames.IndRef ind ->
let (mib,oib) = Inductive.lookup_mind_specif (Global.env ()) ind in
- if mib.Declarations.mind_record <> None then
+ if mib.Declarations.mind_record <> Declarations.NotRecord then
begin match mib.Declarations.mind_finite with
| Finite -> "indrec"
| BiFinite -> "rec"
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index 83ad9af33..288a0bfe0 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -22,7 +22,7 @@ open Libobject
open Nameops
open Context.Rel.Declaration
-exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Context.Rel.t (* found, expected *)
+exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Constr.rel_context (* found, expected *)
let mismatched_ctx_inst_err env c n m = raise (MismatchedContextInstance (env, c, n, m))
module RelDecl = Context.Rel.Declaration
diff --git a/interp/implicit_quantifiers.mli b/interp/implicit_quantifiers.mli
index a8492095e..437fef175 100644
--- a/interp/implicit_quantifiers.mli
+++ b/interp/implicit_quantifiers.mli
@@ -38,14 +38,14 @@ val make_fresh : Id.Set.t -> Environ.env -> Id.t -> Id.t
val implicits_of_glob_constr : ?with_products:bool -> Glob_term.glob_constr -> Impargs.manual_implicits
val combine_params_freevar :
- Id.Set.t -> GlobRef.t option * Context.Rel.Declaration.t ->
+ Id.Set.t -> GlobRef.t option * Constr.rel_declaration ->
Constrexpr.constr_expr * Id.Set.t
val implicit_application : Id.Set.t -> ?allow_partial:bool ->
- (Id.Set.t -> GlobRef.t option * Context.Rel.Declaration.t ->
+ (Id.Set.t -> GlobRef.t option * Constr.rel_declaration ->
Constrexpr.constr_expr * Id.Set.t) ->
constr_expr -> constr_expr * Id.Set.t
(* Should be likely located elsewhere *)
-exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Context.Rel.t (* found, expected *)
-val mismatched_ctx_inst_err : Environ.env -> Typeclasses_errors.contexts -> constr_expr list -> Context.Rel.t -> 'a
+exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Constr.rel_context (* found, expected *)
+val mismatched_ctx_inst_err : Environ.env -> Typeclasses_errors.contexts -> constr_expr list -> Constr.rel_context -> 'a
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index 1d8861cbc..61ed40394 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -265,7 +265,7 @@ type 'a infos_cache = {
i_repr : 'a infos -> 'a infos_tab -> constr -> 'a;
i_env : env;
i_sigma : existential -> constr option;
- i_rels : (Context.Rel.Declaration.t * lazy_val) Range.t;
+ i_rels : (Constr.rel_declaration * lazy_val) Range.t;
}
and 'a infos = {
@@ -587,78 +587,95 @@ let mk_clos_deep clos_fun env t =
let mk_clos2 = mk_clos_deep mk_clos
(* The inverse of mk_clos_deep: move back to constr *)
-let rec to_constr constr_fun lfts v =
+let rec to_constr lfts v =
match v.term with
| FRel i -> mkRel (reloc_rel i lfts)
| FFlex (RelKey p) -> mkRel (reloc_rel p lfts)
| FFlex (VarKey x) -> mkVar x
| FAtom c -> exliftn lfts c
| FCast (a,k,b) ->
- mkCast (constr_fun lfts a, k, constr_fun lfts b)
+ mkCast (to_constr lfts a, k, to_constr lfts b)
| FFlex (ConstKey op) -> mkConstU op
| FInd op -> mkIndU op
| FConstruct op -> mkConstructU op
| FCaseT (ci,p,c,ve,env) ->
- mkCase (ci, constr_fun lfts (mk_clos env p),
- constr_fun lfts c,
- Array.map (fun b -> constr_fun lfts (mk_clos env b)) ve)
- | FFix ((op,(lna,tys,bds)),e) ->
+ if is_subs_id env && is_lift_id lfts then
+ mkCase (ci, p, to_constr lfts c, ve)
+ else
+ let subs = comp_subs lfts env in
+ mkCase (ci, subst_constr subs p,
+ to_constr lfts c,
+ Array.map (fun b -> subst_constr subs b) ve)
+ | FFix ((op,(lna,tys,bds)) as fx, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ mkFix fx
+ else
let n = Array.length bds in
- let ftys = Array.Fun1.map mk_clos e tys in
- let fbds = Array.Fun1.map mk_clos (subs_liftn n e) bds in
- let lfts' = el_liftn n lfts in
- mkFix (op, (lna, Array.Fun1.map constr_fun lfts ftys,
- Array.Fun1.map constr_fun lfts' fbds))
- | FCoFix ((op,(lna,tys,bds)),e) ->
+ let subs_ty = comp_subs lfts e in
+ let subs_bd = comp_subs (el_liftn n lfts) (subs_liftn n e) in
+ let tys = Array.Fun1.map subst_constr subs_ty tys in
+ let bds = Array.Fun1.map subst_constr subs_bd bds in
+ mkFix (op, (lna, tys, bds))
+ | FCoFix ((op,(lna,tys,bds)) as cfx, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ mkCoFix cfx
+ else
let n = Array.length bds in
- let ftys = Array.Fun1.map mk_clos e tys in
- let fbds = Array.Fun1.map mk_clos (subs_liftn n e) bds in
- let lfts' = el_liftn (Array.length bds) lfts in
- mkCoFix (op, (lna, Array.Fun1.map constr_fun lfts ftys,
- Array.Fun1.map constr_fun lfts' fbds))
+ let subs_ty = comp_subs lfts e in
+ let subs_bd = comp_subs (el_liftn n lfts) (subs_liftn n e) in
+ let tys = Array.Fun1.map subst_constr subs_ty tys in
+ let bds = Array.Fun1.map subst_constr subs_bd bds in
+ mkCoFix (op, (lna, tys, bds))
| FApp (f,ve) ->
- mkApp (constr_fun lfts f,
- Array.Fun1.map constr_fun lfts ve)
+ mkApp (to_constr lfts f,
+ Array.Fun1.map to_constr lfts ve)
| FProj (p,c) ->
- mkProj (p,constr_fun lfts c)
+ mkProj (p,to_constr lfts c)
- | FLambda _ ->
- let (na,ty,bd) = destFLambda mk_clos2 v in
- mkLambda (na, constr_fun lfts ty,
- constr_fun (el_lift lfts) bd)
+ | FLambda (len, tys, f, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ Term.compose_lam (List.rev tys) f
+ else
+ let subs = comp_subs lfts e in
+ let tys = List.mapi (fun i (na, c) -> na, subst_constr (subs_liftn i subs) c) tys in
+ let f = subst_constr (subs_liftn len subs) f in
+ Term.compose_lam (List.rev tys) f
| FProd (n,t,c) ->
- mkProd (n, constr_fun lfts t,
- constr_fun (el_lift lfts) c)
+ mkProd (n, to_constr lfts t,
+ to_constr (el_lift lfts) c)
| FLetIn (n,b,t,f,e) ->
- let fc = mk_clos2 (subs_lift e) f in
- mkLetIn (n, constr_fun lfts b,
- constr_fun lfts t,
- constr_fun (el_lift lfts) fc)
+ let subs = comp_subs (el_lift lfts) (subs_lift e) in
+ mkLetIn (n, to_constr lfts b,
+ to_constr lfts t,
+ subst_constr subs f)
| FEvar ((ev,args),env) ->
- mkEvar(ev,Array.map (fun a -> constr_fun lfts (mk_clos2 env a)) args)
- | FLIFT (k,a) -> to_constr constr_fun (el_shft k lfts) a
+ let subs = comp_subs lfts env in
+ mkEvar(ev,Array.map (fun a -> subst_constr subs a) args)
+ | FLIFT (k,a) -> to_constr (el_shft k lfts) a
| FCLOS (t,env) ->
- let fr = mk_clos2 env t in
- let unfv = update v fr.norm fr.term in
- to_constr constr_fun lfts unfv
+ if is_subs_id env && is_lift_id lfts then t
+ else
+ let subs = comp_subs lfts env in
+ subst_constr subs t
| FLOCKED -> assert false (*mkVar(Id.of_string"_LOCK_")*)
+and subst_constr subst c = match Constr.kind c with
+| Rel i ->
+ begin match expand_rel i subst with
+ | Inl (k, lazy v) -> Vars.lift k v
+ | Inr (m, _) -> mkRel m
+ end
+| _ ->
+ Constr.map_with_binders Esubst.subs_lift subst_constr subst c
+
+and comp_subs el s =
+ Esubst.lift_subst (fun el c -> lazy (to_constr el c)) el s
+
(* This function defines the correspondance between constr and
fconstr. When we find a closure whose substitution is the identity,
then we directly return the constr to avoid possibly huge
reallocation. *)
-let term_of_fconstr =
- let rec term_of_fconstr_lift lfts v =
- match v.term with
- | FCLOS(t,env) when is_subs_id env && is_lift_id lfts -> t
- | FLambda(_,tys,f,e) when is_subs_id e && is_lift_id lfts ->
- Term.compose_lam (List.rev tys) f
- | FFix(fx,e) when is_subs_id e && is_lift_id lfts -> mkFix fx
- | FCoFix(cfx,e) when is_subs_id e && is_lift_id lfts -> mkCoFix cfx
- | _ -> to_constr term_of_fconstr_lift lfts v in
- term_of_fconstr_lift el_id
-
-
+let term_of_fconstr c = to_constr el_id c
(* fstrong applies unfreeze_fun recursively on the (freeze) term and
* yields a term. Assumes that the unfreeze_fun never returns a
@@ -803,10 +820,12 @@ let drop_parameters depth n argstk =
constructor is partially applied.
*)
let eta_expand_ind_stack env ind m s (f, s') =
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
match mib.Declarations.mind_record with
- | Some (Some (_,projs,pbs)) when
+ | PrimRecord infos when
mib.Declarations.mind_finite == Declarations.BiFinite ->
+ let (_, projs, _) = infos.(snd ind) in
(* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
arg1..argn ~= (proj1 t...projn t) where t = zip (f,s') *)
let pars = mib.Declarations.mind_nparams in
@@ -817,7 +836,7 @@ let eta_expand_ind_stack env ind m s (f, s') =
let hstack = Array.map (fun p -> { norm = Red; (* right can't be a constructor though *)
term = FProj (Projection.make p true, right) }) projs in
argss, [Zapp hstack]
- | _ -> raise Not_found (* disallow eta-exp for non-primitive records *)
+ | PrimRecord _ | NotRecord | FakeRecord -> raise Not_found (* disallow eta-exp for non-primitive records *)
let rec project_nth_arg n argstk =
match argstk with
diff --git a/kernel/cClosure.mli b/kernel/cClosure.mli
index 63daa4a7c..f8f98f0ab 100644
--- a/kernel/cClosure.mli
+++ b/kernel/cClosure.mli
@@ -244,6 +244,6 @@ val kni: clos_infos -> fconstr infos_tab -> fconstr -> stack -> fconstr * stack
val knr: clos_infos -> fconstr infos_tab -> fconstr -> stack -> fconstr * stack
val kl : clos_infos -> fconstr infos_tab -> fconstr -> constr
-val to_constr : (lift -> fconstr -> constr) -> lift -> fconstr -> constr
+val to_constr : lift -> fconstr -> constr
(** End of cbn debug section i*)
diff --git a/kernel/cbytecodes.ml b/kernel/cbytecodes.ml
index 521f540d2..3095ce148 100644
--- a/kernel/cbytecodes.ml
+++ b/kernel/cbytecodes.ml
@@ -217,6 +217,7 @@ type vm_env = {
type comp_env = {
+ arity : int; (* arity of the current function, 0 if none *)
nb_uni_stack : int ; (* number of universes on the stack, *)
(* universes are always at the bottom. *)
nb_stack : int; (* number of variables on the stack *)
@@ -235,8 +236,8 @@ open Util
let pp_sort s =
let open Sorts in
match s with
- | Prop Null -> str "Prop"
- | Prop Pos -> str "Set"
+ | Prop -> str "Prop"
+ | Set -> str "Set"
| Type u -> str "Type@{" ++ Univ.pr_uni u ++ str "}"
let rec pp_struct_const = function
diff --git a/kernel/cbytecodes.mli b/kernel/cbytecodes.mli
index 238edc0af..de21401b3 100644
--- a/kernel/cbytecodes.mli
+++ b/kernel/cbytecodes.mli
@@ -159,6 +159,7 @@ type vm_env = {
type comp_env = {
+ arity : int; (* arity of the current function, 0 if none *)
nb_uni_stack : int ; (** number of universes on the stack *)
nb_stack : int; (** number of variables on the stack *)
in_stack : int list; (** position in the stack *)
diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml
index 7a27a3d20..6677db2fd 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -112,8 +112,9 @@ let push_fv d e = {
let fv r = !(r.in_env)
-let empty_comp_env ?(univs=0) ()=
- { nb_uni_stack = univs;
+let empty_comp_env ()=
+ { arity = 0;
+ nb_uni_stack = 0;
nb_stack = 0;
in_stack = [];
nb_rec = 0;
@@ -148,7 +149,8 @@ let rec add_param n sz l =
if Int.equal n 0 then l else add_param (n - 1) sz (n+sz::l)
let comp_env_fun ?(univs=0) arity =
- { nb_uni_stack = univs ;
+ { arity;
+ nb_uni_stack = univs ;
nb_stack = arity;
in_stack = add_param arity 0 [];
nb_rec = 0;
@@ -159,7 +161,8 @@ let comp_env_fun ?(univs=0) arity =
let comp_env_fix_type rfv =
- { nb_uni_stack = 0;
+ { arity = 0;
+ nb_uni_stack = 0;
nb_stack = 0;
in_stack = [];
nb_rec = 0;
@@ -173,7 +176,8 @@ let comp_env_fix ndef curr_pos arity rfv =
for i = ndef downto 1 do
prec := Koffsetclosure (2 * (ndef - curr_pos - i)) :: !prec
done;
- { nb_uni_stack = 0;
+ { arity;
+ nb_uni_stack = 0;
nb_stack = arity;
in_stack = add_param arity 0 [];
nb_rec = ndef;
@@ -183,7 +187,8 @@ let comp_env_fix ndef curr_pos arity rfv =
}
let comp_env_cofix_type ndef rfv =
- { nb_uni_stack = 0;
+ { arity = 0;
+ nb_uni_stack = 0;
nb_stack = 0;
in_stack = [];
nb_rec = 0;
@@ -197,7 +202,8 @@ let comp_env_cofix ndef arity rfv =
for i = 1 to ndef do
prec := Kenvacc i :: !prec
done;
- { nb_uni_stack = 0;
+ { arity;
+ nb_uni_stack = 0;
nb_stack = arity;
in_stack = add_param arity 0 [];
nb_rec = ndef;
@@ -249,8 +255,15 @@ let pos_rel i r sz =
Kenvacc(r.offset + pos)
let pos_universe_var i r sz =
- if i < r.nb_uni_stack then
- Kacc (sz - r.nb_stack - (r.nb_uni_stack - i))
+ (* Compilation of a universe variable can happen either at toplevel (the
+ current closure correspond to a constant and has local universes) or in a
+ local closure (which has no local universes). *)
+ if r.nb_uni_stack != 0 then
+ (* Universe variables are represented by De Bruijn levels (not indices),
+ starting at 0. The shape of the stack will be [v1|..|vn|u1..up|arg1..argq]
+ with size = n + p + q, and q = r.arity. So Kacc (sz - r.arity - 1) will access
+ the last universe. *)
+ Kacc (sz - r.arity - (r.nb_uni_stack - i))
else
let env = !(r.in_env) in
let db = FVuniv_var i in
@@ -498,7 +511,7 @@ let rec compile_lam env cenv lam sz cont =
else comp_app compile_structured_constant compile_universe cenv
(Const_ind ind) (Univ.Instance.to_array u) sz cont
- | Lsort (Sorts.Prop _ as s) ->
+ | Lsort (Sorts.Prop | Sorts.Set as s) ->
compile_structured_constant cenv (Const_sort s) sz cont
| Lsort (Sorts.Type u) ->
(* We represent universes as a global constant with local universes
diff --git a/kernel/clambda.ml b/kernel/clambda.ml
index b722e4200..f1b6f3dff 100644
--- a/kernel/clambda.ml
+++ b/kernel/clambda.ml
@@ -814,7 +814,7 @@ let optimize_lambda lam =
let lambda_of_constr ~optimize genv c =
let env = Renv.make genv in
- let ids = List.rev_map Context.Rel.Declaration.get_name genv.env_rel_context.env_rel_ctx in
+ let ids = List.rev_map Context.Rel.Declaration.get_name (rel_context genv) in
Renv.push_rels env (Array.of_list ids);
let lam = lambda_of_constr env c in
let lam = if optimize then optimize_lambda lam else lam in
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 418229330..9bf743152 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -130,8 +130,8 @@ let mkProp = Sort Sorts.prop
let mkSet = Sort Sorts.set
let mkType u = Sort (Sorts.Type u)
let mkSort = function
- | Sorts.Prop Sorts.Null -> mkProp (* Easy sharing *)
- | Sorts.Prop Sorts.Pos -> mkSet
+ | Sorts.Prop -> mkProp (* Easy sharing *)
+ | Sorts.Set -> mkSet
| s -> Sort s
(* Constructs the term t1::t2, i.e. the term t1 casted with the type t2 *)
@@ -260,17 +260,17 @@ let isSort c = match kind c with
| _ -> false
let rec isprop c = match kind c with
- | Sort (Sorts.Prop _) -> true
+ | Sort (Sorts.Prop | Sorts.Set) -> true
| Cast (c,_,_) -> isprop c
| _ -> false
let rec is_Prop c = match kind c with
- | Sort (Sorts.Prop Sorts.Null) -> true
+ | Sort Sorts.Prop -> true
| Cast (c,_,_) -> is_Prop c
| _ -> false
let rec is_Set c = match kind c with
- | Sort (Sorts.Prop Sorts.Pos) -> true
+ | Sort Sorts.Set -> true
| Cast (c,_,_) -> is_Set c
| _ -> false
@@ -828,8 +828,10 @@ let leq_constr_univs_infer univs m n =
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
if UGraph.check_leq univs u1 u2 then true
else
- (cstrs := Univ.enforce_leq u1 u2 !cstrs;
- true)
+ (try let c, _ = UGraph.enforce_leq_alg u1 u2 univs in
+ cstrs := Univ.Constraint.union c !cstrs;
+ true
+ with Univ.UniverseInconsistency _ -> false)
in
let rec eq_constr' nargs m n =
m == n || compare_head_gen eq_universes eq_sorts eq_constr' nargs m n
@@ -1207,3 +1209,10 @@ let hcons =
Id.hcons)
(* let hcons_types = hcons_constr *)
+
+type rel_declaration = (constr, types) Context.Rel.Declaration.pt
+type named_declaration = (constr, types) Context.Named.Declaration.pt
+type compacted_declaration = (constr, types) Context.Compacted.Declaration.pt
+type rel_context = rel_declaration list
+type named_context = named_declaration list
+type compacted_context = compacted_declaration list
diff --git a/kernel/constr.mli b/kernel/constr.mli
index bf7b5e87b..70acf1932 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -372,6 +372,15 @@ val eq_constr_nounivs : constr -> constr -> bool
(** Total ordering compatible with [equal] *)
val compare : constr -> constr -> int
+(** {6 Extension of Context with declarations on constr} *)
+
+type rel_declaration = (constr, types) Context.Rel.Declaration.pt
+type named_declaration = (constr, types) Context.Named.Declaration.pt
+type compacted_declaration = (constr, types) Context.Compacted.Declaration.pt
+type rel_context = rel_declaration list
+type named_context = named_declaration list
+type compacted_context = compacted_declaration list
+
(** {6 Functionals working on the immediate subterm of a construction } *)
(** [fold f acc c] folds [f] on the immediate subterms of [c]
diff --git a/kernel/context.ml b/kernel/context.ml
index 5d4a10184..831dc850f 100644
--- a/kernel/context.ml
+++ b/kernel/context.ml
@@ -43,8 +43,6 @@ struct
| LocalAssum of Name.t * 'types (** name, type *)
| LocalDef of Name.t * 'constr * 'types (** name, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the name bound by a given declaration. *)
let get_name = function
| LocalAssum (na,_)
@@ -157,7 +155,6 @@ struct
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty rel-context *)
let empty = []
@@ -241,8 +238,6 @@ struct
| LocalAssum of Id.t * 'types (** identifier, type *)
| LocalDef of Id.t * 'constr * 'types (** identifier, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the identifier bound by a given declaration. *)
let get_id = function
| LocalAssum (id,_) -> id
@@ -370,7 +365,6 @@ struct
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty named-context *)
let empty = []
@@ -429,8 +423,6 @@ module Compacted =
| LocalAssum of Id.t list * 'types
| LocalDef of Id.t list * 'constr * 'types
- type t = (Constr.constr, Constr.types) pt
-
let map_constr f = function
| LocalAssum (ids, ty) as decl ->
let ty' = f ty in
@@ -454,7 +446,6 @@ module Compacted =
end
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
let fold f l ~init = List.fold_right f l init
end
diff --git a/kernel/context.mli b/kernel/context.mli
index c97db4348..957ac4b3d 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -35,8 +35,6 @@ sig
| LocalAssum of Name.t * 'types (** name, type *)
| LocalDef of Name.t * 'constr * 'types (** name, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the name bound by a given declaration. *)
val get_name : ('c, 't) pt -> Name.t
@@ -93,7 +91,6 @@ sig
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty rel-context *)
val empty : ('c, 't) pt
@@ -153,8 +150,6 @@ sig
| LocalAssum of Id.t * 'types (** identifier, type *)
| LocalDef of Id.t * 'constr * 'types (** identifier, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the identifier bound by a given declaration. *)
val get_id : ('c, 't) pt -> Id.t
@@ -220,7 +215,6 @@ sig
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty named-context *)
val empty : ('c, 't) pt
@@ -270,15 +264,12 @@ sig
| LocalAssum of Id.t list * 'types
| LocalDef of Id.t list * 'constr * 'types
- type t = (Constr.constr, Constr.types) pt
-
val map_constr : ('c -> 'c) -> ('c, 'c) pt -> ('c, 'c) pt
val of_named_decl : ('c, 't) Named.Declaration.pt -> ('c, 't) pt
val to_named_context : ('c, 't) pt -> ('c, 't) Named.pt
end
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
val fold : (('c, 't) Declaration.pt -> 'a -> 'a) -> ('c, 't) pt -> init:'a -> 'a
end
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 68057b389..094609b96 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -126,16 +126,15 @@ let expmod_constr cache modlist c =
| Not_found -> Constr.map substrec c)
| Proj (p, c') ->
- (try
- let p' = share_univs (ConstRef (Projection.constant p)) Univ.Instance.empty modlist in
- let make c = Projection.make c (Projection.unfolded p) in
- match kind p' with
- | Const (p',_) -> mkProj (make p', substrec c')
- | App (f, args) ->
- (match kind f with
- | Const (p', _) -> mkProj (make p', substrec c')
- | _ -> assert false)
- | _ -> assert false
+ (try
+ (** No need to expand parameters or universes for projections *)
+ let map cst =
+ let _ = Cmap.find cst (fst modlist) in
+ pop_con cst
+ in
+ let p = Projection.map map p in
+ let c' = substrec c' in
+ mkProj (p, c')
with Not_found -> Constr.map substrec c)
| _ -> Constr.map substrec c
@@ -158,7 +157,7 @@ type result = {
cook_type : types;
cook_universes : constant_universes;
cook_inline : inline;
- cook_context : Context.Named.t option;
+ cook_context : Constr.named_context option;
}
let on_body ml hy f = function
@@ -205,7 +204,7 @@ let lift_univs cb subst auctx0 =
let auctx' = Univ.subst_univs_level_abstract_universe_context (Univ.make_instance_subst subst) auctx in
subst, (Polymorphic_const (AUContext.union auctx0 auctx'))
-let cook_constant ~hcons env { from = cb; info } =
+let cook_constant ~hcons { from = cb; info } =
let { Opaqueproof.modlist; abstract } = info in
let cache = RefTable.create 13 in
let abstract, usubst, abs_ctx = abstract in
diff --git a/kernel/cooking.mli b/kernel/cooking.mli
index 76c79335f..6ebe691b8 100644
--- a/kernel/cooking.mli
+++ b/kernel/cooking.mli
@@ -10,7 +10,6 @@
open Constr
open Declarations
-open Environ
(** {6 Cooking the constants. } *)
@@ -23,10 +22,10 @@ type result = {
cook_type : types;
cook_universes : constant_universes;
cook_inline : inline;
- cook_context : Context.Named.t option;
+ cook_context : Constr.named_context option;
}
-val cook_constant : hcons:bool -> env -> recipe -> result
+val cook_constant : hcons:bool -> recipe -> result
val cook_constr : Opaqueproof.cooking_info -> constr -> constr
(** {6 Utility functions used in module [Discharge]. } *)
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index 7bd7d6c9c..95078800e 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -50,7 +50,7 @@ type inline = int option
always transparent. *)
type projection_body = {
- proj_ind : MutInd.t;
+ proj_ind : inductive;
proj_npars : int;
proj_arg : int; (** Projection index, starting from 0 *)
proj_type : types; (* Type under params *)
@@ -80,7 +80,7 @@ type typing_flags = {
(* some contraints are in constant_constraints, some other may be in
* the OpaqueDef *)
type constant_body = {
- const_hyps : Context.Named.t; (** New: younger hyp at top *)
+ const_hyps : Constr.named_context; (** New: younger hyp at top *)
const_body : constant_def;
const_type : types;
const_body_code : Cemitcodes.to_patch_substituted option;
@@ -109,13 +109,22 @@ v}
*)
(** Record information:
- If the record is not primitive, then None
- Otherwise, we get:
+ If the type is not a record, then NotRecord
+ If the type is a non-primitive record, then FakeRecord
+ If it is a primitive record, for every type in the block, we get:
- The identifier for the binder name of the record in primitive projections.
- The constants associated to each projection.
- - The checked projection bodies. *)
+ - The checked projection bodies.
-type record_body = (Id.t * Constant.t array * projection_body array) option
+ The kernel does not exploit the difference between [NotRecord] and
+ [FakeRecord]. It is mostly used by extraction, and should be extruded from
+ the kernel at some point.
+*)
+
+type record_info =
+| NotRecord
+| FakeRecord
+| PrimRecord of (Id.t * Constant.t array * projection_body array) array
type regular_inductive_arity = {
mind_user_arity : types;
@@ -129,7 +138,7 @@ type one_inductive_body = {
mind_typename : Id.t; (** Name of the type: [Ii] *)
- mind_arity_ctxt : Context.Rel.t; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
+ mind_arity_ctxt : Constr.rel_context; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
mind_arity : inductive_arity; (** Arity sort and original user arity *)
@@ -181,19 +190,19 @@ type mutual_inductive_body = {
mind_packets : one_inductive_body array; (** The component of the mutual inductive block *)
- mind_record : record_body option; (** The record information *)
+ mind_record : record_info; (** The record information *)
mind_finite : recursivity_kind; (** Whether the type is inductive or coinductive *)
mind_ntypes : int; (** Number of types in the block *)
- mind_hyps : Context.Named.t; (** Section hypotheses on which the block depends *)
+ mind_hyps : Constr.named_context; (** Section hypotheses on which the block depends *)
mind_nparams : int; (** Number of expected parameters including non-uniform ones (i.e. length of mind_params_ctxt w/o let-in) *)
mind_nparams_rec : int; (** Number of recursively uniform (i.e. ordinary) parameters *)
- mind_params_ctxt : Context.Rel.t; (** The context of parameters (includes let-in declaration) *)
+ mind_params_ctxt : Constr.rel_context; (** The context of parameters (includes let-in declaration) *)
mind_universes : abstract_inductive_universes; (** Information about monomorphic/polymorphic/cumulative inductives and their universes *)
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index 1b73096f7..3e6c4858e 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -84,7 +84,7 @@ let subst_const_def sub def = match def with
| OpaqueDef o -> OpaqueDef (Opaqueproof.subst_opaque sub o)
let subst_const_proj sub pb =
- { pb with proj_ind = subst_mind sub pb.proj_ind;
+ { pb with proj_ind = subst_ind sub pb.proj_ind;
proj_type = subst_mps sub pb.proj_type;
}
@@ -208,14 +208,21 @@ let subst_mind_packet sub mbp =
mind_nb_args = mbp.mind_nb_args;
mind_reloc_tbl = mbp.mind_reloc_tbl }
-let subst_mind_record sub (id, ps, pb as r) =
- let ps' = Array.Smart.map (subst_constant sub) ps in
- let pb' = Array.Smart.map (subst_const_proj sub) pb in
- if ps' == ps && pb' == pb then r
+let subst_mind_record sub r = match r with
+| NotRecord -> NotRecord
+| FakeRecord -> FakeRecord
+| PrimRecord infos ->
+ let map (id, ps, pb as info) =
+ let ps' = Array.Smart.map (subst_constant sub) ps in
+ let pb' = Array.Smart.map (subst_const_proj sub) pb in
+ if ps' == ps && pb' == pb then info
else (id, ps', pb')
+ in
+ let infos' = Array.Smart.map map infos in
+ if infos' == infos then r else PrimRecord infos'
let subst_mind_body sub mib =
- { mind_record = Option.Smart.map (Option.Smart.map (subst_mind_record sub)) mib.mind_record ;
+ { mind_record = subst_mind_record sub mib.mind_record ;
mind_finite = mib.mind_finite ;
mind_ntypes = mib.mind_ntypes ;
mind_hyps = (match mib.mind_hyps with [] -> [] | _ -> assert false);
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 3c555f8c7..40873bea7 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -49,9 +49,9 @@ type one_inductive_entry = {
mind_entry_lc : constr list }
type mutual_inductive_entry = {
- mind_entry_record : (Id.t option) option;
- (** Some (Some id): primitive record with id the binder name of the record
- in projections.
+ mind_entry_record : (Id.t array option) option;
+ (** Some (Some ids): primitive records with ids the binder name of each
+ record in their respective projections. Not used by the kernel.
Some None: non-primitive record *)
mind_entry_finite : Declarations.recursivity_kind;
mind_entry_params : (Id.t * local_entry) list;
@@ -75,7 +75,7 @@ type 'a in_constant_universes_entry = 'a * constant_universes_entry
type 'a definition_entry = {
const_entry_body : 'a const_entry_body;
(* List of section variables *)
- const_entry_secctx : Context.Named.t option;
+ const_entry_secctx : Constr.named_context option;
(* State id on which the completion of type checking is reported *)
const_entry_feedback : Stateid.t option;
const_entry_type : types option;
@@ -85,7 +85,7 @@ type 'a definition_entry = {
type section_def_entry = {
secdef_body : constr;
- secdef_secctx : Context.Named.t option;
+ secdef_secctx : Constr.named_context option;
secdef_feedback : Stateid.t option;
secdef_type : types option;
}
@@ -93,7 +93,7 @@ type section_def_entry = {
type inline = int option (* inlining level, None for no inlining *)
type parameter_entry =
- Context.Named.t option * types in_constant_universes_entry * inline
+ Constr.named_context option * types in_constant_universes_entry * inline
type 'a constant_entry =
| DefinitionEntry of 'a definition_entry
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 2d6c9117b..4ab469803 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -55,7 +55,8 @@ type globals = {
env_projections : projection_body Cmap_env.t;
env_inductives : mind_key Mindmap_env.t;
env_modules : module_body MPmap.t;
- env_modtypes : module_type_body MPmap.t}
+ env_modtypes : module_type_body MPmap.t;
+}
type stratification = {
env_universes : UGraph.t;
@@ -76,17 +77,17 @@ let dummy_lazy_val () = ref VKnone
let build_lazy_val vk key = vk := VKvalue (CEphemeron.create key)
type named_context_val = {
- env_named_ctx : Context.Named.t;
- env_named_map : (Context.Named.Declaration.t * lazy_val) Id.Map.t;
+ env_named_ctx : Constr.named_context;
+ env_named_map : (Constr.named_declaration * lazy_val) Id.Map.t;
}
type rel_context_val = {
- env_rel_ctx : Context.Rel.t;
- env_rel_map : (Context.Rel.Declaration.t * lazy_val) Range.t;
+ env_rel_ctx : Constr.rel_context;
+ env_rel_map : (Constr.rel_declaration * lazy_val) Range.t;
}
type env = {
- env_globals : globals; (* globals = constants + inductive types + modules + module-types *)
+ env_globals : globals;
env_named_context : named_context_val; (* section variables *)
env_rel_context : rel_context_val;
env_nb_rel : int;
@@ -208,6 +209,9 @@ let lookup_named_val id env =
let lookup_named_ctxt id ctxt =
fst (Id.Map.find id ctxt.env_named_map)
+let fold_constants f env acc =
+ Cmap_env.fold (fun c (body,_) acc -> f c body acc) env.env_globals.env_constants acc
+
(* Global constants *)
let lookup_constant_key kn env =
@@ -515,11 +519,12 @@ let template_polymorphic_pind (ind,u) env =
let add_mind_key kn (mind, _ as mind_key) env =
let new_inds = Mindmap_env.add kn mind_key env.env_globals.env_inductives in
let new_projections = match mind.mind_record with
- | None | Some None -> env.env_globals.env_projections
- | Some (Some (id, kns, pbs)) ->
- Array.fold_left2 (fun projs kn pb ->
- Cmap_env.add kn pb projs)
- env.env_globals.env_projections kns pbs
+ | NotRecord | FakeRecord -> env.env_globals.env_projections
+ | PrimRecord projs ->
+ Array.fold_left (fun accu (id, kns, pbs) ->
+ Array.fold_left2 (fun accu kn pb ->
+ Cmap_env.add kn pb accu) accu kns pbs)
+ env.env_globals.env_projections projs
in
let new_globals =
{ env.env_globals with
diff --git a/kernel/environ.mli b/kernel/environ.mli
index 8928b32f1..0259dbbdd 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -46,13 +46,8 @@ type constant_key = constant_body * (link_info ref * key)
type mind_key = mutual_inductive_body * link_info ref
-type globals = {
- env_constants : constant_key Cmap_env.t;
- env_projections : projection_body Cmap_env.t;
- env_inductives : mind_key Mindmap_env.t;
- env_modules : module_body MPmap.t;
- env_modtypes : module_type_body MPmap.t
-}
+type globals
+(** globals = constants + projections + inductive types + modules + module-types *)
type stratification = {
env_universes : UGraph.t;
@@ -60,17 +55,17 @@ type stratification = {
}
type named_context_val = private {
- env_named_ctx : Context.Named.t;
- env_named_map : (Context.Named.Declaration.t * lazy_val) Id.Map.t;
+ env_named_ctx : Constr.named_context;
+ env_named_map : (Constr.named_declaration * lazy_val) Id.Map.t;
}
type rel_context_val = private {
- env_rel_ctx : Context.Rel.t;
- env_rel_map : (Context.Rel.Declaration.t * lazy_val) Range.t;
+ env_rel_ctx : Constr.rel_context;
+ env_rel_map : (Constr.rel_declaration * lazy_val) Range.t;
}
type env = private {
- env_globals : globals; (* globals = constants + inductive types + modules + module-types *)
+ env_globals : globals;
env_named_context : named_context_val; (* section variables *)
env_rel_context : rel_context_val;
env_nb_rel : int;
@@ -88,8 +83,8 @@ val eq_named_context_val : named_context_val -> named_context_val -> bool
val empty_env : env
val universes : env -> UGraph.t
-val rel_context : env -> Context.Rel.t
-val named_context : env -> Context.Named.t
+val rel_context : env -> Constr.rel_context
+val named_context : env -> Constr.named_context
val named_context_val : env -> named_context_val
val opaque_tables : env -> Opaqueproof.opaquetab
@@ -108,13 +103,13 @@ val empty_context : env -> bool
(** {5 Context of de Bruijn variables ([rel_context]) } *)
val nb_rel : env -> int
-val push_rel : Context.Rel.Declaration.t -> env -> env
-val push_rel_context : Context.Rel.t -> env -> env
+val push_rel : Constr.rel_declaration -> env -> env
+val push_rel_context : Constr.rel_context -> env -> env
val push_rec_types : rec_declaration -> env -> env
(** Looks up in the context of local vars referred by indice ([rel_context])
raises [Not_found] if the index points out of the context *)
-val lookup_rel : int -> env -> Context.Rel.Declaration.t
+val lookup_rel : int -> env -> Constr.rel_declaration
val lookup_rel_val : int -> env -> lazy_val
val evaluable_rel : int -> env -> bool
val env_of_rel : int -> env -> env
@@ -122,12 +117,12 @@ val env_of_rel : int -> env -> env
(** {6 Recurrence on [rel_context] } *)
val fold_rel_context :
- (env -> Context.Rel.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Constr.rel_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
(** {5 Context of variables (section variables and goal assumptions) } *)
-val named_context_of_val : named_context_val -> Context.Named.t
-val val_of_named_context : Context.Named.t -> named_context_val
+val named_context_of_val : named_context_val -> Constr.named_context
+val val_of_named_context : Constr.named_context -> named_context_val
val empty_named_context_val : named_context_val
val ids_of_named_context_val : named_context_val -> Id.Set.t
@@ -138,19 +133,19 @@ val ids_of_named_context_val : named_context_val -> Id.Set.t
val map_named_val :
(constr -> constr) -> named_context_val -> named_context_val
-val push_named : Context.Named.Declaration.t -> env -> env
-val push_named_context : Context.Named.t -> env -> env
+val push_named : Constr.named_declaration -> env -> env
+val push_named_context : Constr.named_context -> env -> env
val push_named_context_val :
- Context.Named.Declaration.t -> named_context_val -> named_context_val
+ Constr.named_declaration -> named_context_val -> named_context_val
(** Looks up in the context of local vars referred by names ([named_context])
raises [Not_found] if the Id.t is not found *)
-val lookup_named : variable -> env -> Context.Named.Declaration.t
+val lookup_named : variable -> env -> Constr.named_declaration
val lookup_named_val : variable -> env -> lazy_val
-val lookup_named_ctxt : variable -> named_context_val -> Context.Named.Declaration.t
+val lookup_named_ctxt : variable -> named_context_val -> Constr.named_declaration
val evaluable_named : variable -> env -> bool
val named_type : variable -> env -> types
val named_body : variable -> env -> constr option
@@ -158,13 +153,13 @@ val named_body : variable -> env -> constr option
(** {6 Recurrence on [named_context]: older declarations processed first } *)
val fold_named_context :
- (env -> Context.Named.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Constr.named_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
val set_universes : env -> UGraph.t -> env
(** Recurrence on [named_context] starting from younger decl *)
val fold_named_context_reverse :
- ('a -> Context.Named.Declaration.t -> 'a) -> init:'a -> env -> 'a
+ ('a -> Constr.named_declaration -> 'a) -> init:'a -> env -> 'a
(** This forgets named and rel contexts *)
val reset_context : env -> env
@@ -175,6 +170,9 @@ val reset_with_named_context : named_context_val -> env -> env
(** This removes the [n] last declarations from the rel context *)
val pop_rel_context : int -> env -> env
+(** Useful for printing *)
+val fold_constants : (Constant.t -> constant_body -> 'a -> 'a) -> env -> 'a -> 'a
+
(** {5 Global constants }
{6 Add entries to global environment } *)
@@ -280,7 +278,7 @@ val vars_of_global : env -> constr -> Id.Set.t
val really_needed : env -> Id.Set.t -> Id.Set.t
(** like [really_needed] but computes a well ordered named context *)
-val keep_hyps : env -> Id.Set.t -> Context.Named.t
+val keep_hyps : env -> Id.Set.t -> Constr.named_context
(** {5 Unsafe judgments. }
We introduce here the pre-type of judgments, which is
@@ -309,10 +307,10 @@ exception Hyp_not_found
return [tail::(f head (id,_,_) (rev tail))::head].
the value associated to id should not change *)
val apply_to_hyp : named_context_val -> variable ->
- (Context.Named.t -> Context.Named.Declaration.t -> Context.Named.t -> Context.Named.Declaration.t) ->
+ (Constr.named_context -> Constr.named_declaration -> Constr.named_context -> Constr.named_declaration) ->
named_context_val
-val remove_hyps : Id.Set.t -> (Context.Named.Declaration.t -> Context.Named.Declaration.t) -> (lazy_val -> lazy_val) -> named_context_val -> named_context_val
+val remove_hyps : Id.Set.t -> (Constr.named_declaration -> Constr.named_declaration) -> (lazy_val -> lazy_val) -> named_context_val -> named_context_val
@@ -320,6 +318,7 @@ open Retroknowledge
(** functions manipulating the retroknowledge
@author spiwack *)
val retroknowledge : (retroknowledge->'a) -> env -> 'a
+[@@ocaml.deprecated "Use the record projection."]
val registered : env -> field -> bool
diff --git a/kernel/esubst.ml b/kernel/esubst.ml
index 4b8edf63f..9fc3b11d7 100644
--- a/kernel/esubst.ml
+++ b/kernel/esubst.ml
@@ -134,6 +134,29 @@ let rec exp_rel lams k subs =
let expand_rel k subs = exp_rel 0 k subs
+let rec subs_map f = function
+| ESID _ as s -> s
+| CONS (x, s) -> CONS (Array.map f x, subs_map f s)
+| SHIFT (n, s) -> SHIFT (n, subs_map f s)
+| LIFT (n, s) -> LIFT (n, subs_map f s)
+
+let rec lift_subst mk_cl s1 s2 = match s1 with
+| ELID -> subs_map (fun c -> mk_cl ELID c) s2
+| ELSHFT(s, k) -> subs_shft(k, lift_subst mk_cl s s2)
+| ELLFT (k, s) ->
+ match s2 with
+ | CONS(x,s') ->
+ CONS(CArray.Fun1.map mk_cl s1 x, lift_subst mk_cl s1 s')
+ | ESID n -> lift_subst mk_cl s (ESID (n + k))
+ | SHIFT(k',s') ->
+ if k<k'
+ then subs_shft(k, lift_subst mk_cl s (subs_shft(k'-k, s')))
+ else subs_shft(k', lift_subst mk_cl (el_liftn (k-k') s) s')
+ | LIFT(k',s') ->
+ if k<k'
+ then subs_liftn k (lift_subst mk_cl s (subs_liftn (k'-k) s'))
+ else subs_liftn k' (lift_subst mk_cl (el_liftn (k-k') s) s')
+
let rec comp mk_cl s1 s2 =
match (s1, s2) with
| _, ESID _ -> s1
diff --git a/kernel/esubst.mli b/kernel/esubst.mli
index a674c425a..475b64f47 100644
--- a/kernel/esubst.mli
+++ b/kernel/esubst.mli
@@ -72,3 +72,10 @@ val el_liftn : int -> lift -> lift
val el_lift : lift -> lift
val reloc_rel : int -> lift -> int
val is_lift_id : lift -> bool
+
+(** Lift applied to substitution: [lift_subst mk_clos el s] computes a
+ substitution equivalent to applying el then s. Argument
+ mk_clos is used when a closure has to be created, i.e. when
+ el is applied on an element of s.
+*)
+val lift_subst : (lift -> 'a -> 'b) -> lift -> 'a subs -> 'b subs
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 14f2a3d8f..5d45c2c1a 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -120,16 +120,6 @@ let mind_check_names mie =
(* Typing the arities and constructor types *)
-(* An inductive definition is a "unit" if it has only one constructor
- and that all arguments expected by this constructor are
- logical, this is the case for equality, conjunction of logical properties
-*)
-let is_unit constrsinfos =
- match constrsinfos with (* One info = One constructor *)
- | [level] -> is_type0m_univ level
- | [] -> (* type without constructors *) true
- | _ -> false
-
let infos_and_sort env t =
let rec aux env t max =
let t = whd_all env t in
@@ -174,10 +164,9 @@ let infer_constructor_packet env_ar_par params lc =
let lc'' = Array.map (fun j -> Term.it_mkProd_or_LetIn j.utj_val params) jlc in
(* compute the max of the sorts of the products of the constructors types *)
let levels = List.map (infos_and_sort env_ar_par) lc in
- let isunit = is_unit levels in
let min = if Array.length jlc > 1 then Universe.type0 else Universe.type0m in
let level = List.fold_left (fun max l -> Universe.sup max l) min levels in
- (lc'', (isunit, level))
+ (lc'', level)
(* If indices matter *)
let cumulate_arity_large_levels env sign =
@@ -354,7 +343,7 @@ let typecheck_inductive env mie =
(* Compute/check the sorts of the inductive types *)
let inds =
- Array.map (fun ((id,full_arity,sign,expltype,def_level,inf_level),cn,lc,(is_unit,clev)) ->
+ Array.map (fun ((id,full_arity,sign,expltype,def_level,inf_level),cn,lc,clev) ->
let infu =
(** Inferred level, with parameters and constructors. *)
match inf_level with
@@ -425,7 +414,7 @@ let typecheck_inductive env mie =
type ill_formed_ind =
| LocalNonPos of int
| LocalNotEnoughArgs of int
- | LocalNotConstructor of Context.Rel.t * int
+ | LocalNotConstructor of Constr.rel_context * int
| LocalNonPar of int * int * int
exception IllFormedInd of ill_formed_ind
@@ -797,15 +786,23 @@ exception UndefinableExpansion
build an expansion function.
The term built is expecting to be substituted first by
a substitution of the form [params, x : ind params] *)
-let compute_projections ((kn, _ as ind), u) nparamargs params
- mind_consnrealdecls mind_consnrealargs paramslet ctx =
+let compute_projections (kn, i as ind) mib =
+ let pkt = mib.mind_packets.(i) in
+ let u = match mib.mind_universes with
+ | Monomorphic_ind _ -> Univ.Instance.empty
+ | Polymorphic_ind auctx -> Univ.make_abstract_instance auctx
+ | Cumulative_ind acumi -> Univ.make_abstract_instance (Univ.ACumulativityInfo.univ_context acumi)
+ in
+ let subst = List.init mib.mind_ntypes (fun i -> mkIndU ((kn, mib.mind_ntypes - i - 1), u)) in
+ let rctx, _ = decompose_prod_assum (substl subst pkt.mind_nf_lc.(0)) in
+ let ctx, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
let mp, dp, l = MutInd.repr3 kn in
(** We build a substitution smashing the lets in the record parameters so
that typechecking projections requires just a substitution and not
matching with a parameter context. *)
let paramsletsubst =
(* [Ind inst] is typed in context [params-wo-let] *)
- let inst' = rel_list 0 nparamargs in
+ let inst' = rel_list 0 mib.mind_nparams in
(* {params-wo-let |- subst:params] *)
let subst = subst_of_rel_context_instance paramslet inst' in
(* {params-wo-let, x:Ind inst' |- subst':(params,x:Ind inst)] *)
@@ -839,7 +836,7 @@ let compute_projections ((kn, _ as ind), u) nparamargs params
(* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
to [params, x:I |- t(proj1 x,..,projj x)] *)
let fterm = mkProj (Projection.make kn false, mkRel 1) in
- let body = { proj_ind = fst ind; proj_npars = nparamargs;
+ let body = { proj_ind = ind; proj_npars = mib.mind_nparams;
proj_arg = i; proj_type = projty; } in
(i + 1, j + 1, kn :: kns, body :: pbs, fterm :: letsubst)
| Anonymous -> raise UndefinableExpansion
@@ -932,33 +929,9 @@ let build_inductive env prv iu env_ar paramsctxt kn isrecord isfinite inds nmr r
mind_reloc_tbl = rtbl;
} in
let packets = Array.map2 build_one_packet inds recargs in
- let pkt = packets.(0) in
- let isrecord =
- match isrecord with
- | Some (Some rid) when pkt.mind_kelim == all_sorts
- && Array.length pkt.mind_consnames == 1
- && pkt.mind_consnrealargs.(0) > 0 ->
- (** The elimination criterion ensures that all projections can be defined. *)
- let u =
- match aiu with
- | Monomorphic_ind _ -> Univ.Instance.empty
- | Polymorphic_ind auctx -> Univ.make_abstract_instance auctx
- | Cumulative_ind acumi -> Univ.make_abstract_instance (Univ.ACumulativityInfo.univ_context acumi)
- in
- let indsp = ((kn, 0), u) in
- let rctx, indty = decompose_prod_assum (subst1 (mkIndU indsp) pkt.mind_nf_lc.(0)) in
- (try
- let fields, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
- let kns, projs =
- compute_projections indsp nparamargs paramsctxt
- pkt.mind_consnrealdecls pkt.mind_consnrealargs paramslet fields
- in Some (Some (rid, kns, projs))
- with UndefinableExpansion -> Some None)
- | Some _ -> Some None
- | None -> None
- in
- (* Build the mutual inductive *)
- { mind_record = isrecord;
+ let mib =
+ (* Build the mutual inductive *)
+ { mind_record = NotRecord;
mind_ntypes = ntypes;
mind_finite = isfinite;
mind_hyps = hyps;
@@ -970,6 +943,27 @@ let build_inductive env prv iu env_ar paramsctxt kn isrecord isfinite inds nmr r
mind_private = prv;
mind_typing_flags = Environ.typing_flags env;
}
+ in
+ let record_info = match isrecord with
+ | Some (Some rid) ->
+ let is_record pkt =
+ pkt.mind_kelim == all_sorts
+ && Array.length pkt.mind_consnames == 1
+ && pkt.mind_consnrealargs.(0) > 0
+ in
+ (** The elimination criterion ensures that all projections can be defined. *)
+ if Array.for_all is_record packets then
+ let map i id =
+ let kn, projs = compute_projections (kn, i) mib in
+ (id, kn, projs)
+ in
+ try PrimRecord (Array.mapi map rid)
+ with UndefinableExpansion -> FakeRecord
+ else FakeRecord
+ | Some None -> FakeRecord
+ | None -> NotRecord
+ in
+ { mib with mind_record = record_info }
(************************************************************************)
(************************************************************************)
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index 45228e35e..7c36dac67 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -43,7 +43,5 @@ val check_inductive : env -> MutInd.t -> mutual_inductive_entry -> mutual_induct
val enforce_indices_matter : unit -> unit
val is_indices_matter : unit -> bool
-val compute_projections : pinductive ->
- int -> Context.Rel.t -> int array -> int array ->
- Context.Rel.t -> Context.Rel.t ->
- (Constant.t array * projection_body array)
+val compute_projections : inductive ->
+ mutual_inductive_body -> (Constant.t array * projection_body array)
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 090acdf16..88b00600e 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -130,11 +130,6 @@ where
Remark: Set (predicative) is encoded as Type(0)
*)
-let sort_as_univ = let open Sorts in function
-| Type u -> u
-| Prop Null -> Universe.type0m
-| Prop Pos -> Universe.type0
-
(* Template polymorphism *)
(* cons_subst add the mapping [u |-> su] in subst if [u] is not *)
@@ -168,7 +163,7 @@ let make_subst env =
(* arity is a global level which, at typing time, will be enforce *)
(* to be greater than the level of the argument; this is probably *)
(* a useless extra constraint *)
- let s = sort_as_univ (snd (dest_arity env (Lazy.force a))) in
+ let s = Sorts.univ_of_sort (snd (dest_arity env (Lazy.force a))) in
make (cons_subst u s subst) (sign, exp, args)
| LocalAssum (na,t) :: sign, Some u::exp, [] ->
(* No more argument here: we add the remaining universes to the *)
@@ -236,8 +231,8 @@ let type_of_inductive_knowing_parameters env ?(polyprop=true) mip args =
(* The max of an array of universes *)
let cumulate_constructor_univ u = let open Sorts in function
- | Prop Null -> u
- | Prop Pos -> Universe.sup Universe.type0 u
+ | Prop -> u
+ | Set -> Universe.sup Universe.type0 u
| Type u' -> Universe.sup u u'
let max_inductive_sort =
@@ -293,8 +288,8 @@ let elim_sorts (_,mip) = mip.mind_kelim
let is_private (mib,_) = mib.mind_private = Some true
let is_primitive_record (mib,_) =
match mib.mind_record with
- | Some (Some _) -> true
- | _ -> false
+ | PrimRecord _ -> true
+ | NotRecord | FakeRecord -> false
let build_dependent_inductive ind (_,mip) params =
let realargs,_ = List.chop mip.mind_nrealdecls mip.mind_arity_ctxt in
@@ -790,7 +785,7 @@ let rec subterm_specif renv stack t =
| Lambda (x,a,b) ->
let () = assert (List.is_empty l) in
- let spec,stack' = extract_stack renv a stack in
+ let spec,stack' = extract_stack stack in
subterm_specif (push_var renv (x,a,spec)) stack' b
(* Metas and evars are considered OK *)
@@ -822,7 +817,7 @@ and stack_element_specif = function
|SClosure (h_renv,h) -> lazy_subterm_specif h_renv [] h
|SArg x -> x
-and extract_stack renv a = function
+and extract_stack = function
| [] -> Lazy.from_val Not_subterm , []
| h::t -> stack_element_specif h, t
@@ -853,7 +848,7 @@ let error_illegal_rec_call renv fx (arg_renv,arg) =
let error_partial_apply renv fx =
raise (FixGuardError (renv.env,NotEnoughArgumentsForFixCall fx))
-let filter_stack_domain env ci p stack =
+let filter_stack_domain env p stack =
let absctx, ar = dest_lam_assum env p in
(* Optimization: if the predicate is not dependent, no restriction is needed
and we avoid building the recargs tree. *)
@@ -938,7 +933,7 @@ let check_one_fix renv recpos trees def =
let case_spec = branches_specif renv
(lazy_subterm_specif renv [] c_0) ci in
let stack' = push_stack_closures renv l stack in
- let stack' = filter_stack_domain renv.env ci p stack' in
+ let stack' = filter_stack_domain renv.env p stack' in
Array.iteri (fun k br' ->
let stack_br = push_stack_args case_spec.(k) stack' in
check_rec_call renv stack_br br') lrest
@@ -981,7 +976,7 @@ let check_one_fix renv recpos trees def =
| Lambda (x,a,b) ->
let () = assert (List.is_empty l) in
check_rec_call renv [] a ;
- let spec, stack' = extract_stack renv a stack in
+ let spec, stack' = extract_stack stack in
check_rec_call (push_var renv (x,a,spec)) stack' b
| Prod (x,a,b) ->
diff --git a/kernel/inductive.mli b/kernel/inductive.mli
index c7982f1fc..3c1464c6c 100644
--- a/kernel/inductive.mli
+++ b/kernel/inductive.mli
@@ -36,7 +36,7 @@ val lookup_mind_specif : env -> inductive -> mind_specif
(** {6 Functions to build standard types related to inductive } *)
val ind_subst : MutInd.t -> mutual_inductive_body -> Instance.t -> constr list
-val inductive_paramdecls : mutual_inductive_body puniverses -> Context.Rel.t
+val inductive_paramdecls : mutual_inductive_body puniverses -> Constr.rel_context
val instantiate_inductive_constraints :
mutual_inductive_body -> Instance.t -> Constraint.t
@@ -87,7 +87,7 @@ val build_branches_type :
constr list -> constr -> types array
(** Return the arity of an inductive type *)
-val mind_arity : one_inductive_body -> Context.Rel.t * Sorts.family
+val mind_arity : one_inductive_body -> Constr.rel_context * Sorts.family
val inductive_sort_family : one_inductive_body -> Sorts.family
@@ -115,8 +115,8 @@ exception SingletonInductiveBecomesProp of Id.t
val max_inductive_sort : Sorts.t array -> Universe.t
-val instantiate_universes : env -> Context.Rel.t ->
- template_arity -> constr Lazy.t array -> Context.Rel.t * Sorts.t
+val instantiate_universes : env -> Constr.rel_context ->
+ template_arity -> constr Lazy.t array -> Constr.rel_context * Sorts.t
(** {6 Debug} *)
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 50713b957..07a02f6ef 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -5,8 +5,8 @@ UGraph
Esubst
Sorts
Evar
-Constr
Context
+Constr
Vars
Term
Mod_subst
diff --git a/kernel/modops.ml b/kernel/modops.ml
index 22f523a9a..98a997311 100644
--- a/kernel/modops.ml
+++ b/kernel/modops.ml
@@ -47,7 +47,6 @@ type signature_mismatch_error =
| RecordFieldExpected of bool
| RecordProjectionsExpected of Name.t list
| NotEqualInductiveAliases
- | NoTypeConstraintExpected
| IncompatibleInstances
| IncompatibleUniverses of Univ.univ_inconsistency
| IncompatiblePolymorphism of env * types * types
@@ -266,7 +265,7 @@ let subst_structure subst = subst_structure subst do_delta_codom
(* spiwack: here comes the function which takes care of importing
the retroknowledge declared in the library *)
(* lclrk : retroknowledge_action list, rkaction : retroknowledge action *)
-let add_retroknowledge mp =
+let add_retroknowledge =
let perform rkaction env = match rkaction with
| Retroknowledge.RKRegister (f, e) when (isConst e || isInd e) ->
Environ.register env f e
@@ -310,7 +309,7 @@ and add_module mb linkinfo env =
let env = Environ.shallow_add_module mb env in
match mb.mod_type with
|NoFunctor struc ->
- add_retroknowledge mp mb.mod_retroknowledge
+ add_retroknowledge mb.mod_retroknowledge
(add_structure mp struc mb.mod_delta linkinfo env)
|MoreFunctor _ -> env
diff --git a/kernel/modops.mli b/kernel/modops.mli
index ac76d28cf..8e7e618fc 100644
--- a/kernel/modops.mli
+++ b/kernel/modops.mli
@@ -106,7 +106,6 @@ type signature_mismatch_error =
| RecordFieldExpected of bool
| RecordProjectionsExpected of Name.t list
| NotEqualInductiveAliases
- | NoTypeConstraintExpected
| IncompatibleInstances
| IncompatibleUniverses of Univ.univ_inconsistency
| IncompatiblePolymorphism of env * types * types
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 8257dc8b8..39f7de942 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -71,6 +71,8 @@ let eq_gname gn1 gn2 =
String.equal s1 s2 && eq_constructor c1 c2
| Gconstant (s1, c1), Gconstant (s2, c2) ->
String.equal s1 s2 && Constant.equal c1 c2
+ | Gproj (s1, ind1, i1), Gproj (s2, ind2, i2) ->
+ String.equal s1 s2 && eq_ind ind1 ind2 && Int.equal i1 i2
| Gcase (None, i1), Gcase (None, i2) -> Int.equal i1 i2
| Gcase (Some l1, i1), Gcase (Some l2, i2) -> Int.equal i1 i2 && Label.equal l1 l2
| Gpred (None, i1), Gpred (None, i2) -> Int.equal i1 i2
@@ -86,7 +88,9 @@ let eq_gname gn1 gn2 =
| Ginternal s1, Ginternal s2 -> String.equal s1 s2
| Grel i1, Grel i2 -> Int.equal i1 i2
| Gnamed id1, Gnamed id2 -> Id.equal id1 id2
- | _ -> false
+ | (Gind _| Gconstruct _ | Gconstant _ | Gproj _ | Gcase _ | Gpred _
+ | Gfixtype _ | Gnorm _ | Gnormtbl _ | Ginternal _ | Grel _ | Gnamed _), _ ->
+ false
let dummy_gname =
Grel 0
@@ -1645,15 +1649,15 @@ let pp_mllam fmt l =
and pp_letrec fmt defs =
let len = Array.length defs in
- let pp_one_rec i (fn, argsn, body) =
+ let pp_one_rec (fn, argsn, body) =
Format.fprintf fmt "%a%a =@\n %a"
pp_lname fn
pp_ldecls argsn pp_mllam body in
Format.fprintf fmt "@[let rec ";
- pp_one_rec 0 defs.(0);
+ pp_one_rec defs.(0);
for i = 1 to len - 1 do
Format.fprintf fmt "@\nand ";
- pp_one_rec i defs.(i)
+ pp_one_rec defs.(i)
done;
and pp_blam fmt l =
@@ -1841,7 +1845,7 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
in
let auxdefs = List.fold_right get_rel_val fv_rel auxdefs in
let auxdefs = List.fold_right get_named_val fv_named auxdefs in
- let lvl = Context.Rel.length env.env_rel_context.env_rel_ctx in
+ let lvl = Context.Rel.length (rel_context env) in
let fv_rel = List.map (fun (n,_) -> MLglobal (Grel (lvl-n))) fv_rel in
let fv_named = List.map (fun (id,_) -> MLglobal (Gnamed id)) fv_named in
let aux_name = fresh_lname Anonymous in
@@ -1850,7 +1854,7 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
and compile_rel env sigma univ auxdefs n =
let open Context.Rel.Declaration in
let decl = lookup_rel n env in
- let n = List.length env.env_rel_context.env_rel_ctx - n in
+ let n = List.length (rel_context env) - n in
match decl with
| LocalDef (_,t,_) ->
let code = lambda_of_constr env sigma t in
@@ -1937,7 +1941,7 @@ let is_code_loaded ~interactive name =
let param_name = Name (Id.of_string "params")
let arg_name = Name (Id.of_string "arg")
-let compile_mind prefix ~interactive mb mind stack =
+let compile_mind mb mind stack =
let u = Declareops.inductive_polymorphic_context mb in
(** Generate data for every block *)
let f i stack ob =
@@ -1965,6 +1969,7 @@ let compile_mind prefix ~interactive mb mind stack =
in
let constructors = Array.fold_left_i add_construct [] ob.mind_reloc_tbl in
let add_proj j acc pb =
+ let () = assert (eq_ind ind pb.proj_ind) in
let tbl = ob.mind_reloc_tbl in
(* Building info *)
let ci = { ci_ind = ind; ci_npar = nparams;
@@ -1985,12 +1990,14 @@ let compile_mind prefix ~interactive mb mind stack =
let accu_br = MLapp (MLprimitive Mk_proj, [|get_proj_code i;accu|]) in
let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
let code = MLlet(cf_uid, MLapp (MLprimitive Force_cofix, [|MLlocal c_uid|]), code) in
- let gn = Gproj ("", (pb.proj_ind, j), pb.proj_arg) in
+ let gn = Gproj ("", ind, pb.proj_arg) in
Glet (gn, mkMLlam [|c_uid|] code) :: acc
in
let projs = match mb.mind_record with
- | None | Some None -> []
- | Some (Some (id, kns, pbs)) -> Array.fold_left_i add_proj [] pbs
+ | NotRecord | FakeRecord -> []
+ | PrimRecord info ->
+ let _, _, pbs = info.(i) in
+ Array.fold_left_i add_proj [] pbs
in
projs @ constructors @ gtype :: accu :: stack
in
@@ -2013,7 +2020,7 @@ let compile_mind_deps env prefix ~interactive
then init
else
let comp_stack =
- compile_mind prefix ~interactive mib mind comp_stack
+ compile_mind mib mind comp_stack
in
let name =
if interactive then LinkedInteractive prefix
@@ -2052,7 +2059,7 @@ let compile_deps env sigma prefix ~interactive init t =
| Construct (((mind,_),_),u) -> compile_mind_deps env prefix ~interactive init mind
| Proj (p,c) ->
let pb = lookup_projection p env in
- let init = compile_mind_deps env prefix ~interactive init pb.proj_ind in
+ let init = compile_mind_deps env prefix ~interactive init (fst pb.proj_ind) in
aux env lvl init c
| Case (ci, p, c, ac) ->
let mind = fst ci.ci_ind in
@@ -2085,9 +2092,9 @@ let compile_constant_field env prefix con acc cb =
in
gl@acc
-let compile_mind_field prefix mp l acc mb =
+let compile_mind_field mp l acc mb =
let mind = MutInd.make2 mp l in
- compile_mind prefix ~interactive:false mb mind acc
+ compile_mind mb mind acc
let mk_open s = Gopen s
diff --git a/kernel/nativecode.mli b/kernel/nativecode.mli
index 684983a87..96efa7faa 100644
--- a/kernel/nativecode.mli
+++ b/kernel/nativecode.mli
@@ -67,7 +67,7 @@ val register_native_file : string -> unit
val compile_constant_field : env -> string -> Constant.t ->
global list -> constant_body -> global list
-val compile_mind_field : string -> ModPath.t -> Label.t ->
+val compile_mind_field : ModPath.t -> Label.t ->
global list -> mutual_inductive_body -> global list
val mk_conv_code : env -> evars -> string -> constr -> constr -> linkable_code
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index 0325a00b4..5843cd543 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -432,7 +432,6 @@ module Renv =
r
end
-(* What about pattern matching ?*)
let is_lazy prefix t =
match kind t with
| App (f,args) ->
@@ -448,7 +447,7 @@ let is_lazy prefix t =
with Not_found -> true)
| _ -> true
end
- | LetIn _ -> true
+ | LetIn _ | Case _ | Proj _ -> true
| _ -> false
let evar_value sigma ev = sigma.evars_val ev
@@ -520,8 +519,7 @@ let rec lambda_of_constr env sigma c =
| Proj (p, c) ->
let pb = lookup_projection p !global_env in
- (** FIXME: handle mutual records *)
- let ind = (pb.proj_ind, 0) in
+ let ind = pb.proj_ind in
let prefix = get_mind_prefix !global_env (fst ind) in
mkLapp (Lproj (prefix, ind, pb.proj_arg)) [|lambda_of_constr env sigma c|]
@@ -661,7 +659,7 @@ let optimize lam =
let lambda_of_constr env sigma c =
set_global_env env;
let env = Renv.make () in
- let ids = List.rev_map RelDecl.get_name !global_env.env_rel_context.env_rel_ctx in
+ let ids = List.rev_map RelDecl.get_name (rel_context !global_env) in
Renv.push_rels env (Array.of_list ids);
let lam = lambda_of_constr env sigma c in
(* if Flags.vm_draw_opt () then begin
diff --git a/kernel/nativelibrary.ml b/kernel/nativelibrary.ml
index 8bff43632..edce9367f 100644
--- a/kernel/nativelibrary.ml
+++ b/kernel/nativelibrary.ml
@@ -37,7 +37,7 @@ and translate_field prefix mp env acc (l,x) =
let id = mb.mind_packets.(0).mind_typename in
let msg = Printf.sprintf "Compiling inductive %s..." (Id.to_string id) in
Feedback.msg_debug (Pp.str msg));
- compile_mind_field prefix mp l acc mb
+ compile_mind_field mp l acc mb
| SFBmodule md ->
let mp = md.mod_mp in
(if !Flags.debug then
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index da4413a0a..3901cb9ce 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -116,7 +116,7 @@ let mk_ind_accu ind u =
let mk_sort_accu s u =
let open Sorts in
match s with
- | Prop _ -> mk_accu (Asort s)
+ | Prop | Set -> mk_accu (Asort s)
| Type s ->
let u = Univ.Instance.of_array u in
let s = Univ.subst_instance_universe u s in
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index a484c08e8..f8b71e456 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -18,7 +18,7 @@ type work_list = (Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.Named.t * Univ.Instance.t * Univ.AUContext.t }
+ abstract : Constr.named_context * Univ.Instance.t * Univ.AUContext.t }
type proofterm = (constr * Univ.ContextSet.t) Future.computation
type opaque =
| Indirect of substitution list * DirPath.t * int (* subst, lib, index *)
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index b6ae80b46..5ea6da649 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -51,7 +51,7 @@ type work_list = (Univ.Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.Named.t * Univ.Instance.t * Univ.AUContext.t }
+ abstract : Constr.named_context * Univ.Instance.t * Univ.AUContext.t }
(* The type has two caveats:
1) cook_constr is defined after
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index f4af31386..3228a155f 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -649,23 +649,19 @@ let check_leq univs u u' =
let check_sort_cmp_universes env pb s0 s1 univs =
let open Sorts in
if not (type_in_type env) then
+ let check_pb u0 u1 =
+ match pb with
+ | CUMUL -> check_leq univs u0 u1
+ | CONV -> check_eq univs u0 u1
+ in
match (s0,s1) with
- | (Prop c1, Prop c2) when is_cumul pb ->
- begin match c1, c2 with
- | Null, _ | _, Pos -> () (* Prop <= Set *)
- | _ -> raise NotConvertible
- end
- | (Prop c1, Prop c2) -> if c1 != c2 then raise NotConvertible
- | (Prop c1, Type u) ->
- let u0 = univ_of_sort s0 in
- (match pb with
- | CUMUL -> check_leq univs u0 u
- | CONV -> check_eq univs u0 u)
- | (Type u, Prop c) -> raise NotConvertible
- | (Type u1, Type u2) ->
- (match pb with
- | CUMUL -> check_leq univs u1 u2
- | CONV -> check_eq univs u1 u2)
+ | Prop, Prop | Set, Set -> ()
+ | Prop, (Set | Type _) -> if not (is_cumul pb) then raise NotConvertible
+ | Set, Prop -> raise NotConvertible
+ | Set, Type u -> check_pb Univ.type0_univ u
+ | Type u, Prop -> raise NotConvertible
+ | Type u, Set -> check_pb u Univ.type0_univ
+ | Type u0, Type u1 -> check_pb u0 u1
let checked_sort_cmp_universes env pb s0 s1 univs =
check_sort_cmp_universes env pb s0 s1 univs; univs
@@ -693,30 +689,27 @@ let infer_eq (univs, cstrs as cuniv) u u' =
let infer_leq (univs, cstrs as cuniv) u u' =
if UGraph.check_leq univs u u' then cuniv
else
- let cstrs' = Univ.enforce_leq u u' cstrs in
- univs, cstrs'
+ let cstrs', _ = UGraph.enforce_leq_alg u u' univs in
+ univs, Univ.Constraint.union cstrs cstrs'
let infer_cmp_universes env pb s0 s1 univs =
- let open Sorts in
- if type_in_type env then univs
+ if type_in_type env
+ then univs
else
+ let open Sorts in
+ let infer_pb u0 u1 =
+ match pb with
+ | CUMUL -> infer_leq univs u0 u1
+ | CONV -> infer_eq univs u0 u1
+ in
match (s0,s1) with
- | (Prop c1, Prop c2) when is_cumul pb ->
- begin match c1, c2 with
- | Null, _ | _, Pos -> univs (* Prop <= Set *)
- | _ -> raise NotConvertible
- end
- | (Prop c1, Prop c2) -> if c1 == c2 then univs else raise NotConvertible
- | (Prop c1, Type u) ->
- let u0 = univ_of_sort s0 in
- (match pb with
- | CUMUL -> infer_leq univs u0 u
- | CONV -> infer_eq univs u0 u)
- | (Type u, Prop c) -> raise NotConvertible
- | (Type u1, Type u2) ->
- (match pb with
- | CUMUL -> infer_leq univs u1 u2
- | CONV -> infer_eq univs u1 u2)
+ | Prop, Prop | Set, Set -> univs
+ | Prop, (Set | Type _) -> if not (is_cumul pb) then raise NotConvertible else univs
+ | Set, Prop -> raise NotConvertible
+ | Set, Type u -> infer_pb Univ.type0_univ u
+ | Type u, Prop -> raise NotConvertible
+ | Type u, Set -> infer_pb u Univ.type0_univ
+ | Type u0, Type u1 -> infer_pb u0 u1
let infer_convert_instances ~flex u u' (univs,cstrs) =
let cstrs' =
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index e53ab6aef..581e8bd88 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -116,10 +116,10 @@ val betazeta_appvect : int -> constr -> constr array -> constr
(***********************************************************************
s Recognizing products and arities modulo reduction *)
-val dest_prod : env -> types -> Context.Rel.t * types
-val dest_prod_assum : env -> types -> Context.Rel.t * types
-val dest_lam : env -> types -> Context.Rel.t * constr
-val dest_lam_assum : env -> types -> Context.Rel.t * types
+val dest_prod : env -> types -> Constr.rel_context * types
+val dest_prod_assum : env -> types -> Constr.rel_context * types
+val dest_lam : env -> constr -> Constr.rel_context * constr
+val dest_lam_assum : env -> constr -> Constr.rel_context * constr
exception NotArity
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 12c82e20d..f87ec9e02 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -897,9 +897,11 @@ let typing senv = Typeops.infer (env_of_senv senv)
(** {6 Retroknowledge / native compiler } *)
+[@@@ocaml.warning "-3"]
(** universal lifting, used for the "get" operations mostly *)
let retroknowledge f senv =
Environ.retroknowledge f (env_of_senv senv)
+[@@@ocaml.warning "+3"]
let register field value by_clause senv =
(* todo : value closed, by_clause safe, by_clause of the proper type*)
@@ -918,7 +920,7 @@ let register_inline kn senv =
if not (evaluable_constant kn senv.env) then
CErrors.user_err Pp.(str "Register inline: an evaluable constant is expected");
let env = senv.env in
- let (cb,r) = Cmap_env.find kn env.env_globals.env_constants in
+ let cb = lookup_constant kn env in
let cb = {cb with const_inline_code = true} in
let env = add_constant kn cb env in { senv with env}
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index 4078a9092..aca77ccd1 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -221,6 +221,7 @@ val delta_of_senv :
open Retroknowledge
val retroknowledge : (retroknowledge-> 'a) -> safe_environment -> 'a
+[@@ocaml.deprecated "Use the projection of Environ.env"]
val register :
field -> Retroknowledge.entry -> Constr.constr -> safe_transformer0
diff --git a/kernel/sorts.ml b/kernel/sorts.ml
index daeb90be7..a7bb08f5b 100644
--- a/kernel/sorts.ml
+++ b/kernel/sorts.ml
@@ -10,22 +10,21 @@
open Univ
-type contents = Pos | Null
-
type family = InProp | InSet | InType
type t =
- | Prop of contents (* proposition types *)
+ | Prop
+ | Set
| Type of Universe.t
-let prop = Prop Null
-let set = Prop Pos
+let prop = Prop
+let set = Set
let type1 = Type type1_univ
let univ_of_sort = function
| Type u -> u
- | Prop Pos -> Universe.type0
- | Prop Null -> Universe.type0m
+ | Set -> Universe.type0
+ | Prop -> Universe.type0m
let sort_of_univ u =
if is_type0m_univ u then prop
@@ -34,36 +33,34 @@ let sort_of_univ u =
let compare s1 s2 =
if s1 == s2 then 0 else
- match s1, s2 with
- | Prop c1, Prop c2 ->
- begin match c1, c2 with
- | Pos, Pos | Null, Null -> 0
- | Pos, Null -> -1
- | Null, Pos -> 1
- end
- | Type u1, Type u2 -> Universe.compare u1 u2
- | Prop _, Type _ -> -1
- | Type _, Prop _ -> 1
+ match s1, s2 with
+ | Prop, Prop -> 0
+ | Prop, _ -> -1
+ | Set, Prop -> 1
+ | Set, Set -> 0
+ | Set, _ -> -1
+ | Type u1, Type u2 -> Universe.compare u1 u2
+ | Type _, _ -> -1
let equal s1 s2 = Int.equal (compare s1 s2) 0
let is_prop = function
- | Prop Null -> true
+ | Prop -> true
| Type u when Universe.equal Universe.type0m u -> true
| _ -> false
let is_set = function
- | Prop Pos -> true
+ | Set -> true
| Type u when Universe.equal Universe.type0 u -> true
| _ -> false
let is_small = function
- | Prop _ -> true
+ | Prop | Set -> true
| Type u -> is_small_univ u
let family = function
- | Prop Null -> InProp
- | Prop Pos -> InSet
+ | Prop -> InProp
+ | Set -> InSet
| Type u when is_type0m_univ u -> InProp
| Type u when is_type0_univ u -> InSet
| Type _ -> InType
@@ -73,15 +70,11 @@ let family_equal = (==)
open Hashset.Combine
let hash = function
-| Prop p ->
- let h = match p with
- | Pos -> 0
- | Null -> 1
- in
- combinesmall 1 h
-| Type u ->
- let h = Univ.Universe.hash u in
- combinesmall 2 h
+ | Prop -> combinesmall 1 0
+ | Set -> combinesmall 1 1
+ | Type u ->
+ let h = Univ.Universe.hash u in
+ combinesmall 2 h
module List = struct
let mem = List.memq
@@ -101,7 +94,7 @@ module Hsorts =
if u' == u then c else Type u'
| s -> s
let eq s1 s2 = match (s1,s2) with
- | (Prop c1, Prop c2) -> c1 == c2
+ | Prop, Prop | Set, Set -> true
| (Type u1, Type u2) -> u1 == u2
|_ -> false
diff --git a/kernel/sorts.mli b/kernel/sorts.mli
index 1bbde2608..cac6229b9 100644
--- a/kernel/sorts.mli
+++ b/kernel/sorts.mli
@@ -10,13 +10,12 @@
(** {6 The sorts of CCI. } *)
-type contents = Pos | Null
-
type family = InProp | InSet | InType
type t =
-| Prop of contents (** Prop and Set *)
-| Type of Univ.Universe.t (** Type *)
+ | Prop
+ | Set
+ | Type of Univ.Universe.t
val set : t
val prop : t
diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml
index 8cf588c3e..74042f9e0 100644
--- a/kernel/subtyping.ml
+++ b/kernel/subtyping.ml
@@ -17,7 +17,6 @@
open Names
open Univ
open Util
-open Term
open Constr
open Declarations
open Declareops
@@ -138,39 +137,8 @@ let check_inductive cst env mp1 l info1 mp2 mib2 spec2 subst1 subst2 reso1 reso2
in
let mib2 = Declareops.subst_mind_body subst2 mib2 in
let check_inductive_type cst name t1 t2 =
-
- (* Due to template polymorphism, the conclusions of
- t1 and t2, if in Type, are generated as the least upper bounds
- of the types of the constructors.
-
- By monotonicity of the infered l.u.b. wrt subtyping (i.e. if X:U
- |- T(X):s and |- M:U' and U'<=U then infer_type(T(M))<=s), each
- universe in the conclusion of t1 has an bounding universe in
- the conclusion of t2, so that we don't need to check the
- subtyping of the conclusions of t1 and t2.
-
- Even if we'd like to recheck it, the inference of constraints
- is not designed to deal with algebraic constraints of the form
- max-univ(u1..un) <= max-univ(u'1..u'n), so that it is not easy
- to recheck it (in short, we would need the actual graph of
- constraints as input while type checking is currently designed
- to output a set of constraints instead) *)
-
- (* So we cheat and replace the subtyping problem on algebraic
- constraints of the form max-univ(u1..un) <= max-univ(u'1..u'n)
- (that we know are necessary true) by trivial constraints that
- the constraint generator knows how to deal with *)
-
- let (ctx1,s1) = dest_arity env t1 in
- let (ctx2,s2) = dest_arity env t2 in
- let s1,s2 =
- match s1, s2 with
- | Type _, Type _ -> (* shortcut here *) Sorts.prop, Sorts.prop
- | (Prop _, Type _) | (Type _,Prop _) ->
- error (NotConvertibleInductiveField name)
- | _ -> (s1, s2) in
check_conv (NotConvertibleInductiveField name)
- cst (inductive_is_polymorphic mib1) infer_conv_leq env (mkArity (ctx1,s1)) (mkArity (ctx2,s2))
+ cst (inductive_is_polymorphic mib1) infer_conv_leq env t1 t2
in
let check_packet cst p1 p2 =
@@ -226,8 +194,9 @@ let check_inductive cst env mp1 l info1 mp2 mib2 spec2 subst1 subst2 reso1 reso2
else error NotEqualInductiveAliases
end;
(* we check that records and their field names are preserved. *)
- check (fun mib -> mib.mind_record <> None) (==) (fun x -> RecordFieldExpected x);
- if mib1.mind_record <> None then begin
+ (** FIXME: this check looks nonsense *)
+ check (fun mib -> mib.mind_record <> NotRecord) (==) (fun x -> RecordFieldExpected x);
+ if mib1.mind_record <> NotRecord then begin
let rec names_prod_letin t = match kind t with
| Prod(n,_,t) -> n::(names_prod_letin t)
| LetIn(n,_,_,t) -> n::(names_prod_letin t)
@@ -255,57 +224,12 @@ let check_inductive cst env mp1 l info1 mp2 mib2 spec2 subst1 subst2 reso1 reso2
cst
-let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 =
+let check_constant cst env l info1 cb2 spec2 subst1 subst2 =
let error why = error_signature_mismatch l spec2 why in
let check_conv cst poly f = check_conv_error error cst poly f in
let check_type poly cst env t1 t2 =
-
let err = NotConvertibleTypeField (env, t1, t2) in
-
- (* If the type of a constant is generated, it may mention
- non-variable algebraic universes that the general conversion
- algorithm is not ready to handle. Anyway, generated types of
- constants are functions of the body of the constant. If the
- bodies are the same in environments that are subtypes one of
- the other, the types are subtypes too (i.e. if Gamma <= Gamma',
- Gamma |- A |> T, Gamma |- A' |> T' and Gamma |- A=A' then T <= T').
- Hence they don't have to be checked again *)
-
- let t1,t2 =
- if isArity t2 then
- let (ctx2,s2) = destArity t2 in
- match s2 with
- | Type v when not (is_univ_variable v) ->
- (* The type in the interface is inferred and is made of algebraic
- universes *)
- begin try
- let (ctx1,s1) = dest_arity env t1 in
- match s1 with
- | Type u when not (is_univ_variable u) ->
- (* Both types are inferred, no need to recheck them. We
- cheat and collapse the types to Prop *)
- mkArity (ctx1,Sorts.prop), mkArity (ctx2,Sorts.prop)
- | Prop _ ->
- (* The type in the interface is inferred, it may be the case
- that the type in the implementation is smaller because
- the body is more reduced. We safely collapse the upper
- type to Prop *)
- mkArity (ctx1,Sorts.prop), mkArity (ctx2,Sorts.prop)
- | Type _ ->
- (* The type in the interface is inferred and the type in the
- implementation is not inferred or is inferred but from a
- more reduced body so that it is just a variable. Since
- constraints of the form "univ <= max(...)" are not
- expressible in the system of algebraic universes: we fail
- (the user has to use an explicit type in the interface *)
- error NoTypeConstraintExpected
- with NotArity ->
- error err end
- | _ ->
- t1,t2
- else
- (t1,t2) in
- check_conv err cst poly infer_conv_leq env t1 t2
+ check_conv err cst poly infer_conv_leq env t1 t2
in
match info1 with
| Constant cb1 ->
@@ -368,7 +292,7 @@ and check_signatures cst env mp1 sig1 mp2 sig2 subst1 subst2 reso1 reso2=
let check_one_body cst (l,spec2) =
match spec2 with
| SFBconst cb2 ->
- check_constant cst env mp1 l (get_obj mp1 map1 l)
+ check_constant cst env l (get_obj mp1 map1 l)
cb2 spec2 subst1 subst2
| SFBmind mib2 ->
check_inductive cst env mp1 l (get_obj mp1 map1 l)
diff --git a/kernel/term.ml b/kernel/term.ml
index b44e038e9..4851a9c0d 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -16,14 +16,11 @@ open Vars
open Constr
(* Deprecated *)
-type contents = Sorts.contents = Pos | Null
-[@@ocaml.deprecated "Alias for Sorts.contents"]
-
type sorts_family = Sorts.family = InProp | InSet | InType
[@@ocaml.deprecated "Alias for Sorts.family"]
type sorts = Sorts.t =
- | Prop of Sorts.contents (** Prop and Set *)
+ | Prop | Set
| Type of Univ.Universe.t (** Type *)
[@@ocaml.deprecated "Alias for Sorts.t"]
@@ -339,7 +336,7 @@ let strip_lam_n n t = snd (decompose_lam_n n t)
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = Context.Rel.t * Sorts.t
+type arity = Constr.rel_context * Sorts.t
let destArity =
let open Context.Rel.Declaration in
diff --git a/kernel/term.mli b/kernel/term.mli
index f651d1a58..181d714ed 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -25,14 +25,14 @@ val mkNamedLetIn : Id.t -> constr -> types -> constr -> constr
val mkNamedProd : Id.t -> types -> types -> types
(** Constructs either [(x:t)c] or [[x=b:t]c] *)
-val mkProd_or_LetIn : Context.Rel.Declaration.t -> types -> types
-val mkProd_wo_LetIn : Context.Rel.Declaration.t -> types -> types
-val mkNamedProd_or_LetIn : Context.Named.Declaration.t -> types -> types
-val mkNamedProd_wo_LetIn : Context.Named.Declaration.t -> types -> types
+val mkProd_or_LetIn : Constr.rel_declaration -> types -> types
+val mkProd_wo_LetIn : Constr.rel_declaration -> types -> types
+val mkNamedProd_or_LetIn : Constr.named_declaration -> types -> types
+val mkNamedProd_wo_LetIn : Constr.named_declaration -> types -> types
(** Constructs either [[x:t]c] or [[x=b:t]c] *)
-val mkLambda_or_LetIn : Context.Rel.Declaration.t -> constr -> constr
-val mkNamedLambda_or_LetIn : Context.Named.Declaration.t -> constr -> constr
+val mkLambda_or_LetIn : Constr.rel_declaration -> constr -> constr
+val mkNamedLambda_or_LetIn : Constr.named_declaration -> constr -> constr
(** {5 Other term constructors. } *)
@@ -74,8 +74,8 @@ val to_lambda : int -> constr -> constr
where [l] is [fun (x_1:T_1)...(x_n:T_n) => T] *)
val to_prod : int -> constr -> constr
-val it_mkLambda_or_LetIn : constr -> Context.Rel.t -> constr
-val it_mkProd_or_LetIn : types -> Context.Rel.t -> types
+val it_mkLambda_or_LetIn : constr -> Constr.rel_context -> constr
+val it_mkProd_or_LetIn : types -> Constr.rel_context -> types
(** In [lambda_applist c args], [c] is supposed to have the form
[λΓ.c] with [Γ] without let-in; it returns [c] with the variables
@@ -126,29 +126,29 @@ val decompose_lam_n : int -> constr -> (Name.t * constr) list * constr
(** Extract the premisses and the conclusion of a term of the form
"(xi:Ti) ... (xj:=cj:Tj) ..., T" where T is not a product nor a let *)
-val decompose_prod_assum : types -> Context.Rel.t * types
+val decompose_prod_assum : types -> Constr.rel_context * types
(** Idem with lambda's and let's *)
-val decompose_lam_assum : constr -> Context.Rel.t * constr
+val decompose_lam_assum : constr -> Constr.rel_context * constr
(** Idem but extract the first [n] premisses, counting let-ins. *)
-val decompose_prod_n_assum : int -> types -> Context.Rel.t * types
+val decompose_prod_n_assum : int -> types -> Constr.rel_context * types
(** Idem for lambdas, _not_ counting let-ins *)
-val decompose_lam_n_assum : int -> constr -> Context.Rel.t * constr
+val decompose_lam_n_assum : int -> constr -> Constr.rel_context * constr
(** Idem, counting let-ins *)
-val decompose_lam_n_decls : int -> constr -> Context.Rel.t * constr
+val decompose_lam_n_decls : int -> constr -> Constr.rel_context * constr
(** Return the premisses/parameters of a type/term (let-in included) *)
-val prod_assum : types -> Context.Rel.t
-val lam_assum : constr -> Context.Rel.t
+val prod_assum : types -> Constr.rel_context
+val lam_assum : constr -> Constr.rel_context
(** Return the first n-th premisses/parameters of a type (let included and counted) *)
-val prod_n_assum : int -> types -> Context.Rel.t
+val prod_n_assum : int -> types -> Constr.rel_context
(** Return the first n-th premisses/parameters of a term (let included but not counted) *)
-val lam_n_assum : int -> constr -> Context.Rel.t
+val lam_n_assum : int -> constr -> Constr.rel_context
(** Remove the premisses/parameters of a type/term *)
val strip_prod : types -> types
@@ -167,7 +167,7 @@ val strip_lam_assum : constr -> constr
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = Context.Rel.t * Sorts.t
+type arity = Constr.rel_context * Sorts.t
(** Build an "arity" from its canonical form *)
val mkArity : arity -> types
@@ -190,13 +190,10 @@ type ('constr, 'types) kind_of_type =
val kind_of_type : types -> (constr, types) kind_of_type
(* Deprecated *)
-type contents = Sorts.contents = Pos | Null
-[@@ocaml.deprecated "Alias for Sorts.contents"]
-
type sorts_family = Sorts.family = InProp | InSet | InType
[@@ocaml.deprecated "Alias for Sorts.family"]
type sorts = Sorts.t =
- | Prop of Sorts.contents (** Prop and Set *)
+ | Prop | Set
| Type of Univ.Universe.t (** Type *)
[@@ocaml.deprecated "Alias for Sorts.t"]
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 37bf679c5..1f7ee145a 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -179,36 +179,36 @@ let rec is_nth_suffix n l suf =
| _ :: l -> is_nth_suffix (pred n) l suf
(* Given the list of signatures of side effects, checks if they match.
- * I.e. if they are ordered descendants of the current revstruct *)
+ * I.e. if they are ordered descendants of the current revstruct.
+ Returns the number of effects that can be trusted. *)
let check_signatures curmb sl =
- let is_direct_ancestor (sl, curmb) (mb, how_many) =
- match curmb with
- | None -> None, None
- | Some curmb ->
+ let is_direct_ancestor accu (mb, how_many) =
+ match accu with
+ | None -> None
+ | Some (n, curmb) ->
try
let mb = CEphemeron.get mb in
- match sl with
- | None -> sl, None
- | Some n ->
- if is_nth_suffix how_many mb curmb
- then Some (n + how_many), Some mb
- else None, None
- with CEphemeron.InvalidKey -> None, None in
- let sl, _ = List.fold_left is_direct_ancestor (Some 0,Some curmb) sl in
- sl
+ if is_nth_suffix how_many mb curmb
+ then Some (n + how_many, mb)
+ else None
+ with CEphemeron.InvalidKey -> None in
+ let sl = List.fold_left is_direct_ancestor (Some (0, curmb)) sl in
+ match sl with
+ | None -> 0
+ | Some (n, _) -> n
let skip_trusted_seff sl b e =
let rec aux sl b e acc =
let open Context.Rel.Declaration in
- match sl, kind b with
- | (None|Some 0), _ -> b, e, acc
- | Some sl, LetIn (n,c,ty,bo) ->
- aux (Some (sl-1)) bo
+ if Int.equal sl 0 then b, e, acc
+ else match kind b with
+ | LetIn (n,c,ty,bo) ->
+ aux (sl - 1) bo
(Environ.push_rel (LocalDef (n,c,ty)) e) (`Let(n,c,ty)::acc)
- | Some sl, App(hd,arg) ->
+ | App(hd,arg) ->
begin match kind hd with
| Lambda (n,ty,bo) ->
- aux (Some (sl-1)) bo
+ aux (sl - 1) bo
(Environ.push_rel (LocalAssum (n,ty)) e) (`Cut(n,ty,arg)::acc)
| _ -> assert false
end
@@ -378,7 +378,7 @@ let build_constant_declaration kn env result =
str "Proof using " ++ declared_vars ++ fnl () ++
str "to" ++ fnl () ++
str "Proof using " ++ inferred_vars) in
- let sort evn l =
+ let sort l =
List.filter (fun decl ->
let id = NamedDecl.get_id decl in
List.exists (NamedDecl.get_id %> Names.Id.equal id) l)
@@ -411,7 +411,7 @@ let build_constant_declaration kn env result =
[], def (* Empty section context: no need to check *)
| Some declared ->
(* We use the declared set and chain a check of correctness *)
- sort env declared,
+ sort declared,
match def with
| Undef _ as x -> x (* nothing to check *)
| Def cs as x ->
@@ -522,23 +522,24 @@ let export_side_effects mb env c =
end
in
let rec translate_seff sl seff acc env =
- match sl, seff with
- | _, [] -> List.rev acc, ce
- | (None | Some 0), cbs :: rest ->
+ match seff with
+ | [] -> List.rev acc, ce
+ | cbs :: rest ->
+ if Int.equal sl 0 then
let env, cbs =
List.fold_left (fun (env,cbs) (kn, ocb, u, r) ->
let ce = constant_entry_of_side_effect ocb u in
let cb = translate_constant Pure env kn ce in
(push_seff env (kn, cb,`Nothing, Subproof),(kn,cb,r) :: cbs))
(env,[]) cbs in
- translate_seff sl rest (cbs @ acc) env
- | Some sl, cbs :: rest ->
+ translate_seff 0 rest (cbs @ acc) env
+ else
let cbs_len = List.length cbs in
let cbs = List.map turn_direct cbs in
let env = List.fold_left push_seff env cbs in
let ecbs = List.map (fun (kn,cb,u,r) ->
kn, cb, r) cbs in
- translate_seff (Some (sl-cbs_len)) rest (ecbs @ acc) env
+ translate_seff (sl - cbs_len) rest (ecbs @ acc) env
in
translate_seff trusted seff [] env
;;
@@ -553,7 +554,7 @@ let translate_recipe env kn r =
be useless. It is detected by the dirpath of the constant being empty. *)
let (_, dir, _) = Constant.repr3 kn in
let hcons = DirPath.is_empty dir in
- build_constant_declaration kn env (Cooking.cook_constant ~hcons env r)
+ build_constant_declaration kn env (Cooking.cook_constant ~hcons r)
let translate_local_def env id centry =
let open Cooking in
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index 325d5cecd..7c0057696 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -69,7 +69,7 @@ let type_of_type u =
mkType uu
let type_of_sort = function
- | Prop c -> type1
+ | Prop | Set -> type1
| Type u -> type_of_type u
(*s Type of a de Bruijn index. *)
@@ -178,11 +178,11 @@ let type_of_apply env func funt argsv argstv =
let sort_of_product env domsort rangsort =
match (domsort, rangsort) with
(* Product rule (s,Prop,Prop) *)
- | (_, Prop Null) -> rangsort
+ | (_, Prop) -> rangsort
(* Product rule (Prop/Set,Set,Set) *)
- | (Prop _, Prop Pos) -> rangsort
+ | ((Prop | Set), Set) -> rangsort
(* Product rule (Type,Set,?) *)
- | (Type u1, Prop Pos) ->
+ | (Type u1, Set) ->
if is_impredicative_set env then
(* Rule is (Type,Set,Set) in the Set-impredicative calculus *)
rangsort
@@ -190,9 +190,9 @@ let sort_of_product env domsort rangsort =
(* Rule is (Type_i,Set,Type_i) in the Set-predicative calculus *)
Type (Universe.sup Universe.type0 u1)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Pos, Type u2) -> Type (Universe.sup Universe.type0 u2)
+ | (Set, Type u2) -> Type (Universe.sup Universe.type0 u2)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Null, Type _) -> rangsort
+ | (Prop, Type _) -> rangsort
(* Product rule (Type_i,Type_i,Type_i) *)
| (Type u1, Type u2) -> Type (Universe.sup u1 u2)
@@ -301,7 +301,7 @@ let type_of_projection env p c ct =
try find_rectype env ct
with Not_found -> error_case_not_inductive env (make_judge c ct)
in
- assert(MutInd.equal pb.proj_ind (fst ind));
+ assert(eq_ind pb.proj_ind ind);
let ty = Vars.subst_instance_constr u pb.Declarations.proj_type in
substl (c :: CList.rev args) ty
@@ -481,10 +481,6 @@ let judge_of_prop = make_judge mkProp type1
let judge_of_set = make_judge mkSet type1
let judge_of_type u = make_judge (mkType u) (type_of_type u)
-let judge_of_prop_contents = function
- | Null -> judge_of_prop
- | Pos -> judge_of_set
-
let judge_of_relative env k = make_judge (mkRel k) (type_of_relative env k)
let judge_of_variable env x = make_judge (mkVar x) (type_of_variable env x)
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index 546f2d2b4..57acdfe4b 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -28,7 +28,7 @@ val infer_v : env -> constr array -> unsafe_judgment array
val infer_type : env -> types -> unsafe_type_judgment
val infer_local_decls :
- env -> (Id.t * local_entry) list -> (env * Context.Rel.t)
+ env -> (Id.t * local_entry) list -> (env * Constr.rel_context)
(** {6 Basic operations of the typing machine. } *)
@@ -43,7 +43,6 @@ val type1 : types
val type_of_sort : Sorts.t -> types
val judge_of_prop : unsafe_judgment
val judge_of_set : unsafe_judgment
-val judge_of_prop_contents : Sorts.contents -> unsafe_judgment
val judge_of_type : Universe.t -> unsafe_judgment
(** {6 Type of a bound variable. } *)
@@ -103,4 +102,4 @@ val judge_of_case : env -> case_info
val type_of_constant_in : env -> pconstant -> types
(** Check that hyps are included in env and fails with error otherwise *)
-val check_hyps_inclusion : env -> ('a -> constr) -> 'a -> Context.Named.t -> unit
+val check_hyps_inclusion : env -> ('a -> constr) -> 'a -> Constr.named_context -> unit
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index 4a9467de5..bc624ba56 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -747,6 +747,45 @@ let check_constraint g (l,d,r) =
let check_constraints c g =
Constraint.for_all (check_constraint g) c
+let leq_expr (u,m) (v,n) =
+ let d = match m - n with
+ | 1 -> Lt
+ | diff -> assert (diff <= 0); Le
+ in
+ (u,d,v)
+
+let enforce_leq_alg u v g =
+ let enforce_one (u,v) = function
+ | Inr _ as orig -> orig
+ | Inl (cstrs,g) as orig ->
+ if check_smaller_expr g u v then orig
+ else
+ (let c = leq_expr u v in
+ match enforce_constraint c g with
+ | g -> Inl (Constraint.add c cstrs,g)
+ | exception (UniverseInconsistency _ as e) -> Inr e)
+ in
+ (* max(us) <= max(vs) <-> forall u in us, exists v in vs, u <= v *)
+ let c = Universe.map (fun u -> Universe.map (fun v -> (u,v)) v) u in
+ let c = List.cartesians enforce_one (Inl (Constraint.empty,g)) c in
+ (* We pick a best constraint: smallest number of constraints, not an error if possible. *)
+ let order x y = match x, y with
+ | Inr _, Inr _ -> 0
+ | Inl _, Inr _ -> -1
+ | Inr _, Inl _ -> 1
+ | Inl (c,_), Inl (c',_) ->
+ Int.compare (Constraint.cardinal c) (Constraint.cardinal c')
+ in
+ match List.min order c with
+ | Inl x -> x
+ | Inr e -> raise e
+
+(* sanity check wrapper *)
+let enforce_leq_alg u v g =
+ let _,g as cg = enforce_leq_alg u v g in
+ assert (check_leq g u v);
+ cg
+
(* Normalization *)
(** [normalize_universes g] returns a graph where all edges point
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
index e6dd629e4..8c2d877b0 100644
--- a/kernel/uGraph.mli
+++ b/kernel/uGraph.mli
@@ -42,6 +42,9 @@ val merge_constraints : Constraint.t -> t -> t
val check_constraint : t -> univ_constraint -> bool
val check_constraints : Constraint.t -> t -> bool
+(** Picks an arbitrary set of constraints sufficient to ensure [u <= v]. *)
+val enforce_leq_alg : Universe.t -> Universe.t -> t -> Constraint.t * t
+
(** Adds a universe to the graph, ensuring it is >= or > Set.
@raise AlreadyDeclared if the level is already declared in the graph. *)
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 9782312ca..311477dac 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -666,7 +666,7 @@ let constraint_add_leq v u c =
else (* j >= 1 *) (* m = n + k, u <= v+k *)
if Level.equal x y then c (* u <= u+k, trivial *)
else if Level.is_small x then c (* Prop,Set <= u+S k, trivial *)
- else anomaly (Pp.str"Unable to handle arbitrary u <= v+k constraints.")
+ else Constraint.add (x,Le,y) c (* u <= v implies u <= v+k *)
let check_univ_leq_one u v = Universe.exists (Expr.leq u) v
@@ -674,12 +674,7 @@ let check_univ_leq u v =
Universe.for_all (fun u -> check_univ_leq_one u v) u
let enforce_leq u v c =
- let rec aux acc v =
- match v with
- | v :: l ->
- aux (List.fold_right (fun u -> constraint_add_leq u v) u c) l
- | [] -> acc
- in aux c v
+ List.fold_left (fun c v -> (List.fold_left (fun c u -> constraint_add_leq u v c) c u)) c v
let enforce_leq u v c =
if check_univ_leq u v then c
diff --git a/kernel/vars.mli b/kernel/vars.mli
index a0c7ba4bd..fdddbdb34 100644
--- a/kernel/vars.mli
+++ b/kernel/vars.mli
@@ -70,10 +70,10 @@ type substl = constr list
as if usable in [applist] while the substitution is
represented the other way round, i.e. ending with either [u₁] or
[c₁], as if usable for [substl]. *)
-val subst_of_rel_context_instance : Context.Rel.t -> constr list -> substl
+val subst_of_rel_context_instance : Constr.rel_context -> constr list -> substl
(** For compatibility: returns the substitution reversed *)
-val adjust_subst_to_rel_context : Context.Rel.t -> constr list -> constr list
+val adjust_subst_to_rel_context : Constr.rel_context -> constr list -> constr list
(** Take an index in an instance of a context and returns its index wrt to
the full context (e.g. 2 in [x:A;y:=b;z:C] is 3, i.e. a reference to z) *)
@@ -97,13 +97,13 @@ val subst1 : constr -> constr -> constr
accordingly indexes in [a₁],...,[an] and [c]. In terms of typing, if
Γ ⊢ a{_n}..a₁ : Δ and Γ, Δ, Γ', Ω ⊢ with |Γ'|=[k], then
Γ, Γ', [substnl_decl [a₁;...;an]] k Ω ⊢. *)
-val substnl_decl : substl -> int -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val substnl_decl : substl -> int -> Constr.rel_declaration -> Constr.rel_declaration
(** [substl_decl σ Ω] is a short-hand for [substnl_decl σ 0 Ω] *)
-val substl_decl : substl -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val substl_decl : substl -> Constr.rel_declaration -> Constr.rel_declaration
(** [subst1_decl a Ω] is a short-hand for [substnl_decl [a] 0 Ω] *)
-val subst1_decl : constr -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val subst1_decl : constr -> Constr.rel_declaration -> Constr.rel_declaration
(** [replace_vars k [(id₁,c₁);...;(idn,cn)] t] substitutes [Var idj] by
[cj] in [t]. *)
@@ -134,8 +134,8 @@ open Univ
(** Level substitutions for polymorphism. *)
val subst_univs_level_constr : universe_level_subst -> constr -> constr
-val subst_univs_level_context : Univ.universe_level_subst -> Context.Rel.t -> Context.Rel.t
+val subst_univs_level_context : Univ.universe_level_subst -> Constr.rel_context -> Constr.rel_context
(** Instance substitution for polymorphism. *)
val subst_instance_constr : Instance.t -> constr -> constr
-val subst_instance_context : Instance.t -> Context.Rel.t -> Context.Rel.t
+val subst_instance_context : Instance.t -> Constr.rel_context -> Constr.rel_context
diff --git a/lib/cWarnings.ml b/lib/cWarnings.ml
index fda25a0a6..0cf989e49 100644
--- a/lib/cWarnings.ml
+++ b/lib/cWarnings.ml
@@ -120,7 +120,7 @@ let uniquize_flags_rev flags =
(** [normalize_flags] removes redundant warnings. Unknown warnings are kept
because they may be declared in a plugin that will be linked later. *)
-let normalize_flags ~silent warnings =
+let normalize_flags warnings =
let warnings = cut_before_all_rev warnings in
uniquize_flags_rev warnings
@@ -130,7 +130,7 @@ let normalize_flags_string s =
if is_none_keyword s then s
else
let flags = flags_of_string s in
- let flags = normalize_flags ~silent:false flags in
+ let flags = normalize_flags flags in
string_of_flags flags
let parse_warnings items =
@@ -146,7 +146,7 @@ let parse_flags s =
else begin
Flags.make_warn true;
let flags = flags_of_string s in
- let flags = normalize_flags ~silent:true flags in
+ let flags = normalize_flags flags in
parse_warnings flags;
string_of_flags flags
end
diff --git a/lib/coqProject_file.ml4 b/lib/coqProject_file.ml
index 61eb1dafd..c2bcd73ff 100644
--- a/lib/coqProject_file.ml4
+++ b/lib/coqProject_file.ml
@@ -90,30 +90,50 @@ let rec post_canonize f =
exception Parsing_error of string
-let rec parse_string = parser
- | [< '' ' | '\n' | '\t' >] -> ""
- | [< 'c; s >] -> (String.make 1 c)^(parse_string s)
- | [< >] -> ""
-and parse_string2 = parser
- | [< ''"' >] -> ""
- | [< 'c; s >] -> (String.make 1 c)^(parse_string2 s)
- | [< >] -> raise (Parsing_error "unterminated string")
-and parse_skip_comment = parser
- | [< ''\n'; s >] -> s
- | [< 'c; s >] -> parse_skip_comment s
- | [< >] -> [< >]
-and parse_args = parser
- | [< '' ' | '\n' | '\t'; s >] -> parse_args s
- | [< ''#'; s >] -> parse_args (parse_skip_comment s)
- | [< ''"'; str = parse_string2; s >] -> ("" ^ str) :: parse_args s
- | [< 'c; str = parse_string; s >] -> ((String.make 1 c) ^ str) :: (parse_args s)
- | [< >] -> []
+let buffer buf =
+ let ans = Buffer.contents buf in
+ let () = Buffer.clear buf in
+ ans
+
+let rec parse_string buf s = match Stream.next s with
+| ' ' | '\n' | '\t' -> buffer buf
+| c ->
+ let () = Buffer.add_char buf c in
+ parse_string buf s
+| exception Stream.Failure -> buffer buf
+
+and parse_string2 buf s = match Stream.next s with
+| '"' -> buffer buf
+| c ->
+ let () = Buffer.add_char buf c in
+ parse_string2 buf s
+| exception Stream.Failure -> raise (Parsing_error "unterminated string")
+
+and parse_skip_comment s = match Stream.next s with
+| '\n' -> ()
+| _ -> parse_skip_comment s
+| exception Stream.Failure -> ()
+
+and parse_args buf accu s = match Stream.next s with
+| ' ' | '\n' | '\t' -> parse_args buf accu s
+| '#' ->
+ let () = parse_skip_comment s in
+ parse_args buf accu s
+| '"' ->
+ let str = parse_string2 buf s in
+ parse_args buf (str :: accu) s
+| c ->
+ let () = Buffer.add_char buf c in
+ let str = parse_string buf s in
+ parse_args buf (str :: accu) s
+| exception Stream.Failure -> accu
let parse f =
let c = open_in f in
- let res = parse_args (Stream.of_channel c) in
+ let buf = Buffer.create 64 in
+ let res = parse_args buf [] (Stream.of_channel c) in
close_in c;
- res
+ List.rev res
;;
(* Copy from minisys.ml, since we don't see that file here *)
@@ -143,7 +163,7 @@ let process_cmd_line orig_dir proj args =
error "Use \"-install none\" instead of \"-no-install\""
| "-custom" :: _ ->
error "Use \"-extra[-phony] target deps command\" instead of \"-custom command deps target\""
-
+
| ("-no-opt"|"-byte") :: r -> aux { proj with use_ocamlopt = false } r
| ("-full"|"-opt") :: r -> aux { proj with use_ocamlopt = true } r
| "-install" :: d :: r ->
@@ -189,7 +209,7 @@ let process_cmd_line orig_dir proj args =
error "Output file must be in the current directory";
if proj.makefile <> None then
error "Option -o given more than once";
- aux { proj with makefile = Some file } r
+ aux { proj with makefile = Some file } r
| v :: "=" :: def :: r ->
aux { proj with defs = proj.defs @ [sourced (v,def)] } r
| "-arg" :: a :: r ->
diff --git a/lib/envars.ml b/lib/envars.ml
index be82bfe9b..3ee0c7106 100644
--- a/lib/envars.ml
+++ b/lib/envars.ml
@@ -110,6 +110,7 @@ let check_file_else ~dir ~file oth =
if Sys.file_exists (path / file) then path else oth ()
let guess_coqlib fail =
+ getenv_else "COQLIB" (fun () ->
let prelude = "theories/Init/Prelude.vo" in
check_file_else ~dir:Coq_config.coqlibsuffix ~file:prelude
(fun () ->
@@ -117,6 +118,7 @@ let guess_coqlib fail =
then Coq_config.coqlib
else
fail "cannot guess a path for Coq libraries; please use -coqlib option")
+ )
(** coqlib is now computed once during coqtop initialization *)
diff --git a/lib/system.ml b/lib/system.ml
index f109c7192..eef65a4e3 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -302,7 +302,7 @@ let with_time ~batch f x =
raise e
let get_toplevel_path top =
- let dir = Filename.dirname Sys.argv.(0) in
+ let dir = Filename.dirname Sys.executable_name in
let exe = if Sys.(os_type = "Win32" || os_type = "Cygwin") then ".exe" else "" in
let eff = if Dynlink.is_native then ".opt" else ".byte" in
dir ^ Filename.dir_sep ^ top ^ eff ^ exe
diff --git a/lib/util.ml b/lib/util.ml
index 7d7d380b2..38d73d345 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -38,8 +38,8 @@ let is_blank = function
module Empty =
struct
- type t
- let abort (x : t) = assert false
+ type t = { abort : 'a. 'a }
+ let abort (x : t) = x.abort
end
(* Strings *)
diff --git a/library/global.mli b/library/global.mli
index 57e173cb9..b2a191cee 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -23,7 +23,7 @@ val env_is_initial : unit -> bool
val universes : unit -> UGraph.t
val named_context_val : unit -> Environ.named_context_val
-val named_context : unit -> Context.Named.t
+val named_context : unit -> Constr.named_context
(** {6 Enriching the global environment } *)
@@ -79,7 +79,7 @@ val add_module_parameter :
(** {6 Queries in the global environment } *)
-val lookup_named : variable -> Context.Named.Declaration.t
+val lookup_named : variable -> Constr.named_declaration
val lookup_constant : Constant.t -> Declarations.constant_body
val lookup_inductive : inductive ->
Declarations.mutual_inductive_body * Declarations.one_inductive_body
diff --git a/library/lib.ml b/library/lib.ml
index 128b27e75..a20de55bf 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -405,7 +405,7 @@ let find_opening_node id =
- the list of substitution to do at section closing
*)
-type variable_info = Context.Named.Declaration.t * Decl_kinds.binding_kind
+type variable_info = Constr.named_declaration * Decl_kinds.binding_kind
type variable_context = variable_info list
type abstr_info = {
diff --git a/library/lib.mli b/library/lib.mli
index 1d77212e9..5abfccfc7 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -9,6 +9,7 @@
(************************************************************************)
open Names
+
(** Lib: record of operations, backtrack, low-level sections *)
(** This module provides a general mechanism to keep a trace of all operations
@@ -153,7 +154,7 @@ val unfreeze : frozen -> unit
val init : unit -> unit
(** {6 Section management for discharge } *)
-type variable_info = Context.Named.Declaration.t * Decl_kinds.binding_kind
+type variable_info = Constr.named_declaration * Decl_kinds.binding_kind
type variable_context = variable_info list
type abstr_info = private {
abstr_ctx : variable_context;
@@ -165,7 +166,7 @@ type abstr_info = private {
}
val instance_from_variable_context : variable_context -> Id.t array
-val named_of_variable_context : variable_context -> Context.Named.t
+val named_of_variable_context : variable_context -> Constr.named_context
val section_segment_of_constant : Constant.t -> abstr_info
val section_segment_of_mutual_inductive: MutInd.t -> abstr_info
@@ -179,9 +180,9 @@ val is_in_section : GlobRef.t -> bool
val add_section_variable : Id.t -> Decl_kinds.binding_kind -> Decl_kinds.polymorphic -> Univ.ContextSet.t -> unit
val add_section_context : Univ.ContextSet.t -> unit
val add_section_constant : Decl_kinds.polymorphic ->
- Constant.t -> Context.Named.t -> unit
+ Constant.t -> Constr.named_context -> unit
val add_section_kn : Decl_kinds.polymorphic ->
- MutInd.t -> Context.Named.t -> unit
+ MutInd.t -> Constr.named_context -> unit
val replacement_context : unit -> Opaqueproof.work_list
(** {6 Discharge: decrease the section level if in the current section } *)
diff --git a/library/libobject.ml b/library/libobject.ml
index c5cd01525..79a3fed1b 100644
--- a/library/libobject.ml
+++ b/library/libobject.ml
@@ -98,7 +98,7 @@ let declare_object_full odecl = declare_object_full odecl
(* this function describes how the cache, load, open, and export functions
are triggered. *)
-let apply_dyn_fun deflt f lobj =
+let apply_dyn_fun f lobj =
let tag = object_tag lobj in
let dodecl =
try Hashtbl.find cache_tab tag
@@ -107,24 +107,24 @@ let apply_dyn_fun deflt f lobj =
f dodecl
let cache_object ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_cache_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_cache_function node) lobj
let load_object i ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_load_function i node) lobj
+ apply_dyn_fun (fun d -> d.dyn_load_function i node) lobj
let open_object i ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_open_function i node) lobj
+ apply_dyn_fun (fun d -> d.dyn_open_function i node) lobj
let subst_object ((_,lobj) as node) =
- apply_dyn_fun lobj (fun d -> d.dyn_subst_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_subst_function node) lobj
let classify_object lobj =
- apply_dyn_fun Dispose (fun d -> d.dyn_classify_function lobj) lobj
+ apply_dyn_fun (fun d -> d.dyn_classify_function lobj) lobj
let discharge_object ((_,lobj) as node) =
- apply_dyn_fun None (fun d -> d.dyn_discharge_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_discharge_function node) lobj
let rebuild_object lobj =
- apply_dyn_fun lobj (fun d -> d.dyn_rebuild_function lobj) lobj
+ apply_dyn_fun (fun d -> d.dyn_rebuild_function lobj) lobj
let dump = Dyn.dump
diff --git a/library/library.ml b/library/library.ml
index 400f3dcf1..0ff82d7cc 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -167,7 +167,7 @@ let opened_libraries () = !libraries_imports_list
let register_loaded_library m =
let libname = m.libsum_name in
- let link m =
+ let link () =
let dirname = Filename.dirname (library_full_filename libname) in
let prefix = Nativecode.mod_uid_of_dirpath libname ^ "." in
let f = prefix ^ "cmo" in
@@ -176,7 +176,7 @@ let register_loaded_library m =
Nativelib.link_library ~prefix ~dirname ~basename:f
in
let rec aux = function
- | [] -> link m; [libname]
+ | [] -> link (); [libname]
| m'::_ as l when DirPath.equal m' libname -> l
| m'::l' -> m' :: aux l' in
libraries_loaded_list := aux !libraries_loaded_list;
@@ -288,16 +288,15 @@ let locate_absolute_library dir =
try
let name = Id.to_string base ^ ext in
let _, file = System.where_in_path ~warn:false loadpath name in
- [file]
- with Not_found -> [] in
- match find ".vo" @ find ".vio" with
- | [] -> raise LibNotFound
- | [file] -> file
- | [vo;vi] when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
+ Some file
+ with Not_found -> None in
+ match find ".vo", find ".vio" with
+ | None, None -> raise LibNotFound
+ | Some file, None | None, Some file -> file
+ | Some vo, Some vi when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
warn_several_object_files (vi, vo);
vi
- | [vo;vi] -> vo
- | _ -> assert false
+ | Some vo, Some _ -> vo
let locate_qualified_library ?root ?(warn = true) qid =
(* Search library in loadpath *)
@@ -309,18 +308,17 @@ let locate_qualified_library ?root ?(warn = true) qid =
let name = Id.to_string base ^ ext in
let lpath, file =
System.where_in_path ~warn (List.map fst loadpath) name in
- [lpath, file]
- with Not_found -> [] in
+ Some (lpath, file)
+ with Not_found -> None in
let lpath, file =
- match find ".vo" @ find ".vio" with
- | [] -> raise LibNotFound
- | [lpath, file] -> lpath, file
- | [lpath_vo, vo; lpath_vi, vi]
+ match find ".vo", find ".vio" with
+ | None, None -> raise LibNotFound
+ | Some res, None | None, Some res -> res
+ | Some (_, vo), Some (_, vi as resvi)
when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
warn_several_object_files (vi, vo);
- lpath_vi, vi
- | [lpath_vo, vo; _ ] -> lpath_vo, vo
- | _ -> assert false
+ resvi
+ | Some resvo, Some _ -> resvo
in
let dir = add_dirpath_suffix (String.List.assoc lpath loadpath) base in
(* Look if loaded *)
diff --git a/man/gallina.1 b/man/gallina.1
deleted file mode 100644
index f8879c457..000000000
--- a/man/gallina.1
+++ /dev/null
@@ -1,74 +0,0 @@
-.TH COQ 1 "29 March 1995" "Coq tools"
-
-.SH NAME
-gallina \- extracts specification from Coq vernacular files
-
-.SH SYNOPSIS
-.B gallina
-[
-.BI \-
-]
-[
-.BI \-stdout
-]
-[
-.BI \-nocomments
-]
-.I file ...
-
-.SH DESCRIPTION
-
-.B gallina
-takes Coq files as arguments and builds the corresponding
-specification files.
-The Coq file
-.IR foo.v \&
-gives bearth to the specification file
-.IR foo.g. \&
-The suffix '.g' stands for Gallina.
-
-For that purpose, gallina removes all commands that follow a
-"Theorem", "Lemma", "Fact", "Remark" or "Goal" statement until it
-reaches a command "Abort.", "Qed.", "Defined." or "Proof
-<...>.". It also removes every "Hint", "Syntax",
-"Immediate" or "Transparent" command.
-
-Files without the .v suffix are ignored.
-
-
-.SH OPTIONS
-
-.TP
-.BI \-stdout
-Prints the result on standard output.
-.TP
-.BI \-
-Coq source is taken on standard input. The result is printed on
-standard output.
-.TP
-.BI \-nocomments
-Comments are removed in the *.g file.
-
-.SH NOTES
-
-Nested comments are correctly handled. In particular, every command
-"Qed." or "Abort." in a comment is not taken into account.
-
-
-.SH BUGS
-
-Please report any bug to
-.B coq@pauillac.inria.fr
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/parsing/extend.ml b/parsing/extend.ml
index 6805a96ed..f57e32c88 100644
--- a/parsing/extend.ml
+++ b/parsing/extend.ml
@@ -101,7 +101,7 @@ type ('self, 'a) symbol =
| Aself : ('self, 'self) symbol
| Anext : ('self, 'self) symbol
| Aentry : 'a entry -> ('self, 'a) symbol
-| Aentryl : 'a entry * int -> ('self, 'a) symbol
+| Aentryl : 'a entry * string -> ('self, 'a) symbol
| Arules : 'a rules list -> ('self, 'a) symbol
and ('self, _, 'r) rule =
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.mlg
index 1fa26b455..b2913d5d4 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.mlg
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Names
open Constr
open Libnames
@@ -126,396 +128,399 @@ let name_colon =
let aliasvar = function { CAst.v = CPatAlias (_, na) } -> Some na | _ -> None
-GEXTEND Gram
+}
+
+GRAMMAR EXTEND Gram
GLOBAL: binder_constr lconstr constr operconstr universe_level sort sort_family
global constr_pattern lconstr_pattern Constr.ident
closed_binder open_binders binder binders binders_fixannot
record_declaration typeclass_constraint pattern appl_arg;
Constr.ident:
- [ [ id = Prim.ident -> id ] ]
+ [ [ id = Prim.ident -> { id } ] ]
;
Prim.name:
- [ [ "_" -> CAst.make ~loc:!@loc Anonymous ] ]
+ [ [ "_" -> { CAst.make ~loc Anonymous } ] ]
;
global:
- [ [ r = Prim.reference -> r ] ]
+ [ [ r = Prim.reference -> { r } ] ]
;
constr_pattern:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
lconstr_pattern:
- [ [ c = lconstr -> c ] ]
+ [ [ c = lconstr -> { c } ] ]
;
sort:
- [ [ "Set" -> GSet
- | "Prop" -> GProp
- | "Type" -> GType []
- | "Type"; "@{"; u = universe; "}" -> GType u
+ [ [ "Set" -> { GSet }
+ | "Prop" -> { GProp }
+ | "Type" -> { GType [] }
+ | "Type"; "@{"; u = universe; "}" -> { GType u }
] ]
;
sort_family:
- [ [ "Set" -> Sorts.InSet
- | "Prop" -> Sorts.InProp
- | "Type" -> Sorts.InType
+ [ [ "Set" -> { Sorts.InSet }
+ | "Prop" -> { Sorts.InProp }
+ | "Type" -> { Sorts.InType }
] ]
;
universe_expr:
- [ [ id = global; "+"; n = natural -> Some (id,n)
- | id = global -> Some (id,0)
- | "_" -> None
+ [ [ id = global; "+"; n = natural -> { Some (id,n) }
+ | id = global -> { Some (id,0) }
+ | "_" -> { None }
] ]
;
universe:
- [ [ IDENT "max"; "("; ids = LIST1 universe_expr SEP ","; ")" -> ids
- | u = universe_expr -> [u]
+ [ [ IDENT "max"; "("; ids = LIST1 universe_expr SEP ","; ")" -> { ids }
+ | u = universe_expr -> { [u] }
] ]
;
lconstr:
- [ [ c = operconstr LEVEL "200" -> c ] ]
+ [ [ c = operconstr LEVEL "200" -> { c } ] ]
;
constr:
- [ [ c = operconstr LEVEL "8" -> c
- | "@"; f=global; i = instance -> CAst.make ~loc:!@loc @@ CAppExpl((None,f,i),[]) ] ]
+ [ [ c = operconstr LEVEL "8" -> { c }
+ | "@"; f=global; i = instance -> { CAst.make ~loc @@ CAppExpl((None,f,i),[]) } ] ]
;
operconstr:
[ "200" RIGHTA
- [ c = binder_constr -> c ]
+ [ c = binder_constr -> { c } ]
| "100" RIGHTA
[ c1 = operconstr; "<:"; c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastVM c2)
+ { CAst.make ~loc @@ CCast(c1, CastVM c2) }
| c1 = operconstr; "<:"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastVM c2)
+ { CAst.make ~loc @@ CCast(c1, CastVM c2) }
| c1 = operconstr; "<<:"; c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastNative c2)
+ { CAst.make ~loc @@ CCast(c1, CastNative c2) }
| c1 = operconstr; "<<:"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastNative c2)
+ { CAst.make ~loc @@ CCast(c1, CastNative c2) }
| c1 = operconstr; ":";c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastConv c2)
+ { CAst.make ~loc @@ CCast(c1, CastConv c2) }
| c1 = operconstr; ":"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastConv c2)
+ { CAst.make ~loc @@ CCast(c1, CastConv c2) }
| c1 = operconstr; ":>" ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastCoerce) ]
+ { CAst.make ~loc @@ CCast(c1, CastCoerce) } ]
| "99" RIGHTA [ ]
| "90" RIGHTA [ ]
| "10" LEFTA
- [ f=operconstr; args=LIST1 appl_arg -> CAst.make ~loc:(!@loc) @@ CApp((None,f),args)
- | "@"; f=global; i = instance; args=LIST0 NEXT -> CAst.make ~loc:!@loc @@ CAppExpl((None,f,i),args)
+ [ f=operconstr; args=LIST1 appl_arg -> { CAst.make ~loc @@ CApp((None,f),args) }
+ | "@"; f=global; i = instance; args=LIST0 NEXT -> { CAst.make ~loc @@ CAppExpl((None,f,i),args) }
| "@"; lid = pattern_identref; args=LIST1 identref ->
- let { CAst.loc = locid; v = id } = lid in
+ { let { CAst.loc = locid; v = id } = lid in
let args = List.map (fun x -> CAst.make @@ CRef (qualid_of_ident ?loc:x.CAst.loc x.CAst.v, None), None) args in
- CAst.make ~loc:(!@loc) @@ CApp((None, CAst.make ?loc:locid @@ CPatVar id),args) ]
+ CAst.make ~loc @@ CApp((None, CAst.make ?loc:locid @@ CPatVar id),args) } ]
| "9"
[ ".."; c = operconstr LEVEL "0"; ".." ->
- CAst.make ~loc:!@loc @@ CAppExpl ((None, (qualid_of_ident ~loc:!@loc ldots_var), None),[c]) ]
+ { CAst.make ~loc @@ CAppExpl ((None, (qualid_of_ident ~loc ldots_var), None),[c]) } ]
| "8" [ ]
| "1" LEFTA
[ c=operconstr; ".("; f=global; args=LIST0 appl_arg; ")" ->
- CAst.make ~loc:(!@loc) @@ CApp((Some (List.length args+1), CAst.make @@ CRef (f,None)),args@[c,None])
+ { CAst.make ~loc @@ CApp((Some (List.length args+1), CAst.make @@ CRef (f,None)),args@[c,None]) }
| c=operconstr; ".("; "@"; f=global;
args=LIST0 (operconstr LEVEL "9"); ")" ->
- CAst.make ~loc:(!@loc) @@ CAppExpl((Some (List.length args+1),f,None),args@[c])
- | c=operconstr; "%"; key=IDENT -> CAst.make ~loc:(!@loc) @@ CDelimiters (key,c) ]
+ { CAst.make ~loc @@ CAppExpl((Some (List.length args+1),f,None),args@[c]) }
+ | c=operconstr; "%"; key=IDENT -> { CAst.make ~loc @@ CDelimiters (key,c) } ]
| "0"
- [ c=atomic_constr -> c
- | c=match_constr -> c
+ [ c=atomic_constr -> { c }
+ | c=match_constr -> { c }
| "("; c = operconstr LEVEL "200"; ")" ->
- (match c.CAst.v with
+ { (match c.CAst.v with
| CPrim (Numeral (n,true)) ->
- CAst.make ~loc:(!@loc) @@ CNotation("( _ )",([c],[],[],[]))
- | _ -> c)
- | "{|"; c = record_declaration; "|}" -> c
+ CAst.make ~loc @@ CNotation("( _ )",([c],[],[],[]))
+ | _ -> c) }
+ | "{|"; c = record_declaration; "|}" -> { c }
| "{"; c = binder_constr ; "}" ->
- CAst.make ~loc:(!@loc) @@ CNotation(("{ _ }"),([c],[],[],[]))
+ { CAst.make ~loc @@ CNotation(("{ _ }"),([c],[],[],[])) }
| "`{"; c = operconstr LEVEL "200"; "}" ->
- CAst.make ~loc:(!@loc) @@ CGeneralization (Implicit, None, c)
+ { CAst.make ~loc @@ CGeneralization (Implicit, None, c) }
| "`("; c = operconstr LEVEL "200"; ")" ->
- CAst.make ~loc:(!@loc) @@ CGeneralization (Explicit, None, c)
+ { CAst.make ~loc @@ CGeneralization (Explicit, None, c) }
] ]
;
record_declaration:
- [ [ fs = record_fields -> CAst.make ~loc:(!@loc) @@ CRecord fs ] ]
+ [ [ fs = record_fields -> { CAst.make ~loc @@ CRecord fs } ] ]
;
record_fields:
- [ [ f = record_field_declaration; ";"; fs = record_fields -> f :: fs
- | f = record_field_declaration -> [f]
- | -> []
+ [ [ f = record_field_declaration; ";"; fs = record_fields -> { f :: fs }
+ | f = record_field_declaration -> { [f] }
+ | -> { [] }
] ]
;
record_field_declaration:
[ [ id = global; bl = binders; ":="; c = lconstr ->
- (id, mkCLambdaN ~loc:!@loc bl c) ] ]
+ { (id, mkCLambdaN ~loc bl c) } ] ]
;
binder_constr:
[ [ "forall"; bl = open_binders; ","; c = operconstr LEVEL "200" ->
- mkCProdN ~loc:!@loc bl c
+ { mkCProdN ~loc bl c }
| "fun"; bl = open_binders; "=>"; c = operconstr LEVEL "200" ->
- mkCLambdaN ~loc:!@loc bl c
+ { mkCLambdaN ~loc bl c }
| "let"; id=name; bl = binders; ty = type_cstr; ":=";
c1 = operconstr LEVEL "200"; "in"; c2 = operconstr LEVEL "200" ->
- let ty,c1 = match ty, c1 with
+ { let ty,c1 = match ty, c1 with
| (_,None), { CAst.v = CCast(c, CastConv t) } -> (Loc.tag ?loc:(constr_loc t) @@ Some t), c (* Tolerance, see G_vernac.def_body *)
| _, _ -> ty, c1 in
- CAst.make ~loc:!@loc @@ CLetIn(id,mkCLambdaN ?loc:(constr_loc c1) bl c1,
- Option.map (mkCProdN ?loc:(fst ty) bl) (snd ty), c2)
+ CAst.make ~loc @@ CLetIn(id,mkCLambdaN ?loc:(constr_loc c1) bl c1,
+ Option.map (mkCProdN ?loc:(fst ty) bl) (snd ty), c2) }
| "let"; fx = single_fix; "in"; c = operconstr LEVEL "200" ->
- let fixp = mk_single_fix fx in
+ { let fixp = mk_single_fix fx in
let { CAst.loc = li; v = id } = match fixp.CAst.v with
CFix(id,_) -> id
| CCoFix(id,_) -> id
| _ -> assert false in
- CAst.make ~loc:!@loc @@ CLetIn( CAst.make ?loc:li @@ Name id,fixp,None,c)
- | "let"; lb = ["("; l=LIST0 name SEP ","; ")" -> l | "()" -> []];
+ CAst.make ~loc @@ CLetIn( CAst.make ?loc:li @@ Name id,fixp,None,c) }
+ | "let"; lb = ["("; l=LIST0 name SEP ","; ")" -> { l } | "()" -> { [] } ];
po = return_type;
":="; c1 = operconstr LEVEL "200"; "in";
c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@ CLetTuple (lb,po,c1,c2)
+ { CAst.make ~loc @@ CLetTuple (lb,po,c1,c2) }
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
"in"; c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, None, [c1, None, None], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, None, [c1, None, None], [CAst.make ~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], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, None], [CAst.make ~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], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [CAst.make ~loc ([[p]], c2)]) }
| "if"; c=operconstr LEVEL "200"; po = return_type;
"then"; b1=operconstr LEVEL "200";
"else"; b2=operconstr LEVEL "200" ->
- CAst.make ~loc:(!@loc) @@ CIf (c, po, b1, b2)
- | c=fix_constr -> c ] ]
+ { CAst.make ~loc @@ CIf (c, po, b1, b2) }
+ | c=fix_constr -> { c } ] ]
;
appl_arg:
[ [ id = lpar_id_coloneq; c=lconstr; ")" ->
- (c,Some (CAst.make ~loc:!@loc @@ ExplByName id))
- | c=operconstr LEVEL "9" -> (c,None) ] ]
+ { (c,Some (CAst.make ~loc @@ ExplByName id)) }
+ | c=operconstr LEVEL "9" -> { (c,None) } ] ]
;
atomic_constr:
- [ [ g=global; i=instance -> CAst.make ~loc:!@loc @@ CRef (g,i)
- | s=sort -> CAst.make ~loc:!@loc @@ CSort s
- | n=INT -> CAst.make ~loc:!@loc @@ CPrim (Numeral (n,true))
- | s=string -> CAst.make ~loc:!@loc @@ CPrim (String s)
- | "_" -> CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None)
- | "?"; "["; id=ident; "]" -> CAst.make ~loc:!@loc @@ CHole (None, IntroIdentifier id, None)
- | "?"; "["; id=pattern_ident; "]" -> CAst.make ~loc:!@loc @@ CHole (None, IntroFresh id, None)
- | id=pattern_ident; inst = evar_instance -> CAst.make ~loc:!@loc @@ CEvar(id,inst) ] ]
+ [ [ g=global; i=instance -> { CAst.make ~loc @@ CRef (g,i) }
+ | s=sort -> { CAst.make ~loc @@ CSort s }
+ | n=INT -> { CAst.make ~loc @@ CPrim (Numeral (n,true)) }
+ | s=string -> { CAst.make ~loc @@ CPrim (String s) }
+ | "_" -> { CAst.make ~loc @@ CHole (None, IntroAnonymous, None) }
+ | "?"; "["; id=ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroIdentifier id, None) }
+ | "?"; "["; id=pattern_ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroFresh id, None) }
+ | id=pattern_ident; inst = evar_instance -> { CAst.make ~loc @@ CEvar(id,inst) } ] ]
;
inst:
- [ [ id = ident; ":="; c = lconstr -> (id,c) ] ]
+ [ [ id = ident; ":="; c = lconstr -> { (id,c) } ] ]
;
evar_instance:
- [ [ "@{"; l = LIST1 inst SEP ";"; "}" -> l
- | -> [] ] ]
+ [ [ "@{"; l = LIST1 inst SEP ";"; "}" -> { l }
+ | -> { [] } ] ]
;
instance:
- [ [ "@{"; l = LIST0 universe_level; "}" -> Some l
- | -> None ] ]
+ [ [ "@{"; l = LIST0 universe_level; "}" -> { Some l }
+ | -> { None } ] ]
;
universe_level:
- [ [ "Set" -> GSet
- | "Prop" -> GProp
- | "Type" -> GType UUnknown
- | "_" -> GType UAnonymous
- | id = global -> GType (UNamed id)
+ [ [ "Set" -> { GSet }
+ | "Prop" -> { GProp }
+ | "Type" -> { GType UUnknown }
+ | "_" -> { GType UAnonymous }
+ | id = global -> { GType (UNamed id) }
] ]
;
fix_constr:
- [ [ fx1=single_fix -> mk_single_fix fx1
- | (_,kw,dcl1)=single_fix; "with"; dcls=LIST1 fix_decl SEP "with";
+ [ [ fx1=single_fix -> { mk_single_fix fx1 }
+ | f=single_fix; "with"; dcls=LIST1 fix_decl SEP "with";
"for"; id=identref ->
- mk_fix(!@loc,kw,id,dcl1::dcls)
+ { let (_,kw,dcl1) = f in
+ mk_fix(loc,kw,id,dcl1::dcls) }
] ]
;
single_fix:
- [ [ kw=fix_kw; dcl=fix_decl -> (!@loc,kw,dcl) ] ]
+ [ [ kw=fix_kw; dcl=fix_decl -> { (loc,kw,dcl) } ] ]
;
fix_kw:
- [ [ "fix" -> true
- | "cofix" -> false ] ]
+ [ [ "fix" -> { true }
+ | "cofix" -> { false } ] ]
;
fix_decl:
[ [ id=identref; bl=binders_fixannot; ty=type_cstr; ":=";
c=operconstr LEVEL "200" ->
- (id,fst bl,snd bl,c,ty) ] ]
+ { (id,fst bl,snd bl,c,ty) } ] ]
;
match_constr:
[ [ "match"; ci=LIST1 case_item SEP ","; ty=OPT case_type; "with";
- br=branches; "end" -> CAst.make ~loc:!@loc @@ CCases(RegularStyle,ty,ci,br) ] ]
+ br=branches; "end" -> { CAst.make ~loc @@ CCases(RegularStyle,ty,ci,br) } ] ]
;
case_item:
[ [ c=operconstr LEVEL "100";
- ona = OPT ["as"; id=name -> id];
- ty = OPT ["in"; t=pattern -> t] ->
- (c,ona,ty) ] ]
+ ona = OPT ["as"; id=name -> { id } ];
+ ty = OPT ["in"; t=pattern -> { t } ] ->
+ { (c,ona,ty) } ] ]
;
case_type:
- [ [ "return"; ty = operconstr LEVEL "100" -> ty ] ]
+ [ [ "return"; ty = operconstr LEVEL "100" -> { ty } ] ]
;
return_type:
- [ [ a = OPT [ na = OPT["as"; na=name -> na];
- ty = case_type -> (na,ty) ] ->
- match a with
+ [ [ a = OPT [ na = OPT["as"; na=name -> { na } ];
+ ty = case_type -> { (na,ty) } ] ->
+ { match a with
| None -> None, None
- | Some (na,t) -> (na, Some t)
+ | Some (na,t) -> (na, Some t) }
] ]
;
branches:
- [ [ OPT"|"; br=LIST0 eqn SEP "|" -> br ] ]
+ [ [ OPT"|"; br=LIST0 eqn SEP "|" -> { br } ] ]
;
mult_pattern:
- [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> pl ] ]
+ [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> { pl } ] ]
;
eqn:
[ [ pll = LIST1 mult_pattern SEP "|";
- "=>"; rhs = lconstr -> (CAst.make ~loc:!@loc (pll,rhs)) ] ]
+ "=>"; rhs = lconstr -> { (CAst.make ~loc (pll,rhs)) } ] ]
;
record_pattern:
- [ [ id = global; ":="; pat = pattern -> (id, pat) ] ]
+ [ [ id = global; ":="; pat = pattern -> { (id, pat) } ] ]
;
record_patterns:
- [ [ p = record_pattern; ";"; ps = record_patterns -> p :: ps
- | p = record_pattern; ";" -> [p]
- | p = record_pattern-> [p]
- | -> []
+ [ [ p = record_pattern; ";"; ps = record_patterns -> { p :: ps }
+ | p = record_pattern; ";" -> { [p] }
+ | p = record_pattern-> { [p] }
+ | -> { [] }
] ]
;
pattern:
[ "200" RIGHTA [ ]
| "100" RIGHTA
- [ p = pattern; "|"; pl = LIST1 pattern SEP "|" -> CAst.make ~loc:!@loc @@ CPatOr (p::pl) ]
+ [ p = pattern; "|"; pl = LIST1 pattern SEP "|" -> { CAst.make ~loc @@ CPatOr (p::pl) } ]
| "99" RIGHTA [ ]
| "90" RIGHTA [ ]
| "10" LEFTA
[ p = pattern; "as"; na = name ->
- CAst.make ~loc:!@loc @@ CPatAlias (p, na)
- | p = pattern; lp = LIST1 NEXT -> mkAppPattern ~loc:!@loc p lp
+ { CAst.make ~loc @@ CPatAlias (p, na) }
+ | p = pattern; lp = LIST1 NEXT -> { mkAppPattern ~loc p lp }
| "@"; r = Prim.reference; lp = LIST0 NEXT ->
- CAst.make ~loc:!@loc @@ CPatCstr (r, Some lp, []) ]
+ { CAst.make ~loc @@ CPatCstr (r, Some lp, []) } ]
| "1" LEFTA
- [ c = pattern; "%"; key=IDENT -> CAst.make ~loc:!@loc @@ CPatDelimiters (key,c) ]
+ [ c = pattern; "%"; key=IDENT -> { CAst.make ~loc @@ CPatDelimiters (key,c) } ]
| "0"
- [ r = Prim.reference -> CAst.make ~loc:!@loc @@ CPatAtom (Some r)
- | "{|"; pat = record_patterns; "|}" -> CAst.make ~loc:!@loc @@ CPatRecord pat
- | "_" -> CAst.make ~loc:!@loc @@ CPatAtom None
+ [ r = Prim.reference -> { CAst.make ~loc @@ CPatAtom (Some r) }
+ | "{|"; pat = record_patterns; "|}" -> { CAst.make ~loc @@ CPatRecord pat }
+ | "_" -> { CAst.make ~loc @@ CPatAtom None }
| "("; p = pattern LEVEL "200"; ")" ->
- (match p.CAst.v with
+ { (match p.CAst.v with
| CPatPrim (Numeral (n,true)) ->
- CAst.make ~loc:!@loc @@ CPatNotation("( _ )",([p],[]),[])
- | _ -> p)
+ CAst.make ~loc @@ CPatNotation("( _ )",([p],[]),[])
+ | _ -> p) }
| "("; p = pattern LEVEL "200"; ":"; ty = lconstr; ")" ->
- let p =
+ { let p =
match p with
| { CAst.v = CPatPrim (Numeral (n,true)) } ->
- CAst.make ~loc:!@loc @@ CPatNotation("( _ )",([p],[]),[])
+ CAst.make ~loc @@ CPatNotation("( _ )",([p],[]),[])
| _ -> p
in
- CAst.make ~loc:!@loc @@ CPatCast (p, ty)
- | n = INT -> CAst.make ~loc:!@loc @@ CPatPrim (Numeral (n,true))
- | s = string -> CAst.make ~loc:!@loc @@ CPatPrim (String s) ] ]
+ CAst.make ~loc @@ CPatCast (p, ty) }
+ | n = INT -> { CAst.make ~loc @@ CPatPrim (Numeral (n,true)) }
+ | s = string -> { CAst.make ~loc @@ CPatPrim (String s) } ] ]
;
impl_ident_tail:
- [ [ "}" -> binder_of_name Implicit
+ [ [ "}" -> { binder_of_name Implicit }
| nal=LIST1 name; ":"; c=lconstr; "}" ->
- (fun na -> CLocalAssum (na::nal,Default Implicit,c))
+ { (fun na -> CLocalAssum (na::nal,Default Implicit,c)) }
| nal=LIST1 name; "}" ->
- (fun na -> CLocalAssum (na::nal,Default Implicit,
- CAst.make ?loc:(Loc.merge_opt na.CAst.loc (Some !@loc)) @@
- CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None)))
+ { (fun na -> CLocalAssum (na::nal,Default Implicit,
+ CAst.make ?loc:(Loc.merge_opt na.CAst.loc (Some loc)) @@
+ CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None))) }
| ":"; c=lconstr; "}" ->
- (fun na -> CLocalAssum ([na],Default Implicit,c))
+ { (fun na -> CLocalAssum ([na],Default Implicit,c)) }
] ]
;
fixannot:
- [ [ "{"; IDENT "struct"; id=identref; "}" -> (Some id, CStructRec)
- | "{"; IDENT "wf"; rel=constr; id=OPT identref; "}" -> (id, CWfRec rel)
+ [ [ "{"; IDENT "struct"; id=identref; "}" -> { (Some id, CStructRec) }
+ | "{"; IDENT "wf"; rel=constr; id=OPT identref; "}" -> { (id, CWfRec rel) }
| "{"; IDENT "measure"; m=constr; id=OPT identref;
- rel=OPT constr; "}" -> (id, CMeasureRec (m,rel))
+ rel=OPT constr; "}" -> { (id, CMeasureRec (m,rel)) }
] ]
;
impl_name_head:
- [ [ id = impl_ident_head -> (CAst.make ~loc:!@loc @@ Name id) ] ]
+ [ [ id = impl_ident_head -> { CAst.make ~loc @@ Name id } ] ]
;
binders_fixannot:
[ [ na = impl_name_head; assum = impl_ident_tail; bl = binders_fixannot ->
- (assum na :: fst bl), snd bl
- | f = fixannot -> [], f
- | b = binder; bl = binders_fixannot -> b @ fst bl, snd bl
- | -> [], (None, CStructRec)
+ { (assum na :: fst bl), snd bl }
+ | f = fixannot -> { [], f }
+ | b = binder; bl = binders_fixannot -> { b @ fst bl, snd bl }
+ | -> { [], (None, CStructRec) }
] ]
;
open_binders:
(* Same as binders but parentheses around a closed binder are optional if
the latter is unique *)
- [ [ (* open binder *)
+ [ [
id = name; idl = LIST0 name; ":"; c = lconstr ->
- [CLocalAssum (id::idl,Default Explicit,c)]
- (* binders factorized with open binder *)
+ { [CLocalAssum (id::idl,Default Explicit,c)]
+ (* binders factorized with open binder *) }
| id = name; idl = LIST0 name; bl = binders ->
- binders_of_names (id::idl) @ bl
+ { binders_of_names (id::idl) @ bl }
| id1 = name; ".."; id2 = name ->
- [CLocalAssum ([id1;(CAst.make ~loc:!@loc (Name ldots_var));id2],
- Default Explicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
+ { [CLocalAssum ([id1;(CAst.make ~loc (Name ldots_var));id2],
+ Default Explicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
| bl = closed_binder; bl' = binders ->
- bl@bl'
+ { bl@bl' }
] ]
;
binders:
- [ [ l = LIST0 binder -> List.flatten l ] ]
+ [ [ l = LIST0 binder -> { List.flatten l } ] ]
;
binder:
- [ [ id = name -> [CLocalAssum ([id],Default Explicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
- | bl = closed_binder -> bl ] ]
+ [ [ id = name -> { [CLocalAssum ([id],Default Explicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
+ | bl = closed_binder -> { bl } ] ]
;
closed_binder:
[ [ "("; id=name; idl=LIST1 name; ":"; c=lconstr; ")" ->
- [CLocalAssum (id::idl,Default Explicit,c)]
+ { [CLocalAssum (id::idl,Default Explicit,c)] }
| "("; id=name; ":"; c=lconstr; ")" ->
- [CLocalAssum ([id],Default Explicit,c)]
+ { [CLocalAssum ([id],Default Explicit,c)] }
| "("; id=name; ":="; c=lconstr; ")" ->
- (match c.CAst.v with
+ { (match c.CAst.v with
| CCast(c, CastConv t) -> [CLocalDef (id,c,Some t)]
- | _ -> [CLocalDef (id,c,None)])
+ | _ -> [CLocalDef (id,c,None)]) }
| "("; id=name; ":"; t=lconstr; ":="; c=lconstr; ")" ->
- [CLocalDef (id,c,Some t)]
+ { [CLocalDef (id,c,Some t)] }
| "{"; id=name; "}" ->
- [CLocalAssum ([id],Default Implicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
+ { [CLocalAssum ([id],Default Implicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
| "{"; id=name; idl=LIST1 name; ":"; c=lconstr; "}" ->
- [CLocalAssum (id::idl,Default Implicit,c)]
+ { [CLocalAssum (id::idl,Default Implicit,c)] }
| "{"; id=name; ":"; c=lconstr; "}" ->
- [CLocalAssum ([id],Default Implicit,c)]
+ { [CLocalAssum ([id],Default Implicit,c)] }
| "{"; id=name; idl=LIST1 name; "}" ->
- List.map (fun id -> CLocalAssum ([id],Default Implicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))) (id::idl)
+ { List.map (fun id -> CLocalAssum ([id],Default Implicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) (id::idl) }
| "`("; tc = LIST1 typeclass_constraint SEP "," ; ")" ->
- List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Explicit, b), t)) tc
+ { List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Explicit, b), t)) tc }
| "`{"; tc = LIST1 typeclass_constraint SEP "," ; "}" ->
- List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Implicit, b), t)) tc
+ { List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Implicit, b), t)) tc }
| "'"; p = pattern LEVEL "0" ->
- let (p, ty) =
+ { let (p, ty) =
match p.CAst.v with
| CPatCast (p, ty) -> (p, Some ty)
| _ -> (p, None)
in
- [CLocalPattern (CAst.make ~loc:!@loc (p, ty))]
+ [CLocalPattern (CAst.make ~loc (p, ty))] }
] ]
;
typeclass_constraint:
- [ [ "!" ; c = operconstr LEVEL "200" -> (CAst.make ~loc:!@loc Anonymous), true, c
- | "{"; id = name; "}"; ":" ; expl = [ "!" -> true | -> false ] ; c = operconstr LEVEL "200" ->
- id, expl, c
- | iid=name_colon ; expl = [ "!" -> true | -> false ] ; c = operconstr LEVEL "200" ->
- (CAst.make ~loc:!@loc iid), expl, c
+ [ [ "!" ; c = operconstr LEVEL "200" -> { (CAst.make ~loc Anonymous), true, c }
+ | "{"; id = name; "}"; ":" ; expl = [ "!" -> { true } | -> { false } ] ; c = operconstr LEVEL "200" ->
+ { id, expl, c }
+ | iid=name_colon ; expl = [ "!" -> { true } | -> { false } ] ; c = operconstr LEVEL "200" ->
+ { (CAst.make ~loc iid), expl, c }
| c = operconstr LEVEL "200" ->
- (CAst.make ~loc:!@loc Anonymous), false, c
+ { (CAst.make ~loc Anonymous), false, c }
] ]
;
type_cstr:
- [ [ c=OPT [":"; c=lconstr -> c] -> Loc.tag ~loc:!@loc c ] ]
+ [ [ c=OPT [":"; c=lconstr -> { c } ] -> { Loc.tag ~loc c } ] ]
;
- END;;
+ END
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.mlg
index 91dce27fe..774db97f2 100644
--- a/parsing/g_prim.ml4
+++ b/parsing/g_prim.mlg
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Names
open Libnames
@@ -30,93 +32,96 @@ let my_int_of_string loc s =
with Failure _ | Exit ->
CErrors.user_err ~loc (Pp.str "Cannot support a so large number.")
-GEXTEND Gram
+}
+
+GRAMMAR EXTEND Gram
GLOBAL:
bigint natural integer identref name ident var preident
fullyqualid qualid reference dirpath ne_lstring
ne_string string lstring pattern_ident pattern_identref by_notation smart_global;
preident:
- [ [ s = IDENT -> s ] ]
+ [ [ s = IDENT -> { s } ] ]
;
ident:
- [ [ s = IDENT -> Id.of_string s ] ]
+ [ [ s = IDENT -> { Id.of_string s } ] ]
;
pattern_ident:
- [ [ LEFTQMARK; id = ident -> id ] ]
+ [ [ LEFTQMARK; id = ident -> { id } ] ]
;
pattern_identref:
- [ [ id = pattern_ident -> CAst.make ~loc:!@loc id ] ]
+ [ [ id = pattern_ident -> { CAst.make ~loc id } ] ]
;
var: (* as identref, but interpret as a term identifier in ltac *)
- [ [ id = ident -> CAst.make ~loc:!@loc id ] ]
+ [ [ id = ident -> { CAst.make ~loc id } ] ]
;
identref:
- [ [ id = ident -> CAst.make ~loc:!@loc id ] ]
+ [ [ id = ident -> { CAst.make ~loc id } ] ]
;
field:
- [ [ s = FIELD -> Id.of_string s ] ]
+ [ [ s = FIELD -> { Id.of_string s } ] ]
;
fields:
- [ [ id = field; (l,id') = fields -> (l@[id],id')
- | id = field -> ([],id)
+ [ [ id = field; f = fields -> { let (l,id') = f in (l@[id],id') }
+ | id = field -> { ([],id) }
] ]
;
fullyqualid:
- [ [ id = ident; (l,id')=fields -> CAst.make ~loc:!@loc @@ id::List.rev (id'::l)
- | id = ident -> CAst.make ~loc:!@loc [id]
+ [ [ id = ident; f=fields -> { let (l,id') = f in CAst.make ~loc @@ id::List.rev (id'::l) }
+ | id = ident -> { CAst.make ~loc [id] }
] ]
;
basequalid:
- [ [ id = ident; (l,id')=fields -> local_make_qualid !@loc (l@[id]) id'
- | id = ident -> qualid_of_ident ~loc:!@loc id
+ [ [ id = ident; f=fields -> { let (l,id') = f in local_make_qualid loc (l@[id]) id' }
+ | id = ident -> { qualid_of_ident ~loc id }
] ]
;
name:
- [ [ IDENT "_" -> CAst.make ~loc:!@loc Anonymous
- | id = ident -> CAst.make ~loc:!@loc @@ Name id ] ]
+ [ [ IDENT "_" -> { CAst.make ~loc Anonymous }
+ | id = ident -> { CAst.make ~loc @@ Name id } ] ]
;
reference:
- [ [ id = ident; (l,id') = fields ->
- local_make_qualid !@loc (l@[id]) id'
- | id = ident -> local_make_qualid !@loc [] id
+ [ [ id = ident; f = fields -> {
+ let (l,id') = f in
+ local_make_qualid loc (l@[id]) id' }
+ | id = ident -> { local_make_qualid loc [] id }
] ]
;
by_notation:
- [ [ s = ne_string; sc = OPT ["%"; key = IDENT -> key ] -> (s, sc) ] ]
+ [ [ s = ne_string; sc = OPT ["%"; key = IDENT -> { key } ] -> { (s, sc) } ] ]
;
smart_global:
- [ [ c = reference -> CAst.make ~loc:!@loc @@ Constrexpr.AN c
- | ntn = by_notation -> CAst.make ~loc:!@loc @@ Constrexpr.ByNotation ntn ] ]
+ [ [ c = reference -> { CAst.make ~loc @@ Constrexpr.AN c }
+ | ntn = by_notation -> { CAst.make ~loc @@ Constrexpr.ByNotation ntn } ] ]
;
qualid:
- [ [ qid = basequalid -> qid ] ]
+ [ [ qid = basequalid -> { qid } ] ]
;
ne_string:
[ [ s = STRING ->
- if s="" then CErrors.user_err ~loc:!@loc (Pp.str"Empty string."); s
+ { if s="" then CErrors.user_err ~loc (Pp.str"Empty string."); s }
] ]
;
ne_lstring:
- [ [ s = ne_string -> CAst.make ~loc:!@loc s ] ]
+ [ [ s = ne_string -> { CAst.make ~loc s } ] ]
;
dirpath:
[ [ id = ident; l = LIST0 field ->
- DirPath.make (List.rev (id::l)) ] ]
+ { DirPath.make (List.rev (id::l)) } ] ]
;
string:
- [ [ s = STRING -> s ] ]
+ [ [ s = STRING -> { s } ] ]
;
lstring:
- [ [ s = string -> (CAst.make ~loc:!@loc s) ] ]
+ [ [ s = string -> { CAst.make ~loc s } ] ]
;
integer:
- [ [ i = INT -> my_int_of_string (!@loc) i
- | "-"; i = INT -> - my_int_of_string (!@loc) i ] ]
+ [ [ i = INT -> { my_int_of_string loc i }
+ | "-"; i = INT -> { - my_int_of_string loc i } ] ]
;
natural:
- [ [ i = INT -> my_int_of_string (!@loc) i ] ]
+ [ [ i = INT -> { my_int_of_string loc i } ] ]
;
bigint: (* Negative numbers are dealt with elsewhere *)
- [ [ i = INT -> i ] ]
+ [ [ i = INT -> { i } ] ]
;
END
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 6fdd9ea9b..997ea78e6 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -17,9 +17,17 @@ let curry f x y = f (x, y)
let uncurry f (x,y) = f x y
(** Location Utils *)
+let ploc_file_of_coq_file = function
+| Loc.ToplevelInput -> ""
+| Loc.InFile f -> f
+
let coq_file_of_ploc_file s =
if s = "" then Loc.ToplevelInput else Loc.InFile s
+let of_coqloc loc =
+ let open Loc in
+ Ploc.make_loc (ploc_file_of_coq_file loc.fname) loc.line_nb loc.bol_pos (loc.bp, loc.ep) ""
+
let to_coqloc loc =
{ Loc.fname = coq_file_of_ploc_file (Ploc.file_name loc);
Loc.line_nb = Ploc.line_nb loc;
@@ -236,7 +244,7 @@ let rec symbol_of_prod_entry_key : type s a. (s, a) symbol -> _ = function
| Aentry e ->
Symbols.snterm (G.Entry.obj e)
| Aentryl (e, n) ->
- Symbols.snterml (G.Entry.obj e, string_of_int n)
+ Symbols.snterml (G.Entry.obj e, n)
| Arules rs ->
G.srules' (List.map symbol_of_rules rs)
@@ -328,6 +336,7 @@ module Gram =
I'm not entirely sure it makes sense, but at least it would be more correct.
*)
G.delete_rule e pil
+ let gram_extend e ext = grammar_extend e None ext
end
(** Remove extensions
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index f959bd80c..154de1221 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -80,6 +80,8 @@ module type S =
(* Get comment parsing information from the Lexer *)
val comment_state : coq_parsable -> ((int * int) * string) list
+ val gram_extend : 'a entry -> 'a Extend.extend_statement -> unit
+
(* Apparently not used *)
val srules' : production_rule list -> symbol
val parse_tokens_after_filter : 'a entry -> Tok.t Stream.t -> 'a
@@ -299,6 +301,7 @@ val recover_grammar_command : 'a grammar_command -> 'a list
val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
(** Location Utils *)
+val of_coqloc : Loc.t -> Ploc.t
val to_coqloc : Ploc.t -> Loc.t
val (!@) : Ploc.t -> Loc.t
diff --git a/plugins/btauto/g_btauto.ml4 b/plugins/btauto/g_btauto.mlg
index 3ae0f45cb..312ef1e55 100644
--- a/plugins/btauto/g_btauto.ml4
+++ b/plugins/btauto/g_btauto.mlg
@@ -8,11 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
+}
+
DECLARE PLUGIN "btauto_plugin"
TACTIC EXTEND btauto
-| [ "btauto" ] -> [ Refl_btauto.Btauto.tac ]
+| [ "btauto" ] -> { Refl_btauto.Btauto.tac }
END
diff --git a/plugins/cc/ccalgo.ml b/plugins/cc/ccalgo.ml
index 4c6156a38..4a691e442 100644
--- a/plugins/cc/ccalgo.ml
+++ b/plugins/cc/ccalgo.ml
@@ -130,8 +130,8 @@ type cinfo=
ci_nhyps: int} (* # projectable args *)
let family_eq f1 f2 = match f1, f2 with
- | Prop Pos, Prop Pos
- | Prop Null, Prop Null
+ | Set, Set
+ | Prop, Prop
| Type _, Type _ -> true
| _ -> false
diff --git a/plugins/cc/g_congruence.ml4 b/plugins/cc/g_congruence.mlg
index fb013ac13..685059294 100644
--- a/plugins/cc/g_congruence.ml4
+++ b/plugins/cc/g_congruence.mlg
@@ -8,22 +8,26 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Cctac
open Stdarg
+}
+
DECLARE PLUGIN "cc_plugin"
(* Tactic registration *)
TACTIC EXTEND cc
- [ "congruence" ] -> [ congruence_tac 1000 [] ]
- |[ "congruence" integer(n) ] -> [ congruence_tac n [] ]
- |[ "congruence" "with" ne_constr_list(l) ] -> [ congruence_tac 1000 l ]
+| [ "congruence" ] -> { congruence_tac 1000 [] }
+| [ "congruence" integer(n) ] -> { congruence_tac n [] }
+| [ "congruence" "with" ne_constr_list(l) ] -> { congruence_tac 1000 l }
|[ "congruence" integer(n) "with" ne_constr_list(l) ] ->
- [ congruence_tac n l ]
+ { congruence_tac n l }
END
TACTIC EXTEND f_equal
- [ "f_equal" ] -> [ f_equal ]
+| [ "f_equal" ] -> { f_equal }
END
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index 3a61c7747..71e09992c 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -488,7 +488,7 @@ and extract_really_ind env kn mib =
Int.equal (List.length l) 1 && not (type_mem_kn kn (List.hd l))
then raise (I Singleton);
if List.is_empty l then raise (I Standard);
- if Option.is_empty mib.mind_record then raise (I Standard);
+ if mib.mind_record == Declarations.NotRecord then raise (I Standard);
(* Now we're sure it's a record. *)
(* First, we find its field names. *)
let rec names_prod t = match Constr.kind t with
@@ -1069,8 +1069,7 @@ let extract_constant env kn cb =
| false -> mk_typ (get_body c)
| true ->
let pb = lookup_projection (Projection.make kn false) env in
- (** FIXME: handle mutual records *)
- let ind = (pb.Declarations.proj_ind, 0) in
+ let ind = pb.Declarations.proj_ind in
let bodies = Inductiveops.legacy_match_projection env ind in
let body = bodies.(pb.Declarations.proj_arg) in
mk_typ (EConstr.of_constr body))
@@ -1086,8 +1085,7 @@ let extract_constant env kn cb =
| false -> mk_def (get_body c)
| true ->
let pb = lookup_projection (Projection.make kn false) env in
- (** FIXME: handle mutual records *)
- let ind = (pb.Declarations.proj_ind, 0) in
+ let ind = pb.Declarations.proj_ind in
let bodies = Inductiveops.legacy_match_projection env ind in
let body = bodies.(pb.Declarations.proj_arg) in
mk_def (EConstr.of_constr body))
diff --git a/plugins/fourier/g_fourier.ml4 b/plugins/fourier/g_fourier.mlg
index 44560ac18..703e29f96 100644
--- a/plugins/fourier/g_fourier.ml4
+++ b/plugins/fourier/g_fourier.mlg
@@ -8,11 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open FourierR
+}
+
DECLARE PLUGIN "fourier_plugin"
TACTIC EXTEND fourier
- [ "fourierz" ] -> [ fourier () ]
+| [ "fourierz" ] -> { fourier () }
END
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 31496513a..b2a528a1f 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -322,8 +322,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
try
let f = funs.(i) in
- let env = Global.env () in
- let type_sort = Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd InType in
+ let type_sort = Evarutil.evd_comb1 Evd.fresh_sort_in_family evd InType in
let new_sorts =
match sorts with
| None -> Array.make (Array.length funs) (type_sort)
@@ -344,7 +343,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
(* let id_of_f = Label.to_id (con_label f) in *)
let register_with_sort fam_sort =
let evd' = Evd.from_env (Global.env ()) in
- let evd',s = Evd.fresh_sort_in_family env evd' fam_sort in
+ let evd',s = Evd.fresh_sort_in_family evd' fam_sort in
let name = Indrec.make_elimination_ident base_new_princ_name fam_sort in
let evd',value = change_property_sort evd' s new_principle_type new_princ_name in
let evd' = fst (Typing.type_of ~refresh:true (Global.env ()) evd' (EConstr.of_constr value)) in
@@ -354,7 +353,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
Evd.const_univ_entry ~poly evd'
in
let ce = Declare.definition_entry ~univs value in
- ignore(
+ ignore(
Declare.declare_constant
name
(DefinitionEntry ce,
@@ -508,8 +507,8 @@ let make_scheme evd (fas : (pconstant*Sorts.family) list) : Safe_typing.private_
let i = ref (-1) in
let sorts =
List.rev_map (fun (_,x) ->
- Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd x
- )
+ Evarutil.evd_comb1 Evd.fresh_sort_in_family evd x
+ )
fas
in
(* We create the first priciple by tactic *)
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 6b9b10312..5fc4293cb 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -1499,7 +1499,7 @@ let do_build_inductive
let _time2 = System.get_time () in
try
with_full_print
- (Flags.silently (ComInductive.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 ~uniform:ComInductive.NonUniformParameters))
Declarations.Finite
with
| UserError(s,msg) as e ->
diff --git a/plugins/ltac/coretactics.ml4 b/plugins/ltac/coretactics.mlg
index 61525cb49..6388906f5 100644
--- a/plugins/ltac/coretactics.ml4
+++ b/plugins/ltac/coretactics.mlg
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Util
open Locus
open Tactypes
@@ -18,147 +20,153 @@ open Tacarg
open Names
open Logic
+let wit_hyp = wit_var
+
+}
+
DECLARE PLUGIN "ltac_plugin"
(** Basic tactics *)
TACTIC EXTEND reflexivity
- [ "reflexivity" ] -> [ Tactics.intros_reflexivity ]
+| [ "reflexivity" ] -> { Tactics.intros_reflexivity }
END
TACTIC EXTEND exact
- [ "exact" casted_constr(c) ] -> [ Tactics.exact_no_check c ]
+| [ "exact" casted_constr(c) ] -> { Tactics.exact_no_check c }
END
TACTIC EXTEND assumption
- [ "assumption" ] -> [ Tactics.assumption ]
+| [ "assumption" ] -> { Tactics.assumption }
END
TACTIC EXTEND etransitivity
- [ "etransitivity" ] -> [ Tactics.intros_transitivity None ]
+| [ "etransitivity" ] -> { Tactics.intros_transitivity None }
END
TACTIC EXTEND cut
- [ "cut" constr(c) ] -> [ Tactics.cut c ]
+| [ "cut" constr(c) ] -> { Tactics.cut c }
END
TACTIC EXTEND exact_no_check
- [ "exact_no_check" constr(c) ] -> [ Tactics.exact_no_check c ]
+| [ "exact_no_check" constr(c) ] -> { Tactics.exact_no_check c }
END
TACTIC EXTEND vm_cast_no_check
- [ "vm_cast_no_check" constr(c) ] -> [ Tactics.vm_cast_no_check c ]
+| [ "vm_cast_no_check" constr(c) ] -> { Tactics.vm_cast_no_check c }
END
TACTIC EXTEND native_cast_no_check
- [ "native_cast_no_check" constr(c) ] -> [ Tactics.native_cast_no_check c ]
+| [ "native_cast_no_check" constr(c) ] -> { Tactics.native_cast_no_check c }
END
TACTIC EXTEND casetype
- [ "casetype" constr(c) ] -> [ Tactics.case_type c ]
+| [ "casetype" constr(c) ] -> { Tactics.case_type c }
END
TACTIC EXTEND elimtype
- [ "elimtype" constr(c) ] -> [ Tactics.elim_type c ]
+| [ "elimtype" constr(c) ] -> { Tactics.elim_type c }
END
TACTIC EXTEND lapply
- [ "lapply" constr(c) ] -> [ Tactics.cut_and_apply c ]
+| [ "lapply" constr(c) ] -> { Tactics.cut_and_apply c }
END
TACTIC EXTEND transitivity
- [ "transitivity" constr(c) ] -> [ Tactics.intros_transitivity (Some c) ]
+| [ "transitivity" constr(c) ] -> { Tactics.intros_transitivity (Some c) }
END
(** Left *)
TACTIC EXTEND left
- [ "left" ] -> [ Tactics.left_with_bindings false NoBindings ]
+| [ "left" ] -> { Tactics.left_with_bindings false NoBindings }
END
TACTIC EXTEND eleft
- [ "eleft" ] -> [ Tactics.left_with_bindings true NoBindings ]
+| [ "eleft" ] -> { Tactics.left_with_bindings true NoBindings }
END
TACTIC EXTEND left_with
- [ "left" "with" bindings(bl) ] -> [
+| [ "left" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.left_with_bindings false bl)
- ]
+ }
END
TACTIC EXTEND eleft_with
- [ "eleft" "with" bindings(bl) ] -> [
+| [ "eleft" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.left_with_bindings true bl)
- ]
+ }
END
(** Right *)
TACTIC EXTEND right
- [ "right" ] -> [ Tactics.right_with_bindings false NoBindings ]
+| [ "right" ] -> { Tactics.right_with_bindings false NoBindings }
END
TACTIC EXTEND eright
- [ "eright" ] -> [ Tactics.right_with_bindings true NoBindings ]
+| [ "eright" ] -> { Tactics.right_with_bindings true NoBindings }
END
TACTIC EXTEND right_with
- [ "right" "with" bindings(bl) ] -> [
+| [ "right" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.right_with_bindings false bl)
- ]
+ }
END
TACTIC EXTEND eright_with
- [ "eright" "with" bindings(bl) ] -> [
+| [ "eright" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.right_with_bindings true bl)
- ]
+ }
END
(** Constructor *)
TACTIC EXTEND constructor
- [ "constructor" ] -> [ Tactics.any_constructor false None ]
-| [ "constructor" int_or_var(i) ] -> [
+| [ "constructor" ] -> { Tactics.any_constructor false None }
+| [ "constructor" int_or_var(i) ] -> {
Tactics.constructor_tac false None i NoBindings
- ]
-| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> [
+ }
+| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac false None i bl in
Tacticals.New.tclDELAYEDWITHHOLES false bl tac
- ]
+ }
END
TACTIC EXTEND econstructor
- [ "econstructor" ] -> [ Tactics.any_constructor true None ]
-| [ "econstructor" int_or_var(i) ] -> [
+| [ "econstructor" ] -> { Tactics.any_constructor true None }
+| [ "econstructor" int_or_var(i) ] -> {
Tactics.constructor_tac true None i NoBindings
- ]
-| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> [
+ }
+| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac true None i bl in
Tacticals.New.tclDELAYEDWITHHOLES true bl tac
- ]
+ }
END
(** Specialize *)
TACTIC EXTEND specialize
- [ "specialize" constr_with_bindings(c) ] -> [
+| [ "specialize" constr_with_bindings(c) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false c (fun c -> Tactics.specialize c None)
- ]
-| [ "specialize" constr_with_bindings(c) "as" intropattern(ipat) ] -> [
+ }
+| [ "specialize" constr_with_bindings(c) "as" intropattern(ipat) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false c (fun c -> Tactics.specialize c (Some ipat))
- ]
+ }
END
TACTIC EXTEND symmetry
- [ "symmetry" ] -> [ Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} ]
+| [ "symmetry" ] -> { Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} }
END
TACTIC EXTEND symmetry_in
-| [ "symmetry" "in" in_clause(cl) ] -> [ Tactics.intros_symmetry cl ]
+| [ "symmetry" "in" in_clause(cl) ] -> { Tactics.intros_symmetry cl }
END
(** Split *)
+{
+
let rec delayed_list = function
| [] -> fun _ sigma -> (sigma, [])
| x :: l ->
@@ -167,147 +175,159 @@ let rec delayed_list = function
let (sigma, l) = delayed_list l env sigma in
(sigma, x :: l)
+}
+
TACTIC EXTEND split
- [ "split" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
+| [ "split" ] -> { Tactics.split_with_bindings false [NoBindings] }
END
TACTIC EXTEND esplit
- [ "esplit" ] -> [ Tactics.split_with_bindings true [NoBindings] ]
+| [ "esplit" ] -> { Tactics.split_with_bindings true [NoBindings] }
END
TACTIC EXTEND split_with
- [ "split" "with" bindings(bl) ] -> [
+| [ "split" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.split_with_bindings false [bl])
- ]
+ }
END
TACTIC EXTEND esplit_with
- [ "esplit" "with" bindings(bl) ] -> [
+| [ "esplit" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.split_with_bindings true [bl])
- ]
+ }
END
TACTIC EXTEND exists
- [ "exists" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
-| [ "exists" ne_bindings_list_sep(bll, ",") ] -> [
+| [ "exists" ] -> { Tactics.split_with_bindings false [NoBindings] }
+| [ "exists" ne_bindings_list_sep(bll, ",") ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false (delayed_list bll) (fun bll -> Tactics.split_with_bindings false bll)
- ]
+ }
END
TACTIC EXTEND eexists
- [ "eexists" ] -> [ Tactics.split_with_bindings true [NoBindings] ]
-| [ "eexists" ne_bindings_list_sep(bll, ",") ] -> [
+| [ "eexists" ] -> { Tactics.split_with_bindings true [NoBindings] }
+| [ "eexists" ne_bindings_list_sep(bll, ",") ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true (delayed_list bll) (fun bll -> Tactics.split_with_bindings true bll)
- ]
+ }
END
(** Intro *)
TACTIC EXTEND intros_until
- [ "intros" "until" quantified_hypothesis(h) ] -> [ Tactics.intros_until h ]
+| [ "intros" "until" quantified_hypothesis(h) ] -> { Tactics.intros_until h }
END
TACTIC EXTEND intro
-| [ "intro" ] -> [ Tactics.intro_move None MoveLast ]
-| [ "intro" ident(id) ] -> [ Tactics.intro_move (Some id) MoveLast ]
-| [ "intro" ident(id) "at" "top" ] -> [ Tactics.intro_move (Some id) MoveFirst ]
-| [ "intro" ident(id) "at" "bottom" ] -> [ Tactics.intro_move (Some id) MoveLast ]
-| [ "intro" ident(id) "after" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveAfter h) ]
-| [ "intro" ident(id) "before" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveBefore h) ]
-| [ "intro" "at" "top" ] -> [ Tactics.intro_move None MoveFirst ]
-| [ "intro" "at" "bottom" ] -> [ Tactics.intro_move None MoveLast ]
-| [ "intro" "after" hyp(h) ] -> [ Tactics.intro_move None (MoveAfter h) ]
-| [ "intro" "before" hyp(h) ] -> [ Tactics.intro_move None (MoveBefore h) ]
+| [ "intro" ] -> { Tactics.intro_move None MoveLast }
+| [ "intro" ident(id) ] -> { Tactics.intro_move (Some id) MoveLast }
+| [ "intro" ident(id) "at" "top" ] -> { Tactics.intro_move (Some id) MoveFirst }
+| [ "intro" ident(id) "at" "bottom" ] -> { Tactics.intro_move (Some id) MoveLast }
+| [ "intro" ident(id) "after" hyp(h) ] -> { Tactics.intro_move (Some id) (MoveAfter h) }
+| [ "intro" ident(id) "before" hyp(h) ] -> { Tactics.intro_move (Some id) (MoveBefore h) }
+| [ "intro" "at" "top" ] -> { Tactics.intro_move None MoveFirst }
+| [ "intro" "at" "bottom" ] -> { Tactics.intro_move None MoveLast }
+| [ "intro" "after" hyp(h) ] -> { Tactics.intro_move None (MoveAfter h) }
+| [ "intro" "before" hyp(h) ] -> { Tactics.intro_move None (MoveBefore h) }
END
(** Move *)
TACTIC EXTEND move
- [ "move" hyp(id) "at" "top" ] -> [ Tactics.move_hyp id MoveFirst ]
-| [ "move" hyp(id) "at" "bottom" ] -> [ Tactics.move_hyp id MoveLast ]
-| [ "move" hyp(id) "after" hyp(h) ] -> [ Tactics.move_hyp id (MoveAfter h) ]
-| [ "move" hyp(id) "before" hyp(h) ] -> [ Tactics.move_hyp id (MoveBefore h) ]
+| [ "move" hyp(id) "at" "top" ] -> { Tactics.move_hyp id MoveFirst }
+| [ "move" hyp(id) "at" "bottom" ] -> { Tactics.move_hyp id MoveLast }
+| [ "move" hyp(id) "after" hyp(h) ] -> { Tactics.move_hyp id (MoveAfter h) }
+| [ "move" hyp(id) "before" hyp(h) ] -> { Tactics.move_hyp id (MoveBefore h) }
END
(** Rename *)
TACTIC EXTEND rename
-| [ "rename" ne_rename_list_sep(ids, ",") ] -> [ Tactics.rename_hyp ids ]
+| [ "rename" ne_rename_list_sep(ids, ",") ] -> { Tactics.rename_hyp ids }
END
(** Revert *)
TACTIC EXTEND revert
- [ "revert" ne_hyp_list(hl) ] -> [ Tactics.revert hl ]
+| [ "revert" ne_hyp_list(hl) ] -> { Tactics.revert hl }
END
(** Simple induction / destruct *)
+{
+
let simple_induct h =
Tacticals.New.tclTHEN (Tactics.intros_until h)
(Tacticals.New.onLastHyp Tactics.simplest_elim)
+}
+
TACTIC EXTEND simple_induction
- [ "simple" "induction" quantified_hypothesis(h) ] -> [ simple_induct h ]
+| [ "simple" "induction" quantified_hypothesis(h) ] -> { simple_induct h }
END
+{
+
let simple_destruct h =
Tacticals.New.tclTHEN (Tactics.intros_until h)
(Tacticals.New.onLastHyp Tactics.simplest_case)
+}
+
TACTIC EXTEND simple_destruct
- [ "simple" "destruct" quantified_hypothesis(h) ] -> [ simple_destruct h ]
+| [ "simple" "destruct" quantified_hypothesis(h) ] -> { simple_destruct h }
END
(** Double induction *)
TACTIC EXTEND double_induction
- [ "double" "induction" quantified_hypothesis(h1) quantified_hypothesis(h2) ] ->
- [ Elim.h_double_induction h1 h2 ]
+| [ "double" "induction" quantified_hypothesis(h1) quantified_hypothesis(h2) ] ->
+ { Elim.h_double_induction h1 h2 }
END
(* Admit *)
TACTIC EXTEND admit
- [ "admit" ] -> [ Proofview.give_up ]
+|[ "admit" ] -> { Proofview.give_up }
END
(* Fix *)
TACTIC EXTEND fix
- [ "fix" ident(id) natural(n) ] -> [ Tactics.fix id n ]
+| [ "fix" ident(id) natural(n) ] -> { Tactics.fix id n }
END
(* Cofix *)
TACTIC EXTEND cofix
- [ "cofix" ident(id) ] -> [ Tactics.cofix id ]
+| [ "cofix" ident(id) ] -> { Tactics.cofix id }
END
(* Clear *)
TACTIC EXTEND clear
- [ "clear" hyp_list(ids) ] -> [
+| [ "clear" hyp_list(ids) ] -> {
if List.is_empty ids then Tactics.keep []
else Tactics.clear ids
- ]
-| [ "clear" "-" ne_hyp_list(ids) ] -> [ Tactics.keep ids ]
+ }
+| [ "clear" "-" ne_hyp_list(ids) ] -> { Tactics.keep ids }
END
(* Clearbody *)
TACTIC EXTEND clearbody
- [ "clearbody" ne_hyp_list(ids) ] -> [ Tactics.clear_body ids ]
+| [ "clearbody" ne_hyp_list(ids) ] -> { Tactics.clear_body ids }
END
(* Generalize dependent *)
TACTIC EXTEND generalize_dependent
- [ "generalize" "dependent" constr(c) ] -> [ Tactics.generalize_dep c ]
+| [ "generalize" "dependent" constr(c) ] -> { Tactics.generalize_dep c }
END
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
+{
+
open Tacexpr
let initial_atomic () =
@@ -364,3 +384,5 @@ let initial_tacticals () =
]
let () = Mltop.declare_cache_obj initial_tacticals "ltac_plugin"
+
+}
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 660e29ca8..f24ab2bdd 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -293,7 +293,7 @@ open Vars
let constr_flags () = {
Pretyping.use_typeclasses = true;
- Pretyping.solve_unification_constraints = true;
+ Pretyping.solve_unification_constraints = Pfedit.use_unification_heuristics ();
Pretyping.use_hook = Pfedit.solve_by_implicit_tactic ();
Pretyping.fail_evar = false;
Pretyping.expand_evars = true }
diff --git a/plugins/ltac/g_eqdecide.ml4 b/plugins/ltac/g_eqdecide.mlg
index 2251a6620..e57afe3e3 100644
--- a/plugins/ltac/g_eqdecide.ml4
+++ b/plugins/ltac/g_eqdecide.mlg
@@ -14,15 +14,19 @@
(* by Eduardo Gimenez *)
(************************************************************************)
+{
+
open Eqdecide
open Stdarg
+}
+
DECLARE PLUGIN "ltac_plugin"
TACTIC EXTEND decide_equality
-| [ "decide" "equality" ] -> [ decideEqualityGoal ]
+| [ "decide" "equality" ] -> { decideEqualityGoal }
END
TACTIC EXTEND compare
-| [ "compare" constr(c1) constr(c2) ] -> [ compare c1 c2 ]
+| [ "compare" constr(c1) constr(c2) ] -> { compare c1 c2 }
END
diff --git a/plugins/ltac/g_tactic.ml4 b/plugins/ltac/g_tactic.mlg
index 31bc34a32..2e1ce814a 100644
--- a/plugins/ltac/g_tactic.ml4
+++ b/plugins/ltac/g_tactic.mlg
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Pp
open CErrors
open Util
@@ -215,486 +217,488 @@ let warn_deprecated_eqn_syntax =
open Pvernac.Vernac_
-GEXTEND Gram
+}
+
+GRAMMAR EXTEND Gram
GLOBAL: simple_tactic constr_with_bindings quantified_hypothesis
bindings red_expr int_or_var open_constr uconstr
simple_intropattern in_clause clause_dft_concl hypident destruction_arg;
int_or_var:
- [ [ n = integer -> ArgArg n
- | id = identref -> ArgVar id ] ]
+ [ [ n = integer -> { ArgArg n }
+ | id = identref -> { ArgVar id } ] ]
;
nat_or_var:
- [ [ n = natural -> ArgArg n
- | id = identref -> ArgVar id ] ]
+ [ [ n = natural -> { ArgArg n }
+ | id = identref -> { ArgVar id } ] ]
;
(* An identifier or a quotation meta-variable *)
id_or_meta:
- [ [ id = identref -> id ] ]
+ [ [ id = identref -> { id } ] ]
;
open_constr:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
uconstr:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
destruction_arg:
- [ [ n = natural -> (None,ElimOnAnonHyp n)
+ [ [ n = natural -> { (None,ElimOnAnonHyp n) }
| test_lpar_id_rpar; c = constr_with_bindings ->
- (Some false,destruction_arg_of_constr c)
- | c = constr_with_bindings_arg -> on_snd destruction_arg_of_constr c
+ { (Some false,destruction_arg_of_constr c) }
+ | c = constr_with_bindings_arg -> { on_snd destruction_arg_of_constr c }
] ]
;
constr_with_bindings_arg:
- [ [ ">"; c = constr_with_bindings -> (Some true,c)
- | c = constr_with_bindings -> (None,c) ] ]
+ [ [ ">"; c = constr_with_bindings -> { (Some true,c) }
+ | c = constr_with_bindings -> { (None,c) } ] ]
;
quantified_hypothesis:
- [ [ id = ident -> NamedHyp id
- | n = natural -> AnonHyp n ] ]
+ [ [ id = ident -> { NamedHyp id }
+ | n = natural -> { AnonHyp n } ] ]
;
conversion:
- [ [ c = constr -> (None, c)
- | c1 = constr; "with"; c2 = constr -> (Some (AllOccurrences,c1),c2)
+ [ [ c = constr -> { (None, c) }
+ | c1 = constr; "with"; c2 = constr -> { (Some (AllOccurrences,c1),c2) }
| c1 = constr; "at"; occs = occs_nums; "with"; c2 = constr ->
- (Some (occs,c1), c2) ] ]
+ { (Some (occs,c1), c2) } ] ]
;
occs_nums:
- [ [ nl = LIST1 nat_or_var -> OnlyOccurrences nl
+ [ [ nl = LIST1 nat_or_var -> { OnlyOccurrences nl }
| "-"; n = nat_or_var; nl = LIST0 int_or_var ->
(* have used int_or_var instead of nat_or_var for compatibility *)
- AllOccurrencesBut (List.map (map_int_or_var abs) (n::nl)) ] ]
+ { AllOccurrencesBut (List.map (map_int_or_var abs) (n::nl)) } ] ]
;
occs:
- [ [ "at"; occs = occs_nums -> occs | -> AllOccurrences ] ]
+ [ [ "at"; occs = occs_nums -> { occs } | -> { AllOccurrences } ] ]
;
pattern_occ:
- [ [ c = constr; nl = occs -> (nl,c) ] ]
+ [ [ c = constr; nl = occs -> { (nl,c) } ] ]
;
ref_or_pattern_occ:
(* If a string, it is interpreted as a ref
(anyway a Coq string does not reduce) *)
- [ [ c = smart_global; nl = occs -> nl,Inl c
- | c = constr; nl = occs -> nl,Inr c ] ]
+ [ [ c = smart_global; nl = occs -> { nl,Inl c }
+ | c = constr; nl = occs -> { nl,Inr c } ] ]
;
unfold_occ:
- [ [ c = smart_global; nl = occs -> (nl,c) ] ]
+ [ [ c = smart_global; nl = occs -> { (nl,c) } ] ]
;
intropatterns:
- [ [ l = LIST0 nonsimple_intropattern -> l ]]
+ [ [ l = LIST0 nonsimple_intropattern -> { l } ] ]
;
ne_intropatterns:
- [ [ l = LIST1 nonsimple_intropattern -> l ]]
+ [ [ l = LIST1 nonsimple_intropattern -> { l } ] ]
;
or_and_intropattern:
- [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> IntroOrPattern tc
- | "()" -> IntroAndPattern []
- | "("; si = simple_intropattern; ")" -> IntroAndPattern [si]
+ [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> { IntroOrPattern tc }
+ | "()" -> { IntroAndPattern [] }
+ | "("; si = simple_intropattern; ")" -> { IntroAndPattern [si] }
| "("; si = simple_intropattern; ",";
tc = LIST1 simple_intropattern SEP "," ; ")" ->
- IntroAndPattern (si::tc)
+ { IntroAndPattern (si::tc) }
| "("; si = simple_intropattern; "&";
tc = LIST1 simple_intropattern SEP "&" ; ")" ->
(* (A & B & C) is translated into (A,(B,C)) *)
- let rec pairify = function
+ { let rec pairify = function
| ([]|[_]|[_;_]) as l -> l
| t::q -> [t; CAst.make ?loc:(loc_of_ne_list q) (IntroAction (IntroOrAndPattern (IntroAndPattern (pairify q))))]
- in IntroAndPattern (pairify (si::tc)) ] ]
+ in IntroAndPattern (pairify (si::tc)) } ] ]
;
equality_intropattern:
- [ [ "->" -> IntroRewrite true
- | "<-" -> IntroRewrite false
- | "[="; tc = intropatterns; "]" -> IntroInjection tc ] ]
+ [ [ "->" -> { IntroRewrite true }
+ | "<-" -> { IntroRewrite false }
+ | "[="; tc = intropatterns; "]" -> { IntroInjection tc } ] ]
;
naming_intropattern:
- [ [ prefix = pattern_ident -> IntroFresh prefix
- | "?" -> IntroAnonymous
- | id = ident -> IntroIdentifier id ] ]
+ [ [ prefix = pattern_ident -> { IntroFresh prefix }
+ | "?" -> { IntroAnonymous }
+ | id = ident -> { IntroIdentifier id } ] ]
;
nonsimple_intropattern:
- [ [ l = simple_intropattern -> l
- | "*" -> CAst.make ~loc:!@loc @@ IntroForthcoming true
- | "**" -> CAst.make ~loc:!@loc @@ IntroForthcoming false ]]
+ [ [ l = simple_intropattern -> { l }
+ | "*" -> { CAst.make ~loc @@ IntroForthcoming true }
+ | "**" -> { CAst.make ~loc @@ IntroForthcoming false } ] ]
;
simple_intropattern:
[ [ pat = simple_intropattern_closed;
- l = LIST0 ["%"; c = operconstr LEVEL "0" -> c] ->
- let {CAst.loc=loc0;v=pat} = pat in
+ l = LIST0 ["%"; c = operconstr LEVEL "0" -> { c } ] ->
+ { let {CAst.loc=loc0;v=pat} = pat in
let f c pat =
let loc1 = Constrexpr_ops.constr_loc c in
let loc = Loc.merge_opt loc0 loc1 in
IntroAction (IntroApplyOn (CAst.(make ?loc:loc1 c),CAst.(make ?loc pat))) in
- CAst.make ~loc:!@loc @@ List.fold_right f l pat ] ]
+ CAst.make ~loc @@ List.fold_right f l pat } ] ]
;
simple_intropattern_closed:
- [ [ pat = or_and_intropattern -> CAst.make ~loc:!@loc @@ IntroAction (IntroOrAndPattern pat)
- | pat = equality_intropattern -> CAst.make ~loc:!@loc @@ IntroAction pat
- | "_" -> CAst.make ~loc:!@loc @@ IntroAction IntroWildcard
- | pat = naming_intropattern -> CAst.make ~loc:!@loc @@ IntroNaming pat ] ]
+ [ [ pat = or_and_intropattern -> { CAst.make ~loc @@ IntroAction (IntroOrAndPattern pat) }
+ | pat = equality_intropattern -> { CAst.make ~loc @@ IntroAction pat }
+ | "_" -> { CAst.make ~loc @@ IntroAction IntroWildcard }
+ | pat = naming_intropattern -> { CAst.make ~loc @@ IntroNaming pat } ] ]
;
simple_binding:
- [ [ "("; id = ident; ":="; c = lconstr; ")" -> CAst.make ~loc:!@loc (NamedHyp id, c)
- | "("; n = natural; ":="; c = lconstr; ")" -> CAst.make ~loc:!@loc (AnonHyp n, c) ] ]
+ [ [ "("; id = ident; ":="; c = lconstr; ")" -> { CAst.make ~loc (NamedHyp id, c) }
+ | "("; n = natural; ":="; c = lconstr; ")" -> { CAst.make ~loc (AnonHyp n, c) } ] ]
;
bindings:
[ [ test_lpar_idnum_coloneq; bl = LIST1 simple_binding ->
- ExplicitBindings bl
- | bl = LIST1 constr -> ImplicitBindings bl ] ]
+ { ExplicitBindings bl }
+ | bl = LIST1 constr -> { ImplicitBindings bl } ] ]
;
constr_with_bindings:
- [ [ c = constr; l = with_bindings -> (c, l) ] ]
+ [ [ c = constr; l = with_bindings -> { (c, l) } ] ]
;
with_bindings:
- [ [ "with"; bl = bindings -> bl | -> NoBindings ] ]
+ [ [ "with"; bl = bindings -> { bl } | -> { NoBindings } ] ]
;
red_flags:
- [ [ IDENT "beta" -> [FBeta]
- | IDENT "iota" -> [FMatch;FFix;FCofix]
- | IDENT "match" -> [FMatch]
- | IDENT "fix" -> [FFix]
- | IDENT "cofix" -> [FCofix]
- | IDENT "zeta" -> [FZeta]
- | IDENT "delta"; d = delta_flag -> [d]
+ [ [ IDENT "beta" -> { [FBeta] }
+ | IDENT "iota" -> { [FMatch;FFix;FCofix] }
+ | IDENT "match" -> { [FMatch] }
+ | IDENT "fix" -> { [FFix] }
+ | IDENT "cofix" -> { [FCofix] }
+ | IDENT "zeta" -> { [FZeta] }
+ | IDENT "delta"; d = delta_flag -> { [d] }
] ]
;
delta_flag:
- [ [ "-"; "["; idl = LIST1 smart_global; "]" -> FDeltaBut idl
- | "["; idl = LIST1 smart_global; "]" -> FConst idl
- | -> FDeltaBut []
+ [ [ "-"; "["; idl = LIST1 smart_global; "]" -> { FDeltaBut idl }
+ | "["; idl = LIST1 smart_global; "]" -> { FConst idl }
+ | -> { FDeltaBut [] }
] ]
;
strategy_flag:
- [ [ s = LIST1 red_flags -> Redops.make_red_flag (List.flatten s)
- | d = delta_flag -> all_with d
+ [ [ s = LIST1 red_flags -> { Redops.make_red_flag (List.flatten s) }
+ | d = delta_flag -> { all_with d }
] ]
;
red_expr:
- [ [ IDENT "red" -> Red false
- | IDENT "hnf" -> Hnf
- | IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ -> Simpl (all_with d,po)
- | IDENT "cbv"; s = strategy_flag -> Cbv s
- | IDENT "cbn"; s = strategy_flag -> Cbn s
- | IDENT "lazy"; s = strategy_flag -> Lazy s
- | IDENT "compute"; delta = delta_flag -> Cbv (all_with delta)
- | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> CbvVm po
- | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> CbvNative po
- | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> Unfold ul
- | IDENT "fold"; cl = LIST1 constr -> Fold cl
- | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> Pattern pl
- | s = IDENT -> ExtraRedExpr s ] ]
+ [ [ IDENT "red" -> { Red false }
+ | IDENT "hnf" -> { Hnf }
+ | IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ -> { Simpl (all_with d,po) }
+ | IDENT "cbv"; s = strategy_flag -> { Cbv s }
+ | IDENT "cbn"; s = strategy_flag -> { Cbn s }
+ | IDENT "lazy"; s = strategy_flag -> { Lazy s }
+ | IDENT "compute"; delta = delta_flag -> { Cbv (all_with delta) }
+ | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> { CbvVm po }
+ | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> { CbvNative po }
+ | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> { Unfold ul }
+ | IDENT "fold"; cl = LIST1 constr -> { Fold cl }
+ | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> { Pattern pl }
+ | s = IDENT -> { ExtraRedExpr s } ] ]
;
hypident:
[ [ id = id_or_meta ->
- let id : lident = id in
- id,InHyp
+ { let id : lident = id in
+ id,InHyp }
| "("; IDENT "type"; IDENT "of"; id = id_or_meta; ")" ->
- let id : lident = id in
- id,InHypTypeOnly
+ { let id : lident = id in
+ id,InHypTypeOnly }
| "("; IDENT "value"; IDENT "of"; id = id_or_meta; ")" ->
- let id : lident = id in
- id,InHypValueOnly
+ { let id : lident = id in
+ id,InHypValueOnly }
] ]
;
hypident_occ:
- [ [ (id,l)=hypident; occs=occs ->
+ [ [ h=hypident; occs=occs ->
+ { let (id,l) = h in
let id : lident = id in
- ((occs,id),l) ] ]
+ ((occs,id),l) } ] ]
;
in_clause:
[ [ "*"; occs=occs ->
- {onhyps=None; concl_occs=occs}
+ { {onhyps=None; concl_occs=occs} }
| "*"; "|-"; occs=concl_occ ->
- {onhyps=None; concl_occs=occs}
+ { {onhyps=None; concl_occs=occs} }
| hl=LIST0 hypident_occ SEP","; "|-"; occs=concl_occ ->
- {onhyps=Some hl; concl_occs=occs}
+ { {onhyps=Some hl; concl_occs=occs} }
| hl=LIST0 hypident_occ SEP"," ->
- {onhyps=Some hl; concl_occs=NoOccurrences} ] ]
+ { {onhyps=Some hl; concl_occs=NoOccurrences} } ] ]
;
clause_dft_concl:
- [ [ "in"; cl = in_clause -> cl
- | occs=occs -> {onhyps=Some[]; concl_occs=occs}
- | -> all_concl_occs_clause ] ]
+ [ [ "in"; cl = in_clause -> { cl }
+ | occs=occs -> { {onhyps=Some[]; concl_occs=occs} }
+ | -> { all_concl_occs_clause } ] ]
;
clause_dft_all:
- [ [ "in"; cl = in_clause -> cl
- | -> {onhyps=None; concl_occs=AllOccurrences} ] ]
+ [ [ "in"; cl = in_clause -> { cl }
+ | -> { {onhyps=None; concl_occs=AllOccurrences} } ] ]
;
opt_clause:
- [ [ "in"; cl = in_clause -> Some cl
- | "at"; occs = occs_nums -> Some {onhyps=Some[]; concl_occs=occs}
- | -> None ] ]
+ [ [ "in"; cl = in_clause -> { Some cl }
+ | "at"; occs = occs_nums -> { Some {onhyps=Some[]; concl_occs=occs} }
+ | -> { None } ] ]
;
concl_occ:
- [ [ "*"; occs = occs -> occs
- | -> NoOccurrences ] ]
+ [ [ "*"; occs = occs -> { occs }
+ | -> { NoOccurrences } ] ]
;
in_hyp_list:
- [ [ "in"; idl = LIST1 id_or_meta -> idl
- | -> [] ] ]
+ [ [ "in"; idl = LIST1 id_or_meta -> { idl }
+ | -> { [] } ] ]
;
in_hyp_as:
- [ [ "in"; id = id_or_meta; ipat = as_ipat -> Some (id,ipat)
- | -> None ] ]
+ [ [ "in"; id = id_or_meta; ipat = as_ipat -> { Some (id,ipat) }
+ | -> { None } ] ]
;
orient:
- [ [ "->" -> true
- | "<-" -> false
- | -> true ]]
+ [ [ "->" -> { true }
+ | "<-" -> { false }
+ | -> { true } ] ]
;
simple_binder:
- [ [ na=name -> ([na],Default Explicit, CAst.make ~loc:!@loc @@
- CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None))
- | "("; nal=LIST1 name; ":"; c=lconstr; ")" -> (nal,Default Explicit,c)
+ [ [ na=name -> { ([na],Default Explicit, CAst.make ~loc @@
+ CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None)) }
+ | "("; nal=LIST1 name; ":"; c=lconstr; ")" -> { (nal,Default Explicit,c) }
] ]
;
fixdecl:
[ [ "("; id = ident; bl=LIST0 simple_binder; ann=fixannot;
- ":"; ty=lconstr; ")" -> (!@loc, id, bl, ann, ty) ] ]
+ ":"; ty=lconstr; ")" -> { (loc, id, bl, ann, ty) } ] ]
;
fixannot:
- [ [ "{"; IDENT "struct"; id=name; "}" -> Some id
- | -> None ] ]
+ [ [ "{"; IDENT "struct"; id=name; "}" -> { Some id }
+ | -> { None } ] ]
;
cofixdecl:
[ [ "("; id = ident; bl=LIST0 simple_binder; ":"; ty=lconstr; ")" ->
- (!@loc, id, bl, None, ty) ] ]
+ { (loc, id, bl, None, ty) } ] ]
;
bindings_with_parameters:
[ [ check_for_coloneq; "("; id = ident; bl = LIST0 simple_binder;
- ":="; c = lconstr; ")" -> (id, mkCLambdaN_simple bl c) ] ]
+ ":="; c = lconstr; ")" -> { (id, mkCLambdaN_simple bl c) } ] ]
;
eliminator:
- [ [ "using"; el = constr_with_bindings -> el ] ]
+ [ [ "using"; el = constr_with_bindings -> { el } ] ]
;
as_ipat:
- [ [ "as"; ipat = simple_intropattern -> Some ipat
- | -> None ] ]
+ [ [ "as"; ipat = simple_intropattern -> { Some ipat }
+ | -> { None } ] ]
;
or_and_intropattern_loc:
- [ [ ipat = or_and_intropattern -> ArgArg (CAst.make ~loc:!@loc ipat)
- | locid = identref -> ArgVar locid ] ]
+ [ [ ipat = or_and_intropattern -> { ArgArg (CAst.make ~loc ipat) }
+ | locid = identref -> { ArgVar locid } ] ]
;
as_or_and_ipat:
- [ [ "as"; ipat = or_and_intropattern_loc -> Some ipat
- | -> None ] ]
+ [ [ "as"; ipat = or_and_intropattern_loc -> { Some ipat }
+ | -> { None } ] ]
;
eqn_ipat:
- [ [ IDENT "eqn"; ":"; pat = naming_intropattern -> Some (CAst.make ~loc:!@loc pat)
+ [ [ IDENT "eqn"; ":"; pat = naming_intropattern -> { Some (CAst.make ~loc pat) }
| IDENT "_eqn"; ":"; pat = naming_intropattern ->
- let loc = !@loc in
- warn_deprecated_eqn_syntax ~loc "H"; Some (CAst.make ~loc pat)
+ { warn_deprecated_eqn_syntax ~loc "H"; Some (CAst.make ~loc pat) }
| IDENT "_eqn" ->
- let loc = !@loc in
- warn_deprecated_eqn_syntax ~loc "?"; Some (CAst.make ~loc IntroAnonymous)
- | -> None ] ]
+ { warn_deprecated_eqn_syntax ~loc "?"; Some (CAst.make ~loc IntroAnonymous) }
+ | -> { None } ] ]
;
as_name:
- [ [ "as"; id = ident ->Names.Name.Name id | -> Names.Name.Anonymous ] ]
+ [ [ "as"; id = ident -> { Names.Name.Name id } | -> { Names.Name.Anonymous } ] ]
;
by_tactic:
- [ [ "by"; tac = tactic_expr LEVEL "3" -> Some tac
- | -> None ] ]
+ [ [ "by"; tac = tactic_expr LEVEL "3" -> { Some tac }
+ | -> { None } ] ]
;
rewriter :
- [ [ "!"; c = constr_with_bindings_arg -> (Equality.RepeatPlus,c)
- | ["?"| LEFTQMARK]; c = constr_with_bindings_arg -> (Equality.RepeatStar,c)
- | n = natural; "!"; c = constr_with_bindings_arg -> (Equality.Precisely n,c)
- | n = natural; ["?" | LEFTQMARK]; c = constr_with_bindings_arg -> (Equality.UpTo n,c)
- | n = natural; c = constr_with_bindings_arg -> (Equality.Precisely n,c)
- | c = constr_with_bindings_arg -> (Equality.Precisely 1, c)
+ [ [ "!"; c = constr_with_bindings_arg -> { (Equality.RepeatPlus,c) }
+ | ["?" -> { () } | LEFTQMARK -> { () } ]; c = constr_with_bindings_arg -> { (Equality.RepeatStar,c) }
+ | n = natural; "!"; c = constr_with_bindings_arg -> { (Equality.Precisely n,c) }
+ | n = natural; ["?" -> { () } | LEFTQMARK -> { () } ]; c = constr_with_bindings_arg -> { (Equality.UpTo n,c) }
+ | n = natural; c = constr_with_bindings_arg -> { (Equality.Precisely n,c) }
+ | c = constr_with_bindings_arg -> { (Equality.Precisely 1, c) }
] ]
;
oriented_rewriter :
- [ [ b = orient; p = rewriter -> let (m,c) = p in (b,m,c) ] ]
+ [ [ b = orient; p = rewriter -> { let (m,c) = p in (b,m,c) } ] ]
;
induction_clause:
[ [ c = destruction_arg; pat = as_or_and_ipat; eq = eqn_ipat;
- cl = opt_clause -> (c,(eq,pat),cl) ] ]
+ cl = opt_clause -> { (c,(eq,pat),cl) } ] ]
;
induction_clause_list:
[ [ ic = LIST1 induction_clause SEP ","; el = OPT eliminator;
cl_tolerance = opt_clause ->
(* Condition for accepting "in" at the end by compatibility *)
- match ic,el,cl_tolerance with
+ { match ic,el,cl_tolerance with
| [c,pat,None],Some _,Some _ -> ([c,pat,cl_tolerance],el)
| _,_,Some _ -> err ()
- | _,_,None -> (ic,el) ]]
+ | _,_,None -> (ic,el) } ] ]
;
simple_tactic:
[ [
(* Basic tactics *)
IDENT "intros"; pl = ne_intropatterns ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (false,pl))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (false,pl)) }
| IDENT "intros" ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (false,[CAst.make ~loc:!@loc @@IntroForthcoming false]))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (false,[CAst.make ~loc @@IntroForthcoming false])) }
| IDENT "eintros"; pl = ne_intropatterns ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (true,pl))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (true,pl)) }
| IDENT "apply"; cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (true,false,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (true,false,cl,inhyp)) }
| IDENT "eapply"; cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (true,true,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (true,true,cl,inhyp)) }
| IDENT "simple"; IDENT "apply";
cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (false,false,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (false,false,cl,inhyp)) }
| IDENT "simple"; IDENT "eapply";
cl = LIST1 constr_with_bindings_arg SEP",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (false,true,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (false,true,cl,inhyp)) }
| IDENT "elim"; cl = constr_with_bindings_arg; el = OPT eliminator ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacElim (false,cl,el))
+ { TacAtom (Loc.tag ~loc @@ TacElim (false,cl,el)) }
| IDENT "eelim"; cl = constr_with_bindings_arg; el = OPT eliminator ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacElim (true,cl,el))
- | IDENT "case"; icl = induction_clause_list -> TacAtom (Loc.tag ~loc:!@loc @@ mkTacCase false icl)
- | IDENT "ecase"; icl = induction_clause_list -> TacAtom (Loc.tag ~loc:!@loc @@ mkTacCase true icl)
+ { TacAtom (Loc.tag ~loc @@ TacElim (true,cl,el)) }
+ | IDENT "case"; icl = induction_clause_list -> { TacAtom (Loc.tag ~loc @@ mkTacCase false icl) }
+ | IDENT "ecase"; icl = induction_clause_list -> { TacAtom (Loc.tag ~loc @@ mkTacCase true icl) }
| "fix"; id = ident; n = natural; "with"; fd = LIST1 fixdecl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacMutualFix (id,n,List.map mk_fix_tac fd))
+ { TacAtom (Loc.tag ~loc @@ TacMutualFix (id,n,List.map mk_fix_tac fd)) }
| "cofix"; id = ident; "with"; fd = LIST1 cofixdecl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacMutualCofix (id,List.map mk_cofix_tac fd))
+ { TacAtom (Loc.tag ~loc @@ TacMutualCofix (id,List.map mk_cofix_tac fd)) }
- | IDENT "pose"; (id,b) = bindings_with_parameters ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,Names.Name.Name id,b,Locusops.nowhere,true,None))
+ | IDENT "pose"; bl = bindings_with_parameters ->
+ { let (id,b) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (false,Names.Name.Name id,b,Locusops.nowhere,true,None)) }
| IDENT "pose"; b = constr; na = as_name ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,b,Locusops.nowhere,true,None))
- | IDENT "epose"; (id,b) = bindings_with_parameters ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,Names.Name id,b,Locusops.nowhere,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,b,Locusops.nowhere,true,None)) }
+ | IDENT "epose"; bl = bindings_with_parameters ->
+ { let (id,b) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (true,Names.Name id,b,Locusops.nowhere,true,None)) }
| IDENT "epose"; b = constr; na = as_name ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,b,Locusops.nowhere,true,None))
- | IDENT "set"; (id,c) = bindings_with_parameters; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,Names.Name.Name id,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,b,Locusops.nowhere,true,None)) }
+ | IDENT "set"; bl = bindings_with_parameters; p = clause_dft_concl ->
+ { let (id,c) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (false,Names.Name.Name id,c,p,true,None)) }
| IDENT "set"; c = constr; na = as_name; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,c,p,true,None))
- | IDENT "eset"; (id,c) = bindings_with_parameters; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,Names.Name id,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,c,p,true,None)) }
+ | IDENT "eset"; bl = bindings_with_parameters; p = clause_dft_concl ->
+ { let (id,c) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (true,Names.Name id,c,p,true,None)) }
| IDENT "eset"; c = constr; na = as_name; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,c,p,true,None)) }
| IDENT "remember"; c = constr; na = as_name; e = eqn_ipat;
p = clause_dft_all ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,c,p,false,e))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,c,p,false,e)) }
| IDENT "eremember"; c = constr; na = as_name; e = eqn_ipat;
p = clause_dft_all ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,c,p,false,e))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,c,p,false,e)) }
(* Alternative syntax for "pose proof c as id" *)
| IDENT "assert"; test_lpar_id_coloneq; "("; lid = identref; ":=";
c = lconstr; ")" ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eassert"; test_lpar_id_coloneq; "("; lid = identref; ":=";
c = lconstr; ")" ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
(* Alternative syntax for "assert c as id by tac" *)
| IDENT "assert"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eassert"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
(* Alternative syntax for "enough c as id by tac" *)
| IDENT "enough"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eenough"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "assert"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,true,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,true,Some tac,ipat,c)) }
| IDENT "eassert"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,true,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,true,Some tac,ipat,c)) }
| IDENT "pose"; IDENT "proof"; c = lconstr; ipat = as_ipat ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,true,None,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,true,None,ipat,c)) }
| IDENT "epose"; IDENT "proof"; c = lconstr; ipat = as_ipat ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,true,None,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,true,None,ipat,c)) }
| IDENT "enough"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,false,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,false,Some tac,ipat,c)) }
| IDENT "eenough"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,false,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,false,Some tac,ipat,c)) }
| IDENT "generalize"; c = constr ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize [((AllOccurrences,c),Names.Name.Anonymous)])
+ { TacAtom (Loc.tag ~loc @@ TacGeneralize [((AllOccurrences,c),Names.Name.Anonymous)]) }
| IDENT "generalize"; c = constr; l = LIST1 constr ->
- let gen_everywhere c = ((AllOccurrences,c),Names.Name.Anonymous) in
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize (List.map gen_everywhere (c::l)))
+ { let gen_everywhere c = ((AllOccurrences,c),Names.Name.Anonymous) in
+ TacAtom (Loc.tag ~loc @@ TacGeneralize (List.map gen_everywhere (c::l))) }
| IDENT "generalize"; c = constr; lookup_at_as_comma; nl = occs;
na = as_name;
- l = LIST0 [","; c = pattern_occ; na = as_name -> (c,na)] ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize (((nl,c),na)::l))
+ l = LIST0 [","; c = pattern_occ; na = as_name -> { (c,na) } ] ->
+ { TacAtom (Loc.tag ~loc @@ TacGeneralize (((nl,c),na)::l)) }
(* Derived basic tactics *)
| IDENT "induction"; ic = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct (true,false,ic))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct (true,false,ic)) }
| IDENT "einduction"; ic = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(true,true,ic))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(true,true,ic)) }
| IDENT "destruct"; icl = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,false,icl))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(false,false,icl)) }
| IDENT "edestruct"; icl = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,true,icl))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(false,true,icl)) }
(* Equality and inversion *)
| IDENT "rewrite"; l = LIST1 oriented_rewriter SEP ",";
- cl = clause_dft_concl; t=by_tactic -> TacAtom (Loc.tag ~loc:!@loc @@ TacRewrite (false,l,cl,t))
+ cl = clause_dft_concl; t=by_tactic -> { TacAtom (Loc.tag ~loc @@ TacRewrite (false,l,cl,t)) }
| IDENT "erewrite"; l = LIST1 oriented_rewriter SEP ",";
- cl = clause_dft_concl; t=by_tactic -> TacAtom (Loc.tag ~loc:!@loc @@ TacRewrite (true,l,cl,t))
+ cl = clause_dft_concl; t=by_tactic -> { TacAtom (Loc.tag ~loc @@ TacRewrite (true,l,cl,t)) }
| IDENT "dependent"; k =
- [ IDENT "simple"; IDENT "inversion" -> SimpleInversion
- | IDENT "inversion" -> FullInversion
- | IDENT "inversion_clear" -> FullInversionClear ];
+ [ IDENT "simple"; IDENT "inversion" -> { SimpleInversion }
+ | IDENT "inversion" -> { FullInversion }
+ | IDENT "inversion_clear" -> { FullInversionClear } ];
hyp = quantified_hypothesis;
- ids = as_or_and_ipat; co = OPT ["with"; c = constr -> c] ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (DepInversion (k,co,ids),hyp))
+ ids = as_or_and_ipat; co = OPT ["with"; c = constr -> { c } ] ->
+ { TacAtom (Loc.tag ~loc @@ TacInversion (DepInversion (k,co,ids),hyp)) }
| IDENT "simple"; IDENT "inversion";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (SimpleInversion, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (SimpleInversion, cl, ids), hyp)) }
| IDENT "inversion";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (FullInversion, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (FullInversion, cl, ids), hyp)) }
| IDENT "inversion_clear";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (FullInversionClear, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (FullInversionClear, cl, ids), hyp)) }
| IDENT "inversion"; hyp = quantified_hypothesis;
"using"; c = constr; cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (InversionUsing (c,cl), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (InversionUsing (c,cl), hyp)) }
(* Conversion *)
| IDENT "red"; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Red false, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Red false, cl)) }
| IDENT "hnf"; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Hnf, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Hnf, cl)) }
| IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Simpl (all_with d, po), cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Simpl (all_with d, po), cl)) }
| IDENT "cbv"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbv s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbv s, cl)) }
| IDENT "cbn"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbn s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbn s, cl)) }
| IDENT "lazy"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Lazy s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Lazy s, cl)) }
| IDENT "compute"; delta = delta_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbv (all_with delta), cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbv (all_with delta), cl)) }
| IDENT "vm_compute"; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (CbvVm po, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (CbvVm po, cl)) }
| IDENT "native_compute"; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (CbvNative po, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (CbvNative po, cl)) }
| IDENT "unfold"; ul = LIST1 unfold_occ SEP ","; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Unfold ul, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Unfold ul, cl)) }
| IDENT "fold"; l = LIST1 constr; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Fold l, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Fold l, cl)) }
| IDENT "pattern"; pl = LIST1 pattern_occ SEP","; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Pattern pl, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Pattern pl, cl)) }
(* Change ne doit pas s'appliquer dans un Definition t := Eval ... *)
- | IDENT "change"; (oc,c) = conversion; cl = clause_dft_concl ->
- let p,cl = merge_occurrences (!@loc) cl oc in
- TacAtom (Loc.tag ~loc:!@loc @@ TacChange (p,c,cl))
+ | IDENT "change"; c = conversion; cl = clause_dft_concl ->
+ { let (oc, c) = c in
+ let p,cl = merge_occurrences loc cl oc in
+ TacAtom (Loc.tag ~loc @@ TacChange (p,c,cl)) }
] ]
;
-END;;
+END
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 09179dad3..4357689ee 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -115,7 +115,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let keyword x = tag_keyword (str x)
let primitive x = tag_primitive (str x)
- let has_type (Val.Dyn (tag, x)) t = match Val.eq tag t with
+ let has_type (Val.Dyn (tag, _)) t = match Val.eq tag t with
| None -> false
| Some _ -> true
@@ -188,7 +188,7 @@ let string_of_genarg_arg (ArgumentType arg) =
| AN v -> f v
| ByNotation (s,sc) -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc)
- let pr_located pr (loc,x) = pr x
+ let pr_located pr (_,x) = pr x
let pr_evaluable_reference = function
| EvalVarRef id -> pr_id id
@@ -240,7 +240,7 @@ let string_of_genarg_arg (ArgumentType arg) =
in
pr_sequence (fun x -> x) l
- let pr_extend_gen pr_gen lev { mltac_name = s; mltac_index = i } l =
+ let pr_extend_gen pr_gen _ { mltac_name = s; mltac_index = i } l =
let name =
str s.mltac_plugin ++ str "::" ++ str s.mltac_tactic ++
str "@" ++ int i
@@ -260,7 +260,7 @@ let string_of_genarg_arg (ArgumentType arg) =
| Extend.Uentry tag ->
let ArgT.Any tag = tag in
ArgT.repr tag
- | Extend.Uentryl (tkn, lvl) -> "tactic" ^ string_of_int lvl
+ | Extend.Uentryl (_, lvl) -> "tactic" ^ string_of_int lvl
let pr_alias_key key =
try
@@ -288,7 +288,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let p = pr_tacarg_using_rule pr_gen prods in
if pp.pptac_level > lev then surround p else p
with Not_found ->
- let pr arg = str "_" in
+ let pr _ = str "_" in
KerName.print key ++ spc() ++ pr_sequence pr l ++ str" (* Generic printer *)"
let pr_farg prtac arg = prtac (1, Any) (TacArg (Loc.tag arg))
@@ -341,14 +341,14 @@ let string_of_genarg_arg (ArgumentType arg) =
pr_any_arg pr symb arg
| _ -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
- let pr_raw_extend_rec prc prlc prtac prpat =
+ let pr_raw_extend_rec prtac =
pr_extend_gen (pr_farg prtac)
- let pr_glob_extend_rec prc prlc prtac prpat =
+ let pr_glob_extend_rec prtac =
pr_extend_gen (pr_farg prtac)
- let pr_raw_alias prc prlc prtac prpat lev key args =
+ let pr_raw_alias prtac lev key args =
pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.tag a)))) lev key args
- let pr_glob_alias prc prlc prtac prpat lev key args =
+ let pr_glob_alias prtac lev key args =
pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.tag a)))) lev key args
(**********************************************************************)
@@ -743,7 +743,7 @@ let pr_goal_selector ~toplevel s =
(* Main tactic printer *)
and pr_atom1 a = tag_atom a (match a with
(* Basic tactics *)
- | TacIntroPattern (ev,[]) as t ->
+ | TacIntroPattern (_,[]) as t ->
pr_atom0 t
| TacIntroPattern (ev,(_::_ as p)) ->
hov 1 (primitive (if ev then "eintros" else "intros") ++
@@ -1054,7 +1054,7 @@ let pr_goal_selector ~toplevel s =
primitive "fresh" ++ pr_fresh_ids l, latom
| TacArg(_,TacGeneric arg) ->
pr.pr_generic arg, latom
- | TacArg(_,TacCall(loc,(f,[]))) ->
+ | TacArg(_,TacCall(_,(f,[]))) ->
pr.pr_reference f, latom
| TacArg(_,TacCall(loc,(f,l))) ->
pr_with_comments ?loc (hov 1 (
@@ -1112,8 +1112,8 @@ let pr_goal_selector ~toplevel s =
pr_reference = pr_qualid;
pr_name = pr_lident;
pr_generic = (fun arg -> Pputils.pr_raw_generic (Global.env ()) arg);
- pr_extend = pr_raw_extend_rec pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
- pr_alias = pr_raw_alias pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
+ pr_extend = pr_raw_extend_rec pr_raw_tactic_level;
+ pr_alias = pr_raw_alias pr_raw_tactic_level;
} in
make_pr_tac
pr raw_printers
@@ -1142,12 +1142,8 @@ let pr_goal_selector ~toplevel s =
pr_reference = pr_ltac_or_var (pr_located pr_ltac_constant);
pr_name = pr_lident;
pr_generic = (fun arg -> Pputils.pr_glb_generic (Global.env ()) arg);
- pr_extend = pr_glob_extend_rec
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
- pr_alias = pr_glob_alias
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
+ pr_extend = pr_glob_extend_rec prtac;
+ pr_alias = pr_glob_alias prtac;
} in
make_pr_tac
pr glob_printers
@@ -1168,8 +1164,8 @@ let pr_goal_selector ~toplevel s =
| _ -> user_err Pp.(str "Cannot translate fix tactic: not enough products") in
strip_ty [] n ty
- let pr_atomic_tactic_level env sigma n t =
- let prtac n (t:atomic_tactic_expr) =
+ let pr_atomic_tactic_level env sigma t =
+ let prtac (t:atomic_tactic_expr) =
let pr = {
pr_tactic = (fun _ _ -> str "<tactic>");
pr_constr = (fun c -> pr_econstr_env env sigma c);
@@ -1188,18 +1184,15 @@ let pr_goal_selector ~toplevel s =
in
pr_atom pr strip_prod_binders_constr tag_atomic_tactic_expr t
in
- prtac n t
+ prtac t
let pr_raw_generic = Pputils.pr_raw_generic
let pr_glb_generic = Pputils.pr_glb_generic
- let pr_raw_extend env = pr_raw_extend_rec
- pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr
+ let pr_raw_extend _ = pr_raw_extend_rec pr_raw_tactic_level
- let pr_glob_extend env = pr_glob_extend_rec
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- (pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
+ let pr_glob_extend env = pr_glob_extend_rec (pr_glob_tactic_level env)
let pr_alias pr lev key args =
pr_alias_gen (fun _ arg -> pr arg) lev key args
@@ -1207,14 +1200,14 @@ let pr_goal_selector ~toplevel s =
let pr_extend pr lev ml args =
pr_extend_gen pr lev ml args
- let pr_atomic_tactic env sigma c = pr_atomic_tactic_level env sigma ltop c
+ let pr_atomic_tactic env sigma c = pr_atomic_tactic_level env sigma c
let declare_extra_genarg_pprule wit
(f : 'a raw_extra_genarg_printer)
(g : 'b glob_extra_genarg_printer)
(h : 'c extra_genarg_printer) =
begin match wit with
- | ExtraArg s -> ()
+ | ExtraArg _ -> ()
| _ -> user_err Pp.(str "Can declare a pretty-printing rule only for extra argument types.")
end;
let f x =
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index 01c52c413..9f8cd2fc4 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -409,7 +409,7 @@ module TypeGlobal = struct
let inverse env (evd,cstrs) car rel =
- let (evd, sort) = Evarutil.new_Type ~rigid:Evd.univ_flexible env evd in
+ let (evd, sort) = Evarutil.new_Type ~rigid:Evd.univ_flexible evd in
app_poly_check env (evd,cstrs) coq_inverse [| car ; car; sort; rel |]
end
diff --git a/plugins/ltac/taccoerce.ml b/plugins/ltac/taccoerce.ml
index cc9c2046d..026c00b84 100644
--- a/plugins/ltac/taccoerce.ml
+++ b/plugins/ltac/taccoerce.ml
@@ -165,8 +165,7 @@ let coerce_var_to_ident fresh env sigma v =
(* Interprets, if possible, a constr to an identifier which may not
be fresh but suitable to be given to the fresh tactic. Works for
vars, constants, inductive, constructors and sorts. *)
-let coerce_to_ident_not_fresh env sigma v =
-let g = sigma in
+let coerce_to_ident_not_fresh sigma v =
let id_of_name = function
| Name.Anonymous -> Id.of_string "x"
| Name.Name x -> x in
@@ -183,9 +182,9 @@ let id_of_name = function
| Some c ->
match EConstr.kind sigma c with
| Var id -> id
- | Meta m -> id_of_name (Evd.meta_name g m)
+ | Meta m -> id_of_name (Evd.meta_name sigma m)
| Evar (kn,_) ->
- begin match Evd.evar_ident kn g with
+ begin match Evd.evar_ident kn sigma with
| None -> fail ()
| Some id -> id
end
@@ -199,15 +198,16 @@ let id_of_name = function
let basename = Nametab.basename_of_global ref in
basename
| Sort s ->
- begin
+ begin
match ESorts.kind sigma s with
- | Sorts.Prop _ -> Label.to_id (Label.make "Prop")
- | Sorts.Type _ -> Label.to_id (Label.make "Type")
- end
+ | Sorts.Prop -> Label.to_id (Label.make "Prop")
+ | Sorts.Set -> Label.to_id (Label.make "Set")
+ | Sorts.Type _ -> Label.to_id (Label.make "Type")
+ end
| _ -> fail()
-let coerce_to_intro_pattern env sigma v =
+let coerce_to_intro_pattern sigma v =
if has_type v (topwit wit_intro_pattern) then
(out_gen (topwit wit_intro_pattern) v).CAst.v
else if has_type v (topwit wit_var) then
@@ -220,8 +220,8 @@ let coerce_to_intro_pattern env sigma v =
IntroNaming (IntroIdentifier (destVar sigma c))
| _ -> raise (CannotCoerceTo "an introduction pattern")
-let coerce_to_intro_pattern_naming env sigma v =
- match coerce_to_intro_pattern env sigma v with
+let coerce_to_intro_pattern_naming sigma v =
+ match coerce_to_intro_pattern sigma v with
| IntroNaming pat -> pat
| _ -> raise (CannotCoerceTo "a naming introduction pattern")
@@ -254,7 +254,7 @@ let coerce_to_constr env v =
(try [], constr_of_id env id with Not_found -> fail ())
else fail ()
-let coerce_to_uconstr env v =
+let coerce_to_uconstr v =
if has_type v (topwit wit_uconstr) then
out_gen (topwit wit_uconstr) v
else
@@ -298,11 +298,11 @@ let coerce_to_constr_list env v =
List.map map l
| None -> raise (CannotCoerceTo "a term list")
-let coerce_to_intro_pattern_list ?loc env sigma v =
+let coerce_to_intro_pattern_list ?loc sigma v =
match Value.to_list v with
| None -> raise (CannotCoerceTo "an intro pattern list")
| Some l ->
- let map v = CAst.make ?loc @@ coerce_to_intro_pattern env sigma v in
+ let map v = CAst.make ?loc @@ coerce_to_intro_pattern sigma v in
List.map map l
let coerce_to_hyp env sigma v =
@@ -327,7 +327,7 @@ let coerce_to_hyp_list env sigma v =
| None -> raise (CannotCoerceTo "a variable list")
(* Interprets a qualified name *)
-let coerce_to_reference env sigma v =
+let coerce_to_reference sigma v =
match Value.to_constr v with
| Some c ->
begin
@@ -355,7 +355,7 @@ let coerce_to_quantified_hypothesis sigma v =
(* Quantified named or numbered hypothesis or hypothesis in context *)
(* (as in Inversion) *)
-let coerce_to_decl_or_quant_hyp env sigma v =
+let coerce_to_decl_or_quant_hyp sigma v =
if has_type v (topwit wit_int) then
AnonHyp (out_gen (topwit wit_int) v)
else
diff --git a/plugins/ltac/taccoerce.mli b/plugins/ltac/taccoerce.mli
index 56f881684..d2ae92f6c 100644
--- a/plugins/ltac/taccoerce.mli
+++ b/plugins/ltac/taccoerce.mli
@@ -51,12 +51,12 @@ val coerce_to_constr_context : Value.t -> constr
val coerce_var_to_ident : bool -> Environ.env -> Evd.evar_map -> Value.t -> Id.t
-val coerce_to_ident_not_fresh : Environ.env -> Evd.evar_map -> Value.t -> Id.t
+val coerce_to_ident_not_fresh : Evd.evar_map -> Value.t -> Id.t
-val coerce_to_intro_pattern : Environ.env -> Evd.evar_map -> Value.t -> Tacexpr.delayed_open_constr intro_pattern_expr
+val coerce_to_intro_pattern : Evd.evar_map -> Value.t -> Tacexpr.delayed_open_constr intro_pattern_expr
val coerce_to_intro_pattern_naming :
- Environ.env -> Evd.evar_map -> Value.t -> Namegen.intro_pattern_naming_expr
+ Evd.evar_map -> Value.t -> Namegen.intro_pattern_naming_expr
val coerce_to_hint_base : Value.t -> string
@@ -64,7 +64,7 @@ val coerce_to_int : Value.t -> int
val coerce_to_constr : Environ.env -> Value.t -> Ltac_pretype.constr_under_binders
-val coerce_to_uconstr : Environ.env -> Value.t -> Ltac_pretype.closed_glob_constr
+val coerce_to_uconstr : Value.t -> Ltac_pretype.closed_glob_constr
val coerce_to_closed_constr : Environ.env -> Value.t -> constr
@@ -74,17 +74,17 @@ val coerce_to_evaluable_ref :
val coerce_to_constr_list : Environ.env -> Value.t -> constr list
val coerce_to_intro_pattern_list :
- ?loc:Loc.t -> Environ.env -> Evd.evar_map -> Value.t -> Tacexpr.intro_patterns
+ ?loc:Loc.t -> Evd.evar_map -> Value.t -> Tacexpr.intro_patterns
val coerce_to_hyp : Environ.env -> Evd.evar_map -> Value.t -> Id.t
val coerce_to_hyp_list : Environ.env -> Evd.evar_map -> Value.t -> Id.t list
-val coerce_to_reference : Environ.env -> Evd.evar_map -> Value.t -> GlobRef.t
+val coerce_to_reference : Evd.evar_map -> Value.t -> GlobRef.t
val coerce_to_quantified_hypothesis : Evd.evar_map -> Value.t -> quantified_hypothesis
-val coerce_to_decl_or_quant_hyp : Environ.env -> Evd.evar_map -> Value.t -> quantified_hypothesis
+val coerce_to_decl_or_quant_hyp : Evd.evar_map -> Value.t -> quantified_hypothesis
val coerce_to_int_or_var_list : Value.t -> int Locus.or_var list
diff --git a/plugins/ltac/tacentries.ml b/plugins/ltac/tacentries.ml
index 98d451536..fac464a62 100644
--- a/plugins/ltac/tacentries.ml
+++ b/plugins/ltac/tacentries.ml
@@ -45,7 +45,7 @@ let coincide s pat off =
let atactic n =
if n = 5 then Aentry Pltac.binder_tactic
- else Aentryl (Pltac.tactic_expr, n)
+ else Aentryl (Pltac.tactic_expr, string_of_int n)
type entry_name = EntryName :
'a raw_abstract_argument_type * (Tacexpr.raw_tactic_expr, 'a) Extend.symbol -> entry_name
@@ -398,7 +398,7 @@ let create_ltac_quotation name cast (e, l) =
let () = ltac_quotations := String.Set.add name !ltac_quotations in
let entry = match l with
| None -> Aentry e
- | Some l -> Aentryl (e, l)
+ | Some l -> Aentryl (e, string_of_int l)
in
(* let level = Some "1" in *)
let level = None in
@@ -554,13 +554,18 @@ let () =
] in
register_grammars_by_name "tactic" entries
+let get_identifier id =
+ (** Workaround for badly-designed generic arguments lacking a closure *)
+ Names.Id.of_string_soft ("$" ^ id)
+
+
type _ ty_sig =
| TyNil : (Geninterp.interp_sign -> unit Proofview.tactic) ty_sig
| TyIdent : string * 'r ty_sig -> 'r ty_sig
| TyArg :
- (('a, 'b, 'c) Extend.ty_user_symbol * Id.t) Loc.located * 'r ty_sig -> ('c -> 'r) ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * string * 'r ty_sig -> ('c -> 'r) ty_sig
| TyAnonArg :
- ('a, 'b, 'c) Extend.ty_user_symbol Loc.located * 'r ty_sig -> 'r ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * 'r ty_sig -> 'r ty_sig
type ty_ml = TyML : 'r ty_sig * 'r -> ty_ml
@@ -578,10 +583,11 @@ let rec clause_of_sign : type a. a ty_sig -> Genarg.ArgT.any Extend.user_symbol
fun sign -> match sign with
| TyNil -> []
| TyIdent (s, sig') -> TacTerm s :: clause_of_sign sig'
- | TyArg ((loc,(a,id)),sig') ->
- TacNonTerm (loc,(untype_user_symbol a,Some id)) :: clause_of_sign sig'
- | TyAnonArg ((loc,a),sig') ->
- TacNonTerm (loc,(untype_user_symbol a,None)) :: clause_of_sign sig'
+ | TyArg (a, id, sig') ->
+ let id = get_identifier id in
+ TacNonTerm (None,(untype_user_symbol a,Some id)) :: clause_of_sign sig'
+ | TyAnonArg (a, sig') ->
+ TacNonTerm (None,(untype_user_symbol a,None)) :: clause_of_sign sig'
let clause_of_ty_ml = function
| TyML (t,_) -> clause_of_sign t
@@ -604,7 +610,7 @@ let rec eval_sign : type a. a ty_sig -> a -> Geninterp.Val.t list -> Geninterp.i
| _ :: _ -> assert false
end
| TyIdent (s, sig') -> eval_sign sig' tac
- | TyArg ((_loc,(a,id)), sig') ->
+ | TyArg (a, _, sig') ->
let f = eval_sign sig' in
begin fun tac vals ist -> match vals with
| [] -> assert false
@@ -612,7 +618,7 @@ let rec eval_sign : type a. a ty_sig -> a -> Geninterp.Val.t list -> Geninterp.i
let v' = Taccoerce.Value.cast (topwit (prj a)) v in
f (tac v') vals ist
end tac
- | TyAnonArg ((_loc,a), sig') -> eval_sign sig' tac
+ | TyAnonArg (a, sig') -> eval_sign sig' tac
let eval : ty_ml -> Geninterp.Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic = function
| TyML (t,tac) -> eval_sign t tac
@@ -624,14 +630,14 @@ let is_constr_entry = function
let rec only_constr : type a. a ty_sig -> bool = function
| TyNil -> true
| TyIdent(_,_) -> false
-| TyArg((_,(u,_)),s) -> if is_constr_entry u then only_constr s else false
-| TyAnonArg((_,u),s) -> if is_constr_entry u then only_constr s else false
+| TyArg (u, _, s) -> if is_constr_entry u then only_constr s else false
+| TyAnonArg (u, s) -> if is_constr_entry u then only_constr s else false
let rec mk_sign_vars : type a. a ty_sig -> Name.t list = function
| TyNil -> []
| TyIdent (_,s) -> mk_sign_vars s
-| TyArg((_,(_,name)),s) -> Name name :: mk_sign_vars s
-| TyAnonArg((_,_),s) -> Anonymous :: mk_sign_vars s
+| TyArg (_, name, s) -> Name (get_identifier name) :: mk_sign_vars s
+| TyAnonArg (_, s) -> Anonymous :: mk_sign_vars s
let dummy_id = Id.of_string "_"
diff --git a/plugins/ltac/tacentries.mli b/plugins/ltac/tacentries.mli
index 2bfbbe2e1..9bba9ba71 100644
--- a/plugins/ltac/tacentries.mli
+++ b/plugins/ltac/tacentries.mli
@@ -72,9 +72,9 @@ type _ ty_sig =
| TyNil : (Geninterp.interp_sign -> unit Proofview.tactic) ty_sig
| TyIdent : string * 'r ty_sig -> 'r ty_sig
| TyArg :
- (('a, 'b, 'c) Extend.ty_user_symbol * Names.Id.t) Loc.located * 'r ty_sig -> ('c -> 'r) ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * string * 'r ty_sig -> ('c -> 'r) ty_sig
| TyAnonArg :
- ('a, 'b, 'c) Extend.ty_user_symbol Loc.located * 'r ty_sig -> 'r ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * 'r ty_sig -> 'r ty_sig
type ty_ml = TyML : 'r ty_sig * 'r -> ty_ml
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index 9d1cc1643..d9ac96d89 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -312,11 +312,11 @@ let interp_name ist env sigma = function
| Name id -> Name (interp_ident ist env sigma id)
let interp_intro_pattern_var loc ist env sigma id =
- try try_interp_ltac_var (coerce_to_intro_pattern env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_intro_pattern sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found -> IntroNaming (IntroIdentifier id)
let interp_intro_pattern_naming_var loc ist env sigma id =
- try try_interp_ltac_var (coerce_to_intro_pattern_naming env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_intro_pattern_naming sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found -> IntroIdentifier id
let interp_int ist ({loc;v=id} as locid) =
@@ -357,7 +357,7 @@ let interp_hyp_list ist env sigma l =
let interp_reference ist env sigma = function
| ArgArg (_,r) -> r
| ArgVar {loc;v=id} ->
- try try_interp_ltac_var (coerce_to_reference env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_reference sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found ->
try
VarRef (get_id (Environ.lookup_named id env))
@@ -451,7 +451,7 @@ let default_fresh_id = Id.of_string "H"
let interp_fresh_id ist env sigma l =
let extract_ident ist env sigma id =
- try try_interp_ltac_var (coerce_to_ident_not_fresh env sigma)
+ try try_interp_ltac_var (coerce_to_ident_not_fresh sigma)
ist (Some (env,sigma)) (make id)
with Not_found -> id in
let ids = List.map_filter (function ArgVar {v=id} -> Some id | _ -> None) l in
@@ -474,7 +474,7 @@ let interp_fresh_id ist env sigma l =
(* Extract the uconstr list from lfun *)
let extract_ltac_constr_context ist env sigma =
let add_uconstr id v map =
- try Id.Map.add id (coerce_to_uconstr env v) map
+ try Id.Map.add id (coerce_to_uconstr v) map
with CannotCoerceTo _ -> map
in
let add_constr id v map =
@@ -799,7 +799,7 @@ and interp_or_and_intro_pattern ist env sigma = function
and interp_intro_pattern_list_as_list ist env sigma = function
| [{loc;v=IntroNaming (IntroIdentifier id)}] as l ->
- (try sigma, coerce_to_intro_pattern_list ?loc env sigma (Id.Map.find id ist.lfun)
+ (try sigma, coerce_to_intro_pattern_list ?loc sigma (Id.Map.find id ist.lfun)
with Not_found | CannotCoerceTo _ ->
List.fold_left_map (interp_intro_pattern ist env) sigma l)
| l -> List.fold_left_map (interp_intro_pattern ist env) sigma l
@@ -842,7 +842,7 @@ let interp_declared_or_quantified_hypothesis ist env sigma = function
| AnonHyp n -> AnonHyp n
| NamedHyp id ->
try try_interp_ltac_var
- (coerce_to_decl_or_quant_hyp env sigma) ist (Some (env,sigma)) (make id)
+ (coerce_to_decl_or_quant_hyp sigma) ist (Some (env,sigma)) (make id)
with Not_found -> NamedHyp id
let interp_binding ist env sigma {loc;v=(b,c)} =
diff --git a/plugins/micromega/g_micromega.ml4 b/plugins/micromega/g_micromega.mlg
index 81140a46a..21f0414e9 100644
--- a/plugins/micromega/g_micromega.ml4
+++ b/plugins/micromega/g_micromega.mlg
@@ -16,70 +16,74 @@
(* *)
(************************************************************************)
+{
+
open Ltac_plugin
open Stdarg
open Tacarg
+}
+
DECLARE PLUGIN "micromega_plugin"
TACTIC EXTEND RED
-| [ "myred" ] -> [ Tactics.red_in_concl ]
+| [ "myred" ] -> { Tactics.red_in_concl }
END
TACTIC EXTEND PsatzZ
-| [ "psatz_Z" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_Z i
+| [ "psatz_Z" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Z i
(Tacinterp.tactic_of_value ist t))
- ]
-| [ "psatz_Z" tactic(t)] -> [ (Coq_micromega.psatz_Z (-1)) (Tacinterp.tactic_of_value ist t) ]
+ }
+| [ "psatz_Z" tactic(t)] -> { (Coq_micromega.psatz_Z (-1)) (Tacinterp.tactic_of_value ist t) }
END
TACTIC EXTEND Lia
-[ "xlia" tactic(t) ] -> [ (Coq_micromega.xlia (Tacinterp.tactic_of_value ist t)) ]
+| [ "xlia" tactic(t) ] -> { (Coq_micromega.xlia (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Nia
-[ "xnlia" tactic(t) ] -> [ (Coq_micromega.xnlia (Tacinterp.tactic_of_value ist t)) ]
+| [ "xnlia" tactic(t) ] -> { (Coq_micromega.xnlia (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND NRA
-[ "xnra" tactic(t) ] -> [ (Coq_micromega.nra (Tacinterp.tactic_of_value ist t))]
+| [ "xnra" tactic(t) ] -> { (Coq_micromega.nra (Tacinterp.tactic_of_value ist t))}
END
TACTIC EXTEND NQA
-[ "xnqa" tactic(t) ] -> [ (Coq_micromega.nqa (Tacinterp.tactic_of_value ist t))]
+| [ "xnqa" tactic(t) ] -> { (Coq_micromega.nqa (Tacinterp.tactic_of_value ist t))}
END
TACTIC EXTEND Sos_Z
-| [ "sos_Z" tactic(t) ] -> [ (Coq_micromega.sos_Z (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_Z" tactic(t) ] -> { (Coq_micromega.sos_Z (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Sos_Q
-| [ "sos_Q" tactic(t) ] -> [ (Coq_micromega.sos_Q (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_Q" tactic(t) ] -> { (Coq_micromega.sos_Q (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Sos_R
-| [ "sos_R" tactic(t) ] -> [ (Coq_micromega.sos_R (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_R" tactic(t) ] -> { (Coq_micromega.sos_R (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND LRA_Q
-[ "lra_Q" tactic(t) ] -> [ (Coq_micromega.lra_Q (Tacinterp.tactic_of_value ist t)) ]
+| [ "lra_Q" tactic(t) ] -> { (Coq_micromega.lra_Q (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND LRA_R
-[ "lra_R" tactic(t) ] -> [ (Coq_micromega.lra_R (Tacinterp.tactic_of_value ist t)) ]
+| [ "lra_R" tactic(t) ] -> { (Coq_micromega.lra_R (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND PsatzR
-| [ "psatz_R" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) ]
-| [ "psatz_R" tactic(t) ] -> [ (Coq_micromega.psatz_R (-1) (Tacinterp.tactic_of_value ist t)) ]
+| [ "psatz_R" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_R" tactic(t) ] -> { (Coq_micromega.psatz_R (-1) (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND PsatzQ
-| [ "psatz_Q" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) ]
-| [ "psatz_Q" tactic(t) ] -> [ (Coq_micromega.psatz_Q (-1) (Tacinterp.tactic_of_value ist t)) ]
+| [ "psatz_Q" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_Q" tactic(t) ] -> { (Coq_micromega.psatz_Q (-1) (Tacinterp.tactic_of_value ist t)) }
END
diff --git a/plugins/nsatz/g_nsatz.ml4 b/plugins/nsatz/g_nsatz.mlg
index 4ac49adb9..16ff512e8 100644
--- a/plugins/nsatz/g_nsatz.ml4
+++ b/plugins/nsatz/g_nsatz.mlg
@@ -8,11 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Stdarg
+}
+
DECLARE PLUGIN "nsatz_plugin"
TACTIC EXTEND nsatz_compute
-| [ "nsatz_compute" constr(lt) ] -> [ Nsatz.nsatz_compute (EConstr.Unsafe.to_constr lt) ]
+| [ "nsatz_compute" constr(lt) ] -> { Nsatz.nsatz_compute (EConstr.Unsafe.to_constr lt) }
END
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 6f4138828..e14c4e2ec 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -38,15 +38,9 @@ open OmegaSolver
(* Added by JCF, 09/03/98 *)
-let elim_id id =
- Proofview.Goal.enter begin fun gl ->
- simplest_elim (mkVar id)
- end
-let resolve_id id = Proofview.Goal.enter begin fun gl ->
- apply (mkVar id)
-end
+let elim_id id = simplest_elim (mkVar id)
-let timing timer_name f arg = f arg
+let resolve_id id = apply (mkVar id)
let display_time_flag = ref false
let display_system_flag = ref false
diff --git a/plugins/omega/g_omega.ml4 b/plugins/omega/g_omega.mlg
index 170b937c9..c3d063cff 100644
--- a/plugins/omega/g_omega.ml4
+++ b/plugins/omega/g_omega.mlg
@@ -18,6 +18,8 @@
DECLARE PLUGIN "omega_plugin"
+{
+
open Ltac_plugin
open Names
open Coq_omega
@@ -43,14 +45,15 @@ let omega_tactic l =
(Tacticals.New.tclREPEAT (Tacticals.New.tclTHENLIST tacs))
(omega_solver)
+}
TACTIC EXTEND omega
-| [ "omega" ] -> [ omega_tactic [] ]
+| [ "omega" ] -> { omega_tactic [] }
END
TACTIC EXTEND omega'
| [ "omega" "with" ne_ident_list(l) ] ->
- [ omega_tactic (List.map Names.Id.to_string l) ]
-| [ "omega" "with" "*" ] -> [ omega_tactic ["nat";"positive";"N";"Z"] ]
+ { omega_tactic (List.map Names.Id.to_string l) }
+| [ "omega" "with" "*" ] -> { omega_tactic ["nat";"positive";"N";"Z"] }
END
diff --git a/plugins/quote/g_quote.ml4 b/plugins/quote/g_quote.mlg
index 09209dc22..749903c3a 100644
--- a/plugins/quote/g_quote.ml4
+++ b/plugins/quote/g_quote.mlg
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Names
open Tacexpr
@@ -16,8 +18,12 @@ open Quote
open Stdarg
open Tacarg
+}
+
DECLARE PLUGIN "quote_plugin"
+{
+
let cont = Id.of_string "cont"
let x = Id.of_string "x"
@@ -27,12 +33,14 @@ let make_cont (k : Val.t) (c : EConstr.t) =
let ist = { lfun = Id.Map.add cont k (Id.Map.singleton x c); extra = TacStore.empty; } in
Tacinterp.eval_tactic_ist ist (TacArg (Loc.tag tac))
+}
+
TACTIC EXTEND quote
- [ "quote" ident(f) ] -> [ quote f [] ]
-| [ "quote" ident(f) "[" ne_ident_list(lc) "]"] -> [ quote f lc ]
+| [ "quote" ident(f) ] -> { quote f [] }
+| [ "quote" ident(f) "[" ne_ident_list(lc) "]"] -> { quote f lc }
| [ "quote" ident(f) "in" constr(c) "using" tactic(k) ] ->
- [ gen_quote (make_cont k) c f [] ]
+ { gen_quote (make_cont k) c f [] }
| [ "quote" ident(f) "[" ne_ident_list(lc) "]"
"in" constr(c) "using" tactic(k) ] ->
- [ gen_quote (make_cont k) c f lc ]
+ { gen_quote (make_cont k) c f lc }
END
diff --git a/plugins/romega/g_romega.ml4 b/plugins/romega/g_romega.mlg
index 5b77d08de..c1ce30027 100644
--- a/plugins/romega/g_romega.ml4
+++ b/plugins/romega/g_romega.mlg
@@ -9,6 +9,8 @@
DECLARE PLUGIN "romega_plugin"
+{
+
open Ltac_plugin
open Names
open Refl_omega
@@ -39,13 +41,15 @@ let romega_tactic unsafe l =
(Tactics.intros)
(total_reflexive_omega_tactic unsafe))
+}
+
TACTIC EXTEND romega
-| [ "romega" ] -> [ romega_tactic false [] ]
-| [ "unsafe_romega" ] -> [ romega_tactic true [] ]
+| [ "romega" ] -> { romega_tactic false [] }
+| [ "unsafe_romega" ] -> { romega_tactic true [] }
END
TACTIC EXTEND romega'
| [ "romega" "with" ne_ident_list(l) ] ->
- [ romega_tactic false (List.map Names.Id.to_string l) ]
-| [ "romega" "with" "*" ] -> [ romega_tactic false ["nat";"positive";"N";"Z"] ]
+ { romega_tactic false (List.map Names.Id.to_string l) }
+| [ "romega" "with" "*" ] -> { romega_tactic false ["nat";"positive";"N";"Z"] }
END
diff --git a/plugins/rtauto/g_rtauto.ml4 b/plugins/rtauto/g_rtauto.mlg
index aa6757634..9c9fdcfa2 100644
--- a/plugins/rtauto/g_rtauto.ml4
+++ b/plugins/rtauto/g_rtauto.mlg
@@ -8,12 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
open Ltac_plugin
+}
+
DECLARE PLUGIN "rtauto_plugin"
TACTIC EXTEND rtauto
- [ "rtauto" ] -> [ Proofview.V82.tactic (Refl_tauto.rtauto_tac) ]
+| [ "rtauto" ] -> { Proofview.V82.tactic (Refl_tauto.rtauto_tac) }
END
diff --git a/plugins/setoid_ring/g_newring.ml4 b/plugins/setoid_ring/g_newring.ml4
index e9ce306e8..4ea0b30bd 100644
--- a/plugins/setoid_ring/g_newring.ml4
+++ b/plugins/setoid_ring/g_newring.ml4
@@ -29,11 +29,6 @@ TACTIC EXTEND protect_fv
[ protect_tac map ]
END
-TACTIC EXTEND closed_term
- [ "closed_term" constr(t) "[" ne_reference_list(l) "]" ] ->
- [ closed_term t l ]
-END
-
open Pptactic
open Ppconstr
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 84b29a0bf..8e0ca877a 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -96,34 +96,36 @@ let protect_tac_in map id =
(****************************************************************************)
-let closed_term t l =
- let open Quote_plugin in
+let rec closed_under sigma cset t =
+ try
+ let (gr, _) = Termops.global_of_constr sigma t in
+ Refset_env.mem gr cset
+ with Not_found ->
+ match EConstr.kind sigma t with
+ | Cast(c,_,_) -> closed_under sigma cset c
+ | App(f,l) -> closed_under sigma cset f && Array.for_all (closed_under sigma cset) l
+ | _ -> false
+
+let closed_term args _ = match args with
+| [t; l] ->
+ let t = Option.get (Value.to_constr t) in
+ let l = List.map (fun c -> Value.cast (Genarg.topwit Stdarg.wit_ref) c) (Option.get (Value.to_list l)) in
Proofview.tclEVARMAP >>= fun sigma ->
- let l = List.map UnivGen.constr_of_global l in
- let cs = List.fold_right Quote.ConstrSet.add l Quote.ConstrSet.empty in
- if Quote.closed_under sigma cs t then Proofview.tclUNIT () else Tacticals.New.tclFAIL 0 (mt())
-
-(* TACTIC EXTEND echo
-| [ "echo" constr(t) ] ->
- [ Pp.msg (Termops.print_constr t); Tacinterp.eval_tactic (TacId []) ]
-END;;*)
+ let cs = List.fold_right Refset_env.add l Refset_env.empty in
+ if closed_under sigma cs t then Proofview.tclUNIT () else Tacticals.New.tclFAIL 0 (mt())
+| _ -> assert false
-(*
-let closed_term_ast l =
- TacFun([Some(Id.of_string"t")],
- TacAtom(Loc.ghost,TacExtend(Loc.ghost,"closed_term",
- [Genarg.in_gen Constrarg.wit_constr (mkVar(Id.of_string"t"));
- Genarg.in_gen (Genarg.wit_list Constrarg.wit_ref) l])))
-*)
-let closed_term_ast l =
+let closed_term_ast =
let tacname = {
mltac_plugin = "newring_plugin";
mltac_tactic = "closed_term";
} in
+ let () = Tacenv.register_ml_tactic tacname [|closed_term|] in
let tacname = {
mltac_name = tacname;
mltac_index = 0;
} in
+ fun l ->
let l = List.map (fun gr -> ArgArg(Loc.tag gr)) l in
TacFun([Name(Id.of_string"t")],
TacML(Loc.tag (tacname,
@@ -148,8 +150,7 @@ let ic_unsafe c = (*FIXME remove *)
let decl_constant na univs c =
let open Constr in
- let env = Global.env () in
- let vars = Univops.universes_of_constr env c in
+ let vars = Univops.universes_of_constr c in
let univs = Univops.restrict_universe_context univs vars in
let univs = Monomorphic_const_entry univs in
mkConst(declare_constant (Id.of_string na)
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
index 0e056a472..fcd04a2e7 100644
--- a/plugins/setoid_ring/newring.mli
+++ b/plugins/setoid_ring/newring.mli
@@ -18,8 +18,6 @@ val protect_tac_in : string -> Id.t -> unit Proofview.tactic
val protect_tac : string -> unit Proofview.tactic
-val closed_term : EConstr.constr -> GlobRef.t list -> unit Proofview.tactic
-
val add_theory :
Id.t ->
constr_expr ->
diff --git a/plugins/ssr/ssrast.mli b/plugins/ssr/ssrast.mli
index 5571c5420..6ba937a2f 100644
--- a/plugins/ssr/ssrast.mli
+++ b/plugins/ssr/ssrast.mli
@@ -88,7 +88,7 @@ type ssripat =
| IPatCase of (* ipats_mod option * *) ssripatss (* this is not equivalent to /case /[..|..] if there are already multiple goals *)
| IPatInj of ssripatss
| IPatRewrite of (*occurrence option * rewrite_pattern **) ssrocc * ssrdir
- | IPatView of ssrview (* /view *)
+ | IPatView of bool * ssrview (* {}/view (true if the clear is present) *)
| IPatClear of ssrclear (* {H1 H2} *)
| IPatSimpl of ssrsimpl
| IPatAbstractVars of Id.t list
diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml
index f929e9430..23cbf49c0 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -417,8 +417,6 @@ let rwcltac cl rdx dir sr gl =
then errorstrm Pp.(str "Rewriting impacts evars")
else errorstrm Pp.(str "Dependent type error in rewrite of "
++ pr_constr_env (pf_env gl) (project gl) (Term.mkNamedLambda pattern_id (EConstr.Unsafe.to_constr rdxt) (EConstr.Unsafe.to_constr cl)))
- | CErrors.UserError _ as e -> raise e
- | e -> anomaly ("cvtac's exception: " ^ Printexc.to_string e);
in
tclTHEN cvtac' rwtac gl
diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml
index 2c046190f..7fe2421f9 100644
--- a/plugins/ssr/ssrfwd.ml
+++ b/plugins/ssr/ssrfwd.ml
@@ -47,6 +47,7 @@ let ssrsettac id ((_, (pat, pty)), (_, occ)) gl =
let cl = EConstr.Unsafe.to_constr cl in
try fill_occ_pattern ~raise_NoMatch:true env sigma cl pat occ 1
with NoMatch -> redex_of_pattern ~resolve_typeclasses:true env pat, cl in
+ let gl = pf_merge_uc ucst gl in
let c = EConstr.of_constr c in
let cl = EConstr.of_constr cl in
if Termops.occur_existential sigma c then errorstrm(str"The pattern"++spc()++
@@ -56,7 +57,6 @@ let ssrsettac id ((_, (pat, pty)), (_, occ)) gl =
| Cast(t, DEFAULTcast, ty) -> t, (gl, ty)
| _ -> c, pfe_type_of gl c in
let cl' = EConstr.mkLetIn (Name id, c, cty, cl) in
- let gl = pf_merge_uc ucst gl in
Tacticals.tclTHEN (Proofview.V82.of_tactic (convert_concl cl')) (introid id) gl
open Util
diff --git a/plugins/ssr/ssripats.ml b/plugins/ssr/ssripats.ml
index 8207bc11e..46fde4115 100644
--- a/plugins/ssr/ssripats.ml
+++ b/plugins/ssr/ssripats.ml
@@ -119,13 +119,10 @@ let intro_end =
Ssrcommon.tcl0G (isCLR_CONSUME)
(** [=> _] *****************************************************************)
-let intro_clear ids future_ipats =
+let intro_clear ids =
Goal.enter begin fun gl ->
let _, clear_ids, ren =
List.fold_left (fun (used_ids, clear_ids, ren) id ->
- if not(Ssrcommon.is_name_in_ipats id future_ipats) then begin
- used_ids, id :: clear_ids, ren
- end else
let new_id = Ssrcommon.mk_anon_id (Id.to_string id) used_ids in
(new_id :: used_ids, new_id :: clear_ids, (id, new_id) :: ren))
(Tacmach.New.pf_ids_of_hyps gl, [], []) ids
@@ -213,22 +210,22 @@ let tclLOG p t =
tclUNIT ()
end
-let rec ipat_tac1 future_ipats ipat : unit tactic =
+let rec ipat_tac1 ipat : unit tactic =
match ipat with
- | IPatView l ->
- Ssrview.tclIPAT_VIEWS ~views:l
- ~conclusion:(fun ~to_clear:clr -> intro_clear clr future_ipats)
+ | IPatView (clear_if_id,l) ->
+ Ssrview.tclIPAT_VIEWS ~views:l ~clear_if_id
+ ~conclusion:(fun ~to_clear:clr -> intro_clear clr)
| IPatDispatch ipatss ->
- tclEXTEND (List.map (ipat_tac future_ipats) ipatss) (tclUNIT ()) []
+ tclEXTEND (List.map ipat_tac ipatss) (tclUNIT ()) []
| IPatId id -> Ssrcommon.tclINTRO_ID id
| IPatCase ipatss ->
- tclIORPAT (Ssrcommon.tclWITHTOP tac_case) future_ipats ipatss
+ tclIORPAT (Ssrcommon.tclWITHTOP tac_case) ipatss
| IPatInj ipatss ->
tclIORPAT (Ssrcommon.tclWITHTOP
(fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t)))
- future_ipats ipatss
+ ipatss
| IPatAnon Drop -> intro_drop
| IPatAnon One -> Ssrcommon.tclINTRO_ANON
@@ -239,7 +236,7 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatClear ids ->
tacCHECK_HYPS_EXIST ids <*>
- intro_clear (List.map Ssrcommon.hyp_id ids) future_ipats
+ intro_clear (List.map Ssrcommon.hyp_id ids)
| IPatSimpl (Simpl n) ->
V82.tactic ~nf_evars:false (Ssrequality.simpltac (Simpl n))
@@ -256,17 +253,17 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatTac t -> t
-and ipat_tac future_ipats pl : unit tactic =
+and ipat_tac pl : unit tactic =
match pl with
| [] -> tclUNIT ()
| pat :: pl ->
- Ssrcommon.tcl0G (tclLOG pat (ipat_tac1 (pl @ future_ipats))) <*>
+ Ssrcommon.tcl0G (tclLOG pat ipat_tac1) <*>
isTICK pat <*>
- ipat_tac future_ipats pl
+ ipat_tac pl
-and tclIORPAT tac future_ipats = function
+and tclIORPAT tac = function
| [[]] -> tac
- | p -> Tacticals.New.tclTHENS tac (List.map (ipat_tac future_ipats) p)
+ | p -> Tacticals.New.tclTHENS tac (List.map ipat_tac p)
let split_at_first_case ipats =
let rec loop acc = function
@@ -282,12 +279,27 @@ let ssr_exception is_on = function
let option_to_list = function None -> [] | Some x -> [x]
+(* Simple pass doing {x}/v -> /v{x} *)
+let elaborate_ipats l =
+ let rec elab = function
+ | [] -> []
+ | (IPatClear _ as p1) :: (IPatView _ as p2) :: rest -> p2 :: p1 :: elab rest
+ | IPatDispatch p :: rest -> IPatDispatch (List.map elab p) :: elab rest
+ | IPatCase p :: rest -> IPatCase (List.map elab p) :: elab rest
+ | IPatInj p :: rest -> IPatInj (List.map elab p) :: elab rest
+ | (IPatTac _ | IPatId _ | IPatSimpl _ | IPatClear _ |
+ IPatAnon _ | IPatView _ | IPatNoop | IPatRewrite _ |
+ IPatAbstractVars _) as x :: rest -> x :: elab rest
+ in
+ elab l
+
let main ?eqtac ~first_case_is_dispatch ipats =
+ let ipats = elaborate_ipats ipats in
let ip_before, case, ip_after = split_at_first_case ipats in
let case = ssr_exception first_case_is_dispatch case in
let case = option_to_list case in
let eqtac = option_to_list (Option.map (fun x -> IPatTac x) eqtac) in
- Ssrcommon.tcl0G (ipat_tac [] (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
+ Ssrcommon.tcl0G (ipat_tac (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
end (* }}} *)
@@ -576,7 +588,7 @@ let ssrmovetac = function
(tacVIEW_THEN_GRAB view ~conclusion) <*>
tclIPAT (IPatClear clr :: ipats)
| _::_ as view, (_, ({ gens = []; clr }, ipats)) ->
- tclIPAT (IPatView view :: IPatClear clr :: ipats)
+ tclIPAT (IPatView (false,view) :: IPatClear clr :: ipats)
| _, (Some pat, (dgens, ipats)) ->
let dgentac = with_dgens dgens eqmovetac in
dgentac <*> tclIPAT (eqmoveipats pat ipats)
diff --git a/plugins/ssr/ssrparser.ml4 b/plugins/ssr/ssrparser.ml4
index 7a1d06fdc..6b183dab1 100644
--- a/plugins/ssr/ssrparser.ml4
+++ b/plugins/ssr/ssrparser.ml4
@@ -412,8 +412,8 @@ let pr_docc = function
let pr_ssrdocc _ _ _ = pr_docc
ARGUMENT EXTEND ssrdocc TYPED AS ssrclear option * ssrocc PRINTED BY pr_ssrdocc
-| [ "{" ne_ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
| [ "{" ssrocc(occ) "}" ] -> [ mkocc occ ]
+| [ "{" ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
END
(* Old kinds of terms *)
@@ -578,7 +578,7 @@ let rec map_ipat map_id map_ssrhyp map_ast_closure_term = function
| IPatCase iorpat -> IPatCase (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
| IPatDispatch iorpat -> IPatDispatch (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
| IPatInj iorpat -> IPatInj (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatView v -> IPatView (List.map map_ast_closure_term v)
+ | IPatView (clr,v) -> IPatView (clr,List.map map_ast_closure_term v)
| IPatTac _ -> assert false (*internal usage only *)
let wit_ssripatrep = add_genarg "ssripatrep" pr_ipat
@@ -646,7 +646,7 @@ let interp_ipat ist gl =
| IPatInj iorpat -> IPatInj (List.map (List.map interp) iorpat)
| IPatAbstractVars l ->
IPatAbstractVars (List.map get_intro_id (List.map (interp_introid ist gl) l))
- | IPatView l -> IPatView (List.map (fun x -> snd(interp_ast_closure_term ist
+ | IPatView (clr,l) -> IPatView (clr,List.map (fun x -> snd(interp_ast_closure_term ist
gl x)) l)
| (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x
| IPatTac _ -> assert false (*internal usage only *)
@@ -683,11 +683,17 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats
(* TODO | [ "+" ] -> [ [IPatAnon Temporary] ] *)
| [ ssrsimpl_ne(sim) ] -> [ [IPatSimpl sim] ]
| [ ssrdocc(occ) "->" ] -> [ match occ with
+ | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
| None, occ -> [IPatRewrite (occ, L2R)]
| Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, L2R)]]
| [ ssrdocc(occ) "<-" ] -> [ match occ with
+ | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
| None, occ -> [IPatRewrite (occ, R2L)]
| Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, R2L)]]
+ | [ ssrdocc(occ) ssrfwdview(v) ] -> [ match occ with
+ | Some [], _ -> [IPatView (true,v)]
+ | Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl;IPatView (false,v)]
+ | _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here") ]
| [ ssrdocc(occ) ] -> [ match occ with
| Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl]
| _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here")]
@@ -705,7 +711,7 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats
| [ "-/" integer(n) "/=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (n,~-1))] ]
| [ "-/" integer(n) "/" integer (m) "=" ] ->
[ [IPatNoop;IPatSimpl(SimplCut(n,m))] ]
- | [ ssrfwdview(v) ] -> [ [IPatView v] ]
+ | [ ssrfwdview(v) ] -> [ [IPatView (false,v)] ]
| [ "[" ":" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
| [ "[:" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
END
@@ -956,6 +962,7 @@ END
(* the default simpl and unfold tactics would erase blindly. *)
open Ssrmatching_plugin.Ssrmatching
+open Ssrmatching_plugin.G_ssrmatching
let pr_wgen = function
| (clr, Some((id,k),None)) -> spc() ++ pr_clear mt clr ++ str k ++ pr_hoi id
@@ -1678,7 +1685,10 @@ let pr_gen (docc, dt) = pr_docc docc ++ pr_cpattern dt
let pr_ssrgen _ _ _ = pr_gen
ARGUMENT EXTEND ssrgen TYPED AS ssrdocc * cpattern PRINTED BY pr_ssrgen
-| [ ssrdocc(docc) cpattern(dt) ] -> [ docc, dt ]
+| [ ssrdocc(docc) cpattern(dt) ] -> [
+ match docc with
+ | Some [], _ -> CErrors.user_err ~loc (str"Clear flag {} not allowed here")
+ | _ -> docc, dt ]
| [ cpattern(dt) ] -> [ nodocc, dt ]
END
diff --git a/plugins/ssr/ssrprinters.ml b/plugins/ssr/ssrprinters.ml
index 11369228c..8f4b2179e 100644
--- a/plugins/ssr/ssrprinters.ml
+++ b/plugins/ssr/ssrprinters.ml
@@ -107,7 +107,8 @@ let rec pr_ipat p =
| IPatAnon All -> str "*"
| IPatAnon Drop -> str "_"
| IPatAnon One -> str "?"
- | IPatView v -> pr_view2 v
+ | IPatView (false,v) -> pr_view2 v
+ | IPatView (true,v) -> str"{}" ++ pr_view2 v
| IPatNoop -> str "-"
| IPatAbstractVars l -> str "[:" ++ pr_list spc Id.print l ++ str "]"
| IPatTac _ -> str "<tac>"
diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml
index faebe3179..3f974ea06 100644
--- a/plugins/ssr/ssrview.ml
+++ b/plugins/ssr/ssrview.ml
@@ -67,9 +67,9 @@ end
module State : sig
(* View storage API *)
- val vsINIT : EConstr.t -> unit tactic
- val vsPUSH : (EConstr.t -> EConstr.t tactic) -> unit tactic
- val vsCONSUME : (Id.t option -> EConstr.t -> unit tactic) -> unit tactic
+ val vsINIT : EConstr.t * Id.t list -> unit tactic
+ val vsPUSH : (EConstr.t -> (EConstr.t * Id.t list) tactic) -> unit tactic
+ val vsCONSUME : (name:Id.t option -> EConstr.t -> to_clear:Id.t list -> unit tactic) -> unit tactic
val vsASSERT_EMPTY : unit tactic
end = struct (* {{{ *)
@@ -78,6 +78,7 @@ type vstate = {
subject_name : Id.t option; (* top *)
(* None if views are being applied to a term *)
view : EConstr.t; (* v2 (v1 top) *)
+ to_clear : Id.t list;
}
include Ssrcommon.MakeState(struct
@@ -85,13 +86,14 @@ include Ssrcommon.MakeState(struct
let init = None
end)
-let vsINIT view = tclSET (Some { subject_name = None; view })
+let vsINIT (view, to_clear) =
+ tclSET (Some { subject_name = None; view; to_clear })
let vsPUSH k =
tacUPDATE (fun s -> match s with
- | Some { subject_name; view } ->
- k view >>= fun view ->
- tclUNIT (Some { subject_name; view })
+ | Some { subject_name; view; to_clear } ->
+ k view >>= fun (view, clr) ->
+ tclUNIT (Some { subject_name; view; to_clear = to_clear @ clr })
| None ->
Goal.enter_one ~__LOC__ begin fun gl ->
let concl = Goal.concl gl in
@@ -102,15 +104,15 @@ let vsPUSH k =
| _ -> mk_anon_id "view_subject" (Tacmach.New.pf_ids_of_hyps gl) in
let view = EConstr.mkVar id in
Ssrcommon.tclINTRO_ID id <*>
- k view >>= fun view ->
- tclUNIT (Some { subject_name = Some id; view })
+ k view >>= fun (view, to_clear) ->
+ tclUNIT (Some { subject_name = Some id; view; to_clear })
end)
let vsCONSUME k =
tclGET (fun s -> match s with
- | Some { subject_name; view } ->
+ | Some { subject_name; view; to_clear } ->
tclSET None <*>
- k subject_name view
+ k ~name:subject_name view ~to_clear
| None -> anomaly "vsCONSUME: empty storage")
let vsASSERT_EMPTY =
@@ -187,6 +189,16 @@ end
* modular, see the 2 functions below that would need to "uncommit" *)
let tclKeepOpenConstr (_env, sigma, t) = Unsafe.tclEVARS sigma <*> tclUNIT t
+let tclADD_CLEAR_IF_ID (env, ist, t) x =
+ Ssrprinters.ppdebug (lazy
+ Pp.(str"tclADD_CLEAR_IF_ID: " ++ Printer.pr_econstr_env env ist t));
+ let hd, _ = EConstr.decompose_app ist t in
+ match EConstr.kind ist hd with
+ | Constr.Var id when Ssrcommon.not_section_id id -> tclUNIT (x, [id])
+ | _ -> tclUNIT (x,[])
+
+let tclPAIR p x = tclUNIT (x, p)
+
(* The ssr heuristic : *)
(* Estimate a bound on the number of arguments of a raw constr. *)
(* This is not perfect, because the unifier may fail to *)
@@ -203,14 +215,15 @@ let guess_max_implicits ist glob =
(fun _ -> tclUNIT 5)
let pad_to_inductive ist glob = Goal.enter_one ~__LOC__ begin fun goal ->
- interp_glob ist glob >>= fun (env, sigma, term) ->
+ interp_glob ist glob >>= fun (env, sigma, term as ot) ->
let term_ty = Retyping.get_type_of env sigma term in
let ctx, i = Reductionops.splay_prod env sigma term_ty in
let rel_ctx =
List.map (fun (a,b) -> Context.Rel.Declaration.LocalAssum(a,b)) ctx in
- if Ssrcommon.isAppInd (EConstr.push_rel_context rel_ctx env) sigma i
- then tclUNIT (mkGApp glob (mkGHoles (List.length ctx)))
- else Tacticals.New.tclZEROMSG Pp.(str"not an inductive")
+ if not (Ssrcommon.isAppInd (EConstr.push_rel_context rel_ctx env) sigma i)
+ then Tacticals.New.tclZEROMSG Pp.(str"not an inductive")
+ else tclUNIT (mkGApp glob (mkGHoles (List.length ctx)))
+ >>= tclADD_CLEAR_IF_ID ot
end
(* There are two ways of "applying" a view to term: *)
@@ -221,7 +234,7 @@ end
(* They require guessing the view hints and the number of *)
(* implicits, respectively, which we do by brute force. *)
(* Builds v p *)
-let interp_view ist v p =
+let interp_view ~clear_if_id ist v p =
let is_specialize hd =
match DAst.get hd with Glob_term.GHole _ -> true | _ -> false in
(* We cast the pile of views p into a term p_id *)
@@ -230,25 +243,31 @@ let interp_view ist v p =
match DAst.get v with
| Glob_term.GApp (hd, rargs) when is_specialize hd ->
Ssrprinters.ppdebug (lazy Pp.(str "specialize"));
- interp_glob ist (mkGApp p_id rargs) >>= tclKeepOpenConstr
+ interp_glob ist (mkGApp p_id rargs)
+ >>= tclKeepOpenConstr >>= tclPAIR []
| _ ->
Ssrprinters.ppdebug (lazy Pp.(str "view"));
(* We find out how to build (v p) eventually using an adaptor *)
let adaptors = AdaptorDb.(get Forward) in
Proofview.tclORELSE
- (pad_to_inductive ist v >>= fun vpad ->
+ (pad_to_inductive ist v >>= fun (vpad,clr) ->
Ssrcommon.tclFIRSTa (List.map
- (fun a -> interp_glob ist (mkGApp a [vpad; p_id])) adaptors))
+ (fun a -> interp_glob ist (mkGApp a [vpad; p_id])) adaptors)
+ >>= tclPAIR clr)
(fun _ ->
guess_max_implicits ist v >>= fun n ->
Ssrcommon.tclFIRSTi (fun n ->
- interp_glob ist (mkGApp v (mkGHoles n @ [p_id]))) n)
- >>= tclKeepOpenConstr
+ interp_glob ist (mkGApp v (mkGHoles n @ [p_id]))) n
+ >>= fun x -> tclADD_CLEAR_IF_ID x x)
+ >>= fun (ot,clr) ->
+ if clear_if_id
+ then tclKeepOpenConstr ot >>= tclPAIR clr
+ else tclKeepOpenConstr ot >>= tclPAIR []
(* we store in the state (v top), then (v1 (v2 top))... *)
-let pile_up_view (ist, v) =
+let pile_up_view ~clear_if_id (ist, v) =
let ist = Ssrcommon.option_assert_get ist (Pp.str"not a term") in
- State.vsPUSH (fun p -> interp_view ist v p)
+ State.vsPUSH (fun p -> interp_view ~clear_if_id ist v p)
let finalize_view s0 ?(simple_types=true) p =
Goal.enter_one ~__LOC__ begin fun g ->
@@ -292,7 +311,7 @@ let pose_proof subject_name p =
<*>
Tactics.New.reduce_after_refine
-let rec apply_all_views ending vs s0 =
+let rec apply_all_views ~clear_if_id ending vs s0 =
match vs with
| [] -> ending s0
| v :: vs ->
@@ -301,31 +320,35 @@ let rec apply_all_views ending vs s0 =
| `Tac tac ->
Ssrprinters.ppdebug (lazy Pp.(str"..a tactic"));
ending s0 <*> Tacinterp.eval_tactic tac <*>
- Ssrcommon.tacSIGMA >>= apply_all_views ending vs
+ Ssrcommon.tacSIGMA >>= apply_all_views ~clear_if_id ending vs
| `Term v ->
Ssrprinters.ppdebug (lazy Pp.(str"..a term"));
- pile_up_view v <*> apply_all_views ending vs s0
+ pile_up_view ~clear_if_id v <*>
+ apply_all_views ~clear_if_id ending vs s0
(* Entry points *********************************************************)
-let tclIPAT_VIEWS ~views:vs ~conclusion:tac =
+let tclIPAT_VIEWS ~views:vs ?(clear_if_id=false) ~conclusion:tac =
let end_view_application s0 =
- State.vsCONSUME (fun name t ->
- finalize_view s0 t >>= pose_proof name <*>
- tac ~to_clear:(Option.cata (fun x -> [x]) [] name)) in
+ State.vsCONSUME (fun ~name t ~to_clear ->
+ let to_clear = Option.cata (fun x -> [x]) [] name @ to_clear in
+ finalize_view s0 t >>= pose_proof name <*> tac ~to_clear) in
tclINDEPENDENT begin
State.vsASSERT_EMPTY <*>
- Ssrcommon.tacSIGMA >>= apply_all_views end_view_application vs <*>
+ Ssrcommon.tacSIGMA >>=
+ apply_all_views ~clear_if_id end_view_application vs <*>
State.vsASSERT_EMPTY
end
let tclWITH_FWD_VIEWS ~simple_types ~subject ~views:vs ~conclusion:tac =
let ending_tac s0 =
- State.vsCONSUME (fun _ t -> finalize_view s0 ~simple_types t >>= tac) in
+ State.vsCONSUME (fun ~name:_ t ~to_clear:_ ->
+ finalize_view s0 ~simple_types t >>= tac) in
tclINDEPENDENT begin
State.vsASSERT_EMPTY <*>
- State.vsINIT subject <*>
- Ssrcommon.tacSIGMA >>= apply_all_views ending_tac vs <*>
+ State.vsINIT (subject,[]) <*>
+ Ssrcommon.tacSIGMA >>=
+ apply_all_views ~clear_if_id:false ending_tac vs <*>
State.vsASSERT_EMPTY
end
diff --git a/plugins/ssr/ssrview.mli b/plugins/ssr/ssrview.mli
index be51fe7f9..b128a95da 100644
--- a/plugins/ssr/ssrview.mli
+++ b/plugins/ssr/ssrview.mli
@@ -20,9 +20,11 @@ module AdaptorDb : sig
end
-(* Apply views to the top of the stack (intro pattern) *)
+(* Apply views to the top of the stack (intro pattern). If clear_if_id is
+ * true (default false) then views that happen to be a variable are considered
+ * as to be cleared (see the to_clear argument to the continuation) *)
val tclIPAT_VIEWS :
- views:ast_closure_term list ->
+ views:ast_closure_term list -> ?clear_if_id:bool ->
conclusion:(to_clear:Names.Id.t list -> unit Proofview.tactic) ->
unit Proofview.tactic
diff --git a/plugins/ssrmatching/g_ssrmatching.ml4 b/plugins/ssrmatching/g_ssrmatching.ml4
new file mode 100644
index 000000000..746c368aa
--- /dev/null
+++ b/plugins/ssrmatching/g_ssrmatching.ml4
@@ -0,0 +1,101 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Ltac_plugin
+open Genarg
+open Pcoq
+open Pcoq.Constr
+open Ssrmatching
+open Ssrmatching.Internal
+
+(* Defining grammar rules with "xx" in it automatically declares keywords too,
+ * we thus save the lexer to restore it at the end of the file *)
+let frozen_lexer = CLexer.get_keyword_state () ;;
+
+DECLARE PLUGIN "ssrmatching_plugin"
+
+let pr_rpattern _ _ _ = pr_rpattern
+
+ARGUMENT EXTEND rpattern
+ TYPED AS rpatternty
+ PRINTED BY pr_rpattern
+ INTERPRETED BY interp_rpattern
+ GLOBALIZED BY glob_rpattern
+ SUBSTITUTED BY subst_rpattern
+ | [ lconstr(c) ] -> [ mk_rpattern (T (mk_lterm c None)) ]
+ | [ "in" lconstr(c) ] -> [ mk_rpattern (In_T (mk_lterm c None)) ]
+ | [ lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (X_In_T (mk_lterm x None, mk_lterm c None)) ]
+ | [ "in" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (In_X_In_T (mk_lterm x None, mk_lterm c None)) ]
+ | [ lconstr(e) "in" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (E_In_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None)) ]
+ | [ lconstr(e) "as" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (E_As_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None)) ]
+END
+
+let pr_ssrterm _ _ _ = pr_ssrterm
+
+ARGUMENT EXTEND cpattern
+ PRINTED BY pr_ssrterm
+ INTERPRETED BY interp_ssrterm
+ GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
+ RAW_PRINTED BY pr_ssrterm
+ GLOB_PRINTED BY pr_ssrterm
+| [ "Qed" constr(c) ] -> [ mk_lterm c None ]
+END
+
+let input_ssrtermkind strm = match Util.stream_nth 0 strm with
+ | Tok.KEYWORD "(" -> '('
+ | Tok.KEYWORD "@" -> '@'
+ | _ -> ' '
+let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind
+
+GEXTEND Gram
+ GLOBAL: cpattern;
+ cpattern: [[ k = ssrtermkind; c = constr ->
+ let pattern = mk_term k c None in
+ if loc_of_cpattern pattern <> Some !@loc && k = '('
+ then mk_term 'x' c None
+ else pattern ]];
+END
+
+ARGUMENT EXTEND lcpattern
+ TYPED AS cpattern
+ PRINTED BY pr_ssrterm
+ INTERPRETED BY interp_ssrterm
+ GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
+ RAW_PRINTED BY pr_ssrterm
+ GLOB_PRINTED BY pr_ssrterm
+| [ "Qed" lconstr(c) ] -> [ mk_lterm c None ]
+END
+
+GEXTEND Gram
+ GLOBAL: lcpattern;
+ lcpattern: [[ k = ssrtermkind; c = lconstr ->
+ let pattern = mk_term k c None in
+ if loc_of_cpattern pattern <> Some !@loc && k = '('
+ then mk_term 'x' c None
+ else pattern ]];
+END
+
+ARGUMENT EXTEND ssrpatternarg TYPED AS rpattern PRINTED BY pr_rpattern
+| [ rpattern(pat) ] -> [ pat ]
+END
+
+TACTIC EXTEND ssrinstoftpat
+| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof arg) ]
+END
+
+(* We wipe out all the keywords generated by the grammar rules we defined. *)
+(* The user is supposed to Require Import ssreflect or Require ssreflect *)
+(* and Import ssreflect.SsrSyntax to obtain these keywords and as a *)
+(* consequence the extended ssreflect grammar. *)
+let () = CLexer.set_keyword_state frozen_lexer ;;
diff --git a/plugins/ssrmatching/g_ssrmatching.mli b/plugins/ssrmatching/g_ssrmatching.mli
new file mode 100644
index 000000000..bb5161a0e
--- /dev/null
+++ b/plugins/ssrmatching/g_ssrmatching.mli
@@ -0,0 +1,17 @@
+(* (c) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+(* Distributed under the terms of CeCILL-B. *)
+
+open Genarg
+open Ssrmatching
+
+(** CS cpattern: (f _), (X in t), (t in X in t), (t as X in t) *)
+val cpattern : cpattern Pcoq.Gram.entry
+val wit_cpattern : cpattern uniform_genarg_type
+
+(** OS cpattern: f _, (X in t), (t in X in t), (t as X in t) *)
+val lcpattern : cpattern Pcoq.Gram.entry
+val wit_lcpattern : cpattern uniform_genarg_type
+
+(** OS rpattern: f _, in t, X in t, in X in t, t in X in t, t as X in t *)
+val rpattern : rpattern Pcoq.Gram.entry
+val wit_rpattern : rpattern uniform_genarg_type
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml
index c20e415b4..05eda14e9 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml
@@ -10,10 +10,6 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
-(* Defining grammar rules with "xx" in it automatically declares keywords too,
- * we thus save the lexer to restore it at the end of the file *)
-let frozen_lexer = CLexer.get_keyword_state () ;;
-
open Ltac_plugin
open Names
open Pp
@@ -22,8 +18,6 @@ open Stdarg
open Term
module CoqConstr = Constr
open CoqConstr
-open Pcoq
-open Pcoq.Constr
open Vars
open Libnames
open Tactics
@@ -46,8 +40,6 @@ open Evar_kinds
open Constrexpr
open Constrexpr_ops
-DECLARE PLUGIN "ssrmatching_plugin"
-
let errorstrm = CErrors.user_err ~hdr:"ssrmatching"
let loc_error loc msg = CErrors.user_err ?loc ~hdr:msg (str msg)
let ppnl = Feedback.msg_info
@@ -561,8 +553,8 @@ let filter_upat i0 f n u fpats =
let na = Array.length u.up_a in
if n < na then fpats else
let np = match u.up_k with
- | KpatConst when equal u.up_f f -> na
- | KpatFixed when equal u.up_f f -> na
+ | KpatConst when eq_constr_nounivs u.up_f f -> na
+ | KpatFixed when eq_constr_nounivs u.up_f f -> na
| KpatEvar k when isEvar_k k f -> na
| KpatLet when isLetIn f -> na
| KpatLam when isLambda f -> na
@@ -582,8 +574,8 @@ let filter_upat_FO i0 f n u fpats =
let np = nb_args u.up_FO in
if n < np then fpats else
let ok = match u.up_k with
- | KpatConst -> equal u.up_f f
- | KpatFixed -> equal u.up_f f
+ | KpatConst -> eq_constr_nounivs u.up_f f
+ | KpatFixed -> eq_constr_nounivs u.up_f f
| KpatEvar k -> isEvar_k k f
| KpatLet -> isLetIn f
| KpatLam -> isLambda f
@@ -764,8 +756,8 @@ let mk_tpattern_matcher ?(all_instances=false)
let match_let f = match kind f with
| LetIn (_, v, _, b) -> unif_EQ env sigma pv v && unif_EQ env' sigma pb b
| _ -> false in match_let
- | KpatFixed -> equal u.up_f
- | KpatConst -> equal u.up_f
+ | KpatFixed -> eq_constr_nounivs u.up_f
+ | KpatConst -> eq_constr_nounivs u.up_f
| KpatLam -> fun c ->
(match kind c with
| Lambda _ -> unif_EQ env sigma u.up_f c
@@ -907,7 +899,6 @@ let pr_pattern_aux pr_constr = function
let pp_pattern (sigma, p) =
pr_pattern_aux (fun t -> pr_constr_pat (EConstr.Unsafe.to_constr (pi3 (nf_open_term sigma sigma (EConstr.of_constr t))))) p
let pr_cpattern = pr_term
-let pr_rpattern _ _ _ = pr_pattern
let wit_rpatternty = add_genarg "rpatternty" pr_pattern
@@ -987,27 +978,7 @@ let interp_rpattern s = function
| E_As_X_In_T(e,x,t) ->
E_As_X_In_T (interp_ssrterm s e,interp_ssrterm s x,interp_ssrterm s t)
-let interp_rpattern ist gl t = Tacmach.project gl, interp_rpattern ist t
-
-ARGUMENT EXTEND rpattern
- TYPED AS rpatternty
- PRINTED BY pr_rpattern
- INTERPRETED BY interp_rpattern
- GLOBALIZED BY glob_rpattern
- SUBSTITUTED BY subst_rpattern
- | [ lconstr(c) ] -> [ T (mk_lterm c None) ]
- | [ "in" lconstr(c) ] -> [ In_T (mk_lterm c None) ]
- | [ lconstr(x) "in" lconstr(c) ] ->
- [ X_In_T (mk_lterm x None, mk_lterm c None) ]
- | [ "in" lconstr(x) "in" lconstr(c) ] ->
- [ In_X_In_T (mk_lterm x None, mk_lterm c None) ]
- | [ lconstr(e) "in" lconstr(x) "in" lconstr(c) ] ->
- [ E_In_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ]
- | [ lconstr(e) "as" lconstr(x) "in" lconstr(c) ] ->
- [ E_As_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ]
-END
-
-
+let interp_rpattern0 ist gl t = Tacmach.project gl, interp_rpattern ist t
type cpattern = char * glob_constr_and_expr * Geninterp.interp_sign option
let tag_of_cpattern = pi1
@@ -1051,52 +1022,9 @@ let interp_wit wit ist gl x =
let interp_open_constr ist gl gc =
interp_wit wit_open_constr ist gl gc
let pf_intern_term gl (_, c, ist) = glob_constr ist (pf_env gl) (project gl) c
-let pr_ssrterm _ _ _ = pr_term
-let input_ssrtermkind strm = match stream_nth 0 strm with
- | Tok.KEYWORD "(" -> '('
- | Tok.KEYWORD "@" -> '@'
- | _ -> ' '
-let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind
let interp_ssrterm ist gl t = Tacmach.project gl, interp_ssrterm ist t
-ARGUMENT EXTEND cpattern
- PRINTED BY pr_ssrterm
- INTERPRETED BY interp_ssrterm
- GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
- RAW_PRINTED BY pr_ssrterm
- GLOB_PRINTED BY pr_ssrterm
-| [ "Qed" constr(c) ] -> [ mk_lterm c None ]
-END
-
-GEXTEND Gram
- GLOBAL: cpattern;
- cpattern: [[ k = ssrtermkind; c = constr ->
- let pattern = mk_term k c None in
- if loc_ofCG pattern <> Some !@loc && k = '('
- then mk_term 'x' c None
- else pattern ]];
-END
-
-ARGUMENT EXTEND lcpattern
- TYPED AS cpattern
- PRINTED BY pr_ssrterm
- INTERPRETED BY interp_ssrterm
- GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
- RAW_PRINTED BY pr_ssrterm
- GLOB_PRINTED BY pr_ssrterm
-| [ "Qed" lconstr(c) ] -> [ mk_lterm c None ]
-END
-
-GEXTEND Gram
- GLOBAL: lcpattern;
- lcpattern: [[ k = ssrtermkind; c = lconstr ->
- let pattern = mk_term k c None in
- if loc_ofCG pattern <> Some !@loc && k = '('
- then mk_term 'x' c None
- else pattern ]];
-END
-
let interp_term gl = function
| (_, c, Some ist) ->
on_snd EConstr.Unsafe.to_constr (interp_open_constr ist gl c)
@@ -1416,10 +1344,6 @@ let is_wildcard ((_, (l, r), _) : cpattern) : bool = match DAst.get l, r with
(* "ssrpattern" *)
-ARGUMENT EXTEND ssrpatternarg TYPED AS rpattern PRINTED BY pr_rpattern
-| [ rpattern(pat) ] -> [ pat ]
-END
-
let pr_rpattern = pr_pattern
let pf_merge_uc uc gl =
@@ -1428,6 +1352,9 @@ let pf_merge_uc uc gl =
let pf_unsafe_merge_uc uc gl =
re_sig (sig_it gl) (Evd.set_universe_context (project gl) uc)
+(** All the pattern types reuse the same dynamic toplevel tag *)
+let wit_ssrpatternarg = wit_rpatternty
+
let interp_rpattern = interp_rpattern ~wit_ssrpatternarg
let ssrpatterntac _ist arg gl =
@@ -1479,14 +1406,20 @@ let ssrinstancesof arg gl =
done; raise NoMatch
with NoMatch -> ppnl (str"END INSTANCES"); tclIDTAC gl
-TACTIC EXTEND ssrinstoftpat
-| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof arg) ]
-END
-
-(* We wipe out all the keywords generated by the grammar rules we defined. *)
-(* The user is supposed to Require Import ssreflect or Require ssreflect *)
-(* and Import ssreflect.SsrSyntax to obtain these keywords and as a *)
-(* consequence the extended ssreflect grammar. *)
-let () = CLexer.set_keyword_state frozen_lexer ;;
+module Internal =
+struct
+ let wit_rpatternty = wit_rpatternty
+ let glob_rpattern = glob_rpattern
+ let subst_rpattern = subst_rpattern
+ let interp_rpattern = interp_rpattern0
+ let pr_rpattern = pr_rpattern
+ let mk_rpattern x = x
+ let mk_lterm = mk_lterm
+ let mk_term = mk_term
+ let glob_cpattern = glob_cpattern
+ let subst_ssrterm = subst_ssrterm
+ let interp_ssrterm = interp_ssrterm
+ let pr_ssrterm = pr_term
+end
(* vim: set filetype=ocaml foldmethod=marker: *)
diff --git a/plugins/ssrmatching/ssrmatching.mli b/plugins/ssrmatching/ssrmatching.mli
index c55081e0f..f478d48ea 100644
--- a/plugins/ssrmatching/ssrmatching.mli
+++ b/plugins/ssrmatching/ssrmatching.mli
@@ -2,7 +2,6 @@
(* Distributed under the terms of CeCILL-B. *)
open Goal
-open Genarg
open Environ
open Evd
open Constr
@@ -19,24 +18,12 @@ open Tacexpr
type cpattern
val pr_cpattern : cpattern -> Pp.t
-(** CS cpattern: (f _), (X in t), (t in X in t), (t as X in t) *)
-val cpattern : cpattern Pcoq.Gram.entry
-val wit_cpattern : cpattern uniform_genarg_type
-
-(** OS cpattern: f _, (X in t), (t in X in t), (t as X in t) *)
-val lcpattern : cpattern Pcoq.Gram.entry
-val wit_lcpattern : cpattern uniform_genarg_type
-
(** The type of rewrite patterns, the patterns of the [rewrite] tactic.
These patterns also include patterns that identify all the subterms
of a context (i.e. "in" prefix) *)
type rpattern
val pr_rpattern : rpattern -> Pp.t
-(** OS rpattern: f _, in t, X in t, in X in t, t in X in t, t as X in t *)
-val rpattern : rpattern Pcoq.Gram.entry
-val wit_rpattern : rpattern uniform_genarg_type
-
(** Pattern interpretation and matching *)
exception NoMatch
@@ -238,4 +225,25 @@ val debug : bool -> unit
* "Unset SsrMatchingProfiling" to get timings *)
val profile : bool -> unit
+val ssrinstancesof : cpattern -> Tacmach.tactic
+
+(** Functions used for grammar extensions. Do not use. *)
+
+module Internal :
+sig
+ val wit_rpatternty : (rpattern, rpattern, rpattern) Genarg.genarg_type
+ val glob_rpattern : Genintern.glob_sign -> rpattern -> rpattern
+ val subst_rpattern : Mod_subst.substitution -> rpattern -> rpattern
+ val interp_rpattern : Geninterp.interp_sign -> Proof_type.goal Evd.sigma -> rpattern -> Evd.evar_map * rpattern
+ val pr_rpattern : rpattern -> Pp.t
+ val mk_rpattern : (cpattern, cpattern) ssrpattern -> rpattern
+ val mk_lterm : Constrexpr.constr_expr -> Geninterp.interp_sign option -> cpattern
+ val mk_term : char -> Constrexpr.constr_expr -> Geninterp.interp_sign option -> cpattern
+
+ val glob_cpattern : Genintern.glob_sign -> cpattern -> cpattern
+ val subst_ssrterm : Mod_subst.substitution -> cpattern -> cpattern
+ val interp_ssrterm : Geninterp.interp_sign -> Proof_type.goal Evd.sigma -> cpattern -> Evd.evar_map * cpattern
+ val pr_ssrterm : cpattern -> Pp.t
+end
+
(* eof *)
diff --git a/plugins/ssrmatching/ssrmatching_plugin.mlpack b/plugins/ssrmatching/ssrmatching_plugin.mlpack
index 5fb1f1567..02c75f14e 100644
--- a/plugins/ssrmatching/ssrmatching_plugin.mlpack
+++ b/plugins/ssrmatching/ssrmatching_plugin.mlpack
@@ -1 +1,2 @@
Ssrmatching
+G_ssrmatching
diff --git a/plugins/syntax/n_syntax.ml b/plugins/syntax/n_syntax.ml
new file mode 100644
index 000000000..0e202be47
--- /dev/null
+++ b/plugins/syntax/n_syntax.ml
@@ -0,0 +1,81 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+open CErrors
+open Names
+open Bigint
+open Positive_syntax_plugin.Positive_syntax
+
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "n_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
+(**********************************************************************)
+(* Parsing N via scopes *)
+(**********************************************************************)
+
+open Globnames
+open Glob_term
+
+let binnums = ["Coq";"Numbers";"BinNums"]
+
+let make_dir l = DirPath.make (List.rev_map Id.of_string l)
+let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
+
+(* TODO: temporary hack *)
+let make_kn dir id = Globnames.encode_mind dir id
+
+let n_kn = make_kn (make_dir binnums) (Id.of_string "N")
+let glob_n = IndRef (n_kn,0)
+let path_of_N0 = ((n_kn,0),1)
+let path_of_Npos = ((n_kn,0),2)
+let glob_N0 = ConstructRef path_of_N0
+let glob_Npos = ConstructRef path_of_Npos
+
+let n_path = make_path binnums "N"
+
+let n_of_binnat ?loc pos_or_neg n = DAst.make ?loc @@
+ if not (Bigint.equal n zero) then
+ GApp(DAst.make @@ GRef (glob_Npos,None), [pos_of_bignat ?loc n])
+ else
+ GRef(glob_N0, None)
+
+let error_negative ?loc =
+ user_err ?loc ~hdr:"interp_N" (str "No negative numbers in type \"N\".")
+
+let n_of_int ?loc n =
+ if is_pos_or_zero n then n_of_binnat ?loc true n
+ else error_negative ?loc
+
+(**********************************************************************)
+(* Printing N via scopes *)
+(**********************************************************************)
+
+let bignat_of_n n = DAst.with_val (function
+ | GApp (r, [a]) when is_gr r glob_Npos -> bignat_of_pos a
+ | GRef (a,_) when GlobRef.equal a glob_N0 -> Bigint.zero
+ | _ -> raise Non_closed_number
+ ) n
+
+let uninterp_n (AnyGlobConstr p) =
+ try Some (bignat_of_n p)
+ with Non_closed_number -> None
+
+(************************************************************************)
+(* Declaring interpreters and uninterpreters for N *)
+
+let _ = Notation.declare_numeral_interpreter "N_scope"
+ (n_path,binnums)
+ n_of_int
+ ([DAst.make @@ GRef (glob_N0, None);
+ DAst.make @@ GRef (glob_Npos, None)],
+ uninterp_n,
+ true)
diff --git a/plugins/syntax/n_syntax_plugin.mlpack b/plugins/syntax/n_syntax_plugin.mlpack
new file mode 100644
index 000000000..4c56645f0
--- /dev/null
+++ b/plugins/syntax/n_syntax_plugin.mlpack
@@ -0,0 +1 @@
+N_syntax
diff --git a/plugins/syntax/positive_syntax.ml b/plugins/syntax/positive_syntax.ml
new file mode 100644
index 000000000..0c82e4744
--- /dev/null
+++ b/plugins/syntax/positive_syntax.ml
@@ -0,0 +1,101 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+open CErrors
+open Util
+open Names
+open Bigint
+
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "positive_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
+exception Non_closed_number
+
+(**********************************************************************)
+(* Parsing positive via scopes *)
+(**********************************************************************)
+
+open Globnames
+open Glob_term
+
+let binnums = ["Coq";"Numbers";"BinNums"]
+
+let make_dir l = DirPath.make (List.rev_map Id.of_string l)
+let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
+
+let positive_path = make_path binnums "positive"
+
+(* TODO: temporary hack *)
+let make_kn dir id = Globnames.encode_mind dir id
+
+let positive_kn = make_kn (make_dir binnums) (Id.of_string "positive")
+let glob_positive = IndRef (positive_kn,0)
+let path_of_xI = ((positive_kn,0),1)
+let path_of_xO = ((positive_kn,0),2)
+let path_of_xH = ((positive_kn,0),3)
+let glob_xI = ConstructRef path_of_xI
+let glob_xO = ConstructRef path_of_xO
+let glob_xH = ConstructRef path_of_xH
+
+let pos_of_bignat ?loc x =
+ let ref_xI = DAst.make ?loc @@ GRef (glob_xI, None) in
+ let ref_xH = DAst.make ?loc @@ GRef (glob_xH, None) in
+ let ref_xO = DAst.make ?loc @@ GRef (glob_xO, None) in
+ let rec pos_of x =
+ match div2_with_rest x with
+ | (q,false) -> DAst.make ?loc @@ GApp (ref_xO,[pos_of q])
+ | (q,true) when not (Bigint.equal q zero) -> DAst.make ?loc @@ GApp (ref_xI,[pos_of q])
+ | (q,true) -> ref_xH
+ in
+ pos_of x
+
+let error_non_positive ?loc =
+ user_err ?loc ~hdr:"interp_positive"
+ (str "Only strictly positive numbers in type \"positive\".")
+
+let interp_positive ?loc n =
+ if is_strictly_pos n then pos_of_bignat ?loc n
+ else error_non_positive ?loc
+
+(**********************************************************************)
+(* Printing positive via scopes *)
+(**********************************************************************)
+
+let is_gr c gr = match DAst.get c with
+| GRef (r, _) -> GlobRef.equal r gr
+| _ -> false
+
+let rec bignat_of_pos x = DAst.with_val (function
+ | GApp (r ,[a]) when is_gr r glob_xO -> mult_2(bignat_of_pos a)
+ | GApp (r ,[a]) when is_gr r glob_xI -> add_1(mult_2(bignat_of_pos a))
+ | GRef (a, _) when GlobRef.equal a glob_xH -> Bigint.one
+ | _ -> raise Non_closed_number
+ ) x
+
+let uninterp_positive (AnyGlobConstr p) =
+ try
+ Some (bignat_of_pos p)
+ with Non_closed_number ->
+ None
+
+(************************************************************************)
+(* Declaring interpreters and uninterpreters for positive *)
+(************************************************************************)
+
+let _ = Notation.declare_numeral_interpreter "positive_scope"
+ (positive_path,binnums)
+ interp_positive
+ ([DAst.make @@ GRef (glob_xI, None);
+ DAst.make @@ GRef (glob_xO, None);
+ DAst.make @@ GRef (glob_xH, None)],
+ uninterp_positive,
+ true)
diff --git a/plugins/syntax/positive_syntax_plugin.mlpack b/plugins/syntax/positive_syntax_plugin.mlpack
new file mode 100644
index 000000000..ac8f3c425
--- /dev/null
+++ b/plugins/syntax/positive_syntax_plugin.mlpack
@@ -0,0 +1 @@
+Positive_syntax
diff --git a/plugins/syntax/z_syntax.ml b/plugins/syntax/z_syntax.ml
index 09fe8bf70..2534162e3 100644
--- a/plugins/syntax/z_syntax.ml
+++ b/plugins/syntax/z_syntax.ml
@@ -8,20 +8,16 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Pp
-open CErrors
-open Util
open Names
open Bigint
+open Positive_syntax_plugin.Positive_syntax
(* Poor's man DECLARE PLUGIN *)
let __coq_plugin_name = "z_syntax_plugin"
let () = Mltop.add_known_module __coq_plugin_name
-exception Non_closed_number
-
(**********************************************************************)
-(* Parsing positive via scopes *)
+(* Parsing Z via scopes *)
(**********************************************************************)
open Globnames
@@ -32,129 +28,9 @@ let binnums = ["Coq";"Numbers";"BinNums"]
let make_dir l = DirPath.make (List.rev_map Id.of_string l)
let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
-let positive_path = make_path binnums "positive"
-
(* TODO: temporary hack *)
let make_kn dir id = Globnames.encode_mind dir id
-let positive_kn = make_kn (make_dir binnums) (Id.of_string "positive")
-let glob_positive = IndRef (positive_kn,0)
-let path_of_xI = ((positive_kn,0),1)
-let path_of_xO = ((positive_kn,0),2)
-let path_of_xH = ((positive_kn,0),3)
-let glob_xI = ConstructRef path_of_xI
-let glob_xO = ConstructRef path_of_xO
-let glob_xH = ConstructRef path_of_xH
-
-let pos_of_bignat ?loc x =
- let ref_xI = DAst.make ?loc @@ GRef (glob_xI, None) in
- let ref_xH = DAst.make ?loc @@ GRef (glob_xH, None) in
- let ref_xO = DAst.make ?loc @@ GRef (glob_xO, None) in
- let rec pos_of x =
- match div2_with_rest x with
- | (q,false) -> DAst.make ?loc @@ GApp (ref_xO,[pos_of q])
- | (q,true) when not (Bigint.equal q zero) -> DAst.make ?loc @@ GApp (ref_xI,[pos_of q])
- | (q,true) -> ref_xH
- in
- pos_of x
-
-let error_non_positive ?loc =
- user_err ?loc ~hdr:"interp_positive"
- (str "Only strictly positive numbers in type \"positive\".")
-
-let interp_positive ?loc n =
- if is_strictly_pos n then pos_of_bignat ?loc n
- else error_non_positive ?loc
-
-(**********************************************************************)
-(* Printing positive via scopes *)
-(**********************************************************************)
-
-let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> GlobRef.equal r gr
-| _ -> false
-
-let rec bignat_of_pos x = DAst.with_val (function
- | GApp (r ,[a]) when is_gr r glob_xO -> mult_2(bignat_of_pos a)
- | GApp (r ,[a]) when is_gr r glob_xI -> add_1(mult_2(bignat_of_pos a))
- | GRef (a, _) when GlobRef.equal a glob_xH -> Bigint.one
- | _ -> raise Non_closed_number
- ) x
-
-let uninterp_positive (AnyGlobConstr p) =
- try
- Some (bignat_of_pos p)
- with Non_closed_number ->
- None
-
-(************************************************************************)
-(* Declaring interpreters and uninterpreters for positive *)
-(************************************************************************)
-
-let _ = Notation.declare_numeral_interpreter "positive_scope"
- (positive_path,binnums)
- interp_positive
- ([DAst.make @@ GRef (glob_xI, None);
- DAst.make @@ GRef (glob_xO, None);
- DAst.make @@ GRef (glob_xH, None)],
- uninterp_positive,
- true)
-
-(**********************************************************************)
-(* Parsing N via scopes *)
-(**********************************************************************)
-
-let n_kn = make_kn (make_dir binnums) (Id.of_string "N")
-let glob_n = IndRef (n_kn,0)
-let path_of_N0 = ((n_kn,0),1)
-let path_of_Npos = ((n_kn,0),2)
-let glob_N0 = ConstructRef path_of_N0
-let glob_Npos = ConstructRef path_of_Npos
-
-let n_path = make_path binnums "N"
-
-let n_of_binnat ?loc pos_or_neg n = DAst.make ?loc @@
- if not (Bigint.equal n zero) then
- GApp(DAst.make @@ GRef (glob_Npos,None), [pos_of_bignat ?loc n])
- else
- GRef(glob_N0, None)
-
-let error_negative ?loc =
- user_err ?loc ~hdr:"interp_N" (str "No negative numbers in type \"N\".")
-
-let n_of_int ?loc n =
- if is_pos_or_zero n then n_of_binnat ?loc true n
- else error_negative ?loc
-
-(**********************************************************************)
-(* Printing N via scopes *)
-(**********************************************************************)
-
-let bignat_of_n n = DAst.with_val (function
- | GApp (r, [a]) when is_gr r glob_Npos -> bignat_of_pos a
- | GRef (a,_) when GlobRef.equal a glob_N0 -> Bigint.zero
- | _ -> raise Non_closed_number
- ) n
-
-let uninterp_n (AnyGlobConstr p) =
- try Some (bignat_of_n p)
- with Non_closed_number -> None
-
-(************************************************************************)
-(* Declaring interpreters and uninterpreters for N *)
-
-let _ = Notation.declare_numeral_interpreter "N_scope"
- (n_path,binnums)
- n_of_int
- ([DAst.make @@ GRef (glob_N0, None);
- DAst.make @@ GRef (glob_Npos, None)],
- uninterp_n,
- true)
-
-(**********************************************************************)
-(* Parsing Z via scopes *)
-(**********************************************************************)
-
let z_path = make_path binnums "Z"
let z_kn = make_kn (make_dir binnums) (Id.of_string "Z")
let glob_z = IndRef (z_kn,0)
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index bf9e37aa7..5c4cbefad 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -209,8 +209,8 @@ and coerce ?loc env evdref (x : EConstr.constr) (y : EConstr.constr)
match (EConstr.kind !evdref x, EConstr.kind !evdref y) with
| Sort s, Sort s' ->
(match ESorts.kind !evdref s, ESorts.kind !evdref s' with
- | Prop x, Prop y when x == y -> None
- | Prop _, Type _ -> None
+ | Prop, Prop | Set, Set -> None
+ | (Prop | Set), Type _ -> None
| Type x, Type y when Univ.Universe.equal x y -> None (* false *)
| _ -> subco ())
| Prod (name, a, b), Prod (name', a', b') ->
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 2bc603a90..d7118efd7 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -281,8 +281,8 @@ let matches_core env sigma allow_bound_rels
let open Glob_term in
begin match ps, ESorts.kind sigma s with
- | GProp, Prop Null -> subst
- | GSet, Prop Pos -> subst
+ | GProp, Prop -> subst
+ | GSet, Set -> subst
| GType _, Type _ -> subst
| _ -> raise PatternMatchingFailure
end
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index fe49d64c7..d0de2f8c0 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -597,8 +597,8 @@ let detype_universe sigma u =
Univ.Universe.map fn u
let detype_sort sigma = function
- | Prop Null -> GProp
- | Prop Pos -> GSet
+ | Prop -> GProp
+ | Set -> GSet
| Type u ->
GType
(if !print_universes
@@ -690,8 +690,7 @@ and detype_r d flags avoid env sigma t =
let c' =
try
let pb = Environ.lookup_projection p (snd env) in
- (** FIXME: handle mutual records *)
- let ind = (pb.Declarations.proj_ind, 0) in
+ let ind = pb.Declarations.proj_ind in
let bodies = Inductiveops.legacy_match_projection (snd env) ind in
let body = bodies.(pb.Declarations.proj_arg) in
let ty = Retyping.get_type_of (snd env) sigma c in
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 6d08f66c1..a71ef6508 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -510,7 +510,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let tM = Stack.zip evd apprM in
miller_pfenning on_left
(fun () -> if not_only_app then (* Postpone the use of an heuristic *)
- switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i)) (Stack.zip evd apprF) tM
+ switch (fun x y -> Success (Evarutil.add_unification_pb (pbty,env,x,y) i)) (Stack.zip evd apprF) tM
else quick_fail i)
ev lF tM i
and consume (termF,skF as apprF) (termM,skM as apprM) i =
@@ -578,7 +578,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
i,mkEvar ev
else
i,Stack.zip evd apprF in
- switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i))
+ switch (fun x y -> Success (Evarutil.add_unification_pb (pbty,env,x,y) i))
tF tR
else
UnifFailure (evd,OccurCheck (fst ev,tR)))])
@@ -984,9 +984,11 @@ and conv_record trs env evd (ctx,(h,h2),c,bs,(params,params1),(us,us2),(sk1,sk2)
else UnifFailure(evd,(*dummy*)NotSameHead)
and eta_constructor ts env evd sk1 ((ind, i), u) sk2 term2 =
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
match mib.Declarations.mind_record with
- | Some (Some (id, projs, pbs)) when mib.Declarations.mind_finite == Declarations.BiFinite ->
+ | PrimRecord info when mib.Declarations.mind_finite == Declarations.BiFinite ->
+ let (_, projs, _) = info.(snd ind) in
let pars = mib.Declarations.mind_nparams in
(try
let l1' = Stack.tail pars sk1 in
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 8afb9b942..3f5d186d4 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -69,7 +69,7 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) ?(refreshset=false)
if onlyalg && alg then
(evdref := Evd.make_flexible_variable !evdref ~algebraic:false l; t)
else t))
- | Prop Pos when refreshset && not direction ->
+ | Set when refreshset && not direction ->
(* Cannot make a universe "lower" than "Set",
only refreshing when we want higher universes. *)
refresh_sort status ~direction s
diff --git a/pretyping/geninterp.mli b/pretyping/geninterp.mli
index fa522e9c3..606a6ebea 100644
--- a/pretyping/geninterp.mli
+++ b/pretyping/geninterp.mli
@@ -42,8 +42,8 @@ sig
end
-module ValTMap (M : Dyn.TParam) :
- Dyn.MapS with type 'a obj = 'a M.t with type 'a key = 'a Val.typ
+module ValTMap (Value : Dyn.ValueS) :
+ Dyn.MapS with type 'a key = 'a Val.typ and type 'a value = 'a Value.t
(** Dynamic types for toplevel values. While the generic types permit to relate
objects at various levels of interpretation, toplevel values are wearing
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index ba193da60..4dfa789ba 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -112,7 +112,7 @@ let fix_kind_eq f k1 k2 = match k1, k2 with
let eq (i1, o1) (i2, o2) =
Option.equal Int.equal i1 i2 && fix_recursion_order_eq f o1 o2
in
- Int.equal i1 i2 && Array.equal eq a1 a1
+ Int.equal i1 i2 && Array.equal eq a1 a2
| GCoFix i1, GCoFix i2 -> Int.equal i1 i2
| (GFix _ | GCoFix _), _ -> false
@@ -452,7 +452,7 @@ let rec rename_glob_vars l c = force @@ DAst.map_with_loc (fun ?loc -> function
else r
| GProd (na,bk,t,c) ->
let na',l' = update_subst na l in
- GProd (na,bk,rename_glob_vars l t,rename_glob_vars l' c)
+ GProd (na',bk,rename_glob_vars l t,rename_glob_vars l' c)
| GLambda (na,bk,t,c) ->
let na',l' = update_subst na l in
GLambda (na',bk,rename_glob_vars l t,rename_glob_vars l' c)
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 4ab932723..551cc67b6 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -86,7 +86,7 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
if not (Sorts.List.mem kind (elim_sorts specif)) then
raise
(RecursionSchemeError
- (NotAllowedCaseAnalysis (false, fst (UnivGen.fresh_sort_in_family env kind), pind)))
+ (NotAllowedCaseAnalysis (false, fst (UnivGen.fresh_sort_in_family kind), pind)))
in
let ndepar = mip.mind_nrealdecls + 1 in
@@ -136,7 +136,7 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
mkLambda_string "f" t
(add_branch (push_rel (LocalAssum (Anonymous, t)) env) (k+1))
in
- let (sigma, s) = Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env sigma kind in
+ let (sigma, s) = Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg sigma kind in
let typP = make_arity env' sigma dep indf s in
let typP = EConstr.Unsafe.to_constr typP in
let c =
@@ -455,7 +455,7 @@ let mis_make_indrec env sigma ?(force_mutual=false) listdepkind mib u =
| ((indi,u),_,_,dep,kinds)::rest ->
let indf = make_ind_family ((indi,u), Context.Rel.to_extended_list mkRel i lnamesparrec) in
let s =
- Evarutil.evd_comb1 (Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env)
+ Evarutil.evd_comb1 (Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg)
evdref kinds
in
let typP = make_arity env !evdref dep indf s in
@@ -550,8 +550,7 @@ let check_arities env listdepkind =
let kelim = elim_sorts (mibi,mipi) in
if not (Sorts.List.mem kind kelim) then raise
(RecursionSchemeError
- (NotAllowedCaseAnalysis (true, fst (UnivGen.fresh_sort_in_family env
- kind),(mind,u))))
+ (NotAllowedCaseAnalysis (true, fst (UnivGen.fresh_sort_in_family kind),(mind,u))))
else if Int.List.mem ni ln then raise
(RecursionSchemeError (NotMutualInScheme (mind,mind)))
else ni::ln)
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index 1003f86c5..576073344 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -277,8 +277,8 @@ let projection_nparams p = projection_nparams_env (Global.env ()) p
let has_dependent_elim mib =
match mib.mind_record with
- | Some (Some _) -> mib.mind_finite == BiFinite
- | _ -> true
+ | PrimRecord _ -> mib.mind_finite == BiFinite
+ | NotRecord | FakeRecord -> true
(* Annotation for cases *)
let make_case_info env ind style =
@@ -303,7 +303,7 @@ type constructor_summary = {
cs_cstr : pconstructor;
cs_params : constr list;
cs_nargs : int;
- cs_args : Context.Rel.t;
+ cs_args : Constr.rel_context;
cs_concl_realargs : constr array
}
@@ -346,8 +346,10 @@ let get_constructors env (ind,params) =
let get_projections env (ind,params) =
let (mib,mip) = Inductive.lookup_mind_specif env (fst ind) in
match mib.mind_record with
- | Some (Some (id, projs, pbs)) -> Some projs
- | _ -> None
+ | PrimRecord infos ->
+ let (_, projs, _) = infos.(snd (fst ind)) in
+ Some projs
+ | NotRecord | FakeRecord -> None
let make_case_or_project env sigma indf ci pred c branches =
let open EConstr in
@@ -460,25 +462,24 @@ let build_branch_type env sigma dep p cs =
build an expansion function.
The term built is expecting to be substituted first by
a substitution of the form [params, x : ind params] *)
-let compute_projections env (kn, _ as ind) =
+let compute_projections env (kn, i as ind) =
let open Term in
let mib = Environ.lookup_mind kn env in
- let indu = match mib.mind_universes with
- | Monomorphic_ind _ -> mkInd ind
- | Polymorphic_ind ctx -> mkIndU (ind, make_abstract_instance ctx)
- | Cumulative_ind ctx ->
- mkIndU (ind, make_abstract_instance (ACumulativityInfo.univ_context ctx))
+ let u = match mib.mind_universes with
+ | Monomorphic_ind _ -> Instance.empty
+ | Polymorphic_ind auctx -> make_abstract_instance auctx
+ | Cumulative_ind acumi ->
+ make_abstract_instance (ACumulativityInfo.univ_context acumi)
in
let x = match mib.mind_record with
- | None | Some None ->
+ | NotRecord | FakeRecord ->
anomaly Pp.(str "Trying to build primitive projections for a non-primitive record")
- | Some (Some (id, _, _)) -> Name id
+ | PrimRecord info-> Name (pi1 (info.(i)))
in
- (** FIXME: handle mutual records *)
- let pkt = mib.mind_packets.(0) in
- let { mind_consnrealargs; mind_consnrealdecls } = pkt in
+ let pkt = mib.mind_packets.(i) in
let { mind_nparams = nparamargs; mind_params_ctxt = params } = mib in
- let rctx, _ = decompose_prod_assum (subst1 indu pkt.mind_nf_lc.(0)) in
+ let subst = List.init mib.mind_ntypes (fun i -> mkIndU ((kn, mib.mind_ntypes - i - 1), u)) in
+ let rctx, _ = decompose_prod_assum (substl subst pkt.mind_nf_lc.(0)) in
let ctx, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
let mp, dp, l = MutInd.repr3 kn in
(** We build a substitution smashing the lets in the record parameters so
@@ -487,6 +488,7 @@ let compute_projections env (kn, _ as ind) =
let indty =
(* [ty] = [Ind inst] is typed in context [params] *)
let inst = Context.Rel.to_extended_vect mkRel 0 paramslet in
+ let indu = mkIndU (ind, u) in
let ty = mkApp (indu, inst) in
(* [Ind inst] is typed in context [params-wo-let] *)
ty
@@ -496,8 +498,8 @@ let compute_projections env (kn, _ as ind) =
{ ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
{ ci_ind = ind;
ci_npar = nparamargs;
- ci_cstr_ndecls = mind_consnrealdecls;
- ci_cstr_nargs = mind_consnrealargs;
+ ci_cstr_ndecls = pkt.mind_consnrealdecls;
+ ci_cstr_nargs = pkt.mind_consnrealargs;
ci_pp_info = print_info }
in
let len = List.length ctx in
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index aa53f7e67..8eaef24c4 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -93,12 +93,12 @@ val inductive_nparamdecls : inductive -> int
val inductive_nparamdecls_env : env -> inductive -> int
(** @return params context *)
-val inductive_paramdecls : pinductive -> Context.Rel.t
-val inductive_paramdecls_env : env -> pinductive -> Context.Rel.t
+val inductive_paramdecls : pinductive -> Constr.rel_context
+val inductive_paramdecls_env : env -> pinductive -> Constr.rel_context
(** @return full arity context, hence with letin *)
-val inductive_alldecls : pinductive -> Context.Rel.t
-val inductive_alldecls_env : env -> pinductive -> Context.Rel.t
+val inductive_alldecls : pinductive -> Constr.rel_context
+val inductive_alldecls_env : env -> pinductive -> Constr.rel_context
(** {7 Extract information from a constructor name} *)
@@ -141,7 +141,7 @@ type constructor_summary = {
cs_cstr : pconstructor; (* internal name of the constructor plus universes *)
cs_params : constr list; (* parameters of the constructor in current ctx *)
cs_nargs : int; (* length of arguments signature (letin included) *)
- cs_args : Context.Rel.t; (* signature of the arguments (letin included) *)
+ cs_args : Constr.rel_context; (* signature of the arguments (letin included) *)
cs_concl_realargs : constr array; (* actual realargs in the concl of cstr *)
}
val lift_constructor : int -> constructor_summary -> constructor_summary
@@ -154,7 +154,7 @@ val get_projections : env -> inductive_family -> Constant.t array option
(** [get_arity] returns the arity of the inductive family instantiated
with the parameters; if recursively non-uniform parameters are not
part of the inductive family, they appears in the arity *)
-val get_arity : env -> inductive_family -> Context.Rel.t * Sorts.family
+val get_arity : env -> inductive_family -> Constr.rel_context * Sorts.family
val build_dependent_constructor : constructor_summary -> constr
val build_dependent_inductive : env -> inductive_family -> constr
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 4b8e0e096..21c202205 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -123,7 +123,7 @@ let construct_of_constr_notnative const env tag (mind, _ as ind) u allargs =
try
if const then
let ctyp = type_constructor mind mib u (mip.mind_nf_lc.(0)) params in
- retroknowledge Retroknowledge.get_vm_decompile_constant_info env (mkInd ind) tag, ctyp
+ Retroknowledge.get_vm_decompile_constant_info env.retroknowledge (mkInd ind) tag, ctyp
else
raise Not_found
with Not_found ->
@@ -144,7 +144,7 @@ let construct_of_constr_const env tag typ =
let construct_of_constr_block = construct_of_constr false
-let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
+let build_branches_type env sigma (mind,_ as _ind) mib mip u params p =
let rtbl = mip.mind_reloc_tbl in
(* [build_one_branch i cty] construit le type de la ieme branche (commence
a 0) et les lambda correspondant aux realargs *)
@@ -161,20 +161,17 @@ let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
let codom =
let ndecl = List.length decl in
let papp = mkApp(lift ndecl p,crealargs) in
- if dep then
- let cstr = ith_constructor_of_inductive (fst ind) (i+1) in
- let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
- let params = Array.map (lift ndecl) params in
- let dep_cstr = mkApp(mkApp(mkConstructU (cstr,snd ind),params),relargs) in
- mkApp(papp,[|dep_cstr|])
- else papp
+ let cstr = ith_constructor_of_inductive (fst ind) (i+1) in
+ let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
+ let params = Array.map (lift ndecl) params in
+ let dep_cstr = mkApp(mkApp(mkConstructU (cstr,snd ind),params),relargs) in
+ mkApp(papp,[|dep_cstr|])
in
decl, decl_with_letin, codom
in Array.mapi build_one_branch mip.mind_nf_lc
-let build_case_type dep p realargs c =
- if dep then mkApp(mkApp(p, realargs), [|c|])
- else mkApp(p, realargs)
+let build_case_type p realargs c =
+ mkApp(mkApp(p, realargs), [|c|])
(* normalisation of values *)
@@ -188,12 +185,13 @@ let branch_of_switch lvl ans bs =
bs ci in
Array.init (Array.length tbl) branch
-let get_proj env ((mind, _n), i) =
+let get_proj env ((mind, n), i) =
let mib = Environ.lookup_mind mind env in
match mib.mind_record with
- | None | Some None ->
+ | NotRecord | FakeRecord ->
CErrors.anomaly (Pp.strbrk "Return type is not a primitive record")
- | Some (Some (_, projs, _)) ->
+ | PrimRecord info ->
+ let _, projs, _ = info.(n) in
Projection.make projs.(i) true
let rec nf_val env sigma v typ =
@@ -316,9 +314,9 @@ and nf_atom_type env sigma atom =
let pT =
hnf_prod_applist_assum env nparamdecls
(Inductiveops.type_of_inductive env ind) (Array.to_list params) in
- let dep, p = nf_predicate env sigma ind mip params p pT in
+ let p = nf_predicate env sigma ind mip params p pT in
(* Calcul du type des branches *)
- let btypes = build_branches_type env sigma (fst ind) mib mip u params dep p in
+ let btypes = build_branches_type env sigma (fst ind) mib mip u params p in
(* calcul des branches *)
let bsw = branch_of_switch (nb_rel env) ans bs in
let mkbranch i v =
@@ -327,7 +325,7 @@ and nf_atom_type env sigma atom =
Termops.it_mkLambda_or_LetIn_from_no_LetIn b decl_with_letin
in
let branchs = Array.mapi mkbranch bsw in
- let tcase = build_case_type dep p realargs a in
+ let tcase = build_case_type p realargs a in
let ci = ans.asw_ci in
mkCase(ci, p, a, branchs), tcase
| Afix(tt,ft,rp,s) ->
@@ -374,18 +372,18 @@ and nf_atom_type env sigma atom =
and nf_predicate env sigma ind mip params v pT =
match kind (whd_allnolet env pT) with
| LetIn (name,b,t,pT) ->
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalDef (name,b,t)) env) sigma ind mip params v pT in
- dep, mkLetIn (name,b,t,body)
+ mkLetIn (name,b,t,body)
| Prod (name,dom,codom) -> begin
match kind_of_value v with
| Vfun f ->
let k = nb_rel env in
let vb = f (mk_rel_accu k) in
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
- dep, mkLambda(name,dom,body)
- | _ -> false, nf_type env sigma v
+ mkLambda(name,dom,body)
+ | _ -> nf_type env sigma v
end
| _ ->
match kind_of_value v with
@@ -398,8 +396,8 @@ and nf_predicate env sigma ind mip params v pT =
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
let body = nf_type (push_rel (LocalAssum (name,dom)) env) sigma vb in
- true, mkLambda(name,dom,body)
- | _ -> false, nf_type env sigma v
+ mkLambda(name,dom,body)
+ | _ -> nf_type env sigma v
and nf_evar env sigma evk ty args =
let evi = try Evd.find sigma evk with Not_found -> assert false in
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 622a8e982..685aa400b 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -150,8 +150,8 @@ let pattern_of_constr env sigma t =
| Rel n -> PRel n
| Meta n -> PMeta (Some (Id.of_string ("META" ^ string_of_int n)))
| Var id -> PVar id
- | Sort (Prop Null) -> PSort GProp
- | Sort (Prop Pos) -> PSort GSet
+ | Sort Prop -> PSort GProp
+ | Sort Set -> PSort GSet
| Sort (Type _) -> PSort (GType [])
| Cast (c,_,_) -> pattern_of_constr env c
| LetIn (na,c,t,b) -> PLetIn (na,pattern_of_constr env c,Some (pattern_of_constr env t),
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index 746a68b21..7e43c5e41 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -149,18 +149,13 @@ let retype ?(polyprop=true) sigma =
| Cast (c,_, s) when isSort sigma s -> destSort sigma s
| Sort s ->
begin match ESorts.kind sigma s with
- | Prop _ -> Sorts.type1
+ | Prop | Set -> Sorts.type1
| Type u -> Type (Univ.super u)
end
| Prod (name,t,c2) ->
- (match (sort_of env t, sort_of (push_rel (LocalAssum (name,t)) env) c2) with
- | _, (Prop Null as s) -> s
- | Prop _, (Prop Pos as s) -> s
- | Type _, (Prop Pos as s) when is_impredicative_set env -> s
- | Type u1, Prop Pos -> Type (Univ.sup u1 Univ.type0_univ)
- | Prop Pos, (Type u2) -> Type (Univ.sup Univ.type0_univ u2)
- | Prop Null, (Type _ as s) -> s
- | Type u1, Type u2 -> Type (Univ.sup u1 u2))
+ let dom = sort_of env t in
+ let rang = sort_of (push_rel (LocalAssum (name,t)) env) c2 in
+ Typeops.sort_of_product env dom rang
| App(f,args) when is_template_polymorphic env sigma f ->
let t = type_of_global_reference_knowing_parameters env f args in
sort_of_atomic_type env sigma t args
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index d3aa7ac64..efb3c339a 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -74,10 +74,10 @@ type typeclass = {
cl_impl : GlobRef.t;
(* Context in which the definitions are typed. Includes both typeclass parameters and superclasses. *)
- cl_context : GlobRef.t option list * Context.Rel.t;
+ cl_context : GlobRef.t option list * Constr.rel_context;
(* Context of definitions and properties on defs, will not be shared *)
- cl_props : Context.Rel.t;
+ cl_props : Constr.rel_context;
(* The method implementaions as projections. *)
cl_projs : (Name.t * (direction * hint_info) option
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index e4a56960c..80c6d8239 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -35,10 +35,10 @@ type typeclass = {
(** Context in which the definitions are typed. Includes both typeclass parameters and superclasses.
The global reference gives a direct link to the class itself. *)
- cl_context : GlobRef.t option list * Context.Rel.t;
+ cl_context : GlobRef.t option list * Constr.rel_context;
(** Context of definitions and properties on defs, will not be shared *)
- cl_props : Context.Rel.t;
+ cl_props : Constr.rel_context;
(** The methods implementations of the typeclass as projections.
Some may be undefinable due to sorting restrictions or simply undefined if
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index cf34ac016..ca2702d74 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -138,7 +138,7 @@ let is_correct_arity env sigma c pj ind specif params =
then error ()
else sigma
| Evar (ev,_), [] ->
- let sigma, s = Evd.fresh_sort_in_family env sigma (max_sort allowed_sorts) in
+ let sigma, s = Evd.fresh_sort_in_family sigma (max_sort allowed_sorts) in
let sigma = Evd.define ev (mkSort s) sigma in
sigma
| _, (LocalDef _ as d)::ar' ->
@@ -241,10 +241,6 @@ let judge_of_set =
{ uj_val = EConstr.mkSet;
uj_type = EConstr.mkSort Sorts.type1 }
-let judge_of_prop_contents = function
- | Null -> judge_of_prop
- | Pos -> judge_of_set
-
let judge_of_type u =
let uu = Univ.Universe.super u in
{ uj_val = EConstr.mkType u;
@@ -333,10 +329,9 @@ let rec execute env sigma cstr =
| Sort s ->
begin match ESorts.kind sigma s with
- | Prop c ->
- sigma, judge_of_prop_contents c
- | Type u ->
- sigma, judge_of_type u
+ | Prop -> sigma, judge_of_prop
+ | Set -> sigma, judge_of_set
+ | Type u -> sigma, judge_of_type u
end
| Proj (p, c) ->
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 5cf6e4b26..4ba5d2794 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -656,10 +656,12 @@ let rec is_neutral env sigma ts t =
let is_eta_constructor_app env sigma ts f l1 term =
match EConstr.kind sigma f with
- | Construct (((_, i as ind), j), u) when i == 0 && j == 1 ->
+ | Construct (((_, i as ind), j), u) when j == 1 ->
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
(match mib.Declarations.mind_record with
- | Some (Some (_,exp,projs)) when mib.Declarations.mind_finite == Declarations.BiFinite &&
+ | PrimRecord info when mib.Declarations.mind_finite == Declarations.BiFinite &&
+ let (_, projs, _) = info.(i) in
Array.length projs == Array.length l1 - mib.Declarations.mind_nparams ->
(** Check that the other term is neutral *)
is_neutral env sigma ts term
@@ -667,11 +669,13 @@ let is_eta_constructor_app env sigma ts f l1 term =
| _ -> false
let eta_constructor_app env sigma f l1 term =
+ let open Declarations in
match EConstr.kind sigma f with
| Construct (((_, i as ind), j), u) ->
let mib = lookup_mind (fst ind) env in
(match mib.Declarations.mind_record with
- | Some (Some (_, projs, _)) ->
+ | PrimRecord info ->
+ let (_, projs, _) = info.(i) in
let npars = mib.Declarations.mind_nparams in
let pars, l1' = Array.chop npars l1 in
let arg = Array.append pars [|term|] in
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 14c9f49b1..440076c16 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -79,7 +79,7 @@ let construct_of_constr const env tag typ =
(* spiwack : here be a branch for specific decompilation handled by retroknowledge *)
try
if const then
- ((retroknowledge Retroknowledge.get_vm_decompile_constant_info env (mkIndU indu) tag),
+ ((Retroknowledge.get_vm_decompile_constant_info env.retroknowledge (mkIndU indu) tag),
typ) (*spiwack: this may need to be changed in case there are parameters in the
type which may cause a constant value to have an arity.
(type_constructor seems to be all about parameters actually)
@@ -103,7 +103,7 @@ let construct_of_constr_block = construct_of_constr false
let type_of_ind env (ind, u) =
type_of_inductive env (Inductive.lookup_mind_specif env ind, u)
-let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
+let build_branches_type env sigma (mind,_ as _ind) mib mip u params p =
let rtbl = mip.mind_reloc_tbl in
(* [build_one_branch i cty] construit le type de la ieme branche (commence
a 0) et les lambda correspondant aux realargs *)
@@ -120,20 +120,17 @@ let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
let codom =
let ndecl = List.length decl in
let papp = mkApp(lift ndecl p,crealargs) in
- if dep then
- let cstr = ith_constructor_of_inductive ind (i+1) in
- let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
- let params = Array.map (lift ndecl) params in
- let dep_cstr = mkApp(mkApp(mkConstructU (cstr,u),params),relargs) in
- mkApp(papp,[|dep_cstr|])
- else papp
+ let cstr = ith_constructor_of_inductive ind (i+1) in
+ let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
+ let params = Array.map (lift ndecl) params in
+ let dep_cstr = mkApp(mkApp(mkConstructU (cstr,u),params),relargs) in
+ mkApp(papp,[|dep_cstr|])
in
decl, decl_with_letin, codom
in Array.mapi build_one_branch mip.mind_nf_lc
-let build_case_type dep p realargs c =
- if dep then mkApp(mkApp(p, realargs), [|c|])
- else mkApp(p, realargs)
+let build_case_type p realargs c =
+ mkApp(mkApp(p, realargs), [|c|])
(* La fonction de normalisation *)
@@ -266,9 +263,9 @@ and nf_stk ?from:(from=0) env sigma c t stk =
let nparamdecls = Context.Rel.length (Inductive.inductive_paramdecls (mib,u)) in
let pT =
hnf_prod_applist_assum env nparamdecls (type_of_ind env (ind,u)) (Array.to_list params) in
- let dep, p = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
+ let p = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
(* Calcul du type des branches *)
- let btypes = build_branches_type env sigma ind mib mip u params dep p in
+ let btypes = build_branches_type env sigma ind mib mip u params p in
(* calcul des branches *)
let bsw = branch_of_switch (nb_rel env) sw in
let mkbranch i (n,v) =
@@ -277,7 +274,7 @@ and nf_stk ?from:(from=0) env sigma c t stk =
Termops.it_mkLambda_or_LetIn_from_no_LetIn b decl_with_letin
in
let branchs = Array.mapi mkbranch bsw in
- let tcase = build_case_type dep p realargs c in
+ let tcase = build_case_type p realargs c in
let ci = sw.sw_annot.Cbytecodes.ci in
nf_stk env sigma (mkCase(ci, p, c, branchs)) tcase stk
| Zproj p :: stk ->
@@ -289,17 +286,17 @@ and nf_stk ?from:(from=0) env sigma c t stk =
and nf_predicate env sigma ind mip params v pT =
match kind (whd_allnolet env pT) with
| LetIn (name,b,t,pT) ->
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalDef (name,b,t)) env) sigma ind mip params v pT in
- dep, mkLetIn (name,b,t,body)
+ mkLetIn (name,b,t,body)
| Prod (name,dom,codom) -> begin
match whd_val v with
| Vfun f ->
let k = nb_rel env in
let vb = reduce_fun k f in
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
- dep, mkLambda(name,dom,body)
+ mkLambda(name,dom,body)
| _ -> assert false
end
| _ ->
@@ -313,8 +310,8 @@ and nf_predicate env sigma ind mip params v pT =
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
let body = nf_vtype (push_rel (LocalAssum (name,dom)) env) sigma vb in
- true, mkLambda(name,dom,body)
- | _ -> false, nf_val env sigma v crazy_type
+ mkLambda(name,dom,body)
+ | _ -> nf_val env sigma v crazy_type
and nf_args env sigma vargs ?from:(f=0) t =
let t = ref t in
diff --git a/printing/pputils.ml b/printing/pputils.ml
index c6b8d5022..59e5f68f2 100644
--- a/printing/pputils.ml
+++ b/printing/pputils.ml
@@ -68,7 +68,7 @@ let pr_short_red_flag pr r =
let pr_red_flag pr r =
try pr_short_red_flag pr r
- with complexRedFlags ->
+ with ComplexRedFlag ->
(if r.rBeta then pr_arg str "beta" else mt ()) ++
(if r.rMatch && r.rFix && r.rCofix then pr_arg str "iota" else
(if r.rMatch then pr_arg str "match" else mt ()) ++
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 5e5d00362..fd7135b6a 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -40,7 +40,7 @@ type object_pr = {
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
print_modtype : ModPath.t -> Pp.t;
- print_named_decl : env -> Evd.evar_map -> Context.Named.Declaration.t -> Pp.t;
+ print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
print_library_entry : env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
print_context : env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
@@ -246,13 +246,13 @@ let print_type_in_type ref =
else []
let print_primitive_record recflag mipv = function
- | Some (Some (_, ps,_)) ->
+ | PrimRecord _ ->
let eta = match recflag with
| CoFinite | Finite -> str" without eta conversion"
| BiFinite -> str " with eta conversion"
in
[Id.print mipv.(0).mind_typename ++ str" has primitive projections" ++ eta ++ str"."]
- | _ -> []
+ | FakeRecord | NotRecord -> []
let print_primitive ref =
match ref with
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 8dd729610..1668bce29 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -89,7 +89,7 @@ type object_pr = {
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
print_modtype : ModPath.t -> Pp.t;
- print_named_decl : env -> Evd.evar_map -> Context.Named.Declaration.t -> Pp.t;
+ print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
print_library_entry : env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
print_context : env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
diff --git a/printing/printer.ml b/printing/printer.ml
index d76bd1e2b..92224c992 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -852,7 +852,7 @@ type axiom =
type context_object =
| Variable of Id.t (* A section variable or a Let definition *)
- | Axiom of axiom * (Label.t * Context.Rel.t * types) list
+ | Axiom of axiom * (Label.t * Constr.rel_context * types) list
| Opaque of Constant.t (* An opaque constant. *)
| Transparent of Constant.t
diff --git a/printing/printer.mli b/printing/printer.mli
index 7a8b963d2..eddfef6fa 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -152,13 +152,13 @@ val get_compact_context : unit -> bool
val pr_context_unlimited : env -> evar_map -> Pp.t
val pr_ne_context_of : Pp.t -> env -> evar_map -> Pp.t
-val pr_named_decl : env -> evar_map -> Context.Named.Declaration.t -> Pp.t
-val pr_compacted_decl : env -> evar_map -> Context.Compacted.Declaration.t -> Pp.t
-val pr_rel_decl : env -> evar_map -> Context.Rel.Declaration.t -> Pp.t
+val pr_named_decl : env -> evar_map -> Constr.named_declaration -> Pp.t
+val pr_compacted_decl : env -> evar_map -> Constr.compacted_declaration -> Pp.t
+val pr_rel_decl : env -> evar_map -> Constr.rel_declaration -> Pp.t
-val pr_named_context : env -> evar_map -> Context.Named.t -> Pp.t
+val pr_named_context : env -> evar_map -> Constr.named_context -> Pp.t
val pr_named_context_of : env -> evar_map -> Pp.t
-val pr_rel_context : env -> evar_map -> Context.Rel.t -> Pp.t
+val pr_rel_context : env -> evar_map -> Constr.rel_context -> Pp.t
val pr_rel_context_of : env -> evar_map -> Pp.t
val pr_context_of : env -> evar_map -> Pp.t
@@ -210,7 +210,7 @@ type axiom =
type context_object =
| Variable of Id.t (* A section variable or a Let definition *)
- | Axiom of axiom * (Label.t * Context.Rel.t * types) list
+ | Axiom of axiom * (Label.t * Constr.rel_context * types) list
| Opaque of Constant.t (* An opaque constant. *)
| Transparent of Constant.t
diff --git a/printing/printmod.ml b/printing/printmod.ml
index be8bc1357..3f95dcfb6 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -217,7 +217,7 @@ let print_record env mind mib udecl =
)
let pr_mutual_inductive_body env mind mib udecl =
- if mib.mind_record <> None && not !Flags.raw_print then
+ if mib.mind_record != NotRecord && not !Flags.raw_print then
print_record env mind mib udecl
else
print_mutual_inductive env mind mib udecl
diff --git a/proofs/pfedit.mli b/proofs/pfedit.mli
index 7b7973224..e02b5ab95 100644
--- a/proofs/pfedit.mli
+++ b/proofs/pfedit.mli
@@ -85,6 +85,9 @@ val solve : ?with_end_tac:unit Proofview.tactic ->
val by : unit Proofview.tactic -> bool
+(** Option telling if unification heuristics should be used. *)
+val use_unification_heuristics : unit -> bool
+
(** [instantiate_nth_evar_com n c] instantiate the [n]th undefined
existential variable of the current focused proof by [c] or raises a
UserError if no proof is focused or if there is no such [n]th
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index 3120c97b5..7e250faa8 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -93,7 +93,7 @@ type pstate = {
pid : Id.t; (* the name of the theorem whose proof is being constructed *)
terminator : proof_terminator CEphemeron.key;
endline_tactic : Genarg.glob_generic_argument option;
- section_vars : Context.Named.t option;
+ section_vars : Constr.named_context option;
proof : Proof.t;
strength : Decl_kinds.goal_kind;
mode : proof_mode CEphemeron.key;
@@ -348,9 +348,8 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
not (Safe_typing.empty_private_constants = eff))
in
let typ = if allow_deferred then t else nf t in
- let env = Global.env () in
- let used_univs_body = Univops.universes_of_constr env body in
- let used_univs_typ = Univops.universes_of_constr env typ in
+ let used_univs_body = Univops.universes_of_constr body in
+ let used_univs_typ = Univops.universes_of_constr typ in
if allow_deferred then
let initunivs = UState.const_univ_entry ~poly initial_euctx in
let ctx = constrain_variables universes in
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index 9e07ed2d0..854ceaa41 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -126,8 +126,8 @@ val set_endline_tactic : Genarg.glob_generic_argument -> unit
* (w.r.t. type dependencies and let-ins covered by it) + a list of
* ids to be cleared *)
val set_used_variables :
- Names.Id.t list -> Context.Named.t * Names.lident list
-val get_used_variables : unit -> Context.Named.t option
+ Names.Id.t list -> Constr.named_context * Names.lident list
+val get_used_variables : unit -> Constr.named_context option
(** Get the universe declaration associated to the current proof. *)
val get_universe_decl : unit -> UState.universe_decl
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 000000000..3201c5050
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,4 @@
+# Some developers don't want a pinned nix-shell by default.
+# If you want to use the pin nix-shell or a more sophisticated set of arguments:
+# $ nix-shell default.nix --arg shell true
+import ./default.nix { pkgs = import <nixpkgs> {}; shell = true; }
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 773fc1520..9c5fdcd1c 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -477,7 +477,7 @@ let is_Prop env sigma concl =
match EConstr.kind sigma ty with
| Sort s ->
begin match ESorts.kind sigma s with
- | Prop Null -> true
+ | Prop -> true
| _ -> false
end
| _ -> false
diff --git a/tactics/elimschemes.ml b/tactics/elimschemes.ml
index 70f73df5c..3b69d9922 100644
--- a/tactics/elimschemes.ml
+++ b/tactics/elimschemes.ml
@@ -44,7 +44,7 @@ let optimize_non_type_induction_scheme kind dep sort _ ind =
mib.mind_nparams_rec
else
mib.mind_nparams in
- let sigma, sort = Evd.fresh_sort_in_family env sigma sort in
+ let sigma, sort = Evd.fresh_sort_in_family sigma sort in
let sigma, t', c' = weaken_sort_scheme env sigma false sort npars c t in
let sigma = Evd.minimize_universes sigma in
(Evarutil.nf_evars_universes sigma c', Evd.evar_universe_context sigma), eff
diff --git a/tactics/eqschemes.ml b/tactics/eqschemes.ml
index ad5239116..ea5ff4a6c 100644
--- a/tactics/eqschemes.ml
+++ b/tactics/eqschemes.ml
@@ -397,7 +397,7 @@ let build_l2r_rew_scheme dep env ind kind =
rel_vect (nrealargs+4) nrealargs;
rel_vect 1 nrealargs;
[|mkRel 1|]]) in
- let s, ctx' = UnivGen.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
@@ -500,7 +500,7 @@ let build_l2r_forward_rew_scheme dep env ind kind =
name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let realsign_ind_P n aP =
name_context env ((LocalAssum (Name varH,aP))::realsign_P n) in
- let s, ctx' = UnivGen.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
@@ -578,7 +578,7 @@ let build_r2l_forward_rew_scheme dep env ind kind =
let applied_ind = build_dependent_inductive indu specif in
let realsign_ind =
name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
- let s, ctx' = UnivGen.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 91c577405..0e3921570 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -942,7 +942,7 @@ let rec build_discriminator env sigma true_0 false_0 dirn c = function
let (cnum_nlams,cnum_env,kont) = descend_then env sigma c cnum in
let newc = mkRel(cnum_nlams-argnum) in
let subval = build_discriminator cnum_env sigma true_0 false_0 dirn newc l in
- kont sigma subval (false_0,mkSort (Prop Null))
+ kont sigma subval (false_0,mkProp)
(* Note: discrimination could be more clever: if some elimination is
not allowed because of a large impredicative constructor in the
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 85ff02824..748e0362c 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -165,12 +165,17 @@ type hint_mode =
| ModeNoHeadEvar (* No evar at the head *)
| ModeOutput (* Anything *)
+type 'a hints_transparency_target =
+ | HintsVariables
+ | HintsConstants
+ | HintsReferences of 'a list
+
type hints_expr =
| HintsResolve of (hint_info_expr * bool * reference_or_constr) list
| HintsResolveIFF of bool * qualid list * int option
| HintsImmediate of reference_or_constr list
| HintsUnfold of qualid list
- | HintsTransparency of qualid list * bool
+ | HintsTransparency of qualid hints_transparency_target * bool
| HintsMode of qualid * hint_mode list
| HintsConstructors of qualid list
| HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
@@ -828,38 +833,48 @@ let make_exact_entry env sigma info poly ?(name=PathAny) (c, cty, ctx) =
let make_apply_entry env sigma (eapply,hnf,verbose) info poly ?(name=PathAny) (c, cty, ctx) =
let cty = if hnf then hnf_constr env sigma cty else cty in
- match EConstr.kind sigma cty with
- | Prod _ ->
- let sigma' = Evd.merge_context_set univ_flexible sigma ctx in
- let ce = mk_clenv_from_env env sigma' None (c,cty) in
- let c' = clenv_type (* ~reduce:false *) ce in
- let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr ~abort_on_undefined_evars:false sigma c') in
- let hd =
- try head_pattern_bound pat
- with BoundPattern -> failwith "make_apply_entry" in
- let nmiss = List.length (clenv_missing ce) in
- let secvars = secvars_of_constr env sigma c in
- let pri = match info.hint_priority with None -> nb_hyp sigma' cty + nmiss | Some p -> p in
- let pat = match info.hint_pattern with
- | Some p -> snd p | None -> pat
- in
- if Int.equal nmiss 0 then
- (Some hd,
- { pri; poly; pat = Some pat; name;
- db = None;
- secvars;
- code = with_uid (Res_pf(c,cty,ctx)); })
- else begin
- if not eapply then failwith "make_apply_entry";
- if verbose then
- Feedback.msg_info (str "the hint: eapply " ++ pr_leconstr_env env sigma' c ++
- str " will only be used by eauto");
- (Some hd,
- { pri; poly; pat = Some pat; name;
- db = None; secvars;
- code = with_uid (ERes_pf(c,cty,ctx)); })
- end
- | _ -> failwith "make_apply_entry"
+ match EConstr.kind sigma cty with
+ | Prod _ ->
+ let sigma' = Evd.merge_context_set univ_flexible sigma ctx in
+ let ce = mk_clenv_from_env env sigma' None (c,cty) in
+ let c' = clenv_type (* ~reduce:false *) ce in
+ let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr ~abort_on_undefined_evars:false sigma c') in
+ let hd =
+ try head_pattern_bound pat
+ with BoundPattern -> failwith "make_apply_entry" in
+ let miss = clenv_missing ce in
+ let nmiss = List.length miss in
+ let secvars = secvars_of_constr env sigma c in
+ let pri = match info.hint_priority with None -> nb_hyp sigma' cty + nmiss | Some p -> p in
+ let pat = match info.hint_pattern with
+ | Some p -> snd p | None -> pat
+ in
+ if Int.equal nmiss 0 then
+ (Some hd,
+ { pri; poly; pat = Some pat; name;
+ db = None;
+ secvars;
+ code = with_uid (Res_pf(c,cty,ctx)); })
+ else begin
+ if not eapply then failwith "make_apply_entry";
+ if verbose then begin
+ let variables = str (CString.plural nmiss "variable") in
+ Feedback.msg_info (
+ strbrk "The hint " ++
+ pr_leconstr_env env sigma' c ++
+ strbrk " will only be used by eauto, because applying " ++
+ pr_leconstr_env env sigma' c ++
+ strbrk " would leave " ++ variables ++ Pp.spc () ++
+ Pp.prlist_with_sep Pp.pr_comma Name.print (List.map (Evd.meta_name ce.evd) miss) ++
+ strbrk " as unresolved existential " ++ variables ++ str "."
+ )
+ end;
+ (Some hd,
+ { pri; poly; pat = Some pat; name;
+ db = None; secvars;
+ code = with_uid (ERes_pf(c,cty,ctx)); })
+ end
+ | _ -> failwith "make_apply_entry"
(* flags is (e,h,v) with e=true if eapply and h=true if hnf and v=true if verbose
c is a constr
@@ -1014,15 +1029,19 @@ let add_hint dbname hintlist =
let db' = Hint_db.add_list env sigma hintlist db in
searchtable_add (dbname,db')
-let add_transparency dbname grs b =
+let add_transparency dbname target b =
let db = get_db dbname in
- let st = Hint_db.transparent_state db in
+ let (ids, csts as st) = Hint_db.transparent_state db in
let st' =
- List.fold_left (fun (ids, csts) gr ->
- match gr with
- | EvalConstRef c -> (ids, (if b then Cpred.add else Cpred.remove) c csts)
- | EvalVarRef v -> (if b then Id.Pred.add else Id.Pred.remove) v ids, csts)
- st grs
+ match target with
+ | HintsVariables -> (if b then Id.Pred.full else Id.Pred.empty), csts
+ | HintsConstants -> ids, if b then Cpred.full else Cpred.empty
+ | HintsReferences grs ->
+ List.fold_left (fun (ids, csts) gr ->
+ match gr with
+ | EvalConstRef c -> (ids, (if b then Cpred.add else Cpred.remove) c csts)
+ | EvalVarRef v -> (if b then Id.Pred.add else Id.Pred.remove) v ids, csts)
+ st grs
in searchtable_add (dbname, Hint_db.set_transparent_state db st')
let remove_hint dbname grs =
@@ -1032,7 +1051,7 @@ let remove_hint dbname grs =
type hint_action =
| CreateDB of bool * transparent_state
- | AddTransparency of evaluable_global_reference list * bool
+ | AddTransparency of evaluable_global_reference hints_transparency_target * bool
| AddHints of hint_entry list
| RemoveHints of GlobRef.t list
| AddCut of hints_path
@@ -1122,9 +1141,17 @@ let subst_autohint (subst, obj) =
in
let action = match obj.hint_action with
| CreateDB _ -> obj.hint_action
- | AddTransparency (grs, b) ->
- let grs' = List.Smart.map (subst_evaluable_reference subst) grs in
- if grs == grs' then obj.hint_action else AddTransparency (grs', b)
+ | AddTransparency (target, b) ->
+ let target' =
+ match target with
+ | HintsVariables -> target
+ | HintsConstants -> target
+ | HintsReferences grs ->
+ let grs' = List.Smart.map (subst_evaluable_reference subst) grs in
+ if grs == grs' then target
+ else HintsReferences grs'
+ in
+ if target' == target then obj.hint_action else AddTransparency (target', b)
| AddHints hintlist ->
let hintlist' = List.Smart.map subst_hint hintlist in
if hintlist' == hintlist then obj.hint_action else AddHints hintlist'
@@ -1244,7 +1271,7 @@ type hints_entry =
| HintsImmediateEntry of (hints_path_atom * polymorphic * hint_term) list
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
- | HintsTransparencyEntry of evaluable_global_reference list * bool
+ | HintsTransparencyEntry of evaluable_global_reference hints_transparency_target * bool
| HintsModeEntry of GlobRef.t * hint_mode list
| HintsExternEntry of hint_info * Genarg.glob_generic_argument
@@ -1347,14 +1374,19 @@ let interp_hints poly =
let info = { info with hint_pattern = Option.map fp info.hint_pattern } in
(info, poly, b, path, gr)
in
+ let ft = function
+ | HintsVariables -> HintsVariables
+ | HintsConstants -> HintsConstants
+ | HintsReferences lhints -> HintsReferences (List.map fr lhints)
+ in
+ let fp = Constrintern.intern_constr_pattern (Global.env()) in
match h with
| HintsResolve lhints -> HintsResolveEntry (List.map fres lhints)
| HintsResolveIFF (l2r, lc, n) ->
HintsResolveEntry (List.map (project_hint ~poly n l2r) lc)
| HintsImmediate lhints -> HintsImmediateEntry (List.map fi lhints)
| HintsUnfold lhints -> HintsUnfoldEntry (List.map fr lhints)
- | HintsTransparency (lhints, b) ->
- HintsTransparencyEntry (List.map fr lhints, b)
+ | HintsTransparency (t, b) -> HintsTransparencyEntry (ft t, b)
| HintsMode (r, l) -> HintsModeEntry (fref r, l)
| HintsConstructors lqid ->
let constr_hints_of_ind qid =
@@ -1369,7 +1401,7 @@ let interp_hints poly =
PathHints [gr], IsGlobRef gr)
in HintsResolveEntry (List.flatten (List.map constr_hints_of_ind lqid))
| HintsExtern (pri, patcom, tacexp) ->
- let pat = Option.map fp patcom in
+ let pat = Option.map (fp sigma) patcom in
let l = match pat with None -> [] | Some (l, _) -> l in
let ltacvars = List.fold_left (fun accu x -> Id.Set.add x accu) Id.Set.empty l in
let env = Genintern.({ (empty_glob_sign env) with ltacvars }) in
diff --git a/tactics/hints.mli b/tactics/hints.mli
index ca18f835a..9bf6c175a 100644
--- a/tactics/hints.mli
+++ b/tactics/hints.mli
@@ -81,12 +81,17 @@ type hint_mode =
| ModeNoHeadEvar (* No evar at the head *)
| ModeOutput (* Anything *)
+type 'a hints_transparency_target =
+ | HintsVariables
+ | HintsConstants
+ | HintsReferences of 'a list
+
type hints_expr =
| HintsResolve of (hint_info_expr * bool * reference_or_constr) list
| HintsResolveIFF of bool * Libnames.qualid list * int option
| HintsImmediate of reference_or_constr list
| HintsUnfold of Libnames.qualid list
- | HintsTransparency of Libnames.qualid list * bool
+ | HintsTransparency of Libnames.qualid hints_transparency_target * bool
| HintsMode of Libnames.qualid * hint_mode list
| HintsConstructors of Libnames.qualid list
| HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
@@ -173,7 +178,7 @@ type hints_entry =
| HintsImmediateEntry of (hints_path_atom * polymorphic * hint_term) list
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
- | HintsTransparencyEntry of evaluable_global_reference list * bool
+ | HintsTransparencyEntry of evaluable_global_reference hints_transparency_target * bool
| HintsModeEntry of GlobRef.t * hint_mode list
| HintsExternEntry of hint_info * Genarg.glob_generic_argument
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 755494c2d..43786c8e1 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -94,7 +94,7 @@ let make_inv_predicate env evd indf realargs id status concl =
| Some concl -> concl (*assumed it's some [x1..xn,H:I(x1..xn)]C*)
| None ->
let sort = get_sort_family_of env !evd concl in
- let sort = Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd sort in
+ let sort = Evarutil.evd_comb1 Evd.fresh_sort_in_family evd sort in
let p = make_arity env !evd true indf sort in
let evd',(p,ptyp) = Unification.abstract_list_all env
!evd p concl (realargs@[mkVar id])
@@ -495,7 +495,7 @@ let raw_inversion inv_kind id status names =
(* Error messages of the inversion tactics *)
let wrap_inv_error id = function (e, info) -> match e with
| Indrec.RecursionSchemeError
- (Indrec.NotAllowedCaseAnalysis (_,(Type _ | Prop Pos as k),i)) ->
+ (Indrec.NotAllowedCaseAnalysis (_,(Type _ | Set as k),i)) ->
Proofview.tclENV >>= fun env ->
Proofview.tclEVARMAP >>= fun sigma ->
tclZEROMSG (
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index 10937322e..caf4c1eca 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -251,7 +251,7 @@ let add_inversion_lemma_exn ~poly na com comsort bool tac =
let env = Global.env () 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
+ let sigma, sort = Evd.fresh_sort_in_family ~rigid:univ_rigid sigma comsort in
try
add_inversion_lemma ~poly na env sigma c sort bool tac
with
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index f34c83ae7..837865e64 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -753,8 +753,8 @@ module New = struct
let (ind,t) = pf_reduce_to_quantified_ind gl (pf_unsafe_type_of gl c) in
let isrec,mkelim =
match (Global.lookup_mind (fst (fst ind))).mind_record with
- | None -> true,gl_make_elim
- | Some _ -> false,gl_make_case_dep
+ | NotRecord -> true,gl_make_elim
+ | FakeRecord | PrimRecord _ -> false,gl_make_case_dep
in
general_elim_then_using mkelim isrec None tac None ind (c, t)
end
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index c430edf2e..928530744 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -212,6 +212,9 @@ let clear_dependency_msg env sigma id err inglobal =
str "Cannot remove " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
+ | Evarutil.NoCandidatesLeft ev ->
+ str "Cannot remove " ++ Id.print id ++ str " as it would leave the existential " ++
+ Printer.pr_existential_key sigma ev ++ str" without candidates."
let error_clear_dependency env sigma id err inglobal =
user_err (clear_dependency_msg env sigma id err inglobal)
@@ -228,6 +231,9 @@ let replacing_dependency_msg env sigma id err inglobal =
str "Cannot change " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
+ | Evarutil.NoCandidatesLeft ev ->
+ str "Cannot change " ++ Id.print id ++ str " as it would leave the existential " ++
+ Printer.pr_existential_key sigma ev ++ str" without candidates."
let error_replacing_dependency env sigma id err inglobal =
user_err (replacing_dependency_msg env sigma id err inglobal)
diff --git a/test-suite/Makefile b/test-suite/Makefile
index 32e245e36..33b402327 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -519,6 +519,7 @@ $(patsubst %.sh,%.log,$(wildcard misc/*.sh)): %.log: %.sh $(PREREQUISITELOG)
@echo "TEST $<"
$(HIDE){ \
echo $(call log_intro,$<); \
+ export BIN="$(BIN)"; \
export coqc="$(coqc)"; \
export coqtop="$(coqtop)"; \
export coqdep="$(coqdep)"; \
diff --git a/test-suite/bugs/closed/5012.v b/test-suite/bugs/closed/5012.v
new file mode 100644
index 000000000..5326c0fbb
--- /dev/null
+++ b/test-suite/bugs/closed/5012.v
@@ -0,0 +1,17 @@
+Class Foo := { foo : Set }.
+
+Axiom admit : forall {T}, T.
+
+Global Instance Foo0 : Foo
+ := {| foo := admit |}.
+
+Global Instance Foo1 : Foo
+ := { foo := admit }.
+
+Existing Class Foo.
+
+Global Instance Foo2 : Foo
+ := { foo := admit }. (* Error: Unbound method name foo of class Foo. *)
+
+Set Warnings "+already-existing-class".
+Fail Existing Class Foo.
diff --git a/test-suite/bugs/closed/5696.v b/test-suite/bugs/closed/5696.v
new file mode 100644
index 000000000..a20ad1b4d
--- /dev/null
+++ b/test-suite/bugs/closed/5696.v
@@ -0,0 +1,5 @@
+(* Slightly improving interpretation of Ltac subterms in notations *)
+
+Notation "'var2' x .. y = z ; e" := (ltac:(exact z), (fun x => .. (fun y => e)
+..)) (at level 200, x binder, y binder, e at level 220).
+Check (var2 a = 1; a).
diff --git a/test-suite/bugs/closed/7695.v b/test-suite/bugs/closed/7695.v
new file mode 100644
index 000000000..42bdb076b
--- /dev/null
+++ b/test-suite/bugs/closed/7695.v
@@ -0,0 +1,20 @@
+Require Import Hurkens.
+
+Universes i j k.
+Module Type T.
+ Parameter T1 : Type@{i+1}.
+ Parameter e : Type@{j} = T1 : Type@{k}.
+End T.
+
+Module M.
+ Definition T1 := Type@{j}.
+ Definition e : Type@{j} = T1 : Type@{k} := eq_refl.
+End M.
+
+Module F (A:T).
+ Definition bad := TypeNeqSmallType.paradox _ A.e.
+End F.
+
+Set Printing Universes.
+Fail Module X := F M.
+(* Universe inconsistency. Cannot enforce j <= i because i < Coq.Logic.Hurkens.105 = j. *)
diff --git a/test-suite/bugs/closed/7712.v b/test-suite/bugs/closed/7712.v
new file mode 100644
index 000000000..a4e9697fa
--- /dev/null
+++ b/test-suite/bugs/closed/7712.v
@@ -0,0 +1,4 @@
+(* This used to raise an anomaly *)
+
+Fail Reserved Notation "'[tele_arg' x ';' .. ';' z ]"
+ (format "[tele_arg '[hv' x .. z ']' ]").
diff --git a/test-suite/bugs/closed/7723.v b/test-suite/bugs/closed/7723.v
new file mode 100644
index 000000000..216290123
--- /dev/null
+++ b/test-suite/bugs/closed/7723.v
@@ -0,0 +1,58 @@
+Set Universe Polymorphism.
+
+Module Segfault.
+
+Inductive decision_tree : Type := .
+
+Fixpoint first_satisfying_helper {A B} (f : A -> option B) (ls : list A) : option B
+ := match ls with
+ | nil => None
+ | cons x xs
+ => match f x with
+ | Some v => Some v
+ | None => first_satisfying_helper f xs
+ end
+ end.
+
+Axiom admit : forall {T}, T.
+Definition dtree4 : option decision_tree :=
+ match first_satisfying_helper (fun pat : nat => Some pat) (cons 0 nil)
+ with
+ | Some _ => admit
+ | None => admit
+ end
+.
+Definition dtree'' := Eval vm_compute in dtree4. (* segfault *)
+
+End Segfault.
+
+Module OtherExample.
+
+Definition bar@{i} := Type@{i}.
+Definition foo@{i j} (x y z : nat) :=
+ @id Type@{j} bar@{i}.
+Eval vm_compute in foo.
+
+End OtherExample.
+
+Module LocalClosure.
+
+Definition bar@{i} := Type@{i}.
+
+Definition foo@{i j} (x y z : nat) :=
+ @id (nat -> Type@{j}) (fun _ => Type@{i}).
+Eval vm_compute in foo.
+
+End LocalClosure.
+
+Require Import Hurkens.
+Polymorphic Inductive unit := tt.
+
+Polymorphic Definition foo :=
+ let x := id tt in (x, x, Type).
+
+Lemma bad : False.
+ refine (TypeNeqSmallType.paradox (snd foo) _).
+ vm_compute.
+ Fail reflexivity.
+Abort.
diff --git a/test-suite/bugs/closed/7903.v b/test-suite/bugs/closed/7903.v
new file mode 100644
index 000000000..55c7ee99a
--- /dev/null
+++ b/test-suite/bugs/closed/7903.v
@@ -0,0 +1,4 @@
+(* Slightly improving interpretation of Ltac subterms in notations *)
+
+Notation bar x f := (let z := ltac:(exact 1) in (fun x : nat => f)).
+Check bar x (x + x).
diff --git a/test-suite/bugs/closed/8004.v b/test-suite/bugs/closed/8004.v
new file mode 100644
index 000000000..818639997
--- /dev/null
+++ b/test-suite/bugs/closed/8004.v
@@ -0,0 +1,47 @@
+Require Export Coq.Program.Tactics Coq.Classes.SetoidTactics Coq.Classes.CMorphisms .
+
+Set Universe Polymorphism.
+
+Delimit Scope category_theory_scope with category_theory.
+Open Scope category_theory_scope.
+
+Infix "∧" := prod (at level 80, right associativity) : category_theory_scope.
+
+Class Setoid A := {
+ equiv : crelation A;
+ setoid_equiv :> Equivalence equiv
+}.
+
+Notation "f ≈ g" := (equiv f g) (at level 79) : category_theory_scope.
+
+Open Scope list_scope.
+
+Generalizable All Variables.
+
+Fixpoint list_equiv `{Setoid A} (xs ys : list A) : Type :=
+ match xs, ys with
+ | nil, nil => True
+ | x :: xs, y :: ys => x ≈ y ∧ list_equiv xs ys
+ | _, _ => False
+ end.
+
+Axiom proof_admitted : False.
+Tactic Notation "admit" := abstract case proof_admitted.
+
+Program Instance list_equivalence `{Setoid A} : Equivalence list_equiv.
+Next Obligation.
+ repeat intro.
+ induction x; simpl; split; auto.
+ reflexivity.
+Qed.
+Next Obligation.
+ repeat intro.
+ generalize dependent y.
+ induction x, y; simpl; intros; auto.
+ destruct X; split.
+ now symmetry.
+ intuition.
+Qed.
+Next Obligation.
+admit.
+Defined.
diff --git a/test-suite/coq-makefile/timing/precomputed-time-tests/001-correct-diff-sorting-order/time-of-build-both.log.expected b/test-suite/coq-makefile/timing/precomputed-time-tests/001-correct-diff-sorting-order/time-of-build-both.log.expected
index 975e359b7..159e64551 100644
--- a/test-suite/coq-makefile/timing/precomputed-time-tests/001-correct-diff-sorting-order/time-of-build-both.log.expected
+++ b/test-suite/coq-makefile/timing/precomputed-time-tests/001-correct-diff-sorting-order/time-of-build-both.log.expected
@@ -1,6 +1,6 @@
After | File Name | Before || Change | % Change
----------------------------------------------------------------------------------------------
-19m16.05s | Total | 21m25.28s || -2m09.23s | -10.05%
+19m16.04s | Total | 21m25.27s || -2m09.23s | -10.05%
----------------------------------------------------------------------------------------------
4m01.34s | Specific/X25519/C64/ladderstep | 4m59.49s || -0m58.15s | -19.41%
2m48.52s | Specific/solinas32_2e255m765_13limbs/femul | 3m12.95s || -0m24.42s | -12.66%
diff --git a/test-suite/coq-makefile/timing/precomputed-time-tests/002-single-file-sorting/time-of-build-pretty.log.expected b/test-suite/coq-makefile/timing/precomputed-time-tests/002-single-file-sorting/time-of-build-pretty.log.expected
index fdd5ec21d..b9739ddb1 100644
--- a/test-suite/coq-makefile/timing/precomputed-time-tests/002-single-file-sorting/time-of-build-pretty.log.expected
+++ b/test-suite/coq-makefile/timing/precomputed-time-tests/002-single-file-sorting/time-of-build-pretty.log.expected
@@ -1,6 +1,6 @@
Time | File Name
----------------------------------------------------------
-19m16.05s | Total
+19m16.04s | Total
----------------------------------------------------------
4m01.34s | Specific/X25519/C64/ladderstep
3m09.62s | Specific/NISTP256/AMD64/femul
diff --git a/test-suite/misc/7704.sh b/test-suite/misc/7704.sh
new file mode 100755
index 000000000..0ca2c97d2
--- /dev/null
+++ b/test-suite/misc/7704.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -e
+
+export PATH=$BIN:$PATH
+
+${coqtop#"$BIN"} -compile misc/aux7704.v
diff --git a/test-suite/misc/aux7704.v b/test-suite/misc/aux7704.v
new file mode 100644
index 000000000..6fdcf6768
--- /dev/null
+++ b/test-suite/misc/aux7704.v
@@ -0,0 +1,6 @@
+
+Goal True /\ True.
+Proof.
+ split.
+ par:exact I.
+Qed.
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index 996af5927..5ab616160 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -241,3 +241,8 @@ Notation
Notation
"( x , y , .. , z )" := pair .. (pair x y) .. z : core_scope
(default interpretation)
+1 subgoal
+
+ ============================
+ ##@%
+ ^^^
diff --git a/test-suite/output/Notations3.v b/test-suite/output/Notations3.v
index 3cf0c913f..876aaa394 100644
--- a/test-suite/output/Notations3.v
+++ b/test-suite/output/Notations3.v
@@ -385,3 +385,17 @@ Module LocateNotations.
Locate "exists".
Locate "( _ , _ , .. , _ )".
End LocateNotations.
+
+Module Issue7731.
+
+Axiom (P : nat -> Prop).
+Parameter (X : nat).
+Notation "## @ E ^^^" := (P E) (at level 20, E at level 1, format "'[ ' ## '/' @ E '/' ^^^ ']'").
+Notation "%" := X.
+
+Set Printing Width 7.
+Goal ## @ % ^^^.
+Show.
+Abort.
+
+End Issue7731.
diff --git a/test-suite/ssr/ipat_clear_if_id.v b/test-suite/ssr/ipat_clear_if_id.v
new file mode 100644
index 000000000..7a44db2ea
--- /dev/null
+++ b/test-suite/ssr/ipat_clear_if_id.v
@@ -0,0 +1,23 @@
+Require Import ssreflect.
+
+Axiom v1 : nat -> bool.
+
+Section Foo.
+
+Variable v2 : nat -> bool.
+
+Lemma test (v3 : nat -> bool) (v4 : bool -> bool) (v5 : bool -> bool) : nat -> nat -> nat -> nat -> True.
+Proof.
+move=> {}/v1 b1 {}/v2 b2 {}/v3 b3 {}/v2/v4/v5 b4.
+Check b1 : bool.
+Check b2 : bool.
+Check b3 : bool.
+Check b4 : bool.
+Fail Check v3.
+Fail Check v4.
+Fail Check v5.
+Check v2 : nat -> bool.
+by [].
+Qed.
+
+End Foo.
diff --git a/test-suite/ssr/rew_polyuniv.v b/test-suite/ssr/rew_polyuniv.v
new file mode 100644
index 000000000..e2bbbc9ec
--- /dev/null
+++ b/test-suite/ssr/rew_polyuniv.v
@@ -0,0 +1,90 @@
+From Coq Require Import Utf8 Setoid ssreflect.
+Set Default Proof Using "Type".
+
+Local Set Universe Polymorphism.
+
+(** Telescopes *)
+Inductive tele : Type :=
+ | TeleO : tele
+ | TeleS {X} (binder : X → tele) : tele.
+
+Arguments TeleS {_} _.
+
+(** The telescope version of Coq's function type *)
+Fixpoint tele_fun (TT : tele) (T : Type) : Type :=
+ match TT with
+ | TeleO => T
+ | TeleS b => ∀ x, tele_fun (b x) T
+ end.
+
+Notation "TT -t> A" :=
+ (tele_fun TT A) (at level 99, A at level 200, right associativity).
+
+(** A sigma-like type for an "element" of a telescope, i.e. the data it
+ takes to get a [T] from a [TT -t> T]. *)
+Inductive tele_arg : tele → Type :=
+| TargO : tele_arg TeleO
+(* the [x] is the only relevant data here *)
+| TargS {X} {binder} (x : X) : tele_arg (binder x) → tele_arg (TeleS binder).
+
+Definition tele_app {TT : tele} {T} (f : TT -t> T) : tele_arg TT → T :=
+ λ a, (fix rec {TT} (a : tele_arg TT) : (TT -t> T) → T :=
+ match a in tele_arg TT return (TT -t> T) → T with
+ | TargO => λ t : T, t
+ | TargS x a => λ f, rec a (f x)
+ end) TT a f.
+Arguments tele_app {!_ _} _ !_ /.
+
+Coercion tele_arg : tele >-> Sortclass.
+Coercion tele_app : tele_fun >-> Funclass.
+
+(** Inversion lemma for [tele_arg] *)
+Lemma tele_arg_inv {TT : tele} (a : TT) :
+ match TT as TT return TT → Prop with
+ | TeleO => λ a, a = TargO
+ | TeleS f => λ a, ∃ x a', a = TargS x a'
+ end a.
+Proof. induction a; eauto. Qed.
+Lemma tele_arg_O_inv (a : TeleO) : a = TargO.
+Proof. exact (tele_arg_inv a). Qed.
+Lemma tele_arg_S_inv {X} {f : X → tele} (a : TeleS f) :
+ ∃ x a', a = TargS x a'.
+Proof. exact (tele_arg_inv a). Qed.
+
+(** Operate below [tele_fun]s with argument telescope [TT]. *)
+Fixpoint tele_bind {U} {TT : tele} : (TT → U) → TT -t> U :=
+ match TT as TT return (TT → U) → TT -t> U with
+ | TeleO => λ F, F TargO
+ | @TeleS X b => λ (F : TeleS b → U) (x : X), (* b x -t> U *)
+ tele_bind (λ a, F (TargS x a))
+ end.
+Arguments tele_bind {_ !_} _ /.
+
+(* Show that tele_app ∘ tele_bind is the identity. *)
+Lemma tele_app_bind {U} {TT : tele} (f : TT → U) x :
+ (tele_app (tele_bind f)) x = f x.
+Proof.
+ induction TT as [|X b IH]; simpl in *.
+ - rewrite (tele_arg_O_inv x). auto.
+ - destruct (tele_arg_S_inv x) as [x' [a' ->]]. simpl.
+ rewrite IH. auto.
+Qed.
+
+(** Notation-compatible telescope mapping *)
+(* This adds (tele_app ∘ tele_bind), which is an identity function, around every
+ binder so that, after simplifying, this matches the way we typically write
+ notations involving telescopes. *)
+Notation "'λ..' x .. y , e" :=
+ (tele_app (tele_bind (λ x, .. (tele_app (tele_bind (λ y, e))) .. )))
+ (at level 200, x binder, y binder, right associativity,
+ format "'[ ' 'λ..' x .. y ']' , e").
+
+(* The testcase *)
+Lemma test {TA TB : tele} {X} (α' β' γ' : X → Prop) (Φ : TA → TB → Prop) x' :
+ (forall P Q, ((P /\ Q) = Q) * ((P -> Q) = Q)) ->
+ ∀ a b, Φ a b = (λ.. x y, β' x' ∧ (γ' x' → Φ x y)) a b.
+Proof.
+intros cheat a b.
+rewrite !tele_app_bind.
+by rewrite !cheat.
+Qed.
diff --git a/test-suite/ssr/set_polyuniv.v b/test-suite/ssr/set_polyuniv.v
new file mode 100644
index 000000000..436eeafc7
--- /dev/null
+++ b/test-suite/ssr/set_polyuniv.v
@@ -0,0 +1,11 @@
+From Coq Require Import ssreflect.
+Set Default Proof Using "Type".
+
+Local Set Universe Polymorphism.
+
+Axiom foo : Type -> Prop.
+
+Lemma test : foo nat.
+Proof.
+set x := foo _. (* key @foo{i} matches @foo{j} *)
+Abort.
diff --git a/test-suite/ssr/ssr_rew_illtyped.v b/test-suite/ssr/ssr_rew_illtyped.v
new file mode 100644
index 000000000..7358068c8
--- /dev/null
+++ b/test-suite/ssr/ssr_rew_illtyped.v
@@ -0,0 +1,9 @@
+From Coq Require Import ssreflect Setoid.
+
+Structure SEProp := {prop_of : Prop; _ : prop_of <-> True}.
+
+Fact anomaly: forall P : SEProp, prop_of P.
+Proof.
+move=> [P E].
+Fail rewrite E.
+Abort.
diff --git a/test-suite/success/Hints.v b/test-suite/success/Hints.v
index 717dc0deb..ebf5b094e 100644
--- a/test-suite/success/Hints.v
+++ b/test-suite/success/Hints.v
@@ -183,3 +183,33 @@ End HintCut.
Goal forall (m : nat), exists n, m = n /\ m = n.
intros m; eexists; split; [trivial | reflexivity].
Qed.
+
+Section HintTransparent.
+
+ Definition fn (x : nat) := S x.
+
+ Create HintDb trans.
+
+ Hint Resolve eq_refl | (_ = _) : trans.
+
+ (* No reduction *)
+ Hint Variables Opaque : trans. Hint Constants Opaque : trans.
+
+ Goal forall x : nat, fn x = S x.
+ Proof.
+ intros.
+ Fail typeclasses eauto with trans.
+ unfold fn.
+ typeclasses eauto with trans.
+ Qed.
+
+ (** Now allow unfolding fn *)
+ Hint Constants Transparent : trans.
+
+ Goal forall x : nat, fn x = S x.
+ Proof.
+ intros.
+ typeclasses eauto with trans.
+ Qed.
+
+End HintTransparent.
diff --git a/test-suite/success/mutual_record.v b/test-suite/success/mutual_record.v
new file mode 100644
index 000000000..77529733b
--- /dev/null
+++ b/test-suite/success/mutual_record.v
@@ -0,0 +1,57 @@
+Module M0.
+
+Inductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M0.
+
+Module M1.
+
+Set Primitive Projections.
+
+Inductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M1.
+
+Module M2.
+
+Set Primitive Projections.
+
+CoInductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M2.
diff --git a/test-suite/success/uniform_inductive_parameters.v b/test-suite/success/uniform_inductive_parameters.v
new file mode 100644
index 000000000..42236a531
--- /dev/null
+++ b/test-suite/success/uniform_inductive_parameters.v
@@ -0,0 +1,13 @@
+Set Uniform Inductive Parameters.
+
+Inductive list (A : Type) :=
+ | nil : list
+ | cons : A -> list -> list.
+Check (list : Type -> Type).
+Check (cons : forall A, A -> list A -> list A).
+
+Inductive list2 (A : Type) (A' := prod A A) :=
+ | nil2 : list2
+ | cons2 : A' -> list2 -> list2.
+Check (list2 : Type -> Type).
+Check (cons2 : forall A (A' := prod A A), A' -> list2 A -> list2 A).
diff --git a/test-suite/success/vm_records.v b/test-suite/success/vm_records.v
new file mode 100644
index 000000000..8a1544c8e
--- /dev/null
+++ b/test-suite/success/vm_records.v
@@ -0,0 +1,40 @@
+Set Primitive Projections.
+
+Module M.
+
+CoInductive foo := Foo {
+ foo0 : foo;
+ foo1 : bar;
+}
+with bar := Bar {
+ bar0 : foo;
+ bar1 : bar;
+}.
+
+CoFixpoint f : foo := Foo f g
+with g : bar := Bar f g.
+
+Check (@eq_refl _ g.(bar0) <: f.(foo0).(foo0) = g.(bar0)).
+Check (@eq_refl _ g <: g.(bar1).(bar0).(foo1) = g).
+
+End M.
+
+Module N.
+
+Inductive foo := Foo {
+ foo0 : option foo;
+ foo1 : list bar;
+}
+with bar := Bar {
+ bar0 : option bar;
+ bar1 : list foo;
+}.
+
+Definition f_0 := Foo None nil.
+Definition g_0 := Bar None nil.
+
+Definition f := Foo (Some f_0) (cons g_0 nil).
+
+Check (@eq_refl _ f.(foo1) <: f.(foo1) = cons g_0 nil).
+
+End N.
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index 10ca9ecc9..817581cb2 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -29,6 +29,13 @@ Definition not (A:Prop) := A -> False.
Notation "~ x" := (not x) : type_scope.
+(** Create the "core" hint database, and set its transparent state for
+ variables and constants explicitely. *)
+
+Create HintDb core.
+Hint Variables Opaque : core.
+Hint Constants Opaque : core.
+
Hint Unfold not: core.
(** [and A B], written [A /\ B], is the conjunction of [A] and [B]
diff --git a/theories/Numbers/BinNums.v b/theories/Numbers/BinNums.v
index f8b3d9e1d..d5eb4f268 100644
--- a/theories/Numbers/BinNums.v
+++ b/theories/Numbers/BinNums.v
@@ -12,6 +12,8 @@
Set Implicit Arguments.
+Declare ML Module "positive_syntax_plugin".
+Declare ML Module "n_syntax_plugin".
Declare ML Module "z_syntax_plugin".
(** [positive] is a datatype representing the strictly positive integers
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index 8e60d3932..8b6822a4e 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -65,20 +65,20 @@ VERBOSE ?=
# Time the Coq process (set to non empty), and how (see default value)
TIMED?=
TIMECMD?=
-# Use /usr/bin/env time on linux, gtime on Mac OS
+# Use command time on linux, gtime on Mac OS
TIMEFMT?="$* (real: %e, user: %U, sys: %S, mem: %M ko)"
ifneq (,$(TIMED))
-ifeq (0,$(shell /usr/bin/env time -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?))
-STDTIME?=/usr/bin/env time -f $(TIMEFMT)
+ifeq (0,$(shell command time -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?))
+STDTIME?=command time -f $(TIMEFMT)
else
ifeq (0,$(shell gtime -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?))
STDTIME?=gtime -f $(TIMEFMT)
else
-STDTIME?=time
+STDTIME?=command time
endif
endif
else
-STDTIME?=/usr/bin/env time -f $(TIMEFMT)
+STDTIME?=command time -f $(TIMEFMT)
endif
# Coq binaries
@@ -86,7 +86,6 @@ COQC ?= "$(COQBIN)coqc"
COQTOP ?= "$(COQBIN)coqtop"
COQCHK ?= "$(COQBIN)coqchk"
COQDEP ?= "$(COQBIN)coqdep"
-GALLINA ?= "$(COQBIN)gallina"
COQDOC ?= "$(COQBIN)coqdoc"
COQMKFILE ?= "$(COQBIN)coq_makefile"
@@ -256,7 +255,6 @@ VO = vo
VOFILES = $(VFILES:.v=.$(VO))
GLOBFILES = $(VFILES:.v=.glob)
-GFILES = $(VFILES:.v=.g)
HTMLFILES = $(VFILES:.v=.html)
GHTMLFILES = $(VFILES:.v=.g.html)
BEAUTYFILES = $(addsuffix .beautified,$(VFILES))
@@ -442,8 +440,6 @@ all-mli.tex: $(MLIFILES:.mli=.cmi)
$(HIDE)$(CAMLDOC) -latex \
-o $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES)
-gallina: $(GFILES)
-
all.ps: $(VFILES)
$(SHOW)'COQDOC -ps $(GAL)'
$(HIDE)$(COQDOC) \
@@ -564,7 +560,6 @@ clean::
$(HIDE)find . -name .coq-native -type d -empty -delete
$(HIDE)rm -f $(VOFILES)
$(HIDE)rm -f $(VOFILES:.vo=.vio)
- $(HIDE)rm -f $(GFILES)
$(HIDE)rm -f $(BEAUTYFILES) $(VFILES:=.old)
$(HIDE)rm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob all-mli.tex
$(HIDE)rm -f $(VFILES:.v=.glob)
@@ -683,10 +678,6 @@ $(BEAUTYFILES): %.v.beautified: %.v
$(SHOW)'BEAUTIFY $<'
$(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -beautify $<
-$(GFILES): %.g: %.v
- $(SHOW)'GALLINA $<'
- $(HIDE)$(GALLINA) $<
-
$(TEXFILES): %.tex: %.v
$(SHOW)'COQDOC -latex $<'
$(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex $< -o $@
diff --git a/tools/TimeFileMaker.py b/tools/TimeFileMaker.py
index 0d24332f1..b16888c7e 100644
--- a/tools/TimeFileMaker.py
+++ b/tools/TimeFileMaker.py
@@ -1,6 +1,9 @@
-#!/usr/bin/env python
from __future__ import with_statement
+from __future__ import division
+from __future__ import unicode_literals
+from __future__ import print_function
import os, sys, re
+from io import open
# This script parses the output of `make TIMED=1` into a dictionary
# mapping names of compiled files to the number of minutes and seconds
@@ -8,7 +11,7 @@ import os, sys, re
STRIP_REG = re.compile('^(coq/|contrib/|)(?:theories/|src/)?')
STRIP_REP = r'\1'
-INFINITY = '\xe2\x88\x9e'
+INFINITY = '\u221e'
def parse_args(argv, USAGE, HELP_STRING):
sort_by = 'auto'
@@ -27,7 +30,7 @@ def parse_args(argv, USAGE, HELP_STRING):
def reformat_time_string(time):
seconds, milliseconds = time.split('.')
seconds = int(seconds)
- minutes, seconds = int(seconds / 60), seconds % 60
+ minutes, seconds = divmod(seconds, 60)
return '%dm%02d.%ss' % (minutes, seconds, milliseconds)
def get_times(file_name):
@@ -40,7 +43,7 @@ def get_times(file_name):
if file_name == '-':
lines = sys.stdin.read()
else:
- with open(file_name, 'r') as f:
+ with open(file_name, 'r', encoding="utf-8") as f:
lines = f.read()
reg = re.compile(r'^([^\s]+) \([^\)]*?user: ([0-9\.]+)[^\)]*?\)\s*$', re.MULTILINE)
times = reg.findall(lines)
@@ -60,7 +63,7 @@ def get_single_file_times(file_name):
if file_name == '-':
lines = sys.stdin.read()
else:
- with open(file_name, 'r') as f:
+ with open(file_name, 'r', encoding="utf-8") as f:
lines = f.read()
reg = re.compile(r'^Chars ([0-9]+) - ([0-9]+) ([^ ]+) ([0-9\.]+) secs (.*)$', re.MULTILINE)
times = reg.findall(lines)
@@ -101,7 +104,7 @@ def from_seconds(seconds, signed=False):
'''
sign = ('-' if seconds < 0 else '+') if signed else ''
seconds = abs(seconds)
- minutes = int(seconds) / 60
+ minutes = int(seconds) // 60
seconds -= minutes * 60
full_seconds = int(seconds)
partial_seconds = int(100 * (seconds - full_seconds))
@@ -112,7 +115,8 @@ def sum_times(times, signed=False):
Takes the values of an output from get_times, parses the time
strings, and returns their sum, in the same string format.
'''
- return from_seconds(sum(map(to_seconds, times)), signed=signed)
+ # sort the times before summing because floating point addition is not associative
+ return from_seconds(sum(sorted(map(to_seconds, times))), signed=signed)
def format_percentage(num, signed=True):
sign = ('-' if num < 0 else '+') if signed else ''
@@ -153,8 +157,8 @@ def make_diff_table_string(left_times_dict, right_times_dict,
# set the widths of each of the columns by the longest thing to go in that column
left_sum = sum_times(left_times_dict.values())
right_sum = sum_times(right_times_dict.values())
- left_sum_float = sum(map(to_seconds, left_times_dict.values()))
- right_sum_float = sum(map(to_seconds, right_times_dict.values()))
+ left_sum_float = sum(sorted(map(to_seconds, left_times_dict.values())))
+ right_sum_float = sum(sorted(map(to_seconds, right_times_dict.values())))
diff_sum = from_seconds(left_sum_float - right_sum_float, signed=True)
percent_diff_sum = (format_percentage((left_sum_float - right_sum_float) / right_sum_float)
if right_sum_float > 0 else 'N/A')
@@ -203,8 +207,12 @@ def make_table_string(times_dict,
def print_or_write_table(table, files):
if len(files) == 0 or '-' in files:
- print(table)
+ try:
+ binary_stdout = sys.stdout.buffer
+ except AttributeError:
+ binary_stdout = sys.stdout
+ print(table.encode("utf-8"), file=binary_stdout)
for file_name in files:
if file_name != '-':
- with open(file_name, 'w') as f:
+ with open(file_name, 'w', encoding="utf-8") as f:
f.write(table)
diff --git a/tools/coq-font-lock.el b/tools/coq-font-lock.el
deleted file mode 100644
index 068e64002..000000000
--- a/tools/coq-font-lock.el
+++ /dev/null
@@ -1,137 +0,0 @@
-;; coq-font-lock.el --- Coq syntax highlighting for Emacs - compatibilty code
-;; Pierre Courtieu, may 2009
-;;
-;; Authors: Pierre Courtieu
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;; Maintainer: Pierre Courtieu <Pierre.Courtieu@cnam.fr>
-
-;; This is copy paste from ProofGeneral by David Aspinall
-;; <David.Aspinall@ed.ac.uk>. ProofGeneral is under GPL and Copyright
-;; (C) LFCS Edinburgh.
-
-
-;;; Commentary:
-;; This file contains the code necessary to coq-syntax.el and
-;; coq-db.el from ProofGeneral. It is also pocked from ProofGeneral.
-
-
-;;; History:
-;; First created from ProofGeneral may 28th 2009
-
-
-;;; Code:
-
-(setq coq-version-is-V8-1 t)
-(defun coq-build-regexp-list-from-db (db &optional filter)
- "Take a keyword database DB and return the list of regexps for font-lock.
-If non-nil Optional argument FILTER is a function applying to each line of DB.
-For each line if FILTER returns nil, then the keyword is not added to the
-regexp. See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l)) (tl (cdr l)) ; hd is the first infos list
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- )
- ;; TODO delete doublons
- (when (and e5 (or (not filter) (funcall filter hd)))
- (setq res (nconc res (list e5)))) ; careful: nconc destructive!
- (setq l tl)))
- res
- ))
-(defun filter-state-preserving (l)
- ; checkdoc-params: (l)
- "Not documented."
- (not (nth 3 l))) ; fourth argument is nil --> state preserving command
-
-(defun filter-state-changing (l)
- ; checkdoc-params: (l)
- "Not documented."
- (nth 3 l)) ; fourth argument is nil --> state preserving command
-
-;; Generic font-lock
-
-(defvar proof-id "\\(\\w\\(\\w\\|\\s_\\)*\\)"
- "A regular expression for parsing identifiers.")
-
-;; For font-lock, we treat ,-separated identifiers as one identifier
-;; and refontify commata using \{proof-zap-commas}.
-
-(defun proof-anchor-regexp (e)
- "Anchor (\\`) and group the regexp E."
- (concat "\\`\\(" e "\\)"))
-
-(defun proof-ids (proof-id &optional sepregexp)
- "Generate a regular expression for separated lists of identifiers PROOF-ID.
-Default is comma separated, or SEPREGEXP if set."
- (concat proof-id "\\(\\s-*" (or sepregexp ",") "\\s-*"
- proof-id "\\)*"))
-
-(defun proof-ids-to-regexp (l)
- "Maps a non-empty list of tokens `L' to a regexp matching any element."
- (if (featurep 'xemacs)
- (mapconcat (lambda (s) (concat "\\_<" s "\\_>")) l "\\|") ;; old version
- (concat "\\_<\\(?:" (mapconcat 'identity l "\\|") "\\)\\_>")))
-
-;; TODO: get rid of this list. Does 'default work widely enough
-;; by now?
-(defconst pg-defface-window-systems
- '(x ;; bog standard
- mswindows ;; Windows
- w32 ;; Windows
- gtk ;; gtk emacs (obsolete?)
- mac ;; used by Aquamacs
- carbon ;; used by Carbon XEmacs
- ns ;; NeXTstep Emacs (Emacs.app)
- x-toolkit) ;; possible catch all (but probably not)
- "A list of possible values for variable `window-system'.
-If you are on a window system and your value of variable
-`window-system' is not listed here, you may not get the correct
-syntax colouring behaviour.")
-
-(defmacro proof-face-specs (bl bd ow)
- "Return a spec for `defface' with BL for light bg, BD for dark, OW o/w."
- `(append
- (apply 'append
- (mapcar
- (lambda (ty) (list
- (list (list (list 'type ty) '(class color)
- (list 'background 'light))
- (quote ,bl))
- (list (list (list 'type ty) '(class color)
- (list 'background 'dark))
- (quote ,bd))))
- pg-defface-window-systems))
- (list (list t (quote ,ow)))))
-
-;;A new face for tactics
-(defface coq-solve-tactics-face
- (proof-face-specs
- (:foreground "forestgreen" t) ; for bright backgrounds
- (:foreground "forestgreen" t) ; for dark backgrounds
- ()) ; for black and white
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-;;A new face for tactics which fail when they don't kill the current goal
-(defface coq-solve-tactics-face
- (proof-face-specs
- (:foreground "red" t) ; for bright backgrounds
- (:foreground "red" t) ; for dark backgrounds
- ()) ; for black and white
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-
-(defconst coq-solve-tactics-face 'coq-solve-tactics-face
- "Expression that evaluates to a face.
-Required so that 'proof-solve-tactics-face is a proper facename")
-
-(defconst proof-tactics-name-face 'coq-solve-tactics-face)
-(defconst proof-tacticals-name-face 'coq-solve-tactics-face)
-
-(provide 'coq-font-lock)
-;;; coq-font-lock.el ends here
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 6f11ee397..ad489da82 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -218,7 +218,7 @@ let windrive s =
else ""
;;
-let generate_conf_coq_config oc args =
+let generate_conf_coq_config oc =
section oc "Coq configuration.";
let src_dirs = Coq_config.all_src_dirs in
Envars.print_config ~prefix_var_name:"COQMF_" oc src_dirs;
@@ -282,7 +282,7 @@ let generate_conf oc project args =
fprintf oc "# %s\n\n" (String.concat " " (List.map quote args));
generate_conf_files oc project;
generate_conf_includes oc project;
- generate_conf_coq_config oc args;
+ generate_conf_coq_config oc;
generate_conf_defs oc project;
generate_conf_doc oc project;
generate_conf_extra_target oc project.extra_targets;
diff --git a/tools/coqdoc/index.ml b/tools/coqdoc/index.ml
index df493fdf7..885324aa0 100644
--- a/tools/coqdoc/index.ml
+++ b/tools/coqdoc/index.ml
@@ -77,7 +77,7 @@ let add_ref m loc m' sp id ty =
let find m l = Hashtbl.find reftable (m, l)
-let find_string m s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
+let find_string s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
(* Coq modules *)
diff --git a/tools/coqdoc/index.mli b/tools/coqdoc/index.mli
index 5cd301389..7c9aad67f 100644
--- a/tools/coqdoc/index.mli
+++ b/tools/coqdoc/index.mli
@@ -41,7 +41,7 @@ type index_entry =
val find : coq_module -> loc -> index_entry
(* Find what data is referred to by some string in some coq module *)
-val find_string : coq_module -> string -> index_entry
+val find_string : string -> index_entry
val add_module : coq_module -> unit
diff --git a/tools/coqdoc/output.ml b/tools/coqdoc/output.ml
index d25227002..c640167ac 100644
--- a/tools/coqdoc/output.ml
+++ b/tools/coqdoc/output.ml
@@ -431,7 +431,7 @@ module Latex = struct
else if !Cdglobals.interpolate && !in_doc (* always a var otherwise *)
then
try
- let tag = Index.find_string (get_module false) s in
+ let tag = Index.find_string s in
reference (translate s) tag
with _ -> Tokens.output_tagged_ident_string s
else Tokens.output_tagged_ident_string s
@@ -706,7 +706,7 @@ module Html = struct
else if is_keyword s then
printf "<span class=\"id\" title=\"keyword\">%s</span>" (translate s)
else if !Cdglobals.interpolate && !in_doc (* always a var otherwise *) then
- try reference (translate s) (Index.find_string (get_module false) s)
+ try reference (translate s) (Index.find_string s)
with Not_found -> Tokens.output_tagged_ident_string s
else
Tokens.output_tagged_ident_string s
diff --git a/tools/gallina-db.el b/tools/gallina-db.el
deleted file mode 100644
index 9664f69f8..000000000
--- a/tools/gallina-db.el
+++ /dev/null
@@ -1,240 +0,0 @@
-;;; gallina-db.el --- coq keywords database utility functions
-;;
-;; Author: Pierre Courtieu <courtieu@lri.fr>
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;;
-
-;;; We store all information on keywords (tactics or command) in big
-;; tables (ex: `coq-tactics-db') From there we get: menus including
-;; "smart" commands, completions for command coq-insert-...
-;; abbrev tables and font-lock keyword
-
-;;; real value defined below
-
-;;; Commentary:
-;;
-
-;;; Code:
-
-;(require 'proof-config) ; for proof-face-specs, a macro
-;(require 'holes)
-
-(defconst coq-syntax-db nil
- "Documentation-only variable, for coq keyword databases.
-Each element of a keyword database contains the definition of a \"form\", of the
-form:
-
-(MENUNAME ABBREV INSERT STATECH KWREG INSERT-FUN HIDE)
-
-MENUNAME is the name of form (or form variant) as it should appear in menus or
-completion lists.
-
-ABBREV is the abbreviation for completion via \\[expand-abbrev].
-
-INSERT is the complete text of the form, which may contain holes denoted by
-\"#\" or \"@{xxx}\".
-
-If non-nil the optional STATECH specifies that the command is not state
-preserving for coq.
-
-If non-nil the optional KWREG is the regexp to colorize correponding to the
-keyword. ex: \"simple\\\\s-+destruct\" (\\\\s-+ meaning \"one or more spaces\").
-*WARNING*: A regexp longer than another one should be put FIRST. For example:
-
- (\"Module Type\" ... ... t \"Module\\s-+Type\")
- (\"Module\" ... ... t \"Module\")
-
-Is ok because the longer regexp is recognized first.
-
-If non-nil the optional INSERT-FUN is the function to be called when inserting
-the form (instead of inserting INSERT, except when using \\[expand-abbrev]). This
-allows writing functions asking for more information to assist the user.
-
-If non-nil the optional HIDE specifies that this form should not appear in the
-menu but only in interactive completions.
-
-Example of what could be in your emacs init file:
-
-(defvar coq-user-tactics-db
- '(
- (\"mytac\" \"mt\" \"mytac # #\" t \"mytac\")
- (\"myassert by\" \"massb\" \"myassert ( # : # ) by #\" t \"assert\")
- ))
-
-Explanation of the first line: the tactic menu entry mytac, abbreviated by mt,
-will insert \"mytac # #\" where #s are holes to fill, and \"mytac\" becomes a
-new keyword to colorize." )
-
-(defun coq-insert-from-db (db prompt)
- "Ask for a keyword, with completion on keyword database DB and insert.
-Insert corresponding string with holes at point. If an insertion function is
-present for the keyword, call it instead. see `coq-syntax-db' for DB
-structure."
- (let* ((tac (completing-read (concat prompt " (tab for completion) : ")
- db nil nil))
- (infos (cddr (assoc tac db)))
- (s (car infos)) ; completion to insert
- (f (car-safe (cdr-safe (cdr-safe (cdr infos))))) ; insertion function
- (pt (point)))
- (if f (funcall f) ; call f if present
- (insert (or s tac)) ; insert completion and indent otherwise
- (holes-replace-string-by-holes-backward-jump pt)
- (indent-according-to-mode))))
-
-
-
-(defun coq-build-regexp-list-from-db (db &optional filter)
- "Take a keyword database DB and return the list of regexps for font-lock.
-If non-nil Optional argument FILTER is a function applying to each line of DB.
-For each line if FILTER returns nil, then the keyword is not added to the
-regexp. See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l)) (tl (cdr l)) ; hd is the first infos list
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- )
- ;; TODO delete doublons
- (when (and e5 (or (not filter) (funcall filter hd)))
- (setq res (nconc res (list e5)))) ; careful: nconc destructive!
- (setq l tl)))
- res
- ))
-
-;; Computes the max length of strings in a list
-(defun max-length-db (db)
- "Return the length of the longest first element (menu label) of DB.
-See `coq-syntax-db' for DB structure."
- (let ((l db) (res 0))
- (while l
- (let ((lgth (length (car (car l)))))
- (setq res (max lgth res))
- (setq l (cdr l))))
- res))
-
-
-
-(defun coq-build-menu-from-db-internal (db lgth menuwidth)
- "Take a keyword database DB and return one insertion submenu.
-Argument LGTH is the max size of the submenu. Argument MENUWIDTH is the width
-of the largest line in the menu (without abbrev and shortcut specifications).
-Used by `coq-build-menu-from-db', which you should probably use instead. See
-`coq-syntax-db' for DB structure."
- (let ((l db) (res ()) (size lgth)
- (keybind-abbrev (substitute-command-keys " \\[expand-abbrev]")))
- (while (and l (> size 0))
- (let* ((hd (car l))(tl (cdr l)) ; hd is a list of length 3 or 4
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- (e6 (car-safe tl5)) ; e6 = function for smart insertion
- (e7 (car-safe (cdr-safe tl5))) ; e7 = if non-nil : hide in menu
- (entry-with (max (- menuwidth (length e1)) 0))
- (spaces (make-string entry-with ? ))
- ;;(restofmenu (coq-build-menu-from-db-internal tl (- size 1) menuwidth))
- )
- (when (not e7) ;; if not hidden
- (let ((menu-entry
- (vector
- ;; menu entry label
- (concat e1 (if (not e2) "" (concat spaces "(" e2 keybind-abbrev ")")))
- ;;insertion function if present otherwise insert completion
- (if e6 e6 `(holes-insert-and-expand ,e3))
- t)))
- (setq res (nconc res (list menu-entry)))));; append *in place*
- (setq l tl)
- (setq size (- size 1))))
- res))
-
-
-(defun coq-build-title-menu (db size)
- "Build a title for the first submenu of DB, of size SIZE.
-Return the string made of the first and the SIZE nth first element of DB,
-separated by \"...\". Used by `coq-build-menu-from-db'. See `coq-syntax-db'
-for DB structure."
- (concat (car-safe (car-safe db))
- " ... "
- (car-safe (car-safe (nthcdr (- size 1) db)))))
-
-(defun coq-sort-menu-entries (menu)
- (sort menu
- (lambda (x y) (string<
- (downcase (elt x 0))
- (downcase (elt y 0))))))
-
-(defun coq-build-menu-from-db (db &optional size)
- "Take a keyword database DB and return a list of insertion menus for them.
-Submenus contain SIZE entries (default 30). See `coq-syntax-db' for DB
-structure."
- ;; sort is destructive for the list, so copy list before sorting
- (let* ((l (coq-sort-menu-entries (copy-list db))) (res ())
- (wdth (+ 2 (max-length-db db)))
- (sz (or size 30)) (lgth (length l)))
- (while l
- (if (<= lgth sz)
- (setq res ;; careful: nconc destructive!
- (nconc res (list (cons
- (coq-build-title-menu l lgth)
- (coq-build-menu-from-db-internal l lgth wdth)))))
- (setq res ; careful: nconc destructive!
- (nconc res (list (cons
- (coq-build-title-menu l sz)
- (coq-build-menu-from-db-internal l sz wdth))))))
- (setq l (nthcdr sz l))
- (setq lgth (length l)))
- res))
-
-(defun coq-build-abbrev-table-from-db (db)
- "Take a keyword database DB and return an abbrev table.
-See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l))(tl (cdr l)) ; hd is a list of length 3 or 4
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- )
- ;; careful: nconc destructive!
- (when e2
- (setq res (nconc res (list `(,e2 ,e3 holes-abbrev-complete)))))
- (setq l tl)))
- res))
-
-
-(defun filter-state-preserving (l)
- ; checkdoc-params: (l)
- "Not documented."
- (not (nth 3 l))) ; fourth argument is nil --> state preserving command
-
-(defun filter-state-changing (l)
- ; checkdoc-params: (l)
- "Not documented."
- (nth 3 l)) ; fourth argument is nil --> state preserving command
-
-(defconst coq-solve-tactics-face 'coq-solve-tactics-face
- "Expression that evaluates to a face.
-Required so that 'proof-solve-tactics-face is a proper facename")
-
-
-;;A new face for tactics which fail when they don't kill the current goal
-(defface coq-solve-tactics-face
- '((t (:background "red")))
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-
-
-
-
-(provide 'gallina-db)
-
-;;; gallina-db.el ends here
-
-;** Local Variables: ***
-;** fill-column: 80 ***
-;** End: ***
diff --git a/tools/gallina-syntax.el b/tools/gallina-syntax.el
deleted file mode 100644
index 7c59fb6ae..000000000
--- a/tools/gallina-syntax.el
+++ /dev/null
@@ -1,979 +0,0 @@
-;; gallina-syntax.el Font lock expressions for Coq
-;; Copyright (C) 1997-2007 LFCS Edinburgh.
-;; Authors: Thomas Kleymann, Healfdene Goguen, Pierre Courtieu
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;; Maintainer: Pierre Courtieu <courtieu@lri.fr>
-
-;; gallina-syntax.el,v 9.9 2008/07/21 15:14:58 pier Exp
-
-;(require 'proof-syntax)
-;(require 'proof-utils) ; proof-locate-executable
-(require 'gallina-db)
-
-
-
- ;;; keyword databases
-
-
-(defcustom coq-user-tactics-db nil
- "User defined tactic information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own tactics here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your tactics will be colorized by font-lock
-
- 2 your tactics will be added to the menu and to completion when
- calling \\[coq-insert-tactic]
-
- 3 you may define an abbreviation for your tactic."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-(defcustom coq-user-commands-db nil
- "User defined command information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-(defcustom coq-user-tacticals-db nil
- "User defined tactical information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-(defcustom coq-user-solve-tactics-db nil
- "User defined closing tactics. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-
-(defcustom coq-user-reserved-db nil
- "User defined reserved keywords information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-
-(defvar coq-tactics-db
- (append
- coq-user-tactics-db
- '(
- ("absurd " "abs" "absurd " t "absurd")
- ("apply" "ap" "apply " t "apply")
- ("assert by" "assb" "assert ( # : # ) by #" t "assert")
- ("assert" "ass" "assert ( # : # )" t)
- ;; ("assumption" "as" "assumption" t "assumption")
- ("auto with arith" "awa" "auto with arith" t)
- ("auto with" "aw" "auto with @{db}" t)
- ("auto" "a" "auto" t "auto")
- ("autorewrite with in using" "arwiu" "autorewrite with @{db,db...} in @{hyp} using @{tac}" t)
- ("autorewrite with in" "arwi" "autorewrite with @{db,db...} in @{hyp}" t)
- ("autorewrite with using" "arwu" "autorewrite with @{db,db...} using @{tac}" t)
- ("autorewrite with" "ar" "autorewrite with @{db,db...}" t "autorewrite")
- ("case" "c" "case " t "case")
- ("cbv" "cbv" "cbv beta [#] delta iota zeta" t "cbv")
- ("change in" "chi" "change # in #" t)
- ("change with in" "chwi" "change # with # in #" t)
- ("change with" "chw" "change # with" t)
- ("change" "ch" "change " t "change")
- ("clear" "cl" "clear" t "clear")
- ("clearbody" "cl" "clearbody" t "clearbody")
- ("cofix" "cof" "cofix" t "cofix")
- ("coinduction" "coind" "coinduction" t "coinduction")
- ("compare" "cmpa" "compare # #" t "compare")
- ("compute" "cmpu" "compute" t "compute")
- ;; ("congruence" "cong" "congruence" t "congruence")
- ("constructor" "cons" "constructor" t "constructor")
- ;; ("contradiction" "contr" "contradiction" t "contradiction")
- ("cut" "cut" "cut" t "cut")
- ("cutrewrite" "cutr" "cutrewrite -> # = #" t "cutrewrite")
- ;; ("decide equality" "deg" "decide equality" t "decide\\s-+equality")
- ("decompose record" "decr" "decompose record #" t "decompose\\s-+record")
- ("decompose sum" "decs" "decompose sum #" t "decompose\\s-+sum")
- ("decompose" "dec" "decompose [#] #" t "decompose")
- ("dependent inversion" "depinv" "dependent inversion" t "dependent\\s-+inversion")
- ("dependent inversion with" "depinvw" "dependent inversion # with #" t)
- ("dependent inversion_clear" "depinvc" "dependent inversion_clear" t "dependent\\s-+inversion_clear")
- ("dependent inversion_clear with" "depinvw" "dependent inversion_clear # with #" t)
- ("dependent rewrite ->" "depr" "dependent rewrite -> @{id}" t "dependent\\s-+rewrite")
- ("dependent rewrite <-" "depr<" "dependent rewrite <- @{id}" t)
- ("destruct as" "desa" "destruct # as #" t)
- ("destruct using" "desu" "destruct # using #" t)
- ("destruct" "des" "destruct " t "destruct")
- ;; ("discriminate" "dis" "discriminate" t "discriminate")
- ("discrR" "discrR" "discrR" t "discrR")
- ("double induction" "dind" "double induction # #" t "double\\s-+induction")
- ("eapply" "eap" "eapply #" t "eapply")
- ("eauto with arith" "eawa" "eauto with arith" t)
- ("eauto with" "eaw" "eauto with @{db}" t)
- ("eauto" "ea" "eauto" t "eauto")
- ("econstructor" "econs" "econstructor" t "econstructor")
- ("eexists" "eex" "eexists" t "eexists")
- ("eleft" "eleft" "eleft" t "eleft")
- ("elim using" "elu" "elim # using #" t)
- ("elim" "e" "elim #" t "elim")
- ("elimtype" "elt" "elimtype" "elimtype")
- ("eright" "erig" "eright" "eright")
- ("esplit" "esp" "esplit" t "esplit")
- ;; ("exact" "exa" "exact" t "exact")
- ("exists" "ex" "exists #" t "exists")
- ;; ("fail" "fa" "fail" nil)
- ;; ("field" "field" "field" t "field")
- ("firstorder" "fsto" "firstorder" t "firstorder")
- ("firstorder with" "fsto" "firstorder with #" t)
- ("firstorder with using" "fsto" "firstorder # with #" t)
- ("fold" "fold" "fold #" t "fold")
- ;; ("fourier" "four" "fourier" t "fourier")
- ("functional induction" "fi" "functional induction @{f} @{args}" t "functional\\s-+induction")
- ("generalize dependent" "gd" "generalize dependent #" t "generalize\\s-+dependent")
- ("generalize" "g" "generalize #" t "generalize")
- ("hnf" "hnf" "hnf" t "hnf")
- ("idtac" "id" "idtac" nil "idtac") ; also in tacticals with abbrev id
- ("idtac \"" "id\"" "idtac \"#\"") ; also in tacticals
- ("induction" "ind" "induction #" t "induction")
- ("induction using" "indu" "induction # using #" t)
- ("injection" "inj" "injection #" t "injection")
- ("instantiate" "inst" "instantiate" t "instantiate")
- ("intro" "i" "intro" t "intro")
- ("intro after" "ia" "intro # after #" t)
- ("intros" "is" "intros #" t "intros")
- ("intros! (guess names)" nil "intros #" nil nil coq-insert-intros)
- ("intros until" "isu" "intros until #" t)
- ("intuition" "intu" "intuition #" t "intuition")
- ("inversion" "inv" "inversion #" t "inversion")
- ("inversion in" "invi" "inversion # in #" t)
- ("inversion using" "invu" "inversion # using #" t)
- ("inversion using in" "invui" "inversion # using # in #" t)
- ("inversion_clear" "invcl" "inversion_clear" t "inversion_clear")
- ("lapply" "lap" "lapply" t "lapply")
- ("lazy" "lazy" "lazy beta [#] delta iota zeta" t "lazy")
- ("left" "left" "left" t "left")
- ("linear" "lin" "linear" t "linear")
- ("load" "load" "load" t "load")
- ("move after" "mov" "move # after #" t "move")
- ("omega" "o" "omega" t "omega")
- ("pattern" "pat" "pattern" t "pattern")
- ("pattern(s)" "pats" "pattern # , #" t)
- ("pattern at" "pata" "pattern # at #" t)
- ("pose" "po" "pose ( # := # )" t "pose")
- ("prolog" "prol" "prolog" t "prolog")
- ("quote" "quote" "quote" t "quote")
- ("quote []" "quote2" "quote # [#]" t)
- ("red" "red" "red" t "red")
- ("refine" "ref" "refine" t "refine")
- ;; ("reflexivity" "refl" "reflexivity #" t "reflexivity")
- ("rename into" "ren" "rename # into #" t "rename")
- ("replace with" "rep" "replace # with #" t "replace")
- ("replace with in" "repi" "replace # with # in #" t)
- ("rewrite <- in" "ri<" "rewrite <- # in #" t)
- ("rewrite <-" "r<" "rewrite <- #" t)
- ("rewrite in" "ri" "rewrite # in #" t)
- ("rewrite" "r" "rewrite #" t "rewrite")
- ("right" "rig" "right" t "right")
- ;; ("ring" "ring" "ring #" t "ring")
- ("set in * |-" "seth" "set ( # := #) in * |-" t)
- ("set in *" "set*" "set ( # := #) in *" t)
- ("set in |- *" "setg" "set ( # := #) in |- *" t)
- ("set in" "seti" "set ( # := #) in #" t)
- ("set" "set" "set ( # := #)" t "set")
- ("setoid_replace with" "strep2" "setoid_replace # with #" t "setoid_replace")
- ("setoid replace with" "strep" "setoid replace # with #" t "setoid\\s-+replace")
- ("setoid_rewrite" "strew" "setoid_rewrite #" t "setoid_rewrite")
- ("setoid rewrite" "strew" "setoid rewrite #" t "setoid\\s-+rewrite")
- ("simpl" "s" "simpl" t "simpl")
- ("simpl" "sa" "simpl # at #" t)
- ("simple destruct" "sdes" "simple destruct" t "simple\\s-+destruct")
- ("simple inversion" "sinv" "simple inversion" t "simple\\s-+inversion")
- ("simple induction" "sind" "simple induction" t "simple\\s-+induction")
- ("simplify_eq" "simeq" "simplify_eq @{hyp}" t "simplify_eq")
- ("specialize" "spec" "specialize" t "specialize")
- ("split" "sp" "split" t "split")
- ("split_Rabs" "spra" "splitRabs" t "split_Rabs")
- ("split_Rmult" "sprm" "splitRmult" t "split_Rmult")
- ("stepl" "stl" "stepl #" t "stepl")
- ("stepl by" "stlb" "stepl # by #" t)
- ("stepr" "str" "stepr #" t "stepr")
- ("stepr by" "strb" "stepr # by #" t)
- ("subst" "su" "subst #" t "subst")
- ("symmetry" "sy" "symmetry" t "symmetry")
- ("symmetry in" "syi" "symmetry in #" t)
- ;; ("tauto" "ta" "tauto" t "tauto")
- ("transitivity" "trans" "transitivity #" t "transitivity")
- ("trivial" "t" "trivial" t "trivial")
- ("trivial with" "tw" "trivial with @{db}" t)
- ("unfold" "u" "unfold #" t "unfold")
- ("unfold(s)" "us" "unfold # , #" t)
- ("unfold in" "unfi" "unfold # in #" t)
- ("unfold at" "unfa" "unfold # at #" t)
- ))
- "Coq tactics information list. See `coq-syntax-db' for syntax. "
- )
-
-(defvar coq-solve-tactics-db
- (append
- coq-user-solve-tactics-db
- '(
- ("assumption" "as" "assumption" t "assumption")
- ("by" "by" "by #" t "by")
- ("congruence" "cong" "congruence" t "congruence")
- ("contradiction" "contr" "contradiction" t "contradiction")
- ("decide equality" "deg" "decide equality" t "decide\\s-+equality")
- ("discriminate" "dis" "discriminate" t "discriminate")
- ("exact" "exa" "exact" t "exact")
- ("fourier" "four" "fourier" t "fourier")
- ("fail" "fa" "fail" nil)
- ("field" "field" "field" t "field")
- ("omega" "o" "omega" t "omega")
- ("reflexivity" "refl" "reflexivity #" t "reflexivity")
- ("ring" "ring" "ring #" t "ring")
- ("solve" nil "solve [ # | # ]" nil "solve")
- ("tauto" "ta" "tauto" t "tauto")
- ))
- "Coq tactic(al)s that solve a subgoal."
- )
-
-
-(defvar coq-tacticals-db
- (append
- coq-user-tacticals-db
- '(
- ("info" nil "info #" nil "info")
- ("first" nil "first [ # | # ]" nil "first")
- ("abstract" nil "abstract @{tac} using @{name}." nil "abstract")
- ("do" nil "do @{num} @{tac}" nil "do")
- ("idtac" nil "idtac") ; also in tactics
- ; ("idtac \"" nil "idtac \"#\"") ; also in tactics
- ("fail" "fa" "fail" nil "fail")
- ; ("fail \"" "fa\"" "fail" nil) ;
- ; ("orelse" nil "orelse #" t "orelse")
- ("repeat" nil "repeat #" nil "repeat")
- ("try" nil "try #" nil "try")
- ("progress" nil "progress #" nil "progress")
- ("|" nil "[ # | # ]" nil)
- ("||" nil "# || #" nil)
- ))
- "Coq tacticals information list. See `coq-syntax-db' for syntax.")
-
-
-
-
-(defvar coq-decl-db
- '(
- ("Axiom" "ax" "Axiom # : #" t "Axiom")
- ("Hint Constructors" "hc" "Hint Constructors # : #." t "Hint\\s-+Constructors")
- ("Hint Extern" "he" "Hint Extern @{cost} @{pat} => @{tac} : @{db}." t "Hint\\s-+Extern")
- ("Hint Immediate" "hi" "Hint Immediate # : @{db}." t "Hint\\s-+Immediate")
- ("Hint Resolve" "hr" "Hint Resolve # : @{db}." t "Hint\\s-+Resolve")
- ("Hint Rewrite ->" "hrw" "Hint Rewrite -> @{t1,t2...} using @{tac} : @{db}." t "Hint\\s-+Rewrite")
- ("Hint Rewrite <-" "hrw" "Hint Rewrite <- @{t1,t2...} using @{tac} : @{db}." t )
- ("Hint Unfold" "hu" "Hint Unfold # : #." t "Hint\\s-+Unfold")
- ("Hypothesis" "hyp" "Hypothesis #: #" t "Hypothesis")
- ("Hypotheses" "hyp" "Hypotheses #: #" t "Hypotheses")
- ("Parameter" "par" "Parameter #: #" t "Parameter")
- ("Parameters" "par" "Parameter #: #" t "Parameters")
- ("Conjecture" "conj" "Conjecture #: #." t "Conjecture")
- ("Variable" "v" "Variable #: #." t "Variable")
- ("Variables" "vs" "Variables # , #: #." t "Variables")
- ("Coercion" "coerc" "Coercion @{id} : @{typ1} >-> @{typ2}." t "Coercion")
- )
- "Coq declaration keywords information list. See `coq-syntax-db' for syntax."
- )
-
-(defvar coq-defn-db
- '(
- ("CoFixpoint" "cfix" "CoFixpoint # (#:#) : # :=\n#." t "CoFixpoint")
- ("CoInductive" "coindv" "CoInductive # : # :=\n|# : #." t "CoInductive")
- ("Declare Module : :=" "dm" "Declare Module # : # := #." t "Declare\\s-+Module")
- ("Declare Module <: :=" "dm2" "Declare Module # <: # := #." t);; careful
- ("Declare Module Import : :=" "dmi" "Declare Module # : # := #." t)
- ("Declare Module Import <: :=" "dmi2" "Declare Module # <: # := #." t);; careful
- ("Declare Module Export : :=" "dme" "Declare Module # : # := #." t)
- ("Declare Module Export <: :=" "dme2" "Declare Module # <: # := #." t);; careful
- ("Definition" "def" "Definition #:# := #." t "Definition");; careful
- ("Definition (2 args)" "def2" "Definition # (# : #) (# : #):# := #." t)
- ("Definition (3 args)" "def3" "Definition # (# : #) (# : #) (# : #):# := #." t)
- ("Definition (4 args)" "def4" "Definition # (# : #) (# : #) (# : #) (# : #):# := #." t)
- ("Program Definition" "pdef" "Program Definition #:# := #." t "Program\\s-+Definition");; careful ?
- ("Program Definition (2 args)" "pdef2" "Program Definition # (# : #) (# : #):# := #." t)
- ("Program Definition (3 args)" "pdef3" "Program Definition # (# : #) (# : #) (# : #):# := #." t)
- ("Program Definition (4 args)" "pdef4" "Program Definition # (# : #) (# : #) (# : #) (# : #):# := #." t)
- ("Derive Inversion" nil "Derive Inversion @{id} with # Sort #." t "Derive\\s-+Inversion")
- ("Derive Dependent Inversion" nil "Derive Dependent Inversion @{id} with # Sort #." t "Derive\\s-+Dependent\\s-+Inversion")
- ("Derive Inversion_clear" nil "Derive Inversion_clear @{id} with # Sort #." t)
- ("Fixpoint" "fix" "Fixpoint # (#:#) {struct @{arg}} : # :=\n#." t "Fixpoint")
- ("Program Fixpoint" "pfix" "Program Fixpoint # (#:#) {struct @{arg}} : # :=\n#." t "Program\\s-+Fixpoint")
- ("Program Fixpoint measure" "pfixm" "Program Fixpoint # (#:#) {measure @{arg} @{f}} : # :=\n#." t)
- ("Program Fixpoint wf" "pfixwf" "Program Fixpoint # (#:#) {wf @{arg} @{f}} : # :=\n#." t)
- ("Function" "func" "Function # (#:#) {struct @{arg}} : # :=\n#." t "Function")
- ("Function measure" "funcm" "Function # (#:#) {measure @{f} @{arg}} : # :=\n#." t)
- ("Function wf" "func wf" "Function # (#:#) {wf @{R} @{arg}} : # :=\n#." t)
- ("Functional Scheme with" "fsw" "Functional Scheme @{name} := Induction for @{fun} with @{mutfuns}." t )
- ("Functional Scheme" "fs" "Functional Scheme @{name} := Induction for @{fun}." t "Functional\\s-+Scheme")
- ("Inductive" "indv" "Inductive # : # := # : #." t "Inductive")
- ("Inductive (2 args)" "indv2" "Inductive # : # :=\n| # : #\n| # : #." t )
- ("Inductive (3 args)" "indv3" "Inductive # : # :=\n| # : #\n| # : #\n| # : #." t )
- ("Inductive (4 args)" "indv4" "Inductive # : # :=\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Inductive (5 args)" "indv5" "Inductive # : # :=\n| # : #\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Variant" "indv" "Variant # : # := # : #." t "Variant")
- ("Variant (2 args)" "indv2" "Variant # : # :=\n| # : #\n| # : #." t )
- ("Variant (3 args)" "indv3" "Variant # : # :=\n| # : #\n| # : #\n| # : #." t )
- ("Variant (4 args)" "indv4" "Variant # : # :=\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Variant (5 args)" "indv5" "Variant # : # :=\n| # : #\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Let" "Let" "Let # : # := #." t "Let")
- ("Ltac" "ltac" "Ltac # := #" t "Ltac")
- ("Module :=" "mo" "Module # : # := #." t ) ; careful
- ("Module <: :=" "mo2" "Module # <: # := #." t ) ; careful
- ("Module Import :=" "moi" "Module Import # : # := #." t ) ; careful
- ("Module Import <: :=" "moi2" "Module Import # <: # := #." t ) ; careful
- ("Module Export :=" "moe" "Module Export # : # := #." t ) ; careful
- ("Module Export <: :=" "moe2" "Module Export# <: # := #." t ) ; careful
- ("Record" "rec" "Record # : # := {\n# : #;\n# : # }" t "Record")
- ("Scheme" "sc" "Scheme @{name} := #." t "Scheme")
- ("Scheme Induction" "sci" "Scheme @{name} := Induction for # Sort #." t)
- ("Scheme Minimality" "scm" "Scheme @{name} := Minimality for # Sort #." t)
- ("Structure" "str" "Structure # : # := {\n# : #;\n# : # }" t "Structure")
- )
- "Coq definition keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-;; modules and section are indented like goal starters
-(defvar coq-goal-starters-db
- '(
- ("Add Morphism" "addmor" "Add Morphism @{f} : @{id}" t "Add\\s-+Morphism")
- ("Chapter" "chp" "Chapter # : #." t "Chapter")
- ("Corollary" "cor" "Corollary # : #.\nProof.\n#\nQed." t "Corollary")
- ("Declare Module :" "dmi" "Declare Module # : #.\n#\nEnd #." t)
- ("Declare Module <:" "dmi2" "Declare Module # <: #.\n#\nEnd #." t)
- ("Definition goal" "defg" "Definition #:#.\n#\nQed." t);; careful
- ("Fact" "fct" "Fact # : #." t "Fact")
- ("Goal" nil "Goal #." t "Goal")
- ("Lemma" "l" "Lemma # : #.\nProof.\n#\nQed." t "Lemma")
- ("Program Lemma" "pl" "Program Lemma # : #.\nProof.\n#\nQed." t "Program\\s-+Lemma")
- ("Module! (interactive)" nil "Module # : #.\n#\nEnd #." nil nil coq-insert-section-or-module)
- ("Module Type" "mti" "Module Type #.\n#\nEnd #." t "Module\\s-+Type") ; careful
- ("Module :" "moi" "Module # : #.\n#\nEnd #." t "Module") ; careful
- ("Module <:" "moi2" "Module # <: #.\n#\nEnd #." t ) ; careful
- ("Remark" "rk" "Remark # : #.\n#\nQed." t "Remark")
- ("Section" "sec" "Section #." t "Section")
- ("Theorem" "th" "Theorem # : #.\n#\nQed." t "Theorem")
- ("Program Theorem" "pth" "Program Theorem # : #.\nProof.\n#\nQed." t "Program\\s-+Theorem")
- ("Obligation" "obl" "Obligation #.\n#\nQed." t "Obligation")
- ("Next Obligation" "nobl" "Next Obligation.\n#\nQed." t "Next Obligation")
- )
- "Coq goal starters keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-;; command that are not declarations, definition or goal starters
-(defvar coq-other-commands-db
- '(
- ;; ("Abort" nil "Abort." t "Abort" nil nil);don't appear in menu
- ("About" nil "About #." nil "About")
- ("Add" nil "Add #." nil "Add" nil t)
- ("Add Abstract Ring" nil "Add Abstract Ring #." t "Add\\s-+Abstract\\s-+Ring")
- ("Add Abstract Semi Ring" nil "Add Abstract Semi Ring #." t "Add\\s-+Abstract\\s-+Semi\\s-+Ring")
- ("Add Field" nil "Add Field #." t "Add\\s-+Field")
- ("Add LoadPath" nil "Add LoadPath #." nil "Add\\s-+LoadPath")
- ("Add ML Path" nil "Add ML Path #." nil "Add\\s-+ML\\s-+Path")
- ("Add Morphism" nil "Add Morphism #." t "Add\\s-+Morphism")
- ("Add Printing" nil "Add Printing #." t "Add\\s-+Printing")
- ("Add Printing Constructor" nil "Add Printing Constructor #." t "Add\\s-+Printing\\s-+Constructor")
- ("Add Printing If" nil "Add Printing If #." t "Add\\s-+Printing\\s-+If")
- ("Add Printing Let" nil "Add Printing Let #." t "Add\\s-+Printing\\s-+Let")
- ("Add Printing Record" nil "Add Printing Record #." t "Add\\s-+Printing\\s-+Record")
- ("Add Rec LoadPath" nil "Add Rec LoadPath #." nil "Add\\s-+Rec\\s-+LoadPath")
- ("Add Rec ML Path" nil "Add Rec ML Path #." nil "Add\\s-+Rec\\s-+ML\\s-+Path")
- ("Add Ring" nil "Add Ring #." t "Add\\s-+Ring")
- ("Add Semi Ring" nil "Add Semi Ring #." t "Add\\s-+Semi\\s-+Ring")
- ("Add Setoid" nil "Add Setoid #." t "Add\\s-+Setoid")
- ("Admit Obligations" "oblsadmit" "Admit Obligations." nil "Admit\\s-+Obligations")
- ("Bind Scope" "bndsc" "Bind Scope @{scope} with @{type}" t "Bind\\s-+Scope")
- ("Canonical Structure" nil "Canonical Structure #." t "Canonical\\s-+Structure")
- ("Cd" nil "Cd #." nil "Cd")
- ("Check" nil "Check" nil "Check")
- ("Close Local Scope" "cllsc" "Close Local Scope #" t "Close\\s-+Local\\s-+Scope")
- ("Close Scope" "clsc" "Close Scope #" t "Close\\s-+Scope")
- ("Comments" nil "Comments #." nil "Comments")
- ("Delimit Scope" "delsc" "Delimit Scope @{scope} with @{id}." t "Delimit\\s-+Scope" )
- ("Eval" nil "Eval #." nil "Eval")
- ("Export" nil "Export #." t "Export")
- ("Extract Constant" "extrc" "Extract Constant @{id} => \"@{id}\"." nil "Extract\\s-+Constant")
- ("Extract Inlined Constant" "extric" "Extract Inlined Constant @{id} => \"@{id}\"." nil "Extract\\s-+Inlined\\s-+Constant")
- ("Extract Inductive" "extri" "Extract Inductive @{id} => \"@{id}\" [\"@{id}\" \"@{id...}\"]." nil "Extract")
- ("Extraction" "extr" "Extraction @{id}." nil "Extraction")
- ("Extraction (in a file)" "extrf" "Extraction \"@{file}\" @{id}." nil)
- ("Extraction Inline" nil "Extraction Inline #." t "Extraction\\s-+Inline")
- ("Extraction NoInline" nil "Extraction NoInline #." t "Extraction\\s-+NoInline")
- ("Extraction Language" "extrlang" "Extraction Language #." t "Extraction\\s-+Language")
- ("Extraction Library" "extrl" "Extraction Library @{id}." nil "Extraction\\s-+Library")
- ("Focus" nil "Focus #." nil "Focus")
- ("Identity Coercion" nil "Identity Coercion #." t "Identity\\s-+Coercion")
- ("Implicit Arguments Off" nil "Implicit Arguments Off." t "Implicit\\s-+Arguments\\s-+Off")
- ("Implicit Arguments On" nil "Implicit Arguments On." t "Implicit\\s-+Arguments\\s-+On")
- ("Implicit Arguments" nil "Implicit Arguments # [#]." t "Implicit\\s-+Arguments")
- ("Import" nil "Import #." t "Import")
- ("Infix" "inf" "Infix \"#\" := # (at level #) : @{scope}." t "Infix")
- ("Inspect" nil "Inspect #." nil "Inspect")
- ("Locate" nil "Locate" nil "Locate")
- ("Locate File" nil "Locate File \"#\"." nil "Locate\\s-+File")
- ("Locate Library" nil "Locate Library #." nil "Locate\\s-+Library")
- ("Notation (assoc)" "notas" "Notation \"#\" := # (at level #, # associativity)." t)
- ("Notation (at assoc)" "notassc" "Notation \"#\" := # (at level #, # associativity) : @{scope}." t)
- ("Notation (at at scope)" "notasc" "Notation \"#\" := # (at level #, # at level #) : @{scope}." t)
- ("Notation (at at)" "nota" "Notation \"#\" := # (at level #, # at level #)." t)
- ("Notation (only parsing)" "notsp" "Notation # := # (only parsing)." t)
- ("Notation Local (only parsing)" "notslp" "Notation Local # := # (only parsing)." t)
- ("Notation Local" "notsl" "Notation Local # := #." t "Notation\\s-+Local")
- ("Notation (simple)" "nots" "Notation # := #." t "Notation")
- ("Opaque" nil "Opaque #." nil "Opaque")
- ("Obligations Tactic" nil "Obligations Tactic := #." t "Obligations\\s-+Tactic")
- ("Open Local Scope" "oplsc" "Open Local Scope #" t "Open\\s-+Local\\s-+Scope")
- ("Open Scope" "opsc" "Open Scope #" t "Open\\s-+Scope")
- ("Print Coercions" nil "Print Coercions." nil "Print\\s-+Coercions")
- ("Print Hint" nil "Print Hint." nil "Print\\s-+Hint" coq-PrintHint)
- ("Print" "p" "Print #." nil "Print")
- ("Qed" nil "Qed." nil "Qed")
- ("Pwd" nil "Pwd." nil "Pwd")
- ("Recursive Extraction" "recextr" "Recursive Extraction @{id}." nil "Recursive\\s-+Extraction")
- ("Recursive Extraction Library" "recextrl" "Recursive Extraction Library @{id}." nil "Recursive\\s-+Extraction\\s-+Library")
- ("Recursive Extraction Module" "recextrm" "Recursive Extraction Module @{id}." nil "Recursive\\s-+Extraction\\s-+Module")
- ("Remove LoadPath" nil "Remove LoadPath" nil "Remove\\s-+LoadPath")
- ("Remove LoadPath" nil "Remove LoadPath" nil "Remove\\s-+LoadPath")
- ("Remove Printing If" nil "Remove Printing If #." t "Remove\\s-+Printing\\s-+If")
- ("Remove Printing Let" nil "Remove Printing Let #." t "Remove\\s-+Printing\\s-+Let")
- ("Require Export" nil "Require Export #." t "Require\\s-+Export")
- ("Require Import" nil "Require Import #." t "Require\\s-+Import")
- ("Require" nil "Require #." t "Require")
- ("Reserved Notation" nil "Reserved Notation" nil "Reserved\\s-+Notation")
- ("Reset Extraction Inline" nil "Reset Extraction Inline." t "Reset\\s-+Extraction\\s-+Inline")
- ("Search" nil "Search #" nil "Search")
- ("SearchAbout" nil "SearchAbout #" nil "SearchAbout")
- ("SearchPattern" nil "SearchPattern #" nil "SearchPattern")
- ("SearchRewrite" nil "SearchRewrite #" nil "SearchRewrite")
- ("Set Extraction AutoInline" nil "Set Extraction AutoInline" t "Set\\s-+Extraction\\s-+AutoInline")
- ("Set Extraction Optimize" nil "Set Extraction Optimize" t "Set\\s-+Extraction\\s-+Optimize")
- ("Set Implicit Arguments" nil "Set Implicit Arguments" t "Set\\s-+Implicit\\s-+Arguments")
- ("Set Strict Implicit" nil "Set Strict Implicit" t "Set\\s-+Strict\\s-+Implicit")
- ("Set Printing Synth" nil "Set Printing Synth" t "Set\\s-+Printing\\s-+Synth")
- ("Set Printing Wildcard" nil "Set Printing Wildcard" t "Set\\s-+Printing\\s-+Wildcard")
- ("Set Printing All" "sprall" "Set Printing All" t "Set\\s-+Printing\\s-+All")
- ("Set Printing Records" nil "Set Printing Records" t "Set\\s-+Printing\\s-+Records")
- ("Set Hyps Limit" nil "Set Hyps Limit #." nil "Set\\s-+Hyps\\s-+Limit")
- ("Set Printing Coercions" nil "Set Printing Coercions." t "Set\\s-+Printing\\s-+Coercions")
- ("Set Printing Notations" "sprn" "Set Printing Notations" t "Set\\s-+Printing\\s-+Notations")
- ("Set Undo" nil "Set Undo #." nil "Set\\s-+Undo")
- ("Show" nil "Show #." nil "Show")
- ("Solve Obligations" "oblssolve" "Solve Obligations using #." nil "Solve\\s-+Obligations")
- ("Test" nil "Test" nil "Test" nil t)
- ("Test Printing Depth" nil "Test Printing Depth." nil "Test\\s-+Printing\\s-+Depth")
- ("Test Printing If" nil "Test Printing If #." nil "Test\\s-+Printing\\s-+If")
- ("Test Printing Let" nil "Test Printing Let #." nil "Test\\s-+Printing\\s-+Let")
- ("Test Printing Synth" nil "Test Printing Synth." nil "Test\\s-+Printing\\s-+Synth")
- ("Test Printing Width" nil "Test Printing Width." nil "Test\\s-+Printing\\s-+Width")
- ("Test Printing Wildcard" nil "Test Printing Wildcard." nil "Test\\s-+Printing\\s-+Wildcard")
- ("Transparent" nil "Transparent #." nil "Transparent")
- ("Unfocus" nil "Unfocus." nil "Unfocus")
- ("Unset Extraction AutoInline" nil "Unset Extraction AutoInline" t "Unset\\s-+Extraction\\s-+AutoInline")
- ("Unset Extraction Optimize" nil "Unset Extraction Optimize" t "Unset\\s-+Extraction\\s-+Optimize")
- ("Unset Implicit Arguments" nil "Unset Implicit Arguments" t "Unset\\s-+Implicit\\s-+Arguments")
- ("Unset Strict Implicit" nil "Unset Strict Implicit" t "Unset\\s-+Strict\\s-+Implicit")
- ("Unset Printing Synth" nil "Unset Printing Synth" t "Unset\\s-+Printing\\s-+Synth")
- ("Unset Printing Wildcard" nil "Unset Printing Wildcard" t "Unset\\s-+Printing\\s-+Wildcard")
- ("Unset Hyps Limit" nil "Unset Hyps Limit" nil "Unset\\s-+Hyps\\s-+Limit")
- ("Unset Printing All" "unsprall" "Unset Printing All" nil "Unset\\s-+Printing\\s-+All")
- ("Unset Printing Coercion" nil "Unset Printing Coercion #." t "Unset\\s-+Printing\\s-+Coercion")
- ("Unset Printing Coercions" nil "Unset Printing Coercions." nil "Unset\\s-+Printing\\s-+Coercions")
- ("Unset Printing Notations" "unsprn" "Unset Printing Notations" nil "Unset\\s-+Printing\\s-+Notations")
- ("Unset Undo" nil "Unset Undo." nil "Unset\\s-+Undo")
- ; ("print" "pr" "print #" "print")
- )
- "Command that are not declarations, definition or goal starters."
- )
-
-(defvar coq-commands-db
- (append coq-decl-db coq-defn-db coq-goal-starters-db
- coq-other-commands-db coq-user-commands-db)
- "Coq all commands keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-
-(defvar coq-terms-db
- '(
- ("fun (1 args)" "f" "fun #:# => #" nil "fun")
- ("fun (2 args)" "f2" "fun (#:#) (#:#) => #")
- ("fun (3 args)" "f3" "fun (#:#) (#:#) (#:#) => #")
- ("fun (4 args)" "f4" "fun (#:#) (#:#) (#:#) (#:#) => #")
- ("forall" "fo" "forall #:#,#" nil "forall")
- ("forall (2 args)" "fo2" "forall (#:#) (#:#), #")
- ("forall (3 args)" "fo3" "forall (#:#) (#:#) (#:#), #")
- ("forall (4 args)" "fo4" "forall (#:#) (#:#) (#:#) (#:#), #")
- ("if" "if" "if # then # else #" nil "if")
- ("let in" "li" "let # := # in #" nil "let")
- ("match! (from type)" nil "" nil "match" coq-insert-match)
- ("match with" "m" "match # with\n| # => #\nend")
- ("match with 2" "m2" "match # with\n| # => #\n| # => #\nend")
- ("match with 3" "m3" "match # with\n| # => #\n| # => #\n| # => #\nend")
- ("match with 4" "m4" "match # with\n| # => #\n| # => #\n| # => #\n| # => #\nend")
- ("match with 5" "m5" "match # with\n| # => #\n| # => #\n| # => #\n| # => #\n| # => #\nend")
- )
- "Coq terms keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-
-
-
-
-
-
- ;;; Goals (and module/sections) starters detection
-
-
-;; ----- keywords for font-lock.
-
-;; FIXME da: this one function breaks the nice configuration of Proof General:
-;; would like to have proof-goal-regexp instead.
-;; Unfortunately Coq allows "Definition" and friends to perhaps have a goal,
-;; so it appears more difficult than just a proof-goal-regexp setting.
-;; Future improvement may simply to be allow a function value for
-;; proof-goal-regexp.
-
-;; FIXME Pierre: the right way IMHO here would be to set a span
-;; property 'goalcommand when coq prompt says it (if the name of
-;; current proof has changed).
-
-;; excerpt of Jacek Chrzaszcz, implementer of the module system: sorry
-;; for the french:
-;;*) suivant les suggestions de Chritine, pas de mode preuve dans un type de
-;; module (donc pas de Definition truc:machin. Lemma, Theorem ... )
-;;
-;; *) la commande Module M [ ( : | <: ) MTYP ] [ := MEXPR ] est valable
-;; uniquement hors d'un MT
-;; - si :=MEXPR est absent, elle demarre un nouveau module interactif
-;; - si :=MEXPR est present, elle definit un module
-;; (la fonction vernac_define_module dans toplevel/vernacentries)
-;;
-;; *) la nouvelle commande Declare Module M [ ( : | <: ) MTYP ] [ := MEXPR ]
-;; est valable uniquement dans un MT
-;; - si :=MEXPR absent, :MTYP absent, elle demarre un nouveau module
-;; interactif
-;; - si (:=MEXPR absent, :MTYP present)
-;; ou (:=MEXPR present, :MTYP absent)
-;; elle declare un module.
-;; (la fonction vernac_declare_module dans toplevel/vernacentries)
-
-(defun coq-count-match (regexp strg)
- "Count the number of (maximum, non overlapping) matching substring
- of STRG matching REGEXP. Empty match are counted once."
- (let ((nbmatch 0) (str strg))
- (while (and (proof-string-match regexp str) (not (string-equal str "")))
- (incf nbmatch)
- (if (= (match-end 0) 0) (setq str (substring str 1))
- (setq str (substring str (match-end 0)))))
- nbmatch))
-
-;; This function is used for amalgamating a proof into a single
-;; goal-save region (proof-goal-command-p used in
-;; proof-done-advancing-save in generic/proof-script.el) for coq <
-;; 8.0. It is the test when looking backward the start of the proof.
-;; It is NOT used for coq > v8.1
-;; (coq-find-and-forget in gallina.el uses state numbers, proof numbers and
-;; lemma names given in the prompt)
-
-;; compatibility with v8.0, will delete it some day
-(defun coq-goal-command-str-v80-p (str)
- "See `coq-goal-command-p'."
- (let* ((match (coq-count-match "\\<match\\>" str))
- (with (coq-count-match "\\<with\\>" str))
- (letwith (+ (coq-count-match "\\<let\\>" str) (- with match)))
- (affect (coq-count-match ":=" str)))
-
- (and (proof-string-match coq-goal-command-regexp str)
- (not ;
- (and
- (proof-string-match "\\`\\(Local\\|Definition\\|Lemma\\|Module\\)\\>" str)
- (not (= letwith affect))))
- (not (proof-string-match "\\`Declare\\s-+Module\\(\\w\\|\\s-\\|<\\)*:" str))
- )
- )
- )
-
-;; Module and or section openings are detected syntactically. Module
-;; *openings* are difficult to detect because there can be Module
-;; ...with X := ... . So we need to count :='s to detect real openings.
-
-;; TODO: have opened section/chapter in the prompt too, and get rid of
-;; syntactical tests everywhere
-(defun coq-module-opening-p (str)
- "Decide whether STR is a module or section opening or not.
-Used by `coq-goal-command-p'"
- (let* ((match (coq-count-match "\\<match\\>" str))
- (with (coq-count-match "\\<with\\>" str))
- (letwith (+ (coq-count-match "\\<let\\>" str) (- with match)))
- (affect (coq-count-match ":=" str)))
- (and (proof-string-match "\\`\\(Module\\)\\>" str)
- (= letwith affect))
- ))
-
-(defun coq-section-command-p (str)
- (proof-string-match "\\`\\(Section\\|Chapter\\)\\>" str))
-
-
-(defun coq-goal-command-str-v81-p (str)
- "Decide syntactically whether STR is a goal start or not. Use
- `coq-goal-command-p-v81' on a span instead if possible."
- (coq-goal-command-str-v80-p str)
- )
-
-;; This is the function that tests if a SPAN is a goal start. All it
-;; has to do is look at the 'goalcmd attribute of the span.
-;; It also looks if this is not a module start.
-
-;; TODO: have also attributes 'modulecmd and 'sectioncmd. This needs
-;; something in the coq prompt telling the name of all opened modules
-;; (like for open goals), and use it to set goalcmd --> no more need
-;; to look at Modules and section (actually indentation will still
-;; need it)
-(defun coq-goal-command-p-v81 (span)
- "see `coq-goal-command-p'"
- (or (span-property span 'goalcmd)
- ;; module and section starts are detected here
- (let ((str (or (span-property span 'cmd) "")))
- (or (coq-section-command-p str)
- (coq-module-opening-p str))
- )))
-
-;; In coq > 8.1 This is used only for indentation.
-(defun coq-goal-command-str-p (str)
- "Decide whether argument is a goal or not. Use
- `coq-goal-command-p' on a span instead if posible."
- (cond
- (coq-version-is-V8-1 (coq-goal-command-str-v81-p str))
- (coq-version-is-V8-0 (coq-goal-command-str-v80-p str))
- (t (coq-goal-command-str-v80-p str));; this is temporary
- ))
-
-;; This is used for backtracking
-(defun coq-goal-command-p (span)
- "Decide whether argument is a goal or not."
- (cond
- (coq-version-is-V8-1 (coq-goal-command-p-v81 span))
- (coq-version-is-V8-0 (coq-goal-command-str-v80-p (span-property span 'cmd)))
- (t (coq-goal-command-str-v80-p (span-property span 'cmd)));; this is temporary
- ))
-
-(defvar coq-keywords-save-strict
- '("Defined"
- "Qed"
- "End"
- "Admitted"
- "Abort"
- ))
-
-(defvar coq-keywords-save
- (append coq-keywords-save-strict '("Proof"))
- )
-
-(defun coq-save-command-p (span str)
- "Decide whether argument is a Save command or not"
- (or (proof-string-match coq-save-command-regexp-strict str)
- (and (proof-string-match "\\`Proof\\>" str)
- (not (proof-string-match "Proof\\s-*\\(\\.\\|\\<with\\>\\)" str)))
- )
- )
-
-
-(defvar coq-keywords-kill-goal
- '("Abort"))
-
-;; Following regexps are all state changing
-(defvar coq-keywords-state-changing-misc-commands
- (coq-build-regexp-list-from-db coq-commands-db 'filter-state-changing))
-
-(defvar coq-keywords-goal
- (coq-build-regexp-list-from-db coq-goal-starters-db))
-
-(defvar coq-keywords-decl
- (coq-build-regexp-list-from-db coq-decl-db))
-
-(defvar coq-keywords-defn
- (coq-build-regexp-list-from-db coq-defn-db))
-
-
-(defvar coq-keywords-state-changing-commands
- (append
- coq-keywords-state-changing-misc-commands
- coq-keywords-decl ; all state changing
- coq-keywords-defn ; idem
- coq-keywords-goal)) ; idem
-
-
-;;
-(defvar coq-keywords-state-preserving-commands
- (coq-build-regexp-list-from-db coq-commands-db 'filter-state-preserving))
-
-;; concat this is faster that redoing coq-build-regexp-list-from-db on
-;; whole commands-db
-(defvar coq-keywords-commands
- (append coq-keywords-state-changing-commands
- coq-keywords-state-preserving-commands)
- "All commands keyword.")
-
-(defvar coq-solve-tactics
- (coq-build-regexp-list-from-db coq-solve-tactics-db)
- "Keywords for closing tactic(al)s.")
-
-(defvar coq-tacticals
- (coq-build-regexp-list-from-db coq-tacticals-db)
- "Keywords for tacticals in a Coq script.")
-
-
- ;; From JF Monin:
-(defvar coq-reserved
- (append
- coq-user-reserved-db
- '(
- "False" "True" "after" "as" "cofix" "fix" "forall" "fun" "match"
- "return" "struct" "else" "end" "if" "in" "into" "let" "then"
- "using" "with" "beta" "delta" "iota" "zeta" "after" "until"
- "at" "Sort" "Time"))
- "Reserved keywords of Coq.")
-
-
-(defvar coq-state-changing-tactics
- (coq-build-regexp-list-from-db coq-tactics-db 'filter-state-changing))
-
-(defvar coq-state-preserving-tactics
- (coq-build-regexp-list-from-db coq-tactics-db 'filter-state-preserving))
-
-
-(defvar coq-tactics
- (append coq-state-changing-tactics coq-state-preserving-tactics))
-
-(defvar coq-retractable-instruct
- (append coq-state-changing-tactics coq-keywords-state-changing-commands))
-
-(defvar coq-non-retractable-instruct
- (append coq-state-preserving-tactics
- coq-keywords-state-preserving-commands))
-
-(defvar coq-keywords
- (append coq-keywords-goal coq-keywords-save coq-keywords-decl
- coq-keywords-defn coq-keywords-commands)
- "All keywords in a Coq script.")
-
-
-
-(defvar coq-symbols
- '("|"
- "||"
- ":"
- ";"
- ","
- "("
- ")"
- "["
- "]"
- "{"
- "}"
- ":="
- "=>"
- "->"
- ".")
- "Punctuation Symbols used by Coq.")
-
-;; ----- regular expressions
-(defvar coq-error-regexp "^\\(Error:\\|Discarding pattern\\|Syntax error:\\|System Error:\\|User Error:\\|User error:\\|Anomaly[:.]\\|Toplevel input[,]\\)"
- "A regexp indicating that the Coq process has identified an error.")
-
-(defvar coq-id proof-id)
-(defvar coq-id-shy "\\(?:\\w\\(?:\\w\\|\\s_\\)*\\)")
-
-(defvar coq-ids (proof-ids coq-id " "))
-
-(defun coq-first-abstr-regexp (paren end)
- (concat paren "\\s-*\\(" coq-ids "\\)\\s-*" end))
-
-(defcustom coq-variable-highlight-enable t
- "Activates partial bound variable highlighting"
- :type 'boolean
- :group 'coq)
-
-
-(defvar coq-font-lock-terms
- (if coq-variable-highlight-enable
- (list
- ;; lambda binders
- (list (coq-first-abstr-regexp "\\<fun\\>" "\\(?:=>\\|:\\)") 1 'font-lock-variable-name-face)
- ;; forall binder
- (list (coq-first-abstr-regexp "\\<forall\\>" "\\(?:,\\|:\\)") 1 'font-lock-variable-name-face)
- ; (list "\\<forall\\>"
- ; (list 0 font-lock-type-face)
- ; (list (concat "[^ :]\\s-*\\(" coq-ids "\\)\\s-*") nil nil
- ; (list 0 font-lock-variable-name-face)))
- ;; parenthesized binders
- (list (coq-first-abstr-regexp "(" ":[ a-zA-Z]") 1 'font-lock-variable-name-face)
- ))
- "*Font-lock table for Coq terms.")
-
-
-
-;; According to Coq, "Definition" is both a declaration and a goal.
-;; It is understood here as being a goal. This is important for
-;; recognizing global identifiers, see coq-global-p.
-(defconst coq-save-command-regexp-strict
- (proof-anchor-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save-strict)
- "\\)")))
-(defconst coq-save-command-regexp
- (proof-anchor-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save)
- "\\)")))
-(defconst coq-save-with-hole-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save-strict)
- "\\)\\s-+\\(" coq-id "\\)\\s-*\\."))
-
-(defconst coq-goal-command-regexp
- (proof-anchor-regexp (proof-ids-to-regexp coq-keywords-goal)))
-
-(defconst coq-goal-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-goal)
- "\\)\\s-+\\(" coq-id "\\)\\s-*:?"))
-
-(defconst coq-decl-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-decl)
- "\\)\\s-+\\(" coq-ids "\\)\\s-*:"))
-
-;; (defconst coq-decl-with-hole-regexp
-;; (if coq-variable-highlight-enable coq-decl-with-hole-regexp-1 'nil))
-
-(defconst coq-defn-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-defn)
- "\\)\\s-+\\(" coq-id "\\)"))
-
-;; must match:
-;; "with f x y :" (followed by = or not)
-;; "with f x y (z:" (not followed by =)
-;; BUT NOT:
-;; "with f ... (x:="
-;; "match ... with .. => "
-(defconst coq-with-with-hole-regexp
- (concat "\\(with\\)\\s-+\\(" coq-id "\\)\\s-*\\([^=(.]*:\\|[^(]*(\\s-*"
- coq-id "\\s-*:[^=]\\)"))
-;; marche aussi a peu pres
-;; (concat "\\(with\\)\\s-+\\(" coq-id "\\)\\s-*\\([^(.]*:\\|.*)[^(.]*:=\\)"))
-;;"\\<Prop\\>\\|\\<Set\\>\\|\\<Type\\>"
-(defvar coq-font-lock-keywords-1
- (append
- coq-font-lock-terms
- (list
- (cons (proof-ids-to-regexp coq-solve-tactics) 'coq-solve-tactics-face)
- (cons (proof-ids-to-regexp coq-keywords) 'font-lock-keyword-face)
- (cons (proof-ids-to-regexp coq-reserved) 'font-lock-type-face)
- (cons (proof-ids-to-regexp coq-tactics ) 'proof-tactics-name-face)
- (cons (proof-ids-to-regexp coq-tacticals) 'proof-tacticals-name-face)
- (cons (proof-ids-to-regexp (list "Set" "Type" "Prop")) 'font-lock-type-face)
- (cons "============================" 'font-lock-keyword-face)
- (cons "Subtree proved!" 'font-lock-keyword-face)
- (cons "subgoal [0-9]+ is:" 'font-lock-keyword-face)
- (list "^\\([^ \n]+\\) \\(is defined\\)"
- (list 2 'font-lock-keyword-face t)
- (list 1 'font-lock-function-name-face t))
-
- (list coq-goal-with-hole-regexp 2 'font-lock-function-name-face))
- (if coq-variable-highlight-enable (list (list coq-decl-with-hole-regexp 2 'font-lock-variable-name-face)))
- (list
- (list coq-defn-with-hole-regexp 2 'font-lock-function-name-face)
- (list coq-with-with-hole-regexp 2 'font-lock-function-name-face)
- (list coq-save-with-hole-regexp 2 'font-lock-function-name-face)
- ;; Remove spurious variable and function faces on commas.
- '(proof-zap-commas))))
-
-(defvar coq-font-lock-keywords coq-font-lock-keywords-1)
-
-(defun coq-init-syntax-table ()
- "Set appropriate values for syntax table in current buffer."
-
- (modify-syntax-entry ?\$ ".")
- (modify-syntax-entry ?\/ ".")
- (modify-syntax-entry ?\\ ".")
- (modify-syntax-entry ?+ ".")
- (modify-syntax-entry ?- ".")
- (modify-syntax-entry ?= ".")
- (modify-syntax-entry ?% ".")
- (modify-syntax-entry ?< ".")
- (modify-syntax-entry ?> ".")
- (modify-syntax-entry ?\& ".")
- (modify-syntax-entry ?_ "_")
- (modify-syntax-entry ?\' "_")
- (modify-syntax-entry ?\| ".")
-
-;; should maybe be "_" but it makes coq-find-and-forget (in gallina.el) bug
- (modify-syntax-entry ?\. ".")
-
- (condition-case nil
- ;; Try to use Emacs-21's nested comments.
- (modify-syntax-entry ?\* ". 23n")
- ;; Revert to non-nested comments if that failed.
- (error (modify-syntax-entry ?\* ". 23")))
- (modify-syntax-entry ?\( "()1")
- (modify-syntax-entry ?\) ")(4"))
-
-
-(defconst coq-generic-expression
- (mapcar (lambda (kw)
- (list (capitalize kw)
- (concat "\\<" kw "\\>" "\\s-+\\(\\w+\\)\\W" )
- 1))
- (append coq-keywords-decl coq-keywords-defn coq-keywords-goal)))
-
-(provide 'gallina-syntax)
- ;;; gallina-syntax.el ends here
-
-; Local Variables: ***
-; indent-tabs-mode: nil ***
-; End: ***
diff --git a/tools/gallina.el b/tools/gallina.el
deleted file mode 100644
index cbc13118a..000000000
--- a/tools/gallina.el
+++ /dev/null
@@ -1,142 +0,0 @@
-;; gallina.el --- Coq mode editing commands for Emacs
-;;
-;; Jean-Christophe Filliatre, march 1995
-;; Shamelessly copied from caml.el, Xavier Leroy, july 1993.
-;;
-;; modified by Marco Maggesi <maggesi@math.unifi.it> for gallina-inferior
-
-; compatibility code for proofgeneral files
-(require 'coq-font-lock)
-; ProofGeneral files. remember to remove coq version tests in
-; gallina-syntax.el
-(require 'gallina-syntax)
-
-(defvar coq-mode-map nil
- "Keymap used in Coq mode.")
-(if coq-mode-map
- ()
- (setq coq-mode-map (make-sparse-keymap))
- (define-key coq-mode-map "\t" 'coq-indent-command)
- (define-key coq-mode-map "\M-\t" 'coq-unindent-command)
- (define-key coq-mode-map "\C-c\C-c" 'compile)
-)
-
-(defvar coq-mode-syntax-table nil
- "Syntax table in use in Coq mode buffers.")
-(if coq-mode-syntax-table
- ()
- (setq coq-mode-syntax-table (make-syntax-table))
- ; ( is first character of comment start
- (modify-syntax-entry ?\( "()1" coq-mode-syntax-table)
- ; * is second character of comment start,
- ; and first character of comment end
- (modify-syntax-entry ?* ". 23" coq-mode-syntax-table)
- ; ) is last character of comment end
- (modify-syntax-entry ?\) ")(4" coq-mode-syntax-table)
- ; quote is a string-like delimiter (for character literals)
- (modify-syntax-entry ?' "\"" coq-mode-syntax-table)
- ; quote is part of words
- (modify-syntax-entry ?' "w" coq-mode-syntax-table)
-)
-
-(defvar coq-mode-indentation 2
- "*Indentation for each extra tab in Coq mode.")
-
-(defun coq-mode-variables ()
- (set-syntax-table coq-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'comment-start)
- (setq comment-start "(* ")
- (make-local-variable 'comment-end)
- (setq comment-end " *)")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "(\\*+ *")
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments nil)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'coq-indent-command)
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-defaults '(coq-font-lock-keywords-1)))
-
-;;; The major mode
-
-(defun coq-mode ()
- "Major mode for editing Coq code.
-Tab at the beginning of a line indents this line like the line above.
-Extra tabs increase the indentation level.
-\\{coq-mode-map}
-The variable coq-mode-indentation indicates how many spaces are
-inserted for each indentation level."
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'coq-mode)
- (setq mode-name "coq")
- (use-local-map coq-mode-map)
- (coq-mode-variables)
- (run-hooks 'coq-mode-hook))
-
-;;; Indentation stuff
-
-(defun coq-in-indentation ()
- "Tests whether all characters between beginning of line and point
-are blanks."
- (save-excursion
- (skip-chars-backward " \t")
- (bolp)))
-
-(defun coq-indent-command ()
- "Indent the current line in Coq mode.
-When the point is at the beginning of an empty line, indent this line like
-the line above.
-When the point is at the beginning of an indented line
-\(i.e. all characters between beginning of line and point are blanks\),
-increase the indentation by one level.
-The indentation size is given by the variable coq-mode-indentation.
-In all other cases, insert a tabulation (using insert-tab)."
- (interactive)
- (let* ((begline
- (save-excursion
- (beginning-of-line)
- (point)))
- (current-offset
- (- (point) begline))
- (previous-indentation
- (save-excursion
- (if (eq (forward-line -1) 0) (current-indentation) 0))))
- (cond ((and (bolp)
- (looking-at "[ \t]*$")
- (> previous-indentation 0))
- (indent-to previous-indentation))
- ((coq-in-indentation)
- (indent-to (+ current-offset coq-mode-indentation)))
- (t
- (insert-tab)))))
-
-(defun coq-unindent-command ()
- "Decrease indentation by one level in Coq mode.
-Works only if the point is at the beginning of an indented line
-\(i.e. all characters between beginning of line and point are blanks\).
-Does nothing otherwise."
- (interactive)
- (let* ((begline
- (save-excursion
- (beginning-of-line)
- (point)))
- (current-offset
- (- (point) begline)))
- (if (and (>= current-offset coq-mode-indentation)
- (coq-in-indentation))
- (backward-delete-char-untabify coq-mode-indentation))))
-
-;;; gallina.el ends here
-
-(provide 'gallina)
diff --git a/tools/gallina.ml b/tools/gallina.ml
deleted file mode 100644
index c7ff76bec..000000000
--- a/tools/gallina.ml
+++ /dev/null
@@ -1,63 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Gallina_lexer
-
-let vfiles = ref ([] : string list)
-
-let option_moins = ref false
-
-let option_stdout = ref false
-
-let traite_fichier f =
- try
- let chan_in = open_in (f^".v") in
- let buf = Lexing.from_channel chan_in in
- if not !option_stdout then chan_out := open_out (f ^ ".g");
- try
- while true do Gallina_lexer.action buf done
- with Fin_fichier -> begin
- flush !chan_out;
- close_in chan_in;
- if not !option_stdout then close_out !chan_out
- end
- with Sys_error _ ->
- ()
-
-let traite_stdin () =
- try
- let buf = Lexing.from_channel stdin in
- try
- while true do Gallina_lexer.action buf done
- with Fin_fichier ->
- flush !chan_out
- with Sys_error _ ->
- ()
-
-let _ =
- let lg_command = Array.length Sys.argv in
- if lg_command < 2 then begin
- output_string stderr "Usage: gallina [-] [-stdout] file1 file2 ...\n";
- flush stderr;
- exit 1
- end;
- let treat = function
- | "-" -> option_moins := true
- | "-stdout" -> option_stdout := true
- | "-nocomments" -> comments := false
- | f ->
- if Filename.check_suffix f ".v" then
- vfiles := (Filename.chop_suffix f ".v") :: !vfiles
- in
- Array.iter treat Sys.argv;
- if !option_moins then
- traite_stdin ()
- else
- List.iter traite_fichier !vfiles
diff --git a/tools/gallina_lexer.mll b/tools/gallina_lexer.mll
deleted file mode 100644
index 1a594aebb..000000000
--- a/tools/gallina_lexer.mll
+++ /dev/null
@@ -1,126 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-{
-
- let chan_out = ref stdout
-
- let comment_depth = ref 0
- let cRcpt = ref 0
- let comments = ref true
- let print s = output_string !chan_out s
-
- exception Fin_fichier
-
-}
-
-let space = [' ' '\t' '\n' '\r']
-let enddot = '.' (' ' | '\t' | '\n' | '\r' | eof)
-
-rule action = parse
- | "Theorem" space { print "Theorem "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Lemma" space { print "Lemma "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Fact" space { print "Fact "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Remark" space { print "Remark "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Goal" space { print "Goal "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Correctness" space { print "Correctness "; body_pgm lexbuf;
- cRcpt := 1; action lexbuf }
- | "Definition" space { print "Definition "; body_def lexbuf;
- cRcpt := 1; action lexbuf }
- | "Hint" space { skip_until_point lexbuf ; action lexbuf }
- | "Hints" space { skip_until_point lexbuf ; action lexbuf }
- | "Transparent" space { skip_until_point lexbuf ; action lexbuf }
- | "Immediate" space { skip_until_point lexbuf ; action lexbuf }
- | "Syntax" space { skip_until_point lexbuf ; action lexbuf }
- | "(*" { (if !comments then print "(*");
- comment_depth := 1;
- comment lexbuf;
- cRcpt := 0; action lexbuf }
- | [' ' '\t']* '\n' { if !cRcpt < 2 then print "\n";
- cRcpt := !cRcpt+1; action lexbuf}
- | eof { (raise Fin_fichier : unit)}
- | _ { print (Lexing.lexeme lexbuf); cRcpt := 0; action lexbuf }
-
-and comment = parse
- | "(*" { (if !comments then print "(*");
- comment_depth := succ !comment_depth; comment lexbuf }
- | "*)" { (if !comments then print "*)");
- comment_depth := pred !comment_depth;
- if !comment_depth > 0 then comment lexbuf }
- | "*)" [' ''\t']*'\n' { (if !comments then print (Lexing.lexeme lexbuf));
- comment_depth := pred !comment_depth;
- if !comment_depth > 0 then comment lexbuf }
- | eof { raise Fin_fichier }
- | _ { (if !comments then print (Lexing.lexeme lexbuf));
- comment lexbuf }
-
-and skip_comment = parse
- | "(*" { comment_depth := succ !comment_depth; skip_comment lexbuf }
- | "*)" { comment_depth := pred !comment_depth;
- if !comment_depth > 0 then skip_comment lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_comment lexbuf }
-
-and body_def = parse
- | [^'.']* ":=" { print (Lexing.lexeme lexbuf); () }
- | _ { print (Lexing.lexeme lexbuf); body lexbuf }
-
-and body = parse
- | enddot { print ".\n"; skip_proof lexbuf }
- | ":=" { print ".\n"; skip_proof lexbuf }
- | "(*" { print "(*"; comment_depth := 1;
- comment lexbuf; body lexbuf }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf); body lexbuf }
-
-and body_pgm = parse
- | enddot { print ".\n"; skip_proof lexbuf }
- | "(*" { print "(*"; comment_depth := 1;
- comment lexbuf; body_pgm lexbuf }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf); body_pgm lexbuf }
-
-and skip_until_point = parse
- | '.' '\n' { () }
- | enddot { end_of_line lexbuf }
- | "(*" { comment_depth := 1;
- skip_comment lexbuf; skip_until_point lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_until_point lexbuf }
-
-and end_of_line = parse
- | [' ' '\t' ]* { end_of_line lexbuf }
- | '\n' { () }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf) }
-
-and skip_proof = parse
- | "Save" space
- { skip_until_point lexbuf }
- | "Qed." { end_of_line lexbuf }
- | "Qed" space
- { skip_until_point lexbuf }
- | "Defined." { end_of_line lexbuf }
- | "Defined" space
- { skip_until_point lexbuf }
- | "Abort." { end_of_line lexbuf }
- | "Abort" space
- { skip_until_point lexbuf }
- | "Proof" space { skip_until_point lexbuf }
- | "Proof" [' ' '\t']* '.' { skip_proof lexbuf }
- | "(*" { comment_depth := 1;
- skip_comment lexbuf; skip_proof lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_proof lexbuf }
diff --git a/tools/inferior-coq.el b/tools/inferior-coq.el
deleted file mode 100644
index b79d97d66..000000000
--- a/tools/inferior-coq.el
+++ /dev/null
@@ -1,324 +0,0 @@
-;;; inferior-coq.el --- Run an inferior Coq process.
-;;;
-;;; Copyright (C) Marco Maggesi <maggesi@math.unifi.it>
-;;; Time-stamp: "2002-02-28 12:15:04 maggesi"
-
-
-;; Emacs Lisp Archive Entry
-;; Filename: inferior-coq.el
-;; Version: 1.0
-;; Keywords: process coq
-;; Author: Marco Maggesi <maggesi@math.unifi.it>
-;; Maintainer: Marco Maggesi <maggesi@math.unifi.it>
-;; Description: Run an inferior Coq process.
-;; URL: http://www.math.unifi.it/~maggesi/
-;; Compatibility: Emacs20, Emacs21, XEmacs21
-
-;; This is free software; you can redistribute it and/or modify it under
-;; the terms of the GNU General Public License as published by the Free
-;; Software Foundation; either version 2, or (at your option) any later
-;; version.
-;;
-;; This is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-;; for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-;; MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Coq is a proof assistant (http://coq.inria.fr/). This code run an
-;; inferior Coq process and defines functions to send bits of code
-;; from other buffers to the inferior process. This is a
-;; customisation of comint-mode (see comint.el). For a more complex
-;; and full featured Coq interface under Emacs look at Proof General
-;; (http://zermelo.dcs.ed.ac.uk/~proofgen/).
-;;
-;; Written by Marco Maggesi <maggesi@math.unifi.it> with code heavly
-;; borrowed from emacs cmuscheme.el
-;;
-;; Please send me bug reports, bug fixes, and extensions, so that I can
-;; merge them into the master source.
-
-;;; Installation:
-
-;; You need to have gallina.el already installed (it comes with the
-;; standard Coq distribution) in order to use this code. Put this
-;; file somewhere in you load-path and add the following lines in your
-;; "~/.emacs":
-;;
-;; (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
-;; (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
-;; (autoload 'run-coq "inferior-coq" "Run an inferior Coq process." t)
-;; (autoload 'run-coq-other-window "inferior-coq"
-;; "Run an inferior Coq process in a new window." t)
-;; (autoload 'run-coq-other-frame "inferior-coq"
-;; "Run an inferior Coq process in a new frame." t)
-
-;;; Usage:
-
-;; Call `M-x "run-coq'.
-;;
-;; Functions and key bindings (Learn more keys with `C-c C-h' or `C-h m'):
-;; C-return ('M-x coq-send-line) send the current line.
-;; C-c C-r (`M-x coq-send-region') send the current region.
-;; C-c C-a (`M-x coq-send-abort') send the command "Abort".
-;; C-c C-t (`M-x coq-send-restart') send the command "Restart".
-;; C-c C-s (`M-x coq-send-show') send the command "Show".
-;; C-c C-u (`M-x coq-send-undo') send the command "Undo".
-;; C-c C-v (`M-x coq-check-region') run command "Check" on region.
-;; C-c . (`M-x coq-come-here') Restart and send until current point.
-
-;;; Change Log:
-
-;; From -0.0 to 1.0 brought into existence.
-
-
-(require 'gallina)
-(require 'comint)
-
-(setq coq-program-name "coqtop")
-
-(defgroup inferior-coq nil
- "Run a coq process in a buffer."
- :group 'coq)
-
-(defcustom inferior-coq-mode-hook nil
- "*Hook for customising inferior-coq mode."
- :type 'hook
- :group 'coq)
-
-(defvar inferior-coq-mode-map
- (let ((m (make-sparse-keymap)))
- (define-key m "\C-c\C-r" 'coq-send-region)
- (define-key m "\C-c\C-a" 'coq-send-abort)
- (define-key m "\C-c\C-t" 'coq-send-restart)
- (define-key m "\C-c\C-s" 'coq-send-show)
- (define-key m "\C-c\C-u" 'coq-send-undo)
- (define-key m "\C-c\C-v" 'coq-check-region)
- m))
-
-;; Install the process communication commands in the coq-mode keymap.
-(define-key coq-mode-map [(control return)] 'coq-send-line)
-(define-key coq-mode-map "\C-c\C-r" 'coq-send-region)
-(define-key coq-mode-map "\C-c\C-a" 'coq-send-abort)
-(define-key coq-mode-map "\C-c\C-t" 'coq-send-restart)
-(define-key coq-mode-map "\C-c\C-s" 'coq-send-show)
-(define-key coq-mode-map "\C-c\C-u" 'coq-send-undo)
-(define-key coq-mode-map "\C-c\C-v" 'coq-check-region)
-(define-key coq-mode-map "\C-c." 'coq-come-here)
-
-(defvar coq-buffer)
-
-(define-derived-mode inferior-coq-mode comint-mode "Inferior Coq"
- "\
-Major mode for interacting with an inferior Coq process.
-
-The following commands are available:
-\\{inferior-coq-mode-map}
-
-A Coq process can be fired up with M-x run-coq.
-
-Customisation: Entry to this mode runs the hooks on comint-mode-hook
-and inferior-coq-mode-hook (in that order).
-
-You can send text to the inferior Coq process from other buffers
-containing Coq source.
-
-Functions and key bindings (Learn more keys with `C-c C-h'):
- C-return ('M-x coq-send-line) send the current line.
- C-c C-r (`M-x coq-send-region') send the current region.
- C-c C-a (`M-x coq-send-abort') send the command \"Abort\".
- C-c C-t (`M-x coq-send-restart') send the command \"Restart\".
- C-c C-s (`M-x coq-send-show') send the command \"Show\".
- C-c C-u (`M-x coq-send-undo') send the command \"Undo\".
- C-c C-v (`M-x coq-check-region') run command \"Check\" on region.
- C-c . (`M-x coq-come-here') Restart and send until current point.
-"
- ;; Customise in inferior-coq-mode-hook
- (setq comint-prompt-regexp "^[^<]* < *")
- (coq-mode-variables)
- (setq mode-line-process '(":%s"))
- (setq comint-input-filter (function coq-input-filter))
- (setq comint-get-old-input (function coq-get-old-input)))
-
-(defcustom inferior-coq-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'"
- "*Input matching this regexp are not saved on the history list.
-Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters."
- :type 'regexp
- :group 'inferior-coq)
-
-(defun coq-input-filter (str)
- "Don't save anything matching `inferior-coq-filter-regexp'."
- (not (string-match inferior-coq-filter-regexp str)))
-
-(defun coq-get-old-input ()
- "Snarf the sexp ending at point."
- (save-excursion
- (let ((end (point)))
- (backward-sexp)
- (buffer-substring (point) end))))
-
-(defun coq-args-to-list (string)
- (let ((where (string-match "[ \t]" string)))
- (cond ((null where) (list string))
- ((not (= where 0))
- (cons (substring string 0 where)
- (coq-args-to-list (substring string (+ 1 where)
- (length string)))))
- (t (let ((pos (string-match "[^ \t]" string)))
- (if (null pos)
- nil
- (coq-args-to-list (substring string pos
- (length string)))))))))
-
-;;;###autoload
-(defun run-coq (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (switch-to-buffer "*coq*"))
-;;;###autoload (add-hook 'same-window-buffer-names "*coq*")
-
-;;;###autoload
-(defun run-coq-other-window (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (pop-to-buffer "*coq*"))
-;;;###autoload (add-hook 'same-window-buffer-names "*coq*")
-
-(defun run-coq-other-frame (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (switch-to-buffer-other-frame "*coq*"))
-
-(defun switch-to-coq (eob-p)
- "Switch to the coq process buffer.
-With argument, position cursor at end of buffer."
- (interactive "P")
- (if (get-buffer coq-buffer)
- (pop-to-buffer coq-buffer)
- (error "No current process buffer. See variable `coq-buffer'"))
- (cond (eob-p
- (push-mark)
- (goto-char (point-max)))))
-
-(defun coq-send-region (start end)
- "Send the current region to the inferior Coq process."
- (interactive "r")
- (comint-send-region (coq-proc) start end)
- (comint-send-string (coq-proc) "\n"))
-
-(defun coq-send-line ()
- "Send the current line to the Coq process."
- (interactive)
- (save-excursion
- (end-of-line)
- (let ((end (point)))
- (beginning-of-line)
- (coq-send-region (point) end)))
- (next-line 1))
-
-(defun coq-send-abort ()
- "Send the command \"Abort.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Abort.\n"))
-
-(defun coq-send-restart ()
- "Send the command \"Restart.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Restart.\n"))
-
-(defun coq-send-undo ()
- "Reset coq to the initial state and send the region between the
- beginning of file and the point."
- (interactive)
- (comint-send-string (coq-proc) "Undo.\n"))
-
-(defun coq-check-region (start end)
- "Run the commmand \"Check\" on the current region."
- (interactive "r")
- (comint-proc-query (coq-proc)
- (concat "Check "
- (buffer-substring start end)
- ".\n")))
-
-(defun coq-send-show ()
- "Send the command \"Show.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Show.\n"))
-
-(defun coq-come-here ()
- "Reset coq to the initial state and send the region between the
- beginning of file and the point."
- (interactive)
- (comint-send-string (coq-proc) "Reset Initial.\n")
- (coq-send-region 1 (point)))
-
-(defvar coq-buffer nil "*The current coq process buffer.")
-
-(defun coq-proc ()
- "Return the current coq process. See variable `coq-buffer'."
- (let ((proc (get-buffer-process (if (eq major-mode 'inferior-coq-mode)
- (current-buffer)
- coq-buffer))))
- (or proc
- (error "No current process. See variable `coq-buffer'"))))
-
-(defcustom inferior-coq-load-hook nil
- "This hook is run when inferior-coq is loaded in.
-This is a good place to put keybindings."
- :type 'hook
- :group 'inferior-coq)
-
-(run-hooks 'inferior-coq-load-hook)
-
-(provide 'inferior-coq)
diff --git a/tools/make-both-single-timing-files.py b/tools/make-both-single-timing-files.py
index c6af2ff1f..32c52c7a1 100755
--- a/tools/make-both-single-timing-files.py
+++ b/tools/make-both-single-timing-files.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
import sys
from TimeFileMaker import *
diff --git a/tools/make-both-time-files.py b/tools/make-both-time-files.py
index 643429679..f730a8d6b 100755
--- a/tools/make-both-time-files.py
+++ b/tools/make-both-time-files.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
import sys
from TimeFileMaker import *
diff --git a/tools/make-one-time-file.py b/tools/make-one-time-file.py
index c9905249e..e66136df9 100755
--- a/tools/make-one-time-file.py
+++ b/tools/make-one-time-file.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
import sys
from TimeFileMaker import *
diff --git a/toplevel/g_toplevel.ml4 b/toplevel/g_toplevel.mlg
index e3cefe236..53d3eef23 100644
--- a/toplevel/g_toplevel.ml4
+++ b/toplevel/g_toplevel.mlg
@@ -8,6 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
open Pcoq
open Pcoq.Prim
open Vernacexpr
@@ -28,20 +29,26 @@ end
open Toplevel_
-GEXTEND Gram
+}
+
+GRAMMAR EXTEND Gram
GLOBAL: vernac_toplevel;
vernac_toplevel: FIRST
- [ [ IDENT "Drop"; "." -> CAst.make VernacDrop
- | IDENT "Quit"; "." -> CAst.make VernacQuit
+ [ [ IDENT "Drop"; "." -> { CAst.make VernacDrop }
+ | IDENT "Quit"; "." -> { CAst.make VernacQuit }
| IDENT "Backtrack"; n = natural ; m = natural ; p = natural; "." ->
- CAst.make (VernacBacktrack (n,m,p))
+ { CAst.make (VernacBacktrack (n,m,p)) }
| cmd = Pvernac.main_entry ->
- match cmd with
+ { match cmd with
| None -> raise Stm.End_of_input
- | Some (loc,c) -> CAst.make ~loc (VernacControl c)
+ | Some (loc,c) -> CAst.make ~loc (VernacControl c) }
]
]
;
END
+{
+
let parse_toplevel pa = Pcoq.Gram.entry_parse vernac_toplevel pa
+
+}
diff --git a/vernac/assumptions.mli b/vernac/assumptions.mli
index 0e2b0c80e..751e79d89 100644
--- a/vernac/assumptions.mli
+++ b/vernac/assumptions.mli
@@ -23,7 +23,7 @@ open Printer
val traverse :
Label.t -> constr ->
(Refset_env.t * Refset_env.t Refmap_env.t *
- (Label.t * Context.Rel.t * types) list Refmap_env.t)
+ (Label.t * Constr.rel_context * types) list Refmap_env.t)
(** Collects all the assumptions (optionally including opaque definitions)
on which a term relies (together with their type). The above warning of
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 382d18b09..bf734ab36 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -42,7 +42,7 @@ let typeclasses_db = "typeclass_instances"
let set_typeclass_transparency c local b =
Hints.add_hints ~local [typeclasses_db]
- (Hints.HintsTransparencyEntry ([c], b))
+ (Hints.HintsTransparencyEntry (Vernacexpr.HintsReferences [c], b))
let _ =
Hook.set Typeclasses.add_instance_hint_hook
@@ -116,9 +116,8 @@ let instance_hook k info global imps ?hook cst =
let declare_instance_constant k info global imps ?hook id decl poly sigma term termtype =
let kind = IsDefinition Instance in
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
+ let levels = Univ.LSet.union (Univops.universes_of_constr termtype)
+ (Univops.universes_of_constr term) in
Evd.restrict_universe_context sigma levels
in
let uctx = Evd.check_univ_decl ~poly sigma decl in
diff --git a/vernac/classes.mli b/vernac/classes.mli
index bd30b2d60..9c37364cb 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -16,9 +16,9 @@ open Libnames
(** Errors *)
-val mismatched_params : env -> constr_expr list -> Context.Rel.t -> 'a
+val mismatched_params : env -> constr_expr list -> Constr.rel_context -> 'a
-val mismatched_props : env -> constr_expr list -> Context.Rel.t -> 'a
+val mismatched_props : env -> constr_expr list -> Constr.rel_context -> 'a
(** Instance declaration *)
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index a8ac52846..750ed35cb 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -163,7 +163,7 @@ let do_assumptions kind nl l =
let nf_evar c = EConstr.to_constr sigma 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
+ let uvars = Univ.LSet.union uvars (Univops.universes_of_constr t) in
uvars, (coe,t,imps))
Univ.LSet.empty l
in
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index f55c852c0..a8d794642 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -93,7 +93,7 @@ let interp_definition pl bl poly red_option c ctypopt =
let tyopt = Option.map (fun ty -> Term.it_mkProd_or_LetIn (EConstr.to_constr ~abort_on_undefined_evars:false evd ty) ctx) tyopt in
(* Keep only useful universes. *)
let uvars_fold uvars c =
- Univ.LSet.union uvars (universes_of_constr env evd (of_constr c))
+ Univ.LSet.union uvars (universes_of_constr evd (of_constr c))
in
let uvars = List.fold_left uvars_fold Univ.LSet.empty (Option.List.cons tyopt [c]) in
let evd = Evd.restrict_universe_context evd uvars in
diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml
index 1d1cc62de..37258c2d4 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -262,7 +262,7 @@ let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) ind
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 vars = Univops.universes_of_constr (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
@@ -295,8 +295,7 @@ let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) n
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 vars = Univops.universes_of_constr (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
diff --git a/vernac/comFixpoint.mli b/vernac/comFixpoint.mli
index f51bfbad5..b1a9c8a5a 100644
--- a/vernac/comFixpoint.mli
+++ b/vernac/comFixpoint.mli
@@ -82,12 +82,12 @@ val interp_fixpoint :
val declare_fixpoint :
locality -> polymorphic ->
recursive_preentry * UState.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ (Constr.rel_context * Impargs.manual_implicits * int option) list ->
Proof_global.lemma_possible_guards -> decl_notation list -> unit
val declare_cofixpoint : locality -> polymorphic ->
recursive_preentry * UState.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ (Constr.rel_context * Impargs.manual_implicits * int option) list ->
decl_notation list -> unit
(** Very private function, do not use *)
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index 6057c05f5..ad1ffa35a 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -126,7 +126,7 @@ let make_conclusion_flexible sigma ty poly =
else sigma
let is_impredicative env u =
- u = Prop Null || (is_impredicative_set env && u = Prop Pos)
+ u = Prop || (is_impredicative_set env && u = Set)
let interp_ind_arity env sigma ind =
let c = intern_gen IsType env sigma ind.ind_arity in
@@ -146,7 +146,6 @@ let interp_cstrs env sigma impls mldata arity ind =
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)
@@ -245,7 +244,7 @@ let solve_constraints_system levels level_bounds =
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
+ if a = Prop then None
else Some (univ_of_sort a)) destarities
in
let cstrs_levels, min_levels, sizes =
@@ -298,14 +297,14 @@ let inductive_levels env evd poly arities inds =
(** "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
+ Evd.set_leq_sort env evd Set 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
+ Evd.set_eq_sort env evd Prop du
else evd
else Evd.set_eq_sort env evd (Type cu) du
in
@@ -327,14 +326,17 @@ let check_param = function
| CLocalPattern {CAst.loc} ->
Loc.raise ?loc (Stream.Error "pattern with quote not allowed here")
-let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
+let interp_mutual_inductive_gen env0 (uparamsl,paramsl,indl) notations cum poly prv finite =
check_all_names_different indl;
List.iter check_param paramsl;
- let env0 = Global.env() in
+ if not (List.is_empty uparamsl) && not (List.is_empty notations)
+ then user_err (str "Inductives with uniform parameters may not have attached notations.");
let pl = (List.hd indl).ind_univs in
let sigma, decl = interp_univ_decl_opt env0 pl in
+ let sigma, (uimpls, ((env_uparams, ctx_uparams), useruimpls)) =
+ interp_context_evars env0 sigma uparamsl in
let sigma, (impls, ((env_params, ctx_params), userimpls)) =
- interp_context_evars env0 sigma paramsl
+ interp_context_evars ~impl_env:uimpls env_uparams sigma paramsl
in
let indnames = List.map (fun ind -> ind.ind_name) indl in
@@ -346,15 +348,15 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
let sigma, arities = List.fold_left_map (fun sigma -> interp_ind_arity env_params sigma) sigma indl in
let fullarities = List.map (fun (c, _, _) -> EConstr.it_mkProd_or_LetIn c ctx_params) arities in
- let env_ar = push_types env0 indnames fullarities in
+ let env_ar = push_types env_uparams indnames fullarities in
let env_ar_params = EConstr.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 sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in
- let ntn_impls = compute_internalization_env env0 sigma (Inductive (params,true)) indnames fullarities indimpls in
+ let impls = compute_internalization_env env_uparams sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in
+ let ntn_impls = compute_internalization_env env_uparams sigma (Inductive (params,true)) indnames fullarities indimpls in
let mldatas = List.map2 (mk_mltype_data sigma env_params params) arities indnames in
let sigma, constructors =
@@ -365,6 +367,25 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
List.fold_left3_map (fun sigma -> interp_cstrs env_ar_params sigma impls) sigma mldatas arities indl)
() in
+ (* generalize over the uniform parameters *)
+ let nparams = Context.Rel.length ctx_params in
+ let nuparams = Context.Rel.length ctx_uparams in
+ let uargs = Context.Rel.to_extended_vect EConstr.mkRel 0 ctx_uparams in
+ let uparam_subst =
+ List.init (List.length indl) EConstr.(fun i -> mkApp (mkRel (i + 1 + nuparams), uargs))
+ @ List.init nuparams EConstr.(fun i -> mkRel (i + 1)) in
+ let generalize_constructor c = EConstr.Unsafe.to_constr (EConstr.Vars.substnl uparam_subst nparams c) in
+ let constructors = List.map (fun (cnames,ctypes,cimpls) ->
+ (cnames,List.map generalize_constructor ctypes,cimpls))
+ constructors
+ in
+ let ctx_params = ctx_params @ ctx_uparams in
+ let userimpls = useruimpls @ (lift_implicits (Context.Rel.nhyps ctx_uparams) userimpls) in
+ let indimpls = List.map (fun iimpl -> useruimpls @ (lift_implicits (Context.Rel.nhyps ctx_uparams) iimpl)) indimpls in
+ let fullarities = List.map (fun c -> EConstr.it_mkProd_or_LetIn c ctx_uparams) fullarities in
+ let env_ar = push_types env0 indnames fullarities in
+ let env_ar_params = EConstr.push_rel_context ctx_params env_ar in
+
(* Try further to solve evars, and instantiate them *)
let sigma = solve_remaining_evars all_and_fail_flags env_params sigma (Evd.from_env env_params) in
(* Compute renewed arities *)
@@ -423,6 +444,9 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
InferCumulativity.infer_inductive env_ar mind_ent
else mind_ent), Evd.universe_binders sigma, impls
+let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
+ interp_mutual_inductive_gen (Global.env()) ([],paramsl,indl) notations cum poly prv finite
+
(* Very syntactical equality *)
let eq_local_binders bl1 bl2 =
List.equal local_binder_eq bl1 bl2
@@ -505,10 +529,15 @@ 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
+type uniform_inductive_flag =
+ | UniformParameters
+ | NonUniformParameters
+
+let do_mutual_inductive indl cum poly prv ~uniform finite =
+ let (params,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
+ let indl = match uniform with UniformParameters -> (params, [], indl) | NonUniformParameters -> ([], params, indl) in
+ let mie,pl,impls = interp_mutual_inductive_gen (Global.env()) 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 *)
diff --git a/vernac/comInductive.mli b/vernac/comInductive.mli
index 7ae8e8f71..4e30ed7de 100644
--- a/vernac/comInductive.mli
+++ b/vernac/comInductive.mli
@@ -19,9 +19,14 @@ open Decl_kinds
(** Entry points for the vernacular commands Inductive and CoInductive *)
+type uniform_inductive_flag =
+ | UniformParameters
+ | NonUniformParameters
+
val do_mutual_inductive :
(one_inductive_expr * decl_notation list) list -> cumulative_inductive_flag ->
- polymorphic -> private_flag -> Declarations.recursivity_kind -> unit
+ polymorphic -> private_flag -> uniform:uniform_inductive_flag ->
+ Declarations.recursivity_kind -> unit
(************************************************************************)
(** Internal API *)
diff --git a/vernac/egramcoq.ml b/vernac/egramcoq.ml
index cc9be7b0e..48f225f97 100644
--- a/vernac/egramcoq.ml
+++ b/vernac/egramcoq.ml
@@ -274,7 +274,7 @@ let make_sep_rules = function
Arules [r]
let symbol_of_target : type s. _ -> _ -> _ -> s target -> (s, s) symbol = fun p assoc from forpat ->
- if is_binder_level from p then Aentryl (target_entry forpat, 200)
+ if is_binder_level from p then Aentryl (target_entry forpat, "200")
else if is_self from p then Aself
else
let g = target_entry forpat in
@@ -282,7 +282,7 @@ let symbol_of_target : type s. _ -> _ -> _ -> s target -> (s, s) symbol = fun p
begin match lev with
| None -> Aentry g
| Some None -> Anext
- | Some (Some (lev, cur)) -> Aentryl (g, lev)
+ | Some (Some (lev, cur)) -> Aentryl (g, string_of_int lev)
end
let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) symbol = fun assoc from typ -> match typ with
@@ -291,7 +291,7 @@ let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) symbol = fun as
Alist1 (symbol_of_target typ' assoc from forpat)
| TTConstrList (typ', tkl, forpat) ->
Alist1sep (symbol_of_target typ' assoc from forpat, make_sep_rules tkl)
-| TTPattern p -> Aentryl (Constr.pattern, p)
+| TTPattern p -> Aentryl (Constr.pattern, string_of_int p)
| TTClosedBinderList [] -> Alist1 (Aentry Constr.binder)
| TTClosedBinderList tkl -> Alist1sep (Aentry Constr.binder, make_sep_rules tkl)
| TTName -> Aentry Prim.name
@@ -428,6 +428,7 @@ let prepare_empty_levels forpat (pos,p4assoc,name,reinit) =
let rec pure_sublevels : type a b c. int option -> (a, b, c) rule -> int list = fun level r -> match r with
| Stop -> []
| Next (rem, Aentryl (_, i)) ->
+ let i = int_of_string i in
let rem = pure_sublevels level rem in
begin match level with
| Some j when Int.equal i j -> rem
diff --git a/vernac/g_proofs.ml4 b/vernac/g_proofs.ml4
deleted file mode 100644
index 4b11276af..000000000
--- a/vernac/g_proofs.ml4
+++ /dev/null
@@ -1,131 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Glob_term
-open Constrexpr
-open Vernacexpr
-open Proof_global
-
-open Pcoq
-open Pcoq.Prim
-open Pcoq.Constr
-open Pvernac.Vernac_
-
-let thm_token = G_vernac.thm_token
-
-let hint = Gram.entry_create "hint"
-
-let warn_deprecated_focus =
- CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
- (fun () ->
- Pp.strbrk
- "The Focus command is deprecated; use bullets or focusing brackets instead"
- )
-
-let warn_deprecated_focus_n n =
- CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
- (fun () ->
- Pp.(str "The Focus command is deprecated;" ++ spc ()
- ++ str "use '" ++ int n ++ str ": {' instead")
- )
-
-let warn_deprecated_unfocus =
- CWarnings.create ~name:"deprecated-unfocus" ~category:"deprecated"
- (fun () -> Pp.strbrk "The Unfocus command is deprecated")
-
-(* Proof commands *)
-GEXTEND Gram
- GLOBAL: hint command;
-
- opt_hintbases:
- [ [ -> []
- | ":"; l = LIST1 [id = IDENT -> id ] -> l ] ]
- ;
- command:
- [ [ IDENT "Goal"; c = lconstr ->
- VernacDefinition (Decl_kinds.(NoDischarge, Definition), ((CAst.make ~loc:!@loc Names.Anonymous), None), ProveBody ([], c))
- | IDENT "Proof" -> VernacProof (None,None)
- | IDENT "Proof" ; IDENT "Mode" ; mn = string -> VernacProofMode mn
- | IDENT "Proof"; c = lconstr -> VernacExactProof c
- | IDENT "Abort" -> VernacAbort None
- | IDENT "Abort"; IDENT "All" -> VernacAbortAll
- | IDENT "Abort"; id = identref -> VernacAbort (Some id)
- | IDENT "Existential"; n = natural; c = constr_body ->
- VernacSolveExistential (n,c)
- | IDENT "Admitted" -> VernacEndProof Admitted
- | IDENT "Qed" -> VernacEndProof (Proved (Opaque,None))
- | IDENT "Save"; id = identref ->
- VernacEndProof (Proved (Opaque, Some id))
- | IDENT "Defined" -> VernacEndProof (Proved (Transparent,None))
- | IDENT "Defined"; id=identref ->
- VernacEndProof (Proved (Transparent,Some id))
- | IDENT "Restart" -> VernacRestart
- | IDENT "Undo" -> VernacUndo 1
- | IDENT "Undo"; n = natural -> VernacUndo n
- | IDENT "Undo"; IDENT "To"; n = natural -> VernacUndoTo n
- | IDENT "Focus" ->
- warn_deprecated_focus ~loc:!@loc ();
- VernacFocus None
- | IDENT "Focus"; n = natural ->
- warn_deprecated_focus_n n ~loc:!@loc ();
- VernacFocus (Some n)
- | IDENT "Unfocus" ->
- warn_deprecated_unfocus ~loc:!@loc ();
- VernacUnfocus
- | IDENT "Unfocused" -> VernacUnfocused
- | IDENT "Show" -> VernacShow (ShowGoal OpenSubgoals)
- | IDENT "Show"; n = natural -> VernacShow (ShowGoal (NthGoal n))
- | IDENT "Show"; id = ident -> VernacShow (ShowGoal (GoalId id))
- | IDENT "Show"; IDENT "Script" -> VernacShow ShowScript
- | IDENT "Show"; IDENT "Existentials" -> VernacShow ShowExistentials
- | IDENT "Show"; IDENT "Universes" -> VernacShow ShowUniverses
- | IDENT "Show"; IDENT "Conjectures" -> VernacShow ShowProofNames
- | IDENT "Show"; IDENT "Proof" -> VernacShow ShowProof
- | IDENT "Show"; IDENT "Intro" -> VernacShow (ShowIntros false)
- | IDENT "Show"; IDENT "Intros" -> VernacShow (ShowIntros true)
- | IDENT "Show"; IDENT "Match"; id = reference -> VernacShow (ShowMatch id)
- | IDENT "Guarded" -> VernacCheckGuard
- (* Hints for Auto and EAuto *)
- | IDENT "Create"; IDENT "HintDb" ;
- id = IDENT ; b = [ "discriminated" -> true | -> false ] ->
- VernacCreateHintDb (id, b)
- | IDENT "Remove"; IDENT "Hints"; ids = LIST1 global; dbnames = opt_hintbases ->
- VernacRemoveHints (dbnames, ids)
- | IDENT "Hint"; h = hint; dbnames = opt_hintbases ->
- VernacHints (dbnames, h)
- ] ];
- reference_or_constr:
- [ [ r = global -> HintsReference r
- | c = constr -> HintsConstr c ] ]
- ;
- hint:
- [ [ IDENT "Resolve"; lc = LIST1 reference_or_constr; info = hint_info ->
- HintsResolve (List.map (fun x -> (info, true, x)) lc)
- | IDENT "Resolve"; "->"; lc = LIST1 global; n = OPT natural ->
- HintsResolveIFF (true, lc, n)
- | IDENT "Resolve"; "<-"; lc = LIST1 global; n = OPT natural ->
- HintsResolveIFF (false, lc, n)
- | IDENT "Immediate"; lc = LIST1 reference_or_constr -> HintsImmediate lc
- | IDENT "Transparent"; lc = LIST1 global -> HintsTransparency (lc, true)
- | IDENT "Opaque"; lc = LIST1 global -> HintsTransparency (lc, false)
- | IDENT "Mode"; l = global; m = mode -> HintsMode (l, m)
- | IDENT "Unfold"; lqid = LIST1 global -> HintsUnfold lqid
- | IDENT "Constructors"; lc = LIST1 global -> HintsConstructors lc ] ]
- ;
- constr_body:
- [ [ ":="; c = lconstr -> c
- | ":"; t = lconstr; ":="; c = lconstr -> CAst.make ~loc:!@loc @@ CCast(c,CastConv t) ] ]
- ;
- mode:
- [ [ l = LIST1 [ "+" -> ModeInput
- | "!" -> ModeNoHeadEvar
- | "-" -> ModeOutput ] -> l ] ]
- ;
-END
diff --git a/vernac/g_proofs.mlg b/vernac/g_proofs.mlg
new file mode 100644
index 000000000..cccdbfc91
--- /dev/null
+++ b/vernac/g_proofs.mlg
@@ -0,0 +1,139 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+
+open Glob_term
+open Constrexpr
+open Vernacexpr
+open Proof_global
+
+open Pcoq
+open Pcoq.Prim
+open Pcoq.Constr
+open Pvernac.Vernac_
+
+let thm_token = G_vernac.thm_token
+
+let hint = Gram.entry_create "hint"
+
+let warn_deprecated_focus =
+ CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
+ (fun () ->
+ Pp.strbrk
+ "The Focus command is deprecated; use bullets or focusing brackets instead"
+ )
+
+let warn_deprecated_focus_n n =
+ CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
+ (fun () ->
+ Pp.(str "The Focus command is deprecated;" ++ spc ()
+ ++ str "use '" ++ int n ++ str ": {' instead")
+ )
+
+let warn_deprecated_unfocus =
+ CWarnings.create ~name:"deprecated-unfocus" ~category:"deprecated"
+ (fun () -> Pp.strbrk "The Unfocus command is deprecated")
+
+}
+
+(* Proof commands *)
+GRAMMAR EXTEND Gram
+ GLOBAL: hint command;
+
+ opt_hintbases:
+ [ [ -> { [] }
+ | ":"; l = LIST1 [id = IDENT -> { id } ] -> { l } ] ]
+ ;
+ command:
+ [ [ IDENT "Goal"; c = lconstr ->
+ { VernacDefinition (Decl_kinds.(NoDischarge, Definition), ((CAst.make ~loc Names.Anonymous), None), ProveBody ([], c)) }
+ | IDENT "Proof" -> { VernacProof (None,None) }
+ | IDENT "Proof" ; IDENT "Mode" ; mn = string -> { VernacProofMode mn }
+ | IDENT "Proof"; c = lconstr -> { VernacExactProof c }
+ | IDENT "Abort" -> { VernacAbort None }
+ | IDENT "Abort"; IDENT "All" -> { VernacAbortAll }
+ | IDENT "Abort"; id = identref -> { VernacAbort (Some id) }
+ | IDENT "Existential"; n = natural; c = constr_body ->
+ { VernacSolveExistential (n,c) }
+ | IDENT "Admitted" -> { VernacEndProof Admitted }
+ | IDENT "Qed" -> { VernacEndProof (Proved (Opaque,None)) }
+ | IDENT "Save"; id = identref ->
+ { VernacEndProof (Proved (Opaque, Some id)) }
+ | IDENT "Defined" -> { VernacEndProof (Proved (Transparent,None)) }
+ | IDENT "Defined"; id=identref ->
+ { VernacEndProof (Proved (Transparent,Some id)) }
+ | IDENT "Restart" -> { VernacRestart }
+ | IDENT "Undo" -> { VernacUndo 1 }
+ | IDENT "Undo"; n = natural -> { VernacUndo n }
+ | IDENT "Undo"; IDENT "To"; n = natural -> { VernacUndoTo n }
+ | IDENT "Focus" ->
+ { warn_deprecated_focus ~loc ();
+ VernacFocus None }
+ | IDENT "Focus"; n = natural ->
+ { warn_deprecated_focus_n n ~loc ();
+ VernacFocus (Some n) }
+ | IDENT "Unfocus" ->
+ { warn_deprecated_unfocus ~loc ();
+ VernacUnfocus }
+ | IDENT "Unfocused" -> { VernacUnfocused }
+ | IDENT "Show" -> { VernacShow (ShowGoal OpenSubgoals) }
+ | IDENT "Show"; n = natural -> { VernacShow (ShowGoal (NthGoal n)) }
+ | IDENT "Show"; id = ident -> { VernacShow (ShowGoal (GoalId id)) }
+ | IDENT "Show"; IDENT "Script" -> { VernacShow ShowScript }
+ | IDENT "Show"; IDENT "Existentials" -> { VernacShow ShowExistentials }
+ | IDENT "Show"; IDENT "Universes" -> { VernacShow ShowUniverses }
+ | IDENT "Show"; IDENT "Conjectures" -> { VernacShow ShowProofNames }
+ | IDENT "Show"; IDENT "Proof" -> { VernacShow ShowProof }
+ | IDENT "Show"; IDENT "Intro" -> { VernacShow (ShowIntros false) }
+ | IDENT "Show"; IDENT "Intros" -> { VernacShow (ShowIntros true) }
+ | IDENT "Show"; IDENT "Match"; id = reference -> { VernacShow (ShowMatch id) }
+ | IDENT "Guarded" -> { VernacCheckGuard }
+ (* Hints for Auto and EAuto *)
+ | IDENT "Create"; IDENT "HintDb" ;
+ id = IDENT ; b = [ "discriminated" -> { true } | -> { false } ] ->
+ { VernacCreateHintDb (id, b) }
+ | IDENT "Remove"; IDENT "Hints"; ids = LIST1 global; dbnames = opt_hintbases ->
+ { VernacRemoveHints (dbnames, ids) }
+ | IDENT "Hint"; h = hint; dbnames = opt_hintbases ->
+ { VernacHints (dbnames, h) }
+ ] ];
+ reference_or_constr:
+ [ [ r = global -> { HintsReference r }
+ | c = constr -> { HintsConstr c } ] ]
+ ;
+ hint:
+ [ [ IDENT "Resolve"; lc = LIST1 reference_or_constr; info = hint_info ->
+ { HintsResolve (List.map (fun x -> (info, true, x)) lc) }
+ | IDENT "Resolve"; "->"; lc = LIST1 global; n = OPT natural ->
+ { HintsResolveIFF (true, lc, n) }
+ | IDENT "Resolve"; "<-"; lc = LIST1 global; n = OPT natural ->
+ { HintsResolveIFF (false, lc, n) }
+ | IDENT "Immediate"; lc = LIST1 reference_or_constr -> { HintsImmediate lc }
+ | IDENT "Variables"; IDENT "Transparent" -> { HintsTransparency (HintsVariables, true) }
+ | IDENT "Variables"; IDENT "Opaque" -> { HintsTransparency (HintsVariables, false) }
+ | IDENT "Constants"; IDENT "Transparent" -> { HintsTransparency (HintsConstants, true) }
+ | IDENT "Constants"; IDENT "Opaque" -> { HintsTransparency (HintsConstants, false) }
+ | IDENT "Transparent"; lc = LIST1 global -> { HintsTransparency (HintsReferences lc, true) }
+ | IDENT "Opaque"; lc = LIST1 global -> { HintsTransparency (HintsReferences lc, false) }
+ | IDENT "Mode"; l = global; m = mode -> { HintsMode (l, m) }
+ | IDENT "Unfold"; lqid = LIST1 global -> { HintsUnfold lqid }
+ | IDENT "Constructors"; lc = LIST1 global -> { HintsConstructors lc } ] ]
+ ;
+ constr_body:
+ [ [ ":="; c = lconstr -> { c }
+ | ":"; t = lconstr; ":="; c = lconstr -> { CAst.make ~loc @@ CCast(c,CastConv t) } ] ]
+ ;
+ mode:
+ [ [ l = LIST1 [ "+" -> { ModeInput }
+ | "!" -> { ModeNoHeadEvar }
+ | "-" -> { ModeOutput } ] -> { l } ] ]
+ ;
+END
diff --git a/vernac/g_vernac.ml4 b/vernac/g_vernac.ml4
deleted file mode 100644
index 16934fc86..000000000
--- a/vernac/g_vernac.ml4
+++ /dev/null
@@ -1,1156 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Pp
-open CErrors
-open Util
-open Names
-open Glob_term
-open Vernacexpr
-open Constrexpr
-open Constrexpr_ops
-open Extend
-open Decl_kinds
-open Declaremods
-open Declarations
-open Namegen
-open Tok (* necessary for camlp5 *)
-
-open Pcoq
-open Pcoq.Prim
-open Pcoq.Constr
-open Pcoq.Module
-open Pvernac.Vernac_
-
-let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ]
-let _ = List.iter CLexer.add_keyword vernac_kw
-
-(* Rem: do not join the different GEXTEND into one, it breaks native *)
-(* compilation on PowerPC and Sun architectures *)
-
-let query_command = Gram.entry_create "vernac:query_command"
-
-let subprf = Gram.entry_create "vernac:subprf"
-
-let class_rawexpr = Gram.entry_create "vernac:class_rawexpr"
-let thm_token = Gram.entry_create "vernac:thm_token"
-let def_body = Gram.entry_create "vernac:def_body"
-let decl_notation = Gram.entry_create "vernac:decl_notation"
-let record_field = Gram.entry_create "vernac:record_field"
-let of_type_with_opt_coercion = Gram.entry_create "vernac:of_type_with_opt_coercion"
-let instance_name = Gram.entry_create "vernac:instance_name"
-let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
-
-let make_bullet s =
- let open Proof_bullet in
- let n = String.length s in
- match s.[0] with
- | '-' -> Dash n
- | '+' -> Plus n
- | '*' -> Star n
- | _ -> assert false
-
-let parse_compat_version ?(allow_old = true) = let open Flags in function
- | "8.8" -> Current
- | "8.7" -> V8_7
- | "8.6" -> V8_6
- | ("8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
- CErrors.user_err ~hdr:"get_compat_version"
- Pp.(str "Compatibility with version " ++ str s ++ str " not supported.")
- | s ->
- CErrors.user_err ~hdr:"get_compat_version"
- Pp.(str "Unknown compatibility version \"" ++ str s ++ str "\".")
-
-GEXTEND Gram
- GLOBAL: vernac_control gallina_ext noedit_mode subprf;
- vernac_control: FIRST
- [ [ IDENT "Time"; c = located_vernac -> VernacTime (false,c)
- | IDENT "Redirect"; s = ne_string; c = located_vernac -> VernacRedirect (s, c)
- | IDENT "Timeout"; n = natural; v = vernac_control -> VernacTimeout(n,v)
- | IDENT "Fail"; v = vernac_control -> VernacFail v
- | (f, v) = vernac -> VernacExpr(f, v) ]
- ]
- ;
- vernac:
- [ [ IDENT "Local"; (f, v) = vernac_poly -> (VernacLocal true :: f, v)
- | IDENT "Global"; (f, v) = vernac_poly -> (VernacLocal false :: f, v)
-
- | v = vernac_poly -> v ]
- ]
- ;
- vernac_poly:
- [ [ IDENT "Polymorphic"; (f, v) = vernac_aux -> (VernacPolymorphic true :: f, v)
- | IDENT "Monomorphic"; (f, v) = vernac_aux -> (VernacPolymorphic false :: f, v)
- | v = vernac_aux -> v ]
- ]
- ;
- vernac_aux:
- (* Better to parse "." here: in case of failure (e.g. in coerce_to_var), *)
- (* "." is still in the stream and discard_to_dot works correctly *)
- [ [ IDENT "Program"; g = gallina; "." -> ([VernacProgram], g)
- | IDENT "Program"; g = gallina_ext; "." -> ([VernacProgram], g)
- | g = gallina; "." -> ([], g)
- | g = gallina_ext; "." -> ([], g)
- | c = command; "." -> ([], c)
- | c = syntax; "." -> ([], c)
- | c = subprf -> ([], c)
- ] ]
- ;
- vernac_aux: LAST
- [ [ prfcom = command_entry -> ([], prfcom) ] ]
- ;
- noedit_mode:
- [ [ c = query_command -> c None] ]
- ;
-
- subprf:
- [ [ s = BULLET -> VernacBullet (make_bullet s)
- | "{" -> VernacSubproof None
- | "}" -> VernacEndSubproof
- ] ]
- ;
-
- located_vernac:
- [ [ v = vernac_control -> CAst.make ~loc:!@loc v ] ]
- ;
-END
-
-let warn_plural_command =
- CWarnings.create ~name:"plural-command" ~category:"pedantic" ~default:CWarnings.Disabled
- (fun kwd -> strbrk (Printf.sprintf "Command \"%s\" expects more than one assumption." kwd))
-
-let test_plural_form loc kwd = function
- | [(_,([_],_))] ->
- warn_plural_command ~loc:!@loc kwd
- | _ -> ()
-
-let test_plural_form_types loc kwd = function
- | [([_],_)] ->
- warn_plural_command ~loc:!@loc kwd
- | _ -> ()
-
-let lname_of_lident : lident -> lname =
- CAst.map (fun s -> Name s)
-
-let name_of_ident_decl : ident_decl -> name_decl =
- on_fst lname_of_lident
-
-(* Gallina declarations *)
-GEXTEND Gram
- GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
- record_field decl_notation rec_definition ident_decl univ_decl;
-
- gallina:
- (* Definition, Theorem, Variable, Axiom, ... *)
- [ [ thm = thm_token; id = ident_decl; bl = binders; ":"; c = lconstr;
- l = LIST0
- [ "with"; id = ident_decl; bl = binders; ":"; c = lconstr ->
- (id,(bl,c)) ] ->
- VernacStartTheoremProof (thm, (id,(bl,c))::l)
- | stre = assumption_token; nl = inline; bl = assum_list ->
- VernacAssumption (stre, nl, bl)
- | (kwd,stre) = assumptions_token; nl = inline; bl = assum_list ->
- test_plural_form loc kwd bl;
- VernacAssumption (stre, nl, bl)
- | d = def_token; id = ident_decl; b = def_body ->
- VernacDefinition (d, name_of_ident_decl id, b)
- | IDENT "Let"; id = identref; b = def_body ->
- VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b)
- (* Gallina inductive declarations *)
- | cum = OPT cumulativity_token; priv = private_token; f = finite_token;
- indl = LIST1 inductive_definition SEP "with" ->
- let (k,f) = f in
- let indl=List.map (fun ((a,b,c,d),e) -> ((a,b,c,k,d),e)) indl in
- VernacInductive (cum, priv,f,indl)
- | "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
- VernacFixpoint (NoDischarge, recs)
- | IDENT "Let"; "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
- VernacFixpoint (DoDischarge, recs)
- | "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
- VernacCoFixpoint (NoDischarge, corecs)
- | IDENT "Let"; "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
- VernacCoFixpoint (DoDischarge, corecs)
- | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> VernacScheme l
- | IDENT "Combined"; IDENT "Scheme"; id = identref; IDENT "from";
- l = LIST1 identref SEP "," -> VernacCombinedScheme (id, l)
- | IDENT "Register"; IDENT "Inline"; id = identref ->
- VernacRegister(id, RegisterInline)
- | IDENT "Universe"; l = LIST1 identref -> VernacUniverse l
- | IDENT "Universes"; l = LIST1 identref -> VernacUniverse l
- | IDENT "Constraint"; l = LIST1 univ_constraint SEP "," -> VernacConstraint l
- ] ]
- ;
-
- thm_token:
- [ [ "Theorem" -> Theorem
- | IDENT "Lemma" -> Lemma
- | IDENT "Fact" -> Fact
- | IDENT "Remark" -> Remark
- | IDENT "Corollary" -> Corollary
- | IDENT "Proposition" -> Proposition
- | IDENT "Property" -> Property ] ]
- ;
- def_token:
- [ [ "Definition" -> (NoDischarge,Definition)
- | IDENT "Example" -> (NoDischarge,Example)
- | IDENT "SubClass" -> (NoDischarge,SubClass) ] ]
- ;
- assumption_token:
- [ [ "Hypothesis" -> (DoDischarge, Logical)
- | "Variable" -> (DoDischarge, Definitional)
- | "Axiom" -> (NoDischarge, Logical)
- | "Parameter" -> (NoDischarge, Definitional)
- | IDENT "Conjecture" -> (NoDischarge, Conjectural) ] ]
- ;
- assumptions_token:
- [ [ IDENT "Hypotheses" -> ("Hypotheses", (DoDischarge, Logical))
- | IDENT "Variables" -> ("Variables", (DoDischarge, Definitional))
- | IDENT "Axioms" -> ("Axioms", (NoDischarge, Logical))
- | IDENT "Parameters" -> ("Parameters", (NoDischarge, Definitional))
- | IDENT "Conjectures" -> ("Conjectures", (NoDischarge, Conjectural)) ] ]
- ;
- inline:
- [ [ IDENT "Inline"; "("; i = INT; ")" -> InlineAt (int_of_string i)
- | IDENT "Inline" -> DefaultInline
- | -> NoInline] ]
- ;
- univ_constraint:
- [ [ l = universe_level; ord = [ "<" -> Univ.Lt | "=" -> Univ.Eq | "<=" -> Univ.Le ];
- r = universe_level -> (l, ord, r) ] ]
- ;
- univ_decl :
- [ [ "@{" ; l = LIST0 identref; ext = [ "+" -> true | -> false ];
- cs = [ "|"; l' = LIST0 univ_constraint SEP ",";
- ext = [ "+" -> true | -> false ]; "}" -> (l',ext)
- | ext = [ "}" -> true | "|}" -> false ] -> ([], ext) ]
- ->
- let open UState in
- { univdecl_instance = l;
- univdecl_extensible_instance = ext;
- univdecl_constraints = fst cs;
- univdecl_extensible_constraints = snd cs }
- ] ]
- ;
- ident_decl:
- [ [ i = identref; l = OPT univ_decl -> (i, l)
- ] ]
- ;
- finite_token:
- [ [ IDENT "Inductive" -> (Inductive_kw,Finite)
- | IDENT "CoInductive" -> (CoInductive,CoFinite)
- | IDENT "Variant" -> (Variant,BiFinite)
- | IDENT "Record" -> (Record,BiFinite)
- | IDENT "Structure" -> (Structure,BiFinite)
- | IDENT "Class" -> (Class true,BiFinite) ] ]
- ;
- cumulativity_token:
- [ [ IDENT "Cumulative" -> VernacCumulative
- | IDENT "NonCumulative" -> VernacNonCumulative ] ]
- ;
- private_token:
- [ [ IDENT "Private" -> true | -> false ] ]
- ;
- (* Simple definitions *)
- def_body:
- [ [ bl = binders; ":="; red = reduce; c = lconstr ->
- if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = mkCLambdaN ~loc:!@loc bl c in
- DefineBody ([], red, c, None)
- else
- (match c with
- | { CAst.v = CCast(c, CastConv t) } -> DefineBody (bl, red, c, Some t)
- | _ -> DefineBody (bl, red, c, None))
- | bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
- let ((bl, c), tyo) =
- if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = CAst.make ~loc:!@loc @@ CCast (c, CastConv t) in
- (([],mkCLambdaN ~loc:!@loc bl c), None)
- else ((bl, c), Some t)
- in
- DefineBody (bl, red, c, tyo)
- | bl = binders; ":"; t = lconstr ->
- ProveBody (bl, t) ] ]
- ;
- reduce:
- [ [ IDENT "Eval"; r = red_expr; "in" -> Some r
- | -> None ] ]
- ;
- one_decl_notation:
- [ [ ntn = ne_lstring; ":="; c = constr;
- scopt = OPT [ ":"; sc = IDENT -> sc] -> (ntn,c,scopt) ] ]
- ;
- decl_notation:
- [ [ "where"; l = LIST1 one_decl_notation SEP IDENT "and" -> l
- | -> [] ] ]
- ;
- (* Inductives and records *)
- opt_constructors_or_fields:
- [ [ ":="; lc = constructor_list_or_record_decl -> lc
- | -> RecordDecl (None, []) ] ]
- ;
- inductive_definition:
- [ [ oc = opt_coercion; id = ident_decl; indpar = binders;
- c = OPT [ ":"; c = lconstr -> c ];
- lc=opt_constructors_or_fields; ntn = decl_notation ->
- (((oc,id),indpar,c,lc),ntn) ] ]
- ;
- constructor_list_or_record_decl:
- [ [ "|"; l = LIST1 constructor SEP "|" -> Constructors l
- | id = identref ; c = constructor_type; "|"; l = LIST0 constructor SEP "|" ->
- Constructors ((c id)::l)
- | id = identref ; c = constructor_type -> Constructors [ c id ]
- | cstr = identref; "{"; fs = record_fields; "}" ->
- RecordDecl (Some cstr,fs)
- | "{";fs = record_fields; "}" -> RecordDecl (None,fs)
- | -> Constructors [] ] ]
- ;
-(*
- csort:
- [ [ s = sort -> CSort (loc,s) ] ]
- ;
-*)
- opt_coercion:
- [ [ ">" -> true
- | -> false ] ]
- ;
- (* (co)-fixpoints *)
- rec_definition:
- [ [ id = ident_decl;
- bl = binders_fixannot;
- ty = type_cstr;
- def = OPT [":="; def = lconstr -> def]; ntn = decl_notation ->
- let bl, annot = bl in ((id,annot,bl,ty,def),ntn) ] ]
- ;
- corec_definition:
- [ [ id = ident_decl; bl = binders; ty = type_cstr;
- def = OPT [":="; def = lconstr -> def]; ntn = decl_notation ->
- ((id,bl,ty,def),ntn) ] ]
- ;
- type_cstr:
- [ [ ":"; c=lconstr -> c
- | -> CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None) ] ]
- ;
- (* Inductive schemes *)
- scheme:
- [ [ kind = scheme_kind -> (None,kind)
- | id = identref; ":="; kind = scheme_kind -> (Some id,kind) ] ]
- ;
- scheme_kind:
- [ [ IDENT "Induction"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> InductionScheme(true,ind,s)
- | IDENT "Minimality"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> InductionScheme(false,ind,s)
- | IDENT "Elimination"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> CaseScheme(true,ind,s)
- | IDENT "Case"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> CaseScheme(false,ind,s)
- | IDENT "Equality"; "for" ; ind = smart_global -> EqualityScheme(ind) ] ]
- ;
- (* Various Binders *)
-(*
- (* ... without coercions *)
- binder_nodef:
- [ [ b = binder_let ->
- (match b with
- CLocalAssum(l,ty) -> (l,ty)
- | CLocalDef _ ->
- Util.user_err_loc
- (loc,"fix_param",Pp.str"defined binder not allowed here.")) ] ]
- ;
-*)
- (* ... with coercions *)
- record_field:
- [ [ bd = record_binder; pri = OPT [ "|"; n = natural -> n ];
- ntn = decl_notation -> (bd,pri),ntn ] ]
- ;
- record_fields:
- [ [ f = record_field; ";"; fs = record_fields -> f :: fs
- | f = record_field; ";" -> [f]
- | f = record_field -> [f]
- | -> []
- ] ]
- ;
- record_binder_body:
- [ [ l = binders; oc = of_type_with_opt_coercion;
- t = lconstr -> fun id -> (oc,AssumExpr (id,mkCProdN ~loc:!@loc l t))
- | l = binders; oc = of_type_with_opt_coercion;
- t = lconstr; ":="; b = lconstr -> fun id ->
- (oc,DefExpr (id,mkCLambdaN ~loc:!@loc l b,Some (mkCProdN ~loc:!@loc l t)))
- | l = binders; ":="; b = lconstr -> fun id ->
- match b.CAst.v with
- | CCast(b', (CastConv t|CastVM t|CastNative t)) ->
- (None,DefExpr(id,mkCLambdaN ~loc:!@loc l b',Some (mkCProdN ~loc:!@loc l t)))
- | _ ->
- (None,DefExpr(id,mkCLambdaN ~loc:!@loc l b,None)) ] ]
- ;
- record_binder:
- [ [ id = name -> (None,AssumExpr(id, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None)))
- | id = name; f = record_binder_body -> f id ] ]
- ;
- assum_list:
- [ [ bl = LIST1 assum_coe -> bl | b = simple_assum_coe -> [b] ] ]
- ;
- assum_coe:
- [ [ "("; a = simple_assum_coe; ")" -> a ] ]
- ;
- simple_assum_coe:
- [ [ idl = LIST1 ident_decl; oc = of_type_with_opt_coercion; c = lconstr ->
- (not (Option.is_empty oc),(idl,c)) ] ]
- ;
-
- constructor_type:
- [[ l = binders;
- t= [ coe = of_type_with_opt_coercion; c = lconstr ->
- fun l id -> (not (Option.is_empty coe),(id,mkCProdN ~loc:!@loc l c))
- | ->
- fun l id -> (false,(id,mkCProdN ~loc:!@loc l (CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None)))) ]
- -> t l
- ]]
-;
-
- constructor:
- [ [ id = identref; c=constructor_type -> c id ] ]
- ;
- of_type_with_opt_coercion:
- [ [ ":>>" -> Some false
- | ":>"; ">" -> Some false
- | ":>" -> Some true
- | ":"; ">"; ">" -> Some false
- | ":"; ">" -> Some true
- | ":" -> None ] ]
- ;
-END
-
-let only_starredidentrefs =
- Gram.Entry.of_parser "test_only_starredidentrefs"
- (fun strm ->
- let rec aux n =
- match Util.stream_nth n strm with
- | KEYWORD "." -> ()
- | KEYWORD ")" -> ()
- | (IDENT _ | KEYWORD "Type" | KEYWORD "*") -> aux (n+1)
- | _ -> raise Stream.Failure in
- aux 0)
-let starredidentreflist_to_expr l =
- match l with
- | [] -> SsEmpty
- | x :: xs -> List.fold_right (fun i acc -> SsUnion(i,acc)) xs x
-
-let warn_deprecated_include_type =
- CWarnings.create ~name:"deprecated-include-type" ~category:"deprecated"
- (fun () -> strbrk "Include Type is deprecated; use Include instead")
-
-(* Modules and Sections *)
-GEXTEND Gram
- GLOBAL: gallina_ext module_expr module_type section_subset_expr;
-
- gallina_ext:
- [ [ (* Interactive module declaration *)
- IDENT "Module"; export = export_token; id = identref;
- bl = LIST0 module_binder; sign = of_module_type;
- body = is_module_expr ->
- VernacDefineModule (export, id, bl, sign, body)
- | IDENT "Module"; "Type"; id = identref;
- bl = LIST0 module_binder; sign = check_module_types;
- body = is_module_type ->
- VernacDeclareModuleType (id, bl, sign, body)
- | IDENT "Declare"; IDENT "Module"; export = export_token; id = identref;
- bl = LIST0 module_binder; ":"; mty = module_type_inl ->
- VernacDeclareModule (export, id, bl, mty)
- (* Section beginning *)
- | IDENT "Section"; id = identref -> VernacBeginSection id
- | IDENT "Chapter"; id = identref -> VernacBeginSection id
-
- (* This end a Section a Module or a Module Type *)
- | IDENT "End"; id = identref -> VernacEndSegment id
-
- (* Naming a set of section hyps *)
- | IDENT "Collection"; id = identref; ":="; expr = section_subset_expr ->
- VernacNameSectionHypSet (id, expr)
-
- (* Requiring an already compiled module *)
- | IDENT "Require"; export = export_token; qidl = LIST1 global ->
- VernacRequire (None, export, qidl)
- | IDENT "From" ; ns = global ; IDENT "Require"; export = export_token
- ; qidl = LIST1 global ->
- VernacRequire (Some ns, export, qidl)
- | IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl)
- | IDENT "Export"; qidl = LIST1 global -> VernacImport (true,qidl)
- | IDENT "Include"; e = module_type_inl; l = LIST0 ext_module_expr ->
- VernacInclude(e::l)
- | IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
- warn_deprecated_include_type ~loc:!@loc ();
- VernacInclude(e::l) ] ]
- ;
- export_token:
- [ [ IDENT "Import" -> Some false
- | IDENT "Export" -> Some true
- | -> None ] ]
- ;
- ext_module_type:
- [ [ "<+"; mty = module_type_inl -> mty ] ]
- ;
- ext_module_expr:
- [ [ "<+"; mexpr = module_expr_inl -> mexpr ] ]
- ;
- check_module_type:
- [ [ "<:"; mty = module_type_inl -> mty ] ]
- ;
- check_module_types:
- [ [ mtys = LIST0 check_module_type -> mtys ] ]
- ;
- of_module_type:
- [ [ ":"; mty = module_type_inl -> Enforce mty
- | mtys = check_module_types -> Check mtys ] ]
- ;
- is_module_type:
- [ [ ":="; mty = module_type_inl ; l = LIST0 ext_module_type -> (mty::l)
- | -> [] ] ]
- ;
- is_module_expr:
- [ [ ":="; mexpr = module_expr_inl; l = LIST0 ext_module_expr -> (mexpr::l)
- | -> [] ] ]
- ;
- functor_app_annot:
- [ [ "["; IDENT "inline"; "at"; IDENT "level"; i = INT; "]" ->
- InlineAt (int_of_string i)
- | "["; IDENT "no"; IDENT "inline"; "]" -> NoInline
- | -> DefaultInline
- ] ]
- ;
- module_expr_inl:
- [ [ "!"; me = module_expr -> (me,NoInline)
- | me = module_expr; a = functor_app_annot -> (me,a) ] ]
- ;
- module_type_inl:
- [ [ "!"; me = module_type -> (me,NoInline)
- | me = module_type; a = functor_app_annot -> (me,a) ] ]
- ;
- (* Module binder *)
- module_binder:
- [ [ "("; export = export_token; idl = LIST1 identref; ":";
- mty = module_type_inl; ")" -> (export,idl,mty) ] ]
- ;
- (* Module expressions *)
- module_expr:
- [ [ me = module_expr_atom -> me
- | me1 = module_expr; me2 = module_expr_atom -> CAst.make ~loc:!@loc @@ CMapply (me1,me2)
- ] ]
- ;
- module_expr_atom:
- [ [ qid = qualid -> CAst.make ~loc:!@loc @@ CMident qid | "("; me = module_expr; ")" -> me ] ]
- ;
- with_declaration:
- [ [ "Definition"; fqid = fullyqualid; udecl = OPT univ_decl; ":="; c = Constr.lconstr ->
- CWith_Definition (fqid,udecl,c)
- | IDENT "Module"; fqid = fullyqualid; ":="; qid = qualid ->
- CWith_Module (fqid,qid)
- ] ]
- ;
- module_type:
- [ [ qid = qualid -> CAst.make ~loc:!@loc @@ CMident qid
- | "("; mt = module_type; ")" -> mt
- | mty = module_type; me = module_expr_atom ->
- CAst.make ~loc:!@loc @@ CMapply (mty,me)
- | mty = module_type; "with"; decl = with_declaration ->
- CAst.make ~loc:!@loc @@ CMwith (mty,decl)
- ] ]
- ;
- (* Proof using *)
- section_subset_expr:
- [ [ only_starredidentrefs; l = LIST0 starredidentref ->
- starredidentreflist_to_expr l
- | e = ssexpr -> e ]]
- ;
- starredidentref:
- [ [ i = identref -> SsSingl i
- | i = identref; "*" -> SsFwdClose(SsSingl i)
- | "Type" -> SsType
- | "Type"; "*" -> SsFwdClose SsType ]]
- ;
- ssexpr:
- [ "35"
- [ "-"; e = ssexpr -> SsCompl e ]
- | "50"
- [ e1 = ssexpr; "-"; e2 = ssexpr->SsSubstr(e1,e2)
- | e1 = ssexpr; "+"; e2 = ssexpr->SsUnion(e1,e2)]
- | "0"
- [ i = starredidentref -> i
- | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"->
- starredidentreflist_to_expr l
- | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"; "*" ->
- SsFwdClose(starredidentreflist_to_expr l)
- | "("; e = ssexpr; ")"-> e
- | "("; e = ssexpr; ")"; "*" -> SsFwdClose e ] ]
- ;
-END
-
-(* Extensions: implicits, coercions, etc. *)
-GEXTEND Gram
- GLOBAL: gallina_ext instance_name hint_info;
-
- gallina_ext:
- [ [ (* Transparent and Opaque *)
- IDENT "Transparent"; l = LIST1 smart_global ->
- VernacSetOpacity (Conv_oracle.transparent, l)
- | IDENT "Opaque"; l = LIST1 smart_global ->
- VernacSetOpacity (Conv_oracle.Opaque, l)
- | IDENT "Strategy"; l =
- LIST1 [ v=strategy_level; "["; q=LIST1 smart_global; "]" -> (v,q)] ->
- VernacSetStrategy l
- (* Canonical structure *)
- | IDENT "Canonical"; IDENT "Structure"; qid = global ->
- VernacCanonical CAst.(make ~loc:!@loc @@ AN qid)
- | IDENT "Canonical"; IDENT "Structure"; ntn = by_notation ->
- VernacCanonical CAst.(make ~loc:!@loc @@ ByNotation ntn)
- | IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
- let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make (Name s)),None),d)
-
- (* Coercions *)
- | IDENT "Coercion"; qid = global; d = def_body ->
- let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,Coercion),((CAst.make (Name s)),None),d)
- | IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
- s = class_rawexpr; ">->"; t = class_rawexpr ->
- VernacIdentityCoercion (f, s, t)
- | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->";
- t = class_rawexpr ->
- VernacCoercion (CAst.make ~loc:!@loc @@ AN qid, s, t)
- | IDENT "Coercion"; ntn = by_notation; ":"; s = class_rawexpr; ">->";
- t = class_rawexpr ->
- VernacCoercion (CAst.make ~loc:!@loc @@ ByNotation ntn, s, t)
-
- | IDENT "Context"; c = LIST1 binder ->
- VernacContext (List.flatten c)
-
- | IDENT "Instance"; namesup = instance_name; ":";
- expl = [ "!" -> Decl_kinds.Implicit | -> Decl_kinds.Explicit ] ; t = operconstr LEVEL "200";
- info = hint_info ;
- props = [ ":="; "{"; r = record_declaration; "}" -> Some (true,r) |
- ":="; c = lconstr -> Some (false,c) | -> None ] ->
- VernacInstance (false,snd namesup,(fst namesup,expl,t),props,info)
-
- | IDENT "Existing"; IDENT "Instance"; id = global;
- info = hint_info ->
- VernacDeclareInstances [id, info]
-
- | IDENT "Existing"; IDENT "Instances"; ids = LIST1 global;
- pri = OPT [ "|"; i = natural -> i ] ->
- let info = { Typeclasses.hint_priority = pri; hint_pattern = None } in
- let insts = List.map (fun i -> (i, info)) ids in
- VernacDeclareInstances insts
-
- | IDENT "Existing"; IDENT "Class"; is = global -> VernacDeclareClass is
-
- (* Arguments *)
- | IDENT "Arguments"; qid = smart_global;
- args = LIST0 argument_spec_block;
- more_implicits = OPT
- [ ","; impl = LIST1
- [ impl = LIST0 more_implicits_block -> List.flatten impl]
- SEP "," -> impl
- ];
- mods = OPT [ ":"; l = LIST1 arguments_modifier SEP "," -> l ] ->
- let mods = match mods with None -> [] | Some l -> List.flatten l in
- let slash_position = ref None in
- let rec parse_args i = function
- | [] -> []
- | `Id x :: args -> x :: parse_args (i+1) args
- | `Slash :: args ->
- if Option.is_empty !slash_position then
- (slash_position := Some i; parse_args i args)
- else
- user_err Pp.(str "The \"/\" modifier can occur only once")
- in
- let args = parse_args 0 (List.flatten args) in
- let more_implicits = Option.default [] more_implicits in
- VernacArguments (qid, args, more_implicits, !slash_position, mods)
-
- | IDENT "Implicit"; "Type"; bl = reserv_list ->
- VernacReserve bl
-
- | IDENT "Implicit"; IDENT "Types"; bl = reserv_list ->
- test_plural_form_types loc "Implicit Types" bl;
- VernacReserve bl
-
- | IDENT "Generalizable";
- gen = [IDENT "All"; IDENT "Variables" -> Some []
- | IDENT "No"; IDENT "Variables" -> None
- | ["Variable" | IDENT "Variables"];
- idl = LIST1 identref -> Some idl ] ->
- VernacGeneralizable gen ] ]
- ;
- arguments_modifier:
- [ [ IDENT "simpl"; IDENT "nomatch" -> [`ReductionDontExposeCase]
- | IDENT "simpl"; IDENT "never" -> [`ReductionNeverUnfold]
- | IDENT "default"; IDENT "implicits" -> [`DefaultImplicits]
- | IDENT "clear"; IDENT "implicits" -> [`ClearImplicits]
- | IDENT "clear"; IDENT "scopes" -> [`ClearScopes]
- | IDENT "rename" -> [`Rename]
- | IDENT "assert" -> [`Assert]
- | IDENT "extra"; IDENT "scopes" -> [`ExtraScopes]
- | IDENT "clear"; IDENT "scopes"; IDENT "and"; IDENT "implicits" ->
- [`ClearImplicits; `ClearScopes]
- | IDENT "clear"; IDENT "implicits"; IDENT "and"; IDENT "scopes" ->
- [`ClearImplicits; `ClearScopes]
- ] ]
- ;
- scope:
- [ [ "%"; key = IDENT -> key ] ]
- ;
- argument_spec: [
- [ b = OPT "!"; id = name ; s = OPT scope ->
- id.CAst.v, not (Option.is_empty b), Option.map (fun x -> CAst.make ~loc:!@loc x) s
- ]
- ];
- (* List of arguments implicit status, scope, modifiers *)
- argument_spec_block: [
- [ item = argument_spec ->
- let name, recarg_like, notation_scope = item in
- [`Id { name=name; recarg_like=recarg_like;
- notation_scope=notation_scope;
- implicit_status = NotImplicit}]
- | "/" -> [`Slash]
- | "("; items = LIST1 argument_spec; ")"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = NotImplicit}) items
- | "["; items = LIST1 argument_spec; "]"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = Implicit}) items
- | "{"; items = LIST1 argument_spec; "}"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = MaximallyImplicit}) items
- ]
- ];
- (* Same as [argument_spec_block], but with only implicit status and names *)
- more_implicits_block: [
- [ name = name -> [(name.CAst.v, Vernacexpr.NotImplicit)]
- | "["; items = LIST1 name; "]" ->
- List.map (fun name -> (name.CAst.v, Vernacexpr.Implicit)) items
- | "{"; items = LIST1 name; "}" ->
- List.map (fun name -> (name.CAst.v, Vernacexpr.MaximallyImplicit)) items
- ]
- ];
- strategy_level:
- [ [ IDENT "expand" -> Conv_oracle.Expand
- | IDENT "opaque" -> Conv_oracle.Opaque
- | n=INT -> Conv_oracle.Level (int_of_string n)
- | "-"; n=INT -> Conv_oracle.Level (- int_of_string n)
- | IDENT "transparent" -> Conv_oracle.transparent ] ]
- ;
- instance_name:
- [ [ name = ident_decl; sup = OPT binders ->
- (CAst.map (fun id -> Name id) (fst name), snd name),
- (Option.default [] sup)
- | -> ((CAst.make ~loc:!@loc Anonymous), None), [] ] ]
- ;
- hint_info:
- [ [ "|"; i = OPT natural; pat = OPT constr_pattern ->
- { Typeclasses.hint_priority = i; hint_pattern = pat }
- | -> { Typeclasses.hint_priority = None; hint_pattern = None } ] ]
- ;
- reserv_list:
- [ [ bl = LIST1 reserv_tuple -> bl | b = simple_reserv -> [b] ] ]
- ;
- reserv_tuple:
- [ [ "("; a = simple_reserv; ")" -> a ] ]
- ;
- simple_reserv:
- [ [ idl = LIST1 identref; ":"; c = lconstr -> (idl,c) ] ]
- ;
-
-END
-
-GEXTEND Gram
- GLOBAL: command query_command class_rawexpr gallina_ext;
-
- gallina_ext:
- [ [ IDENT "Export"; "Set"; table = option_table; v = option_value ->
- VernacSetOption (true, table, v)
- | IDENT "Export"; IDENT "Unset"; table = option_table ->
- VernacUnsetOption (true, table)
- ] ];
-
- command:
- [ [ IDENT "Comments"; l = LIST0 comment -> VernacComments l
-
- (* Hack! Should be in grammar_ext, but camlp5 factorizes badly *)
- | IDENT "Declare"; IDENT "Instance"; namesup = instance_name; ":";
- expl = [ "!" -> Decl_kinds.Implicit | -> Decl_kinds.Explicit ] ; t = operconstr LEVEL "200";
- info = hint_info ->
- VernacInstance (true, snd namesup, (fst namesup, expl, t), None, info)
-
- (* System directory *)
- | IDENT "Pwd" -> VernacChdir None
- | IDENT "Cd" -> VernacChdir None
- | IDENT "Cd"; dir = ne_string -> VernacChdir (Some dir)
-
- | IDENT "Load"; verbosely = [ IDENT "Verbose" -> true | -> false ];
- s = [ s = ne_string -> s | s = IDENT -> s ] ->
- VernacLoad (verbosely, s)
- | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 ne_string ->
- VernacDeclareMLModule l
-
- | IDENT "Locate"; l = locatable -> VernacLocate l
-
- (* Managing load paths *)
- | IDENT "Add"; IDENT "LoadPath"; dir = ne_string; alias = as_dirpath ->
- VernacAddLoadPath (false, dir, alias)
- | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = ne_string;
- alias = as_dirpath -> VernacAddLoadPath (true, dir, alias)
- | IDENT "Remove"; IDENT "LoadPath"; dir = ne_string ->
- VernacRemoveLoadPath dir
-
- (* For compatibility *)
- | IDENT "AddPath"; dir = ne_string; "as"; alias = as_dirpath ->
- VernacAddLoadPath (false, dir, alias)
- | IDENT "AddRecPath"; dir = ne_string; "as"; alias = as_dirpath ->
- VernacAddLoadPath (true, dir, alias)
- | IDENT "DelPath"; dir = ne_string ->
- VernacRemoveLoadPath dir
-
- (* Type-Checking (pas dans le refman) *)
- | "Type"; c = lconstr -> VernacGlobalCheck c
-
- (* Printing (careful factorization of entries) *)
- | IDENT "Print"; p = printable -> VernacPrint p
- | IDENT "Print"; qid = smart_global; l = OPT univ_name_list -> VernacPrint (PrintName (qid,l))
- | IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
- VernacPrint (PrintModuleType qid)
- | IDENT "Print"; IDENT "Module"; qid = global ->
- VernacPrint (PrintModule qid)
- | IDENT "Print"; IDENT "Namespace" ; ns = dirpath ->
- VernacPrint (PrintNamespace ns)
- | IDENT "Inspect"; n = natural -> VernacPrint (PrintInspect n)
-
- | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
- VernacAddMLPath (false, dir)
- | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
- VernacAddMLPath (true, dir)
-
- (* For acting on parameter tables *)
- | "Set"; table = option_table; v = option_value ->
- VernacSetOption (false, table, v)
- | IDENT "Unset"; table = option_table ->
- VernacUnsetOption (false, table)
-
- | IDENT "Print"; IDENT "Table"; table = option_table ->
- VernacPrintOption table
-
- | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
- -> VernacAddOption ([table;field], v)
- (* A global value below will be hidden by a field above! *)
- (* In fact, we give priority to secondary tables *)
- (* No syntax for tertiary tables due to conflict *)
- (* (but they are unused anyway) *)
- | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
- VernacAddOption ([table], v)
-
- | IDENT "Test"; table = option_table; "for"; v = LIST1 option_ref_value
- -> VernacMemOption (table, v)
- | IDENT "Test"; table = option_table ->
- VernacPrintOption table
-
- | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
- -> VernacRemoveOption ([table;field], v)
- | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
- VernacRemoveOption ([table], v) ]]
- ;
- query_command: (* TODO: rapprocher Eval et Check *)
- [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (Some r, g, c)
- | IDENT "Compute"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (Some (Genredexpr.CbvVm None), g, c)
- | IDENT "Check"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (None, g, c)
- (* Searching the environment *)
- | IDENT "About"; qid = smart_global; l = OPT univ_name_list; "." ->
- fun g -> VernacPrint (PrintAbout (qid,l,g))
- | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchHead c,g, l)
- | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchPattern c,g, l)
- | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchRewrite c,g, l)
- | IDENT "Search"; s = searchabout_query; l = searchabout_queries; "." ->
- let (sl,m) = l in fun g -> VernacSearch (SearchAbout (s::sl),g, m)
- (* compatibility: SearchAbout *)
- | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries; "." ->
- fun g -> let (sl,m) = l in VernacSearch (SearchAbout (s::sl),g, m)
- (* compatibility: SearchAbout with "[ ... ]" *)
- | IDENT "SearchAbout"; "["; sl = LIST1 searchabout_query; "]";
- l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchAbout sl,g, l)
- ] ]
- ;
- printable:
- [ [ IDENT "Term"; qid = smart_global; l = OPT univ_name_list -> PrintName (qid,l)
- | IDENT "All" -> PrintFullContext
- | IDENT "Section"; s = global -> PrintSectionContext s
- | IDENT "Grammar"; ent = IDENT ->
- (* This should be in "syntax" section but is here for factorization*)
- PrintGrammar ent
- | IDENT "LoadPath"; dir = OPT dirpath -> PrintLoadPath dir
- | IDENT "Modules" ->
- user_err Pp.(str "Print Modules is obsolete; use Print Libraries instead")
- | IDENT "Libraries" -> PrintModules
-
- | IDENT "ML"; IDENT "Path" -> PrintMLLoadPath
- | IDENT "ML"; IDENT "Modules" -> PrintMLModules
- | IDENT "Debug"; IDENT "GC" -> PrintDebugGC
- | IDENT "Graph" -> PrintGraph
- | IDENT "Classes" -> PrintClasses
- | IDENT "TypeClasses" -> PrintTypeClasses
- | IDENT "Instances"; qid = smart_global -> PrintInstances qid
- | IDENT "Coercions" -> PrintCoercions
- | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
- -> PrintCoercionPaths (s,t)
- | IDENT "Canonical"; IDENT "Projections" -> PrintCanonicalConversions
- | IDENT "Tables" -> PrintTables
- | IDENT "Options" -> PrintTables (* A Synonymous to Tables *)
- | IDENT "Hint" -> PrintHintGoal
- | IDENT "Hint"; qid = smart_global -> PrintHint qid
- | IDENT "Hint"; "*" -> PrintHintDb
- | IDENT "HintDb"; s = IDENT -> PrintHintDbName s
- | IDENT "Scopes" -> PrintScopes
- | IDENT "Scope"; s = IDENT -> PrintScope s
- | IDENT "Visibility"; s = OPT [x = IDENT -> x ] -> PrintVisibility s
- | IDENT "Implicit"; qid = smart_global -> PrintImplicit qid
- | IDENT "Universes"; fopt = OPT ne_string -> PrintUniverses (false, fopt)
- | IDENT "Sorted"; IDENT "Universes"; fopt = OPT ne_string -> PrintUniverses (true, fopt)
- | IDENT "Assumptions"; qid = smart_global -> PrintAssumptions (false, false, qid)
- | IDENT "Opaque"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (true, false, qid)
- | IDENT "Transparent"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (false, true, qid)
- | IDENT "All"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (true, true, qid)
- | IDENT "Strategy"; qid = smart_global -> PrintStrategy (Some qid)
- | IDENT "Strategies" -> PrintStrategy None ] ]
- ;
- class_rawexpr:
- [ [ IDENT "Funclass" -> FunClass
- | IDENT "Sortclass" -> SortClass
- | qid = smart_global -> RefClass qid ] ]
- ;
- locatable:
- [ [ qid = smart_global -> LocateAny qid
- | IDENT "Term"; qid = smart_global -> LocateTerm qid
- | IDENT "File"; f = ne_string -> LocateFile f
- | IDENT "Library"; qid = global -> LocateLibrary qid
- | IDENT "Module"; qid = global -> LocateModule qid ] ]
- ;
- option_value:
- [ [ -> BoolValue true
- | n = integer -> IntValue (Some n)
- | s = STRING -> StringValue s ] ]
- ;
- option_ref_value:
- [ [ id = global -> QualidRefValue id
- | s = STRING -> StringRefValue s ] ]
- ;
- option_table:
- [ [ fl = LIST1 [ x = IDENT -> x ] -> fl ]]
- ;
- as_dirpath:
- [ [ d = OPT [ "as"; d = dirpath -> d ] -> d ] ]
- ;
- ne_in_or_out_modules:
- [ [ IDENT "inside"; l = LIST1 global -> SearchInside l
- | IDENT "outside"; l = LIST1 global -> SearchOutside l ] ]
- ;
- in_or_out_modules:
- [ [ m = ne_in_or_out_modules -> m
- | -> SearchOutside [] ] ]
- ;
- comment:
- [ [ c = constr -> CommentConstr c
- | s = STRING -> CommentString s
- | n = natural -> CommentInt n ] ]
- ;
- positive_search_mark:
- [ [ "-" -> false | -> true ] ]
- ;
- scope:
- [ [ "%"; key = IDENT -> key ] ]
- ;
- searchabout_query:
- [ [ b = positive_search_mark; s = ne_string; sc = OPT scope ->
- (b, SearchString (s,sc))
- | b = positive_search_mark; p = constr_pattern ->
- (b, SearchSubPattern p)
- ] ]
- ;
- searchabout_queries:
- [ [ m = ne_in_or_out_modules -> ([],m)
- | s = searchabout_query; l = searchabout_queries ->
- let (sl,m) = l in (s::sl,m)
- | -> ([],SearchOutside [])
- ] ]
- ;
- univ_name_list:
- [ [ "@{" ; l = LIST0 name; "}" -> l ] ]
- ;
-END;
-
-GEXTEND Gram
- command:
- [ [
-(* State management *)
- IDENT "Write"; IDENT "State"; s = IDENT -> VernacWriteState s
- | IDENT "Write"; IDENT "State"; s = ne_string -> VernacWriteState s
- | IDENT "Restore"; IDENT "State"; s = IDENT -> VernacRestoreState s
- | IDENT "Restore"; IDENT "State"; s = ne_string -> VernacRestoreState s
-
-(* Resetting *)
- | IDENT "Reset"; IDENT "Initial" -> VernacResetInitial
- | IDENT "Reset"; id = identref -> VernacResetName id
- | IDENT "Back" -> VernacBack 1
- | IDENT "Back"; n = natural -> VernacBack n
- | IDENT "BackTo"; n = natural -> VernacBackTo n
-
-(* Tactic Debugger *)
- | IDENT "Debug"; IDENT "On" ->
- VernacSetOption (false, ["Ltac";"Debug"], BoolValue true)
-
- | IDENT "Debug"; IDENT "Off" ->
- VernacSetOption (false, ["Ltac";"Debug"], BoolValue false)
-
-(* registration of a custom reduction *)
-
- | IDENT "Declare"; IDENT "Reduction"; s = IDENT; ":=";
- r = red_expr ->
- VernacDeclareReduction (s,r)
-
- ] ];
- END
-;;
-
-(* Grammar extensions *)
-
-GEXTEND Gram
- GLOBAL: syntax;
-
- syntax:
- [ [ IDENT "Open"; IDENT "Scope"; sc = IDENT ->
- VernacOpenCloseScope (true,sc)
-
- | IDENT "Close"; IDENT "Scope"; sc = IDENT ->
- VernacOpenCloseScope (false,sc)
-
- | IDENT "Delimit"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT ->
- VernacDelimiters (sc, Some key)
- | IDENT "Undelimit"; IDENT "Scope"; sc = IDENT ->
- VernacDelimiters (sc, None)
-
- | IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with";
- refl = LIST1 class_rawexpr -> VernacBindScope (sc,refl)
-
- | IDENT "Infix"; op = ne_lstring; ":="; p = constr;
- modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- VernacInfix ((op,modl),p,sc)
- | IDENT "Notation"; id = identref;
- idl = LIST0 ident; ":="; c = constr; b = only_parsing ->
- VernacSyntacticDefinition
- (id,(idl,c),b)
- | IDENT "Notation"; s = lstring; ":=";
- c = constr;
- modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- VernacNotation (c,(s,modl),sc)
- | IDENT "Format"; IDENT "Notation"; n = STRING; s = STRING; fmt = STRING ->
- VernacNotationAddFormat (n,s,fmt)
-
- | IDENT "Reserved"; IDENT "Infix"; s = ne_lstring;
- l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ] ->
- let s = CAst.map (fun s -> "x '"^s^"' y") s in
- VernacSyntaxExtension (true,(s,l))
-
- | IDENT "Reserved"; IDENT "Notation";
- s = ne_lstring;
- l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]
- -> VernacSyntaxExtension (false, (s,l))
-
- (* "Print" "Grammar" should be here but is in "command" entry in order
- to factorize with other "Print"-based vernac entries *)
- ] ]
- ;
- only_parsing:
- [ [ "("; IDENT "only"; IDENT "parsing"; ")" ->
- Some Flags.Current
- | "("; IDENT "compat"; s = STRING; ")" ->
- Some (parse_compat_version s)
- | -> None ] ]
- ;
- level:
- [ [ IDENT "level"; n = natural -> NumLevel n
- | IDENT "next"; IDENT "level" -> NextLevel ] ]
- ;
- syntax_modifier:
- [ [ "at"; IDENT "level"; n = natural -> SetLevel n
- | IDENT "left"; IDENT "associativity" -> SetAssoc LeftA
- | IDENT "right"; IDENT "associativity" -> SetAssoc RightA
- | IDENT "no"; IDENT "associativity" -> SetAssoc NonA
- | IDENT "only"; IDENT "printing" -> SetOnlyPrinting
- | IDENT "only"; IDENT "parsing" -> SetOnlyParsing
- | IDENT "compat"; s = STRING ->
- SetCompatVersion (parse_compat_version s)
- | IDENT "format"; s1 = [s = STRING -> CAst.make ~loc:!@loc s];
- s2 = OPT [s = STRING -> CAst.make ~loc:!@loc s] ->
- begin match s1, s2 with
- | { CAst.v = k }, Some s -> SetFormat(k,s)
- | s, None -> SetFormat ("text",s) end
- | x = IDENT; ","; l = LIST1 [id = IDENT -> id ] SEP ","; "at";
- lev = level -> SetItemLevel (x::l,lev)
- | x = IDENT; "at"; lev = level -> SetItemLevel ([x],lev)
- | x = IDENT; "at"; lev = level; b = constr_as_binder_kind -> SetItemLevelAsBinder ([x],b,Some lev)
- | x = IDENT; b = constr_as_binder_kind -> SetItemLevelAsBinder ([x],b,None)
- | x = IDENT; typ = syntax_extension_type -> SetEntryType (x,typ)
- ] ]
- ;
- syntax_extension_type:
- [ [ IDENT "ident" -> ETName | IDENT "global" -> ETReference
- | IDENT "bigint" -> ETBigint
- | IDENT "binder" -> ETBinder true
- | IDENT "constr"; n = OPT at_level; b = constr_as_binder_kind -> ETConstrAsBinder (b,n)
- | IDENT "pattern" -> ETPattern (false,None)
- | IDENT "pattern"; "at"; IDENT "level"; n = natural -> ETPattern (false,Some n)
- | IDENT "strict"; IDENT "pattern" -> ETPattern (true,None)
- | IDENT "strict"; IDENT "pattern"; "at"; IDENT "level"; n = natural -> ETPattern (true,Some n)
- | IDENT "closed"; IDENT "binder" -> ETBinder false
- ] ]
- ;
- at_level:
- [ [ "at"; n = level -> n ] ]
- ;
- constr_as_binder_kind:
- [ [ "as"; IDENT "ident" -> Notation_term.AsIdent
- | "as"; IDENT "pattern" -> Notation_term.AsIdentOrPattern
- | "as"; IDENT "strict"; IDENT "pattern" -> Notation_term.AsStrictPattern ] ]
- ;
-END
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
new file mode 100644
index 000000000..3a01ce6df
--- /dev/null
+++ b/vernac/g_vernac.mlg
@@ -0,0 +1,1173 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+
+open Pp
+open CErrors
+open Util
+open Names
+open Glob_term
+open Vernacexpr
+open Constrexpr
+open Constrexpr_ops
+open Extend
+open Decl_kinds
+open Declaremods
+open Declarations
+open Namegen
+open Tok (* necessary for camlp5 *)
+
+open Pcoq
+open Pcoq.Prim
+open Pcoq.Constr
+open Pcoq.Module
+open Pvernac.Vernac_
+
+let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ]
+let _ = List.iter CLexer.add_keyword vernac_kw
+
+(* Rem: do not join the different GEXTEND into one, it breaks native *)
+(* compilation on PowerPC and Sun architectures *)
+
+let query_command = Gram.entry_create "vernac:query_command"
+
+let subprf = Gram.entry_create "vernac:subprf"
+
+let class_rawexpr = Gram.entry_create "vernac:class_rawexpr"
+let thm_token = Gram.entry_create "vernac:thm_token"
+let def_body = Gram.entry_create "vernac:def_body"
+let decl_notation = Gram.entry_create "vernac:decl_notation"
+let record_field = Gram.entry_create "vernac:record_field"
+let of_type_with_opt_coercion = Gram.entry_create "vernac:of_type_with_opt_coercion"
+let instance_name = Gram.entry_create "vernac:instance_name"
+let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
+
+let make_bullet s =
+ let open Proof_bullet in
+ let n = String.length s in
+ match s.[0] with
+ | '-' -> Dash n
+ | '+' -> Plus n
+ | '*' -> Star n
+ | _ -> assert false
+
+let parse_compat_version ?(allow_old = true) = let open Flags in function
+ | "8.8" -> Current
+ | "8.7" -> V8_7
+ | "8.6" -> V8_6
+ | ("8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
+ CErrors.user_err ~hdr:"get_compat_version"
+ Pp.(str "Compatibility with version " ++ str s ++ str " not supported.")
+ | s ->
+ CErrors.user_err ~hdr:"get_compat_version"
+ Pp.(str "Unknown compatibility version \"" ++ str s ++ str "\".")
+
+}
+
+GRAMMAR EXTEND Gram
+ GLOBAL: vernac_control gallina_ext noedit_mode subprf;
+ vernac_control: FIRST
+ [ [ IDENT "Time"; c = located_vernac -> { VernacTime (false,c) }
+ | IDENT "Redirect"; s = ne_string; c = located_vernac -> { VernacRedirect (s, c) }
+ | IDENT "Timeout"; n = natural; v = vernac_control -> { VernacTimeout(n,v) }
+ | IDENT "Fail"; v = vernac_control -> { VernacFail v }
+ | v = vernac -> { let (f, v) = v in VernacExpr(f, v) } ]
+ ]
+ ;
+ vernac:
+ [ [ IDENT "Local"; v = vernac_poly -> { let (f, v) = v in (VernacLocal true :: f, v) }
+ | IDENT "Global"; v = vernac_poly -> { let (f, v) = v in (VernacLocal false :: f, v) }
+
+ | v = vernac_poly -> { v } ]
+ ]
+ ;
+ vernac_poly:
+ [ [ IDENT "Polymorphic"; v = vernac_aux -> { let (f, v) = v in (VernacPolymorphic true :: f, v) }
+ | IDENT "Monomorphic"; v = vernac_aux -> { let (f, v) = v in (VernacPolymorphic false :: f, v) }
+ | v = vernac_aux -> { v } ]
+ ]
+ ;
+ vernac_aux:
+ (* Better to parse "." here: in case of failure (e.g. in coerce_to_var), *)
+ (* "." is still in the stream and discard_to_dot works correctly *)
+ [ [ IDENT "Program"; g = gallina; "." -> { ([VernacProgram], g) }
+ | IDENT "Program"; g = gallina_ext; "." -> { ([VernacProgram], g) }
+ | g = gallina; "." -> { ([], g) }
+ | g = gallina_ext; "." -> { ([], g) }
+ | c = command; "." -> { ([], c) }
+ | c = syntax; "." -> { ([], c) }
+ | c = subprf -> { ([], c) }
+ ] ]
+ ;
+ vernac_aux: LAST
+ [ [ prfcom = command_entry -> { ([], prfcom) } ] ]
+ ;
+ noedit_mode:
+ [ [ c = query_command -> { c None } ] ]
+ ;
+
+ subprf:
+ [ [ s = BULLET -> { VernacBullet (make_bullet s) }
+ | "{" -> { VernacSubproof None }
+ | "}" -> { VernacEndSubproof }
+ ] ]
+ ;
+
+ located_vernac:
+ [ [ v = vernac_control -> { CAst.make ~loc v } ] ]
+ ;
+END
+
+{
+
+let warn_plural_command =
+ CWarnings.create ~name:"plural-command" ~category:"pedantic" ~default:CWarnings.Disabled
+ (fun kwd -> strbrk (Printf.sprintf "Command \"%s\" expects more than one assumption." kwd))
+
+let test_plural_form loc kwd = function
+ | [(_,([_],_))] ->
+ warn_plural_command ~loc kwd
+ | _ -> ()
+
+let test_plural_form_types loc kwd = function
+ | [([_],_)] ->
+ warn_plural_command ~loc kwd
+ | _ -> ()
+
+let lname_of_lident : lident -> lname =
+ CAst.map (fun s -> Name s)
+
+let name_of_ident_decl : ident_decl -> name_decl =
+ on_fst lname_of_lident
+
+}
+
+(* Gallina declarations *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
+ record_field decl_notation rec_definition ident_decl univ_decl;
+
+ gallina:
+ (* Definition, Theorem, Variable, Axiom, ... *)
+ [ [ thm = thm_token; id = ident_decl; bl = binders; ":"; c = lconstr;
+ l = LIST0
+ [ "with"; id = ident_decl; bl = binders; ":"; c = lconstr ->
+ { (id,(bl,c)) } ] ->
+ { VernacStartTheoremProof (thm, (id,(bl,c))::l) }
+ | stre = assumption_token; nl = inline; bl = assum_list ->
+ { VernacAssumption (stre, nl, bl) }
+ | tk = assumptions_token; nl = inline; bl = assum_list ->
+ { let (kwd,stre) = tk in
+ test_plural_form loc kwd bl;
+ VernacAssumption (stre, nl, bl) }
+ | d = def_token; id = ident_decl; b = def_body ->
+ { VernacDefinition (d, name_of_ident_decl id, b) }
+ | IDENT "Let"; id = identref; b = def_body ->
+ { VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b) }
+ (* Gallina inductive declarations *)
+ | cum = OPT cumulativity_token; priv = private_token; f = finite_token;
+ indl = LIST1 inductive_definition SEP "with" ->
+ { let (k,f) = f in
+ let indl=List.map (fun ((a,b,c,d),e) -> ((a,b,c,k,d),e)) indl in
+ VernacInductive (cum, priv,f,indl) }
+ | "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
+ { VernacFixpoint (NoDischarge, recs) }
+ | IDENT "Let"; "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
+ { VernacFixpoint (DoDischarge, recs) }
+ | "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
+ { VernacCoFixpoint (NoDischarge, corecs) }
+ | IDENT "Let"; "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
+ { VernacCoFixpoint (DoDischarge, corecs) }
+ | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> { VernacScheme l }
+ | IDENT "Combined"; IDENT "Scheme"; id = identref; IDENT "from";
+ l = LIST1 identref SEP "," -> { VernacCombinedScheme (id, l) }
+ | IDENT "Register"; IDENT "Inline"; id = identref ->
+ { VernacRegister(id, RegisterInline) }
+ | IDENT "Universe"; l = LIST1 identref -> { VernacUniverse l }
+ | IDENT "Universes"; l = LIST1 identref -> { VernacUniverse l }
+ | IDENT "Constraint"; l = LIST1 univ_constraint SEP "," -> { VernacConstraint l }
+ ] ]
+ ;
+
+ thm_token:
+ [ [ "Theorem" -> { Theorem }
+ | IDENT "Lemma" -> { Lemma }
+ | IDENT "Fact" -> { Fact }
+ | IDENT "Remark" -> { Remark }
+ | IDENT "Corollary" -> { Corollary }
+ | IDENT "Proposition" -> { Proposition }
+ | IDENT "Property" -> { Property } ] ]
+ ;
+ def_token:
+ [ [ "Definition" -> { (NoDischarge,Definition) }
+ | IDENT "Example" -> { (NoDischarge,Example) }
+ | IDENT "SubClass" -> { (NoDischarge,SubClass) } ] ]
+ ;
+ assumption_token:
+ [ [ "Hypothesis" -> { (DoDischarge, Logical) }
+ | "Variable" -> { (DoDischarge, Definitional) }
+ | "Axiom" -> { (NoDischarge, Logical) }
+ | "Parameter" -> { (NoDischarge, Definitional) }
+ | IDENT "Conjecture" -> { (NoDischarge, Conjectural) } ] ]
+ ;
+ assumptions_token:
+ [ [ IDENT "Hypotheses" -> { ("Hypotheses", (DoDischarge, Logical)) }
+ | IDENT "Variables" -> { ("Variables", (DoDischarge, Definitional)) }
+ | IDENT "Axioms" -> { ("Axioms", (NoDischarge, Logical)) }
+ | IDENT "Parameters" -> { ("Parameters", (NoDischarge, Definitional)) }
+ | IDENT "Conjectures" -> { ("Conjectures", (NoDischarge, Conjectural)) } ] ]
+ ;
+ inline:
+ [ [ IDENT "Inline"; "("; i = INT; ")" -> { InlineAt (int_of_string i) }
+ | IDENT "Inline" -> { DefaultInline }
+ | -> { NoInline } ] ]
+ ;
+ univ_constraint:
+ [ [ l = universe_level; ord = [ "<" -> { Univ.Lt } | "=" -> { Univ.Eq } | "<=" -> { Univ.Le } ];
+ r = universe_level -> { (l, ord, r) } ] ]
+ ;
+ univ_decl :
+ [ [ "@{" ; l = LIST0 identref; ext = [ "+" -> { true } | -> { false } ];
+ cs = [ "|"; l' = LIST0 univ_constraint SEP ",";
+ ext = [ "+" -> { true } | -> { false } ]; "}" -> { (l',ext) }
+ | ext = [ "}" -> { true } | "|}" -> { false } ] -> { ([], ext) } ]
+ ->
+ { let open UState in
+ { univdecl_instance = l;
+ univdecl_extensible_instance = ext;
+ univdecl_constraints = fst cs;
+ univdecl_extensible_constraints = snd cs } }
+ ] ]
+ ;
+ ident_decl:
+ [ [ i = identref; l = OPT univ_decl -> { (i, l) }
+ ] ]
+ ;
+ finite_token:
+ [ [ IDENT "Inductive" -> { (Inductive_kw,Finite) }
+ | IDENT "CoInductive" -> { (CoInductive,CoFinite) }
+ | IDENT "Variant" -> { (Variant,BiFinite) }
+ | IDENT "Record" -> { (Record,BiFinite) }
+ | IDENT "Structure" -> { (Structure,BiFinite) }
+ | IDENT "Class" -> { (Class true,BiFinite) } ] ]
+ ;
+ cumulativity_token:
+ [ [ IDENT "Cumulative" -> { VernacCumulative }
+ | IDENT "NonCumulative" -> { VernacNonCumulative } ] ]
+ ;
+ private_token:
+ [ [ IDENT "Private" -> { true } | -> { false } ] ]
+ ;
+ (* Simple definitions *)
+ def_body:
+ [ [ bl = binders; ":="; red = reduce; c = lconstr ->
+ { if List.exists (function CLocalPattern _ -> true | _ -> false) bl
+ then
+ (* FIXME: "red" will be applied to types in bl and Cast with remain *)
+ let c = mkCLambdaN ~loc bl c in
+ DefineBody ([], red, c, None)
+ else
+ (match c with
+ | { CAst.v = CCast(c, CastConv t) } -> DefineBody (bl, red, c, Some t)
+ | _ -> DefineBody (bl, red, c, None)) }
+ | bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
+ { let ((bl, c), tyo) =
+ if List.exists (function CLocalPattern _ -> true | _ -> false) bl
+ then
+ (* FIXME: "red" will be applied to types in bl and Cast with remain *)
+ let c = CAst.make ~loc @@ CCast (c, CastConv t) in
+ (([],mkCLambdaN ~loc bl c), None)
+ else ((bl, c), Some t)
+ in
+ DefineBody (bl, red, c, tyo) }
+ | bl = binders; ":"; t = lconstr ->
+ { ProveBody (bl, t) } ] ]
+ ;
+ reduce:
+ [ [ IDENT "Eval"; r = red_expr; "in" -> { Some r }
+ | -> { None } ] ]
+ ;
+ one_decl_notation:
+ [ [ ntn = ne_lstring; ":="; c = constr;
+ scopt = OPT [ ":"; sc = IDENT -> { sc } ] -> { (ntn,c,scopt) } ] ]
+ ;
+ decl_sep:
+ [ [ IDENT "and" -> { () } ] ]
+ ;
+ decl_notation:
+ [ [ "where"; l = LIST1 one_decl_notation SEP decl_sep -> { l }
+ | -> { [] } ] ]
+ ;
+ (* Inductives and records *)
+ opt_constructors_or_fields:
+ [ [ ":="; lc = constructor_list_or_record_decl -> { lc }
+ | -> { RecordDecl (None, []) } ] ]
+ ;
+ inductive_definition:
+ [ [ oc = opt_coercion; id = ident_decl; indpar = binders;
+ c = OPT [ ":"; c = lconstr -> { c } ];
+ lc=opt_constructors_or_fields; ntn = decl_notation ->
+ { (((oc,id),indpar,c,lc),ntn) } ] ]
+ ;
+ constructor_list_or_record_decl:
+ [ [ "|"; l = LIST1 constructor SEP "|" -> { Constructors l }
+ | id = identref ; c = constructor_type; "|"; l = LIST0 constructor SEP "|" ->
+ { Constructors ((c id)::l) }
+ | id = identref ; c = constructor_type -> { Constructors [ c id ] }
+ | cstr = identref; "{"; fs = record_fields; "}" ->
+ { RecordDecl (Some cstr,fs) }
+ | "{";fs = record_fields; "}" -> { RecordDecl (None,fs) }
+ | -> { Constructors [] } ] ]
+ ;
+(*
+ csort:
+ [ [ s = sort -> CSort (loc,s) ] ]
+ ;
+*)
+ opt_coercion:
+ [ [ ">" -> { true }
+ | -> { false } ] ]
+ ;
+ (* (co)-fixpoints *)
+ rec_definition:
+ [ [ id = ident_decl;
+ bl = binders_fixannot;
+ ty = type_cstr;
+ def = OPT [":="; def = lconstr -> { def } ]; ntn = decl_notation ->
+ { let bl, annot = bl in ((id,annot,bl,ty,def),ntn) } ] ]
+ ;
+ corec_definition:
+ [ [ id = ident_decl; bl = binders; ty = type_cstr;
+ def = OPT [":="; def = lconstr -> { def }]; ntn = decl_notation ->
+ { ((id,bl,ty,def),ntn) } ] ]
+ ;
+ type_cstr:
+ [ [ ":"; c=lconstr -> { c }
+ | -> { CAst.make ~loc @@ CHole (None, IntroAnonymous, None) } ] ]
+ ;
+ (* Inductive schemes *)
+ scheme:
+ [ [ kind = scheme_kind -> { (None,kind) }
+ | id = identref; ":="; kind = scheme_kind -> { (Some id,kind) } ] ]
+ ;
+ scheme_kind:
+ [ [ IDENT "Induction"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { InductionScheme(true,ind,s) }
+ | IDENT "Minimality"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { InductionScheme(false,ind,s) }
+ | IDENT "Elimination"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { CaseScheme(true,ind,s) }
+ | IDENT "Case"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { CaseScheme(false,ind,s) }
+ | IDENT "Equality"; "for" ; ind = smart_global -> { EqualityScheme(ind) } ] ]
+ ;
+ (* Various Binders *)
+(*
+ (* ... without coercions *)
+ binder_nodef:
+ [ [ b = binder_let ->
+ (match b with
+ CLocalAssum(l,ty) -> (l,ty)
+ | CLocalDef _ ->
+ Util.user_err_loc
+ (loc,"fix_param",Pp.str"defined binder not allowed here.")) ] ]
+ ;
+*)
+ (* ... with coercions *)
+ record_field:
+ [ [ bd = record_binder; pri = OPT [ "|"; n = natural -> { n } ];
+ ntn = decl_notation -> { (bd,pri),ntn } ] ]
+ ;
+ record_fields:
+ [ [ f = record_field; ";"; fs = record_fields -> { f :: fs }
+ | f = record_field; ";" -> { [f] }
+ | f = record_field -> { [f] }
+ | -> { [] }
+ ] ]
+ ;
+ record_binder_body:
+ [ [ l = binders; oc = of_type_with_opt_coercion;
+ t = lconstr -> { fun id -> (oc,AssumExpr (id,mkCProdN ~loc l t)) }
+ | l = binders; oc = of_type_with_opt_coercion;
+ t = lconstr; ":="; b = lconstr -> { fun id ->
+ (oc,DefExpr (id,mkCLambdaN ~loc l b,Some (mkCProdN ~loc l t))) }
+ | l = binders; ":="; b = lconstr -> { fun id ->
+ match b.CAst.v with
+ | CCast(b', (CastConv t|CastVM t|CastNative t)) ->
+ (None,DefExpr(id,mkCLambdaN ~loc l b',Some (mkCProdN ~loc l t)))
+ | _ ->
+ (None,DefExpr(id,mkCLambdaN ~loc l b,None)) } ] ]
+ ;
+ record_binder:
+ [ [ id = name -> { (None,AssumExpr(id, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) }
+ | id = name; f = record_binder_body -> { f id } ] ]
+ ;
+ assum_list:
+ [ [ bl = LIST1 assum_coe -> { bl } | b = simple_assum_coe -> { [b] } ] ]
+ ;
+ assum_coe:
+ [ [ "("; a = simple_assum_coe; ")" -> { a } ] ]
+ ;
+ simple_assum_coe:
+ [ [ idl = LIST1 ident_decl; oc = of_type_with_opt_coercion; c = lconstr ->
+ { (not (Option.is_empty oc),(idl,c)) } ] ]
+ ;
+
+ constructor_type:
+ [[ l = binders;
+ t= [ coe = of_type_with_opt_coercion; c = lconstr ->
+ { fun l id -> (not (Option.is_empty coe),(id,mkCProdN ~loc l c)) }
+ | ->
+ { fun l id -> (false,(id,mkCProdN ~loc l (CAst.make ~loc @@ CHole (None, IntroAnonymous, None)))) } ]
+ -> { t l }
+ ]]
+;
+
+ constructor:
+ [ [ id = identref; c=constructor_type -> { c id } ] ]
+ ;
+ of_type_with_opt_coercion:
+ [ [ ":>>" -> { Some false }
+ | ":>"; ">" -> { Some false }
+ | ":>" -> { Some true }
+ | ":"; ">"; ">" -> { Some false }
+ | ":"; ">" -> { Some true }
+ | ":" -> { None } ] ]
+ ;
+END
+
+{
+
+let only_starredidentrefs =
+ Gram.Entry.of_parser "test_only_starredidentrefs"
+ (fun strm ->
+ let rec aux n =
+ match Util.stream_nth n strm with
+ | KEYWORD "." -> ()
+ | KEYWORD ")" -> ()
+ | (IDENT _ | KEYWORD "Type" | KEYWORD "*") -> aux (n+1)
+ | _ -> raise Stream.Failure in
+ aux 0)
+let starredidentreflist_to_expr l =
+ match l with
+ | [] -> SsEmpty
+ | x :: xs -> List.fold_right (fun i acc -> SsUnion(i,acc)) xs x
+
+let warn_deprecated_include_type =
+ CWarnings.create ~name:"deprecated-include-type" ~category:"deprecated"
+ (fun () -> strbrk "Include Type is deprecated; use Include instead")
+
+}
+
+(* Modules and Sections *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina_ext module_expr module_type section_subset_expr;
+
+ gallina_ext:
+ [ [ (* Interactive module declaration *)
+ IDENT "Module"; export = export_token; id = identref;
+ bl = LIST0 module_binder; sign = of_module_type;
+ body = is_module_expr ->
+ { VernacDefineModule (export, id, bl, sign, body) }
+ | IDENT "Module"; "Type"; id = identref;
+ bl = LIST0 module_binder; sign = check_module_types;
+ body = is_module_type ->
+ { VernacDeclareModuleType (id, bl, sign, body) }
+ | IDENT "Declare"; IDENT "Module"; export = export_token; id = identref;
+ bl = LIST0 module_binder; ":"; mty = module_type_inl ->
+ { VernacDeclareModule (export, id, bl, mty) }
+ (* Section beginning *)
+ | IDENT "Section"; id = identref -> { VernacBeginSection id }
+ | IDENT "Chapter"; id = identref -> { VernacBeginSection id }
+
+ (* This end a Section a Module or a Module Type *)
+ | IDENT "End"; id = identref -> { VernacEndSegment id }
+
+ (* Naming a set of section hyps *)
+ | IDENT "Collection"; id = identref; ":="; expr = section_subset_expr ->
+ { VernacNameSectionHypSet (id, expr) }
+
+ (* Requiring an already compiled module *)
+ | IDENT "Require"; export = export_token; qidl = LIST1 global ->
+ { VernacRequire (None, export, qidl) }
+ | IDENT "From" ; ns = global ; IDENT "Require"; export = export_token
+ ; qidl = LIST1 global ->
+ { VernacRequire (Some ns, export, qidl) }
+ | IDENT "Import"; qidl = LIST1 global -> { VernacImport (false,qidl) }
+ | IDENT "Export"; qidl = LIST1 global -> { VernacImport (true,qidl) }
+ | IDENT "Include"; e = module_type_inl; l = LIST0 ext_module_expr ->
+ { VernacInclude(e::l) }
+ | IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
+ { warn_deprecated_include_type ~loc ();
+ VernacInclude(e::l) } ] ]
+ ;
+ export_token:
+ [ [ IDENT "Import" -> { Some false }
+ | IDENT "Export" -> { Some true }
+ | -> { None } ] ]
+ ;
+ ext_module_type:
+ [ [ "<+"; mty = module_type_inl -> { mty } ] ]
+ ;
+ ext_module_expr:
+ [ [ "<+"; mexpr = module_expr_inl -> { mexpr } ] ]
+ ;
+ check_module_type:
+ [ [ "<:"; mty = module_type_inl -> { mty } ] ]
+ ;
+ check_module_types:
+ [ [ mtys = LIST0 check_module_type -> { mtys } ] ]
+ ;
+ of_module_type:
+ [ [ ":"; mty = module_type_inl -> { Enforce mty }
+ | mtys = check_module_types -> { Check mtys } ] ]
+ ;
+ is_module_type:
+ [ [ ":="; mty = module_type_inl ; l = LIST0 ext_module_type -> { (mty::l) }
+ | -> { [] } ] ]
+ ;
+ is_module_expr:
+ [ [ ":="; mexpr = module_expr_inl; l = LIST0 ext_module_expr -> { (mexpr::l) }
+ | -> { [] } ] ]
+ ;
+ functor_app_annot:
+ [ [ "["; IDENT "inline"; "at"; IDENT "level"; i = INT; "]" ->
+ { InlineAt (int_of_string i) }
+ | "["; IDENT "no"; IDENT "inline"; "]" -> { NoInline }
+ | -> { DefaultInline }
+ ] ]
+ ;
+ module_expr_inl:
+ [ [ "!"; me = module_expr -> { (me,NoInline) }
+ | me = module_expr; a = functor_app_annot -> { (me,a) } ] ]
+ ;
+ module_type_inl:
+ [ [ "!"; me = module_type -> { (me,NoInline) }
+ | me = module_type; a = functor_app_annot -> { (me,a) } ] ]
+ ;
+ (* Module binder *)
+ module_binder:
+ [ [ "("; export = export_token; idl = LIST1 identref; ":";
+ mty = module_type_inl; ")" -> { (export,idl,mty) } ] ]
+ ;
+ (* Module expressions *)
+ module_expr:
+ [ [ me = module_expr_atom -> { me }
+ | me1 = module_expr; me2 = module_expr_atom -> { CAst.make ~loc @@ CMapply (me1,me2) }
+ ] ]
+ ;
+ module_expr_atom:
+ [ [ qid = qualid -> { CAst.make ~loc @@ CMident qid } | "("; me = module_expr; ")" -> { me } ] ]
+ ;
+ with_declaration:
+ [ [ "Definition"; fqid = fullyqualid; udecl = OPT univ_decl; ":="; c = Constr.lconstr ->
+ { CWith_Definition (fqid,udecl,c) }
+ | IDENT "Module"; fqid = fullyqualid; ":="; qid = qualid ->
+ { CWith_Module (fqid,qid) }
+ ] ]
+ ;
+ module_type:
+ [ [ qid = qualid -> { CAst.make ~loc @@ CMident qid }
+ | "("; mt = module_type; ")" -> { mt }
+ | mty = module_type; me = module_expr_atom ->
+ { CAst.make ~loc @@ CMapply (mty,me) }
+ | mty = module_type; "with"; decl = with_declaration ->
+ { CAst.make ~loc @@ CMwith (mty,decl) }
+ ] ]
+ ;
+ (* Proof using *)
+ section_subset_expr:
+ [ [ only_starredidentrefs; l = LIST0 starredidentref ->
+ { starredidentreflist_to_expr l }
+ | e = ssexpr -> { e } ]]
+ ;
+ starredidentref:
+ [ [ i = identref -> { SsSingl i }
+ | i = identref; "*" -> { SsFwdClose(SsSingl i) }
+ | "Type" -> { SsType }
+ | "Type"; "*" -> { SsFwdClose SsType } ]]
+ ;
+ ssexpr:
+ [ "35"
+ [ "-"; e = ssexpr -> { SsCompl e } ]
+ | "50"
+ [ e1 = ssexpr; "-"; e2 = ssexpr-> { SsSubstr(e1,e2) }
+ | e1 = ssexpr; "+"; e2 = ssexpr-> { SsUnion(e1,e2) } ]
+ | "0"
+ [ i = starredidentref -> { i }
+ | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"->
+ { starredidentreflist_to_expr l }
+ | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"; "*" ->
+ { SsFwdClose(starredidentreflist_to_expr l) }
+ | "("; e = ssexpr; ")"-> { e }
+ | "("; e = ssexpr; ")"; "*" -> { SsFwdClose e } ] ]
+ ;
+END
+
+(* Extensions: implicits, coercions, etc. *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina_ext instance_name hint_info;
+
+ gallina_ext:
+ [ [ (* Transparent and Opaque *)
+ IDENT "Transparent"; l = LIST1 smart_global ->
+ { VernacSetOpacity (Conv_oracle.transparent, l) }
+ | IDENT "Opaque"; l = LIST1 smart_global ->
+ { VernacSetOpacity (Conv_oracle.Opaque, l) }
+ | IDENT "Strategy"; l =
+ LIST1 [ v=strategy_level; "["; q=LIST1 smart_global; "]" -> { (v,q) } ] ->
+ { VernacSetStrategy l }
+ (* Canonical structure *)
+ | IDENT "Canonical"; IDENT "Structure"; qid = global ->
+ { VernacCanonical CAst.(make ~loc @@ AN qid) }
+ | IDENT "Canonical"; IDENT "Structure"; ntn = by_notation ->
+ { VernacCanonical CAst.(make ~loc @@ ByNotation ntn) }
+ | IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
+ { let s = coerce_reference_to_id qid in
+ VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make (Name s)),None),d) }
+
+ (* Coercions *)
+ | IDENT "Coercion"; qid = global; d = def_body ->
+ { let s = coerce_reference_to_id qid in
+ VernacDefinition ((NoDischarge,Coercion),((CAst.make (Name s)),None),d) }
+ | IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
+ s = class_rawexpr; ">->"; t = class_rawexpr ->
+ { VernacIdentityCoercion (f, s, t) }
+ | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->";
+ t = class_rawexpr ->
+ { VernacCoercion (CAst.make ~loc @@ AN qid, s, t) }
+ | IDENT "Coercion"; ntn = by_notation; ":"; s = class_rawexpr; ">->";
+ t = class_rawexpr ->
+ { VernacCoercion (CAst.make ~loc @@ ByNotation ntn, s, t) }
+
+ | IDENT "Context"; c = LIST1 binder ->
+ { VernacContext (List.flatten c) }
+
+ | IDENT "Instance"; namesup = instance_name; ":";
+ expl = [ "!" -> { Decl_kinds.Implicit } | -> { Decl_kinds.Explicit } ] ; t = operconstr LEVEL "200";
+ info = hint_info ;
+ props = [ ":="; "{"; r = record_declaration; "}" -> { Some (true,r) } |
+ ":="; c = lconstr -> { Some (false,c) } | -> { None } ] ->
+ { VernacInstance (false,snd namesup,(fst namesup,expl,t),props,info) }
+
+ | IDENT "Existing"; IDENT "Instance"; id = global;
+ info = hint_info ->
+ { VernacDeclareInstances [id, info] }
+
+ | IDENT "Existing"; IDENT "Instances"; ids = LIST1 global;
+ pri = OPT [ "|"; i = natural -> { i } ] ->
+ { let info = { Typeclasses.hint_priority = pri; hint_pattern = None } in
+ let insts = List.map (fun i -> (i, info)) ids in
+ VernacDeclareInstances insts }
+
+ | IDENT "Existing"; IDENT "Class"; is = global -> { VernacDeclareClass is }
+
+ (* Arguments *)
+ | IDENT "Arguments"; qid = smart_global;
+ args = LIST0 argument_spec_block;
+ more_implicits = OPT
+ [ ","; impl = LIST1
+ [ impl = LIST0 more_implicits_block -> { List.flatten impl } ]
+ SEP "," -> { impl }
+ ];
+ mods = OPT [ ":"; l = LIST1 arguments_modifier SEP "," -> { l } ] ->
+ { let mods = match mods with None -> [] | Some l -> List.flatten l in
+ let slash_position = ref None in
+ let rec parse_args i = function
+ | [] -> []
+ | `Id x :: args -> x :: parse_args (i+1) args
+ | `Slash :: args ->
+ if Option.is_empty !slash_position then
+ (slash_position := Some i; parse_args i args)
+ else
+ user_err Pp.(str "The \"/\" modifier can occur only once")
+ in
+ let args = parse_args 0 (List.flatten args) in
+ let more_implicits = Option.default [] more_implicits in
+ VernacArguments (qid, args, more_implicits, !slash_position, mods) }
+
+ | IDENT "Implicit"; "Type"; bl = reserv_list ->
+ { VernacReserve bl }
+
+ | IDENT "Implicit"; IDENT "Types"; bl = reserv_list ->
+ { test_plural_form_types loc "Implicit Types" bl;
+ VernacReserve bl }
+
+ | IDENT "Generalizable";
+ gen = [IDENT "All"; IDENT "Variables" -> { Some [] }
+ | IDENT "No"; IDENT "Variables" -> { None }
+ | ["Variable" -> { () } | IDENT "Variables" -> { () } ];
+ idl = LIST1 identref -> { Some idl } ] ->
+ { VernacGeneralizable gen } ] ]
+ ;
+ arguments_modifier:
+ [ [ IDENT "simpl"; IDENT "nomatch" -> { [`ReductionDontExposeCase] }
+ | IDENT "simpl"; IDENT "never" -> { [`ReductionNeverUnfold] }
+ | IDENT "default"; IDENT "implicits" -> { [`DefaultImplicits] }
+ | IDENT "clear"; IDENT "implicits" -> { [`ClearImplicits] }
+ | IDENT "clear"; IDENT "scopes" -> { [`ClearScopes] }
+ | IDENT "rename" -> { [`Rename] }
+ | IDENT "assert" -> { [`Assert] }
+ | IDENT "extra"; IDENT "scopes" -> { [`ExtraScopes] }
+ | IDENT "clear"; IDENT "scopes"; IDENT "and"; IDENT "implicits" ->
+ { [`ClearImplicits; `ClearScopes] }
+ | IDENT "clear"; IDENT "implicits"; IDENT "and"; IDENT "scopes" ->
+ { [`ClearImplicits; `ClearScopes] }
+ ] ]
+ ;
+ scope:
+ [ [ "%"; key = IDENT -> { key } ] ]
+ ;
+ argument_spec: [
+ [ b = OPT "!"; id = name ; s = OPT scope ->
+ { id.CAst.v, not (Option.is_empty b), Option.map (fun x -> CAst.make ~loc x) s }
+ ]
+ ];
+ (* List of arguments implicit status, scope, modifiers *)
+ argument_spec_block: [
+ [ item = argument_spec ->
+ { let name, recarg_like, notation_scope = item in
+ [`Id { name=name; recarg_like=recarg_like;
+ notation_scope=notation_scope;
+ implicit_status = NotImplicit}] }
+ | "/" -> { [`Slash] }
+ | "("; items = LIST1 argument_spec; ")"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = NotImplicit}) items }
+ | "["; items = LIST1 argument_spec; "]"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = Implicit}) items }
+ | "{"; items = LIST1 argument_spec; "}"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = MaximallyImplicit}) items }
+ ]
+ ];
+ (* Same as [argument_spec_block], but with only implicit status and names *)
+ more_implicits_block: [
+ [ name = name -> { [(name.CAst.v, Vernacexpr.NotImplicit)] }
+ | "["; items = LIST1 name; "]" ->
+ { List.map (fun name -> (name.CAst.v, Vernacexpr.Implicit)) items }
+ | "{"; items = LIST1 name; "}" ->
+ { List.map (fun name -> (name.CAst.v, Vernacexpr.MaximallyImplicit)) items }
+ ]
+ ];
+ strategy_level:
+ [ [ IDENT "expand" -> { Conv_oracle.Expand }
+ | IDENT "opaque" -> { Conv_oracle.Opaque }
+ | n=INT -> { Conv_oracle.Level (int_of_string n) }
+ | "-"; n=INT -> { Conv_oracle.Level (- int_of_string n) }
+ | IDENT "transparent" -> { Conv_oracle.transparent } ] ]
+ ;
+ instance_name:
+ [ [ name = ident_decl; sup = OPT binders ->
+ { (CAst.map (fun id -> Name id) (fst name), snd name),
+ (Option.default [] sup) }
+ | -> { ((CAst.make ~loc Anonymous), None), [] } ] ]
+ ;
+ hint_info:
+ [ [ "|"; i = OPT natural; pat = OPT constr_pattern ->
+ { { Typeclasses.hint_priority = i; hint_pattern = pat } }
+ | -> { { Typeclasses.hint_priority = None; hint_pattern = None } } ] ]
+ ;
+ reserv_list:
+ [ [ bl = LIST1 reserv_tuple -> { bl } | b = simple_reserv -> { [b] } ] ]
+ ;
+ reserv_tuple:
+ [ [ "("; a = simple_reserv; ")" -> { a } ] ]
+ ;
+ simple_reserv:
+ [ [ idl = LIST1 identref; ":"; c = lconstr -> { (idl,c) } ] ]
+ ;
+
+END
+
+GRAMMAR EXTEND Gram
+ GLOBAL: command query_command class_rawexpr gallina_ext;
+
+ gallina_ext:
+ [ [ IDENT "Export"; "Set"; table = option_table; v = option_value ->
+ { VernacSetOption (true, table, v) }
+ | IDENT "Export"; IDENT "Unset"; table = option_table ->
+ { VernacUnsetOption (true, table) }
+ ] ];
+
+ command:
+ [ [ IDENT "Comments"; l = LIST0 comment -> { VernacComments l }
+
+ (* Hack! Should be in grammar_ext, but camlp5 factorizes badly *)
+ | IDENT "Declare"; IDENT "Instance"; namesup = instance_name; ":";
+ expl = [ "!" -> { Decl_kinds.Implicit } | -> { Decl_kinds.Explicit } ] ; t = operconstr LEVEL "200";
+ info = hint_info ->
+ { VernacInstance (true, snd namesup, (fst namesup, expl, t), None, info) }
+
+ (* System directory *)
+ | IDENT "Pwd" -> { VernacChdir None }
+ | IDENT "Cd" -> { VernacChdir None }
+ | IDENT "Cd"; dir = ne_string -> { VernacChdir (Some dir) }
+
+ | IDENT "Load"; verbosely = [ IDENT "Verbose" -> { true } | -> { false } ];
+ s = [ s = ne_string -> { s } | s = IDENT -> { s } ] ->
+ { VernacLoad (verbosely, s) }
+ | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 ne_string ->
+ { VernacDeclareMLModule l }
+
+ | IDENT "Locate"; l = locatable -> { VernacLocate l }
+
+ (* Managing load paths *)
+ | IDENT "Add"; IDENT "LoadPath"; dir = ne_string; alias = as_dirpath ->
+ { VernacAddLoadPath (false, dir, alias) }
+ | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = ne_string;
+ alias = as_dirpath -> { VernacAddLoadPath (true, dir, alias) }
+ | IDENT "Remove"; IDENT "LoadPath"; dir = ne_string ->
+ { VernacRemoveLoadPath dir }
+
+ (* For compatibility *)
+ | IDENT "AddPath"; dir = ne_string; "as"; alias = as_dirpath ->
+ { VernacAddLoadPath (false, dir, alias) }
+ | IDENT "AddRecPath"; dir = ne_string; "as"; alias = as_dirpath ->
+ { VernacAddLoadPath (true, dir, alias) }
+ | IDENT "DelPath"; dir = ne_string ->
+ { VernacRemoveLoadPath dir }
+
+ (* Type-Checking (pas dans le refman) *)
+ | "Type"; c = lconstr -> { VernacGlobalCheck c }
+
+ (* Printing (careful factorization of entries) *)
+ | IDENT "Print"; p = printable -> { VernacPrint p }
+ | IDENT "Print"; qid = smart_global; l = OPT univ_name_list -> { VernacPrint (PrintName (qid,l)) }
+ | IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
+ { VernacPrint (PrintModuleType qid) }
+ | IDENT "Print"; IDENT "Module"; qid = global ->
+ { VernacPrint (PrintModule qid) }
+ | IDENT "Print"; IDENT "Namespace" ; ns = dirpath ->
+ { VernacPrint (PrintNamespace ns) }
+ | IDENT "Inspect"; n = natural -> { VernacPrint (PrintInspect n) }
+
+ | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
+ { VernacAddMLPath (false, dir) }
+ | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
+ { VernacAddMLPath (true, dir) }
+
+ (* For acting on parameter tables *)
+ | "Set"; table = option_table; v = option_value ->
+ { VernacSetOption (false, table, v) }
+ | IDENT "Unset"; table = option_table ->
+ { VernacUnsetOption (false, table) }
+
+ | IDENT "Print"; IDENT "Table"; table = option_table ->
+ { VernacPrintOption table }
+
+ | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
+ -> { VernacAddOption ([table;field], v) }
+ (* A global value below will be hidden by a field above! *)
+ (* In fact, we give priority to secondary tables *)
+ (* No syntax for tertiary tables due to conflict *)
+ (* (but they are unused anyway) *)
+ | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
+ { VernacAddOption ([table], v) }
+
+ | IDENT "Test"; table = option_table; "for"; v = LIST1 option_ref_value
+ -> { VernacMemOption (table, v) }
+ | IDENT "Test"; table = option_table ->
+ { VernacPrintOption table }
+
+ | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
+ -> { VernacRemoveOption ([table;field], v) }
+ | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
+ { VernacRemoveOption ([table], v) } ]]
+ ;
+ query_command: (* TODO: rapprocher Eval et Check *)
+ [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (Some r, g, c) }
+ | IDENT "Compute"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (Some (Genredexpr.CbvVm None), g, c) }
+ | IDENT "Check"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (None, g, c) }
+ (* Searching the environment *)
+ | IDENT "About"; qid = smart_global; l = OPT univ_name_list; "." ->
+ { fun g -> VernacPrint (PrintAbout (qid,l,g)) }
+ | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchHead c,g, l) }
+ | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchPattern c,g, l) }
+ | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchRewrite c,g, l) }
+ | IDENT "Search"; s = searchabout_query; l = searchabout_queries; "." ->
+ { let (sl,m) = l in fun g -> VernacSearch (SearchAbout (s::sl),g, m) }
+ (* compatibility: SearchAbout *)
+ | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries; "." ->
+ { fun g -> let (sl,m) = l in VernacSearch (SearchAbout (s::sl),g, m) }
+ (* compatibility: SearchAbout with "[ ... ]" *)
+ | IDENT "SearchAbout"; "["; sl = LIST1 searchabout_query; "]";
+ l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchAbout sl,g, l) }
+ ] ]
+ ;
+ printable:
+ [ [ IDENT "Term"; qid = smart_global; l = OPT univ_name_list -> { PrintName (qid,l) }
+ | IDENT "All" -> { PrintFullContext }
+ | IDENT "Section"; s = global -> { PrintSectionContext s }
+ | IDENT "Grammar"; ent = IDENT ->
+ (* This should be in "syntax" section but is here for factorization*)
+ { PrintGrammar ent }
+ | IDENT "LoadPath"; dir = OPT dirpath -> { PrintLoadPath dir }
+ | IDENT "Modules" ->
+ { user_err Pp.(str "Print Modules is obsolete; use Print Libraries instead") }
+ | IDENT "Libraries" -> { PrintModules }
+
+ | IDENT "ML"; IDENT "Path" -> { PrintMLLoadPath }
+ | IDENT "ML"; IDENT "Modules" -> { PrintMLModules }
+ | IDENT "Debug"; IDENT "GC" -> { PrintDebugGC }
+ | IDENT "Graph" -> { PrintGraph }
+ | IDENT "Classes" -> { PrintClasses }
+ | IDENT "TypeClasses" -> { PrintTypeClasses }
+ | IDENT "Instances"; qid = smart_global -> { PrintInstances qid }
+ | IDENT "Coercions" -> { PrintCoercions }
+ | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
+ -> { PrintCoercionPaths (s,t) }
+ | IDENT "Canonical"; IDENT "Projections" -> { PrintCanonicalConversions }
+ | IDENT "Tables" -> { PrintTables }
+ | IDENT "Options" -> { PrintTables (* A Synonymous to Tables *) }
+ | IDENT "Hint" -> { PrintHintGoal }
+ | IDENT "Hint"; qid = smart_global -> { PrintHint qid }
+ | IDENT "Hint"; "*" -> { PrintHintDb }
+ | IDENT "HintDb"; s = IDENT -> { PrintHintDbName s }
+ | IDENT "Scopes" -> { PrintScopes }
+ | IDENT "Scope"; s = IDENT -> { PrintScope s }
+ | IDENT "Visibility"; s = OPT IDENT -> { PrintVisibility s }
+ | IDENT "Implicit"; qid = smart_global -> { PrintImplicit qid }
+ | IDENT "Universes"; fopt = OPT ne_string -> { PrintUniverses (false, fopt) }
+ | IDENT "Sorted"; IDENT "Universes"; fopt = OPT ne_string -> { PrintUniverses (true, fopt) }
+ | IDENT "Assumptions"; qid = smart_global -> { PrintAssumptions (false, false, qid) }
+ | IDENT "Opaque"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (true, false, qid) }
+ | IDENT "Transparent"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (false, true, qid) }
+ | IDENT "All"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (true, true, qid) }
+ | IDENT "Strategy"; qid = smart_global -> { PrintStrategy (Some qid) }
+ | IDENT "Strategies" -> { PrintStrategy None } ] ]
+ ;
+ class_rawexpr:
+ [ [ IDENT "Funclass" -> { FunClass }
+ | IDENT "Sortclass" -> { SortClass }
+ | qid = smart_global -> { RefClass qid } ] ]
+ ;
+ locatable:
+ [ [ qid = smart_global -> { LocateAny qid }
+ | IDENT "Term"; qid = smart_global -> { LocateTerm qid }
+ | IDENT "File"; f = ne_string -> { LocateFile f }
+ | IDENT "Library"; qid = global -> { LocateLibrary qid }
+ | IDENT "Module"; qid = global -> { LocateModule qid } ] ]
+ ;
+ option_value:
+ [ [ -> { BoolValue true }
+ | n = integer -> { IntValue (Some n) }
+ | s = STRING -> { StringValue s } ] ]
+ ;
+ option_ref_value:
+ [ [ id = global -> { QualidRefValue id }
+ | s = STRING -> { StringRefValue s } ] ]
+ ;
+ option_table:
+ [ [ fl = LIST1 [ x = IDENT -> { x } ] -> { fl } ]]
+ ;
+ as_dirpath:
+ [ [ d = OPT [ "as"; d = dirpath -> { d } ] -> { d } ] ]
+ ;
+ ne_in_or_out_modules:
+ [ [ IDENT "inside"; l = LIST1 global -> { SearchInside l }
+ | IDENT "outside"; l = LIST1 global -> { SearchOutside l } ] ]
+ ;
+ in_or_out_modules:
+ [ [ m = ne_in_or_out_modules -> { m }
+ | -> { SearchOutside [] } ] ]
+ ;
+ comment:
+ [ [ c = constr -> { CommentConstr c }
+ | s = STRING -> { CommentString s }
+ | n = natural -> { CommentInt n } ] ]
+ ;
+ positive_search_mark:
+ [ [ "-" -> { false } | -> { true } ] ]
+ ;
+ scope:
+ [ [ "%"; key = IDENT -> { key } ] ]
+ ;
+ searchabout_query:
+ [ [ b = positive_search_mark; s = ne_string; sc = OPT scope ->
+ { (b, SearchString (s,sc)) }
+ | b = positive_search_mark; p = constr_pattern ->
+ { (b, SearchSubPattern p) }
+ ] ]
+ ;
+ searchabout_queries:
+ [ [ m = ne_in_or_out_modules -> { ([],m) }
+ | s = searchabout_query; l = searchabout_queries ->
+ { let (sl,m) = l in (s::sl,m) }
+ | -> { ([],SearchOutside []) }
+ ] ]
+ ;
+ univ_name_list:
+ [ [ "@{" ; l = LIST0 name; "}" -> { l } ] ]
+ ;
+END
+
+GRAMMAR EXTEND Gram
+ GLOBAL: command;
+
+ command:
+ [ [
+(* State management *)
+ IDENT "Write"; IDENT "State"; s = IDENT -> { VernacWriteState s }
+ | IDENT "Write"; IDENT "State"; s = ne_string -> { VernacWriteState s }
+ | IDENT "Restore"; IDENT "State"; s = IDENT -> { VernacRestoreState s }
+ | IDENT "Restore"; IDENT "State"; s = ne_string -> { VernacRestoreState s }
+
+(* Resetting *)
+ | IDENT "Reset"; IDENT "Initial" -> { VernacResetInitial }
+ | IDENT "Reset"; id = identref -> { VernacResetName id }
+ | IDENT "Back" -> { VernacBack 1 }
+ | IDENT "Back"; n = natural -> { VernacBack n }
+ | IDENT "BackTo"; n = natural -> { VernacBackTo n }
+
+(* Tactic Debugger *)
+ | IDENT "Debug"; IDENT "On" ->
+ { VernacSetOption (false, ["Ltac";"Debug"], BoolValue true) }
+
+ | IDENT "Debug"; IDENT "Off" ->
+ { VernacSetOption (false, ["Ltac";"Debug"], BoolValue false) }
+
+(* registration of a custom reduction *)
+
+ | IDENT "Declare"; IDENT "Reduction"; s = IDENT; ":=";
+ r = red_expr ->
+ { VernacDeclareReduction (s,r) }
+
+ ] ];
+ END
+
+(* Grammar extensions *)
+
+GRAMMAR EXTEND Gram
+ GLOBAL: syntax;
+
+ syntax:
+ [ [ IDENT "Open"; IDENT "Scope"; sc = IDENT ->
+ { VernacOpenCloseScope (true,sc) }
+
+ | IDENT "Close"; IDENT "Scope"; sc = IDENT ->
+ { VernacOpenCloseScope (false,sc) }
+
+ | IDENT "Delimit"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT ->
+ { VernacDelimiters (sc, Some key) }
+ | IDENT "Undelimit"; IDENT "Scope"; sc = IDENT ->
+ { VernacDelimiters (sc, None) }
+
+ | IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with";
+ refl = LIST1 class_rawexpr -> { VernacBindScope (sc,refl) }
+
+ | IDENT "Infix"; op = ne_lstring; ":="; p = constr;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ];
+ sc = OPT [ ":"; sc = IDENT -> { sc } ] ->
+ { VernacInfix ((op,modl),p,sc) }
+ | IDENT "Notation"; id = identref;
+ idl = LIST0 ident; ":="; c = constr; b = only_parsing ->
+ { VernacSyntacticDefinition
+ (id,(idl,c),b) }
+ | IDENT "Notation"; s = lstring; ":=";
+ c = constr;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ];
+ sc = OPT [ ":"; sc = IDENT -> { sc } ] ->
+ { VernacNotation (c,(s,modl),sc) }
+ | IDENT "Format"; IDENT "Notation"; n = STRING; s = STRING; fmt = STRING ->
+ { VernacNotationAddFormat (n,s,fmt) }
+
+ | IDENT "Reserved"; IDENT "Infix"; s = ne_lstring;
+ l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ] ->
+ { let s = CAst.map (fun s -> "x '"^s^"' y") s in
+ VernacSyntaxExtension (true,(s,l)) }
+
+ | IDENT "Reserved"; IDENT "Notation";
+ s = ne_lstring;
+ l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ]
+ -> { VernacSyntaxExtension (false, (s,l)) }
+
+ (* "Print" "Grammar" should be here but is in "command" entry in order
+ to factorize with other "Print"-based vernac entries *)
+ ] ]
+ ;
+ only_parsing:
+ [ [ "("; IDENT "only"; IDENT "parsing"; ")" ->
+ { Some Flags.Current }
+ | "("; IDENT "compat"; s = STRING; ")" ->
+ { Some (parse_compat_version s) }
+ | -> { None } ] ]
+ ;
+ level:
+ [ [ IDENT "level"; n = natural -> { NumLevel n }
+ | IDENT "next"; IDENT "level" -> { NextLevel } ] ]
+ ;
+ syntax_modifier:
+ [ [ "at"; IDENT "level"; n = natural -> { SetLevel n }
+ | IDENT "left"; IDENT "associativity" -> { SetAssoc LeftA }
+ | IDENT "right"; IDENT "associativity" -> { SetAssoc RightA }
+ | IDENT "no"; IDENT "associativity" -> { SetAssoc NonA }
+ | IDENT "only"; IDENT "printing" -> { SetOnlyPrinting }
+ | IDENT "only"; IDENT "parsing" -> { SetOnlyParsing }
+ | IDENT "compat"; s = STRING ->
+ { SetCompatVersion (parse_compat_version s) }
+ | IDENT "format"; s1 = [s = STRING -> { CAst.make ~loc s } ];
+ s2 = OPT [s = STRING -> { CAst.make ~loc s } ] ->
+ { begin match s1, s2 with
+ | { CAst.v = k }, Some s -> SetFormat(k,s)
+ | s, None -> SetFormat ("text",s) end }
+ | x = IDENT; ","; l = LIST1 [id = IDENT -> { id } ] SEP ","; "at";
+ lev = level -> { SetItemLevel (x::l,lev) }
+ | x = IDENT; "at"; lev = level -> { SetItemLevel ([x],lev) }
+ | x = IDENT; "at"; lev = level; b = constr_as_binder_kind -> { SetItemLevelAsBinder ([x],b,Some lev) }
+ | x = IDENT; b = constr_as_binder_kind -> { SetItemLevelAsBinder ([x],b,None) }
+ | x = IDENT; typ = syntax_extension_type -> { SetEntryType (x,typ) }
+ ] ]
+ ;
+ syntax_extension_type:
+ [ [ IDENT "ident" -> { ETName } | IDENT "global" -> { ETReference }
+ | IDENT "bigint" -> { ETBigint }
+ | IDENT "binder" -> { ETBinder true }
+ | IDENT "constr"; n = OPT at_level; b = constr_as_binder_kind -> { ETConstrAsBinder (b,n) }
+ | IDENT "pattern" -> { ETPattern (false,None) }
+ | IDENT "pattern"; "at"; IDENT "level"; n = natural -> { ETPattern (false,Some n) }
+ | IDENT "strict"; IDENT "pattern" -> { ETPattern (true,None) }
+ | IDENT "strict"; IDENT "pattern"; "at"; IDENT "level"; n = natural -> { ETPattern (true,Some n) }
+ | IDENT "closed"; IDENT "binder" -> { ETBinder false }
+ ] ]
+ ;
+ at_level:
+ [ [ "at"; n = level -> { n } ] ]
+ ;
+ constr_as_binder_kind:
+ [ [ "as"; IDENT "ident" -> { Notation_term.AsIdent }
+ | "as"; IDENT "pattern" -> { Notation_term.AsIdentOrPattern }
+ | "as"; IDENT "strict"; IDENT "pattern" -> { Notation_term.AsStrictPattern } ] ]
+ ;
+END
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index 5d671ef52..534e58f9c 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -871,9 +871,6 @@ let explain_not_match_error = function
pr_enum (function Name id -> Id.print id | _ -> str "_") nal
| NotEqualInductiveAliases ->
str "Aliases to inductive types do not match"
- | NoTypeConstraintExpected ->
- strbrk "a definition whose type is constrained can only be subtype " ++
- strbrk "of a definition whose type is itself constrained"
| CumulativeStatusExpected b ->
let status b = if b then str"cumulative" else str"non-cumulative" in
str "a " ++ status b ++ str" declaration was expected, but a " ++
diff --git a/vernac/himsg.mli b/vernac/himsg.mli
index 1d3807502..91caddcf1 100644
--- a/vernac/himsg.mli
+++ b/vernac/himsg.mli
@@ -25,7 +25,7 @@ val explain_pretype_error : env -> Evd.evar_map -> pretype_error -> Pp.t
val explain_inductive_error : inductive_error -> Pp.t
-val explain_mismatched_contexts : env -> contexts -> Constrexpr.constr_expr list -> Context.Rel.t -> Pp.t
+val explain_mismatched_contexts : env -> contexts -> Constrexpr.constr_expr list -> Constr.rel_context -> Pp.t
val explain_typeclass_error : env -> typeclass_error -> Pp.t
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index da14358ef..240147c8d 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -487,6 +487,15 @@ and check_no_ldots_in_box = function
let error_not_same ?loc () =
user_err ?loc Pp.(str "The format is not the same on the right- and left-hand sides of the special token \"..\".")
+let find_prod_list_loc sfmt fmt =
+ (* [fmt] is some [UnpTerminal x :: sfmt @ UnpTerminal ".." :: sfmt @ UnpTerminal y :: rest] *)
+ if List.is_empty sfmt then
+ (* No separators; we highlight the sequence "x .." *)
+ Loc.merge_opt (fst (List.hd fmt)) (fst (List.hd (List.tl fmt)))
+ else
+ (* A separator; we highlight the separating sequence *)
+ Loc.merge_opt (fst (List.hd sfmt)) (fst (List.last sfmt))
+
let skip_var_in_recursive_format = function
| (_,UnpTerminal s) :: sl (* skip first var *) when not (List.for_all (fun c -> c = " ") (String.explode s)) ->
(* To do, though not so important: check that the names match
@@ -496,6 +505,8 @@ let skip_var_in_recursive_format = function
| [] -> assert false
let read_recursive_format sl fmt =
+ (* Turn [[UnpTerminal s :: some-list @ UnpTerminal ".." :: same-some-list @ UnpTerminal s' :: rest] *)
+ (* into [(some-list,rest)] *)
let get_head fmt =
let sl = skip_var_in_recursive_format fmt in
try split_format_at_ldots [] sl with Exit -> error_not_same ?loc:(fst (List.last (if sl = [] then fmt else sl))) () in
@@ -528,10 +539,10 @@ let hunks_of_format (from,(vars,typs)) symfmt =
let i = index_id m vars in
let typ = List.nth typs (i-1) in
let _,prec = precedence_of_entry_type from typ in
- let slfmt,fmt = read_recursive_format sl fmt in
- let sl, slfmt = aux (sl,slfmt) in
- if not (List.is_empty sl) then error_format ?loc:(fst (List.last fmt)) ();
- let symbs, l = aux (symbs,fmt) in
+ let loc_slfmt,rfmt = read_recursive_format sl fmt in
+ let sl, slfmt = aux (sl,loc_slfmt) in
+ if not (List.is_empty sl) then error_format ?loc:(find_prod_list_loc loc_slfmt fmt) ();
+ let symbs, l = aux (symbs,rfmt) in
let hunk = match typ with
| ETConstr _ -> UnpListMetaVar (i,prec,slfmt)
| ETBinder isopen ->
@@ -1312,8 +1323,15 @@ let make_pa_rule level (typs,symbols) ntn need_squash =
let make_pp_rule level (typs,symbols) fmt =
match fmt with
- | None -> [UnpBox (PpHOVB 0, make_hunks typs symbols level)]
- | Some fmt -> hunks_of_format (level, List.split typs) (symbols, parse_format fmt)
+ | None ->
+ let hunks = make_hunks typs symbols level in
+ if List.exists (function _,(UnpCut (PpBrk _) | UnpListMetaVar _) -> true | _ -> false) hunks then
+ [UnpBox (PpHOVB 0,hunks)]
+ else
+ (* Optimization to work around what seems an ocaml Format bug (see Mantis #7804/#7807) *)
+ List.map snd hunks (* drop locations which are dummy *)
+ | Some fmt ->
+ hunks_of_format (level, List.split typs) (symbols, parse_format fmt)
(* let make_syntax_rules i_typs (ntn,prec,need_squash) sy_data fmt extra onlyprint compat = *)
let make_syntax_rules (sd : SynData.syn_data) = let open SynData in
diff --git a/vernac/misctypes.ml b/vernac/misctypes.ml
index ae725efaa..ef9cd3c35 100644
--- a/vernac/misctypes.ml
+++ b/vernac/misctypes.ml
@@ -17,10 +17,10 @@ type 'a or_by_notation = 'a Constrexpr.or_by_notation
[@@ocaml.deprecated "use [Constrexpr.or_by_notation]"]
type intro_pattern_naming_expr = Namegen.intro_pattern_naming_expr =
- | IntroIdentifier of Id.t [@ocaml.deprecated "Use version in [Evarutil]"]
- | IntroFresh of Id.t [@ocaml.deprecated "Use version in [Evarutil]"]
- | IntroAnonymous [@ocaml.deprecated "Use version in [Evarutil]"]
-[@@ocaml.deprecated "use [Evarutil.intro_pattern_naming_expr]"]
+ | IntroIdentifier of Id.t [@ocaml.deprecated "Use version in [Namegen]"]
+ | IntroFresh of Id.t [@ocaml.deprecated "Use version in [Namegen]"]
+ | IntroAnonymous [@ocaml.deprecated "Use version in [Namegen]"]
+[@@ocaml.deprecated "use [Namegen.intro_pattern_naming_expr]"]
type 'a or_var = 'a Locus.or_var =
| ArgArg of 'a [@ocaml.deprecated "Use version in [Locus]"]
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index 1ab24b670..1f401b4e1 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -40,7 +40,7 @@ let check_evars env evm =
type oblinfo =
{ ev_name: int * Id.t;
- ev_hyps: Context.Named.t;
+ ev_hyps: Constr.named_context;
ev_status: bool * Evar_kinds.obligation_definition_status;
ev_chop: int option;
ev_src: Evar_kinds.t Loc.located;
@@ -480,10 +480,9 @@ let declare_definition prg =
let fix_exn = Hook.get get_fix_exn () in
let typ = nf typ in
let body = nf body in
- let env = Global.env () in
let uvars = Univ.LSet.union
- (Univops.universes_of_constr env typ)
- (Univops.universes_of_constr env body) in
+ (Univops.universes_of_constr typ)
+ (Univops.universes_of_constr body) in
let uctx = UState.restrict prg.prg_ctx uvars in
let univs = UState.check_univ_decl ~poly:(pi2 prg.prg_kind) uctx prg.prg_univdecl in
let ce = definition_entry ~fix_exn ~opaque ~types:typ ~univs body in
@@ -865,7 +864,7 @@ let obligation_terminator name num guard hook auto pf =
else UState.union prg.prg_ctx ctx
in
let uctx = UState.const_univ_entry ~poly:(pi2 prg.prg_kind) ctx in
- let (_, obl) = declare_obligation prg obl body ty uctx in
+ let (defined, obl) = declare_obligation prg obl body ty uctx in
let obls = Array.copy obls in
let _ = obls.(num) <- obl in
let prg_ctx =
@@ -874,10 +873,12 @@ let obligation_terminator name num guard hook auto pf =
polymorphic obligation with the existing ones *)
UState.union prg.prg_ctx ctx
else
- (** The first obligation declares the univs of the constant,
+ (** The first obligation, if defined,
+ declares the univs of the constant,
each subsequent obligation declares its own additional
universes and constraints if any *)
- UState.make (Global.universes ())
+ if defined then UState.make (Global.universes ())
+ else ctx
in
let prg = { prg with prg_ctx } in
try
diff --git a/vernac/ppvernac.ml b/vernac/ppvernac.ml
index 56dfaa54a..5fbe1f4e4 100644
--- a/vernac/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -210,7 +210,10 @@ open Pputils
| HintsTransparency (l, b) ->
keyword (if b then "Transparent" else "Opaque")
++ spc ()
- ++ prlist_with_sep sep pr_qualid l
+ ++ (match l with
+ | HintsVariables -> keyword "Variables"
+ | HintsConstants -> keyword "Constants"
+ | HintsReferences l -> prlist_with_sep sep pr_qualid l)
| HintsMode (m, l) ->
keyword "Mode"
++ spc ()
diff --git a/vernac/record.ml b/vernac/record.ml
index 940859723..7a8ce7d25 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -100,7 +100,7 @@ let binder_of_decl = function
let binders_of_decls = List.map binder_of_decl
-let typecheck_params_and_fields finite def id poly pl t ps nots fs =
+let typecheck_params_and_fields finite def poly pl ps records =
let env0 = Global.env () in
let sigma, decl = Constrexpr_ops.interp_univ_decl_opt env0 pl in
let _ =
@@ -117,7 +117,7 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
Loc.raise ?loc (Stream.Error "pattern with quote not allowed in record parameters")) ps
in
let sigma, (impls_env, ((env1,newps), imps)) = interp_context_evars env0 sigma ps in
- let sigma, typ, sort, template = match t with
+ let fold (sigma, template) (_, t, _, _) = match t with
| Some t ->
let env = EConstr.push_rel_context newps env0 in
let poly =
@@ -132,28 +132,36 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
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
+ (sigma, template), (s, s')
| None ->
- sigma, s, s', false
- else sigma, s, s', false)
+ (sigma, false), (s, s')
+ else (sigma, false), (s, s'))
| _ -> user_err ?loc:(constr_loc t) (str"Sort expected."))
| None ->
let uvarkind = Evd.univ_flexible_alg in
let sigma, s = Evd.new_sort_variable uvarkind sigma in
- sigma, EConstr.mkSort s, s, true
+ (sigma, template), (EConstr.mkSort s, s)
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 (sigma, template), typs = List.fold_left_map fold (sigma, true) records in
+ let arities = List.map (fun (typ, _) -> EConstr.it_mkProd_or_LetIn typ newps) typs in
+ let fold accu (id, _, _, _) arity = EConstr.push_rel (LocalAssum (Name id,arity)) accu in
+ let env_ar = EConstr.push_rel_context newps (List.fold_left2 fold env0 records arities) 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 != Declarations.BiFinite)) in
- let impls_env = compute_internalization_env env0 sigma ~impls:impls_env ty [id] [arity] [imps] in
- let env2,sigma,impls,newfs,data =
- interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs)
+ let impls_env =
+ let params = List.map (RelDecl.get_name %> Name.get_id) assums in
+ let ty = Inductive (params, (finite != Declarations.BiFinite)) in
+ let ids = List.map (fun (id, _, _, _) -> id) records in
+ let imps = List.map (fun _ -> imps) arities in
+ compute_internalization_env env0 sigma ~impls:impls_env ty ids arities imps
in
+ let fold sigma (_, _, nots, fs) arity =
+ let _, sigma, impls, newfs, _ = interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs) in
+ (sigma, (impls, newfs))
+ in
+ let (sigma, data) = List.fold_left2_map fold sigma records arities in
let sigma =
Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar sigma (Evd.from_env env_ar) in
- let sigma, typ =
+ let fold sigma (typ, sort) (_, newfs) =
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
@@ -164,20 +172,24 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
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 *)
- Evd.set_eq_sort env_ar sigma (Prop Pos) sort,
- EConstr.mkSort (Sorts.sort_of_univ univ)
+ Evd.set_eq_sort env_ar sigma Set sort, EConstr.mkSort (Sorts.sort_of_univ univ)
else sigma, typ
in
+ let (sigma, typs) = List.fold_left2_map fold sigma typs data in
let sigma = Evd.minimize_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.from_env env0) 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);
+ let ce t = Pretyping.check_evars env0 (Evd.from_env env0) sigma (EConstr.of_constr t) in
+ let () = List.iter (iter_constr ce) (List.rev newps) in
+ let map (impls, newfs) typ =
+ let newfs = List.map (EConstr.to_rel_decl sigma) newfs in
+ let typ = EConstr.to_constr sigma typ in
List.iter (iter_constr ce) (List.rev newfs);
- ubinders, univs, typ, template, imps, newps, impls, newfs
+ (typ, impls, newfs)
+ in
+ let ans = List.map2 map data typs in
+ ubinders, univs, template, newps, imps, ans
let degenerate_decl decl =
let id = match RelDecl.get_name decl with
@@ -261,9 +273,10 @@ let subst_projection fid l c =
raise (NotDefinable (MissingProj (fid,List.rev !bad_projs)));
c''
-let instantiate_possibly_recursive_type indu paramdecls fields =
+let instantiate_possibly_recursive_type ind u ntypes paramdecls fields =
let subst = List.map_i (fun i _ -> mkRel i) 1 paramdecls in
- Termops.substl_rel_context (subst@[mkIndU indu]) fields
+ let subst' = List.init ntypes (fun i -> mkIndU ((ind, ntypes - i - 1), u)) in
+ Termops.substl_rel_context (subst @ subst') fields
let warn_non_primitive_record =
CWarnings.create ~name:"non-primitive-record" ~category:"record"
@@ -281,19 +294,18 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
| Monomorphic_const_entry ctx -> Univ.Instance.empty
in
let paramdecls = Inductive.inductive_paramdecls (mib, u) in
- let indu = indsp, u in
let r = mkIndU (indsp,u) in
let rp = applist (r, Context.Rel.to_extended_list mkRel 0 paramdecls) in
let paramargs = Context.Rel.to_extended_list mkRel 1 paramdecls in (*def in [[params;x:rp]]*)
let x = Name binder_name in
- let fields = instantiate_possibly_recursive_type indu paramdecls fields in
+ let fields = instantiate_possibly_recursive_type (fst indsp) u mib.mind_ntypes paramdecls fields in
let lifted_fields = Termops.lift_rel_context 1 fields in
let primitive =
if !primitive_flag then
let is_primitive =
match mib.mind_record with
- | Some (Some _) -> true
- | Some None | None -> false
+ | PrimRecord _ -> true
+ | FakeRecord | NotRecord -> false
in
if not is_primitive then
warn_non_primitive_record (env,indsp);
@@ -374,12 +386,9 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
open Typeclasses
-let declare_structure finite ubinders univs id idbuild paramimpls params arity template
- fieldimpls fields ?(kind=StructureComponent) ?name is_coe coers =
- let nparams = List.length params and nfields = List.length fields in
- let args = Context.Rel.to_extended_list mkRel nfields params in
- let ind = applist (mkRel (1+nparams+nfields), args) in
- let type_constructor = it_mkProd_or_LetIn ind fields in
+
+let declare_structure finite ubinders univs paramimpls params template ?(kind=StructureComponent) ?name record_data =
+ let nparams = List.length params in
let template, ctx =
match univs with
| Monomorphic_ind_entry ctx ->
@@ -389,37 +398,51 @@ let declare_structure finite ubinders univs id idbuild paramimpls params arity t
| Cumulative_ind_entry cumi ->
false, Polymorphic_const_entry (Univ.CumulativityInfo.univ_context cumi)
in
- let binder_name =
+ let binder_name =
match name with
- | None -> Id.of_string (Unicode.lowercase_first_char (Id.to_string id))
+ | None ->
+ let map (id, _, _, _, _, _, _) =
+ Id.of_string (Unicode.lowercase_first_char (Id.to_string id))
+ in
+ Array.map_of_list map record_data
| Some n -> n
in
- let mie_ind =
+ let ntypes = List.length record_data in
+ let mk_block i (id, idbuild, arity, _, fields, _, _) =
+ let nfields = List.length fields in
+ let args = Context.Rel.to_extended_list mkRel nfields params in
+ let ind = applist (mkRel (ntypes - i + nparams + nfields), args) in
+ let type_constructor = it_mkProd_or_LetIn ind fields in
{ mind_entry_typename = id;
mind_entry_arity = arity;
mind_entry_template = template;
mind_entry_consnames = [idbuild];
mind_entry_lc = [type_constructor] }
in
+ let blocks = List.mapi mk_block record_data in
let mie =
{ mind_entry_params = List.map degenerate_decl params;
mind_entry_record = Some (if !primitive_flag then Some binder_name else None);
mind_entry_finite = finite;
- mind_entry_inds = [mie_ind];
+ mind_entry_inds = blocks;
mind_entry_private = None;
mind_entry_universes = univs;
}
in
let mie = InferCumulativity.infer_inductive (Global.env ()) mie 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
- let build = ConstructRef cstr in
- let poly = match ctx with | Polymorphic_const_entry _ -> true | Monomorphic_const_entry _ -> false in
- let () = if is_coe then Class.try_add_new_coercion build ~local:false poly in
- Recordops.declare_structure(rsp,cstr,List.rev kinds,List.rev sp_projs);
- rsp
+ let impls = List.map (fun _ -> paramimpls, []) record_data in
+ let kn = ComInductive.declare_mutual_inductive_with_eliminations mie ubinders impls in
+ let map i (_, _, _, fieldimpls, fields, is_coe, coers) =
+ let rsp = (kn, i) in (* This is ind path of idstruc *)
+ let cstr = (rsp, 1) in
+ let kinds,sp_projs = declare_projections rsp ctx ~kind binder_name.(i) coers ubinders fieldimpls fields in
+ let build = ConstructRef cstr in
+ let poly = match ctx with | Polymorphic_const_entry _ -> true | Monomorphic_const_entry _ -> false in
+ let () = if is_coe then Class.try_add_new_coercion build ~local:false poly in
+ let () = Recordops.declare_structure(rsp,cstr,List.rev kinds,List.rev sp_projs) in
+ rsp
+ in
+ List.mapi map record_data
let implicits_of_context ctx =
List.map_i (fun i name ->
@@ -431,22 +454,22 @@ let implicits_of_context ctx =
1 (List.rev (Anonymous :: (List.map RelDecl.get_name ctx)))
let declare_class finite def cum ubinders univs id idbuild paramimpls params arity
- template fieldimpls fields ?(kind=StructureComponent) is_coe coers priorities =
+ template fieldimpls fields ?(kind=StructureComponent) coers priorities =
let fieldimpls =
(* Make the class implicit in the projections, and the params if applicable. *)
let len = List.length params in
let impls = implicits_of_context params in
List.map (fun x -> impls @ Impargs.lift_implicits (succ len) x) fieldimpls
in
- let binder_name = Namegen.next_ident_away (snd id) (Termops.vars_of_env (Global.env())) in
- let impl, projs =
+ let binder_name = Namegen.next_ident_away id (Termops.vars_of_env (Global.env())) in
+ let data =
match fields with
| [LocalAssum (Name proj_name, field) | LocalDef (Name proj_name, _, field)] when def ->
let class_body = it_mkLambda_or_LetIn field params in
let class_type = it_mkProd_or_LetIn arity params in
let class_entry =
Declare.definition_entry ~types:class_type ~univs class_body in
- let cst = Declare.declare_constant (snd id)
+ let cst = Declare.declare_constant id
(DefinitionEntry class_entry, IsDefinition Definition)
in
let cstu = (cst, match univs with
@@ -473,7 +496,7 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
| Some b -> Some ((if b then Backward else Forward), List.hd priorities)
| None -> None
in
- cref, [Name proj_name, sub, Some proj_cst]
+ [cref, [Name proj_name, sub, Some proj_cst]]
| _ ->
let univs =
match univs with
@@ -485,18 +508,21 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
| Monomorphic_const_entry univs ->
Monomorphic_ind_entry univs
in
- let ind = declare_structure Declarations.BiFinite ubinders univs (snd id) idbuild paramimpls
- params arity template fieldimpls fields
- ~kind:Method ~name:binder_name false (List.map (fun _ -> false) fields)
- in
+ let record_data = [id, idbuild, arity, fieldimpls, fields, false, List.map (fun _ -> false) fields] in
+ let inds = declare_structure Declarations.BiFinite ubinders univs paramimpls
+ params template ~kind:Method ~name:[|binder_name|] record_data
+ in
let coers = List.map2 (fun coe pri ->
Option.map (fun b ->
if b then Backward, pri else Forward, pri) coe)
coers priorities
in
- let l = List.map3 (fun decl b y -> RelDecl.get_name decl, b, y)
- (List.rev fields) coers (Recordops.lookup_projections ind)
- in IndRef ind, l
+ let map ind =
+ let l = List.map3 (fun decl b y -> RelDecl.get_name decl, b, y)
+ (List.rev fields) coers (Recordops.lookup_projections ind)
+ in IndRef ind, l
+ in
+ List.map map inds
in
let ctx_context =
List.map (fun decl ->
@@ -517,16 +543,19 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
| Monomorphic_const_entry _ ->
Univ.AUContext.empty, ctx_context, fields
in
- let k =
- { cl_univs = univs;
- cl_impl = impl;
- cl_strict = !typeclasses_strict;
- cl_unique = !typeclasses_unique;
- cl_context = ctx_context;
- cl_props = fields;
- cl_projs = projs }
- in
+ let map (impl, projs) =
+ let k =
+ { cl_univs = univs;
+ cl_impl = impl;
+ cl_strict = !typeclasses_strict;
+ cl_unique = !typeclasses_unique;
+ cl_context = ctx_context;
+ cl_props = fields;
+ cl_projs = projs }
+ in
add_class k; impl
+ in
+ List.map map data
let add_constant_class cst =
@@ -562,48 +591,87 @@ let add_inductive_class ind =
cl_unique = !typeclasses_unique }
in add_class k
+let warn_already_existing_class =
+ CWarnings.create ~name:"already-existing-class" ~category:"automation" Pp.(fun g ->
+ Printer.pr_global g ++ str " is already declared as a typeclass.")
+
let declare_existing_class g =
- match g with
- | ConstRef x -> add_constant_class x
- | IndRef x -> add_inductive_class x
- | _ -> user_err ~hdr:"declare_existing_class"
- (Pp.str"Unsupported class type, only constants and inductives are allowed")
+ if Typeclasses.is_class g then warn_already_existing_class g
+ else
+ match g with
+ | ConstRef x -> add_constant_class x
+ | IndRef x -> add_inductive_class x
+ | _ -> user_err ~hdr:"declare_existing_class"
+ (Pp.str"Unsupported class type, only constants and inductives are allowed")
open Vernacexpr
-(* [fs] corresponds to fields and [ps] to parameters; [coers] is a
- list telling if the corresponding fields must me declared as coercions
- or subinstances. *)
-let definition_structure (kind,cum,poly,finite,(is_coe,({CAst.loc;v=idstruc},pl)),ps,cfs,idbuild,s) =
- let cfs,notations = List.split cfs in
- let cfs,priorities = List.split cfs in
- let coers,fs = List.split cfs in
- let extract_name acc = function
+let check_unique_names records =
+ let extract_name acc (((_, bnd), _), _) = match bnd with
Vernacexpr.AssumExpr({CAst.v=Name id},_) -> id::acc
| Vernacexpr.DefExpr ({CAst.v=Name id},_,_) -> id::acc
| _ -> acc in
- let allnames = idstruc::(List.fold_left extract_name [] fs) in
- let () = match List.duplicates Id.equal allnames with
+ let allnames =
+ List.fold_left (fun acc (_, id, _, _, cfs, _, _) ->
+ id.CAst.v :: (List.fold_left extract_name acc cfs)) [] records
+ in
+ match List.duplicates Id.equal allnames with
| [] -> ()
| id :: _ -> user_err (str "Two objects have the same name" ++ spc () ++ quote (Id.print id))
- in
+
+let check_priorities kind records =
let isnot_class = match kind with Class false -> false | _ -> true in
- if isnot_class && List.exists (fun opt -> not (Option.is_empty opt)) priorities then
- user_err Pp.(str "Priorities only allowed for type class substructures");
- (* Now, younger decl in params and fields is on top *)
- let pl, univs, arity, template, implpars, params, implfs, fields =
+ let has_priority (_, _, _, _, cfs, _, _) =
+ List.exists (fun ((_, pri), _) -> not (Option.is_empty pri)) cfs
+ in
+ if isnot_class && List.exists has_priority records then
+ user_err Pp.(str "Priorities only allowed for type class substructures")
+
+let extract_record_data records =
+ let map (is_coe, id, _, _, cfs, idbuild, s) =
+ let fs = List.map (fun (((_, f), _), _) -> f) cfs in
+ id.CAst.v, s, List.map snd cfs, fs
+ in
+ let data = List.map map records in
+ let pss = List.map (fun (_, _, _, ps, _, _, _) -> ps) records in
+ let ps = match pss with
+ | [] -> CErrors.anomaly (str "Empty record block")
+ | ps :: rem ->
+ let eq_local_binders bl1 bl2 = List.equal local_binder_eq bl1 bl2 in
+ let () =
+ if not (List.for_all (eq_local_binders ps) rem) then
+ user_err (str "Parameters should be syntactically the \
+ same for each inductive type.")
+ in
+ ps
+ in
+ (** FIXME: Same issue as #7754 *)
+ let _, _, pl, _, _, _, _ = List.hd records in
+ pl, ps, data
+
+(* [fs] corresponds to fields and [ps] to parameters; [coers] is a
+ list telling if the corresponding fields must me declared as coercions
+ or subinstances. *)
+let definition_structure kind cum poly finite records =
+ let () = check_unique_names records in
+ let () = check_priorities kind records in
+ let pl, ps, data = extract_record_data records in
+ let pl, univs, template, params, implpars, data =
States.with_state_protection (fun () ->
- typecheck_params_and_fields finite (kind = Class true) idstruc poly pl s ps notations fs) () in
+ typecheck_params_and_fields finite (kind = Class true) poly pl ps data) () in
match kind with
| Class def ->
- let priorities = List.map (fun id -> {hint_priority = id; hint_pattern = None}) priorities in
- declare_class finite def cum pl univs (loc,idstruc) idbuild
- implpars params arity template implfs fields is_coe coers priorities
+ let (_, id, _, _, cfs, idbuild, _), (arity, implfs, fields) = match records, data with
+ | [r], [d] -> r, d
+ | _, _ -> CErrors.user_err (str "Mutual definitional classes are not handled")
+ in
+ let priorities = List.map (fun ((_, id), _) -> {hint_priority = id; hint_pattern = None}) cfs in
+ let coers = List.map (fun (((coe, _), _), _) -> coe) cfs in
+ declare_class finite def cum pl univs id.CAst.v idbuild
+ implpars params arity template implfs fields coers priorities
| _ ->
- let implfs = List.map
- (fun impls -> implpars @ Impargs.lift_implicits
- (succ (List.length params)) impls) implfs
- in
+ let map impls = implpars @ Impargs.lift_implicits (succ (List.length params)) impls in
+ let data = List.map (fun (arity, implfs, fields) -> (arity, List.map map implfs, fields)) data in
let univs =
match univs with
| Polymorphic_const_entry univs ->
@@ -614,7 +682,11 @@ let definition_structure (kind,cum,poly,finite,(is_coe,({CAst.loc;v=idstruc},pl)
| Monomorphic_const_entry univs ->
Monomorphic_ind_entry univs
in
- let ind = declare_structure finite pl univs idstruc
- idbuild implpars params arity template implfs
- fields is_coe (List.map (fun coe -> not (Option.is_empty coe)) coers) in
- IndRef ind
+ let map (arity, implfs, fields) (is_coe, id, _, _, cfs, idbuild, _) =
+ let coers = List.map (fun (((coe, _), _), _) -> coe) cfs in
+ let coe = List.map (fun coe -> not (Option.is_empty coe)) coers in
+ id.CAst.v, idbuild, arity, implfs, fields, is_coe, coe
+ in
+ let data = List.map2 map data records in
+ let inds = declare_structure finite pl univs implpars params template data in
+ List.map (fun ind -> IndRef ind) inds
diff --git a/vernac/record.mli b/vernac/record.mli
index b2c039f0b..567f2b313 100644
--- a/vernac/record.mli
+++ b/vernac/record.mli
@@ -22,13 +22,18 @@ val declare_projections :
bool list ->
UnivNames.universe_binders ->
Impargs.manual_implicits list ->
- Context.Rel.t ->
+ Constr.rel_context ->
(Name.t * bool) list * Constant.t option list
val definition_structure :
- inductive_kind * Decl_kinds.cumulative_inductive_flag * Decl_kinds.polymorphic *
- Declarations.recursivity_kind * ident_decl with_coercion * local_binder_expr list *
+ inductive_kind -> Decl_kinds.cumulative_inductive_flag -> Decl_kinds.polymorphic ->
+ Declarations.recursivity_kind ->
+ (coercion_flag *
+ Names.lident *
+ universe_decl_expr option *
+ local_binder_expr list *
(local_decl_expr with_instance with_priority with_notation) list *
- Id.t * constr_expr option -> GlobRef.t
+ Id.t * constr_expr option) list ->
+ GlobRef.t list
val declare_existing_class : GlobRef.t -> unit
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 479482095..5fda1a0da 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -263,15 +263,13 @@ let print_namespace ns =
let matches mp = match match_modulepath ns mp with
| Some [] -> true
| _ -> false in
- let constants = (Global.env ()).Environ.env_globals.Environ.env_constants in
let constants_in_namespace =
- Cmap_env.fold (fun c (body,_) acc ->
- let kn = Constant.user c in
- if matches (KerName.modpath kn) then
- acc++fnl()++hov 2 (print_constant kn body)
- else
- acc
- ) constants (str"")
+ Environ.fold_constants (fun c body acc ->
+ let kn = Constant.user c in
+ if matches (KerName.modpath kn)
+ then acc++fnl()++hov 2 (print_constant kn body)
+ else acc)
+ (Global.env ()) (str"")
in
(print_list Id.print ns)++str":"++fnl()++constants_in_namespace
@@ -539,25 +537,43 @@ let should_treat_as_cumulative cum poly =
else user_err Pp.(str "The NonCumulative prefix can only be used in a polymorphic context.")
| None -> poly && Flags.is_polymorphic_inductive_cumulativity ()
-let vernac_record cum k poly finite struc binders sort nameopt cfs =
+let uniform_inductive_parameters = ref false
+
+let should_treat_as_uniform () =
+ if !uniform_inductive_parameters
+ then ComInductive.UniformParameters
+ else ComInductive.NonUniformParameters
+
+let vernac_record cum k poly finite records =
let is_cumulative = should_treat_as_cumulative cum poly in
- let const = match nameopt with
- | None -> add_prefix "Build_" (fst (snd struc)).v
- | Some ({v=id} as lid) ->
- Dumpglob.dump_definition lid false "constr"; id in
- if Dumpglob.dump () then (
- Dumpglob.dump_definition (fst (snd struc)) false "rec";
- List.iter (fun (((_, x), _), _) ->
- match x with
- | Vernacexpr.AssumExpr ({loc;v=Name id}, _) -> Dumpglob.dump_definition (make ?loc id) false "proj"
- | _ -> ()) cfs);
- ignore(Record.definition_structure (k,is_cumulative,poly,finite,struc,binders,cfs,const,sort))
+ let map ((coe, (id, pl)), binders, sort, nameopt, cfs) =
+ let const = match nameopt with
+ | None -> add_prefix "Build_" id.v
+ | Some lid ->
+ let () = Dumpglob.dump_definition lid false "constr" in
+ lid.v
+ in
+ let () =
+ if Dumpglob.dump () then
+ let () = Dumpglob.dump_definition id false "rec" in
+ let iter (((_, x), _), _) = match x with
+ | Vernacexpr.AssumExpr ({loc;v=Name id}, _) ->
+ Dumpglob.dump_definition (make ?loc id) false "proj"
+ | _ -> ()
+ in
+ List.iter iter cfs
+ in
+ coe, id, pl, binders, cfs, const, sort
+ in
+ let records = List.map map records in
+ ignore(Record.definition_structure k is_cumulative poly finite records)
(** When [poly] is true the type is declared polymorphic. When [lo] is true,
then the type is declared private (as per the [Private] keyword). [finite]
indicates whether the type is inductive, co-inductive or
neither. *)
let vernac_inductive ~atts cum lo finite indl =
+ let open Pp in
if Dumpglob.dump () then
List.iter (fun (((coe,(lid,_)), _, _, _, cstrs), _) ->
match cstrs with
@@ -567,35 +583,86 @@ let vernac_inductive ~atts cum lo finite indl =
Dumpglob.dump_definition lid false "constr") cstrs
| _ -> () (* dumping is done by vernac_record (called below) *) )
indl;
+ let is_record = function
+ | ((_ , _ , _ , _, RecordDecl _), _) -> true
+ | _ -> false
+ in
+ let is_constructor = function
+ | ((_ , _ , _ , _, Constructors _), _) -> true
+ | _ -> false
+ in
+ let is_defclass = match indl with
+ | [ ( id , bl , c , Class _, Constructors [l]), [] ] -> Some (id, bl, c, l)
+ | _ -> None
+ in
+ if Option.has_some is_defclass then
+ (** Definitional class case *)
+ let (id, bl, c, l) = Option.get is_defclass in
+ let (coe, (lid, ce)) = l in
+ let coe' = if coe then Some true else None in
+ let f = (((coe', AssumExpr ((make ?loc:lid.loc @@ Name lid.v), ce)), None), []) in
+ vernac_record cum (Class true) atts.polymorphic finite [id, bl, c, None, [f]]
+ else if List.for_all is_record indl then
+ (** Mutual record case *)
+ let check_kind ((_, _, _, kind, _), _) = match kind with
+ | Variant ->
+ user_err (str "The Variant keyword does not support syntax { ... }.")
+ | Record | Structure | Class _ | Inductive_kw | CoInductive -> ()
+ in
+ let () = List.iter check_kind indl in
+ let check_where ((_, _, _, _, _), wh) = match wh with
+ | [] -> ()
+ | _ :: _ ->
+ user_err (str "where clause not supported for records")
+ in
+ let () = List.iter check_where indl in
+ let unpack ((id, bl, c, _, decl), _) = match decl with
+ | RecordDecl (oc, fs) ->
+ (id, bl, c, oc, fs)
+ | Constructors _ -> assert false (** ruled out above *)
+ in
+ let ((_, _, _, kind, _), _) = List.hd indl in
+ let kind = match kind with Class _ -> Class false | _ -> kind in
+ let recordl = List.map unpack indl in
+ vernac_record cum kind atts.polymorphic finite recordl
+ else if List.for_all is_constructor indl then
+ (** Mutual inductive case *)
+ let check_kind ((_, _, _, kind, _), _) = match kind with
+ | (Record | Structure) ->
+ user_err (str "The Record keyword is for types defined using the syntax { ... }.")
+ | Class _ ->
+ user_err (str "Inductive classes not supported")
+ | Variant | Inductive_kw | CoInductive -> ()
+ in
+ let () = List.iter check_kind indl in
+ let check_name ((na, _, _, _, _), _) = match na with
+ | (true, _) ->
+ user_err (str "Variant types do not handle the \"> Name\" \
+ syntax, which is reserved for records. Use the \":>\" \
+ syntax on constructors instead.")
+ | _ -> ()
+ in
+ let () = List.iter check_name indl in
+ let unpack (((_, id) , bl, c, _, decl), ntn) = match decl with
+ | Constructors l -> (id, bl, c, l), ntn
+ | RecordDecl _ -> assert false (* ruled out above *)
+ in
+ let indl = List.map unpack indl in
+ let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
+ let uniform = should_treat_as_uniform () in
+ ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo ~uniform finite
+ else
+ user_err (str "Mixed record-inductive definitions are not allowed")
+(*
+
match indl with
- | [ ( _ , _ , _ ,(Record|Structure), Constructors _ ),_ ] ->
- user_err Pp.(str "The Record keyword is for types defined using the syntax { ... }.")
- | [ (_ , _ , _ ,Variant, RecordDecl _),_ ] ->
- user_err Pp.(str "The Variant keyword does not support syntax { ... }.")
- | [ ( id , bl , c , b, RecordDecl (oc,fs) ), [] ] ->
- vernac_record cum (match b with Class _ -> Class false | _ -> b)
- atts.polymorphic finite id bl c oc fs
| [ ( id , bl , c , Class _, Constructors [l]), [] ] ->
let f =
let (coe, ({loc;v=id}, ce)) = l in
let coe' = if coe then Some true else None in
(((coe', AssumExpr ((make ?loc @@ Name id), ce)), None), [])
- in vernac_record cum (Class true) atts.polymorphic finite id bl c None [f]
- | [ ( _ , _, _, Class _, Constructors _), [] ] ->
- user_err Pp.(str "Inductive classes not supported")
- | [ ( id , bl , c , Class _, _), _ :: _ ] ->
- user_err Pp.(str "where clause not supported for classes")
- | [ ( _ , _ , _ , _, RecordDecl _ ) , _ ] ->
- user_err Pp.(str "where clause not supported for (co)inductive records")
- | _ -> let unpack = function
- | ( (false, id) , bl , c , _ , Constructors l ) , ntn -> ( id , bl , c , l ) , ntn
- | ( (true,_),_,_,_,Constructors _),_ ->
- user_err Pp.(str "Variant types do not handle the \"> Name\" syntax, which is reserved for records. Use the \":>\" syntax on constructors instead.")
- | _ -> user_err Pp.(str "Cannot handle mutually (co)inductive records.")
- in
- let indl = List.map unpack indl in
- let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
- ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo finite
+ in vernac_record cum (Class true) atts.polymorphic finite [id, bl, c, None, [f]]
+ *)
let vernac_fixpoint ~atts discharge l =
let local = enforce_locality_exp atts.locality discharge in
@@ -1412,6 +1479,14 @@ let _ =
optwrite = Flags.make_polymorphic_inductive_cumulativity }
let _ =
+ declare_bool_option
+ { optdepr = false;
+ optname = "Uniform inductive parameters";
+ optkey = ["Uniform"; "Inductive"; "Parameters"];
+ optread = (fun () -> !uniform_inductive_parameters);
+ optwrite = (fun b -> uniform_inductive_parameters := b) }
+
+let _ =
declare_int_option
{ optdepr = false;
optname = "the level of inlining during functor application";
@@ -2030,7 +2105,7 @@ let interp ?proof ~atts ~st c =
| VernacExactProof c -> vernac_exact_proof c
| VernacAssumption ((discharge,kind),nl,l) ->
vernac_assumption ~atts discharge kind l nl
- | VernacInductive (cum, priv,finite,l) -> vernac_inductive ~atts cum priv finite l
+ | VernacInductive (cum, priv, finite, l) -> vernac_inductive ~atts cum priv finite l
| VernacFixpoint (discharge, l) -> vernac_fixpoint ~atts discharge l
| VernacCoFixpoint (discharge, l) -> vernac_cofixpoint ~atts discharge l
| VernacScheme l -> vernac_scheme l
diff --git a/vernac/vernacexpr.ml b/vernac/vernacexpr.ml
index f74383b02..f5f37339c 100644
--- a/vernac/vernacexpr.ml
+++ b/vernac/vernacexpr.ml
@@ -121,12 +121,17 @@ type 'a hint_info_gen = 'a Typeclasses.hint_info_gen =
type hint_info_expr = Hints.hint_info_expr
[@@ocaml.deprecated "Please use [Hints.hint_info_expr]"]
+type 'a hints_transparency_target = 'a Hints.hints_transparency_target =
+ | HintsVariables
+ | HintsConstants
+ | HintsReferences of 'a list
+
type hints_expr = Hints.hints_expr =
| HintsResolve of (Hints.hint_info_expr * bool * Hints.reference_or_constr) list
| HintsResolveIFF of bool * qualid list * int option
| HintsImmediate of Hints.reference_or_constr list
| HintsUnfold of qualid list
- | HintsTransparency of qualid list * bool
+ | HintsTransparency of qualid hints_transparency_target * bool
| HintsMode of qualid * Hints.hint_mode list
| HintsConstructors of qualid list
| HintsExtern of int * constr_expr option * Genarg.raw_generic_argument